— 1 —
背景
过去几年,以 Docker、Kubernetes 为代表的容器技术已发展为一项通用技术,BAT、滴滴、京东、头条等大厂,都争相把容器和 K8S 项目作为技术重心,试图“放长线钓大鱼”。
但容器技术本身偏向运维,namespace 资源隔离、cgroups 资源限制等概念,对开发者来说,理解起来比较困难。尤其在实施 K8S 落地时,总有一些问题被反复提及,比如:
一个pod如何创建起来的?
k8s RBAC怎么管理用户权限的?
k8s 网络是怎么样的?
多套k8s是如何管理维护?
本文主要以k8s如何创建一个pod 为问题点展开,如何创建一个pod
— 2 —
pod创建启动过程 创建pod时序图
第一步:kubectl create pod
首先进行认证(RBAC方式 或者 key方式进行认证 )后获得具体的权限,然后kubectl会调用master api创建对象的接口,然后向k8s apiserver发出创建pod的命令
第二步:k8s apiserver
apiserver收到请求后,并非直接创建pod,而是先创建一个包含pod创建信息的yaml文件,并将文件信息写入到etcd中(如果此处是用yaml文件创建pod,则这两步就可以忽略)
这里用pod创建也给出具体cd 部署思路,创建pod形式有二种方案。一种是通过api直接创建生成yaml,另外一种是通过yaml直接应用。
第三步:controller manager
创建Pod的yaml信息会交给controller manager ,controller manager根据配置信息将要创建的资源对象(pod)放到等待队列中。
注意创建的资源对象是并发过程,但是放入队列是一个串行,主要目的还是为了防止1、应用资源创建的先后顺序 2、资源调度过程的优先情况 应用有无状态 3、暂时还没有其他,知道兄弟帮忙补充一下,自己理解。
第四步:scheduler
scheduler (死循环)查看k8s api ,类似于通知机制。首先判断:pod.spec.Node == null? 若为null,表示这个Pod请求是新来的,需要创建;然后进行预选调度和优选调度计算,找到最“闲”的且符合调度条件的node。最后将信息在etcd数据库中更新分配结果:pod.spec.Node = node2(设置一个具体的节点)同样上述操作的各种信息也要写到etcd数据库中。
分配过程需要两层调度:预选调度和优选调度
(1)预选调度:一般根据资源对象的配置信息进行筛选。例如NodeSelector、HostSelector和节点亲和性等。
(2)优选调度:根据资源对象需要的资源和node节点资源的使用情况,为每个节点打分,然后选出最优的节点创建资源对象(pod)。
运维小助手:调度策略在后期成本控制 资源使用 费用计算都是一个好的方案。
第四步:kubelet
节点(选中node)上的kubelet进程通过API Server,查看etcd数据库(kubelet通过API Server的WATCH接口监听Pod信息,如果监听到新的pod副本被调度绑定到本节点)监听到kube-scheduler产生的Pod绑定事件后获取对应的Pod清单,然后调用(被选中node)本机中的docker api初始化volume、分配IP、下载image镜像,创建容器并启动服务。
注意顺序 有状态和无状态创建过程中,有状态是有先后顺序的无状态是没有的
第五步:controller manager
controller manager会通过API Server提供的接口实时监控资源对象的当前状态,当发生各种故障导致系统状态发生变化时,会尝试将其状态修复到“期望状态”。
— 3 —
创建过程注意点
1、合理的设置cicd块 网络划分,注意网络隔离资源及网络冲突预留扩展性
2、在master进行高可用的冗余部署,以防止单可用区 或者 单机房宕机情况
3、注意etcd数据库容量问题
4、注意services 暴露过多导致网络调用链的问题
— 4 —
云厂商K8S对比情况
据aws同学说 最新的eks SLA 增加到了99.95% 创建过程也缩减到了9分钟
— 5 —
k8s排查故障神图