Kubernetes 入门基础与核心架构
1. Kubernetes 都能做什么初学 Kubernetes 时最先要理解的不是各种资源名而是 Kubernetes 能帮我们解决哪些实际问题。一句话概括Kubernetes 可以把一组服务器变成一个统一的应用运行平台自动完成应用部署、调度、恢复、扩缩容、发布、访问、配置和资源治理。1.1 自动部署应用你只需要告诉 Kubernetes使用哪个镜像启动几个副本暴露哪个端口需要哪些配置Kubernetes 会自动选择合适的节点把应用运行起来。例如我要运行 3 个 nginx:1.25 副本。Kubernetes 会负责创建 3 个 Pod并让它们分布在集群节点上。1.2 自动恢复故障如果某个应用容器崩溃Kubernetes 可以自动重启它。如果某个 Pod 被删除Deployment 可以自动创建新的 Pod。如果某台节点宕机Kubernetes 可以把受影响的 Pod 调度到其他可用节点。这就是常说的自愈能力。1.3 管理多个应用副本生产环境中一个服务通常不会只运行一个实例。Kubernetes 可以帮你管理多个副本例如前端服务运行 3 个副本。 订单服务运行 5 个副本。 支付服务运行 2 个副本。当副本数量不符合预期时Kubernetes 会自动调整。1.4 应用扩容和缩容当访问量变大时可以增加副本数。当访问量变小时可以减少副本数。手动扩容示例kubectl scale deployment web--replicas5Kubernetes 也支持基于 CPU、内存或自定义指标的自动扩缩容。1.5 服务发现和负载均衡Pod 的 IP 会变化不能直接依赖 Pod IP 访问应用。Kubernetes 通过 Service 给一组 Pod 提供稳定访问入口。例如订单服务不需要知道用户服务后面有几个 Pod。 订单服务只需要访问 user-service。Service 会把请求转发给后端健康的 Pod。1.6 滚动发布和版本回滚Kubernetes 可以在不中断服务的情况下逐步发布新版本。例如从web:v1升级到web:v2Kubernetes 会逐步创建新版本 Pod同时逐步减少旧版本 Pod。如果新版本有问题可以执行回滚kubectl rollout undo deployment/web1.7 配置和密钥管理不同环境通常有不同配置dev 使用开发数据库。 test 使用测试数据库。 prod 使用生产数据库。Kubernetes 可以通过 ConfigMap 管理普通配置通过 Secret 管理敏感信息。这样镜像可以保持一致环境差异通过配置注入。1.8 挂载存储有些应用需要保存数据例如数据库文件上传服务日志归档服务Kubernetes 可以通过 Volume、PVC、PV、StorageClass 管理存储。这样 Pod 重建后数据仍然可以保留下来。1.9 资源限制和调度Kubernetes 可以限制每个应用使用多少 CPU 和内存。它还能根据节点资源情况把 Pod 调度到合适的机器上。例如普通 Web 服务调度到普通节点GPU 任务调度到 GPU 节点高优先级服务优先获得资源1.10 权限控制和安全治理Kubernetes 支持 RBAC 权限控制。可以做到开发人员只能查看自己的 NamespaceCI/CD 系统只能发布指定应用应用只能读取自己需要的 Secret普通用户不能删除集群节点这对生产环境非常重要。1.11 监控、日志和故障排查Kubernetes 本身会记录资源状态和事件。配合 Prometheus、Grafana、Loki、ELK 等工具可以实现查看 CPU 和内存使用率查看 Pod 重启次数查看应用日志配置告警排查发布失败、镜像拉取失败、服务不可访问等问题1.12 扩展 Kubernetes 能力Kubernetes 不只可以管理内置资源也可以通过 CRD 和 Operator 扩展。例如Prometheus Operator 管理监控系统Argo CD 管理 GitOps 发布Istio 管理服务网格Cert Manager 管理证书这也是 Kubernetes 成为云原生基础平台的重要原因。1.13 Kubernetes 不适合做什么Kubernetes 能力很强但不是所有场景都适合使用。不太适合只有一个很小的应用没有多副本和自动化需求团队还没有容器化基础没有人维护集群应用强依赖单机本地状态为了学习而直接把复杂生产系统迁入 Kubernetes初学者应先从简单应用开始容器镜像 - Deployment - Service - ConfigMap - Probe - Ingress - PVC - RBAC - 监控发布2. 本章学习目标这一章面向 Kubernetes 初学者目标不是一次性记住所有术语而是先建立一套清晰的理解框架。学完本章后你应该能回答这些问题Kubernetes 到底是做什么的为什么有了 Docker 还需要 Kubernetes一个应用从提交 YAML 到运行起来中间发生了什么Pod、Deployment、Service 分别解决什么问题kubectl 常用命令应该怎么看、怎么用如何部署一个最简单的 Nginx 应用3. 先理解容器与 Kubernetes 的关系3.1 Docker 解决了什么问题在没有容器之前部署应用经常遇到这些问题开发环境能跑测试环境不能跑Java、Node、Python、Nginx 等依赖版本不一致部署步骤靠人工记录容易漏步骤一台机器上部署多个应用依赖互相影响Docker 的核心价值是把应用和依赖打包成镜像然后用容器运行。可以把镜像理解成一个应用的安装包把容器理解成这个安装包启动后的运行进程。例如dockerrun-d-p8080:80 nginx这条命令的意思是启动一个 Nginx 容器并把本机 8080 端口转发到容器的 80 端口。3.2 Docker 没有完整解决的问题如果只有一台机器、几个容器Docker 已经够用。但生产环境通常不是这样。生产环境会遇到有很多台服务器有很多个应用每个应用有多个副本某些容器会异常退出某些机器会宕机发布应用时不能停机流量需要自动分发到多个副本配置、密钥、存储、权限都需要统一管理这些问题靠人工维护会非常复杂。Kubernetes 就是为了解决这些多机器、多应用、多副本的自动化管理问题。3.3 Kubernetes 的核心作用Kubernetes 是一个容器编排平台。“编排”可以理解为你告诉 Kubernetes 你想要什么结果Kubernetes 负责把集群调整到这个结果。例如你告诉 Kubernetes我要运行 3 个 Nginx 副本。Kubernetes 会负责找合适的机器运行它们拉取镜像启动容器检查容器是否健康某个副本挂了就重新创建某台机器挂了就迁移到其他机器这就是 Kubernetes 最重要的思想声明式管理。4. 声明式管理初学者必须理解的核心思想4.1 命令式与声明式命令式是告诉系统“怎么做”。例如先登录服务器 A。 再下载镜像。 再启动容器。 再检查端口。 如果失败再重启。声明式是告诉系统“我要什么结果”。例如replicas:3image:nginx:1.25意思是我要 3 个 nginx:1.25 副本。Kubernetes 会不断检查实际状态和期望状态是否一致。如果不一致就自动修正。4.2 期望状态与实际状态Kubernetes 中经常出现两个概念期望状态你写在 YAML 里的状态实际状态集群当前真实运行的状态举例期望状态Deployment 需要 3 个 Pod 实际状态当前只有 2 个 Pod 正常运行Kubernetes 发现少了一个就会自动创建新的 Pod。这就是 Kubernetes 的自愈能力。5. Kubernetes 集群架构5.1 集群是什么Kubernetes 集群可以理解为一组服务器这些服务器共同运行应用。集群中通常有两类节点Control Plane控制平面负责管理和决策Worker Node工作节点负责运行真正的业务应用可以用一个简单类比理解Control Plane 像调度中心。 Worker Node 像真正干活的服务器。你通过 kubectl 提交命令先到控制平面然后控制平面安排工作节点运行 Pod。5.2 Control Plane 组件API ServerAPI Server 是 Kubernetes 的入口。你执行的每条 kubectl 命令基本都会先请求 API Server。例如kubectl get pods这条命令不是直接去每台机器上查 Pod而是向 API Server 查询集群状态。API Server 负责接收请求校验 YAML 是否合法做认证和授权把数据保存到 etcd把结果返回给客户端etcdetcd 是 Kubernetes 的数据库。它保存集群里所有重要信息有哪些节点有哪些 Pod有哪些 ServiceDeployment 期望几个副本ConfigMap 和 Secret 内容RBAC 权限配置初学者可以先记住一句话etcd 保存 Kubernetes 集群状态不能随便删除或修改。SchedulerScheduler 是调度器负责决定 Pod 放在哪个节点运行。它会考虑哪个节点 CPU 和内存够Pod 有没有指定节点节点有没有污点Pod 是否能容忍污点是否有亲和性规则初学阶段可以简单理解为Scheduler 负责给新 Pod 选机器。Controller ManagerController Manager 是控制器管理器负责不断检查实际状态是否符合期望状态。例如Deployment 要 3 个副本但只剩 2 个它会补 1 个Job 没执行完它会继续创建任务 Pod节点异常它会触发相关处理初学阶段可以记住Controller Manager 负责自动纠偏。5.3 Worker Node 组件KubeletKubelet 运行在每个工作节点上负责管理本机 Pod。它的工作包括接收控制平面下发的 Pod 信息调用容器运行时启动容器上报 Pod 状态执行健康检查挂载存储卷初学阶段可以理解为Kubelet 是每台机器上的 Kubernetes 管家。Container RuntimeContainer Runtime 是真正运行容器的组件。常见运行时containerdCRI-OKubernetes 不直接运行容器而是通过容器运行时来运行容器。Kube ProxyKube Proxy 负责 Service 的网络转发。当你访问一个 Service 时请求最终要转发到某个 Pod。Kube Proxy 会维护这些转发规则。初学阶段可以理解为Kube Proxy 帮 Service 把流量转给后端 Pod。6. Kubernetes 最核心的资源对象6.1 Namespace资源分组Namespace 用来把资源分组。例如dev 开发环境 test 测试环境 prod 生产环境这样不同环境的 Pod、Service、ConfigMap 可以分开管理。常用命令kubectl get namespaces kubectl create namespace dev kubectl get pods-ndev初学者常见误区Namespace 不是虚拟机Namespace 不是强安全边界不同 Namespace 里的服务仍然可能通过网络访问是否能访问取决于网络策略6.2 PodKubernetes 最小运行单位Pod 是 Kubernetes 中最小的调度单位。一个 Pod 里可以有一个或多个容器。大多数业务场景中一个 Pod 通常只有一个主容器。Pod 的特点有自己的 IP可以挂载 Volume可以配置环境变量可以设置资源限制可以配置健康检查为什么 Kubernetes 不直接调度容器而是调度 Pod因为有些容器必须紧密协作例如主应用容器日志收集 sidecar 容器代理 sidecar 容器这些容器需要共享网络和存储所以 Kubernetes 用 Pod 把它们放在一起管理。常用命令kubectl get pods kubectl describe podpod-namekubectl logspod-namekubectlexec-itpod-name--sh6.3 Deployment管理无状态应用实际工作中一般不会直接创建 Pod而是创建 Deployment。原因是 Pod 如果被删除不会自己恢复。而 Deployment 会保证副本数量始终符合预期。Deployment 适合Web 服务API 服务前端服务无状态微服务Deployment 能做创建 Pod维持副本数滚动更新版本回滚故障自愈例子你创建一个 replicas3 的 Deployment。 Kubernetes 会创建 3 个 Pod。 如果某个 Pod 挂了Deployment 会让控制器再创建一个新的。6.4 Service给 Pod 一个稳定入口Pod 的 IP 不是固定的。当 Pod 重建后它的 IP 可能会变化。如果其他服务直接访问 Pod IP就会很不稳定。Service 的作用是给一组 Pod 提供稳定访问入口。Service 通过 label selector 找到后端 Pod。例如selector:app:nginx-demo表示这个 Service 会把流量转发给带有appnginx-demo标签的 Pod。常见 Service 类型ClusterIP集群内部访问默认类型NodePort通过节点端口访问LoadBalancer通过云厂商负载均衡访问6.5 ConfigMap保存普通配置ConfigMap 用来保存非敏感配置。例如应用环境production日志级别info配置文件内容功能开关不要把密码放进 ConfigMap。密码应该放到 Secret。6.6 Secret保存敏感配置Secret 用于保存敏感数据。例如数据库密码TokenTLS 证书镜像仓库登录信息注意Secret 不是绝对安全。它只是比 ConfigMap 更适合保存敏感信息生产环境还需要配合 RBAC、etcd 加密和外部密钥系统。7. kubectl 入门命令7.1 查看资源kubectl get nodes kubectl get pods kubectl get pods-Akubectl get deployments kubectl get svc7.2 查看详细信息kubectl describe podpod-namekubectl describe deploymentdeployment-namekubectl describe svcservice-namedescribe很适合排查问题因为它会显示事件、状态、镜像、调度信息和错误原因。7.3 查看日志kubectl logspod-namekubectl logspod-name--previous--previous用于查看上一个已经崩溃的容器日志排查 CrashLoopBackOff 时很常用。7.4 进入容器kubectlexec-itpod-name--sh如果镜像里有 bash也可以用kubectlexec-itpod-name--bash7.5 应用和删除 YAMLkubectl apply-fapp.yaml kubectl delete-fapp.yamlapply的意思是把 YAML 中描述的期望状态提交给 Kubernetes。8. 运用实例部署第一个 Nginx 应用8.1 创建 Deployment文件名nginx-deployment.yamlapiVersion:apps/v1kind:Deploymentmetadata:name:nginx-demospec:replicas:2selector:matchLabels:app:nginx-demotemplate:metadata:labels:app:nginx-demospec:containers:-name:nginximage:nginx:1.25ports:-containerPort:80重点解释apiVersion资源使用的 API 版本kind资源类型这里是 Deploymentmetadata.name资源名称replicas期望运行 2 个副本selector.matchLabelsDeployment 用它找到自己管理的 PodtemplatePod 模板Kubernetes 会根据它创建 Podimage容器镜像containerPort容器内部监听端口执行kubectl apply-fnginx-deployment.yaml kubectl get pods kubectl get deployment nginx-demo8.2 创建 Service文件名nginx-service.yamlapiVersion:v1kind:Servicemetadata:name:nginx-demo-svcspec:selector:app:nginx-demoports:-port:80targetPort:80type:ClusterIP重点解释selector.appnginx-demo找到带有这个标签的 PodportService 暴露的端口targetPortPod 容器里的端口ClusterIP只能在集群内部访问执行kubectl apply-fnginx-service.yaml kubectl get svc8.3 本地访问验证kubectl port-forward svc/nginx-demo-svc8080:80然后访问http://localhost:8080这条命令的意思是把本机 8080 端口临时转发到集群里的nginx-demo-svc:80。8.4 扩容应用kubectl scale deployment nginx-demo--replicas5kubectl get pods这表示把 Nginx 副本数从 2 个调整为 5 个。8.5 更新镜像kubectlsetimage deployment/nginx-demonginxnginx:1.26 kubectl rollout status deployment/nginx-demoKubernetes 会逐步创建新版本 Pod并删除旧版本 Pod。8.6 回滚版本kubectl rollouthistorydeployment/nginx-demo kubectl rollout undo deployment/nginx-demo如果新版本有问题可以回滚到上一个版本。9. 初学者常见问题9.1 Pod 和容器是什么关系容器运行在 Pod 里面Pod 是 Kubernetes 调度和管理的单位。可以简单理解Pod 是房间容器是房间里运行的应用进程。9.2 Deployment 和 Pod 是什么关系Deployment 负责管理 Pod。一般不要直接创建裸 Pod因为裸 Pod 删除后不会自动恢复。9.3 Service 为什么必须要有因为 Pod IP 会变。Service 提供稳定的访问地址并把流量转发给后端 Pod。9.4 label 为什么重要Kubernetes 很多资源都是通过 label 关联的。例如 Service 找 Pod、Deployment 管 Pod都是依赖 label。如果 label 写错Service 可能找不到 Pod。9.5 YAML 改了以后为什么要 applyYAML 只是本地文件。只有执行kubectl apply -f xxx.yamlKubernetes 才会收到新的期望状态。10. 本章小结初学 Kubernetes 时先记住这条主线写 YAML - kubectl apply - API Server 接收 - 控制器调整状态 - Scheduler 选择节点 - Kubelet 启动 Pod - Service 暴露访问最核心的几个对象Pod运行容器Deployment管理 Pod 副本和发布Service提供稳定访问入口ConfigMap保存普通配置Secret保存敏感配置Namespace资源分组11. 初学者实践与验证这一节建议在 Minikube、Kind、Docker Desktop Kubernetes 或测试集群中操作。不要直接在生产集群练习删除、扩容、回滚等命令。11.1 实践一确认集群是否可用实践目的确认 kubectl 能连接 Kubernetes 集群学会查看节点、命名空间和系统 Pod操作步骤kubectl cluster-info kubectl get nodes kubectl get namespaces kubectl get pods-A验证方法kubectl get nodes预期结果至少能看到 1 个 NodeNode 状态应该是 Ready如果失败按下面顺序排查kubectl config current-context kubectl config get-contexts kubectl cluster-info常见原因kubeconfig 没配置当前 context 指向了错误集群本地 Kubernetes 没启动网络无法访问 API Server11.2 实践二创建 Namespace 并观察资源隔离实践目的理解 Namespace 是资源分组学会在指定 Namespace 中创建和查看资源操作步骤kubectl create namespace k8s-beginner kubectl get namespaces kubectl get pods-nk8s-beginner验证方法kubectl get namespace k8s-beginner预期结果k8s-beginner Active进一步理解kubectl get pods kubectl get pods-nk8s-beginner kubectl get pods-A这三个命令的区别kubectl get pods查看当前默认 Namespace 的 Podkubectl get pods -n k8s-beginner查看指定 Namespacekubectl get pods -A查看所有 Namespace清理命令kubectl delete namespace k8s-beginner11.3 实践三用 Deployment 部署 Nginx实践目的理解 Deployment 如何创建和管理 Pod学会用 YAML 描述应用学会验证 Pod 是否运行成功操作步骤创建nginx-deployment.yamlapiVersion:apps/v1kind:Deploymentmetadata:name:nginx-demospec:replicas:2selector:matchLabels:app:nginx-demotemplate:metadata:labels:app:nginx-demospec:containers:-name:nginximage:nginx:1.25ports:-containerPort:80应用配置kubectl apply-fnginx-deployment.yaml验证方法kubectl get deployment nginx-demo kubectl get pods-lappnginx-demo kubectl describe deployment nginx-demo预期结果Deployment 的 READY 应该接近2/2应该看到 2 个 PodPod 状态应该是 Running如果 Pod 没有 Running排查kubectl describe podpod-namekubectl logspod-name重点看Events 中是否有镜像拉取失败Pod 是否因为资源不足无法调度容器是否启动后立即退出11.4 实践四扩容和缩容 Deployment实践目的理解 Kubernetes 如何维持期望副本数观察 Deployment 自动创建和删除 Pod操作步骤kubectl scale deployment nginx-demo--replicas4kubectl get pods-lappnginx-demo验证方法kubectl get deployment nginx-demo预期结果READY 最终变成4/4Pod 数量变成 4 个缩容kubectl scale deployment nginx-demo--replicas1kubectl get pods-lappnginx-demo预期结果READY 最终变成1/1Kubernetes 自动删除多余 Pod11.5 实践五删除 Pod 并观察自愈实践目的理解 Deployment 的自愈能力理解为什么不要直接管理裸 Pod操作步骤kubectl get pods-lappnginx-demo kubectl delete podpod-namekubectl get pods-lappnginx-demo-w验证方法被删除的 Pod 会消失新的 Pod 会自动创建Deployment 的副本数最终恢复到期望值理解重点你删除的是 Pod。 Deployment 发现实际 Pod 数少了。 Controller 又创建了一个新的 Pod。退出观察Ctrl C11.6 实践六创建 Service 并访问应用实践目的理解 Service 为 Pod 提供稳定入口学会通过 port-forward 访问集群内服务创建nginx-service.yamlapiVersion:v1kind:Servicemetadata:name:nginx-demo-svcspec:selector:app:nginx-demoports:-port:80targetPort:80type:ClusterIP应用配置kubectl apply-fnginx-service.yaml验证 Servicekubectl get svc nginx-demo-svc kubectl get endpoints nginx-demo-svc预期结果Service 存在endpoints 中能看到 Pod IP本地访问kubectl port-forward svc/nginx-demo-svc8080:80浏览器访问http://localhost:8080预期结果能看到 Nginx 欢迎页如果访问失败排查kubectl get pods-lappnginx-demo kubectl get endpoints nginx-demo-svc kubectl describe svc nginx-demo-svc重点看Pod 是否 RunningService selector 是否和 Pod label 一致targetPort 是否是容器真实监听端口11.7 本章练习验收标准完成本章后你应该能独立完成查看当前集群和节点状态创建和删除 Namespace使用 YAML 创建 Deployment扩容和缩容 Deployment删除 Pod 并观察自动恢复创建 Service 并通过 port-forward 访问应用使用 describe 和 logs 做基础排查