1.master运行机制

1.1.api server

api server 提供了对k8s资源对象(pod,rc,service)增删改查及watch等http rest接口,是整个系统的数据总线和数据中心

api server 在master监听2个端口
--insecure-port num 监听一个非安全的127.0.0.1本地端口(默认8080)
该端口用于接收HTTP请求;
该端口默认值为8080,可以通过API Server的启动参数"--insecure-port"的值来修改默认值;
默认的IP地址为"localhost",可以通过启动参数"--insecure-bind-address"的值来修改该IP地址
非认证或授权的HTTP请求通过该端口访问API Server

--bind-address=1.1.1.1 监听一个安全的端口(默认为6443)
该端口默认值为6443,可通过启动参数"--secure-port"的值来修改默认值;
默认IP地址为非本地(Non-Localhost)网络端口,通过启动参数"--bind-address"设置该值
该端口用于接收HTTPS请求
用于基于Tocken文件或客户端证书及HTTP Base的认证
用于基于策略的授权

kubernetes API Server的功能与使用

1)提供了集群管理的REST API接口(包括认证授权、数据校验以及集群状态变更)
2)提供其他模块之间的数据交互和通信的枢纽(其他模块通过API Server查询或修改数据,只有API Server才直接操作etcd)
3)是资源配额控制的入口
4)拥有完备的集群安全机制

curl 127.0.0.1:8080/apis #分组api
curl 127.0.0.1:8080/api/v1 #带具体版本号的api
curl 127.0.0.1:8080/ #返回核心api列表
curl 127.0.0.1:8080/version #api 版本信息
curl 127.0.0.1:8080/healthz/etcd #与etcd的心跳监测
curl 127.0.0.1:8080/apis/autoscaling/v1 #api的详细信息

1.2.kube-controller-manager

集群内部的管理控制中心
负责集群内的node,pod副本,服务端点,命名空间,服务账号,资源定额的管理
当某个node意外宕机时,controller manager会及时发现并执行自动化修复流程,确保集群始终处于预期的工作状态

1.3.kube-scheduler

负责pod调度,整个系统中起"承上启下"作用
承上:负责接受controller manager创建新的pod,为其选择一个合适的Node
启下:node上的kubelet接管pod的生命周期
通过调度算法为待调度Pod列表的每个Pod从可用Node列表中选择一个最适合的Node,并将信息写入etcd中
node节点上的kubelet通过API Server监听到kubernetes Scheduler产生的Pod绑定信息,然后获取对应的Pod清单,下载Image,并启动容器。

优选策略
1.LeastRequestedPriority
优先从备选节点列表中选择资源消耗最小的节点(CPU+内存)。
2.CalculateNodeLabelPriority
优先选择含有指定Label的节点。
3.BalancedResourceAllocation
优先从备选节点列表中选择各项资源使用率最均衡的节点。

2.node节点运行机制

2.1.kubelet

ks8集群中,每个Node都会启动kubelet进程,用来处理master节点下发到本节点的任务,管理pod和其中的容器
kubelet会在api server上注册节点信息,定期向master汇报节点资源使用情况,并通过cadvisor监控容器和节点资源
kubelet是node上的pod管家

2.2.kube-proxy

运行在每个节点上,监听apiserver 中服务对象的变化,再通过管理iptables来实现网络的转发
支持三种工作模式:
1)userspace
k8s v1.2后就已经淘汰
2)iptables
目前默认方式
3)ipvs
需要安装ipvsadm,ipset工具包和加载ip_vs内核模块

k8s从1.9开始测试支持ipvs,从1.11版本正式支持ipvs
ipvs相对iptables效率更高一些,使用ipvs模式需要在运行kube-proxy的节点上安装ipvsadm,ipset工具包和加载
ip_vs内核模块
当kube-proxy以ipvs代理模式启动时,kube-proxy 将验证节点上是否安装了ipvs模块,如果未安装,则kube-proxy
将退到iptables代理模式

使用IPVS模式,Kube-Proxy会监视Kubernetes Service对象和Endpoints,
调用宿主机内核Netlink接口以相应地创建IPVS规则并定期与Kubernetes Service对象 Endpoints对象同步IPVS
规则,以确保IPVS状态与期望一致,

访问服务时,流量将被重定向到其中一个后端Pod,
IPVS使用哈希表作为底层数据结构并在内核空间中工作,这意味着IPVS可以更快地重定向流量,并且在同步代理规则
时具有更好的性能,
此外,IPVS 为负载均衡算法提供了更多选项,
例如:rr (轮询调度)、lc (最小连接数)、dh (目标哈希)、sh (源哈希)、sed (最短期望延迟)、nq(不排队调度)等。
kube-proxy监听 master 增加和删除service以及endpoint的消息
对每个service,创建相应的iptables规则,并将发送到service cluster ip 的流量转发到service后端提供服务
的pod的相应端口上
service的cluster ip和服务端口访问到后端pod提供的服务,但该clusterip是ping不通的,其原因是cluster ip
只是iptables中的规则,并不对应到一个任何网络设备。
ipvs模式的cluster ip是可以ping通的

3.etcd运行机制

etcd运行机制
etcd是coreOS团队2013年6月发起的开源项目,目标是构建一个高可用的分布式键值数据库
etcd内部采用raft协议作为一致性算法,etcd基于go语言实现

3.1.Etcd具有属性

1)完全复制:集群中的每个节点都可以使用完整的存档
2)高可用性:Etcd可用于避免硬件的单点故障或网络问题
3)一致性:每次读取都会返回跨多主机的最新写入
4)简单:包括一个定义良好、面向用户的API(gRPC)
5)安全:实现了带有可选的客户端证书身份验证的自动化TLS
6)快速:每秒10000次写入的基准速度
7)可靠:使用Raft算法实现了存储的合理分布Etcd的工作原理

3.2.启动脚本参数

[Unit]
Description=Etcd Server
After=network.target
After=network-online.target
Wants=network-online.target
Documentation=https://github.com/coreos

[Service]
Type=notify
WorkingDirectory=/var/lib/etcd/ #数据保存目录
ExecStart=/usr/bin/etcd \ #二进制文件路径
--name=etcd2 \ #当前node 名称
--cert-file=/etc/etcd/ssl/etcd.pem \
--key-file=/etc/etcd/ssl/etcd-key.pem \
--peer-cert-file=/etc/etcd/ssl/etcd.pem \
--peer-key-file=/etc/etcd/ssl/etcd-key.pem \
--trusted-ca-file=/etc/kubernetes/ssl/ca.pem \
--peer-trusted-ca-file=/etc/kubernetes/ssl/ca.pem \
--initial-advertise-peer-urls=https://192.168.47.51:2380 \ #通告自己的集群端口
--listen-peer-urls=https://192.168.47.51:2380 \ #集群之间通讯端口
--listen-client-urls=https://192.168.47.51:2379,http://127.0.0.1:2379 \ #客户端访问地址
--advertise-client-urls=https://192.168.47.51:2379 \ #通告自己的客户端端口
--initial-cluster-token=etcd-cluster-0 \ #创建集群使用的token,一个集群内的节点保持一致
--initial-cluster=etcd1=https://192.168.47.50:2380,etcd2=https://192.168.47.51:2380,etcd3=https://192.168.47.52:2380 \ #集群所有的节点信息
--initial-cluster-state=new \ #新建集群的时候的值为new,如果是已经存在的集群为existing
--data-dir=/var/lib/etcd #数据目录路径
Restart=on-failure
RestartSec=5
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target

3.3.查看成员信息

etcd v2 和v3 本质上是共享同一套raft协议代码的两个独立的应用,接口不一样,存储不一样,数据互相隔离,
也就是说etcd v2 升级到etcd v3,原来v2的数据还是只能用v2的接口访问,v3的接口创建的数据也只能访问通过v3
的接口访问
ETCDCTL_API=3 etcdctl --help
ETCDCTL_API=3 etcdctl member --help

root@k8s-etcd1:~# ETCDCTL_API=3 etcdctl member list --endpoints=https://192.168.47.50:2379 \
--cacert=/etc/kubernetes/ssl/ca.pem \
--cert=/etc/etcd/ssl/etcd.pem \
--key=/etc/etcd/ssl/etcd-key.pem
a8709311f2fc0a, started, etcd1, https://192.168.47.50:2380, https://192.168.47.50:2379
32904adc080b6d59, started, etcd2, https://192.168.47.51:2380, https://192.168.47.51:2379
6cf277362046d8f0, started, etcd3, https://192.168.47.52:2380, https://192.168.47.52:2379

3.4.验证当前etcd所有成员状态

root@k8s-etcd1:~# export NODE_IPS="192.168.47.50 192.168.47.51 192.168.47.52"
root@k8s-etcd1:~# for ip in ${NODE_IPS}; do ETCDCTL_API=3 /usr/bin/etcdctl endpoint health \
--endpoints=https://${ip}:2379 \
--cacert=/etc/kubernetes/ssl/ca.pem \
--cert=/etc/etcd/ssl/etcd.pem \
--key=/etc/etcd/ssl/etcd-key.pem ; \
done
https://192.168.47.50:2379 is healthy: successfully committed proposal: took = 30.092044ms
https://192.168.47.51:2379 is healthy: successfully committed proposal: took = 1.941332ms
https://192.168.47.52:2379 is healthy: successfully committed proposal: took = 1.02158ms

3.5.查看etcd数据信息

ETCDCTL_API=3 etcdctl get / --prefix --keys-only               #以路径的方式所有key信息
ETCDCTL_API=3 etcdctl get /calico/ipam/v2/assignment/ipv4/block/172.31.169.128-26

k8s运行机制及术语_k8s运行机制及术语

3.6.etcd增删改查数据

#添加数据
root@k8s-etcd1:~# ETCDCTL_API=3 /usr/bin/etcdctl put /testkey "test for linux36"
OK

#查询数据
root@k8s-etcd1:~# ETCDCTL_API=3 /usr/bin/etcdctl get /testkey
/testkey
test for linux36

#改动数据
root@k8s-etcd1:~# ETCDCTL_API=3 /usr/bin/etcdctl put /testkey "test for linux36-new" #直接覆盖就是更新数据
OK
root@k8s-etcd1:~# ETCDCTL_API=3 /usr/bin/etcdctl get /testkey
/testkey
test for linux36-new

#删除数据
root@k8s-etcd1:~# ETCDCTL_API=3 /usr/bin/etcdctl del /testkey
root@k8s-etcd1:~# ETCDCTL_API=3 /usr/bin/etcdctl get /testkey

k8s运行机制及术语_k8s运行机制及术语_02

3.7.etcd数据watch机制

基于不断监看数据,发生变化就主动触发通知客户端,etcd v3的watch机制支持watch某个固定的key,也支持watch一个范围
相比etcd v2 ,etcd v3的一些主要变化:
1)接口通过grpc提供rpc接口,放弃了v2的http接口。
2)优势是长连接效率提升明显,缺点是使用不如以前方便,尤其对不方便维护长连接的场景。
3)废弃了原来的目录结构,变成了纯粹的kv,用户可以通过前缀匹配模式模拟目录
4)内存中不再保存value,同样的内存可以支持存储更多的key
5)watch机制更稳定,基本上可以通过watch机制实现数据的完全同步。
6)提供了批量操作以及事务机制,用户可以通过批量事务请求来实现Etcd v2的CAS机制(批量事务支持if条件判断)。

watch测试

#在etcd node1上watch一个key:
ETCDCTL_API=3 /usr/bin/etcdctl watch /testkey
#在etcd node2修改数据,验证etcd node1是否能够发现数据变化
ETCDCTL_API=3 /usr/bin/etcdctl put /testkey "test for linux36-new"

3.8.etcd数据备份与恢复机制

WAL是write ahead log 的缩写,
wal:存放预写式日志,最大的作用是记录了整个数据变化的全部历程,在etcd中,所有数据的修改在提交前,都要先写
入到WAL中

3.8.1.etcd v2版本数据备份与恢复

/usr/bin/etcdctl backup --help
#V2版本备份数据:
ETCDCTL_API=2 etcdctl backup --data-dir /var/lib/etcd/ --backup-dir /opt/etcd_backup

#恢复
etcd --help | grep force
etcd --data-dir=/var/lib/etcd/default.etcd --force-new-cluster &

k8s运行机制及术语_k8s运行机制及术语_03

3.8.2.etcd v3版本数据备份与恢复

V3版本备份数据:
ETCDCTL_API=3 etcdctl snapshot save snapshot.db

V3版本恢复数据:
ETCDCTL_API=3 etcdctl snapshot restore snapshot.db --datadir=/opt/etcd-testdir

自动备份数据

root@k8s-etcd2:~# mkdir /data/etcd-backup-dir/ -p
root@k8s-etcd2:~# cat script.sh
-------------------------------------------------------------------------------------
#!/bin/bash
source /etc/profile
DATE=`date +%Y-%m-%d_%H-%M-%S`
ETCDCTL_API=3 /usr/bin/etcdctl snapshot save /data/etcd-backup-dir/etcdsnapshot-${DATE}.db
-------------------------------------------------------------------------------------

4.网络通信机制

k8s网络:主要涉及pod的各种访问需求
如:pod内部通信(单容器或多容器)
podA 与pod B 的通信
外部网络访问pod
pod访问外部网络
k8s网络基于第三方插件
插件规范:CNI(Container Network interface) 由CoreOS和Google联合定制

常用插件:calico和flannel

4.1.calico

纯三层的网络解决方案
为容器提供多Node间的访问通信
calico将每个Node节点当作为一个路由器,各节点通过BGP(边界网关协议)学习并在node节点生成路由规则,从而将
不同node节点上的pod连接起来进行通信
BGP是一个去中心化的协议,
通过自动学习和维护路由表实现网络的可用性,但是并不是所有的网络都支持BGP
为了跨网络实现更大规模的网络管理,calico还支持ip-in-ip的叠加模型,简称IPIP,
IPIP可以实现跨不同网段建立路由通信,但是会存在安全性问题,其在内核内置,可以通过calico的配置文件设置是否启用IPIP
在公司k8s的node节点没有跨越网段建议关闭IPIP

calico架构结构原理参考:​​https://blog.csdn.net/chaosj/article/details/83663291​

原理是通过修改每个主机节点上iptables和路由表规则,实现容器间数据路由和访问控制,并通过etcd协调节点配置信息

k8s运行机制及术语_k8s运行机制及术语_04

#组件
Felix:Calico Agent,跑在每台需要运行Workload的节点上,主要负责配置路由及ACLs等信息来确保Endpoint的连通状态;
etcd:分布式键值存储,主要负责网络元数据一致性,确保Calico网络状态的准确性;
BGP Client(BIRD):主要负责把Felix写入Kernel的路由信息分发到当前Calico网络,确保Workload间的通信的有效性;
BGP Route Reflector(BIRD):大规模部署时使用,摒弃所有节点互联的mesh模式,通过一个或者多个BGP Route Reflector
来完成集中式的路由分发

calico 跨节点通信的模式: IPIP模式(默认)和BGP模式(需要交换机支持BGP协议)。
其中IPIP模式分为两种CrossSubnet (我们采用的模式)和 ALL;
ALL:所有节点通信都通过ip隧道,
CrossSubnet: 跨网段的使用ip隧道,走三层,通过tunl0网口转发,同一网段的直接把宿主机作为路由,走二层,通过eth0网口转发

#crosssubnet同网段实例:
podA:eth0 -->caliXXX ---node1:eth0--》node2:eth0 --caliXXX --->podB:eth0

#跨网段:
pod:eth0 ---> caliXXX --->node1:tunl0--》node2:tunl0-->caliXXX-->pod:eth0
#验证当前路由表
calicoctl node status

#开启IPIP的通信状态
root@k8s-master1:~# kubectl get pods -o wide
root@k8s-master1:~# kubectl exec -it net-test1-68898c85b7-z7rgs sh
traceroute ip地址

#关闭IPIP的通信状态
需要关闭IPIP并重启服务器
route -n
root@k8s-master1:/etc/ansible# kubectl run net-test1 --image=alpine --replicas=4 sleep 360000 #创建pod进行网络测试
root@k8s-master1:/etc/ansible# kubectl exec -it net-test1-68898c85b7-qrh7b sh
traceroute ip地址

4.2.flannel

由coreOs开源的针对k8s的网络服务,其目的是为了解决k8s集群中各主机上的pod相互通信的问题,
其借助etcd维护网络ip地址分配,并为每一个node服务器分配一个不同的ip地址段
flannel网络模型(后端),flannel目前有三种方式实现UDP/VXL/host-gw
----------------------------------------------------------------------------------------
1)UDP:早期版本的Flannel使用UDP封装完成报文的跨越主机转发,其安全性及性能略有不足。

2)VXLAN:Linux内核在2012年底的v3.7.0之后加入了VXLAN协议支持,因此新版本的Flannel也由UDP转换为VXLAN,
VXLAN本质上是一种tunnel(隧道)协议,用来基于3层网络实现虚拟的2层网络,目前flannel 的网络模型已经是基于VXLAN的叠加(覆盖)网络。

3)Host-gw:也就是Host GateWay,通过在node节点上创建到达各目标容器地址的路由表来完成报文的转发,因
此这种方式要求各node节点本身必须处于同一个局域网(二层网络)中,因此不适用于网络变动频繁或比较大型的
网络环境,但是其性能较好

4.2.1.Flannel 组件的解释

Cni0:网桥设备,每创建一个pod都会创建一对veth pair,其中一端是pod中的eth0,另一端是Cni0网桥中的端口(网卡),
Pod中从网卡eth0发出的流量都会发送到Cni0网桥设备的端口(网卡)上,Cni0设备获得的ip地址是该节点分配到的网段的第一个地址。

Flannel.1: overlay网络的设备,用来进行vxlan报文的处理(封包和解包),不同node之间的pod数据流量都从overlay
设备以隧道的形式发送到对端

4.2.2.Flannel不同node上的pod的通信流程

k8s运行机制及术语_k8s运行机制及术语_05

->: pod中产生数据,根据pod的路由信息,将数据发送到Cni0
->: Cni0 根据节点的路由表,将数据发送到隧道设备flannel.1
->: Flannel.1查看数据包的目的ip,从flanneld获得对端隧道设备的必要信息,封装数据包。
->: Flannel.1将数据包发送到对端设备,对端节点的网卡接收到数据包

->: 对端节点发现数据包为overlay数据包,解开外层封装,并发送到到本机flannel.1设备。
->: Flannel.1设备查看数据包,根据路由表匹配,将数据发送给Cni0设备。
->: Cni0匹配路由表,发送数据给网桥上对应的端口(pod)。

k8s运行机制及术语_k8s运行机制及术语_06

4.2.3.Flannel的系统文件及目录

root@k8s-node2:~# find / -name flannel
/run/flannel
/usr/bin/flannel
/var/lib/cni/flannel

4.2.4.flannel pod状态

k8s运行机制及术语_k8s运行机制及术语_07

4.2.5.创建测试pod

k8s运行机制及术语_k8s运行机制及术语_08

4.2.6.验证pod状态

k8s运行机制及术语_k8s运行机制及术语_09

4.2.7.当前node主机IP地址范围

k8s运行机制及术语_k8s运行机制及术语_10

4.2.8.当前node主机cni信息

k8s运行机制及术语_k8s运行机制及术语_11

2.2.9.当前node主机路由

k8s运行机制及术语_k8s运行机制及术语_12

2.2.10.验证夸主机pod通信

k8s运行机制及术语_k8s运行机制及术语_13

4.2.11.VxLAN Directrouting

Directrouting 为在同一个二层网络中的node节点启用直接路由机制,类似于host-gw模式

4.2.11.1.修改flannel支持Directrouting

k8s运行机制及术语_k8s运行机制及术语_14

4.2.11.2.验证修改后的路由表

k8s运行机制及术语_k8s运行机制及术语_15

4.2.11.3.验证修改后的路由效果

k8s运行机制及术语_k8s运行机制及术语_16