基于 kubeadm=1.29.15 kubectl=1.29.15 kubelet=1.29.15 进行试验安装。1.24 以后的安装方式相同

主机名 操作系统 IP service 子网 pod 子网 配置
master ubuntu 24.04 192.168.17.130 10.96.0.0/12 10.244.0.0/16 4C 4M 50G
node1 ubuntu 24.04 192.168.17.131 10.96.0.0/12 10.244.0.0/16 4C 4M 50G
node2 ubuntu 24.04 192.168.17.132 10.96.0.0/12 10.244.0.0/16 4C 4M 50G

一、安装前准备

所有节点都执行

1. 修改主机名
hostnamectl set-hostname xxx | bash
2. 修改 hosts 文件
root@master:~/k8s# vim /etc/hosts

192.168.17.130 master
192.168.17.131 node1
192.168.17.132 node2
3. 配置 ssh 免密登录
root@master:~/k8s# ssh-keygen -t rsa

将 ssh token 复制到所有节点
root@master:~/k8s# ssh-copy-id xxxx
4. 加载网络插件且修改配置
modprobe br_netfilter
cat > /etc/sysctl.d/k8s.conf <<EOF

net.bridge.bridge-nf-call-ip6tables = 1

# 让 Linux 网桥(Bridge)的流量经过 iptables/nftables 规则。
# Kubernetes Service 的 kube-proxy 依赖 iptables 实现负载均衡和 NAT。
# 如果设为 0,Service 的 ClusterIP 和 NodePort 可能无法正常工作。
net.bridge.bridge-nf-call-iptables = 1

# 启用 IPv4 数据包转发(路由功能)。
# Kubernetes 的 Pod 网络(如 Flannel、Calico)依赖节点的路由功能。
# 如果禁用,跨节点的 Pod 通信会失败。
net.ipv4.ip_forward = 1
# 控制内核使用 Swap 的倾向性(0 = 尽量不用 Swap,除非内存耗尽)。

vm.swappiness = 0
# 增加单个用户可监听的 文件/目录变化事件(inotify)的实例数上限。
# Kubernetes 组件(如 kubelet)和容器运行时需要监控大量文件变化(如 ConfigMap/Secret 更新)。
# 默认值(通常为 128)可能导致 "Too many open files" 错误
fs.inotify.max_user_instances = 524288

# 提高系统全局的 最大文件句柄数。
# Kubernetes 节点可能同时运行大量容器,每个容器会打开多个文件。
# 避免因句柄不足导致 Pod 启动失败。
fs.file-max = 2097152
EOF

其他配置说明在最后

sysctl -p /etc/sysctl.d/k8s.conf
5. 关闭交换分区 swapoff
# 临时关闭
swapoff -a

注释下面文件中的 swapp 部分内容
vim /etc/fstab
查看是否关闭成功
free -h
6. 关闭防火墙
ufw disable

查看防火墙状态
ufw status
7. 同步时间
timedatectl set-timezone Asia/Shanghai
apt install chrony -y
systemctl enable chrony.service
8. 修改 apt-get 源。查看

二、安装 containerd

所有节点都执行

官方安装教程

1. 删除本机存在的docker相关内容
sudo apt-get remove docker docker-engine docker.io containerd runc
2. 安装需要的包
apt-get update

apt-get install ca-certificates curl gnupg
3. 添加docker key文件
mkdir -m 0755 -p /etc/apt/keyrings

# docker 官方
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg

# 阿里云
curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

# 验证
gpg --show-keys /usr/share/keyrings/docker-archive-keyring.gpg
4. 添加 docker 源
# docker 官方
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

# 阿里云
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://mirrors.aliyun.com/docker-ce/linux/ubuntu noble stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
5. 更新 apt
apt-get update
6. 安装 containerd 并锁定版本
apt-get install -y containerd.io=1.7.27

apt-mark hold containerd.io=1.7.27
7. 生成 containerd 配置文件
  • 创建 /etc/containerd 文件夹
mkdir -p /etc/containerd
  • 生成 containerd 配置文件
containerd config default > /etc/containerd/config.toml
8. 修改 containerd 配置文件
  • 开启 Systemd

SystemdCgroup=false 使用传统的 cgroupfs 驱动
SystemdCgroup=true 让 containerd 使用 systemd 作为 cgroup 管理器

  • systemd 本身会管理 cgroup,如果 containerd 仍用 cgroupfs,可能导致资源隔离冲突。
  • 启用 SystemdCgroup = true 后,containerd 会通过 systemd 的 cgroup 接口管理容器资源(如 CPU、内存限制)。
SystemdCgroup 改为 true
  • 修改 sandbox_image 镜像仓位置

pause:3.9 版本根据 kubernetes 而定

sandbox_image = "registry.aliyuncs.com/google_containers/pause:3.9"
9. 启动 containerd 并开机启动
systemctl enable containerd  --now
10. 修改 /etc/crictl.yaml

设置 kubernetes 创建 pod 时的运行时使用 containerd

cat > /etc/crictl.yaml <<EOF
runtime-endpoint: unix:///run/containerd/containerd.sock
image-endpoint: unix:///run/containerd/containerd.sock
timeout: 10
debug: false
EOF
11. 安装 docker 方便管理镜像
  • ######安装 docker 并设置开机启动
apt-get install docker-ce

systemctl enable docker --now
  • 修改镜像加速
root@master:~/k8s# vim /etc/containerd/config.toml
# 配置本地镜像仓库
[plugins."io.containerd.transfer.v1.local"]

# 镜像拉取加速
[plugins."io.containerd.grpc.v1.cri".registry]
config_path = "/etc/containerd/certs.d"

root@master:~/k8s# mkdir /etc/containerd/certs.d/docker.io/ -p
  • 配置加速器地址
root@master:~/k8s# vim /etc/containerd/certs.d/docker.io/hosts.toml

server = "https://registry-1.docker.io"  # 主仓库地址(必须保留)

[host."https://registry.cn-hangzhou.aliyuncs.com"]
  capabilities = ["pull"]  # 允许拉取


  • docker 镜像加速器
root@master:~/k8s# mkdir /etc/docker
root@master:~/k8s# vim /etc/docker/daemon.json
{
  "registry-mirrors": [
    "https://registry.cn-hangzhou.aliyuncs.com"
  ],
  "exec-opts": ["native.cgroupdriver=systemd"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m"
  }
}
  • 重启 docker
sudo systemctl restart docker
  • 查看 docker 镜像源
docker info|grep Mirrors -A 1

三、安装 kubernetes

1,2,3步骤节点都执行。其他步骤 master 节点执行

1. 配置 kubernetes 源

官方

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

# 添加 Kubernetes 官方 APT 仓库(如果是ARM64替换arch)
echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.29/deb/ /" | sudo tee /etc/apt/sources.list.d/kubernetes.list

阿里

sudo tee /etc/apt/sources.list.d/kubernetes.list <<EOF
deb https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial main
EOF
apt-get clean
apt-get update
2. 安装 kubeadm kubectl kubelet
apt-get install -y kubeadm=1.29.15  kubectl=1.29.15  kubelet=1.29.15
3. 设置容器运行时
crictl config runtime-endpoint /run/containerd/containerd.sock
4. 导出初始化使用的 yaml
kubeadm config print init-defaults > kubeadm.yaml
  • 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:
  # 控制节点 IP
  advertiseAddress: 192.168.17.130
  bindPort: 6443
nodeRegistration:
  # 使用的容器运行时的位置
  # 如果本机安装的 docker 把 criScoket 删除,kubernetes 会找系统默认。
 #  但是 1.24 以后的版本直接使用 containerd。继续使用 docker 安装 kubernetes 会有问题
  # 这里使用自定义的容器运行时位置 /run/containerd/containerd.sock
  criSocket: unix:///run/containerd/containerd.sock
  imagePullPolicy: IfNotPresent
  # 控制节点主机名
  name: master
  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.cn-hangzhou.aliyuncs.com/google_containers
kind: ClusterConfiguration
# kubernetes 版本号。根据自己安装的定义
kubernetesVersion: 1.29.0
networking:
  dnsDomain: cluster.local
  # service 子网
  serviceSubnet: 10.96.0.0/12
  # pod 子网
  podSubnet: 10.244.0.0/16
scheduler: {}
---
apiVersion: kubeproxy.config.k8s.io/v1alpha1
# KubeProxyConfiguration 代理模式,指定 ipvs,默认是 iptables,iptables 效率低。
# 这里需要加载 modprobe ip_vs
kind: KubeProxyConfiguration
mode: ipvs
---
apiVersion: kubelet.config.k8s.io/v1beta1
# 修改 KubeletConfiguration 驱动为 systemd
kind: KubeletConfiguration
cgroupDriver: systemd
5. 初始化 kubernetes 集群
kubeadm init --config=kubeadm.yaml --ignore-preflight-errors=SystemVerification
  • 添加 kubectl 配置文件。安装成功后会提示执行下面的命令
mkdir -p $HOME/.kube

sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config

sudo chown $(id -u):$(id -g) $HOME/.kube/config
6. 添加 node 节点
  • master 执行,生成添加节点命令和 token
root@master:~/k8s# kubeadm token create --print-join-command
kubeadm join 192.168.17.130:6443 --token v1d2bf.zkg38gi5wdktbb7d --discovery-token-ca-cert-hash sha256:8615f5a5d47405c977837c3f1088e67f91b754bc5812f599fe805848c6030db2
  • node 节点执行
kubeadm join 192.168.17.130:6443 --token v1d2bf.zkg38gi5wdktbb7d --discovery-token-ca-cert-hash sha256:8615f5a5d47405c977837c3f1088e67f91b754bc5812f599fe805848c6030db2
  • 添加成功会提示在 master 节点查看 node
kubectl get nodes
7. 修改节点标签
kubectl label nodes xxx node-role.kubernetes.io/work=work
  • 查看 node。发现节点 NotReady 是因为没有安装网络插件
root@master:~/k8s# kubectl get nodes
NAME     STATUS     ROLES           AGE     VERSION
master   NotReady   control-plane   6m56s   v1.29.15
node1    NotReady   work            2m54s   v1.29.15
node2    NotReady   work            117s    v1.29.15
  • 查看 pod 详情发现 corednspending 状态,因为没有网络
root@master:~/k8s# kubectl get pods -n kube-system -o wide
NAME                             READY   STATUS    RESTARTS   AGE     IP               NODE     NOMINATED NODE   READINESS GATES
coredns-7f8cbcb969-9j5v6         0/1     Pending   0          9m38s   <none>           <none>   <none>           <none>
coredns-7f8cbcb969-vnz5h         0/1     Pending   0          9m38s   <none>           <none>   <none>           <none>
etcd-master                      1/1     Running   0          10m     192.168.17.130   master   <none>           <none>
kube-apiserver-master            1/1     Running   0          10m     192.168.17.130   master   <none>           <none>
kube-controller-manager-master   1/1     Running   0          10m     192.168.17.130   master   <none>           <none>
kube-proxy-5hv9x                 1/1     Running   0          9m39s   192.168.17.130   master   <none>           <none>
kube-proxy-gv5g8                 1/1     Running   0          5m21s   192.168.17.132   node2    <none>           <none>
kube-proxy-smk2m                 1/1     Running   0          6m18s   192.168.17.131   node1    <none>           <none>
kube-scheduler-master            1/1     Running   0          10m     192.168.17.130   master   <none>           <none>
8. 安装网络插件
kubectl apply -f calico.yaml --server-side

注意 \color{red}{注意} 注意:如果试验环境是单网卡则不用修改配置,如果对多网卡需要在配置文件中添加下面配置

kind: DaemonSet 
  ......
  containers: 
    - name: calico-node
      ......
      env:
        ......
        name: IP_AUTODETECTION_METHOD
        valule: "interface=eth0" #这里的 eth0 是有网络的网卡
  • 配置 cidr

下载custom-resources.yaml修改里面的cidr要和kubeadm.yaml中的podSubnet 一致

https://docs.tigera.io/calico/latest/reference/installation/api#operator.tigera.io/v1.Installation
apiVersion: operator.tigera.io/v1
kind: Installation
metadata:
  name: default
spec:
  # Configures Calico networking.
  calicoNetwork:
    ipPools:
    - name: default-ipv4-ippool
      blockSize: 26
      # 修改这里
      cidr: 10.244.0.0/16
      encapsulation: VXLANCrossSubnet
      natOutgoing: Enabled
      nodeSelector: all()
---
apiVersion: operator.tigera.io/v1
kind: APIServer
metadata:
  name: default
spec: {}
kubectl apply -f custom-resources.yaml
  • 再次查看 pods
root@master:~# kubectl get pods -A
NAMESPACE          NAME                                       READY   STATUS    RESTARTS      AGE
calico-apiserver   calico-apiserver-5b54567bc5-b6nvs          1/1     Running   0             3m27s
calico-apiserver   calico-apiserver-5b54567bc5-d8zxf          1/1     Running   0             3m27s
calico-system      calico-kube-controllers-757949c4bb-7pcgf   1/1     Running   0             3m26s
calico-system      calico-node-fzx66                          1/1     Running   0             3m26s
calico-system      calico-node-srh48                          1/1     Running   0             3m26s
calico-system      calico-node-wbj7p                          1/1     Running   0             3m26s
calico-system      calico-typha-57bcd98b6c-8dn49              1/1     Running   0             3m24s
calico-system      calico-typha-57bcd98b6c-vvjpq              1/1     Running   0             3m26s
calico-system      csi-node-driver-2ltx7                      2/2     Running   0             3m26s
calico-system      csi-node-driver-r84x9                      2/2     Running   0             3m26s
calico-system      csi-node-driver-rm2bf                      2/2     Running   0             3m26s
kube-system        coredns-5f98f8d567-xl4sw                   1/1     Running   0             61m
kube-system        coredns-5f98f8d567-z7k6g                   1/1     Running   0             61m
kube-system        etcd-master                                1/1     Running   0             61m
kube-system        kube-apiserver-master                      1/1     Running   1 (42m ago)   61m
kube-system        kube-controller-manager-master             1/1     Running   1 (44m ago)   61m
kube-system        kube-proxy-bns8l                           1/1     Running   0             61m
kube-system        kube-proxy-rldwb                           1/1     Running   0             61m
kube-system        kube-proxy-wwf49                           1/1     Running   0             61m
kube-system        kube-scheduler-master                      1/1     Running   1 (44m ago)   61m
tigera-operator    tigera-operator-67fd7b8cf7-nv2jx           1/1     Running   0             3m47s
  • 再次查看那 nodes
root@master:~# kubectl get nodes
NAME     STATUS   ROLES           AGE    VERSION
master   Ready    control-plane   104m   v1.29.15
node1    Ready    work            101m   v1.29.15
node2    Ready    work            101m   v1.29.15

三、测试 pod 中网络

1. 在 master 节点创建一个 pod
kubectl run busybox --image docker.io/library/busybox:1.28  --image-pull-policy=IfNotPresent --restart=Never --rm -it busybox -- sh
2. 创建成功后会自动进入 pod ,执行 ping
/ # ping baidu.com
PING baidu.com (110.242.68.66): 56 data bytes
64 bytes from 110.242.68.66: seq=0 ttl=127 time=26.034 ms
64 bytes from 110.242.68.66: seq=1 ttl=127 time=45.559 ms
3. 测试 DNS
/ # nslookup kubernetes.default.svc.cluster.local
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local

Name:      kubernetes.default.svc.cluster.local
Address 1: 10.96.0.1 kubernetes.default.svc.cluster.local

四、/etc/sysctl.d/k8s.conf 配置说明

网络优化
参数 作用
net.ipv4.ip_forward 1 启用 IPv4 路由转发(跨节点 Pod 通信必备)
net.bridge.bridge-nf-call-iptables 1 让网桥流量经过 iptables(Service 网络依赖)
net.netfilter.nf_conntrack_max 1048576 增大连接跟踪表大小(防高并发丢包)
net.ipv4.tcp_tw_reuse 1 复用 TIME_WAIT 端口(提升 TCP 效率)
net.core.somaxconn 32768 提高 TCP 连接队列长度(防溢出)
内存与 Swap
参数 作用
vm.swappiness 0 尽量不使用 Swap(避免性能下降)
vm.overcommit_memory 1 允许内存超分配(需谨慎)
vm.panic_on_oom 0 OOM 时不触发内核崩溃
vm.transparent_hugepage never 禁用透明大页(减少内存碎片)
文件系统与 IO
参数 作用
fs.inotify.max_user_instances 524288 增加文件事件监听实例数(支持热更新)
fs.inotify.max_user_watches 524288 增加单个用户可监控的文件数
fs.file-max 2097152 提高系统全局文件句柄上限
vm.dirty_ratio 10 控制脏页写入磁盘的阈值
vm.dirty_background_ratio 5 后台刷脏页的阈值
容器与进程
参数 作用
kernel.pid_max 4194303 提高系统最大 PID 数量(支持高密度容器)
user.max_user_namespaces 15000 允许更多用户命名空间(多租户场景)

安全增强

参数 作用
kernel.kptr_restrict 1 防止内核指针泄露(安全加固)
net.ipv4.conf.all.rp_filter 0 关闭严格反向路径校验(某些 CNI 插件需要)

更多推荐