背景:
根底环境centos8+kubeadm1.20.5+cilium+hubble环境搭建,线上次要跑的php nodejs java的环境。
java的pod昨天频繁呈现了cpu 90%的占用率告警:
尽管cpu是可压缩资源(compressible resources ),利用只会饥饿,不会像是内存爆了一样OOM.然而也须要进行一下性能剖析,看一眼是代码逻辑有问题,还是资源分配的大小不合理。
就想传统的形式进入容器查看pid,运行jstack命令进行剖析了:
kubectl exec -it xxx-xxxx-8556c7f98b-9nh28 sh -n official/ # psPID USER TIME COMMAND 1 root 2h38 java -Djava.security.egd=file:/dev/./urandom -jar /xxx-1.0-SNAPSHOT.jar 4178 root 0:00 sh 4193 root 0:00 ps/ # jstack 11: Unable to get pid of LinuxThreads manager thread
what jstack命令无奈剖析利用......
解决过程:
百度搜寻了一下,参见:
https://blog.csdn.net/qq_16887777/article/details/107417059
1. 对于pid1
发现服务的pid=1,网上查问得悉pid1-5为Linux的非凡过程。
pid=1 :init过程,系统启动的第一个用户级过程,是所有其它过程的父过程,疏导用户空间服务。
pid=2 :kthreadd:用于内核线程治理。
pid=3 :migration,用于过程在不同的CPU间迁徙。
pid=4 :ksoftirqd,内核里的软中断守护线程,用于在零碎闲暇时定时解决软中断事务。
pid=5 :watchdog,此过程是看门狗过程,用于监听内核异样。当零碎呈现宕机,能够利用watchdog过程将宕机时的一些堆栈信息写入指定文件,用于预先剖析宕机的起因。
依据排除法最简略的形式就是让java启动的过程pid不是1-5就能够了?嗯启动命令不是第一个。
2. 批改Dcokerfile java启动形式
高低我的Dockerfile
FROM openjdk:8-jdk-alpineVOLUME /tmpENV TZ=Asia/ShanghaiRUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezoneADD target/diversion-0.0.1-SNAPSHOT.jar diversion-0.0.1-SNAPSHOT.jarENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/xxxx-0.0.1-SNAPSHOT.jar"]
嗯集体认为能够将 java 启动文件写入脚本?而后ENTRYPOINT sh脚本?偶尔看到一个tini的办法:docker运行java程序 应用jmap,jstack命令 tini运行的程序获取过程.批改Dockerfile如下:
FROM openjdk:8-jdk-alpineVOLUME /tmpENV TZ=Asia/ShanghaiRUN apk add --no-cache tiniRUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezoneADD target/diversion-0.0.1-SNAPSHOT.jar diversion-0.0.1-SNAPSHOT.jarENTRYPOINT ["tini","java","-Djava.security.egd=file:/dev/./urandom","-jar","/xxxx-0.0.1-SNAPSHOT.jar"]
3. 构建并上传镜像到镜像仓库
docker build -t ccr.ccs.tencentyun.com/xxxx/xxxx:xxxxdocker push ccr.ccs.tencentyun.com/xxxx/xxxx:xxxx
4. 部署利用并测试
cat > test.yaml << EOFapiVersion: apps/v1kind: Deploymentmetadata: name: testspec: replicas: 1 strategy: rollingUpdate: maxSurge: 1 maxUnavailable: 0 selector: matchLabels: app: test template: metadata: labels: app: test spec: containers: - name: test image: ccr.ccs.tencentyun.com/xxxx/xxxx:xxxx env: - name: SPRING_PROFILES_ACTIVE value: "official" ports: - containerPort: test resources: requests: memory: "256M" cpu: "250m" limits: memory: "1024M" cpu: "500m" imagePullSecrets: - name: tencent---apiVersion: v1kind: Servicemetadata: name: test labels: app: testspec: ports: - port: 8081 protocol: TCP targetPort: 8081 selector: app: testEOF
kubectl apply -f test.yaml -n testkubectl exec -it xxxxxxx sh -n testtop
能够看到过程号是1的过程是tini的 有额定一个独自的过程号为7的java 过程,运行jstack进行测试:
jstack 7
嗯能运行jstack就算是实现了本人须要的了。其余的先疏忽。