Kubernetes 1.29集群上部署Java网站项目

K8s上部署java网站项目流程

第一步:制作镜像

像java,C,GO都是编译型语言,使用前需要编译。

解释型语言:php,python

复制代码
# 下载Java项目
[root@k8s-master01 ~]# git clone https://gitee.com/xinghaik8s/java-demo.git

# 安装环境
[root@k8s-master01 ~]# yum install java-1.8.0-openjdk-devel maven -y

# 代码编译
[root@k8s-master01 java-demo]# mvn clean package

# 解压部署文件
[root@k8s-master01 java-demo]# unzip target/*.war -d target/ROOT

#修改maven源为阿里源
[root@k8s-master01 java-demo]# vi /etc/maven/settings.xml
<!-- mirrors
   | This is a list of mirrors to be used in downloading artifacts from remote repositories.
   |
   | It works like this: a POM may declare a repository to use in resolving certain artifacts.
   | However, this repository may have problems with heavy traffic at times, so people have mirrored
   | it to several places.
   |
   | That repository definition will have a unique id, so we can create a mirror reference for that
   | repository, to be used as an alternate download site. The mirror site will be the preferred
   | server for that repository.
   |-->
<mirrors>
    <!-- 阿里云镜像(代理了Central、JCenter、Spring等) -->
    <mirror>
        <id>aliyun</id>
        <name>阿里云公共仓库</name>
        <url>https://maven.aliyun.com/repository/public</url>
        <!-- 星号 * 表示匹配所有仓库,几乎所有的下载都会走这个镜像,速度最快 -->
        <mirrorOf>*</mirrorOf>
    </mirror>
</mirrors>                                                                                                             

制作新镜像并推入镜像仓

复制代码
#根据当前目录下的 Dockerfile 和其他上下文文件,构建一个名为 java-demo:v1 的 Docker 镜像。
[root@k8s-master01 java-demo]# docker build -t java-demo:v1 . #根据当前目录的 Dockerfile 构建一个新的 Docker 镜像
# 为镜像打上仓库标签
[root@k8s-master01 java-demo]# docker tag java-demo:v1 core.harbor.domain/java-demo/java-demo:v1 #要推送到 Harbor 仓库,标签格式必须严格遵守:仓库地址/项目名/镜像名:版本
#登录harbor
[root@k8s-master01 java-demo]# docker login core.harbor.domain
Authenticating with existing credentials... [Username: admin]

i Info → To login with a different account, run 'docker logout' followed by 'docker login'


Login Succeeded

# 推送镜像到仓库
[root@k8s-master01 java-demo]# docker push core.harbor.domain/java-demo/java-demo:v1
The push refers to repository [core.harbor.domain/java-demo/java-demo]
a02a4930cb5d: Pushed
675ab56ce773: Pushed
a2328b746f7b: Pushed
12ac6c660ca4: Pushed
e114a9aff6a2: Pushed
e6f0733c3ee9: Pushed
v1: digest: sha256:85d9e1ab2d7db6b21fe91eae8d6f507b23b6fc5431eadbc485739c7ae25c6ba1 size: 856

第二步:使用工作负载资源部署镜像

复制代码
#预生成一个 Kubernetes Deployment(部署)的 YAML 配置文件,而不会在集群中实际创建任何资源
[root@k8s-master01 java-demo]# kubectl create deployment java-demo --image=core.harbor.domain/java-demo/java-demo:v1 --replicas=2 --dry-run=client -o yaml > deployment.yaml
#apply部署一下
[root@k8s-master01 java-demo]# kubectl apply -f deployment.yaml
deployment.apps/java-demo created

#创建service,为现有的 java-demo Deployment 生成一个 Service(服务)的配置模板,以便将您的 Java 应用暴露给网络访问。
[root@k8s-master01 java-demo]# kubectl expose deployment java-demo --port=80 --target-port=8080 --dry-run=client -o yaml > service.yaml
#为了方便从外部访问,可以把type改为NodePort
#Service 类型是 NodePort。31594就是 Kubernetes 自动分配的一个"节点端口",它允许你通过集群中任意节点的 IP 地址(比如你的 192.168.175.11、12、13)加上这个端口来从外部访问服务。
#Service 类型是默认的 ClusterIP,它只提供一个集群内部的 IP 地址 (10.10.167.74),因此只能在 Kubernetes 集群内部被访问。
[root@k8s-master01 java-demo]# vi service.yaml
[root@k8s-master01 java-demo]# cat  service.yaml
apiVersion: v1
kind: Service
metadata:
  creationTimestamp: null
  labels:
    app: java-demo
  name: java-demo
spec:
  type: NodePort
  ports:
  - port: 80
    protocol: TCP
    targetPort: 8080
  selector:
    app: java-demo
status:
  loadBalancer: {}
复制代码
#进入java服务里面看一下
[root@k8s-master01 java-demo]# kubectl get pod
NAME                        READY   STATUS    RESTARTS   AGE
java-demo-f497fcd95-44z9h   1/1     Running   0          31m
java-demo-f497fcd95-zn89x   1/1     Running   0          31m
[root@k8s-master01 java-demo]# kubectl exec -it    java-demo-f497fcd95-44z9h         sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
sh-4.2# ls
BUILDING.txt  CONTRIBUTING.md  LICENSE  NOTICE  README.md  RELEASE-NOTES  RUNNING.txt  bin  conf  lib  logs  temp  webapps  work
sh-4.2# cd webapps/
sh-4.2# ls
ROOT
sh-4.2# cd ROOT/
sh-4.2# ls
META-INF  WEB-INF
sh-4.2# cd WEB-INF/
sh-4.2# ls
classes  lib
sh-4.2# cd classes/
sh-4.2# ls
application.yml  com  static  templates
sh-4.2# cat application.yml
server:
  port: 8080
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8&useSSL=false&&serverTimezone=CST
    username: root
    password: 123456
    driver-class-name: com.mysql.jdbc.Driver
  freemarker:
    allow-request-override: false
    cache: true
    check-template-location: true
    charset: UTF-8
    content-type: text/html; charset=utf-8
    expose-request-attributes: false
    expose-session-attributes: false
    expose-spring-macro-helpers: false
    suffix: .ftl
    template-loader-path:
      - classpath:/templates/
sh-4.2#


#创建configmap,configmap里面的内容和项目里面的application.yml是一致的
[root@k8s-master01 java-demo]# vi configmap.yaml
[root@k8s-master01 java-demo]# cat configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: java-demo-config
data:
  # 键 application.yml 对应的值是一个多行字符串
  application.yml: |
    server:
      port: 8080
    spring:
      datasource:
        url: jdbc:mysql://java-web-demo-db:3306/test?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=CST
        username: root
        password: "123456"
        driver-class-name: com.mysql.jdbc.Driver
      freemarker:
        allow-request-override: false
        cache: true
        check-template-location: true
        charset: UTF-8
        content-type: text/html; charset=utf-8
        expose-request-attributes: false
        expose-session-attributes: false
        expose-spring-macro-helpers: false
        suffix: .ftl
        template-loader-path:
          - classpath:/templates/
[root@k8s-master01 java-demo]# kubectl apply -f configmap.yaml
configmap/java-demo-config created


#在deployment上增加挂在卷,修改一下deployment文件,要把数据保存到本地
#[root@k8s-master01 java-demo]# vi deployment.yaml
[root@k8s-master01 java-demo]# cat deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: java-demo
  name: java-demo
spec:
  replicas: 2
  selector:
    matchLabels:
      app: java-demo
  strategy: {}
  template:
    metadata:
      labels:
        app: java-demo
    spec:
      containers:
      - image: core.harbor.domain/java-demo/java-demo:v1
        name: java-demo
        volumeMounts: #容器挂载配置 (volumeMounts)
        - name: config #引用下面定义的卷名称
          mountPath: /usr/local/tomcat/webapps/ROOT/WEB-INF/classes/application.yml #容器内的目标路径
          subPath: application.yml #只挂载卷中的特定文件,而不是整个卷
      volumes:
      - name: config #定义卷的名称
        configMap: 
          name: java-demo-config #引用的 ConfigMap 名称
          items:
          - key: application.yml
            path: application.yml

重启java服务生效

复制代码
kubectl rollout restart deployment java-demo

初始化数据库

复制代码
#[root@k8s-master01 opt]# vi mysql.yaml
[root@k8s-master01 opt]# cat mysql.yaml
apiVersion: v1
kind: Secret #作用:安全存储敏感数据
metadata: 
  name: java-web-demo-db #名称:java-web-demo-db
type: Opaque #类型:Opaque(通用类型)/
data:
  mysql-root-password: "MTIzNDU2" #数据:mysql-root-password 的值是 MTIzNDU2(这是 "123456" 的 base64 编码)

---

apiVersion: apps/v1
kind: Deployment
metadata:
  name: java-web-demo-db
spec:
  selector: #标签选择器:选择带有project: www和app: mysql标签的Pod 
    matchLabels:
      project: www
      app: mysql
  template:
    metadata:
      labels:
        project: www
        app: mysql
    spec:
      # 关键修复1:添加Pod级别的securityContext
      securityContext:
          fsGroup: 999 # Kubernetes 会自动设置卷组权限
      # 关键修复2:添加initContainer修复权限
      initContainers:
      - name: volume-permission-fix
        image: busybox:latest
        command: ["sh", "-c", "chmod -R 777 /var/lib/mysql"]
        volumeMounts:
        - name: data
          mountPath: /var/lib/mysql
      containers:
        - name: db
          image: mysql:8.0.33
          # 关键修复3:添加容器级别的securityContext
          securityContext:
            runAsUser: 999  # 以mysql用户运行
            runAsGroup: 999 # 以mysql组运行
            allowPrivilegeEscalation: false
          resources:
            requests:
              cpu: 500m # 0.5核
              memory: 1Gi 
            limits:
              cpu: 800m # 0.8核
              memory: 2Gi 
          env:
            - name: MYSQL_ROOT_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: java-web-demo-db
                  key: mysql-root-password
          ports:
            - name: mysql
              containerPort: 3306
          livenessProbe:
            exec:
              command:
                - sh
                - -c
                - "mysqladmin ping -u root -p${MYSQL_ROOT_PASSWORD}"
            initialDelaySeconds: 120  # 容器启动30秒后开始检查
            periodSeconds: 30 # 每30秒检查一次
          readinessProbe:
            exec:
              command:
                - sh
                - -c
                - "mysqladmin ping -u root -p${MYSQL_ROOT_PASSWORD}"
            initialDelaySeconds: 30
            periodSeconds: 30
          volumeMounts:
            - name: data #要挂载的卷名称(必须与上面volumes中定义的匹配)
              mountPath: /var/lib/mysql # 容器内部的挂载路径
      volumes:
        - name: data
          persistentVolumeClaim:
            claimName: java-web-demo-db

---

apiVersion: v1
kind: PersistentVolumeClaim #持久卷声明
metadata:
  name: java-web-demo-db
spec:
  storageClassName: "nfs-client"
  accessModes:
    - ReadWriteOnce # 单节点读写
  resources:
    requests:
      storage: 8Gi # 请求8GB存储空间

---

apiVersion: v1
kind: Service #服务
metadata:
  name: java-web-demo-db
spec:
  type: ClusterIP #只能在集群内部访问
  ports:
    - name: mysql
      port: 3306 # 服务端口
      targetPort: mysql # 容器端口
  selector:
    project: www
    app: mysql

#命令将本地的 user.sql 文件复制到 Pod 的根目录 / 下(文件名为 user.sql)。
[root@k8s-master01 db]# kubectl cp user.sql java-web-demo-db-6dbfd87646-95hxf:/tmp/user.sql

java项目部署到k8s集群实验完毕!

相关推荐
咩咩啃树皮7 小时前
第40篇:Vue3组件化开发精讲——组件拆分、复用、父子通信、工程化架构
java·前端·架构
鱟鲥鳚7 小时前
Spring Boot 集成 LangChain4j:从模型调用到 Tool Calling(Demo版)
java·spring boot
大模型码小白9 小时前
【Python零基础教程】继承、多态与魔法函数:面向对象编程三大核心特性详解
java·大数据·开发语言·人工智能·python·ai编程
腾渊信息科技公司9 小时前
Spring Boot对接MES实战:视觉检测数据自动同步方案
java·人工智能·spring boot·后端·计算机视觉·ai·软件需求
爱笑的源码基地10 小时前
高并发 Redis 缓存门诊HIS系统源码,含财务统计药房进销存
java·程序·门诊系统·诊所系统·云诊所源码
wuqingshun31415910 小时前
TCP超时重传机制是为了解决什么问题?
java
莫逸风13 小时前
【AgentScope 2.0】 0. 学习指南
java·llm·agent·agentscope
生活爱好者!13 小时前
我把NAS当作下载机,docker一键部署qb
运维·docker·容器
z1234567898613 小时前
2026最新两款AI编程工具深度对比实测
java·数据库·ai编程
yaoxin52112314 小时前
470. Java 反射 - Member 接口与 AccessFlag
java·开发语言·python