ARTICLE DETAIL

资讯详情

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

Kubernetes入门到落地:从容器基础到本地集群部署Nginx实战

Kubernetes入门到落地:从容器基础到本地集群部署Nginx实战 简介《KubernetesK8S入门阶段详细指南》从容器技术基础切入面向具备Linux和Docker基础、希望快速上手K8S的初学者系统讲解Docker镜像管理、容器生命周期、容器与虚拟机差异及镜像分层原理并深入剖析K8S核心组件与Pod、Deployment、Service、Namespace等资源对象帮助读者构建完整的容器编排认知框架。文档重点推荐Minikube与kubectl工具指导本地环境搭建及集群状态验证并以Nginx部署为主线完整演示YAML定义资源、Service暴露应用、日志查看与常见问题排查同时提供常用命令速查和官方文档、书籍等学习资源适合开发与运维人员按章节顺序开展动手实践。资源为单个docx文档压缩包仅19KB内容精炼但体系完整。目前已有274人学习下载适合希望通过实战快速入门并逐步深入Kubernetes的初学者。1. Kubernetes 入门到落地容器技术为什么绕不开 K8SKubernetesK8S入门最反直觉的一件事是别急着搭三节点集群先在本机跑一个单节点环境把容器技术、Pod、Service 这些概念在命令行里过一遍再回头看生产架构会顺很多。标题里的路径——容器技术基础、K8S 核心概念、本地环境搭建、Nginx 部署——其实就是一条公认的入门主路。它回答三个实际诉求容器到底解决了什么、K8S 怎么管理容器、本地怎么获得一个能反复折腾的集群。适合刚接触容器和后端服务的开发者也适合想在公司内部先跑通 Demo 的团队。跟着做下来你会得到一套 minikube kubectl 的最小环境以及一个能从浏览器访问到的 Nginx 服务。2. K8S 核心概念先拆明白Pod、控制器与调度器的关系2.1 容器技术基础镜像、运行时与进程隔离容器本质上不是虚拟机而是一组被约束的进程。Linux 内核用 namespace 隔离进程的视图用 cgroups 限制 CPU、内存等资源用量配合镜像仓库里打包好的只读层形成一个可复制、可分发、可停止再启动的运行单元。你本机装 Docker 之后执行一条docker run背后就是这套机制在工作。K8S 不直接调用 Docker 命令而是通过 CRIContainer Runtime Interface对接任意符合规范的运行时最常见的两个是 containerd 和 Docker。对使用者来说镜像还是那个镜像只是多了一层标准接口。理解这一层你就不会纠结“K8S 到底用不用 Docker”这种问题——运行时可以替换镜像和容器才是稳定的心智模型。# 单机视角一条命令完成拉镜像、建容器、映射端口 docker run -d -p 8080:80 nginx:1.25-alpine # 集群视角同一个动作被拆成“声明状态”和“暴露入口”两份配置 kubectl apply -f deployment.yaml # 描述 Nginx 应该有几个副本、用什么镜像 kubectl apply -f service.yaml # 描述流量如何进到 Nginx Pod这段对比是理解后面所有 YAML 的钥匙。docker run把创建和暴露一步做完而 K8S 把“期望状态”和“访问入口”分开描述。-d表示后台运行-p 8080:80是宿主机端口到容器端口的映射kubectl apply -f则是把声明式配置提交给集群由控制面决定如何执行而不是你手动指定在哪个节点跑。2.2 Pod 是最小调度单元为什么不能只跑容器K8S 的最小调度单元不是容器而是 Pod。一个 Pod 里可以有一个或多个容器这些容器共享同一个网络命名空间共享 localhost也可以挂载同一批存储卷。这种设计的出发点是“超亲密关系”的场景业务容器旁边通常要挂一个 sidecar 容器做日志采集、配置热更新或流量拦截它们必须能通过 localhost 互相通信否则就要引入额外的服务发现。单容器 Pod 也很常见比如只跑一个 Nginx。但你仍然需要把 Pod 作为边界来思考调度器看的是 Pod 的资源请求探针检查的是 Pod 内容器的健康状态滚动更新替换的也是 Pod。如果思想上还停留在“容器组”的层面后面看 ReplicaSet 和 Deployment 的关系会绕。Pod 生命周期是短暂的。节点故障、资源驱逐、手动删除都会让 Pod 消失新 Pod 的 IP 和名称都会变化。所以生产上几乎不会直接创建 Pod而是通过控制器来管理它——这才是 K8S 和传统脚本托管的本质区别。2.3 控制器与控制循环期望状态和当前状态Deployment 是入门第一个要掌握的控制器。它下面管理一个 ReplicaSetReplicaSet 负责维持指定数量的 Pod 副本。你只需要告诉集群“我想要 3 个 nginx 副本”后面的事由控制器完成Pod 挂了会补、节点失联会在其他节点重建、更新镜像时按滚动策略替换。这套机制叫控制循环。kube-apiserver 里保存的是期望状态kubelet 不断上报节点上 Pod 的实际状态controller-manager 里的各个控制器拿两者对比发现不一致就调谐。动手验证一下体会更深执行kubectl delete pod删掉一个由 Deployment 管理的 Pod几秒后会自动出现一个新 Pod因为“期望 3 个副本”这个声明没有变。这种自愈能力是 K8S 的核心价值也解释了为什么部署配置要写成 YAML 而不是一串 shell 命令。命令是一次性的YAML 是持续生效的声明。以后你看到 Operator、自定义控制器本质上都是把某种运维流程也变成“期望状态 调谐”的循环。2.4 Service 与服务发现Pod IP 为什么不值得信Pod 会被随时替换IP 不稳定所以集群内部需要一个稳定的访问入口这就是 Service。Service 通过 selector 选择一组 Pod给它们分配一个稳定的 ClusterIP 和 DNS 名再负责把流量转发到后端 Pod。客户端只认 Service不需要知道 Pod 在哪里。Service 的 type 决定了对外暴露方式。ClusterIP 只在集群内部可达适合服务间调用NodePort 会在每个节点上开一个端口把外部流量引入集群LoadBalancer 面向云环境需要云厂商提供负载均衡器。本地学习和内网环境最常用的是 NodePort后面部署 Nginx 时你会看到具体配置。kube-proxy 负责实现转发规则常见模式有 iptables 和 ipvs默认是 iptables。学习阶段不用深究转发细节只要知道 Service 是稳定的逻辑入口Pod 是后面随时会被替换的实体网络节点即可。概念生命周期访问地址是否稳定谁在管理容器短随时被杀掉重建不稳定容器运行时Pod短受控制器控制不稳定Deployment / ReplicaSetService持久除非你删掉它稳定ClusterIP DNS 名kube-apiserver kube-proxy3. 本地环境搭建kubectl 与 minikube 的最小组合3.1 本地集群选型minikube、kind、kubeadm 谁的坑最少本地跑 K8S 常见三条路minikube、kind、kubeadm。先给结论入门和做本地实验我一般用 minikubekind 适合快速起多节点做 CI 测试kubeadm 适合已经有 Linux 虚拟机或物理机、想模拟生产安装的人。方案上手成本适合场景常见坑minikube低一条命令起单节点入门学习、本地开发、演示镜像仓库不通、驱动选择kind中需要 Docker 环境快速多节点、CI 测试端口访问绕、持久化麻烦kubeadm高需要 Linux 主机生产级安装演练前置检查多网络插件必须配选择 minikube 的核心理由是它对初学者最宽容驱动自动选择节点组件以容器或虚拟机方式跑起来minikube stop和minikube start可以反复开关环境坏了直接minikube delete重置不用动宿主机系统。另外本地机如果装了 Docker Desktop它自带的 K8S 也能用但组件不够透明默认单节点且版本跟随 Desktop 走出问题排查起来比 minikube 麻烦。3.2 安装 kubectl 与 minikube两个最小命令kubectl 是操作集群的客户端minikube 是负责拉起本地集群的启动器。两者要分开安装缺一不可。Linux 和 macOS 可以直接用官方 release 下载二进制Windows 建议下载对应的 exe 安装包或者用包管理器装。# Linux 安装 kubectl取当前稳定版本 curl -LO https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl chmod x kubectl sudo mv kubectl /usr/local/bin/ # Linux 安装 minikube curl -LO https://github.com/kubernetes/minikube/releases/latest/download/minikube-linux-amd64 sudo install minikube-linux-amd64 /usr/local/bin/minikubemacOS 把linux换成darwinCPU 是 ARM 架构的换成arm64。两个文件都装完后先验证一下版本号确认命令能执行。kubectl version --client minikube version这里有个经验kubectl 和集群版本不需要完全一致只要相差不超过一个次要版本就能正常工作。比如集群是 v1.26kubectl 用 v1.27 没问题差太多会在执行操作时报警告甚至直接拒绝。3.3 启动单节点集群minikube start 的参数怎么设启动命令是本地环境搭建里最值得慢慢说的部分。直接用裸的minikube start大概率能成功但在国内网络环境和 Windows 环境下有几个参数能少踩很多坑。minikube start \ --driverdocker \ --container-runtimecontainerd \ --cpus2 \ --memory2048 \ --image-repositoryregistry.cn-hangzhou.aliyuncs.com/google_containers解释一下每个参数的意义。--driverdocker让 minikube 把 K8S 节点以容器方式跑在本机 Docker 里这是 Windows 和 Mac 上最省事的路径但前提是 Docker 已启动且能正常docker ps--container-runtimecontainerd让节点上的容器运行时用 containerd更贴近生产环境也不受 Docker 版本影响--cpus2 --memory2048控制节点占用的宿主机资源2 核 2G 对入门完全够不建议配太高容易掩盖资源不足的问题--image-repository把 kube-apiserver、kubelet 等组件镜像指向国内公开镜像仓库解决本地拉取托管组件镜像慢或超时的问题。启动过程会下载一批镜像第一次可能需要几分钟。看到kubectl get nodes返回 Ready 状态集群就算起来了一半再确认核心组件都正常运行。kubectl get nodes kubectl get pods -A minikube statuskubectl get nodes看节点状态kubectl get pods -A看 kube-system 命名空间里的核心 Pod正常情况下能看到 coredns、etcd、kube-apiserver 等处于 Running。minikube status输出host: Running和kubelet: Running就说明环境就绪。走到这一步本地环境搭建完成后面全是配置层面的问题。4. Nginx 部署实战从一份 YAML 到可访问的 Web 服务4.1 最小 Deployment镜像版本与 Pod 模板本地集群就绪后第一个实战目标就是把 Nginx 跑起来。先写 Deployment它定义了副本数、Pod 模板和容器配置是整个部署的起点。apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deploy labels: app: nginx spec: replicas: 2 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.25-alpine imagePullPolicy: IfNotPresent ports: - containerPort: 80这份 YAML 里有三个地方容易写错。第一个是selector.matchLabels必须和template.metadata.labels保持一致Deployment 靠这个标签找到它管理的 Pod不一致会导致创建出来的 Pod 不被纳管第二个是image选了nginx:1.25-alpinealpine 版本体积小本地拉取快够学习用第三个是imagePullPolicy: IfNotPresent表示本地已有镜像就直接用不每次去仓库拉这对本地反复重建 Pod 很有用。kubectl apply -f nginx-deployment.yaml kubectl get pods -o wideapply 之后用get pods -o wide观察情况。-o wide会多显示 Pod IP 和所在节点方便后面排查。如果看到 STATUS 是 ContainerCreating等十几秒再看如果长时间处于 ImagePullBackOff跳到第 5 章的镜像拉取部分处理。4.2 用 Service 暴露 NodePortnodePort 与 targetPort 的关系Deployment 只解决了“跑起来”外部还访问不到。还需要一个 Service 把流量引进来。这里用 NodePort 类型它会在节点上占用一个 30000-32767 范围内的端口外部请求到这个端口后经过 kube-proxy 转发到后端 Pod。apiVersion: v1 kind: Service metadata: name: nginx-service spec: type: NodePort selector: app: nginx ports: - port: 80 targetPort: 80 nodePort: 30080端口关系是初学者最容易绕晕的地方。port: 80是 Service 自己的端口集群内部访问nginx-service:80走的是它targetPort: 80是 Pod 里容器的端口Nginx 默认监听 80nodePort: 30080是节点对外暴露的端口。外部请求先到节点 30080再转给 Service 的 80最后到达 Nginx 容器。为什么不建议给 Service 配 externalIPs本地环境没有可路由的外部 IP配了也没有实际意义NodePort 是单机学习最直接的方式。生产上则优先用 LoadBalancer 或 IngressNodePort 更多充当兜底。kubectl apply -f nginx-service.yaml kubectl get svc nginx-service看到EXTERNAL-IP是none但PORT(S)显示80:30080/TCP就说明 NodePort 已生效。此时在宿主机浏览器访问http://localhost:30080如果看到 Nginx 欢迎页第一个实战目标完成。4.3 进入 Pod 验证exec 与日志浏览器能访问说明链路通了但作为一个习惯我建议用命令行再验证一遍这能帮你建立“用 kubectl 排错”的肌肉记忆。kubectl get pods -o wide kubectl exec -it deploy/nginx-deploy -- sh -c curl -s -o /dev/null -w %{http_code}\n http://localhost/ kubectl logs -l appnginx --tail20第一条命令看 Pod 的 IP 和状态第二条通过kubectl exec进入某个 Nginx Pod用 curl 请求本机 80 端口返回200说明容器内部的服务本身没问题第三条按标签从多个 Pod 里收集日志--tail20只看最近 20 行避免刷屏。注意logs -l appnginx是 kubectl 支持的标签过滤写法比先查 Pod 名再逐个看日志高效。如果容器内 curl 返回 200但宿主机浏览器访问不了问题一定出在 Service 或节点网络层按第 5 章的端口排查思路走。4.4 扩容与滚动更新控制器的价值不是口号Deployment 的价值这时候体现得最直观。执行几条命令感受一下控制器的调谐能力。kubectl scale deployment nginx-deploy --replicas3 kubectl rollout restart deployment/nginx-deploy kubectl rollout status deployment/nginx-deploy kubectl get podsscale把副本数从 2 扩到 3观察get pods会发现新 Pod 自动创建rollout restart触发一次滚动更新Deployment 会按策略替换 Pod默认是 maxUnavailable 和 maxSurge 各 25%本地环境不需要调。rollout status可以看到更新的实时进度最终显示成功。这个流程就是你在生产环境发布版本时的模版只不过生产上一般用kubectl set image改镜像版本而不是 restart。如果删掉一个 Podreplicas: 3会立刻补一个新 Pod这就是控制循环的实际演示。理解了这一点后面看 HPA、StatefulSet、Operator 都会顺很多。5. 本地 K8S 的避坑手册五个高频问题与处置命令5.1 镜像拉不下来ImagePullBackOff 是本地头号杀手现象Pod 状态卡在 ImagePullBackOff 或 ErrImagePullkubectl describe pod里能看到拉取镜像失败的事件。这是本地环境里遇到最多的问题。原因本地没有目标镜像的缓存同时默认镜像仓库访问超时或版本号写错。K8S 组件镜像和老教程里的地址经常还是 k8s.gcr.io这个域名已经迁移到了 registry.k8s.io旧教程里的地址在新环境里会直接拉不到。解决先拉镜像再导入 minikube这是最稳的后悔药。docker pull nginx:1.25-alpine minikube image load nginx:1.25-alpine kubectl delete pod -l appnginx --force逻辑是用本机 Docker 拉镜像能获得更好的网络兼容性minikube image load把镜像导入到 minikube 节点内部的 containerd最后删掉旧 Pod 触发重新调度。配合 Deployment 里的imagePullPolicy: IfNotPresent新 Pod 会直接用本地镜像不再去仓库拉。组件镜像拉取的问题则用minikube start --image-repository...换仓库解决。5.2 Windows 下 minikube 起不来driver 与 Docker context现象minikube start报Exiting due to MK_DOCKER_DAEMON或者一直卡在创建 Driver 的阶段。原因Docker Desktop 没有启动或者当前 Docker context 不是desktop-linux。Windows 上常见的是 PowerShell 权限不够以及 Docker Desktop 的 WSL2 后端没切对。解决先检查 Docker 状态再切 context。docker context ls docker context use desktop-linux docker ps minikube start第一步看当前 context 名称第二步把它切到desktop-linux第三步确认docker ps能正常输出最后重新启动 minikube。这一步操作是本地环境搭建里最容易被忽略的很多人折腾半天发现 Docker Desktop 压根没运行。5.3 NodePort 访问不了分不清是 kubectl 问题还是防火墙问题现象kubectl get svc显示端口是80:30080/TCP但浏览器访问localhost:30080不通curl 也连不上。原因NodePort 监听的是节点网络而本地用--driverdocker时minikube 会把节点跑在容器里端口映射链路变长。Docker 重启后minikube 自动建立的端口映射偶尔会丢失Windows 上还叠加了防火墙拦截的问题。解决先用kubectl port-forward验证服务本身是否正常再处理网络层。kubectl port-forward svc/nginx-service 8080:80 curl http://localhost:8080port-forward在本地建一条临时隧道绕过 NodePort 直接连到 Service。如果这样能通说明 Nginx 和 Service 都没问题问题在网络栈或防火墙如果这样也不通回去查 Deployment 和 Service 的 selector 是否匹配。临时验证完后 CtrlC 关掉即可别把它当成长期访问方案。5.4 被 kubeadm 日志吓到v1.26.0 的 preflight 不是你的流程现象跟着教程输入命令后看到[init] using kubernetes version: v1.26.0、[preflight] running pre-flight checks这类输出然后被一堆前置检查提示打断。原因这是 kubeadm 初始化集群时的日志属于多节点 Linux 安装路径。本地入门用 minikube根本不需要经过 kubeadm init 这一步输出格式和检查项也完全不一样。解决先确认你参考的教程是哪条路径。凡是出现 kubeadm init、kubeadm join 的教程都预设了至少一台 Linux 主机和足够的资源不适合本机单节点学习。本地环境老老实实用 minikube 或 kind。看到这类日志不用慌换个贴近自己场景的教程即可。5.5 kubectl 与集群版本偏差apply 能跑但告警不停现象执行任何 kubectl 命令都提示版本不匹配或者 apply 时报语法警告。原因kubectl 对集群的版本兼容范围通常是一个次要版本内。比如集群是 v1.26kubectl 是 v1.28 就会出问题。解决先看两边版本再对齐。kubectl version输出里分 Client Version 和 Server Version比较这两个值。如果差超过一个次要版本升级 kubectl 或minikube delete后重新minikube start拉一个和客户端匹配的新集群。本地环境没有存量业务直接重建集群比重装 kubectl 更快。6. 进阶让本地集群更像生产环境的三个验证技巧6.1 用 Ingress 替代 NodePort模拟生产入口NodePort 在本地够用但生产中外部流量一般先进 Ingress Controller再按域名或路径转发到 Service。minikube 自带 ingress 插件开一下就能模拟这条链路。minikube addons enable ingress kubectl get pods -n ingress-nginx等 ingress-nginx 控制器 Running 之后写一个 Ingress 资源apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: nginx-ing spec: rules: - host: nginx.local http: paths: - path: / pathType: Prefix backend: service: name: nginx-service port: number: 80这个 Ingress 的含义是访问nginx.local域名的流量全部转发到nginx-service的 80 端口。把nginx.local解析到 minikube 的 IP在浏览器里就能按域名访问。到这一步你已经完整走了一遍生产环境常见的流量路径Ingress - Service - Pod。6.2 给 Pod 设置资源限额避免本地翻车本地如果只配了 2G 内存不给 Pod 设 limits 很容易把节点整体拖死。给 Nginx 加上资源声明能让集群更稳定。resources: requests: memory: 128Mi cpu: 100m limits: memory: 256Mi cpu: 200mrequests 是调度依据决定 Pod 能不能被放到这个节点上limits 是运行时上限超过会被 OOM Kill。本地集群给每个 Pod 都写清这两个值会逼你提前思考生产环境的容量规划而不是等节点卡死再查问题。6.3 健康检查与清理events、top、stop 与 delete验证集群健康状态两个命令就够了。minikube addons enable metrics-server kubectl top nodes kubectl get events --sort-by.metadata.creationTimestamp | tail -20kubectl top nodes能看节点实际资源占用前提是 metrics-server 已启用kubectl get events按时间排序看最近事件排错时它比 logs 信息更全。用完本地集群minikube stop暂停环境不删数据minikube delete彻底重置这是本地环境最大的后悔药。我现在做现场演示前一定会先minikube image load把 Nginx 镜像准备好再给每个 Pod 写好 requests 和 limits。这两步省掉过无数次翻车。本地集群本来就是用来犯错的地方有一套可重建的环境比背十篇教程都管用。希望帮到你。本文还有配套的精品资源点击获取
返回列表