一、K8s 是什么

Kubernetes 是 Google 基于内部 Borg 系统开源的容器编排平台,用于自动化部署、扩缩和管理容器化应用。简单说:Docker 解决"怎么跑一个容器",K8s 解决"怎么跑成百上千个容器"。

核心能力:服务发现、负载均衡、存储编排、自动部署回滚、自动装箱、自愈、弹性伸缩、密钥配置管理。

二、架构总览

K8s 是 Master-Worker 架构:

Control Plane(控制面)

组件职责
kube-apiserver唯一入口,所有操作都通过 REST API 经它处理
etcd分布式KV存储,保存集群所有状态数据
kube-scheduler调度器,决定 Pod 跑在哪个 Node 上
kube-controller-manager运行各种控制器(Deployment、ReplicaSet、Node等)
cloud-controller-manager对接云厂商的控制器(如华为CCE、阿里ACK集成)

Worker Node(数据面)

组件职责
kubelet节点代理,确保容器按期望状态运行
kube-proxy维护网络规则,实现 Service 的转发
Container Runtime容器运行时,主流用 containerd

三、核心概念(必懂)

1. Pod — 最小调度单元

Pod 不是容器,是一组容器的集合,共享网络和存储。一般一个 Pod 跑一个业务容器。

apiVersion: v1
kind: Pod
metadata:
  name: my-app
spec:
  containers:
  - name: app
    image: my-app:1.0
    ports:
    - containerPort: 8080

2. Deployment — 无状态应用管理

管理 ReplicaSet,实现滚动更新、回滚。你最常用的资源类型。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: spring-boot-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: spring-boot
  template:
    metadata:
      labels:
        app: spring-boot
    spec:
      containers:
      - name: app
        image: registry.cn-north-4.myhuaweicloud.com/myproject/app:v1
        ports:
        - containerPort: 8080
        resources:
          requests:
            cpu: 250m
            memory: 512Mi
          limits:
            cpu: 500m
            memory: 1Gi
        env:
        - name: SPRING_PROFILES_ACTIVE
          value: "prod"
        livenessProbe:
          httpGet:
            path: /actuator/health/liveness
            port: 8080
          initialDelaySeconds: 30
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /actuator/health/readiness
            port: 8080
          initialDelaySeconds: 10
          periodSeconds: 5

3. Service — 服务发现与负载均衡

为一组 Pod 提供稳定的访问入口。

apiVersion: v1
kind: Service
metadata:
  name: spring-boot-svc
spec:
  selector:
    app: spring-boot
  type: ClusterIP        # 集群内访问
  ports:
  - port: 80
    targetPort: 8080

Service 类型:

  • ClusterIP:集群内部访问(默认)
  • NodePort:通过节点端口暴露(30000-32767)
  • LoadBalancer:云厂商LB暴露(CCE会自动创建ELB)
  • ExternalName:CNAME映射到外部域名

4. ConfigMap & Secret — 配置管理

# ConfigMap - 普通配置
apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  application.yml: |
    server:
      port: 8080
    spring:
      datasource:
        url: jdbc:mysql://mysql-svc:3306/mydb
---
# Secret - 敏感信息
apiVersion: v1
kind: Secret
metadata:
  name: db-secret
type: Opaque
data:
  username: cm9vdA==       # base64编码
  password: cGFzc3dvcmQ=

5. Ingress — 七层路由

基于域名/路径的HTTP路由,比 Service 更灵活。

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

6. PV/PVC — 持久化存储

# PVC - 声明需要的存储
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: data-pvc
spec:
  accessModes:
  - ReadWriteOnce
  storageClassName: csi-disk     # 华为CCE用Everest CSI
  resources:
    requests:
      storage: 20Gi

7. 其他重要资源

表格

资源用途
StatefulSet有状态应用(MySQL、ZK等),稳定网络标识和持久存储
DaemonSet每个Node跑一个Pod(日志采集、监控Agent)
CronJob定时任务
HPA自动弹性伸缩
Namespace资源隔离

四、部署方式

方式一:云上托管(推荐生产用)

直接用华为CCE、阿里ACK等,控制面托管,省心。

# 以CCE为例,创建集群后在本地配置kubectl
# 下载kubeconfig
mkdir -p ~/.kube
cp kubeconfig.json ~/.kube/config

# 验证连接
kubectl cluster-info
kubectl get nodes

方式二:kubeadm 自建集群(学习/测试)

# 1. 所有节点安装 containerd + kubeadm + kubelet + kubectl
# 以CentOS为例
sudo yum install -y containerd
sudo systemctl enable --now containerd

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

# 添加K8s源
cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://pkgs.k8s.io/core:/stable:/v1.29/rpm/
enabled=1
gpgcheck=1
gpgkey=https://pkgs.k8s.io/core:/stable:/v1.29/rpm/repodata/repomd.xml.key
EOF

sudo yum install -y kubelet kubeadm kubectl
sudo systemctl enable kubelet

# 2. Master 节点初始化
sudo kubeadm init \
  --pod-network-cidr=10.244.0.0/16 \
  --kubernetes-version=v1.29.0

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

# 4. 安装网络插件(Calico)
kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.27.0/manifests/calico.yaml

# 5. Worker 节点加入集群(kubeadm init 输出的命令)
sudo kubeadm join <master-ip>:6443 \
  --token <token> \
  --discovery-token-ca-cert-hash sha256:<hash>

# 6. 验证
kubectl get nodes

方式三:Kind / Minikube(本地开发)

# Kind - 用Docker容器模拟K8s集群
go install sigs.k8s.io/kind@latest
kind create cluster --name my-cluster
kubectl cluster-info

# Minikube - 本地单节点
minikube start --driver=docker

五、日常使用(实操)

1. 部署 Spring Boot 应用完整流程

# ① 打镜像
docker build -t my-app:v1 .

# ② 推镜像(华为SWR为例)
docker tag my-app:v1 swr.cn-north-4.myhuaweicloud.com/myproject/my-app:v1
docker push swr.cn-north-4.myhuaweicloud.com/myproject/my-app:v1

# ③ 创建镜像拉取密钥
kubectl create secret docker-registry swr-secret \
  --docker-server=swr.cn-north-4.myhuaweicloud.com \
  --docker-username=cn-north-4@AKxxx \
  --docker-password=xxx

# ④ 部署应用
kubectl apply -f deployment.yaml
kubectl apply -f service.yaml
kubectl apply -f ingress.yaml

# ⑤ 查看状态
kubectl get pods -w
kubectl describe pod spring-boot-app-xxxx
kubectl logs -f spring-boot-app-xxxx

2. 滚动更新与回滚

# 更新镜像版本(触发滚动更新)
kubectl set image deployment/spring-boot-app app=my-app:v2

# 查看滚动状态
kubectl rollout status deployment/spring-boot-app

# 查看历史版本
kubectl rollout history deployment/spring-boot-app

# 回滚到上一版
kubectl rollout undo deployment/spring-boot-app

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

3. 弹性伸缩

# HPA - 基于CPU自动扩缩
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: spring-boot-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: spring-boot-app
  minReplicas: 2
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70

4. 排查问题常用命令

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

# Pod事件(为什么起不来)
kubectl describe pod <pod-name>

# 查看日志
kubectl logs <pod-name> -c <container-name>
kubectl logs <pod-name> --previous          # 上一次崩溃的日志

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

# 查看Service端点
kubectl get endpoints <svc-name>

# 查看节点资源
kubectl top nodes
kubectl top pods

# 查看事件
kubectl get events --sort-by=.metadata.creationTimestamp

# 端口转发(本地调试)
kubectl port-forward svc/spring-boot-svc 8080:80

5. 配置管理实战

# 从文件创建ConfigMap
kubectl create configmap app-config \
  --from-file=application.yml=./application-prod.yml

# 从字面量创建
kubectl create configmap app-config \
  --from-literal=SPRING_PROFILES_ACTIVE=prod \
  --from-literal=SERVER_PORT=8080

# 热更新ConfigMap(不会自动重启Pod,需手动触发)
kubectl edit configmap app-config
# 或触发滚动更新
kubectl rollout restart deployment/spring-boot-app

六、Spring Boot 适配 K8s 的几个要点

1. 健康检查

Spring Boot Actuator 天然适配 K8s 探针:

  • livenessProbe → /actuator/health/liveness
  • readinessProbe → /actuator/health/readiness

2. 优雅关闭

# application.yml
server:
  shutdown: graceful
spring:
  lifecycle:
    timeout-per-shutdown-phase: 30s

K8s 侧配置:

spec:
  terminationGracePeriodSeconds: 60
  containers:
  - name: app
    lifecycle:
      preStop:
        exec:
          command: ["/bin/sh", "-c", "sleep 15"]  # 等待Service摘除

3. 外部化配置优先级

K8s ConfigMap/Secret 挂载的配置 > 镜像内置配置,完美契合 Spring Boot 的配置覆盖机制。

内容确实很多,但核心就是 Pod → Deployment → Service → Ingress 这条主线。你日常用 K8s 部署 Spring Boot 应用,掌握这些就能覆盖 80% 的场景了。

更多推荐