Docker入門(mén)與進(jìn)階(基礎(chǔ)+實(shí)戰(zhàn)+進(jìn)階+Compose+Swarm)超詳細(xì)版
一、Docker入門(mén)
1.1 Docker 概述
Docker 是一個(gè)開(kāi)源的輕量級(jí)的應(yīng)用容器引擎。
應(yīng)用場(chǎng)景
- Web 應(yīng)用的自動(dòng)化打包和發(fā)布。
- 自動(dòng)化測(cè)試和持續(xù)集成、發(fā)布。
- 在服務(wù)型環(huán)境中部署和調(diào)整數(shù)據(jù)庫(kù)或其他的后臺(tái)應(yīng)用。
Docker和虛擬機(jī)的對(duì)比
- 傳統(tǒng)虛擬機(jī),虛擬出硬件,運(yùn)行一個(gè)完整的操作系統(tǒng),然后在這個(gè)系統(tǒng)上安裝和運(yùn)行軟件。
- Docker內(nèi)的容器直接運(yùn)行在宿主機(jī)內(nèi),容器是沒(méi)有自己的內(nèi)核的,也沒(méi)有虛擬硬件。每個(gè)容器都是相互隔離的,每個(gè)容器都有屬于自己的文件系統(tǒng),互不影響。
容器化的好處
- 應(yīng)用更快速的交付和部署
- 更便捷的升級(jí)和擴(kuò)展
- 更簡(jiǎn)單的系統(tǒng)運(yùn)維
- 更高效的資源利用
Docker的組成 倉(cāng)庫(kù)、鏡像和容器

- 鏡像
Docker鏡像里包含了已打包的應(yīng)用程序及其所依賴(lài)的環(huán)境。類(lèi)似于Win的程序安裝包。
- 鏡像倉(cāng)庫(kù)
Docker鏡像倉(cāng)庫(kù)用于存放Docker鏡像,以及促進(jìn)不同人和不同電腦之間共享這些鏡像。類(lèi)似于Win放安裝包的倉(cāng)庫(kù)。
- 容器
Docker容器通常是一個(gè)Linux容器,它基于Docker鏡像被創(chuàng)建。一個(gè)運(yùn)行中的容器是一個(gè)運(yùn)行在Docker主機(jī)上的進(jìn)程。類(lèi)似于Win安裝好的程序。
1.2 Docker 安裝、配置、卸載
Docker的安裝步驟
0.刪除舊版本,可以避免出現(xiàn)安裝失敗的情況
yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
1.安裝docker,-y表示不詢(xún)問(wèn)安裝,直到安裝成功
yum install -y docker-ce docker-ce-cli containerd.io
2.啟動(dòng)docker,并查看版本信息
systemctl start docker docker version

3.配置國(guó)內(nèi)鏡像倉(cāng)庫(kù)
vim /etc/docker/daemon.json
{
"registry-mirrors": [
"https://registry.docker-cn.com"
]
}配置完成后需重啟docker服務(wù)
systemctl restart docker # 重啟docker服務(wù) systemctl status docker # 確認(rèn)docker服務(wù)正常運(yùn)行
4.將docker設(shè)置為開(kāi)機(jī)啟動(dòng)
systemctl enable docker
5.卸載Docker
# 1. 卸載依賴(lài) yum remove docker-ce docker-ce-cli containerd.io # 2. 刪除資源 . /var/lib/docker是docker的默認(rèn)工作路徑 rm -rf /var/lib/docker
1.3 Docker 使用流程

1.4 Docker 訪問(wèn)原理
Docker是一個(gè)Client-Server結(jié)構(gòu)的系統(tǒng),Docker的守護(hù)進(jìn)程運(yùn)行在主機(jī)上,通過(guò)Socket從客戶(hù)端訪問(wèn)!Docker Server接收到Docker-Client的指令,就會(huì)執(zhí)行這個(gè)指令!

1.5 Docker 常用命令
1.5.1 基礎(chǔ)命令
docker version # 查看docker的版本信息docker info # 查看docker的系統(tǒng)信息,包括鏡像和容器的數(shù)量docker 命令 --help # 幫助命令(可查看可選的參數(shù))
1.5.2 鏡像命令
docker images查看本地所有鏡像
[root@localhost ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE hello-world latest feb5d9fea6a5 6 months ago 13.3kB # 解釋: 1.REPOSITORY 鏡像的倉(cāng)庫(kù)源 2.TAG 鏡像的標(biāo)簽 3.IMAGE ID 鏡像的id 4.CREATED 鏡像的創(chuàng)建時(shí)間 5.SIZE 鏡像的大小 # 可選參數(shù) -a/--all 列出所有鏡像 -q/--quiet 只顯示鏡像的id
docker search 搜索鏡像
[root@localhost ~]# docker search mysql
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
mysql MySQL is a widely used, open-source relation… 10308 [OK]
mariadb MariaDB is a community-developed fork of MyS… 3819 [OK]
mysql/mysql-server Optimized MySQL Server Docker images. Create… 754 [OK]
percona Percona Server is a fork of the MySQL relati… 517 [OK]
centos/mysql-57-centos7 MySQL 5.7 SQL database server 86
mysql/mysql-cluster Experimental MySQL Cluster Docker images. Cr… 79
centurylink/mysql Image containing mysql. Optimized to be link… 60 [OK]
# 可選參數(shù)
Options:
-f, --filter filter Filter output based on conditions provided
--format string Pretty-print search using a Go template
--limit int Max number of search results (default 25)
--no-trunc Don't truncate output
# 搜索收藏?cái)?shù)大于3000的鏡像
[root@localhost ~]# docker search mysql --filter=STARS=3000
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
mysql MySQL is a widely used, open-source relation… 10308 [OK]
mariadb MariaDB is a community-developed fordockerk of MyS… 3819 [OK]docker pull 鏡像名[:tag] 下載鏡像
分層下載,docker image的核心-聯(lián)合文件系統(tǒng)(UnionFS)
# 如果不寫(xiě)tag默認(rèn)就是下載最新版 latest docker pull mysql # 指定版本下載 docker pull mysql:5.7
docker rmi 刪除鏡像
# 1.刪除指定的鏡像id docker rmi -f 鏡像id # 2.刪除多個(gè)鏡像id docker rmi -f 鏡像id 鏡像id 鏡像id # 3.刪除全部的鏡像id docker rmi -f $(docker images -aq)
1.5.3 容器命令
容器是基于Docker鏡像被創(chuàng)建的。
# 先拉取一個(gè)centos鏡像 docker pull centos
docker run [Options] image運(yùn)行容器
docker run [Options] image #參數(shù)說(shuō)明 --name="名字" 指定容器名字 -d 后臺(tái)方式運(yùn)行 -it 使用交互方式運(yùn)行,進(jìn)入容器查看內(nèi)容 -p 指定容器的端口 -p ip:主機(jī)端口:容器端口 配置主機(jī)端口映射到容器端口 -p 主機(jī)端口:容器端口(常用) -p 容器端口 -P 隨機(jī)指定端口 -e 環(huán)境設(shè)置 -v 容器數(shù)據(jù)卷掛載
運(yùn)行并進(jìn)入容器centos
[root@localhost ~]# docker run -it centos /bin/bash [root@ce2bbae9f151 /]# ls bin etc lib lost+found mnt proc run srv tmp var dev home lib64 media opt root sbin sys usr
退出容器
exit # 停止容器并退出(后臺(tái)方式運(yùn)行則僅退出) Ctrl+P+Q # 不停止容器退出
docker ps 查看運(yùn)行的容器
# 查看當(dāng)前正在運(yùn)行的容器 docker ps -a # 查看所有容器的運(yùn)行記錄 -n=? # 顯示最近創(chuàng)建的n個(gè)容器 -q # 只顯示容器的id
docker start 容器id 啟動(dòng)容器
docker start 容器id # 啟動(dòng)容器 docker restart 容器id # 重啟容器 docker stop 容器id # 停止當(dāng)前運(yùn)行的容器 docker kill 容器id # 強(qiáng)制停止當(dāng)前容器
1.5.4 其他常用命令
docker logs查看日志
docker logs -tf 容器id docker logs --tail num 容器id # num為要顯示的日志條數(shù)
docker top查看容器中進(jìn)程信息
docker top 容器id
docker inspect查看容器的元數(shù)據(jù)
docker inspect 容器id
進(jìn)入容器,因?yàn)橥ǔN覀兊娜萜鞫际鞘褂煤笈_(tái)方式來(lái)運(yùn)行的,有時(shí)需要進(jìn)入容器修改配置
docker exec
# docker exec 進(jìn)入容器后開(kāi)啟一個(gè)新的終端,可以在里面操作 docker exec -it 容器id /bin/bash
docker attach
# docker attach 進(jìn)入容器正在執(zhí)行的終端 docker attach 容器id
docker cp拷貝操作
# 拷貝容器的文件到宿主機(jī)中 docker cp 容器id:容器內(nèi)路徑 宿主機(jī)路徑 # 拷貝宿主機(jī)的文件到容器中 docker cp 宿主機(jī)路徑 容器id:容器內(nèi)路徑 # 注意:源文件在哪就在哪進(jìn)行復(fù)制操作 # 在主機(jī)中創(chuàng)建test.txt文件,并復(fù)制到centos容器的/home路徑下 touch test.txt docker cp /home/test.txt 08d1f5d4e7b1:/home/
1.5.5 鏡像導(dǎo)出、導(dǎo)入
1. 使用export和import
這兩個(gè)命令是通過(guò)容器來(lái)導(dǎo)出、導(dǎo)入鏡像
docker export 容器id > xxx.tar [路徑]docker import [- 鏡像名] < xxx.tar
2. 使用save和load
這兩個(gè)命令是通過(guò)鏡像來(lái)導(dǎo)出、導(dǎo)入鏡像
docker save 鏡像id > xxx.tar [路徑]docker load < xxx.tar
1.6 制作Docker鏡像
Docker的鏡像實(shí)際上由一層一層的文件系統(tǒng)組成,這種層級(jí)的文件系統(tǒng)是UnionFS聯(lián)合文件系統(tǒng)。
可以使用docker image inspect查看鏡像的元數(shù)據(jù)
docker image inspect nginx:latest
# 鏡像的分層信息 ,層級(jí)文件可以共享
"RootFS": {
"Type": "layers",
"Layers": [
"sha256:87c8a1d8f54f3aa4e05569e8919397b65056aa71cdf48b7f061432c98475eee9",
"sha256:5c4e5adc71a82a96f02632433de31c998c5a9e2fccdcbaee780ae83158fac4fa",
"sha256:7d2b207c26790f693ab1942bbe26af8e2b6a14248969e542416155a912fec30d",
"sha256:2c7498eef94aef8c40d106f3e42f7da62b3eee8fd36012bf7379becc4cd639a2",
"sha256:4eaf0ea085df254fd5d2beba4e2c11db70a620dfa411a8ad44149e26428caee4"
]
}鏡像的特點(diǎn)
- 所有的Docker鏡像都起始于一個(gè)基礎(chǔ)
鏡像層,當(dāng)進(jìn)行增加或修改內(nèi)容時(shí),會(huì)在當(dāng)前鏡像層之上,創(chuàng)建新的鏡像層。 - Docker鏡像都是只讀的,當(dāng)容器啟動(dòng)時(shí),一個(gè)新的可寫(xiě)層(
容器層)被加載到鏡像的頂部。
提交鏡像 docker commit
# 使用docker commit 命令提交容器成為一個(gè)新的鏡像版本 docker commit -m=“提交的描述信息” -a="作者" 容器id 目標(biāo)鏡像名:[TAG]
默認(rèn)的Tomcat鏡像的webapps文件夾中沒(méi)有任何內(nèi)容,需要從webapps.dist中拷貝文件到webapps文件夾。下面自行制作鏡像:就是從webapps.dist中拷貝文件到webapps文件夾下,并提交該鏡像作為一個(gè)新的鏡像。使得該鏡像默認(rèn)的webapps文件夾下就有文件。
# 1.復(fù)制項(xiàng)目到webapps下 [root@localhost ~]# docker run -it tomcat /bin/bash root@3762239532cf:/usr/local/tomcat# cd webapps root@3762239532cf:/usr/local/tomcat/webapps# ls root@3762239532cf:/usr/local/tomcat/webapps# cp -r ../webapps.dist/* . root@3762239532cf:/usr/local/tomcat/webapps# ls ROOT docs examples host-manager manager # 2.項(xiàng)目訪問(wèn) http://192.168.0.105:8080/ # 3.提交容器作為一個(gè)新的鏡像 [root@localhost ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 41d0b9c0da0e tomcat "catalina.sh run" 4 minutes ago Up 4 minutes 0.0.0.0:8080->8080/tcp, :::8080->8080/tcp agitated_mccarthy [root@localhost ~]# docker commit -m="add webapps" -a="buckletime" 41d0b9c0da0e mytomcat:1.0 sha256:6bbddb87eb6f909f77c6f851b25edd5a02ad9632f397b68f65f4169b9874f02a # 4.查看鏡像列表 [root@localhost ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE mytomcat 1.0 6bbddb87eb6f 31 seconds ago 684MB tomcat latest fb5657adc892 3 months ago 680MB centos latest 5d0da3dc9764 6 months ago 231MB # 5.運(yùn)行新的容器并查看文件 [root@localhost ~]# docker run -it mytomcat:1.0 /bin/bash root@5c04b86e6369:/usr/local/tomcat# ls webapps ROOT docs examples host-manager manager
二、容器數(shù)據(jù)卷
2.1 數(shù)據(jù)卷介紹
Docker將運(yùn)用與運(yùn)行的環(huán)境打包形成容器運(yùn)行, Docker容器產(chǎn)生的數(shù)據(jù),如果不通過(guò)docker commit生成新的鏡像,使得數(shù)據(jù)做為鏡像的一部分保存下來(lái), 那么當(dāng)容器刪除后,數(shù)據(jù)自然也就沒(méi)有了。 為了能保存數(shù)據(jù)在Docker中我們使用卷。|
卷就是目錄或文件,存在于一個(gè)或多個(gè)容器中,由Docker掛載到容器,但卷不屬于聯(lián)合文件系統(tǒng)(Union FileSystem),因此能夠繞過(guò)聯(lián)合文件系統(tǒng)提供一些用于持續(xù)存儲(chǔ)或共享數(shù)據(jù)的特性:。
卷的設(shè)計(jì)目的就是 數(shù)據(jù)的持久化和同步,容器間可以數(shù)據(jù)共享。
數(shù)據(jù)卷的特點(diǎn):
- 數(shù)據(jù)卷可在容器之間共享或重用數(shù)據(jù)
- 卷中的更改可以直接生效
- 數(shù)據(jù)卷中的更改不會(huì)包含在鏡像的更新中
2.2 數(shù)據(jù)卷使用
運(yùn)行容器,指定掛載數(shù)據(jù)卷命令:
docker run -it -v 主機(jī)目錄:容器目錄
# 1.運(yùn)行centos容器,并指定掛載數(shù)據(jù)卷
[root@localhost ~]# docker run -it -v /home/main_data/:/home/docker_data centos /bin/bash
# 2.使用docker inspect查看容器的元數(shù)據(jù),查看是否掛載成功
[root@localhost ~]# docker inspect 9f80a90b6c54
"Mounts": [
{
"Type": "bind",
"Source": "/home/main_data",
"Destination": "/home/docker_data",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}
]
# 3.在主機(jī)中創(chuàng)建文件
[root@localhost main_data]# touch main.txt
[root@localhost main_data]# ls
main.txt
# 4.查看容器中的文件
[root@9f80a90b6c54 /]# ls /home/docker_data/
main.txt示例:MySQL容器建立數(shù)據(jù)卷同步數(shù)據(jù)
在Linux下的MySQL默認(rèn)的數(shù)據(jù)文檔存儲(chǔ)目錄為/var/lib/mysql,默認(rèn)的配置文件的置/etc/mysql/conf.d,為了避免MySQL鏡像或容器刪除后,造成的數(shù)據(jù)丟失,下面建立數(shù)據(jù)卷保存MySQL的數(shù)據(jù)和文件。
# 1.啟動(dòng)mysql 掛載數(shù)據(jù)卷 docker run -d -p 3306:3306 \ -v /home/mysql/conf:/etc/mysql/conf.d \ -v /home/mysql/data:/var/lib/mysql \ -e MYSQL_ROOT_PASSWORD=123456 mysql # 2.遠(yuǎn)程連接mysql服務(wù),若無(wú)權(quán)限,進(jìn)入mysql容器中修改遠(yuǎn)程連接權(quán)限 docker exec -ti 36d4806c765a /bin/bash # 登錄mysql mysql -u root -p # 修改root 可以通過(guò)任何客戶(hù)端連接 ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123456'; # 3.使用客戶(hù)端創(chuàng)建mytest數(shù)據(jù)庫(kù)并查看主機(jī)中同步的數(shù)據(jù),數(shù)據(jù)同步成功 [root@localhost data]# ls /home/mysql/data
2.3 docker volume 命令
[root@localhost data]# docker volume --help Commands: create # 創(chuàng)建數(shù)據(jù)卷 inspect # 查看數(shù)據(jù)卷詳情 ls # 查看所有數(shù)據(jù)卷列表 prune # 刪除所有未使用的卷 rm # 刪除數(shù)據(jù)卷
docker volume create 創(chuàng)建數(shù)據(jù)卷
[root@localhost data]# docker volume create my-vol
docker volume ls 查看所有數(shù)據(jù)卷列表
[root@localhost data]# docker volume ls
docker volume inspect 查看數(shù)據(jù)卷詳情
[root@localhost data]# docker volume inspect my-vol
[
{
"CreatedAt": "2022-04-07T12:52:42+08:00",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/my-vol/_data",
"Name": "my-vol",
"Options": {},
"Scope": "local"
}
]docker volume rm 刪除數(shù)據(jù)卷
[root@localhost data]# docker volume rm my-vol
docker volume prune 刪除所有未使用的卷
[root@localhost data]# docker volume prune
docker rm -v 刪除容器時(shí)也刪除相關(guān)的卷
2.4 具名掛載和匿名掛載
匿名掛載
匿名掛載就是在指定數(shù)據(jù)卷的時(shí)候,只指定容器路徑,不指定對(duì)應(yīng)的主機(jī)路徑,這樣對(duì)應(yīng)映射的主機(jī)路徑就是默認(rèn)的路徑/var/lib/docker/volumes/中自動(dòng)生成一個(gè)隨機(jī)命名的文件夾。
# 運(yùn)行并匿名掛載Nginx容器 [root@localhost data]# docker run -d -P --name nginx01 -v /etc/nginx nginx # 查看卷列表 [root@localhost data]# docker volume ls DRIVER VOLUME NAME local 0e102dae2f6731494400f7c98c11c835293c030b736588d80d4296b96f10c71d local my-vol
具名掛載
具名掛載,就是指定文件夾名稱(chēng),區(qū)別于指定路徑掛載,這里的指定文件夾名稱(chēng)是在Docker指定的也是默認(rèn)數(shù)據(jù)卷路徑下的。通過(guò)docker volume ls命令可以查看當(dāng)前數(shù)據(jù)卷的目錄情況。
# 運(yùn)行并具名掛載Nginx容器
[root@localhost data]# docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx
# 查看卷列表
[root@localhost data]# docker volume ls
DRIVER VOLUME NAME
local 0e102dae2f6731494400f7c98c11c835293c030b736588d80d4296b96f10c71d
local juming-nginx
local my-vol
# 查看數(shù)據(jù)卷詳情,注意主機(jī)路徑也是默認(rèn)數(shù)據(jù)卷路徑下
[root@localhost data]# docker volume inspect juming-nginx
[
{
"CreatedAt": "2022-04-07T13:10:39+08:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/juming-nginx/_data",
"Name": "juming-nginx",
"Options": null,
"Scope": "local"
}
]匿名掛載,具名掛載,指定路徑掛載的命令區(qū)別如下:
- 匿名掛載
-v 容器內(nèi)路徑,不建議使用 - 具名掛載
-v 卷名:容器內(nèi)路徑 - 指定路徑掛載
-v 宿主機(jī)路徑:容器內(nèi)路徑
擴(kuò)展:指定數(shù)據(jù)卷映射的相關(guān)參數(shù):ro / rw
- ro —— readonly 只讀。設(shè)置了只讀則說(shuō)明此路徑只能通過(guò)宿主機(jī)來(lái)操作,不能通過(guò)容器操作。
- rw ----- readwrite 可讀可寫(xiě)
[root@localhost ~]# docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:ro nginx [root@localhost ~]# docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:rw nginx
2.5 數(shù)據(jù)卷之Dockerfile
Dockerfile 是一個(gè)構(gòu)建docker鏡像的構(gòu)建文件,是一個(gè)命令腳本文件。通過(guò)這個(gè)腳本可以生成鏡像。
可以在Dockerfile中使用VOLUME指令來(lái)給鏡像添加一個(gè)或多個(gè)數(shù)據(jù)卷。
dockerfile腳本
# 腳本中指令(大寫(xiě)) # 基礎(chǔ)鏡像 FROM centos # 匿名掛載 VOLUME ["volume01","volume02"] CMD echo "----end----" # 命令行環(huán)境 CMD /bin/bash
執(zhí)行腳本構(gòu)建鏡像 docker build
[root@localhost docker_test_volume]# docker build -f dockerfile1 -t buckletime-centos:1.0 . Sending build context to Docker daemon 2.048kB Step 1/4 : FROM centos ---> 5d0da3dc9764 Step 2/4 : VOLUME ["volume01","volume02"] ---> Running in 0af875dd3c35 Removing intermediate container 0af875dd3c35 ---> 3876cf15e836 Step 3/4 : CMD echo "----end----" ---> Running in 73344c7d325a Removing intermediate container 73344c7d325a ---> ce432169d4d9 Step 4/4 : CMD /bin/bash ---> Running in 8e12aeb63375 Removing intermediate container 8e12aeb63375 ---> b74eed3e6de1 Successfully built b74eed3e6de1 Successfully tagged buckletime-centos:1.0 # 查看鏡像 [root@localhost docker_test_volume]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE buckletime-centos 1.0 b74eed3e6de1 15 seconds ago 231MB mytomcat 1.0 6bbddb87eb6f 3 hours ago 684MB nginx latest 12766a6745ee 8 days ago 142MB tomcat latest fb5657adc892 3 months ago 680MB mysql latest 3218b38490ce 3 months ago 516MB centos latest 5d0da3dc9764 6 months ago 231MB
查看數(shù)據(jù)卷
# 啟動(dòng)自己構(gòu)建的鏡像并進(jìn)入容器
[root@localhost docker_test_volume]# docker run -it b74eed3e6de1 /bin/bash
# 查看目錄
[root@20978f76e318 /]# ls
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var volume01 volume02
# 查看數(shù)據(jù)卷掛載信息
[root@localhost docker_test_volume]# docker inspect 20978f76e318
"Mounts": [
{
"Type": "volume",
"Name": "9bdb13dbdd9a543a00b01e6a84475c6877547a5b722617d1f2afa0546f5cbb47",
"Source": "/var/lib/docker/volumes/9bdb13dbdd9a543a00b01e6a84475c6877547a5b722617d1f2afa0546f5cbb47/_data",
"Destination": "volume01",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
},
{
"Type": "volume",
"Name": "2edc8939b90a1a6f3b684a279819b7f0f20fd89f9eebc9a78a4318fb77cf22ba",
"Source": "/var/lib/docker/volumes/2edc8939b90a1a6f3b684a279819b7f0f20fd89f9eebc9a78a4318fb77cf22ba/_data",
"Destination": "volume02",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
]可以看到Mounts下有宿主機(jī)的掛載目錄。因?yàn)閐ockerfile中沒(méi)有指定宿主機(jī)目錄,所以屬于匿名掛載,在/var/lib/docker/volumes/目錄下生成了隨機(jī)命名的路徑。
2.6 數(shù)據(jù)卷容器
容器數(shù)據(jù)卷是指建立數(shù)據(jù)卷,來(lái)同步多個(gè)容器間的數(shù)據(jù),實(shí)現(xiàn)容器間的數(shù)據(jù)同步。

首先啟動(dòng)容器1,volume01、volume02為掛載目錄
docker run -it --name cnetos01 buckletime-centos:1.0
然后啟動(dòng)容器2,通過(guò)參數(shù)--volumes-from,設(shè)置容器2和容器1建立數(shù)據(jù)卷掛載關(guān)系
docker run -it --name centos02 --volumes-from cnetos01 buckletime-centos:1.0
數(shù)據(jù)卷容器總結(jié):
- 容器之間配置文件和數(shù)據(jù)的同步,數(shù)據(jù)卷容器的生命周期一直持續(xù)到?jīng)]有容器使用為止
- 如果使用-v 持久化到主機(jī)中,主機(jī)中的數(shù)據(jù)不會(huì)被刪除,永久有效。
三、Dockerfile
3.1 Dockerfile 介紹
Dockerfile 是一個(gè)構(gòu)建docker鏡像的構(gòu)建文件,是一個(gè)命令腳本文件。通過(guò)這個(gè)腳本可以生成鏡像。
構(gòu)建步驟
編寫(xiě)dockerfile文件docker build 構(gòu)建鏡像docker run 運(yùn)行鏡像docker push 發(fā)布鏡像
Dockerfile 基礎(chǔ)知識(shí)點(diǎn)
- 指令必須是大寫(xiě)
- 指令從上到下順序執(zhí)行
- # 表示注釋
- 每個(gè)指令都會(huì)創(chuàng)建并提交一個(gè)新的鏡像層

3.2 Dockerfile 指令
FROM 基礎(chǔ)鏡像,一切從這里構(gòu)建MAINTAINER 鏡像維護(hù)者描述,姓名+郵箱RUN 鏡像構(gòu)建的時(shí)候需要運(yùn)行的命令COPY 將文件復(fù)制到目標(biāo)鏡像中ADD 添加文件到目標(biāo)鏡像中,支持使用tar文件和URL路徑WORKDIR 指定鏡像的工作目錄VOLUME 掛載的目錄,只能指定容器內(nèi)的路徑,宿主機(jī)的路徑為默認(rèn)掛載目錄EXPOSE 指定容器對(duì)外暴露的端口CMD 指定啟動(dòng)容器時(shí)要運(yùn)行的命令,只有最后一個(gè)命令會(huì)生效,可以被替代ENTRYPOINT 類(lèi)似CMD,可以追加命令ENV 構(gòu)建的時(shí)候設(shè)置環(huán)境變量
3.3 Dockerfile 實(shí)戰(zhàn)
實(shí)戰(zhàn)1:基于官方centos鏡像構(gòu)建定制化centos
官方的centos鏡像是最小使用版本,缺失很多命令。我們可以基于官方centos鏡像定制化一個(gè)contos
1.編寫(xiě)dockerfile文件 dockerfile-mycentos
FROM centos:7 MAINTAINER buckletime<1872192281@qq.com> ENV MYPATH /usr/local WORKDIR $MYPATH RUN yum install -y vim RUN yum install -y net-tools EXPOSE 80 CMD echo "-----end------" CMD /bin/bash
2.通過(guò)dockerfile文件構(gòu)建鏡像
docker build -f Dockfile文件 -t 目標(biāo)鏡像:[tag] 目標(biāo)位置
[root@localhost dockerfile]# docker build -f dockerfile-mycentos -t mycentos:0.1 . ... Step 9/9 : CMD /bin/bash ---> Running in d5083707b308 Removing intermediate container d5083707b308 ---> b6a1205a01ec Successfully built b6a1205a01ec Successfully tagged mycentos:0.1 # 查看鏡像 [root@localhost dockerfile]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE mycentos 0.1 b6a1205a01ec 3 minutes ago 580MB centos 7 eeb6ee3f44bd 6 months ago 204MB
3.運(yùn)行測(cè)試

4.可以通過(guò)docker history命令來(lái)分析一個(gè)鏡像的構(gòu)建過(guò)程
# 通過(guò) docker history 命令來(lái)分析剛剛構(gòu)建的鏡像過(guò)程 [root@localhost dockerfile]# docker history b6a1205a01ec IMAGE CREATED CREATED BY SIZE COMMENT b6a1205a01ec 23 minutes ago /bin/sh -c #(nop) CMD ["/bin/sh" "-c" "/bin… 0B 8c604ec85c0d 23 minutes ago /bin/sh -c #(nop) CMD ["/bin/sh" "-c" "echo… 0B ad5af97ad072 23 minutes ago /bin/sh -c #(nop) EXPOSE 80 0B 3cdf414340ac 23 minutes ago /bin/sh -c yum -y install vim 216MB cdc69b9b3a21 24 minutes ago /bin/sh -c yum -y install net-tools 161MB ff54b51b10da 24 minutes ago /bin/sh -c #(nop) WORKDIR /usr/local 0B d62c8129ba70 24 minutes ago /bin/sh -c #(nop) ENV MYPATH=/usr/local 0B 5bc36fed9ecf 24 minutes ago /bin/sh -c #(nop) MAINTAINER buckletime<187… 0B eeb6ee3f44bd 6 months ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0B <missing> 6 months ago /bin/sh -c #(nop) LABEL org.label-schema.sc… 0B <missing> 6 months ago /bin/sh -c #(nop) ADD file:b3ebbe8bd304723d4… 204MB
實(shí)戰(zhàn)2:CMD指令和ENTRYPOINT指令的區(qū)別
CMD 指定啟動(dòng)容器時(shí)要運(yùn)行的命令,只有最后一個(gè)命令會(huì)生效,可以被替代ENTRYPOINT 類(lèi)似CMD,可以追加命令
CMD指令測(cè)試
1.vim dockerfile-cmd
FROM centos:7 CMD ["pwd"] CMD ["ls","-a"]
2.構(gòu)建鏡像
[root@localhost dockerfile]# docker build -f dockerfile-cmd -t cmd-test:1.0 .
3.運(yùn)行測(cè)試
[root@localhost dockerfile]# docker run -it cbe86f605790 . .dockerenv bin etc lib media opt root sbin sys usr .. anaconda-post.log dev home lib64 mnt proc run srv tmp var # 要想追加命令 -l ,CMD指令會(huì)報(bào)錯(cuò),只能使用全部命令去替換 ls -al [root@localhost dockerfile]# docker run -it cbe86f605790 -l docker: Error response from daemon: failed to create shim: OCI runtime create failed: container_linux.go:380: starting container process caused: exec: "-l": executable file not found in $PATH: unknown. [root@localhost dockerfile]# docker run -it cbe86f605790 ls -al total 12 drwxr-xr-x. 1 root root 6 Apr 7 09:02 . drwxr-xr-x. 1 root root 6 Apr 7 09:02 .. -rwxr-xr-x. 1 root root 0 Apr 7 09:02 .dockerenv -rw-r--r--. 1 root root 12114 Nov 13 2020 anaconda-post.log lrwxrwxrwx. 1 root root 7 Nov 13 2020 bin -> usr/bin drwxr-xr-x. 5 root root 360 Apr 7 09:02 dev drwxr-xr-x. 1 root root 66 Apr 7 09:02 etc drwxr-xr-x. 2 root root 6 Apr 11 2018 home lrwxrwxrwx. 1 root root 7 Nov 13 2020 lib -> usr/lib lrwxrwxrwx. 1 root root 9 Nov 13 2020 lib64 -> usr/lib64 drwxr-xr-x. 2 root root 6 Apr 11 2018 media drwxr-xr-x. 2 root root 6 Apr 11 2018 mnt drwxr-xr-x. 2 root root 6 Apr 11 2018 opt dr-xr-xr-x. 241 root root 0 Apr 7 09:02 proc dr-xr-x---. 2 root root 114 Nov 13 2020 root drwxr-xr-x. 11 root root 148 Nov 13 2020 run lrwxrwxrwx. 1 root root 8 Nov 13 2020 sbin -> usr/sbin drwxr-xr-x. 2 root root 6 Apr 11 2018 srv dr-xr-xr-x. 13 root root 0 Apr 7 01:43 sys drwxrwxrwt. 7 root root 132 Nov 13 2020 tmp drwxr-xr-x. 13 root root 155 Nov 13 2020 usr drwxr-xr-x. 18 root root 238 Nov 13 2020 var
ENTRYPOINT指令測(cè)試
1.vim dockerfile-entrypoint
FROM centos:7 ENTRYPOINT ["pwd"] ENTRYPOINT ["ls","-a"]
2.構(gòu)建鏡像
[root@localhost dockerfile]# docker build -f dockerfile-entrypoint -t entrypoint-test:1.0 .
3.運(yùn)行測(cè)試
[root@localhost dockerfile]# docker run -it 1ff2ec561a44 . .dockerenv bin etc lib media opt root sbin sys usr .. anaconda-post.log dev home lib64 mnt proc run srv tmp var # 追加命令 -l [root@localhost dockerfile]# docker run -it 1ff2ec561a44 -l total 12 drwxr-xr-x. 1 root root 6 Apr 7 09:06 . drwxr-xr-x. 1 root root 6 Apr 7 09:06 .. -rwxr-xr-x. 1 root root 0 Apr 7 09:06 .dockerenv -rw-r--r--. 1 root root 12114 Nov 13 2020 anaconda-post.log lrwxrwxrwx. 1 root root 7 Nov 13 2020 bin -> usr/bin drwxr-xr-x. 5 root root 360 Apr 7 09:06 dev drwxr-xr-x. 1 root root 66 Apr 7 09:06 etc drwxr-xr-x. 2 root root 6 Apr 11 2018 home lrwxrwxrwx. 1 root root 7 Nov 13 2020 lib -> usr/lib lrwxrwxrwx. 1 root root 9 Nov 13 2020 lib64 -> usr/lib64 drwxr-xr-x. 2 root root 6 Apr 11 2018 media drwxr-xr-x. 2 root root 6 Apr 11 2018 mnt drwxr-xr-x. 2 root root 6 Apr 11 2018 opt dr-xr-xr-x. 242 root root 0 Apr 7 09:06 proc dr-xr-x---. 2 root root 114 Nov 13 2020 root drwxr-xr-x. 11 root root 148 Nov 13 2020 run lrwxrwxrwx. 1 root root 8 Nov 13 2020 sbin -> usr/sbin drwxr-xr-x. 2 root root 6 Apr 11 2018 srv dr-xr-xr-x. 13 root root 0 Apr 7 01:43 sys drwxrwxrwt. 7 root root 132 Nov 13 2020 tmp drwxr-xr-x. 13 root root 155 Nov 13 2020 usr drwxr-xr-x. 18 root root 238 Nov 13 2020 var
實(shí)戰(zhàn)3:Dockerfile 制作Tomcat鏡像
1. 準(zhǔn)備環(huán)境
準(zhǔn)備Tomcat和jdk的壓縮包
[root@localhost dockerfile]# ll 總用量 188324 -rwxr-xr-x. 1 root root 11560971 4月 7 17:26 apache-tomcat-9.0.62.tar.gz -rwxr-xr-x. 1 root root 181260798 4月 7 17:26 jdk-8u65-linux-x64.tar.gz -rw-r--r--. 1 root root 0 4月 7 18:39 readme.txt
2. 編寫(xiě)Dockerfile文件
官方名字是Dockerfile,直接使用此名字,構(gòu)建時(shí)就不用再指定 -f
FROM centos:7 MAINTAINER buckletime<1872192281@qq.com> ENV MYPATH /usr/local WORKDIR $MYPATH COPY readme.txt /usr/local/readme.txt ADD jdk-8u65-linux-x64.tar.gz /usr/local/ ADD apache-tomcat-9.0.62.tar.gz /usr/local/ RUN yum -y install vim ENV JAVA_HOME /usr/local/jdk1.8.0_65 ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.62 ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.62 ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin EXPOSE 8080 CMD /usr/local/apache-tomcat-9.0.62/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.62/logs/catalina.out
3. 構(gòu)建鏡像
[root@localhost dockerfile]# docker build -t mytomcat:2.0 . Successfully built 874b2eaffc8f Successfully tagged mytomcat:2.0
4. 啟動(dòng)鏡像
[root@localhost dockerfile]# docker run -d -p 9090:8080 --name mytomcat \ -v /home/buckletime/dockerbuild/tomcat/project:/usr/local/apache-tomcat-9.0.62/webapps/project \ -v /home/buckletime/dockerbuild/tomcat/tomcatlogs/:/usr/local/apache-tomcat-9.0.62/logs mytomcat:2.0
訪問(wèn)測(cè)試:http://192.168.0.105:9090 成功進(jìn)入Tomcat主頁(yè)
5. 發(fā)布項(xiàng)目
由于做了卷掛載,直接將項(xiàng)目放在本地就可以發(fā)布項(xiàng)目了
實(shí)戰(zhàn)4:SpringBoot項(xiàng)目打包成Docker鏡像
- Springboot項(xiàng)目打包,這里以jar包為例
- 上傳到Linux中,并編寫(xiě)Dockerfile文件
[root@localhost idea]# ls demo-0.0.1-SNAPSHOT.jar Dockerfile
FROM java:8 # 將demo-0.0.1-SNAPSHOT.jar 復(fù)制 到容器中并重命名為 app.jar COPY demo-0.0.1-SNAPSHOT.jar app.jar CMD ["--server.port=8080"] EXPOSE 8080 ENTRYPOINT ["java","-jar","app.jar"]
構(gòu)建鏡像
[root@localhost idea]# docker build -t springbootdemo:1.0 . [root@localhost idea]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE springbootdemo 1.0 d9648a49a226 50 seconds ago 661MB
運(yùn)行、測(cè)試
[root@localhost idea]# docker run -d -p:8888:8080 --name mydemo springbootdemo:1.0 [root@localhost idea]# curl localhost:8888/hello hello buckletime![root@localhost idea]#
實(shí)戰(zhàn)5:發(fā)布鏡像
發(fā)布鏡像到Docker Hub
Docker Hub官網(wǎng),注冊(cè)賬號(hào)
使用docker login 登錄賬號(hào)
[root@localhost ~]# docker login --help
Usage: docker login [OPTIONS] [SERVER]
Log in to a Docker registry.
If no server is specified, the default is defined by the daemon.
Options:
-p, --password string Password
--password-stdin Take the password from stdin
-u, --username string Username使用docker push 提交鏡像
# 發(fā)布鏡像最好帶上版本號(hào),可以使用docker tag 命令修改鏡像名稱(chēng)和版本號(hào) docker tag 6d27817ecb31 buckletime/mycentos:2.0 # docker push 發(fā)布鏡像 docker push buckletime/mycentos:2.0
發(fā)布鏡像到阿里云容器服務(wù)
- 登錄阿里云,找到容器鏡像服務(wù)
- 創(chuàng)建命名空間
- 創(chuàng)建容器鏡像
- 根據(jù)容器鏡像內(nèi)的描述,發(fā)布鏡像
四、Docker 總結(jié)

五、Docker 網(wǎng)絡(luò)
先清空所有容器和鏡像,方便學(xué)習(xí)
# 清空所有容器 docker rm $(docker ps -aq) # 清空所有鏡像 docker rmi $(docker images -aq)
5.1 了解Docker網(wǎng)絡(luò)

1.運(yùn)行一個(gè)Tomcat容器,tomcat01 ,并查看容器的地址
[root@localhost ~]# docker run -d -P --name tomcat01 tomcat [root@localhost ~]# docker exec -it tomcat01 ip addr

運(yùn)行時(shí)使用ip addr直接查看容器地址,有可能出現(xiàn)報(bào)錯(cuò)找不到ip命令,需要進(jìn)入容器中安裝iproute2
官方Tomcat中沒(méi)有yum命令,使用apt-get命令安裝iproute2和ping命令
[root@localhost ~]# docker exec -it tomcat01 /bin/bash root@8e57c8b48890:/usr/local/tomcat# apt-get update root@8e57c8b48890:/usr/local/tomcat# apt-get -y install iproute2 iproute2-doc root@8e57c8b48890:/usr/local/tomcat# apt-get -y install inetutils-ping
由于容器的ip是docker分配的,容器與主機(jī)在同一個(gè)網(wǎng)段。Linux主機(jī)與容器之間能 ping 通
[root@localhost ~]# ping 172.17.0.2 PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data. 64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.081 ms 64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.046 ms
2.再運(yùn)行一個(gè)Tomcat容器,tomcat02 ,并查看容器的地址
[root@localhost ~]# docker run -d -P --name tomcat02 tomcat
[root@localhost ~]# docker exec -it tomcat02 ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
70: eth0@if71: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.17.0.3/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
可以發(fā)現(xiàn):
- 我們發(fā)現(xiàn)這個(gè)容器帶來(lái)網(wǎng)卡,都是一對(duì)對(duì)的
evth-pair就是一對(duì)的虛擬設(shè)備接口,他們都是成對(duì)出現(xiàn)的,一段連著協(xié)議,一段彼此相連正因?yàn)橛羞@個(gè)特性,evth-pair 充當(dāng)一個(gè)橋梁,連接各種虛擬網(wǎng)絡(luò)設(shè)備的- OpenStac,Docker容器之間的連接,OVS的連接,都是使用 evth-pair 技術(shù)
3.兩個(gè)tomcat01 和tomcat02之間能否ping通? 可以ping同,也在同一網(wǎng)段
[root@localhost ~]# docker exec -it tomcat02 ping 127.17.0.2 PING 127.17.0.2 (127.17.0.2): 56 data bytes 64 bytes from 127.17.0.2: icmp_seq=0 ttl=64 time=0.099 ms 64 bytes from 127.17.0.2: icmp_seq=1 ttl=64 time=0.051 ms

結(jié)論
- 所有容器不指定網(wǎng)絡(luò)的情況下,都是由docker0路由的,docker會(huì)給容器分配一個(gè)可用IP
- Docker使用的是Linux的橋接
- Docker中所有網(wǎng)絡(luò)接口都是虛擬的,轉(zhuǎn)發(fā)效率高

5.2 容器互聯(lián) --link
--link命令可以連接容器,使得容器之間可以使用容器名訪問(wèn)
[root@localhost ~]# docker exec -it tomcat02 ping tomcat01 ping: unknown host # --link命令 連接容器 tomcat03 連接 tomcat02 [root@localhost ~]# docker run -d -P --name tomcat03 --link tomcat02 tomcat # tomcat03 能通過(guò)容器名訪問(wèn) tomcat02 [root@localhost ~]# docker exec -it tomcat03 ping tomcat02 PING tomcat02 (172.17.0.3): 56 data bytes 64 bytes from 172.17.0.3: icmp_seq=0 ttl=64 time=0.137 ms 64 bytes from 172.17.0.3: icmp_seq=1 ttl=64 time=0.061 ms # 但是tomcat02 不能通過(guò)容器名訪問(wèn) tomcat03 [root@localhost ~]# docker exec -it tomcat02 ping tomcat03 ping: unknown host
本質(zhì)原理:--link是在hosts中增加了一個(gè)容器名稱(chēng)的映射關(guān)系,是單向連接的
[root@localhost ~]# docker exec -it tomcat03 cat /etc/hosts 127.0.0.1 localhost ::1 localhost ip6-localhost ip6-loopback fe00::0 ip6-localnet ff00::0 ip6-mcastprefix ff02::1 ip6-allnodes ff02::2 ip6-allrouters 172.17.0.3 tomcat02 03da12909222 172.17.0.4 8e77f2a544a5
真實(shí)開(kāi)發(fā)中,不推薦使用--link,配置是修改hosts文件,且是單向配置
5.3 容器互聯(lián) 自定義網(wǎng)絡(luò)
不使用docker0,因?yàn)閐ocker0不支持使用容器名連接訪問(wèn)。使用自定義網(wǎng)絡(luò)。
docker network命令
[root@localhost ~]# docker network --help Usage: docker network COMMAND Manage networks Commands: connect Connect a container to a network create Create a network disconnect Disconnect a container from a network inspect Display detailed information on one or more networks ls List networks prune Remove all unused networks rm Remove one or more networks [root@localhost ~]# docker network ls NETWORK ID NAME DRIVER SCOPE 9eeca5a5158c bridge bridge local c60f472b3848 host host local a959f5564b21 none null local
網(wǎng)絡(luò)模式
- bridge:橋接(docker默認(rèn),自定義網(wǎng)絡(luò)也是用橋接模式)
- host:和宿主機(jī)共享網(wǎng)絡(luò)
- none:不設(shè)置網(wǎng)絡(luò)
- container:容器網(wǎng)絡(luò)連接(局限性大,很少使用)
創(chuàng)建網(wǎng)絡(luò)
docker network create 創(chuàng)建網(wǎng)絡(luò)
--driver 模式(默認(rèn)bridge)--subnet 子網(wǎng)--gateway 網(wǎng)關(guān)
# docker network create 創(chuàng)建網(wǎng)絡(luò) [root@localhost ~]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet 2b9f9c88b69fbb9917c550d0b8017471e246aeb2c8b17c1667ece8a19b086bca [root@localhost ~]# docker network ls NETWORK ID NAME DRIVER SCOPE 9eeca5a5158c bridge bridge local c60f472b3848 host host local 2b9f9c88b69f mynet bridge local a959f5564b21 none null local
我們自己的網(wǎng)絡(luò)就創(chuàng)建好了:
docker network inspect mynet查看網(wǎng)絡(luò)詳情信息

啟動(dòng)容器指定網(wǎng)絡(luò) --net
[root@localhost ~]# docker run -d -P --name tomcat-net01 --net mynet tomcat 972542a6d6516b6d03d81493d03c1f60cecb5160e4ecdad44fb4d18e4430b03f [root@localhost ~]# docker run -d -P --name tomcat-net02 --net mynet tomcat f4fd35dcefcd8059af0b0a0c607b137b9c8d4c9d6ba0ae2cf6be23d8a3498992 # 這樣兩個(gè)容器可以直接使用容器名互相連接訪問(wèn) [root@localhost ~]# docker exec -it tomcat-net01 ping tomcat-net02 PING tomcat-net02 (192.168.0.3): 56 data bytes 64 bytes from 192.168.0.3: icmp_seq=0 ttl=64 time=0.137 ms 64 bytes from 192.168.0.3: icmp_seq=1 ttl=64 time=0.061 ms
自定義網(wǎng)絡(luò)好處
- 不同的集群使用不同的網(wǎng)絡(luò),保證集群是安全和健康的
5.4 網(wǎng)絡(luò)連通
docker network connect 網(wǎng)絡(luò) 容器 將容器連接到網(wǎng)絡(luò)中
[root@localhost ~]# docker network connect --help
Usage: docker network connect [OPTIONS] NETWORK CONTAINER
Connect a container to a network
Options:
--alias strings Add network-scoped alias for the container
--driver-opt strings driver options for the network
--ip string IPv4 address (e.g., 172.30.100.104)
--ip6 string IPv6 address (e.g., 2001:db8::33)
--link list Add link to another container
--link-local-ip strings Add a link-local address for the container測(cè)試
# 使用docker0啟動(dòng)兩個(gè)tomcat [root@localhost ~]# docker run -d -P --name tomcat04 tomcat [root@localhost ~]# docker run -d -P --name tomcat05 tomcat # tomcat04和 自定義網(wǎng)絡(luò)mynet下的tomcat-net01連接,此時(shí)肯定是不通的 [root@localhost ~]# docker exec -it tomcat04 ping tomcat-net01 ping: unknown host # docker network connect 將容器tomcat04連接到mynet網(wǎng)絡(luò)中 docker network connect mynet tomcat04 # 再次連接,可以連通 [root@localhost ~]# docker exec -it tomcat04 ping tomcat-net01 PING tomcat-net01 (192.168.0.2): 56 data bytes 64 bytes from 192.168.0.2: icmp_seq=0 ttl=64 time=0.137 ms 64 bytes from 192.168.0.2: icmp_seq=1 ttl=64 time=0.061 ms
docker network inspect mynet 查看網(wǎng)絡(luò)詳情信息,發(fā)現(xiàn)容器tomcat04被添加到mynet網(wǎng)絡(luò)中,即:一個(gè)容器,有兩個(gè)ip地址

5.5 Docker網(wǎng)絡(luò) 實(shí)戰(zhàn)
實(shí)戰(zhàn)1:Redis集群部署

# 1.創(chuàng)建redis網(wǎng)絡(luò)
[root@localhost ~]# docker network create redis_net --subnet 172.38.0.0/16 --gateway 172.38.0.1
# 2.通過(guò)shell腳本創(chuàng)建6個(gè)redis配置
for port in $(seq 1 6); \
do \
mkdir -p /mydata/redis/node-${port}/conf
touch /mydata/redis/node-${port}/conf/redis.conf
cat << EOF >>/mydata/redis/node-${port}/conf/redis.conf
port 6379
bind 0.0.0.0
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
cluster-announce-ip 172.38.0.1${port}
cluster-announce-port 6379
cluster-announce-bus-port 16379
appendonly yes
EOF
done
# 3.通過(guò)shell腳本啟動(dòng)6個(gè)redis容器
for port in $(seq 1 6); \
do \
docker run -p 637${port}:6379 -p 1637${port}:16379 --name redis-${port} \
-v /mydata/redis/node-${port}/data:/data \
-v /mydata/redis/node-${port}/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis_net --ip 172.38.0.1${port} redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
done
# 4.配置集群。進(jìn)入一個(gè)redis容器中,注意,redis沒(méi)有/bin/bash 命令,使用/bin/sh
[root@localhost ~]# docker exec -it redis-1 /bin/sh
/data # redis-cli --cluster create 172.38.0.11:6379 172.38.0.12:6379 172.38.0.13:6379 172.38.0.14:6379 172.38.0.15:6379 172.38.0.16:6379 --cluster-replicas 1
配置集群命令執(zhí)行后,出現(xiàn)下圖信息說(shuō)明,集群配置成功

5.redis集群測(cè)試
redis-cli -c 是進(jìn)入redis集群, redis-cli是進(jìn)入單機(jī)版redis
cluster info:查看集群信息cluster nodes:查看集群節(jié)點(diǎn)信息
/data # redis-cli -c 127.0.0.1:6379> cluster nodes 8dea9b0ac434985556f08543f663a1d149772b75 172.38.0.11:6379@16379 myself,master - 0 1649398430000 1 connected 0-5460 29c361a494c043eb2597a3702537bf9553b89c95 172.38.0.16:6379@16379 slave c356c34a7fe0bf89b0abdcf538a910c1444da20e 0 1649398429000 6 connected 187da435dedcc35a48d0236bb8cbb2a2410d354e 172.38.0.15:6379@16379 slave 8dea9b0ac434985556f08543f663a1d149772b75 0 1649398430636 5 connected 17c460274af7f601846685dd91a39cc244823e17 172.38.0.14:6379@16379 slave 554f73de745a0dbdbe8bb8d805b93c622cb98a73 0 1649398429530 4 connected 554f73de745a0dbdbe8bb8d805b93c622cb98a73 172.38.0.13:6379@16379 master - 0 1649398429127 3 connected 10923-16383 c356c34a7fe0bf89b0abdcf538a910c1444da20e 172.38.0.12:6379@16379 master - 0 1649398430133 2 connected 5461-10922 127.0.0.1:6379> set name buckletime -> Redirected to slot [5798] located at 172.38.0.12:6379 OK
在集群中set值,是隨機(jī)處理(172.38.0.12)的。此時(shí)把172.38.0.12上的redis-2容器停止,模擬redis服務(wù)宕機(jī),看看數(shù)據(jù)是否還在,是否還能得到剛才的值。
[root@localhost ~]# docker stop redis-2 redis-2 127.0.0.1:6379> get name -> Redirected to slot [5798] located at 172.38.0.16:6379 "buckletime"
再次進(jìn)入集群中,發(fā)現(xiàn)可以獲得剛剛的值,說(shuō)明數(shù)據(jù)沒(méi)有受到影響,是高可用的。
再次查看集群節(jié)點(diǎn)信息,如下圖:redis-2節(jié)點(diǎn)狀態(tài)是fail,集群自動(dòng)又選舉出一個(gè)master

六、Docker Compose 單機(jī)部署
6.1 Docker Compose 介紹、安裝
Compose 是用于定義和運(yùn)行多容器 Docker 應(yīng)用程序的工具。通過(guò) Compose,您可以使用 YML 文件來(lái)配置應(yīng)用程序需要的所有服務(wù)。然后,使用一個(gè)命令,就可以從 YML 文件配置中創(chuàng)建并啟動(dòng)所有服務(wù)。
詳細(xì)介紹可以參考Docker Compose官網(wǎng),官網(wǎng)教程非常詳細(xì),可以多看官網(wǎng)。
Compose 使用的三個(gè)步驟:
- 使用
Dockerfile定義應(yīng)用程序的環(huán)境。 - 使用
docker-compose.yml定義構(gòu)成應(yīng)用程序的服務(wù),這樣它們可以在隔離環(huán)境中一起運(yùn)行。 - 最后,執(zhí)行
docker-compose up命令來(lái)啟動(dòng)并運(yùn)行整個(gè)應(yīng)用程序。
docker-compose.yml 的配置案例如下:
version: '3'
services:
web:
build: .
ports:
- "5000:5000"
volumes:
- .:/code
- logvolume01:/var/log
links:
- redis
redis:
image: redis
volumes:
logvolume01: {}理解兩個(gè)概念
- 服務(wù)
service,項(xiàng)目中使用的單個(gè)服務(wù)模塊,比如web、redis、mysql… - 項(xiàng)目
project,一組關(guān)聯(lián)的服務(wù)構(gòu)成一個(gè)項(xiàng)目,比如博客…
Docker Compose 安裝
Linux 中安裝Docker Compose:1.下載 2.授權(quán)
# 下載 Docker Compose sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose # 授權(quán) sudo chmod +x /usr/local/bin/docker-compose
6.2 Docker Compose 快速體驗(yàn)
1.創(chuàng)建一個(gè)應(yīng)用。python + flask + redis 實(shí)現(xiàn)的一個(gè)計(jì)數(shù)器。
vim app.py,編寫(xiě)應(yīng)用代碼
import time
import redis
from flask import Flask
app = Flask(__name__)
cache = redis.Redis(host='redis', port=6379)
def get_hit_count():
retries = 5
while True:
try:
return cache.incr('hits')
except redis.exceptions.ConnectionError as exc:
if retries == 0:
raise exc
retries -= 1
time.sleep(0.5)
@app.route('/')
def hello():
count = get_hit_count()
return 'Hello World! I have been seen {} times.\n'.format(count)vim requirements.txt,所需依賴(lài)包
flask redis
2.創(chuàng)建Dockerfile
vim Dockerfile,構(gòu)建Docker 鏡像
# syntax=docker/dockerfile:1 FROM python:3.7-alpine WORKDIR /code ENV FLASK_APP=app.py ENV FLASK_RUN_HOST=0.0.0.0 RUN apk add --no-cache gcc musl-dev linux-headers COPY requirements.txt requirements.txt RUN pip install -r requirements.txt EXPOSE 5000 COPY . . CMD ["flask", "run"]
3.定義docker-compose.yml
vim docker-compose.yml,在配置文件中定義服務(wù)信息
version: "3.9"
services:
web:
build: .
ports:
- "8000:5000"
redis:
image: "redis:alpine"
4.用Compose構(gòu)建和運(yùn)行應(yīng)用程序
docker-compose up -d參數(shù)表示后臺(tái)啟動(dòng)
[root@localhost demo_compose]# docker-compose up Creating network "demo_compose_default" with the default driver Building web Sending build context to Docker daemon 4.608kB Step 1/10 : FROM python:3.7-alpine ... Creating demo_compose_web_1 ... done Creating demo_compose_redis_1 ... done ... web_1 | * Running on http://127.0.0.1:5000 web_1 | * Running on http://172.18.0.2:5000 (Press CTRL+C to quit)
由構(gòu)建過(guò)程可以看出Compose的工作流程:
- 創(chuàng)建一個(gè)網(wǎng)絡(luò),名稱(chēng)為 “文件夾名稱(chēng)_default”
- 讀取docker-compose.yml配置文件
- 根據(jù)配置文件中的服務(wù)定義,構(gòu)建并啟動(dòng)服務(wù)
運(yùn)行結(jié)果測(cè)試:
[root@localhost idea]# curl 172.18.0.2:5000 Hello World! I have been seen 1 times. [root@localhost idea]# curl 172.18.0.2:5000 Hello World! I have been seen 2 times. [root@localhost idea]# curl 172.18.0.2:5000 Hello World! I have been seen 3 times. [root@localhost idea]# curl 172.18.0.2:5000 Hello World! I have been seen 4 times.
5.停止程序
Ctrl + C非后臺(tái)啟動(dòng),可以使用此命令docker-compose stop-d 后臺(tái)啟動(dòng)可以使用此命令docker-compose down [--volumes]
stop和down區(qū)別在于使用down會(huì)完全刪除容器,使用stop是停止一次。參數(shù)--volumes表示刪除容器使用的數(shù)據(jù)卷
6.3 Docker Compose 默認(rèn)命名規(guī)則
1.compose 服務(wù)名命名規(guī)則
使用docker ps查看正在運(yùn)行的服務(wù)可以發(fā)現(xiàn),服務(wù)名稱(chēng)的命名規(guī)則是文件夾名_服務(wù)名_num
[root@localhost idea]# docker ps CONTAINER ID IMAGE NAMES COMMAND CREATED STATUS PORTS f8d252c277d0 redis:alpine demo_compose_redis_1 "docker-entrypoint.s…" 18 minutes ago Up 18 minutes 6379/tcp e29dfaeda7c5 demo_compose_web demo_compose_web_1 "flask run" 18 minutes ago Up 18 minutes 0.0.0.0:8000->5000/tcp, :::8000->5000/tcp
compose啟動(dòng)服務(wù)是以集群的方式啟動(dòng)的,num表示副本數(shù)量
2.網(wǎng)絡(luò)名命名規(guī)則
使用docker network ls 查看網(wǎng)絡(luò)列表,網(wǎng)絡(luò)名的命名規(guī)則是文件夾名_default
[root@localhost idea]# docker network ls NETWORK ID NAME DRIVER SCOPE 9eeca5a5158c bridge bridge local 5fcff058a02c demo_compose_default bridge local c60f472b3848 host host local
這樣,在同一個(gè)項(xiàng)目文件夾下,所有服務(wù)之間都可以通過(guò)域名進(jìn)行訪問(wèn)
6.4 docker-compose.yml 配置規(guī)則
官網(wǎng) docker-compose.yml 配置詳細(xì)說(shuō)明
version: "3.9" # 1.版本
services: # 2.服務(wù)
web: # 服務(wù)名
# 服務(wù)配置
build: .
ports:
- "8000:5000"
redis:
image: "redis:alpine"
# 3.其他配置 網(wǎng)絡(luò)/卷/全局規(guī)則等
volumes:
network:
config:學(xué)習(xí) docker-compose.yml 配置規(guī)則,最好的辦法是多寫(xiě)多看!
- 多看官方文檔
- 多看開(kāi)源項(xiàng)目
6.5 實(shí)戰(zhàn):編寫(xiě)springboot項(xiàng)目通過(guò)Compose構(gòu)建運(yùn)行
1.編寫(xiě)微服務(wù)項(xiàng)目,自己實(shí)現(xiàn)一個(gè)計(jì)數(shù)器(redis)
引入redis依賴(lài)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>編寫(xiě)controller代碼
@RestController
public class CounterController {
@Autowired
StringRedisTemplate redisTemplate;
@RequestMapping("counter")
public String counter(){
Long views = redisTemplate.opsForValue().increment("views");
return "hello, buckletime, views " + views + " times";
}
}application.properties配置文件
server.port=8080 # 配置redis 注意,不要寫(xiě)ip,直接寫(xiě)服務(wù)名再通過(guò)Compose構(gòu)建服務(wù) spring.redis.host=redis
最后將項(xiàng)目打成jar包
2.Dockerfile 構(gòu)建鏡像
FROM java:8 COPY *.jar app.jar CMD ["--server.port=8080"] EXPOSE 8080 ENTRYPOINT ["java","-jar","app.jar"]
3.編寫(xiě) docker-compose.yml 配置
version: "3.8"
services:
mycounter: # 服務(wù)名
build: . # . 表示使用當(dāng)前目錄下的 Dockerfile文件構(gòu)建鏡像
image: mycounter # 鏡像
depends_on:
- redis # depends_on 依賴(lài) 表示需要依賴(lài)redis服務(wù)
ports:
- "8080:8080" # 端口映射
redis:
image: "redis:alpine"
4.通過(guò)Compose構(gòu)建運(yùn)行
[root@localhost mycounter]# ll 總用量 26884 -rwxr-xr-x. 1 root root 27520888 4月 8 19:50 demo-0.0.1-SNAPSHOT.jar -rwxr-xr-x. 1 root root 336 4月 8 19:50 docker-compose.yml -rwxr-xr-x. 1 root root 120 4月 8 19:50 Dockerfile [root@localhost mycounter]# docker-compose up -d
5.訪問(wèn)測(cè)試,運(yùn)行成功
[root@localhost mycounter]# curl localhost:8080/counter hello, buckletime, views 1 times[root@localhost mycounter]# curl localhost:8080/counter hello, buckletime, views 2 times[root@localhost mycounter]# curl localhost:8080/counter hello, buckletime, views 3 times[root@localhost mycounter]# curl localhost:8080/counter hello, buckletime, views 4 times[root@localhost mycounter]# curl localhost:8080/counter hello, buckletime, views 5 times[root@localhost mycounter]#
七、Docker Swarm 集群部署
7.1 Swarm 相關(guān)概念
swarm
集群的管理和編排。docker可以初始化一個(gè)swarm集群,其他節(jié)點(diǎn)可以加入。
Node
就是一個(gè)docker節(jié)點(diǎn)。多個(gè)節(jié)點(diǎn)就組成了一個(gè)網(wǎng)絡(luò)集群。(管理、工作者)
Service
服務(wù),可以在管理節(jié)點(diǎn)或者工作節(jié)點(diǎn)來(lái)運(yùn)行,核心!用戶(hù)訪問(wèn)!
Task
容器內(nèi)的命令,細(xì)節(jié)任務(wù)
swarm和k8s原理一樣的
- 命令 -> manager節(jié)點(diǎn) -> api -> 調(diào)度 -> worker節(jié)點(diǎn)(創(chuàng)建維護(hù)Task)
7.2 Swarm 工作模式
1. Node工作模式

3. Service、Task、Container
將服務(wù)部署到 swarm 時(shí),swarm 管理器會(huì)接受您的服務(wù)定義作為服務(wù)的所需狀態(tài)。然后,它將 swarm 中節(jié)點(diǎn)上的服務(wù)計(jì)劃為一個(gè)或多個(gè)副本任務(wù)。這些任務(wù)在群中的節(jié)點(diǎn)上彼此獨(dú)立運(yùn)行。
例如,假設(shè)您要在 HTTP 偵聽(tīng)器的三個(gè)實(shí)例之間實(shí)現(xiàn)負(fù)載平衡。下圖顯示了具有三個(gè)副本的 HTTP 偵聽(tīng)器服務(wù)。偵聽(tīng)器的三個(gè)實(shí)例中的每一個(gè)都是群中的一個(gè)任務(wù)。

3. Task、Scheduling
下圖顯示了 swarm 模式如何接受服務(wù)創(chuàng)建請(qǐng)求并將任務(wù)計(jì)劃到工作節(jié)點(diǎn)。

7.3 Swarm 集群搭建
[root@localhost ~]# docker swarm --help Commands: ca Display and rotate the root CA init Initialize a swarm join Join a swarm as a node and/or manager join-token Manage join tokens leave Leave the swarm unlock Unlock swarm unlock-key Manage the unlock key update Update the swarm
docker swarm init --advertise-addr 172.24.82.149 初始化一個(gè)節(jié)點(diǎn)

docker swarm join 加入一個(gè)節(jié)點(diǎn)
docker swarm join-token manager獲取manager令牌docker swarm join-token worker獲取worker令牌

在另外兩臺(tái)機(jī)器上分別再加入節(jié)點(diǎn),一個(gè)manager,一個(gè)worker。得到一個(gè)4節(jié)點(diǎn)的swarm集群

集群搭建總結(jié)
docker swarm init初始化主節(jié)點(diǎn)docker swarm join加入節(jié)點(diǎn)(manager、worker)
7.4 了解Raft一致性協(xié)議
7.2示例中集群是兩主兩從,當(dāng)Leader節(jié)點(diǎn)宕機(jī)時(shí),另一個(gè)manager節(jié)點(diǎn)也無(wú)法工作,只有一個(gè)主節(jié)點(diǎn)存活無(wú)法重新選舉出新的Leader;把其中一個(gè)worker節(jié)點(diǎn)更改為manager節(jié)點(diǎn)后,此時(shí)集群是三主一從,當(dāng)Leader節(jié)點(diǎn)宕機(jī)時(shí),另外兩個(gè)manager節(jié)點(diǎn)都可以正常工作,因?yàn)榇藭r(shí)可以選舉出新的Leader。
leader選舉:當(dāng)前l(fā)eader故障時(shí)必須選舉出一個(gè)新的leader。
所以,要保證集群的高可用
- 主節(jié)點(diǎn)數(shù)量必須>=3
- 主節(jié)點(diǎn)存活數(shù)量必須>=2
簡(jiǎn)單來(lái)說(shuō),Raft協(xié)議:保證大多數(shù)節(jié)點(diǎn)存活才可以使用
7.5 Swarm集群動(dòng)態(tài)擴(kuò)縮容服務(wù)
[root@localhost ~]# docker service --help Commands: create Create a new service inspect Display detailed information on one or more services logs Fetch the logs of a service or task ls List services ps List the tasks of one or more services rm Remove one or more services rollback Revert changes to a service's configuration scale Scale one or multiple replicated services update Update a service
docker service create 創(chuàng)建并運(yùn)行一個(gè)服務(wù)
[root@localhost ~]# docker service create -p 8888:80 --name myngnix ngnix
- docker run 容器,不具備擴(kuò)縮容
- docker service 服務(wù),具備擴(kuò)縮容、滾動(dòng)更新功能
docker service ls 查看服務(wù)列表
[root@localhost ~]# docker service ls ID NAME MODE REPLICAS IMAGE PORTS blkxxbxk897b myngnix replicated 1/1 ngnix:latest *:8888->80/tcp
動(dòng)態(tài)擴(kuò)縮容
docker service scale 服務(wù)名=numnum 表示擴(kuò)縮容的服務(wù)數(shù)量docker service update --replicas num 服務(wù)名num 表示擴(kuò)縮容的服務(wù)數(shù)量
[root@localhost ~]# docker service scale myngnix=5 [root@localhost ~]# docker service update --replicas 3 myngnix
兩個(gè)動(dòng)態(tài)擴(kuò)縮容命令等效。scale 方便一些
八、Docker 其他命令(了解)
8.1 Docker Stack
docker stack與 docker compose類(lèi)似
- docker compose 單機(jī)容器編排
- docker stack 集群容器編排
[root@localhost ~]# docker stack --help
Usage: docker stack [OPTIONS] COMMAND
Manage Docker stacks
Options:
--orchestrator string Orchestrator to use (swarm|kubernetes|all)
Commands:
deploy Deploy a new stack or update an existing stack
ls List stacks
ps List the tasks in the stack
rm Remove one or more stacks
services List the services in the stack8.2 Docker Secret
安全、密碼配置、證書(shū)等
[root@localhost ~]# docker secret --help Usage: docker secret COMMAND Manage Docker secrets Commands: create Create a secret from a file or STDIN as content inspect Display detailed information on one or more secrets ls List secrets rm Remove one or more secrets
8.3 Docker Config
統(tǒng)一配置
[root@localhost ~]# docker config --help Usage: docker config COMMAND Manage Docker configs Commands: create Create a config from a file or STDIN inspect Display detailed information on one or more configs ls List configs rm Remove one or more configs
到此這篇關(guān)于Docker入門(mén)與進(jìn)階(基礎(chǔ)+實(shí)戰(zhàn)+進(jìn)階+Compose+Swarm)超詳細(xì)版的文章就介紹到這了,更多相關(guān)Docker入門(mén)教程內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
docker利用WebHook實(shí)現(xiàn)持續(xù)集成
這篇文章主要介紹了docker利用WebHook實(shí)現(xiàn)持續(xù)集成的相關(guān)知識(shí),非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2018-01-01
綁定Dokcer容器到主機(jī)指定網(wǎng)卡的方法
這篇文章主要介紹了綁定 Dokcer 容器到主機(jī)指定網(wǎng)卡的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-03-03
docker部署java項(xiàng)目的詳細(xì)步驟
這篇文章主要介紹了docker部署java項(xiàng)目的詳細(xì)步驟,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2025-03-03
docker運(yùn)行PostgreSQL數(shù)據(jù)庫(kù)維護(hù)執(zhí)行腳本備份數(shù)據(jù)庫(kù)與更新表結(jié)構(gòu)的方法
這篇文章主要介紹了docker運(yùn)行PostgreSQL數(shù)據(jù)庫(kù)維護(hù),執(zhí)行腳本備份數(shù)據(jù)庫(kù)與更新表結(jié)構(gòu),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-05-05

