K8s-服务发现SVC
K8s-服务发现SVC
-
引入:服务发现的分类:
-
Service:主要工作在4层
-
Ingress:主要工作在7层
-
服务发现-Service
- 概念
Kubernetes Service 定义了这样一种抽象:一个 Pod 的逻辑分 组(标签),k:v一致则可以看成是一个逻辑分组,一种可以访问它们 的策略 —— 通常称为微服务。 这一组 Pod 能够被 Service 访问 到,通常是通过 Label Selector(标签选择)
-
Service的核心迭代
- 在 Kubernetes 集群中,每个 Node 运行一个 kube-proxy 进 程。kube-proxy 负责为 Service 实现了一种 VIP(虚拟 IP)的形 式,而不是 ExternalName 的形式。 在 Kubernetes v1.0 版本,代理完全在 userspace。在 Kubernetes v1.1 版本,新增了 iptables 代理,但并不是默认的运行模式。 从 Kubernetes v1.2 起,默认就 是 iptables 代理。 在 Kubernetes v1.8.0-beta.0 中,添加了 ipvs 代理
- 在 Kubernetes 1.14 版本开始默认使用 ipvs 代理
- 在 Kubernetes v1.0 版本,Service 是 “4层”(TCP/UDP over IP)概念。
- 在 Kubernetes v1.1 版本,新增了 Ingress API(beta 版),用来表示 “7层”(HTTP)服务
-
Sevice落地后的实现方式
- 以负载均衡为方案
- 以域名的别名为方案
-
工作模式的转变
userspace代理模式
注释:
客户端首先访问iptables通过iptables访问到kube-proxy然后访问 到具体的pod上,也就是说每次访问的时候都需要Kube-proxy进行一次代理 也就是说kube-proxy压力是非常大的 同时kube-apiserver也会监控kube-proxy服务更新及端点的维护
iptables代理模式
注释:
舍弃掉了kube-proxy,所有访问直接通过iptables而不需要kubeproxy去代理 这样的话访问速度就会大大增加以及kube-proxy稳定性会提高且压 力将会减少很多 当然使用iptables(防火墙)性能并不会怎么高,但除此之外几乎没有 什么缺点。 kube-apiserver依然通过监控kube-proxy去实现iptables的端口的 更新维护
ipvs代理模式
注释:
将iptables代理模式中iptables变更为ipvs,原来是把所有的调度规则 通过iptables 进行所谓的服务转发定向,现在变成了通过ipvs模块去实现负载均 衡以及流量导向,并且和 iptables代理模式相同,所有的访问也是 不经过kube-proxy的, 性能和吞吐量更大,如果没有提前安装ipvs 模块以及一些基本需求没有完成,那些k8s将会使用iptables的代理 模式 kube-proxy将规则写入ipvs是通过netlink接口,即linux内核暴露 的可以被上层防火墙规则实现管理的一种lib库,以此来实现ipvs的 规则创建,被钩子函数所捕获,实现对应的流量转发,ipvs属于集 群的nat模式(端口映射),不采用DR是因为本身局限性太强,又没有 端口映射,还得向每一个pod创建一个子接口(https),太过于麻烦
钩子函数:(回调函数)是系统内核为驱动程序提供的一些特定的函 数,在驱动程序中某个变量的状态发生改变或将要改变或改变完成 时,将会自动调用该回调函数
注意: ipvs 模式假定在运行 kube-proxy 之前在节点上都已经安装了 IPVS 内核模块。当 kube-proxy 以 ipvs 代理模式启动时,kubeproxy 将验证节点上是否安装了 IPVS 模块,如果未安装,则 kubeproxy 将回退到 iptables 代理模式
限制及缺点:
只提供 4 层负载均衡能力,而没有 7 层功能,但有时我们可能需要更多的匹配规则来转发请求,这点上 4 层负载均衡是不支持的
拓展:https的会话卸载层
注释:当客户端访问集群代理Nginx-pod时,走的是https, Nginx-pod代理了后端服务器,但走的是http,所以实现了https的卸载。
还有另外一种方案,每个myapp都添加了https的认证,再以四层的 方案暴露出去,但此方案代价极大,需证书配置,但service没有采 用持久化连接,握手会失效,大量的资源消耗,不推荐使用
优化:使用ingress接口
针对于nginx代理,pod是动态的,ip会发生改变,这样导致 nginx代理会出现问题,需要配置文件重载加入新的IP变化,但 nginx又不会自动重载,所以引入了ingress接口 nginx对接到ingress_api接口,ingress_api会监听到pod的变化, 这样nginx会自动生成up_stream配置文件参数,如下图
这里的对接不止nginx可以,像traffic也可以,haproxy
总结:nginx是多进程并发模型的典范,而traffic server是多线程异 步事件处理模型的典范,各有其优缺点
nginx:
优点:实力强悍,性能排在第一梯队
缺点:不会自动更新配置文件,重载会有对应的用户流量丢失
traffic:
优点:会根据配置文件的变化自动更新到最新版
缺点:目前性能只达到nginx80%的并发量
提问:为什么不使用DNS实现负载均衡?
DNS污染没有被好好解决,DNS缓存机制,客户端会做缓存ip的 操作,但放在集群里会造成负载不均衡 可以放在百度这种大集群里去,因一个DNS后面可以有一个很大 的集群去处理
DNS污染
网域服务器缓存污染(DNS cache pollution),又称域名服 务器缓存投毒(DNS cache poisoning),是指一些刻意制造或无 意中制造出来的域名服务器数据包,把域名指往不正确的IP地址。 一般来说,在互联网上都有可信赖的网域服务器,但为减低网络上 的流量压力,一般的域名服务器都会把从上游的域名服务器获得的 解析记录暂存起来,待下次有其他机器要求解析域名时,可以立即 提供服务。一旦有关网域的局域域名服务器的缓存受到污染,就会 把网域内的计算机引导到错误的服务器或服务器的网址。
-
Service的类型
- ClusterIp:默认类型,自动分配一个仅 Cluster 内部可以访问的 虚拟IP
- NodePort:在 ClusterIP 基础上为 Service 在每台机器上绑定一 个端口,这样就可以通过 : NodePort 来访问该服务
- LoadBalancer:在 NodePort 的基础上,借助 cloud provider 创建一个外部负载均衡器,并将请求转发到NodeIP: NodePort
- ExternalName:把集群外部的服务引入到集群内部来,在集群 内部直接使用。没有任何类型代理被创建,这只有 kubernetes 1.7 或更高版本的 kube-dns 才支持
-
Clusterip:实现7-4层负载,用于集群内部,组件和组件之间的内部访问
注释:
svc-tomcat:监听apiserver是否有变化,如果其中pod挂掉,基于 netlink接口实现当前ipvs规则对真实服务器的删除,如果有新的 pod加入,podip又会加入到ipvs规则中
apiserver:用户通过 kubectl 命令向 apiserver 发送创建 service 的命令,apiserver 接收到请求后将数据存储到etcd 中
kube-proxy:kubernetes 的每个节点中都有一个叫做 kubeporxy 的进程,这个进程负责感知service,pod 的变化,并将变化 的信息写入本地的 ipvs 规则中
ipvs:基于内核的钩子函数机制实现负载
-
NodePort:
用于访问真实物理机IP地址来访问容器内部集群(将集 群内部的服务暴露出给集群外部的用户访问)注意端口的配置,一 般和真实服务器的端口不一致,官方推荐30000以上,用户可以通 过使用路由器进行端口的转换,当然集群内部也能访问
-
LoadBalancer:
集合了clusterip和nodeport功能,并添加了外 部调度功能,oadBalancer 和 nodePort 其实是同一种方式。区别在于 loadBalancer 比 nodePort 多了一步,利用LAAS来对集群进行调用
- ExternalName:
这种类型的 Service 通过返回 CNAME 和它的值,可以将服务映 射到 externalName 字段的内容( 例如:hub.xxx.com )。 ExternalName Service 是 Service 的特例,它没有 selector,也没 有定义任何的端口和 Endpoint。相反的,对于运行在集群外部的服 务,它通过返回该外部服务的别名这种方式来提供服务
当查询主机 my-service.defalut.svc.cluster.local ( SVC_NAME.NAMESPACE.svc.cluster.local )时,集群的 DNS 服务 将返回一个值 my.database.example.com 的 CNAME 记录。访问 这个服务的工作方式和其他的相同,唯一不同的是重定向发生在 DNS 层,而且不会进行代理或转发
- Headless Service-无头服务
有时不需要或不想要负载均衡,以及单独的 Service IP 。遇到这 种情况,可以通过指定 Cluster IP ( spec.clusterIP ) 的值为 “ None ” 来创建 Headless Service 。这类 Service 并不会分配 Cluster IP, kube-proxy 不会处理它们,而且平台也不会为它们进 行负载均衡和路由
-
访问svc的方式
- 以svc的IP地址访问
- 以svc下的域名地址访问(优点,IP地址改变不影响域名访问)
-
svc相关命令
-
只测试不运行
- kubectl create svc clusterip nginx --tcp=80:80 --dry-run
-
只测试不运行以yaml文件格式输出
- kubectl create svc clusterip nginx --tcp=80:80 --dry-run -o yaml
-
基于yaml文件删除已创建的pod
- kubectl delete -f myapp-deploy.v2.yaml
-
更改nodeport端口
- kubectl edit svc myapp-nodeport # 更改nodeport值即可,但一般不建议更改,随机即可
-
clusterip可升级到nodeport,只需要更改类型type即可
-
kubectl edit svc myapp-cluster
注,只允许向上升级,不允许回退,即不能将nodeport类型改为 clusterip类型
-
-
查看名字空间级别的svc和pod
- kubectl get svc -n Cname(实例名)
- kubectl get pod -n Cname(实例名)
-
同时创建同一目录下的多个yaml文件
- kubectl apply -f ../svc
-
服务发现--ingress
Ingress-Nignx github地址:
https://github.com/kubernetes/ingress-nginx
Ingress-Nginx 官方网址:
https://kubernetes.github.io/ingress-nginx/
- 以往结构示意图
- Nginx-Ingress结构示意图
协程:消耗的资源比线程还低,协助主程工作
作用:
Store协程分析当前apiserver传递过来的变化,如果信息变化不 是紧急事件,加入到更新队列(缓存池),若是紧急事件,直接发送到 SyncQueue协程上
reload是(REsource LOcation And Discovery, RELOAD )协 议,由IETF(Internet Engineering Task Force)P2PSIP(Peerto-Peer Session Initiation Protocol)工作组指定。其核心成果, 提供了统一的叠加网对等体和客户端协议,实现抽象的存储和消息 路由服务,reload也是一门语言,可以和nginx结合使用
注意:要想使用ingress,都必须有一个svc来支持