您现在访问的是微软AZURE全球版技术文档网站,若需要访问由世纪互联运营的MICROSOFT AZURE中国区技术文档网站,请访问 https://docs.azure.cn.

使用自定义 traefik 入口控制器并配置 HTTPSUse a custom traefik ingress controller and configure HTTPS

重要

Azure Dev Spaces 即将停用,将于 2023 年 10 月 31 日停止工作。Azure Dev Spaces is being retired and will stop working on October 31, 2023. 请考虑迁移到 Bridge to KubernetesConsider migrating to Bridge to Kubernetes.

本文介绍如何将 Azure Dev Spaces 配置为使用自定义 traefik 入口控制器。This article shows you how to configure Azure Dev Spaces to use a custom traefik ingress controller. 本文还介绍如何将该自定义入口控制器配置为使用 HTTPS。This article also shows you how to configure that custom ingress controller to use HTTPS.

先决条件Prerequisites

配置自定义 traefik 入口控制器Configure a custom traefik ingress controller

使用 kubectl和 Kubernetes 命令行客户端连接到群集。Connect to your cluster using kubectl, the Kubernetes command-line client. 若要将 kubectl 配置为连接到 Kubernetes 群集,请使用 az aks get-credentials 命令。To configure kubectl to connect to your Kubernetes cluster, use the az aks get-credentials command. 此命令将下载凭据,并将 Kubernetes CLI 配置为使用这些凭据。This command downloads credentials and configures the Kubernetes CLI to use them.

az aks get-credentials --resource-group myResourceGroup --name myAKS

若要验证到群集的连接,请使用 kubectl get 命令返回群集节点列表。To verify the connection to your cluster, use the kubectl get command to return a list of the cluster nodes.

kubectl get nodes
NAME                                STATUS   ROLES   AGE    VERSION
aks-nodepool1-12345678-vmssfedcba   Ready    agent   13m    v1.14.1

添加 官方稳定的 Helm 存储库,其中包含 traefik 入口控制器 Helm 图表。Add the official stable Helm repository, which contains the traefik ingress controller Helm chart.

helm repo add stable https://charts.helm.sh/stable

为 traefik 入口控制器创建 Kubernetes 命名空间,并使用安装它 helmCreate a Kubernetes namespace for the traefik ingress controller and install it using helm.

备注

如果 AKS 群集未启用 Kubernetes RBAC,请删除 --set rbac. enabled = true 参数。If your AKS cluster does not have Kubernetes RBAC enabled, remove the --set rbac.enabled=true parameter.

kubectl create ns traefik
helm install traefik stable/traefik --namespace traefik --set kubernetes.ingressClass=traefik --set rbac.enabled=true --set fullnameOverride=customtraefik --set kubernetes.ingressEndpoint.useDefaultPublishedService=true --version 1.85.0

备注

上面的示例为入口控制器创建一个公共终结点。The above example creates a public endpoint for your ingress controller. 如果需要改用入口控制器的专用终结点,请添加 --set 服务。helm install 命令的 \ \ kubernetes \ /azure-load--internal "= true 参数。 If you need to use a private endpoint for your ingress controller instead, add the --set service.annotations."service\.beta\.kubernetes\.io/azure-load-balancer-internal"=true parameter to the helm install command.

helm install traefik stable/traefik --namespace traefik --set kubernetes.ingressClass=traefik --set rbac.enabled=true --set fullnameOverride=customtraefik --set kubernetes.ingressEndpoint.useDefaultPublishedService=true --set service.annotations."service\.beta\.kubernetes\.io/azure-load-balancer-internal"=true --version 1.85.0

此专用终结点在部署 AKS 群集的虚拟网络中公开。This private endpoint is exposed within the virtual network where you AKS cluster is deployed.

使用 kubectl get获取 traefik 入口控制器服务的 IP 地址。Get the IP address of the traefik ingress controller service using kubectl get.

kubectl get svc -n traefik --watch

示例输出显示 traefik 命名空间中所有服务的 IP 地址。The sample output shows the IP addresses for all the services in the traefik name space.

NAME      TYPE           CLUSTER-IP    EXTERNAL-IP   PORT(S)                      AGE
traefik   LoadBalancer   10.0.205.78   <pending>     80:32484/TCP,443:30620/TCP   20s
...
traefik   LoadBalancer   10.0.205.78   MY_EXTERNAL_IP   80:32484/TCP,443:30620/TCP   60s

使用 az network DNS recorda 记录添加到 DNS 区域,使用 TRAEFIK 服务的外部 IP 地址,并设置添加记录。Add an A record to your DNS zone with the external IP address of the traefik service using az network dns record-set a add-record.

az network dns record-set a add-record \
    --resource-group myResourceGroup \
    --zone-name MY_CUSTOM_DOMAIN \
    --record-set-name *.traefik \
    --ipv4-address MY_EXTERNAL_IP

上面的示例将 A 记录添加到 MY_CUSTOM_DOMAIN DNS 区域。The above example adds an A record to the MY_CUSTOM_DOMAIN DNS zone.

本文使用 Azure Dev Spaces 单车共享示例应用程序来演示 Azure Dev Spaces 的用法。In this article, you use the Azure Dev Spaces Bike Sharing sample application to demonstrate using Azure Dev Spaces. 从 GitHub 克隆此应用程序,然后导航到其目录中:Clone the application from GitHub and navigate into its directory:

git clone https://github.com/Azure/dev-spaces
cd dev-spaces/samples/BikeSharingApp/charts

打开 yaml 并进行以下更新:Open values.yaml and make the following updates:

  • <REPLACE_ME_WITH_HOST_SUFFIX> 的所有实例替换为 traefik。MY_CUSTOM_DOMAIN 使用域进行 MY_CUSTOM_DOMAINReplace all instances of <REPLACE_ME_WITH_HOST_SUFFIX> with traefik.MY_CUSTOM_DOMAIN using your domain for MY_CUSTOM_DOMAIN.
  • 替换 kubernetes.io/ingress.class: traefik-azds # Dev Spaces-特定于 kubernetes.io/ingress.class: Traefik # 自定义入口Replace kubernetes.io/ingress.class: traefik-azds # Dev Spaces-specific with kubernetes.io/ingress.class: traefik # Custom Ingress.

下面是已更新文件的示例 values.yamlBelow is an example of an updated values.yaml file:

# This is a YAML-formatted file.
# Declare variables to be passed into your templates.

bikesharingweb:
  ingress:
    annotations:
      kubernetes.io/ingress.class: traefik  # Custom Ingress
    hosts:
      - dev.bikesharingweb.traefik.MY_CUSTOM_DOMAIN  # Assumes deployment to the 'dev' space

gateway:
  ingress:
    annotations:
      kubernetes.io/ingress.class: traefik  # Custom Ingress
    hosts:
      - dev.gateway.traefik.MY_CUSTOM_DOMAIN  # Assumes deployment to the 'dev' space

保存更改并关闭该文件。Save your changes and close the file.

使用创建使用的示例应用程序的 开发 环境 azds space selectCreate the dev space with your sample application using azds space select.

azds space select -n dev -y

使用部署示例应用程序 helm installDeploy the sample application using helm install.

helm install bikesharingsampleapp . --dependency-update --namespace dev --atomic

上面的示例将示例应用程序部署到 dev 命名空间。The above example deploys the sample application to the dev namespace.

显示使用访问示例应用程序的 Url azds list-urisDisplay the URLs to access the sample application using azds list-uris.

azds list-uris

下面的输出显示了来自的示例 Url azds list-urisThe below output shows the example URLs from azds list-uris.

Uri                                                  Status
---------------------------------------------------  ---------
http://dev.bikesharingweb.traefik.MY_CUSTOM_DOMAIN/  Available
http://dev.gateway.traefik.MY_CUSTOM_DOMAIN/         Available

通过 azds list-uris 命令打开公共 URL,导航到 bikesharingweb 服务。Navigate to the bikesharingweb service by opening the public URL from the azds list-uris command. 在以上示例中,bikesharingweb 服务的公共 URL 为 http://dev.bikesharingweb.traefik.MY_CUSTOM_DOMAIN/In the above example, the public URL for the bikesharingweb service is http://dev.bikesharingweb.traefik.MY_CUSTOM_DOMAIN/.

备注

如果看到错误页面而不是 bikesharingweb 服务,请验证是否已在 yaml 文件 中更新 kubernetes.io/ingress.class 批注和主机。If you see an error page instead of the bikesharingweb service, verify you updated both the kubernetes.io/ingress.class annotation and the host in the values.yaml file.

使用 azds space select 命令在 " 开发 " 下创建子空间,并列出用于访问子开发人员空间的 url。Use the azds space select command to create a child space under dev and list the URLs to access the child dev space.

azds space select -n dev/azureuser1 -y
azds list-uris

以下输出显示了中的示例 Url azds list-uris ,可用于访问 azureuser1 子开发人员空间中的示例应用程序。The below output shows the example URLs from azds list-uris to access the sample application in the azureuser1 child dev space.

Uri                                                  Status
---------------------------------------------------  ---------
http://azureuser1.s.dev.bikesharingweb.traefik.MY_CUSTOM_DOMAIN/  Available
http://azureuser1.s.dev.gateway.traefik.MY_CUSTOM_DOMAIN/         Available

通过从命令中打开公共 URL,导航到 azureuser1 子 dev 空间中的 bikesharingweb 服务 azds list-urisNavigate to the bikesharingweb service in the azureuser1 child dev space by opening the public URL from the azds list-uris command. 在上面的示例中, azureuser1 子开发人员空间中 bikesharingweb 服务的公共 URL 是 http://azureuser1.s.dev.bikesharingweb.traefik.MY_CUSTOM_DOMAIN/In the above example, the public URL for the bikesharingweb service in the azureuser1 child dev space is http://azureuser1.s.dev.bikesharingweb.traefik.MY_CUSTOM_DOMAIN/.

将 traefik 入口控制器配置为使用 HTTPSConfigure the traefik ingress controller to use HTTPS

将 traefik 入口控制器配置为使用 HTTPS 时,请使用 证书管理器 自动管理 TLS 证书。Use cert-manager to automate the management of the TLS certificate when configuring your traefik ingress controller to use HTTPS. 使用 helm 安装 certmanager 图表。Use helm to install the certmanager chart.

kubectl apply --validate=false -f https://raw.githubusercontent.com/jetstack/cert-manager/release-0.12/deploy/manifests/00-crds.yaml --namespace traefik
kubectl label namespace traefik certmanager.k8s.io/disable-validation=true
helm repo add jetstack https://charts.jetstack.io
helm repo update
helm install cert-manager --namespace traefik --version v0.12.0 jetstack/cert-manager --set ingressShim.defaultIssuerName=letsencrypt --set ingressShim.defaultIssuerKind=ClusterIssuer

创建一个 letsencrypt-clusterissuer.yaml 文件,并使用您的电子邮件地址更新 "电子邮件" 字段。Create a letsencrypt-clusterissuer.yaml file and update the email field with your email address.

apiVersion: cert-manager.io/v1alpha2
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: traefik

备注

对于测试,还有一个可用于 ClusterIssuer过渡服务器For testing, there is also a staging server you can use for your ClusterIssuer.

使用 kubectl 应用 letsencrypt-clusterissuer.yamlUse kubectl to apply letsencrypt-clusterissuer.yaml.

kubectl apply -f letsencrypt-clusterissuer.yaml --namespace traefik

删除以前的 traefik ClusterRoleClusterRoleBinding,然后将 traefik 升级到使用 HTTPS helmRemove the previous traefik ClusterRole and ClusterRoleBinding, then upgrade traefik to use HTTPS using helm.

备注

如果 AKS 群集未启用 Kubernetes RBAC,请删除 --set rbac. enabled = true 参数。If your AKS cluster does not have Kubernetes RBAC enabled, remove the --set rbac.enabled=true parameter.

kubectl delete ClusterRole traefik
kubectl delete ClusterRoleBinding traefik
helm upgrade traefik stable/traefik --namespace traefik --set kubernetes.ingressClass=traefik --set rbac.enabled=true --set kubernetes.ingressEndpoint.useDefaultPublishedService=true --version 1.85.0 --set ssl.enabled=true --set ssl.enforced=true --set ssl.permanentRedirect=true

使用 kubectl get获取 traefik 入口控制器服务的已更新 IP 地址。Get the updated IP address of the traefik ingress controller service using kubectl get.

kubectl get svc -n traefik --watch

示例输出显示 traefik 命名空间中所有服务的 IP 地址。The sample output shows the IP addresses for all the services in the traefik name space.

NAME      TYPE           CLUSTER-IP    EXTERNAL-IP          PORT(S)                      AGE
traefik   LoadBalancer   10.0.205.78   <pending>            80:32484/TCP,443:30620/TCP   20s
...
traefik   LoadBalancer   10.0.205.78   MY_NEW_EXTERNAL_IP   80:32484/TCP,443:30620/TCP   60s

使用 az network dns recorda 记录添加到 DNS 区域,并使用 traefik 服务的新外部 IP 地址,并使用 az network Dns record 删除上 条记录 -设置删除记录Add an A record to your DNS zone with the new external IP address of the traefik service using az network dns record-set a add-record and remove the previous A record using az network dns record-set a remove-record.

az network dns record-set a add-record \
    --resource-group myResourceGroup \
    --zone-name MY_CUSTOM_DOMAIN \
    --record-set-name *.traefik \
    --ipv4-address MY_NEW_EXTERNAL_IP

az network dns record-set a remove-record \
    --resource-group myResourceGroup \
    --zone-name  MY_CUSTOM_DOMAIN \
    --record-set-name *.traefik \
    --ipv4-address PREVIOUS_EXTERNAL_IP

上面的示例将 MY_CUSTOM_DOMAIN DNS 区域中的 A 记录更新为使用 PREVIOUS_EXTERNAL_IPThe above example updates the A record in the MY_CUSTOM_DOMAIN DNS zone to use PREVIOUS_EXTERNAL_IP.

yaml 更新为包含使用 证书管理器 和 HTTPS 的详细信息。Update values.yaml to include the details for using cert-manager and HTTPS. 下面是已更新文件的示例 values.yamlBelow is an example of an updated values.yaml file:

# This is a YAML-formatted file.
# Declare variables to be passed into your templates.

bikesharingweb:
  ingress:
    annotations:
      kubernetes.io/ingress.class: traefik  # Custom Ingress
      cert-manager.io/cluster-issuer: letsencrypt
    hosts:
      - dev.bikesharingweb.traefik.MY_CUSTOM_DOMAIN  # Assumes deployment to the 'dev' space
    tls:
    - hosts:
      - dev.bikesharingweb.traefik.MY_CUSTOM_DOMAIN
      secretName: dev-bikesharingweb-secret

gateway:
  ingress:
    annotations:
      kubernetes.io/ingress.class: traefik  # Custom Ingress
      cert-manager.io/cluster-issuer: letsencrypt
    hosts:
      - dev.gateway.traefik.MY_CUSTOM_DOMAIN  # Assumes deployment to the 'dev' space
    tls:
    - hosts:
      - dev.gateway.traefik.MY_CUSTOM_DOMAIN
      secretName: dev-gateway-secret

使用以下内容升级示例应用程序 helmUpgrade the sample application using helm:

helm upgrade bikesharingsampleapp . --namespace dev --atomic

导航到 dev/azureuser1 子空间中的示例应用程序,注意将重定向到 "使用 HTTPS"。Navigate to the sample application in the dev/azureuser1 child space and notice you are redirected to use HTTPS.

重要

DNS 更改可能需要30分钟或更长时间才能完成,并且你的示例应用程序可供访问。It may take 30 minutes or more for the DNS changes to complete and your sample application to be accessible.

另请注意,页面加载,但浏览器显示一些错误。Also notice that the page loads, but the browser shows some errors. 打开浏览器控制台时,将显示与尝试加载 HTTP 资源的 HTTPS 页相关的错误。Opening the browser console shows the error relates to an HTTPS page trying to load HTTP resources. 例如:For example:

Mixed Content: The page at 'https://azureuser1.s.dev.bikesharingweb.traefik.MY_CUSTOM_DOMAIN/devsignin' was loaded over HTTPS, but requested an insecure resource 'http://azureuser1.s.dev.gateway.traefik.MY_CUSTOM_DOMAIN/api/user/allUsers'. This request has been blocked; the content must be served over HTTPS.

若要修复此错误,请更新 BikeSharingWeb/azds ,以将 traefik 用于 kubernetes.io/ingress.class ,并使用自定义域 ) $ (hostSuffixTo fix this error, update BikeSharingWeb/azds.yaml to use traefik for kubernetes.io/ingress.class and your custom domain for $(hostSuffix). 例如:For example:

...
    ingress:
      annotations:
        kubernetes.io/ingress.class: traefik
      hosts:
      # This expands to [space.s.][rootSpace.]bikesharingweb.<random suffix>.<region>.azds.io
      - $(spacePrefix)$(rootSpacePrefix)bikesharingweb.traefik.MY_CUSTOM_DOMAIN
...

使用 url 包的依赖项更新 上的 BikeSharingWeb/package.jsUpdate BikeSharingWeb/package.json with a dependency for the url package.

{
...
    "react-responsive": "^6.0.1",
    "universal-cookie": "^3.0.7",
    "url": "0.11.0"
  },
...

更新 BikeSharingWeb/lib/helpers.js中的 getApiHostAsync 方法,以使用 HTTPS:Update the getApiHostAsync method in BikeSharingWeb/lib/helpers.js to use HTTPS:

...
    getApiHostAsync: async function() {
        const apiRequest = await fetch('/api/host');
        const data = await apiRequest.json();
        
        var urlapi = require('url');
        var url = urlapi.parse(data.apiHost);

        console.log('apiHost: ' + "https://"+url.host);
        return "https://"+url.host;
    },
...

导航到 BikeSharingWeb 目录并使用 azds up 运行更新后的 BikeSharingWeb 服务。Navigate to the BikeSharingWeb directory and use azds up to run your updated BikeSharingWeb service.

cd ../BikeSharingWeb/
azds up

导航到 dev/azureuser1 子空间中的示例应用程序,请注意,将重定向到使用 HTTPS,但不会出现任何错误。Navigate to the sample application in the dev/azureuser1 child space and notice you are redirected to use HTTPS without any errors.

后续步骤Next steps

深入了解 Azure Dev Spaces 的工作方式。Learn more about how Azure Dev Spaces works.