Kubernetes 如何使用 aws 证书

Submitted by Lizhe on Thu, 09/19/2019 - 01:48

这个问题来自于Sting哥,Sting哥昨天下午跑上来问了这样一个问题

  • 他使用ingress
  • 他使用aws证书
  • 他的后端服务是基于 http 的
  • 他希望前端浏览器访问到服务endpoint的时候是https的
  • 他的ingress安装 type 指向的是 AWS CLB

 

百度和Google上竟然都没有明确手顺描述这个问题,而且他就是跑不起来,错误如下

 

400 Bad Request

The plain HTTP request was sent to HTTPS port

openresty/1.15.8.1

20190919101835

问题分析:

这个错误以前我只在 后端 endpoint 是 https 的时候见过,就是说 浏览器 - LB - ingress - clusterip service - backend 访问过程中 https 请求不知道在哪一层被转换成了 http ,然后到达了后端的 https 端口

但是这一次,Sting 哥的后端是 http 的, 理论上不存在这个问题

我手里的既存系统中没有类似的架构,我本地的 aws 证书只在 rancher 控制台上使用,中间没有 ingress 

而我本地使用ingress的https服务都是基于 cert manager 做的,没有使用aws证书

而且我的ingress绑定的都是 node 节点的 ip , 但是Sting的环境中 master 节点是 AWS EKS,并且所有node节点都是私有网络,也就是说无 public ip 可用

 

他的全部服务都是通过 ingress 安装的 LB 调用的,看了半天实在看不出问题在哪,只能从头自己做一个helloworld了

我重新创建一个单节点集群,不过这里因为rancher自带了 ingress,我删除之前的自带的ingress然后使用helm重新安装一个新的,指定类型是 CLB

 

20190919104348

 

然后我们创建一套用来测试的应用和服务

测试用的回声nginx服务器部署描述文件

apiVersion: apps/v1beta1

kind: Deployment

metadata:

  name: nginx-deployment

  namespace: study

spec:

  replicas: 2

  template:

    metadata:

      labels:

        app: nginx

    spec:

      containers:

      - name: nginx

        image: mendhak/http-https-echo

        ports:

        - containerPort: 80

 

 

对应的 service 服务

apiVersion: v1

kind: Service

metadata: 

  name: nginx-service-clusterip

  namespace: study

spec:

  type: ClusterIP

  ports:

    - port: 80

  selector: 

    app: nginx

 

 

然后是ingress描述文件

apiVersion: extensions/v1beta1

kind: Ingress

metadata:

  name: test-nginx-ingress

  namespace: study

  annotations:

    kubernetes.io/ingress.class: "nginx"

spec:

  rules:

  - host: test.xxxx.com

    http:

      paths:

      - backend:

          serviceName: nginx-service-clusterip

          servicePort: 80

 

 

当前结构中,你可以直接通过 http 的 80端口访问服务,不过我们最终要实现的是 https 然后绑定 aws的证书

这里因为我只是为了测试,所以我创建了一个新的二级证书,直接使用根证书也是可以的

20190919123040

 

绑定证书到 CLB

20190919123311

 

然后我们在 Route53中创建一个对应的二级域名,并且指向到这个 LB

20190919123711

 

此时你已经可以直接通过 http 80 端口 + 域名 test.xxxxxxx.com 访问到这个nginx了,但是这并不是我们想要的,我们需要的是 https

试一下https, 之前的错误果然出现了

20190919123311

这个时候其实问题已经很清楚了,负载均衡器中 SSL 端口实际上需要转发到 80 端口对应的 32660,

也就是要改成

 

20190919124138

 

 

最终结构有点类似像下面这个样子

20190919125215

 

如果不需要的话把 LB 的 TCP 转发删除掉,在这个结构里实际上如果不使用 aws 证书,在ingress上使用 cert manager 也不错,毕竟是免费的

总之为了避免不必要的麻烦,http 和 https 交互的时候一定要思路清晰 需要在哪一层 上做转换。

直接访问 http

20190919010428

 

访问 https

20190919010720