Skip to content

第六章-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:每台机器的网络模式要一致,能互相通信,机器网卡名字也要统一。

img

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 挂载

imgimg[root@xuegod63 ~]# vim /etc/fstab ##给 swap 这行开头加一下注释## [root@xuegod64 ~]# vim /etc/fstab

[root@xuegod62 ~]# vim /etc/fstab

img

交换分区(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 驱动保持一致。

img2)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 网络,物理机网段不能冲突。

img

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

安装完成。

img

配置 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 角色为空,我们可以手工搭上标签,这里不影响集群正常工作。

[root@xuegod63 ~]#  kubectl label node xuegod64 node- role.kubernetes.io/worker=worker

注意:上面状态都是 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

img

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

img

再次查看集群状态。

[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 证书过期解决方案