这里我使用的是 Kubernetes + 我自己的一个独立域名, 运行在 aws 环境上 , ec2 主机的 ip 是 54.95.179.97
除了 cert-manager 安装在 system 命名空间下之外, 所有的资源 ( deployment, service, ingress, issuer, cert ) 全部都安装在 study 命名空间下
需要注意的是命名空间需要提前创建
安装cert-manager
kubectl create namespace cattle-system
kubectl apply --validate=false -f https://github.com/jetstack/cert-manager/releases/download/v1.0.4/cert-manager.crds.yaml
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.0.4
cert-manager 提供了 Issuer 和 ClusterIssuer 这两种用于创建签发机构的自定义资源对象,
Issuer 只能用来签发自己所在 namespace 下的证书
ClusterIssuer 可以签发任意 namespace 下的证书
创建 issuer
lizhedeMacBook-Pro:lz_study lizhe$ cat issuer.yaml
apiVersion: certmanager.k8s.io/v1alpha1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
namespace: study
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: marshal_li_b@163.com
privateKeySecretRef:
name: letsencrypt-prod
http01: {}
lizhedeMacBook-Pro:lz_study lizhe$
- 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 协议的目的是证明这台机器和域名都是属于你的,然后才准许给你颁发证书)
创建证书
需要注意的是命名空间需要提前创建
lizhedeMacBook-Pro:lz_study lizhe$ cat cert.yaml
apiVersion: certmanager.k8s.io/v1alpha1
kind: Certificate
metadata:
name: study-pactera-deg-com
namespace: study
spec:
secretName: best-tls
issuerRef:
name: letsencrypt-prod
kind: ClusterIssuer
dnsNames:
- www.bestofgit.com
acme:
config:
- http01:
ingressClass: nginx
domains:
- www.bestofgit.com
lizhedeMacBook-Pro:lz_study lizhe$
- 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 指示该证书的可以用于哪些域名
然后安装nginx
deployment
lizhedeMacBook-Pro:lz_study lizhe$ cat nginx.yaml
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: nginx-deployment
namespace: study
spec:
replicas: 2 # tells deployment to run 2 pods matching the template
template: # create pods using pod definition in this template
metadata:
# unlike pod-nginx.yaml, the name is not included in the meta data as a unique name is
# generated from the deployment name
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
lizhedeMacBook-Pro:lz_study lizhe$
svc.yaml
lizhedeMacBook-Pro:lz_study lizhe$ cat svc.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-service
namespace: study
spec:
type: ClusterIP
ports:
- port: 80
selector:
app: nginx
lizhedeMacBook-Pro:lz_study lizhe$
ingress.yaml
lizhedeMacBook-Pro:lz_study lizhe$ cat ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: hello-nginx-ingress
namespace: study
annotations:
kubernetes.io/ingress.class: "nginx"
certmanager.k8s.io/issuer: "letsencrypt-prod"
certmanager.k8s.io/acme-challenge-type: http01
spec:
rules:
- host: www.bestofgit.com
http:
paths:
- backend:
serviceName: nginx-service
servicePort: 80
tls:
- hosts:
- www.bestofgit.com
secretName: best-tls
lizhedeMacBook-Pro:lz_study lizhe$