Zabezpečený doplněk ingress gateway for Istio Service Mesh pro Azure Kubernetes Service
Článek Nasazení externího nebo interního příchozího přenosu dat Istio popisuje, jak nakonfigurovat bránu příchozího přenosu dat tak, aby zpřístupnil službu HTTP externímu nebo internímu provozu. Tento článek ukazuje, jak zveřejnit zabezpečenou službu HTTPS pomocí jednoduchého nebo vzájemného protokolu TLS.
Požadavky
Povolení doplňku Istio v clusteru podle dokumentace
Nasazení externí brány příchozího přenosu dat Istio podle dokumentace
Poznámka:
Tento článek se týká externí brány příchozího přenosu dat pro ukázku. Stejný postup by se použil ke konfiguraci vzájemného protokolu TLS pro interní bránu příchozího přenosu dat.
Požadované certifikáty klienta/serveru a klíče
Tento článek vyžaduje několik certifikátů a klíčů. Pomocí svého oblíbeného nástroje je můžete vytvořit nebo můžete použít následující příkazy openssl .
Vytvořte kořenový certifikát a privátní klíč pro podepisování certifikátů pro ukázkové služby:
mkdir bookinfo_certs openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -subj '/O=bookinfo Inc./CN=bookinfo.com' -keyout bookinfo_certs/bookinfo.com.key -out bookinfo_certs/bookinfo.com.crt
Vygenerujte certifikát a privátní klíč pro
productpage.bookinfo.com
:openssl req -out bookinfo_certs/productpage.bookinfo.com.csr -newkey rsa:2048 -nodes -keyout bookinfo_certs/productpage.bookinfo.com.key -subj "/CN=productpage.bookinfo.com/O=product organization" openssl x509 -req -sha256 -days 365 -CA bookinfo_certs/bookinfo.com.crt -CAkey bookinfo_certs/bookinfo.com.key -set_serial 0 -in bookinfo_certs/productpage.bookinfo.com.csr -out bookinfo_certs/productpage.bookinfo.com.crt
Vygenerujte klientský certifikát a privátní klíč:
openssl req -out bookinfo_certs/client.bookinfo.com.csr -newkey rsa:2048 -nodes -keyout bookinfo_certs/client.bookinfo.com.key -subj "/CN=client.bookinfo.com/O=client organization" openssl x509 -req -sha256 -days 365 -CA bookinfo_certs/bookinfo.com.crt -CAkey bookinfo_certs/bookinfo.com.key -set_serial 1 -in bookinfo_certs/client.bookinfo.com.csr -out bookinfo_certs/client.bookinfo.com.crt
Konfigurace brány příchozího přenosu dat TLS
Vytvoření tajného klíče protokolu TLS Kubernetes pro bránu příchozího přenosu dat; Azure Key Vault slouží k hostování certifikátů a klíčů a doplňků zprostředkovatele tajných kódů služby Azure Key Vault k synchronizaci tajných kódů do clusteru.
Nastavení služby Azure Key Vault a synchronizace tajných kódů do clusteru
Vytvoření služby Azure Key Vault
K zadání certifikátu a vstupů klíčů do doplňku Istio potřebujete prostředek služby Azure Key Vault.
export AKV_NAME=<azure-key-vault-resource-name> az keyvault create --name $AKV_NAME --resource-group $RESOURCE_GROUP --location $LOCATION
Povolte ve svém clusteru zprostředkovatele služby Azure Key Vault doplněk Ovladače CSI pro úložiště tajných kódů.
az aks enable-addons --addons azure-keyvault-secrets-provider --resource-group $RESOURCE_GROUP --name $CLUSTER
Autorizuje spravovanou identitu přiřazenou uživatelem doplňku pro přístup k prostředku služby Azure Key Vault pomocí zásad přístupu. Případně pokud služba Key Vault pro model oprávnění používá Azure RBAC, přiřaďte roli Azure Key Vault pro spravovanou identitu přiřazenou uživatelem podle těchto pokynů.
OBJECT_ID=$(az aks show --resource-group $RESOURCE_GROUP --name $CLUSTER --query 'addonProfiles.azureKeyvaultSecretsProvider.identity.objectId' -o tsv | tr -d '\r') CLIENT_ID=$(az aks show --resource-group $RESOURCE_GROUP --name $CLUSTER --query 'addonProfiles.azureKeyvaultSecretsProvider.identity.clientId') TENANT_ID=$(az keyvault show --resource-group $RESOURCE_GROUP --name $AKV_NAME --query 'properties.tenantId') az keyvault set-policy --name $AKV_NAME --object-id $OBJECT_ID --secret-permissions get list
Vytvářejte tajné kódy ve službě Azure Key Vault pomocí certifikátů a klíčů.
az keyvault secret set --vault-name $AKV_NAME --name test-productpage-bookinfo-key --file bookinfo_certs/productpage.bookinfo.com.key az keyvault secret set --vault-name $AKV_NAME --name test-productpage-bookinfo-crt --file bookinfo_certs/productpage.bookinfo.com.crt az keyvault secret set --vault-name $AKV_NAME --name test-bookinfo-crt --file bookinfo_certs/bookinfo.com.crt
Pomocí následujícího manifestu nasaďte SecretProviderClass a poskytněte ovladači CSI specifické parametry služby Azure Key Vault.
cat <<EOF | kubectl apply -f - apiVersion: secrets-store.csi.x-k8s.io/v1 kind: SecretProviderClass metadata: name: productpage-credential-spc namespace: aks-istio-ingress spec: provider: azure secretObjects: - secretName: productpage-credential type: tls data: - objectName: test-productpage-bookinfo-key key: key - objectName: test-productpage-bookinfo-crt key: cert parameters: useVMManagedIdentity: "true" userAssignedIdentityID: $CLIENT_ID keyvaultName: $AKV_NAME cloudName: "" objects: | array: - | objectName: test-productpage-bookinfo-key objectType: secret objectAlias: "test-productpage-bookinfo-key" - | objectName: test-productpage-bookinfo-crt objectType: secret objectAlias: "test-productpage-bookinfo-crt" tenantId: $TENANT_ID EOF
K nasazení ukázkového podu použijte následující manifest. Ovladač CSI úložiště tajných kódů vyžaduje pod, který odkazuje na prostředek SecretProviderClass, aby se zajistila synchronizace tajných kódů ze služby Azure Key Vault do clusteru.
cat <<EOF | kubectl apply -f - apiVersion: v1 kind: Pod metadata: name: secrets-store-sync-productpage namespace: aks-istio-ingress spec: containers: - name: busybox image: mcr.microsoft.com/oss/busybox/busybox:1.33.1 command: - "/bin/sleep" - "10" volumeMounts: - name: secrets-store01-inline mountPath: "/mnt/secrets-store" readOnly: true volumes: - name: secrets-store01-inline csi: driver: secrets-store.csi.k8s.io readOnly: true volumeAttributes: secretProviderClass: "productpage-credential-spc" EOF
Ověřte
productpage-credential
tajný klíč vytvořený v oboru názvůaks-istio-ingress
clusteru definovaný v prostředku SecretProviderClass.kubectl describe secret/productpage-credential -n aks-istio-ingress
Příklad výstupu:
Name: productpage-credential Namespace: aks-istio-ingress Labels: secrets-store.csi.k8s.io/managed=true Annotations: <none> Type: tls Data ==== cert: 1066 bytes key: 1704 bytes
Konfigurace brány příchozího přenosu dat a virtuální služby
Směrujte provoz HTTPS přes bránu příchozího přenosu dat Istio do ukázkových aplikací. Pomocí následujícího manifestu nasaďte prostředky brány a virtuální služby.
cat <<EOF | kubectl apply -f -
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
name: bookinfo-gateway
spec:
selector:
istio: aks-istio-ingressgateway-external
servers:
- port:
number: 443
name: https
protocol: HTTPS
tls:
mode: SIMPLE
credentialName: productpage-credential
hosts:
- productpage.bookinfo.com
---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: productpage-vs
spec:
hosts:
- productpage.bookinfo.com
gateways:
- bookinfo-gateway
http:
- match:
- uri:
exact: /productpage
- uri:
prefix: /static
- uri:
exact: /login
- uri:
exact: /logout
- uri:
prefix: /api/v1/products
route:
- destination:
port:
number: 9080
host: productpage
EOF
Poznámka:
V definici credentialName
brány musí odpovídat secretName
prostředku SecretProviderClass a selector
musí odkazovat na externí příchozí bránu pomocí jeho popisku, ve kterém je istio
klíč popisku a hodnota je aks-istio-ingressgateway-external
. Pro interní popisek brány příchozího přenosu dat je istio
a hodnota je aks-istio-ingressgateway-internal
.
Nastavte proměnné prostředí pro hostitele a porty externího příchozího přenosu dat:
export INGRESS_HOST_EXTERNAL=$(kubectl -n aks-istio-ingress get service aks-istio-ingressgateway-external -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
export SECURE_INGRESS_PORT_EXTERNAL=$(kubectl -n aks-istio-ingress get service aks-istio-ingressgateway-external -o jsonpath='{.spec.ports[?(@.name=="https")].port}')
export SECURE_GATEWAY_URL_EXTERNAL=$INGRESS_HOST_EXTERNAL:$SECURE_INGRESS_PORT_EXTERNAL
echo "https://$SECURE_GATEWAY_URL_EXTERNAL/productpage"
Ověření
Odešlete požadavek HTTPS pro přístup ke službě productpage prostřednictvím protokolu HTTPS:
curl -s -HHost:productpage.bookinfo.com --resolve "productpage.bookinfo.com:$SECURE_INGRESS_PORT_EXTERNAL:$INGRESS_HOST_EXTERNAL" --cacert bookinfo_certs/bookinfo.com.crt "https://productpage.bookinfo.com:$SECURE_INGRESS_PORT_EXTERNAL/productpage" | grep -o "<title>.*</title>"
Ověřte, že je stránka produktu ukázkové aplikace přístupná. Očekávaný výstup je:
<title>Simple Bookstore App</title>
Poznámka:
Pokud chcete nakonfigurovat přístup příchozího přenosu dat HTTPS ke službě HTTPS, tj. nakonfigurujte bránu příchozího přenosu dat tak, aby prováděla předávání SNI místo ukončení protokolu TLS u příchozích požadavků, aktualizujte režim tls v definici brány na PASSTHROUGH
. To dává bráně pokyn, aby předával příchozí provoz "tak, jak je", aniž by ukončoval protokol TLS.
Konfigurace vzájemné brány příchozího přenosu dat TLS
Rozšiřte definici brány tak, aby podporovala vzájemné tls.
Aktualizujte přihlašovací údaje brány příchozího přenosu dat odstraněním aktuálního tajného kódu a vytvořením nového. Server používá certifikát certifikační autority k ověření svých klientů a k uložení certifikátu certifikační autority musíme použít klíč ca.crt.
kubectl delete secretproviderclass productpage-credential-spc -n aks-istio-ingress kubectl delete secret/productpage-credential -n aks-istio-ingress kubectl delete pod/secrets-store-sync-productpage -n aks-istio-ingress
Pomocí následujícího manifestu znovu vytvořte SecretProviderClass s certifikátem certifikační autority.
cat <<EOF | kubectl apply -f - apiVersion: secrets-store.csi.x-k8s.io/v1 kind: SecretProviderClass metadata: name: productpage-credential-spc namespace: aks-istio-ingress spec: provider: azure secretObjects: - secretName: productpage-credential type: opaque data: - objectName: test-productpage-bookinfo-key key: tls.key - objectName: test-productpage-bookinfo-crt key: tls.crt - objectName: test-bookinfo-crt key: ca.crt parameters: useVMManagedIdentity: "true" userAssignedIdentityID: $CLIENT_ID keyvaultName: $AKV_NAME cloudName: "" objects: | array: - | objectName: test-productpage-bookinfo-key objectType: secret objectAlias: "test-productpage-bookinfo-key" - | objectName: test-productpage-bookinfo-crt objectType: secret objectAlias: "test-productpage-bookinfo-crt" - | objectName: test-bookinfo-crt objectType: secret objectAlias: "test-bookinfo-crt" tenantId: $TENANT_ID EOF
Pomocí následujícího manifestu znovu nasaďte ukázkový pod pro synchronizaci tajných kódů ze služby Azure Key Vault do clusteru.
cat <<EOF | kubectl apply -f - apiVersion: v1 kind: Pod metadata: name: secrets-store-sync-productpage namespace: aks-istio-ingress spec: containers: - name: busybox image: registry.k8s.io/e2e-test-images/busybox:1.29-4 command: - "/bin/sleep" - "10" volumeMounts: - name: secrets-store01-inline mountPath: "/mnt/secrets-store" readOnly: true volumes: - name: secrets-store01-inline csi: driver: secrets-store.csi.k8s.io readOnly: true volumeAttributes: secretProviderClass: "productpage-credential-spc" EOF
Ověřte
productpage-credential
tajný klíč vytvořený v oboru názvůaks-istio-ingress
clusteru .kubectl describe secret/productpage-credential -n aks-istio-ingress
Příklad výstupu:
Name: productpage-credential Namespace: aks-istio-ingress Labels: secrets-store.csi.k8s.io/managed=true Annotations: <none> Type: opaque Data ==== ca.crt: 1188 bytes tls.crt: 1066 bytes tls.key: 1704 bytes
Pomocí následujícího manifestu aktualizujte definici brány tak, aby nastavil režim TLS na VZÁJEMNÉ.
cat <<EOF | kubectl apply -f - apiVersion: networking.istio.io/v1beta1 kind: Gateway metadata: name: bookinfo-gateway spec: selector: istio: aks-istio-ingressgateway-external # use istio default ingress gateway servers: - port: number: 443 name: https protocol: HTTPS tls: mode: MUTUAL credentialName: productpage-credential # must be the same as secret hosts: - productpage.bookinfo.com EOF
Ověření
Pokus o odeslání požadavku HTTPS pomocí předchozího přístupu bez předání klientského certifikátu – a zobrazení se nezdaří.
curl -v -HHost:productpage.bookinfo.com --resolve "productpage.bookinfo.com:$SECURE_INGRESS_PORT_EXTERNAL:$INGRESS_HOST_EXTERNAL" --cacert bookinfo_certs/bookinfo.com.crt "https://productpage.bookinfo.com:$SECURE_INGRESS_PORT_EXTERNAL/productpage"
Příklad výstupu:
...
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.3 (IN), TLS alert, unknown (628):
* OpenSSL SSL_read: error:0A00045C:SSL routines::tlsv13 alert certificate required, errno 0
* Failed receiving HTTP2 data
* OpenSSL SSL_write: SSL_ERROR_ZERO_RETURN, errno 0
* Failed sending HTTP2 data
* Connection #0 to host productpage.bookinfo.com left intact
curl: (56) OpenSSL SSL_read: error:0A00045C:SSL routines::tlsv13 alert certificate required, errno 0
Předejte certifikát klienta s příznakem --cert
a privátním klíčem s příznakem --key
curl.
curl -s -HHost:productpage.bookinfo.com --resolve "productpage.bookinfo.com:$SECURE_INGRESS_PORT_EXTERNAL:$INGRESS_HOST_EXTERNAL" --cacert bookinfo_certs/bookinfo.com.crt --cert bookinfo_certs/client.bookinfo.com.crt --key bookinfo_certs/client.bookinfo.com.key "https://productpage.bookinfo.com:$SECURE_INGRESS_PORT_EXTERNAL/productpage" | grep -o "<title>.*</title>"
Ověřte, že je stránka produktu ukázkové aplikace přístupná. Očekávaný výstup je:
<title>Simple Bookstore App</title>
Odstranění prostředků
Pokud chcete vyčistit síť služby Istio a příchozí přenos dat (opouští se za clusterem), spusťte následující příkaz:
az aks mesh disable --resource-group ${RESOURCE_GROUP} --name ${CLUSTER}
Pokud chcete vyčistit všechny prostředky vytvořené z dokumentů s postupy istio, spusťte následující příkaz:
az group delete --name ${RESOURCE_GROUP} --yes --no-wait
Azure Kubernetes Service