K8s部署Java应用:从镜像构建到服务验证的完整流程(图文并茂超详细版附项目代码)

K8s部署Java应用:从镜像构建到服务验证的完整流程

环境准备:

JDK:26

IDEA:21.0.8

Docker Desktop:Docker version 29.3.1, build c2be9cc

整体架构图:

在这里插入图片描述

一、部署全流程介绍:

  1. 本地开发:你有了一个 Java 应用(Jar包)。
  2. 容器化:编写 Dockerfile,把代码打包成了镜像。
  3. 镜像仓库:注册 Docker Hub,把镜像推送到云端。
  4. K8s 编排:编写 deployment.yaml,告诉 K8s 怎么运行它。
  5. 服务暴露:通过 Service 把应用暴露给外界访问。

二、本地开发

Java项目目录结构:

项目根目录/
├── pom.xml                          # Maven 构建配置
├── Dockerfile                       # Docker 镜像构建脚本
├── target/                          # 编译输出目录(自动生成)
│   └── java-k8s-demo-1.0.0.jar    # 打包后的可执行 JAR
└── src/
    └── main/
        ├── java/
        │   └── com/javatest/
        │       └── DemoApplication.java    # Spring Boot 主类
        └── resources/
            └── application.properties      # 应用配置文件
项目代码示例:
1.pom.xml(Maven 构建配置)
<?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.javatest</groupId>
    <artifactId>java-k8s-demo</artifactId>
    <version>1.0.0</version>
    <packaging>jar</packaging>

    <name>java-k8s-demo</name>
    <description>Demo project for Spring Boot</description>

    <!-- 1. 继承 Spring Boot 父工程 -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.18</version>
        <relativePath/>
    </parent>

    <properties>
        <java.version>11</java.version> 
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    </properties>

    <dependencies>
        <!-- 2. 核心依赖:Spring Boot Web 启动器 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- 3. 测试依赖(可选) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <!-- 4. 最终打包的名字(可选) -->
        <finalName>java-k8s-demo-1.0.0</finalName>

        <plugins>
            <!-- 5. 编译插件 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>11</source> <!-- 这里要和 properties 里的 java.version 一致 -->
                    <target>11</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>

            <!-- 6. Spring Boot 核心打包插件 -->
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>2.7.18</version> <!-- 版本要和 parent 一致 -->
                <configuration>
                    <!-- 显式指定启动类,防止找不到主类 -->
                    <mainClass>com.javatest.DemoApplication</mainClass>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal> <!-- 关键:生成可执行 jar -->
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>
2.DemoApplication.java(Spring Boot 主类)
package com.javatest;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@RestController // 加上这个注解,才能直接返回文字
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

    // 当访问网页根路径时,返回这句话
    @GetMapping("/")
    public String hello() {
        return "Hello! 这是我的第一个 K8s Java 应用!";
    }
}
3.application.properties (应用配置文件)
server.port=8080

三、打包Java应用并测试

1.右键pom.xml——选择maven——添加为maven项目

在这里插入图片描述

2.在右侧maven菜单栏双击package进行打包

在这里插入图片描述

3.打包完成后会提示build success,并在target目录生成以下内容

在这里插入图片描述

4.进行本地测试

在target目录运行jar包,并在浏览器访问测试

java -jar java-k8s-demo-1.0.0.jar

在这里插入图片描述
在这里插入图片描述

本地测试访问正常,然后进行下一步。

四、容器化

K8s 不认识 Java 代码,它只认识容器镜像。需要写一个 Dockerfile 来告诉电脑怎么把你的 JAR 包变成镜像。

1.新建Dockerfile

在项目根目录(和 pom.xml 同级)新建一个文件,命名为 Dockerfile(没有后缀)。写入以下Dockerfile内容

# 使用官方 OpenJDK 基础镜像
FROM eclipse-temurin:11-jre-alpine

# 设置工作目录
WORKDIR /app

# 复制 JAR 包
COPY target/java-k8s-demo-1.0.0.jar app.jar

# 暴露端口(根据你的应用调整)
EXPOSE 8080

# 健康检查(可选)
HEALTHCHECK --interval=30s --timeout=3s --start-period=60s --retries=3 \
  CMD wget --no-verbose --tries=1 --spider http://localhost:8080/actuator/health || exit 1

# 启动命令
ENTRYPOINT ["java", "-jar", "app.jar"]
2.构建镜像

Dockerfile 所在目录打开终端(CMD/PowerShell),运行:

# -t 后面是镜像名字:版本,最后有个点代表当前目录
docker build -t my-java-app:v1 .

在这里插入图片描述

构建成功后,在 Docker Desktop 里就能看到 my-java-app 了。

3.推送镜像到镜像仓库

K8s 集群通常运行在服务器(Linux)上,它拿不到你本地电脑里的镜像。你需要一个“中转站”——镜像仓库

①注册DockerHub账号

DockerHub地址:https://hub.docker.com/ 并记住自己的用户名和密码

②创建Repositories

我们这里给仓库名字取名叫my-java-app
在这里插入图片描述

③登录仓库

在命令行输入登录命令,并在弹出的web页面进行登录

docker login

在这里插入图片描述

提示登录成功
在这里插入图片描述

④给images打标签并推送到仓库
docker tag my-java-app:v1 docker.io/hyz1127/my-java-app:v1
docker push docker.io/hyz1127/my-java-app:v1

推送成功后,可以去网页端刷新查看,现在可以看到最新推送的镜像。

在这里插入图片描述

五、部署到Kubernetes集群

1.编写部署YAML文件

编写一个deployment.yaml文件进行镜像拉取、部署以及暴露端口

# 1. Deployment: 负责管理你的 Java 应用容器
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-java-app
spec:
  replicas: 1  # 副本数,先设为1跑通流程
  selector:
    matchLabels:
      app: my-java-app
  template:
    metadata:
      labels:
        app: my-java-app
    spec:
      containers:
      - name: java-container
        # 这里填你刚才推送成功的镜像地址
        image: docker.io/hyz1127/my-java-app:v1
        ports:
        - containerPort: 8080  # 你的Java应用监听的端口
        resources:
          requests:
            memory: "256Mi"    # 申请内存
            cpu: "250m"        # 申请CPU
          limits:
            memory: "512Mi"    # 最大内存限制
            cpu: "500m"        # 最大CPU限制

---
# 2. Service: 负责把应用暴露出来,让你能访问
apiVersion: v1
kind: Service
metadata:
  name: my-java-app-service
spec:
  selector:
    app: my-java-app
  ports:
  - protocol: TCP
    port: 80           # 访问端口(外部)
    targetPort: 8080   # 容器端口(内部)
  type: NodePort       # 使用 NodePort 方便本地测试
2.执行部署

在任意k8s master节点运行

kubectl apply -f deployment.yaml

检查状态

kubectl get pods

在这里插入图片描述

如果看到状态是 Running,pod运行在node1节点上,说明应用启动成功了!

3.访问测试

获取NodePort端口,可以看到java程序运行在30109端口

kubectl get svc

在这里插入图片描述

在浏览器输入任意集群节点IP+30109,可以成功访问到我们的java项目

在这里插入图片描述

六、测试代码更新发布

1.修改代码
①修改java代码中 文字第一个→第二个

在这里插入图片描述

②修改pom.xml打包名称为1.0.1

在这里插入图片描述

③修改Dockerfile版本号为1.0.1

在这里插入图片描述

④打包新的Jar包

在这里插入图片描述

2.构建新镜像
# 这里的 v2 很重要,它代表新版本
docker build -t docker.io/hyz1127/my-java-app:v2 .
3.推送到云端docker hub镜像仓库
docker push docker.io/hyz1127/my-java-app:v2

在这里插入图片描述

等待推送完成…在DockerHub中已经可以看到有最新的V2镜像

在这里插入图片描述

4.触发K8S更新

现在镜像在云端了,我们要告诉 K8s:“别用 v1 了,换成 v2”。

①修改deployment.yaml:

打开你的配置文件,找到 image 字段,把 v1 改成 v2
在这里插入图片描述

②应用变更

kubectl apply -f deployment.yaml

现在k8s会进行滚动更新,先启动V2,再清除V1

5.验证结果

回到你的浏览器,访问你的应用地址。刷新页面!你应该能看到文字变成了:Hello! 这是我的第二个 K8s Java 应用!
在这里插入图片描述

七、将JAVA应用连接MySQL和Redis

MySQL 和 Redis配置信息如下:

组件Service 类型服务名端口作用
MySQLClusterIP(或 Headless Service: ClusterIP: None)mysql3306为 Java 应用提供稳定的内部访问地址 mysql:3306
RedisClusterIPredis6379为 Java 应用提供稳定的内部访问地址 redis:6379
1.部署MySQL
①创建部署文件mysql.yaml
apiVersion: v1
kind: Service
metadata:
  name: mysql
  labels:
    app: mysql
spec:
  ports:
    - port: 3306
      targetPort: 3306
  selector:
    app: mysql
  clusterIP: None # 使用 Headless Service,适合有状态应用
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysql
spec:
  selector:
    matchLabels:
      app: mysql
  strategy:
    type: Recreate # 确保先删旧 Pod 再建新 Pod,防止数据冲突
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
        - image: library/mysql:5.7.44
          name: mysql
          env:
            - name: MYSQL_ROOT_PASSWORD
              value: "test123" # 数据库密码
            - name: TZ
              value: "Asia/Shanghai" # 设置时区
          ports:
            - containerPort: 3306
              name: mysql
          volumeMounts:
            - name: mysql-persistent-storage
              mountPath: /var/lib/mysql # MySQL 数据目录
      volumes:
        - name: mysql-persistent-storage
          persistentVolumeClaim:
            claimName: mysql-pvc
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mysql-pvc
spec:
  accessModes:
    - ReadWriteOnce # 读写权限
  resources:
    requests:
      storage: 5Gi # 申请 5GB 空间
②应用配置
kubectl apply -f mysql.yaml

在这里插入图片描述

③测试数据库连通
 kubectl exec -it mysql-7bd48cbd97-xs7q6 -- mysql -uroot -p'test123'

在这里插入图片描述

这里我们进行创建一个数据库名为mydb

CREATE DATABASE mydb;
SHOW DATABASES;

在这里插入图片描述

④通过java-app pod中访问测试mysql pod
kubectl exec -it my-java-app-768f5c99d6-h67k8 -- sh -c 'nc -zv mysql 3306 && echo "Port open" || echo "Port closed"'

在这里插入图片描述

显示port open说明mysql网络连通正常!

2.部署Redis
①创建部署文件redis.yaml
apiVersion: v1
kind: Service
metadata:
  name: redis
  labels:
    app: redis
spec:
  ports:
    - port: 6379
      targetPort: 6379
  selector:
    app: redis
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: redis
spec:
  selector:
    matchLabels:
      app: redis
  template:
    metadata:
      labels:
        app: redis
    spec:
      containers:
        - image: library/redis:7.2.12
          name: redis
          command: ["redis-server", "--appendonly", "yes"] # 开启 AOF 持久化
          ports:
            - containerPort: 6379
              name: redis
          volumeMounts:
            - name: redis-persistent-storage
              mountPath: /data # Redis 数据目录
      volumes:
        - name: redis-persistent-storage
          persistentVolumeClaim:
            claimName: redis-pvc
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: redis-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 2Gi
②应用配置
kubectl apply -f redis.yaml

在这里插入图片描述

③通过java-app pod中访问测试redis pod
kubectl exec -it my-java-app-768f5c99d6-h67k8 -- sh -c 'nc -zv redis 6379 && echo "Port open" || echo "Port closed"'

在这里插入图片描述

3.修改项目代码并构建新镜像

我们需要修改java代码进行MySQL和Redis的连接,然后重新打包成docker images push到docker hub镜像仓库中,这里我们做一个待办事项Demo进行测试

目录结构示例:

在这里插入图片描述

修改后的代码示例:

①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.javatest</groupId>
    <artifactId>java-k8s-demo</artifactId>
    <version>1.0.0</version>
    <packaging>jar</packaging>

    <name>java-k8s-demo</name>
    <description>Demo project for Spring Boot</description>

    <!-- 1. 继承 Spring Boot 父工程 -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.18</version>
        <relativePath/>
    </parent>

    <properties>
        <java.version>11</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    </properties>

    <dependencies>
        <!-- 2. 核心依赖:Spring Boot Web 启动器 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- 3. 测试依赖(可选) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!-- 4. MySQL数据库驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.33</version>
            <scope>runtime</scope>
        </dependency>

        <!-- 5. Spring Boot JDBC(用于连接数据库) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
            <version>2.7.18</version>
        </dependency>

        <!-- 6. Spring Boot Redis 支持 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
            <version>2.7.18</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
    </dependencies>

    <build>
        <finalName>java-k8s-demo-2.0.0</finalName>


        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.11.0</version>
                <configuration>
                    <source>11</source>
                    <target>11</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>2.7.18</version>
                <configuration>
                    <mainClass>com.javatest.DemoApplication</mainClass>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>
②application.properties
server.port=8080

spring.datasource.url=${SPRING_DATASOURCE_URL:jdbc:mysql://localhost:3306/mydb?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai}
spring.datasource.username=${SPRING_DATASOURCE_USERNAME:root}

spring.datasource.password=${SPRING_DATASOURCE_PASSWORD:password}
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

spring.redis.host=${SPRING_REDIS_HOST:localhost}
spring.redis.port=${SPRING_REDIS_PORT:6379}
③DemoApplication.java
package com.javatest;

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);
    }
}
④Todo.java
package com.javatest;

import java.io.Serializable;
import java.time.LocalDateTime;

// 这是一个简单的 Java Bean,用来存数据
public class Todo implements Serializable {
    private static final long serialVersionUID = 1L;

    private Long id;
    private String content;
    private LocalDateTime createdAt;

    public Todo() {}

    public Todo(Long id, String content, LocalDateTime createdAt) {
        this.id = id;
        this.content = content;
        this.createdAt = createdAt;
    }

    // 必须有 Getter 和 Setter,否则页面取不到值
    public Long getId() { return id; }
    public void setId(Long id) { this.id = id; }
    public String getContent() { return content; }
    public void setContent(String content) { this.content = content; }
    public LocalDateTime getCreatedAt() { return createdAt; }
    public void setCreatedAt(LocalDateTime createdAt) { this.createdAt = createdAt; }
}
⑤TodoController.java
package com.javatest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

// 1. 确保引入了 javax.annotation.Resource
import javax.annotation.Resource;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.time.LocalDateTime;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Controller
public class TodoController {

    @Autowired
    private JdbcTemplate jdbcTemplate; // 操作 MySQL


    @Resource(name = "redisTemplate")
    private RedisTemplate<String, Object> redisTemplate; // 操作 Redis

    private static final String REDIS_KEY = "todos:list";

    // --- 查 (Read) ---
    @GetMapping("/")
    public String listTodos(Model model) {
        List<Todo> todos;

        // 1. 先查 Redis
        todos = (List<Todo>) redisTemplate.opsForValue().get(REDIS_KEY);

        if (todos != null) {
            System.out.println(">>> 数据来自 Redis 缓存");
        } else {
            // 2. Redis 没有,查 MySQL
            System.out.println(">>> Redis 没数据,查询 MySQL...");
            String sql = "SELECT id, content, created_at FROM todos ORDER BY id DESC";
            todos = jdbcTemplate.query(sql, new TodoRowMapper());

            // 3. 把 MySQL 的数据存回 Redis (缓存 60 秒)
            redisTemplate.opsForValue().set(REDIS_KEY, todos, 60, TimeUnit.SECONDS);
            System.out.println(">>> 数据已同步到 Redis");
        }

        model.addAttribute("todos", todos);
        return "index"; // 对应 templates/index.html
    }

    // --- 增 (Create) ---
    @PostMapping("/add")
    public String addTodo(@RequestParam String content) {
        System.out.println(">>> 添加任务: " + content);

        // 1. 先存 MySQL
        String sql = "INSERT INTO todos (content, created_at) VALUES (?, ?)";
        jdbcTemplate.update(sql, content, LocalDateTime.now());

        // 2. 删除 Redis 缓存 (让下次查询强制走数据库并更新缓存)
        redisTemplate.delete(REDIS_KEY);
        System.out.println(">>> Redis 缓存已清除");

        return "redirect:/";
    }

    // --- 删 (Delete) ---
    @GetMapping("/delete/{id}")
    public String deleteTodo(@PathVariable Long id) {
        System.out.println(">>> 删除任务 ID: " + id);

        // 1. 删 MySQL
        String sql = "DELETE FROM todos WHERE id = ?";
        try {
            jdbcTemplate.update(sql, id);
        } catch (EmptyResultDataAccessException e) {
            // 忽略删除不存在的 ID 的报错
        }

        // 2. 删除 Redis 缓存
        redisTemplate.delete(REDIS_KEY);
        System.out.println(">>> Redis 缓存已清除");

        return "redirect:/";
    }
}

// 内部类:用来把数据库结果映射到 Todo 对象
class TodoRowMapper implements RowMapper<Todo> {
    @Override
    public Todo mapRow(ResultSet rs, int rowNum) throws SQLException {
        return new Todo(
                rs.getLong("id"),
                rs.getString("content"),
                rs.getTimestamp("created_at").toLocalDateTime()
        );
    }
}
⑥index.html
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Redis + MySQL Demo</title>
    <style>
        body { font-family: sans-serif; max-width: 600px; margin: 2rem auto; }
        .item { display: flex; justify-content: space-between; padding: 10px; border-bottom: 1px solid #eee; }
        input[type="text"] { width: 70%; padding: 8px; }
        button { padding: 8px 15px; }
    </style>
</head>
<body>
<h1>待办事项 (Redis+MySQL)</h1>

<!-- 添加表单 -->
<form action="/add" method="post" style="margin-bottom: 20px;">
    <input type="text" name="content" placeholder="输入任务内容..." required />
    <button type="submit">添加</button>
</form>

<!-- 列表展示 -->
<div>
    <!-- thymeleaf 循环 -->
    <div class="item" th:each="todo : ${todos}">
        <span th:text="${todo.content}">内容</span>
        <span style="color: #888; font-size: 0.8em;" th:text="${todo.createdAt}">时间</span>
        <a th:href="@{/delete/{id}(id=${todo.id})}" style="color: red;">[删除]</a>
    </div>
</div>
</body>
</html>
⑦Dockerfile
# 使用官方 OpenJDK 基础镜像
FROM eclipse-temurin:11-jre-alpine

# 设置工作目录
WORKDIR /app

# 复制 JAR 包
COPY target/java-k8s-demo-2.0.0.jar app.jar

# 暴露端口(根据你的应用调整)
EXPOSE 8080

# 健康检查(可选)
HEALTHCHECK --interval=30s --timeout=3s --start-period=60s --retries=3 \
  CMD wget --no-verbose --tries=1 --spider http://localhost:8080/actuator/health || exit 1

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

将Java应用通过Maven打包后,构建Docker镜像并推送到仓库

#注意构建版本改成V3
docker build -t docker.io/hyz1127/my-java-app:v3 .
docker push docker.io/hyz1127/my-java-app:v3
⑧创建数据库表
#进入数据库pod
kubectl exec -it mysql-7bd48cbd97-xs7q6 -- mysql -uroot -p'test123'

登录MySQL后进行以下操作

SHOW DATABASES;
USE mydb;

执行带UTF-8建表语句

CREATE TABLE IF NOT EXISTS todos (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    content VARCHAR(255) NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

创建后执行SHOW CREATE TABLE todos;进行检查

  • DEFAULT CHARSET=utf8mb4
  • contentCollation 变成 utf8mb4_unicode_ci
    在这里插入图片描述
4.更新deployment.yaml配置,使用最新镜像滚动更新
# 1. Deployment: 负责管理你的 Java 应用容器
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-java-app
spec:
  replicas: 2  # 副本数,先设为1跑通流程
  selector:
    matchLabels:
      app: my-java-app
  template:
    metadata:
      labels:
        app: my-java-app
    spec:
      containers:
      - name: java-container
        # 这里填你刚才推送成功的镜像地址
        image: docker.io/hyz1127/my-java-app:v3
        imagePullPolicy: Always
        ports:
        - containerPort: 8080  # 你的Java应用监听的端口
        env:
            # --- 请添加以下环境变量 ---
            # --- 1. mysql 配置 ---
            - name: SPRING_DATASOURCE_URL
              value: "jdbc:mysql://mysql:3306/mydb?useSSL=false&serverTimezone=UTC"   #mydb改成自己新建的数据库名字
            - name: SPRING_DATASOURCE_USERNAME
              value: "root"
            - name: SPRING_DATASOURCE_PASSWORD
              value: "test123"
            - name: SPRING_DATASOURCE_DRIVER_CLASS_NAME
              value: "com.mysql.cj.jdbc.Driver"
             # --- 2. Redis 配置 ---
            - name: SPRING_REDIS_HOST
              value: "redis"   # <--- 这里填 Kubernetes 里 Redis 服务的名称
            - name: SPRING_REDIS_PORT
              value: "6379"
        resources:
          requests:
            memory: "256Mi"    # 申请内存
            cpu: "250m"        # 申请CPU
          limits:
            memory: "512Mi"    # 最大内存限制
            cpu: "500m"        # 最大CPU限制

---
# 2. Service: 负责把应用暴露出来,让你能访问
apiVersion: v1
kind: Service
metadata:
  name: my-java-app-service
spec:
  selector:
    app: my-java-app
  ports:
  - protocol: TCP
    port: 80           # 访问端口(外部)
    targetPort: 8080   # 容器端口(内部)
  type: NodePort       # 使用 NodePort 方便本地测试 (如果是云厂商K8s,可改为 LoadBalancer)

应用配置进行滚动更新

kubectl apply -f  deployment.yaml
5.验证测试
①访问应用:通过 Ingress 或 NodePort 访问 Java 应用的 Web 页面。
  • ✅前端页面正常显示
    在这里插入图片描述

  • 英文任务/中文任务/表情符号都添加成功,且能删除

    在这里插入图片描述

总结:前端页面正常显示、英文/中文任务添加成功说明 Redis + MySQL 双缓存正常工作!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

运维全栈笔记

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值