1. kube-proxy 只容许本地访问node
2. NodePort 使用物理机端口和k8s service虚拟ip:端口 映射nginx
3. LoadBalancer 使用NodeIp+Nodeport的方式实现, 配合云环境GCE、aws提供的负载地址数据库
4. ingress 使用开源的反向代理负载均衡器来实现对外暴漏服务,好比 Nginx、Apache、Haproxy后端
做者:莫逐负载均衡(LB)在微服务架构演进中具备很是重要的意义,能够说的内容有不少,这里仅仅讨论四层和七层负载均衡的一些要点和区别,以便于对ingress的理解。所谓四层和七层负载均衡是按照网络层次OSI来划分的负载均衡类型(也能够按照其余的规则来分类,好比:应用的地理结构),简单来讲:四层负载均衡表示负载均衡器用ip+port接收请求,再直接转发到后端对应的服务上,工做在传输层( transport layer );七层负载均衡表示负载均衡器根据虚拟的url或主机名来接收请求,通过处理后再转向相应的后端服务上,工做在应用层( application layer )。api
下图表示了4层和7层负载均衡在创建TCP链接上的区别,从图中能够看出,四层负载均衡须要创建的TCP链接其实之有一个,它只作一次转发,client直接和server链接;而7层负载均衡则须要创建两次TCP链接,client到LB,LB根据消息中的内容( 好比URL或者cookie中的信息 )来作出负载均衡的决定,接着创建LB到server的链接。浏览器
layer4VSlayer7_LB.pngbash
7层负载均衡有什么好处呢?服务器
举个例子:
正向代理:在使用VPS访问的时候,一般会使用一个本地的代理服务器,浏览器的网络包会先通过本地的代理服务器,代理服务器会经过远在异国它乡的电脑来访问并返回消息;这就比如去附近的咖啡店要先问一下手机咖啡店在哪里同样,手机就是一个正向代理服务器。
反向代理:当访问的请求到达时,那边也设置了一个代理服务器,它经过查看请求的URL,发现是想查找视频内容,于时把消息转给了视频搜索服务器(过程是我乱说的),这就比如你去朋友家作客,开门的倒是个管家,问你找谁?这时候管家就是一个反向代理了。cookie
其余OSI层也能够作反向代理网络
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
负载均衡(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层负载均衡有什么好处呢?
举个例子:
正向代理
:在使用VPS访问的时候,一般会使用一个本地的代理服务器,浏览器的网络包会先通过本地的代理服务器,代理服务器会经过远在异国它乡的电脑来访问
并返回消息;这就比如去附近的咖啡店要先问一下手机咖啡店在哪里同样,手机就是一个正向代理服务器。
反向代理
:当访问的请求到达时,
那边也设置了一个代理服务器,它经过查看请求的URL,发现是想查找视频内容,于时把消息转给了视频搜索服务器(过程是我乱说的),这就比如你去朋友家作客,开门的倒是个管家,问你找谁?这时候管家就是一个反向代理了。
关于反向代理的好处这里就很少介绍,感兴趣能够看这里
其余OSI层也能够作反向代理
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
对外服务方式
1. kube-proxy 只容许本地访问
2. NodePort 使用物理机端口和k8s service虚拟ip:端口 映射
3. LoadBalancer 使用NodeIp+Nodeport的方式实现, 配合云环境GCE、aws提供的负载地址
4. ingress 使用开源的反向代理负载均衡器来实现对外暴漏服务,好比 Nginx、Apache、Haproxy等
做者:莫逐对外服务方式
1. kube-proxy 只容许本地访问
2. NodePort 使用物理机端口和k8s service虚拟ip:端口 映射
3. LoadBalancer 使用NodeIp+Nodeport的方式实现, 配合云环境GCE、aws提供的负载地址
4. ingress 使用开源的反向代理负载均衡器来实现对外暴漏服务,好比 Nginx、Apache、Haproxy等
做者:莫逐