0%

利用cert-manager让Ingress启用免费的HTTPS证书

cert-manager 是替代 kube-lego 的一个开源项目,用于在 Kubernetes 集群中自动提供 HTTPS 证书,支持 Let’s Encrypt, HashiCorp Vault 这些免费证书的签发。

安装 cert-manager

1
2
3
4
helm install \
--name cert-manager \
--namespace kube-system \
stable/cert-manager

生成免费证书

先创建一个签发机构,cert-manager 给我们提供了 Issuer 和 ClusterIssuer 这两种用于创建签发机构的自定义资源对象,Issuer 只能用来签发自己所在 namespace 下的证书,ClusterIssuer 可以签发任意 namespace 下的证书,这里以 ClusterIssuer 为例创建一个签发机构

1
2
3
4
5
6
7
8
9
10
11
12
13
vi issuer.yaml

apiVersion: certmanager.k8s.io/v1alpha1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: ywthings@qq.com
privateKeySecretRef:
name: letsencrypt-prod
http01: {}

metadata.name 是我们创建的签发机构的名称,后面我们创建证书的时候会引用它
spec.acme.email 是你自己的邮箱,证书快过期的时候会有邮件提醒,不过 cert-manager 会利用 acme 协议自动给我们重新颁发证书来续期
spec.acme.server 是 acme 协议的服务端,我们这里用 Let’s Encrypt,这个地址就写死成这样就行
spec.acme.privateKeySecretRef 指示此签发机构的私钥将要存储到哪个 Secret 对象中,名称不重要
spec.acme.http01 这里指示签发机构使用 HTTP-01 的方式进行 acme 协议 (还可以用 DNS 方式,acme 协议的目的是证明这台机器和域名都是属于你的,然后才准许给你颁发证书)

签发机构,接下来我们就可以生成免费证书了,cert-manager 给我们提供了 Certificate 这个用于生成证书的自定义资源对象,它必须局限在某一个 namespace 下,证书最终会在这个 namespace 下以 Secret 的资源对象存储,假如我想在 dashboard 这个 namespace 下生成免费证书(这个 namespace 已存在),创建一个 Certificate 对象:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
vi cert.yaml

apiVersion: certmanager.k8s.io/v1alpha1
kind: Certificate
metadata:
name: ywthings.com
namespace: dashboard
spec:
secretName: ywthings.com-tls
issuerRef:
name: letsencrypt-prod
kind: ClusterIssuer
dnsNames:
- ywthings.com
acme:
config:
- http01:
ingressClass: nginx
domains:
- ywthings.com

spec.secretName 指示证书最终存到哪个 Secret 中
spec.issuerRef.kind 值为 ClusterIssuer 说明签发机构不在本 namespace 下,而是在全局
spec.issuerRef.name 我们创建的签发机构的名称 (ClusterIssuer.metadata.name)
spec.dnsNames 指示该证书的可以用于哪些域名
spec.acme.config.http01.ingressClass 使用 HTTP-01 方式校验该域名和机器时,cert-manager 会尝试创建Ingress 对象来实现该校验,如果指定该值,会给创建的 Ingress 加上 kubernetes.io/ingress.class 这个 annotation,如果我们的 Ingress Controller 是 Nginx Ingress Controller,指定这个字段可以让创建的 Ingress 被 Nginx Ingress Controller 处理。
spec.acme.config.http01.domains 指示该证书的可以用于哪些域名

Ingress 使用来启用免费 HTTPS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: my-nginx
annotations:
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- host: ywthings.com
http:
paths:
- backend:
serviceName: my-nginx
servicePort: 443
path: /
tls:
- secretName: ywthings.com-tls
hosts:
- ywthings.com

在 Ingress 定义的 spec.tls.secretName 引用生成的证书所在的 Secret 名称即可实现使用免费证书
将 Ingress 定义的 spec.rules.host 和 spec.tls.hosts 里的域名都替换为你自己的域名