0.前言

  • 系统:Ubuntu20.04 三台(两台集群;一台rancher(也可以把rancher装入master中))VMware启动
  • Containerd:v1.7.14
  • Kubernetes:v2.18.11(使用kubeadm工具来构建Kubernetes集群)
  • Rancher:v2.8.4

注意:

  • 各个组件版本的匹配
  • Linux系统不同,有些文件的存储位置也不同,若出错请留意。
  • 镜像拉取会出问题,后续介绍

1.配置基础环境(两台集群主机同时进行)

1.1 安装容器运行时

1.1.1 介绍

为了在 Pod 中运行容器,Kubernetes 使用 容器运行时(Container Runtime)
默认情况下,Kubernetes 使用 容器运行时接口(Container Runtime Interface,CRI) 来与你所选择的容器运行时交互。
Docker Engine 没有实现 CRI, 而这是容器运行时在 Kubernetes 中工作所需要的。 为此,必须安装一个额外的服务 cri-dockerd。 cri-dockerd 是一个基于传统的内置 Docker 引擎支持的项目, 它在 1.24 版本从 kubelet 中移除。因此这里我们选择官方推荐的Containerd

1.1.2 安装步骤

官方连接:containerd/docs/getting-started.md at main · containerd/containerd
第一步:下载二进制文件
containerd – containerd downloads

wget https://github.com/containerd/containerd/releases/download/v1.7.14/containerd-1.7.14-linux-amd64.tar.gz

第二步:安装(解压)

sudo tar Cxzvf /usr/local containerd-1.7.14-linux-amd64.tar.gz

第三步:判断Linux系统的服务管理器是否是systemd

$ ps -p 1 -o comm=
systemd

Ubuntu系统默认使用systemd。
若是是使用的systemd,还需下载containerd.service/usr/lib/systemd/system位置,注意,官方文档上写的是下载到/usr/local/lib/systemd/system位置,这里应该是Linux系统版本的问题,因为在Ubuntu20.04中,在/usr/local/lib/systemd/system位置下的服务是无法被systemctl daemon-reload所执行的。
下载:

wget https://raw.githubusercontent.com/containerd/containerd/main/containerd.service

移动到/usr/local/lib/systemd/system:(注意没有local)

sudo mv containerd.service /usr/lib/systemd/system/

重新加载 systemd 的配置文件 :

systemctl daemon-reload
systemctl enable --now containerd

查看状态:

sudo systemctl status containerd

1.1.3 配置containerd

生成配置文件:

sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml

设置systemd:

sudo vim /etc/containerd/config.toml

# 找到[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
# 里面的 SystemdCgroup = 设为true

在容器运行时中设置 Unix 域套接字:

# 创建/etc/crictl.yaml
sudo vim /etc/crictl.yaml

# 写入
runtime-endpoint: unix:///var/run/containerd/containerd.sock

# 查看
sudo crictl info

为了让守护进程与客户端之间通过本地文件系统进行通信。Unix 域套接字提供了一个高效的本地通信机制,常用于本地进程间通信(IPC)。对于容器运行时,如 Docker 或 containerd,配置 Unix 域套接字可以使得 API 客户端与守护进程通信。
重启containerd:

sudo systemctl restart containerd

1.2 禁用swap分区

kubelet 的默认行为是在节点上检测到交换内存时无法启动。 更多细节参阅交换内存管理

  • 如果 kubelet 未被正确配置使用交换分区,则你必须禁用交换分区。 例如,sudo swapoff -a 将暂时禁用交换分区。要使此更改在重启后保持不变,请确保在如 /etc/fstab、systemd.swap 等配置文件中禁用交换分区,具体取决于你的系统如何配置。
# 暂时禁用交换分区
sudo swapoff -a

# 永久禁用交换分区
sudo vim /etc/fstab
# 找到,并注释掉
/swapfile none swap sw 0 0

1.3 在各个节点添加hosts配置

若没有配置k8s会给出默认名称,不利于分辨节点

# 在对应节点设置
vim /etc/hosts
192.168.88.141 k8s-master
vim /etc/hosts
192.168.88.142 k8s-node1

vim /etc/hostname
k8s-master
vim /etc/hostname
k8s-node1

1.4 关闭防火墙

关闭防火墙或者开放必要的端口
启用这些必要的端口后才能使 Kubernetes 的各组件相互通信。 可以使用 netcat 之类的工具来检查端口是否开放,例如:

nc 127.0.0.1 6443 -v

你使用的 Pod 网络插件 (详见后续章节) 也可能需要开启某些特定端口。 由于各个 Pod 网络插件的功能都有所不同,请参阅他们各自文档中对端口的要求。
关闭防火墙:

# 查看防火墙状态 inactive说明是未激活
sudo ufw status

# 开机不启动防火墙,重启即可生效
sudo ufw disable

1.5 转发ipv4流量 并 让 iptables 看到桥接流量

启用 IP 转发使得系统能够转发通过它的网络流量,这对于容器之间的网络通信和容器访问外部网络是必需的。
配置 iptables 以便它可以正确处理通过 Linux 桥接接口(如 docker0 或 cni0)的流量。这对于正确应用防火墙规则、NAT 和容器网络隔离非常重要。

cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF

sudo modprobe overlay
sudo modprobe br_netfilter

# 设置所需的 sysctl 参数,参数在重新启动后保持不变
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables  = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward                 = 1
EOF

# 应用 sysctl 参数而不重新启动
sudo sysctl --system

# 通过运行以下指令确认 br_netfilter 和 overlay 模块被加载:
lsmod | grep br_netfilter
lsmod | grep overlay

# 通过运行以下指令确认 net.bridge.bridge-nf-call-iptables、net.bridge.bridge-nf-call-ip6tables 和 net.ipv4.ip_forward 系统变量在你的 sysctl 配置中被设置为 1:
sysctl net.bridge.bridge-nf-call-iptables net.bridge.bridge-nf-call-ip6tables net.ipv4.ip_forward

1.6 关闭SELinux(ubuntu默认没有安装)

sudo setenforce 0
vim /etc/selinux/config
SELINUX=disabled

1.7 时间同步

默认情况下,Ubuntu 20.04 已经安装了 timedatectl 工具。如果未安装,可以使用以下命令进行安装:

sudo apt update
sudo apt install timedatectl 
# 设置时区为亚洲/上海:
sudo timedatectl set-timezone Asia/Shanghai

# 启用并启动 systemd-timesyncd 服务:
sudo timedatectl set-ntp true

# 验证当前时间
date

1.8 安装 kubeadm、kubelet 和 kubectl

在低于 Debian 12 和 Ubuntu 22.04 的发行版本中,/etc/apt/keyrings 默认不存在。 首先进项创建。

1.更新 apt 包索引并安装使用 Kubernetes apt 仓库所需要的包:

sudo apt-get update
# apt-transport-https 可能是一个虚拟包(dummy package);如果是的话,你可以跳过安装这个包
sudo apt-get install -y apt-transport-https ca-certificates curl gpg

2.下载用于 Kubernetes 软件包仓库的公共签名密钥。所有仓库都使用相同的签名密钥,因此你可以忽略URL中的版本:(官方)

# 如果 `/etc/apt/keyrings` 目录不存在,则应在 curl 命令之前创建它,请阅读下面的注释。
# sudo mkdir -p -m 755 /etc/apt/keyrings
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.30/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg

我们使用阿里云镜像:

curl -fsSL https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-archive-keyring.gpg

3.添加 Kubernetes apt 仓库。(官方)

# 此操作会覆盖 /etc/apt/sources.list.d/kubernetes.list 中现存的所有配置。
echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.30/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list

我们使用阿里云镜像:

echo "deb [signed-by=/etc/apt/keyrings/kubernetes-archive-keyring.gpg] https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list

4.更新 apt 包索引,安装 kubelet、kubeadm 和 kubectl,并锁定其版本:

sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl

2.使用kubeadm工具创建kubernetes集群

2.1 初始化master节点(control-plane node)

使用配置文件初始化master:

# 生成初始化配置文件到kube的目录(目录可自己设定)
kubeadm config print init-defaults > /home/kube/master/init-default.yaml

# 修改配置文件
sudo vim init-default.yaml

# 关注kubernetesVersion:
# 这里我们设置成:
kubernetesVersion:1.28.11

# imageRepository: 
imageRepository: registry.aliyuncs.com/google_containers 

# podSubnet:可自行设置
podSubnet: 10.244.0.0/16

参考配置:
init-default.yaml

apiVersion: kubeadm.k8s.io/v1beta3
bootstrapTokens:
- groups:
  - system:bootstrappers:kubeadm:default-node-token
  token: abcdef.0123456789abcdef
  ttl: 24h0m0s
  usages:
  - signing
  - authentication
kind: InitConfiguration
localAPIEndpoint:
  advertiseAddress: 192.168.88.142
  bindPort: 6443
nodeRegistration:
  criSocket: unix:///var/run/containerd/containerd.sock
  imagePullPolicy: IfNotPresent
  name: node
  taints: null
---
apiServer:
  timeoutForControlPlane: 4m0s
apiVersion: kubeadm.k8s.io/v1beta3
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
controllerManager: {}
dns: {}
etcd:
  local:
    dataDir: /var/lib/etcd
imageRepository: registry.aliyuncs.com/google_containers
kind: ClusterConfiguration
kubernetesVersion: 1.28.11
networking:
  dnsDomain: cluster.local
  serviceSubnet: 10.96.0.0/12
  podSubnet: 10.235.0.0/16
scheduler: {}
---
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
cgroupDriver: systemd

解决可能遇见的报错:
在执行sudo kubeadm init之前,先解决可能遇见的错误
错误: 显示的错误 (failed to get sandbox image “registry.k8s.io/pause:3.6”) 跟 pause镜像版本对不上。

#查看镜像版本
kubeadm config images list
#查看containerd拉取的镜像
crictl --runtime-endpoint unix:///var/run/containerd/containerd.sock images

# 重载沙箱(pause)镜像
vim /etc/containerd/config.toml
# 设置
[plugins."io.containerd.grpc.v1.cri"]
  sandbox_image = "registry.aliyuncs.com/google_containers/pause:3.9"
# 重新启动
systemctl restart containerd

初始化:

sudo kubeadm init --config=init-default.yaml --ignore-preflight-errors=all

若出现报错:

# 排错
journalctl -xeu kubelet

# 再次init之前首先进行重置
sudo kubeadm reset
# 删除残留文件
rm -rf ~/.kube
sudo rm -rf /etc/cni/net.d
sudo rm -rf /var/lib/kubelet

初始化完成:

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

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

You can now join any number of machines by running the following on each node
as root:

  kubeadm join <control-plane-host>:<control-plane-port> --token <token> --discovery-token-ca-cert-hash sha256:<hash>

要使非 root 用户可以运行 kubectl,请运行以下命令, 它们也是 kubeadm init 输出的一部分:

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

2.2 安装 Pod 网络附加组件

你必须部署一个基于 Pod 网络插件的容器网络接口(CNI), 以便你的 Pod 可以相互通信。在安装网络之前,集群 DNS (CoreDNS) 将不会启动。

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/

这段话提示我们需要部署一个pod network,在以下网址里面有很多种不同的插件,这里我们选择flannel

wget https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml

kubectl apply -f kube-flannel.yml

# 查看镜像拉去状态
kubectl get pods -A

这里注意,如果你在上面的init-default.yaml文件中修改过podSubnet: 10.235.0.0/16,这里要在kube-flannel.yml中同样修改:

vim kube-flannel.yml

# 找到net-conf.json: 
# 修改
"Network": "10.235.0.0/16",

这里需要拉去两个镜像,docker hub镜像源无法直接连上,国内镜像源也有失效、不全、版本旧的原因。这里采用科学上网工具,并在Linux主机上和containerd上同时设置代理。(后面章节介绍)

2.3 初始化worker节点

# 在master节点上
kubeadm token create --print-join-command

# 根据上面的参数 在worker节点上
kubeadm join <control-plane-host>:<control-plane-port> --token <token> --discovery-token-ca-cert-hash sha256:<hash>

2.4 查看状态

kubectl get nodes

kubectl get pods -A

3.安装Rancher

rancher的安装需要注意两点:

  • 版本问题:版本要和kubernetes的版本对照,我们这里安装v2.8.4版本,具体的版本对应请看:Rancher Manager v2.8.4
  • docker镜像问题:docker镜像无法拉取。解决方法一:rancher对国内用户非常友好,提供了国内阿里云的镜像源,可以自行配置如何在国内优雅地使用Rancher;解决方法二:科学上网工具+docker配置代理(后面章节介绍)

我们使用docker进行安装:
注意:rancher官网提供的命令没有标明版本Quick Start,无法和我们的Kubernetes匹配

$ sudo docker run --privileged -d --restart=unless-stopped -p 80:80 -p 443:443 rancher/rancher

这里我们加上版本号:

docker run -d --privileged --restart=unless-stopped -p 80:80 -p 443:443 rancher/rancher:v2.8.4

或者指明镜像源:(没有科学上网的)

docker run -itd -p 80:80 -p 443:443 --restart=unless-stopped -e CATTLE_AGENT_IMAGE="registry.cn-hangzhou.aliyuncs.com/rancher/rancher-agent:v2.8.4" registry.cn-hangzhou.aliyuncs.com/rancher/rancher:v2.8.4

镜像比较大,需要等一会儿

# 看见容器运行起来了就算成功了
docker ps -a

网站登录:
登录你的Linux主机ip:443
按照提示获取初始密码,后续可以修改密码
登录完毕后,导入已有集群->导入任意Kubernetes集群->按照提示在master节点输入命令->导入成功
导入过程需要拉取镜像、启动容器,需等待,观察网速是否在下载。

当看到集群Active说明导入成功:
image.png
image.png

可以在集群工具中安装Prometheus进行集群监控:
image.png
image.png

4.代理配置

4.1 Linux

常用http/https以及socks5代理总结 - wanlifeipeng - 博客园
~/.bashrc 中编辑

sudo vim ~/.bashrc

# 在文件末尾写入
export http_proxy=sock5://ip:port
export HTTPS_PROXY=socks5://ip:port
或者
export http_proxy=http://ip:port
export HTTPS_PROXY=http://ip:port

其中port需要你们在科学上网工具中查找
ip需要在windows中用ipconfig命令查看VMnet8中ipv4的ip地址

# 生效
source ~/.bashrc

4.2 Containerd

4.2.1 方法1:在配置文件中设置,只支持http代理

sudo vim /etc/containerd/config.toml

# 找到[plugins."io.containerd.grpc.v1.cri".registry.mirrors]
添加
 [plugins."io.containerd.grpc.v1.cri".registry.configs."docker.io".http]
        proxy = {
          http_proxy = "http://ip:port",
          https_proxy = "http://ip:port"
        }
# ip:port和4.1中一致  
# `no_proxy` 是一个逗号分隔的地址列表,这些地址不使用代理。

# 重启
sudo systemctl restart containerd

4.2.2 方法2: 通过 containerd 的 systemd 服务配置文件来设置环境变量以使用 SOCKS5 代理

也支持http代理

  • 如果你使用 Systemd 来管理 containerd 服务,可以在 Systemd 服务文件中设置环境变量来传递代理配置。这种方式可以确保 containerd 在启动时能够使用正确的代理设置。
  • 可以编辑 /etc/systemd/system/containerd.service.d/environment.conf 文件(没有的自行创建),添加类似以下内容:
[Service]
Environment="HTTP_PROXY=sock5://ip:port"
Environment="HTTPS_PROXY=sock5://ip:port"

然后重新加载 Systemd 并重新启动 containerd 服务:

sudo systemctl daemon-reload
sudo systemctl restart containerd

4.3 docker

# 创建文件
sudo mkdir /etc/systemd/system/docker.service.d
cd /etc/systemd/system/docker.service.d
sudo vim proxy.conf

# 写入
[Service]
Environment="HTTP_PROXY=socks5://ip:port" 
Environment="HTTPS_PROXY=socks5://ip:port"
或者
Environment="HTTP_PROXY=http://ip:port" 
Environment="HTTPS_PROXY=http://ip:port"

# 重启
sudo systemctl daemon-reload
sudo systemctl restart docker

4.4 测试方法

拉个镜像
curl www.google.com
curl www.github.com

5.写在最后

在整个过程中我们会遇到各种各样的问题,当然,科学上网方面的配置至少占一半,如果能顺利拉到镜像,那么其他的问题也不成问题。
在遇到问题时,我们可以尝试重启系统,因为我们这是自己的练习环境,可以自由重启。如果在工作中真正的生产环境下,是不可能频繁的重启服务器的,这里就需要我们有一定的排查错误的能力。例如最基本的:kubectl describekubectl logscrictl logs等查看一些报错信息,根据这些信息进行排错。解决错误的过程也是你积攒经验的过程,更是你进步的过程。
官方文档是最好的教程,跟着官方文档走是最靠谱的,但当你真正去看时就会发现,官方文档有的地方写的真的是晦涩难懂。这时,我建议官方文档和网络上的技术博客搭配来使用。
如果大家觉得有用,欢迎大家点赞、收藏、关注我,有什么问题可以在评论区讨论或者私信我。我会长期分享K8s、CloudNative方面的知识。

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐