Cert Manager 签发证书
Contents
cert-manageropen 是 Kubernetes 上的全能证书管理工具,支持利用 cert-manager 基于 ACMEopen 协议与 Let’s Encryptopen 签发免费证书并为证书自动续期,实现永久免费使用证书
# 安装
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.12.0/cert-manager.yaml
工作原理
cert-manager 部署到 Kubernetes 集群后,它会 watch 它所支持的 CRD 资源,我们通过创建 CRD 资源来指示 cert-manager 为我们签发证书并自动续期
Issuer
/ClusterIssuer
: 用于指示 cert-manager 用什么方式签发证书(ClusterIssuer 与 Issuer 的唯一区别就是 Issuer 只能用来签发自己所在 namespace 下的证书,ClusterIssuer 可以签发任意 namespace 下的证书)- 由权威 CA 机构签名的「公网受信任证书:这类证书会被浏览器、小程序等第三方应用/服务商信任
- 本地签名证书:即由本地 CA 证书签名的数字证书
- 自签名证书:即使用证书的私钥为证书自己签名
Certificate
: 用于告诉 cert-manager 我们想要什么域名的证书以及签发证书所需要的一些配置,包括对 Issuer/ClusterIssuer 的引用
示例
创建自签证书
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: myissuer
namespace: default
spec:
selfSigned: {}
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: tls-p
namespace: default
spec:
secretName: tls-p # 生成的secret名称
duration: 5h # 有效期
renewBefore: 2h # 自动续期临近日期
dnsNames:
- p.virtuallain.com
issuerRef:
name: myissuer # 关联签发者
双向认证
生成CA证书
# 生成key文件
openssl genrsa -out ca.key 2048
# 生成ca.crt证书文件
openssl req -x509 -new -nodes -key ca.key -subj "/CN=*.virtuallain.com" -days 3650 -reqexts v3_req -extensions v3_ca -out ca.crt
# 导入k8s
kubectl create secret tls myca --cert=ca.crt --key=ca.key -n default
创建 issuer 和 certificate 资源,自动生成服务端证书
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: ca-issuer
namespace: default
spec:
ca:
secretName: myca
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: tls-p
namespace: default
spec:
secretName: tls-p
commonName: p.virtuallain.com
dnsNames:
- p.virtuallain.com
issuerRef:
name: ca-issuer
kind: Issuer
ingress 开启双向认证
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: p.virtuallain.com
namespace: default
annotations:
nginx.ingress.kubernetes.io/auth-tls-secret: default/tls-p # 证书secret
nginx.ingress.kubernetes.io/auth-tls-verify-client: "on" # 开启双向认证
spec:
ingressClassName: nginx
rules:
- host: p.virtuallain.com
http:
paths:
- backend:
service:
name: test
port:
number: 80
path: /
pathType: Prefix
tls:
- hosts:
- p.virtuallain.com
secretName: tls-p # 证书secret
生成客户端证书
openssl genrsa -out client.key 2048
openssl req -new -key client.key -out client.csr -subj "/CN=p.virtuallain.com"
openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out client.crt -days 365
客户端请求
func main() {
pool := x509.NewCertPool()
caCrt, _ := ioutil.ReadFile("./certs/ca.crt")
pool.AppendCertsFromPEM(caCrt)
cliCrt, _ := tls.LoadX509KeyPair("./certs/client.crt", "./certs/client.key")
tr := &http.Transport{
TLSClientConfig: &tls.Config{
RootCAs: pool,
Certificates: []tls.Certificate{cliCrt},
// InsecureSkipVerify: true,
},
}
req, err := http.NewRequest("GET", "https://p.virtuallain.com/", nil)
if err != nil {
log.Fatal(err)
}
client := &http.Client{Transport: tr}
rsp, err := client.Do(req)
if err != nil {
log.Fatal(err)
}
defer rsp.Body.Close()
b, _ := ioutil.ReadAll(rsp.Body)
fmt.Println(string(b))
}
签发 Let’s Encrypt 免费证书
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsissuer
spec:
acme:
email: ""
server: https://acme-v02.api.letsencrypt.org/directory
preferredChain: "ISRG Root X1"
privateKeySecretRef:
name: letstlskey
solvers:
- http01:
ingress:
class: nginx
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: tls-p
namespace: default
spec:
secretName: tls-p
subject:
organizations:
- virtuallain.com
issuerRef:
name: letsissuer
kind: ClusterIssuer
group: cert-manager.io
dnsNames:
- p.virtuallain.com
privateKey:
algorithm: RSA
encoding: PKCS1
size: 2048