2.2 部署云部分——Kubernetes
Kubernetes是一个全新的基于容器技术的分布式架构的云部署方案,是Google开源的容器集群管理系统,为部署容器化的应用提供资源调度、服务发现和动态伸缩等一系列完整功能,提高了大规模容器集群管理的便捷性。本书将Kubernetes作为边缘计算系统的云部分解决方案。
本节会对Kubernetes的部署方式进行梳理,主要对Kubernetes相关的容器运行时部署、Kubernetes的学习环境部署、Kubernetes的生产环境部署三方面进行梳理。
2.2.1 Kubernetes相关的容器运行时部署
Kubernetes通过容器运行时以Pod形式运行容器,官方默认支持Docker容器运行时。除此之外,Kubernetes支持的容器运行时还包括Containerd、Cri-o、Frakti等,具体如表2-1所示。
表2-1 Kubernetes支持的容器运行时
从Kubernetes支持的容器运行时列表,我们可知:
1)Docker和Containerd在实现原理上是相同的,只是Containerd裁剪了Docker原有的一些富功能。
2)Cri-o为了追求轻量级和简洁,对CRI和OCI重新进行了实现。
3)Frakti的目的是实现容器运行时的强隔离,基于Hypervisors实现容器运行时,使每个容器具有独立的操作系统。
目前,业界普遍使用的容器运行时是Docker。下面详细说明部署Docker的相关步骤和注意事项。
本书使用的操作系统都是CentOS 7+,所以部署Docker的步骤也是针对CentOS 7+操作环境。
1)安装需要的依赖包,命令如下:
# yum install yum-utils device-Mapper-persistent-data lvm2
2)增加安装Docker所需的Repository,命令如下:
# yum-config-manager --add-repo \ https://download.docker.com/linux/centos/docker-ce.repo
3)安装指定版本的Docker,命令如下:
# yum update && yum install containerd.io-1.2.10 docker-ce-19.03.4 docker-ce-cli-19.03.4
4)设置Docker的配置文件。
①创建配置文件目录:
#mkdir /etc/docker
②设置Docker配置文件:
# cat > /etc/docker/daemon.json <<EOF { "exec-opts": ["native.cgroupdriver=systemd"], "log-driver": "json-file", "log-opts": { "max-size": "100m" }, "storage-driver": "overlay2", "storage-opts": [ "overlay2.override_kernel_check=true" ] } EOF
5)启动Docker,命令如下:
# mkdir -p /etc/systemd/system/docker.service.d # systemctl daemon-reload # systemctl restart docker
至此,Docker容器运行时就安装成功了。接下来,分析Docker配置相关的注意事项。
Docker的相关配置在/etc/docker/daemon.json文件中,包括设置私有仓库、DNS解析服务器、Docker运行时使用的路径、镜像加速地址、日志输出、Cgroup Driver、Docker主机的标签等。本节重点介绍Cgroup Driver的设置。
Linux操作系统的发行版本中将Systemd作为其初始化系统,并初始化进程生成一个root控制组件。Systemd与Cgroup集成紧密,为每个进程分配Cgroup。Docker容器运行时默认的Cgroup管理器是Cgroupfs,也就是说Kubelet使用Cgroupfs来管理Cgroup。这样就造成在同一台主机上同时使用Systemd和Cgroupfs两种Cgroup管理器来对Cgroup进行管理。
Cgroup用来约束分配给进程的资源。单个Cgroup管理器能够简化分配资源的视图,并且默认情况下管理可用资源和使用中的资源时使用一致的视图。当有两个Cgroup管理器时,最终产生两种视图。我们已经看到某些案例中的节点配置让Kubelet和Docker使用Cgroupfs管理器,而节点上运行的其余进程则使用Systemd,这类节点在资源压力下会变得不稳定。
更改设置,令Docker和Kubelet使用Systemd作为Cgroup驱动,以便系统更稳定。请注意在/etc/docker/daemon.json文件中设置native.cgroupdriver=systemd选项,具体如下:
# vi /etc/docker/daemon.json { ... "exec-opts": ["native.cgroupdriver=systemd"], ... }
2.2.2 Kubernetes的学习环境部署
本节对部署Kubernetes学习环境的相关工具进行梳理,如表2-2所示。
表2-2 搭建Kubernetes学习环境的工具
从搭建Kubernetes学习环境的工具列表可知,Minikube、Kind都可以搭建Kubernetes的学习环境,但两者所需要的依赖和原理各不相同。Minikube和Kind都是用于搭建Kubernetes学习环境的工具,二者的安装步骤和使用方法相对比较简单。接下来,笔者对二者的安装步骤和使用方法进行详细说明。
1. Minikube的安装与使用
Minikube是一种可以在本地轻松运行Kubernetes的工具。其首先通过在物理服务器或计算机上创建虚拟机,然后在虚拟机(VM)内运行一个单节点Kubernetes集群。该Kubernetes集群可以用于开发和测试Kubernetes的最新版本。
下面对Minikube的安装和使用进行说明。本书使用的操作系统都是CentOS 7+,所以本节安装Minikube的步骤也是针对CentOS 7+操作环境。
(1)安装Minikube
1)检查对虚拟化的支持,命令如下:
# grep -E --color 'vmx|svm' /proc/cpuinf
2)安装Kubectl。
推荐在Kubernetes的GitHub上的发布主页下载pre-built的二进制压缩包并进行安装。
进入Kubernetes的GitHub仓库上的发布主页,找到需要下载的Kubernetes版本,比如本节要下载的版本是v1.16.6,如图2-2所示。
图2-2 Kubernetes v1.16.6发布版本
点击CHANGELOG-1.16.md进入二进制文件下载列表,复制服务二进制压缩包下载地址,使用wget命令下载服务二进制压缩包,命令如下:
# wget https://dl.k8s.io/v1.16.6/Kubernetes-server-linux-amd64.tar.gz
下载Kubernetes具体如图2-3所示。
图2-3 下载Kubernetes
如图2-4所示,解压kubernetes-server-linux-amd64.tar.gz,命令如下:
# tar -zxvf kubernetes-server-linux-amd64.tar.gz
图2-4 解压Kubernetes
由图2-4可知,Kubectl在kubernetes/server/bin下,只需将其放入/usr/bin下即可:
#cp kubernetes/server/bin/kubectl /usr/bin
3)安装KVM。
在确认所在的操作系统支持虚拟机的前提下,通过如下步骤安装KVM及相关依赖。
更新安装KVM所需的源,命令如下:
#yum -y update && # yum install epel-release
安装KVM及其所需的依赖包,命令如下:
# yum install qemu-kvm libvirt libvirt-python libguestfs-tools virt-install
设置libvirtd开机自动启动,命令如下:
# systemctl enable libvirtd && systemctl start libvirtd
4)安装Minikube,命令如下:
# curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-1.6.2.rpm \ && rpm -ivh minikube-1.6.2.rpm
(2)使用Minikube
1)启动一个本地单节点集群,命令如下:
# minikube start --vm-driver=<driver_name>
2)检查集群状态,命令如下:
# minikube status
3)使用集群部署应用,命令如下:
# kubectl create deployment hello-minikube --image={image-name}
至此,我们已经成功安装了Minikube,并通过Minikube创建了一个本地单节点的Kubernetes集群。
2. Kind的安装与使用
Kind是一种使用Docker容器节点(该容器可用于运行嵌套容器,在该容器里可以使用Systemd运行、管理Kubernetes的组件)运行本地Kubernetes集群的工具。Kind主要是为了测试Kubernetes本身而设计的,可用于本地开发或持续集成。
下面对Kind的安装和使用进行说明。
(1)安装Kind
由于安装Kind需要Go语言环境,使用Kind运行本地Kubernetes集群需要Docker容器运行时,因此在安装Kind之前需要安装Go和Docker。
1)安装Go,命令如下:
# yum -y install Go
参考“部署Docker”小节来部署Docker容器运行时。
2)安装Kind,命令如下:
#GO111MODULE="on" go get sigs.k8s.io/kind@v0.7.0
上述步骤会将Kind安装到GOPATH/bin目录下。为了使用方便,建议将其在/etc/profile中进行追加设置,命令如下:
# vi /etc/profile export PATH=$GOPATH/bin:$PATH
使在/etc/profile中设置的环境变量立即生效,命令如下:
#source /etc/profile
(2)使用Kind
1)使用Kind创建Kubernetes集群(如图2-5所示),命令如下:
# kind create cluster
图2-5 使用Kind创建集群
2)检查、使用Kind部署的集群(如图2-6所示),命令如下:
#kubectl get pods --all-namespaces
图2-6 检查使用Kind部署的集群状态
至此,我们已经成功安装了Kind,并通过Kind创建了一个本地单节点的Kubernetes集群。
2.2.3 Kubernetes的生产环境部署
本节对部署Kubernetes生产环境的相关工具进行梳理,具体如表2-3所示。
表2-3 搭建Kubernetes生产环境的工具
从表2-3可知,Kops、KRIB有明显局限性,因为Kops主要在AWS上进行自动化部署Kubernetes集群;KRIB主要在裸机上进行自动化部署Kubernetes集群。Kubeadm和Kubespray可以在多种平台上搭建Kubernetes的生产环境。Kubespray从v2.3开始支持Kubeadm,也就意味着Kubespray最终还是通过Kubeadm自动化部署Kubernetes集群。
本节首先对使用Kubeadm的注意事项进行说明,然后具体介绍如何安装和使用Kubeam。Kubeadm支持的平台和资源要求如表2-4所示。
表2-4 Kubeadm支持的平台和资源要求
(1)使用Kubeadm的注意事项
1)确保集群中所有主机网络可达。
在集群中不同主机间通过ping命令进行检测,命令如下:
# ping {被检测主机ip}
2)确保集群中所有主机的Hostname、MAC Address和product_uuid唯一。
查看主机Hostname命令:#hostname
查看MAC Address命令:#ip link
或者#ifconfig -a
查看product_uuid命令:#/sys/class/dmi/id/product_uuid
3)IPTables后端不用nftable,命令如下:
# update-alternatives --set iptables /usr/sbin/iptables-legacy
4)Kubernetes集群中主机需要打开的端口如表2-5所示。
表2-5 Kubernetes集群中主机需要打开的端口
由表2-5可知,上述需要打开的端口都是Kubernetes默认打开的端口。我们也可以根据需要对一些端口进行单独指定,比如Kubernetes-api-server默认打开的端口是6443,也可以指定打开其他与现有端口不冲突的端口。
5)在Kubernetes集群的所有节点上关闭Swap分区,命令如下:
#swapoff -a
(2)安装Kubeadm
安装Kubeadm有两种方式,即通过操作系统的包管理工具进行安装,从Kubernetes的GitHub仓库的发布主页下载Pre-build的二进制压缩包进行安装。下面对这两种安装方式进行详细说明。
1)通过操作系统的包管理工具安装Kubeadm。
①在需要安装Kubeadm的节点上设置安装Kubeadm需要的仓库,命令如下:
#cat <<EOF > /etc/yum.repos.d/kubernetes.repo [Kubernetes] name=Kubernetes baseurl=https://packages.cloud.google.com/yum/repos/Kubernetes-el7-x86_64 enabled=1 gpgcheck=1 repo_gpgcheck=1 gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg EOF
②将SELINUX设置为permissive,命令如下:
#setenforce 0 #sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config
③安装Kubeadm、Kubelet、Kubectl,命令如下:
#yum install -y Kubelet kubeadm kubectl --disableexcludes=Kubernetes
④将Kubelet设置为开机自启动,命令如下:
#systemctl enable --now Kubelet
2)通过在Kubernetes GitHub仓库的发布主页下载pre-build的二进制压缩包来安装Kubeadm。
(3)使用Kubeadm
使用Kubeadm可以部署Kubernetes单节点集群、Kubernetes单控制节点集群和Kubernetes高可用集群。下面将详细说明部署这3种集群的具体步骤。
1)部署Kubernetes单节点集群。
使用Kubeadm部署Kubernetes单节点集群,其实是在一个节点使用Kubeadm部署Kubernetes的控制平面,然后对该节点进行设置,使其能够运行应用负载。
①查看使用Kubeadm部署Kubernetes单节点集群时所需的镜像,命令如下:
#kubeadm config images list
所需镜像如图2-7所示。
图2-7 使用Kubeadm部署Kubernetes单节点集群所需镜像
这些镜像都是以k8s.gcr.io*开头的。一般情况下,Kubeadm无法正常下载这些镜像,需要提前准备好。获取这些镜像的方法不止一种,笔者建议通过DockerHub获得。
②使用Kubeadm创建Kubernetes单节点集群,在创建的过程中会用到图2-10列出的所有镜像,命令如下:
#kubeadm init {args}
在args中一般只需指定--control-plane-endpoint、--pod-network-cidr、--cri-socket、--apiserver-advertise-address参数。这些参数的具体作用如下。
- --control-plane-endpoint:指定搭建高可用Kubernetes集群时,多个控制平面共用的域名或负载均衡IP。
- --pod-network-cidr:指定Kubernetes集群中Pod所用的IP池。
- --cri-socket:指定Kubernetes集群使用的容器运行时。
- --apiserver-advertise-address:指定kube-api-server绑定的IP地址——既可以是IPv4,也可以是IPv6。
我们可以根据具体情况指定以上参数。
③根据non-root用户和root用户,设置Kubectl使用的配置文件。
- 若是non-root用户,设置命令如下:
$mkdir -p $HOME/.kube $sudo cp -i /etc/Kubernetes/admin.conf $HOME/.kube/config $sudo chown $(id -u):$(id -g) $HOME/.kube/config
- 若是root用户,设置命令如下:
export KUBECONFIG=/etc/Kubernetes/admin.conf
为了方便,我们也可以将KUBECONFIG设置成自动生效的系统环境变量,命令如下:
# vim /etc/profile export KUBECONFIG=/etc/Kubernetes/admin.conf
④安装Pod所需的网络插件,命令如下:
# kubectl apply -f https://docs.projectCalico.org/v3.8/manifests/Calico.yaml
本节使用的网络插件是Calico,我们也可以根据具体需求选择其他的网络插件,比如Flannel、Weave Net、Kube-router等。
至此,一个完整的Kubernetes控制节点就搭建完成了,但这还不能算一个完整单节点集群,因为该控制节点默认不接受负载调度。要使其能够接受负载调度,需要进行如下设置:
# kubectl taint nodes --all node-role.Kubernetes.io/master-
2)部署Kubernetes单控制节点集群。
Kubernetes单控制节点集群是指该Kubernetes集群只有一个控制节点,但可以有不止一个计算节点。部署该集群只需在部署Kubernetes单节点集群中安装Pod所需的网络插件之后,将计算节点加入该控制节点,具体命令如下:
ubeadm join <control-plane-host>:<control-plane-port> --token <token> --discovery-token-ca-cert-hash sha256:<hash>
使用kubeadm join命令将多个计算节点加入已经部署成功的控制节点,与控制节点组成一个单控制节点的Kubernetes集群。
3)部署Kubernetes高可用集群。
Kubeadm除了可以部署Kubernetes单节点集群和Kubernetes单控制节点集群外,还可以部署Kubernetes高可用集群。Kubeadm部署Kubernetes高可用集群的架构包含两种,即Etcd集群与Kubernetes控制节点集群一起部署的Kubernetes高可用集群,以及Etcd集群与Kubernetes控制节点集群分开部署的Kubernetes高可用集群,具体架构如图2-8和图2-9所示。
图2-8 Etcd集群与Kubernetes控制节点集群一起部署
图2-9 Etcd集群与Kubernetes控制节点集群分开部署
由图2-8和图2-9可知,Kubernetes集群高可用即Kubernetes集群中Master节点和Etcd集群高可用。部署Kubernetes高可用集群是面向生产环境的,需要的资源比较多,部署步骤也相对比较复杂,限于篇幅本书就不展开说明了,感兴趣的读者可以参考Kubernetes官网进行实践。