Docker的安装
Docker的基本组成
镜像:
好比是一个模板,通过这个模板来创建容器服务。一个镜像可以创建多个容器(最终的服务运行或者项目运行就是在容器中的)。
容器:
Docker利用容器技术,独立运行一个或一个组应用。通过镜像来创建的。
可以理解为一个简易的linux系统
仓库:
仓库式用来存放镜像的。仓库分为公有的和私有的
安装Docker
环境准备
1、需要一点点的linux的基础
2、CentOS7
3、使用xshell连接远程服务器
环境查看
进入Docker
hello word
启动docker
sudo systemctl start docker
启动hello-world
sudo docker run hello-world
运行结果如下
hello word运行流程
docker底层工作原里
docker是怎么工作的
Docker是一个client-Service的系统,Docker守护进程运行在主机上,通过Socket从客户端访问
DockerService接收到Docker-Client的指令就会执行这个指令
Docker为什么比VM快
1、Docker有比虚拟机更少的抽象层
2、Docker利用的是宿主机的内核,新建一个容器的时候,docker不需要像虚拟机一样加载一个操作系统内核,避免引导 操作,而Docker利用宿主机的操作组系统,省略了这个复杂的过程
Docker的常用命令
帮助命令
docker version # 显示Docker的本本信息
docker info # 显示Docker的系统信息
dcker 命令 --help # 万能命令
镜像命令
- docker images 查看所有本地主机上的镜像
- docker search 搜索镜像
- docker puu xxx[: tag ] 下载镜像(默认是最新版本)
- docker rmi -f xxxxId 删除镜像
容器命令
有了镜像才可以创建容器,下载一个centos 镜像来测试学习
docker pull centos
新建容器并启动
docker run [ 可选参数] image
– name =“Name” 容器名
-d 后台交互方式运行
-it 使用交互方式运行,进入容器查看内容
-p 指定容器的端口 -p

从容器中能够退回主机
exit # 直接退出
Ctrl+p+q # 不停止容器并退出
列出所有运行的容器
docker ps
-a # 显示出所有的历史运行过得容器
删除容器
docker rm 容器 id # 删除指定的容器
docker rm -f $(docker ps -aq) # 删除所有的容器
启动和停止容器
docker start 容器id
docker restart 容器id
docker stop 容器id
docker kill 容器id
常用其他命令
后台启动容器
docker run -d centos
# 问题 docker ps : 发现centos停止了
# docker容器使用后台运行,就必须要有一个前台进程, 否则会自停止
进入当前正在运行的容器
docker exec -it 7080cef4e8ab /bin/bash # 打开一个新的终端进入当前容器
docker attach 7080cef4e8ab #在当前终端运行容器
Docker安装nginx
# 1、搜索镜像 docker search nginx
# 2、下载镜像 docker pull nginx
# 3、运行测试
# -d 后台运行
# --name 容器命名
# -p 宿主机端口, 容器内部端口
[root@iZf8zeb4pvftjcmv58dmy8Z ~]# docker run -d --name nginx01 -p:3344Z:80 nginx
docker: Invalid hostPort: 3344Z.
See 'docker run --help'.
[root@iZf8zeb4pvftjcmv58dmy8Z ~]# docker run -d --name nginx01 -p:3344:80 nginx
435c6431c466a449d45d1e212e412eeea3ac13e5679378ffe6035ddb360c377d
[root@iZf8zeb4pvftjcmv58dmy8Z ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
435c6431c466 nginx "/docker-entrypoint.…" 11 seconds ago Up 10 seconds 0.0.0.0:3344->80/tcp, :::3344->80/tcp nginx01
[root@iZf8zeb4pvftjcmv58dmy8Z ~]# curl localhost:3344
<!DOCTYPE html>
<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
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
端口暴露
Docker 部署tomcat
# 创建之后的容器用完即删
[root@iZf8zeb4pvftjcmv58dmy8Z ~]# docker run -it --rm tomcat:9.0
# 进入容器,Tomcat是阉割版的,阿里云选择了最小的镜像
[root@iZf8zeb4pvftjcmv58dmy8Z ~]# docker exec -it tomcat01 /bin/bash
root@6f44a448ef61:/usr/local/tomcat# ll
bash: ll: command not found
root@6f44a448ef61:/usr/local/tomcat# ls
BUILDING.txt NOTICE RUNNING.txt lib temp work
CONTRIBUTING.md README.md bin logs webapps
LICENSE RELEASE-NOTES conf native-jni-lib webapps.dist
root@6f44a448ef61:/usr/local/tomcat# ^C
root@6f44a448ef61:/usr/local# cd tomcat
root@6f44a448ef61:/usr/local/tomcat# cd webapps
root@6f44a448ef61:/usr/local/tomcat/webapps# clear
root@6f44a448ef61:/usr/local/tomcat/webapps# cd ..
root@6f44a448ef61:/usr/local/tomcat# ls
BUILDING.txt NOTICE RUNNING.txt lib temp work
CONTRIBUTING.md README.md bin logs webapps
LICENSE RELEASE-NOTES conf native-jni-lib webapps.dist
root@6f44a448ef61:/usr/local/tomcat# cd webapp.dist
bash: cd: webapp.dist: No such file or directory
root@6f44a448ef61:/usr/local/tomcat# cd webapps.dist
root@6f44a448ef61:/usr/local/tomcat/webapps.dist# ls
ROOT docs examples host-manager manager
root@6f44a448ef61:/usr/local/tomcat/webapps.dist# cd ..
root@6f44a448ef61:/usr/local/tomcat# cp webapps.dist/*webapps
cp: missing destination file operand after 'webapps.dist/*webapps'
Try 'cp --help' for more information.
root@6f44a448ef61:/usr/local/tomcat# cp webapps.dist/* webapps
cp: -r not specified; omitting directory 'webapps.dist/ROOT'
cp: -r not specified; omitting directory 'webapps.dist/docs'
cp: -r not specified; omitting directory 'webapps.dist/examples'
cp: -r not specified; omitting directory 'webapps.dist/host-manager'
cp: -r not specified; omitting directory 'webapps.dist/manager'
root@6f44a448ef61:/usr/local/tomcat# cp -r webapps.dist/* webapps
root@6f44a448ef61:/usr/local/tomcat# cd webapps
root@6f44a448ef61:/usr/local/tomcat/webapps# ls
ROOT docs examples host-manager manager
Docker镜像讲解
镜像是什么
镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,包含运行某个软件所需的所有内容,包括代码、运行时、库、环境变量和配置文件
所有的应用,直接打包docker的镜像,就可以直接跑起来
如何得到镜像
- 从远程仓库下载
- 朋友拷贝
- 自己制作
Docker 镜像加载原理
UnionFS(联合文件系统)
UnionFS(联合文件系统):Union文件系统是一种分层、轻量级并且高性能的文件系统,他支持对文件系统的修改作为一次提交来一层层的叠加,同时可以经不同目录加载到同一个虚拟文件系统下。Union文件系统是Docker镜像的基础。镜像可以通过分层来进行继承、基于基础镜像,可以制作各种具体的应用镜像。
特性:
一次同时加载多个文件系统,但从外面来看,只能看到一个文件系统,联合加载时会把各层文件系统叠加起来,这样最终的文件系统会包含所有的底层文件和目录
Docker镜像的加载原理
docker的镜像实际上是由一层一层的文件系统组成,这种层级的文件称为UnionFs
bootfs(boot file system)主要包含bootlloader和kernel。bootloader主要是引导加载kernel,linux刚启动时回家再bootfs文件系统,在Docker镜像的最底层是bootfs,这一层与我们典型的linux、unix是一样的,包含bootloader和kernel。当boot加载完成之后,整个内核都在内存之中了,此时内存的使用权已由bootfs转交给内核,此时系统也会卸载bootfs
对于一个精简的Os,rootfs可以很小,只需要包含最基本的命令,工具和程序就可以了。因为底层直接用host的kerne,子集只需要提供rootfs就可以了
特点
Docker镜像的都只是可读的,当容器启动时,一个新的可写层被加载到镜像的顶部。这一层就是我们所说的容器层,容器之下的都叫镜像层
commit镜像
docker comit 提交容器作为一个新的副本
# 命令和git原理相似
docker comit -m="提交的描述信息" -a="作者" 容器id 目标镜像名:[TAG]
容器数据卷
什么是容器数据卷
docker的理念回顾
将应用和环境的打成一个包
卷技术
容器之间可以有一个数据共享的技术!Docker容器中产生的数据,同步到本地。
将我们容器中搞得内容挂载到linux上面
实现了容器数据的持久化,同步操作和共享数据
使用数据卷
方式一:直接使用命令来挂载
docker run -it -v 主机目录:容器目录
[root@iZf8zeb4pvftjcmv58dmy8Z ~]# docker run -it -v /home/ceshi:/home centos /bin/bash
# 在新开的终端上查看容器详情
[root@iZf8zeb4pvftjcmv58dmy8Z home]# docker inspect 3185b5c2e196
保持同步,双向绑定
修改主机中的test.java看容器中的文件是否被修改
如上图容器中的文件也有了相同的修改
所以我们以后修改只需要在本地进行修改,容器内会自动同步
安装Mysql
思考:Mysql的数据持久化问题
docker镜像中已经有mysql的驱动
阿里云服务器设置安全组3310端口的规则
# 运行容器,需要做数据挂载:# 安装启动MySQl,需要配置密码
# -d 后台运行
# -p 端口映射
# -v 卷挂载
# -e 环境设置
--name
[root@iZf8zeb4pvftjcmv58dmy8Z ~]# 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=y15760946474 mysql:8.0.22
221af180638cfe66ea7f999c110ab4f58beb31746b33972e7fc8ff259cda4896
点击测试连接
在此连接下本地新建一个数据库test,查看本地的data中的文件信息
删除mysql容器
[root@iZf8zeb4pvftjcmv58dmy8Z ~]# docker rm -f 221af180638c
221af180638c
[root@iZf8zeb4pvftjcmv58dmy8Z ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@iZf8zeb4pvftjcmv58dmy8Z ~]# docker ps -a
# 查看所有容器,没有mysql的容器
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3185b5c2e196 centos "/bin/bash" 5 hours ago Exited (0) 4 minutes ago adoring_galileo
6f44a448ef61 tomcat "catalina.sh run" 8 hours ago Exited (143) 5 hours ago tomcat01
435c6431c466 nginx "/docker-entrypoint.…" 10 hours ago Exited (0) 5 hours ago nginx01
7080cef4e8ab centos "/bin/bash" 10 hours ago Exited (0) 10 hours ago objective_shamir
8f6c6c1c3cb5 centos "/bin/bash" 10 hours ago Exited (0) 10 hours ago intelligent_stonebraker
efd0cc448f12 centos "/bin/bash" 11 hours ago Exited (127) 11 hours ago cranky_haslett
1262e43a87b6 hello-world "/hello" 14 hours ago Exited (0) 14 hours ago quizzical_yonath
进入本地查看数据文件是否还在
具名和匿名挂载
# 匿名挂载
-v 容器内路径
# 匿名挂载创建容器
[root@iZf8zeb4pvftjcmv58dmy8Z data]# docker run -d -P --name=nginx02 -v /ect/nginx nginx
af7faed083e60f9310743e001c145f496f1ae0e468b67b791914c2ba97fd75ba
# 查看所有挂载
[root@iZf8zeb4pvftjcmv58dmy8Z data]# docker volume ls
# 这里的name都是乱码,这就是匿名挂载
DRIVER VOLUME NAME
local cbdb1839a339d0166fec1a1f7da37e2b18c904241720d7ca92d967c5d8768523
# 具名挂载
[root@iZf8zeb4pvftjcmv58dmy8Z data]# docker run -d -P --name nginx03 -v juming-nginx:/etc/nginx nginx
ee765eb823af77ee3bd5f43ff59b9d795e6d63b94eecef8bfcdbb59072dd4bc9
[root@iZf8zeb4pvftjcmv58dmy8Z data]# docker volume ls
DRIVER VOLUME NAME
local cbdb1839a339d0166fec1a1f7da37e2b18c904241720d7ca92d967c5d8768523
# 这里的名字就是我们 -v 参数后:前的名字
# -v 卷名:容器内路径
local juming-nginx
所有的容器内的卷,没有指定本地目录的话都在 /var/lib/docker/volumes路径下
进入文件目录查看
通过具名挂载方式可以方便的找到我们的卷
如何确定匿名挂载、具名挂载、指定路径挂载
-v 容器内路径 # 匿名挂载
-v 卷名:容器内路径 # 具名挂载
-v /宿主机路径:容器内路径 # 指定路径挂载
#### 设定卷权限
-v 卷名:容器内路径:ro # 具名挂载只读
-v 卷名:容器内路径:rw # 具名挂载读写
初识Dockerfile
Dockerfile就是用来构建docker镜像的构建文件!命令脚本,通过这个脚本可以生成镜像。
镜像是一层一层的
# 创建docker-test-volum文件
[root@iZf8zeb4pvftjcmv58dmy8Z home]# mkdir docker-test-volume
[root@iZf8zeb4pvftjcmv58dmy8Z home]# ls
ceshi docker-test-volume ecs-assist-user mysql redis www
[root@iZf8zeb4pvftjcmv58dmy8Z home]# cd docker-test-volume
[root@iZf8zeb4pvftjcmv58dmy8Z docker-test-volume]# pwd
/home/docker-test-volume
[root@iZf8zeb4pvftjcmv58dmy8Z docker-test-volume]# vim dockerfile1
#编辑docker-test-volum文件
FROM centos
VOLUME ["volume01", "volume02"]
CMD echo "----end---"
CMD /bin/bash
#这里的每一条命令都是镜像的一层
# 创建镜像
[root@iZf8zeb4pvftjcmv58dmy8Z docker-test-volume]# docker build -f /home/docker-test-volume/dockerfile1 -t painye/centos:1.0 .
# docker执行
Sending build context to Docker daemon 2.048kB
Step 1/4 : FROM centos
---> 5d0da3dc9764
Step 2/4 : VOLUME ["volume01", "volume02"]
---> Running in 907aee532efe
Removing intermediate container 907aee532efe
---> d413bb8fd480
Step 3/4 : CMD echo "----end---"
---> Running in 37bcee35ea60
Removing intermediate container 37bcee35ea60
---> 70cca32a23a8
Step 4/4 : CMD /bin/bash
---> Running in 40fe6970a959
Removing intermediate container 40fe6970a959
---> 2b3d7952ef4a
Successfully built 2b3d7952ef4a
Successfully tagged painye/centos:1.0
# 查看所有镜像
[root@iZf8zeb4pvftjcmv58dmy8Z docker-test-volume]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
painye/centos 1.0 2b3d7952ef4a About a minute ago 231MB
nginx latest 605c77e624dd 2 months ago 141MB
tomcat 9.0 b8e65a4d736d 2 months ago 680MB
tomcat latest fb5657adc892 2 months ago 680MB
redis latest 7614ae9453d1 2 months ago 113MB
centos latest 5d0da3dc9764 6 months ago 231MB
mysql 8.0.22 d4c3cafb11d5 14 months ago 545MB
启动容器,看看有什么
[root@iZf8zeb4pvftjcmv58dmy8Z docker-test-volume]# docker run -it 2b3d7952ef4a /bin/bash
在容器中挂载的卷下创建一个txt文件
[root@iZf8zeb4pvftjcmv58dmy8Z ~]# docker inspect 2addb056d497
[root@iZf8zeb4pvftjcmv58dmy8Z docker-test-volume]# docker run -it 2b3d7952ef4a /bin/bash
# 查看容器中有什么文件
[root@2addb056d497 /]# ls -l
total 56
lrwxrwxrwx 1 root root 7 Nov 3 2020 bin -> usr/bin
drwxr-xr-x 5 root root 360 Mar 15 00:40 dev
drwxr-xr-x 1 root root 4096 Mar 15 00:40 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 14:17 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 132 root root 0 Mar 15 00:40 proc
dr-xr-x--- 2 root root 4096 Sep 15 14:17 root
drwxr-xr-x 11 root root 4096 Sep 15 14:17 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 Mar 15 00:40 sys
drwxrwxrwt 7 root root 4096 Sep 15 14:17 tmp
drwxr-xr-x 12 root root 4096 Sep 15 14:17 usr
drwxr-xr-x 20 root root 4096 Sep 15 14:17 var
# 我们自己挂载的数据卷
drwxr-xr-x 2 root root 4096 Mar 15 00:40 volume01
drwxr-xr-x 2 root root 4096 Mar 15 00:40 volume02
[root@2addb056d497 /]# ls
bin etc lib lost+found mnt proc run srv tmp var volume02
dev home lib64 media opt root sbin sys usr volume01
# 进入数据卷中创建一个文件
[root@2addb056d497 /]# cd volume01
[root@2addb056d497 volume01]# touch container.txt
# 在本机中查看容器信息找到数据卷在本机中对应的位置
[root@iZf8zeb4pvftjcmv58dmy8Z ~]# docker inspect 2addb056d497
在卷对应的目录中找到文件
假设创建镜像的时候没有挂载卷,需要手动镜像挂载卷 -v 卷名:容器内路径
数据卷容器
容器之间实现数据共享与同步
因为此处的练习基本上与之前的练习相同,就不将练习过程贴在上面了 只是命令不同
docker run -it --name 容器名 --volumes-from 父容器
有点类java的继承机制
这个地方狂神哥讲的好像有问题,我的理解是三个容器的数据卷都挂载在了主机的同一个目录里面,所以三个容器之间的卷可以共享且同步。当然如果大家有自己的理解可以评论区讨论一下
总结:
容器之间配置信息的传递,数据卷容器的生命周期一直持续到没有容器使用为止。
DockerFile
DockerFile介绍
dockerfile是用来构建docker镜像的文件!命令参数脚本
构建步骤:
- 编写·一个dockerfile文件
- docker build 构建成为一个镜像
- docker run 运行镜像
- docker push 发布镜像
Dockerfile构建过程
基础知识:
1、每个关键字都必须是大写字母
2、执行从上到下顺序执行
3、# 表示注释
4、每个指令都会创建提交一个新的镜像层,并提交
dockerfile是面向开发的。我们以后要发布项目,作镜像,就要编写dockerfile文件,这个文件十分重要
Dockerfile: 构建文件,定义了一切的步骤,源代码
Dockerimage:通过iDockerfilr构建生成的镜像,最终发布和运行的产品
Docker容器:容器就是镜像运行起来提供服务器
DockerFile的指令
FROM
MAINTAINER
RUN
ADD
WORKDIR
VOLUME
EXPOSE
CMD # 指定这个容器启动的时候要运行的命令, 只有最后一个会生效,可被替代
ENTRYPPOINT # 指定这个容器启动的时候要运行的命令,可以追加命令
ONBUID # 当构建一个被继承DockerFile,这个时候会运行ONBUID的指令。触发指令
COPY # 类似ADD,将我们文件拷贝到镜像中
ENV # 构建的时候设置换洗净变量
创建一个自己的centos
[root@iZf8zeb4pvftjcmv58dmy8Z home]# cd dockerfile
[root@iZf8zeb4pvftjcmv58dmy8Z dockerfile]# ls
[root@iZf8zeb4pvftjcmv58dmy8Z dockerfile]# vim mydockerfile
[root@iZf8zeb4pvftjcmv58dmy8Z dockerfile]# cat mydockerfile
FROM centos
MAINTAINER painye<1850384745@qq.com>
ENV MYPATH /user/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@iZf8zeb4pvftjcmv58dmy8Z dockerfile]# docker build -f mydockerfile -t mycentos:0.1 .
出错
出错原因:FROM centos 会下载centos8但是好像已经·下线了,所以镜像除了问题,改为FROM centos:7
然后继续构建镜像
查看所有的镜像
测试一下容器