Docker学习笔记
Docker和虚拟机技术的不同
1 传统虚拟机,虚拟出一系列的硬件,运行出一个完整的操作系统,然后在这个系统中安装和运行软件
2 容器中的应用是直接运行在宿主机中的内核,容器是没有自己的内核的,也没有自己的硬件,所以就轻便了
3 每个容器是相互间隔的,每个容器内都有一个属于自己的文件系统,互不影响
Docker的安装
Docker的基本组成
镜像(image):
docker景象好比一个模板,可以通过这个模板来创建容器服务,通过这个镜像可以创建多个容器
容器(container)
Docker利用容器技术独立运行或一组应用,通过镜像来创建
基本命令:启动,停止,删除等
可以把容器理解为一个建议的linux系统
仓库(repository)
仓库就是存放镜像的地方,分为共有仓库和私有仓库
安装
环境准备
1、一点点的linux常用命令
2、linux系统
环境查看
# 系统内核是5.4.0
zhangbangyan@zhangbangyan-Lenovo-ideapad-Y700-15ISK:~$ uname -r
5.4.0-80-generic
# 系统版本
zhangbangyan@zhangbangyan-Lenovo-ideapad-Y700-15ISK:~$ cat /etc/os-release
NAME="Ubuntu"
VERSION="18.04.5 LTS (Bionic Beaver)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 18.04.5 LTS"
VERSION_ID="18.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=bionic
UBUNTU_CODENAME=bionic
安装
帮助文档:https://docs.docker.com/
# 卸载旧版本的docker
sudo apt-get remove docker docker-engine docker.io containerd runc
# 安装方法有三种:从镜像仓库安装(推荐)、从DEB包安装(纯手动,对于不需要网络的系统安装docker很有用)、使用便利脚本安装(在一些测试和开发环境里面使用)
从镜像安装:
#设置仓库
#1、更新apt包
sudo apt-get update
sudo apt-get install \
apt-transport-https \
ca-certificates \
curl \
gnupg \
lsb-release
#2、添加Docker的官方GPG密钥
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
#3、设置稳定库
echo \
"deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
#安装docker引擎
#1、更新apt索引以及安装最新的docker引擎
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io
#2、启动docker
systemctl start docker
#3、查看docker是否安装成功
docker version
#4、通过run来启动镜像
docker run “镜像名”#docker run hello-world
#5、查看镜像
zhangbangyan@zhangbangyan-Lenovo-ideapad-Y700-15ISK:~$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest d1165f221234 4 months ago 13.3kB
了解:卸载docker
#卸载docker引擎和包含的包
sudo apt-get purge docker-ce docker-ce-cli containerd.io
#镜像、容器不会自动删除,需要执行以下指令
sudo rm -rf /var/lib/docker
sudo rm -rf /var/lib/containerd
Run的流程和Docker原理
Docker是什么工作的?
Docker是一个client-Sever结构的系统,Docker的守护进程运行在主机上。通过Socket从客户端访问!
DockerSever接收到Docker-Client指令就会执行指令!
Docker为什么比虚拟机快?
1、Docker有着比虚拟机更少的抽象层
2、docker利用的是宿主机的内核,VM需要搭建一个新的操作系统
所以说新建一个容器的时候不需要向虚拟机那样重新加载一个新的操作内核,避免引导。虚拟机是加载操作系统,分钟级别的。而docker是利用宿主机的操作系统,省略了这个复杂的过程,秒级。
Docker的常用命令
帮助命令
docker version #显示Docker的版本信息
docker info #显示Docker的系统信息,包括镜像和容器的数量
docker 命令 --help #帮助命令,可以看到docker的相关命令
帮助文档:https://docs.docker.com/engine/reference/
镜像命令
docker images 查看本地存在的镜像
zhangbangyan@zhangbangyan-Lenovo-ideapad-Y700-15ISK:~$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest d1165f221234 4 months ago 13.3kB
#解释
REPOSITORY 镜像的仓库源
TAG 镜像的标签
IMAGE ID 镜像的id
CREATED 景象的创建时间
SIZE 镜像的大小
#可选项
Options:
-a, --all Show all images (default hides intermediate images)
--digests Show digests # 显示摘要
-f, --filter filter Filter output based on conditions provided
--format string Pretty-print images using a Go template
--no-trunc Don't truncate output #不要截断输出
-q, --quiet Only show image IDs
docker search搜索镜像
zhangbangyan@zhangbangyan-Lenovo-ideapad-Y700-15ISK:~$ docker search mysql
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
mysql MySQL is a widely used, open-source relation… 11188 [OK]
mariadb MariaDB Server is a high performing open sou… 4251 [OK]
mysql/mysql-server Optimized MySQL Server Docker images. Create… 833 [OK]
#可选项
Options:
-f, --filter filter Filter output based on conditions provided
--format string Pretty-print search using a Go template
--limit int Max number of search results (default 25)
--no-trunc Don't truncate output
#例如
zhangbangyan@zhangbangyan-Lenovo-ideapad-Y700-15ISK:~$ docker search mysql --filter=STARS=3000
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
mysql MySQL is a widely used, open-source relation… 11188 [OK]
mariadb MariaDB Server is a high performing open sou… 4251 [OK]
docker pull下载镜像
zhangbangyan@zhangbangyan-Lenovo-ideapad-Y700-15ISK:~$ docker pull mysql
Using default tag: latest #如果不写tag,默认就是latest
latest: Pulling from library/mysql
33847f680f63: Pull complete #分层下载,docker image的核心 联合文件系统
5cb67864e624: Pull complete
1a2b594783f5: Pull complete
b30e406dd925: Pull complete
48901e306e4c: Pull complete
603d2b7147fd: Pull complete
802aa684c1c4: Pull complete
715d3c143a06: Pull complete
6978e1b7a511: Pull complete
f0d78b0ac1be: Pull complete
35a94d251ed1: Pull complete
36f75719b1a9: Pull complete
Digest: sha256:8b928a5117cf5c2238c7a09cd28c2e801ac98f91c3f8203a8938ae51f14700fd #签名
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 容器id #删除单个镜像
docker rmi -f 容器id 容器id 容器id ... #删除多个镜像
docker rmi -f $(docker images -aq) #删除全部容器
容器命令
说明:有了镜像才可以创建容器,linux,下载一个centOS镜像来测试
docker pull centos
新建容器并启动
docker run [可选参数] image
# 参数说明
--name="Name" 容器名字 tomcat01 tomcat02 , 用来区分容器
-d 后台方式运行
-it 使用交互方式运行, 进入容器查看内容
-p 指定容器的端口
#测试, 启动进入容器
zhangbangyan@zhangbangyan-Lenovo-ideapad-Y700-15ISK:~$ docker run -it centos
[root@7fcd4fd44d09 /]# ls #查看容器内的文件, 基础版本,很多命令不完善
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
#从容器中退出
[root@7fcd4fd44d09 /]# exit
exit
zhangbangyan@zhangbangyan-Lenovo-ideapad-Y700-15ISK:~$ ls
Ascend build Docker学习笔记.md examples.desktop java_error_in_MINDSTUDIO_3273.log Python-3.7.5 Python-3.7.5.tgz snap tmp var 公共的 模板 视频 图片 文档 下载 音乐 桌面
列出所有在运行中的容器
#docker ps 命令
#列出当前正在运行的容器
-a #列出当前正在运行的容器+历史运行过的容器
-n=? #显示最近运行的容器
-q #只显示容器的编号
zhangbangyan@zhangbangyan-Lenovo-ideapad-Y700-15ISK:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
zhangbangyan@zhangbangyan-Lenovo-ideapad-Y700-15ISK:~$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7fcd4fd44d09 centos "/bin/bash" 4 minutes ago Exited (0) About a minute ago pensive_feynman
c88bc2806ce6 centos "/bin/bash" 8 minutes ago Exited (0) 5 minutes ago festive_brahmagupta
ee8e88ad5a29 d1165f221234 "/hello" 2 hours ago Exited (0) 2 hours ago keen_edison
5fd01b67ed44 d1165f221234 "/hello" 2 hours ago Exited (0) 2 hours ago recursing_hamilton
退出容器
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 镜像名
zhangbangyan@zhangbangyan-Lenovo-ideapad-Y700-15ISK:~$ docker run -d centos
f8a821f314e10ba93f984ad45a85003540024b9f57dc7e6a4ad039fa98f07d3a
#问题docker ps, 发现centos停止了
#常见的坑:docker容器使用后台运行必须要有一个前台进程,一旦docker发现没有应用,就会自动停止
#容器启动后,发现自己并没有提供服务,就会立刻停止
查看日志
docker logs --help
# docker logs -f -t --trail 容器id后发现日至里面没有东西是因为容器没有操作
#自己编写一个shell脚本
"while true;do echo zby;sleep 1;done"
zhangbangyan@zhangbangyan-Lenovo-ideapad-Y700-15ISK:~$ # docker run -d centos /bin/sh -c "while true;do echo zby;sleep 1;done"
41223283762e4f7e7ea3a8c351458a0eaa85cc591904eff1599fef8769274e59
# zhangbangyan@zhangbangyan-Lenovo-ideapad-Y700-15ISK:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
41223283762e centos "/bin/sh -c 'while t…" 22 seconds ago Up 21 seconds fervent_noether
# 显示日志
-tf #显示日志
--tail number #显示日志的条数
-f #跟踪日志输出
#docker logs -f -t --tail 10 41223283762e
2021-07-31T00:42:36.110432088Z zby
2021-07-31T00:42:37.114711623Z zby
2021-07-31T00:42:38.119040224Z zby
2021-07-31T00:42:39.123426760Z zby
2021-07-31T00:42:40.127736602Z zby
2021-07-31T00:42:41.131593133Z zby
2021-07-31T00:42:42.134010682Z zby
2021-07-31T00:42:43.138386661Z zby
2021-07-31T00:42:44.142655565Z zby
2021-07-31T00:42:45.147044534Z zby
2021-07-31T00:42:46.151376580Z zby
2021-07-31T00:42:47.153788476Z zby
2021-07-31T00:42:48.158548960Z zby
2021-07-31T00:42:49.162656416Z zby
查看容器中的进程信息
# docker top 容器id
zhangbangyan@zhangbangyan-Lenovo-ideapad-Y700-15ISK:~$ #docker top 41223283762e
UID PID PPID C STIME TTY TIME CMD
root 5244 5226 0 08:38 ? 00:00:00 /bin/sh -c while true;do echo zby;sleep 1;done
root 5876 5244 0 08:46 ? 00:00:00 /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 1
查看镜像的元数据
# docker inspect 容器id
zhangbangyan@zhangbangyan-Lenovo-ideapad-Y700-15ISK:~$ docker inspect 27f3809f1d88
[
{
"Id": "27f3809f1d8858088f2e8a7897926276577c12458b1f906a8dd781e1e007a25c",
"Created": "2021-07-31T00:10:33.199391228Z",
"Path": "/bin/bash",
"Args": [],
"State": {
"Status": "exited",
"Running": false,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 0,
"ExitCode": 127,
"Error": "",
"StartedAt": "2021-07-31T00:10:33.482537506Z",
"FinishedAt": "2021-07-31T00:10:50.218862098Z"
}
进入当前正在运行的容器
# 通常都是以后台方式运行容器的,有时需要进入容器,修改一些配置
docke
#命令1
docker exec -it 容器id /bin/bash
zhangbangyan@zhangbangyan-Lenovo-ideapad-Y700-15ISK:~$ #docker exec -it 41223283762e /bin/bash
[root@41223283762e /]#
#命令2
docker attach 容器id
正在执行当前的代码...
# docker exec #进入容器后开启一个新的终端,可以在里面操作
# docker attach #进入容器正在执行的终端,不会启动新的进程
把容器内的文件拷贝到主机
#docker cp 容器id =:容器内的地址 主机地址
docker cp 41223283762e :/home/test.java /home
#查看主机/home目录下的文档
zhangbangyan@zhangbangyan-Lenovo-ideapad-Y700-15ISK:~$ ls
Ascend java_error_in_MINDSTUDIO_3273.log tmp 视频 音乐
build Python-3.7.5 var 图片 桌面
Docker学习笔记.md Python-3.7.5.tgz 公共的 文档
examples.desktop snap 模板 下载
#显示正在运行的容器
zhangbangyan@zhangbangyan-Lenovo-ideapad-Y700-15ISK:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d37f9b78eb36 centos "/bin/bash" About a minute ago Up About a minute lucid_chandrasekhar
#进入正在运行中的容器
zhangbangyan@zhangbangyan-Lenovo-ideapad-Y700-15ISK:~$ docker attach d37f9b78eb36
[root@d37f9b78eb36 /]# cd /home
[root@d37f9b78eb36 home]# ls
[root@d37f9b78eb36 home]# touch test.java #创建一个空文档
[root@d37f9b78eb36 home]# ls
test.java
[root@d37f9b78eb36 home]# exit
exit
zhangbangyan@zhangbangyan-Lenovo-ideapad-Y700-15ISK:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
#将容器内的文件复制到主机上
zhangbangyan@zhangbangyan-Lenovo-ideapad-Y700-15ISK:~$ docker cp d37f9b78eb36:/home/test.java /home
#拷贝是一个手动过程,未来使用 -v 数据卷的技术实现自动拷贝
学习方式:将所有命令自己敲一遍
小结
attach #当前shell下,attach连接指定的运行镜像
build #通过dockerfile定制镜像
commit #提交当前容器为新的镜像
cp #从容器中拷贝文件或者目录到宿主机中
create #创建一个新的容器,同run,但不启动容器
diff #通过docker 查看容器的文件变化
events #从docker服务获取容器的实时事件
exec #在已运行的容器上运行命令
export #到处容器的内容流作为一个tar归档文件『对应import』
history #展示一个镜像的形成历史
images #列出系统当前镜像
import #从tar包中创建一个新的文件映像
info #显示系统相关信息
inspect #查看容器详细信息
kill #停止指定容器
load #从一个tar包中加载一个镜像
login #注册或者登陆一个docker服务器
logout #从当前docker registry 服务退出
logs #输出当前容器的日志信息
port #查看映射端口对应的容器内部源端口
pause #暂停容器
ps #列出容器列表
pull #从镜像源网站拉取指定镜像
push #推送镜像到docker源服务器
restart #重启运行的容器
rm #移除一个或多个容器
rmi #移除镜像
run #创建一个新的容器并运行
save #保存一个镜像为一个tar包
search #在docker hub上搜索镜像
start #启动容器
stop #停止容器
tag #给源中镜像打标签
top #查看容器中运行的进程信息
unpause #取消暂停容器
version #查看docker 版本号
wait #截取容器停止时的退出状态
以上的命令都是最常用的命令。
docker镜像讲解
镜像是什么
镜像是一中轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码、运行时的库、环境变量和配置文件。
所有的应用直接打包docker镜像,就可以直接跑起来
如何得到镜像:
- 远程仓库得到
- 拷贝
- 自己制作一个镜像dockerfile
Docker镜像加载原理
UnionFS(联合文件系统)
Union文件系统是一种分层、轻量级并且高性能的文件系统,他支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下( unite several directories into a single virtual filesystem)。Union文件系统是 Docker镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像
特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录
Docker镜像加载原理
docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统UnionFS。
boots(boot file system)主要包含 bootloader和 Kernel, bootloader主要是引导加 kernel, Linux刚启动时会加载bootfs文件系统,在 Docker镜像的最底层是 bootfs。这一层与我们典型的Linux/Unix系统是一样的,包含boot加载器和内核。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由 bootfs转交给内核,此时系统也会卸载bootfs。
rootfs(root file system),在 bootfs之上。包含的就是典型 Linux系统中的/dev,/proc,/bin,/etc等标准目录和文件。 rootfs就是各种不同的操作系统发行版,比如 Ubuntu, Centos等等。
平时我们安装进虚拟机的CentOS都是好几个G,为什么Docker这里才200M?
对于一个精简的OS,rootfs可以很小,只需要包合最基本的命令,工具和程序库就可以了,因为底层直接用Host的kernel,自己只需要提供rootfs就可以了。
由此可见对于不同的Linux发行版, boots基本是一致的, rootfs会有差別,因此不同的发行版可以公用bootfs.
虚拟机是分钟级别,容器是秒级!
分层理解
们可以去下载一个镜像,注意观察下载的日志输出,可以看到是一层层的在下载
思考:
为什么Docker镜像要采用这种分层的结构呢?
最大的好处,我觉得莫过于资源共享了!比如有多个镜像都从相同的Base镜像构建而来,那么宿主机只需在磁盘上保留一份base镜像,同时内存中也只需要加载一份base镜像,这样就可以为所有的容器服务了,而且镜像的每一层都可以被共享。
查看镜像分层的方式可以通过docker image inspect name命令
理解:
所有的 Docker镜像都起始于一个基础镜像层,当进行修改或培加新的内容时,就会在当前镜像层之上,创建新的镜像层。
举一个简单的例子,假如基于 Ubuntu Linux16.04创建一个新的镜像,这就是新镜像的第一层;如果在该镜像中添加 Python包,
就会在基础镜像层之上创建第二个镜像层;如果继续添加一个安全补丁,就会创健第三个镜像层该像当前已经包含3个镜像层,如下图所示(这只是一个用于演示的很简单的例子)。
在添加额外的镜像层的同时,镜像始终保持是当前所有镜像的组合,理解这一点非常重要。下图中举了一个简单的例子,每个镜像层包含3个文件,而镜像包含了来自两个镜像层的6个文件。
上图中的镜像层跟之前图中的略有区別,主要目的是便于展示文件
下图中展示了一个稍微复杂的三层镜像,在外部看来整个镜像只有6个文件,这是因为最上层中的文件7是文件5的一个更新版
这种情況下,上层镜像层中的文件覆盖了底层镜像层中的文件。这样就使得文件的更新版本作为一个新镜像层添加到镜像当中
Docker通过存储引擎(新版本采用快照机制)的方式来实现镜像层堆栈,并保证多镜像层对外展示为统一的文件系统
Linux上可用的存储引撃有AUFS、 Overlay2、 Device Mapper、Btrfs以及ZFS。顾名思义,每种存储引擎都基于 Linux中对应的件系统或者块设备技术,井且每种存储引擎都有其独有的性能特点。
Docker在 Windows上仅支持 windowsfilter 一种存储引擎,该引擎基于NTFS文件系统之上实现了分层和CoW [1]。
下图展示了与系统显示相同的三层镜像。所有镜像层堆并合井,对外提供统一的视图
特点
Docker 镜像都是只读的,当容器启动时,一个新的可写层加载到镜像的顶部!
这一层就是我们通常说的容器层,容器之下的都叫镜像层!
commit镜像
docker commit 提交容器成为一个新的副本
# 命令和git原理类似
docker commit -m="描述信息" -a="作者" 容器id 目标镜像名:[TAG]
实战测试
# 1、启动一个默认的tomcat
docker run -d -p 8080:8080 tomcat
# 2、发现这个默认的tomcat 是没有webapps应用,官方的镜像默认webapps下面是没有文件的!
docker exec -it 容器id
# 3、拷贝文件进去
# 4、将操作过的容器通过commit提交为一个镜像!我们以后就使用我们修改过的镜像即可,这就是我们自己的一个修改的镜像。
docker commit -m="描述信息" -a="作者" 容器id 目标镜像名:[TAG]
docker commit -a="kuangshen" -m="add webapps app" 容器id tomcat02:1.0
容器数据卷
什么是容器数据卷
docker的理念回顾
将应用和环境打包成一个镜像
数据?如果数据在容器中,容器删除后数据就会丢失!需求:数据可以持久化
容器之间可以有一个数据共享的技术!docker容器中产生的数据,同步到本地
这就是卷技术!目录的挂载,将我们容器内的目录挂载到linux上。
总结:容器的持久化和同步操作!容器间也是可以数据共享的!
使用数据卷
方式一:直接使用命令挂载 -v
docker run -it -v 主机目录:容器内目录 容器 /bin/bash
具名和匿名挂载
# 匿名挂载
-v 容器内路径!
docker run -d -p --name nginx01 -v /etc/nginx nginx #只指定容器目录
docker volume ls #查看所有volume的情况
# 具名挂载
docker run -d -p --name nginx02 -v juming-nginx:/etc/nginx nginx
# 通过 -v 卷名:容器内路径
# 查看一下这个卷
docker volume inspect juming-nginx
所有的docker容器内的卷,没有指定目录的情况下都是在/var/lib/docker/volumes/xxx/_data中的
我们通过具名挂载可以方便找到我们的卷,大多数情况下都是使用具名挂载
# 如何确定是具名挂载还是匿名挂载,还是指定路径挂载
-v 容器内路径 #匿名挂载
-v 卷名:容器内路径 #具名挂载
-v /宿主机路径:容器内路径 #指定路径挂载
扩展:
# 通过-v 容器内路径: ro rw 改变读写权限
ro read only #只读
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就说明这个路径只能通过宿主机来操作,容器内部无法操作!
数据卷容器
容器和容器之间进行挂载,同步数据
命令: --volumes-from
docker run -it --name docker02 --volumes-from docker01 zby:1.0
结论:
容器之间配置信息的传递,数据卷容器的生命周期一直持续到没有容器使用为止
但是一旦挂载到本地,这个时候本地的数据是不会删除的
DockerFile
DckerFile就是用来构建docker镜像的构建文件!命令脚本!
构建步骤:
1、编写一个dockerfile文件
2、docker build构建一个镜像
3、docker run运行镜像
4、docker push发布镜像(dockerhub,阿里云镜像仓库)
通过这个脚本可以生成镜像
方式二:
#编写dockerfile文件, 名字可以随意,但是建议DockerFile
#文件中的内容: 指令(大写),参数
vim dockerfile
#dockerfile文件内部的内容
FROM ubuntu
VOLUME ["volume01","volume02"]
CMD echo "...end..."
CMD /bin/bash #这里的每个命令就是镜像的一层
#查看dockerfile中的内容
zhangbangyan@zhangbangyan-Lenovo-ideapad-Y700-15ISK:~$ #cat dockerfile
FROM ubuntu
VOLUME ["volume01","volume02"]
CMD echo "...end..."
CMD /bin/bash
#创建镜像
docker build -f /home/zhangbangyan/dockerfile -t zby:1.0 .
# 查看自己创建的镜像
root@zhangbangyan-Lenovo-ideapad-Y700-15ISK:/home/zhangbangyan# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
zby 1.0 daf7a229f307 7 minutes ago 72.8MB
ubuntu latest 1318b700e415 4 days ago 72.8MB
centos latest 300e315adb2f 7 months ago 209MB
# 启动自己写的镜像
docker run -it zby:1.0
root@954a4ce3e8cb:/# ls -l
total 56
lrwxrwxrwx 1 root root 7 Jul 23 17:35 bin -> usr/bin
drwxr-xr-x 2 root root 4096 Apr 15 2020 boot
drwxr-xr-x 5 root root 360 Jul 31 08:04 dev
drwxr-xr-x 1 root root 4096 Jul 31 08:04 etc
drwxr-xr-x 2 root root 4096 Apr 15 2020 home
lrwxrwxrwx 1 root root 7 Jul 23 17:35 lib -> usr/lib
lrwxrwxrwx 1 root root 9 Jul 23 17:35 lib32 -> usr/lib32
lrwxrwxrwx 1 root root 9 Jul 23 17:35 lib64 -> usr/lib64
lrwxrwxrwx 1 root root 10 Jul 23 17:35 libx32 -> usr/libx32
drwxr-xr-x 2 root root 4096 Jul 23 17:35 media
drwxr-xr-x 2 root root 4096 Jul 23 17:35 mnt
drwxr-xr-x 2 root root 4096 Jul 23 17:35 opt
dr-xr-xr-x 316 root root 0 Jul 31 08:04 proc
drwx------ 2 root root 4096 Jul 23 17:38 root
drwxr-xr-x 5 root root 4096 Jul 23 17:38 run
lrwxrwxrwx 1 root root 8 Jul 23 17:35 sbin -> usr/sbin
drwxr-xr-x 2 root root 4096 Jul 23 17:35 srv
dr-xr-xr-x 13 root root 0 Jul 31 08:04 sys
drwxrwxrwt 2 root root 4096 Jul 23 17:38 tmp
drwxr-xr-x 13 root root 4096 Jul 23 17:35 usr
drwxr-xr-x 11 root root 4096 Jul 23 17:38 var
drwxr-xr-x 2 root root 4096 Jul 31 08:04 volume01
drwxr-xr-x 2 root root 4096 Jul 31 08:04 volume02
这个卷一定和外部有一个同步的目录!这个卷是匿名挂载
很多官方镜像都是基础包,很多功能都没有,我们通常需要自己搭建自己的镜像
DockerFile构建过程
基础知识
1、每个保留关键字(指令)都必须是大写字母
2、执行从上到下顺序进行
3、#表示注释
4、每一个指令都会创建提交一个新的镜像层,并提交
dockerfile是面向开发的,我们以后要发布项目,作镜像,就需要编写dockerfile文件,这个文件很简单!
docker镜像逐渐成为企业交付的标准,必须要掌握!
步骤:开发,部署,运维。缺一不可!
DockerFile:构建了文件,定义可一切的步骤,源代码
Dockerimages:通过dockerfile构建生成的镜像,最终发布和运行的产品
docker容器:容器就是镜像运行起来提供服务器
Docker指令
FROM #基础镜像
MAINTAINER #镜像是谁,姓名+邮箱
RUN # 镜像构建的时候需要运行的命令
ADD #步骤,tomcat镜像,这个tomcat压缩包!添加内容
WORKDIR #镜像的工作目录
VOLUME # 挂载目录
EXPOSE #保留端口配置
CMD #指定这个容器运行的时候要运行的命令,只有最后一个可以生效,可被替代
ENTRYPOINT #指定这个容器运行的时候要运行的命令,可以追加命令
ONBUILD #当构建一个被继承的DockerFile,这个时候就会运行ONBUILD指令,触发指令
COPY #类似ADD,将我们的文件拷贝到镜像中
ENV #构建的时候设置环境变量
实战测试
dockerhub中大多数的镜像都是从基本镜像加载过来的,根据需要配置软件和环境来进行构建
创建自己的centos
# 1. 编写Dockerfile的文件
[root@iZ2zeg4ytp0whqtmxbsqiiZ dockerfile]# cat mydockerfile-centos
FROM centos
MAINTAINER xiaofan<594042358@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
# 2. 通过这个文件构建镜像
# 命令 docker build -f dockerfile文件路径 -t 镜像名:[tag] .
[root@iZ2zeg4ytp0whqtmxbsqiiZ dockerfile]# docker build -f mydockerfile-centos -t mycentos:0.1 .
Successfully built d2d9f0ea8cb2
Successfully tagged mycentos:0.1
CMD和ENTRYPOINT的区别
CMD # 指定这个容器启动的时候要运行的命令,只有最后一个会生效可被替代
ENTRYPOINT # 指定这个容器启动的时候要运行的命令, 可以追加命令
测试CMD
# 1. 编写dockerfile文件
[root@iZ2zeg4ytp0whqtmxbsqiiZ dockerfile]# vim dockerfile-cmd-test
FROM centos
CMD ["ls", "-a"]
# 2. 构建镜像
[root@iZ2zeg4ytp0whqtmxbsqiiZ dockerfile]# docker build -f dockerfile-cmd-test -t cmdtest .
# 3. run运行, 发现我们的ls -a 命令生效
[root@iZ2zeg4ytp0whqtmxbsqiiZ dockerfile]# docker run ebe6a52bb125
.
..
.dockerenv
bin
dev
etc
home
lib
lib64
# 想追加一个命令 -l 变成 ls -al
[root@iZ2zeg4ytp0whqtmxbsqiiZ dockerfile]# docker run ebe6a52bb125 -l
docker: Error response from daemon: OCI runtime create failed: container_linux.go:349: starting container process caused "exec: \"-l\": executable file not found in $PATH": unknown.
[root@iZ2zeg4ytp0whqtmxbsqiiZ dockerfile]# docker run ebe6a52bb125 ls -l
# cmd的情况下 -l替换了CMD["ls", "-a"]命令, -l不是命令,所以报错了
测试ENTRYPOINT
# 1. 编写dockerfile文件
[root@iZ2zeg4ytp0whqtmxbsqiiZ dockerfile]# vim dockerfile-entrypoint-test
FROM centos
ENTRYPOINT ["ls", "-a"]
# 2. 构建文件
[root@iZ2zeg4ytp0whqtmxbsqiiZ dockerfile]# docker build -f dockerfile-entrypoint-test -t entrypoint-test .
# 3. run运行 发现我们的ls -a 命令同样生效
[root@iZ2zeg4ytp0whqtmxbsqiiZ dockerfile]# docker run entrypoint-test
.
..
.dockerenv
bin
dev
etc
home
lib
# 4. 我们的追加命令, 是直接拼接到ENTRYPOINT命令的后面的!
[root@iZ2zeg4ytp0whqtmxbsqiiZ dockerfile]# docker run entrypoint-test -l
total 56
drwxr-xr-x 1 root root 4096 Aug 13 07:52 .
drwxr-xr-x 1 root root 4096 Aug 13 07:52 ..
-rwxr-xr-x 1 root root 0 Aug 13 07:52 .dockerenv
lrwxrwxrwx 1 root root 7 May 11 2019 bin -> usr/bin
drwxr-xr-x 5 root root 340 Aug 13 07:52 dev
drwxr-xr-x 1 root root 4096 Aug 13 07:52 etc
drwxr-xr-x 2 root root 4096 May 11 2019 home
lrwxrwxrwx 1 root root 7 May 11 2019 lib -> usr/lib
lrwxrwxrwx 1 root root 9 May 11 2019 lib64 -> usr/lib64
drwx------ 2 root root 4096 Aug 9 21:40 lost+found