1.Ingress基本介绍
1.1 暴露服务问题
k8s 集群对外暴露服务的方式有三种:
NotePort
LoadBalance
- Ingress
- NodePort方式:最大的缺点是会占用很多集群机器的端口,而且需要在外部搭建额外的负载均衡;
- LB方式:最大的缺点则是每个service一个LB,有点浪费,并且需要k8s之外的支持,【eg:cloud provider】;
- ingress: Ingress就是为了解决1,2两种方式的限制,只需要一个NodePort或者一个LB就可以满足所有
service
对外服务的需求。
1.2 什么是Ingress
官网地址:GitHub - kubernetes/ingress-nginx: Ingress-NGINX Controller for Kubernetes
Ingress 是 k8s 官方提供的用于对外暴露服务的方式,也是在生产环境用的比较多的方式,一般情况是 LB + Ingress Ctroller 方式对外提供服务,这样就可以在一个 LB 的情况下根据域名路由到对应后端的 Service
类似于 Nginx 反向代理,只不过在 k8s 集群中,这个反向代理是集群外部流量的统一入口。
Ingress 公开了从集群外部到集群内 services 的访问路由。
流量路由,由 Ingress 资源上定义的规则控制。
特点:
- Ingress 是对集群中服务的外部访问进行管理的 API 对象,典型的访问方式是 HTTP和HTTPS。
- Ingress 提供负载均衡、SSL 和基于名称的虚拟托管。
- 必须具有 ingress 控制器【例如 ingress-nginx】才能满足 Ingress 的要求。仅创建 Ingress 资源无效。
可以理解为:
Ingress 是一个规则的集合,它允许集群外的流量通过一定的规则到达集群内的 Service
1.2 Ingress的核心组件
Ingress由三个组件组成:
- ingress
- ingress-controller
- 反向代理负载均衡器
1.2.1 ingress
可以理解为:是一个类型为Ingress
的k8s api对象
一般用yaml配置,作用是定义请求如何转发到service的规则,可以理解为配置模板。
- 是规则集合
- 定义了域名与Kubernetes的service的对应关系
- 规则与 Ingress Controller 结合, Ingress Controller 将其动态写入到负载均衡器配置中,从而实现整体的服务发现和负载均衡。
1.2.2 ingress-controller
kubernetes API 进行交互,实时的感知后端 service、pod 等变化
Ingress Controller 再结合下文的 Ingress 生成配置,然后更新反向代理负载均衡器,并刷新其配置,实现动态服务发现与更新
其核心是一个deployment,实现方式有很多如:
- nginx
- Contour
- Haproxy
- trafik
- Istio
需要编写的yaml有:Deployment, Service, ConfigMap, ServiceAccount(Auth)
其中service的类型可以是NodePort或者LoadBalancer。
实现反向代理及负载均衡的程序,对ingress定义的规则进行解析,根据配置的规则来实现请求转发
总结一下:
Ingress-controller才是负责转发的组件,通过各种方式将他暴露在集群入口,外部对集群的请求流量会先到Ingress-controller,
而Ingress对象是用来告诉Ingress-controller该如何转发请求,比如那些域名那些path要转发到那些服务
1.2.3 反向代理负载均衡器
即常见的负载均衡软件,如 nginx、Haproxy 等
2.安装
2.1 下载/修改配置文件
下载整合配置文件,获取配置文件地址:
ingress-nginx/deploy/static at nginx-0.30.0 · kubernetes/ingress-nginx · GitHub
主要是这两个文件:
service-nodeport.yaml为ingress通过nodeport对外提供服务,注意默认nodeport暴露端口为随机,可以编辑该文件自定义端口。
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/mandatory.yaml
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/provider/baremetal/service-nodeport.yaml
具体位置截图:
2.2 安装资源
应用yml文件创建ingress资源:,执行下面两个命令:
kubectl apply -f mandatory.yaml kubectl apply -f service-nodeport.yaml
2.3 结果
执行以下命令,查看结果:
kubectl get all -n ingress-nginx -o wide
可以看到,结果如下:
总结一下:
Ingress Contronler 通过与 Kubernetes API 交互,动态感知集群中 Ingress 规则变化,然后读取它,按照自定义的规则,规则就是写明了哪个域名对应哪个service,生成一段 Nginx 配置,再写到 Nginx-ingress-control的 Pod 里,
这个 Ingress Contronler 的pod里面运行着一个nginx服务,控制器会把生成的nginx配置写入/etc/nginx.conf文件中,然后 reload 一下 使用配置生效。进而达到域名分配置及动态更新的问题。
2.4 项目示例
2.4.1 创建service及deployment
apiVersion: apps/v1 kind: Deployment metadata: labels: app: test-nginx name: test-nginx spec: replicas: 3 #3个副本 minReadySeconds: 5 #等待5秒后升级 selector: matchLabels: app: test-nginx template: metadata: labels: app: test-nginx spec: containers: - image: nginx name: test-nginx --- apiVersion: v1 kind: Service metadata: name: test-nginx labels: app: test-nginx spec: ports: - port: 80 targetPort: 80 selector: app: test-nginx
2.4.2创建Ingress规则
# ingress规则中,要指定需要绑定暴露的svc名称 apiVersion: extensions/v1beta1 kind: Ingress metadata: name: ingress-test-nginx annotations: kubernetes.io/ingress.class: "nginx" # 指定 Ingress Controller 的类型 nginx.ingress.kubernetes.io/use-regex: "true" # 指定我们的 rules 的 path 可以使用正则表达式 nginx.ingress.kubernetes.io/proxy-connect-timeout: "600" # 连接超时时间,默认为 5s nginx.ingress.kubernetes.io/proxy-send-timeout: "600" # 后端服务器回转数据超时时间,默认为 60s nginx.ingress.kubernetes.io/proxy-send-timeout: "600" # 后端服务器响应超时时间,默认为 60s nginx.ingress.kubernetes.io/proxy-body-size: "10m" # 客户端上传文件,最大大小,默认为 20m spec: rules: #定义路由规则 - host: www.testnginx.com # 主机名,只能是域名,修改为项目域名 http: paths: - path: / backend: serviceName: test-nginx # 后台部署的 Service Name servicePort: 80 # 后台部署的 Service Port
2.4.3 完整文件
apiVersion: apps/v1 kind: Deployment metadata: labels: app: test-nginx name: test-nginx namespace: test spec: replicas: 3 #3个副本 minReadySeconds: 5 #等待5秒后升级 selector: matchLabels: app: test-nginx template: metadata: labels: app: test-nginx spec: containers: - image: nginx name: test-nginx --- apiVersion: v1 kind: Service metadata: name: test-nginx namespace: test labels: app: test-nginx spec: ports: - port: 80 targetPort: 80 selector: app: test-nginx --- apiVersion: extensions/v1beta1 kind: Ingress metadata: name: ingress-test-nginx namespace: test annotations: kubernetes.io/ingress.class: "nginx" # 指定 Ingress Controller 的类型 nginx.ingress.kubernetes.io/use-regex: "true" # 指定我们的 rules 的 path 可以使用正则表达式 nginx.ingress.kubernetes.io/proxy-connect-timeout: "600" # 连接超时时间,默认为 5s nginx.ingress.kubernetes.io/proxy-send-timeout: "600" # 后端服务器回转数据超时时间,默认为 60s nginx.ingress.kubernetes.io/proxy-send-timeout: "600" # 后端服务器响应超时时间,默认为 60s nginx.ingress.kubernetes.io/proxy-body-size: "10m" # 客户端上传文件,最大大小,默认为 20m spec: rules: #定义路由规则 - host: www.testnginx.com # 主机名,只能是域名,修改为项目域名 http: paths: - path: / backend: serviceName: test-nginx # 后台部署的 Service Name servicePort: 80 # 后台部署的 Service Port
应用yaml文件:
kubectl apply -f test-nginx-ingress.yaml
执行命令,查看结果,会看到已经生成了对应的ingress-test-nginx 已经生成:
kubectl get ingress -n test