前一篇文章已經(jīng)對(duì) Jetson-containers 的容器創(chuàng)建腳本進(jìn)行較為深入的說(shuō)明,主要是為了更廣泛地適用于不同 JetPack 版本的環(huán)境,因此使用嵌套式腳本的處理方式,初看之下會(huì)覺(jué)得相當(dāng)繁瑣,不過(guò)只要將腳本之間負(fù)責(zé)傳遞信息的變量?jī)?nèi)容理清,就會(huì)有種豁然開朗的感覺(jué),并不難懂。
本文將帶大家繼續(xù)深入了解 Dockerfile 鏡像創(chuàng)建過(guò)程中最重要的配置文件內(nèi)容,更加透徹地了解整個(gè)容器鏡像的創(chuàng)建過(guò)程。
3、使用 docker_build.sh 腳本創(chuàng)建容器:
在 scripst/docker_build_ml.sh 里有三處調(diào)用 scripst/docker_build.sh 腳本的部分,才是真正創(chuàng)建個(gè)別容器的環(huán)節(jié)。
以創(chuàng)建 l4t-pytorch 的 build_pytorch() 函數(shù)為例,在第 26 行調(diào)用 docker_build.sh 腳本并提供所有需要的相關(guān)參數(shù):
sh ./scripts/docker_build.sh $pytorch_tag Dockerfile.pytorch --build-arg BASE_IMAGE=$BASE_IMAGE --build-arg PYTORCH_URL=$pytorch_url --build-arg PYTORCH_WHL=$pytorch_whl --build-arg TORCHVISION_VERSION=$vision_version --build-arg TORCHAUDIO_VERSION=$audio_version --build-arg TORCH_CUDA_ARCH_LIST=$cuda_arch_list --build-arg OPENCV_URL=$OPENCV_URL --build-argOPENCV_DEB=$OPENCV_DEB
再看看 docker_build.sh 內(nèi)容,里面里其實(shí)只有 “docker build -t $CONTAINER -f $DOCKERFILE "$@" .” 這一道創(chuàng)建鏡像的指令,而相關(guān)所需要的參數(shù)都在上圖中做好完整的配置。
這里調(diào)用了主目錄下的 Dockerfile.pytorch,并且以 “--build-arg” 方式將相關(guān)參數(shù)去對(duì)應(yīng) Dockerfile.pytorch 配置文件里的變量,這些變量在 Dockerfile 里可能會(huì)提供預(yù)設(shè)值,但是這些新的設(shè)定值就會(huì)覆蓋掉配置文件的預(yù)設(shè)值。
創(chuàng)建 l4t-tensorflow 鏡像的方式也是一樣的,在第 172 行 buidl_tensorflow() 函數(shù)里第 181~187 行內(nèi)容(如下),也是調(diào)用 docker_build.sh 腳本去執(zhí)行,不過(guò)配置文件改成 Dockerfile.tensorflow,其他需要的參數(shù)也有所調(diào)整。
sh ./scripts/docker_build.sh $tensorflow_tag Dockerfile.tensorflow --build-arg BASE_IMAGE=$BASE_IMAGE --build-arg TENSORFLOW_URL=$tensorflow_url --build-arg TENSORFLOW_WHL=$tensorflow_whl --build-arg PROTOBUF_VERSION=$protobuf_version --build-arg OPENCV_URL=$OPENCV_URL --build-argOPENCV_DEB=$OPENCV_DEB
在第 275~281 行用同樣的模式去創(chuàng)建 l4t-ml 鏡像,同樣調(diào)用 docker_build.sh 腳本,不過(guò)配置文件換成 Dockerfile.ml,相關(guān)配套參數(shù)也要根據(jù)配置文件內(nèi)的實(shí)際狀況進(jìn)行調(diào)整,這里就不重復(fù)說(shuō)明。
4、分析 Dockerfile 內(nèi)容:
這個(gè)項(xiàng)目所提供的腳本,主要功能是為將對(duì)應(yīng)的 Dockerfile 進(jìn)行變量配置的工作,現(xiàn)在以創(chuàng)建 l4t-ml 鏡像會(huì)使用到的 Dockerfile.pytorch、Dockerfile.tensorflow 與 Dockerfile.ml 為例,簡(jiǎn)單說(shuō)明一下幾個(gè)環(huán)節(jié):
1)檢查 Dockerfile 的變量
可以用文字編輯器打開這些文件,使用 “搜索” 功能查找關(guān)鍵字 “ARG”,就能輕松找到里面的各項(xiàng)變量與預(yù)設(shè)值。
下面列出 Dockerfile.pytorch 的 6 個(gè)變量與預(yù)設(shè)值:
ARG BASE_IMAGE=nvcr.io/nvidia/l4t-base:r32.4.4ARG PYTORCH_URL=https://nvidia.box.com/shared/static/xxx.whlARG PYTORCH_WHL=torch-1.2.0-cp36-cp36m-linux_aarch64.whlARG TORCHVISION_VERSION=v0.4.0ARG TORCH_CUDA_ARCH_LIST="5.3;6.2;7.2;8.7"ARGTORCHAUDIO_VERSION
下面列出 Dockerfile.tensorflow 的 9 個(gè)變量與預(yù)設(shè)值:
ARG BASE_IMAGEARG HDF5_DIR="/usr/lib/aarch64-linux-gnu/hdf5/serial/"ARG MAKEFLAGS=-j$(nproc)ARG PROTOBUF_VERSION=3.19.4ARG PROTOBUF_URL=https://。。。/v${PROTOBUF_VERSION}ARG PROTOBUF_DIR=protobuf-python-${PROTOBUF_VERSION}ARG PROTOC_DIR=protoc-${PROTOBUF_VERSION}-linux-aarch_64ARG TENSORFLOW_URL=https://。。。/。。。-linux_aarch64.whlARGTENSORFLOW_WHL=tensorflow-1.15.3+nv20.9-cp36-cp36m-linux_aarch64.whl
下面列出 Dockerfile.ml 的 10 個(gè)變量與預(yù)設(shè)值:
ARG BASE_IMAGE=nvcr.io/nvidia/l4t-base:r32.4.4ARG PYTORCH_IMAGEARG TENSORFLOW_IMAGEARG MAKEFLAGS=-j$(nproc) ARG PYTHON3_VERSION=3.8ARG CUPY_VERSION=v10.2.0ARG CUPY_NVCC_GENERATE_CODE="arch=compute_53。。。"ARG OPENCV_URL=https://nvidia.box.com/shared/static/。。。.gzARGOPENCV_DEB=OpenCV-4.5.0-aarch64.tar.gz
對(duì)照一下前面腳本所提供的參數(shù),這樣就能很輕松地了解前面腳本的任務(wù)與目的,如果前面腳本中有使用 “--build-arg” 設(shè)定的參數(shù)值,就會(huì)覆蓋配置文件內(nèi)的預(yù)設(shè)值。
2)導(dǎo)入所需要的基礎(chǔ)鏡像
這種 docker build 創(chuàng)建容器的方式,是必須基于某個(gè)(些)已經(jīng)存在的基礎(chǔ)容器之上,添加的相關(guān)依賴庫(kù)與軟件,因此首要工作就是從 “FROM ${BASE_IMAGE}” 導(dǎo)入指定的基礎(chǔ)鏡像開始,在 Dockerfile.pytorch 與 Dockerfile.tensorflow 就是如此,不過(guò)在 Dockerfile.ml 文件中還多了以下兩行內(nèi)容:
FROM ${PYTORCH_IMAGE} as pytorchFROM${TENSORFLOW_IMAGE}astensorflow
就是要從這兩個(gè)鏡像里提取 PyTorch 與 Tensorflow 的配套資源,如下所列的指令:
COPY --from=tensorflow /usr/local/bin/protoc /usr/local/binCOPY --from=tensorflow /usr/local/lib/libproto* /usr/local/lib/COPY --from=tensorflow /usr/local/include/google /usr/local/include/googleCOPY --from=pytorch /usr/local/lib/python2.7/dist-packages/ /usr/local/lib/python2.7/dist-packages/COPY --from=pytorch /usr/local/lib/python${PYTHON3_VERSION}/dist-packages/ /usr/local/lib/python${PYTHON3_VERSION}/dist-packages/COPY --from=tensorflow /usr/local/lib/python2.7/dist-packages/ /usr/local/lib/python2.7/dist-packages/COPY--from=tensorflow/usr/local/lib/python${PYTHON3_VERSION}/dist-packages//usr/local/lib/python${PYTHON3_VERSION}/dist-packages/
這是比較有技巧的安排,然后使用者可以獨(dú)立創(chuàng)建 l4t-pytorch 與 l4t-tensorflow 鏡像,也可以將這兩個(gè)框架合并在 l4t-ml 鏡像內(nèi),此時(shí)只要將前面兩個(gè)鏡像已經(jīng)編譯安裝好的部分復(fù)制到新鏡像里面里就可以。
我們當(dāng)然也可以將 Dockerfile.pytorch 與 Dockerfile.tensorflow 里的安裝步驟全部放入 Dockerfile.ml 里面,不過(guò)這樣會(huì)讓整個(gè)配置文件變得非常冗長(zhǎng),估計(jì)要超過(guò) 400 行的內(nèi)容,其最大的麻煩之處是會(huì)導(dǎo)致除錯(cuò)工作變得相當(dāng)復(fù)雜與冗長(zhǎng),因此這里將處理過(guò)程進(jìn)行分割再做合并。
3)安裝依賴庫(kù)
在 Dockerfile 配置文件內(nèi)使用 “RUN” 指定后面要執(zhí)行的指令,后面加上 Ubuntu 使用的 apt-get install、pip install 等方式安裝依賴庫(kù)或軟件。由于鏡像的操作是設(shè)定為 root 用戶,因此不需要使用 "sudo" 去取得執(zhí)行權(quán)限。
這個(gè)環(huán)節(jié)的最大困難點(diǎn)是 “要安裝哪些內(nèi)容”?這就需要整理出軟件原廠所提供的依賴庫(kù)列表,這個(gè)過(guò)程是相對(duì)繁瑣的,而 Jetson-containers 項(xiàng)目所提供的 12 個(gè) Dockerfile 參考內(nèi)容,能讓我們節(jié)省很多摸索的時(shí)間。
4)需要編譯的部分:
例如在 Dockerfile.pytorch 里面執(zhí)行 torchvision 的編譯安裝步驟,如下內(nèi)容:
RUN git clone https://github.com/pytorch/vision torchvision && cd torchvision && git checkout ${TORCHVISION_VERSION} && python3 setup.py install && cd ../ && rm-rftorchvision
在 Dockerfile.tensorflow 文件里有執(zhí)行 protobuf 與 protoc 的編譯安裝步驟,如下內(nèi)容:
RUN cd /tmp && wget --quiet --show-progress --progress=barnoscroll --no-check-certificate ${PROTOBUF_URL}/$PROTOBUF_DIR.zip && wget --quiet --show-progress --progress=barnoscroll --no-check-certificate ${PROTOBUF_URL}/$PROTOC_DIR.zip && unzip ${PROTOBUF_DIR}.zip -d ${PROTOBUF_DIR} && unzip ${PROTOC_DIR}.zip -d ${PROTOC_DIR} && cp ${PROTOC_DIR}/bin/protoc /usr/local/bin/protoc && cd ${PROTOBUF_DIR}/protobuf-${PROTOBUF_VERSION} && ./autogen.sh && ./configure --prefix=/usr/local && make -j$(nproc) && make check -j4 && make install && ldconfig && cd python && python3 setup.py build --cpp_implementation && python3 setup.py test --cpp_implementation && python3 setup.py bdist_wheel --cpp_implementation && cp dist/*.whl /opt && pip3 install dist/*.whl && cd ../../../ && rm ${PROTOBUF_DIR}.zip && rm ${PROTOC_DIR}.zip && rm -rf ${PROTOBUF_DIR} && rm-rf${PROTOC_DIR}
在 Dockerfile.ml 里面執(zhí)行 OpenCV 的編譯安裝步驟,如下內(nèi)容:
ARG OPENCV_URL=https://nvidia.box.com/shared/static/5v89u6g5rb62fpz4lh0rz531ajo2t5ef.gzARG OPENCV_DEB=OpenCV-4.5.0-aarch64.tar.gz COPY scripts/opencv_install.sh /tmp/opencv_install.shRUNcd/tmp&&./opencv_install.sh${OPENCV_URL}${OPENCV_DEB}
上面這三個(gè)部分是大部分創(chuàng)建深度學(xué)習(xí)相關(guān)應(yīng)用的 Docker 鏡像所需要的步驟,現(xiàn)在可以直接從 Jetson-containers 這些配置文件中,復(fù)制相關(guān)步驟到自己的配置文件中,節(jié)省大量的嘗試與摸索的時(shí)間。
5、小結(jié):
為智能邊緣設(shè)備創(chuàng)建 Docker 版本鏡像,對(duì)應(yīng)用工程師是一項(xiàng)非常重要的技能,因?yàn)檫@個(gè)關(guān)系到將來(lái)的大量部署與長(zhǎng)期維護(hù)的問(wèn)題,因此學(xué)習(xí)使用 “docker build” 指令配合 Dockerfile 配置文件的方式,是一項(xiàng)必備的能力。
這個(gè) Jetson-containers項(xiàng)目作者為了廣泛滿足各種狀況,特別是 JetPack 的 L4T 版本變化以及對(duì)應(yīng)的 TensorFlow、PyTorch、OpenCV 版本,因此使用多個(gè)變量進(jìn)行調(diào)節(jié),但這種方法會(huì)讓配置文件內(nèi)容變得相當(dāng)復(fù)雜。
本系列文章的目的就是為大家解開這些變量的意義,讓讀者能清楚識(shí)別出這些變量之間的關(guān)系,提升對(duì) Dockerfile 配置文件的了解,最終協(xié)助讀者進(jìn)一步簡(jiǎn)化出自己所需要的特定腳本與配置內(nèi)容,以自己創(chuàng)建 Docker 鏡像的能力。
-
OpenCV
+關(guān)注
關(guān)注
32文章
642瀏覽量
42856 -
英偉達(dá)
+關(guān)注
關(guān)注
22文章
3945瀏覽量
93661 -
鏡像
+關(guān)注
關(guān)注
0文章
178瀏覽量
11240 -
Docker
+關(guān)注
關(guān)注
0文章
515瀏覽量
12947
原文標(biāo)題:NVIDIA Jetson 系列文章(11):從頭創(chuàng)建Jetson的容器(2)
文章出處:【微信號(hào):NVIDIA-Enterprise,微信公眾號(hào):NVIDIA英偉達(dá)企業(yè)解決方案】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
如何判斷是否在docker鏡像中?
Docker上的Alpine Linux鏡像建立
淺析Docker鏡像本地存儲(chǔ)機(jī)制及容器啟動(dòng)原理
Docker—簡(jiǎn)介與鏡像用法

go項(xiàng)目怎么讓docker鏡像體積減小
Docker鏡像的詳細(xì)講解
減少docker鏡像大小的方法

Docker 教程:如何將Helix QAC作為容器創(chuàng)建并運(yùn)行

docker 搜索鏡像,docker查看鏡像詳細(xì)信息(docker下載鏡像命令)
如何使用dockerfile創(chuàng)建鏡像
手動(dòng)構(gòu)建Docker鏡像的方法

Docker-鏡像的分層-busybox鏡像制作

docker-proxy鏡像加速倉(cāng)庫(kù)

基于Docker鏡像逆向生成Dockerfile

評(píng)論