第3章:Kubernetes入门:K8s架构解析、核心组件与kubectl实战

好,咱们进入Kubernetes的世界。说实话,我第一次接触K8s的时候,也被它那一堆概念搞得头大。什么Pod、Service、Deployment,听着像是一堆互不相干的东西。但等你真正用起来,会发现这套设计其实非常巧妙。

这一章,我会带你从架构层面先看明白K8s长什么样,再逐个拆解它的核心组件。最后,咱们上手敲几个kubectl命令,让你感受一下“指挥一个集群”是什么体验。

3.1 K8s架构:一个“大脑”加一群“工人”

Kubernetes集群,说白了就是一群服务器在协同工作。这群服务器分成两拨:一拨是“大脑”,叫Master节点;另一拨是“干活的”,叫Worker节点。

我习惯把Master节点想象成公司的CEO,它不直接干活,但所有决策都得经过它。Worker节点就是一线员工,CEO下指令,它们执行。

Master节点(控制平面)

  • API Server:整个集群的入口。你敲的每个kubectl命令,最终都会打到它这里。它负责认证、授权,然后把请求转发给其他组件。
  • Scheduler:调度器。它决定一个新Pod应该放在哪个Worker节点上运行。判断依据包括资源剩余量、节点亲和性等。
  • Controller Manager:控制器管理器。它负责维持集群的“期望状态”。比如你声明要跑3个副本,它就会确保集群里始终有3个Pod在运行。
  • etcd:分布式键值存储。集群的所有配置信息、状态数据都存在这里。你可以把它理解成集群的“数据库”。

避坑指南:我曾经在生产环境遇到过etcd磁盘写满导致集群瘫痪的事故。当时整个API Server都响应不了,所有Pod调度都停了。后来我养成了一个习惯——给etcd单独挂载高性能SSD,并且设置磁盘使用率告警,超过80%就立刻扩容。

Worker节点(数据平面)

  • Kubelet:每个Worker节点上的“小管家”。它负责接收Master下发的指令,管理本节点上的Pod生命周期。
  • Kube-Proxy:网络代理。它负责实现Service的网络规则,比如负载均衡、服务发现。
  • Container Runtime:容器运行时。比如Docker、containerd。Kubelet通过它来真正启动和停止容器。

你想想看,整个架构其实就两件事:Master做决策,Worker执行。这种设计的好处是——Master挂了,Worker上的Pod还能继续运行,只是没法做变更了。

3.2 核心组件:Pod、Service、Deployment

这三个组件,是K8s里最基础也最重要的概念。我当年学的时候,花了整整一周才彻底搞明白它们之间的关系。咱们一个一个来。

Pod:最小的调度单元

Pod是K8s里能创建和部署的最小单位。一个Pod可以包含一个或多个容器。这些容器共享网络命名空间和存储卷。

为什么要有Pod?直接管理容器不行吗?嗯,这里要注意:有些场景下,两个容器需要紧密协作,比如一个写日志,一个读日志。把它们放在同一个Pod里,它们就能通过localhost互相通信,共享同一个数据卷。

我的经验:在实际项目中,我通常一个Pod只放一个容器。除非有明确的“边车模式”需求(比如日志收集、代理转发),否则别把多个容器塞进一个Pod。否则排查问题时会很痛苦——你不知道是哪个容器出了问题。

Service:稳定的网络入口

Pod是动态的,它会因为故障、升级、扩缩容而频繁创建和销毁。每次创建,Pod的IP都会变。那其他服务怎么找到它?

Service就是来解决这个问题的。它给一组Pod提供一个固定的虚拟IP和DNS名称。不管Pod怎么变,只要标签匹配,Service就能把流量转发过去。

Service的类型有几种:

类型 说明 适用场景
ClusterIP 集群内部可访问 服务间调用
NodePort 通过节点IP+端口访问 外部调试、测试
LoadBalancer 云厂商提供负载均衡器 生产环境对外暴露

注意:NodePort的端口范围是30000-32767。我曾经见过有人把端口设成8080,结果死活访问不了——因为不在范围内。这个坑踩过一次就不会忘了。

Deployment:声明式更新

Deployment是用来管理Pod副本的。你告诉它“我要3个副本”,它就会创建3个Pod。你告诉它“我要更新镜像版本”,它会滚动更新,逐个替换Pod,保证服务不中断。

我个人觉得,Deployment是K8s里最实用的控制器。它把“运维操作”变成了“声明式配置”。你不需要手动去停Pod、启Pod,只需要更新YAML文件,剩下的交给Deployment。

一个典型的Deployment YAML长这样:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: crm-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: crm
  template:
    metadata:
      labels:
        app: crm
    spec:
      containers:
      - name: crm-container
        image: crm:v1.0
        ports:
        - containerPort: 8080

你看,replicas: 3 就是声明要3个副本。image: crm:v1.0 就是声明要用的镜像。改版本号,然后kubectl apply,它就自动滚动更新了。

3.3 kubectl常用命令:指挥集群的遥控器

kubectl是K8s的命令行工具。说白了,它就是你和集群交互的遥控器。我每天至少敲几十次kubectl命令,有些命令已经形成肌肉记忆了。

基础操作

  • kubectl get pods:查看所有Pod。加 -n 指定命名空间,加 -o wide 显示更多信息。
  • kubectl describe pod <pod-name>:查看Pod的详细信息。排错时最常用。
  • kubectl logs <pod-name>:查看Pod日志。加 -f 可以实时跟踪。
  • kubectl exec -it <pod-name> -- /bin/sh:进入Pod内部。调试时必备。

资源管理

  • kubectl apply -f deployment.yaml:创建或更新资源。声明式操作,推荐使用。
  • kubectl delete pod <pod-name>:删除Pod。注意,如果Pod由Deployment管理,删除后会自动重建。
  • kubectl scale deployment crm-app --replicas=5:扩缩容。从3个副本变成5个,一行命令搞定。

排错三板斧

遇到Pod起不来怎么办?我一般按这个顺序排查:

  1. kubectl get pods 看状态。如果显示CrashLoopBackOff,说明容器反复崩溃。
  2. kubectl describe pod <pod-name> 看Events。这里会告诉你为什么失败,比如镜像拉取失败、资源不足。
  3. kubectl logs <pod-name> --previous 看上一次的日志。有时候容器启动后立刻退出,不加 --previous 看不到日志。

避坑指南:我曾经遇到一个情况,Pod状态一直是Pending。describe一看,Events里写着“0/3 nodes are available: 3 Insufficient cpu”。说白了就是集群资源不够了。当时我直接加了一个Worker节点,问题解决。所以,Pending状态多半是资源问题,别急着查代码。

3.4 实战:部署一个简单的CRM应用

光说不练假把式。咱们用刚才学的知识,部署一个最简单的CRM应用。

第一步,创建Deployment:

kubectl create deployment crm-demo --image=crm:v1.0 --replicas=2

第二步,暴露Service:

kubectl expose deployment crm-demo --type=NodePort --port=8080

第三步,查看Service的端口:

kubectl get svc crm-demo

看到输出里的PORT(S)列,比如 8080:31234/TCP,说明集群内用8080访问,集群外用任意节点的31234端口访问。

就这么三步,一个高可用的CRM应用就跑起来了。你想想看,如果是传统方式,你得手动在两台服务器上部署应用,配置负载均衡,还要处理故障转移。在K8s里,这些全自动了。

我的建议:刚开始学K8s,别急着搞复杂的集群。先在本地用minikube或者kind搭一个单节点集群,把Pod、Service、Deployment这三个概念玩熟。等你对它们有了手感,再上生产环境。

好了,这一章的内容就到这里。下一章我们会深入Pod的细节,聊聊资源限制、健康检查、生命周期钩子这些实战中绕不开的话题。到时候见。