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

学习路径概览

本指南按照从简单到复杂的路径设计,让您从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

相关推荐
AI码上来7 小时前
再见 K8s!3款开源的云原生部署工具
云原生·kubernetes·开源
大翻哥哥10 小时前
Python云原生与Serverless架构:2025年的开发新范式
python·云原生·架构·serverless
竹竿袅袅11 小时前
Kubernetes 构建高可用、高性能 Redis 集群
redis·云原生·容器·kubernetes
AKAMAI15 小时前
应用平台更新:可定制目录、基于Git的密钥管理与K8s项目自动化管理
人工智能·云原生·云计算
KellenKellenHao17 小时前
k8s三阶段项目
云原生·容器·kubernetes
Insist75319 小时前
k8s--efk日志收集
云原生·容器·kubernetes
阿里云云原生1 天前
让天下没有难查的故障:2025 阿里云 AI 原生编程挑战赛正式启动
云原生
EmiAlyx1 天前
微服务01
微服务·云原生·架构
小猿姐1 天前
KubeBlocks for Oracle 容器化之路
云原生·oracle·容器