Ingress使⽤
1.Nginx Ingress简介
Kubernetes 通过 kube-proxy 服务实现了 Service 的对外发布及负载均衡,它的各种⽅式都是基于传输层实现的。在实际的互联⽹应⽤场景中,不仅要实现单纯的转发,还有更加细致的策略需求,如果使⽤真正的负载均衡器更会增加操作的灵活性和转发性能。
基于以上需求,Kubernetes 引⼊了资源对象 Ingress,Ingress 为 Service 提供了可直接被集外部访问的虚拟主机、负载均衡、SSL 代理、HTTP 路由等应⽤层转发功能。
Kubernetes 官⽅发布了基于 GCE 和 Nginx 的 Ingress 控制器,Nginx Ingress 控制器能根据 Service 中 Pod 的变化动态地调整配置,结合 Nginx 的⾼稳定性、⾼性能、⾼并发处理能⼒等特点,使 Kubernetes 对集中运⾏于容器的应⽤程序具有了更加灵活的应⽤层管理能⼒。
Nginx Ingress 因使⽤ Nginx 的不同版本,分为 Nginx 官⽅版本和 Kubernetes 社区版。Nginx 官⽅版本提供其基于Go语⾔开发的 Ingress 控制器,并与 Nginx 集成分为 Nginx 开源版和 Nginx Plus 版;开源版仅基于 Nginx 的原始功能,提供了 Nginx 原⽣配置指令的⽀持,相较于 Nginx Plus 版功能简单且不⽀持 Pod 变化的动态变更。
Nginx Plus 版则提供了诸多完善的商业功能,其⽀持 Nginx 原⽣配置指令、JWT 验证、Pod 变化的动态配置及主动健康检查等功能。Kubernetes 社区版是基于Nginx 的扩展版 OpenResty 及诸多第三⽅模块构建的,其基于 OpenResty 的 Lua 嵌⼊式编程能⼒,扩展了 Nginx 的功能,并基于 balancer_by_lua 模块实现了Pod 变化的动态变更功能。本节介绍的是基于 Kubernetes 社区版的 Nginx Ingress。
1.1 Nginx Ingress原理
Nginx Ingress 由资源对象 Ingress、Ingress 控制器、Nginx 三部分组成,Ingress 控制器⽤以将 Ingress 资源实例组装成 Nginx 配置⽂件(f),并重新加载 Nginx 使变更的配置⽣效。当它监听到 Service 中 Pod 变化时通过动态变更的⽅式实现 Nginx 上游服务器组配置的变更,⽆须重新加载 Nginx 进程。⼯作原理如下图所⽰。
Ingress,⼀组基于域名或 URL 把请求转发到指定 Service 实例的访问规则,是 Kubernetes 的⼀种资源对象,Ingress 实例被存储在对象存储服务 etcd 中,通过接⼝服务被实现增、删、改、查的操作。
Ingress 控制器(Ingress controller),⽤以实时监控资源对象 Ingress、Service、End-point、Secret(主要是 TLS 证书和 Key)、Node、ConfigMap 的变化,⾃动对 Nginx 进⾏相应的操作。
Nginx,实现具体的应⽤层负载均衡及访问控制。
图:Nginx Ingress⼯作原理
Ingress 控制器通过同步循环机制实时监控接⼝服务 Ingress 等资源对象的变化,当相关 Service 对应的端点列表有变化时,会通过 HTTP POST 请求将变化信息发送到 Nginx 内部运⾏的 Lua 程序进⾏处理,实现对 Nginx Upstream 中后端 Pod IP 变化的动态修改。
每个后端 Pod 的 IP 及 targetPort 信息都存储在 Nginx 的共享内存区域,Nginx 对每个获取的请求将使⽤配置的负载均衡算法进⾏转发,Nginx 的配置中应⽤Lua 模块的 balancer_by_lua 功能实现 upstream 指令域的动态操作,Pod IP 变化及资源对象 Ingress 对 upstream 指令域相关注解(annotation)的变化⽆须执⾏Nginx 的 reload 操作。
当 Ingress 控制器监控的其他资源对象变化时,会对当前变化的内容创建 Nginx 配置模型,如果新的配置模型与当前运⾏的 Nginx 配置模型不⼀致,则将新的配置模型按照模板⽣成新的 Nginx 配置,并对 Nginx 执⾏ reload 操作。
Nginx 配置模型避免了 Nginx 的⽆效 reload 操作。为避免因 Nginx 配置语法错误导致意外中断,Ingress 控制器为 Nginx 的配置内容提供了冲突检测及合并机制,Ingress 控制器使⽤了准⼊控制插件(Validating Admission Webhook)做验证 Ingress 配置语法的准⼊控制,验证通过的 Ingress 资源对象才会被保存在存储服务 etcd 中,并被 Ingress 控制器⽣成确保没有语法错误的 Nginx 配置⽂件。
1.2 集成的第三⽅模块
Kubernetes 的 Nginx Ingress 当前版本是 0.25.1,其集成了 Nginx 的扩展版本 Open-Resty 的 1.15.8.1 版本,OpenResty 的最⼤特点是集成了 Lua 脚本的嵌⼊式编程功能,基于 Nginx 的优化,使 Nginx 具有更强的扩展能⼒。
Nginx Ingress 通过 Lua 脚本编程,利⽤ OpenResty 的 balancer_by_lua 模块,可通过 nginx-ingress 控制器动态地修改 Nginx 上游服务器组的配置,⽆须Nginx 进程的热加载,有效地解决了因 Pod 调度带来的 Pod IP 变化的问题。
Kubernetes 的 Nginx Ingress 在 OpenResty 基础上还集成了诸多的第三⽅模块,模块功能介绍如下。
1) Ajp协议模块(nginx_ajp_module)
Ajp 协议模块是⼀个使 Nginx 实现 Ajp 协议代理的模块,该模块可以使 Nginx 通过 Ajp 协议连接到被代理的 Tomcat 服务。
2) InfluxDB输出模块(nginx-influxdb-module)
InfluxDB 输出模块可以使 Nginx 的每次请求记录以 InfluxDB 作为后端进⾏存储,其以⾮阻塞的⽅式对每个请求进⾏过滤,并使⽤ UDP 协议将处理后的数据发送到 InfluxDB 服务器。可以通过该模块实时监控 Nginx 的所有请求,获得每个请求的连接类型、请求状态,并通过 InfluxDB 实现相关故障状态的报警。
3) GeoIP2数据库模块(ngx_http_geoip2)
MaxMind 的 GeoIP 数据库已经升级到第⼆代,GeoIP2 数据库提供了准确的 IP 信息,包括 IP 地址的位置(国家、城市、经纬度)等数据。该模块增加了GeoIP2 数据的⽀持。
4) 摘要认证模块(nginx-http-auth-digest)
摘要认证模块使 Nginx 的基本认证功能增加了摘要认证(Digest Authentication)的⽀持,这是⼀种简单的⾝份验证机制,是对基本认证的⼀种安全改进,仅通过服务端及客户端根据⽤户名和密码计算的摘要信息进⾏验证,避免了密码的明⽂传递,增加了认证过程的安全性。
5) 内容过滤模块(ngx_http_substitutions_filter_module)
内容过滤模块是⼀个内容过滤功能的模块,其相对于 Nginx ⾃带的内容过滤模块(ngx_http_sub_module)增加了正则匹配的替换⽅式。
6) 分布式跟踪模块(nginx-opentracing)
OpenTracing 由 API 规范、实现该规范的框架和库以及项⽬⽂档组成,是⼀个轻量级的标准化规范,其位于应⽤程序和跟踪分析程序之间,解决了不同分布式追踪系统API不兼容的问题。OpenTracing 允许开发⼈员使⽤ API 向应⽤程序代码中添加⼯具,实现业务应⽤中的分布式请求跟踪。
分布式请求跟踪,也称分布式跟踪,是⼀种⽤于分析和监视应⽤程序的⽅法,特别是那些使⽤微服务体系结构构建的应⽤程序。分布式跟踪有助于查明故障发⽣的位置以及导致性能低下的原因。该模块是将 Nginx 的请求提供给 OpenTracing 项⽬的分布式跟踪系统⽤于应⽤的请求分析和监控。
Nginx Ingress 中集成了 jaeger 和 zipkin 两种分布式跟踪系统的 OpenTracing 项⽬插件,⽤户可根据实际情况进⾏选择使⽤。
7) Brotli压缩模块(ngx_brotli)
Brotli 是 Google 推出的侧重于 HTTP 压缩的⼀种开源压缩算法,它使⽤ lz77 算法的现代变体、Huffman 编码和基于上下⽂的⼆阶建模的组合来压缩数据。在与Deflate 相似的压缩与解压缩速度下,增加了 20% 的压缩密度。在与 gzip 的测试下,因压缩密度⾼其消耗的压缩时间要⽐ gzip 多,但在客户端解压的时间则相当。
8) ModSecurity连接器模块(ModSecurity-nginx)
ModSecurity 是⼀个开源的 Web 应⽤防⽕墙,其主要作⽤是增强 Web 应⽤的安全性并保护 Web 应⽤免受攻击。模块 ModSecurity-nginx 是⼀个 Nginx 的ModSecurity 连接器,其提供了 Nginx 和 libmodsecurity(ModSecurity v3)之间的通信通道。Nignx Ingress 中已经集成了 ModSecurity 和 OWASP 规则集,在 Nginx 配置⽂件⽬录可以查看相关配置。
9) lua-resty-waf模块
lua-resty-waf 是⼀个基于 OpenResty 的⾼性能 Web 应⽤防⽕墙,它使⽤ Nginx Lua API 及灵活的规则架构分析和处理 HTTP 请求信息,并不断开发和测试⼀些⾃定义的规则补丁来应对不断出现的新的安全威胁。lua-resty-waf 提供了 ModSecurity 兼容的规则语法,⽀持 ModSecurity 现有规则的⾃动转换,⽤户⽆须学习新的语法规则就可以扩展 lua-resty-waf 的规则。
2.Nginx Ingress安装部署
2.1 HELM⽅式安装部署
Helm 是⼀个⾮常⽅便的 Kubernetes 应⽤部署⼯具,⽀持 Nginx Ingress 的快速部署和卸载。通过 Helm 可快速将 Nginx Ingress 部署在 Kubernetes 集
中,Helm 中 Nginx Ingress 的 1.19.1 版本 Chart 部分参数如下表所⽰。
参数参数值选项默认值功能说明
pe ClusterIP 或 NodePort 或 LoadBalancer LoadBalancer设置资源对象 Service 的服务类型
controller.hostNetwork true 或 false false设置资源对象 Pod 是否以 hostNet-work⽅式运⾏
alIPs----设置资源对象 Service externalIPs 的 IP 地址
controller.kind Deployment 或 Daemon-Set Deployment设置部署⽅式
al-TrafficPolicy Local 或 Cluster Cluster设置 Pod 流量调度⽅式
abled true 或 false false是否启⽤多副本⽀持,启⽤后最⼩副本数为 1,最⼤值为 11 controller.autoscaling.min-Replicas--1设置创建的最⼩副本数
helm install --name nginx-ingress stable/nginx-ingress --ate=true
具体说明如下:
Helm 安装的应⽤名称为 nginx-ingress;
Nginx Ingress 以 Pod 形式运⾏在 Kubernetes 集中,⽤户可根据 Kubernetes 的⽹络通信特点以及实际场景选择灵活的部署⽅式进⾏ Nginx Ingress 的部署,此处分别以基于资源对象 Service 的 NodePort ⽅式和 Pod 的 hostNetwork ⽅式举例介绍。
1) Service的NodePort⽅式
以 NodePort 类型部署 Nginx Ingress,需要使⽤参数进⾏指定 pe 为 NodePort。为便于管理,可以为 Nginx Ingress 创建单独使⽤的命名空间 nginx-ingress,部署拓扑如下图所⽰。
图:NodePort⽅式
部署命令如下:
# 安装nginx-ingress
helm install --name nginx-ingress \
--namespace nginx-ingress \
stable/nginx-ingress \
--set "ate=true,abled=true,controller. autoscaling.minReplicas=2,pe=NodePort,alTrafficPolicy=Local"
# 也可以在创建后调整副本数
kubectl scale --replicas=3 deployment/nginx-ingress
具体说明如下:
Helm 安装的应⽤名称为 nginx-ingress,命名空间为 nginx-ingress;
nginx 配置文件以默认的 Deployment ⽅式部署,设置 Pod 副本数为 2,并以 Service 的 NodePort ⽅式对外发布服务,设置流量调度策略为 Local;
Kubernetes 将为 nginx-ingress Service 随机创建范围在 30000~32767 之间的 Node-Port 端⼝;
⽤户将 Kubernetes 中节点 IP 和 NodePort ⼿动添加到传输层负载均衡中的虚拟服务器集中;
外部请求发送到传输层负载均衡虚拟服务器,传输层负载将请求数据转发到 Kubernetes 集节点的 NodePort;
NodePort 类型的 Service 将请求负载到对应的 Nginx Pod;
Nginx 将⽤户请求进⾏应⽤层负载转发到配置的应⽤ Pod;
在该部署⽅式下,Nginx Pod 需要使⽤ Local 的流量调度策略,获取客户端的真实 IP。
2) Pod的hostNetwork⽅式
主机⽹络(hostNetwork)⽅式可以使 Pod 与宿主机共享⽹络命名空间,外⽹传输效率最⾼。因 Pod
直接暴露外⽹,虽然存在⼀定的安全问题,但不存在客户端源 IP 隐藏的问题,部署拓扑如下图所⽰。
图:hostNetwork⽅式
部署命令如下:
# 以Deployment⽅式部署
helm install --name nginx-ingress \
--namespace nginx-ingress \
stable/nginx-ingress \
--set "ate=true,pe=ClusterIP,controller. hostNetwork=true"
具体说明如下:
Deployment ⽅式部署时,Nginx Ingress 的 Service 设置类型为 ClusterIP,仅提供内部服务端⼝;
⽤户将 Kubernetes 中节点 IP 及 80、443 端⼝⼿动添加到传输层负载均衡中的虚拟服务器集中;
⽤户请求经传输层负载均衡设备转发到 Nginx,Nginx 将⽤户请求负载到 Kubernetes 集内的 Pod 应⽤。
也可以使⽤ DaemonSet 部署⽅式,在集中的每个节点⾃动创建并运⾏⼀个 Nginx Ingress Pod,实现 Nginx Ingress 的⾃动扩展。
# 以DaemonSet⽅式部署nginx-ingress并成为集唯⼀⼊⼝
helm install --name nginx-ingress \
--namespace nginx-ingress \
stable/nginx-ingress \
--set "ate=true,controller.kind=DaemonSet,pe=ClusterIP,controller.hostNetwork=true"
3) SSL终⽌(SSL Termination)和SSL透传(SSL Passthrough)
SSL 终⽌模式下,客户端的 TLS 数据会在代理服务器 Nginx 中解密,解密的数据由代理服务器直接
或再次 TLS 加密后传递给被代理服务器,这种模式下,相对增加代理服务器的计算负担,但⽅便了 SSL 证书的统⼀管理。
SSL 透传模式下,Nginx 不会对客户端的 HTTPS 请求进⾏解密,加密的请求会被直接转发到后端的被代理服务器,这种⽅式常被应⽤到后端的 HTTPS 服务器需要对客户端进⾏客户端证书验证的场景,相对也会降低 Nginx 对 TLS 证书加解密的负担。由于请求数据是保持加密传输的,HTTP 消息头将⽆法修改,所以消息头字段 X-forwarded-* 的客户端 IP ⽆法被添加。Nginx Ingress 默认部署⽅式没有开启 SSL 透传的⽀持,需要在部署时使⽤参数 --enable-ssl-passthrough 进⾏开启。
# 修改部署资源对象nginx-ingress-controller
kubectl edit Deployment/nginx-ingress-controller -n nginx-ingress
# 在规范部分添加容器启动参数--enable-ssl-passthrough
spec:
containers:
- args:
- /nginx-ingress-controller
- --default-backend-service=nginx-ingress/nginx-ingress-default-backend
- --election-id=ingress-controller-leader
- --ingress-class=nginx
- --configmap=nginx-ingress/nginx-ingress-controller
- --enable-ssl-passthrough
4) 卸载Nginx Ingress
Nginx 的配置是以资源对象 ConfigMap 和 Ingress ⽅式存储在 etcd 服务中的,所以即便删除或重新部署 Nginx Ingress 也不会影响之前的配置。
helm delete --purge nginx-ingress
2.2 ⼿动⽅式安装部署
⼿动⽅式不做过多解释,简单来说到想要安装的版本,直接应⽤其中的mandatory.yaml即可,当然,也可以根据⾃⼰的需求更改yaml⽂件
3.Nginx Ingress配置映射ConfigMap
通过 Helm 安装 Nginx Ingress 的默认关联配置映射实例名称为 nginx-ingress-controller,⽤户可以通过修改资源对象 Deployment/DaemonSet 实例 nginx-ingress-controller 中的参数 --configmap ⾃定义关联配置映射实例的名称。
当然,⼿动增加configmap,只要写上对应的ingress的labels也可以。
Nginx Ingress 控制器约定 Nginx Ingress 配置映射实例中的键值只能是字符串,即便是数字或布尔值时也要以字符串的形式书写,⽐如 "true"、"false"、"100","[]string" 或 "[]int" 的 Slice 类型则表⽰内部数据是以 "," 分隔的字符串。根据配置涉及的功能可以有如下分类。
3.1 Nginx原⽣配置指令
⽤以提供向 Nginx 配置中添加 Nginx 原⽣配置指令,功能说明如下表所⽰。
名称类型默认值功能描述
main-snippet string""在 main 指令域添加 Nginx 配置指令
http-snippet string""在 http 指令域添加 Nginx 配置指令
server-snippet string""在 server 指令域添加 Nginx 配置指令
location-snippet string""在 location 指令域添加 Nginx 配置指令
配置样例如下:
echo '
apiVersion: v1
kind: ConfigMap
data:
http-snippet: |
ancient_browser "UCWEB";
ancient_browser_value oldweb;
server {
listen 8080;
if ($ancient_browser) {
rewrite ^ /${ancient_browser}.html; # 重定向到oldweb.html
}
}
metadata:
name: nginx-ingress-controller
namespace: nginx-ingress
' | kubectl create -f -
3.2 通⽤配置
提供 Nginx 核⼼配置相关配置指令的配置,功能说明如下表所⽰。
名称类型默认值Nginx 指令功能描述
worker-processes string auto worker_processes参见《》⼀节
worker-cpu-affinity string""worker_cpu_affinity参见《》⼀节
worker-shutdown-timeout string10s worker_shutdown_timeout参见《》⼀节
max-worker-connections string--worker_connections参见《》⼀节
max-worker-open-files string--worker_rlimit_nofile参见《》⼀节
enable-multi-accept bool true multi_accept参见《》⼀节
keep-alive int75keepalive_timeout--
keep-alive-requests int100keepalive_requests--
variables-hash-bucket-size int128variables_hash_bucket_size--
variables-hash-max-size int2048variables_hash_max_size--
server-name-hash-max-size int1024server_names_hash_max_size--
server-name-hash-bucket-size int
CPU 缓存⾏的⼤
⼩
server_names_hash_bucket_size--
map-hash-bucket-size int64map_hash_bucket_size--
bind-address[]string""listen设置虚拟主机绑定的 IP 地址
reuse-port bool true listen设置监听端⼝启⽤ reuseport 参数,由 Linux 内核以套接字分⽚⽅式实
现进程调度
disable-ipv6bool false listen--
disable-ipv6-dns bool false resolver设置是否关闭域名解析的 IPv6 地址查
enable-underscores-in-
headers
bool false underscores_in_headers参见《》⼀节
ignore-invalid-headers bool true ignore_invalid_headers参见《》⼀节
client-header-buffer-size string1k client_header_buffer_size参见《》⼀节
client-header-timeout int60client_header_timeout参见《》⼀节
client-body-buffer-size string8k client_body_buffer_size参见《》⼀节
client-body-timeout int69client_body_timeout参见《》⼀节
large-client-header-buffers string 4 8k large_client_header_buffers参见《》⼀节
http-redirect-code int308return设置 URL 跳转时的响应码,可选项为 301,302,307 和 308
use-geoip bool true--启⽤ geoip 功能
use-geoip2bool false--启⽤ geoip2 功能,由第三⽅模块实现
nginx-status-ipv4-whitelist[]string127.0.0.1--设置允许访问路径 /nginx_status 的 IPv4 地址
nginx-status-ipv6-whitelist[]string::1--设置允许访问路径 /nginx_status 的 IPv6 地址server-tokens bool true server_tokens参见《》⼀节
lua-shared-dicts string""--设置 Lua 共享内存字典,Oper_Resty 扩展指令 配置样例如下:
cat>test.yaml<<EOF
apiVersion: v1
kind: ConfigMap
data:
keep-alive: "60"
disable-ipv6: "true"
metadata:
name: nginx-ingress-controller
namespace: nginx-ingress
EOF
kubectl create -f test.yaml
3.3 响应数据配置
提供响应信息头修改及响应数据压缩相关功能的配置,功能说明如下表所⽰。
名称类型默认值Nginx指令功能描述
add-headers string""add_header--
use-gzip bool true gzip启⽤ gzip
gzip-level int5gzip_comp_level参见《》⼀节
gzip-types string application/atom+xml application/javascript application/x-javascript
application/json application/rss+xml application/vnd.ms-fontobject
application/x-font-ttf application/x-web-app-manifest+json
application/xhtml+xml application/xml font/opentype
image/svg+xml image/x-icon text/css text/java-script text/plain
text/x-component
gzip_types参见《》⼀节
enable-brotli bool false--设置是否加载 brotli 模块brotli-level int4--设置 brotli 的压缩级别
brotli-types string application/xml+rss application/atom+xml application/javascript
application/x-javascript application/json applica-tion/rss+xml
application/vnd.ms-fontobject application/x-font-ttf
application/x-web-app-manifest+json application/xhtml+xml
application/xml font/opentype image/svg+xml image/x-icon
text/css text/javascript text/plain text/x-com-ponent
--设置 brotli 的压缩类型
3.4 访问控制
提供限制连接数、访问速度、访问连接及防⽕墙的配置,功能说明如下表所⽰。
名称类型默认值Nginx 指令功能描述
limit-conn-zone-variable string$binary_remote_addr limit_conn_zone参见《》⼀节
limit-conn-status-code int503limit_conn_status参见《》⼀节
limit-rate int0limit_rate--
limit-rate-after int0limit_rate_after--
limit-req-status-code int503limit_req_status参见《》⼀节
whitelist-source-range[]string []string{}--allow设置允许访问的源 IP 地址
block-cidrs[]string""deny禁⽌设置 IP 地址的访问
block-user-agents[]string""map禁⽌设置信息头字段 User-Agent 匹配值的访问block-referers[]string""map禁⽌设置信息头字段 Referer 匹配值的访问enable-modsecurity bool false--设置是否加载 Mod-Security 连接模块
enable-owasp-modsecurity-crs bool false--设置是否加载 OWASP ModSecurity 核⼼规则库
3.5 HTTPS配置
提供与 HTTPS 相关的配置,功能说明如下表所⽰。
名称类型默认值Nginx指令功能描述
ssl-ciphers string ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-
AES256-GCM-SHA384:
ECDHE-ECDSA-CHACHA20-POLY-1305:ECDHE-RSA-
CHACHA20-POLY1305:
ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-
AES128-GCM-SHA256:
ECDHE-ECDSA-AES256-SHA-384:ECDHE-RSA-
AES256-SHA384:ECDHE-ECDSA
-AES-128-SHA256:ECDHE-RSA-AES-128-SHA256
ssl-ciphers参见《》⼀节
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论