一、背景

同事在对某公司进行华为CCE k8s容器应用部署时,遇到了客户没有使用默认ELB Ingress,而需要使用Nginx Ingress的情况,而Nginx Ingress想要使用后面 ClusterIP 来暴漏服务,而不是使用 Nodeport。

先说下什么是Ingress?Ingress是Kubernetes集群中一种独立的资源,制定了集群外部访问流量的转发规则。用户可根据域名和路径对转发规则进行自定义,完成对访问流量的细粒度划分。service为四层负载均衡,Ingress提供了七层负载均衡能力。

二、华为云CCE两种Ingress的对比

华为CCE 两种Ingress对后端service的支持情况:

Ingress Type Access Type ClusterIP NodePort
ELB Ingress LoadBalancer Not supported Supported
ELB Ingress ENI LoadBalancer Supported Not supported
Nginx Ingress LoadBalancer Supported Supported
Nginx Ingress ENI LoadBalancer Supported Not supported

可以看出 Nginx Ingress 在使用非 ENI 网络的情况下对 ClusterIP 和 Nodeport 都是支持的。而其在运维、性能、组件部署等方面的对比见下表:

特性 ELB Ingress Controller Nginx Ingress Controller
运维 免运维,更新升级由华为云负责 自行安装、升级、维护
性能 一个Ingress支持一个ELB实例 多个Ingress只支持一个ELB实例
性能 使用企业级LB,高性能高可用,升级、故障等场景不影响业务转发 性能依赖pod的资源配置
性能 支持配置动态加载 更新配置需reload,可能会造成业务中断
组件部署 Master节点,不占用工作节点 Worker节点,需要Nginx组件运行成本
路由重定向 不支持 支持
SSL配置 支持 支持

参考页面:ELB ingress 和 Nginx Ingress对比

三、配置 Nginx Ingress 对接 ClusterIP

由于CCE的界面化做的很不错(尤其是上一个版本的UI,真心话当前升级过的UI值得吐槽,不如之前的),这里ClusterIP的配置就略过了,直接看结果:

cce-services-clusterip
cce-services-clusterip

一会儿我们就用这个服务来和 Nginx Ingress 对接:

cce-nginx-ingress
cce-nginx-ingress

Nginx Ingress的启用比较简单,打开连接nginx的开关就可以了,这样默认就会使用的nginx ingress,后面也会讲命令行的配置方法。

四、启用HTTPS

HTTPS的启用会分三种情况:

  1. Nginx Ingress 启用HTTPS
  2. 后端 Pod 应用使用HTTPS
  3. 两者都使用HTTPS

Nginx Ingress 启用HTTPS

生成证书和私钥

1$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ${KEY_FILE} -out ${CERT_FILE} -subj "/CN=${HOST}/O=${HOST}" -addext "subjectAltName = DNS:${HOST}"
2$ kubectl create secret tls ${CERT_NAME} --key ${KEY_FILE} --cert ${CERT_FILE}
3
4比如:
5$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout nginx.key -out nginx.crt -subj "/CN=361way/O=mykey" -addext "subjectAltName = DNS:361way"
6$ kubectl create secret tls sslkey--key nginx.key --cert nginx.crt

参考页面:ingress-nginx开启https认证

后端应用启用HTTPS

后端是HTTPS时,需要使用 annotations 指明后端使用的是HTTPS,不然前端 Nginx Ingress 会报502错误,因为其后端请求默认请求的是HTTP的地址。即使前端 Nginx Ingress 使用了HTTPS也没有用,因为前后端不影响(后端 pod 应用启用HTTPS后,前端请求即使用HTTP请求,也会显示为HTTPS)。

 1apiVersion: networking.k8s.io/v1
 2kind: Ingress
 3metadata:
 4  name: ingress-test
 5  namespace: default
 6  annotations:
 7    nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
 8spec:
 9  tls:
10    - secretName: ingress-test-secret  #替换为您的TLS密钥证书
11  rules:
12    - host: ''
13      http:
14        paths:
15          - path: '/'
16            backend:
17              service:
18                name: <your_service_name>  #替换为您的目标服务名称
19                port:
20                  number: <your_service_port>  #替换为您的目标服务端口
21            property:
22              ingress.beta.kubernetes.io/url-match-mode: STARTS_WITH
23            pathType: ImplementationSpecific
24  ingressClassName: nginx

如果是在界面化配置的时候,可以参看第三部分(配置 Nginx Ingress 对接 ClusterIP)的第二张图。当然如果刚开始使用了HTTP,想通过YAML文件更新,也可以参看下下图:

https-annotations
https-annotations

Nginx Ingress对接HTTPS协议的后端服务