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集群实验完毕!

相关推荐
青衫码上行2 小时前
【项目开发日记 | Java架构】第一天
java·开发语言·spring cloud
执笔为剑2 小时前
1.2、docker环境部署
运维·docker·容器
DJ斯特拉2 小时前
自定义jar包导入maven&&注册第三方bean
java·maven·jar
j_xxx404_2 小时前
力扣困难算法精解:串联所有单词的子串与最小覆盖子串
java·开发语言·c++·算法·leetcode·哈希算法
会编程的土豆2 小时前
Set 深度解析:去重、唯一性与你的智能抽屉
java·开发语言·后端·数据结构与算法
java1234_小锋3 小时前
Java高频面试题:JVM内存为什么要分代?
java·开发语言·jvm
linux修理工3 小时前
下载亚马逊Corretto 17的方法(OpenJDK 17发行版)
java·运维·服务器
moonlight03043 小时前
类加载子系统
java·jvm·算法
qhqh3103 小时前
K8S的PV、PVC和storageClass的相关概念及实验
云原生·容器·kubernetes