当前位置: 首页 > news >正文

K8S 二进制集群搭建(一主两从)

👨‍🎓博主简介

  🏅CSDN博客专家
  🏅云计算领域优质创作者
  🏅华为云开发者社区专家博主
  🏅阿里云开发者社区专家博主
💊交流社区:运维交流社区 欢迎大家的加入!
🐋 希望大家多多支持,我们一起进步!😄
🎉如果文章对你有帮助的话,欢迎 点赞 👍🏻 评论 💬 收藏 ⭐️ 加关注+💗


文章目录

  • 一、前言
    • 1.1 温馨提示
    • 1.2 常见的k8s部署方式
    • 1.3 参考文献:
  • 二、准备工作(所有节点都要做同样的操作)
    • 2.1 服务器配置
    • 2.2 关闭防火墙
    • 2.3 关闭selinux
    • 2.4 关闭交换分区Swap
    • 2.5 修改三台集群的主机名:(每个主机限一条命令)
    • 2.6 所有节点都添加集群ip与主机名到hosts中:
    • 2.7 配置相关的内核参数
    • 2.8 三台机器进行时间同步
    • 2.9 安装所需命令
    • 2.10 特殊说明:
  • 三、部署etcd集群
    • 3.1 etcd 简介
    • 3.2 服务器规划
    • 3.3 cfssl证书生成工具准备
    • 3.4 自签证书颁发机构(CA)
      • 3.4.1 创建工作目录
      • 3.4.2 生成自签CA配置
      • 3.4.3 生成自签CA证书
    • 3.5 使用自签CA签发etcd https证书
      • 3.5.1 创建证书申请文件
      • 3.5.2 生成证书
    • 3.6 准备部署etcd集群文件及路径
      • 3.6.1 下载etcd二进制文件
      • 3.6.2 创建工作目录并解压二进制包
    • 3.7 创建etcd配置文件
    • 3.8 systemd管理etcd
    • 3.9 将CA签发的etcd证书复制到etcd的TLS里
    • 3.10 将master节点所有生成的文件拷贝到节点2和节点3
    • 3.11 修改节点2,节点3 ,etcd.conf配置文件中的节点名称和当前服务器IP:
    • 3.12 启动etcd并设置开机自启(集群都启动)
    • 3.13 检查etcd集群状态
    • 3.14 etcd部署完成
  • 四、部署Docker(所有节点)
    • 4.1 解压二进制包
    • 4.2 配置镜像加速
    • 4.3 systemd管理docker
    • 4.4 启动并设置开机启动
  • 五、部署Master节点
    • 5.1 生成kube-apiserver证书
      • 5.1.1 自签证书颁发机构(CA)
      • 5.1.2 使用自签CA签发kube-apiserver https证书
    • 5.2 安装kubectl命令
      • 5.2.1 下载Kubernetes二进制包
      • 5.2.2 解压二进制包并创建软件目录
    • 5.3 部署 kube-apiserver
      • 5.3.1 创建配置文件
      • 5.3.2 将CA签发的k8s证书复制到kubernetes的TLS里
      • 5.3.3 启用TLS bootstrapping机制
      • 5.3.4 systemd管理apiserver
      • 5.3.5 启动并设置开机启动
    • 5.4 部署 kube-controller-manager
      • 5.4.1 创建配置文件
      • 5.4.2 生成kube-controller-manager证书
      • 5.4.3 生成 kube-controller-manager 的 kubeconfig 文件
      • 5.4.4 systemd管理controller-manager
      • 5.4.5 启动并设置开机自启
    • 5.5 部署 kube-scheduler
      • 5.5.1 创建配置文件
      • 5.5.2 生成kube-scheduler证书
      • 5.5.3 生成 kube-scheduler 的 kubeconfig 文件
      • 5.5.4 systemd管理scheduler
      • 5.5.5 启动并设置开机启动
    • 5.6 查看集群状态
      • 5.6.1 生成kubectl连接集群的证书
      • 5.6.2 生成 kubectl 的 kubeconfig 文件
      • 5.6.3 通过kubectl工具查看当前集群组件状态
      • 5.6.4 授权kubelet-bootstrap用户允许请求证书
  • 六、Master节点部署Node
    • 6.1 复制kubelet及kube-proxy命令
    • 6.2 部署kubelet
      • 6.2.1 创建kubelet配置文件
      • 6.2.2 配置kubelet参数文件
      • 6.2.3 生成kubelet初次加入集群引导kubeconfig文件
      • 6.2.4 systemd管理kubelet
      • 6.2.5 启动并设置开机启动
      • 6.2.6 允许kubelet证书申请并加入集群
    • 6.3 部署kube-proxy
      • 6.3.1 创建配置文件
      • 6.3.2 配置参数文件
      • 6.3.3 生成kube-proxy证书文件
      • 6.3.4 生成kube-proxy.kubeconfig文件
      • 6.3.5 systemd管理kube-proxy
      • 6.3.6 启动并设置开机自启
    • 6.4 部署网络组件(Calico)
    • 6.5 授权apiserver访问kubelet
    • 6.6 部署 Metrics-Server 实现 `kubectl top` 与自动伸缩
    • 6.7 kubernetes强化tab(安装之后会tab可以补全命令及参数)
  • 七、新增加Work Node(其他两个node节点)
    • 7.1 拷贝以部署好的相关文件到新节点
    • 7.2 删除kubelet证书和kubeconfig文件
    • 7.3 修改kubelet和kubeproxy配置中的主机名
    • 7.4 启动并设置开机自启
    • 7.5 在Master节点上同意新的Node kubelet证书申请
    • 7.6 查看Node节点的状态
  • 八、附加:网盘链接
  • 九、问题:

一、前言

1.1 温馨提示

内容比较多,请耐心观看,有不懂的可留言

1.2 常见的k8s部署方式

  • Mini kube

Minikube是一个工具,可以在本地快速运行一个单节点微型K8s,仅用于学习预览K8s的一些特性使用。
官方部署地址: https://kubernetes.io/zh-cn/docs/tasks/tools/

  • k8s单机部署

采用的是kubeadm yum安装部署的
部署地址:https://liucy.blog.csdn.net/article/details/120742911

  • Kubeadmin

Kubeadmin也是一个工具,提供kubeadm init和kubeadm join,用于快速部署K8S集群,相对简单
官方部署地址:https://kubernetes.io/zh-cn/docs/reference/setup-tools/kubeadm/

  • 二进制安装部署

生产首选,从官方下载发行版的二进制包,手动部署每个组件和自签TLS证书,组成K8s集群,新手推荐
下载地址:https://github.com/kubernetes/kubernetes/releases


小结:kubeadm降低部署门槛,但屏蔽了很多细节,遇到问题很难排查,如果想更容易可控,推荐使用二进制包部署kubernetes集群,虽然手动部署麻烦点,期间可以学习很多工作原理,也利于后期维护。

1.3 参考文献:

标题链接
k8s二进制安装部署(详细)https://blog.csdn.net/qq_44078641/article/details/120049473
k8s1.20环境搭建部署(二进制版本)https://www.cnblogs.com/lizexiong/p/14882419.html

二、准备工作(所有节点都要做同样的操作)

温馨提示:
服务器需要可以访问外网,需要从网上拉取镜像需求,如果服务器不能上网,需要提前下载对应镜像并导入节点;

2.1 服务器配置

集群(一主两从)ip地址主机名配置(最低要求)安装所需组件
172.16.11.230k8s-master2C/2G/50Gcfssl、etcd、Docker、kubectl、kube-apiserver、kube-controller-manager、kube-scheduler、kubelet、kube-proxy
172.16.11.231k8s-node12C/2G/50Getcd、Docker、kubelet、kube-proxy
172.16.11.232k8s-node22C/2G/50Getcd、Docker、kubelet、kube-proxy

✅ 所需软件组件说明:

组件名称说明
cfssl用于生成 TLS 证书
etcd分布式键值数据库,存储集群所有数据
dockercontainerd容器运行时(推荐 containerd)
kubectl命令行工具,用于与集群交互
kube-apiserverKubernetes API 服务,集群的统一入口
kube-controller-manager控制器管理器,负责资源控制逻辑
kube-scheduler调度器,负责 Pod 的调度
kubelet节点代理,负责启动 Pod 和管理容器
kube-proxy网络代理,负责服务发现和负载均衡

✅ 软件版本说明:

软件版本
linuxcentos7
cfssl1.2.0
etcd3.4.9
Docker24.0.5
Kubernetes1.20.10
Calico3.15.5

✅ Kubernetes一主两从结构图

其他说明:

  • 这里etcd为了节省机器,复用k8s节点;
  • kubectl是操作命令,因为只需要再master节点上操作,所以只需要再master节点安装kubectl就行;


✅ 本文路径说明:

路径说明
/software-cfssl存放cfssl工具包,用于生成证书的
/opt/packages/存放etcd、docker、kubernetes等二进制包
/opt/kubernetes/存放k8s的配置文件、证书、日志等
/opt/etcd/存放etcd的配置文件、证书、日志等
/opt/TLS/存放自签证书的路径(一般生成的证书都在这里)

2.2 关闭防火墙

systemctl stop firewalld && systemctl disable firewalld

如果在生产服务器之类的不能关闭防火墙,那就需要开启几个端口;(这里说的是k8所用到的端口及是否需要对外开放)

  • master节点:
规则端口监听组件用途说明使用者/访问方是否对外开放
TCP2379etcdetcd client 端口(apiserver 读写数据)kube-apiserver(仅对控制面)
TCP2380etcdetcd peer 端口(集群内部选举、复制)其他 etcd 节点(仅对 etcd 成员)
TCP6443kube-apiserverKubernetes API 入口所有外部/内部客户端
TCP179Calico/BIRDBGP 路由协议,用于节点间交换 Pod 网段路由集群内其他 Calico 节点
TCP9099calico/nodeCalico 健康检查 & metrics(liveness/readiness)kubelet、Prometheus
TCP10248kubeletkubelet 健康检查端点 /healthzkubelet 自身、控制面
TCP10249kube-proxykube-proxy metrics 接口Prometheus、HPA 控制器
TCP10250kubeletkubelet HTTPS API(logs/exec/metrics/csi)kube-apiserver、metrics-server
TCP10251kube-schedulerscheduler 指标与调试端点控制面组件、Prometheus
TCP10252kube-controller-managercontroller-manager 指标与调试端点控制面组件、Prometheus
TCP10255kubelet只读 HTTP API(已弃用,默认关闭)早期 heapster、监控组件(建议关闭)
TCP10256kube-proxykube-proxy 健康检查 /healthzkubelet、负载均衡探针
TCP10257kube-controller-managerHTTPS 安全指标与调试端点(–secure-port)控制面、Prometheus
TCP10259kube-schedulerHTTPS 安全指标与调试端点(–secure-port)控制面、Prometheus
  • node节点:
规则端口监听组件用途说明使用者/访问方是否对外开放
TCP179Calico/BIRDBGP 路由协议,用于节点间交换 Pod 网段路由集群内其他 Calico 节点
TCP2379etcdetcd client 端口(apiserver 读写数据)kube-apiserver(仅对控制面)
TCP2380etcdetcd peer 端口(集群内部选举、复制)其他 etcd 节点(仅对 etcd 成员)
TCP9099calico/nodeCalico 健康检查 & Prometheus 指标kubelet、Prometheus
TCP10248kubeletkubelet 自身 /healthz 健康探针kubelet、控制面组件
TCP10249kube-proxykube-proxy Prometheus 指标接口Prometheus、HPA 控制器
TCP10250kubeletkubelet HTTPS API(logs/exec/metrics/CSI)kube-apiserver、metrics-server (控制面需访问)
TCP10255kubelet只读 HTTP API(已弃用,默认关闭)旧版 heapster、监控建议关闭
TCP10256kube-proxykube-proxy /healthz 健康检查kubelet、LB 探针

2.3 关闭selinux

临时关闭selinux(沙盒)如需永久关闭selinux需要修改为sed -i 's/^SELINUX=enforcing$/SELINUX=disabled/' /etc/selinux/config

#临时关闭selinux
setenforce 0#永久关闭selinux
sed -i 's/^SELINUX=enforcing$/SELINUX=disabled/' /etc/selinux/config#查看selinux是否关闭
getenforce
#如果是Disabled就是永久关闭,如果是permissive是临时关闭。

2.4 关闭交换分区Swap

#临时关闭所有的交换分区
swapoff -a#永久关闭所有的交换分区
sed -i '/swap/s/^\(.*\)$/#\1/g' /etc/fstab

2.5 修改三台集群的主机名:(每个主机限一条命令)

找到自己IP对应的主从;

[root@k8s-master ~]# hostnamectl set-hostname k8s-master
[root@k8s-node1 ~]# hostnamectl set-hostname k8s-node1
[root@k8s-node2 ~]# hostnamectl set-hostname k8s-node2

修改完成之后可以重新连接服务器;或执行命令su,新连接一下;

2.6 所有节点都添加集群ip与主机名到hosts中:

cat >> /etc/hosts << EOF 
172.16.11.230 k8s-master
172.16.11.231 k8s-node1
172.16.11.232 k8s-node2
EOF

添加完之后可以自行查看确保添加完成:cat /etc/hosts
注意:ip一定要改成自己的ip,不要直接复制粘贴

2.7 配置相关的内核参数

将桥接的IPv4 流量传递到iptables 的链

cat <<EOF >  /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF#让其生效
sysctl --system

配置此操作的作用:是为了让 Linux 内核对桥接网络流量也使用 iptables 处理,确保 Kubernetes 的 Service、NetworkPolicy 和网络插件能正常工作。

2.8 三台机器进行时间同步

#安裝同步时间命令
yum install ntpdate -y#同步时间
ntpdate cn.pool.ntp.org#设置定时任务每五分钟同步一次时间
echo "*/5 * * * * root /usr/sbin/ntpdate cn.pool.ntp.org &>/dev/null" >> /etc/crontab

2.9 安装所需命令

这里以centos7的操作系统来举例,如果是ubuntu的话可以直接下载,但需要注意安装名称可能会与centos不同;

  • 添加centos源并将下载地址更换为阿里云地址
#添加centos源
curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo#将下载地址更换为阿里云地址
sed -i -e '/mirrors.cloud.aliyuncs.com/d' -e '/mirrors.aliyuncs.com/d' /etc/yum.repos.d/CentOS-Base.repo
  • 添加epel扩展源
curl -o /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
  • 清除缓存
yum clean all
  • 重新加载源缓存
yum makecache
  • 升级yum并安装一些会用到的命令
yum -y update && yum -y install lrzsz wget conntrack ipvsadm ipset jq psmisc sysstat curl iptables net-tools libseccomp gcc gcc-c++ yum-utils device-mapper-persistent-data lvm2 bash-completion

安装需要一些时间,就等待安装即可;

2.10 特殊说明:

如果是虚拟机克隆的环境建议执行 rm -rf /etc/udev/* 保证网卡UUID不同

三、部署etcd集群

3.1 etcd 简介

Etcd 是一个分布式键值存储系统,主要被用来共享配置和服务发现;而Kubernetes默认使用的是Etcd进行数据存储;
所以先准备一个Etcd数据库,为解决Etcd单点故障,应采用集群方式部署,这里使用3台组建集群,可容忍1台机器故障,当然,你也可以使用5台组建集群,可容忍2台机器故障;

3.2 服务器规划

节点名称IP
etcd-1172.16.11.230
etcd-2172.16.11.231
etcd-3172.16.11.232

说明:
为了节省机器,这里与k8s节点复用,也可以部署在k8s机器之外,只要apiserver能连接到就行。

3.3 cfssl证书生成工具准备

cfssl简介:
cfssl是一个开源的证书管理工具,使用json文件生成证书,相比openssl更方便使用。
找任意一台服务器操作,这里用Master节点。

为什么需要证书?

K8s所有组件采用https加密通信,这些组件一般由两套根证书生成:K8S组件(apiserver)和Etcd。

按照需求分类来说,这里所有的服务组件controller-managerschedulerkubeletkube-proxykubectl等需要访问apiserver,这里需要一套。Apiserver访问etcd集群又是一套单独的。所以这里2套证书是2个不同自签CA颁发的。

  • cfssl证书生成工具准备
#创建目录存放cfssl工具
mkdir /software-cfssl#下载相关工具
wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64 -P /software-cfssl/
wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64 -P /software-cfssl/
wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64 -P /software-cfssl/cd /software-cfssl/
chmod +x *
cp -ar cfssl_linux-amd64 /usr/local/bin/cfssl
cp -ar cfssljson_linux-amd64 /usr/local/bin/cfssljson
cp -ar cfssl-certinfo_linux-amd64 /usr/local/bin/cfssl-certinfo

说明:
如果下载失败,可以使用最后提供的下载连接;

3.4 自签证书颁发机构(CA)

3.4.1 创建工作目录

mkdir -p /opt/{etcd,kubernetes,TLS}
mkdir -p /opt/TLS/{etcd,kubernetes}
cd /opt/TLS/etcd

3.4.2 生成自签CA配置

cat > ca-config.json << EOF
{"signing": {"default": {"expiry": "87600h"},"profiles": {"www": {"expiry": "87600h","usages": ["signing","key encipherment","server auth","client auth"]}}}
}
EOFcat > ca-csr.json << EOF
{"CN": "etcd CA","key": {"algo": "rsa","size": 2048},"names": [{"C": "CN","L": "BeiJing","ST": "BeiJing"}]
}
EOF

3.4.3 生成自签CA证书

cfssl gencert -initca ca-csr.json | cfssljson -bare ca -

执行以上命令会在当前目录下生成 ca-key.pemca.pem文件;

3.5 使用自签CA签发etcd https证书

3.5.1 创建证书申请文件

cat > server-csr.json << EOF
{"CN": "etcd","hosts": ["172.16.11.230","172.16.11.231","172.16.11.232"],"key": {"algo": "rsa","size": 2048},"names": [{"C": "CN","L": "BeiJing","ST": "BeiJing"}]
}
EOF

说明:
上述文件hosts字段中ip为所有etcd节点的集群内部通信ip,一个都不能少,为了方便后期扩容可以多写几个预留的ip。

3.5.2 生成证书

cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=www server-csr.json | cfssljson -bare server

执行以上命令会在当前目录下生成 server-key.pemserver.pem文件;

3.6 准备部署etcd集群文件及路径

3.6.1 下载etcd二进制文件

下载地址:https://github.com/etcd-io/etcd/releases/download/v3.4.9/etcd-v3.4.9-linux-amd64.tar.gz

说明:
下载后上传到服务器任意位置即可,如果下载有问题,可使用附件中的文件。
也可以下载到和kubenetes的同级目录/opt/packages/,方便日后寻找或查看等,这里我就下载到这个路径吧。


以下操作在master上面操作,为简化操作,待会将master节点生成的所有文件拷贝到其他节点。

3.6.2 创建工作目录并解压二进制包

mkdir -p /opt/etcd/{bin,cfg,ssl}
mkdir -p /opt/packages/
# 下载上传到 /opt/packages/ 下并进行解压
cd /opt/packages/
tar xf etcd-v3.4.9-linux-amd64.tar.gz
mv etcd-v3.4.9-linux-amd64/{etcd,etcdctl} /opt/etcd/bin/

3.7 创建etcd配置文件

cat > /opt/etcd/cfg/etcd.conf << EOF
#[Member]
ETCD_NAME="etcd-1"
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_LISTEN_PEER_URLS="https://172.16.11.230:2380"
ETCD_LISTEN_CLIENT_URLS="https://172.16.11.230:2379"#[Clustering]
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://172.16.11.230:2380"
ETCD_ADVERTISE_CLIENT_URLS="https://172.16.11.230:2379"
ETCD_INITIAL_CLUSTER="etcd-1=https://172.16.11.230:2380,etcd-2=https://172.16.11.231:2380,etcd-3=https://172.16.11.232:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new"
EOF

配置说明:

  • ETCD_NAME: 节点名称,集群中唯一
  • ETCD_DATA_DIR:数据目录,如果后面需要升级etcd记得需要备份数据目录,否则会冲突报错;
  • ETCD_LISTEN_PEER_URLS:集群通讯监听地址
  • ETCD_LISTEN_CLIENT_URLS:客户端访问监听地址
  • ETCD_INITIAL_CLUSTER:集群节点地址
  • ETCD_INITIALCLUSTER_TOKEN:集群Token
  • ETCD_INITIALCLUSTER_STATE:加入集群的状态:new是新集群,existing表示加入已有集群

3.8 systemd管理etcd

cat > /usr/lib/systemd/system/etcd.service << EOF
[Unit]
Description=Etcd Server
After=network.target
After=network-online.target
Wants=network-online.target[Service]
Type=notify
EnvironmentFile=/opt/etcd/cfg/etcd.conf
ExecStart=/opt/etcd/bin/etcd \
--cert-file=/opt/etcd/ssl/server.pem \
--key-file=/opt/etcd/ssl/server-key.pem \
--peer-cert-file=/opt/etcd/ssl/server.pem \
--peer-key-file=/opt/etcd/ssl/server-key.pem \
--trusted-ca-file=/opt/etcd/ssl/ca.pem \
--peer-trusted-ca-file=/opt/etcd/ssl/ca.pem \
--logger=zap
Restart=on-failure
LimitNOFILE=65536[Install]
WantedBy=multi-user.target
EOF

3.9 将CA签发的etcd证书复制到etcd的TLS里

# 将CA签发的证书复制到etcd的ssl目录里
cp -ar /opt/TLS/etcd/{ca-key.pem,ca.pem,server-key.pem,server.pem} /opt/etcd/ssl/

3.10 将master节点所有生成的文件拷贝到节点2和节点3

IP地址和后面的值根据自己的实际情况改变。

for i in {1..2};do
scp -r /opt/etcd/ root@172.16.11.23$i:/opt/
scp /usr/lib/systemd/system/etcd.service root@172.16.11.23$i:/usr/lib/systemd/system/
done

3.11 修改节点2,节点3 ,etcd.conf配置文件中的节点名称和当前服务器IP:

cd /opt/etcd/cfg/
vim etcd.conf
#[Member]
ETCD_NAME="etcd-1"  #节点2修改为: etcd-2 节点3修改为: etcd-3
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_LISTEN_PEER_URLS="https://172.16.11.230:2380"		#修改为对应节点IP
ETCD_LISTEN_CLIENT_URLS="https://172.16.11.230:2379"	#修改为对应节点IP#[Clustering]
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://172.16.11.230:2380"	#修改为对应节点IP
ETCD_ADVERTISE_CLIENT_URLS="https://172.16.11.230:2379"			#修改为对应节点IP
ETCD_INITIAL_CLUSTER="etcd-1=https://172.16.11.230:2380,etcd-2=https://172.16.11.231:2380,etcd-3=https://172.16.11.232:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new"



3.12 启动etcd并设置开机自启(集群都启动)

说明:
etcd须多个节点同时启动,不然执行systemctl start etcd会一直卡在前台,连接其他节点,建议通过批量管理工具,或者脚本同时启动etcd。

systemctl daemon-reload
systemctl restart etcd
systemctl enable etcd
systemctl status etcd

3.13 检查etcd集群状态

IP需改成自己的

ETCDCTL_API=3 /opt/etcd/bin/etcdctl --cacert=/opt/etcd/ssl/ca.pem --cert=/opt/etcd/ssl/server.pem --key=/opt/etcd/ssl/server-key.pem --endpoints="https://172.16.11.230:2379,https://172.16.11.231:2379,https://172.16.11.232:2379" endpoint health --write-out=table

如果HEALTH为true状态证明部署的没有问题

3.14 etcd部署完成

四、部署Docker(所有节点)

这里使用Docker作为容器引擎,也可以换成别的,例如containerd,k8s在1.20版本就不在支持docker

推荐使用部署脚本一键部署:docker24.0.5离线安装包 (一键部署)

4.1 解压二进制包

# 如果提示下载无法连接SSL,可以多试几次或者网页下载在上传;
wget https://download.docker.com/linux/static/stable/x86_64/docker-24.0.5.tgz
# 下载的包也是统一放到/opt/packages/下,没有的可以创建一下
cd /opt/packages/
tar xf docker-24.0.5.tgz
mv docker/* /usr/bin/
# 查看docker目录下是否还有文件,没有就可以删了。
ls docker
rm -rf docker

4.2 配置镜像加速

mkdir -p /etc/docker
tee /etc/docker/daemon.json <<-'EOF'
{"registry-mirrors": ["https://docker.sunzishaokao.com"]
}
EOF

众所周知,docker镜像在国内基本拉不到了,而且镜像源时不时就不能用了,不过不用担心,大家可以参考此文,每个月都会更新docker镜像源,再也不用担心docker拉镜像拉不下来了。
文章地址:https://liucy.blog.csdn.net/article/details/129085538

4.3 systemd管理docker

cat > /usr/lib/systemd/system/docker.service << EOF
[Unit]  
Description=Docker Application Container Engine  
After=network.target  [Service]  
Type=notify  
ExecStart=/usr/bin/dockerd  
ExecReload=/bin/kill -s HUP $MAINPID  
LimitNOFILE=1048576  
LimitNPROC=1048576  [Install]  
WantedBy=multi-user.target
EOF

4.4 启动并设置开机启动

systemctl daemon-reload
systemctl restart docker
systemctl enable docker
systemctl status docker

五、部署Master节点

5.1 生成kube-apiserver证书

5.1.1 自签证书颁发机构(CA)

cd /opt/TLS/kubernetescat > ca-config.json << EOF
{"signing": {"default": {"expiry": "87600h"},"profiles": {"kubernetes": {"expiry": "87600h","usages": ["signing","key encipherment","server auth","client auth"]}}}
}
EOFcat > ca-csr.json << EOF
{"CN": "kubernetes","key": {"algo": "rsa","size": 2048},"names": [{"C": "CN","L": "Beijing","ST": "Beijing","O": "k8s","OU": "System"}]
}
EOF

生成证书:

cfssl gencert -initca ca-csr.json | cfssljson -bare ca -

执行以上命令会在当前目录下生成 ca-ket.pemca.pem文件;

5.1.2 使用自签CA签发kube-apiserver https证书

创建证书申请文件:

cat > server-csr.json << EOF
{"CN": "kubernetes","hosts": ["10.0.0.1","127.0.0.1","172.16.11.230","172.16.11.231","172.16.11.232","kubernetes","kubernetes.default","kubernetes.default.svc","kubernetes.default.svc.cluster","kubernetes.default.svc.cluster.local"],"key": {"algo": "rsa","size": 2048},"names": [{"C": "CN","L": "BeiJing","ST": "BeiJing","O": "k8s","OU": "System"}]
}
EOF

说明:
上述文件中hosts字段中IP为所有Master/LB/VIP IP,一个都不能少,为了方便后期扩容可以多写几个预留的IP。172的ip可以改为自己集群ip就行;

生成证书:

cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes server-csr.json | cfssljson -bare server

执行以上命令会在当前目录下生成 server-key.pemserver.pem文件;

5.2 安装kubectl命令

5.2.1 下载Kubernetes二进制包

Kubernetes下载地址1.20各版本下载地址:https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.20.md
选择自己要下载的版本,找到Server Binaries,根据平台选择自己需要下载的文件;


也可以直接在服务器上下载,我这里是1.20.10版本:

cd /opt/packages/
wget https://dl.k8s.io/v1.20.10/kubernetes-server-linux-amd64.tar.gz

5.2.2 解压二进制包并创建软件目录

上传刚才下载的kubernetes软件包到服务器上

# 创建kubernetes软件目录
mkdir -p /opt/kubernetes/{bin,cfg,ssl,logs} 
# 解压二进制包
tar xf kubernetes-server-linux-amd64.tar.gz
# 进入复制所需命令
cd kubernetes/server/bin
cp -ar kube-apiserver kube-scheduler kube-controller-manager /opt/kubernetes/bin
cp -ar kubectl /usr/bin/
# kubectl查看版本
kubectl version

5.3 部署 kube-apiserver

5.3.1 创建配置文件

cat > /opt/kubernetes/cfg/kube-apiserver.conf << EOF
KUBE_APISERVER_OPTS="--logtostderr=false \\
--v=2 \\
--log-dir=/opt/kubernetes/logs \\
--etcd-servers=https://172.16.11.230:2379,https://172.16.11.231:2379,https://172.16.11.232:2379 \\
--etcd-cafile=/opt/etcd/ssl/ca.pem \\
--etcd-certfile=/opt/etcd/ssl/server.pem \\
--etcd-keyfile=/opt/etcd/ssl/server-key.pem \\
--bind-address=172.16.11.230 \\
--secure-port=6443 \\
--advertise-address=172.16.11.230 \\
--allow-privileged=true \\
--service-cluster-ip-range=10.0.0.0/24 \\
--service-node-port-range=30000-32767 \\
--enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,ResourceQuota,NodeRestriction \\
--authorization-mode=RBAC,Node \\
--enable-bootstrap-token-auth=true \\
--token-auth-file=/opt/kubernetes/cfg/token.csv \\
--tls-cert-file=/opt/kubernetes/ssl/server.pem  \\
--tls-private-key-file=/opt/kubernetes/ssl/server-key.pem \\
--client-ca-file=/opt/kubernetes/ssl/ca.pem \\
--service-account-issuer=https://kubernetes.default.svc.cluster.local \\
--service-account-key-file=/opt/kubernetes/ssl/ca-key.pem \\
--service-account-signing-key-file=/opt/kubernetes/ssl/server-key.pem \\
--kubelet-client-certificate=/opt/kubernetes/ssl/server.pem \\
--kubelet-client-key=/opt/kubernetes/ssl/server-key.pem \\
--requestheader-client-ca-file=/opt/kubernetes/ssl/ca.pem \\
--proxy-client-cert-file=/opt/kubernetes/ssl/server.pem \\
--proxy-client-key-file=/opt/kubernetes/ssl/server-key.pem \\
--requestheader-allowed-names=kubernetes \\
--requestheader-extra-headers-prefix=X-Remote-Extra- \\
--requestheader-group-headers=X-Remote-Group \\
--requestheader-username-headers=X-Remote-User \\
--enable-aggregator-routing=true \\
--audit-log-path=/opt/kubernetes/logs/k8s-audit.log \\
--audit-log-maxage=30 \\
--audit-log-maxbackup=3 \\
--audit-log-maxsize=100"
EOF

说明:
上面配置后面的两个\\第一个代表的是转义符,第二个代表的是换行符,用转义符是为了使用EOF保留换行符。

  • 日志相关
参数含义
--logtostderr=false不把日志写到 stderr,而是写文件(配合 --log-dir)。
--v=2日志级别,数字越大越详细;2 是官方推荐生产值。
--log-dir=/opt/kubernetes/logs日志目录,需提前建好并给 kube-apiserver 用户写权限。
  • 连接 etcd 集群
参数含义
--etcd-servers=后端 etcd 地址列表,英文逗号分隔,不能有空格
--etcd-cafile=/opt/etcd/ssl/ca.pem校验 etcd 服务端证书的 CA。
--etcd-certfile=/opt/etcd/ssl/server.pemapiserver 访问 etcd 时用的客户端证书。
--etcd-keyfile=/opt/etcd/ssl/server-key.pem对应私钥。
  • 监听与广告地址
参数含义
--bind-address=172.16.11.230监听地址,apiserver 监听的 本地 IP(0.0.0.0 表示全部网卡)。
--secure-port=6443提供 HTTPS 服务的端口,默认 6443。
--advertise-address=172.16.11.230集群外组件(kubelet、kube-proxy、外部 LB)应该连的 IP;多主场景通常写 VIP 或当前节点实 IP。
  • 功能开关
参数含义
--allow-privileged=true允许运行特权容器,必须开,否则 kube-proxy、Calico 等 DaemonSet 无法启动。
  • Service 网段与 NodePort 范围
参数含义
--service-cluster-ip-range=10.0.0.0/24集群 Virtual IP 段,Service 的 ClusterIP 从这里分配;不要和 Pod CIDR、节点网络重叠
--service-node-port-range=30000-32767NodePort 类型 Service 可使用的宿主机端口范围,可自定义。
  • 准入插件
参数含义
--enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,ResourceQuota,NodeRestriction启用的准入控制器,缺一个都可能导致集群异常;顺序也有影响,保持官方推荐即可。
  • 认证与授权
参数含义
--authorization-mode=RBAC,Node授权顺序:先 RBAC,再 Node(kubelet 访问 apiserver 时用的专用授权器)。
--enable-bootstrap-token-auth=true允许使用 bootstrap token 自动签发 kubelet 证书,必需开,否则新节点无法注册。
--token-auth-file=/opt/kubernetes/cfg/token.csv静态 token 文件(旧版 bootstrap 方式,可与 bootstrap token 并存)。
  • 服务端 TLS(对外)
参数含义
--tls-cert-file=/opt/kubernetes/ssl/server.pemapiserver 对外暴露的 HTTPS 证书(含 SAN,必须包含所有访问地址)。
--tls-private-key-file=/opt/kubernetes/ssl/server-key.pem对应私钥。
--client-ca-file=/opt/kubernetes/ssl/ca.pem校验 客户端证书 的 CA(kubectl、kubelet、controller-manager 等)。
  • 服务账户(ServiceAccount)相关
参数含义
--service-account-issuer=签发 ServiceAccount token 的 issuer 字段,任意字符串,但要与 kube-controller-manager 的 --service-account-private-key-file 对应。
--service-account-key-file=/opt/kubernetes/ssl/ca-key.pem用来给 SA token 签名 的私钥(老用法,可用单独 RSA 密钥)。
--service-account-signing-key-file=/opt/kubernetes/ssl/server-key.pem新版 SA JWT 签名私钥,与上面可以复用同一密钥,但建议单独生成。
  • 连接 kubelet 的客户端证书
参数含义
--kubelet-client-certificate=/opt/kubernetes/ssl/server.pemapiserver 访问 kubelet(exec/logs/metrics)时用的客户端证书。
--kubelet-client-key=/opt/kubernetes/ssl/server-key.pem对应私钥。
  • 聚合层(Aggregator)(供 Metrics-Server、Custom-Metrics-API 使用)
参数含义
--requestheader-client-ca-file=/opt/kubernetes/ssl/ca.pem校验 前端代理(如 metrics-server)证书的 CA。
--proxy-client-cert-file=/opt/kubernetes/ssl/server.pemapiserver 当反向代理时,自己用的客户端证书,去向后端扩展 API Server 认证。
--proxy-client-key-file=/opt/kubernetes/ssl/server-key.pem对应私钥。
--requestheader-allowed-names=kubernetes代理证书里的 CN 必须等于 kubernetes,否则拒接。
--requestheader-*-headers告诉 apiserver 从 HTTP 头里取真实用户名/组/扩展字段,防止伪造。
--enable-aggregator-routing=true让 apiserver 把对 /apis/metrics.k8s.io/* 等请求直接转发到扩展服务,而不是让客户端自己去寻址;必需开,否则 metrics-server 会 503。
  • 审计日志
参数含义
--audit-log-path=/opt/kubernetes/logs/k8s-audit.log审计日志输出文件。
--audit-log-maxage=30保留 30 天。
--audit-log-maxbackup=3最多保留 3 个旧文件。
--audit-log-maxsize=100单个文件达到 100 MB 就轮转。


  • 易错点提醒
  • etcd 地址不能有空格,否则 apiserver 启动会报 invalid argument
  • 所有证书路径必须可读,否则启动直接 fail。
  • --service-cluster-ip-range 一旦设定不可更改,除非重建集群。
  • 多主高可用时,--advertise-address当前节点实 IPVIP,不要写 127.0.0.1。
  • 聚合层证书可以复用同一套,但生产建议单独生成一对,权限更小。

把上面参数都检查一遍,确认路径、IP、逗号无误后,就可以启动 kube-apiserver 了。



5.3.2 将CA签发的k8s证书复制到kubernetes的TLS里

cp -ar /opt/TLS/kubernetes/{ca-key.pem,ca.pem,server-key.pem,server.pem} /opt/kubernetes/ssl/

5.3.3 启用TLS bootstrapping机制

TLS Bootstraping:Master apiserver启用TLS认证后,Node节点kubelet和kube-proxy要与kube-apiserver进行通信,必须使用CA签发的有效证书才可以,当Node节点很多时,这种客户端证书颁发需要大量工作,同样也会增加集群扩展复杂度。为了简化流程,Kubernetes引入了TLS bootstraping机制来自动颁发客户端证书,kubelet会以一个低权限用户自动向apiserver申请证书,kubelet的证书由apiserver动态签署。所以强烈建议在Node上使用这种方式,目前主要用于kubelet,kube-proxy还是由我们统一颁发一个证书。
TLS bootstraping 工作流程:

token 通过
token 失败
证书 OK
证书失败
签发成功
签发失败
kubelet 启动
bootstrap.kubeconfig
apiserver
验证证书
启动失败
CSR
颁发证书
启动成功

全部正常工作流程:
token 通过
证书 OK
签发成功
kubelet 启动
bootstrap.kubeconfig
apiserver
验证证书
CSR
颁发证书
启动成功

创建上述配置文件中token文件:
cat > /opt/kubernetes/cfg/token.csv << EOF
14bc0c1956e615553c0f17d38a46626b,kubelet-bootstrap,10001,"system:node-bootstrapper"
EOF

token文件格式:token,用户名,UID,用户组,格式是固定的 4 段,用英文逗号隔开。

token也可自行生成替换(以下命令是随机生成16位字符):

head -c 16 /dev/urandom | od -An -t x | tr -d ' '

5.3.4 systemd管理apiserver

cat > /usr/lib/systemd/system/kube-apiserver.service << EOF
[Unit]
Description=Kubernetes API Server
Documentation=https://github.com/kubernetes/kubernetes[Service]
EnvironmentFile=/opt/kubernetes/cfg/kube-apiserver.conf
ExecStart=/opt/kubernetes/bin/kube-apiserver \$KUBE_APISERVER_OPTS
Restart=on-failure[Install]
WantedBy=multi-user.target
EOF

5.3.5 启动并设置开机启动

systemctl daemon-reload
systemctl start kube-apiserver 
systemctl enable kube-apiserver
systemctl status kube-apiserver

5.4 部署 kube-controller-manager

5.4.1 创建配置文件

cat > /opt/kubernetes/cfg/kube-controller-manager.conf << EOF
KUBE_CONTROLLER_MANAGER_OPTS="--logtostderr=false \\
--v=2 \\
--log-dir=/opt/kubernetes/logs \\
--leader-elect=true \\
--kubeconfig=/opt/kubernetes/cfg/kube-controller-manager.kubeconfig \\
--bind-address=127.0.0.1 \\
--allocate-node-cidrs=true \\
--cluster-cidr=10.244.0.0/16 \\
--service-cluster-ip-range=10.0.0.0/24 \\
--cluster-signing-cert-file=/opt/kubernetes/ssl/ca.pem \\
--cluster-signing-key-file=/opt/kubernetes/ssl/ca-key.pem  \\
--root-ca-file=/opt/kubernetes/ssl/ca.pem \\
--service-account-private-key-file=/opt/kubernetes/ssl/ca-key.pem \\
--cluster-signing-duration=87600h0m0s"
EOF

配置文件说明:

  • 日志相关
内容含义
--logtostderr=false不输出到 stderr,写文件(配合 --log-dir)。
--v=2日志级别,2 足够生产使用。
--log-dir=/opt/kubernetes/logs日志落盘目录,需提前建好并给 systemd 用户写权限。 ⚠️
  • 高可用开关
内容含义
--leader-elect=true多主场景必须开,让各实例通过 etcd 选主;单主可关但建议保留。
  • 身份与连接
内容含义
--kubeconfig=/opt/kubernetes/cfg/kube-controller-manager.kubeconfig自带 apiserver 地址 + 客户端证书 + CA,用于与 apiserver 通信;文件必须存在且证书未过期。 ⚠️
--bind-address=127.0.0.1控制器监听 仅本机 的 metrics 端口(10252/10257);多主监控需改成 0.0.0.0 或实 IP。 ⚠️
  • 网络段分配
内容含义
--allocate-node-cidrs=trueNode IPAM 生效,必须为 true,否则 controller 不会给 Node 分配 PodCIDR。 ⚠️
--cluster-cidr=10.244.0.0/16整个集群 Pod 网段,与 kube-proxy、CNI、kubelet 的 --cluster-cidr 保持一致。 ⚠️
--service-cluster-ip-range=10.0.0.0/24Service VIP 范围,必须和 apiserver 的同名参数完全一致。 ⚠️
  • 证书自动签发(CA 与期限)
内容含义
--cluster-signing-cert-file=/opt/kubernetes/ssl/ca.pemNode、CSR、ServiceAccount 签证书的 CA 证书。自动为kubelet颁发证书的CA,apiserver保持一致
--cluster-signing-key-file=/opt/kubernetes/ssl/ca-key.pem自动为kubelet颁发证书的CA,apiserver保持一致
--cluster-signing-duration=87600h0m0s签出的证书有效期 10 年,生产可缩短(如 8760h)。
  • 根 CA & ServiceAccount JWT
内容含义
--root-ca-file=/opt/kubernetes/ssl/ca.pem注入到 每个 ServiceAccount/var/run/secrets/kubernetes.io/serviceaccount/ca.crt;与 apiserver 的 --client-ca-file 保持一致。 ⚠️
--service-account-private-key-file=/opt/kubernetes/ssl/ca-key.pemSA token 签名的私钥;与 apiserver 的 --service-account-signing-key-file 必须 同一对密钥,否则 token 验证失败。 ⚠️

5.4.2 生成kube-controller-manager证书

# 切换工作目录
cd /opt/TLS/kubernetes# 创建证书请求文件
cat > kube-controller-manager-csr.json << EOF
{"CN": "system:kube-controller-manager","hosts": [],"key": {"algo": "rsa","size": 2048},"names": [{"C": "CN","L": "BeiJing", "ST": "BeiJing","O": "system:masters","OU": "System"}]
}
EOF

生成证书:

cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kube-controller-manager-csr.json | cfssljson -bare kube-controller-manager

执行以上命令会在当前目录下生成 kube-controller-manager-key.pemkube-controller-manager.pem文件;

5.4.3 生成 kube-controller-manager 的 kubeconfig 文件

以下内容是在命令行直接执行的,需要注意生成的kubeconfig文件路径、所有pem的位置、及IP地址,如果不一样记得修改;

KUBE_CONFIG="/opt/kubernetes/cfg/kube-controller-manager.kubeconfig"
KUBE_APISERVER="https://172.16.11.230:6443"kubectl config set-cluster kubernetes \--certificate-authority=/opt/kubernetes/ssl/ca.pem \--embed-certs=true \--server=${KUBE_APISERVER} \--kubeconfig=${KUBE_CONFIG}kubectl config set-credentials kube-controller-manager \--client-certificate=/opt/TLS/kubernetes/kube-controller-manager.pem \--client-key=/opt/TLS/kubernetes/kube-controller-manager-key.pem \--embed-certs=true \--kubeconfig=${KUBE_CONFIG}kubectl config set-context default \--cluster=kubernetes \--user=kube-controller-manager \--kubeconfig=${KUBE_CONFIG}kubectl config use-context default --kubeconfig=${KUBE_CONFIG}

生成完之后会在/opt/kubernetes/cfg/目录下有一个kube-controller-manager.kubeconfig文件;

5.4.4 systemd管理controller-manager

cat > /usr/lib/systemd/system/kube-controller-manager.service << EOF
[Unit]
Description=Kubernetes Controller Manager
Documentation=https://github.com/kubernetes/kubernetes[Service]
EnvironmentFile=/opt/kubernetes/cfg/kube-controller-manager.conf
ExecStart=/opt/kubernetes/bin/kube-controller-manager \$KUBE_CONTROLLER_MANAGER_OPTS
Restart=on-failure[Install]
WantedBy=multi-user.target
EOF

5.4.5 启动并设置开机自启

需确保kube-apiserver服务起来,否则kube-controller-manager会启动失败;

systemctl daemon-reload
systemctl start kube-controller-manager
systemctl enable kube-controller-manager
systemctl status kube-controller-manager

5.5 部署 kube-scheduler

5.5.1 创建配置文件

cat > /opt/kubernetes/cfg/kube-scheduler.conf << EOF
KUBE_SCHEDULER_OPTS="--logtostderr=false \\
--v=2 \\
--log-dir=/opt/kubernetes/logs \\
--leader-elect \\
--kubeconfig=/opt/kubernetes/cfg/kube-scheduler.kubeconfig \\
--bind-address=127.0.0.1"
EOF
  • --kubeconfig :连接apiserver配置文件
  • --leader-elect :当该组件启动多个时,自动选举(HA)。

5.5.2 生成kube-scheduler证书

# 切换工作目录
cd /opt/TLS/kubernetes# 创建证书请求文件
cat > kube-scheduler-csr.json << EOF
{"CN": "system:kube-scheduler","hosts": [],"key": {"algo": "rsa","size": 2048},"names": [{"C": "CN","L": "BeiJing","ST": "BeiJing","O": "system:masters","OU": "System"}]
}
EOF

生成证书

cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kube-scheduler-csr.json | cfssljson -bare kube-scheduler

执行以上命令会在当前目录下生成 kube-scheduler-key.pemkube-scheduler.pem文件;

5.5.3 生成 kube-scheduler 的 kubeconfig 文件

以下内容是在命令行直接执行的,需要注意生成的kubeconfig文件路径、所有pem的位置、及IP地址,如果不一样记得修改;

KUBE_CONFIG="/opt/kubernetes/cfg/kube-scheduler.kubeconfig"
KUBE_APISERVER="https://172.16.11.230:6443"kubectl config set-cluster kubernetes \--certificate-authority=/opt/kubernetes/ssl/ca.pem \--embed-certs=true \--server=${KUBE_APISERVER} \--kubeconfig=${KUBE_CONFIG}kubectl config set-credentials kube-scheduler \--client-certificate=/opt/TLS/kubernetes/kube-scheduler.pem \--client-key=/opt/TLS/kubernetes/kube-scheduler-key.pem \--embed-certs=true \--kubeconfig=${KUBE_CONFIG}kubectl config set-context default \--cluster=kubernetes \--user=kube-scheduler \--kubeconfig=${KUBE_CONFIG}kubectl config use-context default --kubeconfig=${KUBE_CONFIG}

生成完之后会在/opt/kubernetes/cfg/目录下有一个kube-scheduler.kubeconfig文件;

5.5.4 systemd管理scheduler

cat > /usr/lib/systemd/system/kube-scheduler.service << EOF
[Unit]
Description=Kubernetes Scheduler
Documentation=https://github.com/kubernetes/kubernetes[Service]
EnvironmentFile=/opt/kubernetes/cfg/kube-scheduler.conf
ExecStart=/opt/kubernetes/bin/kube-scheduler \$KUBE_SCHEDULER_OPTS
Restart=on-failure[Install]
WantedBy=multi-user.target
EOF

5.5.5 启动并设置开机启动

需确保kube-apiserverkube-controller-manager服务起来了,否则kube-scheduler会启动失败;

systemctl daemon-reload
systemctl start kube-scheduler
systemctl enable kube-scheduler
systemctl status kube-scheduler

5.6 查看集群状态

5.6.1 生成kubectl连接集群的证书

# 切换工作目录
cd /opt/TLS/kubernetes# 创建证书请求文件
cat > admin-csr.json <<EOF
{"CN": "admin","hosts": [],"key": {"algo": "rsa","size": 2048},"names": [{"C": "CN","L": "BeiJing","ST": "BeiJing","O": "system:masters","OU": "System"}]
}
EOF

生成证书

cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes admin-csr.json | cfssljson -bare admin

执行以上命令会在当前目录下生成 admin-key.pemadmin.pem文件;

5.6.2 生成 kubectl 的 kubeconfig 文件

以下内容是在命令行直接执行的,需要注意生成的kubeconfig文件路径、所有pem的位置、及IP地址,如果不一样记得修改;

mkdir /root/.kubeKUBE_CONFIG="/root/.kube/config"
KUBE_APISERVER="https://172.16.11.230:6443"kubectl config set-cluster kubernetes \--certificate-authority=/opt/kubernetes/ssl/ca.pem \--embed-certs=true \--server=${KUBE_APISERVER} \--kubeconfig=${KUBE_CONFIG}kubectl config set-credentials cluster-admin \--client-certificate=/opt/TLS/kubernetes/admin.pem \--client-key=/opt/TLS/kubernetes/admin-key.pem \--embed-certs=true \--kubeconfig=${KUBE_CONFIG}kubectl config set-context default \--cluster=kubernetes \--user=cluster-admin \--kubeconfig=${KUBE_CONFIG}kubectl config use-context default --kubeconfig=${KUBE_CONFIG}

生成完之后会在/root/.kube/目录下有一个config文件;

5.6.3 通过kubectl工具查看当前集群组件状态

[root@k8s-master .kube]# kubectl get cs
Warning: v1 ComponentStatus is deprecated in v1.19+
NAME                 STATUS    MESSAGE             ERROR
scheduler            Healthy   ok                  
controller-manager   Healthy   ok                  
etcd-0               Healthy   {"health":"true"}   
etcd-1               Healthy   {"health":"true"}   
etcd-2               Healthy   {"health":"true"}   

kubectl get cs 里的 cscomponentstatus 的缩写,即“组件状态”。
这条命令用来快速查看 Kubernetes 控制平面四大核心组件的健康状况

  • scheduler
  • controller-manager
  • etcd-0
  • (1.19 之后 apiserver 不再列出,因为 apiserver 自己就是接口提供者)

如上STATUS都是Healthy说明Master节点所有组件运行正常。
更明显的可以看后面的MESSAGE都是oktrue,那么也可以说明Master节点所有组件运行正常。

5.6.4 授权kubelet-bootstrap用户允许请求证书

kubectl create clusterrolebinding kubelet-bootstrap \
--clusterrole=system:node-bootstrapper \
--user=kubelet-bootstrap

验证:

kubectl get clusterrolebinding kubelet-bootstrap -o wide

六、Master节点部署Node

6.1 复制kubelet及kube-proxy命令

# 进入复制所需命令
cd /opt/packages/kubernetes/server/bin
cp -ar kubelet kube-proxy /opt/kubernetes/bin

6.2 部署kubelet

6.2.1 创建kubelet配置文件

cat > /opt/kubernetes/cfg/kubelet.conf << EOF
KUBELET_OPTS="--logtostderr=false \\
--v=2 \\
--log-dir=/opt/kubernetes/logs \\
--hostname-override=k8s-master \\
--network-plugin=cni \\
--kubeconfig=/opt/kubernetes/cfg/kubelet.kubeconfig \\
--bootstrap-kubeconfig=/opt/kubernetes/cfg/bootstrap.kubeconfig \\
--config=/opt/kubernetes/cfg/kubelet-config.yml \\
--cert-dir=/opt/kubernetes/ssl \\
--pod-infra-container-image=registry.cn-hangzhou.aliyuncs.com/google-containers/pause-amd64:3.0"
EOF

个别参数解析:

  • --hostname-override :显示名称,集群唯一(不可重复)。
  • --network-plugin :启用CNI。
  • --kubeconfig : 空路径,会自动生成,后面用于连接apiserver。
  • --bootstrap-kubeconfig :首次启动向apiserver申请证书。
  • --config :配置文件参数。
  • --cert-dir :kubelet证书目录。
  • --pod-infra-container-image :管理Pod网络容器的镜像 init container

6.2.2 配置kubelet参数文件

cat > /opt/kubernetes/cfg/kubelet-config.yml << EOF
kind: KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
address: 0.0.0.0
port: 10250
readOnlyPort: 10255
cgroupDriver: cgroupfs
clusterDNS:
- 10.0.0.2
clusterDomain: cluster.local 
failSwapOn: false
authentication:anonymous:enabled: falsewebhook:cacheTTL: 2m0senabled: truex509:clientCAFile: /opt/kubernetes/ssl/ca.pem 
authorization:mode: Webhookwebhook:cacheAuthorizedTTL: 5m0scacheUnauthorizedTTL: 30s
evictionHard:imagefs.available: 15%memory.available: 100Minodefs.available: 10%nodefs.inodesFree: 5%
maxOpenFiles: 1000000
maxPods: 110
EOF

个别参数解析:

  • imagefs.available: 15%镜像存储剩余 <15% 开始驱离 Pod(按镜像用量排序)。
  • memory.available: 100Mi节点可用内存<100Mi 立即驱离,最敏感指标;可酌情调到 200~500Mi。
  • nodefs.available: 10% / nodefs.inodesFree: 5%根分区空间/索引耗尽保护;/var/lib/kubelet 必须在此分区。
  • maxOpenFiles: 1000000: 给 kubelet 进程的 ulimit;容器太多时防止 “too many open files”。
  • maxPods: 110 :本节点 最大 Pod 数,与 kube-scheduler 的 NodeAllocatable 一致;受 CNI/网卡/CPU 限制,可向下调。

6.2.3 生成kubelet初次加入集群引导kubeconfig文件

KUBE_CONFIG="/opt/kubernetes/cfg/bootstrap.kubeconfig"
KUBE_APISERVER="https://172.16.11.230:6443" # apiserver IP:PORT
TOKEN="14bc0c1956e615553c0f17d38a46626b" # 与token.csv里保持一致  /opt/kubernetes/cfg/token.csv # 生成 kubelet bootstrap kubeconfig 配置文件
kubectl config set-cluster kubernetes \--certificate-authority=/opt/kubernetes/ssl/ca.pem \--embed-certs=true \--server=${KUBE_APISERVER} \--kubeconfig=${KUBE_CONFIG}kubectl config set-credentials "kubelet-bootstrap" \--token=${TOKEN} \--kubeconfig=${KUBE_CONFIG}kubectl config set-context default \--cluster=kubernetes \--user="kubelet-bootstrap" \--kubeconfig=${KUBE_CONFIG}kubectl config use-context default --kubeconfig=${KUBE_CONFIG}

6.2.4 systemd管理kubelet

cat > /usr/lib/systemd/system/kubelet.service << EOF
[Unit]
Description=Kubernetes Kubelet
After=docker.service[Service]
EnvironmentFile=/opt/kubernetes/cfg/kubelet.conf
ExecStart=/opt/kubernetes/bin/kubelet \$KUBELET_OPTS
Restart=on-failure
LimitNOFILE=65536[Install]
WantedBy=multi-user.target
EOF

6.2.5 启动并设置开机启动

systemctl daemon-reload
systemctl restart kubelet
systemctl enable kubelet
systemctl status kubelet

6.2.6 允许kubelet证书申请并加入集群

#查看kubelet证书请求
[root@k8s-master bin]# kubectl get csr
NAME                                                   AGE   SIGNERNAME                                    REQUESTOR           CONDITION
node-csr-EyTv0HKOIFIvYxhnE2Oe5hVIaKkg4cbVeuKnBH2i0_Q   12s   kubernetes.io/kube-apiserver-client-kubelet   kubelet-bootstrap   Pending#允许kubelet节点申请
[root@k8s-master bin]# kubectl certificate approve node-csr-EyTv0HKOIFIvYxhnE2Oe5hVIaKkg4cbVeuKnBH2i0_Q
certificatesigningrequest.certificates.k8s.io/node-csr-EyTv0HKOIFIvYxhnE2Oe5hVIaKkg4cbVeuKnBH2i0_Q approved#查看申请
[root@k8s-master bin]# kubectl get csr
NAME                                                   AGE     SIGNERNAME                                    REQUESTOR           CONDITION
node-csr-KbHieprZUMOvTFMHGQ1RNTZEhsSlT5X6wsh2lzfUry4   2m35s   kubernetes.io/kube-apiserver-client-kubelet   kubelet-bootstrap   Approved,Issued#查看节点
[root@k8s-master bin]# kubectl get nodes
NAME          STATUS     ROLES    AGE     VERSION
k8s-master   NotReady   <none>    17s     v1.20.10

说明:
  由于网络插件还没有部署,所以查看nodes节点的时候STATUS展示的是NotReady状态。

6.3 部署kube-proxy

6.3.1 创建配置文件

cat > /opt/kubernetes/cfg/kube-proxy.conf << EOF
KUBE_PROXY_OPTS="--logtostderr=false \\
--v=2 \\
--log-dir=/opt/kubernetes/logs \\
--config=/opt/kubernetes/cfg/kube-proxy-config.yml"
EOF

6.3.2 配置参数文件

cat > /opt/kubernetes/cfg/kube-proxy-config.yml << EOF
kind: KubeProxyConfiguration
apiVersion: kubeproxy.config.k8s.io/v1alpha1
bindAddress: 0.0.0.0
metricsBindAddress: 0.0.0.0:10249
clientConnection:kubeconfig: /opt/kubernetes/cfg/kube-proxy.kubeconfig
hostnameOverride: k8s-master
clusterCIDR: 10.244.0.0/16
EOF

6.3.3 生成kube-proxy证书文件

# 切换工作目录
cd /opt/TLS/kubernetes# 创建证书请求文件
cat > kube-proxy-csr.json << EOF
{"CN": "system:kube-proxy","hosts": [],"key": {"algo": "rsa","size": 2048},"names": [{"C": "CN","L": "BeiJing","ST": "BeiJing","O": "k8s","OU": "System"}]
}
EOF

生成证书

cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kube-proxy-csr.json | cfssljson -bare kube-proxy

执行以上命令会在当前目录下生成 kube-proxy 相关的证书文件;

6.3.4 生成kube-proxy.kubeconfig文件

KUBE_CONFIG="/opt/kubernetes/cfg/kube-proxy.kubeconfig"
KUBE_APISERVER="https://172.16.11.230:6443"kubectl config set-cluster kubernetes \--certificate-authority=/opt/kubernetes/ssl/ca.pem \--embed-certs=true \--server=${KUBE_APISERVER} \--kubeconfig=${KUBE_CONFIG}kubectl config set-credentials kube-proxy \--client-certificate=./kube-proxy.pem \--client-key=./kube-proxy-key.pem \--embed-certs=true \--kubeconfig=${KUBE_CONFIG}kubectl config set-context default \--cluster=kubernetes \--user=kube-proxy \--kubeconfig=${KUBE_CONFIG}kubectl config use-context default --kubeconfig=${KUBE_CONFIG}

6.3.5 systemd管理kube-proxy

cat > /usr/lib/systemd/system/kube-proxy.service << EOF
[Unit]
Description=Kubernetes Proxy
After=network.target[Service]
EnvironmentFile=/opt/kubernetes/cfg/kube-proxy.conf
ExecStart=/opt/kubernetes/bin/kube-proxy \$KUBE_PROXY_OPTS
Restart=on-failure
LimitNOFILE=65536[Install]
WantedBy=multi-user.target
EOF

6.3.6 启动并设置开机自启

systemctl daemon-reload
systemctl start kube-proxy
systemctl enable kube-proxy
systemctl status kube-proxy

6.4 部署网络组件(Calico)

Calico是一个纯三层的数据中心网络方案,是目前Kubernetes主流的集群网络方案。

  • 拉取calico.yaml文件
# 拉取默认是最新3.15中最新的3.15.5版本,如果需要其他版本可以在文章最后找附件calico-yml。
curl -O https://calico-v3-15.netlify.app/archive/v3.15/manifests/calico.yaml
  • 创建并启动网络服务
kubectl apply -f calico.yaml
# 查看创建的网络服务
kubectl get pods -n kube-system

第一次创建很慢,因为要拉取镜像,可以使用kubectl describe pod -n kube-system calico-node-pgxpz 查看详细创建过程,如果是卡到了docker拉取镜像这里,那就可能是docker的镜像加速地址失效了,可以参考如下文章,每个月都会更新docker镜像加速地址;
docker镜像加速文章地址:https://liucy.blog.csdn.net/article/details/129085538

Calico PodREADY都为1/1或者STATUSRunning的时候,就是正常启动成功了;节点也会准备就绪。

[root@k8s-master packages]# kubectl get pods -n kube-system
NAME                                      READY   STATUS    RESTARTS   AGE
calico-kube-controllers-bc4f7c685-llqwk   1/1     Running   0          33m
calico-node-pgxpz                         1/1     Running   0          33m# 再次查看nodes节点的状态,为Ready即可;
[root@k8s-master packages]# kubectl get nodes 
NAME         STATUS   ROLES    AGE   VERSION
k8s-master   Ready    <none>   21h   v1.20.10


calico默认拉取的镜像都有如下:


6.5 授权apiserver访问kubelet

为什么让apiserver访问kubelete?

需要让 kube-apiserver 有权限去调用 kubelet 的 “只读” 接口(/logs/metrics/exec/portforward…)相当于给“apiserver 自己”签发一张 RBAC 通行证,让它有资格替用户去 kubelet 拿数据,这样 kubectl logskubectl exec等命令才能正常工作。如果没有它,kubectl logs/exec/portforward/ 全部会卡在 Forbidden

应用场景:如kubectl logskubectl exec kubectl cp等。

cat > apiserver-to-kubelet-rbac.yaml << EOF
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:annotations:rbac.authorization.kubernetes.io/autoupdate: "true"labels:kubernetes.io/bootstrapping: rbac-defaultsname: system:kube-apiserver-to-kubelet
rules:- apiGroups:- ""resources:- nodes/proxy- nodes/stats- nodes/log- nodes/spec- nodes/metrics- pods/logverbs:- "*"
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:name: system:kube-apiservernamespace: ""
roleRef:apiGroup: rbac.authorization.k8s.iokind: ClusterRolename: system:kube-apiserver-to-kubelet
subjects:- apiGroup: rbac.authorization.k8s.iokind: Username: kubernetes
EOF
# 创建并运行
kubectl apply -f apiserver-to-kubelet-rbac.yaml
  • 验证
# 看 ClusterRole
kubectl get clusterrole system:kube-apiserver-to-kubelet# 看 ClusterRoleBinding
kubectl get clusterrolebinding system:kube-apiserver# 查看详情
kubectl describe clusterrole system:kube-apiserver-to-kubelet
kubectl describe clusterrolebinding system:kube-apiserver

只要两条 get 都能拿到资源,且 describe 里规则、subjects 无误,就说明 YAML 语法层面成功

# 找任意 Pod 查看日志
kubectl logs -n <ns> <pod>
kubectl logs -n kube-system calico-node-pgxpz
  • 若 RBAC 没配,会报
    Error from server: Forbidden (user kubernetes cannot get nodes/proxy)
  • 若成功返回日志,则 授权链路 100% 生效

总结验证是否成功:先用 kubectl get clusterrole/clusterrolebinding 看对象是否存在,再用 kubectl logs/exec/top 等命令实测功能;两者都通过即可确认“此 YAML 已成功生效”。

6.6 部署 Metrics-Server 实现 kubectl top 与自动伸缩

(解决 error: Metrics API not available,为 HPA/VPA 提供 CPU/内存指标)

为什么必须装 Metrics-Server?
kubectl top、HPA、VPA、调度器评分等都需要实时 CPU/内存数据;Metrics-Server 把这些指标聚合并暴露成 Metrics API (v1beta1.metrics.k8s.io),缺了它集群就“看不见”资源用量。

应用场景kubectl top nodes/pods、HPA 自动伸缩、调度器优选、kube-scheduler 打分。

  • 版本对照表
Metrics-Server 版本兼容 K8s 版本备注
v0.3.x1.8 – 1.17老版本,镜像仍在 gcr.io,国内拉取困难
v0.4.x1.16 – 1.19末代 v1beta1 单版本 API
v0.5.x1.19 – 1.22开始支持 autoscaling/v2beta1;需 TLS 校验
v0.6.31.20 – 1.251.20 推荐版本;支持 autoscaling/v2;国内镜像可用
v0.7.x1.26+默认使用 v1 API,最低要求 1.26
  • 1、安装:下载官方 YAML

下载不下来看最后附件链接里面都有;

wget https://github.com/kubernetes-sigs/metrics-server/releases/download/v0.6.3/components.yaml
  • 2、修改为国内镜像源 + 参数
sed -i 's|registry.k8s.io/metrics-server|registry.cn-hangzhou.aliyuncs.com/google_containers|g' components.yaml# 在 args 区追加两行
sed -i '/args:/a\        - --kubelet-insecure-tls' components.yaml
sed -i '/args:/a\        - --kubelet-preferred-address-types=InternalIP,Hostname,ExternalIP' components.yaml

  • 3、部署 & 等待 Ready
kubectl apply -f components.yaml# 看 Pod
kubectl get pods -n kube-system | grep metrics-server

等待状态 Running 1/1 即成功;

  • 4、验证 API 注册成功
kubectl get apiservice | grep metrics
# 出现 v1beta1.metrics.k8s.io True 即注册完成
  • 5、验证 kuberctl top
kubectl top nodes

如下输出正常,则成功;

6.7 kubernetes强化tab(安装之后会tab可以补全命令及参数)

echo 'source  <(kubectl  completion  bash)' >> ~/.bashrc

1、退出连接,重新连接;
2、或者bash更新环境就可以使用了。

七、新增加Work Node(其他两个node节点)

7.1 拷贝以部署好的相关文件到新节点

Master节点将Work Node涉及文件拷贝到其他新节点 172.16.11.231/172.16.11.232

for i in {1..2}; do scp -r /opt/kubernetes root@172.16.11.23$i:/opt/; donefor i in {1..2}; do scp -r /usr/lib/systemd/system/{kubelet,kube-proxy}.service root@172.16.11.23$i:/usr/lib/systemd/system; done

7.2 删除kubelet证书和kubeconfig文件

rm -f /opt/kubernetes/cfg/kubelet.kubeconfig 
rm -f /opt/kubernetes/ssl/kubelet*

说明:
这几个文件是证书申请审批后自动生成的,每个Node不同,必须删除。

7.3 修改kubelet和kubeproxy配置中的主机名

# ---------------------node1---------------------
vi /opt/kubernetes/cfg/kubelet.conf
--hostname-override=k8s-node1vi /opt/kubernetes/cfg/kube-proxy-config.yml
hostnameOverride: k8s-node1# ---------------------node2---------------------
vi /opt/kubernetes/cfg/kubelet.conf
--hostname-override=k8s-node2vi /opt/kubernetes/cfg/kube-proxy-config.yml
hostnameOverride: k8s-node2

7.4 启动并设置开机自启

systemctl daemon-reload
systemctl start kubelet kube-proxy
systemctl enable kubelet kube-proxy
systemctl status kubelet kube-proxy

7.5 在Master节点上同意新的Node kubelet证书申请

#查看证书请求
[root@k8s-master ~]# kubectl get csr
NAME                                                   AGE   SIGNERNAME                                    REQUESTOR           CONDITION
node-csr-n8MYKY4us2_nVF-qRNZCYFGouhLO9-gj-mHMsPfrvZQ   17h   kubernetes.io/kube-apiserver-client-kubelet   kubelet-bootstrap   Pending
node-csr-nj5FFQBNkH-z2NEoQpRjkVhHfps7mzGvWKIWvoO1Fh4   17h   kubernetes.io/kube-apiserver-client-kubelet   kubelet-bootstrap   Pending#同意新的node请求
[root@k8s-master ~]# kubectl certificate approve node-csr-n8MYKY4us2_nVF-qRNZCYFGouhLO9-gj-mHMsPfrvZQ node-csr-nj5FFQBNkH-z2NEoQpRjkVhHfps7mzGvWKIWvoO1Fh4
certificatesigningrequest.certificates.k8s.io/node-csr-n8MYKY4us2_nVF-qRNZCYFGouhLO9-gj-mHMsPfrvZQ approved
certificatesigningrequest.certificates.k8s.io/node-csr-nj5FFQBNkH-z2NEoQpRjkVhHfps7mzGvWKIWvoO1Fh4 approved# 查看申请
[root@k8s-master ~]# kubectl get csr
NAME                                                   AGE   SIGNERNAME                                    REQUESTOR           CONDITION
node-csr-n8MYKY4us2_nVF-qRNZCYFGouhLO9-gj-mHMsPfrvZQ   18h   kubernetes.io/kube-apiserver-client-kubelet   kubelet-bootstrap   Approved,Issued
node-csr-nj5FFQBNkH-z2NEoQpRjkVhHfps7mzGvWKIWvoO1Fh4   18h   kubernetes.io/kube-apiserver-client-kubelet   kubelet-bootstrap   Approved,Issued

7.6 查看Node节点的状态

要稍等会才STATUS会变成Ready,因为需要再node节点上下载一些初始化calico镜像,当然两台node节点的docker镜像加速地址也需要为可用的,否则会下载失败导致起不来;

[root@k8s-master ~]# kubectl get nodes
NAME         STATUS     ROLES    AGE     VERSION
k8s-master   Ready      <none>   44h     v1.20.10
k8s-node1    NotReady   <none>   6m37s   v1.20.10
k8s-node2    NotReady   <none>   6m37s   v1.20.10

可用使用命令查看所有的pods,会多出来两个calicopod,这代表的是再其他两个节点上运行的网络插件,使用-o wide可用看清楚这个pod再哪个节点上运行着;

[root@k8s-master ~]# kubectl get pods -A  -o wide
NAMESPACE     NAME                                      READY   STATUS    RESTARTS   AGE    IP                NODE         NOMINATED NODE   READINESS GATES
kube-system   calico-kube-controllers-bc4f7c685-llqwk   1/1     Running   0          25h    192.168.235.193   k8s-master   <none>           <none>
kube-system   calico-node-d4mkp                         1/1     Running   1          170m   172.16.11.232     k8s-node2    <none>           <none>
kube-system   calico-node-pgxpz                         1/1     Running   0          25h    172.16.11.230     k8s-master   <none>           <none>
kube-system   calico-node-z56kl                         1/1     Running   0          170m   172.16.11.231     k8s-node1    <none>           <none>

所有calico-node-*READY 都为1/1或者STATUS状态都为Running,说明都起来了, 这时候就可以再次检查node节点的状态了。

[root@k8s-master ~]# kubectl get nodes
NAME         STATUS   ROLES    AGE    VERSION
k8s-master   Ready    <none>   47h    v1.20.10
k8s-node1    Ready    <none>   172m   v1.20.10
k8s-node2    Ready    <none>   172m   v1.20.10

两台node节点上calico服务默认拉取的镜像都有如下:

确保这四个都有,pod的calico的状态就会正常运行;


本文转自 https://blog.csdn.net/qq_44078641/article/details/120049473,如有侵权,请联系删除。

八、附加:网盘链接

网盘链接:k8s1.20.10集群所需包

九、问题:

待定。。

http://www.dtcms.com/a/519822.html

相关文章:

  • 每日一个C语言知识:C typedef
  • 交叉编译FFmpeg:从x264到RK3588部署实战
  • LeetCode算法日记 - Day 82: 环形子数组的最大和
  • Leetcode 36
  • 深入理解epoll:为什么推荐使用epoll_create1而不是epoll_create?
  • 公司被其它人拿来做网站营销渠道的概念
  • 在 Linux 下使用 I2C(Inter-Integrated Circuit)进行用户态编程 — 教程与实战
  • 替代HT1621B液晶驱动显示模块芯片程序演示
  • C++和OpenGL实现3D游戏编程【连载26】——添加TransformComponent组件(设置子物体的位移、旋转、缩放)
  • 常规条形光源在工业视觉检测上的应用
  • Zotero插件安装
  • Llama Factory、Unsloth与Hugging Face三大微调平台深度对比分析
  • 电脑卡在 “正在准备 Windows”?5 步解决:从等待到重装
  • 优惠券网站要怎么做的佛山禅城网站建设
  • 基于深度学习计算s21参数,在射频中的应用
  • 微服务day01——拆分作业参考
  • YOLO11训练后的模型无法正常推理解决办法
  • 网站模版 优帮云深圳网络安全公司排名
  • navicat过期了,怎么操作mysql。用DBeaver
  • LangGraph工作流与智能体核心模式总结
  • redis常见问题解决
  • 网站顶部有空白网络营销是什么时候出现的
  • NFS文件存储
  • 07_朴素贝叶斯
  • 【源码项目】简单实现的WPF浏览器,有兴趣的可以自己扩展(带源码)
  • 大连做网站哪家好一点商务网站建设用的是什么软件
  • Mybatis一级缓存
  • Java+OpenCV实现图片切割
  • Linux云计算基础篇(24)-PXE批量安装和Kickstart工具
  • 从零搭建 RAG 智能问答系统 6:Text2SQL 与工作流实现数据库查询