简介
Kubernetes 是当今最流行的开源容器管理平台,是大名鼎鼎的 Google Borg 的开源版本。因为它的名字有点长,所以一般被称作k8s(因为k和s之间有8个字母,没错就是这么随便)。
但尽管k8s如此重要,不少人在部署k8s集群这一步就被直接劝退了。原因有:
- 网络问题:K8S 是 Google 开发的,官方最新镜像都在墙外,安装时下载不了镜像。
- 机器问题:K8S 运行的组件非常多,对于机器本身有要求,配置不能低,如果要搭建集群,还需要多台机器,是笔不小的开销。
- 运维问题:K8S 的部署安装和维护,涉及到不少 Linux 及网络相关的内容,需要有一定的运维能力。
- 单机可用的minikube虽然易用,但功能不够完善。
其实我自己在部署Kubernetes时也遇到了很多坑,最后非常艰难地完成了部署。不过如今已经有很多的安装工具,甚至有一键安装及图形化界面安装工具。本文使用官方推荐的kubeadm工具部署集群。
Kubernetes官方文档:https://kubernetes.io/zh-cn/
Kubernetes架构图:
安装
准备工作
本次部署的集群为多节点集群,有一个master和两个node节点。(我们仅仅是学习之用,没有集群稳定安全性考虑,这里就不需要浪费资源去搞高可用。)
部署版本为目前的最新版1.25.0
。
Docker Engine没有实现CRI,而这是容器运行时在Kubernetes中工作所需要的。为此,必须安装一个额外的服务cri-dockerd
。cri-dockerd
是一个基于传统的内置Docker引擎支持的项目,它在1.24
版本从kubelet中移除。Kubernetes推荐使用containerd
代替cri-dockerd
,但本文仍使用cri-dockerd
进行部署,后期再考虑升级。官方CRI文档
部署环境为三台VMware Workstation虚拟机,操作系统为Ubuntu 22.04.1 LTS,加入同一虚拟网络。
鉴于我使用国内镜像站部署后一直报错,本文在部署过程中使用Google官方镜像站下载镜像文件,因此请保证你能让虚拟机访问外网。使用Clash的用户可以参考Clash for Windows教程:配置TUN/TAP虚拟网卡。
本文所有操作请使用root用户执行。
因为是在虚拟机内操作,为了防止误操作,请多使用VMware的快照功能。
1 配置虚拟机网络
本段内容需要在所有节点执行。
安装虚拟机的部分不再赘述。安装完一台后克隆两台,随后在虚拟机设置-网络适配器-高级
中分别重新生成mac地址即可(mac地址不能重复)。
之后点击编辑-虚拟网络编辑器
,添加一个网络,选择NAT模式
,配置好子网和网关,如图:
配置三台虚拟机的网络适配器的网络连接为此网络:
这一步是为了将虚拟机置于同一网络内,让它们能互相访问,同时NAT使它们能够访问到广域网。
DHCP为虚拟机分配的IP会变化,对于K8S集群环境来说,管理网络的IP应该是固定的,否则会造成通信的混乱,所以需要配置静态IP。
开启这三台虚拟机,分别编辑/etc/netplan/00-installer-config.yaml
(可能文件名不一样),修改为以下内容:
注意不要把三台虚拟机的IP配一样了。
编辑完之后对三台机器使用如下命令使配置生效:
netplan apply
由于IP发生了变化,SSH连接会断开,再次连接即可。
2 基础环境
本段内容需要在所有节点执行。
关闭swap
在旧版的k8s中kubelet都要求关闭swap,但最新版的kubelet其实已经支持swap,因此这一步其实可以不做。但在生产环境还是建议关闭swap,毕竟如果任务运行到了swap上,性能会大打折扣。
# 临时关闭swap
swapoff -a
# 编辑/etc/fstab,注释掉swap那行,持久化生效
vim /etc/fstab
修改主机名并添加hosts解析
这一步是为了增加节点辨识度。这一步可以不做,但建议还是做一下。
为所有节点使用如下命令设置主机名:
# 将name改为你希望的名称,如master、node1等
hostnamectl set-hostname name
编辑/etc/hosts
,依次加入各个节点的IP和主机名,如图:
修改时区
timedatectl set-timezone Asia/Shanghai
修改后,如果想使得系统日志的时间戳也立即生效,重启rsyslog:
systemctl restart rsyslog
设置内核参数
首先确认你的系统已经加载了br_netfilter
模块。默认是没有该模块的,需要你先安装bridge-utils
。然后再使用modprobe
加载一下,lsmod
就能看到br_netfilter
模块,此时再确认一下内核参数net.bridge.bridge-nf-call-iptables
是否为1
。
# 首先更新源
apt update
apt install -y bridge-utils
modprobe br_netfilter
lsmod | grep br_netfilter
sysctl -a | grep bridge
在Ubuntu新版本上,这个值就是1。如果你的系统上不一致,使用下面的命令来修改:
cat <<EOF | tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sysctl --system
3 基础软件
本段内容需要在所有节点执行。
安装Docker
目前新版的Ubuntu已经有提供Docker的安装包,直接安装即可。
apt install docker.io
systemctl start docker
systemctl enable docker
安装cri-dockerd
wget https://github.com/Mirantis/cri-dockerd/releases/download/v0.2.5/cri-dockerd_0.2.5.3-0.ubuntu-bionic_amd64.deb
dpkg -i cri-dockerd_0.2.5.3-0.ubuntu-bionic_amd64.deb
安装kubeadm、kubelet和kubectl
本段内容来自官方文档。需要虚拟机能够访问外网。
# 安装使用 Kubernetes apt 仓库所需要的包
apt install -y apt-transport-https ca-certificates curl
# 下载 Google Cloud 公开签名秘钥
curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg https://packages.cloud.google.com/apt/doc/apt-key.gpg
# 添加 Kubernetes apt 仓库
echo "deb [signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list
# 更新 apt 包索引,安装 kubelet、kubeadm 和 kubectl,并锁定其版本
apt update
apt install -y kubelet kubeadm kubectl
apt-mark hold kubelet kubeadm kubectl
kubelet现在每隔几秒就会重启,目前这是正常现象,因为它陷入了一个等待kubeadm指令的死循环。
4 使用kubeadm创建集群
本段内容需要在master和node节点执行不同的操作。
使用如下命令初始化master节点。需要虚拟机能够访问外网。
sudo kubeadm init \
--pod-network-cidr 172.16.0.0/16 \ # Pod子网
--image-repository registry.cn-hangzhou.aliyuncs.com/google_containers \ # 国内镜像仓库
--token-ttl 0 \ # Token失效时间,0为永不失效
--cri-socket unix:///var/run/cri-dockerd.sock # 容器运行时端点
执行完成后会提醒你做三件事:
-
配置环境变量
在master上操作以便你能正常使用kubectl进行集群的操作。
对于常规用户如下: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
-
将节点加入集群
在两台node节点运行以下命令将其加入集群。# 注意这里是示例,以你的控制台显示的命令为准 kubeadm join 172.20.20.200:6443 --token abcdef.0123456789abcdef \ --discovery-token-ca-cert-hash sha256:4e4a7d0e848ae6c047d163fbe07f0e6975d71cc156d7705649241a59bbecaa04
完成之后,再到master上查看node,若可以看到node说明成功将worker加入集群中了。
-
部署网络插件
上面我们已经部署好了K8S集群,但是由于还没有安装网络插件,因此整个集群实际上还是不能工作的,通过kubectl get nodes
可以看到虽然已经有两个节点,但Status却都还是NotReady。
K8S的网络插件有很多,常见的有flannel、calico、cilium、kube-ovn等等。Calico 是比较主流的选择,因此这里选择Calico进行安装。
在集群上运行以下命令安装Calico:kubectl apply -f "https://docs.projectcalico.org/manifests/calico.yaml"
等待几分钟,网络插件安装成功运行之后,再次查看Node,其状态会更新为ready。
验收集群
如果可以在K8S集群里成功创建一个Pod,那就说明这个集群是健康的、可用的。
使用如下命令就可以创建一个最简单的nginx pod:
kubectl apply -f https://k8s.io/examples/pods/simple-pod.yaml
simple.pod
的yaml简单内容如下:
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
执行后,通过kubectl get pod
可以观察到状态的变化:
通过加-o wide
可以查看pod的ip,再使用curl,就可以访问这个nginx服务。
至此,我们创建了第一个pod的集群搭建完成。
恭喜你,已经完成了你学习K8S最艰难的一步——环境搭建。
参考:
图解 K8S(01):基于 Ubuntu 20.04 部署 1.23版K8S 集群 - 王炳明
安装 kubeadm - Kubernetes文档
Comments NOTHING