Kubernetes 集群自动生成更新HTTPS证书教程,单域名,通配符域名证书申请

简介

详情请到GitHub查看:https://github.com/PowerDos/k8s-cret-manager-aliyun-webhook-demo

这里介绍如何在K8s中通过cret-manager自动创建HTTPS证书,提供两种方式,一种是单域名证书,一种是通过阿里云DNS验证实现通配符域名证书申请

我们这里通过Helm安装cret-manager,请注意查看k8s版本正确安装对应版本的应用

1.安装Helm 3

官方安装教程: https://helm.sh/docs/intro/install/

$ curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3
$ chmod 700 get_helm.sh
$ ./get_helm.sh

2.安装cert-manager

前期准备

添加命名空间

kubectl create namespace cert-manager

添加cret-manager源

helm repo add jetstack https://charts.jetstack.io

更新源

helm repo update

安装CRDs

注意安装对应的版本

# Kubernetes 1.15+
$ kubectl apply --validate=false -f https://github.com/jetstack/cert-manager/releases/download/v0.15.1/cert-manager.crds.yaml

# Kubernetes <1.15
$ kubectl apply --validate=false -f https://github.com/jetstack/cert-manager/releases/download/v0.15.1/cert-manager-legacy.crds.yaml

安装cert-manager

$ helm install \
  cert-manager jetstack/cert-manager \
  --namespace cert-manager \
  --version v0.15.1

验证是否安装成功

以下结果为成功,你也可以看看镜像日志,是否正常启动,是否正常

$ kubectl get pods --namespace cert-manager

NAME                                       READY   STATUS    RESTARTS   AGE
cert-manager-5c6344597-zw8kh               1/1     Running   0          2m
cert-manager-cainjector-348f6d9fd7-tr77l   1/1     Running   0          2m
cert-manager-webhook-893u48fcdb-nlzsq      1/1     Running   0          2m

3.安装证书

官方介绍这中 Issuer 与 ClusterIssuer 的概念:

Issuers, and ClusterIssuers, are Kubernetes resources that represent certificate authorities (CAs) that are able to generate signed certificates by honoring certificate signing requests. All cert-manager certificates require a referenced issuer that is in a ready condition to attempt to honor the request.

Issuer 与 ClusterIssuer 的区别是 ClusterIssuer 可跨命名空间使用,而 Issuer 需在每个命名空间下配置后才可使用。这里我们使用 ClusterIssuer,其类型选择 Let‘s Encrypt

测试证书

# cluster-issuer-letsencrypt-staging.yaml

apiVersion: cert-manager.io/v1alpha2
kind: ClusterIssuer
metadata:
  name: letsencrypt-staging
spec:
  acme:
    # 务必将此处替换为你自己的邮箱, 否则会配置失败。当证书快过期时 Let's Encrypt 会与你联系
    email: gavin.tech@qq.com
    server: https://acme-staging-v02.api.letsencrypt.org/directory
    privateKeySecretRef:
      # 将用来存储 Private Key 的 Secret 资源
      name: letsencrypt-staging
    # Add a single challenge solver, HTTP01 using nginx
    solvers:
    - http01:
        ingress:
          class: nginx

正式证书

# cluster-issuer-letsencrypt-prod.yaml

apiVersion: cert-manager.io/v1alpha2
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email:  gavin.tech@qq.com
    privateKeySecretRef:
      name: letsencrypt-prod
    solvers:
      - http01:
          ingress:
            class: nginx

这里安装两个环境的证书的作用

这里分别配置了测试环境与生产环境两个 ClusterIssuer, 原因是 Let’s Encrypt 的生产环境有着非常严格的接口调用限制,最好是在测试环境测试通过后,再切换为生产环境。生产环境和测试环境的区别:https://letsencrypt.org/zh-cn/docs/staging-environment/

在Ingress中使用证书

在ingress配置后,会自动生成证书

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: kuard
  annotations:
    # 务必添加以下两个注解, 指定 ingress 类型及使用哪个 cluster-issuer
    kubernetes.io/ingress.class: "nginx"
    cert-manager.io/cluster-issuer:"letsencrypt-staging" # 这里先用测试环境的证书测通后,就可以替换成正式服证书

    # 如果你使用 issuer, 使用以下注解 
    # cert-manager.io/issuer: "letsencrypt-staging"
spec:
  tls:
  - hosts:
    - example.example.com                # TLS 域名 - 这里仅支持单域名,下面会讲通配符的域名配置
    secretName: quickstart-example-tls   # 用于存储证书的 Secret 对象名字,可以是任意名称,cert-manager会自动生成对应名称的证书名称
  rules:
  - host: example.example.com
    http:
      paths:
      - path: /
        backend:
          serviceName: kuard
          servicePort: 80

4.通过DNS配置通配符域名证书

这里样式的是阿里云DNS操作的流程,如果需要其他平台的方法,可以自行开发,或者找已开源webhook,这是官方的例子:https://github.com/jetstack/cert-manager-webhook-example

这里用的是这个包:https://github.com/pragkent/alidns-webhook

安装WebHook

不同cret-manager的安装办法不同

cret-manager 版本大于等于v0.11

安装
# Install alidns-webhook to cert-manager namespace. 
kubectl apply -f https://raw.githubusercontent.com/pragkent/alidns-webhook/master/deploy/bundle.yaml
添加阿里云RAM账号

子账号需要开通HTTPS管理权限(AliyunDNSFullAccess,管理云解析(DNS)的权限)

apiVersion: v1
kind: Secret
metadata:
  name: alidns-secret
  namespace: cert-manager
data:
  access-key: YOUR_ACCESS_KEY # 需要先base64加密
  secret-key: YOUR_SECRET_KEY # 需要先base64加密
创建ClusterIssuer

测试证书申请

apiVersion: cert-manager.io/v1alpha2
kind: ClusterIssuer
metadata:
  name: letsencrypt-staging-dns
spec:
  acme:
    email: gavin.tech@qq.com
    server: https://acme-staging-v02.api.letsencrypt.org/directory
    privateKeySecretRef:
      name: letsencrypt-staging-dns
    solvers:
    - dns01:
        webhook:
          groupName: acme.yourcompany.com # 注意这里要改动,在https://raw.githubusercontent.com/pragkent/alidns-webhook/master/deploy/bundle.yaml中也要改动对应的groupName
          solverName: alidns
          config:
            region: ""
            accessKeySecretRef:
              name: alidns-secret
              key: access-key
            secretKeySecretRef:
              name: alidns-secret
              key: secret-key

正式证书申请

apiVersion: cert-manager.io/v1alpha2
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod-dns
spec:
  acme:
    email: gavin.tech@qq.com
    server: https://acme-v02.api.letsencrypt.org/directory
    privateKeySecretRef:
      name: letsencrypt-prod-dns
    solvers:
    - dns01:
        webhook:
          groupName: acme.yourcompany.com
          solverName: alidns
          config:
            region: "" # 这里可以不填 或者填对应的区域:cn-shenzhen
            accessKeySecretRef:
              name: alidns-secret
              key: access-key
            secretKeySecretRef:
              name: alidns-secret
              key: secret-key
创建Certificate

测试证书

apiVersion: cert-manager.io/v1alpha2
kind: Certificate
metadata:
  name: ditigram-com-staging-tls
spec:
  secretName: ditigram-com-staging-tls
  commonName: ditigram.com
  dnsNames:
  - ditigram.com
  - "*.ditigram.com"
  issuerRef:
    name: letsencrypt-staging-dns
    kind: ClusterIssuer

正式证书

apiVersion: cert-manager.io/v1alpha2
kind: Certificate
metadata:
  name: ditigram-com-prod-tls
spec:
  secretName: ditigram-com-prod-tls
  commonName: ditigram.com
  dnsNames:
  - ditigram.com
  - "*.ditigram.com"
  issuerRef:
    name: letsencrypt-prod-dns
    kind: ClusterIssuer
在Ingress中应用
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: kuard
  annotations:
    # 务必添加以下两个注解, 指定 ingress 类型及使用哪个 cluster-issuer
    kubernetes.io/ingress.class: "nginx"
    cert-manager.io/cluster-issuer:"letsencrypt-staging-dns" # 这里先用测试环境的证书测通后,就可以替换成正式服证书
spec:
  tls:
  - hosts:
    - "*.ditigram.com"                     # 如果填写单域名就只会生产单域名的证书,如果是通配符请填写"*.example.com", 注意:如果填写example.com只会生成www.example.com一个域名。
    secretName: ditigram-com-staging-tls   # 测试的证书,填写刚刚创建Certificate的名称,注意更换环境时证书也要一起更换,这里并不会像单域名一样自动生成
  rules:
  - host: example.ditigram.com
    http:
      paths:
      - path: /
        backend:
          serviceName: kuard
          servicePort: 80

cret-manager 版本小于v0.11

安装
# Install alidns-webhook to cert-manager namespace. 
kubectl apply -f https://raw.githubusercontent.com/pragkent/alidns-webhook/master/deploy/legacy.yaml
添加阿里云RAM账号

子账号需要开通HTTPS管理权限(AliyunDNSFullAccess,管理云解析(DNS)的权限)

apiVersion: v1
kind: Secret
metadata:
  name: alidns-secret
  namespace: cert-manager
data:
  access-key: YOUR_ACCESS_KEY # 需要先base64加密
  secret-key: YOUR_SECRET_KEY # 需要先base64加密
创建ClusterIssuer

测试证书申请

apiVersion: certmanager.k8s.io/v1alpha1
kind: ClusterIssuer
metadata:
  name: letsencrypt-staging-dns
spec:
  acme:
    email: gavin.tech@qq.com
    server: https://acme-staging-v02.api.letsencrypt.org/directory
    privateKeySecretRef:
      name: letsencrypt-staging-dns
    solvers:
    - dns01:
        webhook:
          groupName: acme.yourcompany.com # 注意这里要改动,在https://raw.githubusercontent.com/pragkent/alidns-webhook/master/deploy/bundle.yaml中也要改动对应的groupName
          solverName: alidns
          config:
            region: ""
            accessKeySecretRef:
              name: alidns-secret
              key: access-key
            secretKeySecretRef:
              name: alidns-secret
              key: secret-key

正式证书申请

apiVersion: certmanager.k8s.io/v1alpha1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod-dns
spec:
  acme:
    email: gavin.tech@qq.com
    server: https://acme-v02.api.letsencrypt.org/directory
    privateKeySecretRef:
      name: letsencrypt-prod-dns
    solvers:
    - dns01:
        webhook:
          groupName: acme.yourcompany.com
          solverName: alidns
          config:
            region: "" # 这里可以不填 或者填对应的区域:cn-shenzhen
            accessKeySecretRef:
              name: alidns-secret
              key: access-key
            secretKeySecretRef:
              name: alidns-secret
              key: secret-key
创建Certificate

测试证书

apiVersion: certmanager.k8s.io/v1alpha1
kind: Certificate
metadata:
  name: ditigram-com-staging-tls
spec:
  secretName: ditigram-com-staging-tls
  commonName: ditigram.com
  dnsNames:
  - ditigram.com
  - "*.ditigram.com"
  issuerRef:
    name: letsencrypt-staging-dns
    kind: ClusterIssuer

正式证书

apiVersion: certmanager.k8s.io/v1alpha1
kind: Certificate
metadata:
  name: ditigram-com-prod-tls
spec:
  secretName: ditigram-com-prod-tls
  commonName: ditigram.com
  dnsNames:
  - ditigram.com
  - "*.ditigram.com"
  issuerRef:
    name: letsencrypt-prod-dns
    kind: ClusterIssuer
在Ingress中应用
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: kuard
  annotations:
    # 务必添加以下两个注解, 指定 ingress 类型及使用哪个 cluster-issuer
    kubernetes.io/ingress.class: "nginx"
    cert-manager.io/cluster-issuer:"letsencrypt-staging-dns" # 这里先用测试环境的证书测通后,就可以替换成正式服证书
spec:
  tls:
  - hosts:
    - "*.ditigram.com"                     # 如果填写单域名就只会生产单域名的证书,如果是通配符请填写"*.example.com", 注意:如果填写example.com只会生成www.example.com一个域名。
    secretName: ditigram-com-staging-tls   # 测试的证书,填写刚刚创建Certificate的名称,注意更换环境时证书也要一起更换,这里并不会像单域名一样自动生成
  rules:
  - host: example.ditigram.com
    http:
      paths:
      - path: /
        backend:
          serviceName: kuard
          servicePort: 80
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,839评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,543评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,116评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,371评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,384评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,111评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,416评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,053评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,558评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,007评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,117评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,756评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,324评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,315评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,539评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,578评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,877评论 2 345