裸金属服务器部署kubernetes集群

xuxu Lv1

集群环境

HOSTNAME IP SYSTEM
master 10.0.0.100 Ubuntu Server 24.04
worker1 10.0.0.101 Ubuntu Server 24.04
worker2 10.0.0.102 Ubuntu Server 24.04

1#检测和配置系统环境

1.1#确保每个节点上 MAC 地址和 product_uuid 的唯一性

1
2
你可以使用命令 ip link 或 ifconfig -a 来获取网络接口的 MAC 地址
可以使用 sudo cat /sys/class/dmi/id/product_uuid 命令对 product_uuid 校验

1.2#推荐内核版本

推荐最低内核版本6.5+,因为Pod 用户命名空间支持需要最低内核版本 6.5+

1.3#交换分区的配置

kubelet 的默认行为是在节点上检测到交换内存时无法启动。 这意味着要么禁用交换(swap)功能,要么让 kubelet 容忍交换。

1
2
sed -n "/swap/p" /etc/fstab #匹配swap行并打印
sed -i.bak "/swap/d" /etc/fstab #备份原文件,然后匹配swap行并删除

1.4#启用 IPv4 数据包转发

手动启用 IPv4 数据包转发:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 设置所需的 sysctl 参数,参数在重新启动后保持不变
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-iptables=1
EOF

# 应用 sysctl 参数而不重新启动
sudo sysctl --system
#使用以下命令验证 net.ipv4.ip_forward 是否设置为 1:
sysctl net.ipv4.ip_forward

#关闭ipv6
echo "net.ipv6.conf.all.disable_ipv6 = 1" >> /etc/sysctl.d/99-disable-ipv6.conf
echo "net.ipv6.conf.default.disable_ipv6 = 1" >> /etc/sysctl.d/99-disable-ipv6.conf
sysctl -p /etc/sysctl.d/99-disable-ipv6.conf

1.5#加载内核模块

1
2
3
4
# 立即加载内核模块
sudo modprobe br_netfilter
# 写入开机自动加载配置
echo "br_netfilter" | sudo tee /etc/modules-load.d/k8s.conf

2#安装容器

同一个系统上只能有一个cgroup管理器,要检查你的发行版使用的是哪个 CGroup 版本,请在该节点上运行命令:

1
2
newnew@master:~$ stat -fc %T /sys/fs/cgroup/
cgroup2fs

现代 Linux 发行版默认全部使用 systemd 作为 CGroup 管理器(并且默认启用 CGroup v2),而kubelet 中默认的 CGroup 驱动是(CGroup v1)。
结合上面的输出我们需要更改containerd和kubelet的配置文件。

1
2
3
# 更新软件包索引并安装
sudo apt update && sudo apt install containerd -y
containerd config default | sudo tee /etc/containerd/config.toml

找到 [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options] 这部分,确保 SystemdCgroup = true。

1
sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml

配置镜像源代理(Optional)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#修改 /etc/containerd/config.toml,确保 config_path 没有多余字符
[plugins."io.containerd.grpc.v1.cri".registry]
config_path = "/etc/containerd/registry.d" # 去掉末尾斜杠、

#配置registry代理
sudo tee /etc/containerd/registry.d/registry.k8s.io/hosts.toml <<EOF
server = "https://registry.k8s.io"

[host."httotps://k8s.risun.dev"]
capabilities = ["pull", "resolve"]
EOF

sudo systemctl restart containerd
sudo systemctl enable containerd

或者直接系统层配置网络代理

1
2
3
4
5
6
7
8
9
10
11
12
13
sudo mkdir -p /etc/systemd/system/containerd.service.d
sudo vim /etc/systemd/system/containerd.service.d/proxy.conf
[Service]
Environment="HTTP_PROXY=http://10.0.0.1:10808"
Environment="HTTPS_PROXY=http://10.0.0.1:10808"
Environment="NO_PROXY=localhost,127.0.0.1,10.0.0.0/8,172.16.0.0/12,192.168.0.0.0/16,.svc,.cluster.local"

# 1. 重新加载 systemd 管理器配置
sudo systemctl daemon-reload
# 2. 重启 containerd
sudo systemctl restart containerd
# 3. 检查systemctl是否加载代理
sudo systemctl show containerd --property=Environment

3#安装 kubeadm、kubelet 和 kubectl

需要在所有机器上安装以下的软件包:

  • kubeadm:用来初始化集群的指令。
  • kubelet:在集群中的每个节点上用来启动 Pod 和容器等。
  • kubectl:用来与集群通信的命令行工具。

1、安装使用Kubernetes apt 仓库所需要的包

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

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

1
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.37/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg

3、添加 Kubernetes apt 仓库。

1
echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.37/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list

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

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

5、(可选)先启用 kubelet 服务,再运行 kubeadm:

1
sudo systemctl enable --now kubelet

kubelet 现在每隔几秒就会重启,因为它陷入了一个等待 kubeadm 指令的死循环。

4#创建kubernets集群

1、初始化控制平面(master)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#初始化控制平面
kubeadm init --control-plane-endpoint=10.0.0.100 --pod-network-cidr=10.8.0.0/16

#使用普通用户执行如下命令
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

#生成加入命令
kubeadm token create --print-join-command

#或者手动拼凑(基于你现有的 Token)
kubeadm token list
openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.*=//'

2、安装网络插件

1
2
3
4
5
6
7
8
9
10
11
12
#下载配置文件
wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
#kube-flannel默认的网段是10.244.0.0/16,我们需要改成自己的网段
sed -i 's|10.244.0.0/16|10.8.0.0/16|g' kube-flannel.yml
#应用配置文件
kubectl apply -f kube-flannel.yml
#查看Flannel网络插件是否工作正常
newnew@master:~$ kubectl get pods -n kube-flannel -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
kube-flannel-ds-87sjj 1/1 Running 0 33m 10.0.0.100 master <none> <none>
kube-flannel-ds-88ps5 1/1 Running 0 33m 10.0.0.101 worker1 <none> <none>
kube-flannel-ds-fl85w 1/1 Running 0 33m 10.0.0.102 worker2 <none> <none>

3、加入worker节点(worker)

1
sudo kubeadm join <你的Master节点IP>:6443 --token 3f0lxe.1dikyriye1b0749v --discovery-token-ca-cert-hash sha256:<你的CA证书哈希值>

5#部署第一个应用

1、部署nginx服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#部署nginx镜像,并声明两个副本
kubectl create deployment my-nginx --image=nginx --replicas=2

#查看nginx是否运行起来
kubectl get pods -o wide -l app=my-nginx
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
my-nginx-56d6f5dd87-jrrz5 1/1 Running 0 88m 10.8.1.2 worker1 <none> <none>
my-nginx-56d6f5dd87-qj29f 1/1 Running 0 88m 10.8.2.2 worker2 <none> <none>

#运行起来后对外发布端口
kubectl expose deployment my-nginx --port=80 --type=NodePort

#查看对外发布端口
kubectl get svc my-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
my-nginx NodePort 10.111.153.240 <none> 80:30174/TCP 24m
  • NAME (my-nginx):Service 的名称。
  • TYPE (NodePort):服务类型。这意味着 Kubernetes 会在集群中的每一个节点(Node)上开放一个固定的端口(在本例中是 30174),将外部对该端口的访问流量转发到后端的 Pod 上。
  • CLUSTER-IP (10.111.153.240):集群内部的虚拟 IP,仅供集群内部的其他 Pod 或服务访问。
  • EXTERNAL-IP (<none>):没有分配外部负载均衡器 IP。
  • PORT(S) (80:30174/TCP):
  • 80:Service 自身的端口(集群内部访问时的端口)。
  • 30174:NodePort(节点端口)。外部客户端可以通过访问集群中任意一个节点的 IP 加上这个端口(即 http://<任意节点IP>:30174)来访问你的 Nginx 服务。
  • AGE (24m):该服务已经创建了 24 分钟。

2、测试访问

1
2
3
4
5
6
newnew@master:~$ curl -s 10.0.0.102:30174 | grep -i welcome
<title>Welcome to nginx!</title>
<h1>Welcome to nginx!</h1>
newnew@master:~$ curl -s 10.0.0.101:30174 | grep -i welcome
<title>Welcome to nginx!</title>
<h1>Welcome to nginx!</h1>
  • Title: 裸金属服务器部署kubernetes集群
  • Author: xuxu
  • Created at : 2026-10-28 16:15:14
  • Updated at : 2026-10-28 08:15:02
  • Link: https://risun.dev/裸金属服务器部署kubernetes集群/
  • License: This work is licensed under CC BY-NC-SA 4.0.
Comments