一、环境规划
- 三台装有 CentOS 7 的 VMWare 虚拟机。
- 网络:NAT模式,用NAT模式可以确保机器在任何网络都能通过xshell连上去。
- 配置:4GB 内存/4vCPU/60G存储。
- 这是一个简单的,非高可用架构。
K8S集群角色 | IP | 主机名 | 安装的组件 |
控制节点 | 192.168.40.10 | k8s31master | apiserver、controller-manager、schedule、kubelet、etcd、kube-proxy、容器运行时、calico、kubelet |
工作节点 | 192.168.40.20 | k8s31node1 | Kube-proxy、calico、coredns、容器运行时、kubelet |
工作节点 | 192.168.40.30 | k8s31node2 | Kube-proxy、calico、coredns、容器运行时、kubelet |
二、环境准备
2.1、修改机器 IP 为静态 IP
- 查看系统使用哪个网卡
# ip address 的意思,查看IP,可以同时看网卡
ip addr
- 编辑网卡配置
vi /etc/sysconfig/network-scripts/ifcfg-ens33
master 配置如下:
TYPE=Ethernet
PROXY_METHOD=none
BROWSER_ONLY=no
BOOTPROTO=static
DEFROUTE=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_FAILURE_FATAL=no
IPV6_ADDR_GEN_MODE=stable-privacy
NAME=ens33
DEVICE=ens33
ONBOOT=yes
IPADDR=192.168.40.10
NETMASK=255.255.255.0
GATEWAY=192.168.40.2
DNS1=192.168.40.2
配置说明:
- TYPE=Ethernet: 表示这是一个以太网接口。
- PROXY_METHOD=none: 指定代理方法为“none”,即不使用代理。
- BROWSER_ONLY=no: 表示不仅限于浏览器使用,允许其他应用程序使用该网络接口。
- BOOTPROTO=static: 指定使用静态IP地址配置而不是通过DHCP动态获取。
- DEFROUTE=yes: 表示将默认路由设置为此接口。
- IPV4_FAILURE_FATAL=no: 表示IPv4连接失败不会导致致命错误。
- IPV6INIT=yes: 启用IPv6支持。
- IPV6_AUTOCONF=yes: 启用IPv6自动配置。
- IPV6_DEFROUTE=yes: 将IPv6默认路由设置为此接口。
- IPV6_FAILURE_FATAL=no: 表示IPv6连接失败不会导致致命错误。
- IPV6_ADDR_GEN_MODE=stable-privacy: 设置IPv6地址生成模式为稳定-隐私模式。
- NAME=ens33: 指定接口名称为ens33。
- DEVICE=ens33: 同样指定接口名称为ens33,可能是某些网络配置工具使用的参数。
- ONBOOT=yes: 表示系统启动时激活此接口。
- IPADDR=192.168.40.10: 设置接口的IPv4地址为192.168.40.10。
- NETMASK=255.255.255.0: 设置子网掩码为255.255.255.0,表示该子网中有256个IP地址。
- GATEWAY=192.168.40.2: 指定网关地址为192.168.40.2,用于连接其他网络。
- DNS1=192.168.40.2: 指定首选DNS服务器地址为192.168.40.2,用于解析域名。
- 修改配置文件之后需要重启网络服务才能使配置生效,重启网络服务命令如下:
service network restart
- 查看IP是否修改成功 ip addr
- 尝试用 XShell 连接一下,能连上,说明网络配置是OK的。
- node1、node2 的配置跟 master 类似。在 node1 上执行:
vi /etc/sysconfig/network-scripts/ifcfg-ens33
#--------------------------------
TYPE=Ethernet
PROXY_METHOD=none
BROWSER_ONLY=no
BOOTPROTO=static
DEFROUTE=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_FAILURE_FATAL=no
IPV6_ADDR_GEN_MODE=stable-privacy
NAME=ens33
DEVICE=ens33
ONBOOT=yes
# IP 改为 20
IPADDR=192.168.40.20
NETMASK=255.255.255.0
GATEWAY=192.168.40.2
DNS1=192.168.40.2
#--------------------------------
service network restart
- 在 node2 上执行:
vi /etc/sysconfig/network-scripts/ifcfg-ens33
#--------------------------------
TYPE=Ethernet
PROXY_METHOD=none
BROWSER_ONLY=no
BOOTPROTO=static
DEFROUTE=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_FAILURE_FATAL=no
IPV6_ADDR_GEN_MODE=stable-privacy
NAME=ens33
DEVICE=ens33
ONBOOT=yes
# IP 改为 30
IPADDR=192.168.40.30
NETMASK=255.255.255.0
GATEWAY=192.168.40.2
DNS1=192.168.40.2
#--------------------------------
service network restart
2.2、关闭 SELinux
在 master、node1、node2 都执行如下操作
- 修改 SELinux 配置文件
vi /etc/selinux/config
找到 SELINUX= 这一行,修改为 SELINUX=disabled
- 重启 Linux
修改 SELinux 配置文件之后,需要重启 Linux 机器,SELinux 配置才能永久生效。
sudo reboot
- 验证是否修改成功
显示 Disabled,就表示修改成功。
getenforce
为什么要关闭 SELinux?
SELinux 是 Linux 系统的一种安全机制,可以限制系统资源(如文件、网络等)的访问,提高系统的安全性。在 Kubernetes 运行过程中,需要访问系统资源,但 SELinux 可能会限制访问,从而影响 Kubernetes 的运行。因此,在安装 Kubernetes 时,需要关闭 SELinux,以避免它对 Kubernetes 的影响。
2.3、安装基础软件包
在 master、node1、node2 都执行如下操作
安装基础软件包需要用到 yum 源,CentOS 官方停止了对 CentOS 7 的支持,导致默认的仓库不再可用。你需要手动更新仓库配置文件以指向一个仍然活跃的镜像站。
- 备份 CentOS-Base.repo
mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup
- 修改 CentOS-Base.repo
如果系统有 wget 命令,可以直接
# 远程联网获取阿里云yum仓库配置
# -O output 的意思,用来指定输出文件
wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
不过如果大家的系统跟我一样,都是 Minimal 最小安装包的话,是没有 wget 的。可以尝试,在一台能联网的主机上,执行上面的命令,然后把输出的 CentOS-Base.repo 文件放到 /etc/yum.repos.d/ 下面。
就比如,我在 Windwos 系统下,下载了 CentOS-Base.repo,然后用 XFtp 上传到我的虚拟机里面。
大家也可以用 vi 命令,去修改 /etc/yum.repos.d/CentOS-Base.repo
vi /etc/yum.repos.d/CentOS-Base.repo
CentOS-Base.repo 内容如下:
# CentOS-Base.repo
#
# The mirror system uses the connecting IP address of the client and the
# update status of each mirror to pick mirrors that are updated to and
# geographically close to the client. You should use this for CentOS updates
# unless you are manually picking other mirrors.
#
# If the mirrorlist= does not work for you, as a fall back you can try the
# remarked out baseurl= line instead.
#
#
[base]
name=CentOS-$releasever - Base - mirrors.aliyun.com
failovermethod=priority
baseurl=http://mirrors.aliyun.com/centos/$releasever/os/$basearch/
http://mirrors.cloud.aliyuncs.com/centos/$releasever/os/$basearch/
gpgcheck=1
gpgkey=http://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-7
#released updates
[updates]
name=CentOS-$releasever - Updates - mirrors.aliyun.com
failovermethod=priority
baseurl=http://mirrors.aliyun.com/centos/$releasever/updates/$basearch/
http://mirrors.cloud.aliyuncs.com/centos/$releasever/updates/$basearch/
gpgcheck=1
gpgkey=http://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-7
#additional packages that may be useful
[extras]
name=CentOS-$releasever - Extras - mirrors.aliyun.com
failovermethod=priority
baseurl=http://mirrors.aliyun.com/centos/$releasever/extras/$basearch/
http://mirrors.cloud.aliyuncs.com/centos/$releasever/extras/$basearch/
gpgcheck=1
gpgkey=http://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-7
#additional packages that extend functionality of existing packages
[centosplus]
name=CentOS-$releasever - Plus - mirrors.aliyun.com
failovermethod=priority
baseurl=http://mirrors.aliyun.com/centos/$releasever/centosplus/$basearch/
http://mirrors.cloud.aliyuncs.com/centos/$releasever/centosplus/$basearch/
gpgcheck=1
enabled=0
gpgkey=http://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-7
#contrib - packages by Centos Users
[contrib]
name=CentOS-$releasever - Contrib - mirrors.aliyun.com
failovermethod=priority
baseurl=http://mirrors.aliyun.com/centos/$releasever/contrib/$basearch/
http://mirrors.cloud.aliyuncs.com/centos/$releasever/contrib/$basearch/
gpgcheck=1
enabled=0
gpgkey=http://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-7
- 清理
yum
缓存并重新生成缓存
yum clean all && yum makecache
- yum 安装基础软件包
yum install -y device-mapper-persistent-data lvm2 net-tools nfs-utils lrzsz gcc gcc-c++ make cmake libxml2-devel openssl-devel curl curl-devel unzip sudo ntp libaio-devel wget vim ncurses-devel autoconf automake zlib-devel python-devel epel-release openssh-server socat ipvsadm conntrack telnet
软件说明:
- device-mapper-persistent-data:设备映射器持久数据,用于设备映射器的持久化存储。
- lvm2:逻辑卷管理器,用于管理逻辑卷。
- net-tools:包含了一系列网络工具,如 ifconfig 和 netstat,用于配置和管理网络。
- nfs-utils:NFS(Network File System)工具,用于搭建和管理NFS网络文件系统。
- lrzsz:提供了用于在UNIX系统和计算机终端之间传输文件的工具。
- gcc:GNU编译器集合,用于编译C语言和C++程序。
- gcc-c++:GNU编译器集合的C++编译器。
- make:用于自动化编译和安装程序的工具。
- cmake:用于跨平台软件构建的工具。
- libxml2-devel:libxml2的开发库,用于开发基于XML的应用程序。
- openssl-devel:OpenSSL的开发库,用于在应用程序中使用加密和安全功能。
- curl:用于从命令行或脚本中进行URL数据传输的工具。
- curl-devel:libcurl的开发库,用于在应用程序中使用libcurl进行URL数据传输。
- unzip:用于解压缩ZIP文件的命令行工具。
- sudo:用于以其他用户的身份执行命令的工具,通常用于提升权限。
- ntp:网络时间协议客户端,用于同步系统时钟。
- libaio-devel:异步I/O(AIO)的开发库,用于开发异步I/O应用程序。
- wget:用于从网络下载文件的命令行工具。
- vim:文本编辑器,通常用于在命令行中编辑文本文件。
- ncurses-devel:ncurses的开发库,用于在文本终端上显示复杂的图形界面。
- autoconf:用于自动配置软件包的工具。
- automake:用于自动生成Makefile文件的工具。
- zlib-devel:zlib的开发库,用于在应用程序中进行数据压缩和解压缩。
- python-devel:Python的开发库,用于在应用程序中使用Python编程语言。
- epel-release:Extra Packages for Enterprise Linux (EPEL)软件源的发布包,用于安装额外的软件包。
- openssh-server:OpenSSH服务器,用于远程访问和管理服务器。
- socat:多功能的网络工具,用于在不同类型的网络连接之间传输数据。
- ipvsadm:IPVS管理工具,用于配置Linux内核中的IPVS(IP Virtual Server)负载均衡。
- conntrack:用于查看和管理Linux内核连接跟踪表的工具。
- telnet:用于通过Telnet协议连接到远程主机的工具。
2.4、配置主机名
# && bash 的意思是直接刷新终端显示的主机名。
# master 执行
hostnamectl set-hostname k8s31master && bash
# node1 执行
hostnamectl set-hostname k8s31node1 && bash
# node2 执行
hostnamectl set-hostname k8s31node2 && bash
2.5、配置主机 hosts 文件
使不同机器相互之间可以通过主机名互相访问
在 master、node1、node2 都执行如下操作
vim /etc/hosts
#-------------------------
192.168.40.10 k8s31master
192.168.40.20 k8s31node1
192.168.40.30 k8s31node2
#-------------------------
# 三台都 ping 看看,都能 ping 通,说明主机名配置OK
ping k8s31master
ping k8s31node1
ping k8s31node2
修改之后的文件如下:
2.6、关闭防火墙
在 master、node1、node2 都执行如下操作
# 分号表示两条命令之间是并行关系,前一条命令执行失败不影响后一条命令的执行。
# stop 临时关闭防火墙,系统重启后还在
# disable 永久禁用防火墙
systemctl stop firewalld ; systemctl disable firewalld
# 关闭完查看防火墙状态
systemctl status firewalld
dead 就表示关闭成功。
2.7、配置时间同步
在 master、node1、node2 都执行如下操作
因为是虚拟机环境,可能虚拟机关闭或者挂起后,虚拟机时间跟当前时间就不同步了。
所以有必要配置一下时间同步。
- 安装 ntpdate 工具
ntpdate 的全称是 Network Time Protocol Date。它是一个用于通过网络同步计算机系统时间的工具,基于 Network Time Protocol (NTP) 协议工作。 ntpdate 工具可以从 NTP 服务器获取准确的时间,并调整本地系统的时钟以匹配该时间。它通常被用作一次性的时间同步命令,在某些情况下,比如系统启动时或手动需要更新系统时间时使用。不过需要注意的是,ntpdate 已经被认为是过时的工具,在较新的 Linux 发行版中推荐使用 chrony 或 systemd-timesyncd 来代替,这些工具提供了更先进的特性和服务管理功能,可以持续保持系统时间的准确性。
yum install -y ntpdate
- 把时间同步做成计划任务
因为 ntpdate 命令是一次性的,所以需要把它做成计划任务,每分钟同步一次网络时间。
crontab -e
# cron table 计划任务表
# -e edit 的意思,该命令意思是编辑当前用户 root 的计划任务
# 计划任务表的编辑方式,跟 VIM 是一摸一样的
# i:INSERT
# Esc:退出编辑模式
# :wq 保存并退出
* * * * * /usr/sbin/ntpdate cn.pool.ntp.org
# 该配置的意思是每分钟同步一次网络时间
- 重启 crond 服务
systemctl restart crond
2.8、关闭交换分区swap,提升性能
Swap交换分区是一种在计算机中使用的虚拟内存技术。当物理内存不足以容纳当前运行的程序时,操作系统将会把一部分内存空间暂时转移到硬盘上,以便为当前程序提供运行所需的内存空间。这个过程就称为交换。交换分区(Swap Partition)就是硬盘上专门预留给操作系统进行交换的一块空间。
交换分区的使用可以有效避免程序因为内存不足而崩溃或运行缓慢的问题,但是硬盘的读写速度比内存要慢得多,因此交换分区的使用会对系统的性能产生一定的影响。
在 Kubernetes 运行过程中,需要频繁地使用内存和磁盘等系统资源。如果使用了交换分区,会导致 Kubernetes 的运行速度变慢,从而影响整个集群的性能。因此,在安装 Kubernetes 时,通常会建议关闭交换分区。
- 查看交换分区大小
free -h
# -h human 以人类可阅读的方式
在 master、node1、node2 都执行如下操作
- 临时关闭 swap
swapoff -a
# -a all 的意思,禁用全部 swap,不管是 swap 分区,还是 swap 文件
- 永久关闭 swap
为了确保系统重启后swap不会再次自动启用,你需要编辑 /etc/fstab
文件,注释掉(或移除)与swap相关的行。找到包含swap
类型的行,并在其前面加上#
以注释掉它:
vim /etc/fstab
# fstab file system table 文件系统表
2.9、修改机器内核参数
在 master、node1、node2 都执行如下操作
- 加载名为
br_netfilter
的内核模块
modprobe br_netfilter
modprobe br_netfilter 是一条 Linux 命令,用于加载名为 br_netfilter 的内核模块。这个模块对于桥接网络(bridge networking)和网络命名空间(network namespaces)之间的交互非常重要,尤其是在涉及容器化技术(如 Docker 和 Kubernetes)时。
详细解释
• modprobe:这是一个用来管理 Linux 内核模块的命令行工具。它可以用来加载、卸载以及查看当前加载的内核模块。当使用 modprobe 加载一个模块时,它还会自动处理该模块依赖的其他模块。
• br_netfilter:这是特定的内核模块名称。br_netfilter 模块的作用是为网桥(bridge)提供 Netfilter 集成支持。Netfilter 是 Linux 内核中的框架,它允许各种网络相关的操作,比如包过滤(packet filtering)、NAT(Network Address Translation)、连接跟踪(connection tracking)等。为什么需要加载 br_netfilter?
在某些情况下,默认情况下 br_netfilter 模块可能不会自动加载,特别是当你想要在基于 Linux Bridge 的网络环境中应用 iptables 规则来控制流量时。例如,在 Docker 或 Kubernetes 等容器平台中,为了确保容器间的网络通信能够被正确地过滤和路由,通常需要加载 br_netfilter 模块。
加载 br_netfilter 模块后,你可以:
- 在桥接接口上应用 iptables 规则。
- 对通过桥接设备的数据包执行 NAT。
- 启用或配置 IP 连接跟踪(ip_conntrack)功能。
- 检查是否已加载
要检查 br_netfilter
模块是否已经加载,可以使用以下命令:
lsmod | grep br_netfilter
如果没有输出,则说明该模块尚未加载;如果有输出,则表示模块已经在运行。
- 创建内核参数配置文件
在 sysctl.d 目录下,创建 k8s.conf 配置文件。
vim /etc/sysctl.d/k8s.conf
文件内容如下:
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
参数说明:
- net.bridge.bridge-nf-call-ip6tables = 1:这个参数启用了 IPv6 的iptables netfilter hook,允许 Linux 内核在网络层面上进行 IPv6 数据包的过滤和处理。在 Kubernetes 中,这个参数通常需要启用,因为 Kubernetes 网络通常是基于 iptables 实现的,而且在一些网络插件中可能会使用到 IPv6。这个参数的启用确保了 Linux 内核在处理 IPv6 数据包时会经过 iptables 过滤,从而确保网络功能的正常运行。
- net.bridge.bridge-nf-call-iptables = 1:这个参数启用了 IPv4 的iptables netfilter hook,类似于前一个参数,但是针对 IPv4 数据包。它允许 Linux 内核在网络层面上进行 IPv4 数据包的过滤和处理。在 Kubernetes 中,这个参数通常需要启用,因为 Kubernetes 网络通常是基于 iptables 实现的,而且在一些网络插件中可能会使用到 Ipv4。这个参数的启用确保了 Linux 内核在处理 Ipv4 数据包时会经过 iptables 过滤,从而确保网络功能的正常运行。
- net.ipv4.ip_forward = 1:这个参数启用了 Linux 内核的 IP 转发功能,允许 Linux 主机将收到的数据包从一个网络接口转发到另一个网络接口。在 Kubernetes 中,Pod 可能会跨越多个节点进行通信。例如,当一个 Pod 需要访问另一个 Pod 或外部服务时,网络流量可能需要通过不同的节点进行路由。启用 IP 转发功能允许 Linux 主机将收到的数据包从一个网络接口转发到另一个网络接口,从而实现跨节点通信。
- 将自定义参数加载到内核
sysctl -p /etc/sysctl.d/k8s.conf
# -p, --load[=<file>] read values from file
# 从文件中加载配置参数到内核
2.10、容器 相关一:配置安装 docker 和 containerd 需要的repo源
在 master、node1、node2 都执行如下操作
# 安装 yum-utils 工具以便能使用 yum-config-manager 命令
yum install -y yum-utils
# 添加 repo
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# 清理 yum 缓存并重新生成缓存
yum clean all && yum makecache
执行完会在 /etc/yum.repos.d/ 目录下,新增一个 docker-ce.repo 配置文件。
2.11、容器 相关二:安装 containerd 服务
在 Kubernetes 中,每个节点都需要运行一个容器运行时(containerd),用于管理和运行容器。就像我们在电脑上需要安装一个软件才能打开一个文件一样,在 Kubernetes 中需要安装一个容器运行时才能在pod中运行容器。
在 master、node1、node2 都执行如下操作
yum install -y containerd.io-1.6.22*
cd /etc/containerd
rm -rf *
修改 config.toml 配置文件里的 harbor 的 IP 地址,变成自己真实环境 harbor 的 IP
将修改完的 toml 文件,上传到 master、node1、node2 /etc/containerd
启动、开机自启动 containerd
systemctl start containerd && systemctl enable containerd
2.12、容器 相关三:安装 docker 用来制作镜像
在 master、node1、node2 都执行如下操作
- 安装 docker、启动、开机自启动
yum install -y docker-ce-24.0.6
systemctl start docker && systemctl enable docker
- 配置镜像加速
vim /etc/docker/daemon.json
# 修改 harbor IP
# registry-mirrors 第一个为 自己的 阿里云镜像加速地址
{
"registry-mirrors":["https://n62ddycc.mirror.aliyuncs.com","https://docker.lmirror.top","https://docker.m.daocloud.io", "https://hub.uuuadc.top","https://docker.anyhub.us.kg","https://dockerhub.jobcher.com","https://dockerhub.icu","https://docker.ckyl.me","https://docker.awsl9527.cn","https://docker.laoex.link"],
"insecure-registries":["192.168.40.100","harbor"]
}
- 重启 docker
systemctl daemon-reload && systemctl restart docker
- 查看 docker 状态
systemctl status docker
三、安装 k8s
3.1、安装初始化k8s需要的软件包
在 master、node1、node2 都执行如下操作
-
配置安装k8s组件需要的阿里云的repo源
cat > /etc/yum.repos.d/kubernetes.repo <<EOF
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.31/rpm/
enabled=1
gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.31/rpm/repodata/repomd.xml.key
EOF
yum clean all && yum makecache
命令解释:
cat << EOF
xxxxxxxxxx
EOF
是一种 "Here Document" 语法,是一种将多行文本传递给命令的方式。
在这里,EOF 作为边界标记,告诉 shell 哪些文本应该被传递给 cat 命令。当 shell 遇到第二个 EOF 时,它知道 Here Document 的内容结束了。
Here Document 的结束标记必须单独位于一行,并且不能有任何前导空白字符。否则,shell 不会识别它为结束标记。
> 是覆盖重定向符号。
整句命令的意思是,将 << EOF xxxxx EOF 包裹起来的多行文本,作为 cat 命令的输入。
紧接着用 > 将 cat 命令的输出(原来是要在屏幕上打印出来)重定向到文件 /etc/yum.repos.d/kubernetes.repo。
- 安装软件包
yum install -y kubeadm-1.31.3 kubelet-1.31.3 kubectl-1.31.3
kubeadm: kubeadm是一个工具,用来初始化k8s集群。
kubelet: 安装在集群所有节点上,用于启动Pod的,kubeadm安装k8s,k8s控制节点和工作节点的组件,都是基于pod运行的,只要pod启动,就需要kubelet。
kubectl: 通过 kubectl 可以部署和管理应用,查看各种资源,创建、删除和更新各种组件。
3.2、kubeadm 初始化 k8s 集群
在 master 执行如下操作
- 生成默认配置文件
kubeadm config print init-defaults > kubeadm.yaml
这条命令是用来生成 kubeadm 初始化集群时使用的默认配置文件,并将其输出保存到名为 kubeadm.yaml 的文件中。具体来说,它由以下几个部分组成:
- kubeadm config print init-defaults: 这是 kubeadm 提供的一个子命令,用于打印出 kubeadm init 命令的默认配置。这个配置包含了创建和初始化一个新的 Kubernetes 集群所需的各种参数和设置。
- >: 这是一个重定向操作符,用于将命令的标准输出(stdout)重定向到一个文件中。如果文件已经存在,它会被覆盖;如果不存在,则会创建新文件。
- kubeadm.yaml: 这是你指定的目标文件名,命令执行后,kubeadm 默认配置将会被写入这个文件。
当你运行这条命令时,kubeadm 会根据当前系统环境以及你所使用的 kubeadm 版本生成一套适合用来初始化 Kubernetes 集群的默认配置,并且这些配置信息会被保存到 kubeadm.yaml 文件中。之后,你可以编辑这个文件以调整集群初始化过程中的各项参数,比如 API 服务器的端口、网络插件的配置等,然后再使用 kubeadm init --config=kubeadm.yaml 来初始化你的 Kubernetes 集群。
这种方法允许用户在启动集群之前仔细检查和定制所有必要的设置,从而确保集群按照预期的方式建立。此外,拥有一个配置文件也便于版本控制和文档化,使得集群的配置更加透明和易于管理。
- 修改配置文件
apiVersion: kubeadm.k8s.io/v1beta4
bootstrapTokens:
- groups:
- system:bootstrappers:kubeadm:default-node-token
token: abcdef.0123456789abcdef
ttl: 24h0m0s
usages:
- signing
- authentication
kind: InitConfiguration
localAPIEndpoint:
advertiseAddress: 192.168.40.10 # 控制节点IP
bindPort: 6443
nodeRegistration:
criSocket: unix:///var/run/containerd/containerd.sock
imagePullPolicy: IfNotPresent
imagePullSerial: true
name: k8s31master # 控制节点主机名
taints: null
timeouts:
controlPlaneComponentHealthCheck: 4m0s
discovery: 5m0s
etcdAPICall: 2m0s
kubeletHealthCheck: 4m0s
kubernetesAPICall: 1m0s
tlsBootstrap: 5m0s
upgradeManifests: 5m0s
---
apiServer: {}
apiVersion: kubeadm.k8s.io/v1beta4
caCertificateValidityPeriod: 87600h0m0s
certificateValidityPeriod: 8760h0m0s
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
controllerManager: {}
dns: {}
encryptionAlgorithm: RSA-2048
etcd:
local:
dataDir: /var/lib/etcd
imageRepository: registry.cn-hangzhou.aliyuncs.com/google_containers# 指定阿里云镜像仓库地址,这样在安装k8s时,会自动从阿里云镜像仓库拉取镜像
kind: ClusterConfiguration
kubernetesVersion: 1.31.0
networking:
dnsDomain: cluster.local
podSubnet: 10.244.0.0/16
serviceSubnet: 10.96.0.0/12
proxy: {}
scheduler: {}# 增加以下几行
---
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: ipvs
---
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
cgroupDriver: systemd
kubeadm.yaml 文件说明:
1、localAPIEndpoint: Kubernetes API Server 监听的地址和端口
advertiseAddress: 指定控制节点的 IP 地址,即 API Server 暴露给集群内其他节点的地址。
bindPort: 指定 API Server 监听的端口,默认为 6443。
nodeRegistration: 控制节点的注册信息。
criSocket: 指定容器运行时使用的 CRI Socket,即容器与 Kubernetes API Server 之间的通信通道。这里指定为 Containerd 的 Socket 地址。
imagePullPolicy: 指定容器镜像拉取策略,这里指定为如果本地已有镜像则不拉取。
name: 控制节点的名称,主机名
taints: 控制节点的 taints,即节点的标记,用于限制哪些 Pod 可以调度到该节点。这里指定为空,即不对 Pod 的调度进行限制。
2、podSubnet: 10.244.0.0/16 #指定pod网段, 需要新增加这个
serviceSubnet: 10.96.0.0/12 #指定Service网段。
在Kubernetes集群中,每个Pod都会被分配一个IP地址,这些IP地址需要从一个预定义的IP地址池中分配。 podSubnet参数用于指定Pod IP地址池的范围,它定义了Pod的IP地址范围,例如10.244.0.0/16表示IP地址从10.244.0.1到10.244.255.255。10.244.0.0/16可用的 IP 地址数量是 2^16−2=65536−2=65534。
同样地,Kubernetes服务(Service)也会被分配一个IP地址,用于暴露Kubernetes服务的端口。 serviceSubnet参数用于指定Service IP地址池的范围,它定义了Service的IP地址范围,例如10.96.0.0/12表示IP地址从10.96.0.1到10.96.255.255。/12 表示了网络的子网掩码长度,即前 12 位是网络地址,剩余的 32-12=20 位是主机地址。 对于一个 /12 的网络,总共有 2^20−2 个可用的 IP 地址,因为其中两个 IP 地址分别用作网络地址和广播地址。所以可用的 IP 地址数量是 2^20−2=1048576−2=1048574。
3、mode: ipvs 表示kube-proxy代理模式是ipvs
如果不指定ipvs,会默认使用iptables,开启IPVS可以提高Kubernetes集群的性能和可靠性。IPVS是一个高性能的负载均衡器,与Kubernetes Service一起使用,可以在Pod之间分配负载。相比于Kubernetes自带的iptables模式,IPVS模式在处理大量流量时具有更好的性能和可靠性。此外,IPVS还支持四层和七层协议的负载均衡,能够满足更多的应用场景需求。因此,在安装Kubernetes集群时,建议开启IPVS以提高集群性能和可靠性。
- 初始化
kubeadm init --config=kubeadm.yaml --ignore-preflight-errors=SystemVerification
看到如下,证明成功。
- 保留截图中 kubeadm join 命令(等会儿要用)
kubeadm join 192.168.40.10:6443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:169902d43298c8d80c9f397ab98f3dce9e7e3b8b7d626ba87e798f04f8828e70
3.3、配置kubectl的配置文件config
在 master 执行如下操作
mkdir -p $HOME/.kube
ls -a
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
kubectl get nodes
3.4、扩容k8s集群--添加第一个工作节点 node1
- 在 node1 执行如下操作
kubeadm join 192.168.40.10:6443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:169902d43298c8d80c9f397ab98f3dce9e7e3b8b7d626ba87e798f04f8828e70
- 在 master 查看集群状况
kubectl get nodes
- 给 node1 节点打标签
kubectl label nodes k8s31node1 node-role.kubernetes.io/work=work
kubectl get nodes
kubectl get pods -n kube-system -owide
3.5、扩容k8s集群--添加第二个工作节点 node2
- 在 node2 执行如下操作
kubeadm join 192.168.40.10:6443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:169902d43298c8d80c9f397ab98f3dce9e7e3b8b7d626ba87e798f04f8828e70
- 在 master 查看集群状况
kubectl get nodes
- 给 node2 节点打标签
kubectl label nodes k8s31node1 node-role.kubernetes.io/work=work
kubectl get nodes
3.6、安装kubernetes网络组件-Calico
- 将 calico.yaml上传到 master 节点上
- 确保配置文件里面的 IP_AUTODETECTION_METHOD 参数与你的网卡一致
- kubectl 进行安装
kubectl apply -f calico.yaml
kubectl get pods -n kube-system -owide
有可能拉不到 calico 镜像。
解决方法一:宿主机开代理,行不通。
解决方法二:
找一台能上外网的机器,照着 calico.yaml 需要的镜像,拉取并 save 出来 calico.tar.gz。
将 calico.tar.gz 上传到 master、node1、node2
在 master、node1、node2 执行
ctr -n=k8s.io images import calico.tar.gz
再次执行
kubectl apply -f calico.yaml