1、简介
1、是什么
1、为什么会有docker出现
- 一款产品从开发到上线,从操作系统,到运行环境,再到应用配置。作为开发+运维之间的协作我们需要关心很多东西,这也是很多互联网公司都不得不面对的问题,特别是各种版本的迭代之后,不同版本环境的兼容,对运维人员都是考验
- Docker之所以发展如此迅速,也是因为它对此给出了一个标准化的解决方案。
- 环境配置如此麻烦,换一台机器,就要重来一次, 费力费时。很多人想到,能不能从根本上解决问题,软件可以带环境安装?也就是说安装的时候,把原始环境一模一样地复制过来。开发人员利用Docker可以消除协作编码时“在我的机器上可正常工作”的问题。
- 之前在服务器配置一个应用的运行环境,要安装各种软件,就拿尚硅谷电商项目的环境来说吧,Java/Tomcat/MySQL/JDBC驱动包等。安装和配置这些东西有多麻烦就不说了,它还不能跨平台。假如我们是在Windows上安装的这些环境,到了Linux 又得重新装。况且就算不跨操作系统,换另一台同样操作系统的服务器,要移植应用也是非常麻烦的。
传统上认为,软件编码开发/测试结束后,所产出的成果即是程序或是能够编译执行的二进制字节码等(java为例)。而为了让这些程序可以顺利执行,开发团队也得准备完整的部署文件,让维运团队得以部署应用程式,开发需要清楚的告诉运维部署团队,用的全部配置文件+所有软件环境。不过,即便如此,仍然常常发生部署失败的状况。Docker镜 像的设计,使得Docker得以打破过去「 程序即应用」的观念。透过镜像(images)将作业系统核心除外,运作应用程式所需要的系统环境,由下而上打包,达到应用程式跨平台间的无缝接轨运作。
2、理念
Docker是基于Go语言实现的云开源项目。Docker的主要目标是“Build, Ship and Run Any App,Anywhere”,也就是通过对应用组件的封装、分发、部署、运行等生命周期的管理,使用户的APP (可以是一个WEB应用或数据库应用等等)及其运行环境能够做到“一次封装,到处运行”。
Linux容器技术的出现就解决了这样-一个问题,而Docker就是在它的基础上发展过来的。将应用运行在Docker容器上面,而Docker容器在任何操作系统上都是一-致的,这就实现了跨平台、跨服务器。只需要一- 次配置好环境,换到别的机子上就可以- - 键部署好,大大简化了操作
3、一句话
解决了运行环境和配置问题软件容器,方便做持续集成并有助于整体发布的容器虚拟化技术。
2、能干嘛
1、之前的虚拟机技术
虚拟机(virtual machine)就是带环境安装的一种解决方案。
- 它可以在一种操作系统里面运行另干种操作系统,比如在Windows系统里面运行Linux系统。应用程序对此毫无感知,因为虚拟机看上去跟真实系统一模一样,而对于底层系统来说,虚拟机就是一个普通文件,不需要了就删掉,对其他部分毫无影响。这类虚拟机完美的运行了另一套系统,能够使应用程序,操作系统和硬件三者之间的逻辑不变。
1、虚拟机的缺点
- 资源占用多
- 冗余步骤多
-
2、容器虚拟化技术
由于前面虚拟机存在这些缺点,Linux 发展出了另一种虚拟化技术: Linux 容器(Linux Containers,缩写为LXC)。Linux容器不是模拟一个完整的操作系统,而是对进程进行隔离。有了容器,就可以将软件运行需的所有资源打包到一个隔离的容器中。容器与虚拟机不同,不需要捆绑一整套操作系统,只需要软件工作所需的库资源和设置。系统因此而变得高效轻量并保证部署在任何环境中的软件都能始终如一地运行。
1、比较Docker和传统虛拟化方式的不同之处:
- 传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程;
- 而容器内的应用进程直接运行于宿主的内核,容器内没有自己的内核,而且也没有进行硬件虚拟。因此容器要比传统虚拟机更为轻便。
- 每个容器之间互相隔离,每个容器有自己的文件系统,容器之间进程不会相互影响,能区分计算资源。
3、开发/运维
一次构建、随处运行
- 更快速的应用交付和部署口更便捷的升级和扩缩容口
- 更便捷的升级和扩缩容
- 更简单的系统运维
- 更高效的计算资源利用
4、企业级
3、去哪下
1、官网
https://www.docker.com/2、仓库
https://hub.docker.com/2、Docker安装
1、前提说明
1、CentOS Docker安装Docker支持以下的CentOS版本:
CentOS 7 (64-bit)
-
2、前提条件
目前,CentOS 仅发行版本中的内核支持Docker。
Docker运行在CentOS 7上,要求系统为64位、系统内核版本为3.10以上。
Docker运行在CentOS-6.5或更高的版本的CentOS 上,要求系统为64位、系统内核版本为2.6.32-431或者更高版本。
3、查看内核版本
[root@localhost ~]# uname -r
3.10.0-862.11.6.el7.x86_64
[root@localhost ~]# cat /etc/redhat-release
CentOS Linux release 7.5.1804 (Core)
[root@localhost ~]#
2、Docker的基本组成
1、Docker的架构图
2、镜像
Docker镜像(Image)就是一个只读的模板。镜像可以用来创建Docker容器,一个镜像可以创建很多容器。
3、容器
Docker利用容器(Container)独立运行的一个或一组应用。容器是用镜像创建的运行实例。
- 它可以被启动、开始、停止、删除。每个容器都是相互隔离的、保证安全的平台。
- 可以把容器看做是一个简易版的Linux环境(包括root用户权限、进程空间、用户空间和网络空间等)和运行在其中的应用程序。
容器的定义和镜像几乎一模一样,也是一堆层的统一视角, 唯一区别在于容器的最上面那一层是可读可写的。
4、仓库
仓库(Repository)是集中存放镜像文件的场所。
- 仓库(Repository)和仓库注册服务器(Registry) 是有区别的。仓库注册服务器上往往存放着多个仓库,每个仓库中又包含了多个镜像,每个镜像有不同的标签(tag)。
- 仓库分为公开仓库(Public) 和私有仓库(Private) 两种形式。
- 最大的公开仓库是Docker Hub(https://hub.docker.com/),
存放了数量庞大的镜像供用户下载。国内的公开仓库包括阿里云、网易云等
5、小结
需要正确的理解仓储/镜像/容器这几个概念:
- Docker本身是一个容器运行载体或称之为管理引擎。我们把应用程序和配置依赖打包好形成-一个可交付的运行环境,这个打包好的运行环境就似乎image镜像文件。只有通过这个镜像文件才能生成Docker容器。image文件可以看作是容器的模板。Docker根据image文件生成容器的实例。同
- 一个image文件,可以生成多个同时运行的容器实例。
- image文件生成的容器实例,本身也是一个文件,称为镜像文件。
- 一个容器运行一种服务,当我们需要的时候,就可以通过docker客户端创建一个对应的运行实例,也就是我们的容器
- 至于仓储,就是放了一堆镜像的地方,我们可以把镜像发布到仓储中,需要的时候从仓储中拉下来就可以了。
3、安装步骤
1、CentOS6.8安装Docker
1、yum install -y epel-release
Docker使用EPEL发布,RHEL系的OS首先要确保已经持有EPEL仓库,否则先检查OS的版本,然后安装相应的EPEL包。
2、yum install -y docker-io
3、安装后的配置文件: /etc/sysconfig/docker
4、启动Docker后台服务: service docker start
5、docker version验证
```shell [root@localhost ~]# docker version Client: Docker Engine - Community Version: 20.10.8 API version: 1.41 Go version: go1.16.6 Git commit: 3967b7d Built: Fri Jul 30 19:55:49 2021 OS/Arch: linux/amd64 Context: default Experimental: true Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
<a name="oWu7f"></a>
### 2、CentOS7安装Docker
[https://docs.docker.com/engine/install/centos/](https://docs.docker.com/engine/install/centos/)
<a name="SdrPv"></a>
### 3、mac安装docker
mack在**macOS must be version 10.14 or newer**之后推荐安装docker Desktop for mac
- 前往地址下载
[https://docs.docker.com/desktop/mac/install/](https://docs.docker.com/desktop/mac/install/)
- 根据你的mac电脑的cpu是apple的还是intel的进行下载。
下载完成就按照标准流程安装程序吧
- 安装完毕之后就可以再mac的命令行中使用docker命令了
- 安装完毕之后也可以再阿里云配置阿里云镜像加速器
- 根据阿里云的提示配置
- [https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors](https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors)
<a name="Jlsjo"></a>
## 4、Hello World
<a name="nKa2N"></a>
### 1、阿里云镜像加速
[https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors](https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors)<br /><br />配置好了镜像<br />针对Docker客户端版本大于 1.10.0 的用户<br />您可以通过修改daemon配置文件/etc/docker/daemon.json来使用加速器
```shell
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://6i77dtkl.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
- 检查加速是否生效
2、运行hello-world
docker run hello-world ```shell [root@localhost ~]# docker run hello-world Unable to find image ‘hello-world:latest’ locally latest: Pulling from library/hello-world b8dfde127a29: Pull complete Digest: sha256:0fe98d7debd9049c50b597ef1f85b7c1e8cc81f59c8d623fcb2250e8bec85b38 Status: Downloaded newer image for hello-world:latest
Hello from Docker! This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
- The Docker client contacted the Docker daemon.
- The Docker daemon pulled the “hello-world” image from the Docker Hub. (amd64)
- The Docker daemon created a new container from that image which runs the executable that produces the output you are currently reading.
- The Docker daemon streamed that output to the Docker client, which sent it to your terminal.
To try something more ambitious, you can run an Ubuntu container with: $ docker run -it ubuntu bash
Share images, automate workflows, and more with a free Docker ID: https://hub.docker.com/
For more examples and ideas, visit: https://docs.docker.com/get-started/
<a name="HcAoZ"></a>
#### 1、docker run的过程

<a name="HnLGx"></a>
## 5、底层原理
<a name="EXhwE"></a>
### 1、docker是怎么工作的
- Docker是一个Client-Server结构的系统,Docker守 护进程运行在主机上,然后通过Socket连接从客户端访问,守护进程从客户端接受命令并管理运行在主机上的容器。容器,是一个运行时环境,就是我们前面说到的集装箱。
<a name="P37Q1"></a>
### 2、为什么Docker比较虚拟机
- (1)docker有着比虚拟机更少的抽象层。由亍docker不需要Hypervisor实现硬件资源虚拟化,运行在docker容器上的程序直接使用的都是实际物理机的硬件资源。因此在CPU、内存利用率.上docker将会在效率上有明显优势。
- (2)docker利用的是宿主机的内核,而不需要GuestOS。因此,当新建一个容器时,docker不需要和虚拟机一样重新加载一个操作系统内核。仍而避免引寻、加载操作系统内核返个比较费时费资源的过程,当新建一个虛拟机时,虚拟机软件需要加载GuestOS,返个新建过程是分钟级别的。而docker由于直接利用宿主机的操作系统,则省略了返个过程,因此新建一-个docker容器只需要几秒钟。

<a name="plNTk"></a>
# 3、Docker常用命令
<a name="d6v1Q"></a>
## 1、帮助命令
- docker version : 查看版本
- docker info:docker的详细信息
- docker help: 帮助信息
```shell
[root@localhost ~]# docker help
Usage: docker [OPTIONS] COMMAND
A self-sufficient runtime for containers
Options:
--config string Location of client config files (default "/root/.docker")
-c, --context string Name of the context to use to connect to the daemon (overrides DOCKER_HOST env var and default context set with "docker context use")
-D, --debug Enable debug mode
-H, --host list Daemon socket(s) to connect to
-l, --log-level string Set the logging level ("debug"|"info"|"warn"|"error"|"fatal") (default "info")
--tls Use TLS; implied by --tlsverify
--tlscacert string Trust certs signed only by this CA (default "/root/.docker/ca.pem")
--tlscert string Path to TLS certificate file (default "/root/.docker/cert.pem")
--tlskey string Path to TLS key file (default "/root/.docker/key.pem")
--tlsverify Use TLS and verify the remote
-v, --version Print version information and quit
Management Commands:
app* Docker App (Docker Inc., v0.9.1-beta3)
builder Manage builds
buildx* Build with BuildKit (Docker Inc., v0.6.1-docker)
config Manage Docker configs
container Manage containers
context Manage contexts
image Manage images
manifest Manage Docker image manifests and manifest lists
network Manage networks
node Manage Swarm nodes
plugin Manage plugins
scan* Docker Scan (Docker Inc., v0.8.0)
secret Manage Docker secrets
service Manage services
stack Manage Docker stacks
swarm Manage Swarm
system Manage Docker
trust Manage trust on Docker images
volume Manage volumes
Commands:
attach Attach local standard input, output, and error streams to a running container
build Build an image from a Dockerfile
commit Create a new image from a container's changes
cp Copy files/folders between a container and the local filesystem
create Create a new container
diff Inspect changes to files or directories on a container's filesystem
events Get real time events from the server
exec Run a command in a running container
export Export a container's filesystem as a tar archive
history Show the history of an image
images List images
import Import the contents from a tarball to create a filesystem image
info Display system-wide information
inspect Return low-level information on Docker objects
kill Kill one or more running containers
load Load an image from a tar archive or STDIN
login Log in to a Docker registry
logout Log out from a Docker registry
logs Fetch the logs of a container
pause Pause all processes within one or more containers
port List port mappings or a specific mapping for the container
ps List containers
pull Pull an image or a repository from a registry
push Push an image or a repository to a registry
rename Rename a container
restart Restart one or more containers
rm Remove one or more containers
rmi Remove one or more images
run Run a command in a new container
save Save one or more images to a tar archive (streamed to STDOUT by default)
search Search the Docker Hub for images
start Start one or more stopped containers
stats Display a live stream of container(s) resource usage statistics
stop Stop one or more running containers
tag Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE
top Display the running processes of a container
unpause Unpause all processes within one or more containers
update Update configuration of one or more containers
version Show the Docker version information
wait Block until one or more containers stop, then print their exit codes
Run 'docker COMMAND --help' for more information on a command.
To get more help with docker, check out our guides at https://docs.docker.com/go/guides/
2、镜像命令
1、docker images:列出本地镜像
[root@localhost ~]# docker images;
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest d1165f221234 5 months ago 13.3kB
- 属性名称:
- REPOSITORY:表示镜像的仓库源
- TAG:镜像的标签
- IMAGE ID 镜像ID
- CREATED :创建时间
- SIZE:大小
Option说明
option
docker run [options] images [command][arg…]
- OPTIONS说明(常用) :有些是一个减号,有些是两个减号
- —name=”容器新名字”:为容器指定一个名称;
- -d:后台运行容器,并返回容器ID,也即启动守护式容器;
- -i: 以交互模式运行容器,通常与-t同时使用;
- -t:为容器重新分配一个伪输入终端,通常与-i同时使用;
- -P:随机端口映射;
- -p:指定端口映射,有以下四种格式
- ip:hostPort:containerPort
- ip::containerPort
- hostPort:containerPort
- containerPort
- -v:容器卷挂载:如下
- 添加 —privileged=true 可以让相当于拥有root权限,完全访问
docker run -it -p 8090:8080 -v /Users/djy/Desktop/tomcat9/test:/usr/local/apache-tomcat-9.0.52/webapp/test -v /Users/djy/Desktop/tomcat9/logs://usr/local/apache-tomcat-9.0.52/logs --privileged=true djy/mytomcat
- 添加 —privileged=true 可以让相当于拥有root权限,完全访问
常写的方式
docker run -it —name 容器名称 centos
运行了centos
djydeMacBook-Pro:~ DD$ docker run -it 300e315adb2f [root@3306b0d40969 /]# ls bin etc lib lost+found mnt proc run srv tmp var dev home lib64 media opt root sbin sys usr [root@3306b0d40969 /]# cd root/ [root@3306b0d40969 ~]# ls anaconda-ks.cfg anaconda-post.log original-ks.cfg [root@3306b0d40969 ~]# ps -ef UID PID PPID C STIME TTY TIME CMD root 1 0 0 09:04 pts/0 00:00:00 /bin/bash root 19 1 0 09:06 pts/0 00:00:00 ps -ef [root@3306b0d40969 ~]#
2、列出docker中所有运行的容器
docker ps [OPTIONS]
OPTIONS说明(常用) :
exit
- 容器停止退出
ctrl+p+q
docker rm 容器id或者容器名称
- -f 是强制删除容器
一次性删除多个容器
- docker rm -f $(docker ps -aq)
- docker ps -aq | xargs docker rm
9、重点:
1、启动守护式 docker run -d 镜像名称
使用镜像centos:latest以后台模式启动一个容器docker run -d centos
问题:然后dockerps-a进行查看,会发现容器已经退出
很重要的要说明的一点: Docker容器后台运行,就必须有一个前台进程.
容器运行的命令如果不是那些一直挂起的命令(比如运行top,tail),就是会自动退出的。
这个是docker的机制问题,比如你的web容器,我们以nginx为例,正常情况下,我们配置启动服务只需要启动响应的service即可。例如
service nginx start
但是,这样做,nginx为后台进程模式运行,就导致docker前台没有运行的应用,
这样的容器后台启动后,会立即自杀因为他觉得他没事可做了.
所以,最佳的解决方案是,将你要运行的程序以前台进程的形式运行2、查看容器日志
docker logs -f -t —tail 容器ID
- -t:加入时间戳
- -f:跟随最新的日志打印
- —tail:数字显示最后多少条
以下命令可以让 docker run -d 运行起来马上死的程序 能保持在后台运行,就是让不停的在后台自己打印日志
docker run -d centos /bin/sh -c "while true; do echo hello zzyy; sleep 2; done"
^CdjydeMacBook-Pro:~ DD$ docker logs -tf --tail 3 791c409a6668
2021-08-23T10:02:09.198967042Z hello zzyy
2021-08-23T10:02:11.205973210Z hello zzyy
2021-08-23T10:02:13.208541682Z hello zzyy
2021-08-23T10:02:15.215287531Z hello zzyy
3、查看容器内运行的进程
docker top 容器id或者容器名称
djydeMacBook-Pro:~ DD$ docker top daijunyi
UID PID PPID C STIME TTY TIME CMD
root 3039 3012 0 10:06 ? 00:00:00 /bin/bash
4、查看容器内部细节
5、进入正在运行的容器,并以命令行交互
docker exec -it 容器id 或名称 相关容器命令,但是不会进入容器直接返回结果
- 直接进入容器启动命令的终端,不会启动新的进程
djydeMacBook-Pro:~ DD$ docker exec -it daijunyi ls bin etc lib lost+found mnt proc run srv tmp var dev home lib64 media opt root sbin sys usr djydeMacBook-Pro:~ DD$
- 直接进入容器启动命令的终端,不会启动新的进程
docker attach 容器id或名称 进入容器命令交互
- 是在容器中打开新的终端,并且可以启动新的进程
djydeMacBook-Pro:~ DD$ docker attach daijunyi [root@ffbf1292f7fa /]# ls bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var [root@ffbf1292f7fa /]#
6、从容器中拷贝文件到主机上
docker cp 容器ID(或名称):容器内部路径 主机地址djydeMacBook-Pro:~ DD$ docker cp daijunyi:/tmp/abc.log Desktop/ djydeMacBook-Pro:~ DD$
4、命令总结
- 是在容器中打开新的终端,并且可以启动新的进程
attach
- Attach to a running container
- 当前shell下attach连接指定运行镜像
- build
- Build an image from a Dockerfile
- 通过Dockerfile定制镜像
- commit
- Create a new image from a container changes
- 提交当前容器为新的镜像
- ср
- Copy files/folders from the containers filesystem to the host path
- 从容器中拷贝指定文件或者目录到缩主机中
- create
- 创建一个新的容器,同run,但不启动容器
- diff
- Inspect changes on a container’s filesystem
- 查看docker容器变化
- events
- Get real time events from the server
- 从docker服务获取容器实时事件
- exec
- Run a command in an existing container
- 在已存在的容器上运行命令
- export
- Stream the contents of a container as a tar archive
- 导出容器的内容流作为一个tar归档文件[对应import]
- history
- Show the history of an image
- 展示一个镜像形成历史
- images
- List images
- 列出系统当前镜像
- import
- Create a new filesystem image from the contents of a tarball
- 从tar包中的内容创建一个新的文件系统映像[对应export]
- info
- Display system-wide information
- 显示系统相关信息
- inspect
- Return low-leve! information on a container
- 查看容器详细信息
- kill
- Kill a running container
- kill指定docker容器
- load
- Load an image from a tar archive
- 从一个tar包中加载一个镜像[对应save]
- login
- Register or Login to the docker registry server
- 注册或者登陆一个 docker源服务器
- logout
- Log out from a Docker registry server
- 从当前Docker registry退出
- logs
- Fetch the logs of a container
- 输出当前容器日志信息
- port
- Lookup the public-facing port which is NAT-ed to PRIVATE_ _PORT
- 查看映射端口对应的容器内部源端口
- pause
- Pause all processes within a container
- 暂停容器
- ps
- List containers
- 列出容器列表
- pull
- Pull an image or a repository from the docker registry server
- 从docker镜像源服务器拉取指定镜像或者库镜像
- pushPush an image or a repository to the docker registry server # 推送指定镜像或者库镜像至docker源服务器
- restart
- Restart a running container
- 重启运行的容器
- rm
- Remove one or more containers
- 移除一个或者多个容器
- rmi
- Remove one or more images
- 移除一个或多个镜像[无容器使用该镜像才可删除,否则需删除相关容器才叮继续或-f强制删除]
- run
- Run a command in a new container
- 创建一个新的容器并运行一个命令
- save
- Save an image to a tar archive
- 保存一个镜像为一个tar包[对应load]
- search
- Search for an image on the Docker Hub
- 在dockerhub中搜索镜像
- start
- Start a stopped containers
- 启动容器
- stop
- Stop a running containers
- 停止容器
- tag
- Tag an image into a repository
- 给源中镜像打标签
- top
- Lookup the running processes of a container
- 查看容器中运行的进程信息
- unpause
- Unpause a paused container.
- 取消暂停容器
- version
- Show the docker version information
- 查看docker版本号
- wait
- Block until a container stops, then print its exit code
- 截取容器停止时的退出状态值
4、Docker镜像
1、是什么
镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容包括代码、运行时、库、环境变量和配置文件。
1、UnionFS(联合文件系统)
UnionFS (联合文件系统) : Union文 件系统(UnionFS) 是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directories into asingle virtual filesystem)。Union 文件系统是Docker镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
特性: 一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录
2、Docker镜像加载原理
docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统UnionFS。bootfs(boot file system)主要包含bootloader和kernel, bpotloader主要是引导加载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发行版,bootfs基本是一致的,rootfs会有差别,因此不同的发行版可以公用bootfs。
3、镜像是分层的
4、为什么要采用这种分成结构呢
最大的一个好处就是一共享资源比如:有多个镜像都从相同的base镜像构建而来,那么宿主机只需在磁盘上保存一份base镜像,同时内存中也只需加载一份base镜像,就可以为所有容器服务了。而且镜像的每一层都可以被共享。
2、特点
Docker镜像都是只读的
- 当容器启动时,一个新的可写层被加载到镜像的顶部。
-
3、Docker镜像commit操作补充
docker commit提交容器副本使之成为一个新的镜像
docker commit -m=‘提交的描述信息’ -a=‘作者’容器ID要创建的目标镜像名:[标签名]
1、案例演示
1、从Hub.上下载tomcat镜像到本地并成功运行
- docker run -it -p 8080:8080 tomcat
- -p主机端口:docker容器端口
- -P随机分配端口
- i交互
- t:终端
docker run -it -p 8889:8080 --name tomcat8889 tomcat:8.0
- docker run -it -p 8080:8080 tomcat
2、故意删除上一步镜像生产tomcat容器的文档
djydeMacBook-Pro:~ DD$ docker exec -it 02c3533e1b26 /bin/bash root@02c3533e1b26:/usr/local/tomcat# pwd /usr/local/tomcat root@02c3533e1b26:/usr/local/tomcat# ls LICENSE NOTICE RELEASE-NOTES RUNNING.txt bin conf include lib logs native-jni-lib temp webapps work root@02c3533e1b26:/usr/local/tomcat# cd webapps/ root@02c3533e1b26:/usr/local/tomcat/webapps# ls ROOT docs examples host-manager manager root@02c3533e1b26:/usr/local/tomcat/webapps# rm -rf docs/ root@02c3533e1b26:/usr/local/tomcat/webapps# ls ROOT examples host-manager manager
3、也即当前的tomcat运行实例是一个没有文档内容的容器,以它为模板commit一个没有doc的tomcat新镜像daijunyi/tomcat:1.0
djydeMacBook-Pro:~ DD$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 02c3533e1b26 tomcat:8.0 "catalina.sh run" 11 minutes ago Up 11 minutes 0.0.0.0:8889->8080/tcp, :::8889->8080/tcp tomcat8889 djydeMacBook-Pro:~ DD$ docker commit -a 'djy' -m 'miss docs' 02c3533e1b26 daijunyi/tomcat:1.0 sha256:f207317bb4cbaa7bd718572f5ce51ca96f6864985f45769a06fffbde2aece863 djydeMacBook-Pro:~ DD$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE daijunyi/tomcat 1.0 f207317bb4cb 6 seconds ago 356MB tomcat 8.0 ef6a7c98d192 2 years ago 356MB
4、启动我们的新镜像并和原来的对比
启动我们自己的创建的镜像
每次创建新的容器就得重新映射端口外部才能访问,自己创建的镜像也一样
djydeMacBook-Pro:~ DD$ docker run -it -p 9999:8080 f207317bb4cb
5、Docker容器数据卷
1、简介
- 先来看看Docker的理念:
- 将运用与运行的环境打包形成容器运行,运行可以伴随着容器,但是我们对数据的要求希望是持久化的
- 容器之间希望有可能共享数据
- Docker容器产生的数据,如果不通过docker commit生成新的镜像,使得数据做为镜像的一部分保存下来,
- 那么当容器删除后,数据自然也就没有了。
-
2、作用
数据持久化
- 容器间集成+数据共享
- 卷就是目录或文件,存在于一个或多个容器中,由docker挂载到容器,但不属于联合文件系统,因此能够绕过Union File System提供一些用于持续存储或共享数据的特性:
- 卷的设计目的就是数据的持久化,完全独立于容器的生存周期,因此Docker不会在容器删除时删除其挂载的数据卷
特点:
(1)命令
docker run -it -v /宿主机绝对路径目录:/容器内目录 镜像名
(2)查看看数据卷是否挂载成功
djydeMacBook-Pro:~ DD$ docker run -it -v /Users/djy/dockerDataVolume:/dataVolumeContainer centos [root@bdcc55f51853 /]# ls bin dev home lib64 media opt root sbin sys usr dataVolumeContainer etc lib lost+found mnt proc run srv tmp var djydeMacBook-Pro:~ DD$ cd /Users/djy/dockerDataVolume/ djydeMacBook-Pro:dockerDataVolume DD$
用如下命令可以查看到binds里面有信息了
docker inspect 容器id "HostConfig": { "Binds": [ "/Users/djy/dockerDataVolume:/dataVolumeContainer" ],
(3)容器和宿主机之间数据共享
- (4)容器停止退出后,主机修改后数据是否同步
- 同步
(5)命令(带权限)
根目录下新建mydocker文件夹并进入
djydeMacBook-Pro:~ DD$ mkdir /Users/djy/mydocker
可在Dockerfile中使用VOLUME指令来给镜像添加一个或多个数据卷
- VOLUME[“/dataVolumeContainer”,”/dataVolumeContainer2”,”dataVolumeContainer3”]
- 说明:
- 出于可移植和分享的考虑,用-v主机目录:容器目录这种方法不能够直接在Dockerfile中实现。
- 由于宿主机目录是依赖于特定宿主机的,并不能够保证在所有的宿主机上都存在这样的特定目录。
File构建
djydeMacBook-Pro:mydocker DD$ touch dockerfile djydeMacBook-Pro:mydocker DD$ vim dockerfile
在文件中添加以下内容
FROM centos VOLUME ["/dataVolumeContainer1","/dataVolumeContainer2"] CMD echo "finished,-------success1" CMD /bin/bash
build后生成镜像
- 获得一个新镜像djy/centos
```shell
Use ‘docker scan’ to run Snyk tests against images to find vulnerabilities and learn how to fix them
djydeMacBook-Pro:mydocker DD$ docker build -f /Users/djy/mydocker/dockerfile -t djy/centos .
[+] Building 0.2s (5/5) FINISHED
=> [internal] load build definition from dockerfile 0.0s => => transferring dockerfile: 161B 0.0s => [internal] load .dockerignore 0.0s => => transferring context: 2B 0.0s => [internal] load metadata for docker.io/library/centos:latest 0.0s => [1/1] FROM docker.io/library/centos 0.0s => exporting to image 0.0s => => exporting layers 0.0s => => writing image sha256:1b520c723bd3537b274f087cb969f054dd76d481d7194 0.0s => => naming to docker.io/djy/centos 0.0s
- 获得一个新镜像djy/centos
```shell
Use ‘docker scan’ to run Snyk tests against images to find vulnerabilities and learn how to fix them
djydeMacBook-Pro:mydocker DD$ docker build -f /Users/djy/mydocker/dockerfile -t djy/centos .
[+] Building 0.2s (5/5) FINISHED
Use ‘docker scan’ to run Snyk tests against images to find vulnerabilities and learn how to fix them djydeMacBook-Pro:mydocker DD$ docker images; REPOSITORY TAG IMAGE ID CREATED SIZE djy/centos latest 1b520c723bd3 8 months ago 209MB
- run容器
```shell
djydeMacBook-Pro:mydocker DD$ docker run -it 1b520c723bd3
[root@b5902bf9f91f /]# ls
bin dev lib media proc sbin tmp
dataVolumeContainer1 etc lib64 mnt root srv usr
dataVolumeContainer2 home lost+found opt run sys var
- 通过.上述步骤,容器内的卷目录地址已经知道对应的主机目录地址哪??
主机对应默认地址
docker inspect 容器id
会看到映射的目录
但是会发现 mac先根本找不到目录,具体情况还在学习中
最终发现mac里面的挂载路径是在里面又包了一层 需要用如下命令进入 查看
stty -echo -icanon && nc -U ~/Library/Containers/com.docker.docker/Data/debug-shell.sock && stty sane
使用docker Desktop for mac 也可以查看,但是发现要开通收费版才能使用,泥马还是使用上面的命令查看吧
之后就可以 使用cd /var/lib/docker 进入相关的目录了,费劲
3、备注
4、数据卷容器
1、简介
命名的容器挂载数据卷,其它容器通过挂载这个(父容器)实现数据共享,挂载数据卷的容器,称之为数据卷容器
2、介绍
以上一步新建的镜像djy/centos为模板并运行容器dc01/dc02/dc03
他们已经具有容器卷
先启动一个父容器dc01
- 在dataVolumeContainer2新增内容
dc02/dc03继承自dc01
—volumes-from
docker run -it --name dc02 --volumes-from dc01 djy/centos
命令
- dc02/dc03分别在dataVolumeContainer2各自新增内容
- 回到dc01可以看到02/03各自添加的都能共享了
- 删除dc01,dc02修改后dc03可否访问
- 可以访问
- 删除dc02后dc03可否访问口
- 可以访问
- 新建dc04继承dc03后再删除dc03
- dc04还是可以访问
- 结论:容器之间配置信息的传递,数据卷的生命周期一直持续到没有容器使用它为止
演示案例
djydeMacBook-Pro:~ DD$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
###创建dc01
djydeMacBook-Pro:~ DD$ docker run -it --name dc01 djy/centos
[root@d672cec4719b /]# ls
bin dataVolumeContainer2 etc lib lost+found mnt proc run srv tmp var
dataVolumeContainer1 dev home lib64 media opt root sbin sys usr
[root@d672cec4719b /]# cd dataVolumeContainer2/
[root@d672cec4719b dataVolumeContainer2]# touch dc01.txt
[root@d672cec4719b dataVolumeContainer2]# ls
dc01.txt
[root@d672cec4719b dataVolumeContainer2]# djydeMacBook-Pro:~ DD$
###创建dc02 集成dc01
djydeMacBook-Pro:~ DD$ docker run -it --name dc02 --volumes-from dc01 djy/centos
[root@7c32277cb72b /]# ls
bin dataVolumeContainer2 etc lib lost+found mnt proc run srv tmp var
dataVolumeContainer1 dev home lib64 media opt root sbin sys usr
[root@7c32277cb72b /]# cd dataVolumeContainer2
[root@7c32277cb72b dataVolumeContainer2]# ls
dc01.txt
[root@7c32277cb72b dataVolumeContainer2]# touch dc02.txt
[root@7c32277cb72b dataVolumeContainer2]# djydeMacBook-Pro:~ DD$
###创建dc03 集成dc01
djydeMacBook-Pro:~ DD$ docker run -it --name dc03 --volumes-from dc01 djy/centos
[root@90d01263b8a8 /]# cd /dataVolumeContainer2/
[root@90d01263b8a8 dataVolumeContainer2]# ls
dc01.txt dc02.txt
[root@90d01263b8a8 dataVolumeContainer2]# touch dc03.txt
[root@90d01263b8a8 dataVolumeContainer2]# djydeMacBook-Pro:~ DD$
djydeMacBook-Pro:~ DD$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
90d01263b8a8 djy/centos "/bin/sh -c /bin/bash" 25 seconds ago Up 24 seconds dc03
7c32277cb72b djy/centos "/bin/sh -c /bin/bash" About a minute ago Up About a minute dc02
d672cec4719b djy/centos "/bin/sh -c /bin/bash" 22 minutes ago Up 22 minutes dc01
###进入dc01查看发现文件都在
djydeMacBook-Pro:~ DD$ docker attach dc01
[root@d672cec4719b dataVolumeContainer2]# cd /dataVolumeContainer2/
[root@d672cec4719b dataVolumeContainer2]# ls
dc01.txt dc02.txt dc03.txt
[root@d672cec4719b dataVolumeContainer2]# read escape sequence
###删除dc01
djydeMacBook-Pro:~ DD$ docker rm -f dc01
dc01
djydeMacBook-Pro:~ DD$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
90d01263b8a8 djy/centos "/bin/sh -c /bin/bash" 2 minutes ago Up 2 minutes dc03
7c32277cb72b djy/centos "/bin/sh -c /bin/bash" 3 minutes ago Up 3 minutes dc02
djydeMacBook-Pro:~ DD$ docker attach dc03
###进入dc03查看文件都在
[root@90d01263b8a8 dataVolumeContainer2]# ls
dc01.txt dc02.txt dc03.txt
[root@90d01263b8a8 dataVolumeContainer2]# touch dc02_update.txt
[root@90d01263b8a8 dataVolumeContainer2]# ls
dc01.txt dc02.txt dc02_update.txt dc03.txt
[root@90d01263b8a8 dataVolumeContainer2]# read escape sequence
###创建dc04
djydeMacBook-Pro:~ DD$ docker run -it --name dc04 --volumes-from dc03 djy/centos
[root@6a7996772568 /]# djydeMacBook-Pro:~ DD$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6a7996772568 djy/centos "/bin/sh -c /bin/bash" 14 seconds ago Up 13 seconds dc04
90d01263b8a8 djy/centos "/bin/sh -c /bin/bash" 5 minutes ago Up 5 minutes dc03
7c32277cb72b djy/centos "/bin/sh -c /bin/bash" 6 minutes ago Up 6 minutes dc02
###创建dc02 dc03
djydeMacBook-Pro:~ DD$ docker rm -f dc02 dc03
dc02
dc03
djydeMacBook-Pro:~ DD$ docker attach dc04
###进入dc04查看发现文件都在
[root@6a7996772568 /]# ls
bin dataVolumeContainer2 etc lib lost+found mnt proc run srv tmp var
dataVolumeContainer1 dev home lib64 media opt root sbin sys usr
[root@6a7996772568 /]# cd dataVolumeContainer2/
[root@6a7996772568 dataVolumeContainer2]# ls
dc01.txt dc02.txt dc02_update.txt dc03.txt