在 Azure Kubernetes Service (AKS) 上建立 HTTPS 輸入控制器及使用自有的 TLS 憑證Create an HTTPS ingress controller and use your own TLS certificates 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. 您會產生自己的憑證,並建立 Kubernetes 祕密以便用於輸入路由。You generate your own certificates, and create a Kubernetes secret for use with the ingress route. 最後,會有兩個應用程式在 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

本文使用 Helm 來安裝 NGINX 輸入控制器及範例 Web 應用程式。This article uses Helm to install the NGINX ingress controller 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
virulent-seal-nginx-ingress-controller        LoadBalancer   10.0.48.240   40.87.46.190   80:31159/TCP,443:30657/TCP   7m
virulent-seal-nginx-ingress-default-backend   ClusterIP      10.0.50.5     <none>         80/TCP                       7m

請記下此公用 IP 位址,因為在最後一個步驟中該位址用來測試部署。Make a note of this public IP address, as it's used in the last step to test the deployment.

尚未建立任何輸入規則。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.

產生 TLS 憑證Generate TLS certificates

在本文中,使用 openssl 產生自我簽署的憑證。For this article, let's generate a self-signed certificate with openssl. 針對生產用途,您應該透過提供者或自己的憑證授權單位 (CA) 來要求受信任、已簽署的憑證。For production use, you should request a trusted, signed certificate through a provider or your own certificate authority (CA). 在下一個步驟中,您會使用 OpenSSL 所產生的 TLS 憑證和私密金鑰來產生 Kubernetes「祕密」。In the next step, you generate a Kubernetes Secret using the TLS certificate and private key generated by OpenSSL.

下列範例會產生名為 aks-ingress-tls.crt 的 2048 位元 RSA X509 憑證,有效期為 365 天。The following example generates a 2048-bit RSA X509 certificate valid for 365 days named aks-ingress-tls.crt. 此私密金鑰檔案名為 aks-ingress-tls.key。The private key file is named aks-ingress-tls.key. Kubernetes TLS 祕密需要這兩個檔案。A Kubernetes TLS secret requires both of these files.

這篇文章使用 demo.azure.com 主體一般名稱,而且不需要變更。This article works with the demo.azure.com subject common name and doesn't need to be changed. 針對生產用途,指定自己組織的 -subj 參數值:For production use, specify your own organizational values for the -subj parameter:

openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
    -out aks-ingress-tls.crt \
    -keyout aks-ingress-tls.key \
    -subj "/CN=demo.azure.com/O=aks-ingress-tls"

為 TLS 憑證建立 Kubernetes 祕密Create Kubernetes secret for the TLS certificate

若要允許 Kubernetes 使用輸入控制器的 TLS 憑證和私密金鑰,您可建立及使用祕密。To allow Kubernetes to use the TLS certificate and private key for the ingress controller, you create and use a Secret. 定義祕密一次,並使用在上一個步驟中建立的憑證和金鑰檔案。The secret is defined once, and uses the certificate and key file created in the previous step. 您會接著在定義輸入路由時參考此祕密。You then reference this secret when you define ingress routes.

下列範例會建立祕密名稱 aks-ingress-tls:The following example creates a Secret name aks-ingress-tls:

kubectl create secret tls aks-ingress-tls \
    --namespace ingress-basic \
    --key aks-ingress-tls.key \
    --cert aks-ingress-tls.crt

執行示範應用程式Run demo applications

輸入控制器和您憑證的祕密皆已設定。An ingress controller and a Secret with your certificate 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.azure.com/ 的流量會路由傳送至名為 aks-helloworld 的服務。In the following example, traffic to the address https://demo.azure.com/ is routed to the service named aks-helloworld. 傳至位址 https://demo.azure.com/hello-world-two 的流量會路由至 ingress-demo 服務。Traffic to the address https://demo.azure.com/hello-world-two is routed to the ingress-demo service. 在本文中,您不需要變更這些示範主機名稱。For this article, you don't need to change those demo host names. 針對生產用途,提供在憑證要求和產生過程中指定的名稱。For production use, provide the names specified as part of the certificate request and generation process.

提示

如果在憑證要求程式期間指定的主機名稱(CN 名稱)與輸入路由中定義的主機不符,則輸入控制器會顯示 Kubernetes 輸入控制器假憑證警告。If the host name specified during the certificate request process, the CN name, doesn't match the host defined in your ingress route, you ingress controller displays a Kubernetes Ingress Controller Fake Certificate warning. 請確定您的憑證與輸入路由主機名稱相符。Make sure your certificate and ingress route host names match.

tls 區段會告知輸入路由對主機 demo.azure.com 使用名為 aks-ingress-tls 的祕密。The tls section tells the ingress route to use the Secret named aks-ingress-tls for the host demo.azure.com. 同樣地,針對生產用途,指定您自己的主機位址。Again, for production use, specify your own host address.

建立名為 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
    nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
  tls:
  - hosts:
    - demo.azure.com
    secretName: aks-ingress-tls
  rules:
  - host: demo.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

測試輸入組態Test the ingress configuration

若要使用假的 demo.azure.com 主機測試憑證,請使用 curl 並指定 --resolve 參數。To test the certificates with our fake demo.azure.com host, use curl and specify the --resolve parameter. 此參數可讓您將 demo.azure.com 名稱對應到輸入控制器的公用 IP 位址。This parameter lets you map the demo.azure.com name to the public IP address of your ingress controller. 指定您自有輸入控制器的公用 IP 位址,如下列範例所示:Specify the public IP address of your own ingress controller, as shown in the following example:

curl -v -k --resolve demo.azure.com:443:40.87.46.190 https://demo.azure.com

先前並未提供位址的其他路徑,因此輸入控制器預設為 / 路由。No additional path was provided with the address, so the ingress controller defaults to the / route. 此時會傳回第一個示範應用程式,如下列簡要範例輸出所示:The first demo application is returned, as shown in the following condensed example output:

$ curl -v -k --resolve demo.azure.com:443:40.87.46.190 https://demo.azure.com

[...]
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <link rel="stylesheet" type="text/css" href="/static/default.css">
    <title>Welcome to Azure Kubernetes Service (AKS)</title>
[...]

curl 命令中的 -v 參數會輸出詳細資訊,包括所收到的 TLS 憑證。The -v parameter in our curl command outputs verbose information, including the TLS certificate received. 在 curl 輸出的中途,您可驗證是否已使用自有的 TLS 憑證。Half-way through your curl output, you can verify that your own TLS certificate was used. 即使我們使用自我簽署的憑證,-k 參數會繼續載入頁面。The -k parameter continues loading the page even though we're using a self-signed certificate. 下列範例顯示使用了 issuer:CN=demo.azure.com; O=aks-ingress-tls 憑證:The following example shows that the issuer: CN=demo.azure.com; O=aks-ingress-tls certificate was used:

[...]
* Server certificate:
*  subject: CN=demo.azure.com; O=aks-ingress-tls
*  start date: Oct 22 22:13:54 2018 GMT
*  expire date: Oct 22 22:13:54 2019 GMT
*  issuer: CN=demo.azure.com; O=aks-ingress-tls
*  SSL certificate verify result: self signed certificate (18), continuing anyway.
[...]

現在,將 /hello-world-two 路徑新增至位址,例如 https://demo.azure.com/hello-world-twoNow add /hello-world-two path to the address, such as https://demo.azure.com/hello-world-two. 此時會傳回含有自訂標題的第二個示範應用程式,如下列簡要範例輸出所示:The second demo application with the custom title is returned, as shown in the following condensed example output:

$ curl -v -k --resolve demo.azure.com:443:137.117.36.18 https://demo.azure.com/hello-world-two

[...]
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <link rel="stylesheet" type="text/css" href="/static/default.css">
    <title>AKS Ingress Demo</title>
[...]

清除資源Clean up resources

本文使用 Helm 來安裝輸入元件和範例應用程式。This article used Helm to install the ingress components and sample apps. 部署 Helm 圖表時會建立一些 Kubernetes 資源。When you deploy a Helm chart, a number of Kubernetes resources are created. 這些資源包含 Pod、部署和服務。These resources include 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

然後,移除 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. 使用helm list命令來列出 Helm 版本。List the Helm releases with the helm list command. 尋找名為nginx-ingress 和 aks-helloworld 的圖表,如下列範例輸出所示:Look for charts named nginx-ingress and aks-helloworld, as shown in the following example output:

$ helm list

NAME            REVISION    UPDATED                     STATUS      CHART                   APP VERSION NAMESPACE
virulent-seal   1           Tue Oct 23 16:37:24 2018    DEPLOYED    nginx-ingress-0.22.1    0.15.0      kube-system
billowing-guppy 1           Tue Oct 23 16:41:38 2018    DEPLOYED    aks-helloworld-0.1.0                default
listless-quokka 1           Tue Oct 23 16:41:30 2018    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 and the two sample AKS hello world apps.

$ helm delete virulent-seal billowing-guppy listless-quokka

release "virulent-seal" deleted
release "billowing-guppy" deleted
release "listless-quokka" deleted

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

helm repo remove azure-samples

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

kubectl delete -f hello-world-ingress.yaml

刪除憑證密碼:Delete the certificate Secret:

kubectl delete secret aks-ingress-tls

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

kubectl delete namespace ingress-basic

後續步驟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: