Інтеграція з власним ЦС за допомогою Kubernetes CSR
Ця функція вимагає версії Kubernetes >= 1.18.
Це завдання показує, як забезпечити сертифікати робочого навантаження використовуючи власний центр сертифікації, який інтегрується з API Kubernetes CSR. Різні робочі навантаження можуть отримувати свої сертифікати, підписані різними підписувачами сертифікатів. Кожен підписувач сертифікатів фактично є окремим CA. Очікується, що робочі навантаження, чиї сертифікати видані тим самим підписувачем, можуть взаємодіяти через mTLS, тоді як робочі навантаження, підписані різними підписувачами, не можуть.
Ця функція використовує Chiron, легкий компонент, повʼязаний з Istiod, який підписує сертифікати за допомогою API Kubernetes CSR.
Для цього прикладу ми використовуємо open-source cert-manager. Cert-manager додав експериментальну підтримку Kubernetes CertificateSigningRequests
починаючи з версії 1.4.
Розгортання власного контролера ЦС у кластері Kubernetes
Розгорніть cert-manager дотримуючись настанов з інструкції зі встановлення.
$ helm repo add jetstack https://charts.jetstack.io $ helm repo update $ helm install cert-manager jetstack/cert-manager --namespace cert-manager --create-namespace --set featureGates="ExperimentalCertificateSigningRequestControllers=true" --set installCRDs=true
Створіть трьох самопідписних кластерних емітентів
istio-system
,foo
іbar
для cert-manager. Зауваження: Також можна використовувати емітенти просторів імен та інші типи емітентів.$ cat <<EOF > ./selfsigned-issuer.yaml apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: selfsigned-bar-issuer spec: selfSigned: {} --- apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: bar-ca namespace: cert-manager spec: isCA: true commonName: bar secretName: bar-ca-selfsigned issuerRef: name: selfsigned-bar-issuer kind: ClusterIssuer group: cert-manager.io --- apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: bar spec: ca: secretName: bar-ca-selfsigned --- apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: selfsigned-foo-issuer spec: selfSigned: {} --- apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: foo-ca namespace: cert-manager spec: isCA: true commonName: foo secretName: foo-ca-selfsigned issuerRef: name: selfsigned-foo-issuer kind: ClusterIssuer group: cert-manager.io --- apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: foo spec: ca: secretName: foo-ca-selfsigned --- apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: selfsigned-istio-issuer spec: selfSigned: {} --- apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: istio-ca namespace: cert-manager spec: isCA: true commonName: istio-system secretName: istio-ca-selfsigned issuerRef: name: selfsigned-istio-issuer kind: ClusterIssuer group: cert-manager.io --- apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: istio-system spec: ca: secretName: istio-ca-selfsigned EOF $ kubectl apply -f ./selfsigned-issuer.yaml
Перевірте, що для кожного кластерного емітента створені секрети.
$ kubectl get secret -n cert-manager -l controller.cert-manager.io/fao=true
NAME TYPE DATA AGE
bar-ca-selfsigned kubernetes.io/tls 3 3m36s
foo-ca-selfsigned kubernetes.io/tls 3 3m36s
istio-ca-selfsigned kubernetes.io/tls 3 3m38s
Експортуйте кореневі сертифікати для кожного кластерного емітента
$ export ISTIOCA=$(kubectl get clusterissuers istio-system -o jsonpath='{.spec.ca.secretName}' | xargs kubectl get secret -n cert-manager -o jsonpath='{.data.ca\.crt}' | base64 -d | sed 's/^/ /')
$ export FOOCA=$(kubectl get clusterissuers foo -o jsonpath='{.spec.ca.secretName}' | xargs kubectl get secret -n cert-manager -o jsonpath='{.data.ca\.crt}' | base64 -d | sed 's/^/ /')
$ export BARCA=$(kubectl get clusterissuers bar -o jsonpath='{.spec.ca.secretName}' | xargs kubectl get secret -n cert-manager -o jsonpath='{.data.ca\.crt}' | base64 -d | sed 's/^/ /')
Розгортання Istio з інформацією стандартного підписувача сертифікатів
Розгорніть Istio у кластері за допомогою
istioctl
з наступною конфігурацією. ЗміннаISTIO_META_CERT_SIGNER
є стандартним підписувачем сертифікатів для робочих навантажень.$ cat <<EOF > ./istio.yaml apiVersion: install.istio.io/v1alpha1 kind: IstioOperator spec: values: pilot: env: EXTERNAL_CA: ISTIOD_RA_KUBERNETES_API meshConfig: defaultConfig: proxyMetadata: ISTIO_META_CERT_SIGNER: istio-system caCertificates: - pem: | $ISTIOCA certSigners: - clusterissuers.cert-manager.io/istio-system - pem: | $FOOCA certSigners: - clusterissuers.cert-manager.io/foo - pem: | $BARCA certSigners: - clusterissuers.cert-manager.io/bar components: pilot: k8s: env: - name: CERT_SIGNER_DOMAIN value: clusterissuers.cert-manager.io - name: PILOT_CERT_PROVIDER value: k8s.io/clusterissuers.cert-manager.io/istio-system overlays: - kind: ClusterRole name: istiod-clusterrole-istio-system patches: - path: rules[-1] value: | apiGroups: - certificates.k8s.io resourceNames: - clusterissuers.cert-manager.io/foo - clusterissuers.cert-manager.io/bar - clusterissuers.cert-manager.io/istio-system resources: - signers verbs: - approve EOF $ istioctl install --skip-confirmation -f ./istio.yaml
Створіть простори імен
bar
таfoo
.$ kubectl create ns bar $ kubectl create ns foo
Розгорніть файл
proxyconfig-bar.yaml
у просторі іменbar
, щоб визначити сертифікат підписувача для робочих навантажень у просторі іменbar
.$ cat <<EOF > ./proxyconfig-bar.yaml apiVersion: networking.istio.io/v1beta1 kind: ProxyConfig metadata: name: barpc namespace: bar spec: environmentVariables: ISTIO_META_CERT_SIGNER: bar EOF $ kubectl apply -f ./proxyconfig-bar.yaml
Розгорніть файл
proxyconfig-foo.yaml
у просторі іменfoo
, щоб визначити сертифікат підписувача для робочих навантажень у просторі іменfoo
.$ cat <<EOF > ./proxyconfig-foo.yaml apiVersion: networking.istio.io/v1beta1 kind: ProxyConfig metadata: name: foopc namespace: foo spec: environmentVariables: ISTIO_META_CERT_SIGNER: foo EOF $ kubectl apply -f ./proxyconfig-foo.yaml
Розгорніть демонстраційні застосунки
httpbin
таcurl
у просторах іменfoo
іbar
.$ kubectl label ns foo istio-injection=enabled $ kubectl label ns bar istio-injection=enabled $ kubectl apply -f samples/httpbin/httpbin.yaml -n foo $ kubectl apply -f samples/curl/curl.yaml -n foo $ kubectl apply -f samples/httpbin/httpbin.yaml -n bar
Перевірка мережевої взаємодії між httpbin
і curl
у межах одного простору імен
Коли робочі навантаження розгорнуті, вони надсилають запити CSR з відповідною інформацією про підписувача. Istiod пересилає запит CSR до власного центру сертифікації користувача для підпису. Власний CA використовує відповідного кластерного емітента для підпису сертифіката. Робочі навантаження у просторі імен foo
використовують кластерних емітентів foo
, а робочі навантаження у просторі імен bar
використовують кластерних емітентів bar
. Щоб перевірити, що сертифікати дійсно підписані правильними кластерними емітентами, можна перевірити, чи можуть робочі навантаження в одному просторі імен спілкуватися між собою, тоді як робочі навантаження з різних просторів імен не можуть.
Вкажіть в змінну середовища
CURL_POD_FOO
імʼя podʼаcurl
.$ export CURL_POD_FOO=$(kubectl get pod -n foo -l app=curl -o jsonpath={.items..metadata.name})
Перевірте мережеве зʼєднання між сервісом
curl
таhttpbin
в просторі іменfoo
.$ kubectl exec "$CURL_POD_FOO" -n foo -c curl -- curl http://httpbin.foo:8000/html <!DOCTYPE html> <html> <head> </head> <body> <h1>Herman Melville - Moby-Dick</h1> <div> <p> Availing himself of the mild... </p> </div> </body>
Перевірте мережеве зʼєднання між сервісами
curl
у просторі іменfoo
таhttpbin
у просторі іменbar
.$ kubectl exec "$CURL_POD_FOO" -n foo -c curl -- curl http://httpbin.bar:8000/html upstream connect error or disconnect/reset before headers. reset reason: connection failure, transport failure reason: TLS error: 268435581:SSL routines:OPENSSL_internal:CERTIFICATE_VERIFY_FAILED
Очищення
Видаліть простори імен та видаліть Istio і cert-manager:
$ kubectl delete ns foo $ kubectl delete ns bar $ istioctl uninstall --purge -y $ helm delete -n cert-manager cert-manager $ kubectl delete ns istio-system cert-manager $ unset ISTIOCA FOOCA BARCA $ rm -rf istio.yaml proxyconfig-foo.yaml proxyconfig-bar.yaml selfsigned-issuer.yaml
Причини використання цієї функції
Інтеграція власного CA — Завдяки вказівці імені підписувача в запиті CSR Kubernetes, ця функція дозволяє Istio інтегруватися з власними центрами сертифікації через API інтерфейс Kubernetes CSR. Це вимагає, щоб власний CA реалізував контролер Kubernetes для спостереження за ресурсами
CertificateSigningRequest
і обробки їх.Покращена багатокористувацька підтримка — Вказавши різних підписувачів сертифікатів для різних робочих навантажень, сертифікати для робочих навантажень різних користувачів можуть бути підписані різними центрами сертифікації.