让我们加密发布假证书的 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 文件中为 rulestls 部分指定主机名。 复制主机名后,它开始响应正确的证书。

例子:

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&gt;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 入口控制器的主要内容,如果未能解决你的问题,请参考以下文章

JupyterHub自动HTTPS Letsencrypt:Kubernetes Ingress控制器假证书

让我们加密证书、Python 和 Windows

证书固定和转换 isrg-root 让我们加密

在 JAVA API 上使用时让我们加密证书不起作用

Let's Encrypt证书安装

存储traefik让我们加密证书而不是json