如何在AKS托管的ASP.NET Core 6 Web API上启用HTTPS及相关疑问
关于AKS托管ASP.NET Core 6 Web API启用HTTPS的疑问解答
问题背景
我正在为AKS托管的ASP.NET Core 6 Web API启用HTTPS,查阅线上示例后仍有疑问,现将相关代码分享如下:
ASP.NET Core 6 Web API代码
builder.WebHost.ConfigureKestrel(options => { options.ListenAnyIP(80); // HTTP port options.ListenAnyIP(443, listenOptions => { listenOptions.UseHttps("/app/cert/tls.crt", "/app/cert/tls.key"); }); });
创建TLS密钥的命令
kubectl create secret tls localhost-tls --cert=path/to/tls.crt --key=path/to/tls.key
Ingress配置
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: sslapi namespace: core annotations: kubernetes.io/ingress.class: agic-2 appgw.ingress.kubernetes.io/health-probe-hostname: "localhost" appgw.ingress.kubernetes.io/health-probe-port: "443" appgw.ingress.kubernetes.io/health-probe-path: "/sslapi/swagger/index.html" appgw.ingress.kubernetes.io/use-private-ip: "true" appgw.ingress.kubernetes.io/override-frontend-port: "10005" spec: ingressClassName: agic-2 tls: - hosts: - localhost secretName: localhost-tls rules: - http: paths: - path: /sslapi/swagger backend: service: name: sslapi port: number: 443 pathType: Prefix - path: /sslapi/GetWeatherForecast backend: service: name: sslapi port: number: 443 pathType: Prefix
疑问解答
1. 为何Kestrel和Ingress都要配置证书?能否只配一处?
这两处配置作用完全不同,不能只配置一处:
- Kestrel的证书配置:用于让Web API容器自身监听HTTPS端口(443),保证Ingress到容器内部的通信是加密的——因为你的Ingress规则指向了服务的443端口,如果Kestrel不配置证书,容器的443端口无法提供HTTPS服务,Ingress转发请求时会直接报错。
- Ingress的证书配置:用于外部客户端和Ingress(这里是Azure应用网关,因为使用了AGIC)之间的加密连接,也就是用户访问API时,从客户端到Ingress入口的链路是HTTPS加密的。如果Ingress不配置证书,外部访问会出现证书信任错误,无法建立正常的HTTPS连接。
简单来说,Kestrel证书管集群内部Ingress到容器的加密链路,Ingress证书管外部客户端到Ingress的加密链路,二者是HTTPS通信的两个不同环节。当然你也可以调整架构:让Ingress和容器之间用HTTP通信,此时Kestrel无需配置HTTPS,只保留Ingress的外部证书即可,但这种方式下集群内部通信是明文的,安全性会打折扣,需根据你的安全需求选择。
2. 如何从容器外部传入证书简化续期?
如果必须在Kestrel中配置证书,推荐通过Kubernetes Secret挂载证书,而非将证书打包进镜像,这样续期时只需更新Secret,无需重新构建镜像:
具体步骤:
- 确保你已通过
kubectl create secret tls创建了localhost-tls这个TLS Secret(和你之前的操作一致)。 - 在Deployment配置中,将该Secret挂载到容器的指定路径(比如代码中用到的
/app/cert):
apiVersion: apps/v1 kind: Deployment metadata: name: sslapi namespace: core spec: replicas: 1 selector: matchLabels: app: sslapi template: metadata: labels: app: sslapi spec: containers: - name: sslapi image: your-api-image:tag ports: - containerPort: 80 - containerPort: 443 volumeMounts: - name: tls-cert mountPath: /app/cert readOnly: true volumes: - name: tls-cert secret: secretName: localhost-tls items: - key: tls.crt path: tls.crt - key: tls.key path: tls.key
- 配置完成后,Kestrel代码里的
/app/cert/tls.crt和/app/cert/tls.key就能读取到Secret中的证书文件。
证书续期操作:
当需要更新证书时,只需执行以下步骤:
- 生成新的
tls.crt和tls.key文件 - 更新Kubernetes Secret:
kubectl create secret tls localhost-tls --cert=new-path/tls.crt --key=new-path/tls.key --dry-run=client -o yaml | kubectl apply -f -
- 重启Deployment让容器加载新证书:
kubectl rollout restart deployment sslapi -n core
这种方式无需修改代码或重新构建镜像,完全通过Kubernetes的Secret机制管理证书,大幅简化了续期流程。
内容的提问来源于stack exchange,提问作者Pankaj Kapare
相关产品推荐
相关产品推荐

