现在的Web应用启用HTTPS
服务是真的非常有必要的。一些正规机构颁发的CA
证书费用又特别高,不过比较幸运的是也有免费的午餐 - Let's Encrypt
,虽然只有90天的证书有效期,但是我们完全可以在证书失效之前,重新生成证书替换掉。在Kubernetes
集群中就更方便了,我们可以通过 Kubernetes Ingress 和 Let’s Encrypt 实现外部服务的自动化 HTTPS。
Cert-Manager 是一个云原生证书管理开源项目,用于在 Kubernetes 集群中提供 HTTPS 证书并自动续期,支持 Let’s Encrypt / HashiCorp / Vault 这些免费证书的签发。
部署
我们这里用来管理 SSL/TLS 证书的组件是Cert manager
,它对于每一个 ingress endpoint 将会自动创建一个新的证书,当 certificates 过期时还能自动更新,除此之外,Cert manager 也可以和其它的 providers 一起工作,例如 HashiCorp Vault。这里我们介绍两种部署方式:
Yaml文件部署
# Kubernetes 1.16+
$ kubectl apply --validate=false -f https://github.com/jetstack/cert-manager/releases/download/v1.0.2/cert-manager.yaml
# Kubernetes <1.16
$ kubectl apply --validate=false -f https://github.com/jetstack/cert-manager/releases/download/v1.0.2/cert-manager-legacy.yaml
Helm3 部署
kubectl create namespace cert-manager
helm repo add jetstack https://charts.jetstack.io
helm repo update
helm upgrade --install \
cert-manager jetstack/cert-manager \
--namespace cert-manager \
--version v1.0.2 \
--set ingressShim.defaultIssuerName=letsencrypt-prod \
--set ingressShim.defaultIssuerKind=ClusterIssuer \
--set installCRDs=true
在使用的时候我们需要配置一个缺省的cluster issuer,当部署Cert manager
的时候,用于支持kubernetes.io/tls-acme: "true"
annotation 来自动化 TLS。
安装完成后,然后查看Pod
运行状态:
$ kubectl get pods -n cert-manager
NAME READY STATUS RESTARTS AGE
cert-manager-74fdd7bc8f-bhj6v 1/1 Running 0 6h48m
cert-manager-cainjector-8665f9998-k7bx6 1/1 Running 0 6h48m
cert-manager-webhook-677b8cbf67-2w48n 1/1 Running 0 6h48m
除此之外,安装完成后Cert manager
还提供了一些Kubernetes custom resources:
$ kubectl get crd -n cert-manager
NAME CREATED AT
certificaterequests.cert-manager.io 2020-09-28T05:44:55Z
certificates.cert-manager.io 2020-09-28T05:44:55Z
challenges.acme.cert-manager.io 2020-09-28T05:44:56Z
clusterissuers.cert-manager.io 2020-09-28T05:44:56Z
issuers.cert-manager.io 2020-09-28T05:44:58Z
orders.acme.cert-manager.io 2020-09-28T05:44:58Z
证书签发服务
Cert manager
安装后,接下来需要定义上面的letsencrypt-prod
这个cluster issuer
,这里使用上面的clusterissuers.certmanager.k8s.io
这个CRD
来定义:(cluster-issuer-letsencrypt-prod.yaml)
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: xxx@gmail.com
privateKeySecretRef:
name: letsencrypt-prod
solvers:
- http01:
ingress:
class: nginx
然后直接创建这个ClusterIssuer
资源:
$ kubectl create -f cluster-issuer-letsencrypt-prod.yaml
clusterissuer.certmanager.k8s.io "letsencrypt-prod" created
注意:上面配置的是生产环境,你还可以配置staging环境来测试。Let’s Encrypt 测试环境与生产环境的区别
验证
上面我们已经安装了Cert manager
,定义了ClusterIssuer
,接下来我们来配置 HTTPS 去访问我们的 Nginx服务,Nginx 的部署我们这里就不多说了,直接添加一个 Ingress 资源对象即可:(nginx-ingress.yaml)
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: nginx
annotations:
kubernetes.io/ingress.class: nginx
kubernetes.io/tls-acme: "true"
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
rules:
- http:
paths:
- backend:
serviceName: nginx
servicePort: 80
host: "nginx-demo.qcloud.com"
tls:
- hosts:
- nginx-demo.qcloud.com
secretName: nginx-demo-tls
这里需要注意的是上面我们添加的annotations
非常重要,这个将告诉 Cert Manager 去生成证书,然后由于我们这里要使用 HTTPS,所以我们需要添加一个 tls 证书,而证书就是通过nginx-demo-tls
这个 Secret 对象来提供的,要注意的是这个 Secret 对象并不是我们手动创建的,而是 Cert Manager 自动创建的证书对应的对应。然后直接创建这个资源对象即可:
$ kubectl create -f nginx-ingress.yaml
当然如果需要在公网中进行访问,我们还需要将我们这里的域名解析到 Ingress Controller 所在的任意一个节点,或者在本地的
/etc/hosts
中加上映射也是可以的。
之后 Cert-manager 会读取注解并创建证书,使用以下命令查看:
$ kubectl get certificate
NAME READY SECRET AGE
nginx-demo-tls True nginx-demo-tls 5h20m
到这里我们就完成了使用Let's Encrypt
实现Kubernetes Ingress
自动化 HTTPS。
参考
「真诚赞赏,手留余香」
请我喝杯咖啡?
使用微信扫描二维码完成支付
