快捷菜单
常用功能一站直达
更多功能请点顶栏「快捷菜单」
搭建时期:2026年3月30日。

初始部署方法来自阳总,实际测试输出为One编写。😊
1、硬件环境 3台虚机 2c 2g,20g。(nat模式,可访问外网)
| 角色 | 主机名 | ip | 内核版本 |
|---|---|---|---|
| master节点 | master1 | 192.168.1.24 | 3.10.0-1160.71.1.el7.x86_64 |
| node节点 | node1 | 192.168.1.25 | 3.10.0-1160.71.1.el7.x86_64 |
| node节点 | node2 | 192.168.1.26 | 3.10.0-1160.71.1.el7.x86_64 |
2、软件环境
| 软件 | 版本 |
|---|---|
| 操作系统 | centos7.6_x64 1810 mini(其他centos7.x版本也行) |
| containerd | v1.6.20 |
| kubernetes | v1.27.6 |
警告
默认CentOS Linux release 7.6.1810 (Core)的内核是3.10.0-957.el7.x86_64,但老师当前的内核版本有发生改变。基于之前经验,如果内核版本太低,后续的一些实验可能会有影响。这里就暂且使用默认的内核版本就好,后续遇到问题时,再升级下内核 或者安装好k8s集群后升级下内核就好,或者先升级完内核再k8s集群都是可以的。(本次直接部署k8s集群,未升级节点内核。)2026.3.30-实战-kubeadm方式搭建k8s集群-v1.27.6-2026.3.30-测试成功-阳明-荐(CRI-Containerd)

⚠️ (all节点均要配置)。
使用 containerd 作为容器运行时搭建 Kubernetes 集群。
现在我们使用 kubeadm 从头搭建一个使用 containerd 作为容器运行时的 Kubernetes 集群,这里我们安装 v1.27.6 版本。
在本地pc创建虚机目录:

创建3台虚机:
注意:如说是用模板克隆虚机,要选择完全克隆。
开机并配置好规划的ip:

1hostnamectl --static set-hostname master1
2bash
3
4hostnamectl --static set-hostname node1
5bash
6
7hostnamectl --static set-hostname node2
8bash警告
节点的 hostname 必须使用标准的 DNS 命名,另外千万不用什么默认的localhost 的 hostname,会导致各种错误出现的。hostnamectl set-hostname node1 来修改 hostname。1systemctl stop firewalld && systemctl disable firewalld
2systemctl stop NetworkManager && systemctl disable NetworkManager
3
4setenforce 0
5sed -i s/SELINUX=enforcing/SELINUX=disabled/ /etc/selinux/config1# 使用下面命令验证是否禁用成功
2☸ ➜ cat /etc/selinux/config
3SELINUX=disabled
4
5# 或者用如下命令验证:
6[root@master1 ~]#getenforce
7Disabled警告
如果使用的是云服务器,比如阿里云、腾讯云等,需要配置安全组,放开端口,如果只是为了测试方便可以直接全部放开,对于生产环境则只需要放开 K8s 要是使用到的一些端口,比如 6443 等等。

1# 修改 /etc/fstab 文件,注释掉 SWAP 的自动挂载
2swapoff -a
3sed -ri 's/.*swap.*/#&/' /etc/fstab1[root@master1 ~]#free -mh
2 total used free shared buff/cache available
3Mem: 1.8G 89M 1.5G 9.5M 144M 1.5G
4Swap: 0B 0B 0B问题:k8s集群安装为什么需要关闭swap分区?
swap必须关,否则kubelet起不来,进而导致k8s集群起不来;可能kublet考虑到用swap做数据交换的话,对性能影响比较大1cat >> /etc/hosts << EOF
2192.168.1.24 master1
3192.168.1.25 node1
4192.168.1.26 node2
5EOF节点的 hostname 必须使用标准的 DNS 命名,另外千万别用默认 localhost 的 hostname,会导致各种错误出现的。在 Kubernetes 项目里,机器的名字以及一切存储在 Etcd 中的 API 对象,都必须使用标准的 DNS 命名(RFC 1123)。可以使用命令 hostnamectl set-hostname xxx 来修改 hostname。
问题:k8s集群安装时节点是否需要配置dns解析? 就是后面的kubectl如果需要连接运行在node上面的容器的话,它是通过kubectl get node出来的名称去连接的,所以那个的话,我们需要在宿主机上能够解析到它。如果它解析不到的话,那么他就可能连不上;🤣
由于开启内核 ipv4 转发需要加载 br_netfilter 模块,所以加载下该模块:
1modprobe br_netfilter1[root@master1 ~]#lsmod |grep br_netfilter
2[root@master1 ~]#modprobe br_netfilter
3[root@master1 ~]#lsmod |grep br_netfilter
4br_netfilter 22256 0
5bridge 151336 1 br_netfilter🚩 ==注意:==
最好将上面的命令设置成开机启动,因为重启后模块失效,下面是开机自动加载模块的方式:
1cat >> /etc/rc.d/rc.local << EOF
2for file in /etc/sysconfig/modules/*.modules ; do
3[ -x $file ] "# $file
4done
5EOF1mkdir -p /etc/sysconfig/modules/
2echo "modprobe br_netfilter" >> /etc/sysconfig/modules/br_netfilter.modules1cd /etc/sysconfig/modules/
2chmod 755 br_netfilter.modules1[root@master1 ~]#reboot
2[root@master1 ~]#lsmod |grep br_netfilter
3br_netfilter 22256 0
4bridge 151336 1 br_netfilter
5[root@master1 ~]# 1cat > /etc/sysctl.d/k8s.conf << EOF
2net.bridge.bridge-nf-call-ip6tables = 1
3net.bridge.bridge-nf-call-iptables = 1
4net.ipv4.ip_forward = 1
5# 下面的内核参数可以解决ipvs模式下长连接空闲超时的问题
6net.ipv4.tcp_keepalive_intvl = 30
7net.ipv4.tcp_keepalive_probes = 10
8net.ipv4.tcp_keepalive_time = 600
9vm.swappiness=0
10EOF
11
12# ipvs模式下长连接空闲超时的问题:一般情况,如果是线上环境,基本上不会复现这个问题。这里测试环境可以配一下这个参数。
13# 注意
14swappiness 参数调整
15# 当然如果是生产环境使用还可以先对内核参数进行统一的调优。
16
17# 执行如下命令使修改生效:
18[root@master1 ~]#sysctl -p /etc/sysctl.d/k8s.conf
19net.bridge.bridge-nf-call-ip6tables = 1
20net.bridge.bridge-nf-call-iptables = 1
21net.ipv4.ip_forward = 1
22net.ipv4.tcp_keepalive_intvl = 30
23net.ipv4.tcp_keepalive_probes = 10
24net.ipv4.tcp_keepalive_time = 600
25vm.swappiness = 0警告
注意:将桥接的IPv4流量传递到iptables的链
由于开启内核 ipv4 转发需要加载 br_netfilter 模块,所以加载下该模块:
modprobe br_netfilter
bridge-nf说明:
bridge-nf 使得 netfilter 可以对 Linux 网桥上的 IPv4/ARP/IPv6 包过滤。比如,设置net.bridge.bridge-nf-call-iptables=1后,二层的网桥在转发包时也会被 iptables的 FORWARD 规则所过滤。常用的选项包括:
1cat > /etc/sysconfig/modules/ipvs.modules <<EOF
2#!/bin/bash
3modprobe -- ip_vs
4modprobe -- ip_vs_rr
5modprobe -- ip_vs_wrr
6modprobe -- ip_vs_sh
7modprobe -- nf_conntrack_ipv4
8EOF
9
10chmod 755 /etc/sysconfig/modules/ipvs.modules && bash /etc/sysconfig/modules/ipvs.modules && lsmod | grep -e ip_vs -e nf_conntrack_ipv4上面脚本创建了的/etc/sysconfig/modules/ipvs.modules文件,保证在节点重启后能自动加载所需模块。使用lsmod | grep -e ip_vs -e nf_conntrack_ipv4命令查看是否已经正确加载所需的内核模块;
接下来还需要确保各个节点上已经安装了 ipset 软件包,为了便于查看 ipvs 的代理规则,最好安装一下管理工具ipvsadm:
1yum install ipset ipvsadm -y然后记得一定要同步服务器时间,这里我们使用 chrony 来进行同步,其他工具也可以:
1yum install chrony -y
2systemctl enable chronyd --now
3chronyc sources(方便后期从master节点传文件到node节点)
1#在master1节点执行如下命令,按2次回车
2ssh-keygen
3
4#在master1节点执行
5ssh-copy-id -i ~/.ssh/id_rsa.pub root@192.168.1.25
6ssh-copy-id -i ~/.ssh/id_rsa.pub root@192.168.1.26⚠️ (all节点均要配置)。
接下来需要安装 Containerd 容器运行时。
如果在安装集群的过程出现了容器运行时的问题,启动不起来,可以尝试使用 yum install containerd.io 来安装 Containerd。
1[root@master1 ~]#rpm -qa |grep libseccomp #自己系统当时是有这个包的,且其版本为libseccomp-2.3.1-4.el7.x86_64
2libseccomp-2.3.1-4.el7.x86_64
3
4# 如果没有安装 libseccomp 包则可以执行下面的命令安装依赖(我这里已经提供rpm安装包)
5[root@master1 ~]# rz libseccomp-2.5.1-1.el8.x86_64.rpm
6#[root@master1 ~]#wget http://mirror.centos.org/centos/7/os/x86_64/Packages/libseccomp-2.5.1-1.el8.x86_64.rpm
7[root@master1 ~]#yum install libseccomp-2.5.1-1.el8.x86_64.rpm -y由于 Containerd 需要依赖底层的 runc 工具,所以我们也需要先安装 runc,不过 Containerd 提供了一个包含相关依赖的压缩包 cri-containerd-cni-${VERSION}.${OS}-${ARCH}.tar.gz,可以直接使用这个包来进行安装,强烈建议使用该安装包,不然可能因为 runc 版本问题导致不兼容。(这个安装包包含了一些包,例如runc,ctr命令等)
1#[root@master1 ~]#wget https://github.com/containerd/containerd/releases/download/v1.6.10/cri-containerd-1.6.10-linux-amd64.tar.gz
2
3# 如果有限制,也可以替换成下面的 URL 加速下载(本次就用的这个加速地址)
4#wget https://ghdl.feizhuqwq.cf/https://github.com/containerd/containerd/releases/download/v1.6.10/cri-containerd-1.6.10-linux-amd64.tar.gz
5
6#(我这里已经提供安装包了,直接上传即可)
7[root@master1 ~]#rz cri-containerd-1.6.10-linux-amd64.tar.gzhttps://github.com/containerd/containerd/releases/tag/v1.6.10


1#可以先看下这个压缩包的文件内容:
2[root@master1 ~]#tar tf cri-containerd-1.6.20-linux-amd64.tar.gz
3etc/crictl.yaml
4etc/systemd/
5etc/systemd/system/
6etc/systemd/system/containerd.service
7usr/
8usr/local/
9usr/local/bin/
10usr/local/bin/ctr
11usr/local/bin/critest
12usr/local/bin/crictl
13usr/local/bin/containerd
14usr/local/bin/containerd-shim
15usr/local/bin/ctd-decoder
16usr/local/bin/containerd-stress
17usr/local/bin/containerd-shim-runc-v2
18usr/local/bin/containerd-shim-runc-v1
19usr/local/sbin/
20usr/local/sbin/runc
21opt/containerd/
22opt/containerd/cluster/
23opt/containerd/cluster/version
24opt/containerd/cluster/gce/
25opt/containerd/cluster/gce/configure.sh
26opt/containerd/cluster/gce/cni.template
27opt/containerd/cluster/gce/cloud-init/
28opt/containerd/cluster/gce/cloud-init/master.yaml
29opt/containerd/cluster/gce/cloud-init/node.yaml
30opt/containerd/cluster/gce/env
31
32[root@master1 ~]#tar -C / -xzf cri-containerd-1.6.20-linux-amd64.tar.gz记得将 /usr/local/bin 和 /usr/local/sbin 追加到 PATH 环境变量中:(默认就在环境变量里的,无需添加。)
1[root@master1 ~]#echo $PATH
2/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
3
4[root@master1 ~]#containerd -v
5containerd github.com/containerd/containerd v1.6.10 770bd0108c32f3fb5c73ae1264f7e503fe7b2661
6
7[root@master1 ~]#runc -h
8runc: symbol lookup error: runc: undefined symbol: seccomp_notify_respond可以正常执行 containerd -v 命令证明 Containerd 安装成功了,但是执行 runc -h 命令的时候却出现了类似runc: undefined symbol: seccomp_notify_respond 的错误,这是因为我们当前系统默认安装的 libseccomp是 2.3.1 版本,该版本已经不能满足我们这里的 v1.6.10 版本的 Containerd 了(从 1.5.7 版本开始就不兼容了),需要 2.4 以上的版本,所以我们需要重新安装一个高版本的 libseccomp 。
以下步骤本次忽略。。。。。。。。。。。。。。。。。。
containerd 1.20这里不会报这个错误了哦。。。。🍊🍊🍊🍊🍊🍊
注意:
老师说先要卸载老版本的
libseccomp-2.3.1-4包,但是之前的chrony软件包会依赖这个libseccomp包,卸载libseccomp包的同时chrony也会被卸载掉。后面安装好高版本libseccomp-2.5.1-1要记得再次安装下chrony软件。 另外,新版本libseccomp-2.5.1-1.el8.x86_64.rpm是el8的,但是直接安装到el7上也是没问题的哦;
(1)这里开始操作:
11、卸载老版本libseccom包
2[root@master1 ~]#rpm -qa | grep libseccomp
3libseccomp-2.3.1-4.el7.x86_64
4
52、查询哪些包对这个libseccomp软件包有依赖关系
6[root@master1 ~]#rpm -e --test libseccomp
7error: Failed dependencies:
8 libseccomp.so.2()(64bit) is needed by (installed) chrony-3.4-1.el7.x86_64
9#可以发现libseccomp软件包只被chrony软件依赖
10
113、卸载老版本libseccomp包
12[root@master1 ~]#yum remove -y libseccomp #yum remove/erase 删除一个软件的时候也会删除对该软件具有依赖关系的包。
13……
14Removed:
15 libseccomp.x86_64 0:2.3.1-4.el7
16
17Dependency Removed:
18 chrony.x86_64 0:3.4-1.el7
19
20Complete!
21[root@master1 ~]#rpm -qa | grep libseccomp #查看老版本libseccomp已被卸载
22[root@master1 ~]#
23
244、# 下载高于 2.4 以上的包并安装
25[root@master1 ~]#wget http://rpmfind.net/linux/centos/8-stream/BaseOS/x86_64/os/Packages/libseccomp-2.5.1-1.el8.x86_64.rpm
26[root@master1 ~]#yum install libseccomp-2.5.1-1.el8.x86_64.rpm -y
27……
28Installed:
29 libseccomp.x86_64 0:2.5.1-1.el8
30
31Complete!
32[root@master1 ~]#rpm -qa | grep libseccomp #再次查看,发现此时libseccomp已经是最新版本的了。
33libseccomp-2.5.1-1.el8.x86_64
34
355、重新安装chrony软件
36yum install chrony -y
37systemctl enable chronyd --now
38chronyc sources(2)现在 runc 命令就可以正常使用了:
1[root@master1 ~]#runc -v
2runc version 1.1.4
3commit: v1.1.4-0-g5fd4c4d1
4spec: 1.0.2-dev
5go: go1.18.8
6libseccomp: 2.5.1
7
8[root@master1 ~]#runc -h
9NAME:
10 runc - Open Container Initiative runtime
11
12runc is a command line client for running applications packaged according to
13the Open Container Initiative (OCI) format and is a compliant implementation of the
14Open Container Initiative specification.
15
16runc integrates well with existing process supervisors to provide a production
17container runtime environment for applications. It can be used with your
18existing process monitoring tools and the container will be spawned as a
19direct child of the process supervisor.
20
21Containers are configured using bundles. A bundle for a container is a directory
22that includes a specification file named "config.json" and a root filesystem.
23The root filesystem contains the contents of the container.
24
25To start a new instance of a container:
26
27 # runc run [ -b bundle ] <container-id>
28
29Where "<container-id>" is your name for the instance of the container that you
30are starting. The name you provide for the container instance must be unique on
31your host. Providing the bundle directory using "-b" is optional. The default
32value for "bundle" is the current directory.
33
34USAGE:
35 runc [global options] command [command options] [arguments...]
36
37VERSION:
38 1.1.4
39commit: v1.1.4-0-g5fd4c4d1
40spec: 1.0.2-dev
41go: go1.18.8
42libseccomp: 2.5.1以上步骤本次忽略。。。。。。。。。。。。。。。。。。
Containerd 的默认配置文件为 /etc/containerd/config.toml,我们可以通过如下所示的命令生成一个默认的配置:
这里你可以直接使用我安装包提供的这个config.toml文件,稍微再改一下自己的信息即可。
1[root@master1 ~]#mkdir -p /etc/containerd
2[root@master1 ~]#containerd config default > /etc/containerd/config.tomlcontainerd都是插件化的。

将 containerd 的 cgroup driver 配置为 systemd。
对于使用 systemd 作为 init system 的 Linux 的发行版,使用 systemd 作为容器的 cgroup driver 可以确保节点在资源紧张的情况更加稳定,所以推荐将 containerd 的 cgroup driver 配置为 systemd。
修改前面生成的配置文件 /etc/containerd/config.toml,在 plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options 配置块下面将 SystemdCgroup 设置为 true:
1[root@master1 ~]#vim /etc/containerd/config.toml
2#通过搜索SystemdCgroup进行定位
3[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
4……
5 [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
6 SystemdCgroup = true
7 ....
然后再为镜像仓库配置一个加速器,需要在 cri 配置块下面的 registry 配置块下面进行配置 registry.mirrors:(注意缩进)
编辑/etc/containerd/config.toml文件:
1
2 [plugins."io.containerd.grpc.v1.cri".registry.mirrors]
3 # Docker Hub 加速(nginx等应用镜像)
4 [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
5 endpoint = [
6 "https://registry.cn-hangzhou.aliyuncs.com", #阿里云
7 "https://docker.mirrors.ustc.edu.cn", #中科大
8 "https://mirror.ccs.tencentyun.com", #腾讯云
9 "https://docker.1ms.run", #毫秒镜像
10 "https://registry-1.docker.io" # 最后兜底官方
11 ]
12 # k8s官方镜像加速(pause、coredns等)
13 [plugins."io.containerd.grpc.v1.cri".registry.mirrors."registry.k8s.io"]
14 endpoint = [
15 "https://registry.cn-hangzhou.aliyuncs.com/google_containers",
16 "https://docker.mirrors.ustc.edu.cn/google_containers",
17 "https://k8s.1ms.run"
18 ]
19 # 兼容旧k8s.gcr.io
20 [plugins."io.containerd.grpc.v1.cri".registry.mirrors."k8s.gcr.io"]
21 endpoint = [
22 "https://registry.cn-hangzhou.aliyuncs.com/google_containers"
23 ]
注意:
:::info
现在社区已经将 K8s 默认的镜像仓库从 k8s.gcr.io 迁移到了 registry.k8s.io ,不过国内正常情况下还是不能使用。所以如果我们的节点不能正常获取 registry.k8s.io 的镜像,那么我们需要在上面重新配置sandbox_image 镜像,Containerd 模式下直接通过 kubelet (之前版本可以这么配置的)覆盖该镜像不会生效: Warning: For remotecontainer runtime, “‘pod-infra-container-image is ignored in kubelet, which should beset in that remote runtime instead。因此需要在Containerd 里进行配置。
:::
注意:在宿主机上是可以ping通这个registry.k8s.io域名的,但是可能还是无法正常拉取镜像。

当前v1.6.10版本的containerd里的sandbox_image的pause镜像地址为pause:3.6,但我们要安装的k8s v1.25.4对其pause需求要是pause:3.8才行,这里我们来修改下pause镜像地址。
配置方法:
1[root@master1 ~]#vim /etc/containerd/config.toml
2……
3sandbox_image = "registry.aliyuncs.com/k8sxio/pause:3.8"
4……修改前:
修改后:

由于上面我们下载的 containerd 压缩包中包含一个 etc/systemd/system/containerd.service 的文件,这样我们就可以通过 systemd 来配置 containerd 作为守护进程运行了,现在我们就可以启动 containerd 了,直接执行下面的命令即可:
1systemctl daemon-reload
2systemctl enable containerd --now启动完成后就可以使用 containerd 的本地 CLI 工具 ctr 和 crictl 了,比如查看版本:
1[root@master1 ~]#containerd -v
2containerd github.com/containerd/containerd v1.6.10 770bd0108c32f3fb5c73ae1264f7e503fe7b2661
3
4[root@master1 ~]#ctr version #ctr--containerd类似于docker--dockerd。
5Client:
6 Version: v1.6.10
7 Revision: 770bd0108c32f3fb5c73ae1264f7e503fe7b2661
8 Go version: go1.18.8
9
10Server:
11 Version: v1.6.10
12 Revision: 770bd0108c32f3fb5c73ae1264f7e503fe7b2661
13 UUID: 4b5d9dc9-7e39-47ce-be54-c9f4c0fa4865
14
15[root@master1 ~]#crictl version #crictl是操作k8s里的cri的。
16Version: 0.1.0
17RuntimeName: containerd
18RuntimeVersion: v1.6.10
19RuntimeApiVersion: v1至此,containerd安装完成。
⚠️ (all节点均要配置)。
上面的相关环境配置完成后,接着我们就可以来安装 Kubeadm 了,我们这里是通过指定 yum 源的方式来进行安装的:
1cat <<EOF > /etc/yum.repos.d/kubernetes.repo
2[kubernetes]
3name=Kubernetes
4baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64
5enabled=1
6gpgcheck=1
7repo_gpgcheck=1
8gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg
9 https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
10EOF
当然了,上面的 yum 源是需要科学上网的,如果不能科学上网的话,我们可以使用阿里云的源进行安装:
1cat > /etc/yum.repos.d/kubernetes.repo << EOF
2[kubernetes]
3name=Kubernetes
4baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
5enabled=1
6gpgcheck=0
7repo_gpgcheck=0
8gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
9EOF⚠️ (all节点均要配置)。
1[root@master1 ~]yum makecache fast
2[root@master1 ~]yum install -y kubelet-1.27.6 kubeadm-1.27.6 kubectl-1.27.6 --disableexcludes=kubernetes
3[root@master1 ~]#kubeadm version
4kubeadm version: &version.Info{Major:"1", Minor:"27", GitVersion:"v1.27.6", GitCommit:"741c8db18a52787d734cbe4795f0b4ad860906d6", GitTreeState:"clean", BuildDate:"2023-09-13T09:19:54Z", GoVersion:"go1.20.8", Compiler:"gc", Platform:"linux/amd64"}
5[root@master1 ~]#
6
7
8#可以看到我们这里安装的是 v1.25.4 版本,然后将 master 节点的 kubelet 设置成开机启动:
9[root@master1 ~]#systemctl enable --now kubelet说明:–disableexcludes 禁掉除了kubernetes之外的别的仓库
🍀 注意
到这里为止上面所有的操作都需要在所有节点执行配置 上面所有的操作都需要在所有节点执行配置,在云环境上面的话我们可以将当前环境直接做成一个镜像,然后创建新节点的时候直接使用该镜像即可,这样可以避免重复的工作。
如果是自己测试用虚拟机配置,也建议先配置1台master节点,其余节点直接克隆master节点配置过来就好。注意一点,克隆过来的机器只要配置好对应的ip,主机名和/ect/hosts内容就好,其他内容不变。

(master1节点操作)。
当我们执行 kubelet --help 命令的时候可以看到原来大部分命令行参数都被 DEPRECATED了,这是因为官方推荐我们使用 --config 来指定配置文件,在配置文件中指定原来这些参数的配置,可以通过官方文档 Set Kubelet parameters via a config file 了解更多相关信息,这样 Kubernetes 就可以支持**动态 Kubelet 配置(Dynamic Kubelet Configuration)**了,参考 Reconfigure a Node’s Kubelet in a Live Cluster。
1[root@master1 ~]#kubeadm config print init-defaults --component-configs KubeletConfiguration > kubeadm.yaml然后根据我们自己的需求修改配置:
比如修改 imageRepository 指定集群初始化时拉取 Kubernetes 所需镜像的地址;
kube-proxy 的模式为 ipvs;
另外需要注意的是我们这里是准备安装 flannel 网络插件的,需要将 networking.podSubnet 设置为10.244.0.0/16:
默认yaml内容如下:
1[root@master1 ~]#cat kubeadm.yaml
2apiVersion: kubeadm.k8s.io/v1beta3
3bootstrapTokens:
4- groups:
5 - system:bootstrappers:kubeadm:default-node-token
6 token: abcdef.0123456789abcdef
7 ttl: 24h0m0s
8 usages:
9 - signing
10 - authentication
11kind: InitConfiguration
12localAPIEndpoint:
13 advertiseAddress: 1.2.3.4
14 bindPort: 6443
15nodeRegistration:
16 criSocket: unix:///var/run/containerd/containerd.sock
17 imagePullPolicy: IfNotPresent
18 name: node
19 taints: null
20---
21apiServer:
22 timeoutForControlPlane: 4m0s
23apiVersion: kubeadm.k8s.io/v1beta3
24certificatesDir: /etc/kubernetes/pki
25clusterName: kubernetes
26controllerManager: {}
27dns: {}
28etcd:
29 local:
30 dataDir: /var/lib/etcd
31imageRepository: registry.k8s.io
32kind: ClusterConfiguration
33kubernetesVersion: 1.25.0
34networking:
35 dnsDomain: cluster.local
36 serviceSubnet: 10.96.0.0/12
37scheduler: {}
38---
39apiVersion: kubelet.config.k8s.io/v1beta1
40authentication:
41 anonymous:
42 enabled: false
43 webhook:
44 cacheTTL: 0s
45 enabled: true
46 x509:
47 clientCAFile: /etc/kubernetes/pki/ca.crt
48authorization:
49 mode: Webhook
50 webhook:
51 cacheAuthorizedTTL: 0s
52 cacheUnauthorizedTTL: 0s
53cgroupDriver: systemd
54clusterDNS:
55- 10.96.0.10
56clusterDomain: cluster.local
57cpuManagerReconcilePeriod: 0s
58evictionPressureTransitionPeriod: 0s
59fileCheckFrequency: 0s
60healthzBindAddress: 127.0.0.1
61healthzPort: 10248
62httpCheckFrequency: 0s
63imageMinimumGCAge: 0s
64kind: KubeletConfiguration
65logging:
66 flushFrequency: 0
67 options:
68 json:
69 infoBufferSize: "0"
70 verbosity: 0
71memorySwap: {}
72nodeStatusReportFrequency: 0s
73nodeStatusUpdateFrequency: 0s
74rotateCertificates: true
75runtimeRequestTimeout: 0s
76shutdownGracePeriod: 0s
77shutdownGracePeriodCriticalPods: 0s
78staticPodPath: /etc/kubernetes/manifests
79streamingConnectionIdleTimeout: 0s
80syncFrequency: 0s
81volumeStatsAggPeriod: 0s 1[root@master1 ~]#cat kubeadm.yaml
2apiVersion: kubeadm.k8s.io/v1beta3
3bootstrapTokens:
4- groups:
5 - system:bootstrappers:kubeadm:default-node-token
6 token: abcdef.0123456789abcdef
7 ttl: 24h0m0s
8 usages:
9 - signing
10 - authentication
11kind: InitConfiguration
12localAPIEndpoint:
13 advertiseAddress: 192.168.1.24 # 修改1:指定master节点内网IP
14 bindPort: 6443
15nodeRegistration:
16 criSocket: unix:///var/run/containerd/containerd.sock
17 imagePullPolicy: IfNotPresent
18 name: master1 #修改2:修改master节点名称
19 taints: # 修改3:给master添加污点,master节点不能调度应用
20 - effect: "NoSchedule"
21 key: "node-role.kubernetes.io/master"
22---
23apiServer:
24 timeoutForControlPlane: 4m0s
25apiVersion: kubeadm.k8s.io/v1beta3
26certificatesDir: /etc/kubernetes/pki
27clusterName: kubernetes
28controllerManager: {}
29dns: {}
30etcd:
31 local:
32 dataDir: /var/lib/etcd
33imageRepository: registry.aliyuncs.com/k8sxio #修改5:image地址(这里的地址用于拉取k8s master上一些核心组件起pod用的)
34kind: ClusterConfiguration
35kubernetesVersion: 1.27.6 #修改6:指定k8s版本号,默认这里忽略了小版本号
36networking:
37 dnsDomain: cluster.local
38 serviceSubnet: 10.96.0.0/12
39 podSubnet: 10.244.0.0/16 # 修改7:指定 pod 子网
40scheduler: {}
41
42---
43apiVersion: kubeproxy.config.k8s.io/v1alpha1
44kind: KubeProxyConfiguration
45mode: ipvs # 修改4:修改kube-proxy 模式为ipvs,默认为iptables
46
47---
48apiVersion: kubelet.config.k8s.io/v1beta1
49authentication:
50 anonymous:
51 enabled: false
52 webhook:
53 cacheTTL: 0s
54 enabled: true
55 x509:
56 clientCAFile: /etc/kubernetes/pki/ca.crt
57authorization:
58 mode: Webhook
59 webhook:
60 cacheAuthorizedTTL: 0s
61 cacheUnauthorizedTTL: 0s
62cgroupDriver: systemd
63clusterDNS:
64- 10.96.0.10
65clusterDomain: cluster.local
66cpuManagerReconcilePeriod: 0s
67evictionPressureTransitionPeriod: 0s
68fileCheckFrequency: 0s
69healthzBindAddress: 127.0.0.1
70healthzPort: 10248
71httpCheckFrequency: 0s
72imageMinimumGCAge: 0s
73kind: KubeletConfiguration
74logging:
75 flushFrequency: 0
76 options:
77 json:
78 infoBufferSize: "0"
79 verbosity: 0
80memorySwap: {}
81nodeStatusReportFrequency: 0s
82nodeStatusUpdateFrequency: 0s
83rotateCertificates: true
84runtimeRequestTimeout: 0s
85shutdownGracePeriod: 0s
86shutdownGracePeriodCriticalPods: 0s
87staticPodPath: /etc/kubernetes/manifests
88streamingConnectionIdleTimeout: 0s
89syncFrequency: 0s
90volumeStatsAggPeriod: 0s最终配置:kubeadm.yaml (本次可直接使用我提供的kubeadm.yaml文件,自己改下master ip就好)
1[root@master1 ~]#cat kubeadm.yaml
2mageRepository
3apiVersion: kubeadm.k8s.io/v1beta3
4bootstrapTokens:
5- groups:
6 - system:bootstrappers:kubeadm:default-node-token
7 token: abcdef.0123456789abcdef
8 ttl: 24h0m0s
9 usages:
10 - signing
11 - authentication
12kind: InitConfiguration
13localAPIEndpoint:
14 advertiseAddress: 192.168.1.24
15 bindPort: 6443
16nodeRegistration:
17 criSocket: unix:///var/run/containerd/containerd.sock
18 imagePullPolicy: IfNotPresent
19 name: master1
20 taints:
21 - effect: "NoSchedule"
22 key: "node-role.kubernetes.io/master"
23---
24apiServer:
25 timeoutForControlPlane: 4m0s
26apiVersion: kubeadm.k8s.io/v1beta3
27certificatesDir: /etc/kubernetes/pki
28clusterName: kubernetes
29controllerManager: {}
30dns: {}
31etcd:
32 local:
33 dataDir: /var/lib/etcd
34imageRepository: registry.aliyuncs.com/k8sxio
35kind: ClusterConfiguration
36kubernetesVersion: 1.27.6
37networking:
38 dnsDomain: cluster.local
39 serviceSubnet: 10.96.0.0/12
40 podSubnet: 10.244.0.0/16
41scheduler: {}
42---
43apiVersion: kubeproxy.config.k8s.io/v1alpha1
44kind: KubeProxyConfiguration
45mode: ipvs
46---
47apiVersion: kubelet.config.k8s.io/v1beta1
48authentication:
49 anonymous:
50 enabled: false
51 webhook:
52 cacheTTL: 0s
53 enabled: true
54 x509:
55 clientCAFile: /etc/kubernetes/pki/ca.crt
56authorization:
57 mode: Webhook
58 webhook:
59 cacheAuthorizedTTL: 0s
60 cacheUnauthorizedTTL: 0s
61cgroupDriver: systemd
62clusterDNS:
63- 10.96.0.10
64clusterDomain: cluster.local
65containerRuntimeEndpoint: ""
66cpuManagerReconcilePeriod: 0s
67evictionPressureTransitionPeriod: 0s
68fileCheckFrequency: 0s
69healthzBindAddress: 127.0.0.1
70healthzPort: 10248
71httpCheckFrequency: 0s
72imageMinimumGCAge: 0s
73kind: KubeletConfiguration
74logging:
75 flushFrequency: 0
76 options:
77 json:
78 infoBufferSize: "0"
79 verbosity: 0
80memorySwap: {}
81nodeStatusReportFrequency: 0s
82nodeStatusUpdateFrequency: 0s
83rotateCertificates: true
84runtimeRequestTimeout: 0s
85shutdownGracePeriod: 0s
86shutdownGracePeriodCriticalPods: 0s
87staticPodPath: /etc/kubernetes/manifests
88streamingConnectionIdleTimeout: 0s
89syncFrequency: 0s
90volumeStatsAggPeriod: 0s
91[root@master1 ~]#🍊配置提示
对于上面的资源清单的文档比较杂,要想完整了解上面的资源对象对应的属性,可以查看对应的 godoc 文档,地址: https://godoc.org/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta3。
在开始初始化集群之前可以使用 kubeadm config images pull --config kubeadm.yaml 预先在各个服务器节点上拉取所k8s需要的容器镜像。
1[root@master1 ~]#kubeadm config images list --config kubeadm.yaml
2registry.aliyuncs.com/google_containers/kube-apiserver:v1.27.6
3registry.aliyuncs.com/google_containers/kube-controller-manager:v1.27.6
4registry.aliyuncs.com/google_containers/kube-scheduler:v1.27.6
5registry.aliyuncs.com/google_containers/kube-proxy:v1.27.6
6registry.aliyuncs.com/google_containers/pause:3.9
7registry.aliyuncs.com/google_containers/etcd:3.5.7-0
8registry.aliyuncs.com/google_containers/coredns:v1.10.11[root@master1 ~]#kubeadm config images pull --config kubeadm.yaml
==⚠️ !!!!!!!!此部分删除:为v1.25.4版本配置操作,v1.27.6版本不需要配置次部分。==
上面在拉取 coredns 镜像的时候出错了,阿里云仓库里没有找到这个镜像,我们可以手动到官方仓库 pull 该镜像,然后重新 tag 下镜像地址即可:
1[root@master1 ~]#ctr -n k8s.io i pull docker.io/coredns/coredns:1.9.3
2docker.io/coredns/coredns:1.9.3: resolved |++++++++++++++++++++++++++++++++++++++|
3index-sha256:8e352a029d304ca7431c6507b56800636c321cb52289686a581ab70aaa8a2e2a: done |++++++++++++++++++++++++++++++++++++++|
4manifest-sha256:bdb36ee882c13135669cfc2bb91c808a33926ad1a411fee07bd2dc344bb8f782: done |++++++++++++++++++++++++++++++++++++++|
5layer-sha256:f2401d57212f95ea8e82ff8728f4f99ef02d4b39459837244d1b049c5d43de43: done |++++++++++++++++++++++++++++++++++++++|
6config-sha256:5185b96f0becf59032b8e3646e99f84d9655dff3ac9e2605e0dc77f9c441ae4a: done |++++++++++++++++++++++++++++++++++++++|
7layer-sha256:d92bdee797857f997be3c92988a15c196893cbbd6d5db2aadcdffd2a98475d2d: done |++++++++++++++++++++++++++++++++++++++|
8elapsed: 8.2 s total: 11.1 M (1.4 MiB/s)
9unpacking linux/amd64 sha256:8e352a029d304ca7431c6507b56800636c321cb52289686a581ab70aaa8a2e2a...
10done: 691.900943ms
11
12#重新打上tag
13[root@master1 ~]# ctr -n k8s.io i tag docker.io/coredns/coredns:1.9.3 registry.aliyuncs.com/k8sxio/coredns:v1.9.3
14registry.aliyuncs.com/k8sxio/coredns:v1.9.3
15
16#查看镜像
17[root@master1 ~]#ctr -n k8s.io i list -q|grep coredns
18docker.io/coredns/coredns:1.9.3
19registry.aliyuncs.com/k8sxio/coredns:v1.9.3注意:
然后在2个node节点上执行下预拉取镜像和
coredns镜像拉取与重新打tag操作
1kubeadm config images pull --config kubeadm.yaml
2
3ctr -n k8s.io i pull docker.io/coredns/coredns:1.9.3
4ctr -n k8s.io i tag docker.io/coredns/coredns:1.9.3 registry.aliyuncs.com/k8sxio/coredns:v1.9.3
5
6[root@master1 ~]#scp kubeadm.yaml root@172.29.9.62:~
7kubeadm.yaml 100% 2076 2.1MB/s 00:00
8[root@master1 ~]#scp kubeadm.yaml root@172.29.9.63:~
9kubeadm.yaml 100% 2076 2.2MB/s 00:00 1#注意:可以通过加上--v 5来进一步打印更多的log信息
2kubeadm init --config kubeadm.yaml --v 5 1[root@master1 ~]#kubeadm init --config kubeadm.yaml
2[init] Using Kubernetes version: v1.25.4
3[preflight] Running pre-flight checks
4[preflight] Pulling images required for setting up a Kubernetes cluster
5[preflight] This might take a minute or two, depending on the speed of your internet connection
6[preflight] You can also perform this action in beforehand using 'kubeadm config images pull'
7[certs] Using certificateDir folder "/etc/kubernetes/pki"
8[certs] Generating "ca" certificate and key
9[certs] Generating "apiserver" certificate and key
10[certs] apiserver serving cert is signed for DNS names [kubernetes kubernetes.default kubernetes.default.svc kubernetes.default.svc.cluster.local master1] and IPs [10.96.0.1 172.29.9.61]
11[certs] Generating "apiserver-kubelet-client" certificate and key
12[certs] Generating "front-proxy-ca" certificate and key
13[certs] Generating "front-proxy-client" certificate and key
14[certs] Generating "etcd/ca" certificate and key
15[certs] Generating "etcd/server" certificate and key
16[certs] etcd/server serving cert is signed for DNS names [localhost master1] and IPs [172.29.9.61 127.0.0.1 ::1]
17[certs] Generating "etcd/peer" certificate and key
18[certs] etcd/peer serving cert is signed for DNS names [localhost master1] and IPs [172.29.9.61 127.0.0.1 ::1]
19[certs] Generating "etcd/healthcheck-client" certificate and key
20[certs] Generating "apiserver-etcd-client" certificate and key
21[certs] Generating "sa" key and public key
22[kubeconfig] Using kubeconfig folder "/etc/kubernetes"
23[kubeconfig] Writing "admin.conf" kubeconfig file
24[kubeconfig] Writing "kubelet.conf" kubeconfig file
25[kubeconfig] Writing "controller-manager.conf" kubeconfig file
26[kubeconfig] Writing "scheduler.conf" kubeconfig file
27[kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
28[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
29[kubelet-start] Starting the kubelet
30[control-plane] Using manifest folder "/etc/kubernetes/manifests"
31[control-plane] Creating static Pod manifest for "kube-apiserver"
32[control-plane] Creating static Pod manifest for "kube-controller-manager"
33[control-plane] Creating static Pod manifest for "kube-scheduler"
34[etcd] Creating static Pod manifest for local etcd in "/etc/kubernetes/manifests"
35[wait-control-plane] Waiting for the kubelet to boot up the control plane as static Pods from directory "/etc/kubernetes/manifests". This can take up to 4m0s
36[apiclient] All control plane components are healthy after 7.004110 seconds
37[upload-config] Storing the configuration used in ConfigMap "kubeadm-config" in the "kube-system" Namespace
38[kubelet] Creating a ConfigMap "kubelet-config" in namespace kube-system with the configuration for the kubelets in the cluster
39[upload-certs] Skipping phase. Please see --upload-certs
40[mark-control-plane] Marking the node master1 as control-plane by adding the labels: [node-role.kubernetes.io/control-plane node.kubernetes.io/exclude-from-external-load-balancers]
41[mark-control-plane] Marking the node master1 as control-plane by adding the taints [node-role.kubernetes.io/master:NoSchedule]
42[bootstrap-token] Using token: abcdef.0123456789abcdef
43[bootstrap-token] Configuring bootstrap tokens, cluster-info ConfigMap, RBAC Roles
44[bootstrap-token] Configured RBAC rules to allow Node Bootstrap tokens to get nodes
45[bootstrap-token] Configured RBAC rules to allow Node Bootstrap tokens to post CSRs in order for nodes to get long term certificate credentials
46[bootstrap-token] Configured RBAC rules to allow the csrapprover controller automatically approve CSRs from a Node Bootstrap Token
47[bootstrap-token] Configured RBAC rules to allow certificate rotation for all node client certificates in the cluster
48[bootstrap-token] Creating the "cluster-info" ConfigMap in the "kube-public" namespace
49[kubelet-finalize] Updating "/etc/kubernetes/kubelet.conf" to point to a rotatable kubelet client certificate and key
50[addons] Applied essential addon: CoreDNS
51[addons] Applied essential addon: kube-proxy
52
53Your Kubernetes control-plane has initialized successfully!
54
55To start using your cluster, you need to run the following as a regular user:
56
57 mkdir -p $HOME/.kube
58 sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
59 sudo chown $(id -u):$(id -g) $HOME/.kube/config
60
61Alternatively, if you are the root user, you can run:
62
63 export KUBECONFIG=/etc/kubernetes/admin.conf
64
65You should now deploy a pod network to the cluster.
66Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
67 https://kubernetes.io/docs/concepts/cluster-administration/addons/
68
69Then you can join any number of worker nodes by running the following on each as root:
70
71kubeadm join 172.29.9.61:6443 --token abcdef.0123456789abcdef \
72 --discovery-token-ca-cert-hash sha256:d4bdf1090a033f285e12087147da051a43cf786e03645fdcd48e2d51e1cacaf7
73[root@master1 ~]#master1节点初始化成功。
1 mkdir -p $HOME/.kube
2 sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
3 sudo chown $(id -u):$(id -g) $HOME/.kube/config1[root@master1 ~]#kubectl get node
2NAME STATUS ROLES AGE VERSION
3master1 NotReady control-plane 3m56s v1.25.4现在节点还处于 NotReady 状态,是因为还没有安装 CNI 插件,我们可以先添加一个 Node 节点,再部署网络插件。
记住初始化集群上面的配置和操作要提前做好,将 master 节点上面的 $HOME/.kube/config 文件拷贝到 node 节点对应的文件中(如果想在 node 节点上操作 kubectl,一般不需要),安装 kubeadm、kubelet、kubectl(可选),然后执行上面初始化完成后提示的 join 命令即可:(这里同时添加其它work节点)
1kubeadm join 192.168.1.24:6443 --token abcdef.0123456789abcdef \
2 --discovery-token-ca-cert-hash sha256:ad606555e9de8669df45bf2f0a27183a0977e9ac6c4daf4b8567c7195ced1989
3
4
5
6[root@node1 ~]#kubeadm join 192.168.1.24:6443 --token abcdef.0123456789abcdef \
7 --discovery-token-ca-cert-hash sha256:ad606555e9de8669df45bf2f0a27183a0977e9ac6c4daf4b8567c7195ced1989
8
9
10
11
12[preflight] Running pre-flight checks
13[preflight] Reading configuration from the cluster...
14[preflight] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml'
15[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
16[kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
17[kubelet-start] Starting the kubelet
18[kubelet-start] Waiting for the kubelet to perform the TLS Bootstrap...
19
20This node has joined the cluster:
21* Certificate signing request was sent to apiserver and a response was received.
22* The Kubelet was informed of the new secure connection details.
23
24Run 'kubectl get nodes' on the control-plane to see this node join the cluster.
25
26[root@node1 ~]#
27
28
29[root@node2 ~]#kubeadm join 192.168.1.24:6443 --token abcdef.0123456789abcdef \
30 --discovery-token-ca-cert-hash sha256:ad606555e9de8669df45bf2f0a27183a0977e9ac6c4daf4b8567c7195ced1989
31
32
33[preflight] Running pre-flight checks
34[preflight] Reading configuration from the cluster...
35[preflight] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml'
36[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
37[kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
38[kubelet-start] Starting the kubelet
39[kubelet-start] Waiting for the kubelet to perform the TLS Bootstrap...
40
41This node has joined the cluster:
42* Certificate signing request was sent to apiserver and a response was received.
43* The Kubelet was informed of the new secure connection details.
44
45Run 'kubectl get nodes' on the control-plane to see this node join the cluster.
46
47[root@node2 ~]#join 命令:如果忘记了上面的 join 命令可以使用命令 kubeadm token create --print-join-command 重新获取。
1[root@master1 ~]#kubectl get node
2NAME STATUS ROLES AGE VERSION
3master1 NotReady control-plane 15m v1.25.4
4node1 NotReady <none> 66s v1.25.4
5node2 NotReady <none> 61s v1.25.4警告
可以看到,这里的节点状态都为NotReady,这个时候其实集群还不能正常使用,因为还没有安装网络插件,接下来安装网络插件,可以在文档 https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/ 中选择我们自己的网络插件,这里我们安装 flannel。 1#从官网下载
2#wget https://ghps.cc/https://github.com/flannel-io/flannel/releases/download/v0.22.2/kube-flannel.yml
3
4#本次直接使用我提供的yaml文件就好(里面我把image地址做了转存,不然默认的镜像地址,本地拉取不到哦。。。)
5kube-flannel.yml
6
7[root@master1 ~]#cat kube-flannel.yml |grep image
8 image: uhub.service.ucloud.cn/onedayxyy/flannel:v0.22.2
9 image: uhub.service.ucloud.cn/onedayxyy/flannel-cni-plugin:v1.2.0
10 image: uhub.service.ucloud.cn/onedayxyy/flannel:v0.22.21[root@master1 install-flannel]#kubectl apply -f kube-flannel.yml
2namespace/kube-flannel created
3serviceaccount/flannel created
4clusterrole.rbac.authorization.k8s.io/flannel created
5clusterrolebinding.rbac.authorization.k8s.io/flannel created
6configmap/kube-flannel-cfg created
7daemonset.apps/kube-flannel-ds created
8[root@master1 install-flannel]# 1[root@master1 ~]#kubectl get po -nkube-flannel -owide
2NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
3kube-flannel-ds-24kcm 1/1 Running 0 16h 192.168.1.24 master1 <none> <none>
4kube-flannel-ds-m9nbd 1/1 Running 0 16h 192.168.1.25 node1 <none> <none>
5kube-flannel-ds-xv8q2 1/1 Running 0 16h 192.168.1.26 node2 <none> <none>
6[root@master1 ~]#kubectl get node -owide
7NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
8master1 Ready control-plane 26h v1.27.6 192.168.1.24 <none> CentOS Linux 7 (Core) 3.10.0-957.el7.x86_64 containerd://1.6.20
9node1 Ready <none> 26h v1.27.6 192.168.1.25 <none> CentOS Linux 7 (Core) 3.10.0-957.el7.x86_64 containerd://1.6.20
10node2 Ready <none> 26h v1.27.6 192.168.1.26 <none> CentOS Linux 7 (Core) 3.10.0-957.el7.x86_64 containerd://1.6.20
11[root@master1 ~]# 1# 如果有节点是多网卡,则需要在资源清单文件中指定内网网卡
2# 搜索到名为 kube-flannel-ds 的 DaemonSet,在kube-flannel容器下面
3
4☸ ➜ vi kube-flannel.yml
5......
6containers:
7- name: kube-flannel
8#image: flannelcni/flannel:v0.20.1 for ppc64le and mips64le (dockerhub limitations may
9apply)
10image: docker.io/rancher/mirrored-flannelcni-flannel:v0.20.1
11command:
12- /opt/bin/flanneld
13args:
14- --ip-masq
15- --kube-subnet-mgr
16- --iface=eth0 # 如果是多网卡的话,指定内网网卡的名称
17
18#因为自己使用的是虚拟机,只有一张网卡,不用指定了。当我们部署完网络插件后执行 ifconfig 命令,正常会看到新增的
cni0与flannel1这两个虚拟设备,但是如果没有看到cni0这个设备也不用太担心(一般是会有的),我们可以观察/var/lib/cni目录是否存在,如果不存在并不是说部署有问题,而是该节点上暂时还没有应用运行,我们只需要在该节点上运行一个 Pod 就可以看到该目录会被创建,并且cni0设备也会被创建出来。
1.下载kube-dashboard的yaml文件
1# 下载
2#wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.7.0/aio/deploy/recommended.yaml
3
4#本次直接使用我提供的yaml文件就好(里面我把image地址做了转存,不然默认的镜像地址,本地拉取不到哦。。。)
5kube-dashboard.yaml2.修改kube-dashboard.yaml文件
1#mv recommended.yaml kube-dashboard.yaml
2[root@master1 ~]#vim kube-dashboard.yaml
3# 修改Service为NodePort类型
4kind: Service
5apiVersion: v1
6metadata:
7 labels:
8 k8s-app: kubernetes-dashboard
9 name: kubernetes-dashboard
10 namespace: kubernetes-dashboard
11spec:
12 ports:
13 - port: 443
14 targetPort: 8443
15 selector:
16 k8s-app: kubernetes-dashboard
17 type: NodePort # 加上type=NodePort变成NodePort类型的服务注意:在 YAML 文件中可以看到新版本 Dashboard 集成了一个 metrics-scraper 的组件,可以通过 Kubernetes的 Metrics API 收集一些基础资源的监控信息,并在 web 页面上展示,所以要想在页面上展示监控信息就需要提供 Metrics API,比如安装 Metrics Server。
3.部署kube-dashboard.yaml文件 直接创建:
1[root@master1 ~]#kubectl apply -f kube-dashboard.yaml
2namespace/kubernetes-dashboard created
3serviceaccount/kubernetes-dashboard created
4service/kubernetes-dashboard created
5secret/kubernetes-dashboard-certs created
6secret/kubernetes-dashboard-csrf created
7secret/kubernetes-dashboard-key-holder created
8configmap/kubernetes-dashboard-settings created
9role.rbac.authorization.k8s.io/kubernetes-dashboard created
10clusterrole.rbac.authorization.k8s.io/kubernetes-dashboard created
11rolebinding.rbac.authorization.k8s.io/kubernetes-dashboard created
12clusterrolebinding.rbac.authorization.k8s.io/kubernetes-dashboard created
13deployment.apps/kubernetes-dashboard created
14service/dashboard-metrics-scraper created
15deployment.apps/dashboard-metrics-scraper created4.验证 新版本的 Dashboard 会被默认安装在 kubernetes-dashboard 这个命名空间下面:
1[root@master1 ~]#kubectl get po -owide -nkubernetes-dashboard
2NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
3dashboard-metrics-scraper-7d8b55d866-7k5mz 1/1 Running 0 16h 10.244.2.6 node2 <none> <none>
4kubernetes-dashboard-76c9f774d-kcskd 1/1 Running 0 16h 10.244.2.5 node2 <none> <none>
5[root@master1 ~]#然后查看 Dashboard 的 NodePort 端口:
1[root@master1 ~]# kubectl get svc -n kubernetes-dashboard
2NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
3dashboard-metrics-scraper ClusterIP 10.100.184.32 <none> 8000/TCP 2m8s
4kubernetes-dashboard NodePort 10.101.55.122 <none> 443:30349/TCP 2m8s然后可以通过上面的 30349端口去访问 Dashboard,要记住使用 https,Chrome 不生效可以使用Firefox 测试,如果没有 Firefox 下面打不开页面,可以点击下页面中的信任证书即可:
信任后就可以访问到 Dashboard 的登录页面了:

1#直接使用我提供的文件就好
2admin.yaml
3
4[root@master1 ~]#vim admin.yaml
5kind: ClusterRoleBinding
6apiVersion: rbac.authorization.k8s.io/v1
7metadata:
8 name: admin
9roleRef:
10 kind: ClusterRole
11 name: cluster-admin
12 apiGroup: rbac.authorization.k8s.io
13subjects:
14- kind: ServiceAccount
15 name: admin
16 namespace: kubernetes-dashboard
17---
18apiVersion: v1
19kind: ServiceAccount
20metadata:
21 name: admin
22 namespace: kubernetes-dashboard1[root@master1 ~]#kubectl apply -f admin.yaml
2clusterrolebinding.rbac.authorization.k8s.io/admin created
3serviceaccount/admin created1# 请求创建一个 token 作为 kubernetes-dashboard 命名空间中的 admin这个 sa 对 kubeapiserver 进行身份验证
2[root@master1 ~]#kubectl -n kubernetes-dashboard create token admin
3#上面的命令执行后会打印出如下所示的 token:
4eyJhbGciOiJSUzI1NiIsImtpZCI6ImJXaFVwN29KX0lXODl6SGtFZTN4TklxYnNiQzlmeExpb0dqQ2JYbFNBS3MifQ.eyJhdWQiOlsiaHR0cHM6Ly9rdWJlcm5ldGVzLmRlZmF1bHQuc3ZjLmNsdXN0ZXIubG9jYWwiXSwiZXhwIjoxNjcwMjAwMjY3LCJpYXQiOjE2NzAxOTY2NjcsImlzcyI6Imh0dHBzOi8va3ViZXJuZXRlcy5kZWZhdWx0LnN2Yy5jbHVzdGVyLmxvY2FsIiwia3ViZXJuZXRlcy5pbyI6eyJuYW1lc3BhY2UiOiJrdWJlcm5ldGVzLWRhc2hib2FyZCIsInNlcnZpY2VhY2NvdW50Ijp7Im5hbWUiOiJhZG1pbiIsInVpZCI6IjYyNDkxYzRhLTc1ZDUtNGVmOC1hODM3LTdiNTIxZmZjNTMwZSJ9fSwibmJmIjoxNjcwMTk2NjY3LCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6a3ViZXJuZXRlcy1kYXNoYm9hcmQ6YWRtaW4ifQ.Qw1vzLiabrKslskQnwXnCIKK3kJWtDEvkcS5URhZTHpkkNHObqCoYMpbW9MB6RsfONV7KHQ0l1FZ13OUs31oQ--hernYB197ROl3AUp_0RMzrY_FIIRJzB5_Kr_hKqEYfm7qfYrn6rgVTgQjVsrPYjK14p5fVV0Lng7MasntsT6Dhqsj9yqo2-6Tjj2Xtc0kL4Xr_vVmziJOA9_Fj-axe6SzUd9UoWyz8jjbL31d8A7QbsuhUiyAfInSpgL2IFJ0d8-iXVhLwgFE9C_AfEmsTf_fXn0SIm7e9HS9RQTDw0wtz6aUnnqDlop3LZG-wCzDRd3WN2ajodWUftlNg5hoAQ
到这里我们就完成了使用 kubeadm 搭建 v1.25.4 版本的 kubernetes 集群。😘
最后记得做下3台虚机的快照,方便后期还原。🤣

1#部署nginx服务
2kubectl create deployment web --image=uhub.service.ucloud.cn/library/nginx:1.9.7
3
4#暴漏服务
5kubectl expose deployment web --port=80 --target-port=80 --type=NodePort
6
7#查看
8kubectl get service
9
10#验证
11#curl nodeIP:NodeP
12curl 192.168.1.25:31605具体部署过程:
(1)使用Deployment控制器部署镜像:
1[root@master1 ~]#kubectl create deployment web --image=uhub.service.ucloud.cn/library/nginx:1.9.7
2deployment.apps/web created此时用kubectl get pods命令查看pod是否是运行的:
1[root@master1 ~]#kubectl get pods,deploy
2NAME READY STATUS RESTARTS AGE
3pod/web-8667899c97-4d58d 1/1 Running 0 24s
4
5NAME READY UP-TO-DATE AVAILABLE AGE
6deployment.apps/web 1/1 1 1 24s (2)使用Service将Pod暴露出去:
1[root@master1 ~]#kubectl expose deployment web --port=80 --target-port=80 --type=NodePort
2service/web exposed
3
4#备注
5第一个--port是k8s集群内部访问端口,通过集群内部访问的ip, cluster ip;
6第二个--target--port是镜像里服务跑的端口号;用kubectl get service命令查看刚才创建的service:
1[root@master1 ~]#kubectl get service
2NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
3kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 6h6m
4web NodePort 10.103.191.211 <none> 80:32302/TCP 21s (3)访问应用:(实验现象符合预期,完美!) http://NodeIP:Port # 端口随机生成,通过get svc获取
1#注意:此时你通过任意的nodeip:端口都可访问nginx应用;(masterip:端口是不行的)
如果你的集群安装过程中遇到了其他问题,我们可以使用下面的命令来进行重置:
1kubeadm reset
2ifconfig cni0 down && ip link delete cni0
3ifconfig flannel.1 down && ip link delete flannel.1
4rm -rf /var/lib/cni/我的博客主旨:
🍀 微信二维码 x2675263825 (舍得), qq:2675263825。

🍀 微信公众号 《云原生架构师实战》

🍀 个人博客站点

🍀 csdn
https://blog.csdn.net/weixin_39246554?spm=1010.2135.3001.5421

🍀 知乎
https://www.zhihu.com/people/foryouone

好了,关于本次就到这里了,感谢大家阅读,最后祝大家生活快乐,每天都过的有意义哦,我们下期见!

结束。
日历 · 精选 · 友链 · 更多
如果内容对你有帮助,欢迎请我喝杯咖啡 ☕



One的公众号
爱折腾博客的小白