您现在的位置是:首页 >其他 >Docker详解网站首页其他
Docker详解
一、Docker概述
1.1、Docker为什么出现
1、一款产品:开发–上线 两套环境!应用环境,应用配置!
环境配置是十分麻烦的事,每一个机器都要部署环境(集群Redis、ES、Hadoop…)费时费力
2、原来发布项目 jar、war
但是环境不会一起打包
如果可以发布项目(jar+(Redis MySql jdk es))那样就会方便很多
之前在服务器配置一个应用的环境Redis MySql jdk ES Hadoop ,配置非常麻烦,不能够跨平台
- 传统:开发jar,运维来配置环境
- 现在:开发打包部署上线,一套流程做完
Docker给以上问题提出了解决方案
java—jar(环境)—打包项目带上环境(镜像)—(Docker仓库:商店),运维要用,直接下载我们发布的镜像,直接运行即可
隔离:Docker核心思想,打包装箱,每个箱子是互相隔离的
Docker通过隔离机制,可以将服务器利用到极致
1.2、Docker的历史
2010年,几个搞IT的年轻人,在美国成立了一家公司 dotCloud ,做一些pass的云计算服务,LXC有关的容器技术
他们将自己的技术(容器化技术)命名就是Docker
Docker刚刚诞生的时候,没有引起行业的注意,于是想到开源
2013年,Docker开源
Docker越来越多的人发现了它的优点,于是火了,Docker一开始每个月都会更新一个新的版本
2014年4月9日,Docker1.0发布
- Docker为什么这么火?
轻巧!在容器技术出来之前,我们都是使用虚拟机技术
虚拟机:在windows中装一个Vmware,通过这个软件我们可以虚拟出一台或者多台电脑,很笨重!
docker:隔离,镜像,十分的小巧,运行镜像就可以了。
- Docker是基于Go语言开发,开源项目
- 官网:https://www.docker.com
- 文档!Docker的文档是超级详细的 。一定要结合文档学习
- 仓库地址:https://hub.docker.com
1.3、Docker能做什么
- 虚拟机技术缺点:
- 资源占用十分多
- 冗余步骤多
- 启动很慢
- 容器化技术:
- 容器化技术不是模拟的一个完整的操作系统
- 隔离
- 比较Docker和虚拟机技术的不同:
- 传统虚拟机,虚拟出一条硬件,运行一个完整的操作系统,然后在这个系统上安装和运行软件
- 容器内的应用直接运行在宿主机的内核,容器没有自己的内核,也没有虚拟我们的硬件,所以就轻便了
- 每个容器是互相隔离的,每个容器内都有一个属于自己的文件系统,互不影响
- DevOps(开发、运维)
应用更快速的交付和部署
传统:一堆帮助文档,安装程序,配置环境
Docker:打包镜像发布测试,一键运行
更便捷的升级和扩缩容
使用了Docker之后,我们部署应用就和搭积木一样
更简单的系统运维
在容器化之后,我们的开发,测试环境都是高度一致的
更高效的计算资源利用
Docker是内核级别的虚拟化,可以在一个物理机上运行很多的容器实例。服务器的性能可以发挥到极致!
二、Docker安装
2.1、Docker的基本组成
客户端—服务器—仓库
- 镜像(image):
docker镜像就好比是一个模板,可以通过这个模板来创建容器服务
- 容器(container):
Docker利用容器技术,独立运行一个或者一各组应用,通过镜像来创建的
启动,停止,删除,基本命令!
- 仓库(repository):
仓库就是存放镜像的地方!
仓库分为公有仓库和私有仓库!Docker Hub(默认是国外的)
阿里云…都有容器服务器(配置镜像加速)
2.2、安装Docker
1、准备:
- 一台服务器(云服务器或者虚拟机)
- CentOS7
- 环境查看
3.10.0-1160.el7.x86_64
系统内核需要是3.10以上
- 系统版本
[root@localhost ~]# cat /etc/os-release
NAME="CentOS Linux"
VERSION="7 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="7"
PRETTY_NAME="CentOS Linux 7 (Core)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:7"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"
CENTOS_MANTISBT_PROJECT="CentOS-7"
CENTOS_MANTISBT_PROJECT_VERSION="7"
REDHAT_SUPPORT_PRODUCT="centos"
REDHAT_SUPPORT_PRODUCT_VERSION="7"
2、安装
- 先卸载
yum remove docker
docker-client
docker-client-latest
docker-common
docker-latest
docker-latest-logrotate
docker-logrotate
docker-selinux
docker-engine-selinux
docker-engine
docker-ce
- 需要的安装包
yum install -y yum-utils
- 设置镜像仓库
yum-config-manager
--add-repo
https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
- 更新软件包索引
yum makecache fast
- 安装docker
yum install docker-ce docker-ce-cli containerd.io
- 启动docker
systemctl start docker
- 检查是否安装成功
docker version
- 使用docker
docker run hello-world
出现 Hello from Docker 就说明使用成功
当没有镜像时就会去下载,例如helloworld,没有就会去下载
查看镜像
可以看到刚才下载的hello-world在里面了
- 配置阿里云镜像加速
登录阿里云官方,然后找到容器镜像服务,镜像加速器
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://kynuterj.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
- 卸载docker
# 卸载依赖
yum remove docker-ce docker-ce-cli containerd.io
#删除资源
rm -rf /var/lib/docker # docker的默认工作路径
3、docker RUN机制
开始run一个镜像—> Docker会在本机寻找镜像 —> 判断本机是否有镜像,有就直接运行,没有就去docker仓库下载,下载完后再运行这个仓库
三、底层原理
- Docker是怎么工作的?
Docker是一个Client-Server结构的系统,Docker的守护进程运行在主机上。通过Socket从客户端访问!
DockerServer接收到Docker-Client的指令,就会执行这个命令
docker容器就好比是一个小的linux虚拟机,并且相互隔离
2、Docker为什么比VM快?
- Docker有着比虚拟机更少的抽象层
- docker利用的是宿主机的内核,vm需要的是Guest OS 。所以说,新建一个容器的时候,docker不需要像虚拟机一样重新加载一个操作系统的内核,避免引导。虚拟机是加载GuestOS,分钟级别的。而Docker是利用宿主机的操作系统,省略了这个复杂的过程。秒级
四、Docker的常用命令
4.1、帮助命令
docker version # 显示docker的版本信息
docker info # 显示docker系统信息,详细,包括镜像和容量的数量
docker --help # 列出来docker的命令
4.2、镜像命令
docker images # 查看所有本地的主机上的镜像
REPOSITORY —镜像的复制源
(xshell复制是ctrl+ins ,粘贴是shift+ins)
可选项:
-a:列出所有的镜像
-q:只显示镜像的id
docker search #搜索镜像
docker search --help # 可以得到这个命令的帮助
docker search mysql --filter=STARTS=3000 # 搜索出来的结果是star大于3000的
docker pull #下载镜像
docker pull xxx [:tag] #指定版本,如果不写tag就默认下载最新版
docker pull mysql:5.7
- 分层下载
docker rmi #删除镜像
docker rmi -f xxx #-f是全部删除,可以通过id删,也可以通过镜像名称删
# 删除多个容器 空格
docker rmi -f $(docker images -aq) # 删除全部的容器
4.3、容器命令
说明:我们有了镜像才可以创建容器,linux,下载一个centos镜像来测试学习
docker pull centos # 下载最新版的centos
使用镜像
docker run (image)
# 参数说明
--name="Name" 容器名字,tomcat01,tomcat02,用来区分容器
-d 后台方式运行
-it 使用交互方式运行,进入容器查看内容
-p 指定容器的端口
-P 主机端口:容器端口(常用
docker run -it centos /bin/bash #创建并进入容器
exit # 退出容器
docker ps #列出正在运行的容器
docker ps -a # 列出所有的运行过的容器
进入容器后,ctrl+q+p 可以不退出然后切换到主机下
删除容器
docker rm 容器id #删除指定id的容器 不能删除正在运行的容器,如果要强制删除, rm -f
docker rm -f $(docker ps -aq) # 删除所有的容器
启动和停止容器
docker start 容器id # 启动指定id容器
docker restart 容器id #重启
docker stop 容器id # 暂停容器
docker kill 容器id # 强制停止当前容器
后台启动容器
docker run -d centos
# 当 docker ps 的时候,发现并没有刚才后台启动的容器----这是docker的常见的坑:
当docker 后台启动一个容器的时候,必须此时要有一个前台进程(也就是-it进去容器的这种),如果此时docker发现没有任何前台进程,那么就会把后台运行的进程也停止
例如,nginx,容器启动后,发现自己没有提供服务,就会立刻停止,就是没有程序了
查看日志
docker logs
docker logs -f -t --tail nums xxx
查看容器中进程信息
docker top xxx
查看镜像的元数据
docker inspect xxx
进入当前正在运行的容器
# 我们通常容器都是使用后台方式运行的,当需要进入容器,修改一下配置时
docker exec -it 容器id /bin/bash
可以进入我们想要进的容器,然后使用容器,修改一些配置之类的
docker attach 容器id # 可以直接进入正在运行的容器的命令行,而不是新开一个窗口
- docker exec :进入容器后开启一个新的终端,可以在里面操作(常用)
- docker attach :进入容器正在执行的终端,不会启动新的进程
从容器内拷贝文件到主机上
docker cp 容器id:容器内路径 目的主机路径
五、部署应用
5.1、部署nginx
- 搜索nginx : docker search nginx
- 下载 docker pull nginx
- 运行 docker run -d --name nginx01 -p 3344:80 nginx (意思是将虚拟机的3344端口和nginx的80端口绑定,即待会通过宿主机公网ip:3344就可以访问nginx)
- 本机自测
通过ip访问
- 进入容器
(做完部署的理解:linux系统,安装那些个环境,例如redis啊jdk啊之类的,都会比在windows下安装后启动要快,这也是为什么推荐将这些环境部署到linux系统下,启动更快,而且更轻便。在linux系统中安装docker,用docker,在docker中安装环境,又会更小更方便,docker就像是一个系统,然后docker里面的镜像,可以开启成一个一个的容器,每个容器相互隔离,所以可以部署多套环境,并且这些镜像都比较小,相对于直接在linux系统下安装这些环境,还要更加方便。在docker中部署nginx,nginx默认端口是80,要和自己服务器开放的端口绑定,这样通过自己服务器的公网ip加上绑定的端口号就可以访问部署的应用了 )
5.2、部署tomcat
1、官方的使用
docker run -it --rm tomcat:9.0 # 这种方法,一般用于测试,用完就会把这个容器删除
2、创建容器并绑定端口号
[root@localhost /]# docker run -d --name tomcat01 -p 3355:8080 tomcat:9.0
091cbae35d3e54b1c0bb93748ed8541f72c22764920c7ed5660495ef21e23796
3、此时通过 192.168.180.100:3355 并不能进入到tomcat首页,原因是因为docker默认下载的tomcat是最简化版的,也就是阉割版的,我们需要做一些复制操作
[root@localhost /]# docker exec -it 091cbae35d3e /bin/bash
root@091cbae35d3e:/usr/local/tomcat# cp -r webapps.dist/* webapps
root@091cbae35d3e:/usr/local/tomcat# cd webapps
root@091cbae35d3e:/usr/local/tomcat/webapps# ls
ROOT docs examples host-manager manager
将webapps.dist/* 中的内容复制到webapps中
再次公网测试,成功进到tomcat
5.3、可视化工具
- portainer
- rancher
- 什么是portainer?
Docker图形化界面管理工具,提供一个后台面板供我们操作!
docker run -d -p 8088:9000
--restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
访问测试: http://ip:8088
得到这样一个面板
在里面可以方便直观的看到自己的容器数量还有镜像还有网络等
六、Docker镜像讲解
6.1、镜像是什么
镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码、运行时、库、环境变量和配置文件
所有的应用,直接打包docker镜像,就可以直接跑起来
如何得到镜像?
- 从远程仓库下载
- 他人拷贝
- 自己制作一个镜像 DockerFile
6.2、Docker镜像加载原理
- UnionFS (联合文件系统)
Union文件系统是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下。Union文件系统是Docker镜像的基础。镜像可以通过分层来进行继承,基于基础镜像,可以制作各种具体的应用镜像。
特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录
- Docker镜像加载原理
Docker的镜像实际上由一层一层的文件系统组成
bootfs(boot file system) 主要包含bootloader和kernel , bootloader 主要是引导加载kernel,linux刚启动时会加载bootfs文件系统,在Docker镜像的最底层是bootfs。当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基本是一致的,rootfs会有差别,因此不同的发行版可以公用bootfs
虚拟机是分钟级别的,容器是秒级的
6.3、commit镜像
docker commit # 提交容器成为一个新的副本
# 命令和git原理类似
docker commit -m="提交的描述信息" -a="作者" 容器id 目标镜像名;[TAG]
实战:
官方下载tomcat中,webapps里面是没有任何文件的,没有应用程序,所以打开tomcat容器也仍然访问不到tomcat,所以我们在前面就对tomcat容器内的webapps文件进行了复制操作。现在我们可以将这个修改了内容的tomcat容器反向打包成tomcat镜像,也就是我们修改后的镜像,基于此镜像再创建容器就可以直接访问了
容器—修改—镜像—容器
[root@localhost /]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
091cbae35d3e tomcat:9.0 "catalina.sh run" 2 hours ago Up 3 minutes 0.0.0.0:3355->8080/tcp, :::3355->8080/tcp tomcat01
[root@localhost /]# docker commit -a="xqh" -m="add webapps" 091cbae35d3e tomcat1.0
sha256:5ec5ad45d4e8c56d67965a46f03cb5ef1f86922acc124c661ab172948b751349
[root@localhost /]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
tomcat1.0 latest 5ec5ad45d4e8 6 seconds ago 685MB
nginx latest 605c77e624dd 14 months ago 141MB
tomcat 9.0 b8e65a4d736d 15 months ago 680MB
centos latest 5d0da3dc9764 18 months ago 231MB
portainer/portainer latest 580c0e4e98b0 2 years ago 79.1MB
[root@localhost /]#
commit后的镜像,会到自己的镜像目录里
七、容器数据卷
- 如果数据都在容器里,那么我们容器删除,数据就会丢失! 需求:数据要持久化
- 比如用docker安装MySQL,mysql容器删了,如果里面的数据也一并删除,删库跑路! 需求:MySQL数据可以存储在本地
解决这两个需求----也就是容器之间可以有一个数据共享的技术
Docker容器中产生的数据,同步到本地!
卷技术–目录的挂载,将我们容器内的目录,挂载到Linux上面
容器的持久化和同步操作!
7.1、使用数据卷
一、方式一:直接使用命令来挂载 -v
docker run -it -v /home/ceshi:/home centos /bin/bash
意思是将centos容器内的home目录映射到本地/home/ceshi,在centos容器home下的东西都会自动同步到本地/home/ceshi里
docker inspect 容器id 查看容器具体信息
Mounts就是挂载信息。Source是本地文件目录,destination是挂载的文件目录 — 将本地/home/ceshi 和 容器内/home 绑定
绑定后 在容器内部的操作会同步到容器外
绑定后,即便关掉容器,在容器外的操作依旧会同步到容器内
好处:我们以后修改只需要在本地修改即可,容器内会自动同步!
7.2、实战:安装MySQL
思考:MySQL的数据持久化的问题
- 安装MySql
#获取镜像
[root@localhost /]# docker pull mysql:5.7
#需要配置密码
-e MYSQL_ROOT_PASSWORD
#挂载 将配置文件和数据文件挂载到报本地
[root@localhost /]# docker run -d -p 3310:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MY_SQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7
076faa33a5d8218cdf490d2609b7cb8ff1398a0597137b0dfd74884a11c125cd
[root@localhost /]#
发现,我们挂载到本地的数据卷依旧没有丢失,这就实现了容器数据持久化功能!
7.3、具名和匿名挂载
# 匿名挂载 ,-v后面只写需要挂载出去的容器内的路径,会自动在容器外部生成一个路径
-v 容器内路径!
docker run -d -p --name nginx01 -v /etc/nginx nginx
# 查看所有卷(volume)的情况
docker volume ls
[root@localhost /]# docker run -d -P --name nginx02 -v /etc/nginx nginx
aa9ba0712bae0dd5fa360c2fd229b4fb25dba4867070437b40ed77e71007ef8f
[root@localhost /]# docker volume ls
DRIVER VOLUME NAME
local 0e11e51f5727b8865a2ce9eece159bfc767128e3dda526a9f79b3d8b1fe6aeff
local 40cf9d0ad90a9d417bb809bf34f504024f6e8c2beda3c38c392dc5a2e76e4342
local 246ada27de9db06d476ef0271d4096a85213e53ca419439a1a8ce8c5e64377b8
local 2573fe846b221ff92f1cb50a2ee20e0fb9355124c0ec388bd21200b37851fb1b
local 66083af0e0bdfc926b8097a54629e1527a2720239112a8fe3773269872cb3165
[root@localhost /]#
# 这种就是匿名挂载,我们在-v只写了容器内的路径,没有写容器外的路径!没有写目录名称
# 具名挂载
[root@localhost /]# docker run -d -P --name nginx03 -v juming-nginx:/etc/nginx nginx
141c5b2a15f34fe2c9f2d46801b0753033f0e3fdf60169fef40e1dde2b990d6b
[root@localhost /]# docker volume ls
DRIVER VOLUME NAME
local 0e11e51f5727b8865a2ce9eece159bfc767128e3dda526a9f79b3d8b1fe6aeff
local 40cf9d0ad90a9d417bb809bf34f504024f6e8c2beda3c38c392dc5a2e76e4342
local 246ada27de9db06d476ef0271d4096a85213e53ca419439a1a8ce8c5e64377b8
local 2573fe846b221ff92f1cb50a2ee20e0fb9355124c0ec388bd21200b37851fb1b
local 66083af0e0bdfc926b8097a54629e1527a2720239112a8fe3773269872cb3165
local juming-nginx
[root@localhost /]#
# 这种指定了目录名称的,就是具名挂载
所有的docker容器内的卷,没有指定目录的情况下都是在 /var/lib/docker/volumes/xxx/_data,匿名挂载是在这个路径下生成随机代码目录名,而具名挂载是在这个路径下生成指定名称的目录名
我们通过具名挂载可以方便的找到我们的一个卷,大多数情况使用的是具名挂载
如何确是具名挂载还是匿名挂载,还是指定路径挂载?
-v /容器内路径 # 匿名挂载
-v 卷名:/容器内路径 # 具名挂载
-v /容器外路径 : /容器内路径 # 指定路径挂载
# 拓展
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
#通过 -v 容器内路径:ro rw 改变读写权限
ro : 只读
rw : 可读可写
一旦设定了容器权限,容器对我们挂载出来的内容就有限定了
7.4、初始Dockerfile
方式二:Dockerfile就是用来构建docker镜像的构建文件。命令脚本
通过这个脚本可以生成镜像,镜像是一层一层的!
FORM centos
VOLUME ["volume01","volume02"]
CMD echo "----end----"
CMD /bin/bash
自己构建的镜像,就会在镜像列表里了
创建一个dockerfile文件----文件中的内容,指令大写 ----构建镜像(根据命令一层一层构建镜像)
打开自己构建的镜像,会发现两个挂载的卷。----这就是通过dockerfile来挂载卷
这个卷和外部一定有一个同步的目录! --前面我们写的命令行,只写了内部路径,是匿名挂载
7.5、数据卷容器
#根据刚才我们创建的镜像,开启容器1
[root@localhost /]# docker run -it --name docker01 afa669b6bce7
[root@735d7736d323 /]# ls -l
total 0
lrwxrwxrwx. 1 root root 7 Nov 3 2020 bin -> usr/bin
drwxr-xr-x. 5 root root 360 Apr 20 07:17 dev
drwxr-xr-x. 1 root root 66 Apr 20 07:17 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. 132 root root 0 Apr 20 07:17 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 Mar 25 13:20 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
drwxr-xr-x. 2 root root 6 Apr 20 07:17 volume01
drwxr-xr-x. 2 root root 6 Apr 20 07:17 volume02
#开启第二个容器,并继承容器1docker01,可以看到docker02也会有01挂载的那些卷
[root@localhost /]# docker run -it --name docker02 --volumes-from docker01 afa669b6bce7
[root@8a9b8253c75a /]# ls -l
total 0
lrwxrwxrwx. 1 root root 7 Nov 3 2020 bin -> usr/bin
drwxr-xr-x. 5 root root 360 Apr 20 07:19 dev
drwxr-xr-x. 1 root root 66 Apr 20 07:19 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. 124 root root 0 Apr 20 07:19 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 Mar 25 13:20 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
drwxr-xr-x. 2 root root 6 Apr 20 07:17 volume01
drwxr-xr-x. 2 root root 6 Apr 20 07:17 volume02
# 在docker01挂载的卷中添加文件,在docker02中对应的卷中也会有这个添加的文件。。
[root@localhost /]# docker attach 8a9b8253c75a
[root@8a9b8253c75a /]# ls -l
total 0
lrwxrwxrwx. 1 root root 7 Nov 3 2020 bin -> usr/bin
drwxr-xr-x. 5 root root 360 Apr 20 07:19 dev
drwxr-xr-x. 1 root root 66 Apr 20 07:19 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. 122 root root 0 Apr 20 07:19 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 Mar 25 13:20 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
drwxr-xr-x. 2 root root 30 Apr 20 07:21 volume01
drwxr-xr-x. 2 root root 6 Apr 20 07:17 volume02
[root@8a9b8253c75a /]# cd volume01
[root@8a9b8253c75a volume01]# ls
01 docker
# --volumes-from 就相当于继承一样 son extend father
这样就实现了容器之间的数据共享。并且,在删除了docker01后,docker02和dcoker03依旧可以访问共享的文件。即,只要还有一个容器还在使用共享的数据,就不会被删除
结论:
容器之间配置信息的传递,数据卷容器的生命周期一直持续到没有容器使用为止!
一旦持久化到了本地,这个时候,本地的数据是不会删除的。
八、DockerFile
dockerfile是用来构建docker镜像的文件,命令参数脚本
构建步骤:
1、编写一个dockerfile文件
2、docker build 构建成为一个镜像
3、docker run 运行镜像
4、docker push 发布镜像(DockerHub、阿里云镜像仓库)
很多官方镜像都是基础包,很多功能没有,我们通常会自己搭建自己的镜像
8.1、DockerFile构建过程
1、基础知识:
- 每个保留关键字(指令)都必须是大写字母
- 执行从上到下顺序执行
- “ #” 表示注释
- 每一个指令都会创建提交一个新的镜像层----命令一行一行执行,镜像一层一层构建
dockerfile是面向开发的,我们以后要发布项目,做镜像,就需要编写dockefile文件。
DockerFile: 构建文件,定义了一切的步骤,源代码
DockerImages:通过DockerFile构建生成的镜像,最终发布和运行的产品
8.2、DockerFile的指令
FROM #from一个基础镜像,一切从这里构建。指定基础镜像
MAINTAINER # 镜像是谁写的,姓名+邮箱
RUN #镜像构建的时候需要运行的命令
ADD # 添加本地的文件,构建的时候会自动解压。例如,要做tomcat镜像,这里add一个tomcat压缩包!添加内容
WOKEDIR # 镜像的工作目录
VOLUME #挂载卷
EXPOSE # 指定对外端口
CMD # 指定容器启动的时候要运行的命令,只有最后一个会生效,可被替代
ENTRYPOINT # 指定这个容器启动的时候要运行的命令,区别是可以追加命令
ONBULID # 当构建一个被继承DockerFile,这个时候就会运行ONBUILD的指令。触发指令
COPY #类似ADD,将我们的文件拷贝到镜像中
ENV # 构建的时候设置环境变量
8.3、实战:构建自己的centos
1创建一个自己的centos
#1、编写dockerfile文件
[root@localhost dockerfile]# vi mydockerfile-centos
[root@localhost dockerfile]# cat mydockerfile-centos
FROM centos:7
MAINTAINER xqh<791172229@qq.com>
ENV MYPATH /usr/local
WORKDIR $MYPATH
RUN yum -y install vim
RUN yum -y install net-tools
EXPOSE 80
CMD echo $MYPATH
CMD echo "----end----"
CMD /bin/bash
[root@localhost dockerfile]#
#2、构建镜像
[root@localhost dockerfile]# docker build -f mydockerfile-centos -t centos:0.1 .
可以看到构建好的镜像已经在镜像列表里了
测试运行镜像
原来的镜像是不能vim也不能ifconfig的。现在可以,这就是我们自己构建镜像时加的功能。运行后,目录也是我们在文件中指定的工作目录
查看镜像的构建历史(本地的变更历史)
区别
CMD # 指定容器启动的时候要运行的命令,只有最后一个会生效,可被替代
ENTRYPOINT # 指定这个容器启动的时候要运行的命令,区别是可以追加命令
- 用CMD,当运行容器的时候,追加参数,会直接取代配置文件里的。即只有最后一个命令的参数才会生效
- 而ENTRYPOINT 则是可以追加命令。当运行参数的时候,追加参数,会先执行配置文件里的,再执行追加的命令。
8.4、实战:构建tomcat镜像
1、准备镜像文件tomcat压缩包,jdk压缩包
2、编写dockerfile文件,官方命名Dockerfile ,build的时候会自动去寻找dockerfile文件,不用加-f
[root@localhost tomcat]# vi Dockerfile
[root@localhost tomcat]# cat Dockerfile
FROM centos:7
COPY readme.txt /usr/local/readme.txt
ADD jdk-8u341-linux-x64.tar.gz /usr/local
ADD apache-tomcat-9.0.35.tar.gz /usr/local
RUN yum -y install vim
ENV MYPATH /usr/local
WORKDIR $MYPATH
ENV JAVA_HOME /usr/local/jdk1.8.0_341
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.35
ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.35
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
EXPOSE 8080
CMD /usr/local/apache-tomcat-9.0.35/bin/startup.sh && tail -F /url/local/apache-tomcat-9.0.35/bin/logs/catalina.out
[root@localhost tomcat]#
3、构建镜像。用了官方名字后,不用再指定文件夹了,可以直接build
docker build -t diytomcat .
[root@localhost tomcat]# docker build -t diytomcat .
[+] Building 279.9s (11/11) FINISHED
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 695B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for docker.io/library/centos:7 15.5s
=> CACHED [1/6] FROM docker.io/library/centos:7@sha256:9d4bcbbb213dfd745b58be38b13b996ebb5ac315fe7571 0.0s
=> [internal] load build context 3.5s
=> => transferring context: 159.39MB 3.5s
=> [2/6] COPY readme.txt /usr/local/readme.txt 0.2s
=> [3/6] ADD jdk-8u341-linux-x64.tar.gz /usr/local 6.6s
=> [4/6] ADD apache-tomcat-9.0.35.tar.gz /usr/local 0.4s
=> [5/6] RUN yum -y install vim 250.2s
=> [6/6] WORKDIR /usr/local 0.0s
=> exporting to image 3.5s
=> => exporting layers 3.5s
=> => writing image sha256:0f8e45ff3cd8f0add0e10fc2bddfedfd44536a080951647ae1ca9c38e5c40bd7 0.0s
=> => naming to docker.io/library/diytomcat 0.0s
[root@localhost tomcat]#
4、启动镜像
5、访问测试
6、发布项目(由于做了卷挂载,我们直接在本地编写项目就可以发布了)
编写web.xml,index.jsp在挂载目录test下添加
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
</web-app>
访问项目 192.168.180.100:9090/test
可以看到自己写的页面。项目部署成功,可以直接访问
8.5、发布自己的镜像
1、发布到Dockerhub
- 地址:https://hub.docker.com 注册自己的账号
- 在服务器上提交自己的镜像
# 命令行登录,然后在push
docker login -u xxx -p xxx
docker push
push前,先用docker tag命令将要push的镜像改个名称,改为加上作者和版本号
如
docker tag diytomcat pluto80/diytomcat:1.0
push的时候要指定版本号
2、发布到阿里云镜像服务上
- 登录阿里云
- 找到容器镜像服务
- 创建命名空间
- 创建镜像仓库
- 登录,push