文档使用rocky9.5系统搭建模拟。
搭建环境建议将我分享的网盘资源下载,或自己有VPN也可。否则搭建环境中下载或拉取镜像会超时,或者很慢。
通过网盘分享的文件:linux系统安装kubernetes资源分享链接(镜像1.31.4))calico配置文件
链接: https://pan.baidu.com/s/1_iwIXiRoGKsHi_uqnLGo_g?pwd=1610 提取码: 1610(自动填写)
--来自百度网盘超级会员v5的分享。
https://pan.baidu.com/s/1_iwIXiRoGKsHi_uqnLGo_g?pwd=1610
准备工作
- 兼容的 Linux 主机。Kubernetes 项目提供了 Linux 发行版的通用说明 基于 Debian 和 Red Hat,以及那些没有包管理器的发行版。
- 每台计算机 2 GB 或更多的 RAM(如果少于 RAM 将为您的应用程序留下很少的空间)。
- 2 个或更多 CPU 用于 control plane 计算机。
- 集群中所有计算机之间的完全网络连接(公共或专用网络都可以)。(可以ping通外网即可。)
- 每个节点的唯一主机名、MAC 地址和 product_uuid。(文章下面查看。)
-
Kubernetes 要求系统内核版本至少为 3.10 或更高。此外,还需要确保系统具有以下内核模块:
- iptables 和 ipvs:用于网络功能
- overlay 和 br_netfilter:用于容器网络功能
- cgroup 模块:用于资源管理
执行下面脚本查看准备是否符合:(执行完一次脚本之后会自动删除。)
bash -c 'cat > /kubcheck.sh' << 'jingyu'
#!/bin/bash
# 定义颜色
GREEN='\033[0;32m'
RED='\033[0;31m'
NC='\033[0m' # 恢复默认颜色
# 检查操作系统类型
echo -e "=== 检查操作系统类型 ==="
if [ -f /etc/os-release ]; then
. /etc/os-release
echo -e "操作系统: ${GREEN}${NAME} ${VERSION}${NC}"
else
echo -e "操作系统: ${RED}未知${NC}"
fi
# 检查内存大小
echo -e "\n=== 检查内存大小 ==="
MEMORY=$(grep MemTotal /proc/meminfo | awk '{print $2}')
MEMORY_GB=$((MEMORY / 1024 / 1024))
if [ $MEMORY_GB -ge 2 ]; then
echo -e "内存大小: ${GREEN}${MEMORY_GB} GB${NC}"
else
echo -e "内存大小: ${RED}${MEMORY_GB} GB(需要至少 2 GB)${NC}"
fi
# 检查 CPU 数量
echo -e "\n=== 检查 CPU 数量 ==="
CPU_COUNT=$(grep -c ^processor /proc/cpuinfo)
if [ $CPU_COUNT -ge 2 ]; then
echo -e "CPU 数量: ${GREEN}${CPU_COUNT}${NC}"
else
echo -e "CPU 数量: ${RED}${CPU_COUNT}(需要至少 2 个 CPU)${NC}"
fi
# 检查网络连接
echo -e "\n=== 检查网络连接 ==="
if ping -c 1 www.baidu.cn &> /dev/null; then
echo -e "网络连接: ${GREEN}正常${NC}"
else
echo -e "网络连接: ${RED}失败${NC}"
fi
# 检查主机名
echo -e "\n=== 检查主机名 ==="
HOSTNAME=$(hostname)
if [ -n "$HOSTNAME" ]; then
echo -e "主机名: ${GREEN}${HOSTNAME}${NC}"
else
echo -e "主机名: ${RED}未设置${NC}"
fi
# 检查 MAC 地址
echo -e "\n=== 检查 MAC 地址 ==="
MAC_ADDRESS=$(ip link show | grep link/ether | awk '{print $2}' | head -n 1)
if [ -n "$MAC_ADDRESS" ]; then
echo -e "MAC 地址: ${GREEN}${MAC_ADDRESS}${NC}"
else
echo -e "MAC 地址: ${RED}未找到${NC}"
fi
# 检查 product_uuid
echo -e "\n=== 检查 product_uuid ==="
PRODUCT_UUID=$(cat /sys/class/dmi/id/product_uuid 2>/dev/null)
if [ -n "$PRODUCT_UUID" ]; then
echo -e "product_uuid: ${GREEN}${PRODUCT_UUID}${NC}"
else
echo -e "product_uuid: ${RED}未找到${NC}"
fi
# 检查端口是否开放(根据需要自定义端口)
echo -e "\n=== 检查端口是否开放 ==="
PORTS=("6443" "2379" "2380" "10250" "10251" "10252") # Kubernetes 常用端口
for PORT in "${PORTS[@]}"; do
if ss -tuln | grep ":$PORT" &> /dev/null; then
echo -e "端口 ${PORT}: ${GREEN}已开放${NC}"
else
echo -e "端口 ${PORT}: ${RED}未开放${NC}"
fi
done
echo -e "=== 检查完成 ==="
# 脚本执行完成后删除自身
echo -e "=== 已自动删除脚本 ==="
rm -- "$0"
echo -e "脚本已删除。"
jingyu
示例:
系统是最小化安装,需要一些环境工具依赖包。
dnf -y update && dnf -y groupinstall "development tools" "base" && dnf -y install epel-release && dnf -y install htop tree lrzsz wget
1、安装kubernetes集群所需依赖包
packages=(vim* htop tree lrzsz wget sysstat bash-completion curl jq openssh-server openssh-clients net-tools ipset policycoreutils-python-utils telnet iputils ipvsadm conntrack-tools chrony gcc make automake autoconf libtool pcre pcre-devel zlib zlib-devel openssl openssl-devel yum-utils dnf-plugins-core ansible* bzip2-devel libffi-devel readline-devel sqlite-devel tk-devel nfs-utils xz-devel expat-devel libuuid-devel libblkid-devel libselinux-devel libmount-devel glibc-static bind bind-utils)
for package in "${packages[@]}"; do
dnf -y install "$package"
done
2、添加内核模块
/etc/modules-load.d/k8s.conf
cat > /etc/modules-load.d/k8s.conf << jingyu
br_netfilter
roverlay
jingyu
modprobe overlay
modprobe br_netfilter
overlay、br_netfilter模块
是两个非常重要的内核模块,它们对于实现网络功能至关重要。
overlay 模块
作用:overlay模块支持Overlay网络,这是一种允许创建覆盖在现有网络之上的虚拟网络的技术。在容器和Kubernetes环境中,它通常用于实现跨主机的容器网络通信。
为什么重要:Kubernetes中的Pod网络要求每个Pod都有一个独立的IP地址,并且这些Pod能够跨节点通信。通过使用Overlay网络,可以确保不同节点上的Pod之间能够无缝通信,而不受底层物理网络结构的影响。一些CNI(容器网络接口)插件如Flannel、Calico等依赖于overlay模块来提供这种跨主机的网络连接能力。
br_netfilter 模块
作用:br_netfilter模块允许iptables规则作用于桥接网络流量。默认情况下,Linux桥接不会经过Netfilter(iptables的工作层),但是启用br_netfilter后,可以使iptables规则对桥接流量生效。
为什么重要:在Kubernetes集群中,特别是当你使用某些CNI插件或需要执行复杂的网络策略时,这个模块变得尤为重要。例如,为了使Kubernetes服务正常工作,尤其是NodePort和LoadBalancer类型的服务,可能需要配置iptables规则来正确地转发流量。启用br_netfilter确保了这些规则也能应用于通过Linux桥接的流量,这对于正确的网络隔离和服务发现至关重要。
3、内核模块
/etc/modules-load.d/ipvs.conf
cat > /etc/modules-load.d/ipvs.conf << jingyu
ip_vs
ip_vs_rr
ip_vs_wrr
ip_vs_sh
nf_conntrack
ip_tables
ip_set
xt_set
ipt_set
ipt_rpfilter
ipt_REJECT
jingyu
在系统启动时自动加载的一系列内核模块列表,主要用于支持IPVS(IP Virtual Server),它是linux内核中的一种传输层(四层)负载均衡技术,广泛应用于Kubernetes集群中以实现服务的高性能负载均衡。
文件内容解释
ip_vs:这是IPVS的核心模块,提供了基本的负载均衡功能。
ip_vs_rr:实现了轮询(Round-Robin)调度算法,它简单地循环将请求分配给不同的后端服务器。
ip_vs_wrr:加权轮询(Weighted Round-Robin)调度算法,允许为每个后端服务器设置权重,以便按比例分发请求。
ip_vs_sh:源地址哈希(Source Hashing)调度算法,通过源IP地址进行哈希计算来选择服务器,有助于会话保持。
nf_conntrack:连接跟踪模块,对于需要追踪连接状态的应用程序非常重要,比如在使用NAT或防火墙规则时。
ip_tables:iptables的核心模块,提供包过滤和网络地址转换(NAT)功能。
ip_set:与iptables结合使用,可以高效地匹配大量IP地址或网络。
xt_set、ipt_set:扩展模块,使iptables能够使用ipset定义的集合来进行匹配。
ipt_rpfilter:反向路径过滤(Reverse Path Filtering),帮助防止IP欺骗攻击。
ipt_REJECT:提供拒绝数据包并发送通知的功能,作为iptables的一个目标扩展。
应用场景
高可用性:通过负载均衡多个后端Pod实例,提高了服务的可用性。
性能优化:相比iptables模式,IPVS模式提供了更快的数据包转发速度和更高的性能,尤其适用于大型Kubernetes集群。
灵活的调度策略:不同的调度算法(如轮询、加权轮询和源地址哈希)可以根据具体需求灵活选用,以优化资源利用和服务质量。
4、修改系统内核参数
sed -e '$avm.swappiness = 0' \
-e '$anet.bridge.bridge-nf-call-arptables = 1' \
-e '$anet.bridge.bridge-nf-call-ip6tables = 1' \
-e '$anet.bridge.bridge-nf-call-iptables = 1' \
-i.backup /etc/sysctl.conf
sysctl -p
添加 vm.swappiness = 0,这将告诉Linux内核尽可能避免使用交换空间(swap),从而提高性能,特别是在内存充足的情况下。
添加三条关于桥接网络的设置:
net.bridge.bridge-nf-call-arptables = 1
:允许在ARP表中调用Netfilter规则,这意味着当数据包是ARP类型时,它们会被转发到Netfilter框架进行处理。net.bridge.bridge-nf-call-ip6tables = 1
:允许IPv6数据包在被网桥处理时调用IP6Tables规则。net.bridge.bridge-nf-call-iptables = 1
:允许IPv4数据包在被网桥处理时调用Iptables规则。
之后sysctl -p命令重新加载/etc/sysctl.conf文件中的所有参数,使其生效,无需重启系统。
5、DNS服务器
由于之前安装了,bind和bind-utils工具包,搭建了DNS服务器,修改DNS配置文件。
sed -i.backup '11s/127.0.0.1/any/' /etc/named.conf
允许任何主机查询,这样做可以允许来自任何主机的DNS查询。
客户机配置/etc/resolv.conf文件,本机也是自己的DNS服务器地址。
#nameserver DNS服务器地址
nameserver 192.168.
6、chrony时间同步服务器
linux系统安装搭建chrony(ntp)时间同步服务器_rocky9 ntpd-优快云博客
由于之前安装chrony软件包,直接修改即可。(其他疑惑请看上面详细文章链接。)
sed -e '3cpool ntp.aliyun.com iburst' -e '26callow 0.0.0.0/0' -e '29s/#//' -i.backup /etc/chrony.conf
客户端chrony修改,只需修改这一处即可。
sed -i.backup '3cpool NTP时间同步服务器地址 iburst' /etc/chrony.conf
systemctl enable --now chronyd
7、安装docker
yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
防止docker安装冲突,如果是第一次安装docker,则不需要执行。
for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do dnf -y remove $pkg; done
dnf -y install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
cat > /etc/docker/daemon.json << jingyu
{
"registry-mirrors": [
"https://docker.m.daocloud.io",
"https://hub-mirror.c.163.com",
"https://mirror.ccs.tencentyun.com",
"http://mirrors.ustc.edu.cn",
"http://mirror.azure.cn",
"https://reg-mirror.qiniu.com",
"https://registry-1.docker.io",
"https://mirror.gcr.io",
"https://dockerproxy.com",
"https://dockerpull.org"
# "https://<your-code>.mirror.aliyuncs.com", ---#阿里云加速器地址
# "https://<your-code>.mirror.swr.myhuaweicloud.com" ---#华为云加速器地址
]
}
jingyu
设置docker服务自启动。
systemctl enable --now docker
8、安装cri-dockerd服务(二进制安装方式)(cri-dockerd.service and cri-dockerd.sock)
mkdir -p /usr/local/kubernetes/{cri,config,calico,images}
cd /usr/local/kubernetes/cri/
wget https://github.com/Mirantis/cri-dockerd/releases/download/v0.3.16/cri-dockerd-0.3.16.amd64.tgz
tar zxf cri-dockerd-0.3.16.amd64.tgz
添加cri-dockerd.service服务文件
cat > /etc/systemd/system/cri-dockerd.service << jingyu
[Unit]
Description=CRI Interface for Docker Application Container Engine
Documentation=https://docs.mirantis.com
After=network-online.target firewalld.service docker.service
Wants=network-online.target
Requires=cri-dockerd.socket
[Service]
Type=notify
# 如果需要指定 pause 容器镜像,可以取消注释下一行并替换为你想要的版本
ExecStart=/usr/local/kubernetes/cri/cri-dockerd/cri-dockerd --container-runtime-endpoint fd:// --pod-infra-container-image=registry.k8s.io/pause:3.10
ExecReload=/bin/kill -s HUP $MAINPID
TimeoutSec=0
RestartSec=2
Restart=always
# StartLimit* options were moved from "Service" to "Unit" in systemd 229.
# Both locations are accepted by newer versions of systemd, so we'll use the old location for compatibility.
StartLimitBurst=3
StartLimitInterval=60s
# Setting these limits to infinity can cause performance issues due to accounting overhead in the kernel.
# It's recommended to use cgroups for container-local accounting instead.
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
# TasksMax is supported since systemd 226. Uncomment if your \version supports it.
TasksMax=infinity
Delegate=yes
KillMode=process
[Install]
WantedBy=multi-user.target
jingyu
添加cri-dockerd.sock文件
cat > /etc/systemd/system/cri-dockerd.socket << jingyu
[Unit]
Description=CRI Docker Socket for the API
PartOf=cri-dockerd.service
[Socket]
ListenStream=%t/cri-dockerd.sock
SocketMode=0660
SocketUser=root
SocketGroup=root
[Install]
WantedBy=sockets.target
jingyu
设置cri-dockerd服务自启动。
systemctl daemon-reload
systemctl enable --now cri-dockerd.socket
systemctl enable --now cri-dockerd.service
9、关闭selinux与防火墙
setenforce 0
sed -i '/^SELINUX=/cSELINUX=disabled' /etc/selinux/config
sed -i.backup '/swap/s/^/#/' /etc/fstab
systemctl disable --now firewalld
10、安装kubernetes
cat <<EOF | tee /etc/yum.repos.d/kubernetes.repo
[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
dnf -y install kubelet-1.31.4 kubeadm-1.31.4 kubectl-1.31.4
#指定安装版本
#dnf -y install kubelet-1.31.4 kubeadm-1.31.4 kubectl-1.31.4
#查看所有可用版本,安装其它版本需要将/etc/yum.repos.d/kubernetes.repo文件中的v1.31,修改成要安装的版本。如:1.32.1:修改成v1.32即可。
#dnf list kubelet --showduplicates | sort -r
systemctl enable --now kubelet
sed -e '2asource <(kubeadm completion bash)' -e '3asource <(kubectl completion bash)' -i.backup /etc/bashrc
source /etc/bashrc/
11、初始化kubernetes配置文件
kubeadm config print init-defaults --component-configs KubeletConfiguration > /usr/local/kubernetes/config/config.yaml
修改配置文件
sed -e '12s/1.2.3.4/localhost-address/' \
-e '15s|containerd/containerd.sock|cri-dockerd.sock|' \
-e '18s/node/localhost hostname/' \
-e '43s/1.31.0/1.31.4/' \
-e '45s/cluster.local/rprod.cluster/' \
-e '46s|10.96.0.0/12|192.168.1.0/24|' \
-e '46a\tpodSubnet: 192.168.16.0/24' \
-e '66c- 192.168.6.50' \
-e '67s/cluster.local/jingyu/' -i.backup /usr/local/kubernetes/config/config.yaml
# 12行修改配置文件中的IP地址
# 15行替换containerd路径为cri-dockerd.sock的位置
# 18行修改节点名称为本地主机名
# 43行更新kubernetes版本号
# 45行设置k8s集群的服务域名后缀
# 46行更改clusterDNS选项指定的Pod使用的DNS服务器地址范围
# 添加47行配置项用于指定分配给Pod的IP地址范围
# 66行指定集群内Pod使用的DNS服务器地址192.168.6.50是我内部自己搭建DNS服务器,如果没有可以使用百度的180.76.76.76
# 67行修改Kubernetes集群的域名后缀,定义了Kubernetes集群的域名后缀(即集群域)。它的主要作用是为集群内的服务提供一个命名空间,使得服务可以通过一种结构化的、易于理解的方式进行命名和访问。
12、拉取所需镜像
-
kube-apiserver: Kubernetes API服务器是整个集群的入口点,它处理外部工具(如kubectl)、内部组件之间的所有REST调用。它是控制平面的核心组件之一。
-
kube-controller-manager: 控制器管理器运行控制器进程,这些控制器负责监控集群的状态,并通过API服务器进行调整以达到期望状态。例如节点控制器、副本控制器等。
-
kube-scheduler: 调度器负责将未调度的Pod分配到合适的节点上执行。它根据资源需求、服务质量要求、亲和性与反亲和性规范等因素做出决策。
-
kube-proxy: 这是一个网络代理,每个节点上都会运行一个实例。它维护节点上的网络规则,使得不同服务之间可以相互通信。
kube-proxy
确保服务能够正确地路由流量到相应的后端Pod。 -
etcd: etcd是一个高可用的键值存储系统,用于持久化存储Kubernetes集群的所有数据。它对于集群的状态管理和配置存储至关重要。尽管严格意义上说
etcd
不是Kubernetes的一部分,但它作为集群存储层被紧密集成在一起。
拉取的镜像版本需要与安装的kubelet版本一致。
查看kubernetes版本
kubectl version
docker pull registry.k8s.io/kube-apiserver:v1.31.4
docker pull registry.k8s.io/kube-controller-manager:v1.31.4
docker pull registry.k8s.io/kube-scheduler:v1.31.4
docker pull registry.k8s.io/kube-proxy:v1.31.4
docker pull registry.k8s.io/etcd:v1.31.4
拉取较慢,建议使用我的网盘资源分享链接下载所需镜像。
docker load -i k8s31images.tar
13、地址解析
echo "$(ip -4 addr show ens160 | grep -oP '(?<=inet\s)\d+(\.\d+){3}') $(hostname)" >> /etc/hosts
实现效果:
达到这样的效果。
14、kubernetes初始化
kubeadm init --config /usr/local/kubernetes/config/config.yaml
初始化错误现象!
error execution phase upload-config/kubelet: Error writing Crisocket information for the control-plane node: nodes "whale" not found
rm -rf /var/lib/etcd/
kubeadm reset
之后重新初始化,
端口占用
#!/bin/bash
exec > /dev/null 2>&1
rm -rf /etc/kubernetes/
rm -rf /var/lib/etcd/
kill -9 $(lsof -i :10259|awk '{print $2}'|grep -v "PID")
kill -9 $(lsof -i :10257|awk '{print $2}'|grep -v "PID")
kill -9 $(lsof -i :10259|awk '{print $2}'|grep -v "PID")
kill -9 $(lsof -i :10250|awk '{print $2}'|grep -v "PID")
kill -9 $(lsof -i :2379|awk '{print $2}'|grep -v "PID")
kill -9 $(lsof -i :2380|awk '{print $2}'|grep -v "PID")
kill -9 $(lsof -i :6443|awk '{print $2}'|grep -v "PID")
之后重新初始化。
15、初始化成功
执行初始化成功命令
mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config
export KUBECONFIG=/etc/kubernetes/admin.conf
16、安装网络calico
下载calico配置文件
mkdir /usr/local/kubernetes/calico/config/
cd /usr/local/kubernetes/calico/config/
wget https://raw.githubusercontent.com/projectcalico/calico/v3.29.1/manifests/calico.yaml
下载配置文件的过程中网络不稳定格式可能会发生有所变化,建议使用网盘资源中已经修改的,直接使用。
查看所需镜像
docker下载镜像
docker pull docker.io/calico/cni:v3.29.1
docker pull docker.io/calico/node:v3.29.1
docker pull docker.io/calico/kube-controllers:v3.29.1
拉取较慢,建议使用我的网盘资源分享链接下载所需镜像。
docker load -i calico-v.3.29.1-images.tar
之后创建节点。
下载配置文件的过程中网络不稳定格式可能会发生有所变化,建议使用网盘资源中已经修改的,直接使用。
kubectl create -f calico.yaml
如何之前执行过失败了,在检查完之后。可以用此命令
kubectl delete -f calico.yaml
kubectl create -f calico.yaml