zhangguanzhang's Blog

hostNetwork下hostname的坑

字数统计: 1.3k阅读时长: 6 min
2025/10/13
loading

最近升级和压测遇到的 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-0
0 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-0
0 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#L43C1-L45C3
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 -n1)
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
# staticPod
hostNetwork: true
hostname: kafka-{{ MY_ID }}

# docker-compose
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,则要注意这块。

CATALOG
  1. 1. 由来
  2. 2. 大小问题
  3. 3. hostname 问题
    1. 3.1. 两个带 hostname 目录的问题
    2. 3.2. hostname 问题
  4. 4. 结论