记一下刚刚发生的 Docker Push 一直重试,最后报错 received unexpected HTTP status: 503 Service Unavailable 的事。

我们目前的 Harbor DR 架构见 我们的 Habror 灾备架构,晚 7 点做了切换,入口从 A 切换到 B。

切换之后约一小时,有用户报错说,CI 里面的 Docker Push 一直失败,打包出来的镜像 Push 不了。

查了一会之后,无果,先回退了。

当时现象

  1. 随便找了一台机器,Docker Push 正常。
  2. 在 CI 的机器上面 Push,一直 Retry,最后 503 失败,报错如上。
  3. Harbor Access 日志中没有 503 的请求。
  4. Harbor Access 日志中以此 repo 名字过滤,没有结果。

最终诊断

要搞清楚原因,需要先了解两个知识点

  1. registry 里面的 redirect 配置。比如我请求一个 Blob,Registry 会返回一个 307,重定向到后端存储。这个默认是开启的,但要看后端的 Storage 是不是支持。像本地文件系统和 Swift 不支持,S3 是支持的。

  2. Docker Push 的整个过程。这次故障涉及的是 Layer 的上传:简单说,先 HEAD 看 Layer 是不是存在,然后再 Post 数据。

问题就出在这个 HEAD 请求上面,因为 B 集群后面使用了 S3,所以 307 重定向到了 S3 的服务上面。出问题的机器是配置了 Proxy 的,NoProxy 配置里面没有包含 S3的域名,导致 HEAD 失败了。

如何解决

两个办法吧,一是所有 CI 的机器的 Docker 配置更新 NoProxy 配置,把泛域名的范围扩大一些。 二是给 S3 再创建一个新的域名,可以包含在 NoProxy 里面的。