一款产品:开发—上线 两套环境!应用环境,应用配置!
开发 -------运维。问题:在我这可以运行,但是在你的电脑就不能运行了。或者版本更新就不能使用了。
开发即运维!!
环境配置十分麻烦,每一个机器都要部署环境(集群redis、ES、Hadoop)。费时费力的。
发布一个项目jar(Redis+mysql+jdk+ES),那么你发送一个jar过去,别人还需要去配置运行这个jar包所需要的环境,而且版本一旦稍有不同就可能会出错。
所以希望项目能够带上环境进行打包发布,而不是单纯的一个jar文件。===>Docker
之前在服务器配置一个应用环境Redis、Mysql、jdk、ES、Hadoop,配置超麻烦,不能跨平台。
Windows开发,发布到Linux。
传统:开发jar,运维来部署
现在:开发打包部署上线,一套流程做完。
比如现在开发了一个Android的应用上线了给别人用:
Java->apk->发布(应用商店)->张三使用apk->到商店下载安装即可
回到我们的开发项目流程
Java->jar(环境)->打包项目带上环境(镜像)->上传到docker仓库(类似上面的商店)->运维下载我们发布的镜像->直接运行即可!
Docker的思想来自于集装箱
同一个JRE->多个应用(可能会出现端口冲突)–>原来的项目是交叉的
隔离:Docker的核心思想,打包装箱,每个箱子都是互相隔离的,每个箱子有自己的环境,即使端口一样也不会冲突。
Docker通过隔离可以使得服务器利用到极致。只要有一点空间,docker就可以利用。
传统的虚拟机技术缺点:
资源占用十分多
冗余步骤多
启动慢
容器技术
容器化技术不是虚拟的一个完整的系统,只要一个核心。
容器内部有自己的运行环境,每个 容器是隔离的,容器是建立在我们的虚拟机之上的,可以充分的使用我们的虚拟机资源。
比较docker和虚拟机的不同
DevOps(开发、运维)
应用更快的交付和部署
传统的:一堆帮助文档,安装程序
Docker:打包镜像发布测试,一键运行。
更便捷的升级和扩缩容
使用了Docker之后,部署应用就和搭积木一样
项目打包为一个镜像,扩展为服务器A,直接把镜像下载到服务器B运行就可以使服务器A的工作量减少,到达负载均衡的目的。
更简单的系统运维
在容器化之后,我们的开发测试环境都是高度一致的。(底层的系统kernel是一样的)
更高效的计算资源利用
1核2G可以运行十几个tomcat
Docker是内核级别的虚拟化,可以在一个物理机上运行多个容器实例,服务器性能可以被压榨到极限。
镜像(image)
docker镜像就好比一个模板,可以通过这个模板来创建容器服务,Tomcat镜像===>run---->tomcat1容器(提供服务器),通过这个镜像创建多个容器(最终服务运行或者项目运行就是在容器里面的)。镜像run起来就是容器了。
容器(container):
docker利用容器口域独立运行一个或者一组应用,通过镜像来创建
启动,停止,创建,删除,基本命令
目前可以理解为一个容器就是一个简易的Linux系统,就是有些基本的内容。
仓库(repository):
仓库就是存镜像的地方。
有公有仓库和私有仓库!(这个概念和git的相似)
Docker Hub(默认是国外的)
阿里云。。。。都有容器服务器(配置镜像加速!这里类似于maven)
所以应该docker的启动流程应该是这样的:client去启动一个镜像,而这个镜像要去仓库里面去获取,然后运行这个镜像来创建得到容器,我们实际上就是在跑这个容器。
环境准备
查看官方文档
网址:https://docs.docker.com/get-docker/
我们这里是需要安装在Linux上的。
# 1、卸载旧的版本
sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
# 2、安装的需要的安装包
sudo yum install -y yum-utils
# 3、设置镜像仓库
sudo yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo #这个仓库地址默认是国外的,非常慢,我们不要这样设置,可以去找国内的加速镜像
sudo yum-config-manager \
--add-repo \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo #使用阿里云的镜像来安装
#更新yum软件包索引
yum makecache
#4、安装docker相关的包
#安装最新版本的docker引擎 docker-ce 社区版 ee是企业版
sudo yum install docker-ce docker-ce-cli containerd.io
#我这里安装的时候出现这个问题:
Error:
Problem: package docker-ce-3:20.10.2-3.el7.x86_64 requires containerd.io >= 1.4.1, but none of the providers can be installed
- cannot install the best candidate for the job
- package containerd.io-1.4.3-3.1.el7.x86_64 is filtered out by modular filtering
(try to add '--skip-broken' to skip uninstallable packages or '--nobest' to use not only best candidate packages)
#所以需要安装对应的io
sudo dnf install https://download.docker.com/linux/centos/8/x86_64/stable/Packages/containerd.io-1.4.3-3.1.el8.x86_64.rpm
#接着再重新执行安装命令
sudo yum install docker-ce docker-ce-cli containerd.io
#5、启动docker
systemctl start docker
#查看docker的版本,看看是否安装成功
docker version
#7、运行docker helloworld
docker run hello-world
因为我们没有这个hello-world镜像,所以它去仓库进行pull,拉取这个镜像
然后会返回一个签名,代表拉取完成了。
拉取完成之后就会运行起来了。
#8、查看这个下载的hello-world镜像
[root@iZwz96cj54lr4szndhzbezZ ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest bf756fb1ae65 12 months ago 13.3kB
卸载docker
#1、卸载依赖
sudo yum remove docker-ce docker-ce-cli containerd.io
#2、删除资源
sudo rm -rf /var/lib/docker
# docker的默认工作路径 /var/lib/docker
登录阿里云账号,进入控制台
配置使用
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://9eigil3c.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
Docker是一个client-server结构的系统,Docker的守护进程运行再主机上,通过socket从客户端访问。
DockerServer接受到client的指令,就会执行这个命令。
docker为什么比虚拟机要快
1、Docker有着比虚拟机更少的抽象层,由于Docker不需要Hypervisor实现硬件资源虚拟化,运行在Docker容器上的程序直接使用的都是实际物理机的硬件资源,因此在Cpu、内存利用率上Docker将会在效率上有明显优势。
2、Docker利用的是宿主机的内核,而不需要Guest OS,因此,当新建一个容器时,Docker不需要和虚拟机一样重新加载一个操作系统,避免了引导、加载操作系统内核这个比较费时费资源的过程,当新建一个虚拟机时,虚拟机软件需要加载Guest OS,这个新建过程是分钟级别的,而Docker由于直接利用宿主机的操作系统则省略了这个过程,因此新建一个Docker容器只需要几秒钟。
Docker容器 | 虚拟机(VM) | |
---|---|---|
操作系统 | 与宿主机共享OS | 宿主机OS上运行宿主机OS |
存储大小 | 镜像小,便于存储与传输 | 镜像庞大(vmdk等) |
运行性能 | 几乎无额外性能损失 | 操作系统额外的cpu、内存消耗 |
移植性 | 轻便、灵活、适用于Linux | 笨重、与虚拟化技术耦合度高 |
硬件亲和性 | 面向软件开发者 | 面向硬件运维者 |
docker version #显示docker的版本信息
docker info #显示docker的系统信息,包括镜像和容器数量
docker 命令 --help #帮助命令
帮助文档地址:https://docs.docker.com/reference/
**docker images:**查看所有本地的主机上的镜像
[root@iZwz96cj54lr4szndhzbezZ ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest bf756fb1ae65 12 months ago 13.3kB
#解释
REPOSITORY 镜像的仓库源,也就是这个镜像在仓库里面的命名
TAG 镜像的标签,版本
IMAGE ID 镜像的id
CREATED 镜像的创建时间
SIZE 镜像的大小
#可选项
-a, --all #列出所有的镜像
-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 #只显示镜像的id
docker search搜素镜像
[root@iZwz96cj54lr4szndhzbezZ ~]# docker search mysql
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
mysql MySQL is a widely used, open-source relation… 10380 [OK]
mariadb MariaDB is a community-developed fork of MyS… 3848 [OK]
#可选项,通过收藏来过滤
--filter=stars=3000 搜素出来的镜像的stars就是大于3000的
[root@iZwz96cj54lr4szndhzbezZ ~]# docker search mysql --filter=stars=3000
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
mysql MySQL is a widely used, open-source relation… 10380 [OK]
mariadb MariaDB is a community-developed fork of MyS… 3848 [OK]
docker pull下载镜像
[root@iZwz96cj54lr4szndhzbezZ ~]# docker pull mysql
Using default tag: latest #如果不写tag,默认就是lates
latest: Pulling from library/mysql
a076a628af6f: Pull complete #分层下载,docker image的核心 联合文件系统
f6c208f3f991: Pull complete
88a9455a9165: Pull complete
406c9b8427c6: Pull complete
7c88599c0b25: Pull complete
25b5c6debdaf: Pull complete
43a5816f1617: Pull complete
1a8c919e89bf: Pull complete
9f3cf4bd1a07: Pull complete
80539cea118d: Pull complete
201b3cad54ce: Pull complete
944ba37e1c06: Pull complete
Digest: sha256:feada149cb8ff54eade1336da7c1d080c4a1c7ed82b5e320efb5beebed85ae8c #签名
Status: Downloaded newer image for mysql:latest
docker.io/library/mysql:latest #真实地址
#等价于
docker pull mysql
docker pull docker.io/library/mysql:latest
#指定版本下载
docker pull mysql:5.7
docker rmi删除镜像
docker rmi -f #删除所有的镜像
docker rmi -f id #根据镜像的id来删除镜像
docker rmi -f id1 id2 id3 #根据镜像的多个id来删除镜像
docker rmi -f $(docker images -aq) #删除所有的容器
有了镜像才可以创建容器
下载一个centos的镜像
新建容器并启动
docker run [可选参数] image
#参数的说明
--name="name" #容器的名字 tomcat1 tomcat2 用来区分容器
-d #后台方式运行
-it #使用交互方式运行,进入容器查看内容
-p #指定容器端口 -p 8080:8080
-p ip:主机端口:容器端口
-p 主机端口:容器端口(常用)
-p 容器端口
-P #随机指定端口
#启动并加入容器
[root@iZwz96cj54lr4szndhzbezZ ~]# docker run -it centos /bin/bash
[root@95ca66a1d3d2 /]# ls #查看容器内部的centos
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
#从容器退出到主机
exit
列出所有的运行的容器
#docker ps命令
# 列出所有的正在运行的容器
-a #列出当前正在运行的容器+历史运行过的容器
-n=? #显示最近创建的容器
-q #只显示容器的编号
#查看运行的容器
docker ps
#查看曾经运行的容器
docker ps -a
退出容器
exit #直接容器停止退出
Ctrl+P+Q #容器不停止退出
删除容器
docker rm 容器id #删除指定的容器,不能删除正在运行的容器,如果要强制删除 rm -f
docker rm -f $(docker ps -aq) #删除所有的容器
docker ps -a -q|xargs docker rm #删除所有的容器
启动和停止容器的操作
docker start 容器id #开启容器
docker restart 容器id #重启容器
docker stop 容器id #停止容器
docker kill 容器id #强制停止容器
后台启动容器
# 命令 docker run -d 镜像名
[root@iZwz96cj54lr4szndhzbezZ ~]# docker run -d centos
#问题docker ps,发现centos停止了
# 常见的坑,docker容器使用后台运行,就必须要有一个前台进程,docker发现没有应用,就会自动停止
#nginx,容器启动后,发现自己没有提供服务,就会立刻停止,就是没有程序了
查看日志命令
docker logs -f -t --tail 容器 ,没有日志
#自己编写一段shell脚本,让容器一直执行这一段程序,循环输出hello
[root@iZwz96cj54lr4szndhzbezZ ~]# docker run -d centos /bin/sh -c "while true;do echo hello;sleep 1;done"
[root@iZwz96cj54lr4szndhzbezZ ~]# docker logs -tf --tail 10 ee9e03dfc9b4
查看容器中的进程信息
top命令
docker top 容器id
查看容器元数据
#命令 docker inspect 容器id
进入当前正在运行的容器
#我们通常容器都是通过后台的方式运行的,需要进入容器来修改一下配置
#命令
docker exec -it 容器id bashShell
#测试
[root@iZwz96cj54lr4szndhzbezZ ~]# docker exec -it ee9e03dfc9b4 /bin/bash
#方式二
docker attach 容器id
正在执行当前的代码
#docker exec #进入容器后开启一个新的终端,可以在里面操作
#docker attach #进入容器正在执行的终端,不会启动新的进程
从容器内拷贝文件到主机上
docker cp 容器id:容器内路径 目的主机路径
[root@iZwz96cj54lr4szndhzbezZ home]# docker cp 2b6ceeade7e6:/home/test.java /home
[root@iZwz96cj54lr4szndhzbezZ home]# ls
hello.java test.java
#拷贝的时候即使容器没有运行也是可以拷贝的,因为数据还在
#拷贝是一个手动过程,未来使用-v 卷的技术可以实现自动同步 比如:容器的home 和 主机的home 联通
#1、搜索镜像
docker search nginx
#2、下载镜像
docker pull nginx
#3、运行测试
[root@iZwz96cj54lr4szndhzbezZ ~]# docker run -d --name nginx01 -p 3344:80 nginx #-p映射的端口
端口映射的问题
思考问题:我们每次改动nginx配置文件,都需要进入容器内部,十分的麻烦,我们要是可以在容器外部提供一个映射路径,达到在容器外部修改文件,容器内部的 文件就可以自动的修改?-v 数据卷
#官方的使用
docker run -it --rm tomcat:9.0
#我们之前的启动都是后台,停止容器之后,容器还是可以查到 docker run -it --rm一般用来测试,用完即删
#下载启动
[root@iZwz96cj54lr4szndhzbezZ ~]# docker run -d -p 3355:8080 --name tomcat01 tomcat
启动之后外网访问发现:
1、linux命令少了
2、没有webapps
是因为阿里云镜像的原因,默认的是最小的镜像,所有不必要的都剔除掉,保证最小的可运行的环境
#进入tomcat
[root@iZwz96cj54lr4szndhzbezZ ~]# docker exec -it tomcat01 /bin/bash
#进入webapps目录发现里面的内容是空的
#但是有一个webapps.dist,里面的文件就是我们需要的,把文件拷贝到webapps就可以成功访问tomcat了
root@777b7949eaf3:/usr/local/tomcat# cp -r webapps.dist/* webapps
思考问题:我们以后要部署项目,如果每次都要进入容器是不是十分麻烦?我要是在容器外部提供一个映射路径,webapps,我们在外部部署项目,就可以自动同步到内就好了。
docker容器 tomcat+网站
#es 暴露的端口很多
#es 十分的耗内存
#es 的数据一般需要放置到安全目录!挂载
# --net somenetwork ?网络配置
docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:7.6.2
#es是十分耗内存的
[root@iZwz96cj54lr4szndhzbezZ ~]# curl localhost:9200
{
"name" : "6ada9b775535",
"cluster_name" : "docker-cluster",
"cluster_uuid" : "fUhyrAXvSoS8_XC8lbY0-A",
"version" : {
"number" : "7.6.2",
"build_flavor" : "default",
"build_type" : "docker",
"build_hash" : "ef48eb35cf30adf4db14086e8aabd07ef6fb113f",
"build_date" : "2020-03-26T06:34:37.794943Z",
"build_snapshot" : false,
"lucene_version" : "8.4.0",
"minimum_wire_compatibility_version" : "6.8.0",
"minimum_index_compatibility_version" : "6.0.0-beta1"
},
"tagline" : "You Know, for Search"
}
#可以查看docker的cpu的内存状态 docker stats
#关闭增加内存的限制,修改配置文件-e环境配置
docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms64m -Xmx512m" elasticsearch:7.6.2
docker的图形化界面管理工具!提供一个后台面板供我们操作
docker run -d -p 8088:9000 --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
测试访问:外网8088http://47.106.213.152:8088/
选择本地的
我们下载镜像的时候是一层层的
镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码,运行时,库,环境变量和配置文件
所有的应用直接打包成docker镜像部署,就可以直接跑起来
如何得到镜像:
UnionFS 联合文件系统
联合文件系统(UnionFS)是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下。
联合文件系统是 Docker 镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
特性:一次可以同时加载多个文件系统,但从外面来看,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录。
docker镜像加载原理
所有的Docker镜像都起始于一个基础镜像层,当进行修改或增加新的内容时,就会在当前镜像层之上,创建新的镜像层。分层时有文件更新直接替换,基础镜像一样时直接拿过来复用。
如redis下载时,第一层相同,直接复用,其他几层分层下载。
afb6ec6fdc1c: Already exists
608641ee4c3f: Pull complete
668ab9e1f4bc: Pull complete
78a12698914e: Pull complete
d056855f4300: Pull complete
618fdf7d0dec: Pull complete
举一个简单的例子,假如基于 Ubuntu16.04创建一个新的镜像,这就是新镜像的第一层。如果在该镜像中添加Python包,就会在基础镜像层之上创建第二个镜像层。如果继续添加一个安全补丁,就会创健第三个镜像层该像当前已经包含3个镜像层,如下图所示(这只是一个用于演示的很简单的例子)。
在添加额外的镜像层的同时,镜像始终保持是当前所有镜像的组合。一个简单的例子,每个镜像层包含3个文件,而镜像包含了来自两个镜像层的6个文件。
下图中展示了一个稍微复杂的三层镜像,在外部看来整个镜像只有6个文件,这是因为最上层中的文件7是文件5的一个更新版。
上层镜像层中的文件覆盖了底层镜像层中的文件。这样就使得文件的更新版本作为一个新镜像层添加到镜像当中。
所有镜像层堆并合井,对外提供统一的视图。
Docker镜像都是只读的,当容器启动时,一个新的可写层加载到镜像的顶部。这一层就是我们通常说的容器层,容器之下的都叫镜像层。
docker commit 提交容器成为一个新的副本
#命令和git相似
docker commit -a "作者" -m "提交的描述信息" 容器id 目的镜像名:[tag]
实战
#1、启动一个默认的tomcat
#2、发现这个tomcat是没有webapps应用的,镜像的原因,官方的镜像默认webapps下面是没有文件的。
#3、我自己拷贝进去了基本文件到webapps
#4、将我们操作过的容器通过commit提交为一个镜像,我们以后就使用修改过的镜像就可以,这就是我们自己的一个镜像
如果你想要保存当前容器的状态,就可以通过commit来提交,获得一个镜像,就好比我们之前学习的VM时候,快照!
docker的理念
将应用和环境打包成一个镜像
数据都在容器中,那么容器一删除,数据就会丢失, --需求:数据可以持久化
mysql,容器删了,删库跑路—需求:MySQL 的数据可以存储在本地,
容器之间可以有一个数据共享的技术。docker容器中产生的数据同步到本地,容器删除了,数据还在本地就不会丢失===>目录的挂载,将我们的容器的目录挂载在linux上面
同步机制
总结:容器的持久化和同步操作,容器间也是可以数据共享的。
方式一:直接使用命令来挂载 -v
docker run -it -v 主机目录:容器目录
#测试
[root@iZwz96cj54lr4szndhzbezZ ~]# docker run -it -v /home/test:/home centos /bin/bash
#启动之后我们可以通过docker inspect 容器id 来查看挂载信息
测试文件的同步的具体效果
即使你停止了容器我们在主机上修改文件,容器内的文件也可以同步的,只要这个容器没有被删除
好处:我们以后只需要修改本地的文件即可,容器的文件可以自动同步!
mysql的数据持久化问题,data目录
#获取镜像
docker pull mysql:5.7
#运行容器,需要做数据挂载! #安装启动mysql的时候,需要配置密码的
# 官方的测试
docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag
#启动我们的MySQL
-d 后台运行
-p 端口映射
-v 卷挂载
-e 环境配置
--name 容器名字
[root@iZwz96cj54lr4szndhzbezZ ~]# 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=123456 --name mysql mysql:5.7
#可以使用navicat来进行连接数据库,连接到服务器的3310端口,在本地创建一个mysql数据库,查看路径是否映射成功
即使将容器删除,发现我们挂载到本地的数据卷依旧没有丢失,这实现了数据持久化功能。
# 匿名挂载
-v 容器路径
docker run -d -P --name nginx01 -v /etc/nginx nginx
#查看所有卷的情况
[root@iZwz96cj54lr4szndhzbezZ data]# docker volume ls
发现卷的名字是一串数字,这就是匿名挂载,我们在-v的时候只写了容器的路径
#具名挂载
-v 卷名:容器内路径
#查看卷的路径
docker volume inspect 卷名
比如
docker volume inspect juming-nginx
卷的路径
所有的卷在没有指定目录的情况下都是在/var/lib/docker/volumes/xxx/_data
我们通过具名挂载可以方便找我们的卷,这也是我们大多情况下使用的
#如何确定是具名挂载还是匿名挂载,还是指定路径挂载
-v 容器内路径 #匿名挂载
-v 卷名:容器内路径 #具名挂载
-v /宿主机路径:容器路径 #指定路径挂载
扩展
# 通过 -v 容器内路径,ro rw 改变读写权限
ro readonly #只读
rw radewrite #可读可写
#一旦设定了容器的权限,容器对我们挂载出来的内容就有限定了
docker run -d -P --name nginx01 -v juming-nginx:/etc/nginx:ro nginx
docker run -d -P --name nginx01 -v juming-nginx:/etc/nginx:rw nginx
#ro只要看到ro就说明这个路径只能通过宿主机来操作,容器内部是无法操作的,默认是rw
DockerFile就是用来构建docker镜像的构建文件!之前是commit,现在是dockerFile!命令脚本!
通过这个脚本可以生成镜像,镜像是一层一层的,脚本就是一个个的命令,每个命令都是一层
方式二
#创建一个dockerfile文件,命名随意,但是尽量是dockerfile
#文件内容,指令和参数,指令都是大写的
FROM centos
VOLUME ["volume01","volume02"] #这是一个匿名挂载
CMD ecoh "---------end-------"
CMD /bin/bash
#这里的每一个命令就是镜像的一层
#build这个dockerFile的镜像
[root@iZwz96cj54lr4szndhzbezZ docker-test-volume]# docker build -f dockerfile1 -t zhuzi/centos .
可以看到是一层层的构建的
#启动刚刚自己创建的镜像
[root@iZwz96cj54lr4szndhzbezZ docker-test-volume]# docker run -it zhuzi/centos /bin/bash
#查看文件
这个卷和外部一定有一个同步的目录
查看卷挂载的路径
docker inspect 38f17bbf2c99
可以去source路径去查看数据文件是否被同步成功
这种方式我们未来使用的十分的多,因为我们通常会构建自己的镜像!
假设构建镜像的时候没有挂载卷,要手动挂载卷 -v 卷名:容器路径
两个MySQL同步数据。
#启动3个容器
#第一个
docker run -it --name contos01 zhuzi/centos
#第二个
docker run -it --name centos02 --volumes-from contos01 zhuzi/centos
#第三个
docker run -it --name centos03 --volumes-from contos01 zhuzi/centos
#我们通过 --volumes-from 父容器id 就可以实现容器之间的数据同步
数据共享即使父容器丢了,子容器里面的文件还是可以访问的,即数据没有丢失。
–volumes-from 的理解
实际上–volumes-from 是使得我们创建的子容器共享父容器的数据卷在主机本地的目录,也就是子容器和父容器的数据卷在本地上的位置是一样的,这样子就可以实现数据的同步,因为其中一个容器的文件一旦修改,本地的文件就会修改,本地文件一修改这样其他容器的文件也会修改,牵一而动百
这里需要注意的是,即使是继承了,数据之间是同步了,但是只要数据卷的内容是同步的,非数据卷的目录是不同步的。
所以对于多个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
#第二个MySQL
docker run -d -p 3310:3306 -e MYSQL_ROOT_PASSWORD=123456 --name mysql02 --volume-from mysql01 mysql:5.7
结论
容器之间的配置信息的传递,数据卷容器的生命周期是一直持续到没有容器使用为止
但是一旦你持久化到了本地,本地的数据不会删除
这个问题的发现是偶然的,一次在我安装code-server挂载code文件夹的时候,发现exec进去之后,容器里面不能创建文件,原因是code文件的用户权限是root权限的,而code-server登录的用户的权限是coder,所以没有权限创建文件
#运行容器,把容器的code挂载到/home/zhuzi/code,因为容器里面的code原来是没有的,所以在运行容器的时候是root的身份创建的
docker run -d -p 8081:8080 --name code-server2 -v /home/zhuzi/code:/home/code codercom/code-server
#我们exec进入容器查看这个文件的权限,所属的用户和用户组
在这里我们可以发现,登录容器的用户是coder,而code文件夹是属root用户的,我们试试在code里面创建文件
可以看到我们是没有权限创建文件的,决解的方法就是把容器的用户改位root,不用使用默认的coder用户了
#这里我们使用-u来指定容器的用户为root,这样子登录容器的用户就为root了,我们就有权限在code文件夹创建文件了
docker run -d -u root -p 8088:8080 --name code-server -v /home/zhuzi/code:/home/code codercom/code-server
看到了吗,这样子创建文件是看到没问题了的,有人可能会说我们在exec进去的时候就使用root也可以啊,但是这样子在浏览器登录code-server的时候,还是以coder身份登录,依旧不能在code创建文件
dockerfile是用来构建docker镜像的文件!命令参数脚本。
构建步骤:
1、 编写一个dockerfile文件
2、docker build构建为一个镜像
3、docker run镜像
4、docker push推送我们的镜像
官方就是构建了dockerfile然后发布到github上面的
很多官方镜像都是基础包,很多功能都没有,我们通常需要自己安装。
基础知识
1、每个保留关键字(指令)都必须是大写字母
2、指令是从上到下顺序执行的
3、#表示注释
4、每个指令都会被创建一个新的镜像层,并提交
dockerFile是面向开发的,我们以后开发项目,做镜像,就需要编写dockerFile文件,这个文件十分简单
Docker镜像逐渐成为了企业交付的标准,必须要掌握!
步骤:开发、部署、上线运维
dockerFile:构建文件,定义了一切的步骤,源代码
dockerImage:通过dockerFile构建生成的一个镜像,最终要发布和运行的产品,原来是jar运行,最后哪怕是一个jar都需要创建一个镜像来运行。
docker容器:镜像运行起来提供服务的
FROM #基础镜像 一切从这里开始构建
MAINTARNER #镜像是谁写的,姓名+邮箱
RUN #Docker镜像构建运行时候需要运行的命令
ADD #步骤,tomcat镜像,这个tomcat压缩包,添加的内容
WORKDIR #镜像的工作目录
VOLUME #挂载的目录
EXPOSE #暴露端口配置
RUN #
CMD #指定容器启动的时候运行的命令,只有最后一个会生效,可以被代替
ENTRYPOINT #指定容器启动的时候运行的命令,可追加
ONBUILD #当构建一个被继承的DockerFile中国时候就会运行ONBUILD指令,触发指令
COPY #类似ADD,将文件拷贝到镜像中
ENV #构建的时候设置环境变量
Docker Hub中99%的镜像都是从这个基础的镜像过来的,FROM scratch,然后配置需要的软件和配置来进行构建
创建一个自己的centos
#1、编写在自己的dockerFile文件
FROM centos
MAINTAINER zhuzi<[email protected]>
ENV MYPATH /usr/local
WORKDIR $MYPATH
RUN yun -y install vim
RUN yun -y install net-tools
EXPOSE 80
CMD echo $MYPATH
CMD echo "------end--------"
CMD /bin/bash
#2、通过这个文件构建镜像,不要忘记最后的.
docker build -f mydockerfile -t mycentos .
#3、测试运行
进来之后第一件事pwd
发现我们当前的目录就是工作目录,也就是我们刚刚dockerfile写的WORKDIR的路径
对比之前的centos:官方的。工作目录默认是根目录,
我们增加之后的镜像
我们可以列出本地进行变更的历史docker history 镜像id
我们平时拿到一个镜像可以研究它是怎么做的
CMD和ENTRYPOINT区别
CMD #指定容器启动的时候运行的命令,只有最后一个会生效,可以被代替
ENTRYPOINT #指定容器启动的时候运行的命令,可追加
测试CMD命令
[root@iZwz96cj54lr4szndhzbezZ dockerfile]# vim dockeefile-cmd
FROM centos
CMD ["ls","-a"]
[root@iZwz96cj54lr4szndhzbezZ dockerfile]# docker build -f dockeefile-cmd -t cmd .
#run运行
[root@iZwz96cj54lr4szndhzbezZ dockerfile]# docker run 47ac151e85da
.
..
.dockerenv
bin
dev
etc
home
lib
lib64
lost+found
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var
#想追加一个命令 -l ls -al
[root@iZwz96cj54lr4szndhzbezZ dockerfile]# docker run 47ac151e85da -l
docker: Error response from daemon: OCI runtime create failed: container_linux.go:370: starting container process caused: exec: "-l": executable file not found in $PATH: unknown.
ERRO[0000] error waiting for container: context canceled
#CMD的清理下 -l 替换了CMD["ls","-a"]命令,-l不是命令所有保存
测试ENTRYPOINT命令
#编写脚本
[root@iZwz96cj54lr4szndhzbezZ dockerfile]# vim dockerfile-entrypoint
FROM centos
ENTRYPOINT ["ls","-a"]
[root@iZwz96cj54lr4szndhzbezZ dockerfile]# docker build -f dockerfile-entrypoint -t cmd .
[root@iZwz96cj54lr4szndhzbezZ dockerfile]# docker run entrypoint
.
..
.dockerenv
bin
dev
etc
home
lib
lib64
#我们追加的命令,是直接拼接在我们的ENTRYPOINT命令后面!
[root@iZwz96cj54lr4szndhzbezZ dockerfile]# docker run entrypoint -l
total 0
drwxr-xr-x 1 root root 6 Jan 24 06:11 .
drwxr-xr-x 1 root root 6 Jan 24 06:11 ..
-rwxr-xr-x 1 root root 0 Jan 24 06:11 .dockerenv
lrwxrwxrwx 1 root root 7 Nov 3 15:22 bin -> usr/bin
dockerfile很多的命令都是十分相似的,我们需要了解它们的区别,我们最好的学习就是对比他们然后测试效果
1、准备镜像文件: tomcat压缩包,jdk压缩包
#下载tomcat
wget https://mirrors.tuna.tsinghua.edu.cn/apache/tomcat/tomcat-9/v9.0.41/bin/apache-tomcat-9.0.41.tar.gz
#下载jdk1.8
wget --no-cookies --no-check-certificate --header "Cookie: gpw_e24=http%3A%2F%2Fwww.oracle.com%2F; oraclelicense=accept-securebackup-cookie" "http://download.oracle.com/otn-pub/java/jdk/8u141-b15/336fa29ff2bb4ef291e347e091f7f4a7/jdk-8u141-linux-x64.tar.gz"
2、编写dockerfile文件,官方命名DockerFile
,build会自动寻找这个文件,就不需要-f指定文件了
FROM centos
MAINTAINER zhuzi<[email protected]>
COPY readme.txt /usr/local/readme.txt
ADD jdk-8u141-linux-x64.tar.gz /usr/local/
ADD apache-tomcat-9.0.41.tar.gz /usr/local/
RUN yum -y install vim
ENV MYPATH /usr/local
WORKDIR $MYPATH
ENV JAVA_HOME /usr/local/jdk1.8.0_141
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.41
ENV CATALINA_BASE /usr/local/apache-tomcat-9.0.41
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
EXPOSE 8080
CMD /usr/local/apache-tomcat-9.0.41/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.41/bin/logs/catalina.out
3、构建我们的镜像
docker build -t diytomcat .
4、运行起来
docker run -d -p 9090:8080 --name zhutomcat -v /home/zhu/test:/usr/local/apache-tomcat-9.0.41/webapps/test -v /home/zhu/tomcatlogs:/usr/local/apache-tomcat-9.0.41/logs diytomcat
5、访问测试
6、发布项目(由于做了卷挂载, 我们直接就可以在本地发布了)
cd /home/zhu/test
mkdir WEB-INF
cd WEB-INF
vim web.xml
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
web-app>
cd ..
vim index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>
</head>
<body>
Hello World!<br/>
</body>
</html>
访问IP:9090/test
发布到Docker Hub
1、地址,需要注册自己的账号
2、确定这个账号可以登录
3、在我们的服务器上提交自己的镜像
#先登录在提交
[root@iZwz96cj54lr4szndhzbezZ tomcatlogs]# 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 login -u 用户名
4、登录完毕之后就可以提交镜像了
[root@iZwz96cj54lr4szndhzbezZ tomcatlogs]# docker push diytomcat
Using default tag: latest
The push refers to repository [docker.io/library/diytomcat]
260ffe8a6d50: Preparing
3f712cddb48b: Preparing
e11d641fac9d: Preparing
3fcf3732082d: Preparing
2653d992f4ef: Preparing
denied: requested access to the resource is denied #被拒绝了,因为提交的时候需要带上镜像的作者
[root@iZwz96cj54lr4szndhzbezZ tomcatlogs]# docker push zhuzi/diytomcat
Using default tag: latest
The push refers to repository [docker.io/zhuzi/diytomcat]
An image does not exist locally with the tag: zhuzi/diytomcat
#解决,增加一个tag
[root@iZwz96cj54lr4szndhzbezZ tomcatlogs]# docker tag 4506821fe9c9 csulfz/tomcat:1.0
# docker tag 镜像id 作者/镜像名称:版本号
#需要注意的是这里的作者名称一定要和docker hub上面的用户名一致
提交时候也是按照层级来进行发布的。
发布镜像到阿里云
1、登录阿里云
2、找到容器镜像服务
3、创建命名空间,防止冲突,一般一个命名空间里面可以有很多个镜像
4、创建容器镜像,点击创建镜像仓库,填好信息之后,选本地仓库
5、查看仓库的详细信息
里面会有具体的镜像push操作步骤
测试
有三个网络
#问题,docker是如何处理容器网络的访问的。
[root@iZwz96cj54lr4szndhzbezZ ~]# docker run -d -P --name tomcat01 tomcat
#查看容器内部的网络地址 ip addr 发现容器启动的时候会得到一个eth0@if81 ip地址,docker分配的
[root@iZwz96cj54lr4szndhzbezZ ~]# docker exec -it 4be50fc1352a 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
80: eth0@if81: <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@iZwz96cj54lr4szndhzbezZ ~]# 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.094 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.061 ms
64 bytes from 172.17.0.2: icmp_seq=3 ttl=64 time=0.075 ms
#Linux可以ping通docker容器内部
原理
1、我们每启动一个docker容器,我们的docker就会给容器分配一个ip,我们只要安装了docker,就会有一个网卡docker0
桥接模式,使用的技术就是evth-pair技术!
我们再创建一个tomcat容器,发现又多了一对网卡
我们发现容器带来的网卡都是一对对出现的
evth-pair就是一对虚拟设备接口,他们都是一对出现的,一段连着协议,一段相互相连
正因为这个特性,evth-pair充当一个桥梁,连接各种虚拟网络设备的
OpenStack Docker容器之间的连接,ovs的连接,都是使用evth-pair技术
3、我们测试一下tomcat01能不能ping通tomcat02
[root@iZwz96cj54lr4szndhzbezZ ~]# docker exec -it tomcat02 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.145 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.086 ms
64 bytes from 172.17.0.2: icmp_seq=3 ttl=64 time=0.113 ms
^C
--- 172.17.0.2 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 62ms
发现是可以ping通的
结论:
容器和容器之间是可以互相ping通的
结论:tomcat01和tomcat02是公用一个路由器的,docker01
所有的容器不指定网络的情况下,都是docker0路由的,docker会给我们的容器分配一个默认的可用ip
小结
Docker使用的是Linux的桥接,宿主机中有一个Docker容器的桥接,docker0
Docker中的所有网络接口都是虚拟的,虚拟的转发效率高,内网传递文件
只要容器删除,对应的网桥一对就会没了。
思考
我们编写了一个微服务,database url=ip,项目不重启,数据库ip换掉了,我们下午可以处理这个问题,可以使用名字来访问这容器。==》高可用
[root@iZwz96cj54lr4szndhzbezZ ~]# docker exec -it tomcat02 ping tomcat01
ping: tomcat01: Name or service not known
#解决方法 使用--link
[root@iZwz96cj54lr4szndhzbezZ ~]# docker run -d -P --name tomcat03 --link tomcat02 tomcat
62403ff463e52c0ee41724b69e65b7106ae37254015b384daeb81e475bf7d582
[root@iZwz96cj54lr4szndhzbezZ ~]# docker exec -it tomcat03 ping tomcat02
PING tomcat02 (172.17.0.3) 56(84) bytes of data.
64 bytes from tomcat02 (172.17.0.3): icmp_seq=1 ttl=64 time=0.175 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=2 ttl=64 time=0.083 ms
#但是反向就不能ping通
[root@iZwz96cj54lr4szndhzbezZ ~]# docker exec -it tomcat02 ping tomcat03
ping: tomcat03: Name or service not known
其实就是tomcat03再启动的时候在本地配置了tomcat02的网址,做了域名解析,可以查看tomcat03的/etc/hosts文件
–link就是在hosts文件中增加了域名和地址的映射
我们现在玩docker已经不建议使用–link了
现在一般都是使用自定义网络,不适用docker0
docker0的问题:它不支持容器名进行连接访问
容器互联
#相关的查看docker网络的指令
docker network --help
网络模式
bridge:桥接模式(默认的,自己创建也使用桥接模式)
none:不配置网络
host:和宿主机共享网络
container:容器网络连通!(用的少,局限很大)
测试
#我们直接启动的命令 --net bridge 而这个就是我们的docker0
docker run -d -P --name tomcat01 tomcat
docker run -d -P --name tomcat01 --net bridge tomcat
#docker0特点,默认的,域名不能访问的,--link可以打通连接
#我们可以自定义一个网络
docker network create --help
#--driver bridge 桥接模式
#--subnet 192.168.0.0/16 子网掩码
#--gateway 192.168.0.1 网关,类似家里路由器的地址
[root@iZwz96cj54lr4szndhzbezZ ~]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
我们自己的网络就创建好了,我们
#创建两个容器基于我们刚刚创建的网络上
[root@iZwz96cj54lr4szndhzbezZ ~]# docker run -d -P --name tomcat-net-01 --net mynet tomcat
3ca146219630fcb0dbdbd0abea5b3277bde5cd5af037898611afab2279df5c43
[root@iZwz96cj54lr4szndhzbezZ ~]# docker run -d -P --name tomcat-net-02 --net mynet tomcat
3d0fb38a72ca140c0b6857175eb99fdd36ffc37f38c13df3c88d6b6d968f3678
#可以查看得到这个网络下有两个容器就是我们刚刚创建的
[root@iZwz96cj54lr4szndhzbezZ ~]# docker network inspect mynet
[
{
"Name": "mynet",
"Id": "0b7e18fe62ef35fadbe186e024a96e3c89725a0672f0729b4ce9e464153e3149",
"Created": "2021-01-25T00:16:55.10800343+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "192.168.0.0/16",
"Gateway": "192.168.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"3ca146219630fcb0dbdbd0abea5b3277bde5cd5af037898611afab2279df5c43": {
"Name": "tomcat-net-01",
"EndpointID": "80e5272e6311049ca71160202b403ddeee0d765019942f9157687cae30d5b88c",
"MacAddress": "02:42:c0:a8:00:02",
"IPv4Address": "192.168.0.2/16",
"IPv6Address": ""
},
"3d0fb38a72ca140c0b6857175eb99fdd36ffc37f38c13df3c88d6b6d968f3678": {
"Name": "tomcat-net-02",
"EndpointID": "e36304257875e423faec18a967ea5e511b2fde30a845627e95ad57778adec4a8",
"MacAddress": "02:42:c0:a8:00:03",
"IPv4Address": "192.168.0.3/16",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {}
}
]
#再次测试ping连接
[root@iZwz96cj54lr4szndhzbezZ ~]# docker exec -it tomcat-net-01 ping 192.168.0.3
PING 192.168.0.3 (192.168.0.3) 56(84) bytes of data.
64 bytes from 192.168.0.3: icmp_seq=1 ttl=64 time=0.184 ms
64 bytes from 192.168.0.3: icmp_seq=2 ttl=64 time=0.112 ms
64 bytes from 192.168.0.3: icmp_seq=3 ttl=64 time=0.113 ms
^C
--- 192.168.0.3 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 58ms
rtt min/avg/max/mdev = 0.112/0.136/0.184/0.035 ms
#现在不适使用--link也可以ping名字了
[root@iZwz96cj54lr4szndhzbezZ ~]# docker exec -it tomcat-net-01 ping tomcat-net-02
PING tomcat-net-02 (192.168.0.3) 56(84) bytes of data.
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=1 ttl=64 time=0.073 ms
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=2 ttl=64 time=0.089 ms
我们自定义的网络docker都已经帮我们维护好了对应的关系,推荐我们平时这样使用网络
好处:
redis-保证不同的集群使用不同的网络,保证集群是安全的和健康的
mysql-保证不同的集群使用不同的网络,保证集群是安全的和健康的
连接一个容器到一个网络
#测试打通,tomcat01到mynet
#连通之后,直接把tomcat01放到了mynet网络下,一个容器两个ip(公网ip,私网ip)
结论:假设要跨网络去操作别人,就需要使用docker network connect 连通
实战:Redis集群部署
#建立一个redis的网卡
docker network create redis --subnet 172.38.0.0/16
#编写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
#启动redis
for port in $(seq 1 6); \
do \
docker run -p 637${port}:6379 -p1637${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 --ip 172.38.0.1${port} redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf; \
done
#进入第一个redis容器
docker exec -it redis-1 /bin/sh
#搭建集群
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
redis集群部署完毕
我们使用了docke之后,所以的技术都会慢慢的变得简单起来
1、搭建一个springboot项目
2、打包应用
3、编写dockerfile
4、构建镜像
5、发布运行
首先在IDEA下载docker插件
#1、编写一个简单的controller
#2、然后打包成jar包
#3、编写Dockerfile
FROM java:8
COPY *.jar /app.jar
CMD ["--server.port=8080"]
EXPOSE 8080
ENTRYPOINT ["java","-jar","/app.jar"]
#4、构建自己的镜像
#5、运行镜像
#6、测试
如果有很多镜像 100个,分别启动,维护很麻烦
简介
100个微服务,依赖关系
不能手动运行,通过Docker Compose来高效管理,定义运行多个容器
官方介绍
定义、运行多个容器
YAML file配置文件。
single command。命令有哪些?
Compose is a tool for defining and running multi-container Docker applications. With Compose, you use a YAML file to configure your application’s services. Then, with a single command, you create and start all the services from your configuration. To learn more about all the features of Compose, see the list of features.
所有环境都可以使用docker Compose
Compose works in all environments: production, staging, development, testing, as well as CI workflows. You can learn more about each case in Common Use Cases.
Using Compose is basically a three-step process:
Dockerfile
so it can be reproduced anywhere.
docker-compose.yml
so they can be run together in an isolated environment.
docker-compose up
and Compose starts and runs your entire app.
作用:批量容器编排,根据配置文件启动多个容器,解决他们的依赖关系
自己的理解
Compose是Docker官方的开源项目,需要安装!
Dockerfile
让程序在任何地方运行
重要的两个概念:
项目:由一群容器组成的一套完整的业务
服务:又一个或者多个相同镜像运行起来的容器提高的service
compose
yarml配置文件
version: "3.8"
services:
web:
build: .
ports:
- "5000:5000"
volumes:
- .:/code
- logvolume01:/var/log
links:
- redis
redis:
image: redis
volumes:
logvolume01: {}
docker-compose up
Compose:重要的概念
服务services,容器。应用。(web、redis、mysql…)
项目project。一组关联的容器。博客:web、mysql、wp
安装
1.用app.py
2.DcokerFile应用打包镜像(单机)
记录每天学习生活的点点滴滴,感谢身边的每一位帮助过我的人,感谢狂神