尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

Kubernetes 零基础入门:从 Docker 容器到集群编排的第一条认知路径

Kubernetes 零基础入门:从 Docker 容器到集群编排的第一条认知路径 原文链接Kubernetes 零基础入门从 Docker 容器到集群编排的第一条认知路径如果你已经接触过 Docker可能熟悉这样的流程写一个Dockerfile构建镜像然后通过docker run启动容器。这套方式非常适合本地开发、运行单个服务或快速验证一个想法。但当应用开始出现多个副本、多个服务、跨机器部署、故障恢复和持续发布等需求时仅靠手工执行容器命令会迅速变得难以维护。Kubernetes常缩写为 K8s正是为这类问题提供的容器编排平台你声明“希望应用是什么状态”它负责把应用调度到合适的位置并持续尽量把实际状态维持在目标状态。本文不讨论生产集群安装、高可用控制平面或复杂网络插件而是建立从 Docker 到 Kubernetes 的最小认知闭环。1. Docker 已经解决了什么又还缺什么Docker 的核心价值是把应用及其依赖打包成镜像并以容器形式运行。对开发者而言这意味着环境更容易复现应用部署不再完全依赖“在服务器上手动装依赖”可以通过镜像版本管理应用交付物本地可以用docker run很快启动服务。但 Docker 的docker run更接近“在一台机器上启动一个或几个容器”。假设你的应用需要运行 3 个副本并且要面对下面这些情况某个容器退出后谁来自动重启或替换它一台机器故障后谁来把应用放到另一台机器新版本发布时如何逐步替换旧版本避免一次性中断服务后端副本的 IP 会变化前端应如何稳定地访问它配置、密码、访问权限和资源限制如何统一管理你当然可以自己用脚本、进程守护工具、负载均衡器和运维流程拼出一套方案。Kubernetes 的作用是把这些围绕容器化应用运行的通用能力抽象为统一的 API 和对象模型。可以先用一句话区分Docker 更擅长构建和运行容器Kubernetes 更擅长在集群中部署、连接、扩缩和维护容器化应用。Kubernetes 并不是 Docker 的简单替代品。你仍然可以继续用 Docker 构建镜像只是 Kubernetes 节点运行 Pod 时需要通过兼容 CRI 的容器运行时工作。Kubernetes 在 v1.24 中移除了内置 dockershim但这不影响由docker build生成的标准容器镜像被 Kubernetes 使用。2. Kubernetes 的最小心智模型不要一开始就试图记住所有组件。入门阶段只需要理解这条主链路你使用kubectl提交命令或 YAML 清单。请求进入 Kubernetes API Server。控制平面记录你的目标状态并安排相关工作。工作节点上的kubelet接收任务协同容器运行时启动 Pod。Kubernetes 控制器持续观察状态如果实际状态偏离目标状态就尝试进行调谐。例如你声明“我要运行 3 个副本”。即使其中一个 Pod 因故消失Kubernetes 也会尝试创建替代 Pod使副本数回到 3。这里最重要的思维转变是命令式思维我现在手动启动 3 个容器。声明式思维我希望系统始终维持 3 个副本。Kubernetes 更强调后者。你描述目标系统负责持续逼近目标。注意副本数达到 3不必然等于有 3 个“可用”副本。应用是否就绪还取决于容器状态以及后续会学习到的readinessProbe等配置。3. 必须先认识的 6 个对象Kubernetes 的能力主要通过“对象”表达。对象是保存在 Kubernetes API 中的意图记录spec用于描述期望状态系统再通过状态观察和控制器调谐来维持它。Pod最小部署单位不等于容器Pod 是 Kubernetes 中最小的可创建和管理的部署单位。一个 Pod 可以包含一个或多个容器这些容器共享网络命名空间和存储资源。这意味着Pod 中的容器通常可以通过localhost相互通信一个 Pod 通常拥有自己的 IPPod 内多个容器适合处理紧密耦合的协作任务。但对刚入门的应用而言最常见的模式仍然是一个 Pod 承载一个主应用容器。因此下面两句话都不够准确“Pod 就是容器。”——不对Pod 可以包含多个容器。“一个 Pod 必须有多个容器。”——也不对单容器 Pod 非常常见。Deployment用来管理无状态应用副本通常不应该直接手工创建裸 Pod。因为单独创建一个 Pod 后它消失了没有控制器会确保它被替代。对于常见的无状态 Web 服务或 API 服务应该使用 Deployment。Deployment 会管理 Pod 副本并支持保持指定副本数Pod 失败后的替换扩缩容滚动更新回滚到较早的 Deployment 修订版本。可以把它理解为Pod 是实际运行应用的实例Deployment 是管理这些实例的负责人。Service为易变的 Pod 提供稳定入口Pod 会被重建、替换和扩缩容因此 Pod 名称和 IP 都不适合被其他服务长期依赖。Service 通过标签选择一组 Pod并为符合条件的后端端点提供稳定的网络访问抽象。客户端访问的是 Service而不是某个具体 Pod。这也是 Kubernetes 中服务发现的基础客户端 → Service → 一组匹配标签的 PodService 常见类型包括ClusterIP默认类型仅在集群内部可访问NodePort通过节点端口暴露服务LoadBalancer在支持的云环境中申请外部负载均衡器。本地学习时不必急着理解所有暴露方式。使用ClusterIP配合kubectl port-forward就能完成稳定入口与本机访问的练习。Namespace资源的命名范围与隔离边界Namespace 可以在同一个集群中隔离不同团队、项目或环境的资源。相同名称的 Deployment 或 Service 可以存在于不同 Namespace 中。但零基础练习时直接使用默认的defaultNamespace 即可。用户数量较少、资源简单的集群通常无需过早设计多 Namespace 结构。ConfigMap普通配置ConfigMap 用于保存非敏感配置例如环境名称、功能开关、服务地址或普通配置文件。Pod 可以将它作为环境变量、命令参数或挂载文件使用。Secret敏感数据但不是“默认保险箱”Secret 用于保存密码、令牌和密钥等敏感信息。不过Secret 的存在不自动等于“数据已经安全加密”。实际环境还需要关注访问控制、静态加密和密钥管理。入门时只需先建立边界普通配置放 ConfigMap敏感配置放 Secret不要把密码直接写进镜像或提交到代码仓库。4. 一张图理解核心对象关系Deployment └── 维护期望副本数 └── Pod × N └── Container Service └── 通过 labels / selector 选择一组 Pod └── 为这些 Pod 提供稳定访问入口其中labels是连接对象的重要机制。例如Pod 带有标签labels: app: docker-interest而 Service 使用选择器selector: app: docker-interest那么这个 Service 就会把流量转发给带有该标签、且可作为后端端点使用的 Pod。5. YAML 清单Kubernetes 的声明式语言Kubernetes 对象通常使用 YAML 文件定义。无论是 Deployment、Service 还是 ConfigMap入门时都可以先关注四个顶层字段apiVersion: apps/v1 # 使用哪个 API 版本 kind: Deployment # 要创建什么对象 metadata: # 名称、标签、命名空间等元信息 spec: # 期望状态下面是一个可直接学习的 Deployment 示例。它会创建两个 NGINX 副本apiVersion: apps/v1 kind: Deployment metadata: name: docker-interest spec: replicas: 2 selector: matchLabels: app: docker-interest template: metadata: labels: app: docker-interest spec: containers: - name: web image: nginx:1.27 ports: - containerPort: 80几个关键点replicas: 2目标是维持两个 Pod 副本selector.matchLabelsDeployment 用它识别自己管理的 Podtemplate.metadata.labels新建 Pod 会带上的标签两处app: docker-interest必须保持匹配image容器镜像containerPort声明容器使用的端口信息但它本身不会自动把应用暴露到集群外。接着为这组 Pod 创建一个 ServiceapiVersion: v1 kind: Service metadata: name: docker-interest spec: selector: app: docker-interest ports: - port: 80 targetPort: 80 type: ClusterIP这里的selector会选择带有app: docker-interest标签的 Pod。Service 的port是服务端口targetPort是后端 Pod 中目标容器的端口。6. 最小实践闭环在本地部署一个应用本文选择kind作为本地练习环境。kind 会使用容器作为 Kubernetes 节点适合已经安装 Docker 或兼容容器运行时、希望快速创建本地集群的读者。前置条件已安装 Docker、kind和kubectl。不同操作系统的安装方式不同请以各工具官方安装说明为准。第一步创建集群kind create cluster --name k8s-learning kubectl get nodes如果输出中节点状态为Ready说明本地集群已经可用。第二步保存并应用 YAML将前面的两个 YAML 内容分别保存为deployment.yaml service.yaml然后执行kubectl apply -f deployment.yaml kubectl apply -f service.yaml查看资源状态kubectl get deployments kubectl get pods kubectl get services你应该看到一个名为docker-interest的 Deployment两个由 Deployment 创建的 Pod一个同名的 ClusterIP Service。如果 Pod 没有进入Running状态优先执行kubectl describe pod Pod名称初学阶段最常见的原因包括镜像拉取失败、镜像名称或标签不存在、网络问题以及 YAML 中标签和选择器不匹配。第三步从本机访问 Service由于当前 Service 是ClusterIP它默认只在集群内部可访问。为了避免不同本地环境中 NodePort 行为的差异可以使用端口转发kubectl port-forward service/docker-interest 8080:80保持该终端运行然后在浏览器访问http://localhost:8080你访问的不是某个固定 Pod而是 Service 提供的稳定入口。第四步扩缩容将副本数从 2 扩展到 3kubectl scale deployment/docker-interest --replicas3 kubectl get pods再缩回 1kubectl scale deployment/docker-interest --replicas1 kubectl get pods这一步体现了声明式管理你不需要自己决定“启动哪个容器”只需要修改目标副本数。第五步更新与回滚当你有一个新的、确认存在的镜像版本标签时可以修改 Deployment 中的image字段再执行kubectl apply -f deployment.yaml kubectl rollout status deployment/docker-interestDeployment 默认会以滚动更新的方式逐步替换旧 Pod。若更新后发现问题可以查看历史并回滚kubectl rollout history deployment/docker-interest kubectl rollout undo deployment/docker-interest这就是 Kubernetes 相比单次docker run更重要的一层能力它管理的是持续运行的应用状态和发布过程而不只是一次容器启动。7. Docker 本地镜像与 kind 的一个常见坑当你构建自己的镜像时可能会这样做docker build -t my-app:0.1.0 .但随后在 kind 集群里部署my-app:0.1.0却遇到ImagePullBackOff。原因是你本机 Docker 中存在镜像不代表 kind 节点一定能直接看到它。对于本地构建、未推送到镜像仓库的镜像可以将镜像加载进 kind 集群kind load docker-image my-app:0.1.0 --name k8s-learning同时建议使用明确的版本标签例如0.1.0而不是直接使用latest。对于带有非latest标签的镜像Kubernetes 默认通常会使用IfNotPresent拉取策略在本地练习中如需明确表达这一意图也可以显式设置imagePullPolicy: IfNotPresent这样在节点已经拥有该镜像时Kubernetes 会优先使用本地镜像减少再次尝试远程拉取同名镜像造成的困惑。8. 初学者最容易产生的误解误解一Pod 就是 Docker 容器Pod 可以包含多个容器并拥有共享网络与存储上下文。一个 Pod 经常只有一个主容器但两者不是同义词。误解二先学会手动创建 Pod 就够了学习 Pod 的结构是必要的但实际运行无状态应用时更常见的入口是 Deployment。Deployment 才负责副本维持、更新和替换。误解三Service 就是 Docker 的端口映射Docker 的端口映射主要处理宿主机与容器端口的连通Kubernetes Service 的核心价值还包括为一组可替换 Pod 提供稳定访问入口、负载分发和服务发现。误解四Secret 天然等于安全加密Secret 是敏感信息的对象类型不代表你已经完成了加密、最小权限和审计设计。误解五学习 Kubernetes 就意味着必须自建生产集群不必。许多团队使用托管 Kubernetes 服务即使未来不负责集群运维理解 Deployment、Service、配置、资源限制和发布机制仍然会帮助你更好地交付容器化应用。9. 学完这一篇后下一步学什么完成本文的最小闭环后建议按下面顺序继续健康检查与资源管理livenessProbe、readinessProbe、requests、limits配置与密钥ConfigMap、Secret、环境变量与挂载文件持久化存储Volume、PersistentVolume、PersistentVolumeClaim流量入口Ingress 或 Gateway API应用打包Helm可观测性日志、指标、告警与追踪权限与交付RBAC、镜像仓库、CI/CD托管集群实践理解云厂商 Kubernetes 服务的节点、网络、存储和身份集成方式。结语从 Docker 走向 Kubernetes关键不是先背下大量名词而是完成一次思维升级Docker 让你能稳定地交付并运行一个容器Kubernetes 让你能在集群环境中声明应用目标并持续管理它的副本、访问方式和发布过程。先把Pod、Deployment、Service、标签、YAML 和声明式调谐这条主线理解清楚你就已经跨过了 Kubernetes 入门中最重要的一步。参考资料Kubernetes 概念概览Kubernetes 对象与期望状态PodDeploymentService使用 kubectl 创建 Deploymentkind Quick StartDockershim Removal FAQ
返回列表