一、什么是容器
容器簡介
簡單說:容器(container)就是計算機上的一個沙盒進程,它與計算機上的所有其它進程相隔離。
這種隔離是怎么做到的呢?它利用了內(nèi)核提供的 namespace 和 cgroup 這 2 種技術(shù)。這些技術(shù)能力在 Linux 中已經(jīng)存在了很長時間。而 Docker 或容器技術(shù)致力于將這些功能更易于使用和更方便使用。容器技術(shù)把 linux 中已存在的這些技術(shù)顯性化了,讓用戶容易操作使用,體驗更好。
”沙盒“就像是一個集裝箱,能夠把應(yīng)用及其相關(guān)依賴軟件裝在一起。在 docker 的隔離下,應(yīng)用和應(yīng)用之間就有了邊界,相互隔離不被打擾,也方便“搬來搬去”,搬到各種服務(wù)器環(huán)境中運行。
Docker 的 logo 是一條鯨魚駝著許多"四方盒子“ - 標準集裝箱,很形象的表達。把軟件打包標準化,像一個一個集裝箱,可以方便快捷運輸?shù)礁鞣N服務(wù)器環(huán)境中并安裝。
Docker 的口號:
Develop faster. Run anywhere.
Docker 是容器技術(shù)的一種實現(xiàn),還有其它容器比如 Podman,Container 等。
容器的實質(zhì)是進程。但與直接運行在宿主機上的進程不同,容器進程運行在屬于自己獨立的命名空間。因此,容器可以擁有自己獨立的 root 文件系統(tǒng)、網(wǎng)絡(luò)配置、進程空間、自己的用戶 ID 空間等等。
容器的一些特性總結(jié):
- 它是鏡像(image)的一個運行實例。比如你能夠使用 docker api 或 cli 創(chuàng)建、啟動、停止、移動或刪除容器。
- 它可以在本地機器、虛擬機或云服務(wù)器上運行。
- 它可以在任何操作系統(tǒng)上運行。
- 它可以與其它容器隔離并運行自己的軟件、二進制文件和配置信息。
- 它可以自包含一些軟件,這樣就可以使應(yīng)用程序幾乎在任何地方以相同的方式運行。
比如開發(fā)人員在自己筆記本上創(chuàng)建并測試好的容器,無須修改就可以在生產(chǎn)系統(tǒng)的虛擬機、服務(wù)器等上面運行。
容器解決了什么問題
我們把應(yīng)用程序開發(fā)完之后,部署到服務(wù)器上時,會有很多軟件需要部署,比如部署 PHP 程序開發(fā)的應(yīng)用項目,就有 MySQL,Redis,Nginx 等各種軟件需要部署。
部署的服務(wù)器環(huán)境呈現(xiàn)多樣化,比如物理服務(wù)器,云服務(wù)器,虛擬機等,不同服務(wù)器上安裝的操作系統(tǒng)可能又不同,運行環(huán)境不同,依賴各不同。
面對這種多個軟件需要部署,不同的服務(wù)器環(huán)境、不同的操作系統(tǒng),環(huán)境差異這么大,如何能做到一鍵部署且屏蔽彼此的各種差異?如何做到構(gòu)建一次完之后就能部署到各種不同的服務(wù)器環(huán)境中?也就是,一次構(gòu)建,多地多次部署,且都能順利運行。
這時容器技術(shù)就可以解決這些問題。容器能夠把應(yīng)用程序及其依賴的軟件打包到一個容器中,然后發(fā)布到各種服務(wù)器上。
這樣就能加快運行環(huán)境搭建、應(yīng)用程序的部署,解決了運維效率和成本高的一些問題。
一次構(gòu)建,隨時隨地搬運,任意環(huán)境運行
? (Build,Ship and Run Anywhere)
Docker 還提供了一種類似“編程的方式”來方便構(gòu)建鏡像:Dockerfile。
二、什么是鏡像
鏡像(Container Image)是一個模板,一種容器化標準化交付物,容器應(yīng)用打包的標準格式,用于打包應(yīng)用程序及其依賴環(huán)境。
容器和鏡像的關(guān)系,這個就相當于面向?qū)ο缶幊陶Z言中,類(container image)和實例(container instance)的關(guān)系。鏡像是靜態(tài)定義,容器是鏡像運行時的實體。容器可以被創(chuàng)建、啟動、刪除、暫停等。
容器鏡像是一個隨時可以運行的軟件包,當運行一個容器時,它使用一個隔離的文件系統(tǒng),這個自定義的文件系統(tǒng)包含應(yīng)用程序所需的依賴項、配置、腳本、二進制文件等,鏡像也包含其它平臺的設(shè)置。
我們可以借用 Buildah 等開源工具,來創(chuàng)建兼容 OCI 和 Docker 的鏡像文件。
Dockerfile 是用來構(gòu)建鏡像的文本文件,文本內(nèi)容包含了構(gòu)建鏡像所需的指令和說明。Docker 等工具可以通過讀取 Dockerfile 中的指令自動構(gòu)建生成容器鏡像。
三、鏡像倉庫
鏡像倉庫(container repository)是存儲、分發(fā)鏡像文件的地方。這些鏡像文件放在鏡像倉庫里。鏡像倉庫可以是開放的鏡像倉庫,例如 docker hub;也可以是自建的鏡像倉庫,比如用 docker-registry ,harbor , Nexus 等。
四、什么是Docker
Docker 簡介
Docker 是用 Go 開發(fā)實現(xiàn),基于 linux 的 cgroup,namespace 和 UniosFS 等主要技術(shù),對進程進行封裝隔離,在操作系統(tǒng)之上的虛擬化技術(shù)。隔離的進程是獨立于宿主和其它進程,它又稱為容器。
Docker 容器,又進一步的封裝,從文件系統(tǒng)、網(wǎng)絡(luò)到進程隔離等,簡化了容器的創(chuàng)建、啟動、刪除等操作。Docker 技術(shù)比虛擬機技術(shù)更為輕便。
Docker 可以快速、一致性的交付你的應(yīng)用程序。
Docker和虛擬機比較
(來自 kubernetes 官網(wǎng))
從上圖軟件交付的變化歷程圖可以看出,容器和傳統(tǒng)虛擬機的不同。
-
傳統(tǒng)虛擬機是虛擬出一套硬件,在其上運行完整操作系統(tǒng),在這之上再來運行各種應(yīng)用軟件。
-
容器直接運行在容器運行時上,容器運行時直接運行在宿主機的內(nèi)核里,它也不需要進行硬件虛擬化。
虛擬機和容器的比較:
特點 | 容器 | 虛擬機 |
---|---|---|
隔離性 | 較弱的隔離 | 強隔離 |
啟動速度 | 秒級 | 分鐘級 |
鏡像大小 | 最小的幾 MB | 幾百 MB 到幾個 GB |
性能(與裸機比) | 損耗小于 2% | 損耗 15% 左右 |
系統(tǒng)支持數(shù)量 | 單機可支持 100 個到 1000 個容器 | 單機支持 10 到 100 個左右 |
安全性 | 1.容器內(nèi)的用戶從普通用戶權(quán)限提升到root用戶,就直接具備宿主機root權(quán)限 2. 容器中沒有硬件隔離,這使得容器攻擊彼此牽連 | 1.虛擬機租戶root權(quán)限和主機的root權(quán)限是分離的 2.硬件隔離技術(shù):防止虛擬機彼此交互 |
五、Docker架構(gòu)和執(zhí)行流程
Docker 整體架構(gòu)
Docker 整體架構(gòu)圖:
? (來自:docker docs architecture)
Docker 架構(gòu)是一個客戶端-服務(wù)端架構(gòu),客戶端是 Client
,服務(wù)端是 Docker Host
。后面的 Registry
是一個鏡像倉庫。
Docker 客戶端與 Docker daemon 守護進程進行通信,守護進程負責(zé)構(gòu)建、運行和分發(fā) Docker 容器。Docker 客戶端和 Docker 守護進程直接進行信息交互。Docker 還有另外一個客戶端 Docker Compose,它處理一組容器組成的應(yīng)用程序。
Client :docker 客戶端。docker run
,docker build
,docker pull
,都是 docker 里的命令。
-
docker build
:執(zhí)行 docker 構(gòu)建命令,會根據(jù) docker 文件構(gòu)建一個鏡像存放在本機上。 -
docker run
:執(zhí)行 docker 啟動命令,它會將鏡像運行為容器。 -
docker pull
:該命令從鏡像倉庫拉取鏡像文件至本地 docker 主機,或?qū)⒈镜冂R像推送至遠端鏡像倉庫。
Docker Host:docker 主機。Docker daemon,守護進程;Images,鏡像;Containers,容器。
Registry:鏡像倉庫,存儲鏡像的倉庫。
docker 執(zhí)行流程
其實上面的架構(gòu)圖已經(jīng)把 docker 執(zhí)行流程畫出來了。只不過看起來不太明顯,在簡化下:
? (docker 命令執(zhí)行流程,實線條不同顏色代表不同步驟)
從圖上可以看出,docker 客戶端發(fā)出命令,后都會與 docker host(docker 主機)交互,然后在由 docker 主機進行后面的操作。
比如 docker 構(gòu)建:在 docker 客戶端發(fā)出命令,docker 主機的守護進程接收命令,然后它通過鏡像來運行出一個容器。
docker 底層技術(shù)
請看下面的架構(gòu)圖:
? (docker 底層技術(shù)構(gòu)成簡圖)
linux kernel,docker 技術(shù)的實現(xiàn)依賴了 linux 底層一些技術(shù)特性:
- Namespace:每個容器都有自己獨立的命名空間,運行在其中的應(yīng)用像是在獨立操作系統(tǒng)上運行。命名空間保證了容器彼此不受影響。
- CGroups:對共享資源進行隔離、限制等。比如對CPU、內(nèi)存的限制。
- Union FS:聯(lián)合文件系統(tǒng)是一種分層、輕量級且高性能的文件系統(tǒng)。
Docker 使用存儲驅(qū)動程序(storage driver)來存儲 image 的圖像層,將數(shù)據(jù)存儲在容器的可寫層中。
Docker 鏡像是由一系列層(layers)構(gòu)建而成,每層代表 Dockerfile 的一條指令。除了最后一層之外每一層都是只讀的。
Docker 用 UnionFS (聯(lián)合文件系統(tǒng))把這些層聯(lián)合在一起。
? (來源docker storage driver:images and layers)
? (圖片來源網(wǎng)絡(luò)侵刪)
docker engine
docker engine 引擎里的 runc 是開放容器運行時,它是 OCI(Open Container Initiative)Spec 的一個實現(xiàn)。
docker engine 在 linux 下提供了很多存儲驅(qū)動,Docker Storage Driver:
Docker Storage Driver |
---|
overlay2 |
fuse-overlayfs |
btrfs and zfs
|
vfs |
devicemapper |
關(guān)于上面 docker storage driver 的更多信息請查看:https://docs.docker.com/storage/storagedriver/select-storage-driver/ 。
六、Docker安裝
Docker 可以在不同的操作系統(tǒng)中安裝,官方安裝地址:
- https://docs.docker.com/engine/install/ docker engine 安裝
- https://docs.docker.com/get-docker/ docker desktop 安裝,docker 桌面系統(tǒng)安裝
我在虛擬機中裝的 ubuntu 操作系統(tǒng):
Description: Ubuntu 20.04.2 LTS, Codename: focal
該系統(tǒng)對應(yīng) docker 官方安裝地址:https://docs.docker.com/engine/install/ubuntu/ 。
具體安裝 docker 就不詳細說明了,請按照官方文檔一步一步進行安裝。
我安裝的docker版本:
$ docker -v
Docker version 24.0.1, build 6802122
驗證是否安裝成功:
$ sudo docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
719385e32844: Pull complete
Digest: sha256:fc6cf906cbfa013e80938cdf0bb199fbdbb86d6e3e013783e5a766f50f5dbce0
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.
(amd64)
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/
七、Docker簡單使用
docker cli文檔地址:https://docs.docker.com/engine/reference/commandline/cli/
啟動容器
啟動容器
創(chuàng)建或啟動一個新容器的命令:docker run
, 語法為:
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
獲取更多 docker run 幫助文檔:docker run --help
。
比如,下面的命令輸出一個“hello world”后,終止容器。
因為我本地沒有 ubuntu:20.04 這個鏡像,所以要先下載,docker run
會自動下載這個鏡像,命令和運行過程如下:
$ sudo docker run ubuntu:20.04 /bin/echo 'hello world'
Unable to find image 'ubuntu:20.04' locally
20.04: Pulling from library/ubuntu
ca1778b69356: Pull complete
Digest: sha256:db8bf6f4fb351aa7a26e27ba2686cf35a6a409f65603e59d4c203e58387dc6b3
Status: Downloaded newer image for ubuntu:20.04
hello world
下載完鏡像后,自動運行這個鏡像,最后輸出了 hello world 。
啟動一個 bash 終端,允許用戶進入容器終端進行交互:
$ sudo docker run -t -i ubuntu:20.04 /bin/bash
root@049706bffe28:/#
輸入 ls 命令:
root@049706bffe28:/# ls
bin boot dev etc home lib lib32 lib64 libx32 media mnt opt proc root run sbin srv sys tmp usr var
來解釋一下 docker run -t -i
這個命令中的參數(shù):
-t
選項讓 docker 分配一個偽終端并綁定到容器的標準輸入上
-i
交互式操作,也就是命令行模式進入容器這2個參數(shù)也可以寫一起:
docker run -it ubuntu:20.04 /bin/bash
退出容器終端可以輸入命令 exit
。
上面的兩個參數(shù)還可以合一起:
docker run -dit ubuntu:20.04
- 大部分情況下,我們希望 docker 是在后臺的運行的。加
-d
指定容器運行模式, 默認不會進入容器,想要進入容器需要繼續(xù)執(zhí)行指令docker exec
,下面會介紹。
如果 docker 命令太長,還可以用 \
來換行,如下:
docker run -it --rm \
ubuntu:20.04 \
/bin/bash
- -it:-i 交互操作,-t 終端,上面解釋了
- --rm:這個參數(shù)表示容器退出后隨之將其刪除
- ubuntu:20.04:以 ubuntu:20.04 鏡像為基礎(chǔ)來啟動容器
- /bin/bash:放在鏡像后面的是命令,有一個交互式的 shell,這里使用的 bash
啟動已停止運行容器
啟動已經(jīng)停止運行容器:docker start
或 docker container start
重新啟動容器:docker container restart
命令將一個運行態(tài)的容器終止,然后重新啟動它
終止運行中容器:docker container stop
來終止一個運行中的容器
查看所有的容器:
VirtualBox:~$ sudo docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
56ca83925f03 ubuntu:20.04 "/bin/bash" 15 minutes ago Up 15 minutes strange_allen
c1482012b069 ubuntu:20.04 "/bin/bash" 26 minutes ago Exited (0) 20 minutes ago gallant_ellis
啟動停止的容器 container id c1482012b069:
VirtualBox:~$ sudo docker start c1482012b069
c1482012b069
VirtualBox:~$ sudo docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
56ca83925f03 ubuntu:20.04 "/bin/bash" 21 minutes ago Up 20 minutes strange_allen
c1482012b069 ubuntu:20.04 "/bin/bash" 31 minutes ago Up 8 seconds gallant_ellis
獲取鏡像
大量的鏡像文件都存儲在遠端的鏡像倉庫中,比如 docker hub 。獲取鏡像的命令 docker pull
,語法為:
docker pull [OPTIONS] NAME[:TAG|@DIGEST]
- OPTIONS:選項,比如,-a
- NAME[:TAG|@DIGEST]:鏡像地址
獲取 docker pull 更詳細參數(shù):docker pull --help
。
比如,拉取 ubuntu:20.04 這個鏡像文件:
$ sudo docker pull ubuntu:20.04
20.04: Pulling from library/ubuntu
Digest: sha256:db8bf6f4fb351aa7a26e27ba2686cf35a6a409f65603e59d4c203e58387dc6b3
Status: Image is up to date for ubuntu:20.04
docker.io/library/ubuntu:20.04
由于前面啟動鏡像命令 docker run
運行了這個鏡像文件,顯示 Image is up to date for ubuntu:20.04 。
拉取鏡像后,就可以啟動這個鏡像,命令 docker run
。
$ sudo docker run -it --rm ubuntu:20.04 bash
root@5c2a77428b80:/#
-it
:-i
表示交互操作,-t
表示是一個終端
--rm
:這個參數(shù)表示容器退出后會將其刪除。在默認情況下,為了排障需要,退出的容器并不會馬上刪除,觸發(fā)手動執(zhí)行 docker rm。我這里只是演示命令的執(zhí)行,不需要排障,--rm
可以避免浪費空間ubuntu:20.04:表示鏡像,以這個鏡像來作為啟動容器
bash:放在鏡像后面的是命令。這里希望進入交互式 shell,所以用 bash
列出鏡像
列出所有鏡像
列出鏡像的命令:docker image ls
,顯示鏡像下載到本地后,展開后各層所占用空間的總和。語法:
docker image ls [OPTIONS] [REPOSITORY[:TAG]]
關(guān)于 docker image ls 更多用法,可以查看幫助命令:docker image ls --help
。
$ sudo docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest 9c7a54a9a43c 2 weeks ago 13.3kB
ubuntu 20.04 88bd68917189 5 weeks ago 72.8MB
列出了倉庫名、標簽、鏡像ID、創(chuàng)建時間、所占用的空間大小。
鏡像ID是鏡像的唯一標識符,一個鏡像可以對應(yīng)多個標簽。
列出部分鏡像
列出部分鏡像的命令:docker image ls 鏡像名
比如下面例子;
$ sudo docker image ls ubuntu
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu 20.04 88bd68917189 5 weeks ago 72.8MB
還可以加過濾的參數(shù) --filter
,
$ sudo docker image ls --format "{{.ID}}: {{.Repository}}"
9c7a54a9a43c: hello-world
88bd68917189: ubuntu
刪除本地鏡像
刪除本地鏡像的命令:docker image rm
,語法:
docker image rm [OPTIONS] IMAGE [IMAGE...]
上面大家鏡像 IMAGE ,可以是鏡像長ID、鏡像短ID、鏡像名 或鏡像摘要。
比如用鏡像短ID來刪除鏡像:
$ sudo docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest 9c7a54a9a43c 2 weeks ago 13.3kB
ubuntu 20.04 88bd68917189 5 weeks ago 72.8MB
$ sudo docker image rm 189
查看鏡像詳情
查看鏡像詳細信息的命令:docker image inspect
。
查看鏡像 hello-world:latest 的詳細信息:
docker image inspect hello-world:latest
搜索倉庫鏡像
搜索遠程倉庫鏡像命令:docker search
。
例如 查看遠程倉庫中 ubuntu 的鏡像有哪些:
docker search ubuntu
進入容器
使用 -d
參數(shù),容器啟動后可以進入后臺。
在容器啟動后,我們有時需要進入容器鏡像操作,命令有 docker attach
或 docker exec
,推薦使用 docker exec
, 因為 docker attach
進入容器操作完 exit 退出后,會導(dǎo)致容器停止,而 exec 不會。
docker attach 進入容器:
$ sudo docker run -dit ubuntu:20.04
c1482012b06914449cafd461931eb890dec01fa8e6858233d3fcc98de9ceb4bc
$ sudo docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c1482012b069 ubuntu:20.04 "/bin/bash" 53 seconds ago Up 42 seconds gallant_ellis
$ sudo docker attach c148
root@c1482012b069:/#
上面參數(shù) -d
表示容器啟動后會進入后臺運行。
注意:上面容器用
exit
退出后會導(dǎo)致容器停止運行
root@c1482012b069:/# exit
exit
VirtualBox:~$ sudo docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
用命令查看容器,剛才運行的容器退出了。exec
就不會。
docker exec 進入容器:
// 運行容器
VirtualBox:~$ sudo docker run -dit ubuntu:20.04
56ca83925f039f9ba087aff8a521678e2dcc87836bffede90ed2f2614aec8065
// 列出容器列表
VirtualBox:~$ sudo docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
56ca83925f03 ubuntu:20.04 "/bin/bash" 16 seconds ago Up 13 seconds strange_allen
// 進入容器
VirtualBox:~$ sudo docker exec -it 56ca bash
root@56ca83925f03:/# ls
bin boot dev etc home lib lib32 lib64 libx32 media mnt opt proc root run sbin srv sys tmp usr var
// 退出容器
root@56ca83925f03:/# exit
exit
退出容器后,在列出容器列表:
VirtualBox:~$ sudo docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
56ca83925f03 ubuntu:20.04 "/bin/bash" 2 minutes ago Up 2 minutes strange_allen
CONTAINER ID 和前面顯示的 CONTAINER ID 相同,STATUS 狀態(tài)也是 Up 2 minutes,運行狀態(tài),容器沒有退出。
刪除容器
刪除終止狀態(tài)的容器命令:docker container rm
文章來源:http://www.zghlxwxcb.cn/news/detail-466051.html
docker container rm strange_allen
- 如果要刪除一個運行中的容器,加參數(shù)
-f
歡迎大家提建議,討論,點贊文章來源地址http://www.zghlxwxcb.cn/news/detail-466051.html
八、參考
- https://docs.docker.com/
- https://docs.docker.com/registry/
- https://docs.docker.com/engine/reference/commandline/cli/ Docker CLI 文檔
- https://docs.docker.com/engine/reference/commandline/docker/
- https://docs.docker.com/storage/storagedriver/
- https://dockerlabs.collabnix.com/docker/cheatsheet/
- https://buildah.io/
- https://github.com/goharbor/harbor
- https://github.com/opencontainers/runc
- https://www.opencontainers.org
到了這里,關(guān)于kubernetes(k8s)大白學(xué)習(xí)02:容器和docker基礎(chǔ)、使用、架構(gòu)學(xué)習(xí)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!