0aa8fe6
这次没有正文改动。
这是 cloud/Ingress + TLS 证书自动化.md 的改动记录。后台每次保存都会留一份快照,
这里显示的是快照之间的差异,不会混入其他文章的改动。
还没有后台修改记录。
下面是 Git 里的提交,可能包含其他文章的改动(因为一次提交会带上工作区所有变化)。
0aa8fe6
这次没有正文改动。
ccb3350
@@ -0,0 +1,255 @@ +--- +tags: [Ingress, TLS, 证书, Let's Encrypt, cert-manager] +order: 20 +--- + +# Ingress + TLS 证书自动化 +--- + +## 场景 + +生产环境对外服务必须 HTTPS。手动申请、续期、分发证书太麻烦,尤其多域名、多环境时。 + +**cert-manager + Let's Encrypt** 实现:自动申请、自动续期、自动分发到 Ingress。 + +## 前置条件 + +* K8s 1.19+,已安装 Ingress Controller(nginx-ingress / traefik / alb) +* 域名已解析到 Ingress 的公网 IP / LB +* 集群能访问外网(访问 Let's Encrypt API:`acme-v02.api.letsencrypt.org:443`) +* Helm 3 已安装 + +## 配置 + +### 1\. 安装 cert\-manager + +```bash +# 方式 1:Helm(推荐) +helm repo add jetstack https://charts.jetstack.io +helm repo update +helm install cert-manager jetstack/cert-manager \ + -n cert-manager --create-namespace \ + --version v1.13.0 \ + --set installCRDs=true \ + --set prometheus.enabled=false + +# 验证 +kubectl get pods -n cert-manager +kubectl get crd | grep cert-manager +``` + +### 2\. 配置 Let's Encrypt ClusterIssuer + +```yaml +# cluster-issuer.yaml +apiVersion: cert-manager.io/v1 +kind: ClusterIssuer +metadata: + name: letsencrypt-prod +spec: + acme: + server: https://acme-v02.api.letsencrypt.org/directory + email: ops@example.com # 过期通知邮箱 + privateKeySecretRef: + name: letsencrypt-prod-key + solvers: + - http01: + ingress: + class: nginx # 对应 IngressClass 名称 +--- +# staging 环境用(测试用,不受速率限制) +apiVersion: cert-manager.io/v1 +kind: ClusterIssuer +metadata: + name: letsencrypt-staging +spec: + acme: + server: https://acme-staging-v02.api.letsencrypt.org/directory + email: ops@example.com + privateKeySecretRef: + name: letsencrypt-staging-key + solvers: + - http01: + ingress: + class: nginx +``` + +```bash +kubectl apply -f cluster-issuer.yaml +kubectl get clusterissuer +# READY 列应为 True +``` + +### 3\. Ingress 自动申请证书 + +```yaml +# ingress.yaml +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: myapp + namespace: prod + annotations: + cert-manager.io/cluster-issuer: letsencrypt-prod + nginx.ingress.kubernetes.io/ssl-redirect: "true" + nginx.ingress.kubernetes.io/proxy-body-size: "50m" +spec: + ingressClassName: nginx + tls: + - hosts: + - app.example.com + - api.example.com + secretName: myapp-tls # cert-manager 自动创建 + rules: + - host: app.example.com + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: myapp-svc + port: + number: 80 + - host: api.example.com + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: api-svc + port: + number: 8080 +``` + +```bash +kubectl apply -f ingress.yaml + +# 观察证书申请过程 +kubectl get certificate -n prod +kubectl describe certificate myapp-tls -n prod +kubectl describe certificaterequest -n prod +``` + +### 4\. 通配符证书(DNS\-01 挑战) + +适用于:子域名多、不想暴露 HTTP 端口、内网域名。 + +```yaml +# 需要 DNS 提供商 API Token(以 Cloudflare 为例) +# cluster-issuer-dns.yaml +apiVersion: cert-manager.io/v1 +kind: ClusterIssuer +metadata: + name: letsencrypt-dns +spec: + acme: + server: https://acme-v02.api.letsencrypt.org/directory + email: ops@example.com + privateKeySecretRef: + name: letsencrypt-dns-key + solvers: + - dns01: + cloudflare: + email: ops@example.com + apiTokenSecretRef: + name: cloudflare-api-token + key: api-token +--- …… 改动较长,只显示前一部分