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 "//mirrors.aliyun.com/alpine/latest-stable/main/" > /etc/apk/repositories &&\
    	echo "//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 "//mirrors.aliyun.com/alpine/latest-stable/main/" > /etc/apk/repositories
      echo "//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>
      
Tags: