内部性能测试发现了 java 容器在 k8s 的问题
由来
内部之前 es 是 docker 起的,后面换成 k8s staticPod + hostPath ,在性能压测的时候发现性能很低
过程
和版本无关,所以不放版本信息了,直接写过程了。
眉目
当时看 Prometheus 发现机器占用很低,感觉 es 没充分利用机器资源。查看下 es 的接口:
1 2 3 4 5
| $ curl -s --user xxx:xxx xxx:9200/_nodes/os ... "available_processors": 1, "allocated_processors": 1 ...
|
发现不对劲,默认没限制应该和宿主机 cpu 核心一样的。然后对比了下,发现 docker run 的 es 正常, k8s 则是上面的异常,对比了 docker inspect 发现 k8s 的容器 CpuShares 设置的是 2,docker 是 1024
利用代码测测试下
1 2 3 4 5 6 7 8 9 10 11 12
| cat > /opt/test.java << EOF public class Main { public static void main(String[] args) { System.out.println("Available Processors = " +Runtime.getRuntime().availableProcessors()); } } EOF
$ docker run --rm -v /opt/test.java:/test.java --cpu-shares=2 elasticsearch:7.9.3 /usr/share/elasticsearch/jdk/bin/java /test.java Available Processors = 1 $ docker run --rm -v /opt/test.java:/test.java elasticsearch:7.9.3 /usr/share/elasticsearch/jdk/bin/java /test.java Available Processors = 16
|
通过一下步骤可以看到 docker 默认参数下 cpu.share 是 1024:
1 2 3 4 5 6 7 8
| $ docker inspect xxx | grep Pid $ grep cpu /proc/$pid/cgroup # 用获得的 cgroup path查 $ find /sys -type d -name xxxxxxxxxxxxxxxxxxx $ cat /sys/fs/cgroup/cpu,cpuacct/docker/xxxxxxxxxxxxxxxxxxx/cpu.shares 1024 $ docker run --rm -v /opt/test.java:/test.java --cpu-shares=1024 elasticsearch:7.9.3 /usr/share/elasticsearch/jdk/bin/java /test.java Available Processors = 16
|
解决办法
可以看文章结尾参考关于大佬们的讨论,java 计算可用核心是关于 cpu 几个 cgroup 的值,默认在接口调用 docker 的时候,没给 docker 传递的话,cpu.shares 默认就是 2,可以给 pod 一个 request.cpu 1 即可避免这种问题
参考