You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GitLab-runner使用podman执行器时内部容器网络异常排查

问题背景
  • 本地执行podman play kube pod.yaml可正常启动Pod,应用运行正常
  • 在以podman为执行器的GitLab-runner环境执行相同命令时出现多类网络异常
  • GitLab runner版本:14.9.2(CI runner)、15.0.0(本地GitLab runner)
  • 已配置参数:启动gitlab-runner时添加--privileged与--network=host参数,Pod配置中设置hostNetwork: true与privileged: true
现象汇总
  1. GitLab-runner内启动的容器无法访问外部网络(无法执行软件包安装等操作),但GitLab-runner容器自身可正常访问外部网络
  2. 无论在GitLab-runner环境还是本地环境,访问POD_NAME:8080/均提示connection refused;宿主机直接访问localhost:8080可正常加载页面,runner环境内访问localhost:8080提示“No route to host”
  3. 两类环境启动的容器/etc/hosts配置存在明显差异
  4. 同Pod内容器可通过所有端口互相访问,该特性在两类环境中均生效

本地环境容器/etc/hosts内容

127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
10.88.0.113 cqe dd88a3440675-infra
127.0.1.1 cqe cqe-dispatcher
127.0.1.1 cqe cqe-umbsender
127.0.1.1 cqe cqe-frontend
127.0.1.1 cqe cqe-db
127.0.1.1 cqe cqe-umbreader

GitLab-runner内容器/etc/hosts内容

127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
10.88.0.117 runner--project-0-concurrent-0 runner--project-0-concurrent-0-d244dbca3614d5aa-build-2
10.88.0.2   cqe 4a46f7216e30-infra
10.88.0.1 host.containers.internal
10.88.0.117 host.containers.internal

测试用Pod网络相关配置

apiVersion: v1
kind: Pod
metadata:
  labels:
  name: cqe
spec:
  hostNetwork: true
  privileged: true
  restartPolicy: Always

  containers:
    - name: db
    - name: frontend
      securityContext:
        runAsUser: 5000
        runAsGroup: 5000
      ports:
        - containerPort: 8080
          hostPort: 8080
          protocol: TCP
    - name: dispatcher
      securityContext:
        runAsUser: 5000
        runAsGroup: 5000
    - name: umbreader
      workingDir: /clusterqe-django
      securityContext:
        runAsUser: 5000
        runAsGroup: 5000
    - name: umbsender
      workingDir: /clusterqe-django
      securityContext:
        runAsUser: 5000
        runAsGroup: 5000
问题根因与解答

1. GitLab-runner内启动的容器无法访问外部网络的原因

核心原因是嵌套容器场景下Pod配置的hostNetwork: true未实际生效。

  • 本地裸金属环境运行podman时,podman有权限直接操作宿主机网络命名空间,hostNetwork: true参数生效,Pod直接复用宿主机网络栈,可以正常访问外网。
  • GitLab-runner本身是运行在宿主机上的容器,其内部安装的podman属于嵌套运行的容器引擎。即使给runner配置了--privileged和--network=host,runner内部的podman默认仍会创建独立的CNI网桥(即10.88.0.0/16网段的内部网络)给启动的Pod使用,不会真正复用外层宿主机的网络栈。
  • 这种场景下,内部CNI网桥的流量没有配置对应的iptables源地址转换(MASQUERADE)规则,同时runner容器默认未开启IP转发,导致10.88.0.0/16网段的Pod流量无法转发到外部网络,自然无法访问外网。而runner容器本身直接使用宿主机网络,所以自身外网访问正常。

2. 无法通过Pod名访问暴露端口的原因

两类环境下该问题的根因不同:

  • 本地环境:hostNetwork生效时,podman会自动在每个容器的/etc/hosts中添加127.0.1.1 <Pod名> <容器名>的解析条目,但127.0.1.1属于容器自身的回环地址。部署的frontend服务是绑定在宿主机网络栈的8080端口,不是绑定在每个业务容器自身回环的8080端口,访问解析到127.0.1.1的Pod名时自然会提示connection refused。
  • GitLab-runner环境:hostNetwork未生效,podman给Pod创建了独立的网络命名空间,/etc/hosts中Pod名cqe解析到10.88.0.2,这是Pod的infra容器(仅用于持有网络命名空间的基础容器)的IP,infra容器本身不运行任何业务服务,也没有做8080端口的映射,访问该IP的8080端口必然被拒绝。
  • 额外说明:同Pod内的容器共享网络命名空间,直接访问localhost:端口即可访问同Pod其他容器的服务,不需要通过Pod名访问。

3. 两类环境/etc/hosts配置存在差异的原因

差异完全来自hostNetwork参数是否生效:

  • 本地环境hostNetwork生效,Pod没有独立的网络命名空间和独立CNI IP,podman会按照hostNetwork模式的规则生成hosts文件:将Pod名、各容器名解析到127.0.1.1的本地回环地址,infra条目解析到宿主机在CNI网桥的IP。
  • GitLab-runner内hostNetwork未生效,Pod被分配了独立的CNI网段IP,podman按照默认bridge网络模式生成hosts文件:将Pod名解析到infra容器的独立IP,额外添加host.containers.internal条目用于访问宿主机,和hostNetwork模式的生成逻辑完全不同。
修复方案
  • 优先方案:启动GitLab-runner时,将宿主机的podman socket(/run/podman/podman.sock)、容器存储目录(/var/lib/containers)挂载进runner容器,让runner内的podman命令直接调用宿主机的podman服务,避免嵌套运行容器引擎,hostNetwork等参数就可以和本地环境表现一致。
  • 若必须使用嵌套podman:需要在runner容器内部开启IP转发,配置CNI网桥的iptables MASQUERADE规则,允许10.88.0.0/16网段的流量转发到外网;同时在Pod配置中添加hostAliases,将Pod名解析到127.0.0.1,即可通过Pod名访问同Pod服务。
  • 同Pod服务访问统一使用localhost:端口的方式,不要依赖Pod名解析,避免不同环境下解析规则差异导致的异常。

内容的提问来源于stack exchange,提问作者hrondor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.02 04:01:23