kube-proxy
- kube-proxy是运行在每个节点上的。
- 通过API Server监听Service和Endpoint对象的变化,根据Endpoint中的信息,把流量转发到Service后端的Pod中
Service和Pod关系
Service后面章节详解
Service被分配到ClusterIp,对外访问端口nodePort,Pod端口targetPort,Service端口port(内部集群访问后端Pod:ClusterIp+Service端口;对外访问:nodeIP+nodePort)
kube-proxy的转发模式
- iptables
- 通过每个节点上iptables规则实现
- iptables小规模集群可以使用,大规模集群可能会有性能问题
- iptables规则是一个线性的数据结构,查找匹配需要更多的时间、速度较慢;更新路由规则需全量更新,规模大了集群的性能会下降,目前都逐步不再使用
- ipvs
- 采用的是iptables的扩展ipset,ipset引入了带索引的数据结构(哈希表),运行在内核中
- 优势:哈希表查询速度快,在更新或者创建Service后,无需全量更新路由
容器运行时
- 容器运行时分为高层运行时和底层运行时 高层运行时(主要):Docker、Containerd、Cri-o
- kubelet内嵌的DockerShim操作Docker API来操作容器
- 由于K8S操作容器的复杂度提升,所以:
kubelet通过CRI接口对容器、沙盒、容器镜像进行操作 底层运行时:runc、kata等
网络插件
Kubernetes网络模型设计的基础原则:
-
所有Pod和节点能够不通过NAT就能互相访问
-
容器内看见的IP地址和外部看到的容器地址是一样的
容器运行时读取网络插件配置流程:
容器运行时一般配置两个参数: -
–cni-bin-dir:所在目录/opt/cni/bin
-
–cni-conf-dir:/etc/cni/net.d
-
当kubelet内置的docker作为容器运行时,由kubelet查找CNI插件
网络插件除了支持设置和清理pod的网络接口外,还需要支持iptables
容器—>网络接口—>linux网桥
需将:net/bridge/bridge-nf-call-iptables参数sysctl设置为1,网桥上的数据包将遍历iptables规则
Calico
性能好、灵活性高、可设置网络策略、安全性好
基于第三层,使用BGP路由协议在主机之间路由数据包
跨网段通信:
IPIP使用虚拟网卡设备tunl0(IP封装–>另一个IP数据包),外头数据包的源头地址为隧道入口设备的IP地址
Calico通过ACLs协议和kube-proxy来创建iptables过滤规则
Pod详解
Pod的生命周期
Pod启动
- API Server接收到客户端创建Pod的请求
- API Server查询Etcd之前是否有创建过,并写入Etcd
- Scheduler监听到API Server有创建Pod。查看Pod是否已被调度,如果没有,就会分配一个最优的计算节点
- Scheduler选择好最优的节点后会返回给API Server,API Server会将信息写入Etcd
- 同时Kubelet也会监听到API Server Pod的资源变化,当发现Pod调度到自己所在的节点上时,会用相关的组件调动容器的启动,并返回给API Server,API Server会将信息写入Etcd
Pod删除 - 用户发起删除Pod的请求
- API Server接收到后,并不会立刻删除,而是有一个删除的缓冲期,默认设置时30s
- API Server将Pod已删除的信息返回给用户,此时Pod状态为Terminiating
- Kubelet监听到API Server删除Pod的动作,准备删除Pod
- Kubelet首先会停止Pod内所有的容器
- 容器停止后,容器运行时会向Kubelet发送消息,表示容器的状态发生了改变,并保存到Status中去
- Endpoint监听到Pod删除的状态变化,会删除Pod的IP地址
- Kube-proxy监听到Endpoint对象的变化,会移除删除Pod的IP的转发规则
- 当所有容器被停止后,容器沙箱就会被停止
- Kubelet最终把Pod删除,并返回给API Server
- API Server将这个Pod从Etcd中移除
Pod的质量保证
Qos:Quality of Service
Qos的三种级别:
- Guarantee:Pod中所有容器都申请了Memory和CPU的limits和requests,是最高优先级别的Pod,K8S不会主动去”杀掉“这类容器,除非他们的使用率查过了limits的值(容器只指定了limits,没有requests,那么Kubernetes会自动填写一个与limits值相等的requests)
- Burstable:Pod内至少优一个容器指定了Memory或者CPU的requests或limits
- limits和requests的规则:
- 容器指定了CPU都limits和requests,当容器CPU使用量超过了limits,容器进程将会被限制
- 容器指定了CPU的requests,没有指定limits,当节点压力不大时,该容器可以使用超过requests值的节点上剩余的可用CPU
- 容器指定了Memory的limits和requests,当容器的内存使用超过requests且没有超过limits,如果节点内存不足,那么这个容器将被“杀掉”;如果内存使用量超过了limits,这个容器将被kernel“杀掉”(OOM)
- 容器指定了Memory的requests,没有指定limits,容器可以使用超过requests值的节点上剩余的可用Memory,但当节点内存无法满足其他容器时,该容器会被杀掉
- limits和requests的规则:
- BestEffort:Pod中的容器都没有指定Memory和CPU的limits或requests,如果节点有资源问题,那么该Pod第一个被“杀掉”