这里主要说一下上一层搭建过程中的问题
问题如下
关于网络的问题
一个是解析的问题,一个是虚拟IP分配已经路由的问题,涉及到的是DNS和Flannel两个组件。
DNS 的问题
DNS通过使用插件管理系统cluster add-on,成为了一个内建的自启动服务解析。
我们一般使用CoreDNS 组件来实现service 服务的解析达到找到后面的pod 的目的。
Kubernetes 域名的全称,必须是 service-name.namespace.svc.cluster.local 这种模式,服务名
# nslookup kubernetes.default.svc.cluster.local
Server: 10.200.254.254
Address: 10.200.254.254:53
Name: kubernetes.default.svc.cluster.local
Address: 10.200.0.1
DNS 策略是可以设置的,既dnsPolicy。
DNS解决的是寻址的问题,Flannel 解决的是地址分配的问题,既虚拟IP的分配。
为了解决网络规划的问题,所以我们又使用了Flannel .
Flannel 的问题说明
Flannel的设计目的就是为集群中的所有节点重新规划IP地址的使用规则,从而使得不同节点上的容器能够获得“同属一个内网”且”不重复的”IP地址,并让属于不同节点上的容器能够直接通过内网IP通信。
如果没有这个组件,那么在不同的节点上的Docker 服务起来的容器,虚拟IP 首先是可能重复的,而且不同节点上的IP是无法互通的既ping .
Flannel 是每个节点会有一个网络代理组件(overlay方式)flanneld,会为所在主机从集群的网络地址空间中,获取一个小的网段subnet,本主机内所有容器的IP地址都将从中分配。通过以下命令查看某个节点获取的网段信息:
[root@k8s-node2 ~]# cat /run/flannel/subnet.env
它是一种覆盖网络,也就是会把TCP数据包保证到另一种网络包进行路由转发和通信。
覆盖网络是建立在另一个网络之上并由其基础设施支持的虚拟网络。覆盖网络通过将一个分组封装在另一个分组内来将网络服务与底层基础设施分离。在将封装的数据包转发到端点后,将其解封装
Flannel是一个DaemonSet服务,所以每个节点都会有个代理服务,然后,每个节点也会有一个虚拟网卡,接收docker 网卡的数据,并维护路由,进行数据的封包转发。
Flannel 也是高度和Etcd 集成的,通过etcd ,所有的node 看到的flannel 的配置是相同的,每个节点上的flannel 代理组件箭筒etcd 的数据变化,从而感知集群的node 变化。
[root@k8s-master pki]# kubectl get daemonset --all-namespaces
NAMESPACE NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
kube-system kube-flannel-ds-amd64 2 2 1 2 1 beta.kubernetes.io/arch=amd64 304d
kube-system kube-proxy 2 2 1 2 1 <none> 304d
metallb-system speaker 1 1 1 1 1 <none> 189d
Pod之间互相访问
flanneld将本主机获取的subnet以及用于主机间通信的Public IP通过etcd存储起来,需要时发送给相应模块。
flannel利用各种backend mechanism,例如udp,vxlan等等,跨主机转发容器间的网络流量,完成容器间的跨主机通信。
- 不同node上的pod的通信流程:
pod中产生数据,根据pod的路由信息,将数据发送到Cni0
Cni0 网桥设备,据节点的路由表,将数据发送到隧道设备flannel.1
Flannel.1 overlay网络的设备查看数据包的目的ip,从flanneld获得对端隧道设备的必要信息,封装数据包。
Flannel.1 overlay网络的设备 将数据包发送到对端设备。对端节点的网卡接收到数据包,发现数据包为overlay数据包,解开外层封装,并发送内层封装到flannel.1设备。
Flannel.1设备查看数据包,根据路由表匹配,将数据发送给Cni0设备。
Cni0匹配路由表,发送数据给网桥上对应的端口。
存在问题
1.不支持pod之间的网络隔离。Flannel设计思想是将所有的pod都放在一个大的二层网络中,所以pod之间没有隔离策略。
2.设备复杂,效率不高。Flannel模型下有三种设备,数量经过多种设备的封装、解析,势必会造成传输效率的下降。
关于kebeadm 参数问题
其实,默认使用kubeadm init 安装的时候,在/var/lib/kubelet 下会生成配置文件config.yaml
[root@k8s-master ~]# cd /var/lib/kubelet/
[root@k8s-master kubelet]# ls
config.yaml cpu_manager_state device-plugins kubeadm-flags.env pki plugin-containers plugins plugins_registry pod-resources pods
[root@k8s-master kubelet]#
[root@k8s-master kubelet]# cat config.yaml
其实,更好的方式,是使用kubeadm 的配置文件来配置kubelet,如搭建高可用的时候,就必须使用配置文件了。这样,每个节点的配置很清晰
- 如何实现高可用的master 节点集群
首先,ETCD 组件必须是个集群,然后,我们也是需要在每个master上执行kubeadm init 操作,当然,使用配置文件的话,,命令就是:
kubectl inti --config xxx.yaml
配置文件的格式如下:
apiVersion: kubeadm.k8s.io/v1alpha1
kind: MasterConfiguration
api:
advertiseAddress: <master-private-ip>
etcd:
endpoints:
- [http://<master0-ip-address>:2379](http://%3Cmaster0-ip-address%3E:2379/)
- [http://<master1-ip-address>:2379](http://%3Cmaster1-ip-address%3E:2379/)
- [http://<master2-ip-address>:2379](http://%3Cmaster2-ip-address%3E:2379/)
caFile: /etc/kubernetes/pki/etcd/ca.pem
certFile: /etc/kubernetes/pki/etcd/client.pem
keyFile: /etc/kubernetes/pki/etcd/client-key.pem
networking:
podSubnet: <podCIDR>
apiServerCertSANs:
- <load-balancer-ip>
apiServerExtraArgs:
endpoint-reconciler-type: lease
需要注意的是,我们要获取到etcd 的证书文件信息,配置pod 的网段,配置api service 高可用地址,一般可以用slb 或者HA 做为高可用。
因为k8s 的组件状态,资源信息,配置均存在于ETCD,故ETCD是大脑的核心部分。其他组件均围绕ETCD展开。ETCD必须高可用。
etcd 证书位置
[root@k8s-master pki]# pwd
/etc/kubernetes/pki
[root@k8s-master pki]# ls
apiserver.crt apiserver-etcd-client.key apiserver-kubelet-client.crt ca.crt etcd front-proxy-ca.key front-proxy-client.key sa.pub
apiserver-etcd-client.crt apiserver.key apiserver-kubelet-client.key ca.key front-proxy-ca.crt front-proxy-client.crt sa.key
有时候重启机器,连接不上节点的问题
主要是重启下kubelet 即可。
[root@k8s-master apple]# kubectl get po
The connection to the server 192.168.10.133:6443 was refused - did you specify the right host or port?
执行如下:
systemctl daemon-reload
systemctl restart kubelet
关于cgroups-driver 的配置问题
docker 和 kubelet 的cgroup-driver 不符合,那么在 kubeadm init 的时候会导致Kubelet 启动失败,那么要做以下修改。
修改kubelet 的方式如下:
[root@k8s-master k8s]# vi /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
# 添加--cgroup-driver=cgroupfs"
[Service]
Environment="KUBELET_KUBECONFIG_ARGS=--bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf --cgroup-driver=cgroupfs"
Environment="KUBELET_CONFIG_ARGS=--config=/var/lib/kubelet/config.yaml"
[root@k8s-master k8s]# systemctl daemon-reload
[root@k8s-master k8s]#
[root@k8s-master k8s]# systemctl enable kubelet
docker cgroup-driver 的修改方式如下:
[root@k8s-node1 etcd]# vim /etc/docker/daemon.json
{
"registry-mirrors": ["https://uob2vbvb.mirror.aliyuncs.com"],
"exec-opts": ["native.cgroupdriver=systemd"]
}
[root@k8s-node1 etcd]#
[root@k8s-node1 etcd]#
[root@k8s-node1 etcd]#
[root@k8s-node1 etcd]# systemctl daemon-reload
[root@k8s-node1 etcd]#
[root@k8s-node1 etcd]# systemctl restart docker
kubelet kubeadm kubectl 版本问题
经过查阅官网资料,k8s的组件不能超过1个版本,既1.14 的组件可以安装1.14或者1.13 版本的k8s 集群,
安装k8s 1.15 会有版本倾斜的问题。
一定注意自己使用的版本。