posted

0 Comments

中国的防火墙对容器应用不是太友好,dockerhub里的映像还好,基本都可以访问,而所有基于gcr.io的映像都会被屏蔽。可不幸的是很多流行的应用所发布的映像都放在gcr.io中,导致应用无法部署。现在很多解决方案可以解决这个问题。例如通过一个可以访问gcr.io的终端,把映像下载到本地或者第三方映像注册表里,再将应用配置里的映像位置重定向到新的URL中去。这些方法有的比较繁琐,有的需要对原有的应用进行较大的改动。本文介绍一个名为kbld的工具,可以非常方便的进行映像的重定向,我们通常将它当成中国大陆容器工程师的必备工具之一。

1. 背景介绍

最近很多在VMware vSphere平台上部署 Kubernetes集群的用户经常向我咨询一些和容器映像相关的问题:

  1. 很多企业只能将数据中心部署在内网,容器映像注册表也是部署在内部的,无法和Internet进行互联,在这种情况下如何方便的将外面的容器应用部署到数据中心内部。
  2. 有些数据中心虽然能够和Internet相连,但是在国内无法访问gcr.io里的容器映像,导致很多流行的应用无法部署。这种情况下如何方便的将gcr.io里的映像方便的导入到企业内部,或者其他第三方注册表里。

在下面的章节中我们介绍三种不同的方式来进行容器映像重定向技术,目的是看看kbld这个工具有多方便多强大。

  1. 纯手动迁移,这是最麻烦的,但这是最容易理解的方式。有了对这种方式的理解,才能看到kbld工具的强大。
  2. 使用 “kbld relocate” 命令来进行重定向。这种方式用于你的终端同时既可以访问gcr.io又可以访问你们企业内部的容器映像仓库。
  3. 使用 “”kbld pkg / unpkg”命令来进行重定向。这种方式用于你的终端在同一时间里要么只能访问内网,要么只能访问外网(gcr.io),而不能同时访问两者的仓库。

本文章使用的例子是 “kpack” (详见:https://github.com/pivotal/kpack)中的部署文件,下面就是release.yaml (https://github.com/pivotal/kpack/releases/download/v0.1.2/release-0.1.2.yaml)的一部分文件内容:

可以看到,上面的yaml文件整合了多种kubernetes的资源,从上面标注为红色的部分能看出,这些资源对容器映像的引用有几十个之多(有很多是重复的),这些映像都指向gcr.io,如果没有代理在国内几乎都没有办法访问。

2. 手动方式进行映像重定向

通常使用”kubectl apply -f release-0.1.2.yaml”命令在你的Kubernetes集群里进行kpack的安装,除非你的worker node节点可以访问gcr.io,通常在中国大陆的部署都会失败,原因是所有的对gcr.io的访问都会网络超时。

如果我们自己要手动完成这个应用的部署,通常要包含以下步骤:

  1. 准备一个终端,需要能访问gcr.io,在终端上安装docker运行组件。(例如Docker Desktop)
  2. 找到国内第三方的映像仓库,注册账号。或者在企业内部安装自己的私有仓库,例如Harbor。你的终端也需要能访问这个仓库。
  3. 在终端上登录这个私有仓库。如果是用自签名的证书安装的Harbor,你还可能要导入Harbor的证书:
    • 通过浏览器登录到Harbor界面。选择你要访问的Project或者(Namespace)。转到“Repositories”页,下载注册表证书。
    • 将这个证书添加到本机的系统里,例如,在MacOS里需要运行下面的命令(最后的参数是刚才保存证书的文件路径):
    • 重启Docker服务
    • 用docker login登录到你的私有仓库
  1. 针对部署配置文件里的每一个image标签,都需要做以下的步骤
    • 将io的映像拉到本地
    • 给这个映像打标签,并push到你的私有仓库里(下面的例子中,147.18.2是我的Harbor服务的IP地址):
  1. 将yaml配置文件中的每一个image标签都替换成私有仓库的地址。
  2. 再用kubectl apply -f 作用于你的新配置文件

 

3. 使用kbld进行映像重定向

如果只有一两个配置文件和少量的image需要重新定向,手动的方式可能还能忍受。但是如果是一个较大的应用,有很多的配置部署文件,每个文件有很多的映像需要重新定向,那么手动去做这些事情将是个噩梦。使用kbld工具能够完全将上面手动的部署自动化,使你轻松的进行映像重定向。

  1. 安装kbld (https://get-kbld.io/),也可以安装整个carvel套件(其中包含了kbls)。安装步骤请参考:(https://carvel.dev/
  2. 需要你的终端可以同时访问io和私有映像仓库。
  3. docker login url来登录到你的私有映像仓库。
  4. 用kbld命令” kbld -f release-0.1.2.yaml –lock-output lockfile > temp.yaml” 收集部署配置文件中的所有映像,并且将它们转换成基于哈希值的标签。基于哈希值的标签有很多好处,可以唯一定位一个映像。而其他的标签(例如latest),不同时间有可能对应完全不同的映像。在我们这个例子中,部署配置文件中已经是基于哈希值的标签了。
  5. 从输出的lockfile可以看到kbld命令收集的所有需要重定向的映像。
  6. 使用命令“kbld relocate -f temp.yaml –repository docker.io/yuwang881/kpack –lock-output lockfilenew” 将刚才收集的所有映像,都重新定位到你指定的新的映像仓库中。在我们上面的例子中,我们将收集的所有映像都重定向到docker.io里我私有的仓库里。执行的输出如下图所示:
  7. 现在我们已经把所有的映像都从gcr.io导出(pull),并且导入(push)到我指定的私有仓库里。通过kbld工具,这些导入导出的过程都是自动完成的,而且任务完成后,本地环境里不留痕迹。大家可以自己用”docker images”来查看本地的映像列表,可以发现那些映像都没有在本地保留。而上面命令输出的”lockfilenew”文件,则记录了新旧映像的对应表。
  8. 最后一步是要修改我们原始的部署配置文件,替换里面所有的映像仓库的位置,把它们都指向我们私有仓库里的镜像。这个任务也可以通过kbld命令来自动完成。在我们的例子中使用命令:“kbld -f temp.yaml -f lockfilenew > my-release.yaml”。通过查看这个文件内容,你可以发现,新的部署配置文件(my-release.yaml)中,所有的映像都指向了我的私有映像仓库。在这个文件可以直接用“kubectl apply -f”来部署到你的Kubernetes集群中。

4. 用kbld进行映像备份

在实际生产环境中,有些客户还遇到这个情况,他们的公司数据中心的内网和外网是完全隔离的,也就是说,任何一个终端不可能在同一时间既能连接外部映像仓库,又能连接内部私有仓库。在这种情况下,还可以通过使用kbld的映像备份功能来完成映像导入导出的功能。

  1. 首先在能连接外网的环境里,用kbld命令” kbld -f release-0.1.2.yaml –lock-output lockfile” 收集部署配置文件中的所有映像。
  2. 用kbld的打包命令将所有收集的映像下载并且打包成一个tar文件:“kbld pkg -f lockfile –output packaged-images.tar”。
  3. 将终端切换到内网环境,先用docker login url登录到你的私有仓库,再用kbld的解包命令,将上一步生成的映像包导入到你指定的私有库里:“kbld unpack -f lockfile –input packaged-images.tar –repository docker.io/yuwang881/kpack –lock-output lockfilenew”
  4. 等到导入完成以后,使用新产生的重定向文件“lockfilenew”来更新你的部署配置文件“kbld -f release-0.1.2.yaml -f lockfilenew > my-release.yaml”。这一步和本文第三节描述的的最后一步是一样的,在这个文件可以直接用“kubectl apply -f”来部署到你的Kubernetes集群中。

5. 总结

在各种开发部署的环境下,有着对映像重定向的各种需求,不仅仅是防火墙,公司的内外网策略都会对容器应用部署带来影响。通过使用kbld这个工具可以较为方便的完成各种情况下的映像重定向的功能。当然除了映像重定向功能之外,kbld还有其他的功能,这不在本文的讨论范围中。映像备份功能不仅仅用于重定向,就如它的名字表明的,还可以用于整个应用的映像备份,这也非常有用。