Docker学习入门
原文链接:https://blog.csdn.net/qq_39355828/article/details/113063430 (opens new window)
# Docker学习入门
参考狂神说java https://www.bilibili.com/video/BV1og4y1q7M4
# 1.Docker基本知识
Docker 是一个开源的应用容器引擎,基于 Go 语言 (opens new window) 并遵从 Apache2.0 协议开源。Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。 容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app),更重要的是容器性能开销极低。
Docker和虚拟机区别: 传统虚拟机:虚拟出一套硬件,运行一个完整的操作系统,然后在这个系统上安装和运行软件 Docker: 容器内的应用直接运行在宿主机的内核,容器没有自己的内核,也没有虚拟我们的硬件,所以就轻便了每个容器间是相互隔离,每个容器都有一个属于自己的文件系统,互不影响
Docker基本组成:

镜像(image)
docker镜像就好比是一个模板,可以通过这个模板来创建容器服务。
通过这个镜像可以创建多个容器(最终运行或者项目运行都是在容器中的)。
容器(container)
Docker利用容器技术,独立运行一个或者一组应用,是通过镜像来创建的。
有启动,停止,删除等Linux基本指令!
目前就可以把这个容器理解为一个简易的Linux系统
仓库(repository)
仓库就是存放镜像的地方,分为私有仓库和公有仓库;
Docker 安装
[root@VM-0-9-centos ~]# 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/"
!!
# 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、设置镜像的仓库
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# 更新yum软件包索引
yum makecache fast
# 4、安装docker相关的源 docker-ce 社区 ee 企业版
yum install docker-ce docker-ce-cli containerd.io
# 5、启动docker
systemctl start docker
# 6、使用docker version 查看是否安装成功
# 7、docker run hello-world
# 8、查看下载的这个 hello-world 镜像
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
底层原理
Docker是怎么工作的?
Docker是一个Client-Server结构的系统,Docker的守护进程运行在主机上,通过Socket从客户端访问!
DockerServer接收到Docker-Client的指令,就会执行这个命令!

Docker为什么比VM快?
- Docker有着比虚拟机更少的抽象层
- Docker利用的是宿主机的内核,VM需要的是Guest OS
所以说,新建一个容器的时候,docker不需要像虚拟机一样重新加载一个操作系统内核,避免引导。虚拟机是加载Guset OS , 分钟级别的,而docker是利用宿主机的操作系统,省略了这个复杂的过程,秒级。
# 2.Docker的常用命令
帮助命令
docker vrsion # 显示docker的版本信息
docker info # 显示docker的系统信息,包括镜像和容器的数量
docker 命令 --help # 帮助命令
123
2
3
4
镜像命令
docker images 查看所有本地主机上的镜像
# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest bf756fb1ae65 8 months ago 13.3kB
# 解释
REPOSITORY 镜像的仓库源
TAG 镜像的标签
IMAGE ID 镜像的id
CREATED 镜像的创建时间
# 可选项
-a, --all # 列出所有的镜像
-q, --quiet # 只显示镜像的id
2
3
4
5
6
7
8
9
10
11
12
13
docker search 搜索镜像
[root]# docker search mysql
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
mysql MySQL is a widely used, open-source relation… 9911
# 可选项
--filter , -f Filter output based on conditions provided
docker search mysql -f=stars=5000
2
3
4
5
6
7
8
docker pull 下载镜像
# 下载镜像 docker pull 镜像名[:tag]
[root]# docker pull mysql
Using default tag: latest # 如果不写tag,默认就是latest
latest: Pulling from library/mysql
bf5952930446: Pull complete # 分层下载,docker image的核心 联合文件系统
8254623a9871: Pull complete
938e3e06dac4: Pull complete
ea28ebf28884: Pull complete
f3cef38785c2: Pull complete
894f9792565a: Pull complete
1d8a57523420: Pull complete
6c676912929f: Pull complete
ff39fdb566b4: Pull complete
fff872988aba: Pull complete
4d34e365ae68: Pull complete
7886ee20621e: Pull complete
Digest: sha256:c358e72e100ab493a0304bda35e6f239db2ec8c9bb836d8a427ac34307d074ed # 签名
Status: Downloaded newer image for mysql:latest
docker.io/library/mysql:latest # 真实地址
# 两条命令等价
docker pull mysql
docker.io/library/mysql:latest
# 指定版本下载
docker pull mysql:5.7
[root]# docker pull mysql:5.7
5.7: Pulling from library/mysql
bf5952930446: Already exists
8254623a9871: Already exists
938e3e06dac4: Already exists
ea28ebf28884: Already exists
f3cef38785c2: Already exists
894f9792565a: Already exists
1d8a57523420: Already exists
5f09bf1d31c1: Pull complete
1b6ff254abe7: Pull complete
74310a0bf42d: Pull complete
d398726627fd: Pull complete
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
docker rmi 删除镜像
[root]# docker rmi -f 容器id # 删除指定的容器
[root]# docker rmi -f 容器id 容器id 容器id # 删除多个容器
[root]# docker rmi -f $(docker images -aq) # 删除全部容器
2
3
容器命令
docker pull centos
新建容器并启动
docker run [可选参数] image
# 参数说明
--name = "Name" 容器名字 tomcat01,tomcat02,用来区分容器
-d 后台方式运行
-it 使用交互方式运行,进入容器查看区分
-p 指定容器的端口 -p 8080:8080
-p ip:主机端口:容器端口
-p 主机端口:容器端口(常用)
-p 容器端口
容器端口
-p 随机指定端口
# 测试,启动并进入容器
[root]# docker run -it centos /bin/bash
[root]# ls # 查看容器内的centos,基础版本,很多命令都是不完善的!
bin etc lib lost+found mnt proc run srv tmp var
dev home lib64 media opt root sbin sys usr
# 从容器中退回主机
[root]# exit
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
列出所有的运行的容器
# docker ps 命令
# 列出当前正在运行的容器
-a # 列出当前正在运行的容器+带出历史运行过的容器
-n=? # 显示最近创建的容器
-q # 只显示容器的编号
2
3
4
5
退出容器
exit # 直接容器停止并退出
Ctrl + P + Q # 容器不停止退出
2
删除容器
docker rm 容器id # 删除指定容器,不能删除正在运行的容器,如果要强制删除 rm -f
docker rm -f $(docker ps -aq) # 删除所有的容器
docker ps -aq|xargs docker rm # 删除所有的容器
2
3
启动和停止容器的操作
docker start 容器id # 启动容器
docker restart 容器id # 重启容器
docker stop 容器id # 停止当前正在运行的容器
docker kill 容器id # 强制停止当前容器
2
3
4
常用其他命令
后台启动容器
# 命令 docker run -d 镜像名
[root]# docker run -d centos
# 问题docker ps, 发现 centos 停止了
# 常见的坑, docker容器使用后台运行,就必须要有一个前台进程,docker发现没有应用,就会自动停止
# nginx,容器启动后,发现自己没有提供服务,就会立刻停止,就是没有程序了
2
3
4
5
6
7
查看日志
docker logs -f -t --tail 容器,没有日志
# 自己编写一段shell脚本
[root]# docker run -d centos /bin/sh -c "while true;do echo kuangshen;sleep 1;done"
# 显示日志
-tf # 显示日志
--tail number # 要显示的日志条数
2
3
4
5
6
7
8
查看容器中的进程信息ps
# 命令 docker top 容器id
[root]# docker top f1178d5b0bd8
2
3
进入当前正在运行的容器
# 我们通常都是使用后台方式运行的,需要进入容器,修改一些配置
# 命令
docker exec -it 容器id baseShell
# 测试
[root]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f1178d5b0bd8 centos "/bin/sh -c 'while t…" 2 hours ago Up 2 hours stupefied_colden
[root]# docker exec -it f1178d5b0bd8 /bin/bash
[root]# ls
bin etc lib lost+found mnt proc run srv tmp var
dev home lib64 media opt root sbin sys usr
[root]# ps -ef
UID PID PPID C STIME TTY TIME CMD
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 3.Docker镜像
镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,他包含运行某个软件所需的所有内容,包括代码、运行时库、环境变量和配置文件。
如何得到镜像:
- 从远程仓库下载
- 拷贝
- 自己制作一个镜像 DockerFile
Docker镜像加载原理
UnionFs (联合文件系统)
UnionFs(联合文件系统):Union文件系统(UnionFs)是一种分层、轻量级并且高性能的文件系统,他支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下( 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等等。
由此可见对于不同的Linux发行版, boots基本是一致的, rootfs会有差別,因此不同的发行版可以公用bootfs.
虚拟机是分钟级别,容器是秒级!
分层理解
分层的镜像
我们可以去下载一个镜像,注意观察下载的日志输出,可以看到是一层层的在下载
思考:
为什么Docker镜像要采用这种分层的结构呢?
比如有多个镜像都从相同的Base镜像构建而来,那么宿主机只需在磁盘上保留一份base镜像,同时内存中也只需要加载一份base镜像,这样就可以为所有的容器服务了,而且镜像的每一层都可以被共享。
查看镜像分层的方式可以通过docker image inspect name命令
理解:
所有的 Docker镜像都起始于一个基础镜像层,当进行修改或培加新的内容时,就会在当前镜像层之上,创建新的镜像层。
举一个简单的例子,假如基于 Ubuntu 创建一个新的镜像,这就是新镜像的第一层;如果在该镜像中添加 Python包, 就会在基础镜像层之上创建第二个镜像层;如果继续添加一个安全补丁,就会创健第三个镜像层该像当前已经包含3个镜像层。在添加额外的镜像层的同时,镜像始终保持是当前所有镜像的组合,
Docker 镜像都是只读的,当容器启动时,一个新的可写层加载到镜像的顶部!
这一层就是我们通常说的容器层,容器之下的都叫镜像层!
![外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
commit镜像
docker commit 提交容器成为一个新的副本
# 命令和git原理类似
docker commit -m="描述信息" -a="作者" 容器id 目标镜像名:[TAG]
2
3
4
# 4.Docker进阶
# 容器数据卷
什么是容器数据卷
将应用和环境打包成一个镜像!数据?如果数据都在容器中,那么我们容器删除,数据就会丢失!需求:数据可以持久化
容器之间可以有一个数据共享的技术!Docker容器中产生的数据,同步到本地!
这就是卷技术!目录的挂载,将我们容器内的目录,挂载到Linux上面!
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RMOdtq6f-1611411390190)(C:\Users\lhh31\AppData\Roaming\Typora\typora-user-images\1611410934228.png)]](/csdn-assets/113063430/image-05.png)
总结一句话:容器的持久化和同步操作!容器间也是可以数据共享的!
实战:安装MySQL
思考:MySQL的数据持久化问题
# 获取镜像
[root]# docker pull mysql:5.7
# 运行容器,需要做数据挂载! # 安装启动mysql, 需要配置密码的,这是要注意的点!
# 参考官网hub
docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag
# 启动我们的
-d 后台运行
-p 端口映射
-v 卷挂载
-e 环境配置
--name 容器名字
[root]# 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 mysql01 mysql:5.7
# 启动成功之后,我们使用本地Navicat连接测试
# 在本地测试创建一个数据库,查看一下我们映射的路径是否ok!
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
假设我们将容器删除,我们挂载到本地的数据卷依旧没有丢失,这就实现了容器数据持久化功能。
# DockerFile
dockerfile是用来构建docker镜像的文件!命令参数脚本!
构建步骤:
- 编写一个dockerfile文件
- docker build 构建称为一个镜像
- docker run运行镜像
- docker push发布镜像(DockerHub 、阿里云仓库)
DockerFile构建过程
基础知识:
- 每个保留关键字(指令)都必须是大写字母
- 执行从上到下顺序执行
- /# 表示注释
- 每一个指令都会创建提交一个新的镜像层,并提交!
dockerfile是面向开发的,我们以后要发布项目,做镜像,就需要编写dockerfile文件,这个文件十分简单!
Docker镜像逐渐成为企业交付的标准,必须要掌握!
步骤:开发,部署,运维
DockerFile : 构建文件,定义了一切的步骤,源代码
DockerImages : 通过DokerFile构建生成的镜像,是最终发布和运行的产品
Docker容器:容器就是镜像运行起来提供服务器
DockerFile的指令
以前我们使用别人的,现在我们知道了这些指令之后,我们来练习自己写一个镜像!
FROM # 基础镜像,一切从这里开始构建
MAINTAINER # 镜像是谁写的, 姓名+邮箱
RUN # 镜像构建的时候需要运行的命令
ADD # 步骤,tomcat镜像,这个tomcat压缩包!添加内容 添加同目录
WORKDIR # 镜像的工作目录
VOLUME # 挂载的目录
EXPOSE # 保留端口配置
CMD # 指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替代。
ENTRYPOINT # 指定这个容器启动的时候要运行的命令,可以追加命令
ONBUILD # 当构建一个被继承 DockerFile 这个时候就会运行ONBUILD的指令,触发指令。
COPY # 类似ADD,将我们文件拷贝到镜像中
ENV # 构建的时候设置环境变量!
2
3
4
5
6
7
8
9
10
11
12
ocker容器:容器就是镜像运行起来提供服务器
DockerFile的指令
以前我们使用别人的,现在我们知道了这些指令之后,我们来练习自己写一个镜像!
FROM # 基础镜像,一切从这里开始构建
MAINTAINER # 镜像是谁写的, 姓名+邮箱
RUN # 镜像构建的时候需要运行的命令
ADD # 步骤,tomcat镜像,这个tomcat压缩包!添加内容 添加同目录
WORKDIR # 镜像的工作目录
VOLUME # 挂载的目录
EXPOSE # 保留端口配置
CMD # 指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替代。
ENTRYPOINT # 指定这个容器启动的时候要运行的命令,可以追加命令
ONBUILD # 当构建一个被继承 DockerFile 这个时候就会运行ONBUILD的指令,触发指令。
COPY # 类似ADD,将我们文件拷贝到镜像中
ENV # 构建的时候设置环境变量!
2
3
4
5
6
7
8
9
10
11
12