Kubernetes集群中流量暴露的几种方案

一 背景

在业务使用Kubernetes进行编排管理时,针对业务的南北流量的接入,在Kuberentes中通常有几种方案,本文就接入的方案进行简单介绍。

二 流量接入方案

Kuberentes社区通过为集群增设入口点的方案,解决对外流量的管理。

2.1 通过kube-proxy进行代理

通常在最简单的测试或个人开发环境,可以通过kubectl port-forward来启动一个kube-proxy 进程代理内部的服务至该命令执行的宿主机节点,如果该宿主机具备公网IP,且转发监听端口为0.0.0.0就可以实现公网访问该服务,该方式可以代理单个pod,或者deployment,或者servcie。

$ kubectl port-forward -h
Forward one or more local ports to a pod. This command requires the node to have 'socat' installed.

 Use resource type/name such as deployment/mydeployment to select a pod. Resource type defaults to 'pod' if omitted.

 If there are multiple pods matching the criteria, a pod will be selected automatically. The forwarding session ends
when the selected pod terminates, and rerun of the command is needed to resume forwarding.

Examples:
  # Listen on ports 5000 and 6000 locally, forwarding data to/from ports 5000 and 6000 in the pod
  kubectl port-forward pod/mypod 5000 6000

  # Listen on ports 5000 and 6000 locally, forwarding data to/from ports 5000 and 6000 in a pod selected by the
deployment
  kubectl port-forward deployment/mydeployment 5000 6000

  # Listen on port 8443 locally, forwarding to the targetPort of the service's port named "https" in a pod selected by
the service
  kubectl port-forward service/myservice 8443:https

  # Listen on port 8888 locally, forwarding to 5000 in the pod
  kubectl port-forward pod/mypod 8888:5000

  # Listen on port 8888 on all addresses, forwarding to 5000 in the pod
  kubectl port-forward --address 0.0.0.0 pod/mypod 8888:5000

  # Listen on port 8888 on localhost and selected IP, forwarding to 5000 in the pod
  kubectl port-forward --address localhost,10.19.21.23 pod/mypod 8888:5000

  # Listen on a random port locally, forwarding to 5000 in the pod
  kubectl port-forward pod/mypod :5000
复制代码

2.1 NodePort方式

其次较常用的为NodePort方式,将K8s中service得类型修改为NodePort方式,会得到一个端口范围在30000-32767端口范围内的宿主机端口,同样改宿主机具有公网IP就可以实现对服务的暴露,但是NodePort会占用宿主机端口,一个service对应一个NodePort,该方式仅为四层,无法实现SSL证书的卸载,如果将服务转发到单个Node节点的NodePort也无法实现高可用,一般需要在NodePort前搭配负载均衡来添加多个后端NodePort已实现高可用。

2.2 LoadBalancer

2.2.1 四层

四层流量转发一个LB的端口只能对应一个Service,Servcie的Type为NodePort,例如如下图,LoadBalancer上的88端口对应转发到后端NodePort的32111端口,对应到servcieA;LB上的8080端口对应转发到后端NodePort32001端口;该方案可以通过添加多个NodePort方式实现高可用,但是由于为四层无法实现对SSL的卸载,对应NodePort需要在LB占用一个端口。

2.2.2 七层

七层可以借助LB的域名转发,实现一个域名端口对应多个service,如图可以根据path路径,/cmp对应NodePort的32111,/gateway 对应NodePort的32000端口,不仅可以实现高可用,而且七层可以实现SSL卸载。

目前一般公有云的LB级别都具备四层和七层的功能,配合使用可以实现灵活的业务流量暴露。

2.3 Ingress

在K8s中,存在有Ingress资源来实现单个域名转发根据不同的路径或其他配置规则转发到K8s集群内部不同的service,但是用户请求需要访问ingress实现控制器的NodePort例如Ingress-nginx的controller的service的NodePort,针对具体的业务域名一般不会带端口,所以一般前面还需要一层80/443的端口转发。

一般Ingress的controller实现业界也有不少解决方案,例如比较知名的Ingress—nginx/Ingress-traefik等。

2.4 LoadBalancer + Ingress

如下图所示在最前面有一个四层LB实现端口80/443转发至ingress-provider的service的NodePort,K8s集群内部配置有多个service。

四 Ingress-nginx详解

在上面的几种方案中,均有用到Ingress,Inginx-ingress则为nginx官方提供的实现K8s ingress资源的方案,当然Kubernetes官方提供的基于nginx实现的ingress。 Ingress 控制器的目标是构建完成一个配置文件(nginx.conf)。对此的实现主要通过检测配置文件发生改变后重载NGINX。但并不是仅在upstream更改时重载Nginx(宕部署应用程序时修改Endpoints)使用lua-nginx-module实现。

Nginx Ingress 由资源对象 Ingress、Ingress 控制器、Nginx 三部分组成。

根据下图可以更好的理解Ingress-nginx的使用场景。

图中展示如下信息:

  • 一个K8s集群
  • 集群用户管理、用户A和用户B,它们通过Kubernetes API使用集群。
  • 客户端A和客户端B,它们连接到相应用户部署的应用程序A和B。
  • IC,由Admin部署在名称空间nginx-ingress中的pod中,并通过ConfigMap nginx-ingress进行配置。Admin通常部署至少两个POD以实现冗余。IC使用Kubernetes API获取集群中创建的最新入口资源,然后根据这些资源配置NGINX。
  • 应用程序A由用户A在命名空间A中部署了两个吊舱。为了通过主机A.example.com向其客户机(客户机A)公开应用程序,用户A创建入口A。
  • 用户B在命名空间B中部署了一个pod的应用程序B。为了通过主机B.example.com向其客户机(客户机B)公开应用程序,用户B创建VirtualServer B。
  • 公共端点,它位于IC吊舱前面。这通常是一个TCP负载均衡器(云、软件或硬件),或者这种负载均衡器与NodePort服务的组合。客户端A和B通过公共端点连接到他们的应用程序。

黄色和紫色箭头表示与客户端通信量相关的连接,黑色箭头表示对Kubernetes API的访问。

为了简单,没有显示许多必要的Kubernetes资源,如部署和服务,管理员和用户也需要创建这些资源。

五 其他

在K8s中,通常云厂商的LB一般云厂商提供适配CNI,会在创建K8s集群时会自动创建LB类型的servcie,例如阿里的ACK,腾讯的TKE,华为的CCE等,但是在我们自建或个人测试场景,开源的Metallb是一个不错的选择,其作用通过k8s原生的方式提供LB类型的Service支持,开箱即用,当然还有青云科技 KubeSphere 团队开源的负载均衡器插件 OpenELB,是为物理机(Bare-metal)、边缘(Edge)和私有化环境设计的负载均衡器插件,可作为 Kubernetes、K3s、KubeSphere 的 LB 插件对集群外暴露 “LoadBalancer” 类型的服务。在21年11 月已进入 CNCF 沙箱(Sandbox)托管,也是解决用户将 Kubernetes 集群部署在裸机上,或是私有化环境特别是物理机或边缘集群,Kubernetes 并不提供 LoadBalancer 的痛点,提供与基于云的负载均衡器相同的用户体验。

猜你喜欢

转载自juejin.im/post/7110906490805813256