news 2026/10/27 4:29:12

K8s集群+Kuboard+Harbor+yml:中小团队容器化闭环实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
K8s集群+Kuboard+Harbor+yml:中小团队容器化闭环实战

1. 从零搭建一套可用的容器编排环境:这套组合到底解决了什么问题

很多团队在容器化落地的中段都会卡在同一个坎上:单机跑容器没问题,一旦要上多节点、要可视化管理、要私有镜像仓库、要一键部署业务,环境就变得七零八落。我这次要分享的这套组合——k8s 集群 + kuboard 管理面板 + harbor 私有仓库 + yml 编排文件——本质上就是给中小团队搭一套"能看、能管、能拉、能跑"的完整闭环。它解决的不是某一个点的问题,而是把"集群怎么建、界面怎么看、镜像从哪来、业务怎么发"这四件事串成一条线。

先说清楚这套东西各自扮演什么角色。k8s(Kubernetes)是底座,负责调度容器、维持副本数、做服务发现;kuboard是长在 k8s 之上的可视化管理面板,把 kubectl 那套命令行操作翻译成图形界面,降低团队上手门槛;harbor是私有镜像仓库,解决"镜像不能放公网、内网要能稳定拉取"的诉求;yml 文件则是把业务部署声明化的载体,一份文件描述清楚要几个副本、用什么镜像、暴露什么端口。四者配合,才是一套能交付给团队日常使用的环境。

这套方案适合谁?我的判断是三类人最受益:一是刚接触 k8s、被一堆命令行劝退的运维新手;二是需要给团队搭一套内网可复现环境的后端负责人;三是想把本地验证过的镜像快速推到内网集群跑起来的小型项目组。如果你已经在用云厂商托管集群,这套自建流程同样值得走一遍,因为踩过的坑在托管环境里往往以另一种形式重现,理解底层逻辑能省下大量排查时间。

需要提前说明的是,下面涉及的具体 IP、节点名、镜像名全部用占位符表示,你替换成自己环境的真实值即可。整套流程我在多个内网环境复现过,核心步骤稳定,但细节上的坑不少,我会在每一段把"为什么这么做"和"哪里容易翻车"都讲透。

2. 整体设计与方案选型:为什么是这套组合而不是别的

2.1 集群形态的选择逻辑

搭 k8s 第一步是决定用什么形态。常见有三条路:云厂商托管集群、kubeadm 自建、以及各种轻量发行版(如 k3s)。我这次选的是kubeadm 自建,原因很实在——内网环境往往没有公网出口,托管集群的控制面访问受限;而 k3s 虽然轻,但默认组件裁剪较多,遇到需要完整 API 行为的场景(比如某些 CRD、某些 admission webhook)容易出兼容问题。kubeadm 是官方维护的引导工具,组件齐全、文档透明,出问题能查到根因,适合作为团队长期维护的底座。

节点规划上,我建议至少1 个控制面 + 2 个工作节点。有人会问单节点行不行?技术上可行,但单节点失去了"编排"的意义,而且控制面和工作负载混跑时,资源争抢会让调度行为失真,排查问题时你会分不清是业务问题还是环境问题。三节点是最小可信环境,能验证副本调度、节点亲和、滚动更新这些真实行为。

这里有个容易被忽略的点:容器运行时。新版 k8s 已经移除了对 Docker 作为运行时的直接支持,走的是 CRI 接口。我选containerd,因为它是 k8s 生态里最贴合 CRI 标准的实现,配置简单、资源占用低。如果你之前习惯docker ps看容器,切到 containerd 后要用crictl ps,这是第一个需要适应的习惯变化。

2.2 为什么管理面板选 kuboard

k8s 自带 dashboard 也能用,但功能偏基础,多命名空间管理、工作负载详情、日志查看这些日常高频操作体验一般。kuboard 的优势在于它把"以应用为中心"的视角做得很顺——你能直接看到某个微服务的所有副本、配置、事件,而不是在一堆资源类型之间来回跳。对于团队协作场景,它的权限模型和界面友好度明显更实用。

选 kuboard 还有个现实考量:部署方式简单。它本身就是一个可以跑在 k8s 里的应用,用一份 yml 就能拉起,不需要额外维护一套独立服务。这种"自己管自己"的方式虽然有点递归的意味,但实际很省心,集群起来后面板跟着起来,运维成本低。

2.3 harbor 的定位与选型理由

镜像仓库这块,公网 Docker Hub 有拉取限流和内网访问不稳定的问题,自建是刚需。harbor 相比 registry 原生方案,多了项目管理、RBAC 权限、镜像扫描、复制策略这些企业级能力。对中小团队来说,最直接的价值是"按项目隔离镜像"——不同业务线的镜像放在不同 project 下,权限清晰,不会互相污染。

harbor 的部署我倾向用它的offline installer(离线安装包),因为内网环境拉不了外网镜像,离线包把依赖都打好了,解压改配置就能起。这里要提醒:harbor 默认用 https,自签证书在 k8s 拉镜像时会因为证书不受信而失败,这个坑后面会专门讲怎么绕。

2.4 yml 编排文件的核心作用

最后一块是 yml。k8s 的一切部署最终都落到声明式配置上,一份 Deployment + Service 的 yml 就描述了一个可运行的服务。为什么强调"从 harbor 拉镜像再执行 yml"这个顺序?因为 yml 里写的image字段指向 harbor 地址,如果仓库没准备好、镜像没推上去,apply 之后 Pod 会一直卡在 ImagePullBackOff。所以正确顺序是:仓库先通、镜像先推、再 apply 编排文件。这个顺序看似常识,但实际项目里因为顺序颠倒浪费的时间非常多。

3. 环境准备与核心细节:那些决定成败的前置条件

3.1 系统层的前置配置

在装任何组件之前,所有节点(控制面和工作节点)都要做一批系统级配置,这些是 k8s 稳定运行的地基,漏一个后面就可能出诡异问题。

第一是关闭交换分区。k8s 的调度器假设节点内存是可预测的,swap 会让内存压力判断失真,导致 OOM 行为不可控。执行swapoff -a只是临时生效,还要注释掉/etc/fstab里的 swap 行,否则重启后复活。我见过有环境忘了改 fstab,跑了一周后节点重启,swap 回来,Pod 开始莫名被驱逐,排查了半天。

第二是内核参数。需要开启网桥的 iptables 转发,并确保br_netfilter模块加载。具体是往/etc/modules-load.d/k8s.conf写br_netfilter和overlay,再往/etc/sysctl.d/k8s.conf写net.bridge.bridge-nf-call-iptables=1、net.ipv4.ip_forward=1等。这些参数的作用是让容器网络和宿主机网络能正确互通,缺了会导致 Pod 之间 ping 不通但宿主机能通这种"半通"状态,非常难查。

第三是时间同步。集群里证书、token、事件时间戳都依赖时钟一致,节点间时间偏差过大会导致证书校验失败、join 失败。内网没有外网 NTP 的话,至少保证所有节点指向同一个内网时间源。

注意:以上配置要在所有节点执行,不是只做控制面。工作节点漏配是新手最常见的失误。

3.2 容器运行时的安装要点

containerd 的安装我建议直接用系统包管理器装,版本选稳定版即可。装完后关键在配置文件/etc/containerd/config.toml,需要确认两件事:一是SystemdCgroup要设为true,因为现在主流发行版都用 systemd 管理 cgroup,不匹配会导致资源限制不生效;二是镜像加速或私有仓库的配置,如果 harbor 是 http 的,要在这里加insecure_registries或者在 k8s 的运行时配置里声明。

这里有个实操细节:containerd 的配置改完后要systemctl restart containerd,但重启会杀掉正在跑的容器。所以在集群还没起来时改最安全,等业务跑起来再改就要考虑滚动影响。我的习惯是在 join 集群之前把所有运行时配置定稿,避免后期返工。

3.3 kubeadm 初始化控制面的参数取舍

kubeadm init的参数里,最需要想清楚的是pod 网段(--pod-network-cidr)。这个值必须和后面要装的网络插件配置一致,比如用 Calico 默认192.168.0.0/16,用 Flannel 默认10.244.0.0/16。两者不一致的后果是 Pod 拿到 IP 但跨节点不通,表现为"同节点 Pod 能通、跨节点不通",这是网络问题里最经典的坑。

另一个参数是--apiserver-advertise-address,要填控制面节点的内网 IP,不能填 127.0.0.1,否则工作节点 join 时连不上。如果节点有多块网卡,一定要确认填的是工作节点能访问到的那块。

初始化完成后,kubeadm 会输出 join 命令,这条命令里的 token 有效期默认 24 小时。如果隔天才加节点,token 过期了要重新生成,用kubeadm token create --print-join-command一条命令搞定,不用慌。

3.4 网络插件的选择与验证

网络插件我选Calico,理由是它在网络策略(NetworkPolicy)支持上更完整,而且 BGP 模式在纯内网环境性能好。装完之后验证不能只看 Pod 是否 Running,要做三件事:一是kubectl get nodes确认所有节点 Ready;二是kubectl get pods -n kube-system确认网络插件 Pod 全 Running;三是实际起两个跨节点的测试 Pod 互相 ping,这一步才是真验证。很多人止步于前两步,结果业务一上就发现跨节点不通。

4. 实操过程:从集群到业务跑通的完整链路

4.1 控制面初始化与节点加入

控制面初始化的完整命令大致如下(IP 和网段替换成你的):

kubeadm init \ --apiserver-advertise-address=192.168.x.10 \ --pod-network-cidr=192.168.0.0/16 \ --image-repository=registry.aliyuncs.com/google_containers

--image-repository这个参数很关键,因为默认会去拉k8s.gcr.io的镜像,内网环境基本拉不动。换成国内可访问的镜像源能省掉大量等待。初始化成功后,按提示配置 kubectl 的 kubeconfig:

mkdir -p $HOME/.kube cp -i /etc/kubernetes/admin.conf $HOME/.kube/config chown $(id -u):$(id -g) $HOME/.kube/config

然后装 Calico,apply 官方 yml 即可。等工作节点用 join 命令加入后,kubectl get nodes应该看到三个节点全部 Ready。这一步的验收标准很明确:三节点 Ready + 网络插件 Pod 全 Running + 跨节点 Pod 互通,三者缺一不可。

4.2 kuboard 的部署与访问

kuboard 的部署就是 apply 一份 yml,它会创建自己的命名空间、ServiceAccount、Deployment 和 Service。部署完用kubectl get svc -n kuboard看暴露的端口,通常通过 NodePort 访问。首次登录需要拿一个 token,用kubectl get secret相关命令从对应 secret 里取出来。

这里有个实操心得:kuboard 的 Service 默认可能是 ClusterIP,内网其他机器访问不到,需要改成 NodePort 或者配 Ingress。我一般直接改 NodePort,简单直接,团队内网访问足够用。改完记得确认防火墙放行了对应端口段。

登录进去后,第一件事是导入集群。kuboard 需要一份有足够权限的 kubeconfig 或 token 来连接集群,用 admin 的配置最省事,但生产环境建议单独建一个受限的 ServiceAccount,遵循最小权限原则。这个细节很多人图省事直接用 admin,后面权限审计时就是隐患。

4.3 harbor 的安装与项目初始化

harbor 用离线包安装,解压后编辑harbor.yml,重点改三处:hostname填内网 IP 或域名、harbor_admin_password设强密码、data_volume指定数据目录(建议挂独立磁盘)。改完执行./install.sh,它会拉起一堆容器(harbor 自身也是容器化的)。

装完后浏览器访问http://<harbor-ip>,用 admin 登录,先新建一个 project,比如叫myapp。这个 project 就是镜像的命名空间,后面推镜像的地址格式是<harbor-ip>/myapp/<image>:<tag>。

关键一步:配置 k8s 节点信任 harbor。如果 harbor 是 http 的,containerd 默认拒绝拉取,需要在每个节点的 containerd 配置里把 harbor 地址加到insecure_registries,然后重启 containerd。如果是 https 自签证书,则要把 CA 证书放到节点的信任目录(如/etc/containerd/certs.d/<harbor-ip>/ca.crt)。这一步不做,后面 apply yml 必然 ImagePullBackOff,而且报错信息往往只说"证书错误"或"http response to https client",不熟悉的人会绕很久。

4.4 镜像推送与 yml 编排执行

镜像推送的标准流程是:本地docker tag成 harbor 地址格式,docker login登录 harbor,docker push推上去。推完在 harbor 界面能看到镜像和 tag,这一步是"仓库通了"的实证。

然后是 yml。一份最小可用的 Deployment + Service 大致长这样:

apiVersion: apps/v1 kind: Deployment metadata: name: myapp namespace: default spec: replicas: 2 selector: matchLabels: app: myapp template: metadata: labels: app: myapp spec: containers: - name: myapp image: 192.168.x.20/myapp/myapp:v1 ports: - containerPort: 8080 --- apiVersion: v1 kind: Service metadata: name: myapp-svc spec: selector: app: myapp ports: - port: 80 targetPort: 8080 type: NodePort

image字段必须写全 harbor 地址 + project + 镜像名 + tag,少一段就拉不到。replicas: 2是为了验证调度,两个副本应该分布在不同节点(如果资源够)。apply 之后用kubectl get pods -o wide看 Pod 落在哪个节点、IP 是多少,用kubectl describe pod看事件,这是排查的第一手资料。

验收标准:Pod 全部 Running + Service 有正确 Endpoints + 通过 NodePort 能访问到业务。三步都过,这条链路才算真正打通。

5. 常见问题与排查技巧实录

5.1 镜像拉取失败的几种典型形态

ImagePullBackOff 是这套流程里最高频的问题,但根因分好几种,得对症下药。第一种是地址写错,比如 harbor 地址拼错、project 名大小写不对(harbor 的 project 名是大小写敏感的);第二种是认证失败,私有 project 需要 imagePullSecret,yml 里没配 secret 就会 401;第三种是证书/协议不匹配,http 仓库被当 https 拉,或者自签证书不受信。

排查顺序我总结成一句话:先看 describe 的 Events,再看节点上手动 crictl pull。kubectl describe pod的 Events 会明确告诉你"unauthorized"还是"certificate"还是"not found",比瞎猜快得多。如果 describe 信息不够,直接上节点执行crictl pull <完整镜像地址>,报错更原始更直接。

现象可能原因处理方向
unauthorized缺 imagePullSecret 或密码错创建 secret 并在 yml 引用
certificate signed by unknown authority自签证书未受信把 CA 放到节点信任目录
http response to https client仓库是 http 但按 https 拉配置 insecure_registries
manifest unknowntag 不存在或 project 名错核对 harbor 界面实际 tag

5.2 跨节点网络不通的定位方法

如果 Pod 起来了但跨节点访问失败,先确认网络插件 Pod 是否全 Running,再看节点路由。Calico 环境下可以用calicoctl看 BGP 邻居状态,或者简单粗暴地在两个跨节点 Pod 里互相ping和curl。我遇到过一次是节点防火墙把 BGP 的 179 端口挡了,插件 Pod 看着 Running 但邻居没建立,跨节点就是不通。所以装完网络插件一定要做跨节点实测,别信"Pod Running 就等于网络好"。

5.3 kuboard 连不上集群的排查

kuboard 导入集群失败,常见是 kubeconfig 里的 server 地址填了127.0.0.1或localhost,而 kuboard 是跑在 Pod 里的,它访问127.0.0.1访问的是自己。正确做法是把 server 改成控制面的内网 IP 或集群内 Service 地址。另外 token 权限不足也会导致导入后看不到资源,检查对应 ServiceAccount 的 RBAC 绑定。

5.4 几个我踩过的实操坑

第一个坑:harbor 装完没改默认密码,团队多人用同一个 admin,后面想追溯谁推的镜像完全没辙。建议装完立刻建独立用户,按 project 授权。

第二个坑:yml 里没写 namespace,默认落到 default,多个业务混在一起,后面清理时容易误删。养成习惯,每个业务一个 namespace,yml 里显式声明。

第三个坑:replicas 设了但节点资源不够,Pod 一直 Pending。用kubectl describe pod看 Events 会提示"Insufficient cpu/memory",这时候要么加资源要么降副本,别硬等。

第四个坑:改了 containerd 配置忘了重启,配置不生效还以为配错了。改完systemctl restart containerd是必须动作,且要确认重启后systemctl status containerd是 active。

6. 这套环境后续怎么用得更顺

环境跑通只是起点,真正让团队用起来还得做几件事。一是把 yml 纳入版本管理,每次变更走 git,配合kubectl apply -f做可追溯部署;二是给 kuboard 配好权限分级,开发只能看自己 namespace,运维有全局视角;三是harbor 配镜像清理策略,不然磁盘很快被历史 tag 撑满,这个我吃过亏,一个项目半年堆了几百 GB 的旧镜像。

还有一个我个人的习惯:每次环境重建都写一份 checklist,把系统配置、运行时、网络插件、仓库信任这些前置项列清楚,照着勾。因为这套流程步骤多、依赖强,靠记忆迟早漏项,而漏一项的代价往往是几小时的排查。这份 checklist 我现在已经迭代到十几项,新同事照着走一遍基本能独立搭起来。

最后分享一个小技巧:验证整条链路是否真的通,别只看 Pod Running,直接kubectl exec进 Pod 里curl一下 harbor 地址和外部服务,能通才算数。Running 只代表容器起来了,不代表网络和依赖都就绪,这个区别在实际运维里非常关键。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/27 4:29:08

OpenMontage:从素材堆到成片的批量化自动混剪实战指南

1. 从素材堆到成片&#xff1a;OpenMontage到底解决的是什么问题如果你剪过那种二三十个素材拼一条的短视频&#xff0c;应该懂我说的痛&#xff1a;进度条拖来拖去&#xff0c;转场一个个套&#xff0c;卡点全靠手感和运气。一条两分钟的卡点混剪&#xff0c;手动剪可能要磨一…

作者头像 李华
网站建设 2026/10/27 4:27:49

wxappUnpacker拆解wxapkg:小程序反编译还原与排错实践

简介&#xff1a;wxappUnpacker 是一套面向微信小程序开发者与安全研究人员的反编译工具源码包&#xff0c;重点解决小程序主包与分包二进制内容难以阅读分析的问题&#xff0c;可将包内结构还原为接近源码的形式&#xff0c;便于理解业务逻辑、排查问题并开展合规的安全审计。…

作者头像 李华
网站建设 2026/10/27 4:27:32

Pygame太空射击实战:游戏循环、碰撞检测与状态机

做游戏开发练习时&#xff0c;很多人卡在同一个地方&#xff1a;教程看了一堆&#xff0c;粒子、物理、渲染讲得头头是道&#xff0c;但真要自己搭一个能跑起来的小游戏&#xff0c;还是不知道从哪个文件开始写。这段时间我把一个太空射击小项目「最後の惑星」从零重写了一遍&a…

作者头像 李华
网站建设 2026/10/27 4:27:30

Docker容器化实战:环境一致性、镜像构建与部署排障

1. Docker 到底在解决什么问题我最早认真对待 Docker 容器化技术&#xff0c;是在一个前后端联调反复出问题的项目上。同一份代码&#xff0c;在开发同学的机器上跑得好好的&#xff0c;到了测试环境就报找不到某个动态库&#xff1b;换到另一台机器&#xff0c;连运行时版本都…

作者头像 李华
网站建设 2026/10/27 4:27:25

权重生成与评价模型:从原理到实践应用

1. 权重生成与评价模型概述在数据分析与决策支持领域&#xff0c;权重生成与评价模型是构建科学评价体系的核心工具。这套方法论通过量化各指标的相对重要性&#xff0c;为复杂决策问题提供客观依据。我在金融风控和运营分析项目中多次应用这类模型&#xff0c;发现其价值不仅在…

作者头像 李华
网站建设 2026/10/27 4:27:15

GitHub双因素认证迁移指南:浏览器插件2FA数据转移

1. GitHub双因素认证迁移实战&#xff1a;浏览器插件版2FA数据转移指南刚给新电脑装完开发环境&#xff0c;突然发现GitHub登录需要双重验证(2FA)&#xff0c;而旧电脑上的Authenticator插件数据没迁移过来&#xff1f;这种场景开发者几乎都会遇到。作为每天要提交几十次代码的…

作者头像 李华