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

资讯详情

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

Kubernetes 上手实战(1):K8s 核心概念快速入门

Kubernetes 上手实战(1):K8s 核心概念快速入门 Kubernetes 常被缩写为 K8s它解决的不是“如何启动一个容器”而是“如何让一组容器长期按期望运行”。本系列从一个名为 web 的 Nginx 应用出发逐步加入配置、存储、入口、伸缩、打包、观测和生产治理。第一篇先建立最小心智模型并在不依赖集群的情况下校验清单为后续实操清除概念障碍。一、痛点容器能跑不等于服务可靠单机执行docker run很直接但进程退出后谁重启、机器宕机后往哪里迁移、三个副本如何统一升级、客户端如何找到变化中的容器地址都需要额外系统。Kubernetes 用声明式 API 回答这些问题使用者提交“期望状态”控制器持续观察“实际状态”发现偏差便执行调谐。这里的关键不是一次命令成功而是系统不断把现实拉回目标。集群分为控制平面和工作节点。API Server 是统一入口etcd 保存集群状态Scheduler 为未绑定 Pod 选择节点Controller Manager 运行多种控制循环节点上的 kubelet 根据 PodSpec 管理容器容器运行时真正创建进程kube-proxy 或相应数据面实现 Service 转发。生产排障时按这条链路定位比盲目重启有效得多。Pod 是最小调度单元可容纳共享网络和卷的一个或多个容器但它是可替换资源不应被当成固定虚拟机。Deployment 管理无状态 Pod 的副本与滚动升级ReplicaSet 负责维持副本数Service 给一组由标签选中的 Pod 提供稳定访问地址。Namespace 提供逻辑边界却不是强安全边界还需配合 RBAC、网络策略和资源配额。二、原理对象、标签与调谐循环每个 API 对象都可从四部分阅读apiVersion决定模式版本kind决定资源类型metadata给出名字、命名空间和标签spec描述期望控制器写入的status则描述观察结果。不要手工修改 status也不要把运行时生成字段复制回 Git。标签是对象关系的基础。Deployment 的 selector 必须与 Pod template 标签匹配Service 再用自己的 selector 找到 Pod。标签应表达稳定身份例如app.kubernetes.io/name: web版本、提交号等频繁变化信息可作为附加标签但不宜破坏 Service 的稳定选择范围。annotation 适合保存非标识元数据不能用于选择。下面的清单同时创建 Deployment 和 Service。保存为web.yaml后若本机有集群可直接运行kubectl apply -f web.yaml即使暂时没有集群也能用第二段程序检查关键契约。apiVersion:apps/v1kind:Deploymentmetadata:name:weblabels:app.kubernetes.io/name:webspec:replicas:2selector:matchLabels:app.kubernetes.io/name:webtemplate:metadata:labels:app.kubernetes.io/name:webspec:containers:-name:nginximage:nginx:1.27-alpineports:-name:httpcontainerPort:80---apiVersion:v1kind:Servicemetadata:name:webspec:selector:app.kubernetes.io/name:webports:-name:httpport:80targetPort:http应用后先看 Deployment 的期望与可用副本再看 Pod 是否被 Service 选中。rollout status等待控制器完成调谐endpointslices比旧的 Endpoints 对象更符合当前实现。删除一个 Pod 后再次查询会看到 Deployment 补出新 Pod这正是声明式自愈。kubectl apply-fweb.yaml kubectl rollout status deployment/web--timeout90s kubectl get deployment web kubectl get pods-lapp.kubernetes.io/nameweb-owide kubectl getserviceweb kubectl get endpointslices-lkubernetes.io/service-nameweb kubectl delete pod-lapp.kubernetes.io/nameweb--waitfalse kubectl get pods-lapp.kubernetes.io/nameweb--watch预期可观察到的关键结果是 Deployment 始终把可用副本恢复到 2Pod 名称和 IP 可以变化Service 名称与 ClusterIP 保持稳定。命令输出含随机后缀和环境地址因此验收应看字段含义不能逐字比对。三、实现用 kubectl 沿对象关系检查kubectl get适合概览kubectl describe汇总事件与条件kubectl logs查看容器标准输出kubectl exec才进入容器执行诊断。遇到 Pending 先看调度事件遇到 CrashLoopBackOff 先看当前及上一次日志遇到 Service 不通先核对 selector、EndpointSlice、端口名和 readiness而不是直接怀疑网络插件。声明式操作应优先使用apply资源清单进入版本控制并接受评审。临时的kubectl edit会形成集群漂移命令式create适合探索但确认方案后应导出并整理为清单。kubectl diff -f web.yaml可在变更前展示差异不过服务器端默认值可能让输出比源码更长。资源名字通过 DNS 形成发现机制同命名空间可访问web跨命名空间使用web.namespace。Service 不是额外的代理容器而是一组虚拟访问规则和后端端点。流量只会到 Ready 的 Pod这解释了为什么健康检查与发布安全直接相关系列第七篇会完整实现。四、踩坑不要把控制器当脚本执行器第一类误区是直接管理 Pod。裸 Pod 删除后不会回来也没有滚动升级语义常规无状态应用应由 Deployment 管理。第二类是使用latest镜像它不能表达唯一构建节点缓存还可能制造版本不一致应固定语义版本生产进一步固定镜像摘要。第三类是 selector 写错Service 表面存在却没有端点检查kubectl get endpointslices能迅速识别。还要区分“对象已创建”和“应用已就绪”。API Server 接受清单只表示语法与准入通过镜像拉取、调度、探针和应用启动仍可能失败。自动化流程必须等待条件并设置超时。删除 Namespace 会级联删除其中大部分资源所以学习环境也应先确认当前上下文避免对错误集群操作。资源请求不是可选装饰。Scheduler 依据 requests 安排节点容器实际使用超过 limits 时可能被限制或 OOMKilled。首篇暂不添加数字是为了避免复制脱离负载数据的假配置第七篇会通过指标与压测建立有依据的请求和伸缩阈值。五、验证建立第一张排障地图验收这个最小应用时依次确认 API 对象存在、Deployment 条件为 Available、两个 Pod 为 Ready、Service 有两个端点再通过kubectl port-forward service/web 8080:80本地访问。每一层只回答一个问题能够把“访问失败”缩小到声明、调度、容器、就绪或服务发现。清理时执行kubectl delete -f web.yaml而不是按猜测逐个删除对象。真实团队还应给清单加仓库审查、模式校验和策略检查把错误挡在 API Server 之前。至此读者已经掌握对象、控制器、标签选择、服务发现和声明式变更五个可复用概念。下一篇将在本机创建可重复销毁的 kind 集群安装并核验 kubectl把这里的清单真正跑起来同时解释 kind、minikube 与 Docker Desktop 的取舍。下面两个程序把本篇的对象关系变成离线测试。第一个模拟控制器调谐实际副本少于期望值时创建 Pod多于期望值时删除 Pod。它不调用集群也不依赖其他文章适合先理解“声明目标而非编排步骤”。fromdataclassesimportdataclassdataclassclassDeploymentState:desired:intpods:list[str]next_id:int1defreconcile(state:DeploymentState)-list[str]:actions:list[str][]whilelen(state.pods)state.desired:namefweb-{state.next_id}state.next_id1state.pods.append(name)actions.append(fcreate:{name})whilelen(state.pods)state.desired:namestate.pods.pop()actions.append(fdelete:{name})returnactions stateDeploymentState(desired2,pods[])print(first,.join(reconcile(state)))state.pods.remove(web-1)print(after_failure,.join(reconcile(state)))print(fready{len(state.pods)}/{state.desired})运行输出firstcreate:web-1,create:web-2 after_failurecreate:web-3 ready2/2第二个程序验证 Deployment、Pod 模板与 Service 的标签是否贯通。真实项目可把字典替换为 YAML 解析结果并把它放进 CI可迁移的重点是把“Service 没端点”提前变成明确的契约失败。deployment_selector{app:web,tier:frontend}pod_labels{app:web,tier:frontend,version:v1}service_selector{app:web}defmatches(selector:dict[str,str],labels:dict[str,str])-bool:returnall(labels.get(key)valueforkey,valueinselector.items())checks{deployment_selects_template:matches(deployment_selector,pod_labels),service_selects_pod:matches(service_selector,pod_labels),template_has_stable_app:pod_labels.get(app)web,}forname,passedinchecks.items():print(f{name}{PASSifpassedelseFAIL})ifnotall(checks.values()):raiseSystemExit(label contract is broken)print(resultall selectors are connected)运行输出deployment_selects_templatePASS service_selects_podPASS template_has_stable_appPASS resultall selectors are connected参考来源Kubernetes ComponentsKubernetes ObjectsDeploymentsServices 觉得有用就点个赞 收藏方便回头查阅有疑问直接在评论区留言我看到都会回。 本文属于《Kubernetes 上手实战》系列持续更新关注不迷路。 文章里的代码都能直接跑。想要可直接 clone 的完整工程 配套部署脚本 / 踩坑清单评论一声或发邮件到cj2664qq.com我免费发你。如果你正好在做类似系统、或有工程化难题想找人做也欢迎邮件聊一句——我按实际情况评估能落地的就接单或出方案。评论和邮件都能直接找到我不用跳别的平台。
返回列表