环境介绍

  • 服务器及系统版本:2台阿里云服务器,Cenos7.8版本
  • Kubernetes版本:最新版(截止本文时间24年4月1日,最新版为1.29.3
  • 服务器配置:4核8G
  • Docker版本:最新版(截止本文时间24年4月1日,最新版为26.0.0
  • cri-dockerd版本:最新版(截止本文时间24年4月1日,最新版为0.3.12
  • 网络插件Calico版本:最新版(截止本文时间24年4月1日,最新版为3.27.2

前置准备

  • 2台或以上阿里云服务器,配置至少为4核8G
  • 因为需要从GitHub上下载东西,需要可以下载东西的网络
  • 教程内出现的所有命令,如未特殊标注则默认是在每台机器上都要执行!!!

本文会从机器基础配置、基础插件安装、docker及其cri-dockerd、Kubernetes以及最后的可视化kuboard的安装,循序渐进,并且会在每一步进行对应的解析,来更好的帮助理解

机器基础配置

1. 集群机器互通

首先我们需要确保集群内的网络互通,我们需要从机器内选择一个做为master节点,其余的则是work工作节点,将master机器的名称改为master,其余的改为work1、work2等等(当然也可以不改,这里只是为了更直观一点,但如果是阿里云服务器则有必要改了,因为默认是一串乱码……)

1
2
3
4
# 查看机器名称
hostname
# 修改机器名称
hostnamectl set-hostname master

接下来需要修改每台机器的hosts文件,

1
2
3
4
5
6
vim /etc/hosts

# 追加以下部分(xxx部分是机器的公网Ip,后面的master和work1则是对应的机器名称)
xxx.xxx.xxx.xxx master
xxx.xxx.xxx.xxx work1
xxx.xxx.xxx.xxx work2

2. 关闭setLinux

setLinux是提供访问控制安全策略的安全模块,但它可能限制Kubernetes Pod访问宿主机上的某些资源,导致应用运行失败,所以我们需要在每台机器上将其禁用

1
2
3
4
sudo vim /etc/selinux/config

# 将该值设置为disabled
SELINUX=disabled

3. 关闭swap分区

swap也叫做交换空间,相当于win系统中的虚拟内存。如果在Kubernetes中开启了swap,会导致Kubernetes调度器无法获取真实的节点内存使用情况,会导致意外的性能下降等问题,我们需要关闭所有机器上的swap。PS:官方在1.28又引入了swap的支持,不过是beta版,不过为了严谨,还是统一关闭吧。

1
2
3
4
# 首先临时禁用所有激活的swap分区
sudo swapoff -a
# 永久关闭 找到例如/dev/mapper/ubuntu--vg-swap_1 none swap sw 0 0的行,并将其注释
sudo vi /etc/fstab

4. 修改内核网络规则

1
2
3
4
5
cat > /etc/sysctl.d/k8s.conf << EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
EOF

net.bridge.bridge-nf-call-ip6tables = 1 :针对桥接的IPv6流量,实现IPv6网络的流量过滤和控制
net.bridge.bridge-nf-call-iptables = 1 :针对桥接的IPv4流量,实现IPv4网络的流量过滤和控制
net.ipv4.ip_forward = 1 :启用IPv4的转发功能,节点可能需要转发来自一个Pod到另一个Pod的流量

5. 加载 br_netfilter 模块

这个模块使桥接流量被iptables规则处理,配合内核网络的规则,可以让集群内部通信更安全高效。

PS:br_netfilter与内核网络规则是相辅相成的,我们刚刚编辑完成了一个规则,现在需要一个模块来加载这些规则,这个模块就是br_netfilter,它可以确保网络流量在Pods之间安全的传输。

1
2
3
4
5
6
# 启用br_netfilter模块
modprobe br_netfilter
# 验证是否启用成功
lsmod | grep br_netfilter
# 重新加载/etc/sysctl.conf定义的参数
sysctl --system

6. 关闭防火墙

禁用防火墙的目的是集群内部的通信需要通过特定的端口,以及Pods的动态分配等,在生产中通常不会一棒子打死关闭防火墙。这里仅是做为测试,所以全部关闭

1
2
3
4
5
6
# 关闭防火墙
systemctl disable firewalld
systemctl stop firewalld

# 查看防火墙的状态
systemctl status firewalld

7. 重启

以上内容配置完成后,我们重启机器完成应用

1
reboot

至此,机器的基础部分完成

基础插件安装

接下来我们需要在每台机器上完成时间同步、插件的安装,插件如下:

  • ntpdate:时间同步工具
  • ipvsadm:IPVS负载均衡
  • lrzsz:Linux上传下载工具
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# ntpdate
yum install -y ntpdate
# 设置cn.pool.ntp.org时间
ntpdate cn.pool.ntp.org

# ipvsadm
yum -y install ipset ipvsadm
# 加载以下模块 vs:核心模块,提供负载均衡功能 rr、wrr、sh提供轮询、加权轮询和源散列负载均衡算法、nf_conntrack用来跟踪网络状态
modprobe -- ip_vs
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
modprobe -- ip_vs_sh
modprobe -- nf_conntrack
# 查看已加载模块
lsmod | grep -e ip_vs -e nf_conntrack

# lrzsz 后面上传文件用到
yum install -y lrzsz

Docker及其cri-dockerd

1. Docker和cri-dockerd是什么?

Docker我们都知道,是一个容器化平台,通过运行镜像,避免环境差异带来的问题。而cri-dockerd则是一个组件,是Docker和Kubernetes之间的桥梁,允许Kubernetes通过容器运行时接口(CRI)与Docker交互。从Kubernetes1.20开始,官方弃用Docker Shim,推荐使用兼容CRI的容器运行时。下面我们需要在每台机器上安装Docker与cri-dockerd。

2. 安装Docker

1
2
3
4
5
6
7
8
9
10
11
12
# 下载阿里云的docker-ce文件到yum仓库
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版本
docker version

# 设置docker自启动并启动docker
systemctl enable docker
systemctl start docker

配置cgroup驱动,因为Docker默认使用cgroupfs做为驱动,但Kubernetes则推荐使用systemd,为了确保系统的一致性,我们更改Docker的cgroup驱动为systemd

1
2
3
4
5
6
7
8
9
# 配置守护进程 使用systemd做为驱动
cat > /etc/docker/daemon.json <<EOF
{
"exec-opts": ["native.cgroupdriver=systemd"]
}
EOF

# 重启docker
systemctl restart docker

3. 安装cri-dockerd

dockerd需要我们进入GitHub官网下载,

1
2
# cri-dockerd下载
https://github.com/Mirantis/cri-dockerd/releases/

进入后我们可以看到很多版本,这里对每个版本做一些解释:

  • el7:对应Cenos7系统
  • el8:对应Cenos8系统
  • fc35:对应Fedora 35系统
  • fc36:对应Fedora 36系统
  • x86_64:带此后缀的表示64位版本

image-20240401112533665

选择自己的系统对应的版本,如果不知道自己的系统版本使用下面的命令

1
2
# 查看系统版本
lsb_release -a

在我们本地下载完成后我们需要将下载的文件上传到服务器内

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 通过lrzsz上传文件
rz -be
# 安装cri-dockerd
yum install -y 文件名
# 查看版本
cri-dockerd --version

# 修改默认pause版本
vim /usr/lib/systemd/system/cri-docker.service
# 如下图,在Service中,指定Pod的基础镜像
--pod-infra-container-image=registry.k8s.io/pause:3.9

# 启动cri-dockerd并重启
systemctl start cri-docker
systemctl enable cri-docker

image-20240401093151541

到这里,我们的Docker以及对应的cri就安装完成了,接下来正式进入Kubernetes的安装!

Kubernetes

1. 安装kubeadm kubelet kubectl

在每台机器上应用Kubernetes社区yum源并安装 PS:注意下面的v1.29只能安装1.29.x版本的Kubernetes,如果需要安装其他版本或者更高版本的需要手动将下面的版本改为对应版本,本文截止时,最高版本为1.29!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 应用Kubernetes社区源
cat > /etc/yum.repos.d/k8s.repo <<EOF
[kubernetes]
name=Kubernetes
baseurl=https://pkgs.k8s.io/core:/stable:/v1.29/rpm/
enabled=1
gpgcheck=1
gpgkey=https://pkgs.k8s.io/core:/stable:/v1.29/rpm/repodata/repomd.xml.key
#exclude=kubelet kubeadm kubectl cri-tools kubernetes-cni
EOF

# 安装kubelet
yum -y install kubeadm kubelet kubectl

# 修改kubelet的驱动为systemd 确保和Docker的一致
vim /etc/sysconfig/kubelet
KUBELET_EXTRA_ARGS="--cgroup-driver=systemd"

# 启动kubelet
systemctl enable kubelet

2. 拉取Kubernetes镜像

这里我编写了一段脚本,主要原因是在国内无法直接访问谷歌的仓库,所以我们需要借助阿里云镜像来下载,然后将下载完成的镜像tag重新打包为Kubernets的标签,这样就可以做到不修改镜像源的方式安装原生的Kubernetes。脚本内的前2个变量,一个是Kubernetes的官方仓库地址,一个是阿里云的官方仓库地址,一般不会变,但以防万一可以通过 kubeadm config images lis 命令获取当前最新版,然后查看前缀是否和脚本一致,不一致将脚本的修改为最新的即可。

image-20240401141427752

脚本默认会安装最新的Kubernetes镜像,所以一定要注意和第一步的yum源版本对应上!!!当然你也可以指定版本,就是我注释的那行

创建一个.sh类型的文件,例如pullImages.sh,将下面的内容拷贝到文件内

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#!/bin/bash

# 定义原始和阿里云的镜像仓库地址
original_registry="registry.k8s.io"
aliyun_registry="registry.aliyuncs.com/google_containers"

# 使用 kubeadm config images list 命令获取 Kubernetes 所需的镜像列表
images_list=$(kubeadm config images list)
# 如果要指定版本使用该变量
#images_list=$(kubeadm config images list --kubernetes-version=v1.29.1)

# 循环遍历镜像列表
for image in $images_list; do
# 特殊处理 coredns 镜像
if [[ $image == *"coredns"* ]]; then
# 提取coredns版本号
version=$(echo $image | grep -oP "(?<=coredns:).+")
# 构建在阿里云镜像仓库中的 coredns 镜像路径
ali_image="${aliyun_registry}/coredns:${version}"
echo "Pulling $ali_image..."
docker pull $ali_image
# 重新标记镜像为原始的镜像地址
docker tag $ali_image $image
docker rmi $ali_image
else
# 对于非 coredns 镜像的标准处理
new_image=${image/$original_registry/$aliyun_registry}
echo "Pulling $new_image..."
docker pull $new_image
# 重新标记镜像为原始的镜像地址
docker tag $new_image $image
docker rmi $new_image
fi

done

echo "All images pulled and retagged successfully."

对文件赋予属性并执行

1
2
3
4
5
6
# 赋予可执行属性
chmod -R 755 pullImages.sh
# 执行脚本,开始拉取镜像
./pullImages.sh
# 查看下载完成后的镜像
docker images

下载完成后一般是7个镜像,下面对每个镜像进行解释

image-20240401143054351

  • registry.k8s.io/kube-apiserver:为集群共享状态提供前端,处理用户以及集群内部的所有REST请求,相当于集群大脑
  • registry.k8s.io/kube-controller-manager:运行控制器进程,包括节点控制器、副本控制器、命名空间和服务账号控制器等等,确保集群处于正常的工作状态,并会对故障的副本进行修复、扩展等
  • registry.k8s.io/kube-scheduler:调度Pod到节点,监听那些创建但未指定节点的Pod,为Pod分配工作节点
  • registry.k8s.io/kube-proxy:网络代理与负载均衡,确保每个 Pod 能够通过 Kubernetes 虚拟网络进行通信以及服务的负载均衡
  • registry.k8s.io/etcd:Kubernetes 的所有集群数据的后备存储,保存了整个集群的状态,包括节点、Pods、配置等的信息。
  • registry.k8s.io/coredns/coredns:集群内部的 DNS 服务器,使得 Pod 可以通过服务名进行通信,而不是直接通过 IP 地址。
  • registry.k8s.io/pause:充当 Pod 的基础设施容器

3. 初始化master节点

PS:这里的命令只在master节点执行!!!

1
2
# 初始化master节点
kubeadm init --kubernetes-version=v1.29.3 --pod-network-cidr=10.244.0.0/16 --apiserver-advertise-address=172.27.207.115 --cri-socket unix:///var/run/cri-dockerd.sock

下面对这四个参数进行解释:

  • –kubernetes-version=v1.29.3:指定Kubernetes的节点,这里指定为1.29.3(务必对应自己下载的版本!)

  • –pod-network-cidr=10.244.0.0/16:指定Pod 网络的 CIDR 范围,一般用10.244.0.0/16

  • –apiserver-advertise-address=172.27.207.115:指定API 服务器的 IP 地址,也就是其他集群组件和用户将用来与 API 服务器通信的地址,一般为master节点的内网IP

  • –cri-socket unix:///var/run/cri-dockerd.sock:指定容器运行时接口(CRI)的通信 socket 路径,使用我们下载的cri-dockerd

执行完成后,我们会获得一个token,我们先提前保存一下

1
2
kubeadm join 172.27.207.110:6443 --token xby2g1.nmlhcqqy1ylkwepk \
--discovery-token-ca-cert-hash sha256:834424b2464d80679bd1c1faa429712276c34a5d5763a4b4600b47a40e4a6a05

接下来需要配置kubectl工具,通过kubectl来管理集群

1
2
3
4
# 一般我们只在master管理集群,所以只在master执行
mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config

4. 工作节点加入master节点

我们将刚刚的token后面追加 --cri-socket unix:///var/run/cri-dockerd.sock 然后在所有的工作节点执行

通过在master节点上执行 kubectl get nodes 查看所有节点

image-20240401145424469

5. 安装Calico网络插件

Calico提供了网络连接和高级网络策略,可以为每个Pod提供唯一的IP地址,保证 Pod 之间的通信既安全又高效,下面我们来安装Calico插件 Calico官网

进入官网后往下滑,我们可以看到目前的最新版为3.27.2,我们复制第一个命令并执行(注意是在master节点执行,因为只有master节点能使用kubectl命令)

image-20240401150101937

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 下载tigera-operator自动化部署工具
kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.27.2/manifests/tigera-operator.yaml

# 将custom-resources.yaml下载到本地,因为我们需要修改cidr字段
wget https://raw.githubusercontent.com/projectcalico/calico/v3.27.2/manifests/custom-resources.yaml

# 修改文件ipPools的cidr字段,修改为使用kubeadm init初始化时,我们指定的PodCIDR范围 --pod-network-cidr对应的IP地址段
vim custom-resources.yaml
ipPools:
- blockSize: 26
cidr: 10.244.0.0/16
encapsulation: VXLANCrossSubnet

# 创建Calico资源
kubectl create -f custom-resources.yaml

至此,Kubernetes安装完成,下面我们进入可视化的安装

Kuboard

1. 安装Kuboard

我们在master节点上创建安装脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 创建kuboard缓存文件夹
mkdir -p ~./kuboard/data

# 创建安装脚本
cat > startKuboard.sh << EOF
docker run -d \
--restart=unless-stopped \
--name=kuboard \
-p 1001:80/tcp \
-p 10081:10081/tcp \
-e KUBOARD_ENDPOINT="http://127.0.0.1:80" \
-e KUBOARD_AGENT_SERVER_TCP_PORT="10081" \
-v /home/kuboard/data:/data \
eipwork/kuboard:v3
EOF

# 赋值执行权限
chmod -R 755 startKuboard.sh

# 执行
./startKuboard.sh

注意,我们在访问前需要在阿里云放行对应端口,我暴露在1001端口

在入方向放行所有的端口

image-20240401095450328

出方向只需要放行1001即可

image-20240401095513743

访问IP:1001端口进入主页面,默认用户名和密码为admin、Kuboard123

2. 添加Kubernetes集群

点击添加集群,通过KubeConfig的方式引入,在master节点执行 cat ~/.kube/config,然后将其所有内容复制到输入框,输入集群的名称和描述,将 ApiServer 的IP地址改为公网IP地址即可

image-20240401095731866

image-20240401100024202

至此,Kuboard安装完成。

3. kubernetes常用命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# kubernetes常用命令
kubectl get nodes:列出所有节点,显示集群的节点信息
kubectl cluster-info:显示集群的信息,如 Master 和 services 的地址
kubectl describe node <node-name>:显示特定节点的详细信

kubectl get pods:列出所有 Pod
kubectl get deployment:列出所有部署
kubectl get service:列出所有服务

kubectl apply -f <config-file.yaml>:根据 YAML 配置文件创建或更新资源
kubectl delete -f <config-file.yaml>:根据 YAML 配置文件删除资源
kubectl logs <pod-name>:查看 Pod 的日志

kubectl describe pod/deployment/service <name>:显示特定资源的详细信息,用于调试。
kubectl get events:列出集群中的事件,常用于故障排查

结束语

到这里,Kubernetes最新版就安装完成了。可能随着Kubernetes官方的不断更新,教程可能会失效,但如果安装1.29是肯定没问题的,而且这个版本也算很超前了吧。不少教程甚至停留在1.1x的版本.. 最后,如果这个教程有问题欢迎文章下面留言~