当前位置:首页 > 学习笔记 > 正文内容

Kubernetes 容器编排实战完全指南:从入门到精通

Kubernetes(K8s)是当今最流行的容器编排平台,它让容器化应用的部署、扩展和管理变得简单高效。从单机Docker到大规模集群,Kubernetes重新定义了云原生应用的运行方式。本文将带你从零开始掌握K8s核心概念、架构原理和实战技能。

一、核心概念

1.1 什么是Kubernetes?

Kubernetes是Google开源的容器编排系统,源于Google内部运行十余年的Borg系统。它提供了应用部署、规划、更新、维护的一种机制,让部署容器化应用变得简单高效。

名称来源:希腊语"舵手"或"飞行员",简称K8s(K和s之间有8个字母)。

1.2 核心架构组件

Master节点(控制平面):

  • kube-apiserver:集群统一入口,所有请求都经过它
  • kube-controller-manager:控制器管理器,维护集群状态
  • kube-scheduler:调度器,决定Pod运行在哪个节点
  • etcd:分布式键值存储,保存集群所有数据

Worker节点(工作负载节点):

  • kubelet:节点代理,与Master通信,管理容器生命周期
  • kube-proxy:网络代理,维护网络规则
  • Container Runtime:容器运行时(Docker、containerd等)

1.3 核心资源对象

Pod:最小部署单元,一个或多个容器的组合。Pod内的容器共享网络和存储。

Deployment:管理Pod的副本数量和更新策略,声明式管理的典型代表。

Service:定义Pod的访问策略,提供负载均衡和服务发现。

ConfigMap/Secret:配置管理和敏感信息存储。

PV/PVC:持久化存储的抽象和管理。

二、核心内容

2.1 集群安装与配置

使用kubeadm快速搭建K8s集群是最常见的方式:

# 在所有节点安装Docker/containerd
sudo apt-get update
sudo apt-get install -y containerd

# 配置containerd
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml
sudo systemctl restart containerd

# 安装kubeadm、kubelet、kubectl
sudo apt-get install -y kubeadm kubelet kubectl
sudo systemctl enable kubelet

# 初始化Master节点
sudo kubeadm init --pod-network-cidr=10.244.0.0/16

# 配置kubectl
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

# 安装网络插件(Flannel)
kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml

2.2 部署应用实战

创建一个Nginx应用的Deployment:

# nginx-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3                    # 副本数量
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.21
        ports:
        - containerPort: 80
        resources:
          requests:              # 资源请求
            memory: "128Mi"
            cpu: "100m"
          limits:                # 资源限制
            memory: "256Mi"
            cpu: "200m"
        livenessProbe:           # 存活探针
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 10
          periodSeconds: 5
        readinessProbe:          # 就绪探针
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 5
          periodSeconds: 3

应用部署并创建Service:

# 创建Deployment
kubectl apply -f nginx-deployment.yaml

# 查看部署状态
kubectl get deployments
kubectl get pods -o wide

# 创建Service暴露服务
kubectl expose deployment nginx-deployment --type=NodePort --port=80

# 查看Service
kubectl get svc

2.3 配置管理

使用ConfigMap管理应用配置:

# configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  APP_ENV: "production"
  DATABASE_HOST: "mysql-service"
  DATABASE_PORT: "3306"
  REDIS_HOST: "redis-service"
  LOG_LEVEL: "info"
---
# 在Pod中使用ConfigMap
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
spec:
  replicas: 2
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp
        image: myapp:v1
        envFrom:                    # 从ConfigMap加载环境变量
        - configMapRef:
            name: app-config
        volumeMounts:               # 挂载配置文件
        - name: config-volume
          mountPath: /etc/config
      volumes:
      - name: config-volume
        configMap:
          name: app-config

2.4 持久化存储

使用PV和PVC管理持久化数据:

# PersistentVolume定义
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-nfs
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteMany
  nfs:
    server: 192.168.1.100
    path: "/data/pv"
---
# PersistentVolumeClaim定义
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-data
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 5Gi
---
# 在Pod中使用PVC
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysql
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mysql
  template:
    spec:
      containers:
      - name: mysql
        image: mysql:8.0
        env:
        - name: MYSQL_ROOT_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysql-secret
              key: password
        volumeMounts:
        - name: mysql-data
          mountPath: /var/lib/mysql
      volumes:
      - name: mysql-data
        persistentVolumeClaim:
          claimName: pvc-data

三、实战案例:微服务应用部署

3.1 架构概述

部署一个典型的三层微服务架构:

  • 前端:Nginx + Vue.js
  • 后端API:Python Flask/FastAPI
  • 数据库:MySQL + Redis缓存

3.2 完整部署清单

# 命名空间隔离
apiVersion: v1
kind: Namespace
metadata:
  name: microservice
---
# MySQL数据库
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysql
  namespace: microservice
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
      - name: mysql
        image: mysql:8.0
        ports:
        - containerPort: 3306
        env:
        - name: MYSQL_ROOT_PASSWORD
          valueFrom:
            secretKeyRef:
              name: app-secrets
              key: mysql-password
        - name: MYSQL_DATABASE
          value: "myapp"
        volumeMounts:
        - name: mysql-storage
          mountPath: /var/lib/mysql
      volumes:
      - name: mysql-storage
        persistentVolumeClaim:
          claimName: mysql-pvc
---
apiVersion: v1
kind: Service
metadata:
  name: mysql
  namespace: microservice
spec:
  selector:
    app: mysql
  ports:
  - port: 3306
  clusterIP: None  # Headless Service
---
# Redis缓存
apiVersion: apps/v1
kind: Deployment
metadata:
  name: redis
  namespace: microservice
spec:
  replicas: 1
  selector:
    matchLabels:
      app: redis
  template:
    spec:
      containers:
      - name: redis
        image: redis:7-alpine
        ports:
        - containerPort: 6379
---
apiVersion: v1
kind: Service
metadata:
  name: redis
  namespace: microservice
spec:
  selector:
    app: redis
  ports:
  - port: 6379
---
# 后端API服务
apiVersion: apps/v1
kind: Deployment
metadata:
  name: api
  namespace: microservice
spec:
  replicas: 3
  selector:
    matchLabels:
      app: api
  template:
    spec:
      containers:
      - name: api
        image: myapp/api:v1.0
        ports:
        - containerPort: 8000
        env:
        - name: DATABASE_URL
          value: "mysql://root:$(MYSQL_PASSWORD)@mysql:3306/myapp"
        - name: REDIS_URL
          value: "redis://redis:6379"
        livenessProbe:
          httpGet:
            path: /health
            port: 8000
          initialDelaySeconds: 30
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /ready
            port: 8000
          initialDelaySeconds: 5
          periodSeconds: 5
        resources:
          requests:
            cpu: 100m
            memory: 256Mi
          limits:
            cpu: 500m
            memory: 512Mi
---
apiVersion: v1
kind: Service
metadata:
  name: api
  namespace: microservice
spec:
  selector:
    app: api
  ports:
  - port: 8000
---
# 前端Nginx
apiVersion: apps/v1
kind: Deployment
metadata:
  name: frontend
  namespace: microservice
spec:
  replicas: 2
  selector:
    matchLabels:
      app: frontend
  template:
    spec:
      containers:
      - name: nginx
        image: myapp/frontend:v1.0
        ports:
        - containerPort: 80
        volumeMounts:
        - name: nginx-config
          mountPath: /etc/nginx/conf.d
      volumes:
      - name: nginx-config
        configMap:
          name: nginx-config
---
apiVersion: v1
kind: Service
metadata:
  name: frontend
  namespace: microservice
spec:
  selector:
    app: frontend
  ports:
  - port: 80
  type: LoadBalancer
---
# Ingress入口
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: app-ingress
  namespace: microservice
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: myapp.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: frontend
            port:
              number: 80
      - path: /api
        pathType: Prefix
        backend:
          service:
            name: api
            port:
              number: 8000

3.3 部署与验证

# 创建Secret(敏感信息)
kubectl create secret generic app-secrets \
  --from-literal=mysql-password=MySecurePass123 \
  -n microservice

# 应用所有配置
kubectl apply -f microservice-deployment.yaml

# 查看部署状态
kubectl get all -n microservice

# 查看Pod日志
kubectl logs -f deployment/api -n microservice

# 扩缩容
kubectl scale deployment api --replicas=5 -n microservice

# 滚动更新
kubectl set image deployment/api api=myapp/api:v2.0 -n microservice

# 查看更新状态
kubectl rollout status deployment/api -n microservice

# 回滚
kubectl rollout undo deployment/api -n microservice

四、进阶主题

4.1 Horizontal Pod Autoscaler(HPA)

自动根据CPU/内存使用率扩展Pod数量:

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: api-hpa
  namespace: microservice
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: api
  minReplicas: 2
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70
  - type: Resource
    resource:
      name: memory
      target:
        type: Utilization
        averageUtilization: 80

4.2 健康检查与服务网格

配置健康检查确保服务可用性:

livenessProbe:
  httpGet:
    path: /health
    port: 8000
  failureThreshold: 3
  periodSeconds: 10
readinessProbe:
  httpGet:
    path: /ready
    port: 8000
  failureThreshold: 3
  periodSeconds: 5
startupProbe:
  httpGet:
    path: /health
    port: 8000
  failureThreshold: 30
  periodSeconds: 10

总结

Kubernetes作为云原生时代的操作系统,掌握它已成为后端开发者的必备技能。本文从核心概念出发,详细讲解了集群搭建、应用部署、配置管理、持久化存储等关键知识点,并通过一个完整的微服务案例展示了实战应用。

学习建议:

  • 从单机Minikube开始,逐步过渡到多节点集群
  • 多动手实践,每个资源对象都亲自创建一遍
  • 理解声明式配置的思想,这是K8s的核心理念
  • 关注云原生生态:Helm、Istio、Prometheus等

常用命令速查:

# 集群信息
kubectl cluster-info
kubectl get nodes

# 资源操作
kubectl get pods/svc/deploy -n namespace
kubectl describe pod pod-name
kubectl logs pod-name -f

# 部署管理
kubectl apply -f manifest.yaml
kubectl delete -f manifest.yaml
kubectl edit deploy/deployment-name

# 调试
kubectl exec -it pod-name -- /bin/sh
kubectl port-forward pod-name 8080:80
kubectl cp pod-name:/path/to/file ./local-file

Kubernetes的学习曲线虽然陡峭,但一旦掌握,将极大提升你的基础设施管理能力。从Docker到Kubernetes,是从单机到集群的跨越,也是从运维手动操作到声明式自动化管理的技术飞跃。

本文链接:https://www.kkkliao.cn/?id=912 转载需授权!

分享到:

版权声明:本文由廖万里的博客发布,如需转载请注明出处。


发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。