Docker镜像讲解
镜像是什么
镜像是一种轻量级,可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码,运行时,库,环境变量和配置文件。
所有的应用,直接打包docker镜像,就可以直接跑起来
如何得到镜像:
(1)从远程仓库下载
(2)朋友拷贝给你
(3)自己制作一个镜像DockerFile
Docker镜像加载原理
UnionFS(联合文件系统)
我么下载的时候看到的一层层的就是这个
UnionFS( 联合文件系统):Union文件系统(UnionFs ) 是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下/unite severaldiretories into a single virtualfilesystem)。Union 文件系统是 Docker 镜像的基础。镜像可以通过分层来进行继承,基于基础像( 没有像 ,可以制作各种具体的应用镜像。
特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录
Docker镜像加载原理
docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统UnionFS.
bootfs(boot file system)主要包含bootloader和kernel, bootloader主要是引导加载kernel, Linux刚启动时会加载bootfs文件系统,在Docker像的最底层是bootfs。这一与我们典型的Linux/Ux系统是一样的,包含boot加载聚和内核。当bot加载完成之后整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统也会卸载bootfs.
rootfs(root fle svstem),在bootfs之上,包合的就是典型 Linux 系统中的 /dey,/proc,/bin,/etc 等标准目录和文件。rootfs就是各种不同的操作系统发行版,比如ubuntu,Centos等等
平时我们安装的虚拟机的Centos都是好几个G,为什么Docker这里才200M
对于一个精简的OS,rootfs 可以很小,只需要包含最基本的命令,工具和程序库就可以了,因为底层直接用Host的kernel,自己只需要提供rootfs就可以了。由此可见对于不同的linux发行版,bootfs基本是一致的,rootfs会有差别,因此不同的发行版可以公用bootfs。
分层理解
分层的镜像
我们可以下载一个镜像,注意观察下载的日志输出,可以看到的是一层层的在下载
理解:
所有的 Docker 镜像都起始于一个基础镜像层,当进行修改或增加新的内容时,就会在当前镜像层之上,
举一个简单的例子,假如基于 Ubuntu Linux 16.04 创建一个新的像,这就是新镜像的第一层;如果在该镜像中添加 Python包,就会在基础镜像层之上创建第二个镜像层,如果继续添加一个安全补丁,就会创建第三个镜像层该镜像当前已经包含 3 个镜像层,
如下图所示(这只是一个用于演示的很简单的例子)。
在添加额外的镜像层的同时,镜像始终保持是当前所有镜像的组合,理解这一点非常重要。下图举了一个简单的例子,每个镜像层包含3个文件,而江西包含了来自俩个镜像层的6个文件
上图中的镜像层跟之前图中的略有区别,主要目的是便于展示文件
下图中展示了一个稍微复杂的三层像,在外部看来整个镜像只 6 个文件,这是因为最上层中的文件 7是文件 5 的一个更新版本。
这种情况下,上层镜像层中的文件覆盖了底层镜像层中的文件。这样就使得文件的更新版本作为一个新镜像层添加到镜像当中。
Docker 通过存储引擎(新版本采用快照机制 )的方式来实现镜像层堆栈,并保证多镜像层对外展示为统一的文件系统。
Linux 上可用的存储引擎有AUFS、Overlay2、Device Mapper、Btrfs 以及ZFS。顾名思义,每种存储引擎都基于 Linux 中对应的文件系统或者块设备技术,并且每种存储引擎都有其独有的性能特点。
Docker 在 Windows 上仅支持 windowsfilter 一种存储引擎,该引擎基于 NTFS 文件系统之上实现了分层和 CoW[1].
下图展示了与系统显不5同的三层镜像。所有镜像层堆叠并合并,对外提供统一的视图.
特点
Dokcer镜像都是只读的,当容器启动时,一个新的可写层被加载到镜像的顶部。
这一层就是我们通常说的容器层,容器执行的都叫镜像层
如何提交一个自己的镜像
commit镜像
docker commit 提交容器成为一个新的副本
#命令和git原理相似
docker commit -m=“提交的描述信息” -a=“作者” 容器id 目标镜像名:[TAG]
实战测试
#1,启动一个tomcat
docker run -it -p 8080:8080 tomcat
#2.发现这个tomcat是没有webapps应用,镜像的原因,官方的镜像默认webapps下面是没有文件的
#3,我们自己拷贝进去
docker exec -it 49ebb06d49a9 /bin/bash
cp -r webapps.dist/* webapps
#4,将我们操作过的容器通过commit提交为一个镜像,我们以后就使用我们修改过的镜像即可,这是我们自己修改的镜像
docker ps
docker commit -a="xiao" -m="add webapps app" 49ebb06d49a9 tomcat02:1.0
如果以后想要保存当前容器的状态,就可以通过commit来提交,获得一个镜像,
相当于虚拟机的快照。
容器数据卷
什么是容器数据卷
docker回顾
将应用和环境打包成一个镜像!
如果数据都在容器内,我们不小心将容器删除,那么数据就会丢书!需求:数据持久化
MySQL,容器删了,删库跑路!需求:MySQL数据可以存储在本地!
容器之间可以有一个数据共享的技术!Docker容器中产生的数据,同步到本地!
这就是卷技术,目录的挂载,将我们容器内的目录,挂载到Linux上面!
总结:容器的持久化和同步操作!容器间也是可以数据共享的
使用数据集
方式一:直接使用命令来挂载 -v
docker run -it -v 主机目录:容器内目录
#测试
docker run -it -v /home/ceshi:/home centos /bin/bash
#挂载之后,俩个目录中的数据会同步
#启动之后,可以使用docker inspect 容器id来查看
#测试同步
再来测试
1,退出停止容器
2,修改主机上的文件
3,启动容器
4,进入容器内查看文件
好处:我们以后修改只需要在本地修改即可,容器内会自动同步
实战:安装MySQL
思考:MySQL的数据持久化的问题
#1,查找MySQL镜像
docker search mysql
#2,下载MySQL
docker pull mysql:5.7
#3,运行容器,需要数据挂载 #安装启动MySQL,需要配置密码,注意!!!
-d 后台运行
-p 端口映射
-v 数据卷挂载
-e 环境配置
--name 容器名字
docker run -d -p 3310:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123.com --name mysql01 mysql:5.7
假设我们将容器删除
发现,我们挂载到本地的数据卷依旧没有丢失,这就实现了容器数据持久化功能
具名和匿名挂载
#匿名挂载
-v 容器内路径
docker run -d -P --name nginx01 -v /etc/nginx nginx
#查看所有的卷情况
[root@server3 ~]# docker volume ls
local 5d0203e5bd51a7ec9e6ee66b2a08d4fcc45f298d6ec948191f39f247057aebc9
#这里发现,这种就是匿名挂载,我们在-v只写了容器内的路径,没有写容器外的路径
#具名挂载
[root@server3 home]# docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx
[root@server3 home]# docker volume ls
DRIVER VOLUME NAME
local juming-nginx
#通过-v 卷名:容器内路径
#查看一下这个卷
所有的docker容器内的卷,没有指定目录的情况下都在:/var/lib/docker/volumes/xxxx/_data
我们通过具名挂载可以方便找到我们的一个卷,大多数情况下在使用的是具名挂载
#如何确定是具名挂载还是匿名挂载,还是指定路径挂载!
-v 容器内路径 #匿名挂载
-v 卷名:容器内路径 #具名挂载
-v /宿主机路径:容器内路径 #指定路径挂载
拓展:
#通过-v 容器内路径:ro rw 改变读写权限
ro readonly #只读
rw readwrite #可读可写
#一旦这个设置了容器权限,容器对我们挂载出来的内容就有限定了
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:ro nginx
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:rw nginx
#ro 只要看到ro就说明这个路径只能通过宿主机来操作,容器内部是无法操作的
初始Dockefile
Dockerfile就是用来构建docker镜像的构建文件!命令脚本!
通过这个脚本可以生成镜像,镜像是一层
#创建一个dockerfile文件,名字随意
#[root@server3 docker-test-volume]# pwd
/home/docker-test-volume
#[root@server3 docker-test-volume]# vim dockerfile1
#文件的内容 指令(大写) 参数
FROM centos
VOLUME ["volume01","volume02"]
CMD echo "----end-----"
CMD /bin/bash
#这里的每个命令,就是镜像的一层
#运行
docker build -f ./dockerfile1 -t xiao/centos .
#启动自己生成的容器
docker run -it 5c7b97318f1d /bin/bash
这个卷和外部一定有一个
查看一下卷挂载的路径
docker inspect cb59d9df13e3
测试一下刚才的文件是否同步出去了
这种方式使用的十分多,因为通常会构建自己的镜像
假设构建镜像时候没有挂载卷,要手动镜像挂载 -v 卷名:容器内陆
数据卷容器
多个MySQL同步数据
#启动3个容器,通过我们刚才自己的写镜像启动
我们在docker01中的volume01中创建数据,看看docker02中有没有
#切入docker01中
docker ps
docker attach 19313ef46034
#创建数据
cd volume01
touch docker01
#进入docker02中查看
#测试,可以删除docker01,查看docker02和docker03是否还可以访问这个文件
#测试依旧可以访问
多个MySQL实现数据共享
#docker run -d -p 3310:3306 -v /etc/mysql/conf.d -v /var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7
#docker run -d -p 3310:3306 -e MYSQL_ROOT_PASSWORD=123456 --name mysql02 --volumes-form mysql101 mysql:5.7
#这个时候,可以实现俩个容器数据同步
结论:
容器之间配置信息的传递,数据卷容器的生命周期一致持续到没容器使用为止。
但是一旦你持久化到了本地,这个时候,本地的数据是不会删除的!
DockerFile
DockerFile介绍
dockerfile是用来构建docker镜像的文件!命令参数脚本!
构建步骤:
1,编写一个dockerfile文件
2,docker build构成成为一个镜像
3,docker run运行进行
4,docker push发布镜像(DockerHub,阿里云镜像仓库!)
查看官方是怎么做的
很多官方镜像都是基础包,很多功能没有,我们通常会自己搭建自己的镜像
官方既然可以制作镜像,那么我们也可以
DockerFile构建过程
基础知识:
1,每个保留关键字(指令)都是必须是大写字母
2,执行从上到下顺序执行
3,#表示注释
4,每一个指令都会创建提交一个,并提交
dockerfile是面向开发的,以后要发布项目,做镜像,就需要编写dockerfile文件,这个文件十分简单!
Docker镜像逐渐成为了企业交付的标准
DockerFile:构建文件,定义了一切的步骤,源代码
Dockerimages:通过DockerFile构建生成的镜像,最终发布和运行的产品
Docker容器:容器就是镜像运行起来提供服务
DockerFile指令
FROM # 基础镜像,一切从这里开始构建
MAINTAINER # 镜像是谁写的,姓名+邮箱
RUN # 镜像构建的时候需要运行的命令
ADD # 步骤:tomcat镜像,这个tomcat压缩包!添加内容
WORKDIR # 镜像的工作目录
VOLUME # 挂载的目录
EXPOSE # 暴露端口配置
CMD # 指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替代
EXTRYPOINT # 指定这个容器启动的时候要运行的命令,可以追加命令
ONBUILD # 当构建一个被继承 DockerFile这个时候会执行ONBUILD的指令
COPY # 类似ADD,将我们文件拷贝到镜像中
ENV # 构建的时候设置环境变量
实战测试
Docker Hub中99%镜像都是从这个基础镜像过来的 FROM scrath,然后配置需要的软件和配置进行构建
创建一个自己的centos
#1, 编写DockerFile文件
[root@server3 home]# mkdir dockerfile
[root@server3 home]# cd dockerfile/
[root@server3 dockerfile]# vim mydockerfile-centos
[root@server3 dockerfile]# cat mydockerfile-centos
FROM centos
MAINTAINER xiao<[email protected]>
ENV MYPATH /usr/local
WORKDIR $MYPATH
RUN sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-*
RUN sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-*(sed这俩条必须加上,要不安装vim会报错)
RUN yum makecache
RUN yum -y install vim
RUN yum -y install net-tools
EXPOSE 80
CMD echo $MYPATH
CMD echo "-----构建完毕-----"
CMD /bin/bash
#2,通过这个文件构建镜像
#命令 docker build -f dockerfile文件路径 -t 镜像名:[版本号]
docker build -f mydockerfile-centos -t mycentos:0.1 .
#3,测试运行
docker images
docker run -it mycentos:0.1
#发现直接到了我们定义的工作目录,而且ifconfig命令可以用了
对比:之前原生的centos
我们可以列出本地进行的变更历史
我们平时拿到一个镜像,可以研究一下它是怎么做的?
命令是:docker history 镜像id
CMD 和 ENTRYPOINT区别
CMD #指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替代
ENTRYPOINT #指定这个容器启动的时候要运行的命令,可以追加命令
测试cmd
#编写dockerfile文件
[root@server3 dockerfile]# vim dockerfile-cmd
FROM centos
CMD ["ls","-a"]
#构建镜像
[root@server3 dockerfile]# docker build -f dockerfile-cmd -t cmd .
#run运行,发现我们的ls -a命令生效
[root@server3 dockerfile]# docker run b86b1763e009
.
..
.dockerenv
bin
dev
etc
home
lib
lib64
#想追加一个命令-l ls -al
[root@server3 dockerfile]# docker run b86b1763e009 -l
docker: Error response from daemon: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: exec: "-l": executable file not found in $PATH: unknown.
#cmd的清洗了 -l 替换了CMD ["ls","-a"]命令,-l不是命令所以报错
测试ENTRYPOINT
[root@server3 dockerfile]# vim dockerfile-ENTRYPOINT
[root@server3 dockerfile]# cat dockerfile-ENTRYPOINT
FROM centos
ENTRYPOINT ["ls","-a"]
[root@server3 dockerfile]# docker build -f dockerfile-ENTRYPOINT -t entorypoint .
[root@server3 dockerfile]# docker run 82b255a00e
.
..
.dockerenv
bin
dev
etc
home
lib
lib64
lost+found
media
mnt
opt
proc
#我们的追加命令,是直接衔接我们的 ENTRYPOINT 命令后面的
[root@server3 dockerfile]# docker run 82b255a00e -l
total 0
drwxr-xr-x. 1 root root 6 Apr 28 08:11 .
drwxr-xr-x. 1 root root 6 Apr 28 08:11 ..
-rwxr-xr-x. 1 root root 0 Apr 28 08:11 .dockerenv
lrwxrwxrwx. 1 root root 7 Nov 3 2020 bin -> usr/bin
drwxr-xr-x. 5 root root 340 Apr 28 08:11 dev
drwxr-xr-x. 1 root root 66 Apr 28 08:11 etc
drwxr-xr-x. 2 root root 6 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 6 Sep 15 2021 lost+found
drwxr-xr-x. 2 root root 6 Nov 3 2020 media
drwxr-xr-x. 2 root root 6 Nov 3 2020 mnt
drwxr-xr-x. 2 root root 6 Nov 3 2020 opt
dr-xr-xr-x. 238 root root 0 Apr 28 08:11 proc
dr-xr-x---. 2 root root 162 Sep 15 2021 root
drwxr-xr-x. 11 root root 163 Sep 15 2021 run
lrwxrwxrwx. 1 root root 8 Nov 3 2020 sbin -> usr/sbin
drwxr-xr-x. 2 root root 6 Nov 3 2020 srv
dr-xr-xr-x. 13 root root 0 Apr 16 16:48 sys
drwxrwxrwt. 7 root root 171 Sep 15 2021 tmp
drwxr-xr-x. 12 root root 144 Sep 15 2021 usr
drwxr-xr-x. 20 root root 262 Sep 15 2021 var
Dockerfile中很多命令都十分相似,要主要它们的区别
实战:Tomcat镜像
1,准备镜像文件 tomcat 压缩包,jdk的压缩包
2,编写dockerfile文件,官方命名:Dockerfile,build会自动寻找这个文件,就不需要-f指定了
#vim Dockerfile
FROM centos
MAINTAINER xiao<[email protected]>
COPY readme.txt /usr/local/readme.txt
ADD jdk-8u91-linux-x64.tar.gz /usr/local/
ADD apache-tomcat-8.5.16.tar.gz /usr/local/
RUN sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-*
RUN sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-*
RUN yum makecache
RUN yum -y install vim
ENV MYPATH /usr/local
WORKDIR $MYPATH
ENV JAVA_HOME /usr/local/jdk1.8.0_91
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-8.5.16
ENV CATALINA_BASH /usr/local/apache-tomcat-8.5.16
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
EXPOSE 8080
CMD /usr/local/apache-tomcat-8.5.16/bin/startup.sh && tail -F /usr/local/apache-tomcat-8.5.16/bin/logs/catalina.out
3,构建镜像
#docker build -t diytomcat .
4,启动镜像,并挂载tomcat的站点目录和日志
docker images
docker run -d -p 9090:8080 --name xiaotomcat -v /home/tomcat/test:/usr/local/apache-tomcat-8.5.16/webapps/test -v /home/tomcat/logs/:/usr/local/apache-tomcat-8.5.16/logs diytomcat
5,访问测试
6,发布项目(由于做了卷挂载,我们直接在本地编写项目就可以发布了)
#切换到和tomcat站点目录互相挂载的目录
cd /home/tomcat/test/
#编写页面
cat index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<body>
<h2>Hello Xiao!</h2>
</body>
</html>
#访问http://192.168.10.4:9090/test/进行测试
发布自己的镜像
DockerHub
1,地址https://hub.docker.com/ 注册自己的账户
2,在服务器上提交自己的镜像
[root@server3 test]# docker login --help
Usage: docker login [OPTIONS] [SERVER]
Log in to a 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
[root@server3 test]# docker login -u xiao1226
3,登录完毕之后,就可以提交镜像了,就是一步 docker push
# push自己的镜像到服务器上
发布到阿里云镜像服务上
1,登录阿里云
2,找到容器镜像服务
3,创建命名空间
4,创建容器镜像
5,浏览这个阿里云
6,发布镜像
#登录阿里云
docker login --username=xiaoxiao9189 registry.cn-hangzhou.aliyuncs.com
(密码是登录阿里云的时候设置的)
#更改一下镜像标签
docker images
docker tag diytomcat registry.cn-hangzhou.aliyuncs.com/xiao1226/xiao:1.0
(必须这样更改标签,如果不这样更改,会找不到仓库)
#推送镜像
docker images
docker push registry.cn-hangzhou.aliyuncs.com/xiao1226/xiao:1.0
#查看阿里云上是否有没有
阿里云容器镜像就参考官方地址
小结:
Docker网络
理解Docker0
清空所有环境
测试
三个网络
#问题,docker 是如何处理容器网络访问的?
#使用我们上传阿里云上面的镜像
docker pull registry.cn-hangzhou.aliyuncs.com/xiao1226/xiao:1.0
docker ps
docker run -d -P --name centos1.0 b8cab41e9c97
#查看容器的内部网路地址 ip addr
[root@server3 ~]# docker exec -it centos1.0 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
56: eth0@if57: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
#Linux系统测试是否能不能ping同容器内部
[root@server3 ~]# 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.290 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.044 ms
#Linux系统可以ping通docker容器内部
原理
1,我们每启动一个docker容器,docker就会给docker容器分配一个ip,我们只要安装了docker,就会有一个网卡docker0
桥接模式,使用的技术是evth-pair技术
再次测试本机的ip addr
2,在启动一个容器测试,发现又多了一对网卡
docker run -d -P --name centos2.0 b8cab41e9c97
#我们发现这个容器带来的网卡,都是一对一对的
#evth-pair 就是一对的虚拟设备接口,他们都是成对出现的,一段连着协议,一段彼此相连
#正因为有这个特性,evth-pair充当一个桥梁,连接各种虚拟网络设备的
#Open stack,Docker容器之间的连接,OVS的连接,都是使用evth-pair 技术
3,我们来测试centos1.0和centos2.0是否可以ping通
[root@server3 ~]# 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.040 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.074 ms
#结论容器和容器之间是可以互相ping通的
绘制网络模型图
结论:centos1.0和centos2.0是公用的一个路由器,docker0
所有的容器不指定网络的情况下,都是docker0路由的,docker会给我们的容器分配一个默认的可用IP
小结
Docker使用的Liunx的桥接,宿主机中是一个Docker容器的网桥,docker0
Docker中的所有的网络接口的虚拟的,虚拟的转发效率高(内网传递文件)
只要容器删除,对应网桥就都没了
#docker网络的命令
docker network --help
--link
思考一个场景,我们编写了一个微服务,database url=ip;项目不重启,数据库ip换掉了,我们希望可以处理这个问题,可以用名字来进行访问容器?
[root@server3 ~]# docker exec -it centos2.0 ping centos1.0
ping: centos1.0: Name or service not known
(不能ping通)
#如何解决呢
[root@server3 ~]# docker run -d -P --name centos3.0 --link centos2.0 b8cab41e9c97(id号是镜像id号)
bcf7e52995834b13a85220243d3eb742e277800a47122e53b6bcc73e97e6b027
[root@server3 ~]# docker exec -it centos3.0 ping centos2.0
PING centos2.0 (172.17.0.3) 56(84) bytes of data.
64 bytes from centos2.0 (172.17.0.3): icmp_seq=1 ttl=64 time=0.063 ms
64 bytes from centos2.0 (172.17.0.3): icmp_seq=2 ttl=64 time=0.041 ms
#通过--link就可以解决了网络连通问题
#反向可以ping通吗?
[root@server3 ~]# docker exec -it centos2.0 ping centos3.0
ping: centos3.0: Name or service not known
探究:docker network inspect e126f6c33a48
其实这个centos3.0就是在本地配置了centos2.0的配置?
#查看centos3.0中的hosts的配置,在这里原理发现
[root@server3 ~]# docker exec -it centos3.0 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 centos2.0 5575915b7b37
172.17.0.4 bcf7e5299583
本质:--link就是我们在容器中的hosts配置文件增加了172.17.0.3 centos2.0 5575915b7b37
现在在Dokcer中已经不建议使用--link了!
所以我们用自定义网络,docker0并不好用
docker0问题:他不支持容器名连接访问!
自定义网络
查看所有的docker网络
网络模式
bridge:桥接模式,docker(默认,自己创建的也是用bridge模式)
none:不配置网络
hosts:和宿主机共享网络
container:容器内网络联通!(用的少,局限很大)
测试
# --net bridge,这个启动的时候,默认会带上,而这个就是我们的docker0
docker run -d -P --name centos1 b8cab41e9c97
docker run -d -P --name centos1 --net bridge b8cab41e9c97
#docker0特点:默认自带,域名不能访问,但是--link可以打通连接
#我们可以自定义网络
#--driver bridge
#--subnet 192.168.10.0/16
#--gateway 192.168.10.1
[root@server3 ~]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
359ad7602daceae5fd6f69ca7e0d140d9b9ce6a015be4016eaf7c78569685fe4
[root@server3 ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
e126f6c33a48 bridge bridge local
d8a17cffa6eb host host local
359ad7602dac mynet bridge local
b2b72f5ee6b9 none null local
我们自己创建的网络就好了,使用下面命令查看我们创建的网络信息
docker network inspect mynet
[root@server3 ~]# docker run -d -P --name centos-net-01 --net mynet b8cab41e9c97
[root@server3 ~]# docker run -d -P --name centos-net-02 --net mynet b8cab41e9c97
[root@server3 ~]# docker network inspect mynet
[
{
"Name": "mynet",
"Id": "359ad7602daceae5fd6f69ca7e0d140d9b9ce6a015be4016eaf7c78569685fe4",
"Created": "2023-05-01T20:40:25.286230932+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "192.168.10.0/16",
"Gateway": "192.168.10.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"36462888e4bdbefd3fd76e12a0bd65c6ac8a18a1614182977e1414a91af3965d": {
"Name": "centos-net-02",
"EndpointID": "4f667f493ed6959aaf2d13a6d8b67c4c36cb6416c598c48f74aff4e96d9c5574",
"MacAddress": "02:42:c0:a8:00:02",
"IPv4Address": "192.168.0.2/16",
"IPv6Address": ""
},
"ff1da24783c31a736ef0079daba90df10e7a0b2a59617e233576d331a3676c47": {
"Name": "centos-net-01",
"EndpointID": "3d9a62e3156c08ef335da250ccf948e02ec494857190d9222447d6be32c5cd82",
"MacAddress": "02:42:c0:a8:00:01",
"IPv4Address": "192.168.0.1/16",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {}
}
]
#再次测试ping连接
[root@server3 ~]# docker exec -it centos-net-01 ping 192.168.0.2
PING 192.168.0.2 (192.168.0.2) 56(84) bytes of data.
64 bytes from 192.168.0.2: icmp_seq=1 ttl=64 time=0.146 ms
#现在不适用--link也可以ping名字了
[root@server3 ~]# docker exec -it centos-net-01 ping centos-net-02
PING centos-net-02 (192.168.0.2) 56(84) bytes of data.
64 bytes from centos-net-02.mynet (192.168.0.2): icmp_seq=1 ttl=64 time=0.031 ms
64 bytes from centos-net-02.mynet (192.168.0.2): icmp_seq=2 ttl=64 time=0.043 ms
我们自定义的网络docker都已经帮我们维护好了对应关系,我们平时就这样使用网络!
好处:
redis:不同的集群使用不同的网络,保证集群是安全和健康的
网络联通
#测试打通,使centos01打通 centos-net-01
docker run -d -P --name centos01 b8cab41e9c97
docker run -d -P --name centos02 b8cab41e9c97
[root@server3 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
bae80cd1e214 b8cab41e9c97 "/bin/sh -c '/usr/lo…" 2 minutes ago Up 2 minutes 0.0.0.0:32769->8080/tcp, :::32769->8080/tcp centos02
ba9b4651dede b8cab41e9c97 "/bin/sh -c '/usr/lo…" 2 minutes ago Up 2 minutes 0.0.0.0:32768->8080/tcp, :::32768->8080/tcp centos01
36462888e4bd b8cab41e9c97 "/bin/sh -c '/usr/lo…" 15 hours ago Up 3 seconds 0.0.0.0:32771->8080/tcp, :::32771->8080/tcp centos-net-02
ff1da24783c3 b8cab41e9c97 "/bin/sh -c '/usr/lo…" 15 hours ago Up 5 seconds 0.0.0.0:32770->8080/tcp, :::32770->8080/tcp centos-net-01
[root@server3 ~]# docker network connect mynet centos01
[root@server3 ~]# docker network inspect mynet
#发现连通之后就是将 centos01 放到了 mynet网络下
[root@server3 ~]# docker exec -it centos01 ping centos-net-01
PING centos-net-01 (192.168.0.1) 56(84) bytes of data.
64 bytes from centos-net-01.mynet (192.168.0.1): icmp_seq=1 ttl=64 time=0.092 ms
64 bytes from centos-net-01.mynet (192.168.0.1): icmp_seq=2 ttl=64 time=0.050 ms
#发现centos02依旧是打不通的
[root@server3 ~]# docker exec -it centos02 ping centos-net-01
ping: centos-net-01: Name or service not known
结论:假设要跨网络操作别人,就需要使用 docker network connect 连通
实战:redis集群部署
一共需要6个容器,先清空之前的容器
1,#我们先创建一个redis的网卡
docker network create redis --subnet 172.38.0.0/16
docker network ls
2,通过脚本创建六个redis配置
[root@server3 ~]# vim 1.sh
#!/bin/bash
for port in {1..6}
do
mkdir -p /mydata/redis/redis-$port/conf
touch /mydata/redis/redis-$port/conf/redis.conf
cat << EOF >/mydata/redis/redis-$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
2,#启动容器
[root@server3 ~]# docker run -p 6371:6379 -p 16371:16379 --name redis1 \
-v /mydata/redis/redis-1/data:/data \
-v /mydata/redis/redis-1/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.11 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
[root@server3 ~]# docker run -p 6372:6379 -p 16372:16379 --name redis2 \
-v /mydata/redis/redis-2/data:/data \
-v /mydata/redis/redis-2/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.12 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
[root@server3 ~]# docker run -p 6373:6379 -p 16373:16379 --name redis3 \
-v /mydata/redis/redis-3/data:/data \
-v /mydata/redis/redis-3/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.13 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
[root@server3 ~]# docker run -p 6374:6379 -p 16374:16379 --name redis4 \
-v /mydata/redis/redis-4/data:/data \
-v /mydata/redis/redis-4/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.14 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
[root@server3 ~]# docker run -p 6375:6379 -p 16375:16379 --name redis5 \
-v /mydata/redis/redis-5/data:/data \
-v /mydata/redis/redis-5/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.15 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
[root@server3 ~]# docker run -p 6376:6379 -p 16376:16379 --name redis6 \
-v /mydata/redis/redis-6/data:/data \
-v /mydata/redis/redis-6/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.16 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
3,#创建集群
[root@server3 ~]# docker exec -it redis1 /bin/sh(redis服务器里面没有/bin/bash)
/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 --clust
er-replicas 1
4,#可以进入集群,查看
/data # redis-cli -c
127.0.0.1:6379> cluster info
127.0.0.1:6379> set k1 b1
-> Redirected to slot [12706] located at 172.38.0.13:6379
5,#我们停止一个上面创建值的redis3容器,看看是否高可用
[root@server3 ~]# docker ps
[root@server3 ~]# docker stop redis3
172.38.0.11:6379> get k1
-> Redirected to slot [12706] located at 172.38.0.14:6379
"b1"
(发现k1依旧能获取,那就是redis4替代了redis3)
docker中的redis集群搭建完成
微服务打包Docker镜像
Docker微服务实战
通过IDEA新建一个普通的微服务模块
在自己创建的微服务中修改
运行测试
本机访问测试
打包微服务
将打包文件拖入桌面,尝试在windows中运行
在IDEA中下载docker插件,并直接在IDEA中创建DockerFile文件
别运行,然后将软件包和Dockerfile文件拷入linux中
[root@server3 idea]# pwd
/home/idea
[root@server3 idea]# ls
demo-0.0.1-SNAPSHOT.jar Dockerfile
#生成镜像
[root@server3 idea]# docker build -f Dockerfile -t xiao666 .
#运行容器
[root@server3 idea]# docker images
[root@server3 idea]# docker run -d -p 8080:8080 --name xiao-spingboot xiao666
#运行测试
[root@server3 idea]# curl localhost:8080/hello
hello xiao
Docker Swarm
介绍
官网介绍:Swarm mode overview | Docker Documentation
Docker Swarm 和 Docker Compose 一样,都是 Docker 官方容器编排项目,但不同的是,Docker Compose 是一个在单个服务器或主机上创建多个容器的工具,而 Docker Swarm 则可以在多个服务器或主机上创建容器集群服务,对于微服务的部署,显然 Docker Swarm 会更加适合。
从 Docker 1.12.0 版本开始,Docker Swarm 已经包含在 Docker 引擎中(docker swarm),并且已经内置了服务发现工具,我们就不需要像之前一样,再配置 Etcd 或者 Consul 来进行服务发现配置了。
docker swarm和k8s本质都是容器编排和管理,两者的对比如下:
swarm:内嵌在容器引擎内部,是容器引擎的一部分,与容器深度绑定,swarm偏重的是容器的部署,侧重于容器技术的扩展。
k8s:独立于docker,与docker是分离的,并完全不依赖于底层的docker,它侧重于业务应用的集群部署。k8s对容器的所有操作都渗透着为应用而服务的理念。以服务为中心,docker仅仅是其底层技术支撑的一种技术。
工作模式
Swarm搭建
准备四台服务器
#在四台服务器配置镜像加速器
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://atojdqeh.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
#建立swarm管理节点
[root@server1 ~]# docker swarm init --advertise-addr 192.168.10.2
#让三台服务器成为worker节点加入进来
[root@server2 ~]# docker swarm join --token SWMTKN-1-4ylg4gubjxqkdsvwgcltrb6ztklwst5azf6s1lhmk0yel8knls-24kpc291bfbnhqdxw1bywtf0j 192.168.10.2:2377
[root@server3 ~]# docker swarm join --token SWMTKN-1-12qmp65w9hyxbikfgi7ycqh8ic3wcdm6jukl6zc45jta3mkk04-9cnnbqw0f6dc38zks7eoyfavz 192.168.10.2:2377
[root@server4 ~]# docker swarm join --token SWMTKN-1-12qmp65w9hyxbikfgi7ycqh8ic3wcdm6jukl6zc45jta3mkk04-9cnnbqw0f6dc38zks7eoyfavz 192.168.10.2:2377
#如果想成为manager节点来加入,就按下面命令
[root@server1 ~]# docker swarm join-token manager
[root@server4 ~]# docker swarm join --token SWMTKN-1-4ylg4gubjxqkdsvwgcltrb6ztklwst5azf6s1lhmk0yel8knls-0b42uydkumfqxcfsfw40egz7q 192.168.10.2:2377
#在主manager节点上查看集群信息
[root@server1 ~]# docker node ls
swarm集群管理
(1),重新生成集群token
如果有新的节点需要加入,加入的token忘记了,就需要重新在管理节点生成一个token,如下:
#只能在manager节点生成token
#1、生成manager token
docker swarm join-token manager
#2、生成worker token
docker swarm join-token worker
(2)节点权限升级
比如将server4节点由Worker节点降级为Reachable管理节点
在Leader管理节点server1执行如下命令:
[root@server1 ~]# docker node promote server4
[root@server1 ~]# docker node ls
(3)节点权限降级
比如将server4节点由Reachable管理节点降级为worker节点
在Leader管理节点server1执行如下:
[root@server1 ~]# docker node demote server4
[root@server1 ~]# docker node ls
(4)删除一个集群节点
a、删除集群节点(worker节点),需要被删节点先主动离开集群,然后再由manager节点删除
b、如果删除的是manager节点,则需要先降级为worker节点,再主动离开集群,最后由manager节点删除
- 删除一个普通worker节点操作如下,以删除server2为例
#在server2被删节点执行如下:
[root@server2 ~]# docker swarm leave -f #-f参数表示强制离开集群
#在node1管理节点执行如下:
docker node ls #观察server2节点状态STATUS是否变为Down
docker node rm server2 #删除server2节点
- 删除一个Reachable管理节点,以server4为例
#在server1管理节点操作以下命令:
[root@server1 ~]# docker node demote server4 #先将server4降级为worker
#在server4呗删节点操作:
[root@server4 ~]# docker swarm leave #离开集群
#在server1管理节点操作如下
[root@server1 ~]# docker node rm server4
(5),其他常用命令
(主要为docker node命令和docker swarm命令,详情可使用docker node --help和docker swarm --help查看所有参数)
#查看集群节点状态,只能在manager节点使用
docker node ls
#查看运行节点的任务列表
docker node ps [NODENAME]
#查看节点详细信息
docker node inspect [NODENAME]
#更新节点
docker node update [NODENAME]
集群高可用演示
高可用介绍
在Docker Swarm中,Swarm manager负责管理整个集群,包括成规模的众多Docker主机资源。如果这个Swarm manager挂了,你必须创建一个新的来解决中断的服务。
Docker Swarm具有High Availability的特性,当有一个manager实例出现问题,Docker Swarm可以优雅的进行故障转移-failover。你可以创建一个单独的primary manager实例和多个replica实例来使用这个特性。
一个primary manager是Docker Swarm集群的主要联系人。你也可以创建replica实例作为次要联系人,并与它进行通信。对于replica收到的请求会被自动的代理到primary manager。如果一个primary manager故障,一个replica会成为leader。通过这种机制,你可以始终保持于集群的联系。
高可用切换演示
以如下docker集群状态为例,server1为主管理节点,server2和server4为普通管理节点,server3为工作节点
当server1 Leader节点执行systemctl stop docker,模拟将docker服务挂掉之后,等过一会之后,docker服务会被自动重启,并且集群将重新连接,只是主管理节点(Leader)会转移,如下:
【注意】:如果集群没有设置普通管理节点(Reachable),那么当主管理节点(Leader)挂掉再恢复之后,主管理节点(Leader)不会改变,因为没有普通管理节点(Reachable)参与选举。
通过docker service管理服务
命令详解
(1),创建/启动服务
#创建nginx服务
docker service create nginx
#创建nginx服务,并映射80端口
docker service create -p 80:80 nginx
#创建nginx容器,并设置5个运行副本
docker service create --replicas 5 nginx
(2)、查看正在运行的服务
[root@server1 ~]# docker service ls
(3)、查看某个服务运行状态
[root@server1 ~]# docker service ps great_euler
docker service ps [服务名字]
(4)、增加和删除DNS
docker service update --dns-add 222.222.222.222 mynginx
docker service update --dns-rm 222.222.222.222 mynginx
docker service update --dns-参数 222.222.222.222 [服务名字]
(5)、增加和删除端口映射
[root@server1 ~]# docker service update --publish-add 90:90 great_euler
[root@server1 ~]# docker service update --publish-rm 90:90 great_euler
docker service update --publish-参数 端口:端口 [服务名字]
(6)、缩容和扩容
[root@server1 ~]# docker service scale great_euler=2
[root@server1 ~]# docker service scale great_euler=5
docker service scale 服务名字=参数
(7)、显示服务详细信息
[root@server1 ~]# docker service inspect great_euler
[root@server1 ~]# docker service inspect [服务名字]
(8)、获取服务日志
[root@server1 ~]# docker service logs great_euler
[root@server1 ~]# docker service logs [服务名字]
(9)、删除一个或多个服务
[root@server1 ~]# docker service rm great_euler
[root@server1 ~]# docker service rm [服务名字]
(10)、回滚服务
docker service rollback mynginx
docker service rollback [服务名字]
(11)、更新服务
docker service update mynginx
docker service update [服务名字]
使用docker service管理服务演示
(1)创建服务
以在swarm集群创建nginx服务为例:
集群节点状态如下:
创建mynginx服务:
[root@server1 ~]# docker service create --name mynginx -p 80:80 nginx
查看docker service:
[root@server1 ~]# docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
t6t85avim7t3 mynginx replicated 1/1 nginx:latest *:80->80/tcp
(发现目前REPLICAS为1表示目前只有一个副本在运行)
查看docker service中mynginx的状态和信息:
[root@server1 ~]# docker service ps mynginx
如上图, 可以看到mynginx服务只有一个副本在运行,并且是运行在server3节点上,可以在server3节点执行docker ps -a查看到在运行的mynginx容器:
因为现在mynginx已经在swarm集群运行,并且映射了端口,此时通过node1~4任何一个节点的主机ip都可以访问到nginx服务:
(2),扩容或缩容服务
(当web访问量骤增和骤减,这时候就需要动态的对mynginx服务进行扩容和缩容)
#有以下两种方式,2选1即可
#方式1
docker service update --replicas 5 mynginx #将运行副本数设置为5
#方式2
docker srevice scale mynginx=5 #将运行副本数设置为5
查看扩容/缩容后的服务状态:
[root@server1 ~]# docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
t6t85avim7t3 mynginx replicated 5/5 nginx:latest *:80->80/tcp
[root@server1 ~]# docker service ps mynginx
如上图可以看到,docker service会将所有副本均衡的分布到所有节点上。
Swarm集群数据管理
volume方式管理数据
volume模式:在宿主机上创建一个volume,默认目录为(/var/lib/docker/volume/your_custom_volume/_data),然后把容器的某个目录映射到宿主机的volume上,即使容器挂了,数据还会依然保留在宿主机的volume上。
[root@server1 ~]# docker service create --replicas 1 --mount type=volume,src=nginx,dst=/usr/share/nginx/html --name nginx nginx
#查看服务
[root@server1 ~]# docker service inspect nginx
#查看数据卷
[root@server1 ~]# docker volume inspect nginx
可以看到容器里面的nginx数据目录已经挂在到宿主机的默认目录了
bind mount方式管理数据
bind mount模式:将宿主机某个目录映射到docker容器,很适合于网站,同时把宿主机的这个目录作为git版本目录,每次update代码的时候,容器就会更新。
#创建数据目录
在mananger、worker上创建web网站目录:
[root@server1 ~]# mkdir -p /data/nginx
[root@server3 ~]# mkdir -p /data/nginx
#创建服务
[root@server1 ~]# docker service create --replicas 1 \
--mount type=bind,src=/data/nginx,dst=/usr/share/nginx/html \
--name mynginx \
nginx
#查看服务
[root@server1 ~]# docker service ps mynginx
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
tqrq2rmz3hhx mynginx.1 nginx:latest server1 Running Running 26 seconds ago
(发现运行在server1中)
测试宿主机目录和容器目录是映射关系
[root@server1 ~]# cd /data/nginx/
[root@server1 nginx]# echo 'hello' > index.html
[root@server1 nginx]# docker exec -it bacdb6680c36 /bin/bash
root@bacdb6680c36:/# cat /usr/share/nginx/html/index.html
hello
可以看到我们在宿主机上创建的index.html已经挂在到容器上了!
NFS方式管理数据
前面两种方式都是单机docker上数据共享方式,要是在集群中,这个就不适用了,我们必须使用共享存储或网络存储了。这里我们使用NFS来测试。
我们使用第三台(server3作为NFS服务提供者)
yum install nfs-utils -y
并且在nfs目录放入网站数据内容:
[root@server3 ~]# mkdir -p /nfs/data
[root@server3 ~]# echo "hello nfs" > /nfs/data/index.html
[root@server3 ~]# chmod 777 /nfs/data/
[root@server3 ~]# cat /etc/exports
/nfs/data *(rw)
[root@server3 ~]# systemctl restart nfs
#安装nfs客户端
[root@server1 nginx]# yum install nfs-utils -y
#先手动创建docker volume
root@server1 nginx]# docker volume create --driver local \
--opt type=nfs \
--opt o=addr=192.168.10.4,rw \
--opt device=:/nfs/data \
foo3
#查看一下volume
[root@server1 nginx]# docker volume ls
DRIVER VOLUME NAME
local foo3
local nginx
#看到了docker volume列表中有foo33,查看volume详细
[root@server1 nginx]# docker volume inspect foo3
这里有个问题,如果不用docker compose创建服务的话,你必须在服务所在的节点上创建docker volume
我的服务要创建4个副本,服务可能会分布到4个主机上,那么我在三个主机上都创建docker volume create foo33使用上面的代码在其它3台主机上都执行一遍
#发布服务
[root@server1 nginx]# docker service create \
--name test-nginx-nfs \
--publish 84:80 \
--mount type=volume,source=foo3,destination=/app/share \
--replicas 4 \
nginx
#查看服务分布的节点
[root@server1 nginx]# docker service ps test-nginx-nfs
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
67lujrhuj7ef test-nginx-nfs.1 nginx:latest server4 Running Running 6 minutes ago
knwg2o4h5tro test-nginx-nfs.2 nginx:latest server2 Running Running 56 seconds ago
ittn55i32cpn test-nginx-nfs.3 nginx:latest server3 Running Running 56 seconds ago
ywktwchn44fd test-nginx-nfs.4 nginx:latest server1 Running Running 55 seconds ago
#测试server1
我们在搭建nfs服务器上创建一个文件
[root@server3 ~]# cd /nfs/data/
[root@server3 data]# touch xiao
#我们先查看宿主机目录
[root@server1 nginx]# docker volume inspect foo3
[root@server1 nginx]# ll /var/lib/docker/volumes/foo3/_data/
总用量 4
-rw-r--r--. 1 root root 10 5月 15 11:15 index.html
-rw-r--r--. 1 root root 0 5月 15 11:35 xiao
#查看容器目录
[root@server1 nginx]# docker ps
[root@server1 nginx]# docker exec -it 68431db127bf /bin/bash
root@68431db127bf:/# cd app/share/
root@68431db127bf:/usr/share/nginx/html# ls
index.html xiao
Docker-compose
介绍
compose、machine 和 swarm 是docker 原生提供的三大编排工具。简称docker三剑客。
Docker Compose能够在 Docker 节点上,以单引擎模式(Single-Engine Mode)进行多容器应用的部 署和管理。多数的现代应用通过多个更小的微服务互相协同来组成一个完整可用的应用。
部署和管理繁多的服务是困难的。而这正是 Docker Compose 要解决的问题。Docker Compose 并不 是通过脚本和各种冗长的 docker 命令来将应用组件组织起来,而是通过一个声明式的配置文件描述整 个应用,从而使用一条命令完成部署。应用部署成功后,还可以通过一系列简单的命令实现对其完整声 明周期的管理。甚至,配置文件还可以置于版本控制系统中进行存储和管理。
下载安装
#1,将docker-compose-Linux-x86_64软件包拖入进去
#2,将文件复制到/usr/local/bin下,并改名字
[root@server3 ~]# mv docker-compose-Linux-x86_64 /usr/local/bin/docker-compose
#3,给权限
chmod 777 /usr/local/bin/docker-compose
#4,查看测试版本
[root@server3 ~]# docker-compose -version
标签:实战,容器,--,redis,讲解,镜像,Docker,root,docker
From: https://www.cnblogs.com/xiao1226/p/17402987.html