ACS PPU用户容器镜像开发实践
在日常容器使用场景中,可能会遇到需要在ACS集群中使用Docker构建镜像的诉求。本文介绍在ACS集群中如何使用Docker in Docker (DinD,需要特权模式)和Buildah(不需要特权模式)方式开发用户自定义容器镜像。
前提条件
本文档适用于PTG提供的PPU PIP服务(显式鉴权)和阿里云提供的PPU PIP服务(免密)。具体操作,请参见在ACS上使用PPU PIP服务。
已创建ACS集群。
使用Docker in Docker需要为容器开通特权,请提交工单申请开通。
使用Docker in Docker (DinD) 开发容器镜像
dockerd的数据(--data-root 参数)默认存储在/var/lib/docker,如果想确保使用的storage driver为overlay2,需要把/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
将以下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执行以下命令,创建Pod。
kubectl apply -f acs-dind-demo.yaml执行以下命令,查看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成新自定义容器镜像。主要步骤如下:
准备PPU容器镜像(作为新镜像的Base镜像),并拉取到DinD容器内。
(如果使用ACS提供的标准镜像)需要执行
docker login进行仓库鉴权,然后执行docker pull拉取PPU容器镜像到DinD容器内。(如果使用自定义的镜像)您转存的PPU容器镜像可以直接拉取到DinD容器内。
在DinD容器内执行
id=$(docker run -tid --privileged {ppu-image-uri} bash)命令启动一个内层PPU容器,执行docker exec -it $id bash命令进入内层PPU容器。在内层PPU容器内,您可以像使用普通Linux主机一样安装Linux软件包、Python PIP软件包(把Dockerfile 中安装命令转成Shell脚本或者手动执行)。
安装完成并清理临时文件后,在内层PPU容器中执行
exit退出到外层DinD容器中。在DinD容器中执行
docker commit $id {new-image}:{new-tag}命令Commit内部PPU容器环境为新容器镜像,推送新镜像到您自己的镜像仓库的详细步骤,请参见使用企业版实例推送和拉取镜像。新镜像开发完成后,执行
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
将以下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执行以下命令,创建Pod。
kubectl apply -f acs-buildah-demo.yaml执行以下命令,查看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容器镜像版本发布记录获取,注意本场景只能使用公网镜像地址。构建的新镜像需要推送到您自己的镜像仓库,阿里云提供的镜像仓库只提供拉取权限、不支持上传操作。
主要步骤如下:
执行
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命令省略(可选步骤)如果使用ACS提供的标准镜像作为Base镜像,需要执行
buildah login进行仓库鉴权。执行
buildah --storage-driver=overlay build -t test:v1 .命令进行镜像构建。(可选步骤)检查构建镜像
buildah --storage-driver=overlay images。将新镜像推送到您自己的镜像仓库:
登录仓库:
buildah login -u "{LOGIN_USERNAME}" -p "{LOGIN_PASSWORD}" {target-registry-domain}。推送镜像到仓库:
buildah --storage-driver=overlay push test:v1 docker://{target-registry-prefix}/{target-image}。
常见问题
当ACS VPC的IP地址段设置为172.17.0.0/16时,拉起的DinD Pod无法远程登录,如何解决?
问题分析:问题产生是因为ACS Pod内Docker默认地址是172.17.0.0/16网段和VPC的地址网段冲突了。
解决方法:您可以使用以下方法指定 dockerd 的 bip 参数用于修改 dockerd 默认网段,相关操作如下:
创建一个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命名空间将下面的Volume挂载代码,添加到创建DinD Pod的YAML文件中,将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