Kubernetes 中 Cert-Manager 的自签名证书问题
Issue with Self-signed certificate with Cert-Manager in Kubernetes
我正在尝试使用 Cert-Manager 在我的 AKS 群集中添加自签名证书。
我为 CA 证书创建了一个 ClusterIssuer
(用于签署证书),并为我要使用的证书(自签名)创建了第二个 ClusterIssuer
。
我不确定 certificate2
是否被 Ingress 正确使用,因为它看起来像是在等待某个事件。
我这样做的方式是否正确?
这是第一个 ClusterIssuer
"clusterissuer.yml":
apiVersion: cert-manager.io/v1alpha2
kind: ClusterIssuer
metadata:
name: selfsigned
spec:
selfSigned: {}
这是 CA 证书“certificate.yml”:
apiVersion: cert-manager.io/v1alpha2
kind: Certificate
metadata:
name: selfsigned-certificate
spec:
secretName: hello-deployment-tls-ca-key-pair
dnsNames:
- "*.default.svc.cluster.local"
- "*.default.com"
isCA: true
issuerRef:
name: selfsigned
kind: ClusterIssuer
这是我要使用的证书的第二个ClusterIssuer
“clusterissuer2.yml”:
apiVersion: cert-manager.io/v1alpha2
kind: ClusterIssuer
metadata:
name: hello-deployment-tls
spec:
ca:
secretName: hello-deployment-tls-ca-key-pair
最后这是自签名证书“certificate2.yml”:
apiVersion: cert-manager.io/v1alpha2
kind: Certificate
metadata:
name: selfsigned-certificate2
spec:
secretName: hello-deployment-tls-ca-key-pair2
dnsNames:
- "*.default.svc.cluster.local"
- "*.default.com"
isCA: false
issuerRef:
name: hello-deployment-tls
kind: ClusterIssuer
我在 Ingress 中使用此证书:
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx
cert-manager.io/cluster-issuer: "hello-deployment-tls"
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
name: sonar-ingress
spec:
tls:
- secretName: "hello-deployment-tls-ca-key-pair2"
rules:
- http:
paths:
- pathType: Prefix
path: "/"
backend:
serviceName: sonarqube
servicePort: 80
因为我没有任何注册域名,所以我只想使用 public IP 访问 https://<Public_IP>
上的服务。
当我访问该服务时 https://<Public_IP>
我可以看到“Kubernetes Ingress Controller Fake Certificate”所以我猜这是因为该证书不能被浏览器全局识别。
怪事来了。理论上 Ingress 部署正在使用 selfsigned-certificate2
但看起来它还没有准备好:
kubectl get certificate
NAME READY SECRET AGE
selfsigned-certificate True hello-deployment-tls-ca-key-pair 4h29m
selfsigned-certificate2 False hello-deployment-tls-ca-key-pair2 3h3m
selfsigned-secret True selfsigned-secret 5h25m
kubectl describe certificate selfsigned-certificate2
.
.
.
Spec:
Dns Names:
*.default.svc.cluster.local
*.default.com
Issuer Ref:
Kind: ClusterIssuer
Name: hello-deployment-tls
Secret Name: hello-deployment-tls-ca-key-pair2
Status:
Conditions:
Last Transition Time: 2021-10-15T11:16:15Z
Message: Waiting for CertificateRequest "selfsigned-certificate2-3983093525" to complete
Reason: InProgress
Status: False
Type: Ready
Events: <none>
有什么想法吗?
提前致谢。
Api 版本
首先我注意到您正在使用 v1alpha2
apiVersion,它已被删除并将在 1.6
cert-manager:
中删除
$ kubectl apply -f cluster-alpha.yaml
Warning: cert-manager.io/v1alpha2 ClusterIssuer is deprecated in v1.4+, unavailable in v1.6+; use cert-manager.io/v1 ClusterIssuer
我在复制中使用了apiVersion: cert-manager.io/v1
。
与 v1beta1
入口相同,考虑将其更新为 networking.k8s.io/v1
。
会发生什么
我开始逐步重现您的设置。
我申请了clusterissuer.yaml
:
$ kubectl apply -f clusterissuer.yaml
clusterissuer.cert-manager.io/selfsigned created
$ kubectl get clusterissuer
NAME READY AGE
selfsigned True 11s
注意READY
设置为True
。
下一个我申请了certificate.yaml
:
$ kubectl apply -f cert.yaml
certificate.cert-manager.io/selfsigned-certificate created
$ kubectl get cert
NAME READY SECRET AGE
selfsigned-certificate True hello-deployment-tls-ca-key-pair 7s
下一步 是添加第二个 ClusterIssuer
引用 hello-deployment-tls-ca-key-pair
秘密:
$ kubectl apply -f clusterissuer2.yaml
clusterissuer.cert-manager.io/hello-deployment-tls created
$ kubectl get clusterissuer
NAME READY AGE
hello-deployment-tls False 6s
selfsigned True 3m50
ClusterIssuer hello-deployment-tls
未 就绪。原因如下:
$ kubectl describe clusterissuer hello-deployment-tls
...
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning ErrGetKeyPair 10s (x5 over 75s) cert-manager Error getting keypair for CA issuer: secret "hello-deployment-tls-ca-key-pair" not found
Warning ErrInitIssuer 10s (x5 over 75s) cert-manager Error initializing issuer: secret "hello-deployment-tls-ca-key-pair" not found
这是预期行为,因为:
When referencing a Secret resource in ClusterIssuer resources (eg
apiKeySecretRef) the Secret needs to be in the same namespace as the
cert-manager controller pod. You can optionally override this by using
the --cluster-resource-namespace argument to the controller.
答案-如何前进
我编辑了 cert-manager
部署,因此它将在 default
命名空间中查找 secrets
(这并不理想,我会在 default
命名空间):
$ kubectl edit deploy cert-manager -n cert-manager
spec:
containers:
- args:
- --v=2
- --cluster-resource-namespace=default
cert-manager
大约需要一分钟才能启动。重新部署 clusterissuer2.yaml
:
$ kubectl delete -f clusterissuer2.yaml
clusterissuer.cert-manager.io "hello-deployment-tls" deleted
$ kubectl apply -f clusterissuer2.yaml
clusterissuer.cert-manager.io/hello-deployment-tls created
$ kubectl get clusterissuer
NAME READY AGE
hello-deployment-tls True 3s
selfsigned True 5m42s
两者都是READY
。与 certificate2.yaml
一起前进:
$ kubectl apply -f cert2.yaml
certificate.cert-manager.io/selfsigned-certificate2 created
$ kubectl get cert
NAME READY SECRET AGE
selfsigned-certificate True hello-deployment-tls-ca-key-pair 33s
selfsigned-certificate2 True hello-deployment-tls-ca-key-pair2 6s
$ kubectl get certificaterequest
NAME APPROVED DENIED READY ISSUER REQUESTOR AGE
selfsigned-certificate-jj98f True True selfsigned system:serviceaccount:cert-manager:cert-manager 52s
selfsigned-certificate2-jwq5c True True hello-deployment-tls system:serviceaccount:cert-manager:cert-manager 25s
入口
当 host
未添加到 ingress
时,它不会创建任何证书并且似乎使用了 ingress
中由 CN = Kubernetes Ingress Controller Fake Certificate
颁发的一些假证书.
来自 ingress
的事件:
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning BadConfig 5s cert-manager TLS entry 0 is invalid: secret "example-cert" for ingress TLS has no hosts specified
当我将 DNS 添加到 ingress
时:
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal CreateCertificate 4s cert-manager Successfully created Certificate "example-cert"
答案,第 2 部分(关于入口、证书和颁发者)
如果您在 ingress
规则中引用 issuer
,则无需创建证书。提供所有详细信息后,Ingress 将为您颁发证书,例如:
- 注解
cert-manager.io/cluster-issuer: "hello-deployment-tls"
spec.tls
在 内与主机分离
spec.rules.host
或
如果您想手动创建证书并要求 ingress 使用它,则:
- 删除注释
cert-manager.io/cluster-issuer: "hello-deployment-tls"
- 手动创建证书
- 在
ingress rule
中引用它。
您可以在浏览器中查看证书详细信息,发现它不再有颁发者 CN = Kubernetes Ingress Controller Fake Certificate
,在我的例子中它是空的。
注意 - 证书管理器 v1.4
最初我使用了有点过时的 cert-manager v1.4
并得到了 this issue 更新到 1.4.1
.
后就消失了
看起来像:
$ kubectl describe certificaterequest selfsigned-certificate2-45k2c
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal cert-manager.io 41s cert-manager Certificate request has been approved by cert-manager.io
Warning DecodeError 41s cert-manager Failed to decode returned certificate: error decoding certificate PEM block
有用链接:
我正在尝试使用 Cert-Manager 在我的 AKS 群集中添加自签名证书。
我为 CA 证书创建了一个 ClusterIssuer
(用于签署证书),并为我要使用的证书(自签名)创建了第二个 ClusterIssuer
。
我不确定 certificate2
是否被 Ingress 正确使用,因为它看起来像是在等待某个事件。
我这样做的方式是否正确?
这是第一个 ClusterIssuer
"clusterissuer.yml":
apiVersion: cert-manager.io/v1alpha2
kind: ClusterIssuer
metadata:
name: selfsigned
spec:
selfSigned: {}
这是 CA 证书“certificate.yml”:
apiVersion: cert-manager.io/v1alpha2
kind: Certificate
metadata:
name: selfsigned-certificate
spec:
secretName: hello-deployment-tls-ca-key-pair
dnsNames:
- "*.default.svc.cluster.local"
- "*.default.com"
isCA: true
issuerRef:
name: selfsigned
kind: ClusterIssuer
这是我要使用的证书的第二个ClusterIssuer
“clusterissuer2.yml”:
apiVersion: cert-manager.io/v1alpha2
kind: ClusterIssuer
metadata:
name: hello-deployment-tls
spec:
ca:
secretName: hello-deployment-tls-ca-key-pair
最后这是自签名证书“certificate2.yml”:
apiVersion: cert-manager.io/v1alpha2
kind: Certificate
metadata:
name: selfsigned-certificate2
spec:
secretName: hello-deployment-tls-ca-key-pair2
dnsNames:
- "*.default.svc.cluster.local"
- "*.default.com"
isCA: false
issuerRef:
name: hello-deployment-tls
kind: ClusterIssuer
我在 Ingress 中使用此证书:
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx
cert-manager.io/cluster-issuer: "hello-deployment-tls"
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
name: sonar-ingress
spec:
tls:
- secretName: "hello-deployment-tls-ca-key-pair2"
rules:
- http:
paths:
- pathType: Prefix
path: "/"
backend:
serviceName: sonarqube
servicePort: 80
因为我没有任何注册域名,所以我只想使用 public IP 访问 https://<Public_IP>
上的服务。
当我访问该服务时 https://<Public_IP>
我可以看到“Kubernetes Ingress Controller Fake Certificate”所以我猜这是因为该证书不能被浏览器全局识别。
怪事来了。理论上 Ingress 部署正在使用 selfsigned-certificate2
但看起来它还没有准备好:
kubectl get certificate
NAME READY SECRET AGE
selfsigned-certificate True hello-deployment-tls-ca-key-pair 4h29m
selfsigned-certificate2 False hello-deployment-tls-ca-key-pair2 3h3m
selfsigned-secret True selfsigned-secret 5h25m
kubectl describe certificate selfsigned-certificate2
.
.
.
Spec:
Dns Names:
*.default.svc.cluster.local
*.default.com
Issuer Ref:
Kind: ClusterIssuer
Name: hello-deployment-tls
Secret Name: hello-deployment-tls-ca-key-pair2
Status:
Conditions:
Last Transition Time: 2021-10-15T11:16:15Z
Message: Waiting for CertificateRequest "selfsigned-certificate2-3983093525" to complete
Reason: InProgress
Status: False
Type: Ready
Events: <none>
有什么想法吗?
提前致谢。
Api 版本
首先我注意到您正在使用 v1alpha2
apiVersion,它已被删除并将在 1.6
cert-manager:
$ kubectl apply -f cluster-alpha.yaml
Warning: cert-manager.io/v1alpha2 ClusterIssuer is deprecated in v1.4+, unavailable in v1.6+; use cert-manager.io/v1 ClusterIssuer
我在复制中使用了apiVersion: cert-manager.io/v1
。
与 v1beta1
入口相同,考虑将其更新为 networking.k8s.io/v1
。
会发生什么
我开始逐步重现您的设置。
我申请了clusterissuer.yaml
:
$ kubectl apply -f clusterissuer.yaml
clusterissuer.cert-manager.io/selfsigned created
$ kubectl get clusterissuer
NAME READY AGE
selfsigned True 11s
注意READY
设置为True
。
下一个我申请了certificate.yaml
:
$ kubectl apply -f cert.yaml
certificate.cert-manager.io/selfsigned-certificate created
$ kubectl get cert
NAME READY SECRET AGE
selfsigned-certificate True hello-deployment-tls-ca-key-pair 7s
下一步 是添加第二个 ClusterIssuer
引用 hello-deployment-tls-ca-key-pair
秘密:
$ kubectl apply -f clusterissuer2.yaml
clusterissuer.cert-manager.io/hello-deployment-tls created
$ kubectl get clusterissuer
NAME READY AGE
hello-deployment-tls False 6s
selfsigned True 3m50
ClusterIssuer hello-deployment-tls
未 就绪。原因如下:
$ kubectl describe clusterissuer hello-deployment-tls
...
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning ErrGetKeyPair 10s (x5 over 75s) cert-manager Error getting keypair for CA issuer: secret "hello-deployment-tls-ca-key-pair" not found
Warning ErrInitIssuer 10s (x5 over 75s) cert-manager Error initializing issuer: secret "hello-deployment-tls-ca-key-pair" not found
这是预期行为,因为:
When referencing a Secret resource in ClusterIssuer resources (eg apiKeySecretRef) the Secret needs to be in the same namespace as the cert-manager controller pod. You can optionally override this by using the --cluster-resource-namespace argument to the controller.
答案-如何前进
我编辑了 cert-manager
部署,因此它将在 default
命名空间中查找 secrets
(这并不理想,我会在 default
命名空间):
$ kubectl edit deploy cert-manager -n cert-manager
spec:
containers:
- args:
- --v=2
- --cluster-resource-namespace=default
cert-manager
大约需要一分钟才能启动。重新部署 clusterissuer2.yaml
:
$ kubectl delete -f clusterissuer2.yaml
clusterissuer.cert-manager.io "hello-deployment-tls" deleted
$ kubectl apply -f clusterissuer2.yaml
clusterissuer.cert-manager.io/hello-deployment-tls created
$ kubectl get clusterissuer
NAME READY AGE
hello-deployment-tls True 3s
selfsigned True 5m42s
两者都是READY
。与 certificate2.yaml
一起前进:
$ kubectl apply -f cert2.yaml
certificate.cert-manager.io/selfsigned-certificate2 created
$ kubectl get cert
NAME READY SECRET AGE
selfsigned-certificate True hello-deployment-tls-ca-key-pair 33s
selfsigned-certificate2 True hello-deployment-tls-ca-key-pair2 6s
$ kubectl get certificaterequest
NAME APPROVED DENIED READY ISSUER REQUESTOR AGE
selfsigned-certificate-jj98f True True selfsigned system:serviceaccount:cert-manager:cert-manager 52s
selfsigned-certificate2-jwq5c True True hello-deployment-tls system:serviceaccount:cert-manager:cert-manager 25s
入口
当 host
未添加到 ingress
时,它不会创建任何证书并且似乎使用了 ingress
中由 CN = Kubernetes Ingress Controller Fake Certificate
颁发的一些假证书.
来自 ingress
的事件:
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning BadConfig 5s cert-manager TLS entry 0 is invalid: secret "example-cert" for ingress TLS has no hosts specified
当我将 DNS 添加到 ingress
时:
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal CreateCertificate 4s cert-manager Successfully created Certificate "example-cert"
答案,第 2 部分(关于入口、证书和颁发者)
如果您在 ingress
规则中引用 issuer
,则无需创建证书。提供所有详细信息后,Ingress 将为您颁发证书,例如:
- 注解
cert-manager.io/cluster-issuer: "hello-deployment-tls"
spec.tls
在 内与主机分离
spec.rules.host
或
如果您想手动创建证书并要求 ingress 使用它,则:
- 删除注释
cert-manager.io/cluster-issuer: "hello-deployment-tls"
- 手动创建证书
- 在
ingress rule
中引用它。
您可以在浏览器中查看证书详细信息,发现它不再有颁发者 CN = Kubernetes Ingress Controller Fake Certificate
,在我的例子中它是空的。
注意 - 证书管理器 v1.4
最初我使用了有点过时的 cert-manager v1.4
并得到了 this issue 更新到 1.4.1
.
看起来像:
$ kubectl describe certificaterequest selfsigned-certificate2-45k2c
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal cert-manager.io 41s cert-manager Certificate request has been approved by cert-manager.io
Warning DecodeError 41s cert-manager Failed to decode returned certificate: error decoding certificate PEM block