知识点合集
- 一、Kurbernetes常见的部署方式
- 1.1 Minikube(一般不用)
- 1.2 Kubeadm
- 1.3 二进制安装部署(推荐使用的方式)
- 二、二进制部署Kurbetnetes的思路
- Step1 部署etcd
- Step2 部署master组件
- Step3 部署node组件
- Step4 部署多master高可用
- 三、Kubeadm部署Kurbernetes集群的思路
- 四、更新kubeadm搭建的K8S组件证书有效期
- 五、涉及的理论知识总结
- 5.1 CFSSL工具(了解)
- 5.2 kubelet的RBAC授权机制(了解)
- 5.3 Kurbernetes的网络和接口
- 5.4 Kurbernetes 中 Pod 网络通信
- 5.5 CoreDNS 简介
- 六、CNI网络插件
- 6.1 CNI简介
- 6.2 Flannel插件
- 6.2.1 Flannel UDP模式的工作原理
- 6.2.2 Flannel VXLAN模式的工作原理
- 6.3 Calico插件
- 6.3.1 Calico IPIP模式的工作原理
- 6.3.2 Calico BGP模式的工作原理
- 6.4 Flannel 和 Calico 的区别?
一、Kurbernetes常见的部署方式
1.1 Minikube(一般不用)
Minikube是一个工具,可以在本地快速运行一个单节点微型K8S,仅用于学习、预览K8S的一些特性使用。
部署地址:https://kubernetes.io/docs/setup/minikube
1.2 Kubeadm
Kubeadm也是一个工具,提供kubeadm init
和kubeadm join
,用于快速部署K8S集群,相对简单。
部署地址:https://kubernetes.io/docs/reference/setup-tools/kubeadm/kubeadm/
1.3 二进制安装部署(推荐使用的方式)
生产首选,从官方下载发行版的二进制包,手动部署每个组件和自签TLS证书,组成K8S集群,新手推荐。
https://github.com/kubernetes/kubernetes/releases
Kubeadm降低部署门槛,但屏蔽了很多细节,遇到问题很难排查。如果想更容易可控,推荐使用二进制包部署Kubernetes集群,虽然手动部署麻烦点,期间可以学习很多工作原理,也利于后期维护。
二、二进制部署Kurbetnetes的思路
Step1 部署etcd
1)使用cfssl工具签发证书和私钥;
2)解压etcd软件包,获取二进制文件 etcd
、etcdctl
;
3)准备etcd集群配置文件;
4)启动etcd服务进程,加入到etcd集群。
相关命令补充
#查看etcd集群健康状态
ETCDCTL_API=3 /opt/etcd/bin/etcdctl --endpoints="https://etcd01IP:2379,https://etcd02IP:2379,https://etcd03IP:2379" --cacert=CA证书 --cert=服务端证书 --key=服务端私钥 endpoint health -wtable
#查看etcd集群状态信息
ETCDCTL_API=3 /opt/etcd/bin/etcdctl --endpoints="https://etcd01IP:2379,https://etcd02IP:2379,https://etcd03IP:2379" --cacert=CA证书 --cert=服务端证书 --key=服务端私钥 endpoint status -wtable
#查看etcd集群成员列表
ETCDCTL_API=3 /opt/etcd/bin/etcdctl --endpoints="https://etcd01IP:2379" --cacert=CA证书 --cert=服务端证书 --key=服务端私钥 member list -wtable
#备份etcd数据库
ETCDCTL_API=3 /opt/etcd/bin/etcdctl --endpoints="https://etcd01IP:2379" --cacert=CA证书 --cert=服务端证书 --key=服务端私钥 snapshot save 备份文件路径
#恢复etcd数据库
ETCDCTL_API=3 /opt/etcd/bin/etcdctl --endpoints="https://etcd01IP:2379" --cacert=CA证书 --cert=服务端证书 --key=服务端私钥 snapshot restore 文件路径
#查看备份文件的状态信息
ETCDCTL_API=3 /opt/etcd/bin/etcdctl --endpoints="https://etcd01IP:2379" --cacert=CA证书 --cert=服务端证书 --key=服务端私钥 snapshot status 文件路径
Step2 部署master组件
1)使用cfssl工具签发证书和私钥;
2)解压K8S服务端软件包,获取二进制文件 kube-apiserver
、kube-controller-manager
、 kube-scheduler kubectl
;
3)准备 kube-apiserver 启动时要调用的 bootstrap-token
认证文件(token.csv);
4)准备 kube-apiserver
、kube-controller-manager
和kube-scheduler
的服务进程启动参数配置文件;
5)准备 kube-controller-manager
、 kube-scheduler
和 kubectl
的 kubeconfig 集群引导配置文件(加入K8S集群的引导文件);
6)依次启动 kube-apiserver
、kube-controller-manager
和 kube-scheduler
的服务进程。
Step3 部署node组件
1)获取二进制文件 kubelet
、kube-proxy
;
2)准备 kubelet
、kube-proxy
的 kubeconfig 集群引导配置文件 kube-proxy.kubeconfig bootstrap.kubeconfig(kubelet首次访问apiserver加入K8S集群使用引导文件);
3)准备 kubelet
、kube-proxy
的服务进程启动参数配置文件;
4)启动 kubelet 服务进程,向 apiserver 发起 CSR 请求颁发证书,master 通过 CSR 请求后 kubelet 方可获取到证书;
5)加载 ipvs 模块,启动 kube-proxy 服务进程;
6)安装 cni 网络插件(flannel/calico)
和 CoreDNS
;
7)执行 kubectl get nodes 命令
查看node的状态。
Step4 部署多master高可用
1)复制 master 组件的相关的证书、私钥、启动配置文件、kubeconfig集群引导配置文件、二进制文件和 etcd 的证书、私钥;
2)修改 apiserver 启动配置文件的监听地址和通告地址,依次启动 kube-apiserver
、kube-controller-manager
、kube-scheduler
的服务进程;
3)部署 nginx/haproxy 负载均衡器和 keepalived 高可用;
4)修改 kubelet、kube-proxy、kubectl 的 kubeconfig集群引导配置文件中的 server 参数指向 keepalived 的 VIP 地址;
5)修改 kube-controller-manager、kube-scheduler 的 kubeconfig集群引导配置文件中的 server 参数指向本机的 apiserver 地址。
三、Kubeadm部署Kurbernetes集群的思路
1)所有节点进行初始化,安装 容器运行时、kubeadm、kubelet、kubectl;
2)执行 kubeadm config print init-defaults
命令生成集群初始化配置文件并进行修改;
3)执行 kubeadm init
命令根据初始化配置文件初始化生成K8S master控制管理节点;
4)安装 CNI 网络插件(flannel/calico);
5)在其它节点执行 kubeadm join
命令将将node节点或者其它master节点加入到K8S集群中。
#kubeadm init
在使用kubeadm方式安装K8S集群时,可根据初始化配置文件或者配置参数选项快速地初始化生成一个K8S的master管理平台
#kubeadm join
根据kubeadm init初始化的提示信息快速的将一个node节点或者其它master节点加入到K8S集群中
四、更新kubeadm搭建的K8S组件证书有效期
1)备份老证书和kubeconfig配置文件
mkdir /etc/kubernetes.bak
cp -r /etc/kubernetes/pki /etc/kubernetes.bak
cp /etc/kubernetes/*.conf /etc/kubernetes.bak
2)重新生成证书
kubeadm alpha certs renew all --config=集群初始化配置文件
3)重新生成kubeconfig配置文件
kubeadm init phase kubeconfig all --config=集群初始化配置文件
4)重启kubelet和其它K8S组件的Pod容器
systemctl restart kubelet
mv /etc/kubernetes/manifests/*.yaml /tmp
mv /tmp/*.yaml /etc/kubernetes/manifests
5)查看证书有效期
kubeadm alpha certs check-expiration
openssl x509 -noout -dates -in /etc/kubernetes/pki/XXX.crt
五、涉及的理论知识总结
5.1 CFSSL工具(了解)
CFSSL 是 CloudFlare 公司开源的一款 PKI/TLS 工具。
CFSSL 包含一个命令行工具和一个用于签名、验证和捆绑 TLS 证书的 HTTP API 服务。使用Go语言编写。
CFSSL 使用配置文件生成证书,因此自签之前,需要生成它识别的 json 格式的配置文件,CFSSL 提供了方便的命令行生成配置文件。
CFSSL 用来为 etcd 提供 TLS 证书。
它支持签三种类型的证书:
1)client 证书,服务端连接客户端时携带的证书,用于客户端验证服务端身份,如 kube-apiserver 访问 etcd;
2)server 证书,客户端连接服务端时携带的证书,用于服务端验证客户端身份,如 etcd 对外提供服务;
3)peer 证书,相互之间连接时使用的证书,如 etcd 节点之间进行验证和通信。
这里全部都使用同一套证书认证。
5.2 kubelet的RBAC授权机制(了解)
kubelet 采用 TLS Bootstrapping 机制,自动完成到 kube-apiserver 的注册,在 node 节点量较大或者后期自动扩容时非常有用。
Master apiserver 启用 TLS 认证后,node 节点 kubelet 组件想要加入集群,必须使用CA签发的有效证书才能与 apiserver 通信,当 node 节点很多时,签署证书是一件很繁琐的事情。
因此 Kubernetes 引入了 TLS bootstraping 机制来自动颁发客户端证书,kubelet 会以一个低权限用户自动向 apiserver 申请证书,kubelet 的证书由 apiserver 动态签署。
kubelet 首次启动通过加载 bootstrap.kubeconfig 中的用户 Token 和 apiserver CA 证书发起首次 CSR 请求,这个 Token 被预先内置在 apiserver 节点的 token.csv 中,其身份为 kubelet-bootstrap 用户和 system:kubelet-bootstrap 用户组;
想要首次 CSR 请求能成功(即不会被 apiserver 401 拒绝),则需要先创建一个 ClusterRoleBinding,将 kubelet-bootstrap 用户和 system:node-bootstrapper 内置 ClusterRole 绑定(通过 kubectl get clusterroles 可查询),使其能够发起 CSR 认证请求。
5.3 Kurbernetes的网络和接口
Kurbernetes网络 | |
---|---|
节点网络 | nodeIP |
Pod网络 | podIP |
Service网络 | clusterIP |
Kurbernetes接口 | 描述 | 类型 |
---|---|---|
CRI | 容器运行时接口 | docker containerd podman cir-0 |
CNI | 容器网络接口 | flannel calico cilium |
CSI | 容器存储接口 | ceph nfs gfs oss s3 |
5.4 Kurbernetes 中 Pod 网络通信
1.Pod 内容器与容器之间的通信
在同一个 Pod 内的容器(Pod 内的容器是不会跨宿主机的)共享同一个网络命令空间,相当于它们在同一台机器上一样,可以用 localhost 地址访问彼此的端口。
2.同一个 Node 内 Pod 之间的通信
每个 Pod 都有一个真实的全局 IP 地址,同一个 Node 内的不同 Pod 之间可以直接采用对方 Pod 的 IP 地址进行通信。
Pod1 与 Pod2 都是通过 Veth 连接到同一个 docker0 网桥,网段相同,所以它们之间可以直接通信。
3.不同 Node 上 Pod 之间的通信
Pod 地址与 docker0 在同一网段,docker0 网段与宿主机网卡是两个不同的网段,且不同 Node 之间的通信只能通过宿主机的物理网卡进行。
要想实现不同 Node 上 Pod 之间的通信,就必须想办法通过主机的物理网卡 IP 地址进行寻址和通信,因此要满足两个条件
1)Pod 的 IP 不能冲突;
2)将 Pod 的 IP 和所在的 Node 的 IP 关联起来,通过这个关联让不同 Node 上 Pod 之间直接通过内网 IP 地址通信。
而CNI网络插件,可以满足这两个条件
5.5 CoreDNS 简介
CoreDNS 是 K8S 的默认 DNS 实现。
根据 service 资源名称,解析出对应的 clusterIP;
根据 statefulset 控制器创建的 Pod 资源名称,解析出对应的 podIP。
六、CNI网络插件
为了实现不同 Node 上 Pod 之间的通信。
6.1 CNI简介
CNI (Container Networking Interface) 是一个为容器运行时(如Docker、Kubernetes等)提供网络插件的规范和接口,用于管理容器之间和容器与外部网络之间的通信。
CNI 的目标是提供一个标准的插件架构,使不同的容器运行时可以使用不同的网络实现,并且能够方便地切换和配置网络插件。
6.2 Flannel插件
网络模式 | 描述 |
---|---|
UDP | 出现最早的模式,但是性能较差,基于flanneld应用程序实现数据包的封装/解封装 |
VXLAN | 默认模式,是推荐使用的模式,性能比UDP模式更好,基于内核实现数据帧的封装/解封装,配置简单使用方便 |
HOST-GW | 性能最好的模式,但是配置复杂,且不能跨网段 |
6.2.1 Flannel UDP模式的工作原理
1)原始数据包从源主机的Pod容器发出到cni0网桥接口,再由cni0转发到flannel0虚拟接口;
2)flanneld服务进程会监听flannel0接口收到的数据,flanneld进程会将原始数据包封装到UDP报文里;
3)flanneld进程会根据在etcd中维护的路由表查到目标Pod所在的nodeIP,并在UDP报文外再封装nodeIP报文、MAC报文,再通过物理网卡发送到目标node节点;
4)UDP报文通过8285号端口送到目标node节点的flanneld进程进行解封装,再通过flannel0接口转发到cni0网桥,再由cni0转发到目标Pod容器。
6.2.2 Flannel VXLAN模式的工作原理
1)原始数据帧从源主机的Pod容器发出到cni0网桥接口,再由cni0转发到flannel.1虚拟接口;
2)flannel.1接口收到数据帧后添加VXLAN头部,并在内核将原始数据帧封装到UDP报文里;
3)flanneld进程根据在etcd维护的路由表将UDP报文通过物理网卡发送到目标node节点;
4)UDP报文通过8472号端口送到目标node节点的flannel.1接口在内核进行解封装,再通过flannel.1接口转发到cni0网桥,再由cni0转发到目标Pod容器。
6.3 Calico插件
6.3.1 Calico IPIP模式的工作原理
1)原始数据包从源主机的Pod容器发出到tunl0接口,并被内核的IPIP驱动封装到节点网络的IP报文里;
2)再根据tunl0接口的路由经过物理网卡发送到目标node节点;
3)IP数据包到达目标node节点后再通过内核的IPIP驱动解包得到原始IP数据包;
4)然后根据本地的路由规则经过 veth pair 设备送达到目标Pod容器。
6.3.2 Calico BGP模式的工作原理
本质就是通过路由表来维护每个Pod的通信,Felix负责维护路由规则和网络接口管理,BIRD负责分发路由信息给其它节点。
1)源主机的Pod容器发出的原始IP数据包会通过 veth pair 设备
送达到节点网络空间;
2)然后会根据原始IP数据包的目标IP和节点的路由规则找到目标node节点的IP,再经过物理网卡发送到目标node节点;
3)IP数据包到达目标node节点后会根据本地的路由规则经过 veth pair 设备送达到目标Pod容器。
6.4 Flannel 和 Calico 的区别?
Flannel
1)模式:UDP VXLAN HOST-GW;
2)默认网段:10.244.0.0/16;
3)通常采用VXLAN模式,用的是叠加网络、IP隧道方式传输数据,对性能有一定的影响;
4)功能简单配置方便利于管理;
5)不具备复杂的网络策略规则配置能力。
Calico
1)模式:IPIP BGP 混合模式(CrossSubnet)
2)默认网段:192.168.0.0/16
3)使用IPIP模式可以实现跨子网传输,但是传输过程中需要额外的封包和解包过程,对性能有一定的影响
4)使用BGP模式会把每个node节点看做成路由器,通过Felix、BIRD组件来维护和分发路由规则,可实现直接通过BGP协议路由转发,传输过程中不需要额外的封包和解包,因此性能较好,但是只能同一个网段里使用,无法跨子网传输。
5)它不使用cni0网桥,而是通过路由规则把数据包直接发送到目标网卡,所以性能高;
6)具有更丰富的网络策略配置管理能力、功能更全面,但是维护起来较为复杂。
总结
对于较小规模且网络要求简单的K8S集群,可以采用flannel做cni网络插件。
对于集群规模较大且要求更多的网络策略配置时,可以采用性能更好功能更全的calico。