Ingress简介
- 问题
Service只能解决TCP/IP层的访**问__,其实现的是TCP负载均衡器(__iptables和ipvs均实现的是四层调度,其不能基于URL的请求调度机制,其也不支持为此类负载均衡配置任何类型的健康检查机制)**,但大多数情况下,我们访问的是URL及在应用层访问,这个时候Service这种模式就失效了。Service只能做四层代理,无法做七层代理(如https服务),LVS只能根据第四层的数据进行转发,无法对七层协议数据进行调度。
Service对象的IP地址称为cluster IP,位于K8s集群配置指定的专用IP地址范围内,其是一种虚拟IP地址,其在Service对象创建后保持不变,并且能够被同一集群中的Pod资源访问,Service端口接受客户端的请求并将其转发至后端Pod中的相应端口,因此,其又被称为四层代理,因其工作在TCP/IP层。Ingress实现的是HTTP(S)负载均衡器。
- 方案
为了解决这个问题,我们需要更上一层的对象,这个就是Ingress。Ingress可以给Service提供集群外部访问的 URL、负载均衡、SSL终止、HTTP路由等。为了配置这些Ingress规则,集群管理员需要部署一个Ingress controller,它监听Ingress和Service的变化,并根据规则配置负载均衡并提供访问入口。
Ingress流程
通过Ingress可从集群外访问K8s资源,访问流程如下:
- 从dns获取域名对应的ip。
- 将请求发送到该IP,Ingress Controller收到请求。
- Ingress Controller根据转发规则,找到对应到Service及其背后的Endpoint。
- Ingress Controller随机挑选一个Pod将请求转发给该Pod。
Ingress API版本
Kubernetes 版本 | Extension 版本 |
---|---|
v1.5-v1.17 | extensions/v1beta1 |
v1.8+ | networking.k8s.io/v1beta1 |
Ingress类型
根据Ingress Spec配置的不同,Ingress可以分为以下几种类型:单服务Ingress、多服务的Ingress、虚拟主机Ingress、TLS Ingress。
1. 单服务Ingress
单服务Ingress即该Ingress仅指定一个没有任何规则的后端服务。
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: test-ingress
spec:
backend:
serviceName: testsvc
servicePort: 80
注:单个服务还可以通过设置Service.Type=NodePort或者Service.Type=LoadBalancer来对外暴露。** **
2. 多服务的Ingress
路由到多服务的Ingress即根据请求路径的不同转发到不同的后端服务上,比如:
foo.bar.com -> 178.91.123.132 -> / foo s1:80
/ bar s2:80
可以通过下面的Ingress来定义:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: test
spec:
rules:
- host: foo.bar.com
http:
paths:
- path: /foo
backend:
serviceName: s1
servicePort: 80
- path: /bar
backend:
serviceName: s2
servicePort: 80
使用“kubectl create -f
”创建完Ingress后:
kubectl get ing
######################### console output start #########################
NAME RULE BACKEND ADDRESS
test -
foo.bar.com
/foo s1:80
/bar s2:80
######################### console output end #########################
3. 虚拟主机Ingress
虚拟主机Ingress即根据名字的不同转发到不同的后端服务上,而他们共用同一个的IP地址,如下所示:
foo.bar.com --| |-> foo.bar.com s1:80
| 178.91.123.132 |
bar.foo.com --| |-> bar.foo.com s2:80
下面是一个基于Host header路由请求的Ingress:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: test
spec:
rules:
- host: foo.bar.com
http:
paths:
- backend:
serviceName: s1
servicePort: 80
- host: bar.foo.com
http:
paths:
- backend:
serviceName: s2
servicePort: 80
注:没有定义规则的后端服务称为默认后端服务,可以用来方便的处理404页面。
4. TLS Ingress
TLS Ingress通过Secret获取TLS私钥和证书(名为tls.crt和tls.key),来执行TLS终止。如果Ingress中的TLS配置部分指定了不同的主机,则它们将根据通过SNI TLS扩展指定的主机名(假如Ingress controller支持SNI)在多个相同端口上进行复用。定义一个包含tls.crt和tls.key的 secret:
apiVersion: v1
data:
tls.crt: base64 encoded cert
tls.key: base64 encoded key
kind: Secret
metadata:
name: testsecret
namespace: default
type: Opaque
Ingress中引用secret:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: no-rules-map
spec:
tls:
- secretName: testsecret
backend:
serviceName: s1
servicePort: 80
注意,不同Ingress controller支持的TLS功能不尽相同。 请参阅有关nginx,GCE或任何其他Ingress controller的文档,以了解TLS的支持情况。
Ingress Controller
Ingress正常工作需要集群中运行Ingress Controller。Ingress Controller与其他作为kube-controller-manager中的在集群创建时自动启动的controller成员不同,需要用户选择最适合自己集群的Ingress Controller,或者自己实现一个。
Ingress Controller以Kubernetes Pod的方式部署,以daemon方式运行,保持watch Apiserver的 /ingress接口以更新Ingress资源,以满足Ingress的请求。比如可以使用Nginx Ingress Controller:
helm install stable/nginx-ingress --name nginx-ingress --set rbac.create=true
其他Ingress Controller还有:
- traefik ingress:提供了一个Traefik Ingress Controller的实践案例。
- kubernetes/ingress-nginx:提供了一个详细的Nginx Ingress Controller示例。
- kubernetes/ingress-gce:提供了一个用于GCE的Ingress Controller示例。
- envoy
- haproxy
- vulcand
参考
博客园:Service和Ingress
https://www.cnblogs.com/zjz20/p/12691770.html