博客 / 詳情

返回

Docker安裝與配置

由於格式和圖片解析問題,為了更好的閲讀體驗,可以前往 閲讀原文

為什麼出現Docker?傳統的開發和部署存在着許多環境和配置的不兼容的問題,docker就是將環境和代碼統一打包的來解決這些兼容問題。Docker是一個統一了運行環境和配置問題的虛擬容器技術,是一個內核級虛擬技術。使用鏡像,保證了處處環境的一致性。

我們知道,如果將計算機的層次做一下簡單的劃分,最底層是硬件,最上層是軟件,中間是操作系統。(這是一種極為籠統且不嚴謹不專業的劃分,我只記到這裏了……)我們非常熟悉的虛擬機,就是一個物理硬件層抽象,運行在硬件之上:它向下面對一套硬件和硬件接口,對其進行虛擬,然後向上提供一套獨立的操作系統,然後就可以在操作系統之上再運行各種軟件應用等(如下圖右,可以無視那個“管理程序”層因為我也不知道是啥)。這就使得虛擬機這個東西非常龐大沉重(因為包含了一整套操作系統,一般都好幾G,還可能有一套單獨的存儲空間),啓動時間長(一般幾分鐘,有SSD不算),且不容易移植(因為我們知道,在安裝操作系統的時候,會根據硬件的不同編譯出不同的內核,而每台電腦的硬件配置幾乎不會完全一樣,因而直接把一台電腦的操作系統文件考到另一台一般是沒法啓動的)。而容器是一個應用層抽象,運行在操作系統之上的,確切地説是操作系統內核之上(如下圖左),面對的是操作系統提供的接口,屬於進程級別;容器對我們的代碼和依賴進行打包,比如一個docker中只有一個python3,還有TensorFlow以及其他的package(經常會在一個docker中發現連“sudo”命令都沒有);這樣體積就很小,啓動快(幾秒幾毫秒),且容易移植(不同硬件上的同一操作系統向上提供相同的接口)。

可以將容器鏡像看作是mini版的虛擬機,但兩者並不相通,先來看看二者優缺點。

掃碼關注攻粽號,查看更多優質文章

優缺點

傳統的虛擬技術要在一個機器上安裝虛擬機、各種軟件,再部署應用,存在一系列的缺點:

  • 需要虛擬出一套完整的硬件後,運行一個完整的操作系統,在系統上運行所需的應用程序
  • 啓動慢
  • 資源佔用多
  • 冗餘步驟多
  • 遷移困難

而Docker使用容器化技術完美的解決了這些問題,其具備:

  • 直接運行與宿主機的內核
  • 容器內沒有自己內核,沒有進行硬件虛擬,更輕量
  • 容器相互隔離,互不影響
  • 更快交付、部署
  • 便捷升級和擴容
  • 統一標準、更簡單的運維
  • 節約成本

有了容器化技術對於應用的部署更加方便,也更好維護,這也促使雲原生的發展。

docker架構

Docker 架構分為客户端-服務器架構和主從架構,具體如下:

客户端-服務器架構:Docker 採用客户端-服務器架構,其中客户端是 Docker 命令行工具,用於與 Docker 服務端通信。Docker 服務端是 Docker 引擎,負責管理和運行 Docker 容器。客户端和服務端可以運行在同一台機器上,也可以通過網絡連接運行在不同的機器上。

主從架構:Docker Swarm 是一個用於管理多個 Docker 容器的集羣工具,採用主從架構。Docker Swarm 集羣由一個管理節點和多個工作節點組成,管理節點負責整個集羣的管理和調度,工作節點負責運行 Docker 容器。管理節點和工作節點可以運行在同一台機器上,也可以通過網絡連接運行在不同的機器上。
iShot_2022-09-04_18.05.31

docker所安裝的鏡像在本地都是一個個文件,可以通過docker info查看存儲位置

Docker三大組件

  • 鏡像(Image):一個root文件系統的模板,相當於 一個類
  • 容器(Container):docker run 鏡像就是容器(最小的linux內核文件和運行的應用程序),鏡像和容器的關係,就像是面向對象程序設計中的 實例一樣,鏡像是靜態的定義,容器是鏡像運行時的實體
  • 倉庫(Repositry):保存鏡像的倉庫,每個倉庫可以包含多個Tag,對應不同的鏡像

安裝

本文基於ARM架構Centos7虛擬機安裝的,如果你的環境和我不一致,可以參考官方文檔或其他資料

  1. 卸載掉機器上可能存在的docker相關依賴,如果你沒有安裝過,可以忽略此步驟

    sudo yum remove docker \
      docker-client \
      docker-client-latest \
      docker-common \
      docker-latest \
      docker-latest-logrotate \
      docker-logrotate \
      docker-engine
  2. 配置docker倉庫地址

    sudo yum install -y yum-utils
    
    # 設置ali倉庫加速地址
    sudo yum-config-manager \
     --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
  3. 下載docker
    這裏你可以根據自己的需求安裝指定版本的docker,不指定版本默認latest最新版本

    # 查看可安裝的版本
    yum list docker-ce --showduplicates | sort -r
    
    # 這裏安裝最新版
    sudo yum install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
  4. 啓動docker並配置開機自啓

    systemctl enable docker --now
  5. 查看docker狀態

    # 查看運行狀態
    systemctl status docker
    ● docker.service - Docker Application Container Engine
    Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; vendor preset: disabled)
    Active: active (running) since 四 2023-03-23 22:22:10 CST; 7h left
      Docs: https://docs.docker.com
     Main PID: 1406 (dockerd)
     Tasks: 9
    Memory: 100.0M
    CGroup: /system.slice/docker.service
            └─1406 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
    
    # 查看版本
    docker version
    Client: Docker Engine - Community
     Version:           23.0.1
     API version:       1.42
     Go version:        go1.19.5
     Git commit:        a5ee5b1
     Built:             Thu Feb  9 19:49:05 2023
     OS/Arch:           linux/arm64
     Context:           default
    
    Server: Docker Engine - Community
     Engine:
      Version:          23.0.1
      API version:      1.42 (minimum version 1.12)
      Go version:       go1.19.5
      Git commit:       bc3805a
      Built:            Thu Feb  9 19:47:21 2023
      OS/Arch:          linux/arm64
      Experimental:     false
     containerd:
      Version:          1.6.18
      GitCommit:        2456e983eb9e37e47538f59ea18f2043c9a73640
     runc:
      Version:          1.1.4
      GitCommit:        v1.1.4-0-g5fd4c4d
     docker-init:
      Version:          0.19.0
      GitCommit:        de40ad0
  6. 運行hello-world鏡像

    docker run hello-world
    Unable to find image 'hello-world:latest' locally
    latest: Pulling from library/hello-world
    93288797bd35: Pull complete
    Digest: sha256:2498fce14358aa50ead0cc6c19990fc6ff866ce72aeb5546e1d59caac3d0d60f
    Status: Downloaded newer image for hello-world:latest
    
    Hello from Docker!

    以上運行hello-world鏡像時需要先從遠程倉庫下載鏡像到本地,然後才可以運行,由於docker的官方倉庫在國外,對於國內用户訪問比較慢,因此需要配置一些國內鏡像加速地址,才會加快下載速度

配置

配置vim /etc/docker/daemon.json沒有此文件的可以自行創建json文件

{
  "registry-mirrors": [
      // aliyun
    "https://xxxxxx.mirror.aliyuncs.com",
    // 網易
    "https://hub-mirror.c.163.com",
    // 騰訊
    "https://mirror.ccs.tencentyun.com",
    // 國內docker
    "https://registry.docker-cn.com",
    // 科大
    "https://docker.mirrors.ustc.edu.cn"
  ]
}

更多配置參考官方文檔

修改了配置文件後需要重啓服務:

systemctl daemon-reload
systemctl restart docker

Docker 是一個開源的容器化平台,可以幫助開發者和運維人員更快地構建、發佈和運行應用程序。Docker 使用容器技術,將應用程序和其依賴項打包到一個可移植的容器中,從而實現跨平台、快速部署和易於管理的目的。

本文主要從docker的基礎開始學習,包括基本架構、全局命令、鏡像、倉庫、容器

Docker架構

Docker 架構分為客户端-服務器架構主從架構,具體如下:

客户端-服務器架構:也稱為C/S架構,Docker 採用客户端-服務器架構,其中客户端是 Docker 命令行工具,用於與 Docker 服務端通信。Docker 服務端是 Docker 引擎,負責管理和運行 Docker 容器。客户端和服務端可以運行在同一台機器上,也可以通過網絡連接運行在不同的機器上。

主從架構:集羣模式,Docker Swarm 是一個用於管理多個 Docker 容器的集羣工具,採用主從架構。Docker Swarm 集羣由一個管理節點和多個工作節點組成,管理節點負責整個集羣的管理和調度,工作節點負責運行 Docker 容器。管理節點和工作節點可以運行在同一台機器上,也可以通過網絡連接運行在不同的機器上。

全局命令

  1. 查看docker版本

    docker version
  2. 查看docker詳細信息

    docker info
  3. 查看docker磁盤使用情況

    ➜ docker system df
    TYPE            TOTAL     ACTIVE    SIZE      RECLAIMABLE
    Images          12        5         4.138GB   713.6MB (17%)
    Containers      5         0         2.634MB   2.634MB (100%)
    Local Volumes   24        2         649.6MB   607.7MB (93%)
    Build Cache     0         0         0B        0B
  4. 查看docker server的實時信息,我們從架構可以知道docker是基於C/S架構的,docker server端負責管理和運行docker容器,我們可以查看其具體的操作步驟,先使用以下命令開始監聽server端,然後新開一個終端,啓動或停止容器查看輸出:

    docker system events
    
    # 示例
    2020-03-26T10:53:23.497642694+08:00 container kill 999511b43ca0ffa61979ccb6561ff20f499b087be99aba95836cee20edb794a3 (image=nginx:1.15.3, maintainer=NGINX Docker Maintainers <docker-maint@nginx.com>, name=nginx, signal=15)
    2020-03-26T10:53:23.936509503+08:00 network disconnect 3d9d929e9d34b4c776d993158c3bd8c6074fea2e1de0ab43c846e571c1191711 (container=999511b43ca0ffa61979ccb6561ff20f499b087be99aba95836cee20edb794a3, name=bridge, type=bridge)
    2020-03-26T10:53:23.953543859+08:00 container stop 999511b43ca0ffa61979ccb6561ff20f499b087be99aba95836cee20edb794a3 (image=nginx:1.15.3, maintainer=NGINX Docker Maintainers <docker-maint@nginx.com>, name=nginx)
    2020-03-26T10:53:23.958016229+08:00 container die 999511b43ca0ffa61979ccb6561ff20f499b087be99aba95836cee20edb794a3 (exitCode=0, image=nginx:1.15.3, maintainer=NGINX Docker Maintainers <docker-maint@nginx.com>, name=nginx)
  5. 查看對象的詳細信息,可以查看指定鏡像、容器等等

    docker inspect [name|ID]

核心組件

  • 鏡像(Image):一個root文件系統的模板,相當於 一個類
  • 容器(Container):docker run 鏡像就是容器(最小的linux內核文件和運行的應用程序),鏡像和容器的關係,就像是面向對象程序設計中的 實例一樣,鏡像是靜態的定義,容器是鏡像運行時的實體
  • 倉庫(Repositry):保存鏡像的倉庫,每個倉庫可以包含多個Tag,對應不同的鏡像

鏡像

Docker 鏡像 是一個特殊的文件系統,除了提供容器運行時所需的程序、庫、資源、配置等文件外,還包含了一些為運行時準備的一些配置參數(如匿名卷、環境變量、用户等)。鏡像 不包含 任何動態數據,其內容在構建之後也不會被改變。

對於linux而言,內核啓動後會掛載root文件系統為用户提供空間支持,如一個基本的centos鏡像就包含了一套完整的centos的root文件系統。

鏡像最重要的概念就是鏡像層,以及它的存儲原理。

鏡像層

docker-layer

Docker 使用UnionFS(聯合文件系統)來實現鏡像層之間的共享和複用,從而節省存儲空間和加速構建過程。UnionFS 是一種基於文件系統的技術,它能夠將多個不同的文件系統合併成為一個虛擬的文件系統。

在 Docker 中,UnionFS 主要由以下三個部分組成:

  • 基礎文件系統:Docker鏡像中的每個層都有一個基礎文件系統,它是一個只讀的文件系統,包含了鏡像的構建信息和運行時所需要的依賴項。
  • 容器文件系統:Docker容器層有一個可讀寫的容器文件系統,它是由基礎文件系統和其他層共同組成的。當容器啓動時,Docker 會將容器文件系統掛載到主機上,使其在主機上可以被訪問和修改。
  • UnionFS:UnionFS將多個文件系統合併成為一個虛擬的文件系統,使得用户可以看到一個統一的文件系統結構。Docker使用UnionFS來管理鏡像層之間的依賴關係和共享信息,從而實現鏡像的複用和節省存儲空間的目的。

BootFS 文件系統是一個只讀的文件系統,它位於 Docker 鏡像的最底層。當 Docker 啓動容器時,它會將 BootFS 文件系統加載到內存中,並在其上啓動操作系統。操作系統啓動後,Docker 會將其他文件系統(如容器層和其他鏡像層)掛載到操作系統上,使得容器中的應用程序可以訪問這些文件系統中的文件和數據。

在使用 UnionFS 時,Docker 會將各個鏡像層以只讀的方式合併到一個虛擬的文件系統中,然後再將容器層以可讀寫的方式掛載到虛擬文件系統上。這樣,容器就能夠訪問和修改虛擬文件系統中的內容,而對於只讀的鏡像層,則不會被修改,從而實現了鏡像的共享和複用。

總的來説,Docker 使用 UnionFS 技術來實現鏡像層之間的共享和複用,從而節省存儲空間和加速構建過程。UnionFS 技術能夠將多個文件系統合併成為一個虛擬的文件系統,並且支持只讀和可讀寫兩種模式,使得用户可以看到一個統一的文件系統結構。

查看本地鏡像

# 命令
docker images [options] [REPOSITORY[:TAG]]

# 列出所有鏡像
➜ docker images
REPOSITORY       TAG         IMAGE ID       CREATED         SIZE
alpine           latest      8e1d7573f448   16 months ago   5.33MB
nginx            1.15.3      c5e5a72af32f   4 years ago     103MB

➜ docker images --filter reference=nginx
REPOSITORY   TAG       IMAGE ID       CREATED       SIZE
nginx        1.15.3    c5e5a72af32f   4 years ago   103MB

以上會以表格的方式列表鏡像,其中包含了鏡像倉庫、標籤、鏡像ID、創建時間、大小等等,上面列出了alpinenginx兩個鏡像

常用的參數:

  • -a:顯示所有鏡像中間層鏡像
  • -q:只輸出鏡像ID
  • --filter:篩選鏡像

    • dangling=true|false:顯示有無使用的鏡像
    • reference=<鏡像名>:根據名字或標籤進行篩選鏡像
  • --format:以哪種格式輸出,table、json、TEMPLATE,默認table

搜索、下載、推送

  1. 搜索鏡像

    docker search imageName [options]
    
    ➜ docker search nginx --limit 2
    NAME            DESCRIPTION                  STARS     OFFICIAL   AUTOMATED
    nginx           Official build of Nginx.     18278     [OK]
    bitnami/nginx   Bitnami nginx Docker Image   155                  [OK]

    搜索鏡像會默認從官方的docker registry進行搜索,你可以使用--limit參數限制搜索數

  2. 下載

    # 下載,沒有tag時默認 latest
    docker pull imageName:tag
    # 下載nginx
    docker pull nginx
  3. 推送

    鏡像推送指將本地的鏡像推送到遠程倉庫,如將項目代碼提交到遠程的git倉庫,推送首先要登錄

    # 登錄
    docker login
    # 推送
    docker push imageName:tag

創建、刪除

  1. 創建

    創建新鏡像的方式有很多,可以通過打新的標籤、commit、Dockerfile來創建新鏡像

    # 通過打新標籤
    docker tag nginx:1.1 nginx-me:v1
    # 通過commit
    docker commit container imageName:tag
    # 通過Dockerfile
    docker build -t imageName:tag .
    有關Dockerfile的概念和使用可以查看我的「使用Dockerfile構建鏡像」一文
  2. 刪除

    # 刪除
    docker image rm image ... / docker rmi image ...
    # 刪除latest版本nginx
    docker rmi nginx
    # 刪除所有鏡像
    docker rmi $(docker images -qa)
    # 刪除虛懸鏡像(虛懸鏡像看以下部分)
    docker image prune

其他命令

# 將鏡像導出為 tar文件
docker save imageName > file.tar
# 解壓鏡像
docker load -i file.tar
# 查看鏡像構建歷史
docker history imageName
# 查看鏡像詳細信息
docker inspect imageName

虛懸鏡像

Docker 虛懸鏡像(dangling image)指的是沒有被任何容器使用的鏡像。在 Docker 中,每個新構建的鏡像都會創建一個新的鏡像 ID,並且舊的鏡像 ID 會被保留在本地。當使用 docker images 命令查看本地鏡像列表時,可能會看到一些虛懸鏡像,它們的 REPOSITORY 和 TAG 字段顯示為 <none>

虛懸鏡像可能是由於以下原因導致的:

  • 構建新版本的鏡像時,舊的鏡像 ID 會被保留在本地,而新的鏡像 ID 會覆蓋舊的鏡像 ID。
  • 刪除容器時,容器所依賴的鏡像不會被自動刪除,因此可能會留下一些虛懸鏡像。
  • 在使用docker rmi命令刪除鏡像時,如果沒有指定正確的鏡像ID或名稱,也可能會刪除不正確的鏡像,從而產生虛懸鏡像。

舉一個重複構建同名同tag的nginx鏡像:

➜ docker images --filter reference=nginx
REPOSITORY   TAG       IMAGE ID       CREATED       SIZE
nginx        1.15.3    c5e5a72af32f   4 years ago   103MB

# 啓動容器
➜ docker run -d --name nginx nginx:1.15.3
1453e55d41100b57f5f76ed036f65276e311db36c4f3e9afd3fce49a25c4f8b8

# 打一個新鏡像
➜ docker commit nginx nginx:1.15.3
sha256:db2d3fa0bcb45bdc528960d1b06eb68496f044896d901e23d79bb1e54af56b9e

# 重新查看
➜ docker images --filter reference=nginx
REPOSITORY   TAG       IMAGE ID       CREATED          SIZE
nginx        1.15.3    db2d3fa0bcb4   52 seconds ago   103MB
nginx        <none>    c5e5a72af32f   4 years ago      103MB

容器

容器是鏡像的運行實例。Docker 容器是一個動態的環境,通過在鏡像之上創建一個運行實例,可以啓動和運行應用程序。容器是一個具有生命週期的實體,可以被創建、啓動、停止、刪除和遷移等操作。

容器可以通過鏡像來創建。在 Docker 中,通過 Dockerfile 或者其他方式創建一個鏡像,然後通過這個鏡像來創建一個或多個容器實例。這些容器實例都是基於同一個鏡像創建的,但它們之間是相互獨立的,擁有自己的文件系統、網絡和進程空間。

容器可以通過修改來生成新的鏡像。在容器運行時,可以對容器內部的文件系統進行修改,如添加、刪除、修改文件等。這些修改可以通過 Docker commit 命令來保存為一個新的鏡像,以便後續使用。

啓動

啓動 Docker 容器需要使用 docker run 命令,該命令用於創建和啓動一個新的 Docker 容器實例。下面是 docker run 命令的一些常用選項和參數:

docker run [OPTIONS] IMAGE [COMMAND] [ARG...]

其中,OPTIONS 是一些可選的命令選項,IMAGE 是要創建容器的鏡像名稱或 IDCOMMAND 是容器啓動後要運行的命令,ARG 是命令的參數。一些常用的選項包括:

  • -d:後台運行容器
  • -it:交互運行,並分配一個容器偽終端
  • -p:指定容器的端口映射
  • -v:指定容器與主機之間的文件共享
  • --name:為容器指定一個名稱
  • -e:設置容器的環境變量
  • --rm:退出後刪除容器

這裏是docker run的幾個小例子:

# 後台運行nginx,容器命名nginx,映射宿主機端口 8080到nginx容器的80端口
docker run -d --name nginx -p 8080:80 nginx

# 使用交互式運行centos容器,exit退出後 自動刪除容器
docker run -it --rm centos /bin/bash

# 啓動nginx 並將 nginx容器內部的 nginx靜態文件路徑掛載到宿主機上指定位置
docker run -v /somedir/data:/etc/share/nginx/html nginx

以上便是docker run啓動一個新容器的基本玩法,除了新啓動一個容器外,還可以使用docker start啓動一個已經停止的容器或docker restart重啓一個容器

docker start nginx
docker restart nginx

進入容器

docker exec命令用於在運行中的Docker容器中執行命令。該命令可以讓用户在運行中的容器中打開一個新的終端,以執行任意的命令或者進入容器內部進行交互式操作。以下是docker exec命令的基本語法:

docker exec [OPTIONS] CONTAINER COMMAND [ARG...]

其中,OPTIONS是可選參數,CONTAINER 是要執行命令的容器名稱或 IDCOMMAND 是要在容器中執行的命令,ARG是命令的參數。

除了使用docker exec外,docker還支持docker attach用於連接到正在運行中的Docker容器的標準輸入、輸出和錯誤流(即 STDIN、STDOUT 和 STDERR)。這個命令可以讓用户實時地查看容器中的輸出信息

➜ docker attach nginx
192.168.10.1 - - [26/Mar/2020:02:15:38 +0000] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36" "-"

當使用Ctrl + C時會退出容器並停止容器的運行,官方建議使用docker exec進入容器做一些高級的操作

容器列表

當容器運行後可以在容器列表中看到,要查看當前系統中正在運行的 Docker 容器列表,可以使用 docker ps 命令。該命令顯示了所有正在運行的容器的相關信息,如容器 ID、鏡像名稱、容器名稱、啓動時間、狀態等。以下是一些常用的 docker ps 命令選項:

  • -a:顯示所有容器,包括已經停止的容器
  • -q:只顯示容器的 ID
  • --no-trunc:顯示完整的容器 ID
  • -s:顯示容器的磁盤使用情況
  • --filter:基於條件過濾輸出

    # docker ps -as
    CONTAINER ID   IMAGE           COMMAND               CREATED         STATUS        PORTS     NAMES    SIZE
    ff21fc7bdfbe   nginx:1.15.3  "nginx -g 'daemon of…"  54 seconds ago  Up 53 seconds 80/tcp    nginx    2B (virtual 103MB)
    
    # 只顯示nginx
    docker ps --filter name=nginx

    可以通過查看容器列表容器的狀態查看啓動的容器有沒有正常運行,除了這種方式還可以通過容器的日誌,查看內部運行的細節

容器日誌

docker logs命令用於查看Docker容器的日誌信息。該命令可以查看容器的標準輸出和標準錯誤輸出,以及容器內部運行的進程的日誌信息。以下是 docker logs 命令的語法:

docker logs [OPTIONS] CONTAINER

其中,OPTIONS 是一些可選的命令選項,CONTAINER 是要查看日誌的容器名稱或 ID。一些常用的選項包括:

  • -f:實時跟蹤容器的日誌輸出
  • --tail:指定顯示最後幾行日誌,默認為所有日誌
  • --since:指定顯示從某個時間戳開始的日誌
  • --until:指定顯示到某個時間戳結束的日誌

    # 實時查看nginx的日誌
    ➜ docker logs -f nginx
    192.168.10.1 - - [26/Mar/2020:01:06:35 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36" "-"
    2020/03/26 01:06:35 [error] 7#7: *1 open() "/usr/share/nginx/html/favicon.ico" failed (2: No such file or directory), client: 192.168.10.1, server: localhost, request: "GET /favicon.ico HTTP/1.1", host: "192.168.10.10:8088", referrer: "http://192.168.10.10:8088/"

    通過docker logs可以很看到內部運行的詳細日誌,對於自己的容器需要做好日誌的輸出方便查看日誌和錯誤追溯

停止

容器起來後不想運行了怎麼辦,可以使用停止命令停止正在運行的容器,使用該命令會發送一個 SIGTERM 信號給容器中運行的主進程,請求其停止運行,並等待一定時間(默認為10秒)讓容器中的進程進行清理和保存工作。如果在指定的時間內容器中的進程仍未停止,則會發送一個 SIGKILL 信號,強制終止容器中的進程

docker stop [OPTIONS] CONTAINER [CONTAINER...]

OPTIONS 是一些可選的命令選項,CONTAINER 是要停止的一個或多個容器名稱或 ID。一些常用的選項包括:

  • -t:指定等待容器停止的時間,單位為秒,默認10s
  • --signal:發送給容器的信號

除了docker stop命令,以前還可以使用docker kill命令,不過已經被廢棄掉

刪除

docker rm 命令用於刪除已經停止的 Docker 容器。該命令只能刪除已經停止的容器,如果要刪除正在運行的容器,需要先使用docker stop命令停止容器。以下是 docker rm 命令的語法:

docker rm [OPTIONS] CONTAINER [CONTAINER...]

其中,OPTIONS 是一些可選的命令選項,CONTAINER 是要刪除的一個或多個容器名稱或 ID。一些常用的選項包括:

  • -f:強制刪除容器,即使容器正在運行
  • -v:同時刪除與容器關聯的卷(volume)

    # 強制刪除正在運行的nginx容器
    docker rm -f nginx

    除了docker rm命令外,還可以使用docker ps prune命令來刪除所有已經停止的容器並釋放容器佔用的資源,不過一般不常用,畢竟已經停止的容器一般倒不是不需要的:

    # 強制刪除所有容器
    docker ps prune -f

導入導出

Docker 容器的導入導出可以用於將一個容器的文件系統打包成一個 tar 文件,並在另一台機器上重新導入為一個新的 Docker 鏡像。這種方式可以方便地將一個容器遷移到另一台機器上,或者分享容器鏡像給其他人使用。

:::warning

  1. 導出的 tar 文件只包含容器的文件系統,並不包含容器的元數據(如容器的名稱、ID、端口等信息)
  2. 導入的鏡像只包含容器的文件系統,不包含容器的元數據和啓動命令等信息
  3. 導出的 tar 文件和導入的鏡像都是針對單個容器的,不包含容器依賴的鏡像和容器的運行環境等信息。如果要遷移一個應用程序,需要將所有相關的容器和鏡像一起導出導入
    :::
  4. 導出容器的文件系統為一個 tar 文件,使用 docker export 命令導出容器的文件系統為一個 tar 文件。例如,要將名為 mycontainer 的容器的文件系統導出為一個 mycontainer.tar 文件,可以使用以下命令:

    docker export mycontainer > mycontainer.tar
  5. 導入容器的文件系統為一個鏡像,使用 docker import 命令將 tar 文件導入為一個新的 Docker 鏡像。例如,要將名為 mycontainer.tar 的 tar 文件導入為一個名為 myimage 的 Docker 鏡像,可以使用以下命令:

    docker import mycontainer.tar myimage

倉庫

Docker Registry 是 Docker 平台的一個核心組件,它是一個用於存儲、分發和管理 Docker 鏡像的服務器端應用程序。Docker Registry 允許用户將本地創建的鏡像上傳到 Registry 中,並可以從 Registry 中下載和使用其他用户共享的鏡像。它可以簡化 Docker 鏡像的管理和分發,提高應用的部署效率和可靠性。同時,Docker Registry 還提供了一系列的管理工具和服務,如 Docker Trusted Registry(DTR)、Harbor 等,可以幫助用户更好地管理和保護 Docker 鏡像,確保安全和可靠性。

Docker Registry 可以分為兩種類型:公共Registry私有Registry

每個registry中包含多個倉庫,我們本地的registry其實也是這樣,每個倉庫有多個tag來表示不同版本的倉庫鏡像,你可以將registry看做是一個gitlab,gitlab中的每個倉庫代表着每個鏡像,倉庫的tag表示鏡像的版本

公有倉庫

公共 Registry 是由 Docker 公司維護的一組公共鏡像倉庫,其中最著名的是 Docker Hub。Docker Hub 是一個公共的 Docker Registry,包含了大量的 Docker 鏡像,開發者可以通過 Docker Hub 來獲取和分享 Docker 鏡像。

Docker 公開倉庫的鏡像完整地址由三個部分組成:倉庫地址、鏡像名稱和鏡像標籤。

其中,倉庫地址指的是 Docker 鏡像倉庫的地址,Docker 官方的公開倉庫地址為 docker.io,也可以使用其他的鏡像倉庫地址。鏡像名稱是指 Docker 鏡像的名稱,通常由兩部分組成,即鏡像的命名空間和鏡像的名稱,中間使用斜槓 / 隔開。例如,library/nginx 表示 Docker 官方的 nginx 鏡像。鏡像標籤是指鏡像的版本號或標識符,用冒號 : 隔開。例如,library/nginx:latest 表示最新版本的 Docker 官方的 nginx 鏡像。

# 本地已經存在了 nginx:1.15.3
➜ docker images | grep nginx
nginx  1.15.3  c5e5a72af32f  4 years ago  103MB

# 重新用完整的地址下載nginx:1.15.3,再次查看還是那個nginx
docker pull docker.io/library/nginx:1.15.3

私有倉庫

私有 Registry 是指由用户自己搭建的 Docker 鏡像倉庫,用於存儲和管理自己創建的 Docker 鏡像。私有 Registry 可以在內部部署,也可以在公有云上部署,如 Amazon Web Services、Microsoft Azure 和 Google Cloud Platform 等。

博客中也介紹了關於私有倉庫的搭建,你可以去閲讀我的「搭建docker私有倉庫」一文去了解完整的私庫搭建過程。

認證

Docker 倉庫認證是一種基於用户名和密碼的身份驗證機制,用於保護Docker鏡像倉庫中的鏡像資源,防止未經授權的用户訪問和下載鏡像

  1. 可以使用命令行登錄:

    docker login [OPTIONS] [SERVER]

    其中OPTIONSSERVER是可選部分,OPTIONS 的參數包括:

    • -u:登錄的用户名
    • -p:登錄密碼
      SERVER 則是倉庫的地址,默認是docker官方的倉庫地址
      你可以這樣使用:

      # 一鍵式登錄  ====>   官方不推薦,密碼會暴露😂
      docker login -u root -p password [url]
      
      # 交互式
      docker login [url]
      Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
      Username: root
      Password:
  2. 直接在docker的$HOME/.docker/config.json中配置倉庫地址和登錄憑證,通過命令行登錄後,會在你的$HOME/.docker/config.json文件中添加倉庫和登錄憑證,你可以直接在此文件中添加你想要登錄的地址和密碼,如果沒有此文件自行創建即可,配置文件如下:

    {
      "auths": {
          // 倉庫地址,這裏是官方地址
        "https://index.docker.io/v1/": {
            // 憑證
            "auth": "aWhlbmdzaHVhaToxMjM0NTYK"
        },
        // 其他倉庫
        "192.168.10.10:8000": {
            "auth": "aWhlbmdzaHVhaToxMjM0NTYK"
        },
      }
    }

    上面的配置文件中存在兩個倉庫地址,當使用docker login時如果不指明地址默認會登錄官方倉庫,在登錄時docker會檢查本地的$HOME/.docker/config.json中是否存在已經登錄的憑證,如果存在會直接登錄,否則會和第一步一樣重新輸入賬號、密碼。

    以上的auth值其實就是賬户:密碼的base64結果,其加密結果並不安全,可以通過base64反解碼出來,我們試下:

    ➜ echo 'aWhlbmdzaHVhaToxMjM0NTYK' | base64 --decode
    ihengshuai:123456
    所以不要輕易將加密後的密碼泄露掉
  3. 退出登錄

    docker logout [SERVER]

    退出後同樣會刪除$HOME/.docker/config.json中對應的倉庫地址和密碼

總結

本文從docker的架構、全局命令、鏡像、容器和倉庫入門,簡單的介紹了docker的基本使用,這些命令基本上囊括了docker常見的命令行使用方式,需要大家多多使用才能熟練,雖然docker的命令在生產環境的使用機率不是很多,但是對於我們快速啓動一個想要的環境或驗證一些想法都是非常友好的,總之熟能生巧。

user avatar zhangshilei 頭像 best_6455a509a2177 頭像
2 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.