第4章:Kubernetes入门——从架构到实战

说实话,Kubernetes(简称K8s)是我这几年接触过最让人又爱又恨的技术。爱的是它真的能解决大规模容器编排的痛点,恨的是学习曲线确实陡峭。不过别担心,这一章我会带你从零开始,把K8s的核心概念和实操都过一遍。

我个人习惯把K8s理解成一个「数据中心操作系统」。你想想看,它管理的不再是单个进程,而是整个集群的容器。嗯,这个比喻虽然不完全准确,但能帮你快速建立认知框架。

4.1 K8s架构:Master与Node

K8s集群由两类节点组成:Master节点和Worker节点(也叫Node)。Master是大脑,Node是手脚。我在项目中遇到过不少新手把Master和Node搞混,其实记住一句话就行:Master管决策,Node管干活

4.1.1 Master组件

Master节点上运行着几个关键组件,它们共同决定了集群的「智商」:

  • API Server:整个集群的入口。所有操作都要经过它,说白了就是个RESTful接口。我建议你把它想象成公司的前台,任何请求都得先找它登记。
  • Scheduler:调度器,负责决定Pod该跑到哪个Node上。它的决策依据是资源需求、亲和性策略等。我曾经遇到过调度器把Pod全塞到一台机器上,后来才发现是节点标签没配好。
  • Controller Manager:控制器管理器,负责维护集群的期望状态。比如你声明要跑3个副本,它就会确保始终有3个Pod在运行。
  • etcd:分布式键值存储,保存着集群的所有配置数据。这是K8s的「记忆体」,非常重要。我建议生产环境一定要给etcd做备份,别问我怎么知道的...

4.1.2 Node组件

每个Worker节点上运行着:

  • Kubelet:节点上的「管家」,负责接收Master的指令,管理Pod的生命周期。它会定期向API Server汇报节点状态。
  • Kube-proxy:网络代理,负责实现Service的负载均衡。它维护着节点上的网络规则。
  • Container Runtime:容器运行时,比如Docker、containerd。Kubelet通过它来启动和停止容器。

核心要点:Master组件可以部署在任意节点上,但生产环境建议单独部署。etcd最好奇数节点(3、5、7),保证选举能正常进行。

4.2 核心资源对象

K8s里的一切都是资源对象。你通过声明这些对象,告诉集群「我想要什么」,然后集群自己去实现。我刚开始学的时候觉得概念太多,其实核心就四个:Pod、Deployment、Service、Ingress。

4.2.1 Pod:最小的调度单元

Pod是K8s里最小的部署单元,一个Pod可以包含一个或多个容器。这些容器共享网络命名空间和存储卷。为什么要有Pod?因为有些场景下,你需要把两个容器「绑在一起」运行,比如一个Web服务器和一个日志收集器。

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
  - name: nginx
    image: nginx:1.21
    ports:
    - containerPort: 80

个人经验:我建议一个Pod里只放一个主容器,辅助容器(sidecar)最多一两个。放太多容器会让Pod变得臃肿,排错也麻烦。

4.2.2 Deployment:声明式更新

Deployment是管理Pod的「高级抽象」。你告诉它「我要3个nginx Pod」,它就会帮你创建并维护。如果某个Pod挂了,它会自动重建。这就是声明式的好处——你只管说「要什么」,不用管「怎么做」。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.21
        ports:
        - containerPort: 80

Deployment还支持滚动更新和回滚。我曾经在生产环境更新镜像版本,发现新版本有bug,一条命令就回滚到了旧版本,整个过程零停机。

4.2.3 Service:稳定的网络入口

Pod的IP是动态的,重启就会变。Service就是解决这个问题的——它提供一个稳定的虚拟IP和DNS名称,把请求转发到后端的Pod上。

apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  selector:
    app: nginx
  ports:
  - port: 80
    targetPort: 80
  type: ClusterIP

Service有几种类型:

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

4.2.4 Ingress:七层路由

Service只能做四层负载均衡(IP+端口),而Ingress能做七层路由(域名+路径)。比如你可以让 api.example.com 指向一个Service,web.example.com 指向另一个Service。

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
spec:
  rules:
  - host: api.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: api-service
            port:
              number: 80

注意:Ingress需要安装Ingress Controller才能工作,比如Nginx Ingress Controller或Traefik。默认K8s集群不包含Ingress Controller,需要手动部署。

4.3 kubectl常用命令

kubectl是K8s的命令行工具,几乎所有的操作都靠它。我整理了一些最常用的命令,建议你收藏起来:

# 查看资源
kubectl get pods
kubectl get deployments
kubectl get services
kubectl get nodes

# 查看详细信息
kubectl describe pod <pod-name>

# 查看日志
kubectl logs <pod-name>

# 进入容器
kubectl exec -it <pod-name> -- /bin/bash

# 创建资源
kubectl apply -f deployment.yaml

# 删除资源
kubectl delete pod <pod-name>

# 查看集群信息
kubectl cluster-info

小技巧:我习惯给kubectl设置别名:alias k=kubectl。另外,加上 --watch 参数可以实时监控资源变化,比如 kubectl get pods --watch

4.4 Minikube本地环境搭建

学习K8s最怕的就是没有环境。Minikube就是为解决这个问题而生的——它可以在你的本地机器上跑一个单节点的K8s集群。我建议初学者都用Minikube练手,等熟悉了再上生产环境。

4.4.1 安装Minikube

安装前需要先装好Docker或Hypervisor(比如VirtualBox)。然后执行:

# macOS
brew install minikube

# Linux
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube

# Windows(用管理员PowerShell)
choco install minikube

4.4.2 启动集群

# 启动集群(默认使用Docker驱动)
minikube start

# 指定资源限制
minikube start --cpus=4 --memory=8192

# 查看集群状态
minikube status

# 打开K8s Dashboard
minikube dashboard

避坑指南:我曾经在Windows上遇到Minikube启动失败,原因是Docker Desktop的WSL2配置有问题。解决办法是:确保Docker Desktop开启了WSL2集成,并且分配了足够的内存(至少4GB)。

4.4.3 验证集群

启动成功后,用kubectl验证:

# 查看节点
kubectl get nodes

# 部署一个测试应用
kubectl create deployment hello-minikube --image=k8s.gcr.io/echoserver:1.4

# 暴露服务
kubectl expose deployment hello-minikube --type=NodePort --port=8080

# 访问服务
minikube service hello-minikube

如果一切正常,你会看到浏览器打开了一个页面,显示请求信息。嗯,到这里你的第一个K8s应用就跑起来了。

4.5 本章小结

这一章我们覆盖了K8s的核心内容:Master/Node架构、四大核心资源对象、kubectl常用命令,以及Minikube本地环境搭建。说实话,这些内容够你消化一阵子了。我的建议是:先动手把Minikube搭起来,然后照着命令敲一遍。光看不练是学不会K8s的。

下一章我们会深入Pod的细节,包括生命周期、健康检查、资源限制等。到时候你会发现,Pod虽然看起来简单,但里面的门道还真不少。

课后练习

  1. 用Minikube启动一个K8s集群
  2. 创建一个Deployment,运行nginx,副本数为2
  3. 创建一个Service,类型为NodePort,暴露nginx服务
  4. 用kubectl查看Pod日志,并进入容器内部