ACS PPU用户容器镜像开发实践

更新时间:
复制为 MD 格式

在日常容器使用场景中,可能会遇到需要在ACS集群中使用Docker构建镜像的诉求。本文介绍在ACS集群中如何使用Docker in Docker (DinD,需要特权模式)和Buildah(不需要特权模式)方式开发用户自定义容器镜像。

前提条件

使用Docker in Docker (DinD) 开发容器镜像

说明
  • dockerd的数据(--data-root 参数)默认存储在/var/lib/docker,如果想确保使用的storage driveroverlay2,需要把/var/lib/docker单独挂载成支持 overlay2 的文件系统。这里推荐使用emptyDir的方式来调整/var/lib/docker以支持overlay2。

  • 如果使用 buildkit 作为构建引擎,且想使用 overlayfs ,需要把/var/lib/buildkit单独挂载成支持 overlayfs的文件系统。这里推荐使用emptyDir的方式来调整/var/lib/buildkit以支持overlayfs。

  • 使用registry.cn-hangzhou.aliyuncs.com/acs-demo-ns/docker:27-dind容器镜像,需保证Pod环境能访问公网。

  • 使用Docker in Docker (DinD) 方式从Dockerfile构建容器镜像存在无法挂载PPU设备问题,建议使用Buildah方式构建镜像。

创建DinD Pod

  1. 将以下YAML内容保存acs-dind-demo.yaml。

    重要

    按量场景下,不同卡型的规格会有一定的差异,资源限制详细条件,请参见P16EN容量预留场景不受此限制。

    按量场景

    apiVersion: v1
    kind: Pod
    metadata:
      labels:
        alibabacloud.com/compute-class: gpu
        alibabacloud.com/gpu-model-series: PPU810E
        alibabacloud.com/compute-qos: default
        alibabacloud.com/hpn-type: "rdma" # 可选
      name: acs-dind-demo
    spec:
      containers:
      - image: registry.cn-hangzhou.aliyuncs.com/acs-demo-ns/docker:27-dind
        name: main
        resources: #根据需求调整资源
          limits:
            cpu: "16"
            ephemeral-storage: 256Gi
            memory: 128Gi
            alibabacloud.com/ppu: "2"
          requests:
            cpu: "16"
            ephemeral-storage: 256Gi
            memory: 128Gi
            alibabacloud.com/ppu: "2"
        volumeMounts:
        - mountPath: /var/lib/docker
          name: docker
        # 可选 使用buildkit需要设置
        - mountPath: /var/lib/buildkit
          name: buildkit
        securityContext:
          #  声明为特权容器,需要提交工单申请特权能力
          privileged: true
      volumes:
      - emptyDir: {}
        name: docker
      # 可选 使用buildkit需要设置
      - emptyDir: {}
        name: buildkit

    容量预留场景

    apiVersion: v1
    kind: Pod
    metadata:
      labels:
        alibabacloud.com/compute-class: gpu-hpn
        alibabacloud.com/gpu-model-series: PPU810E
        alibabacloud.com/compute-qos: default
        alibabacloud.com/hpn-type: "rdma"
      name: acs-dind-demo
    spec:
      containers:
      - image: registry.cn-hangzhou.aliyuncs.com/acs-demo-ns/docker:27-dind
        name: main
        resources: #根据需求调整资源
          limits:
            cpu: "16"
            ephemeral-storage: 256Gi
            memory: 128Gi
            alibabacloud.com/ppu: "2"
          requests:
            cpu: "16"
            ephemeral-storage: 256Gi
            memory: 128Gi
            alibabacloud.com/ppu: "2"
        volumeMounts:
        - mountPath: /var/lib/docker
          name: docker
        # 可选 使用buildkit需要设置
        - mountPath: /var/lib/buildkit
          name: buildkit
        securityContext:
          #  声明为特权容器,需要提交工单申请特权能力
          privileged: true
      volumes:
      - emptyDir: {}
        name: docker
      # 可选 使用buildkit需要设置
      - emptyDir: {}
        name: buildkit
  2. 执行以下命令,创建Pod。

    kubectl apply -f acs-dind-demo.yaml
  3. 执行以下命令,查看Pod状态。

    kubectl get pod acs-dind-demo

    预期输出:

    NAME            READY   STATUS    RESTARTS   AGE
    acs-dind-demo   1/1     Running   0          7m41s

DinD Pod中进行PPU镜像开发工作

说明
  • 增量开发PPU的容器镜像需要做显式镜像仓库登录操作才能拉取镜像作为Base镜像,具体docker login命令行请参见ACS容器镜像鉴权方式。PPU容器镜像可以从ACS容器镜像版本发布记录获取,注意本场景只能使用公网镜像地址。

  • DinD中拉起一个PPU的容器需要使用特权模式docker run --privileged启动容器。

  • 构建的新镜像需要推送到您自己的镜像仓库,阿里云提供的镜像仓库只提供拉取权限、不支持上传操作。

DinD Pod中启动一个内层特权PPU容器,在内层PPU容器中安装软件后,到外层DinD Pod中将内层PPU容器环境Commit成新自定义容器镜像。主要步骤如下:

  1. 准备PPU容器镜像(作为新镜像的Base镜像),并拉取到DinD容器内。

    1. (如果使用ACS提供的标准镜像)需要执行docker login进行仓库鉴权,然后执行docker pull拉取PPU容器镜像到DinD容器内。

    2. (如果使用自定义的镜像)您转存的PPU容器镜像可以直接拉取到DinD容器内。

  2. DinD容器内执行id=$(docker run -tid --privileged {ppu-image-uri} bash)命令启动一个内层PPU容器,执行docker exec -it $id bash命令进入内层PPU容器。

  3. 在内层PPU容器内,您可以像使用普通Linux主机一样安装Linux软件包、Python PIP软件包(把Dockerfile 中安装命令转成Shell脚本或者手动执行)。

  4. 安装完成并清理临时文件后,在内层PPU容器中执行exit退出到外层DinD容器中。

  5. DinD容器中执行docker commit $id {new-image}:{new-tag}命令Commit内部PPU容器环境为新容器镜像,推送新镜像到您自己的镜像仓库的详细步骤,请参见使用企业版实例推送和拉取镜像

  6. 新镜像开发完成后,执行docker stop $id && docker rm $id退出并删除内层PPU容器。

使用Buildah构建用户自定义容器镜像

说明
  • 使用registry-cn-hangzhou.ack.aliyuncs.com/ack-demo/buildah:v1.40.1容器镜像,需保证Pod环境能访问公网。

  • 本例将容器镜像构建步骤单独手动执行,如需查看包含构建步骤的完整YAML文件,您可以参考ACS实例运行镜像构建任务一站式构建容器镜像。请注意:您构建镜像使用的Dockerfile以及依赖文件请通过volume挂载到Pod中,本例中并未包含这部分内容。更多详细的内容,您可参考存储概述

  • 使用Buildah建议使用ACS按量模式,如果要使用“容量预留”,可以自行替换metadata.labels即可。

创建Buildah Pod

  1. 将以下YAML内容保存acs-buildah-demo.yaml

    重要

    按量场景下,不同卡型的规格会有一定的差异,资源限制详细条件,请参见P16EN容量预留场景不受此限制。

    kind: Pod
    apiVersion: v1
    metadata:
      name: acs-buildah-demo
      labels:
        alibabacloud.com/compute-class: gpu
        alibabacloud.com/gpu-model-series: PPU810E
        alibabacloud.com/compute-qos: default
    spec:
      restartPolicy: OnFailure
      volumes:
      - emptyDir: {}
        name: buildah
      containers:
      - name: builder
        image: registry-cn-hangzhou.ack.aliyuncs.com/ack-demo/buildah:v1.40.1
        command:
        - sh
        - -c
        - sleep infinity 
        imagePullPolicy: Always
        volumeMounts:
        - mountPath: /var/lib/containers/storage
          name: buildah
        resources: #根据需求调整资源
          limits:
            cpu: "16"
            memory: "128Gi"
            ephemeral-storage: 500Gi
            alibabacloud.com/ppu: 2
          requests:
            cpu: "16"
            memory: "128Gi"
            ephemeral-storage: 500Gi
            alibabacloud.com/ppu: 2
  2. 执行以下命令,创建Pod。

    kubectl apply -f acs-buildah-demo.yaml
  3. 执行以下命令,查看Pod状态。

    kubectl get pod acs-buildah-demo

    预期输出:

    NAME               READY   STATUS    RESTARTS   AGE
    acs-buildah-demo   1/1     Running   0          7m41s

Buildah Pod中构建自定义容器镜像

说明
  • 增量开发PPU的容器镜像需要做显式镜像仓库登录操作才能拉取镜像作为Base镜像,具体buildah login命令行请参见ACS容器镜像鉴权方式。PPU容器镜像可以从ACS容器镜像版本发布记录获取,注意本场景只能使用公网镜像地址。

  • 构建的新镜像需要推送到您自己的镜像仓库,阿里云提供的镜像仓库只提供拉取权限、不支持上传操作。

主要步骤如下:

  1. 执行cd命令切换到Dockerfile目录 。

    PPU容器镜像为Base镜像的Dockerfile示例:

    # 如果使用ACS提供的标准镜像
    # FROM egslingjun-registry.cn-wulanchabu.cr.aliyuncs.com/egslingjun/{image:tag}
    
    # 也可以使用您转存的PPU镜像
    # FROM {customers-docker-registery}/{image:tag}
    
    # 其他Dockerfile命令省略
  2. (可选步骤)如果使用ACS提供的标准镜像作为Base镜像,需要执行buildah login进行仓库鉴权。

  3. 执行buildah --storage-driver=overlay build -t test:v1 .命令进行镜像构建。

  4. (可选步骤)检查构建镜像buildah --storage-driver=overlay images

  5. 将新镜像推送到您自己的镜像仓库:

    1. 登录仓库:buildah login -u "{LOGIN_USERNAME}" -p "{LOGIN_PASSWORD}" {target-registry-domain}

    2. 推送镜像到仓库:buildah --storage-driver=overlay push test:v1 docker://{target-registry-prefix}/{target-image}

常见问题

ACS VPCIP地址段设置为172.17.0.0/16时,拉起的DinD Pod无法远程登录,如何解决?

  • 问题分析:问题产生是因为ACS PodDocker默认地址是172.17.0.0/16网段和VPC的地址网段冲突了。

  • 解决方法:您可以使用以下方法指定 dockerd 的 bip 参数用于修改 dockerd 默认网段,相关操作如下:

    1. 创建一个ConfigMap,其中bip字段可自定义为一个不冲突的其他地址段,比如192.168.5.1/24

      kubectl create configmap docker-daemon-config \
        --from-literal=daemon.json='{
        "bip": "192.168.5.1/24"
      }' \
        -n <your-namespace>  # 如果不指定-n,则创建在default命名空间
    2. 将下面的Volume挂载代码,添加到创建DinD PodYAML文件中,将ConfigMap挂载到DinD容器中。

              volumeMounts:
              - name: docker-config-volume
                mountPath: /etc/docker/daemon.json  
                subPath: daemon.json                
      
            
            volumes:
            - name: docker-config-volume
              configMap:
                name: docker-daemon-config
                items:
                - key: daemon.json         
                  path: daemon.json