无法让kubernetes将我的tls证书传递给浏览器

时间:2018-08-14 04:02:32

标签: ssl nginx kubernetes

我一直在努力尝试让HTTPS访问Kubernetes中的Elasticsearch集群。

认为问题是Kubernetes不喜欢我尝试使用的TLS证书,这就是为什么它没有一直传递到浏览器的原因。

一切似乎都可以正常工作,因为当我接受Kubernetes入口控制器伪造证书时,请求将按预期进行。

为此,我进行了以下设置:

  • 集群本身
  • nginx控件
  • 入口资源

这是相关的Yaml:

  • 集群:

    apiVersion: v1
    kind: Service
    metadata:
        creationTimestamp: 2018-08-03T03:20:47Z
    labels:
        run: my-es
    name: my-es
    namespace: default
    resourceVersion: "3159488"
    selfLink: /api/v1/namespaces/default/services/my-es
    uid: 373047e0-96cc-11e8-932b-42010a800043
    spec:
        clusterIP: 10.63.241.39
    ports:
        - name: http
    port: 8080
    protocol: TCP
    targetPort: 9200
    selector:
        run: my-es
    sessionAffinity: None
    type: ClusterIP
    status:
        loadBalancer: {}
    
  • 入口资源

    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
        annotations:kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/cors-allow-methods: PUT, GET, POST, OPTIONS
    nginx.ingress.kubernetes.io/cors-origins: http://localhost:3425 https://mydomain.ca
        https://myOtherDomain.ca
            nginx.ingress.kubernetes.io/enable-cors: "true"
    nginx.ingress.kubernetes.io/rewrite-target: /
    creationTimestamp: 2018-08-12T08:44:29Z
    generation: 16
    name: es-ingress
    namespace: default
    resourceVersion: "3159625"
    selfLink: /apis/extensions/v1beta1/namespaces/default/ingresses/es-ingress
    uid: ece0071d-9e0b-11e8-8a45-42001a8000fc
    spec:
        rules:
            - http:
    paths:
        - backend:
    serviceName: my-es
    servicePort: 8080
    path: /
    tls:
        - hosts:
    - mydomain.ca
    secretName: my-tls-secret
    status:
        loadBalancer:
            ingress:
                - ip: 130.211.179.225
    
  • nginx-inress控制器:

    apiVersion: v1
    kind: Service
    metadata:
      creationTimestamp: 2018-08-12T00:41:32Z
      labels:
        app: nginx-ingress
        chart: nginx-ingress-0.23.0
        component: controller
        heritage: Tiller
        release: nginx-ingress
      name: nginx-ingress-controller
      namespace: default
      resourceVersion: "2781955"
      selfLink: /api/v1/namespaces/default/services/nginx-ingress-controller
      uid: 755ee4b8-9dc8-11e8-85a4-4201a08000fc
    spec:
      clusterIP: 10.63.250.256
      externalTrafficPolicy: Cluster
      ports:
      - name: http
        nodePort: 32084
        port: 80
        protocol: TCP
        targetPort: http
      - name: https
        nodePort: 31182
        port: 443
        protocol: TCP
        targetPort: https
      selector:
        app: nginx-ingress
        component: controller
        release: nginx-ingress
      sessionAffinity: None
      type: LoadBalancer
    status:
      loadBalancer:
        ingress:
        - ip: 35.212.6.131
    

我觉得我缺少基本的东西,因为似乎很难暴露出这么简单的东西……

要获取我的证书,我刚刚从Godaddy申请了mydomain.ca的证书。

我是否需要使用入口资源的群集IP作为通用名称来获取证书?

似乎无法验证IP所有权。

我见过人们提到Kubernetes自动为入口资源创建证书的方法,但是这些似乎是自签名的。

以下是来自Nginx控制器的一些日志:

这是在谈论带有tls-secret的PEM,但这只是一个警告。

{
 insertId:  "1kvvhm7g1q7e0ej"
 labels: {
  compute.googleapis.com/resource_name:  "fluentd-gcp-v2.0.17-5b82n"
  container.googleapis.com/namespace_name:  "default"
  container.googleapis.com/pod_name:  "nginx-ingress-controller-58f57fc597-zl25s"
  container.googleapis.com/stream:  "stderr"
 }
 logName:  "projects/project-7d320/logs/nginx-ingress-controller"
 receiveTimestamp:  "2018-08-14T02:58:42.135388365Z"
 resource: {
  labels: {
   cluster_name:  "my-elasticsearch-cluster"
   container_name:  "nginx-ingress-controller"
   instance_id:  "2341889542400230234"
   namespace_id:  "default"
   pod_id:  "nginx-ingress-controller-58f57fc597-zl25s"
   project_id:  "project-7d320"
   zone:  "us-central1-a"
  }
  type:  "container"
 }
 severity:  "WARNING"
 textPayload:  "error obtaining PEM from secret default/my-tls-cert: error retrieving secret default/my-tls-cert: secret default/my-tls-cert was not found"
 timestamp:  "2018-08-14T02:58:37Z"
}

我发生过几次握手错误,这可能是上次警告的结果...

{
 insertId:  "148t6rfg1xmz978"
 labels: {
  compute.googleapis.com/resource_name:  "fluentd-gcp-v2.0.17-5b82n"
  container.googleapis.com/namespace_name:  "default"
  container.googleapis.com/pod_name:  "nginx-ingress-controller-58f57fc597-zl25s"
  container.googleapis.com/stream:  "stderr"
 }
 logName:  "projects/project-7d320/logs/nginx-ingress-controller"
 receiveTimestamp:  "2018-08-14T15:55:52.438035706Z"
 resource: {
  labels: {
   cluster_name:  "my-elasticsearch-cluster"
   container_name:  "nginx-ingress-controller"
   instance_id:  "2341889542400230234"
   namespace_id:  "default"
   pod_id:  "nginx-ingress-controller-58f57fc597-zl25s"
   project_id:  "project-7d320"
   zone:  "us-central1-a"
  }
  type:  "container"
 }
 severity:  "ERROR"
 textPayload:  "2018/08/14 15:55:50 [crit] 1548#1548: *860 SSL_do_handshake() failed (SSL: error:1417D18C:SSL routines:tls_process_client_hello:version too low) while SSL handshaking, client: 127.0.0.1, server: 0.0.0.0:442"
 timestamp:  "2018-08-14T15:55:50Z"
}

以上日志使我的tls密码似乎无法正常工作,但是当我运行kubectl描述入口时,它说我的密码终止了。

aaronmw@project-7d320:~$ kubectl describe ing
Name:             es-ingress
Namespace:        default
Address:          130.221.179.212
Default backend:  default-http-backend:80 (10.61.3.7:8080)
TLS:
  my-tls-secret terminates mydomain.ca
Rules:
  Host  Path  Backends
  ----  ----  --------
  *
        /   my-es:8080 (<none>)
Annotations:
Events:  <none>

1 个答案:

答案 0 :(得分:2)

我知道了!

我最终要做的是使用以下命令在创建时向我的nginx-ingress控制器添加默认的ssl证书

helm install --name nginx-ingress --set controller.extraArgs.default-ssl-certificate=default/search-tls-secret stable/nginx-ingress

一旦有了该证书,它就会按预期方式通过证书,但是由于CN与我的负载均衡器IP不匹配,我仍然使用了错误的证书。

所以我所做的是:

  • 使我的负载均衡器IP保持静态
  • 将A记录添加到我的域,以将子域映射到该IP
  • 重新密钥我的证书以匹配该新子域

我在做生意!

感谢@Crou,他的评论提醒我查看日志,使我处在正确的轨道上。