بوابة الدخول الآمنة للوظيفة الإضافية لشبكة خدمة Istio لخدمة Azure Kubernetes
توضح مقالة Deploy external or internal Istio Ingress كيفية تكوين بوابة دخول لعرض خدمة HTTP لحركة المرور الخارجية/الداخلية. توضح هذه المقالة كيفية كشف خدمة HTTPS آمنة باستخدام TLS بسيطة أو متبادلة.
المتطلبات الأساسية
إشعار
تشير هذه المقالة إلى بوابة الدخول الخارجية للعرض التوضيحي، سيتم تطبيق نفس الخطوات لتكوين TLS المتبادل لبوابة الدخول الداخلية.
شهادات ومفاتيح العميل/الخادم المطلوبة
تتطلب هذه المقالة العديد من الشهادات والمفاتيح. يمكنك استخدام الأداة المفضلة لديك لإنشائها أو يمكنك استخدام أوامر openssl التالية.
إنشاء شهادة جذر ومفتاح خاص لتوقيع الشهادات لنماذج الخدمات:
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
إنشاء شهادة ومفتاح خاص ل
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
إنشاء شهادة عميل ومفتاح خاص:
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
تكوين بوابة دخول TLS
إنشاء سر Kubernetes TLS لبوابة الدخول؛ استخدم Azure Key Vault لاستضافة الشهادات/المفاتيح والوظيفة الإضافية لموفر أسرار Azure Key Vault لمزامنة الأسرار مع نظام المجموعة.
إعداد Azure Key Vault ومزامنة البيانات السرية إلى نظام المجموعة
إنشاء Azure Key Vault
تحتاج إلى مورد Azure Key Vault لتوفير الشهادة والمدخلات الرئيسية إلى الوظيفة الإضافية Istio.
export AKV_NAME=<azure-key-vault-resource-name> az keyvault create --name $AKV_NAME --resource-group $RESOURCE_GROUP --location $LOCATION
تمكين موفر Azure Key Vault للوظيفة الإضافية لبرنامج تشغيل CSI للمخزن السري على مجموعتك.
az aks enable-addons --addons azure-keyvault-secrets-provider --resource-group $RESOURCE_GROUP --name $CLUSTER
تخويل الهوية المدارة المعينة من قبل المستخدم للوظيفة الإضافية للوصول إلى مورد Azure Key Vault باستخدام نهج الوصول. بدلا من ذلك، إذا كان Key Vault الخاص بك يستخدم Azure RBAC لنموذج الأذونات، فاتبع الإرشادات هنا لتعيين دور Azure ل Key Vault للهوية المدارة المعينة من قبل المستخدم للوظيفة الإضافية.
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
إنشاء أسرار في Azure Key Vault باستخدام الشهادات والمفاتيح.
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
استخدم البيان التالي لنشر SecretProviderClass لتوفير معلمات خاصة ب Azure Key Vault إلى برنامج تشغيل 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
استخدم البيان التالي لنشر نموذج pod. يتطلب برنامج تشغيل CSI للمخزن السري جراب للإشارة إلى مورد SecretProviderClass لضمان مزامنة الأسرار من Azure Key Vault إلى نظام المجموعة.
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
تحقق من
productpage-credential
البيانات السرية التي تم إنشاؤها على مساحةaks-istio-ingress
اسم نظام المجموعة كما هو محدد في مورد SecretProviderClass.kubectl describe secret/productpage-credential -n aks-istio-ingress
مثال على الإخراج:
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
تكوين بوابة الدخول والخدمة الظاهرية
توجيه حركة مرور HTTPS عبر بوابة دخول Istio إلى نماذج التطبيقات. استخدم البيان التالي لنشر موارد البوابة والخدمة الظاهرية.
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
إشعار
في تعريف البوابة، credentialName
يجب أن يتطابق secretName
مع في مورد selector
SecretProviderClass ويجب أن يشير إلى بوابة الدخول الخارجية بواسطة التسمية الخاصة بها، حيث يكون istio
مفتاح التسمية والقيمة هي aks-istio-ingressgateway-external
. بالنسبة لتسمية بوابة الدخول الداخلية هي istio
والقيمة هي aks-istio-ingressgateway-internal
.
تعيين متغيرات البيئة لمضيف الدخول الخارجي والمنافذ:
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"
التحقق من الصحة
إرسال طلب HTTPS للوصول إلى خدمة صفحة المنتج من خلال 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>"
تأكد من إمكانية الوصول إلى صفحة منتج نموذج التطبيق. الإخراج المتوقع هو:
<title>Simple Bookstore App</title>
إشعار
لتكوين الوصول إلى دخول HTTPS إلى خدمة HTTPS، أي تكوين بوابة دخول لتنفيذ تمرير SNI بدلا من إنهاء TLS على الطلبات الواردة، قم بتحديث وضع tls في تعريف البوابة إلى PASSTHROUGH
. هذا يوجه البوابة لتمرير حركة مرور الدخول "كما هي"، دون إنهاء TLS.
تكوين بوابة دخول TLS متبادلة
توسيع تعريف البوابة لدعم TLS المتبادل.
تحديث بيانات اعتماد بوابة الدخول عن طريق حذف السر الحالي وإنشاء سر جديد. يستخدم الخادم شهادة المرجع المصدق للتحقق من عملائه، ويجب علينا استخدام المفتاح 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
استخدم البيان التالي لإعادة إنشاء SecretProviderClass مع شهادة 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
استخدم البيان التالي لإعادة نشر نموذج pod لمزامنة البيانات السرية من Azure Key Vault إلى نظام المجموعة.
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
تحقق من
productpage-credential
البيانات السرية التي تم إنشاؤها على مساحةaks-istio-ingress
اسم نظام المجموعة .kubectl describe secret/productpage-credential -n aks-istio-ingress
مثال على الإخراج:
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
استخدم البيان التالي لتحديث تعريف البوابة لتعيين وضع TLS إلى 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
التحقق من الصحة
حاول إرسال طلب HTTPS باستخدام النهج السابق - دون تمرير شهادة العميل - واطلع على فشلها.
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"
مثال على الإخراج:
...
* 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
مرر شهادة العميل مع العلامة --cert
والمفتاح الخاص مع العلامة --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>"
تأكد من إمكانية الوصول إلى صفحة منتج نموذج التطبيق. الإخراج المتوقع هو:
<title>Simple Bookstore App</title>
حذف الموارد
إذا كنت ترغب في تنظيف شبكة خدمة Istio والدخول (تاركا وراءها نظام المجموعة)، فقم بتشغيل الأمر التالي:
az aks mesh disable --resource-group ${RESOURCE_GROUP} --name ${CLUSTER}
إذا كنت ترغب في تنظيف جميع الموارد التي تم إنشاؤها من مستندات إرشادات Istio الإرشادية، فقم بتشغيل الأمر التالي:
az group delete --name ${RESOURCE_GROUP} --yes --no-wait
Azure Kubernetes Service