1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        Docker進階-Dockerfile建立一個自定義的鏡像執(zhí)行自定義進程

        共 9452字,需瀏覽 19分鐘

         ·

        2022-12-17 19:22

        前言

        docker對我來說是一個很方便的工具,,上一篇文章也寫了docker基本的一些使用,這篇文章重點描述一下Dockerfile的使用,從零建立一個自己定制化的鏡像,并可以執(zhí)行我們需要的任務。

        作者:良知猶存

        轉載授權以及圍觀:歡迎關注微信公眾號:羽林君

        或者添加作者個人微信:become_me


        命令列表

        FROM 指定基礎鏡像:所謂定制鏡像,那一定是以一個鏡像為基礎,在其上進行定制。就像我們之前運行了一個 nginx 鏡像的容器,再進行修改一樣,基礎鏡像是必須指定的。而 FROM 就是指定 基礎鏡像,因此一個 Dockerfile 中 FROM 是必備的指令,并且必須是第一條指令

        RUN 執(zhí)行命令:RUN 指令是用來執(zhí)行命令行命令的。其格式有兩種:

        • shell 格式:RUN <命令>,就像直接在命令行中輸入的命令一樣。剛才寫的 Dockerfile 中的 RUN 指令就是這種格式
        • exec 格式:RUN ["可執(zhí)行文件", "參數(shù)1", "參數(shù)2"],這更像是函數(shù)調用中的格式。

        COPY 指令將從構建上下文目錄中 <源路徑> 的文件/目錄復制到新的一層的鏡像內的 <目標路徑> 位置

        ADD 指令和 COPY 的格式和性質基本一致。但是在 COPY 基礎上增加了一些功能。因此在 COPY 和 ADD 指令中選擇的時候,可以遵循這樣的原則,所有的文件復制均使用 COPY 指令,僅在需要自動解壓縮的場合使用 ADD。

        CMD 指令的格式和 RUN 相似,也是兩種格式:

        • shell 格式:CMD <命令>

        • exec 格式:CMD ["可執(zhí)行文件", "參數(shù)1", "參數(shù)2"...]

        參數(shù)列表格式:CMD ["參數(shù)1", "參數(shù)2"...]。在指定了 ENTRYPOINT 指令后,用 CMD 指定具體的參數(shù)。Docker 不是虛擬機,容器就是進程。既然是進程,那么在啟動容器的時候,需要指定所運行的程序及參數(shù)。CMD 指令就是用于指定默認的容器主進程的啟動命令的。

        ENTRYPOINT 的格式和 RUN 指令格式一樣,分為 exec 格式和 shell 格式。

        LABEL:你可以給鏡像添加標簽來幫助組織鏡像、記錄許可信息、輔助自動化構建等。每個標簽一行,由 LABEL 開頭加上一個或多個標簽對。下面的示例展示了各種不同的可能格式。# 開頭的行是注釋內容。

        EXPOSE:EXPOSE 指令用于指定容器將要監(jiān)聽的端口。因此,你應該為你的應用程序使用常見的端口。例如,提供 Apache web 服務的鏡像應該使用 EXPOSE 80,而提供 MongoDB 服務的鏡像使用 EXPOSE 27017。對于外部訪問,用戶可以在執(zhí)行 docker run 時使用一個標志來指示如何將指定的端口映射到所選擇的端口。

        ENV:為了方便新程序運行,你可以使用 ENV 來為容器中安裝的程序更新 PATH 環(huán)境變量。例如使用 ENV PATH /usr/local/nginx/bin:$PATH 來確保 CMD ["nginx"] 能正確運行。ENV 指令也可用于為你想要容器化的服務提供必要的環(huán)境變量,比如 Postgres 需要的 PGDATA。最后,ENV 也能用于設置常見的版本號,比如下面的示例:

        VOLUME:VOLUME 指令用于暴露任何數(shù)據(jù)庫存儲文件,配置文件,或容器創(chuàng)建的文件和目錄。強烈建議使用 VOLUME 來管理鏡像中的可變部分和用戶可以改變的部分。

        USER:如果某個服務不需要特權執(zhí)行,建議使用 USER 指令切換到非 root 用戶。先在 Dockerfile 中使用類似 RUN groupadd -r postgres && useradd -r -g postgres postgres 的指令創(chuàng)建用戶和用戶組。

        WORKDIR:為了清晰性和可靠性,你應該總是在 WORKDIR 中使用絕對路徑。另外,你應該使用 WORKDIR 來替代類似于 RUN cd ... && do-something 的指令,后者難以閱讀、排錯和維護。

        https://yeasy.gitbook.io/docker_practice/appendix/best_practices

        命令驗證執(zhí)行

        從docker build 開發(fā)

        先做個簡單編譯demo:

        FROM ubuntu:18.04

        USER root

        COPY sources.list /etc/apt/sources.list

        docker build . 當前目錄執(zhí)行 可以看到執(zhí)行情況,一共分為三步

        每條指令創(chuàng)建一層:

        此時通過docker images就可以看到我們編好的鏡像了,好了正式進入正題了。

        from命令幫助我們找尋原始鏡像

        第一行:FROM ubuntu:18.04from本質上等效于 docker pull命令,我們可以使用本地鏡像,也可以指定鏡像源,用如下

        FROM registry.hub.docker.com/library/ubuntu:18.04

        執(zhí)行效果:

        對于國內鏡像源大家可以從此文獲?。篽ttps://segmentfault.com/a/1190000023117518

        使用RUN命令安裝工具代替我們在容器執(zhí)行命令:

        RUN apt update 不要在腳本中使用apt命令,如果在腳本中使用apt命令,有可能會得到"WARNING: apt does not have a stable CLI interface. Use with caution in scripts." 提示。請使用apt-get、apt-cache等命令進行替換。apt命令不適合在腳本中運行,因為apt命令是為用戶(人)而設計的,它會有顏色的顯示、進度條顯示等一些友好的交互界面。而在腳本中,對于這些“特性”是不穩(wěn)定(不支持或者是輸出錯亂等)的。

        WARNING: apt does not have a stable CLI interface. Use with caution in scripts.

        修改為RUN apt-get update

        此外我們可以進行命令一次執(zhí)行完成

        RUN apt-get update
        RUN apt-get  --fix-broken install
        RUN  apt-get install -y gcc \
            zip\
            curl\
            python\
            kmod\
            openssh-server\
            sudo

        安裝之后進行 設置一個賬戶

        RUN groupadd -g 1011 lyn
        RUN useradd -d /home/lyn -m -s /bin/bash -u 1010 -g lyn lyn

        RUN mkdir -p /home/lyn/work\
        &&chown -R lyn:lyn /home/lyn

        RUN echo "lyn ALL=(ALL)    ALL" > /etc/sudoers

        RUN echo 'root:root' | chpasswd && echo 'lyn:lyn' | chpassswd

        WORKDIR /home/lyn/work

        USER lyn
        COPY .bashrc /home/lyn/.bashrc

        設置工具目錄,可以看到進去之后工具目錄被設置為/home/lyn,通過WORKDIR /home/lyn/work執(zhí)行。

        使用

        docker images 看一下打包好的鏡像

        看到有個沒有命名的包,就是我們剛剛編出來的

        這個時候我們進行改個名字

        docker tag IMAGEID(鏡像id) REPOSITORY:TAG(倉庫:標簽)

        docker tag 025673a91e65 lyn_image:v1

        啟動使用 這個時候給大家介紹 volume命令

        docker使用volume實現(xiàn)數(shù)據(jù)的持久化,不僅如此volume還能幫助容器和容器之間,容器和host之間共享數(shù)據(jù)。

        我們可以使用dockerfile的VOLUME或者 docker run -v參數(shù) ,直接設置需要掛載的目錄。

        在Dockerfile增加 VOLUME /home/lyn/work,開始編譯。

        編譯完成后,首先通過docker inspect查看我們編譯好的鏡像信息或者容器信息:

        docker inspect 47920709b10c 鏡像id進行查看是否設置掛載目錄

        docker inspect f4c2449431c5 啟動之后的容器id

        docker volume ls 可以看到當前所有的volume

        修改映射的文件夾內容

        sudo touch /var/lib/docker/volumes/567f9c362f6067b3b354bea8b0b370bf304b845ae18e38b125fbdaaface09cfb/_data/lyn.log

        可以看到文件已經同步過來了

        同樣我們也可以使用 docker run -v進行控制,首先注釋掉這句VOLUME /home/lyn/work,重新編譯鏡像

        docker run -v /home/lyn/docker_share:/home/lyn/work [imageid] -v A:B A是在主機上的地址,B是在容器中的地址,這兩個地址如果不存在都會創(chuàng)建,一旦容器運行,AB的會完全同步。

        具體執(zhí)行為:docker run -it -v /home/lyn/docker_share:/home/lyn/work 208aca0306ab /bin/bash

        關于volume更詳細的介紹大家可以看此文:https://docs.docker.com/engine/reference/commandline/volume_create/

        寫了一個循環(huán)執(zhí)行的代碼,編譯成固件,用dockerfile 編譯讓鏡像自動執(zhí)行

        COPY hello_world /home/lyn/work

        CMD ./hello_world

        docker run -it 47920709b10c

        最終的Dockerfile文件

        FROM ubuntu:18.04

        USER root

        COPY sources.list /etc/apt/sources.list

        RUN apt-get update
        RUN  apt-get install -y gcc \
            zip\
            curl\
            python\
            kmod\
            openssh-server\
            sudo


        RUN groupadd -g 1011 lyn
        RUN useradd -d /home/lyn -m -s /bin/bash -u 1010 -g lyn lyn

        RUN mkdir -p /home/lyn/work \
           &&chown -R lyn:lyn /home/lyn

        RUN echo "lyn ALL=(ALL)    ALL" > /etc/sudoers

        RUN echo 'root:root' | chpasswd && echo 'lyn:lyn' | chpasswd

        WORKDIR /home/lyn/work

        USER lyn
        COPY .bashrc /home/lyn/.bashrc


        VOLUME /home/lyn/work

        COPY hello_world /home/lyn/work

        CMD ./hello_world

        docker build執(zhí)行的log:因為有過編譯了,所以這里好多執(zhí)行就是Using cache,很少的打印了

        lyn@lyn:~/Documents/lyn_test/docker_build_ubuntu$ docker build .
        Sending build context to Docker daemon  28.16kB
        Step 1/16 : FROM ubuntu:18.04
         ---> 71eaf13299f4
        Step 2/16 : USER root
         ---> Using cache
         ---> d3fe45bd0e46
        Step 3/16 : COPY sources.list /etc/apt/sources.list
         ---> Using cache
         ---> d4f825c3fc77
        Step 4/16 : RUN apt-get update
         ---> Using cache
         ---> 3863a99d6e2b
        Step 5/16 : RUN  apt-get install -y gcc     zip    curl    python    kmod    openssh-server    sudo
         ---> Using cache
         ---> 9b77c43d6709
        Step 6/16 : RUN groupadd -g 1011 lyn
         ---> Using cache
         ---> bbba5f18057a
        Step 7/16 : RUN useradd -d /home/lyn -m -s /bin/bash -u 1010 -g lyn lyn

         ---> Using cache
         ---> 47e999f10256
        Step 8/16 : RUN mkdir -p /home/lyn/work    &&chown -R lyn:lyn /home/lyn
         ---> Using cache
         ---> 36faf04c6390
        Step 9/16 : RUN echo "lyn ALL=(ALL)    ALL" > /etc/sudoers
         ---> Using cache
         ---> 0422bf50db6b
        Step 10/16 : RUN echo 'root:root' | chpasswd && echo 'lyn:lyn' | chpasswd
         ---> Using cache
         ---> 68da5bb15877
        Step 11/16 : WORKDIR /home/lyn/work
         ---> Using cache
         ---> b30d4dcd99f8
        Step 12/16 : USER lyn
         ---> Using cache
         ---> 5dfa565d0c6a
        Step 13/16 : COPY .bashrc /home/lyn/.bashrc
         ---> Using cache
         ---> f2b39d61f05b
        Step 14/16 : VOLUME /home/lyn/work
         ---> Running in 5482493ab221
        Removing intermediate container 5482493ab221
         ---> 0e359e093a4f
        Step 15/16 : COPY hello_world /home/lyn/work
         ---> ac326932752c
        Step 16/16 : CMD ./hello_world
         ---> Running in 430cfd90ad30
        Removing intermediate container 430cfd90ad30
         ---> fc180e4919da
        Successfully built fc180e4919da

        補充操作:

        發(fā)現(xiàn)兩個鏡像的id相同,如果用docker rmi [鏡像id]它就不知道該如何刪除,我們可以用:

        Error response from daemon: conflict: unable to delete 71eaf13299f4 (must be forced) - image is referenced in multiple repositories

        docker rmi 鏡像名:版本號 當我建立錯誤的鏡像之后,使用rmi進行刪除

        結語

        這就是我自己的一些Dockerfile使用分享。如果大家有更好的想法和需求,也歡迎大家加我好友交流分享哈。

        此外對于想要更加細節(jié)的dockerfile使用可以官網的文章:https://docs.docker.com/engine/reference/builder/ https://docs.docker.com/develop/develop-images/dockerfile_best-practices/ 這篇文章:https://yeasy.gitbook.io/docker_practice/image/build


        作者:良知猶存,白天努力工作,晚上原創(chuàng)公號號主。公眾號內容除了技術還有些人生感悟,一個認真輸出內容的職場老司機,也是一個技術之外豐富生活的人,攝影、音樂 and 籃球。關注我,與我一起同行。

                                      ????????????????  END  ????????????????

        推薦閱讀

        【1】jetson nano開發(fā)使用的基礎詳細分享

        【2】Linux開發(fā)coredump文件分析實戰(zhàn)分享

        【3】CPU中的程序是怎么運行起來的 必讀

        【4】cartographer環(huán)境建立以及建圖測試

        【5】設計模式之簡單工廠模式、工廠模式、抽象工廠模式的對比

        本公眾號全部原創(chuàng)干貨已整理成一個目錄,回復[ 資源 ]即可獲得。


        瀏覽 53
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            无码视频中文字幕 | 9色视频 97人妻人人揉人人躁 原 | 亚洲精品一卡 | 欧美日韩第一页 | 成都私人高清影院最火的一句 | 操逼电影五月天 | 天天操真逼网 | 欧美另类一二三四 | 国产又粗又猛又大爽又 | 92c.cc国产黃色A片 |