前言
近期使用一套线上 K8s 实训沙箱练习 kubectl 基础操作,一边执行命令探测底层架构,一边验证容器镜像调度、流量接入、租户隔离等 K8s 基础原理。本次探索目标:熟练集群查询命令、理清 Pod 镜像完整加载流程、定位 toolbox 实训终端镜像来源,同时梳理整套平台外网访问实现方式。
环境概况
整套实训平台由底层 Kubernetes 集群 + 上层 KubeSphere 多租户管理平台组成。
集群硬件架构:3 台 Master 控制节点实现控制面高可用,业务负载全部运行在单台 Worker 工作节点;控制面高可用,业务层面存在单点瓶颈。
K8s 集群版本:v1.33.4
实训操作终端:toolbox Pod
toolbox 内置 kubectl 版本:1.28,客户端与集群版本差距巨大,存在 API 兼容性警告
租户隔离机制:每位学员自动分配独立
user-xxxx命名空间,通过 RBAC 严格限制权限,学员仅拥有基础查询、创建 Pod 权限,无法访问核心密钥、宿主机配置。资源限制:平台开启 LimitRanger,对学员创建的 Pod 强制约束 CPU、内存上下限,防止资源抢占。
探索过程
1. 测试创建 Nginx Pod,遭遇镜像拉取失败
执行命令测试调度功能:
kubectl run nginx-demo --image=nginx --port=80
Pod 状态持续流转:Pending → ContainerCreating → ErrImagePull → ImagePullBackOff 更换国内公开镜像源再次尝试,依旧拉取失败。 判断:问题不只是海外镜像网络超时,平台存在访问管控,禁止 Pod 直接拉取外网公共镜像,仅放行内部私有仓库镜像。
核心知识点:kubectl 只是向 apiserver 发送创建资源指令,本身不下载镜像;真正执行镜像拉取操作的是 Worker 节点操作系统内的
containerd。 containerd 镜像加速、网络策略配置文件存放于宿主机/etc/containerd/config.toml,学员容器没有权限登录节点查看、修改。
2. 全局检索私有镜像仓库登录凭证
猜想内部存在私有 Harbor 仓库,尝试筛选镜像登录密钥:
kubectl get secrets -A --field-selector type=kubernetes.io/dockerconfigjson
返回No resources found。 说明集群不存在全局统一镜像登录 Secret。镜像拉取凭证绑定平台内部服务账号,隔离在权限边界之外,普通学员无法读取。
3. Jsonpath 精准提取当前 toolbox 镜像地址
利用 jsonpath 语法精准抓取目标字段,规避大量冗余表格输出:
kubectl get pod $(hostname) -o jsonpath='{.spec.containers[0].image}'
输出私有 Harbor 镜像地址,确认 toolbox 镜像托管在平台自建私有仓库。 仓库域名支持公网 DNS 解析,但仓库开启鉴权,缺少账号密码,外部无法直接拉取镜像。
4. 外网用户如何访问这套实训平台(完整链路)
用户浏览器输入平台域名;
DNS 解析域名,指向机房 / 家庭宽带的公网 IP;
请求流量抵达路由器,配置端口转发 (NAT),将公网端口流量转发至唯一 Worker 节点内网地址;
Worker 节点上运行
ingress-nginx网关 Pod 接收流量;
补充:ingress-nginx 部署了多副本,分散在多台节点,但路由器流量仅转发单一 Worker,其余网关实例闲置,无法实现业务流量容灾;
Ingress 根据域名路由,把请求转发给 KubeSphere 前端、后台服务;
用户在网页点击开启实训环境,平台后端调用 K8s API,调度创建 toolbox Pod;
网页通过 websocket 打通终端,实现网页内直接操作 kubectl。
5. 集群资源与存储相关观察
通过资源查询能够看到平台内置监控体系:Prometheus、Grafana、日志组件等;同时大量 KubeSphere 专属 Quota 类型 Secret,用于管控每个租户资源配额,限制 Pod 数量、存储、算力消耗。
本次探索总结
多租户实训平台依靠「命名空间 + RBAC + 资源配额」三重隔离,学员权限被锁死,无法触及宿主机配置、私有仓库密钥等核心敏感信息;
ImagePullBackOff不要单一归结为网络问题,网络策略、镜像黑白名单、仓库鉴权都是高频诱因;集群架构需要区分:控制面高可用 ≠ 业务负载高可用,本案例所有业务运行在单 Worker 节点,存在明显单点风险;
外网访问内网 K8s 服务,家用环境普遍依靠路由器 NAT 端口转发实现,生产环境更多使用负载均衡;
复刻同类实训沙箱的正确思路:自行编写 Dockerfile 构建 toolbox 镜像、搭建私有 Harbor,不要尝试获取第三方平台私有镜像;
kubectl 客户端版本与 K8s 集群版本尽量保持接近,跨大版本使用极易出现兼容异常。
自建实训集群参考要点
对齐 kubectl 客户端与集群版本,规避 API 兼容问题;
containerd 预先配置国内镜像加速器,规划镜像访问策略,区分内部私有镜像、外部公共镜像;
合理规划节点架构,避免业务全部单点运行;
利用 NetworkPolicy、资源配额做好租户隔离,防止滥用集群资源。
拓展:如何构建同款学员沙箱 toolbox 镜像 & 镜像仓库访问方案
本次实训环境的操作终端 toolbox 是定制容器镜像,也是整个实训平台的核心载体。与其尝试抓取他人私有仓库内的镜像,不如从零自行构建,同时区分镜像构建流程、私有仓库连通方案,对比梳理。
一、toolbox 沙箱镜像构建完整流程
编写
Dockerfile选择轻量基础系统镜像,预装kubectl、curl、nslookup、jq 等运维工具;重点:kubectl 版本与 K8s 集群版本保持一致,消除版本兼容警告。本地构建镜像
docker build -t [私有仓库地址]/public/opslab/toolbox:版本标签 .
登录私有 Harbor 仓库,推送镜像
docker login [私有仓库地址]
docker push [私有仓库地址]/public/opslab/toolbox:版本标签
K8s 侧配置 编写 Pod 模板,平台后端通过 API 动态创建临时 toolbox Pod;搭配 Web Terminal 组件(xterm.js),通过 WebSocket 实现网页终端访问。
生命周期管理 实训结束自动删除 Pod,实现环境回收、租户隔离。
二、基础认知:公共镜像 vs 自制镜像构建区别
公共镜像(nginx、mysql):官方预先构建完成,直接拉取即可,无法修改内部工具版本;受平台网络策略限制很容易拉取失败。
自制 toolbox 镜像:自主编写 Dockerfile,自定义预装软件、调整工具版本,推送到自有私有仓库;集群内部放行访问,稳定性可控,也是实训平台普遍采用的方案。
三、K8s 节点连接私有镜像仓库两种方式
节点层面配置(containerd) 在
/etc/containerd/config.toml写入仓库地址、账号密码、镜像加速器,所有 Pod 共享该配置。 本次实训集群未采用此方案,全局检索kubernetes.io/dockerconfigjson无结果。命名空间 ServiceAccount 绑定 Secret 创建
kubernetes.io/dockerconfigjson类型 Secret 存放仓库凭证,绑定服务账号。 优势:可以按租户、命名空间隔离权限;本次平台就是使用该方式,学员权限无法读取密钥,因此无法外部拉取 toolbox 镜像。
四、补充:为什么本次环境无法拉取公网 Nginx 镜像
平台做了双层限制: ① 网络策略拦截 Worker 节点访问外网镜像仓库; ② 权限管控,仅信任内部 Harbor 地址。 因此出现 ErrImagePull → ImagePullBackOff,单纯更换国内公开镜像域名依旧无法解决。
如果你需要,我把这段直接无缝嵌入你整篇博客。
一次 KubeSphere 实训 K8s 网站环境探索实录
本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。
评论交流
欢迎留下你的想法