无法为Azure托管Kubernetes集群的LoadBalancer服务配置SSL证书
刚上手Kubernetes和Azure AKS预览版就碰到TLS证书配置的问题,确实容易懵——我帮你梳理一套针对LoadBalancer服务场景的可行方案,一步步来:
第一步:先搞定静态IP和自定义DNS(关键前提)
Azure默认给LoadBalancer分配的是动态IP,对应的DNS名称也是临时的,根本没法稳定配置证书。所以首先得把IP改成静态,再绑定你要用的自定义DNS名称:
- 登录Azure门户,找到你的AKS集群对应的负载均衡器(一般在
MC_开头的资源组里) - 把负载均衡器的公共IP配置为静态
- 在公共IP的设置里,添加自定义DNS名称(比如
my-api.yourdomain.com) - 也可以用Azure CLI快速完成:
# 获取现有LB的公共IP ID IP_ID=$(az network public-ip list --resource-group MC_your-resource-group_your-aks-cluster_your-region --query "[0].id" -o tsv) # 设置为静态IP az network public-ip update --ids $IP_ID --allocation-method Static # 配置自定义DNS名称 az network public-ip update --ids $IP_ID --dns-name my-api
第二步:用cert-manager自动管理证书(AKS最常用方案)
cert-manager是Kubernetes生态里专门用来自动化签发、续期TLS证书的工具,对接Let's Encrypt这类CA非常方便:
安装cert-manager(用Helm是最简单的方式):
helm repo add jetstack https://charts.jetstack.io helm repo update helm install cert-manager jetstack/cert-manager \ --namespace cert-manager \ --create-namespace \ --version v1.13.0 \ --set installCRDs=true注意:要选和你的AKS K8s版本兼容的cert-manager版本,比如K8s 1.27+对应cert-manager v1.12+
配置ClusterIssuer对接Let's Encrypt:
创建一个ClusterIssuer资源,让cert-manager能和Let's Encrypt通信签发证书:apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: letsencrypt-prod spec: acme: server: https://acme-v02.api.letsencrypt.org/directory email: your-email@example.com # 填你的邮箱,用来收证书过期提醒 privateKeySecretRef: name: letsencrypt-prod solvers: - http01: ingress: class: nginx # 如果你用的是NGINX Ingress Controller;如果用AGIC就填azure/application-gateway把这个yaml保存为
cluster-issuer.yaml,然后执行kubectl apply -f cluster-issuer.yaml
第三步:通过Ingress绑定证书到LoadBalancer服务
Kubernetes的LoadBalancer服务本身不直接支持TLS终止,所以我们需要用Ingress来做反向代理,同时关联证书:
创建一个Ingress资源,指向你的LoadBalancer服务,并让cert-manager自动签发证书:
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: my-api-ingress annotations: cert-manager.io/cluster-issuer: letsencrypt-prod # 关联刚才创建的ClusterIssuer spec: tls: - hosts: - my-api.yourdomain.com # 填你之前配置的自定义DNS名称 secretName: my-api-tls # 证书会自动存在这个Secret里 rules: - host: my-api.yourdomain.com http: paths: - path: / pathType: Prefix backend: service: name: your-loadbalancer-service # 填你的LoadBalancer服务名称 port: number: 80 # 填你的服务暴露的HTTP端口
执行kubectl apply -f ingress.yaml部署Ingress
第四步:验证配置是否生效
- 查看证书状态:执行
kubectl get certificates,如果状态是Ready,说明证书签发成功了 - 访问你的自定义DNS地址
https://my-api.yourdomain.com,检查浏览器地址栏的证书是否正常显示
额外说明:如果不想用Ingress怎么办?
如果你的服务本身已经在Pod内部处理TLS(比如应用程序自己加载证书),那可以直接把证书放到Kubernetes Secret里,然后挂载到Pod中,再把LoadBalancer服务的端口设为443。但这种方式不如Ingress层统一管理证书方便,也没法自动续期,只适合小规模场景。
内容的提问来源于stack exchange,提问作者esc0tc

