背景:

根底环境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就算是实现了本人须要的了。其余的先疏忽。

总结:

1. 对于linux的pid

2. tini的命令,可参照https://zhuanlan.zhihu.com/p/59796137

3. docker的启动形式与过程隔离实现形式