kubernetes使用cert-manager自动签发letsencrypt证书

kubernetes使用cert-manager自动签发letsencrypt证书

九月 16, 2021

参考内容

部署 cert-manager

  1. 部署 crds

    1
    kubectl apply -f https://github.com/jetstack/cert-manager/releases/download/v1.5.3/cert-manager.crds.yaml
  2. 创建 Namespace

    1
    kubectl create namespace cert-manager
  3. 部署 cert-manager

    1
    kubectl apply -f https://github.com/jetstack/cert-manager/releases/download/v1.5.3/cert-manager.yaml
  4. 创建私钥

生成签名密钥对

1
2
3
4
5
# Generate a CA private key
$ openssl genrsa -out ca.key 2048

# Create a self signed Certificate, valid for 10yrs with the 'signing' option set
$ openssl req -x509 -new -nodes -key ca.key -subj "/CN=${COMMON_NAME}" -days 3650 -reqexts v3_req -extensions v3_ca -out ca.crt

将签名密钥对保存为Secret

1
2
3
4
kubectl create secret tls ca-key-pair \
--cert=ca.crt \
--key=ca.key \
--namespace=default
  1. 创建ClusterIssuer
    我们需要先创建一个签发机构,cert-manager 给我们提供了 Issuer 和ClusterIssuer 这两种用于创建签发机构的自定义资源对象,Issuer 只能用来签发自己所在 namespace 下的证书,ClusterIssuer 可以签发任意 namespace 下的证书,这里以 ClusterIssuer 为例
    1
    kubectl apply -f cluster-issuer.yaml
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    cluster-issuer.yaml
    piVersion: v1
    kind: ClusterIssuer
    metadata:
    name: letsencrypt-prod #这里是issuer的名称,后面要使用
    spec:
    acme:
    # 邮箱,证书过期前会发邮件到这个邮箱
    email: admin@aispring.cloud
    server: https://acme-v02.api.letsencrypt.org/directory
    privateKeySecretRef:
    name: issuer-key
    solvers:
    - http01:
    ingress:
    class: nginx

    签发证书

    Let’s Encrypt常见生成证书的方式是cerbot,可以使用http 01和dns 01两种方式认证方式,http 01不支持生成通配符证书,这里需要生成通配符域名,所以才用dns 01认证方式。

若dns服务商是阿里云,官方暂不支持,有开源的AliDNS-Webhook供我们使用。

  1. 部署 AliDNS-Webhook

    1
    2
    kubectl apply -f https://raw.githubusercontent.com/pragkent/alidns-webhook/master/deploy/bundle.yaml

  2. 创建阿里云访问凭据

    1
    2
    3
    4
    5
    6
    7
    8
    apiVersion: v1
    kind: Secret
    metadata:
    name: alidns-secret
    namespace: cert-manager
    data:
    access-key: YOUR_ACCESS_KEY
    secret-key: YOUR_SECRET_KEY
  3. 创建 ClusterIssuer 发行证书

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    apiVersion: cert-manager.io/v1alpha2
    kind: ClusterIssuer
    metadata:
    name: letsencrypt-staging
    spec:
    acme:
    # Change to your letsencrypt email
    email: certmaster@example.com
    server: https://acme-staging-v02.api.letsencrypt.org/directory
    privateKeySecretRef:
    name: letsencrypt-staging-account-key
    solvers:
    - dns01:
    webhook:
    groupName: acme.yourcompany.com
    solverName: alidns
    config:
    region: ""
    accessKeySecretRef:
    name: alidns-secret
    key: access-key
    secretKeySecretRef:
    name: alidns-secret
    key: secret-key
  4. 签发证书

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    apiVersion: cert-manager.io/v1alpha2
    kind: Certificate
    metadata:
    name: example-tls
    spec:
    secretName: example-com-tls
    commonName: example.com
    dnsNames:
    - example.com
    - "*.example.com"
    issuerRef:
    name: letsencrypt-staging
    kind: ClusterIssuer
  5. 测试证书

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
    annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod #需要使用这个标记,letsencrypt-prod是上面issuer的名称
    name: nginx
    namespace: default
    spec:
    rules:
    - host: dev.arfront.cn
    http:
    paths:
    - backend:
    serviceName: nginx
    servicePort: 80
    pathType: ImplementationSpecific
    tls:
    - hosts:
    - dev.arfront.cn
    secretName: dev.arfront.cn #证书的域名