K8S架构
一、简介
Kubernetes、容器编排。
、
1.1、主要分为Master、Node、Etcd
1.2、核心概念
【pod】:最小调度单元。提供容器运行环境、定义容器执行方式。
【Volume】:Pod可访问的文件目录,支持多种存储抽象。
【Deployment】:管理Pod部署的副本、部署方案版本。
【Service】:提供Pod对外访问地址。
【Namespace】:集群内资源隔离机制。
二、Deployment
简介:用于编排 Pod 的一种控制器资源。
创建Deployment步骤:
- 首先是 kubectl 发起一个创建 deployment 的请求。
- apiserver 接收到创建 deployment 请求,将相关资源写入 etcd;之后所有组件与 apiserver/etcd 的交互都是类似的。
- deployment controller list/watch 资源变化并发起创建 replicaSet 请求。
- replicaSet controller list/watch 资源变化并发起创建 pod 请求。
- scheduler 检测到未绑定的 pod 资源,通过一系列匹配以及过滤选择合适的 node 进行绑定。
- kubelet 发现自己 node 上需创建新 pod,负责 pod 的创建及后续生命周期管理。
- kube-proxy 负责初始化 service 相关的资源,包括服务发现、负载均衡等网络规则。
到这里,经过 Kubenetes 各组件的分工协调,完成了从创建一个 Deployment 请求开始到具体各 Pod 正常运行的全过程。
三、Pod
简介:最小部署单元。
不同的Container之间通过 Infra Container 的方式统一识别外部网络空间,通过挂载同一份Volume就可以共享存储。不同的Pod之间,通过Docker0网桥,实现网络通信。
3.1、如果想在pod内部的容器里面使用pod信息,有两种方式:
1、通过环境变量方式,
2、通过配置文件。
3.2、pod健康检查
有3类探针:
1、LivenessProbe:判断是否存活,kubele会重启不是存活的pod。
2、RedinessProbe:判断是否可用,service只有在RedinessProbe为ready状态,才将该pod加到service的endpoint中,对外提供服务。
3、StartupProbe:有且仅有一次的超长启动延迟。
探针实现方式:
1、ExecAction:容器内部运行命令,返回码为0,代表健康
2、TCPSocketAction:通过容器IP+端口,执行TCP检查,能够建立TCP连接,则健康。
3、HTTPGetAction:HTTP get响应状态码在200~400间,则认为容器健康。
四、容器编排
Kubernetes 中有诸多编排相关的控制资源,例如编排无状态应用的 Deployment,编排有状态应用的 Statefulset,编排守护进程 Daemonset 以及编排离线业务的 job/cronjob 等等。
以Deployment 为例。Deployment、Replicatset、Pod 之间的关系是一种层层控制的关系。
简单来说,Replicaset 控制 Pod 的数量,而 Deployment 控制 Replicaset 的版本属性。
这种设计模式也为两种最基本的编排动作实现了基础,即数量控制的水平扩缩容、版本属性控制的更新/回滚。
【水平扩/缩容】
水平扩缩容非常好理解,我们只需修改 Replicaset 控制的 Pod 副本数量即可,比如从 2 改到 3,那么就完成了水平扩容这个动作,反之即水平收缩。
【更新/回滚】
更新/回滚则体现了 Replicaset 这个对象的存在必要性。例如我们需要应用 3 个实例的版本从 v1 改到 v2。
那么 v1 版本 Replicaset 控制的 Pod 副本数会逐渐从 3 变到 0,而 v2 版本 Replicaset 控制的 Pod 数会注解从 0 变到 3,当 Deployment 下只存在 v2 版本的 Replicaset 时变完成了更新。回滚的动作与之相反。
【滚动更新】
可以发现,在上述例子中,我们更新应用,Pod 总是一个一个升级,并且最小有 2 个 Pod 处于可用状态,最多有 4 个 Pod 提供服务。
这种”滚动更新”的好处是显而易见的,一旦新的版本有了 Bug,那么剩下的 2 个 Pod 仍然能够提供服务,同时方便快速回滚。
在实际应用中我们可以通过配置 RollingUpdateStrategy 来控制滚动更新策略。
maxSurge 表示 Deployment 控制器还可以创建多少个新 Pod;而 maxUnavailable 指的是,Deployment 控制器可以删除多少个旧 Pod。
五、K8S网络
1、Node到Pod之间通信。通过cni/docker0网桥通信。
2、Node的Pod之间通信。通过cni/docker0网桥通信。
3、不同Node之间的Pod通信。比如普遍的Flannel的vxlan/hostgw模式等。Flannel 通过 Etcd 获知其他 Node 的网络信息,并会为本 Node 创建路由表,最终使得不同 Node 间可以实现跨主机通信。
六、微服务 Service
服务调用过程中,service解决了两个问题:
1、Pod的IP不固定,利用非固定IP进行网络调用不现实。
2、服务调用需要对不同的Pod进行负载均衡。
service通过Lable选择器选取合适的pod,构建出一个Engpoints,即pod负载均衡列表。
实际应用中,一般会为一个微服务的pod实例都打上app=xxx的标签,同时为该微服务创建一个标签选择器为 app=xxx的service。
七、k8s中的服务发现与网络调用
7.1、服务间调用
服务间调用,是东西流向的调用。主要有两种:ClusterIp模式、DNS模式。
1、ClusterIp模式
ClusterIp 是 Service 的一种类型,在这种类型模式下,kube-proxy 通过 iptables/ipvs 为 Service 实现了一种 VIP(虚拟 IP)的形式。只需要访问该 VIP,即可负载均衡地访问到 Service 背后的 Pod。
还有其他方式:userSpace 代理模式(基本不用),以及 ipvs 模式(性能更好)。
2、DNS模式
DNS 模式很好理解,对 ClusterIp 模式的 Service 来说,它有一个 A 记录是 service-name.namespace-name.svc.cluster.local,指向 ClusterIp 地址。所以一般使用过程中,我们直接调用 service-name 即可。
7.2、服务外访问
南北向的流量,即外部访问k8s集群,包括3种方式:
1、nodePort
2、loadbalancer
3、ingress
【nodePort】
同样是 Service 的一种类型,通过 IPtables 赋予了调用宿主机上的特定 Port 就能访问到背后 Service 的能力。
【loadbalancer】
是另一种 Service 类型,通过公有云提供的负载均衡器实现。
【ingress】
我们访问 100 个服务可能需要创建 100 个 nodePort/Loadbalancer。我们希望通过一个统一的外部接入层访问内部 Kubernetes 集群。这就是 Ingress 的功能。
Ingress 提供了统一接入层,通过路由规则的不同匹配到后端不同的 Service 上。
Ingress 可以看做是“Service 的 Service”。Ingress 在实现上往往结合 nodePort 以及 Loadbalancer 完成功能。