Kubernetes (k8s) 完全入门教程

14 阅读8分钟

容器编排的工业标准,从入门到生产实践


目录

  1. 什么是 Kubernetes?
  2. 核心概念与架构
  3. 安装与环境搭建
  4. 基本操作(kubectl)
  5. Pod
  6. Deployment
  7. Service
  8. ConfigMap 与 Secret
  9. 数据持久化(PV / PVC)
  10. Ingress
  11. Namespace
  12. 实战示例:部署完整 Web 应用
  13. 常见命令速查
  14. 总结

什么是 Kubernetes?

Kubernetes(简称 k8s)是 Google 开源的容器编排平台,用于自动化部署、扩缩容和管理容器化应用。

为什么需要 Kubernetes?

单机 Docker 能运行容器,但面对生产环境的挑战:

问题Kubernetes 的解决方案
容器崩溃怎么办?自动重启(自愈)
流量激增如何扩容?水平自动扩缩(HPA)
多台服务器如何调度?智能调度器
服务间如何通信?内置 Service 发现
如何做滚动更新?零停机发布
配置和密钥如何管理?ConfigMap / Secret

核心概念与架构

集群架构

┌─────────────────────────────────────────┐
│              Kubernetes 集群             │
│                                         │
│  ┌──────────────┐   ┌────────────────┐  │
│  │  Control     │   │   Worker Node  │  │
│  │  Plane       │   │                │  │
│  │              │   │  ┌──────────┐  │  │
│  │  API Server  │   │  │  Pod     │  │  │
│  │  Scheduler   │   │  │ [容器]   │  │  │
│  │  etcd        │   │  └──────────┘  │  │
│  │  Controller  │   │                │  │
│  └──────────────┘   └────────────────┘  │
└─────────────────────────────────────────┘

核心组件

Control Plane(控制平面)

  • API Server:集群的统一入口,所有操作都通过它
  • Scheduler:决定 Pod 运行在哪个节点上
  • Controller Manager:维护集群期望状态(如保证副本数)
  • etcd:分布式键值数据库,存储集群所有状态

Worker Node(工作节点)

  • kubelet:节点代理,负责管理 Pod 生命周期
  • kube-proxy:维护网络规则,实现 Service 转发
  • Container Runtime:容器运行时(如 containerd)

核心资源对象

对象作用
Pod最小部署单元,包含一个或多个容器
Deployment管理 Pod 副本,支持滚动更新
Service为 Pod 提供稳定的网络访问入口
Ingress管理外部 HTTP/HTTPS 流量路由
ConfigMap存储非敏感配置信息
Secret存储敏感信息(密码、证书)
PersistentVolume持久化存储资源
Namespace集群内的逻辑隔离空间

安装与环境搭建

本地开发:minikube(推荐入门)

# macOS
brew install minikube

# 启动集群(单节点)
minikube start

# 查看集群状态
minikube status

# 打开 Dashboard
minikube dashboard

# 停止集群
minikube stop

本地开发:kind(用 Docker 模拟多节点)

# 安装 kind
brew install kind   # macOS
# 或
go install sigs.k8s.io/kind@latest

# 创建集群
kind create cluster --name my-cluster

# 删除集群
kind delete cluster --name my-cluster

安装 kubectl(集群管理命令行工具)

# macOS
brew install kubectl

# Linux
curl -LO "https://dl.k8s.io/release/$(curl -sL https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
chmod +x kubectl
sudo mv kubectl /usr/local/bin/

# 验证
kubectl version --client

配置集群访问

# 查看当前配置
kubectl config view

# 查看所有上下文(集群)
kubectl config get-contexts

# 切换集群
kubectl config use-context my-cluster

基本操作(kubectl)

命令结构

kubectl <动词> <资源类型> <资源名> [选项]

常用动词

kubectl get       # 查看资源
kubectl describe  # 查看详细信息
kubectl apply     # 创建或更新资源(推荐)
kubectl delete    # 删除资源
kubectl logs      # 查看容器日志
kubectl exec      # 进入容器
kubectl port-forward  # 端口转发

常用示例

# 查看节点
kubectl get nodes

# 查看所有命名空间的 Pod
kubectl get pods -A

# 查看特定命名空间
kubectl get pods -n kube-system

# 实时监听变化
kubectl get pods -w

# 查看资源详情
kubectl describe pod my-pod

# 应用 YAML 配置
kubectl apply -f deployment.yaml

# 删除资源
kubectl delete -f deployment.yaml
kubectl delete pod my-pod

Pod

Pod 是 Kubernetes 中最小的调度单元,通常包含一个主容器(有时也有 sidecar 辅助容器)。

创建 Pod(pod.yaml)

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
  labels:
    app: nginx
spec:
  containers:
    - name: nginx
      image: nginx:1.25
      ports:
        - containerPort: 80
      resources:
        requests:
          cpu: "100m"
          memory: "128Mi"
        limits:
          cpu: "500m"
          memory: "256Mi"
# 创建
kubectl apply -f pod.yaml

# 查看
kubectl get pod my-pod

# 查看日志
kubectl logs my-pod

# 进入容器
kubectl exec -it my-pod -- bash

# 端口转发(本地访问)
kubectl port-forward pod/my-pod 8080:80

⚠️ 生产中不直接使用裸 Pod,应使用 Deployment 管理。


Deployment

Deployment 是最常用的工作负载对象,负责声明式管理 Pod 副本,支持滚动更新和回滚。

deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3                    # 副本数
  selector:
    matchLabels:
      app: nginx
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1               # 更新时最多多创建 1 个 Pod
      maxUnavailable: 0         # 更新时最多 0 个 Pod 不可用
  template:                      # Pod 模板
    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

Deployment 操作

# 部署
kubectl apply -f deployment.yaml

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

# 扩缩容
kubectl scale deployment nginx-deployment --replicas=5

# 更新镜像(触发滚动更新)
kubectl set image deployment/nginx-deployment nginx=nginx:1.26

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

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

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

Service

Service 为一组 Pod 提供稳定的网络访问入口,即使 Pod IP 变化,Service IP 保持不变。

Service 类型

类型说明
ClusterIP默认,仅集群内部访问
NodePort通过节点 IP + 端口从外部访问
LoadBalancer云厂商负载均衡器(AWS/GCP/阿里云)
ExternalName映射到外部 DNS 名称

service.yaml

apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  selector:
    app: nginx           # 选择带此标签的 Pod
  type: ClusterIP
  ports:
    - protocol: TCP
      port: 80           # Service 端口
      targetPort: 80     # Pod 端口

NodePort 示例

apiVersion: v1
kind: Service
metadata:
  name: nginx-nodeport
spec:
  selector:
    app: nginx
  type: NodePort
  ports:
    - port: 80
      targetPort: 80
      nodePort: 30080    # 范围 30000-32767
kubectl apply -f service.yaml
kubectl get service nginx-service

# 本地访问(minikube)
minikube service nginx-nodeport --url

ConfigMap 与 Secret

ConfigMap(非敏感配置)

apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  APP_ENV: production
  LOG_LEVEL: info
  config.yaml: |
    server:
      port: 8080
      timeout: 30s

Secret(敏感数据)

# 命令行创建(值会自动 base64 编码)
kubectl create secret generic db-secret \
  --from-literal=username=admin \
  --from-literal=password=S3cr3t!
apiVersion: v1
kind: Secret
metadata:
  name: db-secret
type: Opaque
data:
  username: YWRtaW4=        # base64(admin)
  password: UzNjcjN0IQ==   # base64(S3cr3t!)

在 Pod 中使用

spec:
  containers:
    - name: app
      image: my-app:latest
      env:
        # 从 ConfigMap 注入环境变量
        - name: APP_ENV
          valueFrom:
            configMapKeyRef:
              name: app-config
              key: APP_ENV
        # 从 Secret 注入环境变量
        - name: DB_PASSWORD
          valueFrom:
            secretKeyRef:
              name: db-secret
              key: password
      volumeMounts:
        # 将 ConfigMap 挂载为文件
        - name: config-volume
          mountPath: /etc/config
  volumes:
    - name: config-volume
      configMap:
        name: app-config

数据持久化(PV / PVC)

概念

  • PersistentVolume (PV) :集群管理员预先创建的存储资源
  • PersistentVolumeClaim (PVC) :用户申请存储的请求
  • StorageClass:动态创建 PV 的模板

PVC 示例

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-pvc
spec:
  accessModes:
    - ReadWriteOnce        # 单节点读写
  storageClassName: standard
  resources:
    requests:
      storage: 5Gi

在 Pod 中挂载 PVC

spec:
  containers:
    - name: app
      image: my-app:latest
      volumeMounts:
        - name: data
          mountPath: /app/data
  volumes:
    - name: data
      persistentVolumeClaim:
        claimName: my-pvc
kubectl get pv
kubectl get pvc

Ingress

Ingress 管理外部 HTTP/HTTPS 流量如何路由到集群内的 Service,是生产环境暴露服务的标准方式。

安装 Ingress Controller(以 nginx 为例)

# minikube
minikube addons enable ingress

# 通用
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/cloud/deploy.yaml

ingress.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: nginx
  rules:
    - host: app.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: nginx-service
                port:
                  number: 80
          - path: /api
            pathType: Prefix
            backend:
              service:
                name: api-service
                port:
                  number: 8080
  tls:
    - hosts:
        - app.example.com
      secretName: tls-secret     # TLS 证书 Secret

Namespace

Namespace 提供集群内的逻辑隔离,适合多团队、多环境(dev/staging/prod)共用一个集群。

# 创建 namespace
kubectl create namespace dev
kubectl create namespace production

# 在指定 namespace 部署
kubectl apply -f deployment.yaml -n dev

# 查看某 namespace 下的资源
kubectl get all -n dev

# 设置默认 namespace(避免每次 -n)
kubectl config set-context --current --namespace=dev

实战示例:部署完整 Web 应用

部署一个包含前端、后端 API 和数据库的完整应用。

文件结构

k8s/
├── namespace.yaml
├── configmap.yaml
├── secret.yaml
├── postgres/
│   ├── pvc.yaml
│   ├── deployment.yaml
│   └── service.yaml
├── api/
│   ├── deployment.yaml
│   └── service.yaml
└── ingress.yaml

namespace.yaml

apiVersion: v1
kind: Namespace
metadata:
  name: myapp

postgres/pvc.yaml

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: postgres-pvc
  namespace: myapp
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi

postgres/deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: postgres
  namespace: myapp
spec:
  replicas: 1
  selector:
    matchLabels:
      app: postgres
  template:
    metadata:
      labels:
        app: postgres
    spec:
      containers:
        - name: postgres
          image: postgres:15
          env:
            - name: POSTGRES_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: db-secret
                  key: password
          volumeMounts:
            - name: data
              mountPath: /var/lib/postgresql/data
      volumes:
        - name: data
          persistentVolumeClaim:
            claimName: postgres-pvc
---
apiVersion: v1
kind: Service
metadata:
  name: postgres
  namespace: myapp
spec:
  selector:
    app: postgres
  ports:
    - port: 5432

api/deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: api
  namespace: myapp
spec:
  replicas: 2
  selector:
    matchLabels:
      app: api
  template:
    metadata:
      labels:
        app: api
    spec:
      containers:
        - name: api
          image: my-api:latest
          ports:
            - containerPort: 8080
          env:
            - name: DATABASE_URL
              value: "postgresql://postgres:5432/mydb"
            - name: DB_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: db-secret
                  key: password
---
apiVersion: v1
kind: Service
metadata:
  name: api
  namespace: myapp
spec:
  selector:
    app: api
  ports:
    - port: 8080

部署步骤

# 1. 创建命名空间
kubectl apply -f namespace.yaml

# 2. 创建 Secret
kubectl create secret generic db-secret \
  --from-literal=password=MyP@ssw0rd \
  -n myapp

# 3. 按顺序部署
kubectl apply -f postgres/
kubectl apply -f api/
kubectl apply -f ingress.yaml

# 4. 查看所有资源状态
kubectl get all -n myapp

# 5. 查看 Ingress
kubectl get ingress -n myapp

常见命令速查

# ── 查看资源 ──────────────────────────────────
kubectl get nodes
kubectl get pods -A
kubectl get deploy,svc,ingress -n myapp
kubectl get all -n myapp

# ── 调试 ──────────────────────────────────────
kubectl describe pod <pod-name> -n myapp
kubectl logs <pod-name> -n myapp
kubectl logs <pod-name> -c <container> --previous   # 查看上次崩溃日志
kubectl exec -it <pod-name> -n myapp -- bash
kubectl port-forward svc/api 8080:8080 -n myapp

# ── 更新与回滚 ─────────────────────────────────
kubectl set image deploy/api api=my-api:v2 -n myapp
kubectl rollout status deploy/api -n myapp
kubectl rollout undo deploy/api -n myapp

# ── 扩缩容 ─────────────────────────────────────
kubectl scale deploy/api --replicas=5 -n myapp

# ── 资源使用情况 ───────────────────────────────
kubectl top nodes
kubectl top pods -n myapp

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

# ── 导出当前配置 ───────────────────────────────
kubectl get deploy api -n myapp -o yaml > api-backup.yaml

总结

场景使用的资源
运行应用Deployment + Pod
内部服务通信Service (ClusterIP)
对外暴露服务Ingress / Service (LoadBalancer)
非敏感配置ConfigMap
密码/证书Secret
持久化存储PVC + PV
环境隔离Namespace

学习路线

Docker 基础
    ↓
kubectl 基本操作
    ↓
Deployment + Service
    ↓
ConfigMap / Secret / PVC
    ↓
Ingress + 多环境管理
    ↓
Helm(包管理)
    ↓
监控(Prometheus + Grafana)
    ↓
服务网格(Istio)

Happy Orchestrating! ☸️