ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

devops-exercises 实战:用 kubectl 为 nginx Pod 创建 Kubernetes Service 并验证可达性

devops-exercises 实战:用 kubectl 为 nginx Pod 创建 Kubernetes Service 并验证可达性 文档教程DevOps运维【免费下载链接】devops-exercisesLinux, Jenkins, AWS, SRE, Prometheus, Docker, Python, Ansible, Git, Kubernetes, Terraform, OpenStack, SQL, NoSQL, Azure, GCP, DNS, Elastic, Network, Virtualization. DevOps Interview Questions项目地址https://gitcode.com/GitHub_Trending/de/devops-exercises点击查看免费下载本指南以 devops-exercises 仓库中的 Services 01 练习 及其参考答案为核心完整演示「创建 Pod → 编写 Service 清单 → 验证应用可达」的完整链路。读者学完后将掌握 Service 清单的编写规范、port与targetPort的正确配法、selector标签匹配原理以及一套可复用的验证与排错方法可直接迁移到 CKA 备考与日常集群运维中。练习背景Kubernetes 为什么要引入 Service在 Kubernetes 中Pod 是最小的部署单元但它的生命周期是短暂且不稳定的Pod 可以被删除、重建、漂移到其他节点每次重建后 IP 都会变化。直接通过 Pod IP 访问应用显然不可靠。Service 正是为解决这一问题而生的抽象对象。仓库 Kubernetes README 的 Services 问答区给出了官方定义An abstract way to expose an application running on a set of Pods as a network service.通俗地说Service 为「一组具备相同标签的 Pod」提供一个稳定的访问入口集群内虚拟 IP 端口Pod 消亡后 Service 依然存在README 中明确这一点为 True新 Pod 只要满足标签条件就会被自动纳入转发范围。Services 01练习的目标就是创建一个运行 nginx 的 Pod为该 Pod 创建 Service验证应用可达。前置条件一个可用的 Kubernetes 集群如 minikube、kind、kubeadm 或云托管集群并已配置好kubectl本仓库练习均在 default 命名空间操作无需切换 namespace建议熟悉kubectl基础命令get、describe、run、apply。如果你是从零开始可以先完成仓库中的 Pods 01 练习其答案展示了最基础的kubectl run用法。第一步创建带标签的 nginx Pod参考答案的第一步是使用命令式imperative方式直接创建 Podkubectl run nginx --imagenginx --restartNever --port80 --labelsappdev-nginx逐项拆解这条命令参数含义nginxPod 的名称--imagenginx使用的容器镜像来自 Docker Hub 官方 nginx 镜像--restartNever声明这不是 Deployment 而是一个裸 Pod裸 Pod 退出后不会被控制器重建--port80声明容器监听端口为 80即 containerPort--labelsappdev-nginx给 Pod 打上标签appdev-nginx这是后续 Service 选择它的关键仓库 Pods 01 的参考答案 中用的是更简短的kubectl run nginx --imagenginx --restartNever而 Services 01 特意增加了--port与--labels两个参数——它们正是为第二步 Service 的targetPort与selector埋下的伏笔。说明kubectl run创建裸 Pod 只是练习场景。生产环境通常使用 Deployment 管理 Pod仓库 Kubernetes README 的问答区也提醒初学者日常更常见的做法是用 Deployment 间接运行 Pod且 Pod/Deployment 通常定义在 YAML 文件中而非纯命令行。本练习用裸 Pod 是为了聚焦 Service 本身的概念。创建后可以用以下命令确认 Pod 状态kubectl get pods -o wide重点观察STATUS是否为Running并记下IP列——稍后验证 Service 的 Endpoints 时会用到。同时可以确认标签是否生效kubectl get pods --show-labels第二步编写 Service 清单YAML参考答案使用cat EOF的方式把清单写入nginx-service.yamlcat EOF nginx-service.yaml apiVersion: v1 kind: Service metadata: name: nginx-service spec: selector: app: dev-nginx ports: - protocol: TCP port: 80 targetPort: 9372 EOF这份清单不长但每个字段都值得逐项深挖——它们对应 Kubernetes 官方文档中 Service 的核心设计apiVersion: v1Service 是最早一批核心 API 对象属于v1稳定版本没有apps/v1那种版本迁移问题。kind: Service对象类型。metadata.name: nginx-serviceService 名称。在集群内kube-dnsCoreDNS会自动为它生成一条 DNS 记录同一命名空间中的其他 Pod 可以直接通过nginx-service访问它。spec.selector.app: dev-nginxService 与 Pod 建立关联的唯一依据。Service 并不感知 Deployment、ReplicaSet 等上层对象README 明确写道Service points to Pod(s) directly, without connecting to the Deployment in any way它只通过标签选择器筛选出所有appdev-nginx的 Pod 作为转发目标。这就是第一步必须给 Pod 打appdev-nginx标签的原因。spec.ports[0].protocol: TCP传输层协议。TCP 是默认值写明是为了语义清晰若应用使用 UDP则需显式声明README 的 NodePort 问答示例中也提到 protocol 默认即 TCP。spec.ports[0].port: 80Service 对外集群内部暴露的端口也就是访问nginx-service:80时使用的端口。spec.ports[0].targetPort: 9372流量被转发到 Pod 容器内部时的目标端口。一个刻意设计的「坑」port 80 与 targetPort 9372细心的读者会发现Pod 的 containerPort 是80但清单里的targetPort却写成了9372。这不是笔误而是练习的精心设计——它强迫你理解port与targetPort是两个完全独立的维度port决定 Service 的入口targetPort决定容器内部真正监听的端口。targetPort的取值可以等于、也可以不等于容器端口还可以是引用容器端口名name的字符串。关键约束是targetPort必须与 Pod 中容器的containerPort匹配否则流量到达容器后找不到对应端口验证环节必然失败。这一点在 README 的 Services 问答区被列为「定义/添加 Service 的重要步骤」之一确保 Service 的targetPort与 Pod 的containerPort匹配确保selector至少匹配一个 Pod 的标签。所以如果照抄这份答案并期望「立即可达」你需要自行将targetPort改回80或保持9372前提是容器确实监听 9372。这正是本练习希望读者学会的调试判断。为什么不直接写port: 80, targetPort: 80port与targetPort分离带来的灵活性体现在真实场景中微服务内部约定端口如8080与外部暴露端口如80不一致容器端口升级、应用监听端口变更时只需改targetPortService 对外入口保持不变客户端无感知同一 Service 可通过多个ports条目暴露多个端口如80与443分别映射到不同targetPort。在本次练习中若要真正跑通第 3 步验证推荐把targetPort调整为与容器监听一致的80apiVersion: v1 kind: Service metadata: name: nginx-service spec: selector: app: dev-nginx ports: - protocol: TCP port: 80 targetPort: 80创建 Service 有两种等价方式kubectl apply -f nginx-service.yaml # 或 kubectl create -f nginx-service.yamlService 的默认类型与常见类型清单中没有写spec.type此时默认值是ClusterIP——Service 只获得一个集群内部虚拟 IP供集群内访问外部无法直接访问。README 问答区总结了四种 Service 类型类型用途ClusterIP默认集群内部暴露内部通信专用NodePort在每个节点上暴露一个固定端口30000-32767可对外访问创建 NodePort 时 ClusterIP 也会自动创建LoadBalancer对接云厂商负载均衡器将外部流量引入集群ExternalName将 Service 映射到外部 DNS 名称externalName本练习创建的是默认 ClusterIP 类型验证可达性时应在集群内进行见下一步。第三步验证应用可达练习要求「Verify the app is reachable」参考答案虽未给出验证命令但 README 的 Services 问答区补充了完整的验证手法这里串成一套可执行的验证流程。1. 确认 Service 创建成功kubectl get svc输出示例NAME TYPE CLUSTER-IP PORT(S) AGE nginx-service ClusterIP 10.96.x.x 80/TCP 10s2. 检查 Endpoints 是否命中 PodService 通过标签选择器匹配 Pod 后会自动维护一个同名的Endpoints对象里面记录的是当前命中的 Pod IP:port 列表。这是验证「Service 是否真的选中了我们的 Pod」最直接的证据kubectl get endpoints nginx-service # 或 kubectl get ep nginx-service若输出中出现了第一步kubectl get pods -o wide看到的 Pod IP说明选择器命中成功。README 给出的核对技巧是运行kubectl describe service看 Endpoints 中的 IP 是否与kubectl get pod -o wide输出的 Pod IP 一致。如果ENDPOINTS列为空通常是两类问题selector 写错与 Pod 标签不匹配、或 Pod 尚未 Running。3. 在集群内发起请求ClusterIP 只能在集群内部访问最方便的验证方式是进入任意一个 Pod 内用curl请求 Servicekubectl exec nginx -- curl -s http://nginx-service:80如果 nginx 容器内没有 curl也可以临时运行一个工具 Pod 作为测试客户端kubectl run curl-test --imagecurlimages/curl --restartNever --rm -it -- curl http://nginx-service:80请求返回 nginx 的默认欢迎页 HTMLWelcome to nginx!即证明「Service → Endpoints → Pod 容器」整条链路已打通。注意若保留答案中的targetPort: 9372而容器实际监听 80此步将连接失败或超时——这正是对targetPort与containerPort必须匹配这一原则的实战印证。4. 更深入的排错辅助命令kubectl describe svc nginx-service查看 Service 详情包括Endpoints列表与事件Events。kubectl get pod -o wide拿到 Pod IP与 Endpoints 比对。kubectl logs nginx若请求已到达容器可观察 nginx 访问日志。原理纵深创建 Service 后集群里发生了什么仓库 README 的问答区用 6 步描述了创建 Service 时集群内部的完整流程值得在这里完整保留kubectl 向 API server 发送请求创建 Service控制器Controller检测到新 Service控制器创建与 Service 同名的 Endpoint 对象控制器使用 Service 的 selector 来识别 Endpointskube-proxy 检测到新的 Endpoint 对象与新的 Service添加 iptables 规则将发往 Service 端口的流量重定向到 Endpointskube-dns 检测到新的 Service在 DNS 服务器中追加对应的记录。结合本练习的对象串联理解这条链路API server接收kubectl apply -f nginx-service.yaml的请求并持久化到 etcdService controller读取selector: app: dev-nginx把匹配的 Pod 写入 Endpointskube-proxy在每个节点上维护 iptables/IPVS 规则把nginx-service:80的流量 DNAT 到 Endpoints 中的真实 Pod IP:targetPortCoreDNS/kube-dns让集群内其他 Pod 可以通过服务名nginx-service解析到 ClusterIP。从源码结构看本仓库主要提供文档与练习没有 kube-proxy/API server 的实现代码上述行为属于 Kubernetes 控制面的标准机制README 中的描述即为本仓库内可引用的权威依据。标签与选择器Service 的「寻址语言」本练习中的selector.appdev-nginx用到了Labels标签与 Selectors选择器这对核心概念。仓库单独提供了 Labels and Selectors 101 练习其答案展示了选择器的两种典型用法k get po -l appweb # 按单个标签筛选 Pod k get deploy -l envprod,typeweb # 多标签组合筛选逗号分隔 逻辑与README 引用官方定义说明了两者的关系Label是附着在对象如 Pod上的 key/value 对用于组织和筛选对象Selector是客户端/用户识别一组对象的机制是 Kubernetes 的核心分组原语选择器支持等值型equality-based与集合型set-based两种多个条件用逗号分隔时相当于逻辑 AND。Service 的spec.selector使用的就是等值型选择器。练习中 Pod 的标签appdev-nginx与 Service 的 selectorapp: dev-nginx精确匹配因此 Service 能够稳定地把这个 Pod 纳入转发集合——哪怕以后 Pod 被删除重建只要新 Pod 仍带相同标签Service 无需任何改动即可继续转发。将本练习延伸到真实部署命令式 vs 声明式本练习的第二步用cat EOF nginx-service.yaml手工写出清单属于**声明式Declarative管理而第一步的kubectl run属于命令式Imperative**管理。在生产与 CKA 考试中两者各有适用场景命令式适合快速验证如kubectl run、kubectl expose声明式kubectl apply -f xxx.yaml是 GitOps 与 CI/CD 的主流方式清单文件可以入库、评审、审计。仓库中 Deployments 命令区 还展示了命令式创建 Service 的捷径可作为本练习的命令式对照kubectl expose deploy some-deployment --port80 --target-port8080甚至可以用一条命令同时创建 Pod 与 Servicekubectl run nginx --imagenginx --restartNever --port 80 --expose理解这两种风格能帮助你判断何时该写 YAML、何时该用一行命令。常见错误排查清单现象可能原因处理kubectl get ep nginx-service的 ENDPOINTS 为空selector 与 Pod 标签不匹配kubectl get pods --show-labels核对标签修正 selector请求nginx-service:80超时/拒绝targetPort与容器containerPort不一致查看kubectl describe po nginx中的端口调整targetPortPod 状态不是 Running镜像拉取失败或镜像本身不支持kubectl describe po nginx查看事件想在集群外访问默认 ClusterIP 不对外改为 NodePort 或 LoadBalancer或借助 IngressREADME 中 Ingress 用于集群外 HTTP/HTTPS 路由与仓库其他练习的衔接前置Pods 01 与答案——裸 Pod 的创建与验证配套Labels and Selectors 101——选择器筛选命令进阶Kubernetes 完整练习题索引 中的 Service 问答区覆盖kubectl expose、NodePort/LoadBalancer/ExternalName、Endpoints 查看、Service 与 Deployment 关系等大量面试与实操问题以及 CKA 备考页。Services 01 虽然只有两个命令加一份 YAML但它浓缩了 Service 机制的三大支柱——标签选择、端口映射、Endpoints 转发。把本文的验证与排错流程在真实集群上完整跑一遍你就掌握了 Kubernetes 服务发现与流量接入的最小闭环。赞分享文档教程DevOps运维【免费下载链接】devops-exercisesLinux, Jenkins, AWS, SRE, Prometheus, Docker, Python, Ansible, Git, Kubernetes, Terraform, OpenStack, SQL, NoSQL, Azure, GCP, DNS, Elastic, Network, Virtualization. DevOps Interview Questions项目地址https://gitcode.com/GitHub_Trending/de/devops-exercises点击查看免费下载相关推荐部署background-agents前必须知道的6件安全事项单租户模型的安全边界部署background agents前必须知道的6件安全事项单租户模型的安全边界 background agents又称 Open Inspect是一个文档教程DevOps运维devops-exercises 实战指南用 kubectl run 创建你的第一个 Kubernetes PodPods 01 练习详解devops exercises 实战指南用 kubectl run 创建你的第一个 Kubernetes PodPods 01 练习详解 导读 本文以开文档教程DevOps运维devops-exercises 实战AWS EC2 创建 EBS 卷并验证实例终止时的卷生命周期行为devops exercises 实战AWS EC2 创建 EBS 卷并验证实例终止时的卷生命周期行为 本篇是 devops exercises 仓库中 EB文档教程DevOps运维上一篇ComfyUI-Impact-Pack深度解析模块化架构与图像增强技术实现下一篇5分钟解锁Foobar2000的逐字歌词魔法让音乐拥有灵魂字幕创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表