Kubernetes容器编排入门教程

教程简介

零基础Kubernetes容器编排入门教程,涵盖K8s概念架构、Pod、Deployment、Service、ConfigMap/Secret、Ingress、PV/PVC、HPA、命名空间等核心技能,配有微服务应用部署实战项目,适合DevOps初学者。

Kubernetes 容器编排入门教程

面向零基础用户 | 从概念到实战,一步步掌握 K8s 核心知识


目录

  1. 什么是 Kubernetes?
  2. Kubernetes 核心架构
  3. 环境搭建:安装 Minikube
  4. Pod:最小调度单元
  5. Deployment:声明式管理副本
  6. Service:服务发现与负载均衡
  7. Namespace:资源隔离
  8. ConfigMap 与 Secret:配置管理
  9. Ingress:七层流量入口
  10. PV 与 PVC:持久化存储
  11. HPA:水平自动伸缩
  12. 实战项目:部署微服务应用
  13. 常用命令速查表
  14. 学习路线建议

1. 什么是 Kubernetes?

Kubernetes(简称 K8s,因为 K 和 s 之间有 8 个字母)是 Google 开源的容器编排平台,用于自动化部署、扩展和管理容器化应用程序。

为什么需要 Kubernetes?

假设你有一个 Web 应用,打包成了 Docker 镜像。手动部署一两个容器很简单,但当面临以下场景时,事情就变得复杂了:

  • 应用需要 10 个副本来应对流量高峰
  • 某个容器崩溃了,需要自动重启
  • 需要滚动更新,不停机发布新版本
  • 不同服务之间需要互相发现和通信
  • 需要根据 CPU 使用率自动扩缩容

Kubernetes 就是为了解决这些问题而生的。你只需要声明期望状态(比如"我要 3 个副本"),K8s 会自动帮你实现并维持这个状态。

核心理念

理念 说明
声明式 API 你告诉 K8s "我想要什么",而不是 "怎么做"
自愈能力 容器挂了自动重启,节点挂了自动迁移
水平扩展 轻松增减副本数量
服务发现 内置 DNS,服务间自动寻址
滚动更新 零停机部署新版本

2. Kubernetes 核心架构

K8s 采用 主从架构(Master-Worker),由控制平面和工作节点组成。

2.1 控制平面(Control Plane)

控制平面是集群的大脑,负责全局决策和状态管理。

组件 职责
kube-apiserver 所有操作的统一入口,提供 RESTful API
etcd 分布式键值存储,保存集群的所有状态数据
kube-scheduler 决定 Pod 应该调度到哪个节点
kube-controller-manager 运行各种控制器(如副本控制器、节点控制器)

2.2 工作节点(Worker Node)

工作节点是实际运行容器的地方。

组件 职责
kubelet 确保 Pod 中的容器正常运行
kube-proxy 维护网络规则,实现 Service 的负载均衡
容器运行时 实际运行容器的引擎(如 containerd、Docker)

2.3 架构图示

┌─────────────────── 控制平面 ───────────────────┐
│                                                 │
│  ┌──────────────┐  ┌──────────────────────────┐ │
│  │  API Server   │  │   Controller Manager     │ │
│  └──────┬───────┘  └──────────────────────────┘ │
│         │                                       │
│  ┌──────┴───────┐  ┌──────────────────────────┐ │
│  │    etcd       │  │     Scheduler            │ │
│  └──────────────┘  └──────────────────────────┘ │
└─────────────────────────────────────────────────┘
              │
    ┌─────────┼─────────┐
    ▼         ▼         ▼
┌────────┐┌────────┐┌────────┐
│ Node 1 ││ Node 2 ││ Node 3 │
│ kubelet││ kubelet││ kubelet│
│ proxy  ││ proxy  ││ proxy  │
│ [Pods] ││ [Pods] ││ [Pods] │
└────────┘└────────┘└────────┘

3. 环境搭建:安装 Minikube

Minikube 是官方提供的本地单节点 K8s 环境,非常适合学习和开发。

3.1 前置条件

  • 操作系统:Linux / macOS / Windows
  • 内存:至少 2GB 可用
  • CPU:至少 2 核
  • 容器运行时:Docker(推荐)

3.2 安装步骤

Linux (amd64):

# 安装 Docker(如果尚未安装)
# 注意:以下为标准安装步骤,实际安装请参考 Docker 官方文档
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
sudo usermod -aG docker $USER
# 重新登录终端以生效

# 安装 kubectl
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl

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

macOS(使用 Homebrew):

brew install kubectl
brew install minikube

Windows(使用 Chocolatey):

choco install kubernetes-cli
choco install minikube

3.3 启动集群

# 使用 Docker 作为驱动启动
minikube start --driver=docker

# 查看状态
minikube status

# 验证 kubectl 能正常通信
kubectl cluster-info
kubectl get nodes

预期输出类似:

NAME       STATUS   ROLES           AGE   VERSION
minikube   Ready    control-plane   30s   v1.28.3

3.4 启用常用插件

# 启用 Ingress 控制器
minikube addons enable ingress

# 启用 Metrics Server(HPA 需要)
minikube addons enable metrics-server

# 启用 Dashboard
minikube addons enable dashboard

# 查看所有插件
minikube addons list

4. Pod:最小调度单元

4.1 什么是 Pod?

Pod 是 K8s 中最小的可部署单元。一个 Pod 可以包含一个或多个紧密关联的容器,它们:

  • 共享同一个网络命名空间(可以用 localhost 互访)
  • 共享存储卷
  • 总是被调度到同一个节点

大多数情况下,一个 Pod 只运行一个容器。多容器 Pod 用于 sidecar 模式(如日志收集、代理)。

4.2 创建 Pod

创建文件 pod.yaml

apiVersion: v1
kind: Pod
metadata:
  name: my-nginx
  labels:
    app: nginx
    env: demo
spec:
  containers:
    - name: nginx
      image: nginx:1.25
      ports:
        - containerPort: 80
      resources:
        requests:
          cpu: "100m"      # 0.1 核
          memory: "128Mi"
        limits:
          cpu: "250m"      # 0.25 核
          memory: "256Mi"

部署并查看:

kubectl apply -f pod.yaml
kubectl get pods
kubectl describe pod my-nginx
kubectl logs my-nginx
kubectl exec -it my-nginx -- /bin/bash

4.3 多容器 Pod 示例(Sidecar 模式)

apiVersion: v1
kind: Pod
metadata:
  name: sidecar-example
spec:
  containers:
    # 主容器:Web 应用
    - name: web
      image: nginx:1.25
      volumeMounts:
        - name: shared-logs
          mountPath: /var/log/nginx

    # Sidecar 容器:日志收集器
    - name: log-collector
      image: busybox:1.36
      command: ["sh", "-c", "tail -f /var/log/nginx/access.log"]
      volumeMounts:
        - name: shared-logs
          mountPath: /var/log/nginx

  volumes:
    - name: shared-logs
      emptyDir: {}

4.4 Pod 生命周期

Pod 有以下几种状态:

状态 说明
Pending 已创建,但容器尚未全部就绪
Running 所有容器已创建,至少一个正在运行
Succeeded 所有容器正常终止
Failed 至少一个容器异常退出
Unknown 无法获取 Pod 状态

5. Deployment:声明式管理副本

5.1 为什么需要 Deployment?

直接创建 Pod 有一个问题:如果 Pod 挂了,没人会帮你重建。Deployment 提供了:

  • 副本管理:确保指定数量的 Pod 始终运行
  • 滚动更新:逐步替换旧版本 Pod
  • 回滚能力:一键回退到之前的版本
  • 自愈能力:Pod 挂了自动重建

5.2 创建 Deployment

创建文件 deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3                    # 期望 3 个副本
  selector:
    matchLabels:
      app: nginx                 # 选择标签为 app=nginx 的 Pod
  strategy:
    type: RollingUpdate          # 滚动更新策略
    rollingUpdate:
      maxUnavailable: 1          # 更新时最多 1 个不可用
      maxSurge: 1                # 更新时最多多出 1 个 Pod
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx:1.25
          ports:
            - containerPort: 80
          readinessProbe:         # 就绪探针
            httpGet:
              path: /
              port: 80
            initialDelaySeconds: 5
            periodSeconds: 10
          livenessProbe:          # 存活探针
            httpGet:
              path: /
              port: 80
            initialDelaySeconds: 15
            periodSeconds: 20

部署操作:

kubectl apply -f deployment.yaml

# 查看 Deployment 状态
kubectl get deployments
kubectl rollout status deployment/nginx-deployment

# 查看 ReplicaSet(Deployment 自动创建)
kubectl get rs

# 查看 Pod
kubectl get pods -l app=nginx

5.3 滚动更新与回滚

# 更新镜像版本
kubectl set image deployment/nginx-deployment nginx=nginx:1.26

# 观察滚动更新过程
kubectl rollout status deployment/nginx-deployment

# 查看更新历史
kubectl rollout history deployment/nginx-deployment

# 回滚到上一个版本
kubectl rollout undo deployment/nginx-deployment

# 回滚到指定版本
kubectl rollout undo deployment/nginx-deployment --to-revision=2

5.4 扩缩容

# 手动扩容到 5 个副本
kubectl scale deployment/nginx-deployment --replicas=5

# 缩容到 2 个副本
kubectl scale deployment/nginx-deployment --replicas=2

6. Service:服务发现与负载均衡

6.1 为什么需要 Service?

Pod 的 IP 地址是临时的,重建后会变化。Service 为一组 Pod 提供:

  • 稳定的访问入口(固定 ClusterIP 或 DNS 名称)
  • 负载均衡:自动将流量分发到后端 Pod
  • 服务发现:通过 DNS 名称访问

6.2 Service 类型

类型 说明 使用场景
ClusterIP 仅集群内部可访问(默认) 微服务间通信
NodePort 在每个节点上开放一个端口 开发/测试环境
LoadBalancer 创建外部负载均衡器 生产环境(云平台)
ExternalName 映射到外部 DNS 名称 访问外部服务

6.3 创建 ClusterIP Service

apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  type: ClusterIP
  selector:
    app: nginx                # 匹配标签为 app=nginx 的 Pod
  ports:
    - protocol: TCP
      port: 80                # Service 端口
      targetPort: 80          # Pod 端口

6.4 创建 NodePort Service

apiVersion: v1
kind: Service
metadata:
  name: nginx-nodeport
spec:
  type: NodePort
  selector:
    app: nginx
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
      nodePort: 30080         # 节点端口范围:30000-32767

访问方式:

# Minikube 环境下获取访问地址
minikube service nginx-nodeport --url

# 或直接访问
curl $(minikube ip):30080

6.5 DNS 服务发现

K8s 内置 DNS,Service 创建后自动注册:

# 同命名空间内访问
http://<service-name>

# 跨命名空间访问
http://<service-name>.<namespace>.svc.cluster.local

# 示例:访问 default 命名空间下的 nginx-service
http://nginx-service.default.svc.cluster.local

7. Namespace:资源隔离

7.1 什么是 Namespace?

Namespace(命名空间)用于将集群资源逻辑隔离,适合:

  • 多团队共享集群
  • 区分开发、测试、生产环境
  • 设置资源配额和权限

7.2 默认命名空间

命名空间 说明
default 默认命名空间,未指定时使用
kube-system K8s 系统组件
kube-public 公共资源
kube-node-lease 节点心跳

7.3 创建命名空间

apiVersion: v1
kind: Namespace
metadata:
  name: development
  labels:
    env: dev

或使用命令:

kubectl create namespace development

7.4 在指定命名空间中部署资源

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
  namespace: development          # 指定命名空间
spec:
  replicas: 2
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
        - name: app
          image: nginx:1.25
          ports:
            - containerPort: 80

7.5 资源配额

限制命名空间的资源使用:

apiVersion: v1
kind: ResourceQuota
metadata:
  name: dev-quota
  namespace: development
spec:
  hard:
    pods: "10"                    # 最多 10 个 Pod
    requests.cpu: "4"             # CPU 请求总和不超过 4 核
    requests.memory: "8Gi"        # 内存请求总和不超过 8GB
    limits.cpu: "8"               # CPU 限制总和不超过 8 核
    limits.memory: "16Gi"         # 内存限制总和不超过 16GB

8. ConfigMap 与 Secret:配置管理

8.1 ConfigMap:存储非敏感配置

ConfigMap 用于存储键值对配置数据,与 Pod 解耦。

创建 ConfigMap:

apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  # 键值对形式
  APP_ENV: "production"
  APP_DEBUG: "false"
  LOG_LEVEL: "info"
  # 文件形式
  nginx.conf: |
    server {
        listen 80;
        server_name localhost;
        location / {
            root /usr/share/nginx/html;
            index index.html;
        }
    }

在 Pod 中使用 ConfigMap:

apiVersion: v1
kind: Pod
metadata:
  name: config-demo
spec:
  containers:
    - name: app
      image: nginx:1.25
      # 方式一:作为环境变量
      envFrom:
        - configMapRef:
            name: app-config
      # 方式二:单独映射某个键
      env:
        - name: CUSTOM_ENV
          valueFrom:
            configMapKeyRef:
              name: app-config
              key: APP_ENV
      # 方式三:挂载为文件
      volumeMounts:
        - name: config-volume
          mountPath: /etc/nginx/conf.d
  volumes:
    - name: config-volume
      configMap:
        name: app-config
        items:
          - key: nginx.conf
            path: default.conf

8.2 Secret:存储敏感数据

Secret 用于存储密码、Token、证书等敏感信息,数据以 Base64 编码存储。

创建 Secret:

apiVersion: v1
kind: Secret
metadata:
  name: db-secret
type: Opaque
data:
  DB_HOST: bXlzcWwtaG9zdA==          # echo -n 'mysql-host' | base64
  DB_USER: cm9vdA==                    # echo -n 'root' | base64
  DB_PASSWORD: czNjcjN0UEBzc3cwcmQ=   # echo -n 's3cretP@ssw0rd' | base64

或使用命令创建:

kubectl create secret generic db-secret \
  --from-literal=DB_HOST=mysql-host \
  --from-literal=DB_USER=root \
  --from-literal=DB_PASSWORD='s3cretP@ssw0rd'

在 Pod 中使用 Secret:

apiVersion: v1
kind: Pod
metadata:
  name: secret-demo
spec:
  containers:
    - name: app
      image: my-app:1.0
      envFrom:
        - secretRef:
            name: db-secret
      volumeMounts:
        - name: secret-volume
          mountPath: /etc/secrets
          readOnly: true
  volumes:
    - name: secret-volume
      secret:
        secretName: db-secret

9. Ingress:七层流量入口

9.1 什么是 Ingress?

Ingress 是 K8s 的七层(HTTP/HTTPS)流量管理组件,提供:

  • 基于域名的路由:不同域名指向不同服务
  • 基于路径的路由:不同 URL 路径指向不同服务
  • TLS 终止:在入口处处理 HTTPS
  • 虚拟主机:多个服务共享一个外部 IP

9.2 架构示意

互联网流量
    │
    ▼
┌─────────┐
│ Ingress │  ← Ingress Controller (如 nginx-ingress)
│Controller│
└────┬────┘
     │
     ├── api.example.com ──→ api-service:8080
     ├── web.example.com ──→ web-service:80
     └── app.example.com/admin ──→ admin-service:8080

9.3 创建 Ingress 资源

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: app-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: nginx
  rules:
    # 基于域名的路由
    - host: api.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: api-service
                port:
                  number: 8080

    - host: web.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: web-service
                port:
                  number: 80

    # 基于路径的路由
    - host: app.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: frontend-service
                port:
                  number: 80
          - path: /api
            pathType: Prefix
            backend:
              service:
                name: backend-service
                port:
                  number: 8080

9.4 TLS 配置

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: tls-ingress
spec:
  ingressClassName: nginx
  tls:
    - hosts:
        - secure.example.com
      secretName: tls-secret          # 包含证书的 Secret
  rules:
    - host: secure.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: secure-service
                port:
                  number: 80

创建 TLS Secret:

kubectl create secret tls tls-secret \
  --cert=path/to/tls.crt \
  --key=path/to/tls.key

10. PV 与 PVC:持久化存储

10.1 为什么需要持久化存储?

容器中的数据是临时的,容器重建后数据丢失。K8s 提供了两层抽象:

  • PV(PersistentVolume):集群级别的存储资源,由管理员创建
  • PVC(PersistentVolumeClaim):用户对存储的请求,类似 "我需要 10GB 存储"

10.2 创建 PV

apiVersion: v1
kind: PersistentVolume
metadata:
  name: my-pv
spec:
  capacity:
    storage: 5Gi                    # 存储容量
  accessModes:
    - ReadWriteOnce                 # 单节点读写
  storageClassName: standard
  hostPath:                         # 本地目录(仅用于测试)
    path: /data/pv

10.3 创建 PVC

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-pvc
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: standard
  resources:
    requests:
      storage: 5Gi                  # 请求 5GB 存储

10.4 在 Pod 中使用 PVC

apiVersion: v1
kind: Pod
metadata:
  name: data-pod
spec:
  containers:
    - name: app
      image: nginx:1.25
      volumeMounts:
        - name: data-volume
          mountPath: /usr/share/nginx/html
  volumes:
    - name: data-volume
      persistentVolumeClaim:
        claimName: my-pvc           # 引用 PVC

10.5 动态存储供给

在云环境中,可以通过 StorageClass 实现自动创建 PV:

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: fast-storage
provisioner: kubernetes.io/aws-ebs   # AWS EBS 示例
parameters:
  type: gp3
  fsType: ext4
reclaimPolicy: Retain
volumeBindingMode: WaitForFirstConsumer

使用动态存储的 PVC:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: dynamic-pvc
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: fast-storage     # 引用 StorageClass
  resources:
    requests:
      storage: 20Gi

11. HPA:水平自动伸缩

11.1 什么是 HPA?

HPA(Horizontal Pod Autoscaler) 根据 CPU、内存或自定义指标自动调整 Pod 副本数量。

工作流程:

指标监控 → 与目标值比较 → 调整副本数 → 等待冷却 → 重复

11.2 前置条件

需要安装 Metrics Server

# Minikube 环境
minikube addons enable metrics-server

# 验证
kubectl top nodes
kubectl top pods

11.3 创建 HPA

方式一:命令行

kubectl autoscale deployment nginx-deployment \
  --cpu-percent=50 \
  --min=2 \
  --max=10

方式二:YAML 文件

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: nginx-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: nginx-deployment
  minReplicas: 2                    # 最少 2 个副本
  maxReplicas: 10                   # 最多 10 个副本
  metrics:
    # 基于 CPU 使用率
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 50    # 目标:平均 CPU 使用率 50%
    # 基于内存使用率
    - type: Resource
      resource:
        name: memory
        target:
          type: Utilization
          averageUtilization: 70    # 目标:平均内存使用率 70%
  behavior:
    scaleUp:
      stabilizationWindowSeconds: 60
      policies:
        - type: Pods
          value: 4
          periodSeconds: 60
    scaleDown:
      stabilizationWindowSeconds: 300
      policies:
        - type: Percent
          value: 10
          periodSeconds: 60

11.4 验证 HPA

# 查看 HPA 状态
kubectl get hpa

# 详细信息
kubectl describe hpa nginx-hpa

# 生成负载测试(另开终端)
kubectl run -i --tty load-generator --rm --image=busybox:1.36 -- /bin/sh
# 在容器内执行
while true; do wget -q -O- http://nginx-service; done

12. 实战项目:部署微服务应用

12.1 项目架构

我们将部署一个简单的微服务应用,包含:

  • 前端(Frontend):Nginx 反向代理,端口 80
  • 后端 API(Backend):简单的 HTTP 服务,端口 8080
  • Redis 缓存:存储访问计数
用户请求 → Ingress → Frontend Service → Frontend Pod
                                    ↓
                            Backend Service → Backend Pod
                                    ↓
                            Redis Service → Redis Pod

12.2 第一步:创建命名空间

# namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: microservice-demo
  labels:
    project: demo

12.3 第二步:部署 Redis

# redis-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: redis
  namespace: microservice-demo
spec:
  replicas: 1
  selector:
    matchLabels:
      app: redis
  template:
    metadata:
      labels:
        app: redis
    spec:
      containers:
        - name: redis
          image: redis:7-alpine
          ports:
            - containerPort: 6379
          resources:
            requests:
              cpu: "100m"
              memory: "64Mi"
            limits:
              cpu: "200m"
              memory: "128Mi"
---
apiVersion: v1
kind: Service
metadata:
  name: redis-service
  namespace: microservice-demo
spec:
  selector:
    app: redis
  ports:
    - port: 6379
      targetPort: 6379

12.4 第三步:部署后端 API

# backend-deployment.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: backend-config
  namespace: microservice-demo
data:
  REDIS_HOST: "redis-service"
  REDIS_PORT: "6379"
  APP_PORT: "8080"
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: backend
  namespace: microservice-demo
spec:
  replicas: 2
  selector:
    matchLabels:
      app: backend
  template:
    metadata:
      labels:
        app: backend
    spec:
      containers:
        - name: backend
          image: hashicorp/http-echo:latest
          args:
            - "-text=Hello from Backend! Visit count is tracked by Redis."
            - "-listen=:8080"
          ports:
            - containerPort: 8080
          envFrom:
            - configMapRef:
                name: backend-config
          resources:
            requests:
              cpu: "100m"
              memory: "64Mi"
            limits:
              cpu: "200m"
              memory: "128Mi"
          readinessProbe:
            httpGet:
              path: /
              port: 8080
            initialDelaySeconds: 3
            periodSeconds: 5
          livenessProbe:
            httpGet:
              path: /
              port: 8080
            initialDelaySeconds: 5
            periodSeconds: 10
---
apiVersion: v1
kind: Service
metadata:
  name: backend-service
  namespace: microservice-demo
spec:
  selector:
    app: backend
  ports:
    - port: 8080
      targetPort: 8080

12.5 第四步:部署前端

# frontend-deployment.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-config
  namespace: microservice-demo
data:
  default.conf: |
    server {
        listen 80;
        server_name localhost;

        location / {
            return 200 '{"status": "ok", "service": "frontend"}';
            add_header Content-Type application/json;
        }

        location /api/ {
            proxy_pass http://backend-service:8080/;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
        }
    }
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: frontend
  namespace: microservice-demo
spec:
  replicas: 2
  selector:
    matchLabels:
      app: frontend
  template:
    metadata:
      labels:
        app: frontend
    spec:
      containers:
        - name: nginx
          image: nginx:1.25
          ports:
            - containerPort: 80
          volumeMounts:
            - name: nginx-config
              mountPath: /etc/nginx/conf.d
          resources:
            requests:
              cpu: "100m"
              memory: "64Mi"
            limits:
              cpu: "200m"
              memory: "128Mi"
      volumes:
        - name: nginx-config
          configMap:
            name: nginx-config
---
apiVersion: v1
kind: Service
metadata:
  name: frontend-service
  namespace: microservice-demo
spec:
  selector:
    app: frontend
  ports:
    - port: 80
      targetPort: 80

12.6 第五步:配置 Ingress

# ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: microservice-ingress
  namespace: microservice-demo
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: nginx
  rules:
    - host: demo.local
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: frontend-service
                port:
                  number: 80
          - path: /api
            pathType: Prefix
            backend:
              service:
                name: backend-service
                port:
                  number: 8080

12.7 第六步:配置 HPA

# hpa.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: backend-hpa
  namespace: microservice-demo
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: backend
  minReplicas: 2
  maxReplicas: 8
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 60

12.8 部署整个应用

# 创建目录结构
mkdir -p k8s-microservice
cd k8s-microservice

# 将上面的 YAML 文件分别保存,然后一键部署
kubectl apply -f namespace.yaml
kubectl apply -f redis-deployment.yaml
kubectl apply -f backend-deployment.yaml
kubectl apply -f frontend-deployment.yaml
kubectl apply -f ingress.yaml
kubectl apply -f hpa.yaml

# 或者一次性部署整个目录
kubectl apply -f .

12.9 验证部署

# 查看所有资源
kubectl get all -n microservice-demo

# 查看 Pod 状态
kubectl get pods -n microservice-demo -o wide

# 查看 Service
kubectl get svc -n microservice-demo

# 查看 Ingress
kubectl get ingress -n microservice-demo

# 查看 HPA
kubectl get hpa -n microservice-demo

# 测试前端
kubectl run -it --rm test-curl --image=curlimages/curl --restart=Never -- \
  curl http://frontend-service.microservice-demo.svc.cluster.local

# 测试后端 API
kubectl run -it --rm test-curl --image=curlimages/curl --restart=Never -- \
  curl http://backend-service.microservice-demo.svc.cluster.local:8080

# Minikube 环境下通过 Ingress 访问
# 先添加 hosts 映射
echo "$(minikube ip) demo.local" | sudo tee -a /etc/hosts
curl http://demo.local
curl http://demo.local/api

12.10 清理资源

# 删除整个命名空间(会删除其中所有资源)
kubectl delete namespace microservice-demo

13. 常用命令速查表

资源查看

# 查看所有资源
kubectl get all

# 查看指定命名空间的资源
kubectl get all -n <namespace>

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

# 以 YAML 格式查看资源
kubectl get pod <pod-name> -o yaml

# 以 JSON 格式查看
kubectl get pod <pod-name> -o json

# 查看资源使用情况(需要 metrics-server)
kubectl top nodes
kubectl top pods

资源操作

# 创建/更新资源
kubectl apply -f <file.yaml>

# 删除资源
kubectl delete -f <file.yaml>
kubectl delete pod <pod-name>
kubectl delete deployment <deployment-name>

# 强制删除卡住的 Pod
kubectl delete pod <pod-name> --grace-period=0 --force

调试排查

# 查看 Pod 日志
kubectl logs <pod-name>
kubectl logs <pod-name> -f              # 实时跟踪
kubectl logs <pod-name> --previous      # 查看上一个容器的日志

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

# 端口转发(本地调试)
kubectl port-forward pod/<pod-name> 8080:80
kubectl port-forward svc/<service-name> 8080:80

# 查看事件
kubectl get events --sort-by='.lastTimestamp'

配置管理

# 查看当前上下文
kubectl config current-context

# 切换上下文
kubectl config use-context <context-name>

# 查看所有上下文
kubectl config get-contexts

# 设置默认命名空间
kubectl config set-context --current --namespace=<namespace>

14. 学习路线建议

初级阶段

  1. 理解核心概念:Pod、Deployment、Service、Namespace
  2. 掌握基本操作:kubectl 的常用命令
  3. 本地实践:用 Minikube 搭建环境,跟着教程动手

中级阶段

  1. 配置管理:ConfigMap、Secret、环境变量
  2. 存储管理:PV、PVC、StorageClass
  3. 网络管理:Ingress、NetworkPolicy
  4. 自动伸缩:HPA、VPA
  5. 安全基础:RBAC、ServiceAccount

高级阶段

  1. Helm:K8s 包管理工具
  2. Operator 模式:自定义控制器
  3. 服务网格:Istio、Linkerd
  4. CI/CD 集成:GitOps(ArgoCD、Flux)
  5. 监控告警:Prometheus + Grafana

推荐学习资源

  • 官方文档:https://kubernetes.io/zh/docs/
  • 互动教程:https://kubernetes.io/zh/docs/tutorials/
  • Katacoda 替代:https://killercoda.com/playgrounds/scenario/kubernetes
  • kubectl 速查:https://kubernetes.io/zh/docs/reference/kubectl/cheatsheet/

总结

本教程涵盖了 Kubernetes 的核心知识体系:

知识点 核心作用
Pod 最小调度单元,运行容器
Deployment 管理副本,滚动更新,自愈
Service 服务发现,负载均衡
Namespace 资源隔离
ConfigMap/Secret 配置与敏感数据管理
Ingress 七层流量入口
PV/PVC 持久化存储
HPA 自动水平伸缩

最重要的建议:K8s 是实践性很强的技术,光看文档远远不够。一定要动手操作,从 Minikube 开始,逐步构建自己的实验环境。遇到问题时,kubectl describekubectl logs 是你最好的调试伙伴。

祝你学习愉快!🚀

内容声明

本文内容为AI技术学习教程,仅供学习参考。如涉及技术问题,欢迎通过 xurj005@163.com 与我们交流。

目录