最近升级和压测遇到的 hostNetwork 下 hostname 的坑问题
由来 性能压测团队压测后发现 kafka 的数据目录下有俩个很大的目录给机器目录占满:
1 2 3 total 88 drwxr-xr-x 568 nfsnobody nfsnobody 28672 Oct 1 17:42 kafka-logs-kafka-1 drwxr-xr-x 535 nfsnobody nfsnobody 28672 Sep 26 19:51 kafka-logs-vm10-7-131-94
大小问题 大小问题是因为 kafka 默认配置 log.retention.bytes = -1
:
1 2 3 4 5 6 $ docker logs 2d21e7 |& grep -P '^\s+log\.retention' log.retention.bytes = -1 log.retention.check.interval.ms = 150000 log.retention.hours = 168 log.retention.minutes = null log.retention.ms = null
查看了下 kafka 的启动脚本,支持 env 配置,配置下 KAFKA_LOG_RETENTION_BYTES: "1073741824"
后测试没问题:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 # 终端1写入topic for i in {1..1000}; do head -c 102400000 /dev/urandom | base64 |kafka-console-producer.sh --bootstrap-server 127.0.0.1:9092 --topic test; done # 终端2 观察 $ du -shx *; ls -lh test-00 cleaner-offset-checkpoint 4.0K log-start-offset-checkpoint 4.0K meta.properties 4.0K recovery-point-offset-checkpoint 4.0K replication-offset-checkpoint 3.5G test-0 3.5G test-1 总用量 3.5G -rwxr-xr-x 1 65534 65534 514K 10月 13 17:58 00000000000012487638.index.deleted -rwxr-xr-x 1 65534 65534 1.0G 10月 13 17:58 00000000000012487638.log.deleted -rwxr-xr-x 1 65534 65534 355K 10月 13 17:58 00000000000012487638.timeindex.deleted -rwxr-xr-x 1 65534 65534 517K 10月 13 19:02 00000000000024975185.index -rwxr-xr-x 1 65534 65534 1.0G 10月 13 19:02 00000000000024975185.log -rwxr-xr-x 1 65534 65534 4.0K 10月 13 17:58 00000000000024975185.snapshot -rwxr-xr-x 1 65534 65534 372K 10月 13 19:02 00000000000024975185.timeindex -rwxr-xr-x 1 65534 65534 4.1K 10月 13 18:02 00000000000027453871.snapshot -rw-r--r-- 1 65534 65534 10M 10月 13 19:02 00000000000037462545.index -rw-r--r-- 1 65534 65534 430M 10月 13 19:02 00000000000037462545.log -rw-r--r-- 1 65534 65534 4.6K 10月 13 19:02 00000000000037462545.snapshot -rw-r--r-- 1 65534 65534 10M 10月 13 19:02 00000000000037462545.timeindex -rw-r--r-- 1 65534 65534 15 10月 13 19:03 leader-epoch-checkpoint -rwxr-xr-x 1 65534 65534 43 10月 13 17:33 partition.metadata $ du -shx *; ls -lh test-00 cleaner-offset-checkpoint 4.0K log-start-offset-checkpoint 4.0K meta.properties 4.0K recovery-point-offset-checkpoint 4.0K replication-offset-checkpoint 1.5G test-0 1.5G test-1 总用量 1.5G -rwxr-xr-x 1 65534 65534 517K 10月 13 19:02 00000000000024975185.index -rwxr-xr-x 1 65534 65534 1.0G 10月 13 19:02 00000000000024975185.log -rwxr-xr-x 1 65534 65534 4.0K 10月 13 17:58 00000000000024975185.snapshot -rwxr-xr-x 1 65534 65534 372K 10月 13 19:02 00000000000024975185.timeindex -rwxr-xr-x 1 65534 65534 4.1K 10月 13 18:02 00000000000027453871.snapshot -rw-r--r-- 1 65534 65534 10M 10月 13 19:02 00000000000037462545.index -rw-r--r-- 1 65534 65534 430M 10月 13 19:02 00000000000037462545.log -rw-r--r-- 1 65534 65534 4.6K 10月 13 19:02 00000000000037462545.snapshot -rw-r--r-- 1 65534 65534 10M 10月 13 19:02 00000000000037462545.timeindex -rw-r--r-- 1 65534 65534 15 10月 13 19:03 leader-epoch-checkpoint -rwxr-xr-x 1 65534 65534 43 10月 13 17:33 partition.metadata
hostname 问题 两个带 hostname 目录的问题 1 2 3 4 # https://github.com/wurstmeister/kafka-docker/blob/master/start-kafka.sh if [[ -z "$KAFKA_LOG_DIRS" ]]; then export KAFKA_LOG_DIRS="/kafka/kafka-logs-$HOSTNAME" fi
从启动脚本看到上面逻辑,没有设置就拼接 hostname,指定 KAFKA_LOG_DIRS
成固定,再修改启动脚本支持升级后把老目录 mv 成不带 hostname 的唯一目录:
1 2 3 4 5 6 7 if [ -n "$KAFKA_LOG_DIRS" ] && ! [ -d "$KAFKA_LOG_DIRS" ];then latest_log_dir=$(ls -1 -t -d /kafka/kafka-logs-* | head) if [ -n "$latest_log_dir" ];then echo "found old kafka-logs-: ${latest_log_dir}" mv -v $latest_log_dir $KAFKA_LOG_DIRS fi fi
hostname 问题 两个目录问题还是要查找原因的,出现的场景是在我们 kafka 之前是 staticPod + hostPath 部署的,后面切成 docker-compose 部署后发生的,相关配置为:
1 2 3 4 5 6 7 hostNetwork: true hostname: kafka-{{ MY_ID }} network_mode: host hostname: kafka-{{ kafka.MY_ID }}
而仔细看 mtime:
1 2 3 total 88 drwxr-xr-x 568 nfsnobody nfsnobody 28672 Oct 1 17:42 kafka-logs-kafka-1 drwxr-xr-x 535 nfsnobody nfsnobody 28672 Sep 26 19:51 kafka-logs-vm10-7-131-94
-kafka-1
是最新的,也就是说 docker-compose 没问题,而 k8s 的容器获取到的是宿主机的 hostname,验证了下确实:
1 2 $ docker run -ti --entrypoint hostname --net host --hostname test111 m.daocloud.io/docker.io/library/nginx:alpine test111
测试 hostNetwork
和 hostname
一起下,容器的 hostname 是宿主机的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 --- apiVersion: v1 kind: Pod metadata: namespace: default name: test-hostname spec: containers: - name: test image: m.daocloud.io/docker.io/library/nginx:alpine command: ["/bin/sh" ] tty: true hostname: test111 hostNetwork: true
一开始想着是 cri-dockerd 的 bug,想着去再提交一个 pr ,于是先让群友 containerd 环境 K8S 测下,好拿信息去提交 pr。结果发现 containerd K8S 下也一样是宿主机的 hostname,搜索了下后发现:
https://github.com/kubernetes/kubernetes/issues/67019
是 K8S 代码逻辑导致的,看了下 issue,看到有 pr 关联 KEP-4762: Allows setting any FQDN as the pod’s hostname 是新版本里加了个特性 features.HostnameOverride
门控和字段 HostnameOverride
,但是看了下描述,发现压根不是一回事:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 // HostnameOverride specifies an explicit override for the pod's hostname as perceived by the pod. // This field only specifies the pod's hostname and does not affect its DNS records. // When this field is set to a non-empty string: // - It takes precedence over the values set in `hostname` and `subdomain`. // - The Pod's hostname will be set to this value. // - `setHostnameAsFQDN` must be nil or set to false. // - `hostNetwork` must be set to false. // // This field must be a valid DNS subdomain as defined in RFC 1123 and contain at most 64 characters. // Requires the HostnameOverride feature gate to be enabled. // // +featureGate=HostnameOverride // +optional HostnameOverride *string
注意看上面的 hostNetwork must be set to false.
,新版本的这个特性压根解决不了这个问题,只能是自己踩坑了。
结论 截止目前为止,k8s 的 Pod 同时配置 hostNetwork
和 hostname
下,容器内的 hostname 是宿主机的,docker 直接起这样配置的容器则没问题,如果你的进程依赖 hostname,则要注意这块。