记录一次在云服务器上部署安装 K8S集群
本文记录一次在云服务器上部署安装K8S集群,安装的K8S集群版本是1.31。
本文记录一次在云服务器上部署安装K8S集群,安装的K8S集群版本是1.31。
首先说下为什么想在云服务器上部署安装K8S集群?
假设在自己笔记本电脑虚拟机上部署K8S,当你关机再开机笔记本电脑,打开虚拟机,如果没有部署高可用,你的K8S node节点会显示NotReady状态。

这时候需要你重启kubelet,或者重装网络插件,甚至都处理不好,重新部署安装node才能解决NotReady状态,这样就显得麻烦。
所以萌生了在云服务器上部署安装 K8S集群的想法。
部署安装K8S集群最少需要三台服务器,一台Master节点,两台Node节点。
我刚好有三台云服务器,是阿里云的服务器,配置均为CPU 2核、内存 2GB,满足K8S集群部署安装的最低配置要求。
部署安装k8s集群的方式有好几种,本文记录介绍通过kubeadm进行安装。下面开始部署安装:
一、部署安装K8S的前置工作
我的三台云服务器镜像统一使用CentOS 7.6 64位。
1、安装所使用到的基础软件包
三台云服务器均要安装这些用到的软件包,均执行如下命令安装:
yum install -y device-mapper-persistent-data lvm2 wget net-tools nfs-utils lrzsz gcc gcc-c++ make cmake libxml2-devel openssl-devel curl curl-devel unzip sudo libaio-devel wget vim ncurses-devel autoconf automake zlib-devel python-devel epel-release openssh-server socat ipvsadm conntrack telnet ipvsadm
2、关闭云服务器SElinux安全机制
在部署安装K8S旧版本时,需要关闭SElinux安全机制,不然会限制K8S访问系统资源。
来自DeepSeek讲解:SELinux(Security-Enhanced Linux) 是由美国国家安全局(NSA)设计并贡献给开源社区的一种**强制访问控制(MAC,Mandatory Access Control)**安全机制,集成在 Linux 内核中。它的核心目标是为系统提供更细粒度的权限控制,超越传统的 Linux 自主访问控制(DAC,Discretionary Access Control)(如用户/组权限),从而限制进程、用户和文件之间的交互,降低恶意程序或漏洞对系统的破坏风险。
三台云服务器均执行如下命令进行关闭SElinux安全机制:
sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
之后重启云服务器使之生效,重启后输入如下命令进行验证:
getenforce
如显示Disabled说明SElinux已经关闭了。
据说随着K8S增强对SElinux安全机制的支持,在K8S新版本中SElinux安全机制可以启用了。
3、关闭交换分区
来自DeepSeek讲解:Swap交换分区(交换空间) 是操作系统在硬盘上预留的一块特殊存储区域,用于扩展系统的可用内存。当物理内存(RAM)不足时,系统会将暂时不活跃的内存数据(如长时间未使用的进程)转移到Swap空间中,从而释放RAM供其他急需的程序使用。Swap本质上是一种内存扩展机制,通过“以空间换时间”避免因内存耗尽导致的系统崩溃或进程被强制终止。
swap交换分区会导致K8S运行速度变慢。
使用如下命令查看是否有交换分区:
free -h
如果有使用如下命令进行临时关闭:
swapoff -a
若要永久关闭需要编辑文件/etc/fstab将swap这行进行注释:
vim /etc/fstab
#
# /etc/fstab
# Created by anaconda on Mon Jan 13 02:47:33 2025
#
# Accessible filesystems, by reference, are maintained under '/dev/disk/'.
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info.
#
# After editing this file, run 'systemctl daemon-reload' to update systemd
# units generated from this file.
#
UUID=XXXXXXX-XXXX-XXX-XXXX-XXXXXXXX / xfs defaults 0 0
UUID=XXXX-XXXX /boot/efi vfat defaults,uid=0,gid=0,umask=077,shortname=winnt 0 2
#/dev/mapper/centos-swap swap swap defaults 0 0
我的三台云服务器均没有交换分区,就不用做如上操作。
4、修改云服务器主机名
我设定阿里云的这台云服务器为Master节点,执行以下命令修改:
hostnamectl set-hostname master && bash
设定另外两个腾讯云服务器和华为云服务器为Node节点,分别执行以下命令修改:
hostnamectl set-hostname node1 && bash
hostnamectl set-hostname node2 && bash
5、配置云服务器hosts文件
云服务器一般有两个地址:公网地址和私网地址,如下表所示:
| 云服务器 | 主机名 | 公网地址 | 私网地址 |
|---|---|---|---|
| 阿里云1 | master | 8.137.13.XXX | 172.23.170.XXX |
| 阿里云2 | node1 | 47.109.146.XXX | 172.23.170.XXX |
| 阿里云3 | node2 | 8.137.156.XXX | 172.23.170.XXX |
上述表格中公网地址和私网地址为示例,IP为瞎编的,如有雷同纯属巧合。
我的三台云服务器均使用同一个交换机,私网地址在一个网段上。
编辑云服务器上/etc/hosts文件进行配置:
vim /etc/hosts
其中master节点这台编辑如下:
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
172.23.170.XXX master
47.109.146.XXX node1
8.137.156.XXX node2
其中node1节点这台编辑如下:
127.0.0.1 localhost.localdomain localhost
127.0.0.1 localhost4.localdomain4 localhost4
::1 localhost.localdomain localhost
::1 localhost6.localdomain6 localhost6
8.137.13.XXX master
172.23.170.XXX node1
8.137.156.XXX node2
其中node2节点这台编辑如下:
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
127.0.0.1 hcss-ecs-7ebb hcss-ecs-7ebb
8.137.13.XXX master
47.109.146.XXX node1
172.23.170.XXX node2
6、设置IP映射打通内网(可选)
来自DeepSeek讲解:IP映射 是指将一个IP地址(或端口)映射到另一个IP地址(或端口)的网络技术,通常用于流量重定向、负载均衡或隐藏真实服务器地址。
常见的实现方式包括 DNAT(Destination Network Address Translation,目的地址转换),它修改数据包的目的地址,使流量被转发到指定目标。
这个步骤要根据你云服务器实际情况来定,是否需要做IP映射打通内网。
我在两个node节点上设置针对master节点的IP映射:
(1)node1节点设置IP映射
在node1节点上输入如下命令进行设置:
iptables -t nat -A OUTPUT -d 172.23.170.XXX -j DNAT --to-destination 8.137.13.XXX
#iptables -t nat -A OUTPUT -d master内网IP -j DNAT --to-destination master外网IP
(2)node2节点设置IP映射
在node2节点上输入如下命令进行设置:
iptables -t nat -A OUTPUT -d 172.23.170.XXX -j DNAT --to-destination 8.137.13.XXX
#iptables -t nat -A OUTPUT -d master内网IP -j DNAT --to-destination master外网IP
7、配置云服务器之间免密登录
来自DeepSeek讲解:配置云服务器之间免密登录,指的是在多台云服务器之间设置 SSH 密钥认证,使得服务器之间通过 SSH 协议互相访问时无需手动输入密码。
配置云服务器之间的免密登录主要是为了方便,不然每次传文件之类的都要输入密码登录。
对于免密登录如果感兴趣可参看我的另一篇文章 https://blog.csdn.net/qq_33765205/article/details/118336346,基于RSA算法进行的免密登录操作。
下面开始操作配置免密登录:
(1)master节点配置免密登录
在master节点上输入如下命令:
ssh-keygen
一直按回车确认,之后输入如下命令将私钥文件拷贝至node1节点上:
ssh-copy-id node1
输入如下命令将私钥文件拷贝至node2节点上:
ssh-copy-id node2
Master节点配置免密登录就操作完成。两个Node节点也如此操作。
(2)node1节点配置免密登录
在node1节点上输入如下命令:
ssh-keygen
一直按回车确认,之后输入如下命令将私钥文件拷贝至master节点上:
ssh-copy-id master
输入如下命令将私钥文件拷贝至node2节点上:
ssh-copy-id node2
(3)node2节点配置免密登录
在node2节点上输入如下命令:
ssh-keygen
一直按回车确认,之后输入如下命令将私钥文件拷贝至master节点上:
ssh-copy-id master
输入如下命令将私钥文件拷贝至node1节点上:
ssh-copy-id node1
8、修改主机模块加载配置网络插件
Master节点和两个Node节点均执行如下命令,将 br_netfilter 模块添加到主机内核中:
modprobe br_netfilter
之后新建k8s.conf文件编辑如下:
vim /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
之后执行如下命令:
sysctl -p /etc/sysctl.d/k8s.conf
9、防火墙放行相关端口
K8S集群所使用到的端口如下表所示:
| K8S服务 | 端口类型 | 所使用到的端口号 |
|---|---|---|
| Kube-apiserver | TCP | 6443 |
| etcd datastore | TCP | 2379、2380 |
| Kube-controller-manager | TCP | 10257 |
| Kube-scheduler | TCP | 10259 |
| Kubelet | TCP | 10250 |
| Kube-proxy | TCP | 在1024到65535之间 |
| Calico Networking(BGP) | TCP | 179、5743 |
| Calico Networking(VXLAN) | UDP | 4789 |
| HTTPS | TCP | 443 |
归纳上述端口为:
TCP:6443,2379,2380,10257,10259,10250,1024-65535,179,5743,443
UPD:4789
打开云服务器控制台页面中的安全组进行配置,在入方向放行K8S所使用的相关端口,如下图所示:

需要注意的是,如果你不是用的云服务器,是自己本地的虚拟机练习部署搭建,建议你可以直接把防火墙关闭。
输入如下命令关闭Firewalld防火墙:
systemctl stop firewalld && systemctl disable firewalld
如果你在本地生产环境,不能关闭Firewalld防火墙,可以配置防火墙将上述K8S集群所使用到的端口放开。
例如放开TCP端口6643,输入如下命令:
firewall-cmd --zone=public --add-port=6443/tcp --permanent
例如放开UCP端口6643,输入如下命令:
firewall-cmd --zone=public --add-port=4789/udp --permanent
配置完之后执行如下命令进行防火墙规则加载:
firewall-cmd --reload
对于Firewalld防火墙更多的使用配置,可参看我的公众号推文 https://mp.weixin.qq.com/s/vWfR10N4mMlOHma7l4BE2g
10、配置阿里云的repo源
使用如下命令配置docker的阿里云源,输入如下命令配置:
yum install yum-utils -y
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
11、云服务器时间同步配置(可选)
进行时间同步配置,使得K8S集群节点时间保持一致。
云服务器上通常时间一致,但也可以配置时间同步。
首先在master、node1和node2三个节点中安装chrony软件服务,执行如下命令:
yum -y install chrony
设置开机自启动,执行如下命令:
systemctl enable chronyd --now
编辑/etc/chrony.conf文件设置时间服务器:
vim /etc/chrony.conf
# Enable kernel RTC synchronization.
rtcsync
# In first three updates step the system clock instead of slew
# if the adjustment is larger than 10 seconds.
makestep 10 3
# Allow NTP client access from local network.
#allow 192.168/16
# Listen for commands only on localhost.
bindcmdaddress 127.0.0.1
bindcmdaddress ::1
# Serve time even if not synchronized to any NTP server.
#local stratum 10
# Disable logging of client accesses.
noclientlog
# Send a message to syslog if a clock adjustment is larger than 0.5 seconds.
logchange 0.5
logdir /var/log/chrony
#log measurements statistics tracking
server ntp1.aliyun.com iburst
server ntp2.aliyun.com iburst
server ntp1.tencent.com iburst
server ntp2.tencent.com iburst
可以写个计划任务定时同步下时间,执行以下命令:
crontab -e
* * * * * /usr/bin/systemctl restart chronyd
配置好之后还可以查看下master、node1和node2三个节点时间是否一致:

以上就是所有前置工作,不仅是部署安装K8S集群,部署其他集群的前置工作如部署Hadoop集群也类似之处,也可以参看。
二、安装容器运行时containerd和docker
1、安装containerd
来自DeepSeek讲解:containerd 是一个开源的容器运行时(Container Runtime),专注于管理容器生命周期(如创建、启动、停止、删除容器)和镜像管理(如下载、存储镜像)。它是 Docker 生态系统的一部分,但设计为更轻量级、模块化的核心组件。
这里装的是1.6.22这个版本,安装执行如下命令:
yum install containerd.io-1.6.22* -y
之后修改配置文件,输入如下命令进入/etc/containerd目录下:
cd /etc/containerd
修改目录下的config.toml这个文件,修改之后如下所示:
disabled_plugins = []
imports = []
oom_score = 0
plugin_dir = ""
required_plugins = []
root = "/var/lib/containerd"
state = "/run/containerd"
temp = ""
version = 2
[cgroup]
path = ""
[debug]
address = ""
format = ""
gid = 0
level = ""
uid = 0
[grpc]
address = "/run/containerd/containerd.sock"
gid = 0
max_recv_message_size = 16777216
max_send_message_size = 16777216
tcp_address = ""
tcp_tls_ca = ""
tcp_tls_cert = ""
tcp_tls_key = ""
uid = 0
[metrics]
address = ""
grpc_histogram = false
[plugins]
[plugins."io.containerd.gc.v1.scheduler"]
deletion_threshold = 0
mutation_threshold = 100
pause_threshold = 0.02
schedule_delay = "0s"
startup_delay = "100ms"
[plugins."io.containerd.grpc.v1.cri"]
device_ownership_from_security_context = false
disable_apparmor = false
disable_cgroup = false
disable_hugetlb_controller = true
disable_proc_mount = false
disable_tcp_service = true
enable_selinux = false
enable_tls_streaming = false
enable_unprivileged_icmp = false
enable_unprivileged_ports = false
ignore_image_defined_volumes = false
max_concurrent_downloads = 3
max_container_log_line_size = 16384
netns_mounts_under_state_dir = false
restrict_oom_score_adj = false
sandbox_image = "registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.7"
selinux_category_range = 1024
stats_collect_period = 10
stream_idle_timeout = "4h0m0s"
stream_server_address = "127.0.0.1"
stream_server_port = "0"
systemd_cgroup = false
tolerate_missing_hugetlb_controller = true
unset_seccomp_profile = ""
[plugins."io.containerd.grpc.v1.cri".cni]
bin_dir = "/opt/cni/bin"
conf_dir = "/etc/cni/net.d"
conf_template = ""
ip_pref = ""
max_conf_num = 1
[plugins."io.containerd.grpc.v1.cri".containerd]
default_runtime_name = "runc"
disable_snapshot_annotations = true
discard_unpacked_layers = false
ignore_rdt_not_enabled_errors = false
no_pivot = false
snapshotter = "overlayfs"
[plugins."io.containerd.grpc.v1.cri".containerd.default_runtime]
base_runtime_spec = ""
cni_conf_dir = ""
cni_max_conf_num = 0
container_annotations = []
pod_annotations = []
privileged_without_host_devices = false
runtime_engine = ""
runtime_path = ""
runtime_root = ""
runtime_type = ""
[plugins."io.containerd.grpc.v1.cri".containerd.default_runtime.options]
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes]
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
base_runtime_spec = ""
cni_conf_dir = ""
cni_max_conf_num = 0
container_annotations = []
pod_annotations = []
privileged_without_host_devices = false
runtime_engine = ""
runtime_path = ""
runtime_root = ""
runtime_type = "io.containerd.runc.v2"
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
BinaryName = ""
CriuImagePath = ""
CriuPath = ""
CriuWorkPath = ""
IoGid = 0
IoUid = 0
NoNewKeyring = false
NoPivotRoot = false
Root = ""
ShimCgroup = ""
SystemdCgroup = true
[plugins."io.containerd.grpc.v1.cri".containerd.untrusted_workload_runtime]
base_runtime_spec = ""
cni_conf_dir = ""
cni_max_conf_num = 0
container_annotations = []
pod_annotations = []
privileged_without_host_devices = false
runtime_engine = ""
runtime_path = ""
runtime_root = ""
runtime_type = ""
[plugins."io.containerd.grpc.v1.cri".containerd.untrusted_workload_runtime.options]
[plugins."io.containerd.grpc.v1.cri".image_decryption]
key_model = "node"
[plugins."io.containerd.grpc.v1.cri".registry]
config_path = ""
[plugins."io.containerd.grpc.v1.cri".registry.auths]
[plugins."io.containerd.grpc.v1.cri".registry.configs]
[plugins."io.containerd.grpc.v1.cri".registry.configs."你的Harbor的IP地址".tls]
insecure_skip_verify = true
[plugins."io.containerd.grpc.v1.cri".registry.configs."你的Harbor的IP地址".auth]
username = "你的Harbor的账号名"
password = "你的Harbor的密码"
[plugins."io.containerd.grpc.v1.cri".registry.headers]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."你的Harbor的IP地址"]
endpoint = ["https://你的Harbor的IP地址:443"]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
endpoint = ["https://docker-0.unsee.tech","https://docker-cf.registry.cyou","https://docker.1panel.live","https://registry.docker-cn.com"]
[plugins."io.containerd.grpc.v1.cri".x509_key_pair_streaming]
tls_cert_file = ""
tls_key_file = ""
[plugins."io.containerd.internal.v1.opt"]
path = "/opt/containerd"
[plugins."io.containerd.internal.v1.restart"]
interval = "10s"
[plugins."io.containerd.internal.v1.tracing"]
sampling_ratio = 1.0
service_name = "containerd"
[plugins."io.containerd.metadata.v1.bolt"]
content_sharing_policy = "shared"
[plugins."io.containerd.monitor.v1.cgroups"]
no_prometheus = false
[plugins."io.containerd.runtime.v1.linux"]
no_shim = false
runtime = "runc"
runtime_root = ""
shim = "containerd-shim"
shim_debug = false
[plugins."io.containerd.runtime.v2.task"]
platforms = ["linux/amd64"]
sched_core = false
[plugins."io.containerd.service.v1.diff-service"]
default = ["walking"]
[plugins."io.containerd.service.v1.tasks-service"]
rdt_config_file = ""
[plugins."io.containerd.snapshotter.v1.aufs"]
root_path = ""
[plugins."io.containerd.snapshotter.v1.btrfs"]
root_path = ""
[plugins."io.containerd.snapshotter.v1.devmapper"]
async_remove = false
base_image_size = ""
discard_blocks = false
fs_options = ""
fs_type = ""
pool_name = ""
root_path = ""
[plugins."io.containerd.snapshotter.v1.native"]
root_path = ""
[plugins."io.containerd.snapshotter.v1.overlayfs"]
root_path = ""
upperdir_label = false
[plugins."io.containerd.snapshotter.v1.zfs"]
root_path = ""
[plugins."io.containerd.tracing.processor.v1.otlp"]
endpoint = ""
insecure = false
protocol = ""
[proxy_plugins]
[stream_processors]
[stream_processors."io.containerd.ocicrypt.decoder.v1.tar"]
accepts = ["application/vnd.oci.image.layer.v1.tar+encrypted"]
args = ["--decryption-keys-path", "/etc/containerd/ocicrypt/keys"]
env = ["OCICRYPT_KEYPROVIDER_CONFIG=/etc/containerd/ocicrypt/ocicrypt_keyprovider.conf"]
path = "ctd-decoder"
returns = "application/vnd.oci.image.layer.v1.tar"
[stream_processors."io.containerd.ocicrypt.decoder.v1.tar.gzip"]
accepts = ["application/vnd.oci.image.layer.v1.tar+gzip+encrypted"]
args = ["--decryption-keys-path", "/etc/containerd/ocicrypt/keys"]
env = ["OCICRYPT_KEYPROVIDER_CONFIG=/etc/containerd/ocicrypt/ocicrypt_keyprovider.conf"]
path = "ctd-decoder"
returns = "application/vnd.oci.image.layer.v1.tar+gzip"
[timeouts]
"io.containerd.timeout.bolt.open" = "0s"
"io.containerd.timeout.shim.cleanup" = "5s"
"io.containerd.timeout.shim.load" = "5s"
"io.containerd.timeout.shim.shutdown" = "3s"
"io.containerd.timeout.task.state" = "2s"
[ttrpc]
address = ""
gid = 0
uid = 0
修改的内容为:
(1)将SystemdCgroup = false改为SystemdCgroup = true。
(2)将sandbox_image的源改为sandbox_image = "registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.7"。
(3)加入Harbor仓库地址,注意缩进:
[plugins."io.containerd.grpc.v1.cri".registry.auths]
[plugins."io.containerd.grpc.v1.cri".registry.configs]
[plugins."io.containerd.grpc.v1.cri".registry.configs."你的Harbor的IP地址".tls]
insecure_skip_verify = true
[plugins."io.containerd.grpc.v1.cri".registry.configs."你的Harbor的IP地址".auth]
username = "你的Harbor的账号名"
password = "你的Harbor的密码"
[plugins."io.containerd.grpc.v1.cri".registry.headers]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."你的Harbor的IP地址"]
endpoint = ["https://你的Harbor的IP地址:443"]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
endpoint = ["https://vh3bm52y.mirror.aliyuncs.com","https://registry.docker-cn.com"]
之后输入如下命令启动containerd:
systemctl start containerd && systemctl enable containerd
查看的版本使用如下命令:
ctr version
2、安装docker
来自DeepSeek讲解:Docker 是一个开源的容器化平台,用于开发、部署和运行应用程序。它通过将应用程序及其依赖项打包到一个轻量级、可移植的“容器”中,实现了应用在不同环境(如开发、测试、生产)中的一致性运行。
安装与适配的docker,这里安装的是24.0.6版本,执行如下命令进行安装:
yum install docker-ce-24.0.6 -y
执行如下命令启动docker并设置开机自启动:
systemctl start docker && systemctl enable docker
之后配置docker镜像加速器,输入如下命令进行编辑:
tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": [
"https://docker-0.unsee.tech",
"https://docker-cf.registry.cyou",
"https://docker.1panel.live"
]
}
EOF
三、安装K8S
1、安装kubelet
在master和node节点上都要安装kubelet。
首先进行配置安装K8S组件用到的源,输入如下命令:
cat > /etc/yum.repos.d/kubernetes.repo <<EOF
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.31/rpm/
enabled=1
gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.31/rpm/repodata/repomd.xml.key
EOF
之后运行如下命令:
yum clean all && yum makecache
接下来安装kubelet,这次安装的版本为1.31.3,执行如下命令:
yum install -y kubelet-1.31.3 kubeadm-1.31.3 kubectl-1.31.3
将kubelet设置为开机自启动,执行如下命令:
systemctl enable kubelet
2、在master节点里安装K8S
在master节点上执行如下命令:
kubeadm config print init-defaults > kubeadm.yaml
之后输入如下命令修改文件:
vim kubeadm.yaml
apiVersion: kubeadm.k8s.io/v1beta4
bootstrapTokens:
- groups:
- system:bootstrappers:kubeadm:default-node-token
token: abcdef.0123456789abcdef
ttl: 24h0m0s
usages:
- signing
- authentication
kind: InitConfiguration
localAPIEndpoint:
advertiseAddress: 172.23.170.XXX #你的master节点的IP
bindPort: 6443
nodeRegistration:
criSocket: unix:///run/containerd/containerd.sock
imagePullPolicy: IfNotPresent
imagePullSerial: true
name: master
taints: null
timeouts:
controlPlaneComponentHealthCheck: 4m0s
discovery: 5m0s
etcdAPICall: 2m0s
kubeletHealthCheck: 4m0s
kubernetesAPICall: 1m0s
tlsBootstrap: 5m0s
upgradeManifests: 5m0s
---
apiServer: {}
apiVersion: kubeadm.k8s.io/v1beta4
caCertificateValidityPeriod: 87600h0m0s
certificateValidityPeriod: 8760h0m0s
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
controllerManager: {}
dns: {}
encryptionAlgorithm: RSA-2048
etcd:
local:
dataDir: /var/lib/etcd
imageRepository: registry.cn-hangzhou.aliyuncs.com/google_containers
kind: ClusterConfiguration
kubernetesVersion: 1.31.0
networking:
dnsDomain: cluster.local
serviceSubnet: 10.96.0.0/12
podSubnet: 10.244.0.0/16
proxy: {}
scheduler: {}
---
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: ipvs
---
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
cgroupDriver: systemd
需要修改的地方有:
(1)将advertiseAddress这项后面的IP修改为你的控制节点的IP,注意是云服务器内网IP。
(2)在name这里要填写自己的主机名,我这里的主机名是master。
(3)criSocket项后面的位置,需要查看本机的文件所在地址进行填写,例如我的这个文件在/run/containerd/containerd.sock这。
(4)需要指定pod网段,增加podSubnet: 10.244.0.0/16这个内容。
(5)将imageRepository改成国内的镜像仓库,例如改成registry.cn-hangzhou.aliyuncs.com/google_containers。
(6)在最后追加如下行内容:
---
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: ipvs
---
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
cgroupDriver: systemd
特别注意:上述的6个修改的内容一定要认真仔细修改,不可以漏项,不然后面会出错。其次,这里的kubeadm.yaml一定是前面命令生成的,然后根据生成的进行修改。而不是新建一个把我上面的复制或覆盖进去。
之后在master节点里执行如下命令安装K8S:
kubeadm init --config=kubeadm.yaml --ignore-preflight-errors=SystemVerification
如果报错提示云服务器使用内存不足,例如:
[init] Using Kubernetes version: v1.31.0
[preflight] Running pre-flight checks
error execution phase preflight: [preflight] Some fatal errors occurred:
[ERROR Mem]: the system RAM (1675 MB) is less than the minimum 1700 MB
[preflight] If you know what you are doing, you can make a check non-fatal with `--ignore-preflight-errors=...`
可以通过加上 --ignore-preflight-errors=Mem 参数忽略内存检查错误:
kubeadm init --config=kubeadm.yaml --ignore-preflight-errors=Mem
之后根据输出内容提示执行命令:
mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config
之后运行如下命令验证:
kubectl get nodes
4、添加node节点
首先在master节点上运行如下命令:
kubeadm token create --print-join-command
之后在node1节点上执行上述命令的反馈结果,例如:
kubeadm join XXX.XXX.XXX.XX:6443 --token vulvta.XXXXXXXXX --discovery-token-ca-cert-hash sha256:XXXXXXXXX --ignore-preflight-errors=SystemVerification
这样就将node1节点加入进来了。
node2节点也是一样的操作。
在node2节点上执行上述命令的反馈结果,例如:
kubeadm join XXX.XXX.XXX.XX:6443 --token vulvta.XXXXXXXXX --discovery-token-ca-cert-hash sha256:XXXXXXXXX --ignore-preflight-errors=SystemVerification
需要在反馈结果后面加上--ignore-preflight-errors=SystemVerification,这样node2节点也加入进来了。
如果报错,可在反馈结果后面加上--ignore-preflight-errors=SystemVerification。
然后,可以使用如下命令将node节点打标签为work。
kubectl label nodes node1 node-role.kubernetes.io/work=work
四、安装Calico网络插件
来自DeepSeek讲解:Calico 是一个开源的容器网络解决方案,专为 Kubernetes、OpenShift、OpenStack 等云原生平台设计。它提供了高性能、高可扩展性和灵活的网络策略管理能力,支持容器间的安全通信和网络隔离。
如何安装Calico可参看官网说明 Installing on on-premises deployments | Calico Documentation
在官网安装Calico那选择Manifest,如下图所示,根据官网上描述的进行安装:

首先运行官网上的这个命令:
curl https://raw.githubusercontent.com/projectcalico/calico/v3.29.3/manifests/calico.yaml -O
之后修改calico.yaml这个文件。
vim calico.yaml
文件内容太多了,通过vim编辑器定位修改的地方。
输入 / 进入查找模式,然后输入要查找的文本,这里是查找value:这个,如下图所示:

在图中位置加入修改的内容:
- name: IP_AUTODETECTION_METHOD
value: "interface=eth0"
其中,interface= 后面的值为你的云服务的网卡名称。
例如我的云服务的网卡名称是eth0,所以写成 value: "interface=eth0"。
之后在master节点运行如下命令:
kubectl apply -f calico.yaml
然后执行如下命令验证,如果状态都为Ready,Calico网络插件安装就成功了:
kubectl get nodes

五、安装Dashboard监控集群资源状态和性能(可选)
Dashboard是网页端图形可视化监控集群资源状态和性能,可装可不装。
首先下载官方提供的YAML文件,用于部署Dashboard,执行如下命令:
wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.7.0/aio/deploy/recommended.yaml
之后修改recommended.yaml这个文件,执行如下命令:
vim recommended.yaml
在spec里加上type: NodePort,如下图所示:

之后执行如下命令进行部署安装Dashboard:
kubectl apply -f recommended.yaml
之后通过执行如下命令查看端口:
kubectl get svc -n kubernetes-dashboard

比如我的端口是32032,要打开云服务器控制台页面中的安全组进行配置,将端口32032放开。
之后在网页输入 https:// 8.137.13.XXX:32032,其中8.137.13.XXX是master节点地址,32032是端口。
如果网页打不开,在网页的任意位置,直接键盘敲入这11个字符:thisisunsafe,可以直接跳过安全报错进入页面。
之后创建相应的Token登入即可使用。
至此,云服务器上部署安装 K8S集群基本完成了。大家如果觉得K8S复杂,还可以参看我另一篇文章K3S的安装 https://blog.csdn.net/qq_33765205/article/details/139699106 。
更多推荐



所有评论(0)