Skip to content

02 快速了解和搭建K8s集群

你好,我是雪飞。

上一讲我们介绍了容器相关知识,相信你已经理解了容器带来的巨大变革。你的应用也可以拆成多个微服务,每个服务可以通过容器的方式快速部署。但是问题来了,如果你只部署少量几个微服务应用,通过 Docker 命令管理起来很容易,但是如果你有几十甚至上百个微服务需要容器化部署,那么部署和管理这些大量容器也是巨大的工作量。

这个时候你会想,如果有个容器管理工具就好了,只要把需要部署微服务的容器事先编排好,部署的时候一键执行,然后你的应用就可以按照预期直接访问,这该有多轻松呀。对,Kubernetes 就能满足你的需求。

应用、业务应用、应用程序在本课程中是同样的意思,就是研发开发出来的一个软件系统,最终提供给用户访问使用。

微服务架构是指你的应用可能拆分成了多个子应用,每个子应用实现了一部分业务功能,这些子应用就是一个个微服务,这些微服务独立打包镜像和部署。

认识 K8s

Kubernetes 这个名字源于希腊语,意思为“舵手”。K8s 这个缩写是因为 K 和 s 之间有8个字符的关系(后面的课程我会使用 K8s 这个缩写代替 Kubernetes)。它是一个开源的容器编排平台,用于自动部署、扩展和管理大规模容器化应用。K8s 最初由 Google 设计并捐赠给云原生计算基金会(CNCF,Cloud Native Computing Foundation)来维护,所以 CKA 证书也是由 CNCF 组织颁发。

K8s 是安装在多个服务器组成的集群环境上,这些服务器可以是物理机、虚拟机或者是云服务器,它们在集群中都叫做节点,这些节点协同工作组成了 K8s 的硬件基础设施,K8s 就运行在这个集群环境上,所以 K8s 也被称为云原生操作系统。

图片

在集群中,所有的服务器有两个角色,一个是管理节点,也被称为控制面节点或者 Master 节点(Master Node),另一个是工作节点(Worker Node),也简称为节点。

管理节点(Master)扮演着大脑的角色,负责维护集群的整体状态和调度决策。管理节点上运行着 K8s 的核心组件,包括 API Server、调度器、控制器管理组件和 etcd,这些组件共同确保了集群的稳定性和高效运行。

工作节点(Node)则是执行具体任务的劳动力,工作节点上运行着 kubelet、容器运行时和 kube-proxy 等组件,负责启动和管理容器的生命周期,以及实现集群内部的网络路由。

我们大致了解了 K8s 的组成,你是不是已经跃跃欲试了,我现在就来带你搭建一套 K8s 集群,这样后续的知识点都可以在搭建好的集群上进行尝试,从而加深你对概念的理解。

快速搭建 K8s 集群

搭建 K8s 集群通常有多种方式,kubeadm 是 K8s 官方提供的集群部署工具,这种方法最为常用,简单快速,适合初学者。本次课程我就带你使用 kubeadm 搭建集群。

准备硬件

首先做一下准备工作,本次我们搭建一套 3 个节点的 K8s 集群,服务器可以使用个人电脑虚拟出 3 台服务器,也可以在云厂商(例如阿里云、腾讯云)租用 3 台服务器,配置不用太高,最小硬件配置:2 核 CPU、2G 内存、20G 硬盘,操作系统需要是 Linux。服务器需要可以访问外网,有些镜像要从网上拉取。以下表格是我在本次实验中使用的服务器配置。

注意: 这 3 台服务器需要在同一个内网环境,可以通过内网 IP 相互访问,在集群配置过程中会使用到内网 IP。如果你要使用外网 IP 搭建集群,还需要单独配置虚拟网卡以及修改一些配置,可以参考网上相关文章。

图片

准备好硬件,我们先要从个人电脑中通过 SSH 命令分别连接到这 3 台服务器。打开个人电脑上的终端命令应用,然后输入连接命令,再输入密码,就可以远程连接服务器了。

 ssh <username>@<IP>”  #username 是服务器的用户名,IP 地址使用公网 IP 地址

连接成功后就会进入到服务器的 Shell 终端窗口。下面安装过程中的命令都需要在服务器的 Shell 终端窗口里去执行。

准备系统配置

我们需要在所有 3 台服务器上都完成以下准备工作。在这 3 台服务器的 Shell 终端窗口里逐步执行以下命令。

1. 关闭防火墙及相关配置

以下操作是为了关闭 Linux 操作系统的防火墙、安全服务和 swap 分区,你直接将命令拷贝到终端窗口中执行即可。如果有提示执行命令权限不够,可以切换到 root 用户或者在命令前增加 “sudo” 来提升执行命令的权限。

# 关闭和禁用防火墙
systemctl stop firewalld
systemctl disable firewalld

# 关闭selinux,selinux 是 Linux 系统下的一个安全服务,需要关闭
setenforce 0  # 临时
sed -i 's/enforcing/disabled/' /etc/selinux/config  # 永久

# 关闭 Linux 的 swap 分区,提升 Kubernetes 的性能
swapoff -a  # 临时
sed -ri 's/.*swap.*/#&/' /etc/fstab    # 永久

2. 按照规划修改主机名

K8s 使用主机名进行节点的通信,所以需要按照表格中的主机名修改 3 台服务器的主机名。注意:K8s 要求主机名使用 “-” 或者 “.” 连接,不能使用下划线 “_”。

# 在192.168.1.11 这个机器上执行修改主机名命令
hostnamectl set-hostname k8s-master

# 在192.168.1.12 这个机器上执行修改主机名命令
hostnamectl set-hostname k8s-worker1

# 在192.168.1.13 这个机器上执行修改主机名命令
hostnamectl set-hostname k8s-worker2

3. 主机名解析

在每个服务器上都增加主机名和 IP 的对应关系,执行以下命令快速编辑 “/etc/hosts” 文件,增加解析配置。

# 添加各个节点的解析,IP 地址需要替换为你自己服务器的内网 IP 地址。
cat >> /etc/hosts << EOF
192.168.1.11 k8s-master
192.168.1.12 k8s-worker1
192.168.1.13 k8s-worker2
EOF

4. 时间同步

K8s 要求集群中的所有服务器时间一致,使用 ntpdate(Network Time Protocol)从网络同步时间,执行以下命令安装 ntpdate,之后再执行同步命令。

# 安装ntp服务
yum install ntpdate -y

# 安装完成后使用阿里云的时间服务同步时间
ntpdate ntp1.aliyun.com

如果提示没有匹配到 ntpdate(Unable to find a match: ntpdate),则可以使用 wlnmp 的软件源安装 wntp,然后再执行时间同步,执行以下命令:

rpm -ivh http://mirrors.wlnmp.com/centos/wlnmp-release-centos.noarch.rpm
yum install wntp -y

# 安装完成后使用阿里云的时间服务同步时间
ntpdate ntp1.aliyun.com

5. 配置网络

为了让 K8s 能够转发网络流量,你需要修改 iptables 的配置。执行以下命令快速编辑 “etc/sysctl.d/k8s.conf” 配置文件,增加 iptables 的配置。

# 修改 Linux 内核参数,添加网桥过滤和地址转发功能
cat > /etc/sysctl.d/k8s.conf << EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF

# 使配置生效
sudo sysctl --system

6. 重启服务器

运行 “reboot” 命令,重启服务器,让以上配置生效。

reboot

安装相关软件

完成系统配置,我们继续在这 3 台服务器上执行以下命令来安装相关软件。

1. 安装 Docker

我们使用 Docker 作为运行容器的运行时组件,需要先安装 Docker。通过 wget 命令来下载 Docker 的安装包仓库,然后通过 yum 命令进行安装,安装完成之后再执行开启 Docker 服务命令。

# 通过 wget 命令获取 docker 软件仓库信息
wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -O /etc/yum.repos.d/docker-ce.repo

# 安装 docker-ce
yum -y install docker-ce

# 开启 docker 服务
systemctl enable docker && systemctl start docker

Docker 安装完成之后,配置阿里云提供的镜像库来加速镜像下载。执行以下命令快速编辑 “/etc/docker/daemon.json” 文件,增加镜像库配置,最后再重启 Docker 服务。

# 配置镜像下载加速器,国内使用阿里云镜像库会更快
cat > /etc/docker/daemon.json << EOF
{
  "registry-mirrors": ["https://b9pmyelo.mirror.aliyuncs.com"],
  "exec-opts": ["native.cgroupdriver=systemd"]
}
EOF

# 重启 docker 服务
systemctl restart docker

2. 安装cri-dockerd

cri-dockerd 用于为 Docker 提供一个能够支持 K8s 容器运行时标准的工具,从而能够让 Docker 作为 K8s 容器引擎。通过 wget 下载 cri-dockerd 安装包,然后通过 rpm 命令进行安装。如果官方地址下载太慢,可以使用我提供的离线安装包( 下载地址)。

# 通过 wget 命令获取 cri-dockerd软件
wget https://github.com/Mirantis/cri-dockerd/releases/download/v0.3.12/cri-dockerd-0.3.12-3.el7.x86_64.rpm
# 通过 rpm 命令执行安装包
rpm -ivh cri-dockerd-0.3.12-3.el7.x86_64.rpm

安装完成后使用 vi 编辑器修改配置文件(/usr/lib/systemd/system/cri-docker.service),在 “ExecStart=/usr/bin/cri-dockerd --container-runtime-endpoint fd://” 这一行增加 “–pod-infra-container-image=registry.aliyuncs.com/google_containers/pause:3.9”。

vi 编辑器使用简介

在终端窗口里编辑文件可以使用 vi 编辑器,使用 “vi <文件名>” 命令打开编辑器,然后输入字母 “i”,进入到插入(Insert)模式,这时通过键盘移动光标到要修改的位置,然后输入修改的配置,修改完成后使用键盘上 “esc” 按键退出插入模式,然后输入 “:wq” 之后回车,就可以保存文件并退出编辑器。

# 打开 cri-docker.service 配置文件
vi /usr/lib/systemd/system/cri-docker.service

# 修改对应的配置项
ExecStart=/usr/bin/cri-dockerd --container-runtime-endpoint fd:// --pod-infra-container-image=registry.aliyuncs.com/google_containers/pause:3.9

配置文件修改成功后,重新加载配置并开启 cri-dockerd 服务。

# 加载配置并开启服务
systemctl daemon-reload
systemctl enable cri-docker && systemctl start cri-docker

3. 添加阿里云 YUM 软件源

执行以下命令快速编辑 “/etc/yum.repos.d/kubernetes.repo” 配置文件,添加阿里云的镜像库。

注意 国内是无法访问 K8s 官方的镜像库,如果不增加这个配置,后续就无法安装相关工具。

cat > /etc/yum.repos.d/kubernetes.repo << EOF
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF

4. 安装 kubeadm kubelet 和 kubectl

镜像库配置好之后,就进入正式安装过程了。3 台服务器上都需要安装 kubeadm、kubelet 和 kubectl 这三个工具。kubeadm 用来初始化 K8s 集群;kubelet 是每个节点的 K8s 管理员;kubectl 是 K8s 的命令行交互工具。由于版本更新比较快,我这里指定安装的版本是1.28.0。

# 指定了安装的版本是 1.28.0
yum install -y kubelet-1.28.0 kubeadm-1.28.0 kubectl-1.28.0

安装成功之后需要先设置开机启动 kubelet 服务。

# 开机启动 kubelet 服务
systemctl enable kubelet

Master 节点初始化 K8s

所有准备工作都完成了,我们终于可以进行 K8s 的初始化了,只需要在 Master 节点上执行以下初始化命令。

注意 “apiserver-advertise-address” 参数需要替换成你的 Master 节点服务器的内网 IP。

kubeadm init \
  --apiserver-advertise-address=192.168.1.11 \
  --image-repository registry.aliyuncs.com/google_containers \
  --kubernetes-version v1.28.0 \
  --service-cidr=10.96.0.0/12 \
  --pod-network-cidr=10.244.0.0/16 \
  --cri-socket=unix:///var/run/cri-dockerd.sock \
  --ignore-preflight-errors=all

参数介绍:

  • apiserver-advertise-address: 集群广播地址,用 master 节点的内网 IP。
  • image-repository: 由于默认拉取镜像地址 k8s.gcr.io 国内无法访问,这里指定阿里云镜像仓库地址。
  • kubernetes-version: K8s 版本,与上面安装的软件版本一致。
  • service-cidr: 集群 Service 网段。
  • pod-network-cidr: 集群 Pod 网段。
  • cri-socket: 指定 cri-socket 接口,我们这里使用 unix:///var/run/cri-dockerd.sock。

执行命令后耐心等待,直到安装完成,会出现以下内容。

[addons] Applied essential addon: kube-proxy

Your Kubernetes control-plane has initialized successfully!

To start using your cluster, you need to run the following as a regular user:

  mkdir -p $HOME/.kube
  sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
  sudo chown $(id -u):$(id -g) $HOME/.kube/config

Alternatively, if you are the root user, you can run:

  export KUBECONFIG=/etc/kubernetes/admin.conf

You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
  https://kubernetes.io/docs/concepts/cluster-administration/addons/

Then you can join any number of worker nodes by running the following on each as root:

kubeadm join 192.168.1.11:6443 --token xxxxxx \
        --discovery-token-ca-cert-hash sha256:xxxxxx

其中,在以上返回结果中有 3 条命令需要立即执行,这是用来设置 kubectl 工具的管理员权限,执行之后就可以在 Master 节点上通过终端窗口使用 kubectl 命令了。

# 在 Master 节点上执行以下命令
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

在返回结果的最后,还有 1 条 “kubeadm join” 命令,这个是用来加入工作节点的,需要在工作节点上执行。

Worker 节点加入 K8s 集群

K8s 初始化之后,就可以在其他 2 个工作节点上执行 “kubeadm join” 命令,因为我们使用了 cri-dockerd ,需要在命令加上 “–cri-socket=unix:///var/run/cri-dockerd.sock” 参数。

注意 如果使用公有云的服务器,需要先打开 Master 节点所在服务器的 6443 端口,这个是 K8s 的 API server 端口。

# 在两个工作节点上执行
kubeadm join 192.168.1.11:6443 --token xxxxxx \
        --discovery-token-ca-cert-hash sha256:xxxxxx \
        --cri-socket=unix:///var/run/cri-dockerd.sock

命令中 token 有效期为 24 小时,当 token 过期之后,执行 “kubeadm join” 命令就会报错。这时可以直接在 Master 节点上使用以下命令生成新的 token,然后再使用 “kubeadm join” 命令加入节点。

kubeadm token create --print-join-command

此时,我们的集群就部署成功了。你可以使用 “kubectl get node” 命令来查看集群节点状态。

[root@k8s-master ~]# kubectl get node
NAME           STATUS     ROLES           AGE   VERSION
k8s-master     NotReady   control-plane   84m   v1.28.0
k8s-worker1    NotReady   <none>          82m   v1.28.0
k8s-worker2    NotReady   <none>          47s   v1.28.0

你会注意到所有节点的状态都是 “NotReady”,这是由于集群还缺少网络插件,集群的内部网络还没有正常运作。

安装 K8s 网络插件

K8s 网络插件,也称为容器网络接口(CNI)插件,是实现 K8s 集群中容器间通信和网络连接的关键组件。在这里我使用 Calico 作为集群的网络插件。

Calico 是通过执行一个 YAML 文件部署到 K8s 集群里的,所以我们首先需要通过 “wget” 命令下载这个 YAML 文件。

# 下载 Calico 插件部署文件
wget https://docs.projectcalico.org/manifests/calico.yaml

其次,通过 vi 编辑器修改 “calico.yaml” 文件中的 “CALICO_IPV4POOL_CIDR” 参数,需要与前面 “kubeadm init” 命令中的 “–pod-network-cidr” 参数一样(10.244.0.0/16)。如果文件里的 “CALICO_IPV4POOL_CIDR” 参数前面有 “#”,表示被注释了,需要删除 “#”。

注意 修改文件时确保格式对齐,YAML 文件有严格的格式要求。

修改位置如下所示。(在 vi 中可以通过输入 “:set nu” 来查看行号,同时可以输入 “/CALICO_IPV4POOL_CIDR” 来快速定位到参数位置)

# 修改文件时注意格式对齐
4598 # The default IPv4 pool to create on startup if none exists. Pod IPs will be
4599 # chosen from this range. Changing this value after installation will have
4600 # no effect. This should fall within `--cluster-cidr`.
4601 - name: CALICO_IPV4POOL_CIDR
4602   value: "10.244.0.0/16"
4603 # Disable file logging so `kubectl logs` works.
4604 - name: CALICO_DISABLE_FILE_LOGGING
4605   value: "true"

最后,使用 “kubectl apply” 命令将 Calico 插件部署到集群里,部署 YAML 文件命令如下:

kubectl apply -f calico.yaml

Calico 部署会比较慢,大概等个几分钟,等待 Calico 部署完成后,再次通过命令 “kubectl get node” 查看节点状态,就可以看到所有节点已经准备就绪,恭喜你!此时集群正式搭建成功。

[root@k8s-master ~]# kubectl get node
NAME           STATUS   ROLES           AGE   VERSION
k8s-master     Ready    control-plane   12h   v1.28.0
k8s-worker1    Ready    <none>          12h   v1.28.0
k8s-worker2    Ready    <none>          10h   v1.28.0

注意 如果 Calico 无法安装成功,可能是由于 Calico 镜像无法拉取。我提供了离线镜像包( 下载地址),可以下载两个压缩文件,然后传输到集群中的所有 3 个节点上。

“calico-image-3.25.1.zip” 中是离线镜像文件,解压后在每个节点上执行导入命令。

ls *.tar |xargs -i docker load -i {}

“calico-yaml.zip” 中是部署文件,在 Master 节点上依次部署两个 YAML 文件。

# 先删除之前部署不成功的 Calico
kubectl delete -f calico.yaml

# 依次部署两个 yaml 文件
kubectl apply -f tigera-operator.yaml --server-side
kubectl apply -f custom-resources.yaml

然后等待部署完成,就可以看到所有节点准备就绪。

小结

今天我给你讲了 K8s 的相关概念,我们再来总结一下。

首先,了解了什么是 K8s ,K8s 是一个强大的开源容器编排平台。它通过自动化的方式简化了容器的部署、扩展和维护,同时确保了应用程序的高可用性和稳定运行。

然后,我们探讨了 K8s 集群组成的两个角色,其中管理节点(Master Node)负责集群的整体管理和控制,而工作节点(Worker Node)则运行实际的容器应用。

最后,我带你搭建了一套 3 台服务器的 K8s 集群。在搭建 K8s 集群的过程中,首先确保所有服务器的硬件和系统配置符合要求;接着在每个服务器安装了 Docker 和 cri-dockerd 作为容器引擎;然后再安装 kubeadm、kubelet 和 kubectl 这三个工具。

这些准备好了,就可以在 Master 节点上执行集群初始化,初始化完成后就可以加入工作节点。最后部署 Calico 网络插件,以确保集群内部的网络通信。这样,你就成功搭建了一个功能强大的 K8s 集群,后续课程我们就可以在这个搭建好的集群上实战操作了。

思考题

这就是今天的全部内容,最后希望你能按照上面的过程一步步实际操作,自己搭建一套 K8s 集群,你也可以只使用两台服务器,一台作为 Master 节点,另一台作为 Worker 节点,多练几次,你一定能 10 分钟就搭建好一套 K8s 环境。另外欢迎你把搭建集群中遇到的问题写到留言区,我们下节课再见!