1. 程式人生 > 實用技巧 >Docker基本命令

Docker基本命令

目錄

映象

  1. 版本

    docker version
    
  2. 登入

    docker login -u User -p Pasword <docker-server>
    

    Docker會將token儲存在~/.docker/config.json檔案中,從而作為拉取私有映象的憑證。

  3. 登出

    docker logout <docker-server>
    
  4. 查詢

    docker images
    
  5. 搜尋映象

    docker search image
    
  6. 拉取映象

    docker pull image:tag
    
    docker pull ubuntu 
    
    Using default tag: latest
    latest: Pulling from library/ubuntu
    da7391352a9b: Pull complete 
    14428a6d4bcd: Pull complete 
    2c2d948710f2: Pull complete 
    Digest: sha256:c95a8e48bf88e9849f3e0f723d9f49fa12c5a00cfc6e60d2bc99d87555295e4c
    Status: Downloaded newer image for ubuntu:latest
    docker.io/library/ubuntu:latest
    
    • 預設抓取的地址是官方的 docker hub,官方存放映象的位置預設在 library 目錄下
    • 在抓取的時候,先有一個下載的過程,映象是多層儲存所構成,分層下載,並非單一檔案,下載過程中給出了每一層的前 12 位 ID
    • 下載結束後,顯示 pull complete,並給出該映象的完整 sha256摘要
  7. 建立映象

    docker image build -t <image name>:<tag> .
    
    • -t 指定 image 檔案,最後的 . 表示上下文環境,Dockerfile 在當前路徑
    • -f 指定dockfile 檔案
  8. 檢視映象

    # 列出所有映象,不包含中間層映象
    docker images
    # 或者
    docker image ls
    
    # 列出所有虛懸映象
    docker image ls -f dangling=true
    
    # 列出所有映象,包含中間層映象
    docker images -a
    # 或者
    docker image ls -a
    
    # 列出指定映象
    docker images <image name>
    
    REPOSITORY                             TAG                 IMAGE ID            CREATED             SIZE
    mysql                                  8.0                 ab2f358b8612        10 days ago         545MB
    

    說明:

    • REPOSITORY 表示映象名
    • TAG 表示映象標記,通常是版本號,或者其他可以區別映象不同版本的標記
    • IMAGE ID 表示映象 ID,映象可以通過<REPOSITORY>:<TAG>
      來識別,也可以通過<IMAGE ID>來識別
    • CREATED 表示這個映象製作的時間
    • SIZE 表示這個映象的大小

    注意:

    ​ 無標籤的映象<none>,與之前的虛空映象不同,這些無標籤的映象很多都是中間層映象,是其他映象的依賴物件,只要刪除了這些中間層映象,這些依賴他們的映象也將會被刪除。

  9. 檢視映象的詳細資訊

    docker inspect <image name>:<tag>
    
  10. 刪除映象

docker rmi <image name>:<tag>
# 或者
docker image rm <image name>:<tag>

# 刪除所有映象 
docker rmi $(docker images -q)
# 或者
docker image prune -f -a

標籤名預設是latest,如果標籤名是latest,則不用新增標籤名

  • -f 引數: 強制刪除此映象,並會刪除通過此映象建立的容器
  1. 釋出映象

    docker push <image name>:<tag>
    

容器

容器的實質是程序,容器程序運行於屬於自己的獨立的名稱空間。容器也是分層儲存,每一個容器執行時,是以映象為基礎層,在其上建立一個當前容器的儲存層。

  1. 列出正在執行的容器檔案
docker ps
# 或者
docker container ls

# 列出所有的容器檔案(包括停止執行的容器)
docker ps -a 
# 或者
docker container ls -a
CONTAINER ID        IMAGE               COMMAND                   CREATED             STATUS                      PORTS                               NAMES
6f4e1e80e33c        echo1:1.0           "/bin/sh -c 'echo us…"    55 minutes ago      Exited (0) 55 minutes ago                                       strange_mirzakhani
0094e5d008c9        mysql:8.0           "docker-entrypoint.s…"    4 days ago          Exited (255) 4 days ago     33060/tcp, 0.0.0.0:3308->3306/tcp   slave_mysql
174711ccb475        mysql:8.0           "docker-entrypoint.s…"    4 days ago          Exited (255) 4 days ago     33060/tcp, 0.0.0.0:3307->3306/tcp   master_mysql
  • CONTAINER ID 表示容器 ID
  • IMAGE 表示執行的映象,映象和容器的關係,就像是面向物件程式設計中例項一樣,映象是靜態的定義,容器是執行時的實體
  • CREATED 表示執行的時間
  • STATUS UP表示執行
  • PORTS 表示可以通過指定的埠號來訪問
  • NAMES 表示對映象容器的描述
  • COMMAND 表示表示容器啟動後執行的命令
  • STATUS UP表示執行,Exited表示已經停止運行了
  1. 執行容器

    docker run -p 3307:3306 --name <container name> -d <image name>:<tag>
    
    • -p引數:容器的 3306 埠對映到本機的 3307 埠
    • --name引數:指定容器名
    • -d引數: 後臺執行
  2. 進入容器

    docker exec -it <container ID>|<container name> /bin/bash
    
    • -it引數:容器的 Shell 對映到當前的 Shell,然後你在本機視窗輸入的命令,就會傳入容器
    • /bin/bash:容器啟動以後,內部第一個執行的命令。這裡是啟動 Bash,保證使用者可以使用 Shell
  3. 停止容器

    docker stop <container ID>|<container name>
    
    # 停止所有容器
    docker stop $(docker ps -aq) 
    
  4. 刪除容器

    docker rm <container ID>|<container name>
    
    # 刪除所有停止的容器
    docker container prune
    # 或者
    docker rm $(docker ps -aq) 
    
  5. 查詢容器ip

    docker inspect --format='{{.NetworkSettings.IPAddress}}' container_id|container_name
    
  6. 檢視容器日誌

    docker logs -f <container ID>|<container name>
    
    • -f 引數: 代表會實時重新整理日誌資訊
  7. 檢視容器的詳細資訊

    docker inspect <container ID>
    
  8. 複製檔案

    # docker -> local
    docker cp <container ID>:/opt/file.txt /opt/local/
    # local -> docker
    docker cp /opt/local/file.txt <container ID>:/opt/
    

Dockfile

Dockerfile 中的每一條指令都會建立一個層,所以多條sh指令最好使用&&,;等連線,這樣生成的層會很少,映象也會小很多。

  • Dockerfile 必須以FROM 開頭
  • 一個 Dockerfile,只能有一個ENTRYPOINT,如果有多個以最後一個為準
  • 一個 Dockerfile,只能有一個CMD,如果有多個以最後一個為準
  • 在Dockerfile中,ENTRYPOINT指令或CMD指令,至少必有其一
  1. Dockerfile

    FROM alpine:latest as production
    LABEL Author="[email protected]"
    RUN mkdir /lib64 &&\
    	ln -s /lib/libc.musl-x86_64.so.1 /lib64/ld-linux-x86-64.so.2 &&\
    	echo "http://mirrors.aliyun.com/alpine/latest-stable/main/" > /etc/apk/repositories &&\
    	echo "http://mirrors.aliyun.com/alpine/latest-stable/community/" >> /etc/apk/repositories &&\
    	apk add tzdata &&\
    	ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime &&\
    	echo "Asia/Shanghai" > /etc/timezone &&\
    	mkdir -p /app/ /config/
    COPY ./bin/* /app/*
    COPY ./config/* /config/
    EXPOSE 8080
    ENTRYPOINT ["/app/server","-c","/config/app.yaml"]
    
    • FROM 指定基礎映象為 alpine,版本為 latest,並重命名為production

    • LABEL 指定署名郵箱

    • RUN 指定在容器內執行的命令

      # musl和glibc是相容的,通過建立該符號連結修復缺少的依賴項,可以保證編譯後 go 程式可以正常執行
      mkdir /lib64
      ln -s /lib/libc.musl-x86_64.so.1 /lib64/ld-linux-x86-64.so.2
      
      # 更新源
      echo "http://mirrors.aliyun.com/alpine/latest-stable/main/" > /etc/apk/repositories
      echo "http://mirrors.aliyun.com/alpine/latest-stable/community/" >> /etc/apk/repositories
      
      # 同步時間
      apk add tzdata
      ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
      echo "Asia/Shanghai" > /etc/timezone
      
      # 建立專案目錄
      mkdir -p /app/ /config/
      
    • COPY 將當前本機上的檔案複製到容器內指定位置

    • EXPOSE 容器將使用 8080 埠,這裡只是宣告並不會建立和本機的埠對映

    • ENTRYPOINT 容器啟動時執行的命令

      /app/server -c /config/app.yaml
      
  2. FORM

    基礎映象必須指定,FROM指令指定基礎映象,因此一個 Dockerfile 檔案中 FROM 是必備指令,而且是第一個指令

    FROM scratch指定一個空白映象,scratch 不以任何映象為基礎,接下來寫的指令將作為映象第一層開始存在

  3. LABEL

    新增元資料到映象。LABEL是以鍵值對形式出現的

  4. RUN

    在容器內執行指定命令

  5. COPY

    將本機構建上下文中的指定檔案複製到映象中

  6. ADD

    僅在需要自動解壓縮的情況下才使用ADD指令,如果只是複製檔案就使用COPY指令

  7. ENV

    設定容器的環境變數

    ENV name=linux
    
  8. EXPOSE

    宣告容器將要使用的埠,並不建立和主機的埠對映。當執行容器時使用-p才是真正的建立埠對映

  9. ENTRYPOINT

    • exec格式用法 [推薦]

      程式入口點,執行docker run命令時,設定的任何命令引數或CMD指令的命令,都將作為ENTRYPOINT指令的命令引數,追加到ENTRYPOINT指令的命令之後。

      ENTRYPOINT ["top","-b","-H"]
      

      如果此時建立docker 例項

      docker run <container-name> -v
      

      則實際執行的命令是 top -b -H -v

    • shell 格式用法

      遮蔽追加任何引數,即CMD指令或docker run … 的引數都將被忽略。

      ENTRYPOINT top -b -H
      

      在建立容器後會首先呼叫Shell,即自動在命令前面追加/bin/sh -c。既容器啟動時,將執行/bin/sh -c top -b -H。這樣會導致top命令就不是容器中的第一個程序PID 1,這樣在容器停止的時候就無法收到系統的SIGTERM訊號。要想收到SIGTERM訊號,務必使用Bash的內建exec命令使得top的PID 1,定義ENTRYPOINT指令如下:

      ENTRYPOINT exec top -b -H
      
  10. CMD

    用於指定預設的容器主程序的啟動命令。

    不同格式:

    • exec格式用法 [推薦]

      引數追加模式,第一個引數必須是命令的全路徑

      如果docker run沒有指定任何的執行命令或引數,但是,dockerfile 中有CMD和ENTRYPOINT, 那麼 CMD 中的全部內容將作為 ENTRYPOINT 的引數

      FROM ubuntu:latest
      CMD ["echo","username"]
      ENTRYPOINT ["echo","ENTRYPOINT"]
      
      # 構建
      docker image build -t echo1:2.0 -f Dockerfile .
      
      # 無參執行
      docker run echo1:2.0  # 輸出:ENTRYPOINT
      
      # 帶引數執行
      docker run echo1:2.0 echo "test"  # 輸出:ENTRYPOINT echo test
      

      輸出變數:

      FROM ubuntu:latest
      ENV user=feiquan
      
      # 這種寫法無法輸出變數,會直接輸出 username:$user
      # CMD ["username:$user"]
      # ENTRYPOINT ["/bin/echo,"echo ENTRYPOINT:$user"]
      
      CMD ["/bin/sh","-c","echo username:$user"]
      ENTRYPOINT ["/bin/sh","-c","echo ENTRYPOINT:$user"]
      
      # 構建
      docker image build -t echo1:4.0 -f Dockerfile .
      
      # 無參執行
      docker run echo1:4.0  # 輸出:ENTRYPOINT:feiquan
      
      # 帶引數執行
      docker run echo1:4.0 docker run echo1:4.0  && echo "test:$user" 
      # 輸出:
      
      ENTRYPOINT:feiquan
      test:
      

      由於在傳入&& echo "test:$user" 時,$user使用的本機中環境變數,它為空,所以這裡命令在追加後執行的其實是/bin/sh -c echo ENTRYPOINT:$user && echo "test:"

      設定user=xx後,再次執行輸出:

      ENTRYPOINT:feiquan
      test:xx
      
    • shell 格式用法

      遮蔽追加任何引數,即CMD指令或docker run … 的引數都將被忽略。在建立容器後會首先呼叫Shell,即自動在命令前面追加/bin/sh -c

      如果docker run沒有指定任何的執行命令或者dockerfile裡面也沒有ENTRYPOINT,那麼,就會使用cmd指定的預設的執行命令執行。

      FROM ubuntu:latest
      CMD echo username
      
      # 構建
      docker image build -t echo1:1.0 -f Dockerfile .
      # 無參執行
      docker run echo1:1.0  # 輸出:username
      
      # 帶引數執行
      docker run echo1:1.0 echo "test"  # 輸出:test
      

      輸出變數:

      FROM ubuntu:latest
      ENV user=feiquan
      CMD echo username:$user
      
      # 構建
      docker image build -t echo1:3.0 -f Dockerfile .
      # 無參執行
      docker run echo1:3.0  # 輸出:username:feiquan
      
      # 帶引數執行
      docker run echo1:3.0 echo "test"  # 輸出:test
      
  11. WORKDIR

    指定工作目錄,也就是啟動容器後終端所在路徑,預設~。如果WORKDIR指 定的目錄不存在,即使隨後的指令沒有用到這個目錄,都會建立

  12. VOLUME

    實現資料的持久化,為了防止執行時使用者忘記將動態檔案所儲存目錄掛載為卷,在 Dockerfile 中,我們可以事先指定某些目錄掛載為匿名卷,這樣在執行時如果使用者不指定掛載,其應用也可以正常執行,不會向容器儲存層寫入大量資料。

    • 管理卷

      # 建立一個自定義容器卷
      docker volume create mdata
      # 檢視所有容器卷
      docker volume ls
      # 檢視指定容器卷詳情資訊
      docker volume inspect mdata
      
      [
          {
              "CreatedAt": "2020-12-22T10:41:39Z",
              "Driver": "local",
              "Labels": {},
              "Mountpoint": "/var/lib/docker/volumes/mdata/_data",
              "Name": "mdata",
              "Options": {},
              "Scope": "local"
          }
      ]
      
    • 使用指定卷

      FROM ubuntu:latest
      
      VOLUME /data
      RUN ls -ah / > /data/dir.txt
      ENTRYPOINT sleep 10000
      
      # 構建
      docker image build -t echo1:5.0 -f Dockerfile .
      # 掛載
      docker run -d -v mdata:/data echo1:5.0
      
      • -v引數:-v代表掛載資料卷,這裡使用自定義卷mdata,並將其掛載到/data
    • 進入容器檢視:

      docker exec -it 90177637380d /bin/bash
      
      ls data
      
      root@90177637380d:/# ll /data/
      total 12
      drwxr-xr-x 2 root root 4096 Dec 22 11:26 ./
      drwxr-xr-x 1 root root 4096 Dec 22 11:12 ../
      -rw-r--r-- 1 root root  119 Dec 22 11:10 dir.txt
      
    • 本機檢視

      # mac 主機需要先執行
      # screen ~/Library/Containers/com.docker.docker/Data/vms/0/tty
      ll /var/lib/docker/volumes/mdata/_data
      
    • 刪除卷

      docker volume rm <volume-name>