Gateway ingress aman untuk add-on mesh layanan Istio untuk Azure Kubernetes Service
Artikel Sebarkan Istio Ingress eksternal atau internal menjelaskan cara mengonfigurasi gateway ingress untuk mengekspos layanan HTTP ke lalu lintas eksternal/internal. Artikel ini menunjukkan cara mengekspos layanan HTTPS yang aman menggunakan TLS sederhana atau bersama.
Aktifkan add-on Istio pada kluster sesuai dokumentasi
Menyebarkan gateway masuk Istio eksternal sesuai dokumentasi
Catatan
Artikel ini mengacu pada gateway ingress eksternal untuk demonstrasi, langkah yang sama akan berlaku untuk mengonfigurasi TLS bersama untuk gateway masuk internal.
Artikel ini memerlukan beberapa sertifikat dan kunci. Anda dapat menggunakan alat favorit Anda untuk membuatnya atau Anda dapat menggunakan perintah openssl berikut.
Buat sertifikat akar dan kunci privat untuk menandatangani sertifikat untuk layanan sampel:
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
Buat sertifikat dan kunci privat untuk
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
Buat sertifikat klien dan kunci privat:
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
Buat rahasia TLS Kubernetes untuk gateway ingress; gunakan Azure Key Vault untuk menghosting sertifikat/kunci dan add-on Penyedia Rahasia Azure Key Vault untuk menyinkronkan rahasia ke kluster.
Buat Azure Key Vault
Anda memerlukan sumber daya Azure Key Vault untuk menyediakan sertifikat dan input kunci ke add-on Istio.
export AKV_NAME=<azure-key-vault-resource-name> az keyvault create --name $AKV_NAME --resource-group $RESOURCE_GROUP --location $LOCATION
Aktifkan penyedia Azure Key Vault untuk add-on Driver Secret Store CSI di kluster Anda.
az aks enable-addons --addons azure-keyvault-secrets-provider --resource-group $RESOURCE_GROUP --name $CLUSTER
Otorisasi identitas terkelola add-on yang ditetapkan pengguna untuk mengakses sumber daya Azure Key Vault menggunakan kebijakan akses. Atau, jika Key Vault Anda menggunakan Azure RBAC untuk model izin, ikuti instruksi di sini untuk menetapkan peran Azure Key Vault untuk identitas terkelola add-on yang ditetapkan pengguna.
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
Buat rahasia di Azure Key Vault menggunakan sertifikat dan kunci.
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
Gunakan manifes berikut untuk menyebarkan SecretProviderClass untuk menyediakan parameter khusus Azure Key Vault ke driver CSI.
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
Gunakan manifes berikut untuk menyebarkan pod sampel. Driver CSI penyimpanan rahasia memerlukan pod untuk mereferensikan sumber daya SecretProviderClass untuk memastikan sinkronisasi rahasia dari Azure Key Vault ke kluster.
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
Verifikasi
productpage-credential
rahasia yang dibuat pada namespaceaks-istio-ingress
kluster seperti yang didefinisikan dalam sumber daya SecretProviderClass.kubectl describe secret/productpage-credential -n aks-istio-ingress
Contoh output:
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
Rutekan lalu lintas HTTPS melalui gateway masuk Istio ke aplikasi sampel. Gunakan manifes berikut untuk menyebarkan gateway dan sumber daya layanan virtual.
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
Catatan
Dalam definisi gateway, credentialName
harus cocok dengan secretName
dalam sumber daya SecretProviderClass dan selector
harus merujuk ke gateway ingress eksternal dengan labelnya, di mana kunci label adalah istio
dan nilainya adalah aks-istio-ingressgateway-external
. Untuk label gateway ingress internal adalah istio
dan nilainya adalah aks-istio-ingressgateway-internal
.
Atur variabel lingkungan untuk host dan port ingress eksternal:
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"
Kirim permintaan HTTPS untuk mengakses layanan halaman produk melalui 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>"
Konfirmasikan bahwa halaman produk aplikasi sampel dapat diakses. Output yang diharapkan adalah:
<title>Simple Bookstore App</title>
Catatan
Untuk mengonfigurasi akses masuk HTTPS ke layanan HTTPS, yaitu, konfigurasikan gateway ingress untuk melakukan passthrough SNI alih-alih penghentian TLS pada permintaan masuk, perbarui mode tls dalam definisi gateway ke PASSTHROUGH
. Ini menginstruksikan gateway untuk melewati lalu lintas masuk "apa adanya", tanpa mengakhiri TLS.
Perluas definisi gateway Anda untuk mendukung TLS bersama.
Perbarui kredensial gateway masuk dengan menghapus rahasia saat ini dan membuat yang baru. Server menggunakan sertifikat CA untuk memverifikasi kliennya, dan kita harus menggunakan ca.crt kunci untuk memegang sertifikat CA.
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
Gunakan manifes berikut untuk membuat ulang SecretProviderClass dengan sertifikat CA.
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
Gunakan manifes berikut untuk menyebarkan ulang pod sampel untuk menyinkronkan rahasia dari Azure Key Vault ke kluster.
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
Verifikasi
productpage-credential
rahasia yang dibuat pada namespaceaks-istio-ingress
kluster .kubectl describe secret/productpage-credential -n aks-istio-ingress
Contoh output:
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
Gunakan manifes berikut untuk memperbarui definisi gateway untuk mengatur mode TLS ke 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
Coba kirim permintaan HTTPS menggunakan pendekatan sebelumnya - tanpa meneruskan sertifikat klien - dan melihatnya gagal.
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"
Contoh output:
...
* 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
Teruskan sertifikat klien Anda dengan --cert
bendera dan kunci privat dengan --key
bendera untuk melengkung.
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>"
Konfirmasikan bahwa halaman produk aplikasi sampel dapat diakses. Output yang diharapkan adalah:
<title>Simple Bookstore App</title>
Jika Anda ingin membersihkan jala layanan Istio dan ingress (meninggalkan kluster), jalankan perintah berikut:
az aks mesh disable --resource-group ${RESOURCE_GROUP} --name ${CLUSTER}
Jika Anda ingin membersihkan semua sumber daya yang dibuat dari dokumen panduan Istio, jalankan perintah berikut:
az group delete --name ${RESOURCE_GROUP} --yes --no-wait
Umpan balik Azure Kubernetes Service
Azure Kubernetes Service adalah proyek sumber terbuka. Pilih tautan untuk memberikan umpan balik: