第六章-kubeadm搭建单master节点k8s
本章所讲内容:
6.1 Kubernetes 简介
6.2 使用 kubeadm 部署 Kubernetes 集群
6.3 实战-工作节点加入 k8s 集群
6.4 安装 kubernetes 网络组件-Calico
6.5 kubeadm 初始化 k8s 证书过期解决方案
6.5 测试 k8s 集群的 DNS 解析和网络是否正常
6.1 使用 kubeadm 部署Kubernetes 集群
6.1.1 初始化集群环境
准备三台 Centos7.9 的 linux 机器。每台机器配置:4VCPU/4G 内存/60G 硬盘环境说明(centos7.9):
| IP | 主机名 | 角色 | 内存 | cpu |
|---|---|---|---|---|
| 192.168.1.63 | xuegod63 | master | 4G | 4vCPU |
| 192.168.1.64 | xuegod64 | worker | 4G | 4vCPU |
| 192.168.1.62 | xuegod62 | worker | 4G | 4vCPU |
1、配置静态 IP:每台机器的网络模式要一致,能互相通信,机器网卡名字也要统一。
![]() |
2、永久关闭 selinux
[root@localhost ~]# sed -i 's/SELINUX=enforcing/SELINUX=disabled/g'
/etc/selinux/config
##注意:修改 selinux 配置文件之后,重启机器,selinux 才能永久生效
[root@localhost~]# getenforce Disabled
SELinux(Security-Enhanced Linux)是一种基于 Mandatory Access Control(MAC)的安
全模块,它可以在 Linux 系统中提供强制访问控制机制。通过 SELinux,系统管理员可以对系统中的各种对象(如文件、进程、网络端口等)进行更加精细的安全控制,提高系统的安全性。
在安装 k8s 时,关闭 SELinux 是因为默认情况下 SELinux 会阻止 Kubernetes 一些操作,如kubelet 对容器文件的访问等。为了避免由于 SELinux 导致 Kubernetes 运行不正常,建议在安装Kubernetes 之前关闭 SELinux。
如果启用了 SELinux,需要针对 Kubernetes 进行特定的 SELinux 配置,以确保 Kubernetes
正常工作。具体的操作如下:
安装 policycoreutils-python 工具:
yum install -y policycoreutils-python
为 kubelet、kube-proxy 和 container runtime 的进程添加 SELinux 策略。例如,为
kubelet 添加策略的命令为:
semanage fcontext -a -t container_runtime_exec_t /usr/local/bin/kubelet
重载 SELinux 策略:
restorecon -R /usr/local/bin/kubelet
3、配置主机名
在 192.168.1.63 上执行如下:
hostnamectl set-hostname xuegod63 && bash
在 192.168.1.64 上执行如下:
hostnamectl set-hostname xuegod64 && bash
在 192.168.1.62 上执行如下:
hostnamectl set-hostname xuegod62 && bash
4、配置 hosts 文件:
修改每台机器的/etc/hosts 文件,在内容最后增加如下三行:
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 192.168.1.63 xuegod63
192.168.1.64 xuegod64
192.168.1.62 xuegod62
5、安装基础软件包
6、配置主机之间无密码登录
7、关闭所有主机 firewalld 防火墙
[root@xuegod63 ~]# systemctl stop firewalld ; systemctl disable firewalld [root@xuegod64 ~]# systemctl stop firewalld ; systemctl disable firewalld [root@xuegod62 ~]# systemctl stop firewalld ; systemctl disable firewalld
如果生产机器,防火墙开启,不能关,也可以,但是要放行一些端口: 6443:Kubernetes API Server
2379、2380:etcd 服务
10250、10255:kubelet 服务
10257:kube-controller-manager 服务
10259:kube-scheduler 服务
30000-32767:在物理机映射的 NodePort 端口
179、473、4789、9099:Calico 服务端口
如何在防火墙规则里放行端口:
firewall-cmd --zone=public --add-port=6443/tcp --permanent
##--zone 指定了防火墙规则所属的区域,--add-port 指定了要开放的端口号和协议,-- permanent 表示在重启后也会保留这个规则。
8、关闭交换分区 swap ##临时关闭交换分区
[root@xuegod63 ~]# swapoff -a [root@xuegod64 ~]# swapoff -a [root@xuegod62 ~]# swapoff -a
永久关闭:注释 swap 挂载

[root@xuegod63 ~]# vim /etc/fstab ##给 swap 这行开头加一下注释## [root@xuegod64 ~]# vim /etc/fstab
[root@xuegod62 ~]# vim /etc/fstab
交换分区(Swap)是为了在内存不足时,把部分内存的数据交换到硬盘上,以释放内存空间的一种机制。这样,即使物理内存不足,也可以保证系统运行的稳定性和正常性。
在安装 Kubernetes 时,需要禁用交换分区。这是因为 Kubernetes 在运行时需要使用大量的内存和 CPU 资源,如果系统开始使用交换分区,会导致性能下降,严重影响 Kubernetes 的正常运行。因此,为了保证 Kubernetes 的性能和稳定性,建议在安装 Kubernetes 时禁用交换分区。
9、修改内核参数:
[root@xuegod63 ~]# modprobe br_netfilter [root@xuegod64 ~]# modprobe br_netfilter [root@xuegod62 ~]# modprobe br_netfilter
modprobe 是一个 Linux 命令,它用于动态地加载内核模块到 Linux 内核中。br_netfilter 是Linux 内核模块之一,它提供了桥接网络设备和 Netfilter 之间的接口。Netfilter 是 Linux 内核中的一个框架,它可以在数据包通过网络协议栈时进行修改或过滤。
在 Kubernetes 中,br_netfilter 模块用于实现 Kubernetes 集群中的网络功能。通过加载
br_netfilter 模块,我们可以确保在 Kubernetes 集群中使用的 iptables 规则正确应用。
[root@xuegod63 ~]# cat > /etc/sysctl.d/k8s.conf <<EOF net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1 EOF
[root@xuegod63 ~]# sysctl -p /etc/sysctl.d/k8s.conf
[root@xuegod64 ~]# cat > /etc/sysctl.d/k8s.conf <<EOF net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1 EOF
[root@xuegod64 ~]# sysctl -p /etc/sysctl.d/k8s.conf
[root@xuegod62 ~]# cat > /etc/sysctl.d/k8s.conf <<EOF net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1 EOF
[root@xuegod62 ~]# sysctl -p /etc/sysctl.d/k8s.conf
1) net.bridge.bridge-nf-call-ip6tables: 当数据包经过网桥时,是否需要将 IPv6 数据包传递给
iptables 进行处理。将其设置为 1 表示启用。
2) net.bridge.bridge-nf-call-iptables: 当数据包经过网桥时,是否需要将 IPv4 数据包传递给
iptables 进行处理。将其设置为 1 表示启用。
3) net.ipv4.ip_forward: 是否允许主机转发网络包。将其设置为 1 表示启用。
这些参数是为了让 Linux 系统的网络功能可以更好地支持 Kubernetes 的网络组件(如
flannel、Calico 等),启用这些参数可以确保集群中的 Pod 能够正常通信和访问外部网络。
10、配置安装 docker 和containerd 的需要的阿里云 yum 源
11、配置安装 k8s 命令行工具需要的阿里云的 yum 源
12、配置时间同步:
[root@xuegod63 ~]# yum install -y ntp ntpdate [root@xuegod63 ~]# ntpdate cn.pool.ntp.org
##编写计划任务
[root@xuegod63 ~]# crontab -e
* * * * * /usr/sbin/ntpdate cn.pool.ntp.org
[root@xuegod64 ~]# yum install -y ntp ntpdate [root@xuegod64 ~]# ntpdate cn.pool.ntp.org
##编写计划任务
[root@xuegod64 ~]# crontab -e
* * * * * /usr/sbin/ntpdate cn.pool.ntp.org
[root@xuegod62~]# yum install -y ntp ntpdate [root@xuegod62 ~]# ntpdate cn.pool.ntp.org ##编写计划任务
[root@xuegod62 ~]# crontab -e
* * * * * /usr/sbin/ntpdate cn.pool.ntp.org
在 Kubernetes 集群中,各个组件之间的通信和协调都需要依赖时间的同步,如果集群中各节点时间不一致,可能会导致各种奇怪的问题,例如节点之间无法进行正确的 TLS 握手等。因此,建议在安装Kubernetes 集群之前,将集群中各个节点的时间同步到相同的时间源,保持时间的一致性。
13、安装 containerd
在 Kubernetes 集群中,containerd 是容器运行时,它的主要作用是负责管理节点上的容器,实现容器的创建、销毁、运行、暂停、恢复等操作。而 Pod 是 Kubernetes 中最基本的调度单元,一个Pod 包含一个或多个紧密关联的容器,在 Kubernetes 集群中,当一个 Pod 被调度到一个节点上时, Kubernetes 就会基于 containerd 在 pod 里运行容器。
在 xuegod63 上安装 containerd [root@xuegod63~]# yum install containerd.io-1.6.6 -y
Containerd 版本要按照我这个版本,其他版本有问题。生成 containerd 的配置文件:
[root@xuegod63~]# mkdir -p /etc/containerd
[root@xuegod63 ~]# containerd config default > /etc/containerd/config.toml
修改配置文件,打开/etc/containerd/config.toml
把 SystemdCgroup = false 修改成 SystemdCgroup = true
把 sandbox_image = "k8s.gcr.io/pause:3.6"修改成sandbox_image="registry.aliyuncs.com/google_containers/pause:3.7"
找到 config_path = "",修改成如下目录: config_path = "/etc/containerd/certs.d"
上述修改的内容解释说明:
1)SystemdCgroup = true 表示把 containerd 驱动变成systemd,跟kubelet 驱动保持一致。
2)pause 容器:当 Kubernetes 启动一个 Pod 时,会为其创建一个 Pause 容器。Pause 容器是一个极小的 Linux 容器,它不做任何事情,只是为 Pod 中的其他容器创建一个 Linux 命名空间和一个网络命名空间,并且共享了一个 IPC 命名空间,以便其他容器可以与之通信。
3)config_path = "/etc/containerd/certs.d":在这个目录下,可以存放容器镜像仓库的证书, 以便 containerd 可以安全地与容器镜像仓库进行通信。如果需要在 Kubernetes 中使用私有的容器镜像仓库,就需要将该仓库的证书放置到这个目录下,以便 containerd 可以正常地与该仓库进行通信。
创建/etc/crictl.yaml 文件
[root@xuegod63 ~]# cat > /etc/crictl.yaml <<EOF
runtime-endpoint: unix:///run/containerd/containerd.sock image-endpoint: unix:///run/containerd/containerd.sock timeout: 10
debug: false EOF
通过修改 /etc/crictl.yaml 中的配置,可以更改 cri-tools 工具的默认配置,以便更好地与容器运行时进行交互。在上述配置中,修改 runtime-endpoint 和 image-endpoint 可以指定 cri-tools 与 containerd 通信的套接字路径,这样就可以使用 cri-tools 对 Kubernetes 中的容器进行管理和调试。
cri-tools 是一组用于与容器运行时接口(CRI)交互的工具集。它包含了一些常用的命令,例如:
1) crictl:与 CRI 容器运行时交互的命令行工具,可以创建、删除和列出容器、镜像等。
2) critest:用于测试容器运行时的命令行工具,可以检查容器运行时是否符合 CRI 规范。
3) cri-resmgr:容器运行时资源管理器,用于管理容器的资源限制和调度。
4) cri-octool:Open Container Initiative(OCI)工具,用于检查 OCI 格式的镜像和容器。
| /etc/crictl.yaml 是 cri-tools 工具使用的配置文件,用于与 CRI 运行时通信。其中包含以下信 息: | |
|---|---|
| ·runtime-endpoint: CRI 运行时的 Unix 域套接字路径,用于与容器运行时(如 containerd)通信。 · image-endpoint: CRI 镜像仓库的 Unix 域套接字路径,用于与镜像运行时(如 containerd)通信。 · timeout: 指定 cri-tools 命令等待响应的超时时间,以秒为单位。 · debug: 指定是否启用调试模式,用于输出更详细的日志信息。 |
[root@xuegod63 ~]# mkdir /etc/containerd/certs.d/docker.io/ -p [root@xuegod63 ~]# vim /etc/containerd/certs.d/docker.io/hosts.toml ##写入如下内容:
[host."https://vh3bm52y.mirror.aliyuncs.com",host."https://registry.docker-cn.com"] capabilities = ["pull","push"]
备注:capabilities = ["pull","push"]表示从 dockerhub 和阿里云上上传和下载镜像都会加快速
度
启动 containerd、并设置开启自启动
[root@xuegod63 ~]# systemctl enable containerd --now
##在 xuegod64 上安装 containerd [root@xuegod64~]# yum install containerd.io-1.6.6 -y
生成 containerd 的配置文件:
[root@xuegod64~]# mkdir -p /etc/containerd
[root@xuegod64 ~]# containerd config default > /etc/containerd/config.toml
修改配置文件,打开/etc/containerd/config.toml
把 SystemdCgroup = false 修改成 SystemdCgroup = true
把 sandbox_image = "k8s.gcr.io/pause:3.6"修改成sandbox_image="registry.aliyuncs.com/google_containers/pause:3.7"
找到 config_path = "",修改成如下目录: config_path = "/etc/containerd/certs.d" 修改/etc/crictl.yaml 文件
[root@xuegod64 ~]# cat > /etc/crictl.yaml <<EOF
runtime-endpoint: unix:///run/containerd/containerd.sock image-endpoint: unix:///run/containerd/containerd.sock timeout: 10
debug: false EOF
[root@xuegod64 ~]# mkdir /etc/containerd/certs.d/docker.io/ -p [root@xuegod64 ~]# vim /etc/containerd/certs.d/docker.io/hosts.toml ##写入如下内容:
[host."https://vh3bm52y.mirror.aliyuncs.com",host."https://registry.docker-cn.com"] capabilities = ["pull","push"]
启动 containerd、并设置开启自启动
[root@xuegod64 ~]# systemctl enable containerd --now
##在 xuegod62 上安装 containerd [root@xuegod62~]# yum install containerd.io-1.6.6 -y
生成 containerd 的配置文件: [root@xuegod62~]# mkdir -p /etc/containerd
[root@xuegod62 ~]# containerd config default > /etc/containerd/config.toml
修改配置文件,打开/etc/containerd/config.toml
把 SystemdCgroup = false 修改成 SystemdCgroup = true
把 sandbox_image = "k8s.gcr.io/pause:3.6"修改成sandbox_image="registry.aliyuncs.com/google_containers/pause:3.7"
找到 config_path = "",修改成如下目录: config_path = "/etc/containerd/certs.d"
修改/etc/crictl.yaml 文件
[root@xuegod62 ~]# cat > /etc/crictl.yaml <<EOF
runtime-endpoint: unix:///run/containerd/containerd.sock image-endpoint: unix:///run/containerd/containerd.sock
timeout: 10 debug: false EOF
[root@xuegod62 ~]# mkdir /etc/containerd/certs.d/docker.io/ -p [root@xuegod62 ~]# vim /etc/containerd/certs.d/docker.io/hosts.toml ##写入如下内容:
[host."https://vh3bm52y.mirror.aliyuncs.com",host."https://registry.docker-cn.com"] capabilities = ["pull","push"]
启动 containerd、并设置开启自启动
[root@xuegod62 ~]# systemctl enable containerd --now
14、安装 docker-ce
K8s1.24 开始已经不支持 docker 了,但是还要把docker 安装在 k8s 节点上,主要是为了用
docker build 基于dockerfile 做镜像,docker 跟 containerd 不冲突、
[root@xuegod63 ~]# yum install docker-ce -y
[root@xuegod63 ~]# systemctl start docker && systemctl enable docker.service [root@xuegod63 ~]# tee /etc/docker/daemon.json << 'EOF'
{
"registry-mirrors":["https://vh3bm52y.mirror.aliyuncs.com","https://registry.docker- cn.com","https://docker.mirrors.ustc.edu.cn","https://dockerhub.azk8s.cn",&##34;http://hub- mirror.c.163.com"],
"exec-opts": ["native.cgroupdriver=systemd"]
} EOF
[root@xuegod63 ~]# systemctl restart docker
[root@xuegod64 ~]# yum install docker-ce -y
[root@xuegod64 ~]# systemctl start docker && systemctl enable docker.service [root@xuegod64 ~]# tee /etc/docker/daemon.json << 'EOF'
{
"registry-mirrors":["https://vh3bm52y.mirror.aliyuncs.com","https://registry.docker- cn.com","https://docker.mirrors.ustc.edu.cn","https://dockerhub.azk8s.cn",&##34;http://hub- mirror.c.163.com"],
"exec-opts": ["native.cgroupdriver=systemd"]
} EOF
[root@xuegod62 ~]# systemctl restart docker
[root@xuegod62 ~]# yum install docker-ce -y
[root@xuegod62 ~]# systemctl start docker && systemctl enable docker.service [root@xuegod62 ~]# tee /etc/docker/daemon.json << 'EOF'
{
"registry-mirrors":["https://vh3bm52y.mirror.aliyuncs.com","https://registry.docker- cn.com","https://docker.mirrors.ustc.edu.cn","https://dockerhub.azk8s.cn",&##34;http://hub- mirror.c.163.com"],
"exec-opts": ["native.cgroupdriver=systemd"]
} EOF
[root@xuegod62 ~]# systemctl restart docker
15、安装初始化 k8s 需要的组件
[root@xuegod63 ~]# yum install -y kubelet-1.26.0 kubeadm-1.26.0 kubectl-1.26.0 [root@xuegod63 ~]# systemctl enable kubelet
[root@xuegod64 ~]# yum install -y kubelet-1.26.0 kubeadm-1.25.0 kubectl-1.26.0 [root@xuegod64~]# systemctl enable kubelet
[root@xuegod62 ~]# yum install -y kubelet-1.26.0 kubeadm-1.25.0 kubectl-1.26.0 [root@xuegod62~]# systemctl enable kubelet
注:每个软件包的作用
kubelet: kubelet 是 Kubernetes 集群中的一个核心组件,是每个节点上的代理服务,负责与主控制节点通信,管理节点上的 Pod 和容器。
kubelet 的主要职责包括:
监控 pod 的状态并按需启动或停止容器、检查容器是否正常运行、与主控制节点通信,将节点状态和 Pod 状态上报给主控制节点、通过各种插件(如 volume 插件)与其他组件协同工作、管理容器的生命周期,包括启动、停止、重启等、拉取镜像
kubeadm:用于初始化 k8s 集群的命令行工具
kubectl: 用于和集群通信的命令行,通过 kubectl 可以部署和管理应用,查看各种资源,创建、删除和更新各种组件
6.1.2 初始化集群
备注:安装 k8s,物理机网段、pod 网段、service 网段不能冲突
使用 kubeadm 初始化 k8s 集群
[root@xuegod63~]# kubeadm config print init-defaults > kubeadm.yaml
备注:kubeadm.yaml 文件一定要自己手动生成,不要复制文档里的。
根据我们自己的需求修改配置,比如修改 imageRepository 的值,kube-proxy 的模式为
ipvs,初始化节点的时候需要指定 cgroupDriver 为 systemd
kubeadm.yaml 配置文件如下:
apiVersion: kubeadm.k8s.io/v1beta3
。。。
kind: InitConfiguration localAPIEndpoint:
advertiseAddress: 192.168.1.63 ##控制节点的 ip 地址
bindPort: 6443 nodeRegistration:
criSocket: unix:///run/containerd/containerd.sock ##指定 containerd 容器运行时
imagePullPolicy: IfNotPresent name: xuegod63 ##控制节点主机名taints: null
---
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 kubernetesVersion: 1.26.0 ##k8s 版本networking:
dnsDomain: cluster.local
podSubnet: 10.244.0.0/16 ##指定 pod 网段, 需要新增加这个
serviceSubnet: 10.96.0.0/12 ##指定 Service 网段
scheduler: {}
##在文件最后,插入以下内容,(复制时,要带着---):
---
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration mode: ipvs
---
apiVersion: kubelet.config.k8s.io/v1beta1 kind: KubeletConfiguration cgroupDriver: systemd
特别提醒:
1、nodeRegistration: criSocket: unix:///run/containerd/containerd.sock nodeRegistration 是在 Kubernetes 集群中注册节点的一种方式。在这个配置中,criSocket 表
示与此节点相关的容器运行时的地址,此处指的是使用 Containerd 作为容器运行时。
2、--image-repository registry.cn-hangzhou.aliyuncs.com/google_containers 表示从阿里云镜像仓库的的名为"google_containers"的命名空间中拉取容器镜像,因为 kubeadm 安装 k8s,控制节点的组件基于 pod 运行,所以需要镜像,默认的镜像仓库国内无法访问,所以需要指定阿里云镜像仓库,也可以把安装 k8s1.26 需要的镜像用 ctr -n=k8s.io images import 解压,这样就可以直接在 本地找镜像了。
3、podSubnet: 10.244.0.0/16 ##指定 pod 网段
serviceSubnet: 10.96.0.0/12 ##指定 Service 网段
在 k8s 集群中,pod 网段,service 网络,物理机网段不能冲突。
![]() |
4、mode: ipvs 表示 kube-proxy 代理模式是 ipvs,如果不指定 ipvs,会默认使用 iptables,但是 iptables 效率低,所以我们生产环境建议开启 ipvs,阿里云托管的 K8s,也提供 ipvs 模式,如下:
##基于 kubeadm.yaml 文件初始化 k8s
[root@xuegod63 ~]# ctr -n=k8s.io images import k8s_1.26.0.tar.gz
[root@xuegod64 ~]# ctr -n=k8s.io images import k8s_1.26.0.tar.gz [root@xuegod62 ~]# ctr -n=k8s.io images import k8s_1.26.0.tar.gz
备注:
1、k8s_1.26.0.tar.gz 是什么?
k8s_1.26.0.tar.gz 是基于 ctr -n=k8s.io images export <安装 k8s 组件需要的 k8s 镜像> k8s_1.26.0.tar.gz 生成的,这个压缩包里面包含的镜像只适合安装 k8s1.26 这个版本,如何安装其他版本,第一次安装不需要 ctr -n=k8s.io images import k8s_1.26.0.tar.gz 解压镜像,执行 kubeadm init 会自动把安装 k8s 组件需要的镜像拉下来,然后可以基于 ctr -n=k8s.io images import 命令把这个版本镜像打包,下次再安装此版本,就可以基于 ctr -n=k8s.io images import 解压了。
2、ctr 解压镜像为何加-n=k8s.io?
n=k8s.io 参数指定将镜像导入到 k8s.io 命名空间下,这通常是一个虚构的命名空间,用于导入
Kubernetes 官方发布的容器镜像。只要放到这个名称空间的镜像,才会被 k8s pod 找到。
[root@xuegod63 ~]# kubeadm init --config=kubeadm.yaml --ignore-preflight- errors=SystemVerification
安装完成。
配置 kubectl 的 config 文件,这样就可以基于 kubectl 操作 k8s 集群了。
[root@xuegod63 ~]# mkdir -p $HOME/.kube
[root@xuegod63 ~]# sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config [root@xuegod63 ~]# sudo chown $(id -u):$(id -g) $HOME/.kube/config [root@xuegod63 ~]# kubectl get nodes
| NAME | STATUS | ROLES | AGE VERSION |
|---|---|---|---|
| xuegod63 | NotReady | control-plane | 60s v1.26.0 |
此时集群状态还是 NotReady 状态,因为网络组件没有启动。
6.2 实战-工作节点加入 k8s 集群
##把 xuegod64 作为工作节点加入到 k8s 集群在 xuegod63 上查看加入节点的命令:
[root@xuegod63 ~]# kubeadm token create --print-join-command
显示如下:
kubeadm join 192.168.1.63:6443 --token s6f1ab.g6s71a2gn4d9pq5v \
--discovery-token-ca-cert-hash sha256:30092f3fd915c48b67695b8242a6196aebdde3a21c3bc521a8936bd628e30b0f
把 xuegod64 加入 k8s 集群:
[root@xuegod64 ~]# kubeadm join 192.168.1.63:6443 --token s6f1ab.g6s71a2gn4d9pq5v \
--discovery-token-ca-cert-hash sha256:30092f3fd915c48b67695b8242a6196aebdde3a21c3bc521a8936bd628e30b0f -- ignore-preflight-errors=SystemVerification
[root@xuegod63~]# kubectl get nodes
| NAME | STATUS | ROLES | AGE | VERSION |
|---|---|---|---|---|
| xuegod63 | NotReady | <none> |
97s | v1.26.0 |
| xuegod64 | NotReady | <none> |
99s | v1.26.0 |
可以看到 xuegod64 的 ROLES 角色为空,我们可以手工搭上标签,这里不影响集群正常工作。
注意:上面状态都是 notready 状态,说明没有安装网络插件互动:如何在普通的 node 节点上执行 kubectl 命令?
将 xuegod63 证书导入到 xuegod64 上,这样在 xuegod64 才可以使用 kubectl 命令管理 k8s
[root@xuegod64 ~]# mkdir ~/.kube
拷贝 xuegod63 的配置文件到 xuegod64
[root@xuegod63 ~]# scp ~/.kube/config 192.168.1.64:/root/.kube/
##把 xuegod62 作为工作节点加入到 k8s 集群在 xuegod63 上查看加入节点的命令:
[root@xuegod63 ~]# kubeadm token create --print-join-command
显示如下:
kubeadm join 192.168.1.63:6443 --token s6f1ab.g6s71a2gn4d9pq5v \
--discovery-token-ca-cert-hash sha256:30092f3fd915c48b67695b8242a6196aebdde3a21c3bc521a8936bd628e30b0f
把 xuegod62 加入 k8s 集群:
[root@xuegod62 ~]# kubeadm join 192.168.1.63:6443 --token s6f1ab.g6s71a2gn4d9pq5v \
--discovery-token-ca-cert-hash sha256:30092f3fd915c48b67695b8242a6196aebdde3a21c3bc521a8936bd628e30b0f -- ignore-preflight-errors=SystemVerification
[root@xuegod63 ~]# kubectl get nodes
| NAME | STATUS | ROLES | AGE | VERSION |
|---|---|---|---|---|
| xuegod63 | NotReady | <none> |
97s | v1.26.0 |
| xuegod64 | NotReady | <none> |
99s | v1.26.0 |
| xuegod62 | NotReady | <none> |
99s | v1.26.0 |
可以看到 xuegod62 的 ROLES 角色为空,我们可以手工搭上标签,这里不影响集群正常工作。
[root@xuegod63 ~]# kubectl label node xuegod62 node- role.kubernetes.io/worker=worker
扩展:kubeadm init 初始化k8s 集群具体流程:
1、准备工作
在执行 kubeadm init 命令之前,需要先准备好以下工作:
1)、在每个节点上安装容器和 Kubernetes 组件,如 kubeadm、kubelet 和 kubectl。 2)、确保节点之间可以互相通信,并且能够通过 DNS 解析域名。
3)、配置节点的网络,使得节点之间可以通过 IP 地址互相通信。
2、检查主机名
kubeadm 会检查节点的主机名是否符合 DNS 命名规范,即主机名必须只包含小写字母、数字和连字符,并且必须以字母或数字开头和结尾。
3、检查内核参数
kubeadm 会检查节点的内核参数是否符合 Kubernetes 的最佳实践,如:
1) 禁用 swap 分区;
2) 启用桥接流量;
3) 启用 IP 转发;
4) 禁用 SELinux
5) 如果节点的内核参数不符合要求,kubeadm 将输出警告信息,并提供相应的解决方法。
4、检查依赖软件
kubeadm 会检查是否安装了必要的依赖软件,如 iptables、ipvs 等,并在需要时自动安装。
6、检查容器运行时
kubeadm 会检查容器运行时,如 containerd 是否已安装并运行。如果容器运行时未安装或未运行,kubeadm 将输出错误信息。
7、生成证书和配置文件
kubeadm 会生成证书和配置文件,用于授权和加密 Kubernetes 集群的通信。这些文件包括:
1) CA 证书和私钥:用于签署和验证 Kubernetes 组件之间的通信;
2) API Server 证书和私钥:用于验证 API Server 的身份; 3)Kubernetes 服务账号和私钥:用于 Kubernetes 组件之间的认证; 4)kubeconfig 文件:用于配置 Kubernetes 组件的访问权限。
8、部署 etcd
kubeadm 会部署 etcd,用于存储 Kubernetes 集群的状态和元数据。etcd 是 Kubernetes 控制面板的核心组件之一,用于保存 Kubernetes 的配置信息和状态信息。
9、部署控制面板组件
kubeadm 会部署 Kubernetes 控制面板组件,如 kube-apiserver、kube-controller- manager、kube-scheduler 等。这些组件是 Kubernetes 集群的核心组件,用于控制集集群的状态和管理工作负载、服务发现等重要功能。
10、部署 kube-proxy、coredns
kubeadm 会部署 kubelet 和 kube-proxy、coredns
11、生成加入命令和配置文件
kubeadm 初始化 Kubernetes 集群成功后,将生成一个加入命令(join command),用于将 worker 节点加入集群。此外,kubeadm 还会生成默认的 Kubernetes 配置文件
/etc/kubernetes/admin.conf,用于配置 kubectl 命令行工具连接到 Kubernetes API 服务器。
6.3 安装 kubernetes 网络组件-Calico
Calico 是一个开源的 Kubernetes 网络插件。
Calico 的设计理念是基于 Linux 系统网络的,使用标准的 Linux 路由和 iptables 规则,以实现高性能的网络互联和安全隔离。它支持 IPv4 和 IPv6 双栈网络,并且可以轻松地与现有的数据中心网络集成,提供了丰富的网络策略功能,可以通过简单的标签选择器来定义容器间的网络隔离和通信规则。
Calico 的架构采用了一种分布式的方式,其中每个节点都运行一个 Calico 的网络代理组件,称为Felix,Felix 负责监听 Kubernetes API Server,获取节点和网络信息,并在本地维护一个路由表和iptables 规则集,用于控制容器的网络访问。当容器发生变化时,Felix 会自动更新路由表和 iptables 规则,确保网络互联和隔离的正确性。
Calico 还支持 BGP 协议,可以将 Kubernetes 集群扩展到跨数据中心和云提供商的多个节点上,从而实现灵活、可扩展的容器网络解决方案。
6.3.1 安装 Calico 网络组件
[root@xuegod63 ~]# ctr -n=k8s.io images import calico.tar.gz [root@xuegod64 ~]# ctr -n=k8s.io images import calico.tar.gz [root@xuegod62 ~]# ctr -n=k8s.io images import calico.tar.gz
上传 calico.yaml 到 xuegod63 中,使用 yaml 文件安装 calico 网络插件 。备注:
修改 calico.yaml 文件:
如果机器有多个网卡,需要在 calico 配置文件里指定可以联网的网卡,假如机器只有一个网卡,也要指定下,这样就直接找到可以用的网卡了。
找到 3645 行:增加如下配置:
- name: IP_AUTODETECTION_METHOD
![]() |
value: "interface=ens33"
[root@xuegod63 ~]# kubectl apply -f calico.yaml
注:在线下载配置文件地址是: https://docs.projectcalico.org/manifests/calico.yaml
拉取镜像需要一定时间,所以我们查看 pod 状态为 running 则安装成功。
[root@xuegod63 ~]# kubectl get pod --all-namespaces
再次查看集群状态。
[root@xuegod63 ~]# kubectl get nodes
| NAME | STATUS | ROLES | AGE | VERSION |
|---|---|---|---|---|
| xuegod63 | Ready | <none> |
97s | v1.26.0 |
| xuegod64 | Ready | <none> |
99s | v1.26.0 |
| xuegod62 | Ready | <none> |
99s | v1.26.0 |
6.4 kubeadm 初始化k8s 证书过期解决方案
查看 apiserver 证书有效时间:
[root@xuegod63 ~]# openssl x509 -in /etc/kubernetes/pki/apiserver.crt -noout -text
|grep Not
Not Before: Apr 25 14:10:09 2023 GMT
Not After : Apr 24 14:10:09 2024 GMT
延长证书过期时间
1. 把 update-kubeadm-cert.sh 文件上传到 xuegod63 节点
2. 在 xuegod63 上执行如下:
1)给 update-kubeadm-cert.sh 证书授权可执行权限[root@xuegod63 ~]# chmod +x update-kubeadm-cert.sh 2)执行下面命令,修改证书过期时间,把时间延长到 100 年[root@xuegod63 ~]# ./update-kubeadm-cert.sh all
3)在 xuegod63 节点查询 Pod 是否正常,能查询出数据说明证书签发完成
kubectl get pods -n kube-system
显示如下,能够看到 pod 信息,说明证书签发正常:
| ...... | |||||
|---|---|---|---|---|---|
| calico-node-b5ks5 | 1/1 | Running | 0 | 157m | |
| calico-node-r6bfr | 1/1 | Running | 0 | 155m | |
| calico-node-r8qzv | 1/1 | Running | 0 | 7h1m | |
| coredns-66bff467f8-5vk2q | 1/1 | Running | 0 | 7h | |
| ...... |
验证证书有效时间是否延长到 100 年
[root@xuegod63 ~]# openssl x509 -in /etc/kubernetes/pki/apiserver.crt -noout -text
|grep Not
Not Before: Apr 25 14:29:27 2023 GMT
Not After : Apr 1 14:29:27 2123 GMT
[root@xuegod63 ~]# openssl x509 -in /etc/kubernetes/pki/apiserver-etcd-client.crt - noout -text |grep Not
Not Before: Apr 25 14:29:27 2023 GMT
Not After : Apr 1 14:29:27 2123 GMT
6.5 测试 k8s 集群的 DNS 解析和网络是否正常
##把 busybox-1-28.tar.gz 上传到 xuegod64 和 xuegod62 节点,手动解压[root@xuegod64 ~]# ctr -n=k8s.io images import busybox-1-28.tar.gz [root@xuegod62 ~]# ctr -n=k8s.io images import busybox-1-28.tar.gz
[root@xuegod63 ~]# kubectl run busybox --image busybox:1.28 --restart=Never --rm
-it busybox -- sh
/ ## ping www.baidu.com
PING www.baidu.com (39.156.66.18): 56 data bytes
64 bytes from 39.156.66.18: seq=0 ttl=127 time=39.3 ms ##通过上面可以看到能访问网络,说明 calico 网络插件正常
/ ## 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
看到上面内容,说明 k8s 的 coredns 服务正常
总结:
10.1 Kubernetes 简介
10.2 使用 kubeadm 部署 Kubernetes 集群
10.3 实战-node 节点加入集群
10.4 安装 kubernetes 网络组件-Calico
10.5 kubeadm 初始化 k8s 证书过期解决方案





