目錄
- 一,Docker 簡介
- 1.1,什么是 Docker
- 1.2,Docker 與虛擬機(jī)的區(qū)別
- 1.3,Docker 架構(gòu)
- 1.4,為什么用 Docker
- 二,Docker 基本概念
- 2.1,鏡像
- 2.2,容器
- 2.3,倉庫
- 三,Docker 使用
- 3.1,Docker 服務(wù)
- 3.2,下載與使用Docker公共鏡像(Images)
- 四,Docker 鏡像命令
- 五,Docker 容器命令
- 5.1,docker run 命令
- 5.2 docker run命令語法
- 六,參考資料
一,Docker 簡介
1.1,什么是 Docker
Docker
使用 Google 公司推出的 Go 語言 進(jìn)行開發(fā)實(shí)現(xiàn),基于 Linux 內(nèi)核的 cgroup,namespace,以及 OverlayFS 類的 Union FS 等技術(shù),對進(jìn)程進(jìn)行封裝隔離,屬于操作系統(tǒng)層面的虛擬化技術(shù)。由于隔離的進(jìn)程獨(dú)立于宿主和其它的隔離的進(jìn)程,因此也稱其為容器。Docker容器與虛擬機(jī)類似,但二者在原理上不同。容器是將操作系統(tǒng)層虛擬化,虛擬機(jī)則是虛擬化硬件,因此容器更具有便攜性、能更高效地利用服務(wù)器。
專業(yè)名詞 Docker
有兩個(gè)意思:
代指整個(gè) Docker 項(xiàng)目。 代指 Docker 引擎。
Docker 引擎(Docker Engine)是指一個(gè)服務(wù)端-客戶端結(jié)構(gòu)的應(yīng)用,主要有這些部分:Docker 守護(hù)進(jìn)程、Docker Engine API(頁面存檔備份,存于互聯(lián)網(wǎng)檔案館)、Docker 客戶端。
1.2,Docker 與虛擬機(jī)的區(qū)別
傳統(tǒng)虛擬機(jī)技術(shù)是虛擬出一套硬件后,在其上運(yùn)行一個(gè)完整操作系統(tǒng),在該系統(tǒng)上再運(yùn)行所需應(yīng)用進(jìn)程。 Docker 容器內(nèi)的應(yīng)用進(jìn)程直接運(yùn)行于宿主的內(nèi)核,容器內(nèi)沒有自己的內(nèi)核,而且也沒有進(jìn)行硬件虛擬。因此容器要比傳統(tǒng)虛擬機(jī)更為輕便。 特性 Docker 虛擬機(jī) 啟動(dòng) 秒級 分鐘級 硬盤使用 一般為 MB 一般為 GB 性能 接近原生 弱于 系統(tǒng)支持量 單機(jī)支持上千個(gè)容器 一般幾十個(gè)
1.3,Docker 架構(gòu)
runc 是一個(gè) Linux 命令行工具,用于根據(jù) OCI容器運(yùn)行時(shí)規(guī)范 創(chuàng)建和運(yùn)行容器。
containerd 是一個(gè)守護(hù)程序,它管理容器生命周期,提供了在一個(gè)節(jié)點(diǎn)上執(zhí)行容器和管理鏡像的最小功能集。
1.4,為什么用 Docker
Docker 作為一種新的虛擬化技術(shù),跟傳統(tǒng)的虛擬化技術(shù)相比具有眾多的優(yōu)勢:
- 更高效的利用系統(tǒng)資源:不需要進(jìn)行硬件虛擬以及運(yùn)行完整操作系統(tǒng)等額外開銷,Docker 對系統(tǒng)資源的利用率更高。
- 更快速的啟動(dòng)時(shí)間:Docker 容器應(yīng)用直接運(yùn)行于宿主內(nèi)核,不需要啟動(dòng)完整的操作系統(tǒng),所以啟動(dòng)時(shí)間可做到秒級的啟動(dòng)時(shí)間。
- 一致的運(yùn)行環(huán)境:Docker 鏡像提供了除內(nèi)核外完整的運(yùn)行時(shí)環(huán)境,確保開發(fā)環(huán)境、測試環(huán)境、生產(chǎn)環(huán)境的一致性。
- 持續(xù)交付和部署:開發(fā)人員可以通過 Dockerfile 來進(jìn)行鏡像構(gòu)建,并結(jié)合持續(xù)集成(Continuous Integration) 系統(tǒng)進(jìn)行集成測試,而運(yùn)維人員則可以直接在生產(chǎn)環(huán)境中快速部署該鏡像,甚至結(jié)合持續(xù)部署(Continuous Delivery/Deployment) 系統(tǒng)進(jìn)行自動(dòng)部署。
- 更輕松的遷移:Docker 可以在很多平臺上運(yùn)行,無論是物理機(jī)、虛擬機(jī)、公有云、私有云,甚至是筆記本,其運(yùn)行結(jié)果是一致的。 更輕松的維護(hù)和擴(kuò)展。
二,Docker 基本概念
Docker 三個(gè)基本概念:
鏡像(Image) 容器(Container) 倉庫(Repository)
2.1,鏡像
操作系統(tǒng)分為內(nèi)核和用戶空間。對于 Linux 而言,內(nèi)核啟動(dòng)后,會掛載 root 文件系統(tǒng)為其提供用戶空間支持。而 Docker 鏡像(Image),就相當(dāng)于是一個(gè) root 文件系統(tǒng)。比如官方鏡像 ubuntu:18.04 就包含了完整的一套 Ubuntu 18.04 最小系統(tǒng)的 root 文件系統(tǒng)。
Docker 鏡像 是一個(gè)特殊的文件系統(tǒng),除了提供容器運(yùn)行時(shí)所需的程序、庫、資源、配置等文件外,還包含了一些為運(yùn)行時(shí)準(zhǔn)備的一些配置參數(shù)(如匿名卷、環(huán)境變量、用戶等)。鏡像 不包含 任何動(dòng)態(tài)數(shù)據(jù),其內(nèi)容在構(gòu)建之后也不會被改變。
Docker 鏡像并非是像一個(gè) ISO
那樣的打包文件,鏡像只是一個(gè)虛擬的概念,其實(shí)際體現(xiàn)并非由一個(gè)文件組成,而是由一組文件系統(tǒng)組成,或者說,由多層文件系統(tǒng)聯(lián)合組成。其被設(shè)計(jì)為分層存儲的架構(gòu),鏡像構(gòu)建時(shí),會一層層構(gòu)建,前一層是后一層的基礎(chǔ)。每一層構(gòu)建完就不會再發(fā)生改變,后一層上的任何改變只發(fā)生在自己這一層。分層存儲的特征還使得鏡像的復(fù)用、定制變的更為容易。甚至可以用之前構(gòu)建好的鏡像作為基礎(chǔ)層,然后進(jìn)一步添加新的層,以定制自己所需的內(nèi)容,構(gòu)建新的鏡像。
2.2,容器
鏡像(Image)和容器(Container)的關(guān)系,類似面向?qū)ο蟪绦蛟O(shè)計(jì)中的類和實(shí)例的關(guān)系。可以把 Docker容器(Container) 看做是一個(gè)簡易版的 Linux 環(huán)境(包括 root 用戶權(quán)限、進(jìn)程空間、用戶空間和網(wǎng)絡(luò)空間等)和運(yùn)行在其中的應(yīng)用程序。它可以被啟動(dòng)、開始、停止、 刪除。
容器的實(shí)質(zhì)是進(jìn)程,但與直接在宿主執(zhí)行的進(jìn)程不同,容器進(jìn)程運(yùn)行于屬于自己的獨(dú)立的 命名空間。因此容器可以擁有自己的 root 文件系統(tǒng)、自己的網(wǎng)絡(luò)配置、自己的進(jìn)程空間,甚至自己的用戶 ID 空間。容器內(nèi)的進(jìn)程是運(yùn)行在一個(gè)隔離的環(huán)境里,使用起來,就好像是在一個(gè)獨(dú)立于宿主的系統(tǒng)下操作一樣。
容器和鏡像一樣都是使用分層存儲,每一個(gè)容器運(yùn)行時(shí),是以鏡像為基礎(chǔ)層,在其上創(chuàng)建一個(gè)當(dāng)前容器的存儲層,我們可以稱這個(gè)為容器運(yùn)行時(shí)讀寫而準(zhǔn)備的存儲層為容器存儲層。
2.3,倉庫
鏡像構(gòu)建完成后,可以很容器的在當(dāng)前宿主主機(jī)上運(yùn)行,但是如果需要在其他服務(wù)器上使用這個(gè)鏡像,我們就需要一個(gè)集中的存儲、分發(fā)鏡像的服務(wù),Docker Registry 就是這樣的服務(wù)。
一個(gè) Docker Registry 中可以包含多個(gè) 倉庫(Repository);每個(gè)倉庫可以包含多個(gè) 標(biāo)簽(Tag);每個(gè)標(biāo)簽對應(yīng)一個(gè)鏡像。
通常,一個(gè)倉庫會包含同一個(gè)軟件不同版本的鏡像,而標(biāo)簽就常用于對應(yīng)該軟件的各個(gè)版本。我們可以通過 <倉庫名>:<標(biāo)簽>
的格式來指定具體是這個(gè)軟件哪個(gè)版本的鏡像。如下所示:
registry.sensetime.com/kestrel_tatraffic/kestrel_tatraffic:kestrel_cuda11_1.2.21_opencv3.4.13_with_ffmpeg
Docker倉庫(Registry) 分為公開倉庫(Public)和私有倉庫(Private)兩種形式。最大的公開倉庫是 Docker Hub, 存放了數(shù)量龐大的鏡像供用戶下載。國內(nèi)的公開倉庫包括 Docker Pool 等,可以提供大陸用戶更穩(wěn)定快速的訪問。私有倉庫是指用戶在本地搭建的私有 Docker Registry。
三,Docker 使用
3.1,Docker 服務(wù)
安裝 Docker 這里不做介紹。以下是 Linux 系統(tǒng)下,一些 docker 使用命令:
1,查看 Docker 服務(wù)狀態(tài):使用 systemctl status docker
命令查看 Docker 服務(wù)的狀態(tài)。其中 Active: active (running) 即表示 Docker 服務(wù)為正在運(yùn)行狀態(tài)。
2,停止 Docker 服務(wù):使用 systemctl stop docker
命令。
3,啟動(dòng) Docker 服務(wù):使用 systemctl start docker
命令。
4,重啟 Docker 服務(wù):使用 systemctl restart docker
命令。
5,測試 Docker 是否安裝正確。
$ docker run --rm hello-world Unable to find image 'hello-world:latest' locally latest: Pulling from library/hello-world 7050e35b49f5: Pull complete Digest: sha256:13e367d31ae85359f42d637adf6da428f76d75dc9afeb3c21faea0d976f5c651 Status: Downloaded newer image for hello-world:latest Hello from Docker! This message shows that your installation appears to be working correctly. To generate this message, Docker took the following steps: 1. The Docker client contacted the Docker daemon. 2. The Docker daemon pulled the "hello-world" image from the Docker Hub. (arm64v8) 3. The Docker daemon created a new container from that image which runs the executable that produces the output you are currently reading. 4. The Docker daemon streamed that output to the Docker client, which sent it to your terminal. To try something more ambitious, you can run an Ubuntu container with: $ docker run -it ubuntu bash Share images, automate workflows, and more with a free Docker ID: https://hub.docker.com/ For more examples and ideas, visit: https://docs.docker.com/get-started/
3.2,下載與使用Docker公共鏡像(Images)
1,使用 docker search 命令從 Docker Repo 搜索 Dokcer 可用的鏡像。示例命令:docker search ubuntu18.04
。
2,使用 docker image pull 命令從 Docker Repo 獲取指定的 Dokcer鏡像(Images)。示例命令: docker image pull docker.io/hello-world
。拉取名為 docker.io/hello-world 的鏡像。
3,使用 docker image ls 命令查看本地的 Dokcer 鏡像(Images)。
4,使用 docker run 命令運(yùn)行 Dokcer 鏡像(Images)。示例命令:docker run hello-world
。
5,使用 docker info 命令,查看當(dāng)前 docker容器 的所有的信息。
6,使用 docker version 查看容器的版本信息。
$ dockerd --versio # 這個(gè)命令查看 docker 版本更簡單 Docker version 19.03.13, build 4484c46d9d
四,Docker 鏡像命令
Docker鏡像(Images) 也可以理解為是一個(gè)用于創(chuàng)建 Docker容器(Container) 的靜態(tài)模板。一個(gè) Docker鏡像(Images) 可以創(chuàng)建很多 Docker容器(Container)。
Docker 鏡像常用命令如下:
命令 描述 docker commit 創(chuàng)建鏡像。 docker images 查看鏡像信息。 docker load 導(dǎo)入鏡像。 docker pull 拉取 Docker 鏡像。 docker push 上傳鏡像。 docker rmi 刪除鏡像。 docker save 導(dǎo)出鏡像。 docker search 在 Docker Hub 搜索鏡像。 docker tag 為鏡像打標(biāo)簽。
五,Docker 容器命令
5.1,docker run 命令
通過 docker run 命令可以基于鏡像新建一個(gè)容器并啟動(dòng),語法如下:
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
其他常用容器管理命令如下:
# 新建容器并啟動(dòng) $ docker run [鏡像名/鏡像ID] # 啟動(dòng)已終止容器 $ docker start [容器ID] # 列出本機(jī)運(yùn)行的容器 $ docker ps # 停止運(yùn)行的容器 $ docker stop [容器ID] # 殺死容器進(jìn)程 $ docker kill [容器ID] # 重啟容器 $ docker restart [容器ID]
5.2 docker run命令語法
1, docker run 命令常用選項(xiàng):可通過 docker run –help 命令查看全部內(nèi)容。
選項(xiàng) | 說明 |
---|---|
-d, –detach=false | 指定容器運(yùn)行于前臺還是后臺,默認(rèn)為 false。 |
-i, –interactive=false | 打開 STDIN,用于控制臺交互。 |
-t, –tty=false | 分配 tty 設(shè)備,該可以支持終端登錄,默認(rèn)為 false。 |
-u, –user="" | 指定容器的用戶。 |
-a, –attach=[] | 登錄容器(必須是以 docker run -d 啟動(dòng)的容器)。 |
-w, –workdir="" | 指定容器的工作目錄。 |
-c, –cpu-shares=0 | 設(shè)置容器 CPU 權(quán)重,在 CPU 共享場景使用。 |
-e, –env=[] | 指定環(huán)境變量,容器中可以使用該環(huán)境變量。 |
-m, –memory="" | 指定容器的內(nèi)存上限。 |
-P, –publish-all=false | 指定容器暴露的端口。 |
-p, –publish=[] | 指定容器暴露的端口。 |
-h, –hostname="" | 指定容器的主機(jī)名。 |
-v, –volume=[] | 給容器掛載存儲卷,掛載到容器的某個(gè)目錄。 |
–volumes-from=[] | 給容器掛載其他容器上的卷,掛載到容器的某個(gè)目錄。 |
–cap-add=[] | 添加權(quán)限。 |
–cap-drop=[] | 刪除權(quán)限。 |
–cidfile="" | 運(yùn)行容器后,在指定文件中寫入容器 PID 值,一種典型的監(jiān)控系統(tǒng)用法。 |
–cpuset="" | 設(shè)置容器可以使用哪些 CPU,此參數(shù)可以用來容器獨(dú)占 CPU。 |
–device=[] | 添加主機(jī)設(shè)備給容器,相當(dāng)于設(shè)備直通。 |
–dns=[] | 指定容器的 dns 服務(wù)器。 |
–dns-search=[] | 指定容器的 dns 搜索域名,寫入到容器的 /etc/resolv.conf 文件。 |
–entrypoint="" | 覆蓋 image 的入口點(diǎn)。 |
–env-file=[] | 指定環(huán)境變量文件,文件格式為每行一個(gè)環(huán)境變量。 |
–expose=[] | 指定容器暴露的端口,即修改鏡像的暴露端口。 |
–link=[] | 指定容器間的關(guān)聯(lián),使用其他容器的 IP、env 等信息。 |
–lxc-conf=[] | 指定容器的配置文件,只有在指定 –exec-driver=lxc 時(shí)使用。 |
–name="" | 指定容器名字,后續(xù)可以通過名字進(jìn)行容器管理,links 特性需要使用名字。 |
–net=“bridge” | 器網(wǎng)絡(luò)設(shè)置: 1. bridge 使用 docker daemon 指定的網(wǎng)橋。 2. host //容器使用主機(jī)的網(wǎng)絡(luò)。 3. container:NAME_or_ID >//使用其他容器的網(wǎng)路,共享 IP 和 PORT 等網(wǎng)絡(luò)資源。 4. none 容器使用自己的網(wǎng)絡(luò)(類似–net=bridge),但是不進(jìn)行配置。 |
–privileged=false | 指定容器是否為特權(quán)容器,特權(quán)容器擁有所有的 capabilities。 |
–restart=“no” | 指定容器停止后的重啟策略: 1. no:容器退出時(shí)不重啟。 2. on-failure:容器故障退出(返回值非零)時(shí)重啟。 3. always:容器退出時(shí)總是重啟。 |
–rm=false | 指定容器停止后自動(dòng)刪除容器(不支持以 docker run -d 啟動(dòng)的容器)。 |
–sig-proxy=true | 設(shè)置由代理接受并處理信號,但是 SIGCHLD、SIGSTOP 和 SIGKILL 不能被代理。 |
示例:kestrel 人群等 sdk 使用運(yùn)行容器的腳本如下:
export BUILDER=registry.sensetime.com/kestrel_tatraffic/kestrel_tatraffic:kestrel_cuda11_1.2.21_opencv3.4.13_with_ffmpeg # -t 選項(xiàng)讓Docker分配一個(gè)偽終端(pseudo-tty)并綁定到容器的標(biāo)準(zhǔn)輸入上, -i 則讓容器的標(biāo)準(zhǔn)輸入保持打開。 # --rm 指定容器停止后自動(dòng)刪除容器 # --net=host 容器使用主機(jī)的網(wǎng)絡(luò) # --ipc 要使用的 IPC 模式 # --ipc=host # -e 指定環(huán)境變量,容器中可以使用 # --privileged 指定容器是否為特權(quán)容器,特權(quán)容器擁有所有的 capabilities # -u 指定容器的用戶為 root # -entrypoint=bash 覆蓋 image 的入口點(diǎn) # -v 給容器掛載存儲卷,掛載到容器的 /kestrel_baggage # 指定容器的工作目錄為 /kestrel_baggage # ${BUILDER} 為運(yùn)行的鏡像 docker run --gpus '"device=0"' -it --rm --net=host --ipc=host \ -e DISPLAY=$DISPLAY \ --privileged \ -e XAUTHORITY=$XAUTH \ -u root \ --entrypoint=bash \ --ulimit core=-1 \ --security-opt seccomp=unconfined \ -v ${PWD}:/kestrel_baggage \ -w /kestrel_baggage \ ${BUILDER}
2,Docker交互式運(yùn)行的語法為:docker run -i -t IMAGE [COMMAND] [ARG]
。Docker交互式運(yùn)行,即 Docker 啟動(dòng)直接進(jìn)入 Docker 鏡像內(nèi)部。
3,使用 docker ps
命令,查看正在運(yùn)行的 docker。
六,參考資料
Docker-從入門到實(shí)踐
Docker教程