Kubernetes快速搭建

搭建K8s环境平台规划

架构设计对比

架构类型优点缺点适用场景
单Master节点部署简单,资源消耗低存在单点故障风险,扩展性差测试环境、小规模开发环境
多Master节点高可用、无单点故障,支持大规模集群部署复杂,资源消耗高生产环境、中大型企业级应用

多Master节点核心组件高可用设计

  • API Server高可用:通过负载均衡器(如Nginx、HAProxy)暴露VIP,流量分发到多个Master节点的API Server。
  • etcd集群:部署3/5节点etcd集群,确保数据一致性和高可用。
  • Controller Manager与Scheduler:以 Leader Election 模式运行,同一时间只有一个实例生效

服务器硬件配置要求

测试环境(非生产)

节点类型CPU内存硬盘数量说明
Master节点2核4GB20GB1可运行核心组件(API Server、etcd等)
Worker节点4核8GB40GB≥2运行业务容器

生产环境(最低要求)

节点类型CPU内存硬盘数量说明
Master节点4核8GB100GB≥3(奇数)需分离etcd与Master节点(若etcd独立部署)
Worker节点8核16GB100GB+≥3根据业务负载动态扩展

搭建K8s集群部署方式-Kubeadm

前置知识点

目前生产部署Kubernetes集群主要有两种方式

Kubeadm vs 二进制部署对比

部署方式优点缺点适用场景
Kubeadm官方推荐,自动化程度高,适合快速搭建屏蔽底层细节,定制化能力有限中小规模集群、快速验证场景
二进制部署灵活可控,适合深度定制和优化部署复杂,需手动配置各组件和依赖生产环境、大规模定制化需求

kubeadm是官方社区推出的一个用于快速部署kubernetes集群的工具,这个工具能通过两条指令完成一个kubernetes集群的部署

  1. 创建一个Master节点kubeadm inito
  2. 将Node 节点加入到当前集群中kubeadm join <Master节点的IP和端口>

核心特性

  • 自动化生成证书、配置文件及服务单元(systemd)。
  • 支持一键初始化Master节点和加入Worker节点。
  • 默认集成CoreDNS、kube-proxy等核心插件。

环境规划与准备

角色IP地址主机名资源配置
Master192.168.56.101k8smaster4CPU/4GB/20GB+
Node1192.168.56.102k8snode14CPU/8GB/40GB+
Node2192.168.56.103k8snode24CPU/8GB/40GB+

系统环境要求

  • 操作系统:CentOS 7.x x86_64
  • 硬件配置:
    • 最小配置:2核CPU/2GB内存/30GB硬盘
    • 生产推荐:4核CPU+/8GB内存+/100GB硬盘+
  • 网络要求:
    • 所有节点间网络互通
    • 可访问外网(或已配置本地镜像仓库)
  • 必须配置:
    • 关闭防火墙
    • 禁用SELinux
    • 关闭Swap分区

系统初始化配置(所有节点执行)

脚本内容包括:初始化配置、安装Docker、安装Kubernetes组件kubelet、kubeadm、kubectl

sudo ./setup_k8s.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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#!/bin/bash
# ------------------------- 初始化配置 -------------------------
# 定义执行命令并处理结果的函数
run_cmd() {
local cmd="$1"
local success_msg="$2"
local failure_msg="${3:-命令执行失败,请检查。}"

echo "正在执行:$cmd"
eval "$cmd" 2>/dev/null
if [ $? -eq 0 ]; then
echo -e "\e[32m成功: $success_msg\e[0m" # 绿色表示成功
else
echo -e "\e[31m失败: $failure_msg\e[0m" # 红色表示失败
exit 1
fi
}

# 关闭防火墙
run_cmd "systemctl stop firewalld && systemctl disable firewalld" \
"防火墙已成功关闭并禁用。"

# 禁用 SELinux
run_cmd "setenforce 0" "SELinux 已临时禁用。" "临时禁用 SELinux 失败,请检查权限。"
run_cmd "sed -i 's/^SELINUX=enforcing$/SELINUX=disabled/' /etc/selinux/config" \
"SELinux 已永久禁用,重启后生效。" "永久禁用 SELinux 失败,请检查权限或配置文件。"

# 关闭 Swap
run_cmd "swapoff -a" "Swap 已临时关闭。" "临时关闭 Swap 失败,请检查权限。"
run_cmd "sed -ri '/swap/s/^/#/' /etc/fstab" \
"Swap 已永久关闭,重启后生效。" "永久关闭 Swap 失败,请检查权限或配置文件。"

# 设置主机名(用户输入)
read -p "请输入当前主机的名称(例如 k8smaster/k8snode1/k8snode2): " hostname
if [ -n "$hostname" ]; then
run_cmd "hostnamectl set-hostname $hostname" \
"主机名已设置为: $hostname 需重新建立连接" "设置主机名失败,请检查权限。"
else
echo -e "\e[33m⚠️ 主机名不能为空,跳过设置。\e[0m" # 黄色表示警告
fi

# 添加主机解析
cat >> /etc/hosts <<EOF
192.168.56.101 k8smaster
192.168.56.102 k8snode1
192.168.56.103 k8snode2
EOF
echo -e "\e[32m成功: 主机解析已添加到 /etc/hosts 文件。\e[0m"

# 加载内核模块
run_cmd "cat > /etc/sysctl.d/k8s.conf <<EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF" "内核模块配置文件已创建。" "创建内核模块配置文件失败,请检查权限。"
run_cmd "sysctl --system" "内核参数已生效。" "应用内核参数失败,请检查配置。"

# 配置阿里云YUM源
run_cmd "curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo" \
"配置 阿里云 YUM源成功。" "配置 阿里云 YUM源失败。"

# 时间同步
run_cmd "yum install -y chrony" "Chrony安装成功。" "Chrony安装失败。"
run_cmd "systemctl enable chronyd && systemctl start chronyd" "Chrony服务启动成功。" "Chrony服务启动失败。"
run_cmd "chronyc sources" "时间同步状态验证成功。" "时间同步状态验证失败。"

# ------------------------- 安装 Docker -------------------------
echo -e "\n\e[34m开始安装 Docker...\e[0m" # 蓝色提示阶段

# 配置阿里云 Docker 源
run_cmd "yum install -y yum-utils wget" "已安装 yum-utils wget。" "安装 yum-utils wget失败。"
run_cmd "yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo" \
"Docker 源已配置成功。" "配置 Docker 源失败。"

# 旧版本Docker清理
run_cmd "yum remove -y docker* containerd.io" "旧版本Docker清理完成。" "旧版本Docker清理失败。"

# 安装指定版本的 Docker
run_cmd "yum install -y docker-ce-20.10.23 docker-ce-cli-20.10.23 containerd.io" \
"Docker 已安装成功。" "安装 Docker 失败,请检查版本是否存在。"

# 配置 Docker 镜像加速
run_cmd "mkdir -p /etc/docker" "Docker 配置目录已创建。" "创建目录失败。"
run_cmd "cat > /etc/docker/daemon.json <<EOF
{
\"log-driver\": \"json-file\",
\"log-opts\": {
\"max-size\": \"100m\",
\"max-file\": \"1\"
},
\"exec-opts\": [\"native.cgroupdriver=systemd\"],
\"registry-mirrors\": [
\"https://x9r52uz5.mirror.aliyuncs.com\",
\"https://dockerhub.icu\",
\"https://docker.chenby.cn\",
\"https://docker.1panel.live\",
\"https://docker.awsl9527.cn\",
\"https://docker.anyhub.us.kg\",
\"https://dhub.kubesre.xyz\"
]
}
EOF" "Docker 镜像加速配置完成。" "配置镜像加速失败。"

# 启动 Docker 服务
run_cmd "systemctl enable docker && systemctl start docker" \
"Docker 服务已启用并启动。" "Docker 服务启动失败。"

# ------------------------- 安装 Kubernetes -------------------------
echo -e "\n\e[34m开始安装 Kubernetes...\e[0m" # 蓝色提示阶段

# 配置阿里云 Kubernetes 源
run_cmd "cat > /etc/yum.repos.d/kubernetes.repo <<EOF
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg
EOF" "Kubernetes 源已配置成功。" "配置 Kubernetes 源失败。"

# 安装指定版本的 Kubernetes 组件
run_cmd "yum install -y kubelet-1.23.9 kubeadm-1.23.9 kubectl-1.23.9" \
"Kubernetes 组件已安装成功。" "安装 Kubernetes 组件失败。"

# 启用 kubelet 服务
run_cmd "systemctl enable kubelet" "kubelet 服务已启用。" "启用 kubelet 失败。"

echo -e "\n\e[32m所有配置已完成,建议重启系统以确保更改生效!\e[0m"

Master节点初始化

初始化控制平面

1
2
3
4
5
6
kubeadm init \
--apiserver-advertise-address=192.168.56.101 \
--image-repository registry.aliyuncs.com/google_containers \
--kubernetes-version v1.23.9 \
--service-cidr=10.96.0.0/12 \
--pod-network-cidr=10.244.0.0/16

由于默认拉取镜像地址k8s.gcr.io国内无法访问,这里指定阿里云镜像仓库地址。

安装好以后会出现以下内容,中文为我手动翻译

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
您的Kubernetes控制平面已成功初始化!
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

或者,如果您是root用户,可以运行:
Alternatively, if you are the root user, you can run:

export KUBECONFIG=/etc/kubernetes/admin.conf

现在,您应该将pod网络部署到集群。
使用以下列出的选项之一运行“kubectl apply -f [podnetwork].yaml”:https://kubernetes.io/docs/concepts/cluster-administration/addons/
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/

然后,您可以通过以root身份在每个工作节点上运行以下命令来加入任意数量的工作节点:
Then you can join any number of worker nodes by running the following on each as root:

kubeadm join 192.168.56.101:6443 --token y99zkx.bh0hvsssdwnexcef \
--discovery-token-ca-cert-hash sha256:2467b7096abe9fcac0b1b39b19ec2d7681e1317c04a0c69c19a7500db2cf4101

配置kubectl

1
2
3
4
5
6
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

# 验证节点状态
kubectl get nodes

Worker节点加入集群

获取加入命令

1
2
# 在Master节点执行
kubeadm token create --print-join-command

节点加入(Node节点执行)

1
2
kubeadm join 192.168.56.101:6443 --token <token> \
--discovery-token-ca-cert-hash sha256:<hash>

token有时效性,token失效记得重新获取加入命令

CNI网络插件部署

部署Flannel网络

1
2
3
4
5
6
7
8
9
10
11
# 下载并替换镜像源
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

# 验证部署 Flannel Pod 部署在 kube-flannel 命名空间中
kubectl get pods -n kube-flannel

# 结果
NAME READY STATUS RESTARTS AGE
kube-flannel-ds-bgc4g 1/1 Running 0 66m
kube-flannel-ds-dp4z9 1/1 Running 0 66m
kube-flannel-ds-mcgnh 1/1 Running 0 66m

如默认镜像地址无法访问,wget下载到本地sed命令修改kube-flannel.yml为docker hub镜像仓库,在应用配置kubectl apply -f kube-flannel.yml

集群功能验证

创建测试应用

1
2
3
4
5
6
7
8
9
10
# 部署Nginx
kubectl create deployment nginx --image=nginx:alpine

# 暴露服务
kubectl expose deployment nginx --port=80 --type=NodePort

# 查看资源状态
kubectl get pod,svc -o wide
# 结果:比如80:31061 NODE_PORT就等于31061
service/nginx NodePort 10.109.142.81 <none> 80:31061/TCP 3m17s app=nginx

访问验证

1
2
3
4
5
6
7
# 获取NodePort端口
NODE_PORT=$(kubectl get svc nginx -o jsonpath='{.spec.ports[0].nodePort}')

# 访问测试(使用任一节点IP)
curl http://192.168.56.101:$NODE_PORT
curl http://192.168.56.102:$NODE_PORT
curl http://192.168.56.103:$NODE_PORT

关键注意事项

  1. Token有效期管理

    • 默认Token 24小时有效,过期后需重新生成:
    1
    kubeadm token create --print-join-command
  2. 网络插件选择

  • 生产环境建议根据需求选择Calico/Cilium等CNI插件
  1. 版本兼容性
  • 确保Docker/Kubernetes/CNI插件版本兼容
  1. 节点通信
  • 确保所有节点间6443/10250等端口互通
  1. 故障排查

    1
    2
    3
    4
    # 查看组件日志
    journalctl -u kubelet -f
    # 检查组件状态
    kubectl get componentstatus

附录:常用维护命令

功能命令
查看节点状态kubectl get nodes -o wide
查看Pod详细信息kubectl describe pod <pod-name>
查看服务端点kubectl get endpoints
查看集群事件kubectl get events --sort-by=.metadata.creationTimestamp
排错节点加入问题journalctl -u kubelet -f