Kubernetes 入门实战:从 docker run 到声明式集群

举报
yd_237615889 发表于 2026/09/10 18:34:32 2026/09/10
【摘要】 Kubernetes 入门实战:从 docker run 到声明式集群上一篇《Docker 容器化入门实战》结尾留了个钩子:什么时候轮到 K8s。这篇就来接住它——当你需要多机调度、故障自愈、滚动发布、弹性扩缩容时,单机 Docker 的天花板就到了。目标不是读完就能当运维,而是建立一张正确的概念地图,外加一条能在本地跑通的最小上手路径。一、先回答:K8s 到底解决什么问题Docker 单机...

Kubernetes 入门实战:从 docker run 到声明式集群

上一篇《Docker 容器化入门实战》结尾留了个钩子:什么时候轮到 K8s。这篇就来接住它——当你需要多机调度、故障自愈、滚动发布、弹性扩缩容时,单机 Docker 的天花板就到了。目标不是读完就能当运维,而是建立一张正确的概念地图,外加一条能在本地跑通的最小上手路径。

一、先回答:K8s 到底解决什么问题

Docker 单机有四个天花板:

·         多机docker run 只管一台机器,机器挂了服务就没了

·         自愈:进程崩了 Docker 能重启容器,但整台机器宕机时,没人把容器搬到别的机器

·         发布:升级靠手动 stoprmrun,停机窗口和回滚全靠手速

·         扩缩容:流量来了手动多开几个容器,流量走了再手动关掉

K8sKubernetes)的答案是一个控制循环:你声明"我要 3 个副本跑 myapp:1.0",它永远把集群现状对齐到这个期望——容器挂了自动重建,机器挂了把负载搬到健康节点,升级时逐个替换实例,出问题一键回滚。

命令式是"帮我做这件事",声明式是"让世界保持这个样子"K8s 只接受后者——这是理解它所有设计的钥匙。

二、概念地图:从 Docker 语言翻译过来

你熟悉的

K8s 对应

一句话区别

docker run

Pod

K8s 最小调度单位,通常一个 Pod 一个业务容器

--restart=always

Deployment

不是"崩了重启",而是"永远对齐期望副本数"

docker network

Service

稳定虚拟 IP + 负载均衡,后面的 Pod IP 无感

-e 环境变量

ConfigMap / Secret

配置与镜像分离;注意 Secret 只是 base64,不是加密

手动 build & run

kubectl apply

yaml 提交给集群,其余交给控制器

 

五个对象各管一段:

·         Pod:一个或多个容器的组合,共享网络和存储。99% 的场景一个 Pod 就一个业务容器

·         DeploymentPod "包工头",管副本数、滚动更新、回滚

·         ServicePod 会死、会换 IPService 提供稳定访问入口,自动负载均衡到健康副本

·         Ingress:集群的统一门卫,按域名和路径把外部流量路由到各 Service

·         Namespace:资源分组隔离,devstagingprod 各占一个

三、最小上手路径:本地起一个真集群

本地集群工具二选一:minikube,或更轻更快的 kind(用 Docker 跑容器来模拟节点)。90 秒得到一个单节点集群:

kind create cluster --name demo      # 创建本地集群

kubectl get nodes                    # 确认节点 Ready

kubectl 是你和集群说话的唯一方式,先记六条:

kubectl apply -f myapp.yaml          # 提交声明(最重要的一条)

kubectl get pods -w                  # 实时盯 Pod 状态

kubectl logs -f deploy/myapp         # 看日志

kubectl describe pod <名字>          # 看事件与失败原因(排障第一入口)

kubectl rollout status deploy/myapp  # 看发布进度

kubectl rollout undo deploy/myapp    # 一键回滚

四、把 Docker 篇的 myapp 部署上去

一个最小但完整的 Deployment,注意资源限额和健康探针已经内嵌:

apiVersion: apps/v1

kind: Deployment

metadata:

  name: myapp

spec:

  replicas: 3

  selector:

    matchLabels:

      app: myapp

  template:

    metadata:

      labels:

        app: myapp

    spec:

      containers:

        - name: myapp

          image: myapp:1.0

          ports:

            - containerPort: 3000

          resources:

            requests: { cpu: "100m", memory: "128Mi" }

            limits:   { cpu: "500m", memory: "256Mi" }

          livenessProbe:

            httpGet: { path: /healthz, port: 3000 }

            initialDelaySeconds: 10

再配一个 Service 把流量导进来:

apiVersion: v1

kind: Service

metadata:

  name: myapp

spec:

  type: NodePort

  selector:

    app: myapp

  ports:

    - port: 80

      targetPort: 3000

新手第一次 apply 失败的头号原因Deployment selector.matchLabels 必须和 template.metadata.labels 完全一致——控制器靠这组标签认领自己管的 Pod,对不上就直接拒绝。

五、生产保命件:资源限额与健康探针

·         requests / limitsrequests 是调度依据(节点按它装箱),limits 是运行上限。两个都不写的 Pod 属于 BestEffort,节点资源紧张时第一个被杀

·         livenessProbe:检查失败就重启容器——死锁、假死的进程靠它救活

·         readinessProbe:没就绪就不接流量——发布时慢启动的应用靠它避免一波 5xx

·         startupProbe:给慢启动应用一个宽限期,探测通过前不跑 liveness

发布与回滚的完整闭环:

kubectl set image deploy/myapp myapp=myapp:1.1

kubectl rollout status deploy/myapp   # 盯发布进度

kubectl rollout undo deploy/myapp     # 1.1 有问题,30 秒回到 1.0

六、六个新手坑

·         镜像用 latest 标签:发布不可追溯,"回滚"可能拉回同一个镜像。永远用明确的版本号

·         不写 requests/limits:一个失控容器吃光节点内存,殃及同节点所有邻居

·         只配 liveness 不配 readiness:应用还在预热,流量已经打进去,全是 5xx

·         Secret 当加密:它只是 base64 编码,本质是明文——真正的秘密交给外部密管系统或开启 etcd 加密

·         直接 `kubectl edit` 改线上:改完即漂移,下次 apply 又被 git 里的声明覆盖。一切以仓库里的 yaml 为准——这就是 GitOps 的起点

·         上来就把数据库搬进 K8s:有状态应用的存储和故障恢复复杂度高一个量级。先用云数据库,让无状态服务先进 K8s

七、学习路线:三步走,别跳

·         1 · 本地:用 kind minikube 把上面的 myapp 跑通,练熟 applylogsdescriberollout 四板斧

·         2 · 单节点试验:找一台 2C4G 云主机装 k3s,体验真实的 NodePort 访问和 Ingress 路由

·         3 · 托管集群:云厂商托管 K8sEKSAKSTKE 等)——控制面人家管,你只管工作节点和 yaml

K8s 的学习曲线在"概念多"而不是""—— PodDeploymentService 三件套的声明式模型想通,后面 80% 的对象都是同一套模式的重复。

速查卡

场景

命令

起本地集群

kind create cluster

提交 / 更新

kubectl apply -f xxx.yaml

盯副本

kubectl get pods -w

看日志

kubectl logs -f deploy/xxx

排障

kubectl describe pod xxx

发布进度

kubectl rollout status deploy/xxx

回滚

kubectl rollout undo deploy/xxx

 

写在最后

docker run kubectl apply,改变的不是一个命令,而是你和基础设施的关系:从"我来操作"变成"我来声明"。先在本地 kind 里把 myapp 跑起来——等你真正被半夜爬起来重启服务折磨过,就会感谢那个写了 livenessProbe 的自己。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。