用ACS实例运行镜像构建任务

在日常容器使用场景中,可能会遇到需要在ACS集群中构建镜像的诉求。本文介绍在ACS集群如何启动buildah Pod来创建新的容器镜像并推送到仓库。

基本功能验证

准备工作

已创建一个ACS集群

网络

在ACS集群中构建镜像的过程中对网络的诉求主要是在推送和拉取中,在开始构建镜像前,请先确保:

  1. Pod中对base镜像仓库拉取的网络连通性。

  2. Pod中对push目标镜像仓库的网络连通性。

创建验证Pod

ACS提供一个基于buildah社区标准能力构建的功能验证镜像,可以按照下面的YAML在ACS集群中创建一个Pod。

验证Pod会构建一个仅安装了bash和coreutils的镜像,并将其推送到在环境变量中指定的仓库中。

可以通过Pod的标准输出日志看到Pod内执行的命令,如果Pod可以正常结束,这说明环境已经满足了在集群中使用buildah构建镜像的基本能力,可以进一步添加业务逻辑。

kind: Pod 
apiVersion: v1
metadata:
  name: buildah-demo-pod
spec:
  containers:
  - name: builder
    image: registry.cn-hangzhou.aliyuncs.com/acsimage/buildah:sampleBuild
    env:
      - name: LOGIN_USERNAME
        value: "TODO:targetRepoLoginUsername"
      - name: LOGIN_PASSWORD
        value: "TODO:targetRepoLoginPassword"
      - name: TAREGET_REPO
        value: "registry.cn-hangzhou.aliyuncs.com/yourRepoNS/yourRepoName:testTag"
      - name: TARGET_HOSTNAME
        value: "registry.cn-hangzhou.aliyuncs.com"
      - name: IMAGE_NAME
        value: "buildahTestImage"
      - name: IMAGE_CREATOR
        value: "yourName"
    command: ["/home/build/build.sh"]
    imagePullPolicy: Always
    resources:
      limits:
        cpu: "1"
        memory: "2Gi"
      requests:
        cpu: "1" 
        memory: "2Gi"
    restartPolicy: OnFailure

在启动上面YAML前,需要修改一些环境变量,每个环境变量含义如下。

环境变量键

环境变量含义

LOGIN_USERNAME

用于登录推送目标仓库的username。

LOGIN_PASSWORD

用于登录推送目标仓库的password。

TAREGET_REPO

推送目标仓库的地址:tag。

TARGET_HOSTNAME

推送目标仓库的域名。

IMAGE_NAME

构建出镜像元信息中记录的镜像名(不会影响镜像构建和推送)。

IMAGE_CREATOR

构建出镜像元信息中记录的构建者(不会影响镜像构建和推送)。

构建标准OCI镜像

ACS提供一个buildah社区标准能力的基础镜像,可以以此镜像为基础搭建后续的构建逻辑。

registry.cn-hangzhou.aliyuncs.com/acsimage/buildah:latest
说明

ACS会定期从quay.io/buildah/stable:latest同步镜像到此仓库,但是并不能保证时效性。如果希望确保用到社区最新版本,可以考虑使用社区最新Release或从源代码构建。

通过外部存储来加速镜像构建

如果选择通过Dockerfile构建容器镜像,且希望复用base image的内容,无需在每次构建的时候重新下载base image,可以考虑通过外部存储作为buildah的后端缓存,在启动镜像构建容器时挂载并使用该存储来加速镜像构建流程。

准备工作

  1. 需要准备一个ACS集群。具体操作,请参见创建ACS集群

  2. 需要在ACS集群准备一个外部存储介质,它在集群中以PVC的形式存在。具体操作,请参见存储概述(下文会以nas-pvc指代该PVC)。

填充外部存储

可以选择任意方式来将希望缓存并共享的base image(base layer)填充到外部存储介质中,我们这里会以将ACR制品中心的alinux3镜像(alibaba-cloud-linux-3-registry.cn-hangzhou.cr.aliyuncs.com/alinux3/alinux3:230602.1)填充到一个NAS实例(NAS存储卷概述)作为例子来演示流程。

  1. 按照如下YAML创建一个Pod。

    创建后,会生成以下配置。

    1. 以registry.cn-hangzhou.aliyuncs.com/acsimage/buildah:sampleBuild为基础,启动一个内置社区buildah二进制的容器。

    2. 将外部存储实例挂载到该容器的buildah全局缓存目录(默认为/var/lib/containers/storage)。

    3. 运行buildah pull alibaba-cloud-linux-3-registry.cn-hangzhou.cr.aliyuncs.com/alinux3/alinux3:230602.1,将我们想要的base镜像填充到NAS实例中。

      kind: Pod 
      apiVersion: v1
      metadata:
        name: filler-pod
      spec:
        containers:
        - name: builder
          image: registry.cn-hangzhou.aliyuncs.com/acsimage/buildah:sampleBuild
          command: ["buildah", "pull", "alibaba-cloud-linux-3-registry.cn-hangzhou.cr.aliyuncs.com/alinux3/alinux3:230602.1"]
          imagePullPolicy: Always
          resources:
            limits:
              cpu: "1"
              memory: "1Gi"
            requests:
              cpu: "1" 
              memory: "1Gi" 
          volumeMounts:
            - name: nas 
              mountPath: "/var/lib/containers/storage"
        restartPolicy: OnFailure
        volumes:
        - name: nas 
          persistentVolumeClaim:
            claimName: nas-pvc
  2. 删除该Pod,再次使用如下YAML创建一个Pod。

    创建后,会生成以下配置。

    1. 以registry.cn-hangzhou.aliyuncs.com/acsimage/buildah:sampleBuild为基础,启动一个内置社区buildah二进制的容器。

    2. 将外部存储实例挂载到该容器的buildah全局缓存目录(默认为/var/lib/containers/storage)。

    3. 通过sampleBuild镜像内置的Dockerfile构建一个新的镜像。

      kind: Pod 
      apiVersion: v1
      metadata:
        name: builder-pod
      spec:
        containers:
        - name: builder
          image: registry.cn-hangzhou.aliyuncs.com/acsimage/buildah:sampleBuild
          command: ["buildah", "bud", "-t", "registry.cn-hangzhou.aliyuncs.com/acsimage/buildah:resultImage", "."]
          imagePullPolicy: Always
          resources:
            limits:
              cpu: "1"
              memory: "1Gi"
            requests:
              cpu: "1" 
              memory: "1Gi" 
          volumeMounts:
            - name: nas 
              mountPath: "/var/lib/containers/storage"
        restartPolicy: OnFailure
        volumes:
        - name: nas 
          persistentVolumeClaim:
            claimName: nas-pvc
  3. 通过日志buildah日志我们可以看到,用于构建的Pod并没有重新拉取alinux3镜像,而是复用了NAS实例中的缓存来构建镜像,节省了镜像下载的构建时间与开销。