NginxIngress Letsencrypt

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

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

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

安装cert-manager

kubectl create namespace cattle-system
kubectl apply --validate=false -f https://github.com/jetstack/cert-manager/releases/download/v1.0.4/cert-manager.crds.yaml
kubectl create namespace cert-manager
helm repo add jetstack https://charts.jetstack.io
helm repo update
helm install \
  cert-manager jetstack/cert-manager \
  --namespace cert-manager \
  --version v1.0.4

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$ 
Send a Message