一、Ingress对象基本原理
Ingress作为一个K8S的资源对象,为了解决集群之外访问内部Service服务的问题。所以,Ingress主要提供反向代理与负载均衡的功能,其功能框架如图所示:
其中,在K8S集群中,Ingress Controller通过读取Ingress配置信息,并根据配置信息初始化或重新加载Nginx反向代理服务器。当用户请求request到达时,ingerss可以根据已配置的路由转发规则,将请求根据不同的path路径转发到响应的service服务中。Service主要在逻辑层面管理相同功能的一组Pod服务,Pod即服务的基本单元,负责根据request请求完成对应功能并返回response响应。Pod部署的过程中可以通过多种方式添加ConfigMap配置。
二、Ingress组件部署
想要在K8S集群中使用Ingress,首先需要在K8S集群中部署Ingress插件。 Ingress的部署过程如下:
1、Ingress组件包括Ingress Service、Ingress Controller与Controller管理下的两个Pod。
2、根据官方部署手册,基于yaml文件部署Ingress Service、Controller与Pod。
wget raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.2.0/deploy/static/provider/cloud/deploy.yaml kubectl apply -f deploy.yaml |
3、通过kubectl get svc,deploy,podes 查看各组件的部署状态与部署结果。
三、Ingress的使用与配置Https证书认证
当集群中有一个正常工作的Ingress controller后,可以使用Ingress完成反向代理并对代理的资源进行TLS配置。对此,我们使用实际的示例演示Ingress对象创建使用和Https证书认证过程。
3.1 Ingress反向代理对象创建
在实际应用中,可以基于yaml文件和kubctl命令行两种方式创建Ingress对象,但通常使用yaml文件进行创建,基本的对象配置信息示例格式如下:
spec: backend: 全局默认后端。若不匹配任何规则的请求,都会代理到默认后端 serviceName: service的名称。要将请求代理到哪个Service上 servicePort: service的端口 rules: 定义入站流量的转发规则 host: 第一条规则,检查入站流量是否匹配此处定义的域名 http: paths: path: 第二条规则,检查入站流量的URI路径,是否匹配此处定义的path(省略即为"/") backend: 自定义后端。所有入站流量都会先匹配host与path规则,当两个都匹配时,才会将流量代理到下面定义的service上,否则会发送到默认backend serviceName: servicePort: tls: 配置HTTPS |
根据ingress对象配置格式,本文以yaml文件的方式创建hello-app-ingress对象进行反向代理,写入代理规则。使用的yaml文件如下 通过kubectl apply部署ingress对象,完成对Service的代理,可以通过kubectl get ing 命令查看部署情况。
3.2 Ingress添加证书认证
使用ingress进行证书认证的基本要求是有SSL/TLS证书,可以通过几种图途径来获取SSL/TLS证书:
1、自签名机构:使用自己的证书颁发机构来创建和签名TLS证书,并把证书分享给团队内成员,比较适合开发环境,
2、购买TLS证书:从知名证书颁发机构购买,他们已经在浏览器和操作系统中完成认证。
3、使用Letsencrpt证书:从非盈利可信证书办法机构Letsencrpt处免费获取。
Ingress主要通过Ingress controller从ingress配置信息中找到tls.crt和tls.key文件并载入TLS配置。在请求到达时,通过反向代理服务器nginx.conf动态地处理和验证。主要流程如下图所示:
在此,通过实际演示,给出Ingress的TLS证书具体应用流程:
1、通过证书颁发机构获取TLS证书tls.crt和tls.key(自签名证书)
# 根据域名创建rootCA.key和rootCA.crt > openssl req -x509 -sha256 -days 356 -nodes -newkey rsa:2048 -subj "/CN=demo.test.com/C=US/L=San Fransisco" -keyout rootCA.key -out rootCA.crt > openssl genrsa -out server.key 2048 # 创建服务端私钥 > openssl genrsa -out server.key 2048 # 创建证书签名请求配置文件 > cat > csr.conf <<EOF # 使用服务器私钥生成证书签名请求 > openssl req -new -key server.key -out server.csr -config csr.conf # 创建外部文件 > cat > cert.conf <<EOF # 生成SSL证书和自签名CA > openssl x509 -req -in server.csr -CA rootCA.crt -CAkey rootCA.key -CAcreateserial -out server.crt -days 365 -sha256 -extfile cert.conf # 证书生成结果 |
2、通过Deployment、Service部署服务
创建yaml文件,通过kubectl apply -f 进行部署
3、创建Secret资源对象,引入tls证书文件tls.crt和tls.key
> kubectl create secret -n defalut tls nginx-tls --namespace defalut --key server.key --cert server.crt |
4、在Ingress对象配置文件中,通过secretName将tls绑定Secret资源对象。
5、curl demo.test.com -kv验证证书信息
四、Ingress Nginx配置文件
Ingress作为对K8S集群外部请求公开服务的组件,在网络协议栈中的应用层工作,能够根据请求的主机名和路径决定转发到对应服务容器中。Ingress Controller可以动态生成Nginx配置文件,我们通过Ingress实例的部署,查看Nginx文件变化情况。
在Ingress组件启动前,默认Nginx的配置文件主要包括
1)user指定用户和用户组、worker_processes指定工作进程数、events指定工作模式和连接限制等。
2)在http配置规则中进行server的配置,每个Server监控不同的端口。
3)在server中配置location,根据不同的path路径完成转发,实现反向代理、重定向、路径重写等功能。
events { worker_connections 1024; } http { keepalive_timeout 65; server { listen 80; server_name localhost; location / { root html; index index.html index.htm; } error_page 500 502 503 504 /50x.html; location /xx { } } server { } } |
Ingress组件启动后,Ingress-Nginx配置文件主要包括
1)通过<lua_package_path "/etc/nginx/lua/?.lua;;">引入lua脚本完成动态配置的刷新。
2)init_by_lua_block初始化资源lua_ingress、configuration、balancer、monitor、certificate、plugins
3)补充变量、资源约束、资源路径、数据压缩、地域信息转换、日志格式、SSL认证信息、性能优化等配置
4)在upstream upstream_balancer中通过lua配置负载均衡规则
5)defalut server:给出默认server,在location中,配置基于lua的路径重写、header、body过滤规则、上游服务器、超时时间、版本信息等。此外,加入健康检查/healthz与状态检测/nginx_status功能。
6)server:根据ingress文件中配置的server信息,构建server。如,加入域名demo.hello.com对应的server。
7)stream:通过stream进行tcp/udp数据流的代理,流量转发和负载均衡。
http { lua_shared_dict xxx ; init_by_lua_block{ xxx } init_worker_by_lua_block{ xxx } map $http_upgrade $connection_upgrade { default upgrade; } ssl_xxx ; upstream upstream_balancer{ balancer_by_lua_block } Server{ Location / { header_filter_by_lua_block{ xxx } body_filter_by_lua_block{ xxx } proxy_set_xxx ; } location /healthz { xxx } location /nginx_status { xxx } } Server{ server_name demo.hello.com; Location / { header_filter_by_lua_block{ xxx } body_filter_by_lua_block{ xxx } proxy_set_xxx ; } } } stream { init_by_lua_block{ xxx } init_worker_by_lua_block{ xxx } upstream upstream_balancer { xxx } server { xxx } # TCP services # UDP services } |