image.png

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的变化,并根据规则配置负载均衡并提供访问入口。
屏幕快照 2020-03-08 下午9.24.22.png

Ingress流程

通过Ingress可从集群外访问K8s资源,访问流程如下:

  1. 从dns获取域名对应的ip。
  2. 将请求发送到该IP,Ingress Controller收到请求。
  3. Ingress Controller根据转发规则,找到对应到Service及其背后的Endpoint。
  4. Ingress Controller随机挑选一个Pod将请求转发给该Pod。

屏幕快照 2020-03-08 下午9.28.04.png

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仅指定一个没有任何规则的后端服务。

  1. apiVersion: extensions/v1beta1
  2. kind: Ingress
  3. metadata:
  4. name: test-ingress
  5. spec:
  6. backend:
  7. serviceName: testsvc
  8. servicePort: 80

注:单个服务还可以通过设置Service.Type=NodePort或者Service.Type=LoadBalancer来对外暴露。** **

2. 多服务的Ingress

路由到多服务的Ingress即根据请求路径的不同转发到不同的后端服务上,比如:

  1. foo.bar.com -> 178.91.123.132 -> / foo s1:80
  2. / bar s2:80

可以通过下面的Ingress来定义:

  1. apiVersion: extensions/v1beta1
  2. kind: Ingress
  3. metadata:
  4. name: test
  5. spec:
  6. rules:
  7. - host: foo.bar.com
  8. http:
  9. paths:
  10. - path: /foo
  11. backend:
  12. serviceName: s1
  13. servicePort: 80
  14. - path: /bar
  15. backend:
  16. serviceName: s2
  17. servicePort: 80

使用“kubectl create -f”创建完Ingress后:

  1. kubectl get ing
  2. ######################### console output start #########################
  3. NAME RULE BACKEND ADDRESS
  4. test -
  5. foo.bar.com
  6. /foo s1:80
  7. /bar s2:80
  8. ######################### console output end #########################

3. 虚拟主机Ingress

虚拟主机Ingress即根据名字的不同转发到不同的后端服务上,而他们共用同一个的IP地址,如下所示:

  1. foo.bar.com --| |-> foo.bar.com s1:80
  2. | 178.91.123.132 |
  3. bar.foo.com --| |-> bar.foo.com s2:80

下面是一个基于Host header路由请求的Ingress:

  1. apiVersion: extensions/v1beta1
  2. kind: Ingress
  3. metadata:
  4. name: test
  5. spec:
  6. rules:
  7. - host: foo.bar.com
  8. http:
  9. paths:
  10. - backend:
  11. serviceName: s1
  12. servicePort: 80
  13. - host: bar.foo.com
  14. http:
  15. paths:
  16. - backend:
  17. serviceName: s2
  18. 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:

  1. apiVersion: v1
  2. data:
  3. tls.crt: base64 encoded cert
  4. tls.key: base64 encoded key
  5. kind: Secret
  6. metadata:
  7. name: testsecret
  8. namespace: default
  9. type: Opaque

Ingress中引用secret:

  1. apiVersion: extensions/v1beta1
  2. kind: Ingress
  3. metadata:
  4. name: no-rules-map
  5. spec:
  6. tls:
  7. - secretName: testsecret
  8. backend:
  9. serviceName: s1
  10. 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:

  1. 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