SPIRE
SPIRE є готовою до використання реалізацією специфікації SPIFFE, яка виконує атестацію вузлів та навантажень для безпечної видачі криптографічних ідентифікаторів навантаженням, що працюють в гетерогенних середовищах. SPIRE можна налаштувати як джерело криптографічних ідентифікаторів для навантажень Istio через інтеграцію з SDS API Envoy. Istio може виявити існування UNIX Domain Socket, який реалізує Envoy SDS API на визначеному шляху до сокета, що дозволяє Envoy безпосередньо звʼязуватися та отримувати ідентифікатори з нього.
Ця інтеграція з SPIRE забезпечує гнучкі варіанти атестації, недоступні з типовим управлінням ідентифікацією в Istio, використовуючи потужне управління сервісами Istio. Наприклад, архітектура втулків SPIRE дозволяє використовувати різноманітні варіанти атестації навантажень за межами простору імен Kubernetes та облікових записів сервісів, що пропонуються Istio. Атестація вузлів SPIRE розширює атестацію на фізичне або віртуальне апаратне забезпечення, на якому працюють навантаження.
Для швидкого демонстраційного прикладу того, як працює інтеграція SPIRE з Istio, див. Інтеграція SPIRE як CA через SDS API Envoy.
Встановлення SPIRE
Рекомендуємо дотримуватись інструкцій з встановлення SPIRE та найкращих практик для розгортання SPIRE у промислових середовищах.
Для прикладів у цьому посібнику використовуватимуться Helm чарти SPIRE з типовими налаштуваннями, щоб зосередитися лише на конфігурації, необхідній для інтеграції SPIRE та Istio.
$ helm upgrade --install -n spire-server spire-crds spire-crds --repo https://spiffe.github.io/helm-charts-hardened/ --create-namespace
$ helm upgrade --install -n spire-server spire spire --repo https://spiffe.github.io/helm-charts-hardened/ --wait --set global.spire.trustDomain="example.org"
Вище також буде встановлено:
SPIFFE CSI драйвер, який використовується для монтування SDS сокетів, сумісних з Envoy, у проксі. Використання SPIFFE CSI драйвера для монтування SDS сокетів наполегливо рекомендується як Istio, так і SPIRE, оскільки
hostMounts
є більшим ризиком безпеки та створюють оперативні труднощі. Цей посібник припускає використання SPIFFE CSI драйвера.SPIRE Controller Manager, який спрощує створення реєстрацій SPIFFE для навантажень.
Реєстрація навантажень
За задумом, SPIRE надає ідентифікатори тільки навантаженням, які були зареєстровані на сервері SPIRE; це включає навантаження користувача, а також компоненти Istio. Sidecar Istio та шлюзи Istio, після налаштування інтеграції з SPIRE, не можуть отримати ідентифікатори а, отже, не можуть досягти статусу READY, якщо заздалегідь не було створено відповідну реєстрацію SPIRE.
Дивіться документацію SPIRE про реєстрацію навантажень для отримання додаткової інформації про використання кількох селекторів для зміцнення критеріїв атестації та доступних селекторів.
Цей розділ описує варіанти, доступні для реєстрації навантажень Istio на сервері SPIRE, і наводить приклади реєстрацій навантажень.
Варіант 1: Автоматична реєстрація за допомогою SPIRE Controller Manager
Нові записи будуть автоматично реєструватися для кожного нового podʼа, що відповідає селектору, визначеному в ClusterSPIFFEID користувацькому ресурсі.
Sidecar Istio та шлюзи Istio повинні бути зареєстровані з SPIRE, щоб вони могли запитувати ідентифікатори.
Istio Gateway ClusterSPIFFEID
Наступне створить ClusterSPIFFEID
, який автоматично зареєструє будь-який Istio Ingress gateway pod з SPIRE, якщо він розгорнутий у просторі імен istio-system
і має обліковий запис сервісу з імʼям istio-ingressgateway-service-account
. Ці селектори використовуються як простий приклад; зверніться до документації SPIRE Controller Manager для отримання більш детальної інформації.
$ kubectl apply -f - <<EOF
apiVersion: spire.spiffe.io/v1alpha1
kind: ClusterSPIFFEID
metadata:
name: istio-ingressgateway-reg
spec:
spiffeIDTemplate: "spiffe://{{ .TrustDomain }}/ns/{{ .PodMeta.Namespace }}/sa/{{ .PodSpec.ServiceAccountName }}"
workloadSelectorTemplates:
- "k8s:ns:istio-system"
- "k8s:sa:istio-ingressgateway-service-account"
EOF
Istio Sidecar ClusterSPIFFEID
Наступне створить ClusterSPIFFEID
, який автоматично зареєструє будь-який pod з міткою spiffe.io/spire-managed-identity: true
, що розгорнутий у просторі імен default
, з SPIRE. Ці селектори використовуються як простий приклад; зверніться до документації SPIRE Controller Manager для отримання більш детальної інформації.
$ kubectl apply -f - <<EOF
apiVersion: spire.spiffe.io/v1alpha1
kind: ClusterSPIFFEID
metadata:
name: istio-sidecar-reg
spec:
spiffeIDTemplate: "spiffe://{{ .TrustDomain }}/ns/{{ .PodMeta.Namespace }}/sa/{{ .PodSpec.ServiceAccountName }}"
podSelector:
matchLabels:
spiffe.io/spire-managed-identity: "true"
workloadSelectorTemplates:
- "k8s:ns:default"
EOF
Варіант 2: Ручна реєстрація
Якщо ви бажаєте вручну створити ваші реєстрації SPIRE, а не використовувати SPIRE Controller Manager, згаданий в рекомендованому варіанті, зверніться до документації SPIRE з ручної реєстрації.
Нижче наведені еквівалентні ручні реєстрації на основі автоматичних реєстрацій в Варіанті 1. Наступні кроки припускають, що ви вже виконали інструкції SPIRE для ручної реєстрації вашого агента SPIRE та атестації вузлів і що ваш агент SPIRE був зареєстрований з ідентифікатором SPIFFE spiffe://example.org/ns/spire/sa/spire-agent
.
Отримайте pod
spire-server
:$ SPIRE_SERVER_POD=$(kubectl get pod -l statefulset.kubernetes.io/pod-name=spire-server-0 -n spire-server -o jsonpath="{.items[0].metadata.name}")
Зареєструйте запис для podʼа шлюзу Istio Ingress:
$ kubectl exec -n spire "$SPIRE_SERVER_POD" -- \ /opt/spire/bin/spire-server entry create \ -spiffeID spiffe://example.org/ns/istio-system/sa/istio-ingressgateway-service-account \ -parentID spiffe://example.org/ns/spire/sa/spire-agent \ -selector k8s:sa:istio-ingressgateway-service-account \ -selector k8s:ns:istio-system \ -socketPath /run/spire/sockets/server.sock Entry ID : 6f2fe370-5261-4361-ac36-10aae8d91ff7 SPIFFE ID : spiffe://example.org/ns/istio-system/sa/istio-ingressgateway-service-account Parent ID : spiffe://example.org/ns/spire/sa/spire-agent Revision : 0 TTL : default Selector : k8s:ns:istio-system Selector : k8s:sa:istio-ingressgateway-service-account
Зареєструйте запис для навантажень, в які вставлено sidecar Istio:
$ kubectl exec -n spire "$SPIRE_SERVER_POD" -- \ /opt/spire/bin/spire-server entry create \ -spiffeID spiffe://example.org/ns/default/sa/curl \ -parentID spiffe://example.org/ns/spire/sa/spire-agent \ -selector k8s:ns:default \ -selector k8s:pod-label:spiffe.io/spire-managed-identity:true \ -socketPath /run/spire/sockets/server.sock
Встановлення Istio
Створіть конфігурацію Istio з власними патчами для Ingress Gateway і
istio-proxy
. Компонент Ingress Gateway включає міткуspiffe.io/spire-managed-identity: "true"
.$ cat <<EOF > ./istio.yaml apiVersion: install.istio.io/v1alpha1 kind: IstioOperator metadata: namespace: istio-system spec: profile: default meshConfig: trustDomain: example.org values: # Це використовується для налаштування шаблону sidecar. # Додає як мітку, щоб вказати, що SPIRE повинен керувати # ідентичністю цього pod, так і монтуванням драйвера CSI. sidecarInjectorWebhook: templates: spire: | labels: spiffe.io/spire-managed-identity: "true" spec: containers: - name: istio-proxy volumeMounts: - name: workload-socket mountPath: /run/secrets/workload-spiffe-uds readOnly: true volumes: - name: workload-socket csi: driver: "csi.spiffe.io" readOnly: true components: ingressGateways: - name: istio-ingressgateway enabled: true label: istio: ingressgateway k8s: overlays: # Це використовується для налаштування шаблону ingress gateway. # Додає монтування драйвера CSI, а також контейнер ініціалізації # для затримки запуску gateway до тих пір, поки драйвер CSI не змонтує сокет. - apiVersion: apps/v1 kind: Deployment name: istio-ingressgateway patches: - path: spec.template.spec.volumes.[name:workload-socket] value: name: workload-socket csi: driver: "csi.spiffe.io" readOnly: true - path: spec.template.spec.containers.[name:istio-proxy].volumeMounts.[name:workload-socket] value: name: workload-socket mountPath: "/run/secrets/workload-spiffe-uds" readOnly: true - path: spec.template.spec.initContainers value: - name: wait-for-spire-socket image: busybox:1.36 volumeMounts: - name: workload-socket mountPath: /run/secrets/workload-spiffe-uds readOnly: true env: - name: CHECK_FILE value: /run/secrets/workload-spiffe-uds/socket command: - sh - "-c" - |- echo "$(date -Iseconds)" Waiting for: ${CHECK_FILE} while [[ ! -e ${CHECK_FILE} ]] ; do echo "$(date -Iseconds)" File does not exist: ${CHECK_FILE} sleep 15 done ls -l ${CHECK_FILE} EOF
Застосуйте конфігурацію:
$ istioctl install --skip-confirmation -f ./istio.yaml
Перевірте стан podʼа Ingress Gateway:
$ kubectl get pods -n istio-system NAME READY STATUS RESTARTS AGE istio-ingressgateway-5b45864fd4-lgrxs 1/1 Running 0 17s istiod-989f54d9c-sg7sn 1/1 Running 0 23s
Pod Ingress Gateway знаходиться в статусі
Ready
, оскільки відповідний запис реєстрації автоматично створюється для нього на сервері SPIRE. Envoy може отримувати криптографічні ідентичності з SPIRE.Ця конфігурація також додає
initContainer
до шлюзу, який буде чекати, поки SPIRE створить UNIX Domain Socket, перш ніж запуститиistio-proxy
. Якщо агент SPIRE не готовий або не був належним чином налаштований з тим же шляхом сокета,initContainer
Ingress Gateway буде чекати вічно.Розгорніть приклад навантаження:
$ istioctl kube-inject --filename @samples/security/spire/curl-spire.yaml@ | kubectl apply -f -
Окрім необхідності мітки
spiffe.io/spire-managed-identity
, навантаження потребуватиме тому SPIFFE CSI Driver для доступу до сокета агента SPIRE. Для цього ви можете скористатися шаблоном анотації podʼаspire
з розділу Встановлення Istio або додати том CSI до специфікації розгортання вашого навантаження. Обидва ці варіанти виділені в наступному прикладі:apiVersion: apps/v1 kind: Deployment metadata: name: curl spec: replicas: 1 selector: matchLabels: app: curl template: metadata: labels: app: curl # Впроваджує власний шаблон користувача sidecar annotations: inject.istio.io/templates: "sidecar,spire" spec: terminationGracePeriodSeconds: 0 serviceAccountName: curl containers: - name: curl image: curlimages/curl command: ["/bin/sleep", "3650d"] imagePullPolicy: IfNotPresent volumeMounts: - name: tmp mountPath: /tmp securityContext: runAsUser: 1000 volumes: - name: tmp emptyDir: {} # Обсяг CSI - name: workload-socket csi: driver: "csi.spiffe.io" readOnly: true
Конфігурація Istio ділиться spiffe-csi-driver
між Ingress Gateway і sidecarʼами, які будуть впроваджені на podʼах навантаження, надаючи їм доступ до UNIX Domain Socket агента SPIRE.
Дивіться Перевірка, що ідентичності були створені для навантажень для перевірки виданих ідентичностей.
Перевірка створення ідентичностей для навантажень
Використовуйте наступну команду, щоб підтвердити, що ідентичності були створені для навантажень:
$ kubectl exec -t "$SPIRE_SERVER_POD" -n spire-server -c spire-server -- ./bin/spire-server entry show
Found 2 entries
Entry ID : c8dfccdc-9762-4762-80d3-5434e5388ae7
SPIFFE ID : spiffe://example.org/ns/istio-system/sa/istio-ingressgateway-service-account
Parent ID : spiffe://example.org/spire/agent/k8s_psat/demo-cluster/bea19580-ae04-4679-a22e-472e18ca4687
Revision : 0
X509-SVID TTL : default
JWT-SVID TTL : default
Selector : k8s:pod-uid:88b71387-4641-4d9c-9a89-989c88f7509d
Entry ID : af7b53dc-4cc9-40d3-aaeb-08abbddd8e54
SPIFFE ID : spiffe://example.org/ns/default/sa/curl
Parent ID : spiffe://example.org/spire/agent/k8s_psat/demo-cluster/bea19580-ae04-4679-a22e-472e18ca4687
Revision : 0
X509-SVID TTL : default
JWT-SVID TTL : default
Selector : k8s:pod-uid:ee490447-e502-46bd-8532-5a746b0871d6
Перевірте стан pod Ingress Gateway:
$ kubectl get pods -n istio-system
NAME READY STATUS RESTARTS AGE
istio-ingressgateway-5b45864fd4-lgrxs 1/1 Running 0 60s
istiod-989f54d9c-sg7sn 1/1 Running 0 45s
Після реєстрації запису для pod Ingress Gateway, Envoy отримує ідентичність, видану SPIRE, і використовує її для всіх TLS і mTLS комунікацій.
Перевірка, що ідентичність навантаження була видана SPIRE
Отримайте інформацію про pod:
$ CURL_POD=$(kubectl get pod -l app=curl -o jsonpath="{.items[0].metadata.name}")
Отримайте документ ідентичності SVID для
curl
за допомогою команди istioctl proxy-config secret:$ istioctl proxy-config secret "$CURL_POD" -o json | jq -r \ ʼ.dynamicActiveSecrets[0].secret.tlsCertificate.certificateChain.inlineBytesʼ | base64 --decode > chain.pem
Перевірте сертифікат і підтвердіть, що SPIRE є видавцем:
$ openssl x509 -in chain.pem -text | grep SPIRE Subject: C = US, O = SPIRE, CN = curl-5f4d47c948-njvpk
Федерація SPIFFE
Сервери SPIRE можуть автентифікувати ідентичності SPIFFE, які походять з різних доменів довіри. Це відомо як федерація SPIFFE.
SPIRE Agent можна налаштувати на передачу обʼєднаних пакетів до Envoy через API Envoy SDS, що дозволяє Envoy використовувати контекст перевірки для перевірки однорангових сертифікатів і довіри робочому навантаженню з іншого домену довіри. Щоб дозволити Istio федерацію ідентичностей SPIFFE через інтеграцію SPIRE, ознайомтеся з конфігурацією SPIRE Agent SDS та встановіть наступні значення конфігурації SDS у вашому конфігураційному файлі SPIRE Agent.
Конфігурація | Опис | Назва ресурсу |
---|---|---|
default_svid_name | Назва ресурсу сертифіката TLS для використання як стандартного X509-SVID з Envoy SDS | default |
default_bundle_name | Назва ресурсу контексту перевірки для використання як стандартного X.509 пакет з Envoy SDS | null |
default_all_bundles_name | Назва ресурсу контексту перевірки для всіх пакетів (включаючи федеративні) з Envoy SDS | ROOTCA |
Це дозволить Envoy отримувати федеративні пакети безпосередньо з SPIRE.
Створення федеративних записів реєстрації
Якщо ви використовуєте SPIRE Controller Manager, створіть федеративні записи для навантажень, встановивши поле
federatesWith
у ClusterSPIFFEID CR на домени довіри, з якими pod повинен федеративно з’єднуватися:apiVersion: spire.spiffe.io/v1alpha1 kind: ClusterSPIFFEID metadata: name: federation spec: spiffeIDTemplate: "spiffe://{{ .TrustDomain }}/ns/{{ .PodMeta.Namespace }}/sa/{{ .PodSpec.ServiceAccountName }}" podSelector: matchLabels: spiffe.io/spire-managed-identity: "true" federatesWith: ["example.io", "example.ai"]
Для ручної реєстрації дивіться Створення записів реєстрації для федерації.
Очищення SPIRE
Видаліть SPIRE, видаливши його Helm-чарти:
$ helm delete -n spire-server spire
$ helm delete -n spire-server spire-crds