Skip to content

搭载blog之配置https证书(二)

要求:配置阿里云证书,服务器https可自签,分为4步 一. 在Kubernetes上安装cert-manager 二. 安装alidns的webhook 三. 配置ClusterIssuer 四. 配置Ingress

一、安装cert-manager
  • 创建命名空间

    $ kubectl create namespace cert-manager namespace/cert-manager created

    $ kubectl label namespace cert-manager certmanager.k8s.io/disable-validation=true 如果是1.12或者以下的k8s集群,需要添加--validate=false

  • 安装1.10.1版本的cert-manager

    $kubectl apply -f https://cdn-blog.jamesyt.com/k8s/cert-manager.yml --validate=false$ kubectl get po -n cert-manager

    以下表示安装成功 root@JamesWuService:~/cert# kubectl get po -n cert-manager NAME READY STATUS RESTARTS AGE cert-manager-74d949c895-nkdw4 1/1 Running 0 118s cert-manager-cainjector-d9bc5979d-nsc9c 1/1 Running 0 118s cert-manager-webhook-84b7ddd796-fmw74 1/1 Running 0 118s

使用证书,来验证是否可行 创建 test-cert-resource.yaml

apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
  name: test-selfsigned
  namespace: cert-manager
spec:
  selfSigned: {}
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: selfsigned-cert
  namespace: cert-manager
spec:
  commonName: example.com
  secretName: selfsigned-cert-tls
  issuerRef:
    name: test-selfsigned

执行

$ kaf test-cert-resource.yaml
$ kubectl describe certificate -n cert-manager

Events:
  Type    Reason     Age   From                                       Message 
  ----    ------     ----  ----                                       ------- 
  Normal  Issuing    60s   cert-manager-certificates-trigger          Issuing certificate as Secret does not exist 
  Normal  Generated  60s   cert-manager-certificates-key-manager      Stored new private key in temporary Secret resource "selfsigned-cert-zgllx"  
  Normal  Requested  60s   cert-manager-certificates-request-manager  Created new CertificateRequest resource "selfsigned-cert-8jfjq" 
  Normal  Issuing    60s   cert-manager-certificates-issuing          The certificate has been successfully issued 

看到最后一行 successfully issued 就表明成功,但是会发现没有secret,我们一会创建,先杀掉测试

$ kubectl delete -f test-cert-resource.yaml
二、安装alidns的webhook

在这里已经上传到七牛云,直接执行

$ kaf https://cdn-blog.jamesyt.com/k8s/bundle.yaml

$ 查看结果
$ kubectl get po -n cert-manager

NAME                                      READY   STATUS    RESTARTS   AGE
cert-manager-74d949c895-nkdw4             1/1     Running   0          62m
cert-manager-cainjector-d9bc5979d-nsc9c   1/1     Running   0          62m
cert-manager-webhook-84b7ddd796-fmw74     1/1     Running   0          62m
alidns-webhook-77cbdf86d5-nsxp2           1/1     Running   0          13m
三、配置ClusterIssuer
  • 创建alidns-secret 创建alidns-secret.yaml

    apiVersion: v1 kind: Secret metadata: name: alidns-secret namespace: cert-manager stringData: access-key: xxxx #阿里云dns权限ak secret-key: xxxxxx #阿里云dns权限sk

执行

$ kaf alidns-secret.yaml 
$ kubectl get secret -n cert-manager
NAME                         TYPE                DATA   AGE
cert-manager-webhook-ca      Opaque              3      79m
selfsigned-cert-tls          kubernetes.io/tls   3      55m
alidns-webhook-ca            kubernetes.io/tls   3      30m
alidns-webhook-webhook-tls   kubernetes.io/tls   3      30m
letsencrypt-account-key      Opaque              1      8m20s
alidns-secret                Opaque              2      21s
  • 创建ClusterIssuer cert-manager有两种issuer,Issuer和ClusterIssuer,区别就是Role和ClusterRole的区别 创建clusterissuer.yaml

    apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: letsencrypt-pro spec: acme: # Change to your letsencrypt email email: xxxx@qq.com #申请者邮箱地址 server: https://acme-v02.api.letsencrypt.org/directory privateKeySecretRef: name: letsencrypt-account-key solvers: - dns01: webhook: groupName: acme.xxxx.com #须和bundle.yaml文件中定义的groupname 一致 solverName: alidns config: region: "" accessKeySecretRef: name: alidns-secret #这里就是上面对应的secret名字 key: access-key secretKeySecretRef: name: alidns-secret key: secret-key

执行

$ kaf clusterissuer.yaml
$ kubectl get clusterissuer
NAME          READY   AGE
letsencrypt-pro   True    22s
四、配置Ingress

修改在上篇文章中的ingress

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-nginx
  namespace: ns-test
  annotations:
    kubernetes.io/ingress.class: traefik
    cert-manager.io/cluster-issuer: letsencrypt-pro #这里为上面创建的name
    ingress.kubernetes.io/ssl-redirect: "true"
    kubernetes.io/tls-acme: "true"
spec:
  tls:
    - hosts:
        - jamesyt.com
      secretName: nginx-com
    - hosts:
        - www.jamesyt.com
      secretName: nginx-www-com
  rules:
  - host: "jamesyt.com"
    http:
      paths:
      - pathType: Prefix
        path: "/"
        backend:
          service:
            name: nginx-service #和对应的service 名字必须对应
            port:
              number: 80
  - host: "www.jamesyt.com"
    http:
      paths:
      - pathType: Prefix
        path: "/"
        backend:
          service:
            name: nginx-service #和对应的service 名字必须对应
            port:
              number: 80

这里面加入了cluster-issuer的注解,cert-manager会自动根据域名去创建certificate,order,challenge等

$ kaf 
$ kubectl get ing -A
NAMESPACE   NAME       CLASS     HOSTS                         ADDRESS         PORTS     AGE
ns-test     my-nginx   traefik   jamesyt.com,www.jamesyt.com   172.31.251.79   80, 443   34h

$ kubectl get certificate -A
NAMESPACE      NAME                         READY   SECRET                       AGE
cert-manager   alidns-webhook-ca            True    alidns-webhook-ca            43m
cert-manager   alidns-webhook-webhook-tls   True    alidns-webhook-webhook-tls   43m
ns-test        nginx-com                    False   nginx-com                    5m42s
ns-test        nginx-www-com                False   nginx-www-com                5m42s

可以看到 READY 为false,z这个时候,查看challenge状态,dns的验证需要等一会,为了让txt记录生效
$ kubectl get challenge -A
NAME                            STATE     DOMAIN         AGE
**-tle-23556563-0                pending   ***.com   5m

如果,查不到challenge 就说明可以了

如果出现问题,可进一步查看
$ kubectl describe challenge ***-tls-23556563-0 ,成功后会有如下的提示,challenge在成功验证后会被自动删除
Normal   Presented     28s      cert-manager  Presented challenge using dns-01 challenge mechani

访问 https://xxx.com 恭喜你成功了