K8S的服务注册发现和负载均衡原理
一:k8s为什么需要服务发现
我们都知道kubernates 的部署跟传统服务的部署是不一样的
二:pod在生产环境的访问流程
2.1 pod的结构
pod是一个拥有独立ip的容器,这个容器是通过namespace进行资源隔离,和其他的容器相互分开的,相当于一个独立的沙箱环境。
pod内部封装的是容器,可以封装一组部署相关服务或者组件的容器。
2.2 pod网络介绍
每一个pod有自己独立ip
pod内部容器之间可以通过lcoalhost进行访问
pod 是一个虚拟的对象资源(进程),没有对应的实体(物理机,物理网卡)与之对应,没有对应的物理端口提供服务访问,如果pod要对外提供访问,必须绑定一个物理端口,pod会开启一个端口与物理机的端口进行绑定映射,这样再通过物理机进行数据的转发。通过这种方法pod就能对外提供服务了
三:pod服务之间如何实现负载均衡
了解了pod和外网之间访问方式,我们就可以访问pod服务,但是我们现在都是服务集群,可能有多个node节点(如下图),每个节点部署相同服务的pod的数量不一致,如果对这些服务实现负载均衡,是k8s需要解决的一个问题
3.1 使用nginx做负载均衡是否可行
如果我们要访问上图的的商品服务,第一个node节点有三个商品服务,第二个node节点有一个商品服务,我们通过nginx绑定对应的物理机的ip和端口进行负载
但是pod实际上是一个进程,如果进程销毁以后,nginx做分发的ip和端口将不会存在,实际请求中就会出现报错,所以这个就是行不通的,所以k8s提供了一个Service对象服务和虚拟ip来实现pod之间的负载均衡
3.2 什么是serivce
service是一个K8S抽象出来一组服务的对象,这个对象使用虚拟ip,并且为同一组pod提供相同的DNS,并且在他们之间实现负载均衡,总结来说就是service定义了一组pods逻辑集合和一个访问他的策略。
3.3 定义service
3.3.1 service 配置定义
3.3.2 service配置参数含义
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: MyApp
ports:
- protocol: TCP
port: 80
targetPort: 9376
参数 | 含义 |
---|---|
kind | 对象类型 |
metadata | 命名空间 |
app | pod的标签 |
port | service服务的端口 |
target | 同组pod暴露的端口,service请求的目标端口 |
3.3.3 service访问相关pod的图示
K8S的一个node中会运行一个kube-proxy进程,service就是由这个进程创建的
service一旦创建,k8s就会在一个集群(可能一个集群中分散在多个node)中分配给该service一个唯一的虚拟ip(clusterIP),通过VIP进行数据包的转发。
service接受到node的物理机端口转发的请求,service根据iptables的规则,由kube-proxy进行请求的转发到具体的pod
一个具体请求到pod的图示流程
3.3.4 service和pod的关联
3.3.5 pod如果宕机,service如何和pod如何联系
通过上图,我们看到每个node都会有个kube-proxy进程,这个进程会根据不断的对该node里面的pod进程信息进行跟踪,如果有pod的创建和销毁就会更新ets的对应的selector的endpoint信息,这样就能保证service转发的请求对应的pod是正确的
总结
K8S的服务注册发现和负载均衡通过虚拟ip和service代理来实现,内容很多,后期会继续跟踪