云原生新手入门完整学习指南

学习路径概览

本指南按照从简单到复杂的路径设计,让您从Docker基础开始,逐步掌握Kubernetes和CI/CD,最终具备生产环境云原生应用部署能力。

复制代码
第一步: Docker基础 → 第二步: K8s体验 → 第三步: CI/CD → 第四步: K8s进阶
 (1-2周)        (1-2周)        (2-3周)     (3-4周)

第一步:掌握Docker (1-2周)

目标

  • 熟练使用Docker基本命令
  • 能够将Spring Boot应用打包成镜像
  • 理解容器化的核心概念

1.1 环境准备

Docker安装(Ubuntu为例)
复制代码
# 更新包管理器
sudo apt update

# 安装Docker
sudo apt install docker.io

# 启动Docker服务
sudo systemctl start docker
sudo systemctl enable docker

# 将用户添加到docker组
sudo usermod -aG docker $USER
newgrp docker

# 验证安装
docker --version
docker run hello-world
Java环境准备
复制代码
# 安装OpenJDK 11
sudo apt install openjdk-11-jdk

# 安装Maven
sudo apt install maven

# 验证安装
java --version
mvn --version

1.2 创建Spring Boot示例应用

项目结构
复制代码
spring-boot-demo/
├── pom.xml
├── src/
│   └── main/
│       └── java/
│           └── com/
│               └── example/
│                   └── demo/
│                       ├── DemoApplication.java
│                       └── controller/
│                           └── HelloController.java
└── Dockerfile
pom.xml
复制代码
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
         http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    
    <groupId>com.example</groupId>
    <artifactId>spring-boot-demo</artifactId>
    <version>1.0.0</version>
    <packaging>jar</packaging>
    
    <name>spring-boot-demo</name>
    <description>Demo project for Spring Boot</description>
    
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.0</version>
        <relativePath/>
    </parent>
    
    <properties>
        <java.version>11</java.version>
    </properties>
    
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>
    
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>
DemoApplication.java
复制代码
package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}
HelloController.java
复制代码
package com.example.demo.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {
    
    @GetMapping("/")
    public String hello() {
        return "Hello, Cloud Native World!";
    }
    
    @GetMapping("/health")
    public String health() {
        return "OK";
    }
    
    @GetMapping("/info")
    public String info() {
        return "Spring Boot Demo v1.0.0";
    }
}

1.3 创建Dockerfile

Dockerfile (多阶段构建)
复制代码
# 第一阶段:构建应用
FROM maven:3.8.5-openjdk-11 AS builder

WORKDIR /app
COPY pom.xml .
# 下载依赖(利用Docker缓存)
RUN mvn dependency:go-offline -B

COPY src ./src
# 构建应用
RUN mvn package -DskipTests

# 第二阶段:运行应用
FROM openjdk:11-jre-slim

# 创建非root用户
RUN addgroup --system app && adduser --system --group app

# 设置工作目录
WORKDIR /app

# 从构建阶段复制jar文件
COPY --from=builder /app/target/*.jar app.jar

# 更改文件所有者
RUN chown app:app app.jar

# 切换到非root用户
USER app

# 暴露端口
EXPOSE 8080

# 健康检查
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
  CMD curl -f http://localhost:8080/health || exit 1

# 启动命令
ENTRYPOINT ["java", "-jar", "app.jar"]

1.4 Docker核心命令实践

构建镜像
复制代码
# 进入项目目录
cd spring-boot-demo

# 构建镜像
docker build -t spring-boot-demo:1.0.0 .
docker build -t spring-boot-demo:latest .

# 查看构建的镜像
docker images

# 查看镜像详细信息
docker inspect spring-boot-demo:latest

# 查看镜像构建历史
docker history spring-boot-demo:latest
运行容器
复制代码
# 基本运行
docker run -p 8080:8080 spring-boot-demo:latest

# 后台运行
docker run -d -p 8080:8080 --name demo-app spring-boot-demo:latest

# 测试应用
curl http://localhost:8080/
curl http://localhost:8080/health
curl http://localhost:8080/info

# 查看容器
docker ps
docker ps -a

# 查看容器日志
docker logs demo-app
docker logs -f demo-app  # 实时查看

# 进入容器
docker exec -it demo-app bash

# 查看容器资源使用
docker stats demo-app
容器管理
复制代码
# 停止容器
docker stop demo-app

# 启动容器
docker start demo-app

# 重启容器
docker restart demo-app

# 删除容器
docker rm demo-app

# 删除镜像
docker rmi spring-boot-demo:latest

1.5 第一步总结与练习

必掌握技能检查单
  • \] 能独立编写Dockerfile

  • \] 熟练使用docker run命令及常用参数

  • \] 理解镜像分层和缓存机制

  1. 修改HelloController,添加一个返回当前时间的API
  2. 重新构建镜像,使用新的版本标签
  3. 同时运行多个容器实例,映射到不同端口

第二步:体验托管K8s (1-2周)

目标

  • 体验Kubernetes托管服务
  • 掌握kubectl基本操作
  • 理解Pod、Service等基础概念

2.1 选择云服务商

阿里云容器服务ACK
复制代码
# 1. 登录阿里云控制台
# 2. 搜索"容器服务Kubernetes版"
# 3. 点击"免费试用"
# 4. 创建托管版集群(选择最小规格节省费用)
腾讯云TKE
复制代码
# 1. 登录腾讯云控制台
# 2. 搜索"容器服务TKE"
# 3. 点击"免费试用"
# 4. 创建托管集群

2.2 kubectl安装和配置

Linux安装kubectl
复制代码
# 下载最新版本
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"

# 安装kubectl
sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl

# 验证安装
kubectl version --client
配置访问凭证
复制代码
# 从云服务商控制台下载kubeconfig文件
# 通常保存在 ~/.kube/config

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

2.3 推送镜像到镜像仓库

使用阿里云容器镜像服务
复制代码
# 1. 在阿里云控制台创建容器镜像服务命名空间
# 2. 创建镜像仓库

# 登录阿里云镜像仓库
docker login --username=your-username registry.cn-hangzhou.aliyuncs.com

# 给镜像打标签
docker tag spring-boot-demo:latest registry.cn-hangzhou.aliyuncs.com/your-namespace/spring-boot-demo:latest

# 推送镜像
docker push registry.cn-hangzhou.aliyuncs.com/your-namespace/spring-boot-demo:latest
使用Docker Hub
复制代码
# 登录Docker Hub
docker login

# 给镜像打标签
docker tag spring-boot-demo:latest your-dockerhub-username/spring-boot-demo:latest

# 推送镜像
docker push your-dockerhub-username/spring-boot-demo:latest

2.4 通过控制台部署应用

控制台操作步骤
  1. 进入K8s集群控制台
  2. 选择"工作负载" -> "无状态"
  3. 点击"使用镜像创建"
  4. 配置如下参数:
    • 应用名称:spring-boot-demo
    • 镜像:your-registry/spring-boot-demo:latest
    • 端口:8080
    • 副本数:2

2.5 kubectl基本操作实践

查看资源
复制代码
# 查看所有命名空间
kubectl get namespaces

# 查看Pod
kubectl get pods
kubectl get pods -o wide
kubectl get pods -n kube-system

# 查看部署
kubectl get deployments
kubectl get deploy

# 查看服务
kubectl get services
kubectl get svc

# 查看所有资源
kubectl get all
查看详细信息
复制代码
# 描述Pod详细信息
kubectl describe pod <pod-name>

# 描述部署详细信息
kubectl describe deployment spring-boot-demo

# 查看Pod日志
kubectl logs <pod-name>
kubectl logs -f <pod-name>  # 实时查看
kubectl logs <pod-name> -c <container-name>  # 多容器情况
Pod操作
复制代码
# 进入Pod
kubectl exec -it <pod-name> -- bash
kubectl exec -it <pod-name> -- sh

# 在Pod中执行命令
kubectl exec <pod-name> -- ls /app
kubectl exec <pod-name> -- curl http://localhost:8080/health

# 端口转发
kubectl port-forward <pod-name> 8080:8080
kubectl port-forward service/spring-boot-demo 8080:8080

2.6 YAML配置文件部署

deployment.yaml
复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  name: spring-boot-demo
  labels:
    app: spring-boot-demo
spec:
  replicas: 2
  selector:
    matchLabels:
      app: spring-boot-demo
  template:
    metadata:
      labels:
        app: spring-boot-demo
    spec:
      containers:
      - name: spring-boot-demo
        image: registry.cn-hangzhou.aliyuncs.com/your-namespace/spring-boot-demo:latest
        ports:
        - containerPort: 8080
        env:
        - name: JAVA_OPTS
          value: "-Xmx512m -Xms256m"
        livenessProbe:
          httpGet:
            path: /health
            port: 8080
          initialDelaySeconds: 30
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /health
            port: 8080
          initialDelaySeconds: 5
          periodSeconds: 5
        resources:
          limits:
            cpu: 500m
            memory: 512Mi
          requests:
            cpu: 200m
            memory: 256Mi
service.yaml
复制代码
apiVersion: v1
kind: Service
metadata:
  name: spring-boot-demo-service
spec:
  selector:
    app: spring-boot-demo
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080
  type: LoadBalancer  # 或者 ClusterIP, NodePort
使用YAML部署
复制代码
# 部署应用
kubectl apply -f deployment.yaml
kubectl apply -f service.yaml

# 或者一次性部署
kubectl apply -f deployment.yaml -f service.yaml

# 查看部署状态
kubectl rollout status deployment/spring-boot-demo

# 获取服务访问地址
kubectl get service spring-boot-demo-service

2.7 第二步总结与练习

必掌握技能检查单
  • \] 能使用kubectl连接到K8s集群

  • \] 理解Pod、Deployment、Service的基本概念

练习作业
  1. 尝试扩容和缩容应用副本数
  2. 修改应用配置,体验滚动更新
  3. 使用不同的Service类型访问应用

第三步:搭建简易CI/CD (2-3周)

目标

  • 搭建GitLab和Jenkins环境
  • 实现代码提交自动触发构建
  • 完成自动部署到K8s的完整流程

3.1 环境准备

使用Docker搭建GitLab
复制代码
# 创建GitLab目录
mkdir -p /opt/gitlab/{config,logs,data}

# 运行GitLab容器
docker run -d \
  --hostname gitlab.example.com \
  -p 80:80 -p 443:443 -p 22:22 \
  --name gitlab \
  --restart always \
  -v /opt/gitlab/config:/etc/gitlab \
  -v /opt/gitlab/logs:/var/log/gitlab \
  -v /opt/gitlab/data:/var/opt/gitlab \
  --shm-size 256m \
  gitlab/gitlab-ce:latest

# 查看初始密码
docker exec -it gitlab grep 'Password:' /etc/gitlab/initial_root_password
使用Docker搭建Jenkins
复制代码
# 创建Jenkins数据目录
mkdir -p /opt/jenkins_home
sudo chown -R 1000:1000 /opt/jenkins_home

# 运行Jenkins容器
docker run -d \
  -p 8080:8080 -p 50000:50000 \
  --name jenkins \
  --restart always \
  -v /opt/jenkins_home:/var/jenkins_home \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v /usr/bin/docker:/usr/bin/docker \
  jenkins/jenkins:lts

# 获取初始管理员密码
docker exec jenkins cat /var/jenkins_home/secrets/initialAdminPassword

3.2 GitLab配置

创建项目
  1. 访问 http://localhost (GitLab)

  2. 使用root账户登录

  3. 创建新项目:spring-boot-demo

  4. 上传代码到GitLab仓库

    配置Git(如果未配置)

    git config --global user.name "Your Name"
    git config --global user.email "your.email@example.com"

    初始化本地仓库

    cd spring-boot-demo
    git init
    git add .
    git commit -m "Initial commit"

    关联远程仓库

    git remote add origin http://localhost/root/spring-boot-demo.git
    git push -u origin master

创建GitLab CI配置
复制代码
# .gitlab-ci.yml
stages:
  - build
  - test
  - deploy

variables:
  IMAGE_NAME: "registry.cn-hangzhou.aliyuncs.com/your-namespace/spring-boot-demo"
  IMAGE_TAG: "$CI_COMMIT_SHORT_SHA"

build:
  stage: build
  image: maven:3.8.5-openjdk-11
  services:
    - docker:dind
  variables:
    DOCKER_HOST: tcp://docker:2375
    DOCKER_DRIVER: overlay2
    DOCKER_TLS_CERTDIR: ""
  before_script:
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
  script:
    - mvn clean package -DskipTests
    - docker build -t $IMAGE_NAME:$IMAGE_TAG .
    - docker build -t $IMAGE_NAME:latest .
    - docker push $IMAGE_NAME:$IMAGE_TAG
    - docker push $IMAGE_NAME:latest
  artifacts:
    paths:
      - target/*.jar
    expire_in: 1 hour

test:
  stage: test
  image: maven:3.8.5-openjdk-11
  script:
    - mvn test
  dependencies:
    - build

deploy:
  stage: deploy
  image: bitnami/kubectl:latest
  script:
    - echo $KUBECONFIG | base64 -d > /tmp/kubeconfig
    - export KUBECONFIG=/tmp/kubeconfig
    - kubectl set image deployment/spring-boot-demo spring-boot-demo=$IMAGE_NAME:$IMAGE_TAG
    - kubectl rollout status deployment/spring-boot-demo
  only:
    - master

3.3 Jenkins配置

安装必需插件
  1. 访问 http://localhost:8080 (Jenkins)
  2. 安装建议的插件
  3. 额外安装以下插件:
    • Git Plugin
    • Docker Plugin
    • Kubernetes Plugin
    • Pipeline Plugin
创建Pipeline任务
  1. 新建Item -> Pipeline

  2. 配置Git仓库地址

  3. 创建Jenkinsfile

    // Jenkinsfile
    pipeline {
    agent any

    复制代码
     environment {
         DOCKER_REGISTRY = 'registry.cn-hangzhou.aliyuncs.com'
         IMAGE_NAME = 'your-namespace/spring-boot-demo'
         KUBECONFIG_CREDENTIAL = 'kubeconfig'
     }
     
     stages {
         stage('Checkout') {
             steps {
                 checkout scm
             }
         }
         
         stage('Build') {
             steps {
                 sh 'mvn clean package -DskipTests'
             }
         }
         
         stage('Test') {
             steps {
                 sh 'mvn test'
             }
             post {
                 always {
                     junit 'target/surefire-reports/*.xml'
                 }
             }
         }
         
         stage('Docker Build') {
             steps {
                 script {
                     def imageTag = "${env.BUILD_NUMBER}-${env.GIT_COMMIT[0..7]}"
                     def image = docker.build("${DOCKER_REGISTRY}/${IMAGE_NAME}:${imageTag}")
                     
                     docker.withRegistry("https://${DOCKER_REGISTRY}", 'docker-registry-credential') {
                         image.push()
                         image.push('latest')
                     }
                     
                     env.IMAGE_TAG = imageTag
                 }
             }
         }
         
         stage('Deploy to K8s') {
             steps {
                 withKubeConfig([credentialsId: KUBECONFIG_CREDENTIAL]) {
                     sh """
                         kubectl set image deployment/spring-boot-demo \
                             spring-boot-demo=${DOCKER_REGISTRY}/${IMAGE_NAME}:${env.IMAGE_TAG}
                         kubectl rollout status deployment/spring-boot-demo
                     """
                 }
             }
         }
     }
     
     post {
         always {
             cleanWs()
         }
         success {
             echo 'Pipeline succeeded!'
         }
         failure {
             echo 'Pipeline failed!'
         }
     }

    }

3.4 完整部署YAML文件

k8s/namespace.yaml
复制代码
apiVersion: v1
kind: Namespace
metadata:
  name: demo
k8s/deployment.yaml
复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  name: spring-boot-demo
  namespace: demo
  labels:
    app: spring-boot-demo
    version: v1
spec:
  replicas: 3
  selector:
    matchLabels:
      app: spring-boot-demo
  template:
    metadata:
      labels:
        app: spring-boot-demo
        version: v1
    spec:
      containers:
      - name: spring-boot-demo
        image: registry.cn-hangzhou.aliyuncs.com/your-namespace/spring-boot-demo:latest
        imagePullPolicy: Always
        ports:
        - containerPort: 8080
          name: http
        env:
        - name: JAVA_OPTS
          value: "-Xmx512m -Xms256m -Dspring.profiles.active=prod"
        - name: TZ
          value: "Asia/Shanghai"
        livenessProbe:
          httpGet:
            path: /health
            port: 8080
          initialDelaySeconds: 60
          periodSeconds: 10
          timeoutSeconds: 5
          failureThreshold: 3
        readinessProbe:
          httpGet:
            path: /health
            port: 8080
          initialDelaySeconds: 10
          periodSeconds: 5
          timeoutSeconds: 3
          failureThreshold: 3
        resources:
          limits:
            cpu: 1000m
            memory: 1Gi
          requests:
            cpu: 500m
            memory: 512Mi
      imagePullSecrets:
      - name: registry-secret
k8s/service.yaml
复制代码
apiVersion: v1
kind: Service
metadata:
  name: spring-boot-demo-service
  namespace: demo
  labels:
    app: spring-boot-demo
spec:
  type: ClusterIP
  ports:
  - port: 80
    targetPort: 8080
    name: http
  selector:
    app: spring-boot-demo
k8s/ingress.yaml
复制代码
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: spring-boot-demo-ingress
  namespace: demo
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
    nginx.ingress.kubernetes.io/ssl-redirect: "false"
spec:
  rules:
  - host: demo.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: spring-boot-demo-service
            port:
              number: 80

3.5 自动化部署脚本

deploy.sh
复制代码
#!/bin/bash

set -e

# 配置变量
NAMESPACE="demo"
APP_NAME="spring-boot-demo"
IMAGE_TAG=${1:-latest}

echo "Deploying $APP_NAME with image tag: $IMAGE_TAG"

# 创建命名空间(如果不存在)
kubectl create namespace $NAMESPACE --dry-run=client -o yaml | kubectl apply -f -

# 部署应用
kubectl apply -f k8s/

# 更新镜像
kubectl set image deployment/$APP_NAME \
    $APP_NAME=registry.cn-hangzhou.aliyuncs.com/your-namespace/$APP_NAME:$IMAGE_TAG \
    -n $NAMESPACE

# 等待部署完成
kubectl rollout status deployment/$APP_NAME -n $NAMESPACE

# 获取服务信息
echo "Deployment completed successfully!"
kubectl get pods -n $NAMESPACE
kubectl get svc -n $NAMESPACE

3.6 第三步总结与练习

必掌握技能检查单
  • \] 能搭建GitLab和Jenkins环境

  • \] 能编写Jenkinsfile或.gitlab-ci.yml

练习作业
  1. 添加代码质量检查阶段(如SonarQube)
  2. 实现多环境部署(开发、测试、生产)
  3. 添加部署失败自动回滚功能

第四步:深入学习K8s核心概念 (3-4周)

目标

  • 掌握K8s核心资源对象
  • 理解声明式API理念
  • 具备生产环境K8s应用管理能力

4.1 核心概念深入理解

声明式API理念
复制代码
# 传统命令式
kubectl run nginx --image=nginx --port=80
kubectl expose deployment nginx --type=LoadBalancer

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

4.2 Deployment深入学习

高级Deployment配置
复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  name: spring-boot-demo
  namespace: production
  labels:
    app: spring-boot-demo
    tier: backend
    version: v2
spec:
  # 副本数量
  replicas: 5
  
  # 选择器
  selector:
    matchLabels:
      app: spring-boot-demo
      tier: backend
  
  # 更新策略
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1      # 更新时最多不可用的Pod数量
      maxSurge: 2            # 更新时最多超出期望副本数的Pod数量
  
  # 修订历史限制
  revisionHistoryLimit: 10
  
  # 进度截止时间
  progressDeadlineSeconds: 600
  
  # Pod模板
  template:
    metadata:
      labels:
        app: spring-boot-demo
        tier: backend
        version: v2
      annotations:
        prometheus.io/scrape: "true"
        prometheus.io/port: "8080"
        prometheus.io/path: "/actuator/prometheus"
    spec:
      # 优雅停止时间
      terminationGracePeriodSeconds: 30
      
      # 重启策略
      restartPolicy: Always
      
      # 调度相关
      affinity:
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 100
            podAffinityTerm:
              labelSelector:
                matchExpressions:
                - key: app
                  operator: In
                  values:
                  - spring-boot-demo
              topologyKey: kubernetes.io/hostname
      
      containers:
      - name: spring-boot-demo
        image: registry.cn-hangzhou.aliyuncs.com/your-namespace/spring-boot-demo:v2.0.0
        imagePullPolicy: Always
        
        ports:
        - name: http
          containerPort: 8080
          protocol: TCP
        - name: management
          containerPort: 8081
          protocol: TCP
        
        # 环境变量
        env:
        - name: JAVA_OPTS
          value: "-Xmx1g -Xms512m -Dspring.profiles.active=prod"
        - name: SERVER_PORT
          value: "8080"
        - name: MANAGEMENT_SERVER_PORT
          value: "8081"
        
        # 资源限制
        resources:
          limits:
            cpu: 2000m
            memory: 2Gi
            ephemeral-storage: 1Gi
          requests:
            cpu: 1000m
            memory: 1Gi
            ephemeral-storage: 500Mi
        
        # 健康检查
        livenessProbe:
          httpGet:
            path: /actuator/health/liveness
            port: 8081
          initialDelaySeconds: 90
          periodSeconds: 10
          timeoutSeconds: 5
          failureThreshold: 3
          successThreshold: 1
        
        readinessProbe:
          httpGet:
            path: /actuator/health/readiness
            port: 8081
          initialDelaySeconds: 30
          periodSeconds: 5
          timeoutSeconds: 3
          failureThreshold: 3
          successThreshold: 1
        
        # 启动探针
        startupProbe:
          httpGet:
            path: /actuator/health
            port: 8081
          initialDelaySeconds: 20
          periodSeconds: 10
          timeoutSeconds: 5
          failureThreshold: 30
        
        # 安全上下文
        securityContext:
          allowPrivilegeEscalation: false
          runAsNonRoot: true
          runAsUser: 1000
          runAsGroup: 1000
          readOnlyRootFilesystem: true
          capabilities:
            drop:
            - ALL
        
        # 挂载卷
        volumeMounts:
        - name: tmp
          mountPath: /tmp
        - name: app-config
          mountPath: /app/config
          readOnly: true
        - name: app-logs
          mountPath: /app/logs
      
      # 定义卷
      volumes:
      - name: tmp
        emptyDir: {}
      - name: app-config
        configMap:
          name: spring-boot-demo-config
      - name: app-logs
        emptyDir: {}
      
      # 镜像拉取密钥
      imagePullSecrets:
      - name: registry-secret
Deployment管理命令
复制代码
# 部署应用
kubectl apply -f deployment.yaml

# 查看部署状态
kubectl get deployments -n demo
kubectl describe deployment spring-boot-demo -n demo

# 查看副本集
kubectl get replicasets -n demo
kubectl get rs -n demo

# 扩容缩容
kubectl scale deployment spring-boot-demo --replicas=5 -n demo

# 滚动更新
kubectl set image deployment/spring-boot-demo \
    spring-boot-demo=registry.cn-hangzhou.aliyuncs.com/your-namespace/spring-boot-demo:v2.1.0 \
    -n demo

# 查看更新状态
kubectl rollout status deployment/spring-boot-demo -n demo

# 查看更新历史
kubectl rollout history deployment/spring-boot-demo -n demo

# 回滚
kubectl rollout undo deployment/spring-boot-demo -n demo
kubectl rollout undo deployment/spring-boot-demo --to-revision=2 -n demo

# 暂停和恢复更新
kubectl rollout pause deployment/spring-boot-demo -n demo
kubectl rollout resume deployment/spring-boot-demo -n demo

4.3 Service深入学习

ClusterIP Service
复制代码
apiVersion: v1
kind: Service
metadata:
  name: spring-boot-demo-clusterip
  namespace: demo
  labels:
    app: spring-boot-demo
spec:
  type: ClusterIP
  selector:
    app: spring-boot-demo
  ports:
  - name: http
    port: 80
    targetPort: 8080
    protocol: TCP
  - name: management
    port: 8081
    targetPort: 8081
    protocol: TCP
NodePort Service
复制代码
apiVersion: v1
kind: Service
metadata:
  name: spring-boot-demo-nodeport
  namespace: demo
spec:
  type: NodePort
  selector:
    app: spring-boot-demo
  ports:
  - name: http
    port: 80
    targetPort: 8080
    nodePort: 30080
    protocol: TCP
LoadBalancer Service
复制代码
apiVersion: v1
kind: Service
metadata:
  name: spring-boot-demo-lb
  namespace: demo
  annotations:
    service.beta.kubernetes.io/aws-load-balancer-type: nlb
    service.beta.kubernetes.io/alicloud-loadbalancer-spec: slb.s1.small
spec:
  type: LoadBalancer
  selector:
    app: spring-boot-demo
  ports:
  - name: http
    port: 80
    targetPort: 8080
  externalTrafficPolicy: Local
Headless Service
复制代码
apiVersion: v1
kind: Service
metadata:
  name: spring-boot-demo-headless
  namespace: demo
spec:
  clusterIP: None
  selector:
    app: spring-boot-demo
  ports:
  - name: http
    port: 8080
    targetPort: 8080

4.4 Ingress配置

Nginx Ingress Controller
复制代码
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: spring-boot-demo-ingress
  namespace: demo
  annotations:
    kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/rewrite-target: /
    nginx.ingress.kubernetes.io/ssl-redirect: "false"
    nginx.ingress.kubernetes.io/use-regex: "true"
    nginx.ingress.kubernetes.io/proxy-body-size: "10m"
    nginx.ingress.kubernetes.io/proxy-connect-timeout: "60"
    nginx.ingress.kubernetes.io/proxy-send-timeout: "60"
    nginx.ingress.kubernetes.io/proxy-read-timeout: "60"
    # 限流配置
    nginx.ingress.kubernetes.io/rate-limit: "100"
    nginx.ingress.kubernetes.io/rate-limit-window: "1m"
spec:
  tls:
  - hosts:
    - demo.example.com
    secretName: demo-tls
  rules:
  - host: demo.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: spring-boot-demo-service
            port:
              number: 80
      - path: /api/v1
        pathType: Prefix
        backend:
          service:
            name: spring-boot-demo-service
            port:
              number: 80
SSL证书配置
复制代码
apiVersion: v1
kind: Secret
metadata:
  name: demo-tls
  namespace: demo
type: kubernetes.io/tls
data:
  tls.crt: LS0tLS1CRUdJTi... # base64编码的证书
  tls.key: LS0tLS1CRUdJTi... # base64编码的私钥

4.5 ConfigMap和Secret

ConfigMap示例
复制代码
apiVersion: v1
kind: ConfigMap
metadata:
  name: spring-boot-demo-config
  namespace: demo
data:
  # 属性文件格式
  application.properties: |
    server.port=8080
    management.server.port=8081
    management.endpoints.web.exposure.include=health,info,metrics,prometheus
    spring.datasource.url=jdbc:mysql://mysql-service:3306/demo
    spring.datasource.username=app_user
    logging.level.com.example=DEBUG
    
  # YAML格式
  application.yml: |
    server:
      port: 8080
    management:
      server:
        port: 8081
      endpoints:
        web:
          exposure:
            include: health,info,metrics,prometheus
    spring:
      datasource:
        url: jdbc:mysql://mysql-service:3306/demo
        username: app_user
    logging:
      level:
        com.example: DEBUG
        
  # 普通文本配置
  nginx.conf: |
    upstream backend {
        server spring-boot-demo-service:80;
    }
    server {
        listen 80;
        location / {
            proxy_pass http://backend;
        }
    }
Secret示例
复制代码
apiVersion: v1
kind: Secret
metadata:
  name: spring-boot-demo-secret
  namespace: demo
type: Opaque
data:
  # base64编码的值
  database-password: cGFzc3dvcmQxMjM=  # password123
  api-key: YWJjZGVmZ2hpams=             # abcdefghijk
  
stringData:
  # 明文值,会自动base64编码
  jwt-secret: "my-super-secret-jwt-key"
  redis-password: "redis123456"
在Pod中使用ConfigMap和Secret
复制代码
apiVersion: v1
kind: Pod
metadata:
  name: demo-pod
spec:
  containers:
  - name: app
    image: spring-boot-demo:latest
    
    # 环境变量方式
    env:
    - name: DB_PASSWORD
      valueFrom:
        secretKeyRef:
          name: spring-boot-demo-secret
          key: database-password
    - name: API_KEY
      valueFrom:
        secretKeyRef:
          name: spring-boot-demo-secret
          key: api-key
    
    # 环境变量组
    envFrom:
    - configMapRef:
        name: spring-boot-demo-config
    - secretRef:
        name: spring-boot-demo-secret
    
    # 文件挂载方式
    volumeMounts:
    - name: config-volume
      mountPath: /app/config
    - name: secret-volume
      mountPath: /app/secrets
      readOnly: true
  
  volumes:
  - name: config-volume
    configMap:
      name: spring-boot-demo-config
      items:
      - key: application.yml
        path: application.yml
  - name: secret-volume
    secret:
      secretName: spring-boot-demo-secret
      defaultMode: 0400
ConfigMap和Secret管理命令
复制代码
# 创建ConfigMap
kubectl create configmap app-config --from-file=config/
kubectl create configmap app-config --from-literal=key1=value1 --from-literal=key2=value2

# 创建Secret
kubectl create secret generic app-secret --from-file=secret-file.txt
kubectl create secret generic app-secret --from-literal=password=123456

# 查看ConfigMap和Secret
kubectl get configmaps -n demo
kubectl get secrets -n demo

# 查看详细内容
kubectl describe configmap spring-boot-demo-config -n demo
kubectl get secret spring-boot-demo-secret -o yaml -n demo

# 编辑ConfigMap
kubectl edit configmap spring-boot-demo-config -n demo

# 删除
kubectl delete configmap spring-boot-demo-config -n demo
kubectl delete secret spring-boot-demo-secret -n demo

4.6 水平自动扩缩容(HPA)

HPA配置
复制代码
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: spring-boot-demo-hpa
  namespace: demo
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: spring-boot-demo
  minReplicas: 2
  maxReplicas: 10
  metrics:
  # CPU使用率
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70
  # 内存使用率
  - type: Resource
    resource:
      name: memory
      target:
        type: Utilization
        averageUtilization: 80
  # 自定义指标(需要metrics-server)
  - type: Pods
    pods:
      metric:
        name: http_requests_per_second
      target:
        type: AverageValue
        averageValue: "100"
  
  # 扩缩容行为
  behavior:
    scaleDown:
      stabilizationWindowSeconds: 300
      policies:
      - type: Percent
        value: 50
        periodSeconds: 60
      - type: Pods
        value: 2
        periodSeconds: 60
      selectPolicy: Min
    scaleUp:
      stabilizationWindowSeconds: 60
      policies:
      - type: Percent
        value: 100
        periodSeconds: 15
      - type: Pods
        value: 4
        periodSeconds: 15
      selectPolicy: Max
HPA管理命令
复制代码
# 查看HPA状态
kubectl get hpa -n demo
kubectl describe hpa spring-boot-demo-hpa -n demo

# 手动测试扩容(压力测试)
kubectl run -i --tty load-generator --rm --image=busybox --restart=Never -- /bin/sh
# 在容器内执行
while true; do wget -q -O- http://spring-boot-demo-service.demo.svc.cluster.local/; done

# 查看扩容过程
kubectl get pods -n demo -w

4.7 数据持久化

PersistentVolume和PersistentVolumeClaim
复制代码
# PV定义
apiVersion: v1
kind: PersistentVolume
metadata:
  name: mysql-pv
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  storageClassName: standard
  hostPath:
    path: /data/mysql
---
# PVC定义
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mysql-pvc
  namespace: demo
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
  storageClassName: standard
使用动态存储
复制代码
# StorageClass定义
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: fast-ssd
provisioner: kubernetes.io/aws-ebs
parameters:
  type: gp2
  fsType: ext4
allowVolumeExpansion: true
---
# 使用StorageClass的PVC
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: app-data-pvc
  namespace: demo
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: fast-ssd
  resources:
    requests:
      storage: 20Gi
MySQL有状态应用示例
复制代码
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mysql
  namespace: demo
spec:
  serviceName: mysql
  replicas: 1
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
      - name: mysql
        image: mysql:8.0
        ports:
        - containerPort: 3306
          name: mysql
        env:
        - name: MYSQL_ROOT_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysql-secret
              key: root-password
        - name: MYSQL_DATABASE
          value: "demo"
        - name: MYSQL_USER
          value: "app_user"
        - name: MYSQL_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysql-secret
              key: user-password
        volumeMounts:
        - name: mysql-storage
          mountPath: /var/lib/mysql
        - name: mysql-config
          mountPath: /etc/mysql/conf.d
        livenessProbe:
          exec:
            command:
            - mysqladmin
            - ping
            - -h
            - localhost
          initialDelaySeconds: 30
          periodSeconds: 10
          timeoutSeconds: 5
        readinessProbe:
          exec:
            command:
            - mysql
            - -h
            - localhost
            - -u
            - root
            - -p$MYSQL_ROOT_PASSWORD
            - -e
            - "SELECT 1"
          initialDelaySeconds: 10
          periodSeconds: 5
          timeoutSeconds: 3
      volumes:
      - name: mysql-config
        configMap:
          name: mysql-config
  volumeClaimTemplates:
  - metadata:
      name: mysql-storage
    spec:
      accessModes: [ "ReadWriteOnce" ]
      storageClassName: fast-ssd
      resources:
        requests:
          storage: 20Gi

4.8 命名空间和资源配额

命名空间管理
复制代码
apiVersion: v1
kind: Namespace
metadata:
  name: production
  labels:
    environment: production
    team: backend
---
apiVersion: v1
kind: Namespace
metadata:
  name: staging
  labels:
    environment: staging
    team: backend
ResourceQuota配置
复制代码
apiVersion: v1
kind: ResourceQuota
metadata:
  name: compute-quota
  namespace: production
spec:
  hard:
    requests.cpu: "10"
    requests.memory: 20Gi
    limits.cpu: "20"
    limits.memory: 40Gi
    persistentvolumeclaims: "10"
    pods: "50"
    services: "10"
    secrets: "20"
    configmaps: "20"
LimitRange配置
复制代码
apiVersion: v1
kind: LimitRange
metadata:
  name: default-limit-range
  namespace: production
spec:
  limits:
  - default:
      cpu: 1000m
      memory: 1Gi
    defaultRequest:
      cpu: 200m
      memory: 256Mi
    type: Container
  - max:
      cpu: 2000m
      memory: 4Gi
    min:
      cpu: 100m
      memory: 128Mi
    type: Container

4.9 高级调度策略

节点选择器
复制代码
apiVersion: v1
kind: Pod
metadata:
  name: demo-pod
spec:
  nodeSelector:
    disktype: ssd
    zone: us-west1-a
  containers:
  - name: app
    image: spring-boot-demo:latest
节点亲和性
复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  name: spring-boot-demo
spec:
  replicas: 3
  selector:
    matchLabels:
      app: spring-boot-demo
  template:
    metadata:
      labels:
        app: spring-boot-demo
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: kubernetes.io/arch
                operator: In
                values:
                - amd64
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 100
            preference:
              matchExpressions:
              - key: disktype
                operator: In
                values:
                - ssd
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 100
            podAffinityTerm:
              labelSelector:
                matchExpressions:
                - key: app
                  operator: In
                  values:
                  - spring-boot-demo
              topologyKey: kubernetes.io/hostname
      containers:
      - name: spring-boot-demo
        image: spring-boot-demo:latest
污点和容忍
复制代码
# 给节点添加污点
kubectl taint nodes node1 key1=value1:NoSchedule

# 查看节点污点
kubectl describe node node1

# 删除污点
kubectl taint nodes node1 key1=value1:NoSchedule-

# Pod容忍配置
apiVersion: v1
kind: Pod
metadata:
  name: demo-pod
spec:
  tolerations:
  - key: "key1"
    operator: "Equal"
    value: "value1"
    effect: "NoSchedule"
  - key: "dedicated"
    operator: "Equal"
    value: "gpu"
    effect: "NoSchedule"
  containers:
  - name: app
    image: spring-boot-demo:latest

4.10 监控和可观测性

Prometheus监控配置
复制代码
apiVersion: v1
kind: ServiceMonitor
metadata:
  name: spring-boot-demo
  namespace: demo
  labels:
    app: spring-boot-demo
spec:
  selector:
    matchLabels:
      app: spring-boot-demo
  endpoints:
  - port: management
    path: /actuator/prometheus
    interval: 30s
    scrapeTimeout: 10s
日志收集配置
复制代码
apiVersion: v1
kind: ConfigMap
metadata:
  name: filebeat-config
  namespace: demo
data:
  filebeat.yml: |
    filebeat.inputs:
    - type: container
      paths:
        - /var/log/containers/*spring-boot-demo*.log
      processors:
      - add_kubernetes_metadata:
          host: ${NODE_NAME}
          matchers:
          - logs_path:
              logs_path: "/var/log/containers/"
              resource_type: "container"
    output.elasticsearch:
      hosts: ["elasticsearch:9200"]
    setup.kibana:
      host: "kibana:5601"

4.11 安全配置

RBAC配置
复制代码
# ServiceAccount
apiVersion: v1
kind: ServiceAccount
metadata:
  name: spring-boot-demo-sa
  namespace: demo
---
# Role
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: demo
  name: demo-role
rules:
- apiGroups: [""]
  resources: ["pods", "configmaps", "secrets"]
  verbs: ["get", "list", "watch"]
- apiGroups: ["apps"]
  resources: ["deployments"]
  verbs: ["get", "list", "watch", "update"]
---
# RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: demo-rolebinding
  namespace: demo
subjects:
- kind: ServiceAccount
  name: spring-boot-demo-sa
  namespace: demo
roleRef:
  kind: Role
  name: demo-role
  apiGroup: rbac.authorization.k8s.io
NetworkPolicy配置
复制代码
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: spring-boot-demo-netpol
  namespace: demo
spec:
  podSelector:
    matchLabels:
      app: spring-boot-demo
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          name: ingress-nginx
    - podSelector:
        matchLabels:
          app: nginx
    ports:
    - protocol: TCP
      port: 8080
  egress:
  - to:
    - podSelector:
        matchLabels:
          app: mysql
    ports:
    - protocol: TCP
      port: 3306
  - to: []
    ports:
    - protocol: TCP
      port: 53
    - protocol: UDP
      port: 53

4.12 完整的生产环境部署示例

kustomization.yaml
复制代码
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

resources:
- namespace.yaml
- configmap.yaml
- secret.yaml
- deployment.yaml
- service.yaml
- ingress.yaml
- hpa.yaml

images:
- name: spring-boot-demo
  newTag: v2.1.0

namespace: production

commonLabels:
  app: spring-boot-demo
  environment: production
  version: v2.1.0

replicas:
- name: spring-boot-demo
  count: 5
使用Kustomize部署
复制代码
# 查看生成的YAML
kubectl kustomize overlays/production

# 部署到生产环境
kubectl apply -k overlays/production

# 查看部署状态
kubectl get all -n production -l app=spring-boot-demo

4.13 故障排除和调试

常用调试命令
复制代码
# 查看Pod详细信息
kubectl describe pod <pod-name> -n demo

# 查看Pod日志
kubectl logs <pod-name> -n demo
kubectl logs <pod-name> -c <container-name> -n demo
kubectl logs -f <pod-name> -n demo  # 实时日志
kubectl logs --previous <pod-name> -n demo  # 查看上一次的日志

# 进入Pod调试
kubectl exec -it <pod-name> -n demo -- bash
kubectl exec -it <pod-name> -n demo -c <container-name> -- sh

# 端口转发调试
kubectl port-forward pod/<pod-name> 8080:8080 -n demo
kubectl port-forward service/spring-boot-demo-service 8080:80 -n demo

# 查看事件
kubectl get events -n demo --sort-by=.metadata.creationTimestamp
kubectl get events --field-selector involvedObject.name=<pod-name> -n demo

# 查看资源使用情况
kubectl top nodes
kubectl top pods -n demo

# 调试DNS解析
kubectl run test-pod --image=busybox --rm -it --restart=Never -- nslookup spring-boot-demo-service.demo.svc.cluster.local
常见问题排查
Pod无法启动
复制代码
# 1. 查看Pod状态
kubectl get pods -n demo

# 2. 查看Pod详细信息
kubectl describe pod <pod-name> -n demo

# 3. 常见原因和解决方法
# - ImagePullBackOff: 检查镜像地址、拉取权限
# - CrashLoopBackOff: 检查应用日志、健康检查配置
# - Pending: 检查资源限制、节点调度条件
服务无法访问
复制代码
# 1. 检查Service配置
kubectl get svc -n demo
kubectl describe svc spring-boot-demo-service -n demo

# 2. 检查EndPoints
kubectl get endpoints spring-boot-demo-service -n demo

# 3. 测试服务连通性
kubectl run test-pod --image=busybox --rm -it --restart=Never -n demo -- wget -qO- http://spring-boot-demo-service:80

4.14 最佳实践总结

资源管理最佳实践
复制代码
# 1. 始终设置资源请求和限制
resources:
  requests:
    cpu: 200m
    memory: 256Mi
  limits:
    cpu: 1000m
    memory: 1Gi

# 2. 使用合适的健康检查
livenessProbe:
  httpGet:
    path: /health
    port: 8080
  initialDelaySeconds: 60
  periodSeconds: 10

readinessProbe:
  httpGet:
    path: /ready
    port: 8080
  initialDelaySeconds: 10
  periodSeconds: 5

# 3. 设置安全上下文
securityContext:
  runAsNonRoot: true
  runAsUser: 1000
  allowPrivilegeEscalation: false
  readOnlyRootFilesystem: true
命名和标签最佳实践
复制代码
metadata:
  name: spring-boot-demo
  labels:
    app.kubernetes.io/name: spring-boot-demo
    app.kubernetes.io/instance: demo-instance
    app.kubernetes.io/version: "v2.1.0"
    app.kubernetes.io/component: backend
    app.kubernetes.io/part-of: demo-application
    app.kubernetes.io/managed-by: kustomize
    environment: production
    team: backend

4.15 学习验证和下一步

技能验证检查单
  • \] 理解K8s声明式API理念

  • \] 能配置HPA自动扩缩容

  • \] 掌握基本的故障排除技能

综合练习项目

创建一个完整的微服务应用,包含:

  1. 前端服务(Nginx + React)
  2. 后端API服务(Spring Boot)
  3. 数据库服务(MySQL)
  4. 缓存服务(Redis)
  5. 配置管理(ConfigMap/Secret)
  6. 服务发现(Service/Ingress)
  7. 自动扩缩容(HPA)
  8. 持久化存储(PVC)
进阶学习方向
  1. 服务网格:学习Istio或Linkerd
  2. 云原生存储:学习Rook、Longhorn
  3. 多集群管理:学习ArgoCD、Flux
  4. 可观测性:深入学习Prometheus、Grafana、Jaeger
  5. 安全加固:学习Falco、OPA Gatekeeper

相关推荐
木风小助理2 小时前
PostgreSQL 的范式跃迁:从关系型数据库到统一数据平台
服务器·云原生·kubernetes
阿里云云原生2 小时前
ECS 端口不通,丢包诊断看这里!阿里云 SysOM 智能诊断实战!
云原生
阿里云云原生3 小时前
从这张年度技术力量榜单里,看见阿里云从云原生到 AI 原生的进化能力和决心
云原生
阿里云云原生3 小时前
2025 智能体工程现状
云原生·llm
是一个Bug4 小时前
云原生架构
云原生·架构
BUTCHER58 小时前
【漏洞扫描】ZooKeeper 未授权访问
分布式·zookeeper·云原生
企鹅侠客9 小时前
探索Kubernetes的ServiceAccounts
云原生·容器·kubernetes
虫小宝10 小时前
电商返利APP容器编排实践:K8s在多环境部署中的资源调度优化
云原生·容器·kubernetes
Linux云计算+运维开发10 小时前
k8s集群(k8s-v1.35.0)
云原生·容器·kubernetes
Gold Steps.10 小时前
Prometheus+Grafana+Alertmanager:云原生部署的 K8s 集群监控架构方案
云原生·grafana·prometheus