在 Azure Kubernetes Service (AKS) 上建立 HTTPS 輸入控制器Create an HTTPS ingress controller on Azure Kubernetes Service (AKS)

輸入控制器是一項可為 Kubernetes 服務提供反向 Proxy、可設定的流量路由和 TLS 終止的軟體。An ingress controller is a piece of software that provides reverse proxy, configurable traffic routing, and TLS termination for Kubernetes services. Kubernetes 輸入資源可用來設定個別 Kubernetes 服務的輸入規則和路由。Kubernetes ingress resources are used to configure the ingress rules and routes for individual Kubernetes services. 透過輸入控制器和輸入規則,您可以使用單一 IP 位址將流量路由至 Kubernetes 叢集中的多個服務。Using an ingress controller and ingress rules, a single IP address can be used to route traffic to multiple services in a Kubernetes cluster.

本文說明如何在 Azure Kubernetes Service (AKS) 叢集中部署NGINX 輸入控制器This article shows you how to deploy the NGINX ingress controller in an Azure Kubernetes Service (AKS) cluster. Cert-manager專案是用來自動產生和設定Let's Encrypt憑證。The cert-manager project is used to automatically generate and configure Let's Encrypt certificates. 最後,會有兩個應用程式在 AKS 叢集中執行,且均可透過單一 IP 位址來存取。Finally, two applications are run in the AKS cluster, each of which is accessible over a single IP address.

您也可以:You can also:

開始之前Before you begin

此文章假設您目前具有 AKS 叢集。This article assumes that you have an existing AKS cluster. 如果您需要 AKS 叢集, 請參閱使用 Azure CLI使用 Azure 入口網站的 AKS 快速入門。If you need an AKS cluster, see the AKS quickstart using the Azure CLI or using the Azure portal.

本文使用 Helm 來安裝 NGINX 輸入控制器、cert-manager 及範例 Web 應用程式。This article uses Helm to install the NGINX ingress controller, cert-manager, and a sample web app. 您需要在 AKS 叢集內將 Helm 初始化,並使用適用於 Tiller 的服務帳戶。You need to have Helm initialized within your AKS cluster and using a service account for Tiller. 請確定您使用的是 Helm 的最新版本。Make sure that you are using the latest release of Helm. 如需升級指示, 請參閱Helm 安裝檔。如需設定和使用 Helm 的詳細資訊, 請參閱在 Azure Kubernetes Service (AKS) 中使用 Helm 安裝應用程式For upgrade instructions, see the Helm install docs. For more information on configuring and using Helm, see Install applications with Helm in Azure Kubernetes Service (AKS).

本文也會要求您執行 Azure CLI 版本2.0.64 或更新版本。This article also requires that you are running the Azure CLI version 2.0.64 or later. 執行 az --version 以尋找版本。Run az --version to find the version. 如果您需要安裝或升級,請參閱安裝 Azure CLIIf you need to install or upgrade, see Install Azure CLI.

建立輸入控制器Create an ingress controller

若要建立輸入控制器,請使用 Helm 以安裝 nginx-ingressTo create the ingress controller, use Helm to install nginx-ingress. 為了新增備援,您必須使用 --set controller.replicaCount 參數部署兩個 NGINX 輸入控制器複本。For added redundancy, two replicas of the NGINX ingress controllers are deployed with the --set controller.replicaCount parameter. 為充分享有執行輸入控制器複本的好處,請確定 AKS 叢集中有多個節點。To fully benefit from running replicas of the ingress controller, make sure there's more than one node in your AKS cluster.

輸入控制器也必須在 Linux 節點上排程。The ingress controller also needs to be scheduled on a Linux node. Windows Server 節點 (目前在 AKS 中處於預覽狀態) 不應執行輸入控制器。Windows Server nodes (currently in preview in AKS) shouldn't run the ingress controller. 使用--set nodeSelector參數來指定節點選取器, 以指示 Kubernetes 排程器在以 Linux 為基礎的節點上執行 NGINX 輸入控制器。A node selector is specified using the --set nodeSelector parameter to tell the Kubernetes scheduler to run the NGINX ingress controller on a Linux-based node.

提示

下列範例會建立名為「輸入 -基本」的輸入資源的 Kubernetes 命名空間。The following example creates a Kubernetes namespace for the ingress resources named ingress-basic. 視需要指定您自己環境的命名空間。Specify a namespace for your own environment as needed. 如果您的 AKS 叢集未啟用 RBAC, 請--set rbac.create=false將新增至 Helm 命令。If your AKS cluster is not RBAC enabled, add --set rbac.create=false to the Helm commands.

提示

如果您想要為叢集中的容器要求啟用用戶端來源 IP 保留, 請將--set controller.service.externalTrafficPolicy=Local新增至 Helm install 命令。If you would like to enable client source IP preservation for requests to containers in your cluster, add --set controller.service.externalTrafficPolicy=Local to the Helm install command. 用戶端來源 IP 會儲存在要求標頭的 [ X-轉送- ] 下。The client source IP is stored in the request header under X-Forwarded-For. 當使用已啟用用戶端來源 IP 保留的輸入控制器時, SSL 傳遞將無法運作。When using an ingress controller with client source IP preservation enabled, SSL pass-through will not work.

# Create a namespace for your ingress resources
kubectl create namespace ingress-basic

# Use Helm to deploy an NGINX ingress controller
helm install stable/nginx-ingress \
    --namespace ingress-basic \
    --set controller.replicaCount=2 \
    --set controller.nodeSelector."beta\.kubernetes\.io/os"=linux \
    --set defaultBackend.nodeSelector."beta\.kubernetes\.io/os"=linux

在安裝期間,會為輸入控制器建立 Azure 公用 IP 位址。During the installation, an Azure public IP address is created for the ingress controller. 在輸入控制器的生命週期內,此公用 IP 位址都是靜態的。This public IP address is static for the life-span of the ingress controller. 如果您刪除輸入控制器,公用 IP 位址指派將會遺失。If you delete the ingress controller, the public IP address assignment is lost. 如果您後續又建立其他輸入控制器,將會指派新的公用 IP 位址。If you then create an additional ingress controller, a new public IP address is assigned. 如果您想要保留使用公用 IP 位址, 您可以改為建立具有靜態公用 ip 位址的輸入控制器。If you wish to retain the use of the public IP address, you can instead create an ingress controller with a static public IP address.

若要取得公用 IP 位址,請使用 kubectl get service 命令。To get the public IP address, use the kubectl get service command. 將 IP 位址指派給服務需要幾分鐘的時間。It takes a few minutes for the IP address to be assigned to the service.

$ kubectl get service -l app=nginx-ingress --namespace ingress-basic

NAME                                             TYPE           CLUSTER-IP     EXTERNAL-IP     PORT(S)                      AGE
billowing-kitten-nginx-ingress-controller        LoadBalancer   10.0.182.160   51.145.155.210  80:30920/TCP,443:30426/TCP   20m
billowing-kitten-nginx-ingress-default-backend   ClusterIP      10.0.255.77    <none>          80/TCP                       20m

尚未建立任何輸入規則。No ingress rules have been created yet. 如果您瀏覽至公用 IP 位址,即會顯示 NGINX 輸入控制器的預設 404 頁面。If you browse to the public IP address, the NGINX ingress controller's default 404 page is displayed.

設定 DNS 名稱Configure a DNS name

對於正常運作的 HTTPS 憑證,設定適用於輸入控制器 IP 位址的 FQDN。For the HTTPS certificates to work correctly, configure an FQDN for the ingress controller IP address. 以您輸入控制器的 IP 位址和您要針對 FQDN 使用的名稱來更新下列指令碼:Update the following script with the IP address of your ingress controller and a unique name that you would like to use for the FQDN:

#!/bin/bash

# Public IP address of your ingress controller
IP="51.145.155.210"

# Name to associate with public IP address
DNSNAME="demo-aks-ingress"

# 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 $DNSNAME

輸入控制器現在已可透過 FQDN 來存取。The ingress controller is now accessible through the FQDN.

安裝 cert-managerInstall cert-manager

NGINX 輸入控制器支援 TLS 終止。The NGINX ingress controller supports TLS termination. 有數種方式可擷取和設定 HTTPS 的憑證。There are several ways to retrieve and configure certificates for HTTPS. 本文示範如何使用cert 管理員, 它會提供自動憑證產生和管理功能的加密。This article demonstrates using cert-manager, which provides automatic Lets Encrypt certificate generation and management functionality.

注意

本文會針對 Let's Encrypt 使用 staging 環境。This article uses the staging environment for Let's Encrypt. 在生產環境部署中,於資源定義中以及安裝 Helm 圖表時使用 letsencrypt-prodhttps://acme-v02.api.letsencrypt.org/directoryIn production deployments, use letsencrypt-prod and https://acme-v02.api.letsencrypt.org/directory in the resource definitions and when installing the Helm chart.

若要在已啟用 RBAC 的叢集中安裝 cert-manager 控制器,請使用下列 helm install 命令:To install the cert-manager controller in an RBAC-enabled cluster, use the following helm install command:

# Install the CustomResourceDefinition resources separately
kubectl apply -f https://raw.githubusercontent.com/jetstack/cert-manager/release-0.8/deploy/manifests/00-crds.yaml

# Create the namespace for cert-manager
kubectl create namespace cert-manager

# Label the cert-manager namespace to disable resource validation
kubectl label namespace cert-manager certmanager.k8s.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 \
  --name cert-manager \
  --namespace cert-manager \
  --version v0.8.0 \
  jetstack/cert-manager

如需 cert-管理員設定的詳細資訊, 請參閱cert-管理員專案For more information on cert-manager configuration, see the cert-manager project.

建立 CA 叢集簽發者Create a CA cluster issuer

在頒發證書之前, 憑證管理員需要簽發者ClusterIssuer資源。Before certificates can be issued, cert-manager requires an Issuer or ClusterIssuer resource. 這些 Kubernetes 資源在功能上完全相同,但是 Issuer 會在單一命名空間中運作,而 ClusterIssuer 會跨所有命名空間運作。These Kubernetes resources are identical in functionality, however Issuer works in a single namespace, and ClusterIssuer works across all namespaces. 如需詳細資訊, 請參閱cert-管理員簽發者檔。For more information, see the cert-manager issuer documentation.

使用下列範例資訊清單來建立叢集簽發者,例如 cluster-issuer.yamlCreate a cluster issuer, such as cluster-issuer.yaml, using the following example manifest. 利用您組織中的有效電子郵件地址來更新電子郵件地址:Update the email address with a valid address from your organization:

apiVersion: certmanager.k8s.io/v1alpha1
kind: ClusterIssuer
metadata:
  name: letsencrypt-staging
  namespace: ingress-basic
spec:
  acme:
    server: https://acme-staging-v02.api.letsencrypt.org/directory
    email: user@contoso.com
    privateKeySecretRef:
      name: letsencrypt-staging
    http01: {}

若要建立簽發者,請使用 kubectl apply -f cluster-issuer.yaml 命令。To create the issuer, use the kubectl apply -f cluster-issuer.yaml command.

$ kubectl apply -f cluster-issuer.yaml

clusterissuer.certmanager.k8s.io/letsencrypt-staging created

執行示範應用程式Run demo applications

輸入控制器和憑證管理解決方案皆已設定。An ingress controller and a certificate management solution have been configured. 現在讓我們在您的 AKS 叢集中執行兩個示範應用程式。Now let's run two demo applications in your AKS cluster. 在此範例中,會使用 Helm 來部署簡單 'Hello world' 應用程式的兩個執行個體。In this example, Helm is used to deploy two instances of a simple 'Hello world' application.

在您可以安裝範例 Helm 圖表之前,先將 Azure 範例存放庫新增至您的 Helm 環境,如下所示:Before you can install the sample Helm charts, add the Azure samples repository to your Helm environment as follows:

helm repo add azure-samples https://azure-samples.github.io/helm-charts/

使用下列命令,從 Helm 圖表建立第一個示範應用程式:Create the first demo application from a Helm chart with the following command:

helm install azure-samples/aks-helloworld --namespace ingress-basic

現在,請安裝示範應用程式的第二個執行個體。Now install a second instance of the demo application. 對第二個執行個體指定新的標題,以便在視覺上區分這兩個應用程式。For the second instance, you specify a new title so that the two applications are visually distinct. 您也要指定唯一的服務名稱:You also specify a unique service name:

helm install azure-samples/aks-helloworld \
    --namespace ingress-basic \
    --set title="AKS Ingress Demo" \
    --set serviceName="ingress-demo"

建立輸入路由Create an ingress route

這兩個應用程式現在都已在您的 Kubernetes 叢集上執行,不過,它們是以 ClusterIP 類型的服務設定的。Both applications are now running on your Kubernetes cluster, however they're configured with a service of type ClusterIP. 因此,這些應用程式無法從網際網路存取。As such, the applications aren't accessible from the internet. 若要使其可公開使用,請建立 Kubernetes 輸入資源。To make them publicly available, create a Kubernetes ingress resource. 輸入資源會設定將流量路由至這兩個應用程式之一的規則。The ingress resource configures the rules that route traffic to one of the two applications.

在下列範例中,傳至位址 https://demo-aks-ingress.eastus.cloudapp.azure.com/ 的流量會路由傳送至名為 aks-helloworld 的服務。In the following example, traffic to the address https://demo-aks-ingress.eastus.cloudapp.azure.com/ is routed to the service named aks-helloworld. 傳至位址 https://demo-aks-ingress.eastus.cloudapp.azure.com/hello-world-two 的流量會路由至 ingress-demo 服務。Traffic to the address https://demo-aks-ingress.eastus.cloudapp.azure.com/hello-world-two is routed to the ingress-demo service. hostshost 更新為您在上一個步驟中建立的 DNS 名稱。Update the hosts and host to the DNS name you created in a previous step.

建立名為 hello-world-ingress.yaml 的檔案,並複製到下列範例 YAML 中。Create a file named hello-world-ingress.yaml and copy in the following example YAML.

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: hello-world-ingress
  namespace: ingress-basic
  annotations:
    kubernetes.io/ingress.class: nginx
    certmanager.k8s.io/cluster-issuer: letsencrypt-staging
    nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
  tls:
  - hosts:
    - demo-aks-ingress.eastus.cloudapp.azure.com
    secretName: tls-secret
  rules:
  - host: demo-aks-ingress.eastus.cloudapp.azure.com
    http:
      paths:
      - backend:
          serviceName: aks-helloworld
          servicePort: 80
        path: /(.*)
      - backend:
          serviceName: ingress-demo
          servicePort: 80
        path: /hello-world-two(/|$)(.*)

使用 kubectl apply -f hello-world-ingress.yaml 命令建立輸入資源。Create the ingress resource using the kubectl apply -f hello-world-ingress.yaml command.

$ kubectl apply -f hello-world-ingress.yaml

ingress.extensions/hello-world-ingress created

建立憑證物件Create a certificate object

接下來,必須建立憑證資源。Next, a certificate resource must be created. 憑證資源會定義所需的 X.509 憑證。The certificate resource defines the desired X.509 certificate. 如需詳細資訊, 請參閱cert-管理員憑證For more information, see cert-manager certificates.

Cert-manager 有可能已使用 ingress-shim 自動為您建立憑證物件,v0.2.2 之後的 cert-manager 會自動與 ingress-shim 搭配部署。Cert-manager has likely automatically created a certificate object for you using ingress-shim, which is automatically deployed with cert-manager since v0.2.2. 如需詳細資訊, 請參閱輸入填充碼檔For more information, see the ingress-shim documentation.

若要確認已成功建立憑證,請使用 kubectl describe certificate tls-secret --namespace ingress-basic 命令。To verify that the certificate was created successfully, use the kubectl describe certificate tls-secret --namespace ingress-basic command.

如果已發出憑證,您將會看到類似下列的輸出:If the certificate was issued, you will see output similar to the following:

Type    Reason          Age   From          Message
----    ------          ----  ----          -------
  Normal  CreateOrder     11m   cert-manager  Created new ACME order, attempting validation...
  Normal  DomainVerified  10m   cert-manager  Domain "demo-aks-ingress.eastus.cloudapp.azure.com" verified with "http-01" validation
  Normal  IssueCert       10m   cert-manager  Issuing certificate...
  Normal  CertObtained    10m   cert-manager  Obtained certificate from ACME server
  Normal  CertIssued      10m   cert-manager  Certificate issued successfully

如果您需要建立額外的憑證資源,可以使用下列範例資訊清單來執行該動作。If you need to create an additional certificate resource, you can do so with the following example manifest. dnsNamesdomains 更新為您在上一個步驟中建立的 DNS 名稱。Update the dnsNames and domains to the DNS name you created in a previous step. 如果您使用僅供內部使用的輸入控制器,請為您的服務指定內部 DNS 名稱。If you use an internal-only ingress controller, specify the internal DNS name for your service.

apiVersion: certmanager.k8s.io/v1alpha1
kind: Certificate
metadata:
  name: tls-secret
  namespace: ingress-basic
spec:
  secretName: tls-secret-staging
  dnsNames:
  - demo-aks-ingress.eastus.cloudapp.azure.com
  acme:
    config:
    - http01:
        ingressClass: nginx
      domains:
      - demo-aks-ingress.eastus.cloudapp.azure.com
  issuerRef:
    name: letsencrypt-staging
    kind: ClusterIssuer

若要建立憑證資源,請使用 kubectl apply -f certificates.yaml 命令。To create the certificate resource, use the kubectl apply -f certificates.yaml command.

$ kubectl apply -f certificates.yaml

certificate.certmanager.k8s.io/tls-secret-staging created

測試輸入組態Test the ingress configuration

開啟網頁瀏覽器至您 Kubernetes 輸入控制器的 FQDN,例如 https://demo-aks-ingress.eastus.cloudapp.azure.comOpen a web browser to the FQDN of your Kubernetes ingress controller, such as https://demo-aks-ingress.eastus.cloudapp.azure.com.

由於這些範例會使用 letsencrypt-staging,因此,簽發的 SSL 憑證不會受到瀏覽器信任。As these examples use letsencrypt-staging, the issued SSL certificate is not trusted by the browser. 接受警告提示以繼續您的應用程式。Accept the warning prompt to continue to your application. 憑證資訊顯示這個 Fake LE Intermediate X1 憑證是由 Let's Encrypt 所簽發的。The certificate information shows this Fake LE Intermediate X1 certificate is issued by Let's Encrypt. 這個假憑證表示 cert-manager 已正確處理要求並接收來自提供者的憑證:This fake certificate indicates cert-manager processed the request correctly and received a certificate from the provider:

Let's Encrypt 暫存憑證

當您變更 Let's Encrypt 來使用 prod 而非 staging 時,會使用由 Let's Encrypt 所簽發的信任憑證,如下列範例所示:When you change Let's Encrypt to use prod rather than staging, a trusted certificate issued by Let's Encrypt is used, as shown in the following example:

Let’s Encrypt 憑證

示範應用程式會顯示於網頁瀏覽器中:The demo application is shown in the web browser:

應用程式範例一

現在,將 /hello-world-two 路徑新增至 FQDN,例如 https://demo-aks-ingress.eastus.cloudapp.azure.com/hello-world-twoNow add the /hello-world-two path to the FQDN, such as https://demo-aks-ingress.eastus.cloudapp.azure.com/hello-world-two. 即會顯示第二個具有自訂標題的示範應用程式:The second demo application with the custom title is shown:

應用程式範例二

清除資源Clean up resources

本文使用 Helm 來安裝輸入元件、憑證及範例應用程式。This article used Helm to install the ingress components, certificates, and sample apps. 部署 Helm 圖表時會建立一些 Kubernetes 資源。When you deploy a Helm chart, a number of Kubernetes resources are created. 這些資源包含 Pod、部署和服務。These resources includes pods, deployments, and services. 若要清除這些資源, 您可以刪除整個範例命名空間或個別資源。To clean up these resources, you can either delete the entire sample namespace, or the individual resources.

刪除範例命名空間和所有資源Delete the sample namespace and all resources

若要刪除整個範例命名空間, 請kubectl delete使用命令並指定您的命名空間名稱。To delete the entire sample namespace, use the kubectl delete command and specify your namespace name. 命名空間中的所有資源都會被刪除。All the resources in the namespace are deleted.

kubectl delete namespace ingress-basic
kubectl delete namespace cert-manager

然後, 移除 AKS hello world 應用程式的 Helm 存放庫:Then, remove the Helm repo for the AKS hello world app:

helm repo remove azure-samples

個別刪除資源Delete resources individually

或者, 更細微的方法是刪除所建立的個別資源。Alternatively, a more granular approach is to delete the individual resources created. 首先, 移除憑證資源:First, remove the certificate resources:

kubectl delete -f certificates.yaml
kubectl delete -f cluster-issuer.yaml

現在使用 helm list 命令,列出 Helm 版本。Now list the Helm releases with the helm list command. 尋找名為 nginx-ingress、cert-manager 和 aks-helloworld 的圖表,如下列範例輸出所示:Look for charts named nginx-ingress, cert-manager, and aks-helloworld, as shown in the following example output:

$ helm list

NAME                    REVISION    UPDATED                     STATUS      CHART                   APP VERSION NAMESPACE
billowing-kitten        1           Wed Mar  6 19:37:43 2019    DEPLOYED    nginx-ingress-1.3.1     0.22.0      kube-system
loitering-waterbuffalo  1           Wed Mar  6 20:25:01 2019    DEPLOYED    cert-manager-v0.6.6     v0.6.2      kube-system
flabby-deer             1           Wed Mar  6 20:27:54 2019    DEPLOYED    aks-helloworld-0.1.0                default
linting-echidna         1           Wed Mar  6 20:27:59 2019    DEPLOYED    aks-helloworld-0.1.0                default

使用 helm delete 命令刪除版本。Delete the releases with the helm delete command. 下列範例會刪除 NGINX 輸入部署、憑證管理員以及兩個範例 AKS hello world 應用程式。The following example deletes the NGINX ingress deployment, certificate manager, and the two sample AKS hello world apps.

$ helm delete billowing-kitten loitering-waterbuffalo flabby-deer linting-echidna

release "billowing-kitten" deleted
release "loitering-waterbuffalo" deleted
release "flabby-deer" deleted
release "linting-echidna" deleted

接下來,移除 AKS hello world 應用程式的 Helm 存放庫:Next, remove the Helm repo for the AKS hello world app:

helm repo remove azure-samples

刪除本身的命名空間。Delete the itself namespace. kubectl delete使用命令, 並指定您的命名空間名稱:Use the kubectl delete command and specify your namespace name:

kubectl delete namespace ingress-basic

最後,移除將流量導向範例應用程式的輸入路由:Finally, remove the ingress route that directed traffic to the sample apps:

kubectl delete -f hello-world-ingress.yaml

後續步驟Next steps

本文包含 AKS 的一些外部元件。This article included some external components to AKS. 若要深入了解這些元件,請參閱下列專案頁面:To learn more about these components, see the following project pages:

您也可以:You can also: