k8s服务暴露之ingress与负载均衡

k8s 对外暴露服务的方法

向 k8s 集群外部暴露服务的方式有三种: nodePort,LoadBalancer 和本文要介绍的 Ingress。每种方式都有各自的优缺点,nodePort 方式在服务变多的情况下会导致节点要开的端口越来越多,不好管理。而 LoadBalancer 更适合结合云提供商的 LB 来使用,但是在 LB 越来越多的情况下对成本的花费也是不可小觑。Ingress 是 k8s 官方提供的用于对外暴露服务的方式,也是在生产环境用的比较多的方式,一般在云环境下是 LB + Ingress Ctroller 方式对外提供服务,这样就可以在一个 LB 的情况下根据域名路由到对应后端的 Service,有点类似于 Nginx 反向代理,只不过在 k8s 集群中,这个反向代理是集群外部流量的统一入口。
 
Service 虽然解决了服务发现和负载均衡的问题,但对外访问的时候,NodePort类型需要在外部搭建额外的负载均衡,而LoadBalancer需要Kubernetes必须跑在支持的cloud provider上面。 Ingress就是为了解决这些限制的。

Ingress 是一个规则的集合,它允许集群外的流量通过一定的规则到达集群内的 Service 。 request--->ingress--->service.

Ingress由三个组件组成:

1.反向代理负载均衡器:即常见的负载均衡软件,如 nginx、Haproxy 等

2.Ingress Controller: kubernetes API 进行交互,实时的感知后端 service、pod 等变化, Ingress Controller 再结合下文的 Ingress 生成配置,然后更新反向代理负载均衡器,并刷新其配置,实现动态服务发现与更新

3.Ingress:规则集合;定义了域名与Kubernetes的service的对应关系;这个规则将与 Ingress Controller 结合, Ingress Controller 将其动态写入到负载均衡器配置中,从而实现整体的服务发现和负载均衡。

四:Service Load Balancer
在Ingress出现以前,Service Load Balancer谁推荐的解决Service局限性的方式。Service Load Balancer将haproxy跑在容器中,并监控service和endpoint的变化,通过容器IP对外提供4层和7层负载均衡服务。

五:Custom Load Balancer
自定义组件,代替kube-proxy来做负载均衡。如nginx plus, kube2haproxy等。

六:Endpoints
有几种情况需要用到没有selector的service
1.使用kubernetes集群外部的数据库时。
2.service中用到了其它namespace或kubernetes集群中的service
3.在kubernetes的工作负载与集群外的后端之间互相迁移。

1. kube-proxy 只允许本地访问

2. NodePort 使用物理机端口和k8s service虚拟ip:端口 映射

3. LoadBalancer 使用NodeIp+Nodeport的方式实现, 配合云环境GCE、aws提供的负载地址

4. ingress  使用开源的反向代理负载均衡器来实现对外暴漏服务,比如 Nginx、Apache、Haproxy

作者:莫逐
链接: https://www.jianshu.com/p/b02dd40a16da
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

7层负载均衡

负载均衡(LB)在微服务架构演进中具有非常重要的意义,可以说的内容有很多,这里仅仅讨论四层和七层负载均衡的一些要点和区别,以便于对ingress的理解。所谓四层和七层负载均衡是按照网络层次OSI来划分的负载均衡类型(也可以按照其他的规则来分类,比如:应用的地理结构),简单来说:四层负载均衡表示负载均衡器用ip+port接收请求,再直接转发到后端对应的服务上,工作在传输层( transport layer );七层负载均衡表示负载均衡器根据虚拟的url或主机名来接收请求,经过处理后再转向相应的后端服务上,工作在应用层( application layer )。

下图表示了4层和7层负载均衡在建立TCP连接上的区别,从图中可以看出,四层负载均衡需要建立的TCP连接其实之有一个,它只做一次转发,client直接和server连接;而7层负载均衡则需要建立两次TCP连接,client到LB,LB根据消息中的内容( 比如URL或者cookie中的信息 )来做出负载均衡的决定,接着建立LB到server的连接。

 

layer4VSlayer7_LB.png

7层负载均衡有什么好处呢?

  • 因为存在解包/封包的过程,比4层LB更加CPUintensive,但是却极少降低性能;
  • 可以编写更加智能的负载均衡策略,比如根据URL、cookie中的信息等,甚至对接收到的内容做一些优化和修改,比如加密、压缩;
  • 使用buffer的方式来缓解服务器连接慢的问题,从而提高性能
  • 具有7层负载均衡功能的设备通常也被称为反向代理服务器(reverseproxy server)

反向代理

举个例子:
正向代理:在使用VPS访问的时候,通常会使用一个本地的代理服务器,浏览器的网络包会先经过本地的代理服务器,代理服务器会通过远在异国它乡的电脑来访问并返回消息;这就好比去附近的咖啡店要先问一下手机咖啡店在哪里一样,手机就是一个正向代理服务器。
反向代理:当访问的请求到达时,那边也设置了一个代理服务器,它通过查看请求的URL,发现是想查找视频内容,于时把消息转给了视频搜索服务器(过程是我乱说的),这就好比你去朋友家做客,开门的却是个管家,问你找谁?这时候管家就是一个反向代理了。

其他OSI层也可以做反向代理

ingress

k8s 对外暴露服务(service)主要有两种方式:NotePort, LoadBalance, 此外externalIPs也可以使各类service对外提供服务,但是当集群服务很多的时候,NodePort方式最大的缺点是会占用很多集群机器的端口;LB方式最大的缺点则是每个service一个LB又有点浪费和麻烦,并且需要k8s之外的支持; 而ingress则只需要一个NodePort或者一个LB就可以满足所有service对外服务的需求。工作机制大致可以用下图表示:

 

 

实际上,ingress相当于一个7层的负载均衡器,是k8s对反向代理的一个抽象。大概的工作原理也确实类似于Nginx,可以理解成在 Ingress 里建立一个个映射规则 , ingress Controller 通过监听 Ingress这个api对象里的配置规则并转化成 Nginx 的配置(kubernetes声明式API和控制循环) , 然后对外部提供服务。ingress包括:ingress controller和ingress resources

ingress controller:核心是一个deployment,实现方式有很多,比如nginx, Contour, Haproxy, trafik, Istio,需要编写的yaml有:Deployment, Service, ConfigMap, ServiceAccount(Auth),其中service的类型可以是NodePort或者LoadBalancer。

ingress resources:这个就是一个类型为Ingress的k8s api对象了,这部分则是面向开发人员。

 

 使用 Ingress 对外暴露服务

为了快速体验 Ingress,下面部署一个 nginx 服务,然后通过 Ingress 对外暴露 nginx service 进行访问。
首先部署 nginx 服务:
Deployment + Service:nginx.yml

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 2
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80
---
kind: Service
apiVersion: v1
metadata:
  name: nginx
spec:
  selector:
    app: nginx
  ports:
    - port: 80
      targetPort: 80

kubectl create -f nginx.yml

接下来创建 Ingress 对外暴露 nginx service 80 端口:
ingress.yml:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress-nginx
  annotations:
    # use the shared ingress-nginx
    kubernetes.io/ingress.class: "nginx"
spec:
  rules:
  - host: nginx.kube.com
    http:
      paths:
      - path: /
        backend:
          serviceName: nginx
          servicePort: 80

说明:
    kubernetes.io/ingress.class: "nginx":Nginx Ingress Controller 根据该注解自动发现 Ingress;
    host: nginx.kube.com:对外访问的域名;
    serviceName: nginx:对外暴露的 Service 名称;
    servicePort: 80:nginx service 监听的端口;

注意:创建的 Ingress 必须要和对外暴露的 Service 在同一命名空间下!
将域名 nginx.kube.com 绑定到 k8s 任意节点 ip 即可访问:http://nginx.kube.com
上面的示例不支持 https 访问,下面举一个支持 https 的 Ingress 例子:通过 Ingress 访问 kubernetes dashboard 服务。
通过 Ingress 访问 kubernetes dashboard(支持 HTTPS 访问)
之前我们使用 helm 以 nodePort 的方式部署了 kubernetes dashboard:「helm 部署 kubernetes-dashboard」,从集群外部只能通过 nodeIP:nodePort 端口号 访问,接下来基于之前部署的 kubernetes-dashboard 配置如何通过 Ingress 访问,并且支持 HTTPS 访问,HTTP 自动跳转到 HTTPS。 :
首先,练习使用,先用自签名证书来代替吧:

openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout kube-dashboard.key -out kube-dashboard.crt -subj "/CN=dashboard.kube.com/O=dashboard.kube.com"

使用生成的证书创建 k8s Secret 资源,下一步创建的 Ingress 会引用这个 Secret:
kubectl create secret tls kube-dasboard-ssl --key kube-dashboard.key --cert kube-dashboard.crt -n kube-system
创建 Ingress 资源对象(支持 HTTPS 访问):
kube-dashboard-ingress.yml


apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress-kube-dashboard
  annotations:
    # use the shared ingress-nginx
    kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
spec:
  tls:
  - hosts:
    - dashboard.kube.com
    secretName: kube-dasboard-ssl
  rules:
  - host: dashboard.kube.com
    http:
      paths:
      - path: /
        backend:
          serviceName: kubernetes-dashboard
          servicePort: 443
kubectl create -f kube-dashboard-ingress.yml -n kube-system


说明:
    kubernetes.io/ingress.class: "nginx":Inginx Ingress Controller 根据该注解自动发现 Ingress;
    nginx.ingress.kubernetes.io/backend-protocol: Controller 向后端 Service 转发时使用 HTTPS 协议,这个注解必须添加,否则访问会报错,可以看到 Ingress Controller 报错日志:kubectl logs -f nginx-ingress-controller-mg8df

    2019/08/12 06:40:00 [error] 557#557: *56049 upstream sent no valid HTTP/1.0 header while reading response header from upstream, client: 192.168.26.10, server: dashboard.kube.com, request: “GET / HTTP/1.1”, upstream: “http://10.244.1.8:8443/”, host: “dashboard.kube.com”

报错原因主要是 dashboard 服务后端只支持 https,但是 Ingress Controller 接到客户端的请求时往后端 dashboard 服务转发时使用的是 http 协议,解决办法就是给 创建的 Ingress 设置:nginx.ingress.kubernetes.io/backend-protocol: "HTTPS" 注解。解决方法参考自 StackOverflow:https://stackoverflow.com/questions/48324760/ingress-configuration-for-dashboard

    secretName: kube-dasboard-ssl:https 证书 Secret;
    host: dashboard.kube.com:对外访问的域名;
    serviceName: kubernetes-dashboard:集群对外暴露的 Service 名称;
    servicePort: 443:service 监听的端口;

    注意:创建的 Ingress 必须要和对外暴露的 Service 在同一命名空间下!
将域名 dashboard.kube.com 绑定到 k8s 任意节点 ip 即可访问:https://dashboard.kube.com

7层负载均衡

负载均衡(LB)在微服务架构演进中具有非常重要的意义,可以说的内容有很多,这里仅仅讨论四层和七层负载均衡的一些要点和区别,以便于对ingress的理解。所谓四层和七层负载均衡是按照网络层次OSI来划分的负载均衡类型(也可以按照其他的规则来分类,比如:应用的地理结构),简单来说:四层负载均衡表示负载均衡器用ip+port接收请求,再直接转发到后端对应的服务上,工作在传输层( transport layer );七层负载均衡表示负载均衡器根据虚拟的url或主机名来接收请求,经过处理后再转向相应的后端服务上,工作在应用层( application layer )。

下图表示了4层和7层负载均衡在建立TCP连接上的区别,从图中可以看出,四层负载均衡需要建立的TCP连接其实之有一个,它只做一次转发,client直接和server连接;而7层负载均衡则需要建立两次TCP连接,client到LB,LB根据消息中的内容( 比如URL或者cookie中的信息 )来做出负载均衡的决定,接着建立LB到server的连接。

layer4VSlayer7_LB.png

7层负载均衡有什么好处呢?

  • 因为存在解包/封包的过程,比4层LB更加CPU‑intensive,但是却极少降低性能;
  • 可以编写更加智能的负载均衡策略,比如根据URL、cookie中的信息等,甚至对接收到的内容做一些优化和修改,比如加密、压缩;
  • 使用buffer的方式来缓解服务器连接慢的问题,从而提高性能
  • 具有7层负载均衡功能的设备通常也被称为反向代理服务器(reverse‑proxy server)

反向代理

举个例子:
正向代理:在使用VPS访问Google的时候,通常会使用一个本地的代理服务器,浏览器的网络包会先经过本地的代理服务器,代理服务器会通过远在异国它乡的电脑来访问Google并返回消息;这就好比去附近的咖啡店要先问一下手机咖啡店在哪里一样,手机就是一个正向代理服务器。
反向代理:当访问的请求到达Google时,Google那边也设置了一个代理服务器,它通过查看请求的URL,发现是想查找视频内容,于时把消息转给了视频搜索服务器(过程是我乱说的),这就好比你去朋友家做客,开门的却是个管家,问你找谁?这时候管家就是一个反向代理了。
关于反向代理的好处这里就不多介绍,感兴趣可以看这里

其他OSI层也可以做反向代理

ingress

k8s 对外暴露服务(service)主要有两种方式:NotePort, LoadBalance, 此外externalIPs也可以使各类service对外提供服务,但是当集群服务很多的时候,NodePort方式最大的缺点是会占用很多集群机器的端口;LB方式最大的缺点则是每个service一个LB又有点浪费和麻烦,并且需要k8s之外的支持; 而ingress则只需要一个NodePort或者一个LB就可以满足所有service对外服务的需求。工作机制大致可以用下图表示:

ingress.png

实际上,ingress相当于一个7层的负载均衡器,是k8s对反向代理的一个抽象。大概的工作原理也确实类似于Nginx,可以理解成在 Ingress 里建立一个个映射规则 , ingress Controller 通过监听 Ingress这个api对象里的配置规则并转化成 Nginx 的配置(kubernetes声明式API和控制循环) , 然后对外部提供服务。ingress包括:ingress controller和ingress resources

ingress controller:核心是一个deployment,实现方式有很多,比如nginx, Contour, Haproxy, trafik, Istio,需要编写的yaml有:Deployment, Service, ConfigMap, ServiceAccount(Auth),其中service的类型可以是NodePort或者LoadBalancer。

ingress resources:这个就是一个类型为Ingress的k8s api对象了,这部分则是面向开发人员。

假设已经有两个服务部署在了k8s集群内部:

$ kubectl get svc,deploy
NAME             TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
svc/coffee-svc   ClusterIP   <none>       <none>        80/TCP    1m
svc/tea-svc      ClusterIP   <none>       <none>        80/TCP    1m

NAME            DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
deploy/coffee   2         2         2            2           1m
deploy/tea      1         1         1            1           1m
作者:MunCN
链接:https://www.jianshu.com/p/97dd4d59ac5a
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

对外服务方式

1. kube-proxy 只允许本地访问

2. NodePort 使用物理机端口和k8s service虚拟ip:端口 映射

3. LoadBalancer 使用NodeIp+Nodeport的方式实现, 配合云环境GCE、aws提供的负载地址

4. ingress  使用开源的反向代理负载均衡器来实现对外暴漏服务,比如 Nginx、Apache、Haproxy等

作者:莫逐
链接:https://www.jianshu.com/p/b02dd40a16da
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

对外服务方式

1. kube-proxy 只允许本地访问

2. NodePort 使用物理机端口和k8s service虚拟ip:端口 映射

3. LoadBalancer 使用NodeIp+Nodeport的方式实现, 配合云环境GCE、aws提供的负载地址

4. ingress  使用开源的反向代理负载均衡器来实现对外暴漏服务,比如 Nginx、Apache、Haproxy等

作者:莫逐
链接:https://www.jianshu.com/p/b02dd40a16da
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

猜你喜欢

转载自www.cnblogs.com/xyz999/p/11717451.html