欢迎访问宙启技术站
智能推送

在Kubernetes中如何使用cert-mananager申请TLS 证书

发布时间:2023-05-18 13:18:05

在Kubernetes中使用cert-manager申请TLS证书是非常方便的,本章节将从以下方面介绍cert-manager的使用:

* 简要介绍cert-manager

* 部署cert-manager

* 申请TLS证书

* 部署一个使用TLS证书的应用

## 简要介绍cert-manager

Cert-manager是一个简单易用的Kubernetes证书管理器,可用于自动化证书申请,颁发,续期和检索证书。它的主要原则是自动化Web证书管理使撤销和周期性更换变得简单,易于操作和安全。它支持ACME v1 / v2,以及其他各种商业和公共证书颁发机构的验证。

## 部署cert-manager

首先需要在Kubernetes集群上部署cert-manager。cert-manager主要由两个组件组成:cert-manager控制器和webhook。

### 安装cert-manager控制器

对于Helm版本小于等于v3.7.0的用户:

$ 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 \
  --create-namespace \
  --version v1.3.1 \
  --set installCRDs=true

对于Helm版本大于v3.7.0的用户:

$ 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.3.1 \
  --set installCRDs=true

### 安装cert-manager webhook

安装完cert-manager控制器后,部署webhook,需要等待控制器启动并生成相应的证书后,才能部署webhook。

$ kubectl apply -f https://github.com/jetstack/cert-manager/releases/download/v1.3.1/cert-manager-webhook.yaml

部署完成后,可以运行以下命令来检查是否部署成功。

$ kubectl get pods --namespace cert-manager

输出应该类似于以下内容:

NAME                                       READY   STATUS    RESTARTS   AGE
cert-manager-77678c8fd8-8x69n              1/1     Running   0          3d16h
cert-manager-cainjector-66d489ff86-bfwtt   1/1     Running   0          3d16h
cert-manager-webhook-55f4d9c6b5-2gcqm      1/1     Running   0          3d16h

## 申请TLS证书

部署完cert-manager后,我们可以使用自定义资源定义(CRD)来申请TLS证书。在这里,我们将使用Let's Encrypt作为ACME的颁发机构。让我们看看如何为Ingress对象申请证书。

在此之前,需要预先创建ingress资源。

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
spec:
  tls:
  - secretName: example-tls
    hosts:
    - example.com
  rules:
  - host: example.com
    http:
      paths:
      - backend:
          serviceName: example-service
          servicePort: 80
        path: /

直接使用kubectl apply -f <ingress文件>来创建ingress对象。

接下来,需要安装一个Issuer,Issuer是声明使用的CA的Kubernetes CRD。需要安装相应Issuer的 CRD,以便cert-manager 可以读取和处理这些注册。

Let's Encrypt提供了一个ACME Issuer,让我们为Let's Encrypt颁发的证书安装一个ACME Issuer。

ACME(自动证书管理环境)Issuer 部署命令如下:

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

然后创建一个ACME Issuer。

apiVersion: cert-manager.io/v1alpha2
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
spec:
  acme:
    # 配置要访问的 Let’s Encrypt 的 ACME 服务器,我们采用的是生产环境的服务器
    server: https://acme-v02.api.letsencrypt.org/directory
    # 配置 DNS01 验证方式,使用支持的 DNS 服务可以自动验证,只需要修改 cname 记录即可
    solvers:
    - dns01:
        cloudDNS:
          # 配置 Google Cloud DNS 作为我们的 DNS 服务,
          # 这个账号需要有dns.googleapis.com API 权限
          project: project-id
          # 这个 Service Account 需要在 GCP 中配上DNS Administrator权限,并且给当前 Kubernetes 集群提供[roles/editor]权限
          serviceAccountSecretRef:
            name: letsencrypt-prod-cloud-dns-sa
            key: sa.json

然后再创建一个 Certificate。

apiVersion: cert-manager.io/v1alpha2
kind: Certificate
metadata:
  name: example-tls
spec:
  secretName: example-tls
  issuerRef:
    name: letsencrypt-prod
    kind: ClusterIssuer
  commonName: example.com
  dnsNames:
  - example.com
  acme:
    config:
    - http01:
        ingressClass: nginx
      domains:
      - example.com
    - dns01:
        provider: cloudDNS
      domains:
      - example.com

这将创建一个Certificate对象,它使用ClusterIssuer指向 Name;letsencrypt-prod,这可以让我们为它配置 ACME 服务器和验证 DNS 自动完成验证。

这指定了要使用secured Ingress对象的secretName、commonName和dnsNames,通常供ACME验证。

这个Certificate对象配置了2个Acme配置,因此,在验证域名时,cert-manager将尝试使用2种不同的方式。http01将尝试使用Ingress资源自动验证,dns01将尝试使用CloudDNS自动验证。

如果您想单独验证HTTP或DNS,则可以提供相应的Acme配置。

运行下面的命令检查证书是否已颁发。

$ kubectl describe certificat example-tls

在输出中,你应该看到一个绿色的“证书已准备好”,这是证书已经颁发的标志。

Conditions:
  Type          Status
  ----          ------
  Ready         True

## 部署一个使用TLS证书的应用

为了检查证书是否实际工作,您需要在您的Ingress对象上使用创建的Certificate对象。

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
spec:
  tls:
  - secretName: example-tls
    hosts:
    - example.com
  rules:
  - host: example.com
    http:
      paths:
      - backend:
          serviceName: example-service
          servicePort: 80
        path: /

执行kubectl apply -f <ingress文件>命令以应用更改。

现在,使用以下命令检查Ingress是否使用了证书。

$ kubectl describe ingress example-ingress

这应该输出一个名称为example-tls的tls-secret,这就是Kubernetes TLS秘密对象,其证书将用于加密 Ingress 流量。

TLS:
  example-tls terminates example.com
  secretName: example-tls

现在,访问example.com时,应使用您的证书安全地加密。

总结:使用cert-manager申请TLS证书是非常方便的,在Kubernetes上使用它是一种自动化