CA证书和Ingress (3) cert-manager 和 letsencrypt

Submitted by Lizhe on Mon, 04/22/2019 - 10:45

这玩意最大的好处就是 renew 是自动的

cert-manager is a Kubernetes addon to automate the management and issuance of TLS certificates from various issuing sources.

It will ensure certificates are valid and up to date periodically, and attempt to renew certificates at an appropriate time before expiry.

环境描述

这里我使用的是 Kubernetes + 我自己的一个独立域名, 运行在 aws 环境上 , ec2 主机的 ip 是 54.95.179.97

除了 cert-manager 安装在 system 命名空间下之外, 所有的资源 ( deployment, service, ingress, issuer, cert ) 全部都安装在 study 命名空间下

需要注意的是命名空间需要提前创建

20190422043043

 

 

 

安装cert-manager

 

helm install stable/cert-manager \
--namespace kube-system \
--set ingressShim.defaultIssuerName=letsencrypt-prod \
--set ingressShim.defaultIssuerKind=ClusterIssuer \
--version v0.5.2

也可以使用

 

helm install stable/cert-manager \
--name cert-manager \
--namespace kube-system \
--version v0.5.2
 

 

20190422104842

 

cert-manager 提供了 Issuer 和 ClusterIssuer 这两种用于创建签发机构的自定义资源对象,

Issuer 只能用来签发自己所在 namespace 下的证书

ClusterIssuer 可以签发任意 namespace 下的证书

 

创建 issuer

 

lizhedeMacBook-Pro:lz_study lizhe$ cat issuer.yaml 

apiVersion: certmanager.k8s.io/v1alpha1

kind: ClusterIssuer

metadata:

  name: letsencrypt-prod

  namespace: study

spec:

  acme:

    server: https://acme-v02.api.letsencrypt.org/directory

    email: marshal_li_b@163.com

    privateKeySecretRef:

      name: letsencrypt-prod

    http01: {}

lizhedeMacBook-Pro:lz_study lizhe$ 

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

 

创建证书

需要注意的是命名空间需要提前创建

 

lizhedeMacBook-Pro:lz_study lizhe$ cat cert.yaml 

apiVersion: certmanager.k8s.io/v1alpha1

kind: Certificate

metadata:

  name: study-pactera-deg-com

  namespace: study

spec:

  secretName: best-tls

  issuerRef:

    name: letsencrypt-prod

    kind: ClusterIssuer

  dnsNames:

  - www.bestofgit.com

  acme:

    config:

    - http01:

        ingressClass: nginx

      domains:

      - www.bestofgit.com

 

lizhedeMacBook-Pro:lz_study lizhe$ 

 

  • spec.secretName 指示证书最终存到哪个 Secret 中
  • spec.issuerRef.kind 值为 ClusterIssuer 说明签发机构不在本 namespace 下,而是在全局
  • spec.issuerRef.name 我们创建的签发机构的名称 (ClusterIssuer.metadata.name)
  • spec.dnsNames 指示该证书的可以用于哪些域名
  • spec.acme.config.http01.ingressClass 使用 HTTP-01 方式校验该域名和机器时,cert-manager 会尝试创建Ingress 对象来实现该校验,如果指定该值,会给创建的 Ingress 加上 kubernetes.io/ingress.class 这个 annotation,如果我们的 Ingress Controller 是 Nginx Ingress Controller,指定这个字段可以让创建的 Ingress 被 Nginx Ingress Controller 处理。
  • spec.acme.config.http01.domains 指示该证书的可以用于哪些域名

 

然后安装nginx

 

deployment

 

lizhedeMacBook-Pro:lz_study lizhe$ cat nginx.yaml 

apiVersion: apps/v1beta1

kind: Deployment

metadata:

  name: nginx-deployment

  namespace: study

spec:

  replicas: 2 # tells deployment to run 2 pods matching the template

  template: # create pods using pod definition in this template

    metadata:

      # unlike pod-nginx.yaml, the name is not included in the meta data as a unique name is

      # generated from the deployment name

      labels:

        app: nginx

    spec:

      containers:

      - name: nginx

        image: nginx:1.7.9

        ports:

        - containerPort: 80

 

lizhedeMacBook-Pro:lz_study lizhe$ 

svc.yaml

 

lizhedeMacBook-Pro:lz_study lizhe$ cat svc.yaml 

apiVersion: v1

kind: Service

metadata: 

  name: nginx-service

  namespace: study

spec:

  type: ClusterIP

  ports:

    - port: 80

  selector: 

      app: nginx

lizhedeMacBook-Pro:lz_study lizhe$ 

ingress.yaml

 

lizhedeMacBook-Pro:lz_study lizhe$ cat ingress.yaml 

apiVersion: extensions/v1beta1

kind: Ingress

metadata:

  name: hello-nginx-ingress

  namespace: study

  annotations:

    kubernetes.io/ingress.class: "nginx"

    certmanager.k8s.io/issuer: "letsencrypt-prod"

    certmanager.k8s.io/acme-challenge-type: http01

spec:

  rules:

  - host: www.bestofgit.com

    http:

      paths:

      - backend:

          serviceName: nginx-service

          servicePort: 80

  tls:

  - hosts:

    - www.bestofgit.com

    secretName: best-tls

lizhedeMacBook-Pro:lz_study lizhe$ 

 

20190422045855

20190422042710