kubelet
kubelet 进程用于处理master 下发的任务, 管理pod 中的容器, 注册 自身所在的节点.
节点管理
启动参数说明
--register-node #如果设置为true 则会向api server 注册自身node,如果设置为false 需要管理员手工配置
--api-server # api server 的位置 ip 地址或域名
--kubeconfig # kubeconfig 文件, 用于访问 api server 的安全配置文件
--cloud-provider: #云服务商地址, 仅用于公有云
--node-status-update-frequency #设置 kubelet 上报时间间隔.
pod 管理
kubelet 通过以下方式获取node 上运行的 pod 信息
- 文件: kubelet 通过启动参数 --config 指定配置文件目录下的文件(默认为 /etc/kubernetes/manifests/ 静态pod读取位置), 通过 --file-check-frequency 设置检查目录的间隔时间, 默认20s
- http 端点(url): 通过 --manifest-url 参数设置. 通过 --http-check-frequency 设置检查间隔时间, 默认20秒 (另外一种静态pod读取位置)
- api server: kubelet 通过 api server 监听 etcd 目录, 同步pod 列表
kubelet watch 加 list的方式监听 /registry/nodes/$NODENAME 当前节点名称, 和 registry/pods , 将获取的信息同步到本地缓存.
kubelet 读取监听信息, 对创建和修改做如下处理
- 为该 POD 创建一个数据目录
- 从 api server 读取 pod 清单
- 为该 pod 挂载外部卷 (External Volume)
- 下载 pod 用到 secret
- 检查已经运行在该节点的 pod, 如果 pod 没有容器, 或者 kubernetes/pause 容器没启动, 则先停止所有容器进程, 如果有需要删除的容器则删除
- 创建 kubernetes/pause 容器到pod中, 该 pause 容器 用于接管 pod 中所有其他容器的网络. 然后再创建其他容器.
- 为每个pod 中的容器做如下处理
- 为容器计算一个hash值, 然后用容器名称去查询对应的hash值, 如果发现不对,则停止容器中的进程, 停止与pause 容器的关联. 如果相同不做处理
- 如果容器被终止, 其容器没有指定 restartPolicy 则不做处理
- 调用docker client 下载容器镜像, 调用docker client 运行容器
容器健康检查
检查容器健康的两类探针
- LivenessProbe 探针, 用于判断容器是否健康, 并反馈给kubelet, 如果返回结果为不健康, kubelet 则删除容器,并根据重启策略做相应处理. 如果容器的yaml 定义中不包含 LivenessProbe 探针, 则认为该容器健康永远返回 success.
- ReadinessProbe 探针, 用于判断容器是否启动完成, 并且开始接受请求. 如果 ReadinessProbe 返回失败, 则容器状态被修改 Endpoint Controller 将从 service 的 Endpoint 中删除改 容器所在的 POD 的 IP
LivenessProbe 探针的实现方式
- ExecAction: 在容器内部执行一个命令, 如果改命令退出码为 0 , 则表示容器健康
- TCPSocketAction: 通过容器的 IP 地址和端口执行 TCP 检查, 如果端口能通, 则表明容器健康
- HttpGetAction: 通过 http get 访问容器 IP 的地址和端口 , 如果返回的状态吗大于200 小于 400 则认为容器状态健康
kube-proxy 运行机制解析
kube-proxy 本质上,类似一个反向代理. 我们可以把每个节点上运行的 kube-proxy 看作 service 的透明代理兼LB.
第二代转发机制: iptables 直接 nat
kube-proxy 监听 apiserver 中service 与Endpoint 的信息, 配置iptables 规则,请求通过iptables 直接转发给 pod
- 优点:效率高
- 缺点: 当 service 与pod 增加后 iptables 规则急剧膨胀, 性能下降与丢失请求.
第三代转发机制 IPVS + ipset
ipvs 是一个基于iptables 的高性能的负载均衡, 并使用高效的数据结构(hash), 允许无限规模扩张
ipvs 优势
- 更好的扩展性和性能
- 支持比 iptables 更复杂的LB 算法
- 支持服务健康检查及连接充实
- 可以动态修改ipset的集合, 即使iptables 的规则正在使用这个集合
ipvs 缺陷
无法提供包过滤, airpin-masquerade tricks (地址伪装) , SNAT 等功能, 因此需要与iptables 搭配使用. 在 IPVS 模式下, kube-proxy 使用 iptables 的扩展 ipset 来生成规则链.
iptables 是一个线性数据结构, ipset 则引入了带索引的数据结构,可以高效匹配.
kube-proxy主要的iptables 规则
- KUBE-CLUSTER-IP: 在 masquerade-all=true 或 clusterCIDR 指定的情况下, 对 service cluster ip 地址进行伪装, 以解决数据包欺骗问题.
- KUBE-EXTERNAL-IP: 将数据包装为 service 的外部 ip 地址
- KUBE-LOAD-BALANCER, KUBE-LOAD-BALANCER-LOCAL: 伪装 Loadbalance 类型的 service 流量
- KUBE-NODE-PORT-TCP, KUBE-NODE-PORT-LOCAL-TCP, KUBE-NODE-PORT-UDP, KUBE-NODE-LOCAL-UDP: 伪装 Nodeport 类型的service 流量.
IPVS启用方式
添加内核配置
cat > /etc/sysconfig/modules/ipvs.modules <<EOF
#!/bin/bash
modprobe -- ip_vs
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
modprobe -- ip_vs_sh
modprobe -- nf_conntrack_ipv4
EOF
# 授权
chmod 755 /etc/sysconfig/modules/ipvs.modules
# 加载模块
bash /etc/sysconfig/modules/ipvs.modules
# 查看加载
lsmod | grep -e ip_vs -e nf_conntrack_ipv4
# 输出如下:
-----------------------------------------------------------------------
nf_conntrack_ipv4 20480 0
nf_defrag_ipv4 16384 1 nf_conntrack_ipv4
ip_vs_sh 16384 0
ip_vs_wrr 16384 0
ip_vs_rr 16384 0
ip_vs 147456 6 ip_vs_rr,ip_vs_sh,ip_vs_wrr
nf_conntrack 110592 2 ip_vs,nf_conntrack_ipv4
libcrc32c 16384 2 xfs,ip_vs
-----------------------------------------------------------------------
K8S 配置
配合kubeadm 使用:
kubeadm config print init-defaults > init-config.yaml
在config.yaml 中添加
kind: MasterConfiguration
apiVersion: kubeadm.k8s.io/v1alpha1
…
kubeProxy:
config:
featureGates: SupportIPVSProxyMode=true
mode: ipvs
或者添加
---
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: "ipvs"
两者二选一
然后使用
kubeadm init --config init-config.yaml 进行安装
kubeadm 默认配置查看
kubeadm config print init-defaults #查看默认配置
kubeadm config print init-defaults --component-configs KubeProxyConfiguration #查看某个组件的默认配置