0%

k8s证书管理【Cert-manager自动签发/更新证书】

Cert-manager 是一个云原生证书管理开源项目,用于在 Kubernetes 集群中提供 HTTPS 证书并自动续期,支持 Let’s Encrypt, HashiCorp Vault 这些免费证书的签发。在Kubernetes集群中,我们可以通过 Kubernetes Ingress 和 Let’s Encrypt 实现外部服务的自动化 HTTPS。
本文 Cert manager使用版本:v0.12.0
cert-manager
强烈建议参考官方文档:https://cert-manager.io/docs

添加helm源

注意stable/cert-manager已经过时不再维护了,转到jetstack/cert-manager

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

更新源

helm repo update

创建CRDs

kubectl apply --validate=false -f https://raw.githubusercontent.com/jetstack/cert-manager/release-0.12/deploy/manifests/00-crds.yaml
或
kubectl create -f https://raw.githubusercontent.com/jetstack/cert-manager/release-0.12/deploy/manifests/00-crds.yaml

安装

这里设置了两个默认值
–set ingressShim.defaultIssuerName=letsencrypt-prod
–set ingressShim.defaultIssuerKind=ClusterIssuer
–set ingressShim.defaultIssuerGroup=cert-manager.io
用于在后续创建Ingress时,配合annotations
kubernetes.io/tls-acme: “true”
kubernetes.io/ingress.class: “nginx”
实现自动创建证书。

helm install --name cert-manager --namespace cert-manager --version v0.12.0 --set ingressShim.defaultIssuerName=letsencrypt-prod --set ingressShim.defaultIssuerKind=ClusterIssuer --set ingressShim.defaultIssuerGroup=cert-manager.io jetstack/cert-manager

查看安装是否完成

注意事项:下面的pod需要部署在可以访问外网的机器上.

[root@k8s-master cert]# kubectl get pod -n cert-manager
NAME                                      READY   STATUS    RESTARTS   AGE
cert-manager-5cd477f7bb-fxpvf             1/1     Running   0          22m
cert-manager-cainjector-df4dc78cd-l527b   1/1     Running   0          22m
cert-manager-webhook-5f78ff89bc-ggvqt     1/1     Running   0          22m
[root@k8s-master cert]# kubectl get crd | grep cert-manager
certificaterequests.cert-manager.io         2020-01-07T01:38:32Z
certificates.cert-manager.io                2020-01-07T01:38:32Z
challenges.acme.cert-manager.io             2020-01-07T01:38:32Z
clusterissuers.cert-manager.io              2020-01-07T01:38:32Z
issuers.cert-manager.io                     2020-01-07T01:38:32Z
orders.acme.cert-manager.io                 2020-01-07T01:38:32Z

创建默认签发机构

刚刚安装时已经指定了默认签发类型是ClusterIssuer ,签发机构名称是letsencrypt-prod ,但是我们还没有创建,现在需要创建cluster-issuer.yaml

cert-manager 给我们提供了 IssuerClusterIssuer 这两种用于创建签发机构的自定义资源对象,Issuer 只能用来签发自己所在 namespace 下的证书,ClusterIssuer 可以签发任意 namespace 下的证书.

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

上述配置,更多配置参考ClusterIssuer

  • metadata.name 是我们创建的签发机构的名称,后面我们创建证书的时候会引用它
  • spec.acme.email 是你自己的邮箱,证书快过期的时候会有邮件提醒,不过 cert-manager 会利用 acme 协议自动给我们重新颁发证书来续期
  • spec.acme.server 是 acme 协议的服务端,我们这里用 Let’s Encrypt,这个地址就写死成这样就行
  • spec.acme.privateKeySecretRef 指示此签发机构的私钥将要存储到哪个 Secret 对象中,名称不重要
  • spec.acme.solvers.http01 这里指示签发机构使用 HTTP-01 的方式进行 acme 协议 (还可以用 DNS 方式,acme 协议的目的是证明这台机器和域名都是属于你的,然后才准许给你颁发证书)
kubectl create -f cluster-issuer.yaml
kubectl get clusterissuer

配置ingress

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: nginx
    kubernetes.io/tls-acme: "true"
    nginx.ingress.kubernetes.io/backend-protocol: HTTPS
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
  labels:
    app: kubernetes-dashboard
    chart: kubernetes-dashboard-1.10.0
    heritage: Tiller
    release: kubernetes-dashboard
  name: kubernetes-dashboard
  namespace: kube-system
spec:
  rules:
  - host: k8s.deri.com
    http:
      paths:
      - backend:
          serviceName: kubernetes-dashboard
          servicePort: 443
        path: /
  tls:
  - hosts:
    - k8s.deri.com
    secretName: deri-com-tls-secret-cc

由于添加了annotations kubernetes.io/tls-acme: "true",tls这个secret会自动创建。

创建完成后隔一会儿我们可以看到会多出现一个随机名称的 Ingress 对象cm-acme-http-solver-hl5sx,这个 Ingress 对象就是用来专门验证证书的:

$ kubectl get ingress -n gateway
NAME                        HOSTS                   ADDRESS   PORTS     AGE
cm-acme-http-solver-hl5sx   cs.deri.com             80        37s
kube-ui                     cs.deri.com             80, 443   41s

验证成功后,这个 Ingress 对象会自动删除.

卸载

helm delete --purge cert-manager
kubectl delete -f https://raw.githubusercontent.com/jetstack/cert-manager/release-0.12/deploy/manifests/00-crds.yaml

Check

检查服务是否正常

[root@master ~]# kubectl get certificate -n gateway 
NAME              READY   SECRET            AGE
consul-tls-test   True    consul-tls-test   19m
 
[root@master ~]# kubectl get clusterissuer
NAME               READY   AGE
letsencrypt-prod   True    157m
 
[root@master ~]# kubectl get certificate -n gateway 
NAME              READY   SECRET            AGE
consul-tls-test   True    consul-tls-test   19m
 
[root@master ~]# kubectl get Order -n gateway
NAME                                    STATE   AGE
consul-tls-test-3546184973-1845474898   valid   20m
 
[root@master ~]# kubectl get  CertificateRequest -n gateway
NAME                         READY   AGE
consul-tls-test-3546184973   True    27m
 
[root@master ~]# kubectl get secret -ngateway
NAME                      TYPE                                  DATA   AGE
consul-tls-test           kubernetes.io/tls                     3      29m

用到的镜像

quay.io/jetstack/cert-manager-cainjector:v0.12.0
quay.io/jetstack/cert-manager-webhook:v0.12.0
quay.io/jetstack/cert-manager-controller:v0.12.0
#这里由于上面配置solve是acme所以用到这个镜像,如果你配置别的,可能不一致
quay.io/jetstack/cert-manager-acmesolver:v0.12.0