暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

配置使用cert-manager

ItTalk 2020-03-28
3470

概述

一直对cert-manager项目很感兴趣,今天着重研究了一下他的架构,并做了个尝试,这里做个记录。

cert-manager简介

它支持从Let’s Encrypt,HashiCorp Vault,Venafi等颁发证书。架构如下:

它由以下组件组成:

Issuer

Issuer和ClusterIssuers是Kubernetes资源,它们代表证书颁发机构(CA),能够通过执行证书签名请求来生成签名证书。Issuers只能在当前命名空间下使用,如果要创建可以在多个名称空间中使用的单个Issuer,则应考虑创建ClusterIssuer资源。它支持的证书颁发机构如下:https://cert-manager.io/docs/configuration

Certificate

“Certificate”定义了所需的x509证书,该证书将被更新并保持最新状态。证书是一个命名空间资源,它引用Issuer或ClusterIssuer,它们确定将接受证书请求的内容。CertificateRequestCertificateRequest是cert-manager中的命名空间资源,用于从颁发者请求x509证书。该资源包含PEM编码的证书请求的base64编码的字符串,该字符串被发送到引用的Issuer。成功发行后,将根据证书签名请求返回已签名的证书。证书请求通常由控制器或其他系统使用和管理,除非特别需要,否则不应由我们自己使用。

ACME Orders and Challenges

cert-manager支持使用ACME颁发者向ACME服务器(包括Let’s Encrypt)请求证书。大多数计算机通常在公共Internet上信任这些证书。要成功请求证书,证书管理者必须解决ACME Challenges,这些Challenges必须完成才能证明客户端拥有所请求的DNS地址。为了完成 Challenges,cert-manager引入了两种CustomResource类型,Order与Challenge。ACME使用Orders资源来管理签名的TLS证书的ACME“Order”的生命周期。Order代表单个证书申请,一旦创建了引用ACME颁发者的新CertificateRequest资源,该订单便会自动创建。创建证书资源,更改其规范或需要更新证书资源后,cert-manager会自动创建CertificateRequest资源。作为最终用户,您将不需要手动创建Order资源。创建后,便无法更改Order。而是,必须创建一个新的Order资源。Order资源为该“订单”封装了多个ACME Challenges,因此将管理一个或多个Challenges资源。ACME Issuer使用Challenge资源来管理必须完成的ACME Challenge的生命周期,以完成单个DNS名称/标识符的“授权”。创建Order资源后,订单控制器将为ACME服务器授权的每个DNS名称创建Challenge资源。作为最终用户,您将无需手动创建Challenge资源。创建Challenge后,便无法更改。相反,必须创建一个新的Challenge资源。

Webhook

cert-manager利用Webhook服务器扩展Kubernetes API服务器,以提供对cert-manager资源的动态准入控制。Webhook组件被部署为另一个Pod,与主要的证书管理器控制器和CA注入器组件一起运行。为了使API服务器与webhook组件进行通信,webhook需要配置为apiserver信任的TLS证书。为了使API服务器与webhook组件进行通信,webhook需要配置为apiserver信任的TLS证书。这是由cainjector创建的,并由以下两个secret实现:secret cert-manager-webhook-ca:一种自签名的根CA证书,用于签署Webhook容器的证书。secret /cert-manager-webhook-tls:由上面的根CA颁发的TLS证书,由Webhook提供。

CA Injector

证书管理器CA注入程序控制器负责将CA捆绑软件注入到Webhook的ValidatingWebhookConfiguration和MutatingWebhookConfiguration资源中,以允许Kubernetes API服务器“信任” Webhook API服务器。

配置使用(v0.12.0)

1.下载并配置crd资源

    wget -c https://raw.githubusercontent.com/jetstack/cert-manager/release-0.12/deploy/manifests/00-crds.yaml
    kubectl apply -f 00-crds.yaml

    2.下载,这里选择v0.12.0,并解压

      helm fetch --untar jetstack/cert-manager --version v0.12.0

      3.编辑values.yaml

        #修改安装的node结点
        #94
        nodeSelector:
        node: sre

        #160
        nodeSelector:
        node: sre
        #207
        nodeSelector:
        node: sre

        4.通过helm安装cert-manager

          kubectl create ns cert-manager
          helm install cert-manager -n cert-manager -f values.yaml ./

          5.验证cert-manager是否安装正确

            #创建如下测试资源test-resources.yaml
            apiVersion: v1
            kind: Namespace
            metadata:
            name: cert-manager-test
            ---
            apiVersion: cert-manager.io/v1alpha2
            kind: Issuer
            metadata:
            name: test-selfsigned
            namespace: cert-manager-test
            spec:
            selfSigned: {}
            ---
            apiVersion: cert-manager.io/v1alpha2
            kind: Certificate
            metadata:
            name: selfsigned-cert
            namespace: cert-manager-test
            spec:
            commonName: example.com
            secretName: selfsigned-cert-tls
            issuerRef:
            name: test-selfsigned
            # 执行以下命令
            kubectl apply -f test-resources.yaml
            # 观察以下命令输出,最后一行看到Certificate issued successfully,就代表安装成功
            kubectl describe certificate -n cert-manager-test
            # 清空测试
            kubectl delete -f test-resources.yaml

            6.安装alidns-webhook,这里选择官方推荐的

            alidns-webhook(https://cert-manager.io/docs/configuration/acme/dns01/)

              #下载alidns-webhook
              git clone https://github.com/pragkent/alidns-webhook
              #执行以下安装,cert-manager的v0.11以上,选择bundle.yaml
              kubectl apply -f deploy/bundle.yaml
              #创建secret
              kubectl -n cert-manager create secret generic alidns-secret --from-literal=access-key='xxxxx' --from-literal=secret-key='xxxx'

              7.创建ClusterIssuer

                apiVersion: cert-manager.io/v1alpha2
                kind: ClusterIssuer
                metadata:
                name: letsencrypt-prod
                spec:
                acme:
                email: xxx@example.org
                server: https://acme-v02.api.letsencrypt.org/directory
                privateKeySecretRef:
                name: letsencrypt-prod-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

                8.创建测试ingress

                  #创建以下yarn文件,test-ingress.yaml
                  apiVersion: extensions/v1beta1
                  kind: Ingress
                  metadata:
                  name: test-ingress
                  namespace: test
                  annotations:
                  cert-manager.io/cluster-issuer: "letsencrypt-prod"
                  spec:
                  tls:
                  - hosts:
                  - 'test-ingress.yourdomain.com'
                  secretName: test-ingress1-yourdomain-com-tls
                  rules:
                  - host: test-yourdomain.insyunmi.com
                  http:
                  paths:
                  - path: /
                  backend:
                  serviceName: mynginx
                  servicePort: 80
                  ---
                  apiVersion: apps/v1
                  kind: Deployment
                  metadata:
                  labels:
                  run: mynginx
                  name: mynginx
                  namespace: test
                  spec:
                  replicas: 1
                  selector:
                  matchLabels:
                  run: mynginx
                  template:
                  metadata:
                  labels:
                  run: mynginx
                  spec:
                  containers:
                  - image: nginx
                  imagePullPolicy: Always
                  name: mynginx
                  ports:
                  - containerPort: 80
                  protocol: TCP
                  ---
                  apiVersion: v1
                  kind: Service
                  metadata:
                  name: mynginx
                  namespace: test
                  spec:
                  ports:
                  - port: 80
                  protocol: TCP
                  targetPort: 80
                  selector:
                  run: mynginx
                  #执行
                  kubectl apply -f test-ingress.yaml

                  9.查看生成的证书

                    kubectl get certificates -n test
                    NAME READY SECRET AGE
                    test-ingress1-yourdomain-com-tls True test-ingress1-yourdomain-com-tls 106m


                    总结

                    1. 在安装alidns-webhook时,需要注意,alidns-webhook给出的示例是letsencrypt测试环境,实际使用时,需要改为正式环境。

                    2. 配置完后,只需要在ingress中增加以下annotations: cert-manager.io/cluster-issuer: "letsencrypt-prod"。

                    文章转载自ItTalk,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

                    评论