https://docs.docker.com/
Docker概述
Docker为什么会出现
-
开发和运维的矛盾:“在我的电脑可以运行”
-
从开发到上线,需要两套环境,不同环境都需要配置;
-
应用版本更新,导致服务不可用,对运维提出挑战;
-
环境配置非常麻烦:
-
每一台机器都要配置环境(集群 Redis, ES, Hadoop);
Docker的解决方案:
-
发布一个项目【jar】项目包含了所有依赖环境【Redis,mysql, jdk, ES】;
-
开发打包部署上线,一套流程做完,开发即运维;
apk - 发布(应用商店)- 下载、安装即可用;
jar 打包项目带上环境(镜像) - 发布(Docker仓库:商店) - 下载发布的镜像,直接可用;
Docker镜像逐渐成为了企业的交付标准
Docker的历史
2010年, 几个搞IT的年轻人, 在美国成立了一家公司 dotCloud,做一些Pass的云计算服务;
他们将自己的容器化技术命名为Docker ,Docker刚诞生的时候,没有引起行业的注意, dotCloud活不下去了就开源;
2013年,Docker开源了, 越来越多的人发现了docker的优点,Docker每个月都会更新一个版本;
2014年4月9日,Docker1.0发布;
Docker为什么这么火,因为十分轻巧, 在容器技术出来之前,都是使用的虚拟机技术;
虚拟机:在windows中使用Vmare, 通过这个软件可以虚拟出一台或者多台电脑,但是非常笨重;
虚拟机也是属于虚拟化技术,Docker使用容器技术,也是一种虚拟化技术;
Docker传送门
Docker是基于Go语言开发的
官方网站
https://www.docker.com/
官方文档
https://docs.docker.com/?_gl=1*18f27x1*_ga*MTUwNjQxMjE1OC4xNjg2NzMyODU1*_ga_XJWPQMJYHQ*MTY5MjE3MzUyNS41LjEuMTY5MjE3Mzk2Mi42MC4wLjA.
Docker Hub
https://hub.docker.com/
Docker能干嘛
虚拟机技术
虚拟机技术的缺点:
-
资源占用十分多;
-
冗余步骤多;
-
启动很慢
容器化技术
容器化技术不是模拟的一个完整的操作系统
比较Docker和虚拟机技术的不同
-
传统虚拟机,运行一个完整的操作系统,然后在这个系统上安装和运行软件;
-
容器内的应用直接运行在宿主机的内核,容器是没有自己的内核,也没有虚拟硬件,所以就轻便;
-
每个容器间是互相隔离,每个容器内都有一个属于自己的文件系统,互不影响;
DevOps(开发、运维)
-
应用更快速的交付和部署
-
传统:一堆帮助文档和安装程序;
-
Docker: 打包镜像发布测试,一键运行;
-
更便捷的升级和扩缩容
-
使用了docker之后,我们部署应用就和搭积木一样;
-
项目打包为一个镜像,做扩展的时候,直接部署到服务器A, B , C…;
-
更简单的系统运维
-
在容器化后,我们的开发,测试环境都是高度一致的;
-
更高效的计算资源利用
-
Docker是内核级别的虚拟化,可以在一个物理机上运行很多的容器实例,服务器性能可以被压榨到极致;
Docker安装
Docker的基本组成
-
客户端
-
服务器
-
远程仓库
-
镜像(image):
-
docker镜像就好比是一个模板,可以通过这个模板来创建容器服务;
-
tomcat镜像 => run => tomcat01容器,提供服务,通过这个镜像可以创建多个容器;
-
最终服务运行或者项目运行就是在容器中的;
-
容器(container):
-
Docker利用容器技术,独立运行一个或者一组应用,通过镜像来创建;
-
容器可以启动,停止,删除;
-
可以把容器理解为一个简易的linux系统
-
仓库(repository):
-
仓库就是存放镜像的地方;
-
仓库分为共有仓库和私有仓库;
环境查看
root@dev:~ # cat /etc/os-release
NAME="Ubuntu"
VERSION="16.04.7 LTS (Xenial Xerus)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 16.04.7 LTS"
VERSION_ID="16.04"
HOME_URL="http://www.ubuntu.com/"
SUPPORT_URL="http://help.ubuntu.com/"
BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"
VERSION_CODENAME=xenial
UBUNTU_CODENAME=xenial
官方安装路径
https://docs.docker.com/engine/install/ubuntu/
docker-ce:社区版本
docker-ee:企业版(没啥用)
root@dev:~ # docker version
Client:
Version: 18.03.0-ce
API version: 1.37
Go version: go1.9.4
Git commit: 0520e24
Built: Wed Mar 21 23:10:01 2018
OS/Arch: linux/amd64
Experimental: false
Orchestrator: swarm
Server:
Engine:
Version: 18.03.0-ce
API version: 1.37 (minimum version 1.12)
Go version: go1.9.4
Git commit: 0520e24
Built: Wed Mar 21 23:08:31 2018
OS/Arch: linux/amd64
Experimental: false
HelloWorld
底层原理
Docker是怎么工作的
-
Docker是一个Client-Server结构的系统, Docker的守护进程运行在主机上,通过Socket从客户端访问;
-
DockerServer接收到Docker-Client的命令,就会执行这个命令;
Docker为什么比VM快
-
Docker有比虚拟机更少的抽象层
-
Docker利用的是宿主机的内核,VM需要是Guest OS
所以说,新建一个容器的时候,docker不需要像虚拟机一样重新加载一个操作系统内核,避免引导;
-
虚拟机是加载Guest OS,需要分钟级别启动;
-
docker利用宿主机的操作系统,省略了复杂的过程,秒级启动;
Docker 常用命令
帮助命令
docker version # 显示docker的版本信息
docker info # 显示docker的系统信息, 包括镜像和容器的数量
docker 命令 --help # 万能命令
帮助文档的地址:
https://docs.docker.com/reference/
镜像命令
docker images :查看镜像
查看所有本地主机上的镜像
root@dev:~ # docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
tensorflow/serving latest 97e0a2470728 3 weeks ago 518MB
tensorflow/serving <none> 07511a317c0b 3 months ago 510MB
tensorflow/serving <none> e874bf5e4700 2 years ago 406MB
hello-world latest d1165f221234 2 years ago 13.3kB
-
REPOSITORY 镜像的仓库源
-
TAG 镜像的标签
-
IMAGE ID 镜像的ID
-
CREATE 镜像的创建时间
-
SIZE 镜像的大小
Usage: docker images [OPTIONS] [REPOSITORY[:TAG]]
List images
Options:
-a, --all Show all images (default hides intermediate images)
--digests Show digests
-f, --filter filter Filter output based on conditions provided
--format string Pretty-print images using a Go template
--no-trunc Don't truncate output
-q, --quiet Only show numeric IDs
-
-a 列出所有的镜像
-
-q 只显示镜像的id
root@dev:~ # docker images -aq
97e0a2470728
07511a317c0b
e874bf5e4700
d1165f221234
docker search:搜索镜像
root@dev:~ # docker search mysql
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
mysql MySQL is a widely used, open-source relation… 14384
mariadb MariaDB Server is a high performing open sou… 5490
phpmyadmin phpMyAdmin - A web interface for MySQL and M… 849
percona Percona Server is a fork of the MySQL relati… 620
bitnami/mysql Bitnami MySQL Docker Image 93
可选项, 通过收藏来过滤
-
--filter-STARS=3000, 搜索出来的镜像是收藏大于3000
root@dev:~ # docker search mysql --filter=STARS=3000
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
mysql MySQL is a widely used, open-source relation… 14384 [OK]
mariadb MariaDB Server is a high performing open sou… 5490 [OK]
docker pull:下载镜像
# 下载镜像 docker pull 镜像名[:tag]
如果不写tag, 默认就是latest
docker下载的时候是分层下载(相关的知识点:联合文件系统)
root@dev:~ # docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mysql latest 99afc808f15b 5 days ago 577MB
tensorflow/serving latest 97e0a2470728 3 weeks ago 518MB
tensorflow/serving <none> 07511a317c0b 3 months ago 510MB
tensorflow/serving <none> e874bf5e4700 2 years ago 406MB
hello-world latest d1165f221234 2 years ago 13.3kB
指定版本的镜像
root@dev:~ # docker pull mysql:5.7
5.7: Pulling from library/mysql
70e9ff4420fb: Pull complete
7ca4383b183f: Pull complete
3e282e7651b1: Pull complete
1ffa0e0ca707: Pull complete
6eb790cf6382: Pull complete
b4b277ff2929: Pull complete
692fe4469429: Pull complete
c0d447d97bbd: Pull complete
99ee594517ba: Pull complete
a9ae52de4d77: Pull complete
66cc05a182b5: Pull complete
Digest: sha256:2c23f254c6b9444ecda9ba36051a9800e8934a2f5828ecc8730531db8142af83
Status: Downloaded newer image for mysql:5.7
root@dev:~ # docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mysql latest 99afc808f15b 5 days ago 577MB
mysql 5.7 92034fe9a41f 13 days ago 581MB
tensorflow/serving latest 97e0a2470728 3 weeks ago 518MB
tensorflow/serving <none> 07511a317c0b 3 months ago 510MB
tensorflow/serving <none> e874bf5e4700 2 years ago 406MB
hello-world latest d1165f221234 2 years ago 13.3kB
docker rmi:删除镜像
删除镜像, 可以通过镜像的ID也可以通过镜像的名称删除
root@dev:~ # docker rmi mysql
Untagged: mysql:latest
Untagged: mysql@sha256:c0455ac041844b5e65cd08571387fa5b50ab2a6179557fd938298cab13acf0dd
Deleted: sha256:99afc808f15be15cd1d9890394123034a79d1f3204d5b417d8558990cdf30167
Deleted: sha256:4ef558dbdf981f0511214063c2f024fdc349bdfc096e1c0c5fe051df7715d3a8
Deleted: sha256:2c65961b0dc1248756315521ec79f56d5baaa6c2dde56630327f13088bdb8c48
Deleted: sha256:ef0d0e39979a8108231a1ef7b79419a76ec3b3bd4d4604b6b17d132ab39fe0db
Deleted: sha256:9cf001ade3f88ba49e7c9a3cdf74deb7dc00256921b7b90911d8db389c3b91a3
Deleted: sha256:649167b3b6547c68b0327f5eed76a5b8e1aab76a040748b16ff693c3f55d52ad
Deleted: sha256:e42aec727a07fdc663fcf11eab94a9e8357b9242ba278190544c1c42c1f7ed93
Deleted: sha256:c91f3694a10505a6c50a83511d3ae43c45858019d267c1b002bcd1b8295c9896
Deleted: sha256:7af435fc0f64d278f0567aaf575001c9952e5ed5f69d72f049c15a9e5a5b9d62
Deleted: sha256:8f5cb0ae989a7a9dd9ec73a0b48fa0c5fe9691b731f74a559ed043cf37ab2aa7
Deleted: sha256:3bf99074f96df6af6ec205f8df88af239fc48ff936c75e3af9a6a1626f22a567
root@dev:~ # docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mysql 5.7 92034fe9a41f 13 days ago 581MB
tensorflow/serving latest 97e0a2470728 3 weeks ago 518MB
tensorflow/serving <none> 07511a317c0b 3 months ago 510MB
tensorflow/serving <none> e874bf5e4700 2 years ago 406MB
hello-world latest d1165f221234 2 years ago 13.3kB
root@dev:~ # docker rmi 92034fe9a41f
Untagged: mysql:5.7
Untagged: mysql@sha256:2c23f254c6b9444ecda9ba36051a9800e8934a2f5828ecc8730531db8142af83
Deleted: sha256:92034fe9a41f4344b97f3fc88a8796248e2cfa9b934be58379f3dbc150d07d9d
Deleted: sha256:df9054037a39d9d0e98b43bbf940793c0b5bdcfa165a2895ee87b4c1dc8f362f
Deleted: sha256:8eb2c1c2676cb3cb3d1e01fada914df102cddddcd5763dce1a623b9505882f2d
Deleted: sha256:c38117f45694b767c799d7a4e3941e69f6bd05db6cbb5373126eb29842661e19
Deleted: sha256:1cf26960e390f7df8be8f0f4d23c12441b832e95ededa363c9e2eb1be4dba1bb
Deleted: sha256:c646c79ec9cf7480a2f1fc40ebda6ce1973571f3e166015f36cc7bff29d3ef2c
Deleted: sha256:13a81468adbe0652a713fea05ce7cfa6d4326f1560cd77b3b468fc9721e8a5d2
Deleted: sha256:422c4721f357ead3754ea1b3a630d5334a93db6a5d3d41642778e50194e5e9b4
Deleted: sha256:3356622c341e34d779294e5c450424a43bd6f55538a1dbbbdd30489f33315764
Deleted: sha256:10213d78b510219f6cf8e143c99d29db6ba8dc6bea318ae9c812ea5948805b39
Deleted: sha256:82afa988bdb62c2f462d0d88e709afaf7b529cc944ea5197633c875e2a70636f
Deleted: sha256:616461b0543d6905f05f2b384bc403d268886c8845a6de09629a2b022388c830
root@dev:~ # docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
tensorflow/serving latest 97e0a2470728 3 weeks ago 518MB
tensorflow/serving <none> 07511a317c0b 3 months ago 510MB
tensorflow/serving <none> e874bf5e4700 2 years ago 406MB
hello-world latest d1165f221234 2 years ago 13.3kB
删除镜像
docker rmi -f $(docker images -aq) # 删除所有镜像
docker rmi -f 镜像id # 删除指定镜像
docker rmi -f 镜像id—1 镜像id-2 镜像id-3 #删除多个镜像
容器命令
说明:我们有了镜像才可以创建容器, 下载一个centos镜像来测试学习
root@dev:~ # docker pull centos
Using default tag: latest
latest: Pulling from library/centos
a1d0c7532777: Pull complete
Digest: sha256:a27fd8080b517143cbbbab9dfb7c8571c40d67d534bbdee55bd6c473f432b177
Status: Downloaded newer image for centos:latest
root@dev:~ # docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
tensorflow/serving latest 97e0a2470728 3 weeks ago 518MB
tensorflow/serving <none> 07511a317c0b 3 months ago 510MB
centos latest 5d0da3dc9764 23 months ago 231MB
tensorflow/serving <none> e874bf5e4700 2 years ago 406MB
hello-world latest d1165f221234 2 years ago 13.3kB
docker run:新建容器并启动
docker run [可选参数] image
# 参数说明
--name="Name" 容器名字,tomcat01, tomcat02, 用来区分容器
-d 后台方式运行
-it 使用交互方式运行,进入容器查看内容
-p 置顶容器的端口, -p 8080:8080
-p 主机端口:容器端口
-p 容器端口
-p ip:主机端口:容器端口
-P 随机指定端口
-v 数据卷挂载, 可以用多个
-e 环境配置
root@dev:~ # docker run -it centos /bin/bash
# 主机名其实就是镜像ID
[root@315989e8155c /]# ls
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
# 从容器中退回主机
[root@315989e8155c /]# exit
exit
root@dev:~ # ls
anaconda3 install.jenkins.sh logtail.sh start.server.sh tomcat.ab.origin.log tomcat.ab.threads.log
dangxuan install.jenkinsuser.sh NVIDIA_CUDA-11.2_Samples temp.txt tomcat.ab.t117.log xuzijun
game-python jupyter.log recommend-python tomcat.ab.log tomcat.ab.threads2.log
-
run -d : 后台启动
docker run -d centos
# 问题docker ps 发现centos停止了
# 常见的坑, docker使用后台运行,就必须要有一个前台进程,docker发现没有应用,就会自动停止
docker ps:列出运行的容器
-
docker ps : 列出当前正在运行的容器,如果容器停了就不会展现
-
docker ps -a : 查看曾经运行过的容器
# docker ps 列出当前正在运行的容器
-a # 列出当前正在运行的容器,带出历史运行过的容器
-n=? # 显示出最近创建的容器
-q # 只显示容器的编号
exit: 退出容器
exit #直接容器停止并退出
Ctrl + P + Q #容器不停止退出
docker rm : 删除容器
docker rm 容器id # 删除指定的容器
docker rm $(docker ps -aq) # 删除所有的容器
docker ps -a -q | xargs docker rm # 删除所有的容器
不能删除正在运行的容器,如果要强制删除,rm -f
root@dev:~ # docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7242caa68ff1 centos "/bin/bash" 3 minutes ago Up 3 minutes infallible_clarke
07ef5d12ab92 tensorflow/serving "/usr/bin/tf_serving…" 3 hours ago Up 3 hours 8500/tcp, 0.0.0.0:8501->8501/tcp clever_kirch
root@dev:~ # docker rm 7242caa68ff1
Error response from daemon: You cannot remove a running container 7242caa68ff1cc012cdfc1786b7fd94220aaacdf0773c85c1f62125b8ea3bde8. Stop the container before attempting removal or force remove
root@dev:~ # docker rm -f 7242caa68ff1
7242caa68ff1
root@dev:~ # docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
07ef5d12ab92 tensorflow/serving "/usr/bin/tf_serving…" 3 hours ago Up 3 hours 8500/tcp, 0.0.0.0:8501->8501/tcp clever_kirch
docker start & stop : 启动和停止容器的操作
docker start 容器id # 启动容器
docker restart 容器id # 重启容器
docker stop 容器id # 停止当前正在运行的容器
docker kill 容器id # 杀掉容器
root@dev:~ # docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
07ef5d12ab92 tensorflow/serving "/usr/bin/tf_serving…" 3 hours ago Up 3 hours 8500/tcp, 0.0.0.0:8501->8501/tcp clever_kirch
root@dev:~ # docker start e6ee99288a9e
e6ee99288a9e
root@dev:~ # docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e6ee99288a9e centos "/bin/bash" 19 seconds ago Up 3 seconds gracious_nightingale
07ef5d12ab92 tensorflow/serving "/usr/bin/tf_serving…" 3 hours ago Up 3 hours 8500/tcp, 0.0.0.0:8501->8501/tcp clever_kirch
root@dev:~ # docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e6ee99288a9e centos "/bin/bash" About a minute ago Up About a minute gracious_nightingale
07ef5d12ab92 tensorflow/serving "/usr/bin/tf_serving…" 3 hours ago Up 3 hours 8500/tcp, 0.0.0.0:8501->8501/tcp clever_kirch
root@dev:~ # docker stop e6ee99288a9e
e6ee99288a9e
root@dev:~ # docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
07ef5d12ab92 tensorflow/serving "/usr/bin/tf_serving…" 3 hours ago Up 3 hours 8500/tcp, 0.0.0.0:8501->8501/tcp clever_kirch
docker exec: 进入当前正在运行的容器
我们容器通常都是使用后台方式运行的,需要进入容器,修改一些配置
# docker exec -it 容器id
root@dev:~ # docker exec -it 0850b7f88891 /bin/bash
[root@0850b7f88891 /]# ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 03:06 ? 00:00:00 /bin/sh -c while true;do echo ma
root 859 0 0 03:20 pts/0 00:00:00 /bin/bash
root 875 1 0 03:20 ? 00:00:00 /usr/bin/coreutils --coreutils-p
root 876 859 0 03:20 pts/0 00:00:00 ps -ef
[root@0850b7f88891 /]# exit
exit
对比一下docker run 就是新建一个容器
root@dev:~ # docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0850b7f88891 centos "/bin/sh -c 'while t…" 10 minutes ago Up 10 minutes unruffled_jepsen
07ef5d12ab92 tensorflow/serving "/usr/bin/tf_serving…" 3 hours ago Up 3 hours 8500/tcp, 0.0.0.0:8501->8501/tcp clever_kirch
root@dev:~ # docker run -it centos
[root@fd7f20ee8d6e /]# #root@dev:~ # docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
fd7f20ee8d6e centos "/bin/bash" 14 seconds ago Up 13 seconds cocky_swartz
0850b7f88891 centos "/bin/sh -c 'while t…" 11 minutes ago Up 11 minutes unruffled_jepsen
07ef5d12ab92 tensorflow/serving "/usr/bin/tf_serving…" 3 hours ago Up 3 hours 8500/tcp, 0.0.0.0:8501->8501/tcp clever_kirch
docker attach : 也是进入当前正在运行的容器
-
docker exec # 进入容器后开启一个新的终端, 可以在里面操作(常用)
-
docker attach # 进入容器正在执行的终端,不会启动新的进程;
root@dev:~ # docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0850b7f88891 centos "/bin/sh -c 'while t…" 15 minutes ago Up 15 minutes unruffled_jepsen
07ef5d12ab92 tensorflow/serving "/usr/bin/tf_serving…" 3 hours ago Up 3 hours 8500/tcp, 0.0.0.0:8501->8501/tcp clever_kirch
docker logs: 查看日志
root@dev:~ # docker logs -f -t --tail 10 e6ee99288a9e
2023-08-17T02:55:08.917130283Z [root@e6ee99288a9e /]# exit
2023-08-17T02:55:08.917202631Z exit
2023-08-17T02:56:37.405344334Z [root@e6ee99288a9e /]# exit
#显示日志
-tf #显示日志,-t是会带上时间戳
--tail number #要显示日志条数
root@dev:~ # docker run -d centos /bin/sh -c "while true;do echo maoyaozong;sleep 1;done"
0850b7f888917782634b1f75d04b92bb3fb335829296c13b1a7cd8b1b0cf664a
docker top: 查看容器中的进程信息
root@dev:~ # docker top 0850b7f88891
UID PID PPID C STIME TTY TIME CMD
root 14933 14916 0 11:06 ? 00:00:00 /bin/sh -c while true;do echo maoyaozong;sleep 1;done
root 15378 14933 0 11:10 ? 00:00:00 /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 1
docker inspect: 查看容器元信息
root@dev:~
[
{
"Id": "0850b7f888917782634b1f75d04b92bb3fb335829296c13b1a7cd8b1b0cf664a",
"Created": "2023-08-17T03:06:43.299459431Z",
"Path": "/bin/sh",
"Args": [
"-c",
"while true;do echo maoyaozong;sleep 1;done"
],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 14933,
"ExitCode": 0,
"Error": "",
"StartedAt": "2023-08-17T03:06:43.653879501Z",
"FinishedAt": "0001-01-01T00:00:00Z"
},
"Image": "sha256:5d0da3dc976460b72c77d94c8a1ad043720b0416bfc16c52c45d4847e53fadb6",
"ResolvConfPath": "/var/lib/docker/containers/0850b7f888917782634b1f75d04b92bb3fb335829296c13b1a7cd8b1b0cf664a/resolv.conf",
"HostnamePath": "/var/lib/docker/containers/0850b7f888917782634b1f75d04b92bb3fb335829296c13b1a7cd8b1b0cf664a/hostname",
"HostsPath": "/var/lib/docker/containers/0850b7f888917782634b1f75d04b92bb3fb335829296c13b1a7cd8b1b0cf664a/hosts",
"LogPath": "/var/lib/docker/containers/0850b7f888917782634b1f75d04b92bb3fb335829296c13b1a7cd8b1b0cf664a/0850b7f888917782634b1f75d04b92bb3fb335829296c13b1a7cd8b1b0cf664a-json.log",
"Name": "/unruffled_jepsen",
"RestartCount": 0,
"Driver": "overlay2",
"Platform": "linux",
"MountLabel": "",
"ProcessLabel": "",
"AppArmorProfile": "docker-default",
"ExecIDs": null,
"HostConfig": {
"Binds": null,
"ContainerIDFile": "",
"LogConfig": {
"Type": "json-file",
"Config": {}
},
"NetworkMode": "default",
"PortBindings": {},
"RestartPolicy": {
"Name": "no",
"MaximumRetryCount": 0
},
"AutoRemove": false,
"VolumeDriver": "",
"VolumesFrom": null,
"CapAdd": null,
"CapDrop": null,
"Dns": [],
"DnsOptions": [],
"DnsSearch": [],
"ExtraHosts": null,
"GroupAdd": null,
"IpcMode": "shareable",
"Cgroup": "",
"Links": null,
"OomScoreAdj": 0,
"PidMode": "",
"Privileged": false,
"PublishAllPorts": false,
"ReadonlyRootfs": false,
"SecurityOpt": null,
"UTSMode": "",
"UsernsMode": "",
"ShmSize": 67108864,
"Runtime": "runc",
"ConsoleSize": [
0,
0
],
"Isolation": "",
"CpuShares": 0,
"Memory": 0,
"NanoCpus": 0,
"CgroupParent": "",
"BlkioWeight": 0,
"BlkioWeightDevice": [],
"BlkioDeviceReadBps": null,
"BlkioDeviceWriteBps": null,
"BlkioDeviceReadIOps": null,
"BlkioDeviceWriteIOps": null,
"CpuPeriod": 0,
"CpuQuota": 0,
"CpuRealtimePeriod": 0,
"CpuRealtimeRuntime": 0,
"CpusetCpus": "",
"CpusetMems": "",
"Devices": [],
"DeviceCgroupRules": null,
"DiskQuota": 0,
"KernelMemory": 0,
"MemoryReservation": 0,
"MemorySwap": 0,
"MemorySwappiness": null,
"OomKillDisable": false,
"PidsLimit": 0,
"Ulimits": null,
"CpuCount": 0,
"CpuPercent": 0,
"IOMaximumIOps": 0,
"IOMaximumBandwidth": 0
},
"GraphDriver": {
"Data": {
"LowerDir": "/var/lib/docker/overlay2/67f004b6510be2bcb8051ebbad966f1292f73531220b422f1b8bd7a959145dba-init/diff:/var/lib/docker/overlay2/e982c1c95f5cf3e928849023b4c5c02bd0f4018255a8c026754e60e31a078fb2/diff",
"MergedDir": "/var/lib/docker/overlay2/67f004b6510be2bcb8051ebbad966f1292f73531220b422f1b8bd7a959145dba/merged",
"UpperDir": "/var/lib/docker/overlay2/67f004b6510be2bcb8051ebbad966f1292f73531220b422f1b8bd7a959145dba/diff",
"WorkDir": "/var/lib/docker/overlay2/67f004b6510be2bcb8051ebbad966f1292f73531220b422f1b8bd7a959145dba/work"
},
"Name": "overlay2"
},
"Mounts": [],
"Config": {
"Hostname": "0850b7f88891",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": [
"/bin/sh",
"-c",
"while true;do echo maoyaozong;sleep 1;done"
],
"Image": "centos",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": null,
"OnBuild": null,
"Labels": {
"org.label-schema.build-date": "20210915",
"org.label-schema.license": "GPLv2",
"org.label-schema.name": "CentOS Base Image",
"org.label-schema.schema-version": "1.0",
"org.label-schema.vendor": "CentOS"
}
},
"NetworkSettings": {
"Bridge": "",
"SandboxID": "b3e217704a8919d20b1a32c30779921e62d78952cce831659ab09bd990adefe3",
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"Ports": {},
"SandboxKey": "/var/run/docker/netns/b3e217704a89",
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "f3edea89d0d3b80acf01f659c1c764bb6b678f742baaece058ff792111cd9df9",
"Gateway": "172.17.0.1",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "172.17.0.3",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"MacAddress": "02:42:ac:11:00:03",
"Networks": {
"bridge": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"NetworkID": "915022882edaeda987987002b1d310cace261b012c201c4e9b245639e1cc7746",
"EndpointID": "f3edea89d0d3b80acf01f659c1c764bb6b678f742baaece058ff792111cd9df9",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.3",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:11:00:03",
"DriverOpts": null
}
}
}
}
]
docker cp : 从容器内拷贝文件到主机上
docker cp 容器id:容器内路径 目的地主机路径
拷贝是一个手动过程, 更好的是通过-v 数据卷的方式进行打通
![Docker 容器技术]()
Docker部署实例
部署Nginx
root@dev:~ # docker search nginx
root@dev:~ # docker pull nginx
root@dev:~ # docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest eea7b3dcba7e 18 hours ago 187MB
tensorflow/serving latest 97e0a2470728 3 weeks ago 518MB
tensorflow/serving <none> 07511a317c0b 3 months ago 510MB
centos latest 5d0da3dc9764 23 months ago 231MB
root@dev:~ # docker run -d --name nginx01 -p 3340:80 nginx
d9acd4cf581880f002490eb8b9864535d89c2c4d05d20b2d4f7a5807770b360a
root@dev:~ # docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d9acd4cf5818 nginx "/docker-entrypoint.…" 9 seconds ago Up 7 seconds 0.0.0.0:3340->80/tcp nginx01
07ef5d12ab92 tensorflow/serving "/usr/bin/tf_serving…" 4 hours ago Up 4 hours 8500/tcp, 0.0.0.0:8501->8501/tcp clever_kirch
root@dev:~ # curl localhost:3340
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<ahref="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<ahref="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
Docker 可视化
-
portainer
docker run -d -p 8088:9000 --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
Docker图形化界面管理工具,提供一个后台面板操作
https://docs.portainer.io/
Docker镜像
镜像是什么
镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,他包含运行某个软件所需的所有内容,包括代码、运行时、库、环境变量和配置文件。
Docker镜像加载原理
UnionFS(联合文件系统)
UnionFS ( 联合文件系统): 是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下。Union 文件系统是 Docker 像的基础。镜像可以通过分层来进行继承。
特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录
Docker镜像加载原理
docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统UnionFS。
-
bootfs(boot file system)主要包含bootloader和kernel, bootloader主要是引导加载kernel, Linux刚启动时会加载bootfs文件系统,在Dockeri像的最底层是bootfs。这一层与我们典型的Linux/nix系统是一样的,包含boot加载器和内核。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统也会卸载bootfs。
-
rootfs (root file system), 在bootfs之上包含的就是典型 Linux 系统中的 /dev,/proc,/bin,/etc 等标准目录和文件。rootfs就是各种不同的操作系统发行版,比如Ubuntu,Centos等等。
平时我们安装进虚拟机的CentoS都是好几个G,为什么Docker这里才200M ?
对于一个精简的OS,rootfs 可以很小,只需要包含最基本的命令,工具和程序库就可以了,因为底层直接用Host的kernel,自己只需要提供rootfs就可以了。由此可见对于不同的linux发行版,bootfs基本是一致的,rotfs会有差别,因此不同的发行版可以公用bootfs。
Docker 分层理解
我们下载一个镜像, 注意观察下载的日志输出,可以看到是一层一层的在下载,已经下载过的就不会再下载了
思考: 为什么Docker镜像要采用这种分层的结构呢
最大的好处,我觉得莫过于是资源共享了! 比如有多个镜像都从相同的Base像构建而来,那么宿主机只需在磁盘上保留一份base镜像,同时内存中也只需要加载一份base镜像,这样就可以为所有的容器服务了,而且镜像的每一层都可以被共享。
查看镜像分层的方式可以通过 docker image inspect 命令!
root~ # docker image inspect nginx :
[
{
"Id": "sha256:eea7b3dcba7ee47c0d16a60cc85d2b977d166be3960541991f3e6294d795ed24",
"RepoTags": [
"nginx:latest"
],
"RepoDigests": [
"nginx@sha256:13d22ec63300e16014d4a42aed735207a8b33c223cff19627dd3042e5a10a3a0"
],
"Parent": "",
"Comment": "",
"Created": "2023-08-16T09:50:55.765544033Z",
"Container": "50b019921f82064e1d8af7e2723929d4c5fafcfd6d8b03595711bd1e455dd3c4",
"ContainerConfig": {
"Hostname": "50b019921f82",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"ExposedPorts": {
"80/tcp": {}
},
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"NGINX_VERSION=1.25.2",
"NJS_VERSION=0.8.0",
"PKG_RELEASE=1~bookworm"
],
"Cmd": [
"/bin/sh",
"-c",
"#(nop) ",
"CMD ["nginx""-g""daemon off;"]"
],
"Image": "sha256:d59ed5fe14c2a306f94488f41ddc8fb060312ee31997f5e077a4c4b29b19114e",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": [
"/docker-entrypoint.sh"
],
"OnBuild": null,
"Labels": {
"maintainer": "NGINX Docker Maintainers <[email protected]>"
},
"StopSignal": "SIGQUIT"
},
"DockerVersion": "20.10.23",
"Author": "",
"Config": {
"Hostname": "",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"ExposedPorts": {
"80/tcp": {}
},
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"NGINX_VERSION=1.25.2",
"NJS_VERSION=0.8.0",
"PKG_RELEASE=1~bookworm"
],
"Cmd": [
"nginx",
"-g",
"daemon off;"
],
"Image": "sha256:d59ed5fe14c2a306f94488f41ddc8fb060312ee31997f5e077a4c4b29b19114e",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": [
"/docker-entrypoint.sh"
],
"OnBuild": null,
"Labels": {
"maintainer": "NGINX Docker Maintainers <[email protected]>"
},
"StopSignal": "SIGQUIT"
},
"Architecture": "amd64",
"Os": "linux",
"Size": 186639842,
"VirtualSize": 186639842,
"GraphDriver": {
"Data": {
"LowerDir": "/var/lib/docker/overlay2/d745cef5963eb1b97431486b30dd71b2605a380faba47690838107b3c4ba2630/diff:/var/lib/docker/overlay2/f5e313e6f689f2f9c1fa159b138722b9739a2de4d0a4c93449900387e7d8555e/diff:/var/lib/docker/overlay2/bfc2a784caec1d2b3a17b56679f7111bccb3f4b297e772af91ce1023f7cf5488/diff:/var/lib/docker/overlay2/00cdcd19f2471b5176a7f63b0bf41fc9a01322b25375675a2dc21decb9153ae1/diff:/var/lib/docker/overlay2/4145b85df78cb19147ad122bb6f2f1314b60d28ad1c459cfaec53587fa3c8131/diff:/var/lib/docker/overlay2/9024483c771500047fbde0bee5f5d356568fdec7c09d018a1bf0d7c01148b3c5/diff",
"MergedDir": "/var/lib/docker/overlay2/703253eda4146f25fd4689a106743bc91d0d435314cb210f8a6f35c988e60843/merged",
"UpperDir": "/var/lib/docker/overlay2/703253eda4146f25fd4689a106743bc91d0d435314cb210f8a6f35c988e60843/diff",
"WorkDir": "/var/lib/docker/overlay2/703253eda4146f25fd4689a106743bc91d0d435314cb210f8a6f35c988e60843/work"
},
"Name": "overlay2"
},
"RootFS": {
"Type": "layers",
"Layers": [
"sha256:511780f88f80081112aea1bfdca6c800e1983e401b338e20b2c6e97f384e4299",
"sha256:4713cb24eeff341d0c36343149beba247572a5ff65c2be5b5d9baafb345c7393",
"sha256:d0a62f56ef413f60049bc87e43e60032b2a2ab8d931e15b86ee0286c85ae91a2",
"sha256:8a7e12012e6f60450e6d2d777b2a2c2256d34a0ccd84d605f72cc5329a87c8b8",
"sha256:e161c3f476b5199ab13856c7e190ed12a6562b7be059c7026ae9f594e1abbcaf",
"sha256:6fb960878295b567d25900b590157b976d080340caeaa8bf8c46d38c01b4537d",
"sha256:563c64030925e9016a2329d3a2b7d47b0c90931baf5d2d0aa926c4c8d94ab894"
]
},
"Metadata": {
"LastTagTime": "0001-01-01T00:00:00Z"
}
}
]
可以看到所有的层
理解
所有的 Docker 镜像都起始于一个基础镜像层,当进行修改或增加新的内容时,就会在当前镜像层之上,创建新的镜像层.
举一个简单的例子,假如基于 Ubuntu Linux 16.04 创建一个新的像,这就是新像的第一层如果在该像中添加 Pvthon包就会在基础镜像层之上创建第二个镜像层;如果继续添加一个安全补丁,就会创建第三个镜像层.该镜像当前已经包合3 个镜像层,如下图所示(这只是一个用于演示的很简单的例子)。
在添加额外的镜像层的同时,镜像始终保持是当前所有镜像的组合,理解这一点非常重要。下图中举了一个简单的例子,每个镜像层包含 3 个文件,而镜像包含了来自两个镜像层的 6 个文件。
Docker 通过存储引擎(新版本采用快照机制 的方式来实现像层堆栈,并保证多像层对外展示为统一的文件系统.
Linux 上可用的存诸引擎有 AUFS、Overlay2、 Device Mapper、 Btrfs 以及 ZFS顾名思义,每种存储引擎都基于 Linux 中对应的文件系统或者块设备技术,并且每种存储引擎都有其独有的性能特点。
Docker 在 Windows 上仅支持 windowsfilter -种存储引擎,该引擎基于 NTFS 文件系统之上实现了分层和 CoW[1]。
下图展示了与系统显示相同的三层镜像。所有镜像层堆叠并合并,对外提供统一的视图。
Docker镜像都是只读的,当容器启动时,一个新的可写层被加载到镜像的顶部, 这一层就是我们通常说的容器层,容器之下的都叫镜像层!
所有的操作都是基于容器层的。
Commit镜像
docker commit
docker commit 提交容器成为一个新的副本
docker commit -m="提交的描述信息" -a="作者" 容器id 目标镜像名
root@dev:~ # docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9714036cd5ff portainer/portainer "/portainer" About an hour ago Up About an hour 8000/tcp, 9443/tcp, 0.0.0.0:8088->9000/tcp dreamy_mestorf
d9acd4cf5818 nginx "/docker-entrypoint.…" 3 hours ago Up 3 hours 0.0.0.0:3340->80/tcp nginx01
07ef5d12ab92 tensorflow/serving "/usr/bin/tf_serving…" 7 hours ago Up 7 hours 8500/tcp, 0.0.0.0:8501->8501/tcp clever_kirch
root@dev:~ # docker commit -m "测试commit" -a="myz" d9acd4cf5818 nginx:1.0
sha256:d93c5436de5dc26f97aa9cedefa833bd6d519c3159fbd41f05424c33515bcf79
root@dev:~ # docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx 1.0 d93c5436de5d 13 seconds ago 187MB
tomcat latest 6adff26d17ba 13 hours ago 426MB
nginx latest eea7b3dcba7e 21 hours ago 187MB
tensorflow/serving latest 97e0a2470728 3 weeks ago 518MB
tensorflow/serving <none> 07511a317c0b 3 months ago 510MB
portainer/portainer latest 5f11582196a4 8 months ago 287MB
centos latest 5d0da3dc9764 23 months ago 231MB
tensorflow/serving <none> e874bf5e4700 2 years ago 406MB
hello-world latest d1165f221234 2 years ago 13.3kB
总结:
我们要打一个自己的镜像:1、下载要用的镜像,变成自己的容器,在容器中安装各种软件;2、从容器中commit ;
实战案例:
1、启动一个默认的tensorflow;
2、发现这个默认的tensorflow没有sklearn , 没有gensim, 没有pandas;
3、我们根据这个镜像启动一个容器;
4、我们往这个容器里头各种安装软件, 并且把我们自己的代码封装成库放到容器里;
5、将我们修改过的容器通过commit提交为一个镜像,比如4fun-recommend;
6、后续其他地方要用的时候,直接从4fun-recommend开启容器,并且所有环境都安装好了!!!
对于稳定的服务,极大的标准化和省略了安装配置的工作
容器数据卷
什么是容器数据卷
docker的理念
将应用和环境打包成一个镜像,那么数据怎么办,如果数据都在容器中,那么删除容器,数据就会丢失,需求:数据可以持久化
容器之间可以有一个数据共享的技术,Docker容器中产生的数据,同步到本地
这就是容器数据卷,目录的挂载,将我们容器内的目录,挂载到本地。
总结一句话:容器的持久化和同步操作,容器间也可以数据共享
使用数据卷
使用命令来挂载 -v
docker run -it -v 主机目录:容器内目录
root@dev:/home/maoyaozong # docker run -it -v /home/maoyaozong:/home centos /bin/bash
[root@9a627f0d4046 /]# ls
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
[root@9a627f0d4046 /]# cd /home
[root@9a627f0d4046 home]# ls
recommend-python
[root@9a627f0d4046 home]# touch test.java
[root@9a627f0d4046 home]# ls
recommend-python test.java
root@dev:/home/maoyaozong # ll
total 4.0K
drwxr-xr-x 9 root root 4.0K Jul 18 2022 recommend-python
root@dev:/home/maoyaozong # ls
recommend-python test.java
docker run -it -v /home/maoyaozong:/home centos /bin/bash
Source: 主机内地址
Destination : docker容器内地址
root@dev:/home/maoyaozong # touch test1.java
[root@9a627f0d4046 home]# ls
recommend-python test.java test1.java
就算是关掉了容器, 如果在本机继续修改目录, 重新启动容器,数据一样会同步
1、 CentOS已经没有运行了
root@dev:/home/maoyaozong # docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9714036cd5ff portainer/portainer "/portainer" 2 hours ago Up 2 hours 8000/tcp, 9443/tcp, 0.0.0.0:8088->9000/tcp dreamy_mestorf
d9acd4cf5818 nginx "/docker-entrypoint.…" 5 hours ago Up 5 hours 0.0.0.0:3340->80/tcp nginx01
07ef5d12ab92 tensorflow/serving "/usr/bin/tf_serving…" 8 hours ago Up 8 hours 8500/tcp, 0.0.0.0:8501->8501/tcp clever_kirch
2、在主机新加一个文件
root@dev:/home/maoyaozong # touch test2.java
3、重启容器并查看
root@dev:/home/maoyaozong # docker start 9a627f0d4046
9a627f0d4046
root@dev:/home/maoyaozong # ls
recommend-python test1.java test2.java test.java
我们的配置和数据,都可以挂载出来,后续在主机进行修改就不需要重启docker
具名和匿名挂载
匿名挂载
# 匿名挂载
-v 容器内路径
docker run -d -P --name nginx02 -v /etc/nginx nginx
#-P 是随机映射端口
root@dev:/home/maoyaozong # docker run -d -P --name nginx02 -v /etc/nginx nginx 125 ↵
4862fd444c261f2b1bee7c5e7e6f964a0672ce295292ce291b66e170888e55e8
root@dev:/home/maoyaozong # docker volume ls
DRIVER VOLUME NAME
local 2607062efba488ea3abafffdbf2fa3b5e04d7d7bdb8cf9c813261562aed1adee
local e50d3a028a9f57a8512695e0cd71ad6b2eb2e6308f86359bca6b973e6b63d5f9
docker volume ls: 查看所有volume 本地的挂载
因为我们在 -v 的时候只写了容器内的路径,没有写容器外的路径
具名挂载
通过 -v 卷名:容器内路径
root@dev:/home/maoyaozong # docker run -d -P --name nginx03 -v have-name-nginx:/etc/nginx nginx
84fe15fee4117ccce7f817eb7fc525fe2db845df84d19d90c7addffe2403e623
root@dev:/home/maoyaozong # docker volume ls
DRIVER VOLUME NAME
local 2607062efba488ea3abafffdbf2fa3b5e04d7d7bdb8cf9c813261562aed1adee
local e50d3a028a9f57a8512695e0cd71ad6b2eb2e6308f86359bca6b973e6b63d5f9
local have-name-nginx
查看卷的挂载
root@dev:/home/maoyaozong # docker volume inspect have-name-nginx
[
{
"CreatedAt": "2023-08-17T16:39:53+08:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/have-name-nginx/_data",
"Name": "have-name-nginx",
"Options": {},
"Scope": "local"
}
]
所有docker容器内的卷,没有指定目录的情况下都是在/var/lib/docker/volumes/xxxxx
root@dev:/home/maoyaozong # cd /var/lib/docker
root@dev:/var/lib/docker # ls
builder containerd containers image network overlay2 plugins runtimes swarm tmp trust volumes
root@dev:/var/lib/docker # cd volumes
root@dev:/var/lib/docker/volumes # ll
total 36K
drwxr-xr-x 3 root root 4.0K Aug 17 14:12 2607062efba488ea3abafffdbf2fa3b5e04d7d7bdb8cf9c813261562aed1adee
drwxr-xr-x 3 root root 4.0K Aug 17 16:33 e50d3a028a9f57a8512695e0cd71ad6b2eb2e6308f86359bca6b973e6b63d5f9
drwxr-xr-x 3 root root 4.0K Aug 17 16:39 have-name-nginx
-rw------- 1 root root 32K Aug 17 16:39 metadata.db
root@dev:/var/lib/docker/volumes # cd have-name-nginx
root@dev:/var/lib/docker/volumes/have-name-nginx # ll
total 4.0K
drwxr-xr-x 3 root root 4.0K Aug 17 16:39 _data
root@dev:/var/lib/docker/volumes/have-name-nginx # cd _data
root@dev:/var/lib/docker/volumes/have-name-nginx/_data # ll
total 28K
drwxr-xr-x 2 root root 4.0K Aug 17 16:39 conf.d
-rw-r--r-- 1 root root 1007 Aug 16 01:03 fastcgi_params
-rw-r--r-- 1 root root 5.3K Aug 16 01:03 mime.types
lrwxrwxrwx 1 root root 22 Aug 16 02:48 modules -> /usr/lib/nginx/modules
-rw-r--r-- 1 root root 648 Aug 16 02:48 nginx.conf
-rw-r--r-- 1 root root 636 Aug 16 01:03 scgi_params
-rw-r--r-- 1 root root 664 Aug 16 01:03 uwsgi_params
我们通过具名挂载可以方便的找到我们的卷,大多数情况下最好使用具名挂载
如何确定是具名挂载还是匿名挂载还是指定路径挂载
-v 容器内路径 #匿名挂载
-v 卷名:容器内路径 # 具名挂载
-v /主机路径: 容器内路径 # 指定路径挂载
拓展:
ro, rw改变读写权限
ro readonly #只读, 就说明这个路径只能通过宿主机来操作,容器内部是无法操作的
rw readwrite #可读可写
一旦这个设置了容器权限,容器对我们挂载出来的内容就有限定了
docker run -d -P --name nginx03 -v have-name-nginx:/etc/nginx:ro nginx
docker run -d -P --name nginx03 -v have-name-nginx:/etc/nginx:rw nginx
--volumes-from: 容器数据同步
-
首先启动一个父容器命名为test01
root@dev:/home/maoyaozong # docker run -it --name=test01 maoyaozong-centos2:1.0
[root@47f5939e87a5 /]# #root@dev:/home/maoyaozong # docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
47f5939e87a5 maoyaozong-centos2:1.0 "/bin/sh -c /bin/bash" 6 seconds ago Up 5 seconds test01
-
再启动一个子容器挂载到test01
root@dev:/home/maoyaozong # docker run -it --name=test02 --volumes-from test01 maoyaozong-centos2:1.0
[root@1793455bbad3 /]# ls -l
total 56
lrwxrwxrwx 1 root root 7 Nov 3 2020 bin -> usr/bin
drwxr-xr-x 5 root root 360 Aug 17 09:37 dev
drwxr-xr-x 1 root root 4096 Aug 17 09:37 etc
drwxr-xr-x 2 root root 4096 Nov 3 2020 home
lrwxrwxrwx 1 root root 7 Nov 3 2020 lib -> usr/lib
lrwxrwxrwx 1 root root 9 Nov 3 2020 lib64 -> usr/lib64
drwx------ 2 root root 4096 Sep 15 2021 lost+found
drwxr-xr-x 2 root root 4096 Nov 3 2020 media
drwxr-xr-x 2 root root 4096 Nov 3 2020 mnt
drwxr-xr-x 2 root root 4096 Nov 3 2020 opt
dr-xr-xr-x 418 root root 0 Aug 17 09:37 proc
dr-xr-x--- 2 root root 4096 Sep 15 2021 root
drwxr-xr-x 11 root root 4096 Sep 15 2021 run
lrwxrwxrwx 1 root root 8 Nov 3 2020 sbin -> usr/sbin
drwxr-xr-x 2 root root 4096 Nov 3 2020 srv
dr-xr-xr-x 13 root root 0 Aug 17 09:21 sys
drwxrwxrwt 7 root root 4096 Sep 15 2021 tmp
drwxr-xr-x 12 root root 4096 Sep 15 2021 usr
drwxr-xr-x 20 root root 4096 Sep 15 2021 var
drwxr-xr-x 2 root root 4096 Aug 17 09:36 volume01
drwxr-xr-x 2 root root 4096 Aug 17 09:36 volume02
-
进入test01容器,在volume01中新建文件
root@dev:/home/maoyaozong/docker-test-volume # docker attach test01
drwxr-xr-x 2 root root 4096 Aug 17 09:36 volume02
[root@47f5939e87a5 /]# cd volume01
[root@47f5939e87a5 volume01]# ls
[root@47f5939e87a5 volume01]# touch xxxxxxxxxxxxx.java
-
在test02容器里,查看volume01中是否有新文件
[ ]
[ ]
xxxxxxxxxxxxx.java
-
test01相当于java中的父类, test02通过volumes-from继承了test01 , 也称为数据卷容器;
-
如果在新建一个test03, 挂载了test01 , 那么三个容器之间的数据都是共享的;
-
修改test01, test02, test03 任何一个数据都是实现同步;
-
即使删除test01, 保存在test02, test03的数据不会丢失,只要有一个容器还在就行;
结论:
-
容器之间配置信息的传递,数据卷容器的生命周期一直持续到没有容器使用位置。
-
但是一旦持久化到了本地,这个时候,本地的数据是不会删除的。
原文始发于微信公众号(风物长宜 AI):Docker 容器技术
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论