生产环境还是建议购买了付费通配符的证书,毕竟万一出事没人给你兜底,测试环境就没必要了。

安装 cert-manager

  • yaml 文件安装
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.18.2/cert-manager.yaml
  • helm 安装
# 添加仓库
helm repo add jetstack https://charts.jetstack.io --force-update
# 安装
helm install 
  cert-manager jetstack/cert-manager 
  --namespace cert-manager 
  --create-namespace 
  --version v1.18.2 
  --set crds.enabled=true

配置阿里云 DNS 权限

在阿里云 RAM 控制台创建 RAM 子用户,分配权限 AliyunDNSFullAccess 即可,将生成的 AccessKey ID 和 AccessKey Secret 转一下 Base64。

echo "xxxxx" | base64
echo "xxxxxxxxxxxx" | base64

创建文件 alidns-secret.yaml,填入 AK 和 SK。

apiVersion: v1
kind: Secret
metadata:
  name: alidns-secrets
  namespace: cert-manager
type: Opaque
data:
  # base64
  access-token: xxxxxxxxxx
  secret-key: xxxxxxxxxxxxxxxxxxx

然后执行命令 kubectl apply -f alidns-secret.yaml 创建 Secret。

安装阿里云 DNS 插件

cert-manager 并没有内置阿里云 DNS,需要手动安装。

wget https://github.com/DEVmachine-fr/cert-manager-alidns-webhook/releases/download/alidns-webhook-0.8.3/alidns-webhook-0.8.3.tgz
helm install alidns-webhook ./alidns-webhook-0.8.3.tgz 
    --set groupName=alidns 
    --namespace cert-manager

创建 issue

cert-manager 有 issuser 和 clusterissuer 两种,区别是 issuer 只能为指定命名空间创建证书,clusterissuer 可以为集群所有命名空间创建,这里直接创建 clusterissuer。

  • alidns-letsencrypt.yaml
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: alidns-letsencrypt
spec:
  acme:
    email: mail@example.com # 你的邮箱
    server: https://acme-v02.api.letsencrypt.org/directory # 这里直接使用正式地址
    privateKeySecretRef:
      name: letsencrypt
    solvers:
    - dns01:
        webhook:
            config:
              accessTokenSecretRef:
                key: access-token
                name: alidns-secrets
              regionId: cn-beijing
              secretKeySecretRef:
                key: secret-key
                name: alidns-secrets
            groupName: alidns
            solverName: alidns-solver
kubectl apply -f alidns-letsencrypt.yaml

创建证书

dnsNames 里写要申请证书的域名,可以是通配符,可以填写多个。commonName 从 dnsNames 里随便找一个就行。

  • example-com-tls.yaml
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: example-com-tls
  namespace: applications
spec:
  secretName: example-com-tls
  commonName: 'example.com'
  dnsNames:
  - 'example.com'
  - 'www.example.com'
  issuerRef:
    name: alidns-letsencrypt
    kind: ClusterIssuer
kubectl apply -f example-com-tls.yaml

配置 Ingress

配置 Ingress 的时候需要注意添加注解 cert-manager.io/issuer: alidns-letsencrypt,这样 Ingress 才能正确匹配到证书的 Secret。

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    cert-manager.io/issuer: alidns-letsencrypt
  name: example-ingresss
  namespace: applications
spec:
  ingressClassName: nginx
  rules:
    - host: 'www.example.com'
      http:
        paths:
          - backend:
              service:
                name: example-svc
                port:
                  number: 8080
            path: /
            pathType: ImplementationSpecific
    - host: 'example.com'
      http:
        paths:
          - backend:
              service:
                name: example-svc
                port:
                  number: 8080
            path: /
            pathType: ImplementationSpecific
  tls:
    - hosts:
        - 'example.com'
        - 'www.example.com'
      secretName: example-com-tls

且乐生前一杯酒