让我们加密发布假证书的 kubernetes 入口控制器
Posted
技术标签:
【中文标题】让我们加密发布假证书的 kubernetes 入口控制器【英文标题】:Let's Encrypt kubernetes Ingress Controller issuing Fake Certificate 【发布时间】:2019-08-02 19:36:53 【问题描述】:不确定为什么我会收到假证书,即使证书是由 Let's Encrypt 使用 certmanager
正确颁发的设置在阿里云ECS控制台上运行,一个Kube-master和一个cube-minion组成一个Kubernetes集群。
服务详情
root@kube-master:~# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 3h20m
my-nginx ClusterIP 10.101.150.247 <none> 80/TCP 77m
Pod 详细信息
root@kube-master:~# kubectl get pods --show-labels
NAME READY STATUS RESTARTS AGE LABELS
my-nginx-6cc48cd8db-n6scm 1/1 Running 0 46s app=my-nginx,pod-template-hash=6cc48cd8db
Helm Cert-manager 已部署
root@kube-master:~# helm ls
NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE
cert-manager 1 Tue Mar 12 15:29:21 2019 DEPLOYED cert-manager-v0.5.2 v0.5.2 kube-system
kindred-garfish 1 Tue Mar 12 17:03:41 2019 DEPLOYED nginx-ingress-1.3.1 0.22.0 kube-system
证书颁发正确
root@kube-master:~# kubectl describe certs
Name: tls-prod-cert
Namespace: default
Labels: <none>
Annotations: <none>
API Version: certmanager.k8s.io/v1alpha1
Kind: Certificate
Metadata:
Creation Timestamp: 2019-03-12T10:26:58Z
Generation: 2
Owner References:
API Version: extensions/v1beta1
Block Owner Deletion: true
Controller: true
Kind: Ingress
Name: nginx-ingress-prod
UID: 5ab11929-44b1-11e9-b431-00163e005d19
Resource Version: 17687
Self Link: /apis/certmanager.k8s.io/v1alpha1/namespaces/default/certificates/tls-prod-cert
UID: 5dad4740-44b1-11e9-b431-00163e005d19
Spec:
Acme:
Config:
Domains:
zariga.com
Http 01:
Ingress:
Ingress Class: nginx
Dns Names:
zariga.com
Issuer Ref:
Kind: ClusterIssuer
Name: letsencrypt-prod
Secret Name: tls-prod-cert
Status:
Acme:
Order:
URL: https://acme-v02.api.letsencrypt.org/acme/order/53135536/352104603
Conditions:
Last Transition Time: 2019-03-12T10:27:00Z
Message: Order validated
Reason: OrderValidated
Status: False
Type: ValidateFailed
Last Transition Time: <nil>
Message: Certificate issued successfully
Reason: CertIssued
Status: True
Type: Ready
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal CreateOrder 27s cert-manager Created new ACME order, attempting validation...
Normal IssueCert 27s cert-manager Issuing certificate...
Normal CertObtained 25s cert-manager Obtained certificate from ACME server
Normal CertIssued 25s cert-manager Certificate issued successfully
入口详情
root@kube-master:~# kubectl describe ingress
Name: nginx-ingress-prod
Namespace: default
Address:
Default backend: my-nginx:80 (192.168.123.202:80)
TLS:
tls-prod-cert terminates zariga.com
Rules:
Host Path Backends
---- ---- --------
* * my-nginx:80 (192.168.123.202:80)
Annotations:
kubernetes.io/ingress.class: nginx
kubernetes.io/tls-acme: true
certmanager.k8s.io/cluster-issuer: letsencrypt-prod
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal CREATE 7m13s nginx-ingress-controller Ingress default/nginx-ingress-prod
Normal CreateCertificate 7m8s cert-manager Successfully created Certificate "tls-prod-cert"
Normal UPDATE 6m57s nginx-ingress-controller Ingress default/nginx-ingress-prod
Letsencrypt Nginx 生产定义
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: nginx-ingress-prod
annotations:
kubernetes.io/ingress.class: nginx
certmanager.k8s.io/cluster-issuer: letsencrypt-prod
kubernetes.io/tls-acme: 'true'
labels:
app: 'my-nginx'
spec:
backend:
serviceName: my-nginx
servicePort: 80
tls:
- secretName: tls-prod-cert
hosts:
- zariga.com
【问题讨论】:
您使用的是哪个 DNS 提供商?您也可以发布您的 yaml 文件吗? DNS 提供者是 Godaddy 一些事情,您使用的是 http01,正如我在您的证书描述中看到的那样?还有一件事需要注意的是,如果旧的不存在,证书只会创建 tls 秘密。因此,如果您刚刚从 staging 切换到 prod URL,请删除该密钥。 【参考方案1】:也许会对遇到类似问题的人有所帮助。至于我,忘记在 Ingress yaml 文件中为 rules
和 tls
部分指定主机名。
复制主机名后,它开始响应正确的证书。
例子:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: test-web-ingress
annotations:
kubernetes.io/ingress.class: nginx
spec:
tls:
- hosts:
- my.host.com # <----
secretName: tls-secret
rules:
- host: my.host.com # <----
http:
paths:
- path: /
pathType: Prefix
backend:
serviceName: my-nginx
servicePort: 80
【讨论】:
这正是我的情况。谢谢你的回答!【参考方案2】:如果您使用 clusterissuer URL 作为暂存 URL,有时可能会发生这种情况。
检查在 issuer.yaml 或 clusterissuer.yaml 中设置的letsencrypt url并将其更改为生产url:https://acme-v02.api.letsencrypt.org/directory
我曾经遇到过同样的问题,将 url 更改为生产 url 解决了它。
还要检查您使用的入口 tls 机密是否正确。
实际的集群发行者应该类似于生产环境:
apiVersion: cert-manager.io/v1alpha2
kind: ClusterIssuer
metadata:
name: dev-clusterissuer
spec:
acme:
email: harsh@example.com
privateKeySecretRef:
name: dev-clusterissuer
server: https://acme-v02.api.letsencrypt.org/directory # <----check this server URL it is for Prod and use this only
solvers:
- http01:
ingress:
class: nginx
如果您使用 server: https://acme-staging-v02.api.letsencrypt.org/directory 您将面临问题,最好将其替换为 server: https://acme-v02.api.letsencrypt.org/directory
【讨论】:
这对其他人来说是有用的建议,但从问题中的屏幕截图来看,OP 似乎没有临时证书。如果是,它会将组织显示为(STAGING) Let's Encrypt
。
是的,如果入口假证书错误 tls 进入入口配置甚至暂存让我们加密证书丢失并且未正确设置为秘密。【参考方案3】:
如果您确信一切设置正确但仍然无法正常工作,请尝试此操作。
编辑 nginx 控制器的部署。为什么?因为,如果它在部署它的命名空间中找不到秘密,Nginx 控制器就会部署它自己的证书(假证书)。不知道这一点(我是游戏新手)花了我几天的时间。
因此,要么更改 Nginx Ingress 控制器所在的命名空间并获取部署的名称,然后:
kubectl edit deployment nginx-ingress-ingress-nginx-controller -n nginx-ingress
或者,如果该命名空间中只有一个部署,您可以这样做
kubectl edit deployment
您的 nginx 控制器部署应该处于编辑模式。查找以下部分:规范 --> 容器:--> args:
spec:
containers:
- args:
- /nginx-ingress-controller
- --publish-service=$(POD_NAMESPACE)/nginx-ingress-ingress-nginx-controller
- --election-id=ingress-controller-leader
- --ingress-class=nginx
- --configmap=$(POD_NAMESPACE)/nginx-ingress-ingress-nginx-controller
- --validating-webhook=:8443
- --validating-webhook-certificate=/usr/local/certificates/cert
- --validating-webhook-key=/usr/local/certificates/key
- --default-ssl-certificate=app-namespace/letsencrypt-cert-prod
如果你的 nginx 控制器没有找到一个默认证书(如我上面所说),你可以添加一个要使用的默认证书,因此它将通过添加以下内容在命名空间中搜索一个秘密:
--default-ssl-certificate=your-cert-namespace/your-cert-secret
your-cert-namespace:证书密码所在的命名空间 your-cert-secret:包含机密的证书的名称
保存并关闭编辑器后,它应该会更新。然后检查您的证书管理器 pod 的日志:
kubectl logs cert-manager-xxxpodxx-abcdef -n cert-manager
确保一切正常。
如果您的所有资源都部署在同一个命名空间中,您可能不会遇到此问题。
【讨论】:
【参考方案4】:需要注意的是,求解器的 ClusterIssuer 规范发生了变化。对于使用cer-manager>0.7.2
的人,这条评论为我节省了很多时间:https://github.com/jetstack/cert-manager/issues/1650#issuecomment-518953464。特别是关于如何配置 ClusterIssuer 和 Certificate。
【讨论】:
【参考方案5】:对我来说,问题是入口类名称,因为我使用的是 microk8s,入口类名称是 public
:
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
email: "your@email.tld"
privateKeySecretRef:
name: letsencrypt-prod
server: "https://acme-v02.api.letsencrypt.org/directory"
solvers:
- http01:
ingress:
class: public
【讨论】:
【参考方案6】:在我的情况下,问题是在错误的端口访问域,我的默认 https 端口不是 443 而是 4443
【讨论】:
【参考方案7】:对我来说,问题是我忘记了 kubectl apply
的秘密(在我的情况下是 'tls-secret.yml'
)。手动部署 K8S 时,很少会出现这样的错误。不过我是用gitlab CICD部署应用的,忘记加- kubectl apply -f ./kube/secret
我的.gitlab-ci.yml
了。
【讨论】:
以上是关于让我们加密发布假证书的 kubernetes 入口控制器的主要内容,如果未能解决你的问题,请参考以下文章