What is HTTPS?

Hypertext Transfer protocol HTTP is used to transmit information between Web browsers and Web servers. HTTP sends content in plain text without any data encryption. If an attacker intercepts packets transmitted between Web browsers and Web servers, he can directly understand the information. The HTTP protocol is not suitable for transmitting sensitive information, such as payment information such as credit card numbers and passwords.

To overcome this shortcoming of HTTP, another protocol is needed: secure Sockets Layer hypertext Transfer protocol HTTPS. To secure data transmission, HTTPS adds SSL to HTTP. SSL relies on certificates to verify the identity of the server and encrypts the communication between the browser and the server. HTTP and HTTPS use completely different connections and use different ports, the former 80 and the latter 443.

What is certManager?

Cert-manager is an open source project for cloud native certificate management. It is used to provide HTTPS certificates in Kubernetes cluster and automatically renew them. It supports the issuance of free certificates such as Let’s Encrypt and HashiCorp Vault. In a Kubernetes cluster, we can automate HTTPS for external services with Kubernetes Ingress and Let’s Encrypt.

To use HTTPS in Kubernetes cluster, you need a certificate manager, a certificate automatic issuing service, mainly through the Ingress to publish HTTPS services, so you need to configure the Ingress Controller, enable HTTPS and its routing.

How do I install certManager?

Environment depends on

  • The cluster must already have an Ingress Controller installed
  • Configure hosts on the external client, and the IP address points to the address exposed by the Ingress Controller. (If the IP address is a public IP address and the domain name has been resolved, this configuration is not required.)

Start the installation

  • Install the cert – manager

    • Liverpoolfc.tv: cert – manager. IO/docs/instal…
    • Installation:Kubectl apply -f https://github.com/jetstack/cert-manager/releases/download/v1.6.1/cert-manager.yaml
  • Viewing installation Results

    • kubectl get pods -n cert-manager

      [root@master cert-manager-161]# kubectl get pods -n cert-manager 
      NAME                                      READY   STATUS    RESTARTS   AGE
      cert-manager-55658cdf68-9wbwh             1/1     Running   0          37s
      cert-manager-cainjector-967788869-ddmlv   1/1     Running   0          37s
      cert-manager-webhook-6668fbb57d-gqr7t     1/1     Running   0          37s
      Copy the code

Generating a CA Certificate

  • Install CFSSL

    • Download the latest executable file

      [root @ master SSL] # wget HTTP: / / https://github.com/cloudflare/cfssl/releases/download/v1.6.1/cfssl_1.6.1_linux_amd64 [root @ master SSL] # wget HTTP: / / https://github.com/cloudflare/cfssl/releases/download/v1.6.1/cfssljson_1.6.1_linux_amd64 [root @ master SSL] # wget HTTP: / / https://github.com/cloudflare/cfssl/releases/download/v1.6.1/cfssl-certinfo_1.6.1_linux_amd64 [root@master SSL]# mv cfssl_1.6.1_linux_amd64 CFSSL [root@master SSL]# mv cfssl-certInfo_1.6.1_linux_amd64 certinfo [root@master SSL]# mv cfssljson_1.6.1_linux_amd64 cfssljson [root@master SSL]# chmod +x certinfo [root@master SSL]# chmod +x cfssl [root@master ssl]# chmod +x cfssljsonCopy the code
    • Copied to/usr/local/bin

      [root@master ssl]# mv cfssl /usr/local/sbin/
      [root@master ssl]# mv certinfo /usr/local/sbin/
      [root@master ssl]# mv cfssljson /usr/local/sbin/
      Copy the code
  • Generating a CA Certificate

    • Configure the certificate request file
    cfssl print-defaults csr > csr.json
    Copy the code
    {
        "CN": "kdemo",
        "key": {
            "algo": "rsa",
            "size": 2048
        },
        "names": [
            {
                "C": "CN",
                "ST": "ShenZhen",
                "L": "ShenZhen",
                "O": "k8s",
                "OU": "systemGroup"
            }
        ],
        "ca": {
            "expiry": "87600h"
        }
    }
    Copy the code

    Field description: default: indicates the default policy. The validity period of the certificate is one year (8760h). Signing: indicates that the certificate can be used to sign other certificates. In the generated ca.pem certificate, ca =TRUE server auth: indicates that the client can use the CA to authenticate the certificate provided by the server. Expiry: Indicates that the SERVER can use the CA to verify the certificate provided by the client

  • cfssl gencert -initca csr.json | cfssljson -bare ca

    [root@master ssl]# cfssl gencert -initca csr.json  | cfssljson -bare ca
    2021/12/28 17:25:55 [INFO] generating a new CA key and certificate from CSR
    2021/12/28 17:25:55 [INFO] generate received request
    2021/12/28 17:25:55 [INFO] received CSR
    2021/12/28 17:25:55 [INFO] generating key: rsa-2048
    2021/12/28 17:25:55 [INFO] encoded CSR
    2021/12/28 17:25:55 [INFO] signed certificate with serial number 151317294092143127619036180787140414839328861547
    [root@master ssl]# ls
    ca.csr  ca-key.pem  ca.pem  csr.json
    Copy the code

Use certManager to manage certificates

Create using a local certificate

  • Save the signing key pair as Secret

    • kubectl create secret tls ca-key-pair --cert=ca.crt --key=ca.key --namespace=kdemo

      [root@master ssl]# kubectl create secret tls ca-key-pair --cert=ca.pem --key=ca-key.pem --namespace=kdemo
      secret/ca-key-pair created
      [root@master ssl]# kubectl get se
      secrets                             serviceaccounts                     serviceentries.networking.istio.io  services
      [root@master ssl]# kubectl get secrets -n kdemo
      NAME                  TYPE                                  DATA   AGE
      ca-key-pair           kubernetes.io/tls                     2      16s
      default-token-n7xwn   kubernetes.io/service-account-token   3      90s
      Copy the code
  • Create an issuing authority

    We need to create an issuing authority first. Cert-manager provides two customized resource objects, Issuer and ClusterIssuer, which are used to create issuing authorities. Issuer can only be used to issue certificates of its own namespace. ClusterIssuer Can issue certificates of any namespace. The following uses Issuer as an example to create an issuing authority

    • vim kdemo-issuer.yaml
    apiVersion: cert-manager.io/v1
    kind: Issuer
    metadata:
      name: kdemo-issuer
      namespace: kdemo
    spec:
      ca:
        secretName: ca-key-pair
    Copy the code
    • kubectl apply -f kdemo-issuer.yaml
    [root@master ssl]# kubectl apply -f kdemo-issuer.yaml 
    issuer.cert-manager.io/kdemo-issuer created
    [root@master ssl]# kubectl get issuers.cert-manager.io -n kdemo 
    NAME           READY   AGE
    kdemo-issuer   True    25s
    Copy the code
  • Create a free Certificate Certificate

    • vim kdemo-certificate.yaml
    apiVersion: cert-manager.io/v1
    kind: Certificate
    metadata:
      name: kdemo-tls
      namespace: kdemo
    spec:
      secretName: kdemo-tls
      issuerRef:
        name: kdemo-issuer
        kind: Issuer
      commonName: kdemo.com
      dnsNames:
      - kdemo.com
    Copy the code
    • kubectl apply -f kdemo-certificate.yaml
    [root@master ssl]# kubectl apply -f kdemo-certificate.yaml 
    certificate.cert-manager.io/kdemo-tls created
    [root@master ssl]# kubectl get certificate -n kdemo 
    NAME        READY   SECRET      AGE
    kdemo-tls   True    kdemo-tls   21s
    Copy the code
    • Kubectl get secrets -n kdemo

      [root@master ssl]# kubectl get secrets -n kdemo 
      NAME                  TYPE                                  DATA   AGE
      ca-key-pair           kubernetes.io/tls                     2      61m
      default-token-n7xwn   kubernetes.io/service-account-token   3      62m
      kdemo-tls             kubernetes.io/tls                     3      63s
      Copy the code
    • Kubectl describe -n kdemo secrets kdemo- TLS

      [root@master ssl]# kubectl describe -n kdemo secrets kdemo-tls 
      Name:         kdemo-tls
      Namespace:    kdemo
      Labels:       <none>
      Annotations:  cert-manager.io/alt-names: kdemo.com
                    cert-manager.io/certificate-name: kdemo-tls
                    cert-manager.io/common-name: kdemo.com
                    cert-manager.io/ip-sans: 
                    cert-manager.io/issuer-group: 
                    cert-manager.io/issuer-kind: Issuer
                    cert-manager.io/issuer-name: kdemo-issuer
                    cert-manager.io/uri-sans: 
      
      Type:  kubernetes.io/tls
      
      Data
      ====
      ca.crt:   1314 bytes
      tls.crt:  1224 bytes
      tls.key:  1679 bytes
      Copy the code
  • Create a service to test

    • vim kdemo-nginx.yaml

      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: kdemo
        namespace: kdemo
        labels:
          app: kdemo
      spec:
        replicas: 1
        template:
          metadata:
            name: kdemo
            labels:
              app: kdemo
          spec:
            containers:
              - name: nginx
                image: Nginx: 1.20.2 - alpine
                imagePullPolicy: IfNotPresent
            restartPolicy: Always
        selector:
          matchLabels:
            app: kdemo
      
      ---
      apiVersion: v1
      kind: Service
      metadata:
        name: kdemo
        namespace: kdemo
      spec:
        selector:
          app: kdemo
        ports:
          - port: 80
        type: ClusterIP
      
      ---
      apiVersion: networking.k8s.io/v1
      kind: Ingress
      metadata:
        name: kdemo
        namespace: kdemo
      spec:
        ingressClassName: nginx
        rules:
          - host: kdemo.com
            http:
              paths:
                - backend:
                    service:
                      name: kdemo
                      port:
                        number: 80
                  path: /
                  pathType: Prefix
        tls:
          - hosts:
              - kdemo.com
            secretName: kdemo-tls
      status:
        loadBalancer: {}
      Copy the code
    • kubectl apply -f kdemo-nginx.yaml

      [root@master ssl]# kubectl apply -f kdemo-nginx.yaml 
      deployment.apps/kdemo created
      service/kdemo created
      ingress.networking.k8s.io/kdemo created
      Copy the code
  • Access to the test

Use Aliyun-dns-webhook to automatically renew HTTPS certificate for Aliyun domain name

Install the aliyun-dnS-webhook plug-in

  • Installation using helm

    helm repo add cert-manager-alidns-webhook https://gitee.com/daiminr/cert-manager-alidns-webhook
    helm repo update
    helm install cert-manager-alidns-webhook/alidns-webhook
    Copy the code
  • Install the results

    [root@master alidns-webhook]# helm install alidns-webhook cert-manager-alidns-webhook/alidns-webhook -n cert-manager
    NAME: alidns-webhook
    LAST DEPLOYED: Wed Dec  8 16:11:08 2021
    NAMESPACE: cert-manager
    STATUS: deployed
    REVISION: 1
    TEST SUITE: None
    Copy the code
  • Check the installation: kubectl get Pods, svC-n cert-Manager

    [root@master AtarisMio-alidns]# kubectl get pods,svc -n cert-manager NAME READY STATUS RESTARTS AGE pod/alidns-webhook-6d4d766fd7-chd89 1/1 Running 0 4m20s pod/cert-manager-55658cdf68-9wbwh 1/1 Running 2 (14h ago) 2d pod/cert-manager-cainjector-967788869-ddmlv 1/1 Running 2 (14h ago) 2d pod/cert-manager-webhook-6668fbb57d-gqr7t 1/1 Running 0 2D NAME TYPE cluster-ip external-ip PORT(S) AGE service/alidns-webhook ClusterIP 10.1.169.162 < None > 443/TCP 4M20S service/cert-manager ClusterIP 10.1.17.75 < None > 9402/TCP 2D service/cert-manager-webhook ClusterIP 10.1.167.181 <none> 443/TCP 2dCopy the code
  • Add the alidnsSecret configuration: vim alidnssecret.yaml

    apiVersion: v1
    kind: Secret
    metadata:
      name: alidns-secret
      namespace: cert-manager
    data:
      access-key: base64(accessKey)
      secret-key: base64(secretKey)
    type: Opaque
    Copy the code

The issuer of ClusterIssuer is added

  • GroupName: kubectl edit pod -n cert-manager alidns-webhook-6d4d766fd7-chd89 groupName: kubectl edit pod -n cert-manager alidns-webhook-6d4d766fd7-chd89

  • vim clusterIssuer.yaml

    Kind: ClusterIssuer Metadata: name: letsencrypt-Alidns spec: acme: # Modify your email address: [email protected] Server: https://acme-v02.api.letsencrypt.org/directory privateKeySecretRef: name: letsencrypt-alidns-key solvers: - dns01: SolverName: alidns config: region: "" accessKeyIdSecretRef: name: alidns-secret key: access-key accessSecretSecretRef: name: alidns-secret key: secret-keyCopy the code
  • Run kubectl apply -f clusterIssuer.yaml

    [root@master aliyun-dns-webhook]# kubectl apply -f clusterIssuer.yaml 
    clusterissuer.cert-manager.io/letsencrypt-alidns created
    [root@master aliyun-dns-webhook]#
    Copy the code

Add a certificate

  • vim certificate-test.yaml

    kind: Certificate
    metadata:
      name: test-xxxx-tls
      namespace: test
    spec:
      secretName: test-xxxx-cn-tls
      commonName: test.xxxx.cn
      dnsNames:
      - test.xxxx.cn
      - "*.test.xxxx.cn"
      issuerRef:
        name: letsencrypt-alidns
        kind: ClusterIssuer
    Copy the code
  • Kubectl apply-f certificate-test.yaml

    [root@master aliyun-dns-webhook]# kubectl apply -f certificate-test.yaml 
    certificate.cert-manager.io/test-xxxx-tls created
    [root@master aliyun-dns-webhook]# 
    Copy the code
  • Check aliyun DNS resolution records

  • Check certificate information:

    [root@master AtarisMio-alidns]# kubectl get certificate -n test 
    NAME             READY   SECRET              AGE
    test-xxxx-tls   True    test-xxxx-cn-tls   10m
    [root@master AtarisMio-alidns]#
    Copy the code

Test the waters by configuring a domain name

  • Domain name: kuboard. XXXX. Cn

  • Namespace: kuboard

  • Add the certificate – kuboard. Yaml

    • vim certificate-kuboard.yaml

      apiVersion: cert-manager.io/v1
      kind: Certificate
      metadata:
        name: kuboard-xxxx-tls
        namespace: kuboard
      spec:
        secretName: kuboard-xxxx-cn-tls
        commonName: kuboard.xxxx.cn
        dnsNames:
        - kuboard.xxxx.cn
        issuerRef:
          name: letsencrypt-alidns
          kind: ClusterIssuer
      Copy the code
    • Run kubectl apply -f certificate-kuboard.yaml

    • Kubectl get certificate -n kuboard

      [root@master AtarisMio-alidns]# kubectl get certificate -n kuboard 
      NAME                READY   SECRET                 AGE
      kuboard-xxxx-tls   True    kuboard-xxxx-cn-tls   2d20h
      Copy the code
    • New kuboard – ingress. Yaml

      apiVersion: networking.k8s.io/v1
      kind: Ingress
      metadata:
        name: kuboard
        namespace: kuboard
      spec:
        ingressClassName: nginx
        tls: 
        - hosts:
          - kuboard.xxxx.cn
          secretName: kuboard-xxxx-tls
        rules:
        - host: kuboard.xxxx.cn
          http:
            paths:
            - backend:
                service:
                  name: kuboard-v3
                  port:
                    number: 80
              path: /
              pathType: Prefix
      status:
        loadBalancer: {}
      Copy the code
  • access