需求

当我们对Java应用完成Maven/Gradle打包并将镜像推送至远程仓库后,剩下的工作就是应用上K8S了,涉及到的工作主要为:

  • 编写Deployment/Service/Ingress部署应用;
  • 环境变量传递Xmx、应用名、环境名等个性化配置;
  • configmap传递统一标准规范的jvm参数;
  • 共享目录统一管理配置文件;

通过对Java应用运行依赖的JVM参数、运行目录等内容的分析,需要分别通过K8S内置环境变量、Configmap、PV/PVC等功能进行不同程度的集成。

JVM参数管理

一套统一标准的JVM参数便于运维团队对Java进程的统一管理,例如统一的内存参数、日志目录、gc日志等等。我们将统一的JVM参数定义如下:

-server
-Xms2048m
-Xmx2048m
-XX:MaxPermSize:256m
-Dapp.name=test
-Denv=prod
-Djava.io.tmpdir=/tmp
# gc.log输出到统一的日志目录
-Xloggc:/data/logs/gc.log
-XX:+PrintGC
-XX:+PrintGCDetails
-XX:+PrintGCTimeStamps
-XX:+PrintGCDateStamps
-XX:+PrintHeapAtGC
-XX:+PrintReferenceGC
-Dsun.jnu.encoding=UTF-8
-XX:+HeapDumpOnOutOfMemoryError
# dump文件输出到统一的日志目录
-XX:HeapDumpPath=/data/logs/HeapDumpOnOutOfMemoryError.dump

其中:

  • "-Xms2048m -Xmx2048m"从JVM参数拆分,需要K8S环境变量单独传递变量,以便应用内存个性化调整;
  • "-Denv=prod"从JVM参数拆分,需要K8S环境变量单独传递变量,以便不同环境应用配置文件访问;
  • "-Dapp.name=test"在Dockerfile构建阶段就通过代码内部的变量进行自动配置;
  • 剩余的JVM参数因没有个性化配置,统一通过configmap配置文件进行统一管理;

1.Dockerfile 参数化传递

# vim Dockerfile
FROM harbor.xxx.com/public/centos-jdk8:1.0.0
MAINTAINER yunwei
#VOLUME /tmp
ARG JAR_FILE
ARG APP_NAME
ENV APP_NAME=${APP_NAME}
COPY ${JAR_FILE} ${APP_NAME}.jar
ENTRYPOINT ["/bin/sh","-c","java -Dapp.name=${APP_NAME} -Denv=${PROFILE} ${XM} -Xbootclasspath/a:/data/config/${APP_NAME} $JVM_OPTS -jar /${APP_NAME}.jar"]

其中:

  • "-Dapp.name"通过gradle打包镜像传递;
  • "-Denv"和"XM"通过K8S环境变量传递;
  • "-Xbootclasspath"为配置文件共享目录;
  • "$JVM_OPTS"通过K8S的configmap传递;

2.K8S集成变量和配置

我们通过Deployment中的环境变量和configmap来进一步集成环境运行参数:

# vim configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:name: jvmoptionsnamespace: test
data:JVM_OPTS: "-server -XX:MaxPermSize:256m -Djava.io.tmpdir=/tmp -Xloggc:/data/logs/gc.log -XX:+PrintGC -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -XX:+PrintHeapAtGC -XX:+PrintReferenceGC -Dsun.jnu.encoding=UTF-8 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/data/logs/HeapDumpOnOutOfMemoryError.dump"# vim Deployment.yaml
apiVersion: apps/v1
kind: Deployment
...省略...spec:containers:- name: sysmonitorenv:- name: PROFILEvalue: "test"- name: XMvalue: "-Xms2048m -Xmx2048m"- name: JVM_OPTSvalueFrom:configMapKeyRef:name: jvmoptionskey: JVM_OPTS
...省略...

目录管理

通过JVM参数可以发现,应用运行依赖的运行目录主要有:

  • /data/logs,gc日志目录和运行日志目录;
  • /data/config/应用名,应用名的配置文件目录;

以上目录我们一定要持久化,以便应用崩溃时能够进行排查或后续日志收集,K8S的解决方案是通过PV/PVC的方式实现持久卷的管理。

  • PV是集群中的一块存储,可以由管理员事先制备(静态制备), 或者使用存储类(Storage Class)来动态制备
  • PVC是用户对存储的请求, Pod 通过 PVC 申领 PV 资源,实现对存储的使用。

虽然静态制备和动态制备都能实现我们对存储资源的使用,但是从目前对目录使用情况的分析,静态制备是最适合我们的使用方案。而动态制备更适用于多目录及不同等级存储资源的需求及动态分配,对我们目前的使用量不太适用。
对于存储的适用,我们统一基于NFS的文件存储:

# vim static-pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:name: pv-staticlabels:type: pv-static
spec:storageClassName: nfsaccessModes:- ReadWriteManypersistentVolumeReclaimPolicy: RecyclemountOptions:- vers=3- async- rsize=1048576- wsize=1048576nfs:path: /dataserver: 10.10.20.250capacity: storage: 10Gi# vim static-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:name: pvc-staticnamespace: testlabels:type: pvc-static
spec:storageClassName: nfsaccessModes:- ReadWriteManyresources:requests:storage: 5Gi# Deployment挂载
# vim deployment.yaml
apiVersion: apps/v1
kind: Deployment
...省略...template:spec:containers:- name: testenv:- name: PROFILEvalue: "test"- name: XMvalue: "-Xms2048m -Xmx2048m"- name: JVM_OPTSvalueFrom:configMapKeyRef:name: jvmoptionskey: JVM_OPTS
...省略...ports:- containerPort: 8090volumeMounts:- name: datamountPath: /data
...省略...volumes:- name: datapersistentVolumeClaim:claimName: pvc-static

我们在Nas上创建一个 data (10G)共享目录,可方便对配置文件进行统一管理:

  • 将Nas 共享目录挂载到K8S 的一个master节点上,可在容器外进行管理;
  • /data/config目录下的所有应用配置文件,后续可在容器外手动git pull更新;
  • 通过pv/pvc 将Nas 共享目录 /data 挂载到应用pod容器内的 /data 目录,多个pod共享文件;
  • 其他logs或其他目录均由应用自动生成;

Deployment/Service/Ingress

完整的一套应用上K8S的部署如下:

# vim helloworld.yaml
apiVersion: apps/v1
kind: Deployment
metadata:name: helloworldnamespace: test
spec:replicas: 1selector:matchLabels:app: helloworldtemplate:metadata: name: helloworldlabels:app: helloworldspec:containers:- name: helloworldenv:- name: PROFILEvalue: "p2"- name: XMvalue: "-Xms2048m -Xmx2048m"- name: JVM_OPTSvalueFrom:configMapKeyRef:name: jvmoptionskey: JVM_OPTSimage: harbor.xxx.com:8000/helloworld:1.1.21imagePullPolicy: IfNotPresentlivenessProbe:httpGet:path: /app/healthport: 8090initialDelaySeconds: 60timeoutSeconds: 5readinessProbe:httpGet:path: /app/healthport: 8090initialDelaySeconds: 60timeoutSeconds: 5ports:- containerPort: 8090volumeMounts:- name: datamountPath: /dataimagePullSecrets: - name: harbor-secretvolumes:- name: datapersistentVolumeClaim:claimName: pvc-static---
apiVersion: v1
kind: Service
metadata:name: helloworldnamespace: test
spec:type: NodePortselector:app: helloworldports:- port: 8090targetPort: 8090---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:name: helloworldnamespace: test
spec:rules:- host: helloworld.xxx.nethttp:paths:- path: /pathType: Prefixbackend:service:name: sysmonitorport:number: 8090

总结

应用上K8S后并不意味着结束,相反我们仍还有其他需要工作要做:

  • Prometheus监控应用状态;
  • 流水线实现应用的版本更新、快速交付;
  • 应用根据负载的弹性伸缩;
  • 应用的日志收集;

其实本文应用的日志最终写在NFS共享存储上,还是将其持久化到集群node节点上。尤其是在上百已经级别的情况下,毕竟NFS的性能也是我们不得不面对的一个问题。其最终的解决方案,需要我们去从容选择。

应用上K8S:K8S集成Java应用相关推荐

  1. k8s和harbor的集成_Harbor与K8s的集成实践

    Harbor与K8s的集成实践 Harbor提供了基于角色的访问控制机制,并通过项目来对镜像进行组织和访问权限的控制.kubernetes中通过namespace来对资源进行隔离,在企业级应用场景中, ...

  2. kubernetes(K8S)学习笔记P6:K8s集群|java项目部署

    kubernetes(K8S)学习笔记P6:K8s集群|java项目部署 8.集群资源监控 8.1概述 8.2搭建集群监控平台系统 8.2.1部署prometheus 8.2.3部署Grafana 8 ...

  3. 通过Rancher Desktop在桌面上运行K8s

    Rancher 发行的操作系统新选择:Rancher Desktop for Windows,它可以帮助你在Windows桌面上管理Kubernetes和容器.当然他当然会支持Linux,Mac的. ...

  4. 利用VisualVm和JMX远程监控K8S里的Java进程

    在利用VisualVm和JMX远程监控Java进程和VisualVm利用SSL连接JMX的方法里介绍了如 何使用VisualVm+JMX监控远程Java进程的方法.那么如何监控一个运行在K8S集群中的 ...

  5. 使用 k3s 在 Centos7 上运行 K8S

    本文参考: 使用 k3s 在 Fedora IoT 上运行 K8S | Linux 中国 https://mp.weixin.qq.com/s?__biz=MzI1NDQwNDYyMg==&m ...

  6. 阿里云上的k8s中某些节点的pod报dns错误,dns解析失败,bad address

    php报错为:php_network_getaddresses:getaddrinfo failed 问题可能出现的位置 这类问题对应的都是dns解析错误.这里我的错误是因为我连接阿里云数据库用的域名 ...

  7. RabbitMQ –使用Spring集成Java DSL串行处理消息

    如果您曾经需要使用RabbitMQ来串行处理消息,并且有一群监听器来处理消息,那么我所看到的最好方法是在监听器上使用"独占消费者"标志,每个监听器上有1个线程来处理消息. 专用使用 ...

  8. 案例 github_2019年12月Github上最热门的Java开源项目,速来围观!

    转眼之间,已经进入了2020年,2019年发生的一切仿佛就在昨天.那么,刚过去不久的12月份GitHub上最热门的Java开源项目排行已经出炉啦.下面我带大家一起来看看上榜详情: 1.Alink ht ...

  9. github java开源项目经验_3月份GitHub上最热门的Java开源项目

    今天,我们来盘点3月份GitHub上最热门的Java项目的时候了,如果你每月都有关注猿妹发布的排行榜,那么本月的Java项目对你来说一定不陌生,这些都是曾经多次出现在榜单中的项目: 1 advance ...

  10. 2019年1月份GitHub上最热门的Java开源项目

    相信大多数程序猿们都回归工作岗位啦,不知道是否调整好心态了呢?1月份GitHub上最热门的Java开源项目新鲜出炉,还是一起来看看都有哪些项目上榜吧: 1JavaGuide https://githu ...

最新文章

  1. Linux硬盘性能测试工具 - FIO
  2. scrapy接selenium关键步骤
  3. Java对存储过程的调用方法
  4. 【Tomcat】解决GET方式传递的参数(URL中的参数)乱码问题
  5. C#事件中的两个参数(object sender,EventArgs e)
  6. 性别有什么用_为啥不让男孩玩布娃娃?别让你的“性别偏见”,给孩子的人生设限...
  7. 深度搜索和广度搜索领接表实现_数据结构与算法--图的搜索(深度优先和广度优先)...
  8. 《软件需求分析(第二版)》第 14 章——需求管理的原则和实践 重点部分总结
  9. mysql yog中文版下载_SQLyog 12
  10. vc++中ListBox用法
  11. C++ string 成员函数 length() size() 和 C strlen() 的区别
  12. python3 range函数_为什么python3中的xrange函数不能用
  13. 这 26个中国式创新,征服了全世界
  14. VUE 身份证号验证
  15. centos7下显卡型号查询
  16. Genymotion模拟器及其相关虚拟机下载地址
  17. Unity倒计时动画
  18. 计算机行业未来20年前景,未来20年,哪个专业最有“前景“?符合一定要报
  19. GameMaker如何导入JSON文件
  20. android 原生请求权限代码

热门文章

  1. 一分钟解决连接git/github失败问题!亲测可行!
  2. 问一个sql方面的问题
  3. 2021数学建模国赛总结(含题目)
  4. 试用Unity3D体验(三):添加Loading页面
  5. EXCEL 懒人,节约时间,摸鱼小技巧-1
  6. html把一张图片动态的代码,原神:4张动态图演示168皮肤琴的实机效果,三种玩家可入手...
  7. 京东店铺详情页如何做关联销售?如何给图片加热点链接?
  8. SSM网上商城购物系统(前台+后台)
  9. 颜色模型(color model)
  10. Ajax、JSON数据和文件上传与下载