上文 Docker系列技術(shù)分享(一) 容器技術(shù)和Docker 介紹了容器的歷史和應(yīng)用場(chǎng)景茅特,本文將介紹如何從零上手使用Docker掩缓,幫助讀者更直觀的理解容器技術(shù)
Docker安裝
Docker支持 Linux 背传、Windows 和 MacOS 等多個(gè)平臺(tái)拯欧,當(dāng)然主陣地還是Linux别凤,因?yàn)榉?wù)器大多使用Linux操作系統(tǒng)建芙,其他系統(tǒng)的Docker可以作為開發(fā)環(huán)境來體驗(yàn)
各個(gè)平臺(tái)的安裝流程:官網(wǎng)安裝文檔 已經(jīng)介紹的很詳細(xì)了旷偿,不在贅述。這里以CentOS為例走下流程
系統(tǒng)要求
CentOS 7/8
額外注意的點(diǎn):
- 必須啟用 centos-extras 降允,默認(rèn)情況下是開啟的恩闻,如果手動(dòng)禁用了,需用重新打開剧董,參考文檔 https://wiki.centos.org/AdditionalResources/Repositories
- Docker官方推薦使用 overlay2 存儲(chǔ)驅(qū)動(dòng)
卸載老版本
首先先要卸載老版本幢尚,防止多個(gè)版本沖突,不好管理翅楼。直接使用如下命令一鍵卸載尉剩。
老版本的Docker叫 docker 或者 docker-engine ,新版本的Docker引擎叫 docker-ce毅臊。
$ sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
開始安裝
Docker提供了多種安裝方式理茎,推薦使用第一種。
- 通過yum安裝,推薦功蜓!
- 通過rpm包進(jìn)行安裝沛贪,參考文檔产舞,沒網(wǎng)的時(shí)候可以使用,其余場(chǎng)景不推薦告匠,rpm依賴處理繁瑣求厕,推薦使用Linux包管理工具yum安裝著隆。
- 使用官方一鍵安裝腳本,參考文檔呀癣,不推薦美浦,雖然可以一鍵安裝,但是安裝腳本是個(gè)黑盒项栏,一旦安裝出了問題就需要額外熟悉腳本內(nèi)容來定位浦辨,學(xué)習(xí)成本較高,推薦采用標(biāo)準(zhǔn)yum安裝沼沈。
以下介紹yum安裝流程:
設(shè)置yum倉(cāng)庫
添加官方y(tǒng)um倉(cāng)庫
$ sudo yum install -y yum-utils
$ sudo yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
據(jù)說因?yàn)閲?guó)內(nèi)的網(wǎng)絡(luò)環(huán)境限制流酬,可能拉取有問題或者網(wǎng)速較慢,我是香港機(jī)器所以沒遇到這個(gè)問題列另,如果官方源使用有問題可以試下國(guó)內(nèi)的阿里云倉(cāng)庫
$ sudo yum-config-manager \
--add-repo \
https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
$ sudo sed -i 's/download.docker.com/mirrors.aliyun.com\/docker-ce/g' /etc/yum.repos.d/docker-ce.repo
上述倉(cāng)庫默認(rèn)只開啟穩(wěn)定版芽腾,這也是官方推薦的版本,類似于一個(gè)軟件的release版本页衙,如果需要最新版本或者測(cè)試版本摊滔,可以使用enable開啟,要注意新版本測(cè)試不充分店乐,未經(jīng)過大規(guī)模生產(chǎn)驗(yàn)證艰躺,可能存在bug。
$ sudo yum-config-manager --enable docker-ce-nightly #最新版本
$ sudo yum-config-manager --enable docker-ce-test # 測(cè)試版本
安裝 Docker Engine
yum一鍵安裝响巢,默認(rèn)安裝的是最新版Docker
$ sudo yum install docker-ce docker-ce-cli containerd.io
如果需要安裝老的版本的Docker描滔,可以用list查詢歷史版本。
[root@VM-4-15-centos ~]# yum list docker-ce --showduplicates | sort -r
Loading mirror speeds from cached hostfile
Loaded plugins: fastestmirror, langpacks
docker-ce.x86_64 3:20.10.9-3.el7 docker-ce-stable
docker-ce.x86_64 3:20.10.8-3.el7 docker-ce-stable
docker-ce.x86_64 3:20.10.7-3.el7 docker-ce-stable
docker-ce.x86_64 3:20.10.6-3.el7 docker-ce-stable
docker-ce.x86_64 3:20.10.5-3.el7 docker-ce-stable
docker-ce.x86_64 3:20.10.4-3.el7 docker-ce-stable
docker-ce.x86_64 3:20.10.3-3.el7 docker-ce-stable
然后指定版本進(jìn)行安裝踪古,比如如下安裝3:20.10.9這個(gè)版本的Docker含长。
$ sudo yum install docker-ce-3:20.10.9 docker-ce-cli-3:20.10.9 containerd.io
啟動(dòng) Docker
Docker引擎使用Systemd管理,可以直接start啟動(dòng)
[root@VM-4-15-centos ~]# sudo systemctl start docker
啟動(dòng)完可以status看下運(yùn)行狀態(tài)
或者使用ps也可以看到docker daemon進(jìn)程是否存活
[root@VM-4-15-centos ~]# ps aux|grep docker
root 971 0.0 0.7 1170136 60464 ? Ssl 11:57 0:00 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
root 2166 0.0 0.0 112812 980 pts/0 R+ 12:04 0:00 grep --color=auto docker
docker官方也提供了一個(gè) hello-world 鏡像來驗(yàn)證 Docker Engine是否正確安裝運(yùn)行伏穆,該鏡像會(huì)打印一條語句并退出拘泞。
可以docker run跑起來看下效果。
[root@VM-4-15-centos ~]# sudo docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
2db29710123e: Pull complete
Digest: sha256:10d7d58d5ebd2a652f4d93fdd86da8f265f5318c6a73cc5b6a9798ff6d2b2e67
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 的工作流程枕扫,先介紹下docker的一些基本概念:
- 鏡像 :鏡像本質(zhì)是一個(gè)容器的快照陪腌,提供了容器運(yùn)行時(shí)所需的信息:程序、庫、資源诗鸭、配置等染簇。因?yàn)殓R像的存在,Docker才可以做到一次構(gòu)建强岸,到處運(yùn)行锻弓,通過將服務(wù)打包到鏡像里,其他環(huán)境只需要拉取鏡像就可以在本地把容器運(yùn)行起來蝌箍。
- 鏡像倉(cāng)庫 :類似于Git倉(cāng)庫青灼,可以把構(gòu)建好的鏡像上傳到鏡像倉(cāng)庫,這樣部署的時(shí)候無需手動(dòng)傳輸大的鏡像文件妓盲,只需要一句命令就可以從鏡像倉(cāng)庫拉取并執(zhí)行杂拨。
- 容器 :鏡像run起來就叫容器,就跟進(jìn)程和程序的概念一樣悯衬,靜態(tài)的是鏡像文件弹沽,而鏡像的運(yùn)行時(shí)就是容器
- Docker daemon :Docker最核心的后臺(tái)進(jìn)程,它負(fù)責(zé)響應(yīng)來自Docker client的請(qǐng)求筋粗,通過實(shí)現(xiàn)這些請(qǐng)求來完成容器的管理贷币,包括容器的元數(shù)據(jù)管理,鏡像管理等
- docker客戶端 :官方提供的客戶端亏狰,提供了一些docker的常用操作役纹,如編譯鏡像、拉取鏡像暇唾、運(yùn)行容器等
我們基本上大多數(shù)的操作都是通過docker這個(gè)客戶端來進(jìn)行的促脉,通常的使用流程是:
- 把我們要跑的程序打包到一個(gè)鏡像里,我們需要編寫一個(gè)文本文件Dockerfile策州,該文件用于描述鏡像瘸味,然后使用docker build就可以編譯出來一個(gè)鏡像了
- docker build出來的鏡像是在本地,為了一次構(gòu)建够挂,任何地方都可以使用旁仿,我們需要使用docker push把鏡像推送到鏡像倉(cāng)庫
- 鏡像倉(cāng)庫有鏡像了之后,就可以在任何地方使用docker pull來拉取鏡像
- 拉取下來鏡像后使用docker run將容器允許起來(前提是要有docker環(huán)境)
Docker倉(cāng)庫
Docker官方提供了一個(gè)公共倉(cāng)庫 Docker Hub孽糖,用來給社區(qū)開發(fā)者存放鏡像枯冈,里面有開發(fā)者上傳的海量鏡像,大部分系統(tǒng)鏡像比如各種操作系統(tǒng)如ubuntu办悟、centos等都可以找到尘奏,我們可以拿來當(dāng)作應(yīng)用的運(yùn)行基礎(chǔ)鏡像,一些常用的開源軟件如nginx病蛉、redis等也可以找到對(duì)應(yīng)的應(yīng)用鏡像下載使用炫加。
企業(yè)用戶為了安全一般會(huì)選擇自建Docker倉(cāng)庫瑰煎,用法上差異不大,以下演示下Docker Hub的常用操作俗孝。
倉(cāng)庫地址:https://hub.docker.com/ , Docker Hub有個(gè)可視化的Web端酒甸,可以查到倉(cāng)庫內(nèi)所有鏡像,也可以進(jìn)行條件篩選出想要的鏡像赋铝。
點(diǎn)擊需要使用的鏡像烘挫,里面有該鏡像的各個(gè)版本提供選擇,點(diǎn)擊拷貝右側(cè)命令在自己機(jī)器上執(zhí)行就可以拉取鏡像了柬甥。
如下在本機(jī)拉取mysql最新鏡像:這個(gè)拉取的過程中也可以看到一個(gè)docker鏡像是由多個(gè)層組成的,這就是docker鏡像的分層概念其垄,后面會(huì)講到苛蒲。
[root@VM-4-15-centos ~]# docker pull mysql
Using default tag: latest
latest: Pulling from library/mysql
4be315f6562f: Pull complete
96e2eb237a1b: Pull complete
8aa3ac85066b: Pull complete
ac7e524f6c89: Pull complete
f6a88631064f: Pull complete
15bb3ec3ff50: Pull complete
ae65dc337dcb: Pull complete
654aa78d12d6: Pull complete
6dd1a07a253d: Pull complete
a32905dc9e58: Pull complete
152d41026e44: Pull complete
42e0f73ebe32: Pull complete
Digest: sha256:fc77d54cacef90ad3d75964837fad0f2a9a368b69e7d799665a3f4e90e600c2d
Status: Downloaded newer image for mysql:latest
docker.io/library/mysql:latest
也可以指定版本號(hào)來拉取某個(gè)版本的鏡像
$ docker pull mysql:8.0.28-debian # 拉取指定版本
然后可以查看本地鏡像有沒有,如下命令列出本地鏡像
[root@VM-4-15-centos ~]# docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
mysql latest f2ad9f23df82 3 days ago 521MB
hello-world latest feb5d9fea6a5 7 months ago 13.3kB
除了頁面上可視化查看鏡像绿满,docker客戶端也提供了命令可以操作鏡像倉(cāng)庫臂外,用search可以搜索到想要的鏡像。
[root@VM-4-15-centos ~]# docker search mysql --limit 5
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
mysql MySQL is a widely used, open-source relation… 12453 [OK]
mariadb MariaDB Server is a high performing open sou… 4800 [OK]
percona Percona Server is a fork of the MySQL relati… 575 [OK]
phpmyadmin phpMyAdmin - A web interface for MySQL and M… 512 [OK]
circleci/mysql MySQL is a widely used, open-source relation… 25
docker沒有提供獲取某個(gè)鏡像所有歷史版本的命令喇颁,如果想要拿到某個(gè)鏡像的歷史版本漏健,可以使用如下curl拿到。
[root@VM-4-15-centos ~]# curl https://registry.hub.docker.com/v1/repositories/mysql/tags | python -m json.tool
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 4654 0 4654 0 0 4485 0 --:--:-- 0:00:01 --:--:-- 4487
[
{
"layer": "",
"name": "latest"
},
{
"layer": "",
"name": "5"
},
{
"layer": "",
"name": "5-debian"
},
...
]
docker客戶端還有很多好用的命令不在贅述橘霎,大家可以看下help自行體驗(yàn)下蔫浆。
[root@VM-4-15-centos ~]# docker -h
Flag shorthand -h has been deprecated, please use --help
Usage: docker [OPTIONS] COMMAND
A self-sufficient runtime for containers
Options:
--config string Location of client config files (default "/root/.docker")
-c, --context string Name of the context to use to connect to the daemon (overrides DOCKER_HOST env var and default context set with "docker
context use")
-D, --debug Enable debug mode
-H, --host list Daemon socket(s) to connect to
-l, --log-level string Set the logging level ("debug"|"info"|"warn"|"error"|"fatal") (default "info")
--tls Use TLS; implied by --tlsverify
--tlscacert string Trust certs signed only by this CA (default "/root/.docker/ca.pem")
--tlscert string Path to TLS certificate file (default "/root/.docker/cert.pem")
--tlskey string Path to TLS key file (default "/root/.docker/key.pem")
--tlsverify Use TLS and verify the remote
-v, --version Print version information and quit
Docker鏡像
除了使用一些公共鏡像外,我們更多的需求其實(shí)是自己制作鏡像姐叁,因?yàn)樽匝械能浖枰茉谌萜骼?/p>
我們知道內(nèi)核啟動(dòng)前要先掛載rootfs瓦盛,根據(jù)rootfs來啟動(dòng)內(nèi)核,然后在運(yùn)行其他應(yīng)用程序外潜。
Docker啟動(dòng)也是原环,先要跑系統(tǒng)內(nèi)核,才能跑應(yīng)用程序处窥,所以 Docker 的鏡像嘱吗,其實(shí)就是一個(gè)rootfs。
我們通過Dockerfile來描述鏡像內(nèi)容滔驾,其內(nèi)包含了一條條的 指令(Instruction)谒麦,每一條指令構(gòu)建一層,因此每一條指令的內(nèi)容哆致,就是描述該層應(yīng)當(dāng)如何構(gòu)建弄匕,通過Dockerfile也可以直觀的看到鏡像做了啥。
由于Docker鏡像是分層的沽瞭,當(dāng)前層必須在上一層上構(gòu)建迁匠,所以Docker要求必須有基礎(chǔ)鏡像,Dockerfile的第一條指令必須要使用FROM來設(shè)置一個(gè)基礎(chǔ)鏡像,基礎(chǔ)鏡像可以在鏡像倉(cāng)庫找到城丧,通常會(huì)使用一些系統(tǒng)鏡像centos延曙、ubuntu等做來服務(wù)的系統(tǒng)環(huán)境
#設(shè)置基礎(chǔ)鏡像為Centos
FROM centos
如果實(shí)在是不需要基礎(chǔ)鏡像,Docker也提供了一個(gè)空白的鏡像 scratch可以作為基礎(chǔ)鏡像亡哄,通常對(duì)鏡像體積大小有要求的場(chǎng)景會(huì)需要這么做枝缔,但從零開始搭建運(yùn)行環(huán)境是比較繁瑣滴
FROM scratch
ENV用來設(shè)置環(huán)境變量,無論是后續(xù)的指令還是運(yùn)行在容器里的應(yīng)用都可以直接使用
ENV TZ=UTC CGO_ENABLED=1 GOTRACEBACK=crash
RUN 指令是用來執(zhí)行shell命令的蚊惯,常用于服務(wù)啟動(dòng)前做一些前置工作愿卸。
RUN set -x \
&& mkdir -p /data/testsvr
COPY指令用于將本地文件復(fù)制到鏡像內(nèi)目錄,比如要運(yùn)行的二進(jìn)制文件截型、配置等趴荸。
使用 COPY 指令,源文件的各種元數(shù)據(jù)都會(huì)保留宦焦。比如讀发钝、寫、執(zhí)行權(quán)限波闹、文件變更時(shí)間等酝豪。這個(gè)特性對(duì)于鏡像定制很有用,特別是源文件采用Git管理時(shí)精堕。
COPY ./testsvr \
/data/testsvr/
還有個(gè)ADD指令 功能跟COPY很像孵淘,可以添加文件到指定目錄,區(qū)別是可以自動(dòng)解壓tar包歹篓,如果是鏈接URL會(huì)自動(dòng)wget下載到目標(biāo)目錄夺英。該指令不建議使用,因?yàn)檎Z義不直觀滋捶,解壓和下載操作可以通過RUN指令來實(shí)現(xiàn)
ADD test.tgz /data
前面提到容器的啟動(dòng)需要通過鏡像文件痛悯,而容器運(yùn)行時(shí)對(duì)當(dāng)前環(huán)境的修改是不會(huì)同步修改鏡像的,這時(shí)候有個(gè)問題是如果你在容器運(yùn)行時(shí)修改了一些文件重窟,當(dāng)容器重啟過后這些修改是不生效的载萌。
對(duì)于一些需要持久化數(shù)據(jù)的業(yè)務(wù),比如說服務(wù)打印的日志巡扇、數(shù)據(jù)庫文件等扭仁,我們希望容器重啟后仍然存在,Docker提供了VOLUME厅翔,VOLUME類似于 Linux 下對(duì)目錄或文件進(jìn)行 mount乖坠,鏡像中的被指定為掛載點(diǎn)的目錄/文件會(huì)復(fù)制到VOLUME中,使用VOLUME可以實(shí)現(xiàn)容器運(yùn)行時(shí)針對(duì)掛載目錄的寫入不會(huì)隨著容器刪除而消失刀闷。
以下是創(chuàng)建一個(gè)匿名卷掛載在/data目錄熊泵。
VOLUME [ "/data" ]
容器的本質(zhì)就是一個(gè)進(jìn)程仰迁,通常跟我們的服務(wù)生命周期綁定,Docker提供了CMD命令用于指定容器的啟動(dòng)命令顽分,這是一個(gè)容器最主要做的事情徐许,當(dāng)啟動(dòng)命令結(jié)束,容器的生命周期也就結(jié)束了卒蘸,所以啟動(dòng)命令一般來啟動(dòng)服務(wù)進(jìn)程雌隅,如下
#設(shè)置容器的啟動(dòng)命令,該配置可用運(yùn)行時(shí)參數(shù)覆蓋
CMD ["./testsvr", "-conf ../etc/config.yaml"]
Docker還提供了一個(gè)ENTRYPOINT指令缸沃,該指令也是用來指定容器的啟動(dòng)命令恰起,但是可以使用腳本,我們通常會(huì)寫一個(gè)entry腳本來作為啟動(dòng)腳本趾牧,然后CMD來給啟動(dòng)腳本傳參检盼,這樣可以在啟動(dòng)腳本里做一些前置的準(zhǔn)備工作,比如一些初始化武氓、一些依賴安裝等
ENTRYPOINT [ "./testsvr.entry" ]
CMD [ "-conf ../etc/config.yaml" ]
如下是entry腳本內(nèi)容,可以直接使用shell命令
#!/bin/sh
export GOTRACEBACK=crash
cd /data
echo "start testsvr"
./testsvr $*
Docker鏡像文件常用指令介紹的差不多了仇箱,詳細(xì)指令使用可以查閱文檔
有了Dockerfile之后县恕,我們可以通過docker build來編譯出鏡像,鏡像編譯輸出過程可以很明顯的看到每一層的指令執(zhí)行過程
[root@VM-4-15-centos ~]# docker build -t testsvr:v1 -f ./testsvr.Dockerfile --network=host .
Sending build context to Docker daemon 78.85kB
Step 1/4 : FROM centos
latest: Pulling from library/centos
a1d0c7532777: Pull complete
Digest: sha256:a27fd8080b517143cbbbab9dfb7c8571c40d67d534bbdee55bd6c473f432b177
Status: Downloaded newer image for centos:latest
---> 5d0da3dc9764
Step 2/4 : ENV TZ=UTC CGO_ENABLED=1 GOTRACEBACK=crash
---> Running in 5bfc6cdf203d
Removing intermediate container 5bfc6cdf203d
---> 700b7da62095
Step 3/4 : RUN set -x && mkdir -p /data/testsvr
---> Running in cc7757be117f
+ mkdir -p /data/testsvr
Removing intermediate container cc7757be117f
---> 95b95c993e5d
Step 4/4 : CMD [ "curl", "-s", "ifconfig.me" ]
---> Running in 01cf6e59216e
Removing intermediate container 01cf6e59216e
---> 26ca123fe1c6
Successfully built 26ca123fe1c6
Successfully tagged testsvr:v1
可以看到剛編譯好的新鮮鏡像
[root@VM-4-15-centos ~]# docker image ls|grep testsvr
testsvr v1 26ca123fe1c6 3 minutes ago 231MB
本地鏡像也可以上傳遠(yuǎn)程倉(cāng)庫方便其他環(huán)境下載剂桥,需要先在docker倉(cāng)庫里新建一個(gè)倉(cāng)庫忠烛, 使用docker login進(jìn)行鑒權(quán)后直接push就可以了
docker login --username ***** --password ***** testsvr
docker push testsvr:v1
Docker運(yùn)行
我們通過docker run就可以跑起來一個(gè)容器,不帶任何參數(shù)時(shí)要求鏡像里定義了CMD或ENTRYPOINT权逗,因?yàn)槿萜饕繂?dòng)命令來啟動(dòng)
[root@VM-4-15-centos ~]# docker run testsvr:v1
43.154.203.100
docker客戶端也支持使用命令行參數(shù)設(shè)置啟動(dòng)命令的方式美尸,如下 cat /etc/os-release 就是該容器的啟動(dòng)指令
[root@VM-4-15-centos ~]# docker run centos cat /etc/os-release
NAME="CentOS Linux"
VERSION="8"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="8"
PLATFORM_ID="platform:el8"
PRETTY_NAME="CentOS Linux 8"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:8"
HOME_URL="https://centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"
CENTOS_MANTISBT_PROJECT="CentOS-8"
CENTOS_MANTISBT_PROJECT_VERSION="8"
另外上述提到的大多數(shù)鏡像指令都可以通過docker客戶端的命令行參數(shù)使用,不過我們大多數(shù)還是使用dockerfile方式斟薇,更加直觀且可以備份师坎。比如-v參數(shù)添加數(shù)據(jù)卷
docker run -v /tmp/data testsvr:v1
也可以運(yùn)行交互式bash,比如如下運(yùn)行centos鏡像堪滨,可以直接進(jìn)入容器內(nèi)部查看
[root@VM-4-15-centos ~]# docker run -it centos bash
[root@735e1dfb0a57 /]# ls
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
運(yùn)行中的容器也可以使用exec進(jìn)入
[root@VM-4-15-centos ~]# docker exec -ti 735e1dfb0a57 bash
[root@735e1dfb0a57 /]# pwd
/
docker ps可以查看運(yùn)行中的鏡像胯陋,還可以查看容器進(jìn)程在宿主機(jī)的進(jìn)程pid等信息
$ docker ps
[root@VM-4-15-centos ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
735e1dfb0a57 centos "bash" About a minute ago Up About a minute exciting_bassi
#查看容器進(jìn)程在系統(tǒng)中的進(jìn)程號(hào)
[root@VM-4-15-centos ~]# docker inspect --format '{{ .State.Pid }}' 735e1dfb0a57
3549
我們也可以來驗(yàn)證下上述提到的數(shù)據(jù)卷到底有沒有實(shí)現(xiàn)持久化能力,我們先掛載一個(gè)匿名卷到/tmp/data袱箱,接著給這個(gè)目錄寫文件
[root@VM-4-15-centos ~]# docker run -v /tmp/data -it centos bash
[root@4fa3b36b96dc /]# echo "volume test" > /tmp/data/volume-test.txt
[root@4fa3b36b96dc /]# ls -ahtl /tmp/data/
total 12K
drwxr-xr-x 2 root root 4.0K May 8 03:21 .
-rw-r--r-- 1 root root 12 May 8 03:21 volume-test.txt
drwxrwxrwt 1 root root 4.0K May 8 03:19 ..
需要注意的是容器掛載目錄和宿主機(jī)目錄不是一一對(duì)應(yīng)的遏乔,可以使用inspect查到宿主機(jī)該卷的位置,來看下是否生效
[root@VM-4-15-centos ~]# docker inspect 4fa3b36b96dc | grep volumes
"Source": "/var/lib/docker/volumes/755e1a810b8ba41c35cd3cd2d5cc207b13079ad14fc98289ecd1a7f7703546b5/_data",
[root@VM-4-15-centos ~]# ll -aht /var/lib/docker/volumes/755e1a810b8ba41c35cd3cd2d5cc207b13079ad14fc98289ecd1a7f7703546b5/_data
total 12K
drwxr-xr-x 2 root root 4.0K May 8 11:21 .
-rw-r--r-- 1 root root 12 May 8 11:21 volume-test.txt
drwx-----x 3 root root 4.0K May 8 11:19 ..
我們也可以將主機(jī)目錄掛載為數(shù)據(jù)卷发笔,這樣就可以人為指定某個(gè)卷在宿主機(jī)的路徑盟萨,便于管理
$ docker run -it -v /host/data:/data centos bash
Docker架構(gòu)
老版本的Docker容器是通過 Docker Daemon 直接來啟動(dòng)的,Docker Client通過命令行與Daemon交互了讨,管理鏡像和容器捻激,同時(shí)Daemon負(fù)責(zé)容器生命周期的管理制轰,這樣有個(gè)問題是一旦Daemon因?yàn)镃lient操作問題掛了或者重啟,所有運(yùn)行中的容器都會(huì)掛铺罢,所以Docker做了架構(gòu)上的升級(jí)艇挨,新架構(gòu)如下
新架構(gòu)將Daemon功能做了拆分解耦,Daemon進(jìn)程只負(fù)責(zé)和 Docker Client 端交互韭赘,管理 Docker 鏡像和容器缩滨,由Containerd 來管理容器的生命周期,并向上為 Docker Daemon 提供 gRPC 接口泉瞻。
當(dāng)創(chuàng)建一個(gè)容器時(shí)脉漏,Docker Daemon 不直接幫我們創(chuàng)建,而是請(qǐng)求 Containerd 來創(chuàng)建袖牙,Containerd 收到請(qǐng)求后侧巨,也不會(huì)直接去操作容器,而是創(chuàng)建一個(gè)叫做 Containerd-Shim 的進(jìn)程鞭达,讓這個(gè)進(jìn)程去操作容器司忱。這里有個(gè)好處是一個(gè)容器對(duì)應(yīng)一個(gè)Containerd-Shim,Containerd-Shim作為容器進(jìn)程的父進(jìn)程畴蹭,避免了如果所有容器都使用Containerd做父進(jìn)程的時(shí)候坦仍,Containerd掛了所有的容器都會(huì)掛。
Docker提供了RunC來創(chuàng)建一個(gè)容器叨襟,由他來完成容器運(yùn)行的前置工作繁扎,包括容器的一些基礎(chǔ)能力,比如配置Namespace來進(jìn)行資源隔離糊闽、配置Cgroup的來進(jìn)行資源限制等一系列操作梳玫,RunC啟動(dòng)完容器后本身會(huì)直接退出,由Containerd-Shim來作為容器進(jìn)程的父進(jìn)程右犹,負(fù)責(zé)收集容器進(jìn)程的狀態(tài)提澎,上報(bào)給Containerd,監(jiān)管容器的生命周期念链,確保容器可以真正運(yùn)行和正常退出虱朵。