向 k8s 集群外部暴露服务的方式有三种: nodePort,LoadBalancer 和本文要介绍的 Ingress。每种方式都有各自的优缺点,nodePort 方式在服务变多的情况下会导致节点要开的端口越来越多,不好管理。而 LoadBalancer 更适合结合云提供商的 LB 来使用,但是在 LB 越来越多的情况下对成本的花费也是不可小觑。Ingress 是 k8s 官方提供的用于对外暴露服务的方式,也是在生产环境用的比较多的方式,一般在云环境下是 LB + Ingress Ctroller 方式对外提供服务,这样就可以在一个 LB 的情况下根据域名路由到对应后端的 Service,有点类似于 Nginx 反向代理,只不过在 k8s 集群中,这个反向代理是集群外部流量的统一入口。
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更加CPU intensive,但是却极少降低性能;
- 可以编写更加智能的负载均衡策略,比如根据URL、cookie中的信息等,甚至对接收到的内容做一些优化和修改,比如加密、压缩;
- 使用buffer的方式来缓解服务器连接慢的问题,从而提高性能
- 具有7层负载均衡功能的设备通常也被称为反向代理服务器(reverse proxy 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的连接。
7层负载均衡有什么好处呢?
- 因为存在解包/封包的过程,比4层LB更加CPU‑intensive,但是却极少降低性能;
- 可以编写更加智能的负载均衡策略,比如根据URL、cookie中的信息等,甚至对接收到的内容做一些优化和修改,比如加密、压缩;
- 使用buffer的方式来缓解服务器连接慢的问题,从而提高性能
- 具有7层负载均衡功能的设备通常也被称为反向代理服务器(reverse‑proxy server)
反向代理
举个例子:
正向代理
:在使用VPS访问的时候,通常会使用一个本地的代理服务器,浏览器的网络包会先经过本地的代理服务器,代理服务器会通过远在异国它乡的电脑来访问并返回消息;这就好比去附近的咖啡店要先问一下手机咖啡店在哪里一样,手机就是一个正向代理服务器。
反向代理
:当访问的请求到达时,那边也设置了一个代理服务器,它通过查看请求的URL,发现是想查找视频内容,于时把消息转给了视频搜索服务器(过程是我乱说的),这就好比你去朋友家做客,开门的却是个管家,问你找谁?这时候管家就是一个反向代理了。
关于反向代理的好处这里就不多介绍,感兴趣可以看这里
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对象了,这部分则是面向开发人员。
假设已经有两个服务部署在了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
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。