Centos7安装k8s集群
主机准备
所有的主机最低配置
:2C/2G
!!!注意
: 主机名不能带有下划线_
,否则K8S会报错.可以带中划线-
参考: https://www.cnblogs.com/xiao987334176/p/11899321.html
主机名 | IP地址 |
---|---|
master | 192.168.32.200 |
node1 | 192.168.32.201 |
node2 | 192.168.32.202 |
软件环境:
软件 | 版本 |
---|---|
操作系统 | Cnetos7.9 |
Docker | 26.1.4(CE) |
cri-dockerd | cri-dockerd-0.3.14-3.el7.x86_64.rpm |
K8s | 1.28.0(Centos7支持的最高版本) |
禁用防火墙和SELinux
# 临时关闭SELinux
sudo setenforce 0
# 永久关闭SELinux
sudo sed -i 's/enforcing/disabled/' /etc/selinux/config
# 清空防火墙规则
iptables -F
# 禁用防火墙服务
systemctl disable --now firewalld
配置好国内yum源
https://blog.youkuaiyun.com/omaidb/article/details/120393850
安装依赖包
在所有主机上执行
原文链接:https://blog.youkuaiyun.com/omaidb/article/details/129405503
# 安装lsb包
yum install -y redhat-lsb
# 安装建议依赖包
yum install -y ipset ipvsadm conntrack jq sysstat libseccomp git chrony iptables-devel
# 安装常用工具包
yum install -y pv net-tools vim lrzsz curl wget tree screen socat lsof telnet tcpdump iperf3 qrencode proxychains-ng traceroute bind-utils
关闭swap
# 临时关闭swap
swpoff -a
# 永久关闭swap
sed -ri 's/.*swap.*/#&/' /etc/fstab
系统启动时加载内核模块
模块名称 | 简短解释 |
---|---|
overlay | 联合文件系统模块,用于将多个目录的内容合并到一个挂载点,常用于容器技术。 |
br_netfilter | 桥接网络的 netfilter 模块,允许 netfilter 在桥接层工作,用于虚拟化环境中的流量过滤。 |
nf_conntrack | netfilter 的连接跟踪模块,用于跟踪网络连接的状态(新建、已建立、关闭等)。 |
ip_conntrack | IPv4 的连接跟踪模块,专门用于跟踪 IPv4 网络连接。 |
nf_conntrack_ipv4 | IPv4 的 netfilter 连接跟踪模块,支持 IPv4 流量的连接跟踪。 |
ip_vs | IP 虚拟服务器模块,用于负载均衡,支持多种调度算法。 |
ip_vs_rr | IPVS 的轮询(Round Robin)调度算法模块。 |
ip_vs_wrr | IPVS 的加权轮询(Weighted Round Robin)调度算法模块。 |
ip_vs_sh | IPVS 的基于源的哈希(Source Hashing)调度算法模块。 |
ip_vs_lc | IPVS 的最少连接(Least Connections)调度算法模块。 |
ip_vs_lblc | IPVS 的基于局部最少连接(Locality-Based Least Connections)调度算法模块。 |
ip_vs_lblcr | IPVS 的基于局部最少连接(带复制)调度算法模块。 |
ip_vs_dh | IPVS 的基于目的的哈希(Destination Hashing)调度算法模块。 |
ip_vs_fo | IPVS 的故障转移(Failover)调度算法模块。 |
ip_vs_nq | IPVS 的无队列(No Queueing)调度算法模块。 |
ip_vs_sed | IPVS 的最短期望延迟(Shortest Expected Delay)调度算法模块。 |
ip_vs_ftp | IPVS 的 FTP 协议支持模块,用于对 FTP 数据连接的负载均衡。 |
ip_tables | IPv4 的 netfilter 表模块,用于配置 IPv4 的防火墙规则。 |
ip_set | netfilter 的集合模块,允许创建和管理 IP 地址、端口等的集合。 |
ipt_set | iptables 的集合匹配模块,允许在 iptables 规则中使用 ip_set 定义的集合。 |
ipt_rpfilter | 反向路径过滤模块,用于防止 IP 欺骗。 |
ipt_REJECT | iptables 的拒绝目标模块,用于拒绝不符合规则的流量。 |
ipip | IP-in-IP 隧道模块,用于在 IP 网络上传输 IP 数据包。 |
xt_set | 扩展的集合匹配模块,支持更复杂的集合匹配规则。 |
# 在os启动时加载内核模块
## Overlay 容器分层文件系统
## br_netfilter网桥过滤模块
## nf_conntrack: netfilter 的连接跟踪模块
## ip_conntrack IPv4 的连接跟踪模块
## ip_vs - IP 虚拟服务器模块
## ip_vs_rr - IP 虚拟服务器的轮询调度算法模块
## ip_vs_wrr - IP 虚拟服务器的加权轮询调度算法模块
## ip_vs_sh - IP 虚拟服务器的基于源的哈希调度算法模块
cat <<EOF | tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
nf_conntrack
ip_conntrack
nf_conntrack_ipv4
ip_vs
ip_vs_rr
ip_vs_wrr
ip_vs_sh
EOF
- 立即加载内核模块
# Overlay 容器分层文件系统
## 允许多个文件系统层以只读的方式合并挂载,创建统一虚拟文件系统
modprobe overlay
# 桥接流量经 iptables 过滤
modprobe br_netfilter
# 网络连接状态跟踪
modprobe ip_conntrack
配置内核参数
启用iptables过滤桥接流量
,防止k8s网络插件出现丢包
情况.
# 编辑用于k8s的内核参数
vim /etc/sysctl.d/k8s.conf
配置内容如下:
# 启用iptables过滤桥接流量
# 在iptables链中过滤IPv4包
net.bridge.bridge-nf-call-iptables=1
# 在ip6tables链中过滤IPv6包
net.bridge.bridge-nf-call-ip6tables=1
# 开启内核开启数据包转发
## 1为开启;0为关闭
net.ipv4.ip_forward = 1
使内核配置生效
# 全局加载所有配置
sysctl --system
同步时间
https://blog.youkuaiyun.com/omaidb/article/details/120107999
# 永久关闭ntpd服务
systemctl disable --now ntpd
# 安装chrony包
yum install chrony -y
# 启动chrony服务并开机启动
systemctl enable --now chronyd
# 强制同步时间
chronyc -a makestep
配置好hosts和ssh免密登录
在所有主机上执行
建议使用ansible
来完成
https://blog.youkuaiyun.com/omaidb/article/details/120921192
更新Centos7的内核到4.4以上
在所有主机上执行
k8s在内核3.10下有bug,内核
建议更新到4.4
https://blog.youkuaiyun.com/omaidb/article/details/121856924
开启CPU负载均衡服务
# 开启tuned调优服务
systemctl enable --now tuned
# 使用系统推荐的优化方案
tuned-adm recommend
# 开机自启并现在开启irqbanlance服务
systemctl enable --now irqbalance
设置rsyslogd和systemd journald
在所有主机上执行
# 持久化保存日志的目录
mkdir /var/log/journal
# 创建journal服务配置目录
mkdir /etc/systemd/journald.conf.d
# 写入journal配置
cat > /etc/systemd/journald.conf.d/99-prophet.conf << EOF
[Journal]
# 持久化保存到磁盘
Storage=persistent
# 压缩历史记录
Compress=yes
SyncIntervalSec=5m
RateLimitInterval=30s
RateLimitBurst=1000
# 最大占用空间
SystemMaxUse=10G
# 单文件最大200M
SystemMaxFileSize=200M
# 日志保存时间2周
MaxRetentionSec=2week
# 是否将日志转发到syslog
ForwardToSyslog=no
EOF
# 重启systemd-journald
systemctl restart systemd-journald
安装Docker
Centos7
安装Docker
https://blog.youkuaiyun.com/omaidb/article/details/121683661
RHEL8
安装Docker
https://blog.youkuaiyun.com/omaidb/article/details/121071924
# 安装yum-utils
yum install -y yum-utils
# 添加docker-ce源 https://docs.docker.com/engine/install/centos/
## docker-ce国内源--aliyun
yum-config-manager --add-repo=https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
## docker-ce官方源
#yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
# 安装docker-ce
yum -y install docker-ce
配置docker镜像加速和存储目录
参考: https://kubernetes.io/zh-cn/docs/tasks/administer-cluster/kubeadm/configure-cgroup-driver/
Centos7安装docker参考:
https://blog.youkuaiyun.com/omaidb/article/details/121683661
配置docker的cgroup
https://www.cnblogs.com/chuanzhang053/p/15826837.html
docker
默认使用的Cgroup Driver
为cgroupfs
,K8S官方推荐
使用systemd
来代替cgroupfs
参考 https://v1-22.docs.kubernetes.io/zh/docs/setup/production-environment/container-runtimes/
# 配置docker加速器和cgroup驱动
vim /etc/docker/daemon.json
配置内容如下:
{
"registry-mirrors": ["https://isdp30x2.mirror.aliyuncs.com"],
"exec-opts": [
"native.cgroupdriver=systemd"
]
}
保存配置,重启docker服务
## 重载服务
systemctl daemon-reload
## 重启docker服务
systemctl restart docker
# 设置docker开机自启
systemctl enable docker
# 查看docker配置
docker info
# 查看docker当前的cgroup Driver
docker info | grep -i "Cgroup Driver"
安装cri-dockerd
K8s1.23
是最后一个直接支持Docker
的版本。
k8s 1.24
之后,k8s
不再使用docker
,需要安装cri-dockerd
中间件来与k8s
通信.
cri-dockerd
是k8s
和docker
的通信中间件
.
项目地址: https://github.com/Mirantis/cri-dockerd
# Centos7安装
yum install -y https://github.com/Mirantis/cri-dockerd/releases/download/v0.3.14/cri-dockerd-0.3.14-3.el7.x86_64.rpm
# 启动cri-docker服务
systemctl enable --now cri-docker
修改cri-docker服务文件
vim /usr/lib/systemd/system/cri-docker.service
cri-docker服务中指定pause国内镜像地址
ExecStart=/usr/bin/cri-dockerd --container-runtime-endpoint fd:// --pod-infra-container-image=registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.10
重载重启cri-docker服务
# 重载cri-docker服务
systemctl daemon-reload
# 重启cri-docker服务
systemctl restart cri-docker
# 查看cri-docker服务状态
systemctl status cri-docker
安装k8s组件
在所有主机上执行
注意,安装的版本要求和k8s版本一致
添加kubernetes软件源
https://kubernetes.io/zh-cn/docs/setup/production-environment/tools/kubeadm/install-kubeadm/
- k8s海外源:
cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-\$basearch
enabled=1
gpgcheck=1
gpgkey=https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
exclude=kubelet kubeadm kubectl
EOF
- k8s国内源:
# 添加k8s--国内源
cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
安装kubeadm和kubectl
# 查看k8s源中支持哪些版本
## sort -n 用数字排序
## sort -r 倒序
yum list kubeadm --showduplicates | grep 1.28 |sort -nr
在这里插入图片描述
# 安装最新版
#yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes
# 安装指定版本
yum install -y kubelet-1.28.0 kubeadm-1.28.0 kubectl-1.28.0 --disableexcludes=kubernetes
# 安装软件包版本锁定插件
sudo yum install -y yum-plugin-versionlock
# 标记软件包为保留状态
sudo yum versionlock kubelet kubectl kubeadm
# 设置kubelet自启动--失败是正常现象
## 由于没有生成配置文件,集群初始化后自动启动
systemctl enable --now kubelet
# 查看kubelet状态
systemctl status kubelet
# 验证kubectl版本
kubectl version
# 验证kubeadm版本
yum info kubeadm
配置kubectl命令行自动补全
在
所有主机
上执行
https://blog.youkuaiyun.com/omaidb/article/details/121855263
国内镜像下载集群需要的镜像(非必须执行)
在
所有主机
上执行
2025年3月29日
: 该方法拉取的镜像版本不真确,请勿使用
因为要从国外的谷歌服务器上下载镜像,速度非常慢,要么自备科学上网,要么就先用国内源将镜像下载到本地
# 安装k8s集群之前,必须要提前准备好集群需要的镜像
## 查看需要的镜像
kubeadm config images list
kubeadm config images list|cut -d/ -f2
## 把查询到的最新组件版本信息添加到脚本中
sudo tee ./images.sh <<-'EOF'
#!/bin/bash
# 定义好需要国内加速下载的镜像列表
images=(
kube-apiserver:v1.28.15
kube-controller-manager:v1.28.15
kube-scheduler:v1.28.15
kube-proxy:v1.28.15
pause:3.9
etcd:3.5.9-0
coredns
)
# 循环下载镜像,并重新打标签
for imageName in ${images[@]} ; do
# 拉取镜像
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/$imageName
# 给镜像打标签,阿里云前缀换成registry.k8s.io前缀
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/$imageName registry.k8s.io/$imageName
# 删除阿里云前缀的标签
docker rmi registry.cn-hangzhou.aliyuncs.com/google_containers/$imageName
done
# 将coredns重新打标签
docker tag registry.k8s.io/coredns:latest registry.k8s.io/coredns/coredns:v1.10.1
EOF
执行脚本下载镜像
# 运行下载镜像的脚本
chmod +x ./images.sh && ./images.sh
# 查看所有镜像是否下载完成
docker images
检查镜像版本
在
所有主机
上执行
镜像tag不可以是latest,会报错
,必须指定版本号
指定版本号
# 修改镜像标签名
docker tag k8s.gcr.io/coredns:latest k8s.gcr.io/coredns/coredns:v1.10.1
配置cluster-endpoint
所有机器
添加master域名映射
# 所有机器添加master域名映射,以下需要修改为自己的ip(一般是master IP)
echo "${master-ip} cluster-endpoint" >> /etc/hosts
kuadm创建集群(本地镜像)
可以先在本地下载好所需镜像
所有网络范围不能重叠
# Centos8需要安装tc,否则会报没有tc
yum install -y iproute-tc
安装指定k8s版本
只在master节点
上执行
https://kubernetes.io/zh-cn/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/
- 科学网络不需要加多余参数
# 不指定k8s版本时会默认安装最新版
# 不指定apiserver-advertise-address默认使用本机的默认ipv4地址(建议指定ip)
## --cri-socket 指定容器运行时环境
kubeadm init \
--kubernetes-version=v1.28.0 \
--pod-network-cidr=10.244.0.0/16 \
--service-cidr=10.93.0.0/12 \
--apiserver-advertise-address=192.168.32.200
- 国内网络
# 安装指定k8s版本
## --apiserver-advertise-address 指定 Kubernetes API 服务器监听的 主节点 IP 地址
## --kubernetes-version 指定要安装的k8s版本
## --control-plane-endpoint 指定高可用(HA)集群的控制平面入口
## --service-cidr 定义service的虚拟ip范围
## --pod-network-cidr 定义pod的虚拟ip范围,要与cni插件配置的yml中保持一致
## --cri-socket 指定容器运行时(CRI)的套接字
kubeadm init \
--apiserver-advertise-address=${master_ip}
--kubernetes-version=v1.28.0 \
--control-plane-endpoint=cluster-endpoint \
--service-cidr=10.96.0.0/12 \
--pod-network-cidr=10.244.0.0/16 \
--cri-socket=unix:///var/run/cri-dockerd.sock
创建集群(从国内镜像源拉取镜像)
只在master节点
上执行
如果没有科学网络,建议从国内镜像源拉取k8s镜像
。
# 使用国内源拉取镜像
## --apiserver-advertise-address 集群通告地址
## --image-repository 指定国内镜像仓库地址
## --kubernetes-version 指定要安装的k8s版本
## --control-plane-endpoint 指定高可用(HA)集群的控制平面入口
## --service-cidr 定义service的虚拟ip范围
## --pod-network-cidr pod网段地址,要与cni插件配置的yml中保持一致
## --cri-socket 指定容器运行时(CRI)的套接字
kubeadm init \
--apiserver-advertise-address=${master_ip} \
--image-repository registry.aliyuncs.com/google_containers \
--kubernetes-version=v1.28.0 \
--control-plane-endpoint=cluster-endpoint \
--service-cidr=10.96.0.0/12 \
--pod-network-cidr=10.244.0.0/16 \
--cri-socket=unix:///var/run/cri-dockerd.sock
创建集群报错排错
# 查看集群创建报错日志
journalctl -u kubelet
# coredns的pod一直是Pending状态
## 查看coredns的pod详情
kubectl describe po coredns-6d8c4cb4d-qf2br -n kube-system
## 错误提示是node有污点无法创建pod
# 查看node是否有污点
kubectl describe node node名称|grep -A 10 Taint
# 删除污点
## 允许master节点调度pod;去除污点NoSchedule,最后一个"-"代表删除
kubectl taint nodes k8s-master02 node-role.kubernetes.io/master:NoSchedule-
# 检查node的docker有没有配置systemd
复制k8s授权文件
# 复制k8s授权文件
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
# 注意保存加入node到集群的token
安装cni网络插件
https://blog.youkuaiyun.com/omaidb/article/details/121283067
将node加入到集群
加入集群的
token默认24小时有效
在node
节点上执行
加入node
节点和加入master
节点的区别
.
# 加入node节点 和 加入maste节点--多了这个参数
--control-plane
查看k8s默认token和hash
# 在master节点上打印token
# 查看k8s默认token和hash
kubeadm token create --print-join-command
kubeadm init超过24小时node加入集群
参考: https://blog.youkuaiyun.com/qq_36820037/article/details/108696508
K8S的Token
管理:https://kubernetes.io/zh-cn/docs/reference/setup-tools/kubeadm/kubeadm-token/
k8s用户获取node加入集群的kubeadm jion命令
: https://gitcode.com/liqiaofei/k8s-node-joi
# 下载kubeadm jion 命令获取脚本
# 下载k8s-node-jion.sh到 ~/root~/bin/
wget -P ~/bin -c https://raw.gitcode.com/liqiaofei/k8s-node-join/blobs/987769fe5194b3bbecc7b3c7d3ccd957989fa9ca/k8s-node-jion.sh
# 赋予可执行权限
chmod +x ~/bin/k8s-node-jion.sh
# 查看node加入集群时要用的kubeadm jion 命令
k8s-node-jion.sh
# 以master角色加入集群 添加这个这个参数
--control-plane
node加入到集群
# 将node加入到集群
## 要指定cri-socket
kubeadm join 192.168.32.200:6443 --token j0qa1k.a6kq24f7cjh5qp1t \
--discovery-token-ca-cert-hash sha256:59c7f63b40b4aa15dc62304babc403d2be66584737094184ab1d018fd541f6a8 --cri-socket=unix:///var/run/cri-dockerd.sock
查看node是否加入成功
在master节点上执行
# 查看node是否加入成功
kubectl get nodes
这时候的状态是NotReady
,因为没有安装网络插件
查看所有pod是否正常运行
# 查看所有pod的状态
kubectl get pods -A
# 查看异常pod的详细信息
kubectl describe pod coredns-78fcd69978-hdrbd -n kube-system
健康检查scheduler提示ERROR
# 查看健康检查告警
[root@master ~]# kubectl get cs
Warning: v1 ComponentStatus is deprecated in v1.19+
NAME STATUS MESSAGE ERROR
scheduler Unhealthy Get "http://127.0.0.1:10251/healthz": dial tcp 127.0.0.1:10251: connect: connection refused
# 查看本地10251端口是否处于监听状态
ss -tunlp|grep 10251
# 解决办法
vim /etc/kubernetes/manifests/kube-scheduler.yaml
vim /etc/kubernetes/manifests/kube-controller-manager.yaml
# 在这两个文件中找到port=0这一行注释掉即可. 保存会立即生效,pod自动重启.
# 再次执行健康检查就没有ERROR了
kubectl get cs
修改Services的负载均衡模式为ipvs(可选)
该方法只适用于kubeadm
安装的k8s
修改kube-proxy为ipvs
# 修改configmap kube-proxy
# kubectl -n kube-system edit configmap kube-proxy
kubectl -n kube-system edit cm kube-proxy
搜索mode
关键字,参数默认为“ ”
# 修改为负载均衡模式ipvs
mode: "ipvs"
保存后kube-proxy
相关的pod
会重建
,如果pod未自动重建,则需要手动重建所有kube-proxy
相关的pod
.
部署Kubernetes Dashboard
https://blog.youkuaiyun.com/omaidb/article/details/121746492
重新初始化集群
在所有节点上执行
如果集群出错,可以重新初始化,初始化完成后再次加入node即可
注意: 数据会完全清空,生产环境慎用
https://blog.youkuaiyun.com/omaidb/article/details/121784091