Centos7.9 使用 Kubeadm 自动化部署 K8S 集群(一个脚本)

news2024/11/15 19:55:30

文章目录

  • 一、环境准备
    • 1、硬件准备(虚拟主机)
    • 2、操作系统版本
    • 3、硬件配置
    • 4、网络
  • 二、注意点
    • 1、主机命名格式
    • 2、网络插件 flannel 镜像拉取
      • 2.1、主机生成公私钥
      • 2.2、为啥有 Github 还用 Gitee
      • 2.3、将主机公钥添加到 Gitee
        • 2.3.1、复制主机上的公钥
        • 2.3.2、登录码云
        • 2.3.3、设置 --> 安全设置 --> SSH公钥
        • 2.3.4、添加公钥
      • 2.4、将主机公钥添加到 Github
        • 2.4.1、点击头像 --> settings
        • 2.4.2、左侧列表中找到 SSH and GPG keys 点击 New SSH key
    • 3、阿里云的镜像加速地址
      • 3.1、镜像加速器地址
      • 3.2、对应脚本的修改位置
    • 4、运行脚本时需要加入集群的主机都在线
      • 4.1、通过 SSH 配置免密登录
      • 4.2、在 master 节点上执行登录各节点执行加入集群命令
    • 5、输入正确的目标主机名
    • 6、脚本适用性
  • 三、脚本
  • 四、实例演示
    • 1、硬件准备
    • 2、**,启动!
    • 3、创建脚本文件(CV大法)
    • 4、运行脚本
    • 5、判断并关闭完firewalld、selinux、swap 后输入目标主机名
    • 6、master节点将预设的集群列表一个个追加到/etc/hosts文件中,所有节点执行判断逻辑
    • 7、所有节点设置 sysctl 参数,安装 ntpdate 并同步时间
    • 8、安装 wget git curl zsh...(pass)
    • 9、清除原有的 yum 仓库,下载新的仓库文件
    • 10、安装,配置 Docker 、添加 Kubernetes 仓库(pass)
    • 11、输入想要安装的 k8s 版本
    • 12、安装三件套kubelet、kubeadm、kubectl(pass)
    • 13、node节点:克隆镜像仓库
    • 14、加载 Docker 镜像
    • 15、master 节点 kubeadm 初始化好了以后保存 kubeadm join 命令为环境变量、创建 .kube 目录并复制 admin.conf 文件以及设置 KUBECONFIG 环境变量、kubectl 设置命令补全
    • 16、克隆镜像仓库,部署网络插件
    • 17、master 节点配置免密登录
    • 18、通过 SSH 登录 node 节点执行 join 操作
    • 19、每十秒检查集群状态,都为 Ready 即可退出脚本
    • 20、小坑:node节点是需要 admin.conf 文件并且设置 export KUBECONFIG=/etc/kubernetes/admin.conf 环境变量才可以使用kubectl命令操作集群的

一、环境准备

1、硬件准备(虚拟主机)

角色主机名ip地址
masterk8s-master192.168.112.10
nodek8s-node1192.168.112.20
nodek8s-node2192.168.112.30

2、操作系统版本

CentOS Linux release 7.9.2009 (Core)

兼容版本包含7.7~7.9

3、硬件配置

每个虚拟主机都需要至少分配2核CPU、3GB以上内存(2C3G)、硬盘20G(VMware Workstation)

4、网络

  • 需要可以访问外网(ping -c 2 www.baidu.com 测试连通性)
  • 集群中所有节点之间网络互通(可以提前设置,脚本里也有相关逻辑)

二、注意点

1、主机命名格式

hostnamectl set-hostname <node-name>

需要与脚本中预设的集群列表一一对应,ip地址建议使用静态ip(nmtui设置)

# 定义主机名与 IP 地址的映射关系
declare -A hosts=(
    ["k8s-master"]="192.168.112.10"
    ["k8s-node1"]="192.168.112.20"
    ["k8s-node2"]="192.168.112.30"
)

2、网络插件 flannel 镜像拉取

主机需要有公钥私钥并添加公钥到 Gitee 的安装设置中的SSH公钥

2.1、主机生成公私钥

ssh-keygen

一路回车即可在 ~/.ssh/ 目录下发现 id_ras(私钥)以及id_rsa.pub(公钥)

image-20240921234533461

2.2、为啥有 Github 还用 Gitee

  • 一方面考虑到 Github 的网络连接不太稳定可能导致克隆仓库失败(git clone git@something.git)

  • 另一方面就是 Github 对仓库限制单个文件大小为 50MB(除非使用 Git LFS 管理文件),因为有一个镜像文件的大小超过了 50MB

  • 但其实两者都可以使用(测试过了)

# Github 仓库地址
git clone git@github.com:misakivv/flannel-needs.git

# Gitee 仓库地址
git clone git@gitee.com:kurosaki01/flannel-needs.git

对应脚本修改

替换为你喜欢使用的

# 克隆 Gitee 仓库
    echo "克隆 Gitee 仓库..."
    git clone git@gitee.com:kurosaki01/flannel-needs.git

# 检查克隆仓库是否成功
if [ $? -ne 0 ]; then
    echo "克隆仓库失败,可能的原因包括:"
    echo "1. 目标主机没有公钥。"
    echo "2. 公钥没有正确设置到 Gitee 上。"
    echo "3. 克隆仓库时发生网络错误。"
    echo "请检查 SSH 配置和网络连接。"

2.3、将主机公钥添加到 Gitee

2.3.1、复制主机上的公钥
cat ~/.ssh/id_rsa.pub
2.3.2、登录码云
https://gitee.com/
2.3.3、设置 --> 安全设置 --> SSH公钥

image-20240921235701220

image-20240921235907042

2.3.4、添加公钥

标题无所谓

公钥粘贴刚才在主机上复制的内容

每次添加公钥都需要输入账号密码(与 Github 流程一致)

每个节点都需要添加哦,不然部署网络插件时报(ImagePullBackOff)

image-20240922000112559

2.4、将主机公钥添加到 Github

2.4.1、点击头像 --> settings
https://github.com/dashboard

image-20240922000653088

2.4.2、左侧列表中找到 SSH and GPG keys 点击 New SSH key

添加过程与 Gitee 一致,这里不再演示

image-20240922001025463

image-20240922000838773

3、阿里云的镜像加速地址

3.1、镜像加速器地址

这里请在脚本中替换为自己的

https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors

image-20240922001317387

3.2、对应脚本的修改位置

# 配置 Docker
echo "配置 Docker..."
cat > /etc/docker/daemon.json <<EOF
{
  "exec-opts": ["native.cgroupdriver=systemd"],
  "registry-mirrors": [
    "https://jzjzrggd.mirror.aliyuncs.com",
    "https://dockerproxy.com",
    "https://docker.chenby.cn",
    "https://dockerpull.com",
    "https://dockerhub.jobcher.com",
    "https://docker.mirrors.ustc.edu.cn",
    "https://hub.uuuabc.top",
    "https://mirror.baidubce.com",
    "https://mirror.css.tencentyun.com",
    "https://docker.m.daocloud.io",
    "https://docker.nju.edu.cn",
    "https://hub-mirror.c.163.com",
    "https://dockerhub.azk8s.cn",
    "https://registry.cn-hangzhou.aliyuncs.com"
  ]
}
EOF
systemctl daemon-reload && systemctl restart docker.service
echo "Docker 配置完成。"

4、运行脚本时需要加入集群的主机都在线

因为脚本有两处均需要集群主机在线(开启状态)

4.1、通过 SSH 配置免密登录

# 循环遍历所有节点并复制公钥,排除 master 节点
for node in "${!hosts[@]}"; do
    if [[ ! $node == *"master"* ]]; then
        ip="${hosts[$node]}"
        echo "复制公钥到 $node ($ip)"
        ssh-copy-id -i ~/.ssh/id_rsa.pub root@$ip
    else
        echo "跳过 master 节点 $node"
    fi
done

echo "所有非 master 节点的公钥复制完成。"

4.2、在 master 节点上执行登录各节点执行加入集群命令

# 从 hosts 映射中获取所有 worker 节点
for node in "${!hosts[@]}"; do
    if [[ ! $node == *"-master"* ]]; then
        # 在 worker 节点上直接执行 join 命令
        echo "在节点 $node 上执行 join 命令..."
        ssh root@${hosts[$node]} "$JOIN_COMMAND"
    fi
done

5、输入正确的目标主机名

主要是这块懒得加逻辑判断了

别三台主机运行脚本还能整出排列组合来:)

这里只要输入的主机名在预设的集群列表中脚本就继续运行了,想要优化的可以自行添加逻辑

# 循环提示用户输入主机名,直到输入正确的主机名
while true; do
    read -p "请输入目标主机名 (例如: k8s-master/ks8-node1): " hostname

# 检查输入的主机名是否存在于映射关系中
    if [[ -n "${hosts[$hostname]}" ]]; then
        break
    else
        echo "错误:未知的主机名 '$hostname'。请重新输入。"
    fi
done

6、脚本适用性

  • 因为选的 docker 作为容器运行时,使用限定了 k8s 集群版本必须 < 1.24.x

  • 想要集群版本大于等于 1.24.x 的自己用换成 containerd吧

# 获取用户输入的 Kubernetes 版本
while true; do
    read -p "请输入 Kubernetes 版本号(如 1.23.16,建议不超过 1.24.x): " K8S_VERSION

    # 检查版本号是否符合要求
    if [[ $K8S_VERSION =~ ^1\.([0-9]{1,2})\..* ]] && ((BASH_REMATCH[1] < 24)); then
        break
    else
        echo "错误:版本号不符合要求。建议使用 1.23.x 或之前的版本。请重新输入。"
    fi
done

三、脚本

csnd 直接复制的话后面会跟一些无关紧要的文字,记得删除哦

vim k8s-install.sh
#!/bin/bash

# 定义停止并禁用 firewalld 的函数
stop_and_disable_firewalld() {
    local max_attempts=$1
    local attempt=0

    while [ $attempt -lt $max_attempts ]; do
        systemctl stop firewalld
        systemctl disable firewalld
        if systemctl is-active --quiet firewalld; then
            echo "Attempt $((attempt+1)): firewalld is still active, attempting to stop and disable again."
            attempt=$((attempt+1))
        else
            echo "firewalld has been successfully disabled and stopped."
            return 0
        fi
    done

    echo "firewalld could not be stopped and disabled after $max_attempts attempts."
    echo "This could be due to:"
    echo "1. A service or process is preventing firewalld from being stopped."
    echo "2. There might be a configuration issue with the firewalld service."
    echo "3. There could be a problem with the system's systemd manager."
    return 1
}

# 主逻辑
check_firewalld_status() {
    if systemctl is-active --quiet firewalld; then
        echo "firewalld is currently active, proceeding to stop and disable."
        if ! stop_and_disable_firewalld 3; then
            echo "Failed to stop and disable firewalld."
        fi
    elif systemctl is-enabled --quiet firewalld; then
        echo "firewalld is not active but is enabled, proceeding to disable."
        systemctl disable firewalld
        echo "firewalld has been successfully disabled."
    else
        echo "firewalld is not active and not enabled, no action needed."
    fi
}

# 执行主逻辑
check_firewalld_status

# 定义一个函数来检查 SELinux 状态
check_selinux_status() {
    if getenforce | grep -q "Disabled"; then
        echo "SELinux is already disabled."
        return 0
    else
        echo "SELinux is currently enforcing."
        return 1
    fi
}

# 定义一个函数来更改 SELinux 配置
disable_selinux() {
    # 更改配置文件中的 SELinux 状态
    if sed -i 's/^SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config; then
        echo "SELinux configuration updated in /etc/selinux/config."
    else
        echo "Failed to update SELinux configuration in /etc/selinux/config."
        return 1
    fi

    # 应用更改
    if setenforce 0; then
        echo "SELinux has been temporarily disabled."
    else
        echo "Failed to disable SELinux temporarily."
        return 1
    fi

    return 0
}

# 主逻辑
if check_selinux_status; then
    echo "No action required."
else
    if disable_selinux; then
        echo "SELinux has been disabled."
    else
        echo "Failed to disable SELinux."
    fi
fi

# 临时关闭 swap
echo "临时关闭 swap..."
swapoff -a

# 永久关闭 swap (注释掉 /etc/fstab 中的 swap 行)
echo "永久关闭 swap..."
sed -ri 's/.*swap.*/#&/' /etc/fstab

# 验证 swap 是否已经被注释掉
echo "验证 swap 是否已经被注释掉..."
cat /etc/fstab | grep swap

# 定义主机名与 IP 地址的映射关系
declare -A hosts=(
    ["k8s-master"]="192.168.112.10"
    ["k8s-node1"]="192.168.112.20"
    ["k8s-node2"]="192.168.112.30"
)

# 循环提示用户输入主机名,直到输入正确的主机名
while true; do
    read -p "请输入目标主机名 (例如: k8s-master/ks8-node1): " hostname

# 检查输入的主机名是否存在于映射关系中
    if [[ -n "${hosts[$hostname]}" ]]; then
        break
    else
        echo "错误:未知的主机名 '$hostname'。请重新输入。"
    fi
done

# 遍历所有主机名与 IP 地址映射关系,并追加到 /etc/hosts 文件中
for node in "${!hosts[@]}"; do
    ip_address=${hosts[$node]}
    host_line="${ip_address} ${node}"

# 检查该行是否已经存在于 /etc/hosts 文件中
    if ! grep -q "$host_line" /etc/hosts; then
# 如果不存在,则追加到 /etc/hosts 文件中
        echo "$host_line" >> /etc/hosts
        echo "已将 '$node' 添加到 /etc/hosts 文件中。"
    fi
done

# 验证用户输入的主机名与对应的 IP 地址是否存在于本地的 /etc/hosts 文件中
ip_address=${hosts[$hostname]}
host_line="${ip_address} ${hostname}"

if grep -q "$host_line" /etc/hosts; then
    echo "主机名 '$hostname' 与对应的 IP 地址 '$ip_address' 已经存在于本地的 /etc/hosts 文件中。"
else
    echo "主机名 '$hostname' 与对应的 IP 地址 '$ip_address' 未能在本地的 /etc/hosts 文件中找到,请检查。"
fi

# 设置 sysctl 参数
echo "设置 sysctl 参数..."
cat > /etc/sysctl.d/k8s.conf << EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sysctl --system
echo "sysctl 参数设置完成。"

# 安装 ntpdate 并同步时间
echo "安装 ntpdate 并同步时间..."
yum install -y ntpdate
ntpdate time.windows.com
echo "时间同步完成。"

# 安装 wget
echo "安装 wget git curl zsh..."
yum install -y wget.x86_64 git curl zsh
echo "wget 安装完成。"

# 清除原有的 yum 仓库
echo "清除原有的 yum 仓库..."
rm -rf /etc/yum.repos.d/*
echo "原有仓库清除完成。"

# 下载新的仓库文件
echo "下载新的仓库文件..."
wget -O /etc/yum.repos.d/centos7.repo http://mirrors.aliyun.com/repo/Centos-7.repo
wget -O /etc/yum.repos.d/epel-7.repo http://mirrors.aliyun.com/repo/epel-7.repo
wget -O /etc/yum.repos.d/docker-ce.repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
echo "新的仓库文件下载完成。"

# 安装 Docker
echo "安装 Docker..."
yum install docker-ce -y
systemctl start docker && systemctl enable docker
echo "Docker 安装并启动完成。"

# 配置 Docker
echo "配置 Docker..."
cat > /etc/docker/daemon.json <<EOF
{
  "exec-opts": ["native.cgroupdriver=systemd"],
  "registry-mirrors": [
    "https://jzjzrggd.mirror.aliyuncs.com",
    "https://dockerproxy.com",
    "https://docker.chenby.cn",
    "https://dockerpull.com",
    "https://dockerhub.jobcher.com",
    "https://docker.mirrors.ustc.edu.cn",
    "https://hub.uuuabc.top",
    "https://mirror.baidubce.com",
    "https://mirror.css.tencentyun.com",
    "https://docker.m.daocloud.io",
    "https://docker.nju.edu.cn",
    "https://hub-mirror.c.163.com",
    "https://dockerhub.azk8s.cn",
    "https://registry.cn-hangzhou.aliyuncs.com"
  ]
}
EOF
systemctl daemon-reload && systemctl restart docker.service
echo "Docker 配置完成。"

# 添加 Kubernetes 仓库
echo "添加 Kubernetes 仓库..."
cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
echo "Kubernetes 仓库添加完成。"

# 获取用户输入的 Kubernetes 版本
while true; do
    read -p "请输入 Kubernetes 版本号(如 1.23.16,建议不超过 1.24.x): " K8S_VERSION

    # 检查版本号是否符合要求
    if [[ $K8S_VERSION =~ ^1\.([0-9]{1,2})\..* ]] && ((BASH_REMATCH[1] < 24)); then
        break
    else
        echo "错误:版本号不符合要求。建议使用 1.23.x 或之前的版本。请重新输入。"
    fi
done

# 安装指定版本的 Kubernetes 组件
echo "安装指定版本的 Kubernetes 组件..."
yum install kubelet-$K8S_VERSION kubeadm-$K8S_VERSION kubectl-$K8S_VERSION -y

# 启动并启用 kubelet 服务
echo "启动并启用 kubelet 服务..."
systemctl enable kubelet  && systemctl start kubelet

# 检查 kubelet 是否成功启动
if systemctl is-active --quiet kubelet; then
    echo "Kubernetes 组件安装并启动完成。"
else
    echo "错误:kubelet 服务未能成功启动。请检查安装过程是否有误。"
fi

# 判断是否为 master 节点
if [[ $hostname == *"-master"* ]]; then
    echo "检测到当前节点为主节点 '$hostname',执行 kubeadm 初始化..."

# 动态填充 kubeadm init 命令中的参数
    kubeadm init \
        --apiserver-advertise-address=$ip_address \
        --image-repository registry.aliyuncs.com/google_containers \
        --kubernetes-version v$K8S_VERSION \
        --control-plane-endpoint $hostname \
        --service-cidr=172.16.0.0/16 \
        --pod-network-cidr=10.244.0.0/16

# 输出 kubeadm join 命令并保存到变量中
    JOIN_COMMAND=$(kubeadm token create --print-join-command)
# 输出提示信息
    echo "kubeadm 初始化完成,请记录以下 join 命令:"
    echo "$JOIN_COMMAND"
	
# 创建 .kube 目录并复制 admin.conf 文件
    mkdir -p $HOME/.kube
    sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
    sudo chown $(id -u):$(id -g) $HOME/.kube/config

# 设置 KUBECONFIG 环境变量
    export KUBECONFIG=/etc/kubernetes/admin.conf

# 输出提示信息
    echo "为了开始使用您的集群,请执行以下命令:"
    echo "source <(kubectl completion bash)"
	
# 克隆 Gitee 仓库
    echo "克隆 Gitee 仓库..."
    git clone git@gitee.com:kurosaki01/flannel-needs.git
	
# 检查克隆仓库是否成功
if [ $? -ne 0 ]; then
    echo "克隆仓库失败,可能的原因包括:"
    echo "1. 目标主机没有公钥。"
    echo "2. 公钥没有正确设置到 Gitee 上。"
    echo "3. 克隆仓库时发生网络错误。"
    echo "请检查 SSH 配置和网络连接。"
else
    # 进入克隆的仓库目录
    echo "进入 flannel-needs 目录..."
    cd flannel-needs || {
        echo "进入 flannel-needs 目录失败,可能的原因包括:"
        echo "1. 克隆仓库未成功创建目录。"
        echo "2. 当前目录不存在 flannel-needs 子目录。"
        echo "请检查克隆仓库是否成功。"
    }
fi

# 加载 Docker 镜像
    echo "加载 Docker 镜像..."
    docker load -i lizhenliang-flannel-v0.11.0-amd64.tar
    docker load -i ranche-mirrored-flannelcni-flannel-cni-plugin.tar

# 应用 Flannel 配置
    echo "应用 Flannel 配置..."
    kubectl apply -f flannel.yaml

# 输出提示信息
    echo "Flannel 配置已应用,网络插件已准备好。"
    
# 循环遍历所有节点并复制公钥,排除 master 节点
for node in "${!hosts[@]}"; do
    if [[ ! $node == *"master"* ]]; then
        ip="${hosts[$node]}"
        echo "复制公钥到 $node ($ip)"
        ssh-copy-id -i ~/.ssh/id_rsa.pub root@$ip
    else
        echo "跳过 master 节点 $node"
    fi
done

echo "所有非 master 节点的公钥复制完成。"

# 从 hosts 映射中获取所有 worker 节点
for node in "${!hosts[@]}"; do
    if [[ ! $node == *"-master"* ]]; then
        # 在 worker 节点上直接执行 join 命令
        echo "在节点 $node 上执行 join 命令..."
        ssh root@${hosts[$node]} "$JOIN_COMMAND"
    fi
done

# 从预设的集群列表中获取预期的节点数量
EXPECTED_COUNT=${#hosts[@]}

# 获取当前已加入集群的节点数量
CURRENT_COUNT=$(kubectl get nodes | grep -v NAME | wc -l)

# 获取当前已加入集群的节点名称
CURRENT_NODES=$(kubectl get nodes | awk 'NR>1{print $1}')

# 循环检查直到所有预期的节点都已加入集群并且状态为 Ready
while [ $CURRENT_COUNT -ne $EXPECTED_COUNT ]; do
    echo "当前已加入集群的节点数量 ($CURRENT_COUNT) 与预期数量 ($EXPECTED_COUNT) 不匹配,请等待..."
    sleep 10  # 等待10秒后再次检查
    CURRENT_COUNT=$(kubectl get nodes | grep -v NAME | wc -l)
    CURRENT_NODES=$(kubectl get nodes | awk 'NR>1{print $1}')
done

# 检查所有节点的状态是否为 Ready=True
while true; do
    NODES_STATUS=$(kubectl get nodes -o jsonpath='{range .items[*]}{.status.conditions[-1:].type}{"="}{.status.conditions[-1:].status}{"\n"}{end}')
    
    # 使用数组存储每个节点的状态
    IFS=$'\n' read -d '' -r -a nodeStatusArray <<< "$NODES_STATUS"
    
    # 标记所有节点是否都 Ready
    allReady=true
    
    for status in "${nodeStatusArray[@]}"; do
        if [[ $status != "Ready=True" ]]; then
            allReady=false
            break
        fi
    done
    
    if $allReady; then
        echo "所有节点的状态均为 Ready,集群安装成功。"
        break
    else
        echo "集群中有节点状态不是 Ready,请等待..."
        sleep 10  # 等待10秒后再次检查
    fi
done

# 输出当前集群节点状态
echo "检查集群节点状态..."
kubectl get nodes

else
    echo "检测到当前节点为 worker 节点 '$hostname',执行命令..."

# "检测到当前节点为 worker 节点 '$hostname',执行命令..."

# 克隆 Gitee 仓库
    echo "克隆 Gitee 仓库..."
    git clone git@gitee.com:kurosaki01/flannel-needs.git

# 检查克隆仓库是否成功
if [ $? -ne 0 ]; then
    echo "克隆仓库失败,可能的原因包括:"
    echo "1. 目标主机没有公钥。"
    echo "2. 公钥没有正确设置到 Gitee 上。"
    echo "3. 克隆仓库时发生网络错误。"
    echo "请检查 SSH 配置和网络连接。"
    
else
    # 进入克隆的仓库目录
    echo "进入 flannel-needs 目录..."
    cd flannel-needs || {
        echo "进入 flannel-needs 目录失败,可能的原因包括:"
        echo "1. 克隆仓库未成功创建目录。"
        echo "2. 当前目录不存在 flannel-needs 子目录。"
        echo "请检查克隆仓库是否成功。"
    }
fi

# 加载 Docker 镜像
    echo "加载 Docker 镜像..."
    docker load -i lizhenliang-flannel-v0.11.0-amd64.tar
    docker load -i ranche-mirrored-flannelcni-flannel-cni-plugin.tar

# 输出提示信息
    echo "Docker 镜像已加载,worker 节点准备完毕。"
	
# 提示用户在 master 节点上检查集群状态
    echo "请在 master 节点上执行 'kubectl get nodes' 来检查集群状态。"
fi

四、实例演示

1、硬件准备

image-20240922004359969image-20240922004425278image-20240922004452023

2、**,启动!

hostnamectl set-hostname <hostname>

bash

hostname
image-20240922004845284image-20240922004820629image-20240922004757656

3、创建脚本文件(CV大法)

vim k8s-install.sh

4、运行脚本

bash k8s-install.sh

5、判断并关闭完firewalld、selinux、swap 后输入目标主机名

输入 k8s-master
image-20240922005551225
输入 k8s-node1
image-20240922005608245
输入 k8s-node2
image-20240922005642113

6、master节点将预设的集群列表一个个追加到/etc/hosts文件中,所有节点执行判断逻辑

image-20240922010253406
image-20240922010401758
image-20240922010422813

7、所有节点设置 sysctl 参数,安装 ntpdate 并同步时间

image-20240922010546964
image-20240922010623422
image-20240922010654943

8、安装 wget git curl zsh…(pass)

不截图,太长了

9、清除原有的 yum 仓库,下载新的仓库文件

当然了,涉及到 rm 删除操作可以添加备份的逻辑

我就懒得搞(快照)

image-20240922011245695
image-20240922011327439
image-20240922011357208

10、安装,配置 Docker 、添加 Kubernetes 仓库(pass)

硬编码一般没什么问题

11、输入想要安装的 k8s 版本

此脚本只适用 k8s < 1.24.0 版本的

想要高版本自行修改脚本

image-20240922012214265
image-20240922012335232
image-20240922012304908

12、安装三件套kubelet、kubeadm、kubectl(pass)

13、node节点:克隆镜像仓库

输入 yes
image-20240922013615991
输入 yes
image-20240922013637960

14、加载 Docker 镜像

k8s-node1: 我滴使命完成啦
image-20240922015311806
k8s-node2: 我滴使命也完成啦
image-20240922015423351

15、master 节点 kubeadm 初始化好了以后保存 kubeadm join 命令为环境变量、创建 .kube 目录并复制 admin.conf 文件以及设置 KUBECONFIG 环境变量、kubectl 设置命令补全

image-20240922020036634

16、克隆镜像仓库,部署网络插件

image-20240922020133551

17、master 节点配置免密登录

需要输入 k8s-node1、k8s-node2 的登录密码

image-20240922020511525

18、通过 SSH 登录 node 节点执行 join 操作

k8s-master:done

image-20240922020315496

19、每十秒检查集群状态,都为 Ready 即可退出脚本

image-20240922020813978

20、小坑:node节点是需要 admin.conf 文件并且设置 export KUBECONFIG=/etc/kubernetes/admin.conf 环境变量才可以使用kubectl命令操作集群的

解决办法详见这篇:centos7.9部署k8s的几种方式

image-20240922021302739

想优化脚本的自己优化吧,我后续会把坑补上并且加上花里胡哨的 oh-my-zsh + p10k

毕竟这脚本写的还是比较拉的

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2157794.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【C++篇】走进C++标准模板库:STL的奥秘与编程效率提升之道

文章目录 C STL 初探&#xff1a;打开标准模板库的大门前言第一章: 什么是STL&#xff1f;1.1 标准模板库简介1.2 STL的历史背景1.3 STL的组成 第二章: STL的版本与演进2.1 不同的STL版本2.2 STL的影响与重要性 第三章: 为什么学习 STL&#xff1f;3.1 从手动编写到标准化解决方…

FortiGate 防火墙 DNS 地址转换(DNS Translation)

简介 本例介绍 FortiGate 防火墙 DNS 地址转换&#xff08;DNS Translation&#xff09;配置方法。 一、 网络结构 网络结构如下图&#xff0c;PC1 连接在 FG60B 的 Internal 接口&#xff0c;FG60B 的 Wan1 接口连接 FG80CM 的 DMZ 接口&#xff0c;Wan1 接口开启 DNS 服务…

无人机之工作温度篇

无人机的工作温度是一个相对复杂的问题&#xff0c;因为它受到多种因素的影响&#xff0c;包括无人机的类型&#xff08;如民用、军用&#xff09;、设计规格、应用场景以及环境条件等。以下是对无人机工作温度范围的详细解析&#xff1a; 一、正常工作温度范围 一般来说&…

LeetcodeTop100 刷题总结(二)

LeetCode 热题 100&#xff1a;https://leetcode.cn/studyplan/top-100-liked/ 文章目录 八、二叉树94. 二叉树的中序遍历&#xff08;递归与非递归&#xff09;补充&#xff1a;144. 二叉树的前序遍历&#xff08;递归与非递归&#xff09;补充&#xff1a;145. 二叉树的后序遍…

RK3568驱动指南|第十六篇 SPI-第190章 配置模式下寄存器的配置

瑞芯微RK3568芯片是一款定位中高端的通用型SOC&#xff0c;采用22nm制程工艺&#xff0c;搭载一颗四核Cortex-A55处理器和Mali G52 2EE 图形处理器。RK3568 支持4K 解码和 1080P 编码&#xff0c;支持SATA/PCIE/USB3.0 外围接口。RK3568内置独立NPU&#xff0c;可用于轻量级人工…

JavaEE---Spring之小练习

实现一个验证码项目 后端代码 后端代码测试 整体代码测试 输入正确的验证码 输入错误的验证码

【C++掌中宝】缺省参数的全面解析

文章目录 前言1. 什么是缺省参数&#xff1f;2. 缺省参数的分类2.1 全缺省【备胎是如何使用的&#x1f605;】2.1.1 疑难细究 2.2 半缺省2.2.1 错误用法示范2.2.2 正确用法示范2.2.3&#x1f525;实参缺省与形参缺省的混合辨析&#x1f525; 3. 缺省参数的规则和限制4. 规定必须…

Gartner发布2024年中国基础设施战略技术成熟度曲线

Gartner于近日首次发布2024年中国基础设施战略技术成熟度曲线&#xff0c;该曲线收录的21项技术主要覆盖四大领域&#xff0c;分别是&#xff1a;自主可控计划、AI 影响、运营效率以及基础设施现代化。 Gartner研究总监张吟铃表示&#xff1a;“中国市场与全球市场虽然使用的技…

[Redis][预备知识]详细讲解

目录 1.命令1.最核心的两个命令1.SET2.GET3.说明 2.基本全局命令0.前言1.KEYS2.EXISTS3.DEL4.EXPIRE5.TTL6.TYPE 2.数据结构和内部编码3.单线程架构1.单线程模型2.单线程还效率高&#xff1f;(重点)3.注意 1.命令 1.最核心的两个命令 1.SET 语法&#xff1a;SET key value功…

jmeter发送邮件:详细步骤与功能配置指南?

jmeter发送邮件如何设置&#xff1f;怎么配置JMeter以发送邮件&#xff1f; Apache JMeter作为一款强大的性能测试工具&#xff0c;不仅可以用于测试Web应用的性能&#xff0c;还可以通过插件扩展其功能&#xff0c;实现诸如发送邮件等操作。AokSend将详细介绍如何使用JMeter发…

核心复现—计及需求响应的区域综合能源系统双层优化调度策略

目录 一、主要内容&#xff1a; 二、摘要介绍&#xff1a; 三、综合能源系统结构&#xff1a; 四、实际仿真运行结果&#xff1a; 五、代码数据下载&#xff1a; 一、主要内容&#xff1a; 在模型构建部分&#xff1a;建立了一个综合能源系统双层优化调度模型&#xff0c;…

openeuler22.03 LTS 源码编译安装fastdfs-6.06

openeuler22.03 LTS 源码编译安装fastdfs-6.06 1、环境 名称版本备注openeuler22.03 LTSfastdfs6.06libfastcommon1.0.43libfastcommon是一个开源的C语言库&#xff0c;用于实现高性能的分布式文件系统和分布式存储系统 2、准备安装包 fastdfs 官网&#xff1a; https://git…

《概率论与数理统计》学渣笔记

文章目录 1 随机事件和概率1.1 古典概型求概率随机分配问题简单随机抽样问题 1.2 几何概型求概率1.3 重要公式求概率 2 一维随机变量及其分布2.1 随机变量及其分布函数的定义离散型随机变量及其概率分布&#xff08;概率分布&#xff09;连续型随机变量及其概率分布&#xff08…

【machine learning-12-多元线性回归】

线性回归-多特征 多特征线性回归多特征表示更简单的多元线性回归表示方法 之前节的线性回归为简化都是用的单特征&#xff0c;但现实中我们的预测因素很复杂不可能只有一个特征&#xff0c;下面总结多特征线性回归 多特征 之前总是用房价举例&#xff0c;预测房价和房屋面积的…

个人量化成功之路-----从 Yahoo! Finance 下载交易策略数据

雅虎财经 是投资者最受欢迎的网站之一。它提供有关股票、债券、货币和加密货币的各种市场数据。它还提供市场新闻、报告和分析、期权和基本数据 官方的雅虎财经 API 于 2017 年被下架 Yfinance 是由 Ran Aroussi 开发的开源 Python 库&#xff0c;用于访问雅虎财经上可用的财…

基于微信小程序的宠物寄养平台的设计与实现+ssm(lw+演示+源码+运行)

摘 要 随着科技和网络的进步&#xff0c;微信小程序技术与网络、生活贴和的更加紧密。需要依靠客户端的单机系统逐渐被淘汰&#xff0c;利用互联网可以处理大量数据的新型系统如雨后春笋般迅速发展起来。这类系统和信息化时代的同步发展对传统的办公管理方式造成了很大的压力。…

C++进阶学习——模版进阶

1. 非类型模板参数 模板参数分类类型形参与非类型形参。 类型形参即&#xff1a;出现在模板参数列表中&#xff0c;跟在class或者typename之类的参数类型名称。 非类型形参&#xff0c;就是用一个常量作为类(函数)模板的一个参数&#xff0c;在类(函数)模板中可将该参数当成…

如何基于scrcpy改造实现大厂一键连招/触摸宏功能(带java源码)-千里马安卓framework实战

背景&#xff1a; 前面公众号文章已经分享过如何实现这种大厂里面一键连招&#xff0c;触摸宏的功能&#xff0c;原理本身是对dev/input下面的节点进行读取保存文件&#xff0c;然后在读取文件进行写入dev/input下面的节点&#xff0c;从而实现了触摸事件的读取和写入&#xf…

OpenMVG试用

1 OpenMVG 简介 全称 Open Multiple View Geometry&#xff0c;是法国人 Pierre Moulon 读博期间开源的一个 C 库 最早版本 OpenMVG 0.1 是 2013年 2月 发布的&#xff0c;目前最新版本是 2021年 10月 发布的 OpenMVG 2.0 LinkedIn 显示&#xff0c;此前一直在…

docker存储

docker分层结构 如图所示&#xff0c;容器是由最上面可读可写的容器层&#xff0c;以及若干个只读镜像层组成&#xff0c;创建容器时&#xff0c;容器中的 数据都来自镜像层。这样的分层机构最大的特点是写时复制&#xff1a; 1、容器中新生成的数据会直接存放在容器层&#xf…