Contents
cert-manager安装
参考: https://cert-manager.io/docs/
参考: https://cert-manager.io/docs/getting-started/
前面装好ingress之后,默认只提供80端口的http访问。如果要使用https,需要在ingress中配置tls。
配置tls需要提供证书和key。
- 购买域名的时候,有的域名服务商会给购买的域名提供免费的域名证书服务。
- 也可以用openssl等工具自签证书,但浏览器和各操作系统,一般是不认自签证书的,会提示不安全,问你要不要继续访问。
- 大部分域名权威机构或其二级机构,需要单独购买域名证书,才提供域名证书服务。
- letsencrypt也是一家域名二级机构,提供免费的域名证书服务。
前面用openssl工具自签过一个证书,用于测试。正常来说,是需要向权威机构申请域名证书的。
k8s的cert-manager基于上述机构(主要是letsencrypt)的证书服务,自动提供,自动更新域名证书。
参考: https://cert-manager.io/docs/
cert-manager adds certificates and certificate issuers as resource types in Kubernetes clusters, and simplifies the process of obtaining, renewing and using those certificates. cert-manager 将证书和证书颁发者添加为 Kubernetes 集群中的资源类型,并简化了获取、更新和使用这些证书的过程。
参考: https://cert-manager.io/docs/getting-started/
参考: https://cert-manager.io/docs/tutorials/acme/nginx-ingress/
prerequisite
安装k8s
私网安装metallb或云服务商提供loadbalancer实现
安装nginx-ingress
开始
参考: https://cert-manager.io/docs/getting-started/
主要是参考其中如下部分:
Learn how to deploy cert-manager and how to configure it to get certificates for the NGINX Ingress controller from Let’s Encrypt.
本章节主要学习实践如何部署cert-manager, 并为 ingress-nginx控制器配置来自 Let’s Encrypt的证书。
至于对其他云厂商和ingress controller环境下的配置,略,有需要再看。
helm安装cert-manager
这里采用helm安装方式。
参考: https://cert-manager.io/docs/installation/
参考: https://cert-manager.io/docs/installation/helm/
添加helm仓库:
helm repo add jetstack https://charts.jetstack.io --force-update
更新仓库缓存:
helm repo update
创建命名空间
kubectl create ns cert-manager
设为当前默认命名空间
kubectl config set-context --current --namespace cert-manager
开始安装cert-manager组件
官网这里提供了两种方式安装。
- 一种单独安装自定义资源类型(custom resource defination), 然后用helm安装剩余部分。
- 另一种直接用helm安装所有内容,包含crd。
生产环境建议第一种方式,原因是,卸载helm装的cert-manager时,不会卸载crd部分,也不会移除已经生成的证书,防止对外的https服务异常。
这里使用第一种方式。
看下helm仓库当前的cert-manager版本
root@wangjm-B550M-K-1:~/k8s/helm/cert-manager# helm search repo jetstack
NAME CHART VERSION APP VERSION DESCRIPTION
jetstack/cert-manager v1.14.5 v1.14.5 A Helm chart for cert-manager
jetstack/cert-manager-approver-policy v0.14.0 v0.14.0 approver-policy is a CertificateRequest approve...
jetstack/cert-manager-csi-driver v0.8.0 v0.8.0 cert-manager csi-driver enables issuing secretl...
jetstack/cert-manager-csi-driver-spiffe v0.5.0 v0.5.0 csi-driver-spiffe is a Kubernetes CSI plugin wh...
jetstack/cert-manager-google-cas-issuer v0.8.0 v0.8.0 A Helm chart for jetstack/google-cas-issuer
jetstack/cert-manager-istio-csr v0.8.1 v0.8.1 istio-csr enables the use of cert-manager for i...
jetstack/cert-manager-trust v0.2.1 v0.2.0 DEPRECATED: The old name for trust-manager. Use...
jetstack/trust-manager v0.9.2 v0.9.2 trust-manager is the easiest way to manage TLS ...
jetstack/version-checker v0.5.4 v0.5.4 A Helm chart for version-checker
嗯, v1.14.5
下载对应的crd
参考: https://cert-manager.io/docs/installation/helm/#option-1-installing-crds-with-kubectl
看了下github的分支和tag,已经有v1.12.3了,下载对应的crd
wget https://github.com/cert-manager/cert-manager/releases/download/v1.14.5/cert-manager.crds.yaml
创建对应的crd资源
kubectl create -f ./cert-manager.crds.yaml
helm安装cert-manager
helm install \
cert-manager jetstack/cert-manager \
--namespace cert-manager \
--create-namespace \
--version v1.14.5
前面已经安装crd了,如果没有安装的话,也可以按前面说的第二种方式安装
helm install \
cert-manager jetstack/cert-manager \
--namespace cert-manager \
--create-namespace \
--version v1.12.3 \
# --set installCRDs=true
安装完成的输出:
root@wangjm-B550M-K-1:~/k8s/helm/cert-manager# helm install \
cert-manager jetstack/cert-manager \
--namespace cert-manager \
--create-namespace \
--version v1.14.5
NAME: cert-manager
LAST DEPLOYED: Thu May 9 21:10:22 2024
NAMESPACE: cert-manager
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
cert-manager v1.14.5 has been deployed successfully!
In order to begin issuing certificates, you will need to set up a ClusterIssuer
or Issuer resource (for example, by creating a 'letsencrypt-staging' issuer).
More information on the different types of issuers and how to configure them
can be found in our documentation:
https://cert-manager.io/docs/configuration/
For information on how to configure cert-manager to automatically provision
Certificates for Ingress resources, take a look at the `ingress-shim`
documentation:
https://cert-manager.io/docs/usage/ingress/
这里提示下一步,可以配置Issuer或者ClusterIssuer了,比如免费的letsencrypt。
如果要卸载cert-manager
helm --namespace cert-manager delete cert-manager
删除crd (危险!!!),先查一下有哪些资源
kubectl get Issuers,ClusterIssuers,Certificates,CertificateRequests,Orders,Challenges --all-namespaces
去当初安装安装crd的目录下
kubectl delete -f ./cert-manager.crds.yaml
删除命名空间
kubectl delete namespace cert-manager
如果删除命名空间的过程中,卡住了
kubectl delete apiservice v1beta1.webhook.cert-manager.io
使用cert-manager为ingress-nginx提供tls服务
参考: https://cert-manager.io/docs/tutorials/acme/nginx-ingress/
Step1 – Install Helm
略,前面章节已装
Step2 – Deploy the NGINX Ingress Controller
略,前面章节已装
Step3 – Assign a DNS name
略。买域名,去域名服务商网站那里配置。
绑一下ip
Step4 – Deploy an Example Service
创建test命名空间
kubectl create ns test
切换到test命名空间,做测试
kubectl config set-context --current --namespace test
下载demo相关yaml文件
wget https://raw.githubusercontent.com/cert-manager/website/master/content/docs/tutorials/acme/example/deployment.yaml
wget https://raw.githubusercontent.com/cert-manager/website/master/content/docs/tutorials/acme/example/service.yaml
wget https://raw.githubusercontent.com/cert-manager/website/master/content/docs/tutorials/acme/example/ingress.yaml
部署deployment和service
kubectl create -f ./deployment.yaml
kubectl create -f ./service.yaml
ingress需要调整一下其中的域名,改为自己掌控的域名或其二级域名(需要在域名服务商那里做好ip绑定)
[root@jingmin-kube-archlinux cert-manager-demo]# vim ./ingress.yaml
[root@jingmin-kube-archlinux cert-manager-demo]# cat ./ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: kuard
annotations: {}
#cert-manager.io/issuer: "letsencrypt-staging"
spec:
ingressClassName: nginx
tls:
- hosts:
- kuard.ole12138.cn
secretName: quickstart-example-tls
rules:
- host: kuard.ole12138.cn
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: kuard
port:
number: 80
这里我使用二级域名kuard.ole12138.cn
,并需要到域名服务商那里做下ingress controller(loadbalancer)的ip地址的绑定。
部署ingress
kubectl create -f ./ingress.yaml
查看ingress
[root@jingmin-kube-archlinux cert-manager-demo]# kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
demo-external nginx demo.ole12138.cn 192.168.1.100 80, 443 35h
demo-localhost nginx demo.localdev.me 192.168.1.100 80, 443 35h
kuard nginx kuard.ole12138.cn 192.168.1.100 80, 443 4m39s
可以看到有一行是kuard
公网访问https://kuard.ole12138.cn/
, 应该可以访通,但是浏览器会有警告,因为使用的是ingress-nginx默认的自签证书。
查看ingress-nginx控制器的日志,也能看到证书相关的提示
kubectl -n ingress-nginx logs pods/ingress-nginx-controller-5fcb5746fc-47q6m
Step5 – Deploy cert-manager
本文前面,已经装了相关的crd资源,以及helm安装了cert-manager
Step6 – Configure a Let’s Encrypt Issuer
许多CA提供的证书都是要钱的。Let‘s Encrypt则不然,可以提供免费的证书。而且有较好的验证接口。
但是生产环境的证书签注接口,Let‘s Encrypt有较为严格的调用次数限制,very strict rate limits. 同时它也提供了非生产环境,较为宽松的签注接口。
因此,我们部署两套Issuer,一套staging环境,一套production环境。(注意:Issuer这里特指这种crd,而且是namespaced的资源,如果想要cluster全局都可以使用,科室使用CluserIssuer这种crd,并修改对应位置的annotation)
将defaut设为默认命名空间,即之后创建的资源,默认是在default命名空间中的
kubectl config set-context --current --namespace test
创建staging-issuer
wget https://raw.githubusercontent.com/cert-manager/website/master/content/docs/tutorials/acme/example/staging-issuer.yaml
修改其中的邮箱部分,用于创建账号,以及将来有证书将要过期相关的内容会发到对应的邮箱
[root@jingmin-kube-archlinux issuer]# vim staging-issuer.yaml
[root@jingmin-kube-archlinux issuer]# cat staging-issuer.yaml
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: letsencrypt-staging
spec:
acme:
# The ACME server URL
server: https://acme-staging-v02.api.letsencrypt.org/directory
# Email address used for ACME registration
email: 784319947@qq.com
# Name of a secret used to store the ACME account private key
privateKeySecretRef:
name: letsencrypt-staging
# Enable the HTTP-01 challenge provider
solvers:
- http01:
ingress:
ingressClassName: nginx
部署staging-issuer
kubectl create -f ./staging-issuer.yaml
类似的方式,创建production-issuer
wget https://raw.githubusercontent.com/cert-manager/website/master/content/docs/tutorials/acme/example/production-issuer.yaml
同样,修改其中的邮箱为自己的邮箱
[root@jingmin-kube-archlinux issuer]# vim production-issuer.yaml
[root@jingmin-kube-archlinux issuer]# cat production-issuer.yaml
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: letsencrypt-prod
spec:
acme:
# The ACME server URL
server: https://acme-v02.api.letsencrypt.org/directory
# Email address used for ACME registration
email: 784319947@qq.com
# Name of a secret used to store the ACME account private key
privateKeySecretRef:
name: letsencrypt-prod
# Enable the HTTP-01 challenge provider
solvers:
- http01:
ingress:
ingressClassName: nginx
部署到当前命名空间中
kubectl create -f ./production-issuer.yaml
这两个issuer都通过http01的方式向Let’s Encrypt 发出challenge.
kubectl describe issuer
可以看到description中都有一条Message: The ACME account was registered with the ACME server
Step7 – Deploy a TLS Ingress Resource
修改前面部署的kuard demo ingress
删除tls部分(前面好像本来就没有加,默认用的ingress-nginx自动生成的自签证书)
annotations部分添加一行cert-manager相关的注解cert-manager.io/issuer: "letsencrypt-staging"
[root@jingmin-kube-archlinux issuer]# kubectl edit ingress kuard
[root@jingmin-kube-archlinux issuer]# kubectl get ingress kuard -o yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
cert-manager.io/issuer: letsencrypt-staging
creationTimestamp: "2023-08-23T02:47:41Z"
generation: 1
name: kuard
namespace: default
resourceVersion: "411121"
uid: 7f2c7dfb-12a6-446d-95a9-24dfebd9fa00
spec:
ingressClassName: nginx
rules:
- host: kuard.ole12138.cn
http:
paths:
- backend:
service:
name: kuard
port:
number: 80
path: /
pathType: Prefix
tls:
- hosts:
- kuard.ole12138.cn
secretName: quickstart-example-tls
status:
loadBalancer:
ingress:
- ip: 192.168.1.100
这个时候,cert-manager会自动替我们向Let’s Encrypt申请域名证书,并维护证书的可用性(比如快过期时自动更新证书)。
[root@jingmin-kube-archlinux issuer]# kubectl get certificate
NAME READY SECRET AGE
quickstart-example-tls False quickstart-example-tls 16s
[root@jingmin-kube-archlinux issuer]# kubectl get certificate
NAME READY SECRET AGE
quickstart-example-tls True quickstart-example-tls 67s
可以看到,过了一会儿,才准备好证书。
这个时候,到浏览器中,请求前面的ingress域名, 我的是https://kuard.ole12138.cn
可以发现,还是提示不安全,但是点击浏览器那个证书图标(这里可能是个叹号图标),显示的证书内容已经更新(注意签发机构等内容)。
说明ingress中issuer的配置是可用的。
OK, 现在我们可以吧staging-issuer切换为producation-issuer了。
还是调整ingress中annotations中issuer相关的内容, 切换为正式的“letsencrypt-prod“
[root@jingmin-kube-archlinux issuer]# kubectl edit ingress kuard
ingress.networking.k8s.io/kuard edited
[root@jingmin-kube-archlinux issuer]# kubectl get ingress kuard -o yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
cert-manager.io/issuer: letsencrypt-prod
creationTimestamp: "2023-08-23T02:47:41Z"
generation: 1
name: kuard
namespace: default
resourceVersion: "412929"
uid: 7f2c7dfb-12a6-446d-95a9-24dfebd9fa00
spec:
ingressClassName: nginx
rules:
- host: kuard.ole12138.cn
http:
paths:
- backend:
service:
name: kuard
port:
number: 80
path: /
pathType: Prefix
tls:
- hosts:
- kuard.ole12138.cn
secretName: quickstart-example-tls
status:
loadBalancer:
ingress:
- ip: 192.168.1.100
然后查看对应的secrets,certificate, 确认已经更新(issuer相关的annotations字段)
kubectl get secrets,certificate -o yaml
浏览器再请求一下,前面的ingress域名, 我的是https://kuard.ole12138.cn
。访问的时候,已经没有任何警告,点击浏览器里地址栏前面的锁头标志,提示地址是安全的,并可以看到具体的证书信息。
注意,前面创建的两个Issuer实例,都是namespaced受限的。如果要cluster中全局可用,请切换CluserIssuer,创建对应的资源。而且annotations注解也要调整为cert-manager.io/cluster-issuer
(注意Let’s Encrypt 每个帐号能签发的证书个数是有限制的。Cluser情况注意下容易超限)
前面的时间算是基础,但是这样来一遍之后,基本已经可以在ingress中自动配置tls了。日常使用应该已经够了。
如果想要进一步了解其构成以及配置,以及使用自定义的CA服务商,可以阅读官网其他部分的文档。
比如如下内容:
https://cert-manager.io/docs/concepts/
https://cert-manager.io/docs/configuration/
https://cert-manager.io/docs/usage/
发表回复