k8s的学习一部分重点概述
- 理解练习脚本安装的内容
- 理解最后的几个问题
基于containerd脚本安装k8s
脚本内容
[root@master1 ~]#cat install_kubernetes_containerd_single_master.sh
#!/bin/bash
#
#********************************************************************
#Author: bai
#QQ: 2236492142
#Date: 2025
#FileName: install_kubernetes_containerd.sh
#Description: The test script
#********************************************************************
#执行前准备:
#必须确保安装Kubernetes的主机内存至少2G
#必须指定KUBE_VERSION变量版本
#必须在变量中指定集群中各节点的IP信息
#必须在HOSTS变量中指定集群各节点的主机名称和IP的对应关系
#其它配置可选
. /etc/os-release
KUBE_VERSION="1.30.0"
KUBE_RELEASE=${KUBE_VERSION}-1.1
#v1.28以后需要此变量
KUBE_MAJOR_VERSION=`echo ${KUBE_VERSION}| cut -d . -f 1,2`
#KUBE_VERSION="1.29.3"
#KUBE_VERSION="1.25.0"
#KUBE_VERSION="1.24.4"
#KUBE_VERSION="1.24.3"
#KUBE_VERSION="1.24.0"
KUBE_VERSION2=$(echo $KUBE_VERSION |awk -F. '{print $2}')
#####################指定修改集群各节点的地址,必须按环境修改###################
KUBEAPI_IP=10.0.0.100
MASTER1_IP=10.0.0.100
#MASTER2_IP=10.0.0.102
#MASTER3_IP=10.0.0.103
NODE1_IP=10.0.0.101
NODE2_IP=10.0.0.102
NODE3_IP=10.0.0.103
#HARBOR_IP=10.0.0.200
DOMAIN=wang.org
##########参考上面变量,修改HOST变量指定hosts文件中主机名和IP对应关系###########
HOSTS="
$KUBEAPI_IP kubeapi.$DOMAIN kubeapi
$MASTER1_IP master1.$DOMAIN master1
#$MASTER2_IP master2.$DOMAIN master2
#$MASTER3_IP master3.$DOMAIN master3
$NODE1_IP node1.$DOMAIN node1
$NODE2_IP node2.$DOMAIN node2
$NODE3_IP node3.$DOMAIN node3
"
POD_NETWORK="10.244.0.0/16"
SERVICE_NETWORK="10.96.0.0/12"
IMAGES_URL="registry.aliyuncs.com/google_containers"
LOCAL_IP=`hostname -I|awk '{print $1}'`
COLOR_SUCCESS="echo -e \\033[1;32m"
COLOR_FAILURE="echo -e \\033[1;31m"
END="\033[m"
color () {
RES_COL=60
MOVE_TO_COL="echo -en \\033[${RES_COL}G"
SETCOLOR_SUCCESS="echo -en \\033[1;32m"
SETCOLOR_FAILURE="echo -en \\033[1;31m"
SETCOLOR_WARNING="echo -en \\033[1;33m"
SETCOLOR_NORMAL="echo -en \E[0m"
echo -n "$1" && $MOVE_TO_COL
echo -n "["
if [ $2 = "success" -o $2 = "0" ] ;then
${SETCOLOR_SUCCESS}
echo -n $" OK "
elif [ $2 = "failure" -o $2 = "1" ] ;then
${SETCOLOR_FAILURE}
echo -n $"FAILED"
else
${SETCOLOR_WARNING}
echo -n $"WARNING"
fi
${SETCOLOR_NORMAL}
echo -n "]"
echo
}
check () {
if [ $ID = 'ubuntu' ] && [[ ${VERSION_ID} =~ 2[02].04 ]];then
true
else
color "不支持此操作系统,退出!" 1
exit
fi
if [ $KUBE_VERSION2 -lt 24 ] ;then
color "当前kubernetes版本过低,Containerd要求不能低于v1.24.0版,退出!" 1
exit
fi
}
install_prepare () {
echo "$HOSTS" >> /etc/hosts
hostnamectl set-hostname $(awk -v ip=$LOCAL_IP '{if($1==ip && $2 !~ "kubeapi")print $2}' /etc/hosts)
swapoff -a
sed -i '/swap/s/^/#/' /etc/fstab
color "安装前准备完成!" 0
sleep 1
}
config_kernel () {
cat <<EOF | tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
modprobe overlay
modprobe br_netfilter
cat <<EOF | tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF
sysctl --system
}
install_containerd () {
apt update
apt -y install containerd || { color "安装Containerd失败!" 1; exit 1; }
mkdir /etc/containerd/
containerd config default > /etc/containerd/config.toml
sed -i "s#registry.k8s.io#${IMAGES_URL}#g" /etc/containerd/config.toml
#sed -i "s#registry.k8s.io/pause:3.8#${IMAGES_URL}/pause:3.9#g" /etc/containerd/config.toml
#sed -i "s#k8s.gcr.io#${IMAGES_URL}#g" /etc/containerd/config.toml
sed -i 's#SystemdCgroup = false#SystemdCgroup = true#g' /etc/containerd/config.toml
systemctl restart containerd.service
[ $? -eq 0 ] && { color "安装Containerd成功!" 0; sleep 1; } || { color "安装Containerd失败!" 1 ; exit 2; }
}
install_kubeadm () {
apt-get update && apt-get install -y apt-transport-https
curl -fsSL https://mirrors.aliyun.com/kubernetes-new/core/stable/v${KUBE_MAJOR_VERSION}/deb/Release.key | gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://mirrors.aliyun.com/kubernetes-new/core/stable/v${KUBE_MAJOR_VERSION}/deb/ /" > /etc/apt/sources.list.d/kubernetes.list
#curl https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | apt-key add -
#cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
#deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main
#EOF
apt-get update
apt-cache madison kubeadm |head
${COLOR_FAILURE}"5秒后即将安装: kubeadm-"${KUBE_VERSION}" 版本....."${END}
${COLOR_FAILURE}"如果想安装其它版本,请按ctrl+c键退出,修改版本再执行"${END}
sleep 6
#安装指定版本
apt install -y kubeadm=${KUBE_RELEASE} kubelet=${KUBE_RELEASE} kubectl=${KUBE_RELEASE}
[ $? -eq 0 ] && { color "安装kubeadm成功!" 0;sleep 1; } || { color "安装kubeadm失败!" 1 ; exit 2; }
#实现kubectl命令自动补全功能
kubectl completion bash > /etc/profile.d/kubectl_completion.sh
}
#只有Kubernetes集群的第一个master节点需要执行下面初始化函数
kubernetes_init () {
kubeadm init --control-plane-endpoint="kubeapi.$DOMAIN" \
--kubernetes-version=v${KUBE_VERSION} \
--pod-network-cidr=${POD_NETWORK} \
--service-cidr=${SERVICE_NETWORK} \
--token-ttl=0 \
--upload-certs \
--image-repository=${IMAGES_URL}
[ $? -eq 0 ] && color "Kubernetes集群初始化成功!" 0 || { color "Kubernetes集群初始化失败!" 1 ; exit 3; }
mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config
}
reset_kubernetes() {
kubeadm reset -f
rm -rf /etc/cni/net.d/ $HOME/.kube/config
}
config_crictl () {
cat > /etc/crictl.yaml <<EOF
runtime-endpoint: unix:///run/containerd/containerd.sock
image-endpoint: unix:///run/containerd/containerd.sock
EOF
}
check
PS3="请选择编号(1-4): "
ACTIONS="
初始化新的Kubernetes集群
加入已有的Kubernetes集群
退出Kubernetes集群
退出本程序
"
select action in $ACTIONS;do
case $REPLY in
1)
install_prepare
config_kernel
install_containerd
install_kubeadm
kubernetes_init
config_crictl
break
;;
2)
install_prepare
config_kernel
install_containerd
install_kubeadm
$COLOR_SUCCESS"加入已有的Kubernetes集群已准备完毕,还需要执行最后一步加入集群的命令 kubeadm join ... "${END}
break
;;
3)
reset_kubernetes
break
;;
4)
exit
;;
esac
done
exec bash
脚本解释
总结:这个脚本实现了 1,系统准备(关闭 swap,配置 hosts)2,内核参数配置 3,Containerd 安装和配置 4 , Kubernetes 组件安装(kubeadm/kubelet/kubectl) 5, kube init集群初始化
使用时注意: 1,要跟据自己的环境 修改你的实际网络配置(也就是几个主节点,几个从节点)
2,在执行脚本时,在我们的主节点上 运行脚本执行 1号选项集群初始化,在其他节点上执行2号选项 加入集群。
3,从节点 的脚本跑完之后 将主节点生成的证书秘钥信息 kubectl join 复制在从节点执行即可 (注意 如果有多个主节点 例如:3主3从架构也要 导入 主节点的证书秘钥信息)
4,都导入完成 在安装(apply)网络插件即可。(注意 ,网络插件 有时候 会拉不下需要 “翻墙“,还有自己做实验的话 不会“翻墙“ 也是无法下载镜像的 ,除非搭建自己的docker hub 或 阿里云仓库。我有适合 自己做实验的随便下载 镜像的方法 主页https://blog.csdn.net/qq_53661153/article/details/148926064?sharetype=blogdetail&sharerId=148926064&sharerefer=PC&sharesource=qq_53661153&spm=1011.2480.3001.8118可以去了解一下)网络插件完成 就完成了。
这个脚本是一个自动化安装 Kubernetes 集群的脚本(使用 Containerd 作为容器运行时)。要创建一个 Kubernetes 集群,你需要按照以下步骤操作:
1. 修改脚本配置(必须)
在运行脚本前,必须修改以下关键配置:
# 集群版本 (当前设置 1.30.0)
KUBE_VERSION="1.30.0"
# 修改为你的实际网络配置
KUBEAPI_IP=10.0.0.100 # Kubernetes API 服务器 IP
MASTER1_IP=10.0.0.100 # 第一个 master 节点 IP
NODE1_IP=10.0.0.101 # worker 节点 1 IP
NODE2_IP=10.0.0.102 # worker 节点 2 IP
NODE3_IP=10.0.0.103 # worker 节点 3 IP
DOMAIN=wang.org # 你的域名
# 网络配置 (保持默认或按需修改)
POD_NETWORK="10.244.0.0/16" # Pod 网络 CIDR
SERVICE_NETWORK="10.96.0.0/12" # Service 网络 CIDR
2. 集群创建步骤
(1) 在 Master 节点上执行
# 1. 上传修改后的脚本到 master1 节点
scp install_kubernetes_containerd_single_master.sh root@master1:
# 2. 登录 master1 节点
ssh root@master1
# 3. 添加执行权限并运行脚本
chmod +x install_kubernetes_containerd_single_master.sh
./install_kubernetes_containerd_single_master.sh
# 4. 选择选项 1: "初始化新的Kubernetes集群"
请选择编号(1-4): 1
脚本会自动完成:
- 系统准备(关闭 swap,配置 hosts)
- 内核参数配置
- Containerd 安装和配置
- Kubernetes 组件安装(kubeadm/kubelet/kubectl)
- 集群初始化
(2) 在 Worker 节点上执行
# 1. 上传相同的脚本到每个 worker 节点
scp install_kubernetes_containerd_single_master.sh root@node1:
# 2. 登录每个 worker 节点
ssh root@node1
# 3. 添加执行权限并运行脚本
chmod +x install_kubernetes_containerd_single_master.sh
./install_kubernetes_containerd_single_master.sh
# 4. 选择选项 2: "加入已有的Kubernetes集群"
请选择编号(1-4): 2
脚本会完成前置准备,但不会自动加入集群,你需要手动执行 kubeadm join
命令(初始化时输出的命令)。
3. 关键操作点
在 Master 节点初始化后:
- 保存输出的
kubeadm join
命令(包含 token 和证书密钥) - 安装网络插件(脚本未包含),例如:
# 安装 Flannel 网络插件
kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml
在 Worker 节点:
- 运行脚本选择 "加入集群"
- 执行 Master 初始化时生成的 join 命令:
kubeadm join kubeapi.wang.org:6443 --token xxx \
--discovery-token-ca-cert-hash sha256:xxx
4. 验证集群
在 Master 节点执行:
kubectl get nodes # 查看所有节点状态
kubectl get pods -A # 查看所有 Pod 状态
5. 重要注意事项
- 环境要求:
-
- 所有节点必须是 Ubuntu 22.04
- 每个节点至少 2GB 内存
- 禁用 swap
- 网络要求:
-
- 所有节点必须能互相通信
- 所有节点必须能解析
kubeapi.your-domain
(通过 /etc/hosts 或 DNS) - 确保 6443(API Server)、10250(Kubelet)等端口开放
- 版本兼容性:
-
- 脚本仅支持 Kubernetes 1.24+(Containerd 要求)
- 当前配置为 1.30.0 版本
- 多 Master 支持:
要创建高可用集群(多 master):
-
- 取消脚本中 MASTER2/MASTER3 的注释
- 在初始化时添加
--control-plane-endpoint
负载均衡地址 - 使用外部 etcd 或 stacked etcd 拓扑
6. 故障排查
如果加入节点失败:
- 检查 token 是否过期(默认24小时)
- 重置节点后重试:
kubeadm reset -f
rm -rf /etc/kubernetes/*
- 检查网络连接和防火墙
这个脚本自动化了大部分安装过程,但你需要:
- 根据实际环境修改 IP/域名配置
- 在 master 初始化后手动安装网络插件
- 在 worker 节点手动执行 join 命令
最后记得保存初始化成功时输出的 join 命令,这是 worker 节点加入集群的关键凭证!
最终结果
节点已经 全部 Ready了
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
总结:kubectl
命令来访问和操作你刚刚初始化完成的 Kubernetes 集群。
🔧 命令作用详解
✅ mkdir -p $HOME/.kube
- 作用:创建一个
.kube
目录,作为当前用户的 Kubernetes 配置文件存储位置。 -p
参数的作用是:如果上级目录不存在也一并创建,并且不会报错。$HOME
是当前用户的家目录(比如/root
或/home/yourname
)。
🔍 举个例子:
mkdir -p /root/.kube # 如果你是root用户
mkdir -p /home/bai/.kube # 如果你是普通用户bai
✅ sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
- 作用:将
kubeadm init
生成的admin.conf
配置文件,复制到你当前用户的.kube/config
路径下。 - 这是 kubeconfig 文件,是
kubectl
命令需要用的配置文件,它告诉kubectl
怎么去连接你的集群、用哪个用户、带什么证书等等。 -i
参数表示如果文件已存在,会提示是否覆盖。
🔍 举个例子:
sudo cp -i /etc/kubernetes/admin.conf /root/.kube/config
✅ sudo chown $(id -u):$(id -g) $HOME/.kube/config
- 作用:修改配置文件的属主为当前用户,确保你当前用户有权限去读取
.kube/config
文件。 $(id -u)
获取当前用户的 UID,$(id -g)
获取 GID。- 通常你用 root 执行
kubeadm init
,这个文件默认就是 root 权限的,普通用户可能读不了,所以要改权限。
🔍 举个例子:
sudo chown 1000:1000 /home/bai/.kube/config
总结一下 🧠
这三个命令的整体作用就是:
✅ 让你当前的用户(不管是 root
还是普通用户)可以通过 kubectl
命令来访问和操作你刚刚初始化完成的 Kubernetes 集群。
🚀 建议
- 如果你是
root
用户,路径是/root/.kube/config
; - 如果你是普通用户,比如
bai
,路径是/home/bai/.kube/config
,要加sudo
权限去复制; - 这几条命令执行完之后,你就可以使用
kubectl get nodes
、kubectl get pods -A
来查看集群状态了!
问题二 :kubectl 是怎么访问 k8s 集群的
总结: kubctl 要通过kubeconfig 文件 获取API server 的地址 从而发送请求 ---- 认证和权限校验(基于 RBAC) ----- etcd 或 controller-manager 等组件处理并返回响应结果
kubectl 是 Kubernetes 提供的 CLI 工具,它通过 kubeconfig 文件获取 API Server 的地址和认证信息,然后向 Kubernetes 的 RESTful API 发送请求。API Server 接收请求后会进行认证和权限校验(基于 RBAC),然后交由 etcd 或 controller-manager 等组件处理并返回响应结果。
🧠 简要回答:
kubectl
是通过读取本地的 kubeconfig 配置文件(通常是 ~/.kube/config
)来知道:
- 集群的 API Server 地址在哪(比如 https://192.168.1.100:6443)
- 用哪个用户身份访问(比如 admin、system:node)
- 使用哪种认证方式(比如证书、Token)
- 访问哪个命名空间(默认是 default)
然后通过 HTTP(S) 协议请求 API Server,间接操作整个集群。
🧰 工作流程详解
以 kubectl get pods
为例,它背后的访问流程如下:
① 读取 kubeconfig 文件
默认路径是 ~/.kube/config
你也可以通过 --kubeconfig 参数指定其他路径
这个配置文件里包含:
apiVersion: v1
kind: Config
clusters: # 集群地址
- cluster:
server: https://192.168.1.100:6443
certificate-authority-data: <CA证书>
name: kubernetes
users: # 访问集群的身份和认证信息
- name: kubernetes-admin
user:
client-certificate-data: <客户端证书>
client-key-data: <客户端私钥>
contexts: # 上下文,组合 cluster + user + namespace
- context:
cluster: kubernetes
user: kubernetes-admin
namespace: default
name: kubernetes-admin@kubernetes
② 构造请求(发给 API Server)
例如:
GET /api/v1/namespaces/default/pods
Host: 192.168.1.100:6443
Authorization: Bearer <token>(或使用证书)
👉 kubectl 本质就是一个 REST 客户端,调用 Kubernetes API。
③ API Server 验证 & 授权
- 验证身份:通过证书、Token、用户名密码等方式认证你是谁;
- 授权判断:这个用户是否有权限访问该资源(RBAC);
- 返回结果:如果有权限,返回
Pod
的列表;否则返回403 Forbidden
。
📦 你可以这样验证下:
# 查看当前上下文(使用哪个用户连接哪个集群)
kubectl config current-context
# 查看集群信息
kubectl config view --minify
# 连接的是哪个 API Server?
kubectl cluster-info
# 以 REST 请求形式查看 pods
kubectl get pods -o json
✅ 总结:kubectl 访问集群的关键依赖
要素 |
说明 |
API Server 地址 |
集群控制面入口 |
认证信息 |
证书、Token、用户名密码等 |
授权信息 |
通过 RBAC 控制访问权限 |
Context 上下文 |
决定你操作哪个集群、哪个命名空间、以哪个用户身份 |
💡 面试技巧提示:
如果你去面试时被问到:
“kubectl 是怎么工作的?”
你可以这么回答(专业版)👇:
kubectl 是 Kubernetes 提供的 CLI 工具,它通过 kubeconfig 文件获取 API Server 的地址和认证信息,然后向 Kubernetes 的 RESTful API 发送请求。API Server 接收请求后会进行认证和权限校验(基于 RBAC),然后交由 etcd 或 controller-manager 等组件处理并返回响应结果。
问题三
kubectl apply -f https://raw.githubusercontent.com/flannelio/flannel/master/Documentation/kube-flannel.yml
这条网络插件的命令是要在每个 节点上都要执行一下吗
总结:我认为 flannel 插件是 DaemonSet 是部署的所有不用每个节点都执行
不需要! 您只需要在 Master 节点上执行一次 这个命令即可。这条命令是向 Kubernetes API 服务器提交网络插件的配置,集群会自动在所有节点上部署 Flannel。
正确的操作方式:
在 Master 节点上执行:
- bash复制下载kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml
- Kubernetes 会自动处理:
-
- 这个命令会创建一系列资源(DaemonSet、ConfigMap 等)
- Kubernetes 会自动在所有节点(包括 Master 和 Worker)上部署 Flannel Pod
- 不需要在每个节点单独执行
验证安装:
在 Master 节点上检查 Flannel Pod 是否在所有节点运行:
- bash复制下载kubectl get pods -n kube-system -o wide | grep flannel
输出应该类似:
- text复制下载
kube-flannel-ds-abcde 1/1 Running 0 2m node1
kube-flannel-ds-fghij 1/1 Running 0 2m node2
kube-flannel-ds-klmno 1/1 Running 0 2m node3
kube-flannel-ds-pqrst 1/1 Running 0 2m master1
检查节点状态变化(等待几分钟):
- bash复制下载watch kubectl get nodes
所有节点应该从 NotReady
变为 Ready
为什么不需要在每个节点执行?
- DaemonSet 的作用:
-
kube-flannel.yml
包含一个 DaemonSet 资源- DaemonSet 确保集群中每个节点都运行一个 Flannel Pod 副本
- Kubernetes 控制平面会自动调度这些 Pod
- 集群级操作:
-
kubectl apply
是向 API 服务器提交配置- API 服务器会将这些配置同步到所有节点
- 节点上的 kubelet 会根据指令拉取镜像并启动容器
常见误解澄清:
❌ 错误:在每个节点上运行 kubectl apply
✅ 正确:只在 Master 节点运行一次
❌ 错误:在 Worker 节点手动安装 Flannel
✅ 正确:Flannel 容器会自动部署到所有节点
如果安装失败怎么办?
检查网络连接:
# 从 Master 节点测试能否访问 GitHub
curl -I https://raw.githubusercontent.com
手动下载然后应用:
# 在 Master 节点
curl -O https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml
kubectl apply -f kube-flannel.yml
检查防火墙(如果节点间无法通信):
# 在所有节点开放 Flannel 需要的 UDP 8472 端口
sudo ufw allow 8472/udp
sudo ufw reload
记住:所有集群级别的操作(部署应用、安装插件等)都只需要在 Master 节点上通过 kubectl
执行一次,Kubernetes 会自动处理节点间的同步!