經驗拾憶(純手工)=> Docker語法全面回憶

Hello Docker

官方安裝教程:https://docs.docker.com/install/linux/docker-ce/ubuntu/
進去選好對應系統/發行版, 照着命令複製-粘貼-運行。  就可以安裝成功(根本不需要多餘操作)

Image(鏡像)

  • docker search

       docker search python    # 列出dockerhub 提供的 image
  • docker pull(下載)

       docker pull python:3.7  # 從 dockerhub下載 image    冒號:數字  用來指定版本(不指定就是最新版本)   
  • docker images(列出)

       docker images           # 列出本地鏡像 (或 docker image ls)
       docker images py*       # 也可以通過名稱來篩選查看 image, 也可使用通配符
  • docker rmi(刪除)

       docker rmi "image名" 或 "imageID"    # 刪除 image
       docker rmi python -f                # 強制刪除(當image內有容器運行無法刪除時,可通過-f強制刪除)
           如果兩個image有相同 "imageID",會刪除失敗, 這時可以考慮用 "image名" 來刪除
           如果兩個image有相同的 "image名", 那麼可以考慮用  "image名:Tag"  來刪除
  • docker save(保存備份)

       方式1:docker save python > python.tar        # 可追加多個image來 把多個image打包保存  
       方式2: docker save python -o python.tar
       python.tar文件 可分享傳輸,給別人還原加載使用
       注: 上令爲例,如果有多個python版本, 那麼會將所有python images 都會打包在一起保存
            如果你有多個鏡像, 爲了避免混淆,一定要指定一下版本號  docker save python:latest  
  • docker load(還原)

       方式1: docker load -i python.tar
       方式2: docker load < python.tar
  • docker tag(改名,改版本號)

       docker tag python:latest py:3.7        #  把 "python:latest"  改爲  "py:3.7 "
       注1: 若image名不爲<none>, 那麼首先會將 image 複製創建一份,然後改名
       注2: 若原image名爲 <none> ,那麼 改名後,會直接在原有image上直接改名
  • docker inspect(查看詳細信息)

       docker inspect python
  • docker history(查看分層歷史信息)

       docker history mypython:3.7

Container(容器)

  • docker create(創建)

       docker create --name py-con python:latest    #  --name後自定義名字,  最後指定哪一個鏡像
       docker create -it python:latest  python       #  創建帶有標準輸入環境的容器,並執行python命令
           -t 爲了給容器創建一個 terminal
           -i 爲了給容器提供一個 標準輸入流 (否則,容器終端裏無法輸入)
       注:創建默認是 created狀態, 需要下面 docker start 命令來啓動     
  • docker start(開啓)

       docker start -ai 容器ID        # 以標標準環境開啓容器
           -a 代表提供標準輸出
           -i 同create -i ,提供標準輸入
  • docker run(創建+啓動, 推薦)

       docker run -it python:latest python      # 一套搞定  create+start 的繁雜過程, -it同上不解釋
           # 命令防混淆解釋: 根據python:latest鏡像 ,創建並執行容器,同時執行 python命令
       docker run  -d -it python:latest python
           # 其他不變,多加一個 -d, 可以創建並放入 "後臺" 執行 (不加-d , 默認"前臺")
       docker run -dit --rm python:latest python
           # --rm 參數代表 容器停止,即(exited狀態),  就會自動刪除。 
       docker run --network bridge -itd mypython:latest python
           # --network 代表指定網絡(若不指定,默認也是bridge,見下面 網絡章節)
       docker run -dit -p 6006:6379 redis
           # 端口映射, 宿主機(6006):容器(6379)        (-P代表容器內部所有端口 與宿主機隨即映射)
       docker run --restart always
           # --restart always 代表 docker服務重啓時, 裏面的容器也會跟着重啓
  • docker stop(終止,結束)

       docker ps             # 查看一下   "運行中容器ID"
       docker stop 容器ID    # 停止 "運行中" 的容器  ( 默認 10秒鐘後 才停止)
       docker stop -t 0 374  # -t指定時間 0秒後, 即瞬間就可以停止
       擴展(停止所有正在運行的容器):
           docker stop $(docker ps -q)    # -q參數代表只顯示容器ID
           
  • docker restart(重啓)

       docker restart -t 0  281    # 0秒重啓
  • docker pause(暫停)

       docker pause 281    # 暫停容器內的所有進程, 注意是暫停, 不是終止
  • docker unpause(繼續)

       docker unpause 281    # 把暫停的容器,繼續開啓
  • docker ps(查看)

       docker ps         # 列出所有 "運行中" 的容器
       docker ps -a      # 列出所有 容器
  • docker logs(查看輸出日誌)

       docker logs 281   # 查看容器內部輸出日誌
       docker logs -f 281   # -f 代表阻塞監控,   (和 tail -f 一個道理)
  • docker rename(重命名)

       docker rename 281 python    # 把 281的容器  改名爲  python
  • docker inspect(查看容器詳細信息)

       docker inspect 374    # 查看容器所有信息
  • docker rm(刪除)

       docker rm 容器ID        # 刪除已停止的容器
       docker rm 容器ID -f     # 強制刪除(運行中)等特殊情況的容器
  • docker attach(進入到容器命令執行處)

       docker run -itd python:latest python    # 新創建容器,名執行 python命令
       docker attach 281     # 直接進入281這個容器,並直接跳到 python控制檯內部 
       "注: 進入python控制檯後,再退出去,就意味着, 容器的退出。"
  • docker exec(執行命令)

       docker exec -it 281 python    # 在"容器外部", 執行"內部容器"的 python命令
       "注: 與上一條attach不同的是,退出python控制檯後,容器依舊運行!(因爲是在容器外面執行的python命令)"

Container and Images(容器與鏡像關聯)

  • docker commit (把容器"封裝"成一個新鏡像)

       docker commit 4d mypython:3.7   # 把4d這個容器所有內容,封裝爲一個"名字:版本"叫"mypython:3.7"的鏡像
  • docker export (容器導出爲一個文件)

       docker export fc8 -o mypython.tar  # 把此容器導出爲一個.tar文件 ,和前面說過的 image的 save類似
  • docker import (把export導出的文件導出,並"生成"一個鏡像)

       docker import mypython.tar mypython:latest
           注: 把export導出的 mypython.tar文件導入 並 直接創建一個  mypython:latest 的 鏡像
  • docker commit & docker import區別

       前面說過:
           docker commit 是 直接把一個container 封裝爲一個image
           docker import 是 把export導出的container.tar文件 再 導入進來,並重新生成一個 新 image
       docker commit 是繼承封裝的,並創建具有分層歷史記錄 (docker history imageID 即可查看) 
       docker import 是直接生成的,不具有分層記錄     (docker history imageID 即可查看) 

網絡

  • docker network ls (查看)

       docker network ls
           bridge(網橋):容器默認網絡模式
               容器-容器網絡連接:
                   container1(etho0)--veth1--Docker(bridge)--veth2--container2(etho0)
               容器-宿主機網絡連接:
                   container1(etho0)--veth1--Docker(bridge)--宿主機(etho0)
                   注: veth是創建網絡時,自動創建的,不需要手動管理
                   
           host(主機):  容器網絡和主機使用同一個網絡
               容器-容器網絡連接:
                   container1(etho0)--宿主機--container2(etho0)
               容器-宿主機網絡連接:    
                   container1(etho0)--宿主機
               容器網絡(特殊host):    
                   container1--container2    # 就是 ‘每個容器互相把對方認作爲 宿主機’ 這個意思
                   使用方法:
                       docker run -it --network container:24f1 mypython:latest ls
                       # container:24f1   的container是語法關鍵詞   24f1是連接的對方容器()
                                               
           null(無網絡):所有容器無網絡
           
    
  • docker network create (創建)

       docker network create -d bridge mybridge    # 可創建多個bridge
       docker network create -d host myhost        # 只可創建一個host(默認就有一個,故無法創建)
       docker network create -d null mynull        # 只可創建一個null(默認就有一個,故無法創建) 
  • docker network rm (刪除)

       docker network rm ab5
       注:默認自帶的網絡不可以刪除(null host 和 自帶的一個 bridge)
  • docker network connect (給容器綁定網絡)

       docker network connect mybridge 4c4  # 給4c4這個容器綁定一個  mybridge網絡(自定義的bridge)
       docker inspect 4c4    # 查看一下容器信息,最下面就是網絡
       注:一個container 可以綁定 多個bridge 網絡, 
  • docker network disconnect (給容器 解除綁定的網絡)

       docker network disconnect mybridge 4c4    # 給容器解除綁定網絡mybridge
       注: 一個container 中 bridge 和 none 網絡不可以共存, (若衝突,則先disconnect再connect)
       注2:host 網絡不能 connect 和 disconnect

數據卷 (volume)

  • docker volume create(創建數據卷)

       docker volume create myvolume
       注: myvolume爲數據卷名
  • docker volume ls(列出數據卷)

       docker volume ls
       注: 若數據卷未指定名字,當 使用docker run -v 方式時,則會新建數據卷ID,並以此ID命名。
  • docker volume prune(刪除未被容器使用的 所有 數據卷)

       docker volume prune
       注:容器佔用的數據卷,刪不了
  • docker volume rm (刪除 一個 或 多個 指定數據卷)

       docker volume rm myvolume
       注: 刪除 myvolume這個數據卷,當然也可以連續參數,追加刪除多個數據卷
  • 掛載數據卷

       """意義: 可以讓 宿主機 與 容器 數據聯通共享"""
       方式1 (-v參數)
           -v使用方式1:(指定路徑映射掛載)
               docker run -itd -v /root:/root mypython:latest python  # -v  宿主機路徑:容器路徑
               測試:
                   cd /root
                   touch aaa.txt                  # 宿主機創建文件 aaa.txt
                   docker exec -it cfb ls /root   # 結果可看見容器裏面也有 aaa.txt 文件
                   
           -v使用方式2:(指定數據卷對象 映射掛載)
               docker run -itd -v myvolume:/root mypython:latest python    # 冒號前面 變成了myvolume
               注1: 這個myvolume就是一個數據卷對象, 執行上面這條命令,就會爲我們自動創建這個數據卷對象
               注2: 由於沒有宿主映射路徑,那麼映射的宿主路徑 是什麼呢??
                   docker volume inspect myvolume  # 結果Mountpoint後面的就是,宿主機映射的 默認鉤子路徑
                   cd /var/lib/docker/volumes/myvolume11/_data    # 此路徑和volume名有關
                   touch bbb.txt                   # 宿主機創建文件 bbb.txt
                   docker exec -it 916 ls /root    # 打印結果可見,容器內部也有bbb.txt,說明成功共享。
               
       方式2:(--mount參數,同樣包括 -v的兩種使用方式, 另外還新增另一種 文件"緩存"掛載方式) 
           docker run -itd --mount type=volume,src=myvolume11,dst=/root mypython:latest python
           注:
               type: 指定類型(路徑映射: bind)或 (數據卷對象映射: volume) 或(內存映射:tmpfs)
               src: 對應上面方式1(宿主機路徑)  或 對應上面方式2(數據卷名) 或 省略此項(對應新增)
               dst: 容器路徑
               逗號分隔,其他沒變
           docker run -itd --mount type=tmpfs,dst=/root mypython:latest python  (tmpfs"緩存"掛載)
           
       "綜上,可總結爲3種掛載選擇用途":
           一. "宿主路徑 與 容器路徑"  映射掛載
           二. "數據卷   與 容器路徑"  映射掛載
           三. "宿主內存 與 容器路徑"  映射掛載
           
       "綜上,可總結爲2種掛載參數使用":
           一、 "-v 參數"        2種用途 (路徑映射 和 數據卷對象映射)
           二、 "--mount 參數"   3種用途 (路徑映射 和 數據卷對象映射 和 內存映射)
  • 容器之間共享數據

       """藉助已經擁有數據卷的容器   來 創建一個新容器"""
       docker run -itd --volumes-from 6252 python:latest     # 藉助6252容器創建新容器,來共享數據卷
       驗證:
            docker exec -it 97db touch /root/abc    # 新容器 創建一個文件abc
            docker exec -it 6252 ls /root           # 舊容器查看 ,也有新文件abc,共享成功
  • 細節注意事項

       一、若將 "空數據卷"   掛載到 容器非空目錄中,則"此容器目錄下的內容 會copy一份到 數據卷中"
       二、若將 "非空數據卷" 掛載到 容器任意目錄中,則"數據卷的數據 會copy到這個目錄中,並將此目錄原數據隱藏" 
       更通俗一點理解就是:
           數據卷大哥說:"如果我這裏有數據, 你的容器來掛載,你的數據就會被我這裏面的數據覆蓋。。"
           數據卷大哥又說:"如果我這裏是空的(沒有數據),那麼 你的容器來掛載, 你的數據就要提供一份給我"
           

DockerHub(倉庫)

  • 無認證 私有倉庫

  • 搭建倉庫

       docker pull registry    # 拉取 registry鏡像
       docker run -itd \
           --restart always \                    # docker重啓時,此容器也跟着重啓
           --name myregistry \                   # 指定容器名
           -p 6006:5000 \                        # 端口映射 (registry服務默認爲5000端口,映射爲6006)
           -v /root:/var/lib/registry \          # 綁定數據卷 (持久化存儲), 冒號後面的容器路徑時默認的
           registry                              # 拉取的 registry鏡像
       驗證:(一種web服務,所以通過固定Url訪問即可)
           外部瀏覽器驗證: 瀏覽器輸入    服務器外網IP:6006/v2/_catalog  即可  
           服務器內部驗證: curl 127.0.0.1:6006/v2/_catalog
  • 上傳鏡像

       一、先把要上傳的鏡像改名
           docker tag   mypython:latest    127.0.0.1:6006/mython_hub
           注: 目標名固定格式(需注意,必須此格式):   IP:Port/新鏡像名
       二、開始上傳
           docker push 127.0.0.1:6006/mython_hub    # docker push 鏡像名,注意這裏用ID不好使,必須用這名
       三、驗證
           同上面搭建倉庫時的驗證方法, 可看見結果 repositories列表中多了一個 剛剛上傳的鏡像
           curl 127.0.0.1:6006/v2/_catalog
  • 下載鏡像

       docker pull  127.0.0.1:6006/mython_hub
       注: 這個名就是上傳時候的 那個名, 一樣的

Dockerfile(配置文件式)

  • Dockerfile認知

       Docker 與 docker命令的關係就相當於  shell編程 與 單條命令
       主要就是把上面講的所有命令連起來,腳本式執行,  當然dockerfile也有自己的語法關鍵詞。
       Dockerfile是基於緩存,所以裏面的文件內容(某條命令) "如果未發生改變,則不會重新執行(用的是緩存)"
       
       Dockerfile機制:
           一、若在結尾每"追加"一條新命令,重新構建Dockerfile時,"只會執行這個新命令,其他舊命令都會使用緩存"
           二、若新命令 是在"中間插入編寫的",則此條新命令"之前的命令用緩存", "之後"的命令都會重新執行一遍,
           三、FROM 關鍵字是 Dockerfile的入口。
               新命令只要不是 寫在 "FROM的下一條", 那麼所有新命令及其之後的命令都會在 構建Dockerfile時-->
               觸發"層層封裝"機制  ,即每條"非緩存命令"運行一遍,都會commit封裝一層鏡像    
  • Dockerfile構建

       docker build /Dockerfile所在路徑 -t mypython:v2
       注1: 指定Dockerfile所在路徑即可,build會自動幫我們找到dockerfile文件
       注2: 如果Dockerfile就在當前路徑下,那麼可以用 . 來替代絕對路徑
       注3: -t 給鏡像指定名字   
  • Dockerfile語法

  • FROM

       "下載鏡像,類似 docker pull"
       FROM python:latest    # 同樣可以指定版本號
  • RUN | CMD | ENTRYPOINT

       這三個 命令 都有共同的 2種書寫方式:
           一、(exec)格式--當前進程執行
               eg:  python -V        # 就是玩linux的命令正常寫
           二、(shell) 格式--子進程執行
               eg:  ["python", "-V"]    # 命令與作爲字符串列表來書寫, 和py的scrapy的shell類似
               
       RUN: 
           "構建鏡像過程中"執行的命令, 比如安裝東西之類的。。(可寫多個)
       CMD:
           啓動容器時 執行的命令, 就和 之前說過的 docker run 跟的命令是一樣的
           "但是 docker run 要是指定了一個命令,那麼  這個CMD配置就會失效"
       ENRTYPOINT:
           和CMD類似, 不過 在docker run 指定新命令是,  ENTRYPOINT的命令是不會被覆蓋的。都會執行
       
    
  • ADD | COPY

       """將宿主機文件 拷貝 到鏡像的某個目錄中"""
       COPY aaa.txt /root    # 將aaa.txt  拷貝到  鏡像的/root目錄中
       ADD aaa.txt /root     # 和COPY一樣,不過 ADD可以將壓縮文件拷貝進去後,"自動解壓"
  • ENV

       """就相當於編程語言的 變量賦值"""
       ENV name=python       
       ENV nickname=$name    # $name 意爲取出 name變量的值
  • WORKDIR

       """切換目錄 類似cd命令"""
       WORKDIR /root
  • VOLUME

       """添加數據卷"""
       VOLUME /root   # 就相當於前面說過的docker run -v /root, 即自動創建一個數據卷映射到 容器的/root
  • EXPOSE

       """暴露端口"""
       EXPOSE 6379  
       EXPOSE 3306    # 可以用多個 EXPOSE 暴露多個端口
       注1: 暴露端口後,可以通過 前面說的  docker run -P 來做自動端口映射
       注2: 或者不暴露端口,直接使用手動映射-p,都是可以的。
  • 官方模板參考網址

       官方文檔:https://docs.docker.com/engine/reference/builder/
       各種開源Dockerfile模板:https://github.com/docker-library/docs/tree/master/
    

Docker Compose

  • Docker-Compose認知

       一、Dockerfile 可以看作是 Docker命令的組合
       二、Docker-Compose 可以看作是 Dockerfile的組合(也稱作 容器編排工具)
       三、Docker-Compose 文件默認名爲  docoker-compose.yaml
       四、docoker-compose.yaml 文件指令中間都有空格  eg:  version: 3.7(3.7之前是有空格的)
       五、docoker-compose.yaml 採用縮進對格式語法進行區分
  • Docker-Compose安裝

       官方安裝教程:https://docs.docker.com/compose/install/
       從上往下,命令複製-粘貼-運行。。。Easy略
  • Docker-Compose文件指令

       version: "3.7"    # 必有
           # 此版本號與docker版本對應地址: https://docs.docker.com/compose/compose-file/  
           
       services:         # services關鍵字,寫上就行, 必有
           mypython:     # mypython是我隨便起個名
               build: .  # Dockerfile的路徑位置, build是構建Dockerfile文件的
               ports:
                   -"6006:3003"    # 注意-後面是有空格的,markdown語法充衝突,我就沒寫空格
           myredis:      # 同理 myredis 也是我隨便起的名
               image: redis    # 指定一個成品鏡像  類似DockerfilE的 FROM指令
               container_name: myredis    # 指定容器名
               networks:     # 使用下面創建的mynet網絡
                   -mynet    # (同-後有空格,避免markdown語法衝突) 
               volumes:      # 使用下面創建的myvolume數據卷,並映射到容器的/root目錄
                   -myvolume:/root  
                   
       networks:    # 創建網絡
           mynet:   # 給網絡起名爲 mynet 
               driver: "bridge"    # 指定爲橋接模式
       volumes:     # 創建數據卷
           myvolume:    # 給數據捲起名爲 myvolume
               driver: "local"     # 默認就是local,即數據卷存儲在宿主機的目錄下
  • 預檢查docker-compose.yml文件語法格式是否有誤

       docker-compose config
       注:需要在 docker-compose.yml 所在目錄下執行
  • 啓動/停止 docker comopse

       docker-compose up    # 前臺終端阻塞執行(就是執行之後,你不能在終端輸入東西了)
       docker-compose up -d # 後臺終端非阻塞執行 (作爲服務一樣後臺執行)
       
       docker-compose stop  # 停止編排(即停止 所有 編排運行的容器)

END

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章