K8S之Ingress-Nginx
Ingress诞生背景
我们都知道Service的表现形式为IP:Port,工作在TCP/IP层。对于基于HTTP的服务来说,不同的URL地址经常对应到不同的后端服务或者虚拟服务器,这些应用层的转发机制仅通过kubernetes的Service机制是无法实现的。
因此就有了Ingress将不同URL的访问请求转发到后端不同的Service,以实现HTTP层的业务路由机制。
Ingress 是对集群中服务的外部访问进行管理的 API 对象,典型的访问方式是 HTTP和HTTPS。可以提供负载均衡、SSL 和基于名称的虚拟托管
Pod和ingress的关系
- 通过Service关联Pod
- 基于域名访问
- 通过Ingress controller实现Pod的负载
- 支持TCP/UDP四层和HTTP七层
Ingress-Nginx工作原理
- ingress controller,它是一个nginx控制器,通过和kubernetes api交互,动态的去感知集群中ingress规则变化,
- 然后读取它,按照自定义的规则,规则就是写明了哪个域名对应哪个service,生成一段nginx配置,
- 再写到nginx-ingress-controller的pod里,这个Ingress controller的pod里运行着一个Nginx服务,控制器会把生成的nginx配置写入/etc/nginx.conf文件中,
- 然后reload一下使配置生效。以此达到域名分别配置和动态更新的问题。
- 访问的端口是不会发生改变,访问域名+端口的形式进行负载,不识别IP+port的形式访问
- 默认对外暴露的端口是80和443
ingress-nginx会创建一个NodePort类型的service,暴露端口提供给外部访问。
通过ingress策略的改变(比如:增加一个域名解析,解析不同的集群内部的service),ingress controller会监听APIserver的变化,发生变化以后会在ingress controller(本质是一个在ingress-nginx空间下的pod)动态更新nginx的配置文件,增加nginx的域名解析条数。到达动态更新配置的目的。(一个ingress规则实例化对象就是一个域名)
Ingress-nginx的构成
Ingress-nginx由两部分组成:Ingress Controller 和 **Ingress **
- Ingress 这个玩意,简单的理解就是 你原来要改 Nginx 配置,然后配置各种域名对应哪个 Service,现在把这个动作抽象出来,变成一个 Ingress 对象,你可以用 yml 创建,每次不要去改 Nginx 了,直接改 yml 然后创建/更新就行了;那么问题来了:”Nginx 咋搞?”
- Ingress Controller 这东西就是解决 “Nginx 咋搞” 的;Ingress Controoler 通过与 Kubernetes API 交互,动态的去感知集群中 Ingress 规则变化,然后读取他,按照他自己模板生成一段 Nginx 配置,再写到 Nginx Pod 里,最后 reload 一下,工作流程如下图
在实际应用中,最新版本 Kubernetes 已经将 Nginx 与 Ingress Controller 合并为一个组件,所以 Nginx 无需单独部署,只需要部署 Ingress Controller 即可
Ingress-nginx作用
- 动态配置服务
如果按照传统方式, 当新增加一个服务时, 我们可能需要在流量入口加一个反向代理指向我们新的k8s服务. 而如果用了Ingress-nginx, 只需要配置好这个服务, 当服务启动时, 会自动注册到Ingress的中, 不需要而外的操作。 - 减少不必要的端口映射
配置过k8s的都清楚, 第一步是要关闭防火墙的, 主要原因是k8s的很多服务会以NodePort方式映射出去, 这样就相当于给宿主机打了很多孔, 既不安全也不优雅. 而Ingress可以避免这个问题, 除了Ingress自身服务可能需要映射出去, 其他服务都不要用NodePort方式
部署 Ingress-Nginx
1.下载Ingress-nginx
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.18.0/deploy/mandatory.yaml
2.创建 Ingress - Nginx
kubectl apply -f mandatory.yaml # 生成ingress-nginx的pod
kubectl get pods -n ingress-nginx
NAME READY STATUS RESTARTS AGE
nginx-ingress-controller-7995bd9c47-7vvfd 1/1 Running 0 5h5m
kubectl apply -f service-nodeport.yaml # 生成一个nodeport类型的service,提供给外部用户方式
kubectl get service -n ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx NodePort 10.106.240.167 <none> 80:31839/TCP,443:30704/TCP 5h5m
3.测试
curl http://10.106.240.167 # ip来自上一步
# 如果返回404则表示安装成功
<