抽空读完了《k8s权威指南》一书,对k8s的总算有了较为系统的认知。node
好记忆不如多写字,如下是读书笔记linux
k8s是什么: 一个开源的容器集群管理平台,可提供容器集群的自动部署,扩缩容,维护等功能。分为管理节点Master和工做节点Node
web
核心组件:算法
分层架构:docker
apiVersion : v1
用来标识版本
kind : Pod/Service
类型可选Pod Service等
metadata: name: nameSpace:
后端
静态pod 是由kubelet进行管理建立的只存在于特定Node上的Pod,kubelet没法对其进行静态检查,且通常只存在于kubelet所在的节点上。
且没法经过API server进行管理,也不会和ReplicationController Deployment产生关联。api
建立方式: yml文件【配置文件】或者http请求安全
如何删除: 没法经过API server进行管理,因此Master没法对静态pod进行删除【状态更新为pending】。删除只能经过所在的node节点删除配置文件网络
在同一个pod内的容器能够共享pod级别的volume架构
pod能够经过k8s提供的集群化配置管理方案 configMap来实现配置信息和程序分离。
建立方式: yaml文件
生命周期 在系统内被定义为各类状态。能够分为 Pending Running Succeeded Failed Unknow
重启策略 应用于Pod内的全部容器,并由Pod所在node节点上的kubelet进行状态判断和重启。当容器异常退出或者健康检查状态失败的时候,kubelet会根据所设置的重启策略从新启动该container
重启的间隔时间以设定的间隔时间的2n来计算,且在成功重启的10分钟后重置该时间。
不一样的控制器对Pod的重启策略的要求是不同的:
pod的健康检查可以使用2类探针: LivenessProbe 和ReadinessProbe
LivenessProbe 探针的实现方法
全自动调度,用户配置好应用容器的副本数量后RC会自动调度+持续监控始终让副本数量为此在规定的个数当中。
调度算法 系统内置的调度算法/NodeSelector/NodeAffinity
和RC相似,不一样之处在于DaementSet控制每一台Node上只容许一个Pod副本实例,适用于须要单个Node运行一个实例的应用:
批处理模型
这里在项目中的具体应用待更新,如今项目所用的k8s 调度模型【后续会单独写篇文章更新】
手动更新 kubectl scale命令更新RC的副本实例数量
自动更新 使用HAP控制器,基于在controller-manager设置好的周期,周期性的对Pod的cup占用率进行监控,自动的调节RC或者Deployment中副本实例进行调整来达到设定的CPU占用率。
service能够为一组具备相同功能的容器提供一个统一的入口地址,并将请求负载进行分发到后端各个容器应用上。
kubectl create -f name.yaml
kubectl get pods -l app=webapp -o yaml | grep podIP
由于RC配置的副本实例数量为2 因此可得2个可用的Pod EndPoint 分别为172.17.172.3:80
172.17.172.4:80
不管任何一个Pod出现问题,kubelet 会根据重启策略对Pod进行从新启动,再次查询PodIP会发现PodIP发生变化
由于Pod的不可靠,从新启动被k8s调度到其余Node上会致使实例的endpoint不同。且在分布式部署的状况下,多个容器对外提供服务,还须要在Pod前本身动手解决负载均衡的问题,这些问题均可经过SVC解决。
建立方式 : kubectl expose命令/配置文件
kubectl expose命令
kubectl expose rc webapp
此时端口号会根据以前RC设置的containerPort 来进行设置kubectl get SVC
配置文件方式启动
定义的关键在于 selector 和ports
负载分发策略 RoundRobin/SessionAffinity/自定义实现
思路是把SVC或者pod的虚拟端口映射到宿主机的端口,使得客户端应用能够经过宿主机端口访问容器应用。
将容器应用的端口号映射到主机
1 容器级别 设置hostPort = prodNum yaml中的配置表为hostPort: 8081
,指的是绑定到的宿主机端口。HostPort和containerPort能够不相等
2 Pod级别 设置hostNetWork = true 这时候设置的全部的containerPort 都会直接映射到宿主机相同的端口上。默认且必须是HostPort = containerPort,若显示的指定HostPort和containerPort不相等则无效。
将SVC端口号映射到主机
关键配置为 kind = service type = NodePort
nodePort = xxxxx
,同时在物理机上对防火墙作对应的设置便可。
能够直接完成服务名称到ClusterIP的解析。由如下部分组成
主要提供了各种资源对象【SVC Pod RC】等的增删查改以及Watch等Http Rest接口,是各个模块之间的数据交互和通信的枢纽。
Kubernetes API Server : 提供API接口来完成各类资源对象的建立和管理,自己也是一个SVC 名称为Kubernetes
Kubernetes Proxy API :负责把收到的请求转到对应Node上的kubelet守护进程的端口上,kubelet负责相应,来查询Node上的实时信息 包括node pod SVC等 多用于集群外想实时获取Node内的信息用于状态查询以及管理。 【kubelet也会定时和etcd 同步自身的状态,和直接查询etcd存在必定的差别,这里强调实时】
集群模块之间的通讯: 都须要经过API Server 来完成模块之间的通讯,最终会将资源对象状态同步到etcd,各个集群模块根据经过API Server在etcd定时同步信息,来对所管理的资源进行相应处理。
集群内部的管理中心,负责集群内部的Node Pod Endpoint Namespace 服务帐号(ServiceAccount)资源定额(ResourceQuota)等的管理。出现故障时候会尝试自动修复,达到预期工做状态。
通常咱们把资源对象 Replication Controller 简写为RC 是为了区别于Controller Manager 中的Replication Controller【副本控制器】,副本控制器是经过管理资源对象RC来达到动态调控Pod的
副本控制器Replication Controller的做用:
Node节点在启动时候,会同kubelet 主动向API Server汇报节点信息,API Server将节点信息存储在etcd中,Node Controller经过API Server获取到Node的相关信息对Node节点进行管理和监控。
节点状态包括:就绪 未就绪 未知三种状态
资源配额管理,确保指定资源对象在任一时刻不会超量占用系统物理资源。支持如下维度的系统资源配额管理
用户经过API server 设置的Namespace会保存在etcd中,Namespace Controller会定时的获取namespace状态,根据所得状态对不一样的namespace进行相应的删除,释放namespace下对应的物理资源。
Endpoints 表示一个svc对应的全部的pod的访问地址,Endpoint Controller是负责维护和生成全部endpoint对象的控制器。
每一个Node对应的kube-proxy获取到svc对应的Endpoints来实现svc的负载均衡。
Scheduler 主要是接受controller Manager建立的pod为Pod选定目标Node,调度到合适的Node后,由Node中的kubelet负责接下来的管理运维。
过程当中涉及三个对象 待调度的Pod列表,空闲的Node列表,调度算法和策略。
也就是根据调度算法和策略为待调度的每一个Pod从空闲的Node中选择合适的。 随后kubelet经过API Server监听到Pod的调度事件,获取对应的Pod清单,下载Image镜像,并启动容器。
1【预选调度】遍历全部的Node节点,选出合适的Node
2优选策略肯定最优节点
每一个Node节点中都会启动一个Kubelet,该进程用于处理Master节点下发到本节点的任务,管理Pod以及Pod中的容器,每一个Kubelet都会向API Server注册自身信息,按期和Master节点汇报Node节点资源使用状况。
使用2类探针LivenessProbe 和ReadinessProbe
使用cAdvisor
总结:kubelet 做为链接K8s Master节点机和Node机器的桥梁,管理运行在Node机器上的Pod和容器,同时从cAdvisor中获取容器使用统计信息,而后经过API Server上报资源使用信息。
SVC是对一组提供相同服务Pod的抽象,会根据访问策略来访问这一组Pod。在每个Node节点上都存在一个Kube-proxy,能够在任意Node上发起对SVC的访问请求。
SVC的ClusterIp和NodePort等概念是kube-proxy服务经过IPtables的NAT转换实现重定向到本地端口,再均衡到后端的Pod
待补充
k8s+docker 网络原理经常涉及到如下问题
IP-per-Pod:每一个Pod都有本身独立的IP,不管是否处于同一个Node节点,Pod直接均可以经过IP相互访问。同时Pod内的容器共享一个网络堆栈【=网络命名空间 包括IP地址,网络设备,配置等】按照这个网络模型抽象出来的一个Pod对应一个IP也叫IP-per-Pod
Pod内部应用程序看到的本身的IP+port和pod外部的应用程序看到的IP+port是一致的,他们都是Pod实际分配的ip地址,从docker0上分配的。这样能够不用NAT来进行转换,设计的原则是为了兼容之前的应用 。
K8S对网络的要求:
因为网络命名空间以及Veth设备对是创建在同一个linux内核的基础上。因此Docker的跨主机通信处理的不够友好。
--net= host
指定--net = container: Id_or_NAME
指定--net= none
指定--net = bridge
指定bridge模式 : 也是docker默认的网络模型,在这个模型下Docker第一次启动会建立一个新的网桥 大名鼎鼎的docker0
,每一个容器独享一个网络命名空间,且每个容器具备一个Veth设备对,一端链接容器设备eth0一端链接网桥,docker0。以下图:
同一个Pod内的容器共享同一个网络命名空间,能够直接使用Localhost进行通信,不一样Pod之间容器的通信能够理解为Pod到Pod OR Pod到SVC之间的通信
能够分为同一个Node内Pod之间的通信&不一样Node内Pod之间的通信
同一Node中Pod的默认路由都是docker0的地址,因为它们关联在同一个docker0网桥上,地址网段相同,能够直接进行通信。
docker0网段和宿主机的网卡是2个不一样的IP段,Pod地址和docker0处于同一网段。因此为了使不一样Node之间的Pod能够通信,须要将PodIP和所在Node的IP进行关联且保证惟一性。
SVC是对一组Pod服务的抽象,至关于一组服务的负载均衡。且对外暴露统一的clusterIP,因此Pod到SVC之间的通信能够理解为Pod到Pod之间的通信
集群外和内部组件之间通信,将Pod OR SVC端口绑定到物理机端口便可。