在 Azure Kubernetes Service (AKS) 上搭配輸入控制器使用 TLS
傳輸層安全性 (TLS) 通訊協定會使用憑證來提供通訊、加密、驗證和完整性的安全性。 在 AKS 上搭配輸入控制器使用 TLS,可讓您保護應用程式之間的通訊,並體驗輸入控制器的優點。
您可以攜帶自己的憑證,並將其與「秘密存放區」CSI 驅動程式整合。 或者,您可以使用 cert-manager \(英文\),其會自動產生並設定 Let's Encrypt \(英文\) 憑證。 有兩個應用程式會在 AKS 叢集中執行,每個均可透過單一 IP 位址來存取。
重要
建議將應用程式路由附加元件用於 AKS 中的輸入。 如需詳細資訊,請參閱具有應用程式路由附加元件的受控 nginx 輸入。
重要
Microsoft「不」會管理或支援憑證管理員,以及其使用所產生的任何問題。 如需 cert-manager 的問題,請參閱 cert-manager 疑難解答文件。
以 Nginx 為基礎的 Kubernetes 具有兩個開放原始碼輸入控制器:一個由 Kubernetes 社群維護 (kubernetes/ingress-nginx),一個則由 NGINX, Inc. 維護 (nginxinc/kubernetes-ingress)。 本文使用「Kubernetes 社群輸入控制器」。
開始之前
此文章假設您已設定輸入控制器與應用程式。 如果您需要輸入控制器或範例應用程式,請參閱建立輸入控制器。
本文使用 Helm 3,在Kubernetes 的已支援版本上安裝 NGINX 輸入控制器。 確定您使用的是最新版的 Helm,而且可以存取
ingress-nginx
與jetstack
Helm 存放庫。 本文所述的步驟可能與舊版 Helm 圖表、NGINX 輸入控制器或 Kubernetes 不相容。- 如需設定和使用 Helm 的詳細資訊,請參閱在 AKS 中使用 Helm 來安裝應用程式。 如需升級指示,請參閱 Helm 安裝文件。
此文章假設您有具有整合式 Azure Container Registry (ACR) 的現有 AKS 叢集。 如需使用整合式 ACR 來建立 AKS 叢集的詳細資訊,請參閱從 AKS 使用 ACR 進行驗證。
如果您使用 Azure CLI,此文章會要求您執行 Azure CLI 2.0.64 版或更新版本。 執行
az --version
以尋找版本。 如果您需要安裝或升級,請參閱安裝 Azure CLI。如果您使用 Azure PowerShell,此文章會要求您執行 Azure PowerShell 5.9.0 版或更新版本。 執行
Get-InstalledModule -Name Az
以尋找版本。 如果您需要安裝或升級,請參閱安裝 Azure PowerShell。
透過「秘密存放區」CSI 驅動程式搭配您自己的憑證使用 TLS
若要透過祕密存放區 CSI 驅動程式搭配您自己的憑證使用 TLS,您需要已設定祕密存放區 CSI 驅動程式的 AKS 叢集,以及 Azure Key Vault 執行個體。
如需詳細資訊,請參閱「秘密存放區」CSI 驅動程式以啟用具有 TLS 的 NGINX 輸入控制器。
將 TLS 與 Let's Encrypt 一起使用
若要搭配 Let's Encrypt \(英文\) 憑證使用 TLS,您必須部署 cert-manager \(英文\),其會自動產生並設定 Let's Encrypt 憑證。
將 Helm 圖表所使用的影像匯入至您的 ACR
使用
az acr import
,將下列映像匯入您的 ACR。REGISTRY_NAME=<REGISTRY_NAME> CERT_MANAGER_REGISTRY=quay.io CERT_MANAGER_TAG=v1.8.0 CERT_MANAGER_IMAGE_CONTROLLER=jetstack/cert-manager-controller CERT_MANAGER_IMAGE_WEBHOOK=jetstack/cert-manager-webhook CERT_MANAGER_IMAGE_CAINJECTOR=jetstack/cert-manager-cainjector az acr import --name $REGISTRY_NAME --source $CERT_MANAGER_REGISTRY/$CERT_MANAGER_IMAGE_CONTROLLER:$CERT_MANAGER_TAG --image $CERT_MANAGER_IMAGE_CONTROLLER:$CERT_MANAGER_TAG az acr import --name $REGISTRY_NAME --source $CERT_MANAGER_REGISTRY/$CERT_MANAGER_IMAGE_WEBHOOK:$CERT_MANAGER_TAG --image $CERT_MANAGER_IMAGE_WEBHOOK:$CERT_MANAGER_TAG az acr import --name $REGISTRY_NAME --source $CERT_MANAGER_REGISTRY/$CERT_MANAGER_IMAGE_CAINJECTOR:$CERT_MANAGER_TAG --image $CERT_MANAGER_IMAGE_CAINJECTOR:$CERT_MANAGER_TAG
注意
您也可以將 Helm 圖表匯入至 ACR。 如需詳細資訊,請參閱將 Helm 圖表推送並提取至 ACR。
輸入控制器設定選項
您可以使用靜態公用 IP 位址或動態公用 IP 位址來設定 NGINX 輸入控制器。 如果您使用自訂網域,則必須將 A 記錄新增至您的 DNS 區域。 如果您未使用自訂網域,則可以設定輸入控制器 IP 位址的完整網域名稱 (FQDN)。
建立靜態或動態公用 IP 位址
使用靜態公用 IP 位址
您可以使用靜態公用 IP 位址來設定輸入控制器。 如果您刪除輸入控制器,則仍會保留靜態公用 IP 位址。 如果您刪除 AKS 叢集,則「不」會保留 IP 位址。
當您升級輸入控制器時,必須將參數傳遞至 Helm 版本,確保輸入控制器服務知道將對其進行配置的負載平衡器。 為了讓 HTTPS 憑證正常運作,您使用 DNS 標籤來設定輸入控制器 IP 位址的 FQDN。
使用
az aks show
命令來取得 AKS 叢集的資源群組名稱。az aks show --resource-group myResourceGroup --name myAKSCluster --query nodeResourceGroup -o tsv
使用
az network public-ip create
命令,建立具有「靜態」配置方法的公用 IP 位址。 下列範例會在上於一個步驟取得的 AKS 叢集資源群組中,建立名為 myAKSPublicIP 的公用 IP 位址。az network public-ip create --resource-group MC_myResourceGroup_myAKSCluster_eastus --name myAKSPublicIP --sku Standard --allocation-method static --query publicIp.ipAddress -o tsv
注意
或者,您可以在不同的資源群組中建立可與 AKS 叢集分開管理的 IP 位址。 如果您在不同的資源群組中建立 IP 位址,請確定下列為真:
- AKS 叢集所使用的叢集身分識別具有資源群組的委派權限,例如:網路參與者。
- 新增
--set controller.service.annotations."service\.beta\.kubernetes\.io/azure-load-balancer-resource-group"="<RESOURCE_GROUP>"
參數。 將<RESOURCE_GROUP>
取代為 IP 位址所在的資源群組名稱。
新增
--set controller.service.annotations."service\.beta\.kubernetes\.io/azure-dns-label-name"="<DNS_LABEL>"
參數。 可以在輸入控制器第一次部署時設定 DNS 標籤,也可以稍後進行設定。新增
--set controller.service.loadBalancerIP="<STATIC_IP>"
參數。 指定您在上一個步驟中所建立的自有公用 IP 位址。DNS_LABEL="<DNS_LABEL>" NAMESPACE="ingress-basic" STATIC_IP=<STATIC_IP> helm upgrade ingress-nginx ingress-nginx/ingress-nginx \ --namespace $NAMESPACE \ --set controller.service.annotations."service\.beta\.kubernetes\.io/azure-dns-label-name"=$DNS_LABEL \ --set controller.service.loadBalancerIP=$STATIC_IP \ --set controller.service.annotations."service\.beta\.kubernetes\.io/azure-load-balancer-health-probe-request-path"=/healthz
如需詳細資訊,請參閱搭配 AKS 負載平衡器使用靜態公用 IP 位址和 DNS 標籤。
使用動態公用 IP 位址
建立時,會建立輸入控制器的 Azure 公用 IP 位址。 在輸入控制器的生命週期內,公用 IP 位址為靜態。 如果您刪除輸入控制器,則「不」會保留公用 IP 位址。 如果您建立新的輸入控制器,則其將會獲指派新的公用 IP 位址。 輸出看起來應該類似下列範例輸出。
使用
kubectl get service
命令,以取得輸入控制器的公用 IP 位址。# Get the public IP address for your ingress controller kubectl --namespace ingress-basic get services -o wide -w nginx-ingress-ingress-nginx-controller # Sample output NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR nginx-ingress-ingress-nginx-controller LoadBalancer 10.0.74.133 EXTERNAL_IP 80:32486/TCP,443:30953/TCP 44s app.kubernetes.io/component=controller,app.kubernetes.io/instance=nginx-ingress,app.kubernetes.io/name=ingress-nginx
將 A 記錄新增至您的 DNS 區域
如果您要使用自訂網域,則需要將「A」 記錄新增至您的 DNS 區域。 如果您未使用自訂網域,則可以設定具有 FQDN 的公用 IP 位址。
使用
az network dns record-set a add-record
,以將「A」記錄新增至具有 NGINX 服務外部 IP 位址的 DNS 區域。az network dns record-set a add-record \ --resource-group myResourceGroup \ --zone-name MY_CUSTOM_DOMAIN \ --record-set-name "*" \ --ipv4-address MY_EXTERNAL_IP
設定輸入控制器的 FQDN
您可以選擇性地設定 DNS 標籤來設定輸入控制器 IP 位址的 FQDN,而不是自訂網域。 FQDN 應該遵循此格式:<CUSTOM DNS LABEL>.<AZURE REGION NAME>.cloudapp.azure.com
。
重要
DNS 標籤在其 Azure 位置內必須是唯一的。
您可以使用下列其中一個方法來設定 FQDN:
- 使用 Azure CLI 或 Azure PowerShell 來設定 DNS 標籤。
- 使用 Helm 圖表設定來設定 DNS 標籤。
如需詳細資訊,請參閱公用 IP 位址 DNS 名稱標籤。
使用 Azure CLI 或 Azure PowerShell 來設定 DNS 標籤
請務必將 <DNS_LABEL>
取代為您的唯一 DNS 標籤。
# Public IP address of your ingress controller
IP="MY_EXTERNAL_IP"
# Name to associate with public IP address
DNSLABEL="<DNS_LABEL>"
# Get the resource-id of the public IP
PUBLICIPID=$(az network public-ip list --query "[?ipAddress!=null]|[?contains(ipAddress, '$IP')].[id]" --output tsv)
# Update public IP address with DNS name
az network public-ip update --ids $PUBLICIPID --dns-name $DNSLABEL
# Display the FQDN
az network public-ip show --ids $PUBLICIPID --query "[dnsSettings.fqdn]" --output tsv
使用 Helm 圖表設定來設定 DNS 標籤
您可以使用 --set controller.service.annotations."service\.beta\.kubernetes\.io/azure-dns-label-name"
參數,以將註釋設定傳遞至 Helm 圖表設定。 可以在輸入控制器第一次部署時設定此參數,也可以稍後進行設定。
下列範例說明如何在部署控制器之後更新此設定。 請務必將 <DNS_LABEL>
取代為您的唯一 DNS 標籤。
DNSLABEL="<DNS_LABEL>"
NAMESPACE="ingress-basic"
helm upgrade ingress-nginx ingress-nginx/ingress-nginx \
--namespace $NAMESPACE \
--set controller.service.annotations."service\.beta\.kubernetes\.io/azure-dns-label-name"=$DNSLABEL \
--set controller.service.annotations."service\.beta\.kubernetes\.io/azure-load-balancer-health-probe-request-path"=/healthz
安裝 cert-manager
NGINX 輸入控制器支援 TLS 終止。 有數種方式可以擷取和設定 HTTPS 的憑證。 此文章使用 cert-manager \(英文\),其會提供自動化的 Lets Encrypt \(英文\) 憑證產生與管理功能。
若要安裝 cert-manager 控制器,請使用下列命令。
# Set variable for ACR location to use for pulling images
ACR_URL=<REGISTRY_URL>
# Label the ingress-basic namespace to disable resource validation
kubectl label namespace ingress-basic cert-manager.io/disable-validation=true
# Add the Jetstack Helm repository
helm repo add jetstack https://charts.jetstack.io
# Update your local Helm chart repository cache
helm repo update
# Install the cert-manager Helm chart
helm install cert-manager jetstack/cert-manager \
--namespace ingress-basic \
--version=$CERT_MANAGER_TAG \
--set installCRDs=true \
--set nodeSelector."kubernetes\.io/os"=linux \
--set image.repository=$ACR_URL/$CERT_MANAGER_IMAGE_CONTROLLER \
--set image.tag=$CERT_MANAGER_TAG \
--set webhook.image.repository=$ACR_URL/$CERT_MANAGER_IMAGE_WEBHOOK \
--set webhook.image.tag=$CERT_MANAGER_TAG \
--set cainjector.image.repository=$ACR_URL/$CERT_MANAGER_IMAGE_CAINJECTOR \
--set cainjector.image.tag=$CERT_MANAGER_TAG
如需 cert-manager 設定的詳細資訊,請參閱 cert-manager 專案。
建立 CA 叢集簽發者
發行憑證之前,cert-manager 需要下列其中一個簽發者:
- 簽發者 \(英文\),其可在單一命名空間中運作。
- ClusterIssuer \(英文\) 資源,其可跨所有命名空間運作。
如需詳細資訊,請參閱 cert-manager 簽發者文件。
使用下列範例資訊清單來建立叢集簽發者,例如
cluster-issuer.yaml
。 使用您組織的有效位址來取代MY_EMAIL_ADDRESS
。apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: letsencrypt spec: acme: server: https://acme-v02.api.letsencrypt.org/directory email: MY_EMAIL_ADDRESS privateKeySecretRef: name: letsencrypt solvers: - http01: ingress: class: nginx podTemplate: spec: nodeSelector: "kubernetes.io/os": linux
使用
kubectl apply
命令來套用簽發者。kubectl apply -f cluster-issuer.yaml --namespace ingress-basic
更新輸入路由
您必須更新輸入路由來處理流向您 FQDN 或自訂網域的流量。
在下列範例中,流量會以如下方式路由傳送:
- 流向 hello-world-ingress.MY_CUSTOM_DOMAIN 的流量會路由傳送至 aks-helloworld-one 服務。
- 流向 hello-world-ingress.MY_CUSTOM_DOMAIN/hello-world-two 的流量會路由傳送至 aks-helloworld-two 服務。
- hello-world-ingress.MY_CUSTOM_DOMAIN/static 的流量會路由傳送至 aks-helloworld-one,以取得靜態資產。
注意
如果您已針對輸入控制器 IP 位址設定 FQDN,而不是自訂網域,請使用 FQDN 而不是 hello-world-ingress.MY_CUSTOM_DOMAIN。
例如,如果您的 FQDN 是 demo-aks-ingress.eastus.cloudapp.azure.com,將 hello-world-ingress.MY_CUSTOM_DOMAIN 取代為 hello-world-ingress.yaml
中的 demo-aks-ingress.eastus.cloudapp.azure.com。
使用下列範例 YAML 檔案來建立或更新
hello-world-ingress.yaml
檔案。 將spec.tls.hosts
和spec.rules.host
更新為您在上一個步驟中所建立的 DNS 名稱。apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: hello-world-ingress annotations: nginx.ingress.kubernetes.io/rewrite-target: /$2 nginx.ingress.kubernetes.io/use-regex: "true" cert-manager.io/cluster-issuer: letsencrypt spec: ingressClassName: nginx tls: - hosts: - hello-world-ingress.MY_CUSTOM_DOMAIN secretName: tls-secret rules: - host: hello-world-ingress.MY_CUSTOM_DOMAIN http: paths: - path: /hello-world-one(/|$)(.*) pathType: Prefix backend: service: name: aks-helloworld-one port: number: 80 - path: /hello-world-two(/|$)(.*) pathType: Prefix backend: service: name: aks-helloworld-two port: number: 80 - path: /(.*) pathType: Prefix backend: service: name: aks-helloworld-one port: number: 80 --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: hello-world-ingress-static annotations: nginx.ingress.kubernetes.io/ssl-redirect: "false" nginx.ingress.kubernetes.io/rewrite-target: /static/$2 spec: ingressClassName: nginx tls: - hosts: - hello-world-ingress.MY_CUSTOM_DOMAIN secretName: tls-secret rules: - host: hello-world-ingress.MY_CUSTOM_DOMAIN http: paths: - path: /static(/|$)(.*) pathType: Prefix backend: service: name: aks-helloworld-one port: number: 80
使用
kubectl apply
命令更新輸入資源。kubectl apply -f hello-world-ingress.yaml --namespace ingress-basic
驗證是否已建立憑證物件
接下來,必須建立憑證資源。 憑證資源會定義所需的 X.509 憑證。 如需詳細資訊,請參閱 cert-manager 憑證。
Cert-manager 會使用 ingress-shim 自動為您建立憑證物件,自 0.2.2 版起,ingress-shim 即會隨著 cert-manager 會自動部署。 如需詳細資訊,請參閱 ingress-shim 文件。
若要驗證是否已成功建立憑證,請使用 kubectl get certificate --namespace ingress-basic
命令,並確認 READY 是否為 True。 可能需要幾分鐘的時間才能取得輸出。
kubectl get certificate --namespace ingress-basic
下列輸出顯示憑證的狀態。
NAME READY SECRET AGE
tls-secret True tls-secret 11m
測試輸入組態
將網頁瀏覽器開啟至 Kubernetes 輸入控制器的 hello-world-ingress.MY_CUSTOM_DOMAIN。 確保下列條件成立:
- 系統已將您重新導向至使用 HTTPS。
- 憑證是「受信任的」。
- 示範應用程式已顯示於網頁瀏覽器中。
- 將 /hello-world-two 新增至網域結尾,並確定已顯示具有自訂標題的第二個示範應用程式。
清除資源
本文使用 Helm 來安裝輸入元件、憑證及範例應用程式。 部署 Helm 圖表時會建立許多 Kubernetes 資源。 這些資源包含 Pod、部署和服務。 若要清除這些資源,您可以刪除整個範例命名空間或個別資源。
刪除範例命名空間和所有資源
刪除範例命名空間也會刪除命名空間中的所有資源。
使用
kubectl delete
命令,並指定命名空間名稱,以刪除整個範例命名空間。kubectl delete namespace ingress-basic
個別刪除資源
或者,您可以個別刪除資源。
移除叢集簽發者資源。
kubectl delete -f cluster-issuer.yaml --namespace ingress-basic
使用
helm list
命令,列出 Helm 版本。 尋找名為 nginx 與 cert-manager 的圖表,如下列範例輸出所示。$ helm list --namespace ingress-basic NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION cert-manager ingress-basic 1 2020-01-15 10:23:36.515514 -0600 CST deployed cert-manager-v0.13.0 v0.13.0 nginx ingress-basic 1 2020-01-15 10:09:45.982693 -0600 CST deployed nginx-ingress-1.29.1 0.27.0
使用
helm uninstall
命令,以解除安裝這些版本。 下列範例會解除安裝 NGINX 輸入和 cert-manager 部署。$ helm uninstall cert-manager nginx --namespace ingress-basic release "cert-manager" uninstalled release "nginx" uninstalled
移除這兩個範例應用程式。
kubectl delete -f aks-helloworld-one.yaml --namespace ingress-basic kubectl delete -f aks-helloworld-two.yaml --namespace ingress-basic
移除將流量導向範例應用程式的輸入路由。
kubectl delete -f hello-world-ingress.yaml --namespace ingress-basic
刪除自身的命名空間。 使用
kubectl delete
命令,並指定命名空間名稱。kubectl delete namespace ingress-basic
下一步
本文包含 AKS 的一些外部元件。 若要深入了解這些元件,請參閱下列專案頁面:
您也可以: