Ingress资源配置
# Ingress控制器介绍
# Ingress控制器介绍
Ingress控制器是七层调度器,而Service只是四层调度器。
四层调度器只能解析OSI模型的下四层,它的优点是处理速度相较七层更快,但缺点是只支持HTTP协议,而不支持HTTPS协议。 而七层调度器七能解析OSI模型的所有层,它支持HTTPS。
Ingress控制器不受控制器管理器所管理,它是自己独立运行的一个或一组Pod,它通常就是一个有七层代理、七层调度能力的应用程序,比如Nginx、Traefik(常用于微服务)、Envoy等。
我们可以把Ingress当成集群版的Nginx。
# Ingress控制器实现方式
它是作为调度器Pod构建在某些节点上,且每个节点只运行一个,所以要用到DaemonSet控制器。
该调度器Pod需要能够引入外部流量,然后才能对其流量进行调度。
首选必须有一个外部负载均衡器来调度外部流量,需要能够调度流量到多个调度器Pod中。
我们可以通过将这些调度器Pod运行为共享节点,使能够直接不通过Service接收外部流量,在Pod的配置中设置HostNetwork,就可以实现将Pod的端口运行在节点的网络上。
当然也可以通过Service暴露这些调度器Pod的端口到节点端口,用于接收外部流量,此方式会多走一层,性能可能会有一点损耗。
它的配置文件需要配置成可以对不同服务的请求。做不同Pod集群资源的调度,他转发流量会直接使用Pod IP而非Service的集群IP。
- 可以通过一个Server中配置多个Location来进行不同请求的调度。
但集群中的Pod是会被重构的,也就意味着Pod的IP可能会发生改变,所以需要一种可以获取变动的Pod的IP的方法。
- 可以通过Service来对Pod进行分类,同时用于监视并获取变动的Pod的IP。仅用于此,并不需要将该Service当调度功能使用。
同时也需要将获取到的变动Pod的IP,映射到调度器Pod的配置文件中,并进行配置文件的重载、。
- 此时就可以通过Ingress资源来实现,Ingress可以将Service监视到的Pod的变动,即时的动态注入到调度器Pod的配置文件中,同时重载配置文件。
# Ingress介绍
Ingress用来定义如何转发请求到service。也就是管理Ingress Controller,告诉它如何转发请求。
Ingress可用于将Service监视的Pod的变动,即时的动态注入到Ingress Controller中调度器的配置文件中,同时重载配置文件。
注意:Ingress和Ingress Controller是两回事。
# IngressClass介绍
nginx-ingress部署时自带IngressClass,直接在ingress资源中引用即可,IngressClass资源包含额外的配置,其中包括应当实现该类的控制器名称。
不同类型的Ingress控制器对应的Ingress配置通常也是不同的,当集群中存在多个的Ingress控制器时,就需要为Ingress指定对应的控制器。
# Nginx-Ingress控制器部署
# 部署方法
Ingress控制器分K8S官方版本和Nginx官方版本两种,两种版本都是基于Nginx进行负载均衡,但是Nginx版没有任何第三方模块、同时去掉了Lua代码,所以速度相较快一点点,此处选用Nginx版本的Ingress控制器。
- 克隆Ingress控制器存储库并更改为部署文件夹。
git clone https://github.com/nginxinc/kubernetes-ingress.git --branch v3.4.0
cd kubernetes-ingress/
2
3
- 配置RBAC
# 创建命名空间和服务帐户
kubectl apply -f deployments/common/ns-and-sa.yaml
# 为服务帐户创建集群角色和绑定
kubectl apply -f deployments/rbac/rbac.yaml
2
3
4
5
- 创建公共资源
# 创建TLS证书密钥和Nginx默认服务器的密钥
kubectl apply -f examples/shared-examples/default-server-secret/default-server-secret.yaml
# 创建一个ConfigMap来自定义NGINX设置
kubectl apply -f deployments/common/nginx-config.yaml
# 创建IngressClass资源
# 如果想将该控制器设置为默认控制器,请取消注释ingressclass.kubernetes.io/is-default-class,之后所有未指定ingressClassName字段的新Ingress资源都将分配此IngressClass
kubectl apply -f deployments/common/ingress-class.yaml
2
3
4
5
6
7
8
9
- 创建自定义资源
默认情况下,需要为VirtualServer、VirtualServerRoute、TransportServer和Policy创建自定义资源定义,Ingress控制器pod才能正常变成Ready。如果您想禁用该要求,请配置-enable-custom-resources
命令行参数false并跳过此部分。
# 为VirtualServer和VirtualServerRoute、TransportServer和Policy资源创建自定义资源定义
kubectl apply -f config/crd/bases/k8s.nginx.org_virtualservers.yaml
kubectl apply -f config/crd/bases/k8s.nginx.org_virtualserverroutes.yaml
kubectl apply -f config/crd/bases/k8s.nginx.org_transportservers.yaml
kubectl apply -f config/crd/bases/k8s.nginx.org_policies.yaml
# 为GlobalConfiguration资源创建自定义资源定义,如果想使用Ingress Controller的四层TCP和UDP负载均衡功能,请创建以下附加资源
# kubectl apply -f config/crd/bases/k8s.nginx.org_globalconfigurations.yaml
2
3
4
5
6
7
8
- 部署Ingress Controller
# 使用 DaemonSet 在每个节点或节点子集上部署Ingress控制器 (推荐)
kubectl apply -f deployments/daemon-set/nginx-ingress.yaml
# 如果您计划动态更改Ingress控制器副本的数量,请使用Deployment,两种方式二选一即可
# kubectl apply -f deployments/deployment/nginx-ingress.yaml
# 检查Ingress Controller是否正常运行
kubectl get pods --namespace=nginx-ingress
2
3
4
5
6
7
8
访问Ingress Controller
如果是以DaemonSet方式创建的Ingress控制器,则Ingress控制器容器的端口80和443将映射到运行容器的节点的相同端口。
如果是以Deployment方式创建的Ingress控制器,则还需要为Ingress控制器Pod创建一个NodePort的Service,或者使用 LoadBalancer Service。
kubectl create -f deployments/service/nodeport.yaml
# 卸载方法
kubectl delete namespace nginx-ingress
kubectl delete clusterrole nginx-ingress
kubectl delete clusterrolebinding nginx-ingress
kubectl delete -f config/crd/bases/crds.yaml
2
3
4
# Ingress资源配置清单
# HEAD头部字段
apiVersion: networking.k8s.io/v1
kind: Ingress
2
# metadata
name
- 应当写为和目标资源相关的名称,如:ingress-myapp。namespace
- 需要和转发的目标资源所在的名称空间一致。annotations
- 可以指定参数,写一些自定义转发配置。
# svc.spec.ingressClassName <string>
- 指定使用的IngressClass的类名。可以直接指定部署Ingress控制器时创建的ingressClass资源。
- 可以通过
kubectl get ingressclasses.networking.k8s.io
命令查看默认的IngressClass名。
# svc.spec.rules <[]object>
定义转发规则。
host <string>
- 定义虚拟主机名称,指定用于匹配HTTP请求的虚拟主机,对应Nginx的server_name配置。http <object>
- 定义转发到的后端和URL路径。paths <[]object>
backend <object>
- 指定后端(必选)service <object>
- 通过Service选择后端,指定用于发现和分类后端Pod的Service,指定的Service仅用来分类后端Pod资源,并不实际经过该Service。name <string>
- 指定Service名称(必选),用于发现和分类后端Pod的Service名称。port <string>
- 指定Service暴露的Port。- 以下只能二选一:
name <string>
- 指定Service暴露的端口名称,如果Service中Port配置指定了名称,则可以直接引用该名称来指定。number <integer>
- 指定Service暴露的端口号。
path <string>
- 域名访问路径,对应Nginx的location匹配域,如果通过url进行转发则需要修改,不指定默认是 "/"。pathType <string>
- 指定路径的匹配方式,他可以指定以下三种值:ImplementationSpecific
- 该匹配方式的行为取决于Ingress控制器的实现,一般使用这个即可。Extract
- 以区分大小写的方式精确匹配整个URL路径,也会精确匹配尾部斜线。例如:路径配置: /foo 请求路径: /foo/ 不匹配
。Prefix
- 基于以/分隔的URL路径前缀匹配,匹配区分大小写,并且对路径中的元素逐个完成。- 路径元素指的是由/分隔符分隔的路径中的标签列表。 如果每个p都是请求路径p的元素前缀,则请求与路径p匹配。
- 如果路径的最后一个元素是请求路径中最后一个元素的子字符串,则不会匹配。例如:
/foo/bar 匹配 /foo/bar/baz, 但不匹配 /foo/barbaz
。
ing.spec.defaultBackend <object>
- 默认后端,如果hosts或paths都没有与Ingress对象中的HTTP请求匹配,则流量将路由到默认后端。ing.spec.tls <[]pbject>
- TLS证书验证。hosts <list>
- 指定校验的主机名。secretName <string>
- 指定secret资源。
# 例子
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ngapp-ingress
spec:
ingressClassName: nginx
rules:
- host: www.test.com
http:
paths:
- backend:
service:
name: nginx-svc
port:
name: nginx-80
path: /
pathType: ImplementationSpecific
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# Ingress控制器负载均衡
1. 使用负载均衡服务对Ingress-controller节点的主机端口进行转发。
首先需要将Ingress-controller配置为hostNetwork模式,然后就可以直接对节点网络中各节点的80端口进行负载均衡,这样就可以少走一层service。
有请求访问时,通过外部的负载均衡服务来调度请求到节点的80端口上,然后再由Ingress控制器调度请求给各Pod。控制器可有一个或多个,用于调度请求给后端Pod。
2. 使用Service对Ingress-controller进行转发。
需要对ingress-controller-service进行主机名配置,使可以通过域名解析来访问该ingress-controller-service。如果rules中没有指定host字段,则允许直接使用ingress-controller-service的IP地址来访问该service。
测试可在hosts中配置service的域名解析,或直接使用curl命令:
curl -H "host: 域名" serviceIP/index.html
。如:
curl -H "host: www.test.com" 10.101.145.19/index.html
或则用域名也行:
curl -H "host: www.test.com" nginx-ingress-svc.nginx-ingress.svc.cluster.local./index.html
有请求访问时先通过ingress-controller-service调度请求到各Ingress控制器,然后通过控制器来调度请求到各节点。
例子:
apiVersion: v1
kind: Service
metadata:
name: nginx-ingress-svc
# 需要和Ingress控制器一个名称空间
namespace: nginx-ingress
spec:
type: ClusterIP
# 需要选择Ingress控制器Pod
selector:
app: nginx-ingress
ports:
- name: nginx-ingress-80
port: 80
2
3
4
5
6
7
8
9
10
11
12
13
14
# Ingress配置HTTPS
# 创建测试用证书
openssl genrsa -out tls.key 2048
openssl req -new -x509 -key tls.key -out tls.crt -subj /C=CN/ST=Beijing/Beiing/O=DevOps/CN=[你的域名]
# 将证书转化为secret资源
kubectl create secret tls [secret名] --cert=tls.crt --key=tls.key
# 将secure添加到ingress资源配置中
2
3
4
5
6
7
8