Säker ingressgateway för Tillägg för Istio-tjänstnät för Azure Kubernetes Service
Artikeln Distribuera extern eller intern Istio-ingress beskriver hur du konfigurerar en ingressgateway för att exponera en HTTP-tjänst för extern/intern trafik. Den här artikeln visar hur du exponerar en säker HTTPS-tjänst med enkel eller ömsesidig TLS.
Förutsättningar
Aktivera Istio-tillägget i klustret enligt dokumentationen
Distribuera en extern Ingress-gateway för Istio enligt dokumentationen
Kommentar
Den här artikeln refererar till den externa ingressgatewayen för demonstration, samma steg skulle gälla för att konfigurera ömsesidig TLS för intern ingressgateway.
Nödvändiga klient-/servercertifikat och nycklar
Den här artikeln kräver flera certifikat och nycklar. Du kan använda ditt favoritverktyg för att skapa dem eller så kan du använda följande openssl-kommandon .
Skapa ett rotcertifikat och en privat nyckel för signering av certifikaten för exempeltjänster:
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
Generera ett certifikat och en privat nyckel för
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
Generera ett klientcertifikat och en privat nyckel:
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
Konfigurera en TLS-ingressgateway
Skapa en Kubernetes TLS-hemlighet för ingressgatewayen. Använd Azure Key Vault som värd för certifikat/nycklar och Azure Key Vault Secrets Provider-tillägget för att synkronisera hemligheter till klustret.
Konfigurera Azure Key Vault och synkronisera hemligheter till klustret
Skapa Azure Key Vault
Du behöver en Azure Key Vault-resurs för att ange certifikatet och nyckelindata till Istio-tillägget.
export AKV_NAME=<azure-key-vault-resource-name> az keyvault create --name $AKV_NAME --resource-group $RESOURCE_GROUP --location $LOCATION
Aktivera Azure Key Vault-providern för CSI-drivrutinstillägget för Secret Store i klustret.
az aks enable-addons --addons azure-keyvault-secrets-provider --resource-group $RESOURCE_GROUP --name $CLUSTER
Auktorisera den användartilldelade hanterade identiteten för tillägget för åtkomst till Azure Key Vault-resursen med hjälp av åtkomstprincip. Om ditt Key Vault använder Azure RBAC för behörighetsmodellen följer du anvisningarna här för att tilldela en Azure-roll för Key Vault för tilläggets användartilldelade hanterade identitet.
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
Skapa hemligheter i Azure Key Vault med hjälp av certifikat och nycklar.
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
Använd följande manifest för att distribuera SecretProviderClass för att tillhandahålla Azure Key Vault-specifika parametrar till CSI-drivrutinen.
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
Använd följande manifest för att distribuera en exempelpodd. CSI-drivrutinen för det hemliga arkivet kräver att en podd refererar till SecretProviderClass-resursen för att säkerställa att hemligheter synkroniseras från Azure Key Vault till klustret.
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
Verifiera
productpage-credential
hemligheten som skapats i klusternamnområdetaks-istio-ingress
enligt definitionen i SecretProviderClass-resursen.kubectl describe secret/productpage-credential -n aks-istio-ingress
Exempel på utdata>
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
Konfigurera ingressgateway och virtuell tjänst
Dirigera HTTPS-trafik via Istio-ingressgatewayen till exempelprogrammen. Använd följande manifest för att distribuera gateway- och virtuella tjänstresurser.
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
Kommentar
I gatewaydefinitionen credentialName
måste den matcha resursen secretName
i SecretProviderClass och selector
måste referera till den externa ingressgatewayen med dess etikett, där etikettens nyckel är istio
och värdet är aks-istio-ingressgateway-external
. För den interna ingressgatewayetiketten är istio
och värdet är aks-istio-ingressgateway-internal
.
Ange miljövariabler för extern inkommande värd och portar:
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"
Verifiering
Skicka en HTTPS-begäran för att få åtkomst till tjänsten productpage via 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>"
Bekräfta att exempelprogrammets produktsida är tillgänglig. Förväntade utdata är:
<title>Simple Bookstore App</title>
Kommentar
Om du vill konfigurera HTTPS-inkommande åtkomst till en HTTPS-tjänst, d.v.s. konfigurera en ingressgateway för att utföra SNI-genomströmning i stället för TLS-avslutning på inkommande begäranden, uppdaterar du tls-läget i gatewaydefinitionen till PASSTHROUGH
. Detta instruerar gatewayen att skicka inkommande trafik "som den är", utan att avsluta TLS.
Konfigurera en ömsesidig TLS-ingressgateway
Utöka gatewaydefinitionen så att den stöder ömsesidig TLS.
Uppdatera ingressgatewayens autentiseringsuppgifter genom att ta bort den aktuella hemligheten och skapa en ny. Servern använder CA-certifikatet för att verifiera sina klienter, och vi måste använda nyckeln ca.crt för att lagra CA-certifikatet.
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
Använd följande manifest för att återskapa SecretProviderClass med CA-certifikat.
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
Använd följande manifest för att distribuera om exempelpodden för att synkronisera hemligheter från Azure Key Vault till klustret.
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
Verifiera
productpage-credential
hemligheten som skapats på klusternamnområdetaks-istio-ingress
.kubectl describe secret/productpage-credential -n aks-istio-ingress
Exempel på utdata>
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
Använd följande manifest för att uppdatera gatewaydefinitionen för att ställa in TLS-läget på MUTUAL.
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
Verifiering
Försök att skicka HTTPS-begäran med den tidigare metoden – utan att skicka klientcertifikatet – och se att den misslyckas.
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"
Exempel på utdata>
...
* 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
Skicka klientens certifikat med flaggan och den --cert
privata nyckeln med --key
flaggan för att curla.
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>"
Bekräfta att exempelprogrammets produktsida är tillgänglig. Förväntade utdata är:
<title>Simple Bookstore App</title>
Ta bort resurser
Om du vill rensa Istio-tjänstnätet och ingresserna (lämnar kvar klustret) kör du följande kommando:
az aks mesh disable --resource-group ${RESOURCE_GROUP} --name ${CLUSTER}
Om du vill rensa alla resurser som skapats från instruktionsdokumenten för Istio kör du följande kommando:
az group delete --name ${RESOURCE_GROUP} --yes --no-wait
Azure Kubernetes Service