最近终于基本看完了《Docker — 从入门到实践》 一书,学了后面忘了前面的就掌握了基本的使用哈哈哈(这玩意真的太需要实践了!!!) 顺便写个总结 都是些最简单的东西 方便快速上手 后面深入的东西再继续学习吧 像 Docker compose之类
Docker是什么
Docker是操作系统层面的虚拟化技术, 类似的还有以前用的虚拟机技术 他们都是提供虚拟化服务
区别在于 Docker 是作为进程 直接运行在宿主机的内核中 不需要进行硬件虚拟
而虚拟机是先虚拟出一套硬件后在上面运行一个完成的操作系统 在系统上在运行所需要的进程
这样比起来 Docker 就显得轻量级 更轻便
镜像 Image
Docker 镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含任何动态数据,其内容在构建之后也不会被改变。
容器 Container
容器是镜像运行时的实体。 它可以被创建、启动、停止、删除、暂停等
容器的实质是进程,但与直接在宿主执行的进程不同,容器进程运行于属于自己的独立的 命名空间。因此容器可以拥有自己的 root 文件系统、自己的网络配置、自己的进程空间,甚至自己的用户 ID 空间。容器内的进程是运行在一个隔离的环境里,使用起来,就好像是在一个独立于宿主的系统下操作一样。这种特性使得容器封装的应用比直接在宿主运行更加安全
仓库 Registry
Docker Registry 公开服务是开放给用户使用、允许用户管理镜像的 Registry 服务。一般这类公开服务允许用户免费上传、下载公开的镜像,并可能提供收费服务供用户管理私有镜像。
一个 Docker Registry 中可以包含多个仓库(Repository);每个仓库可以包含多个标签(Tag);每个标签对应一个镜像
镜像操作
当我们想要运行某个服务的时候 肯定需要一个镜像作为基础 然后才可以生成容器跑服务,所以需要先把镜像下载到本地
获取镜像
|
|
这个是常用的一个命令,因为一个镜像可以有很多的版本所以可以通过指定tag来声明你需要具体的哪个版本的镜像。后面的tag也可以省略 如果省略的话默认会找 latest
也就是最新的镜像下载 更多请自己查看 docker pull --help
列出本地镜像
如果想要列出本地的镜像 常用的命令
|
|
删除本地镜像
如果想要删除本地镜像 常用的命令
|
|
更多骚操作请自己查看 --help
Dockerfile定制镜像
镜像的定制实际上就是定制每一层所添加的配置、文件。
Dockerfile 是一个文本文件,其内包含了一条条的指令(Instruction),每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建
拿Nginx基础镜像来做个测试
下面新建个目录来创建 Dockerfile
|
|
这是一个很简单的配置 就2个命令 FROM
和 RUN
FROM
是指定基础镜像 表示已哪个镜像做为基础 他必须是第一条指令
RUN
是用来执行命令行命令的 它有两个格式用法
shell 格式:RUN <命令>,就像直接在命令行中输入的命令一样。刚才写的 Dockerfile 中的 RUN 指令就是这种格式。
RUN echo ‘Hello, Docker!’ > /usr/share/nginx/html/index.htmlexec 格式:RUN [“可执行文件”, “参数1”, “参数2”],这更像是函数调用中的格式。
现在有了Dockerfile就可以构建镜像了
|
|
我们通过 -t
参数 给新的镜像打了个 tag
所以最终生成的镜像是 nginx:v3
然后看下他的执行过程
1.先是把上下文路径资源上传 Docker 引擎
2.从基础容器启动一个容器 568c4670fa80
3.然后 run 命令 启动一个容器 95bfd552874e
然后删除它 并用新内容生成了最后的容器 3d4e1fb1e8ea
注意:docker build -t nginx:v3 .
最后是有个 .
的 这个点是 上下文路径
上下文路径
Docker 在运行时分为 Docker 引擎(也就是服务端守护进程)和客户端工具.Docker 的引擎提供了一组 REST API,被称为 Docker Remote API,而如 docker 命令这样的客户端工具,则是通过这组 API 与 Docker 引擎交互,从而完成各种功能。因此,虽然表面上我们好像是在本机执行各种 docker 功能,但实际上,一切都是使用的远程调用形式在服务端(Docker 引擎)完成。也因为这种 C/S 设计,让我们操作远程服务器的 Docker 引擎变得轻而易举
理解了上面的东西 在来看 上下文路径 的概念
我当前的路径是:
|
|
注意在生成镜像的时候 Docker 会把 上下文路径 内的资源全部上传到Docker引擎中,所以不要傻的把 根目录 当作Docker的上下文路径 这样它会把所有东西都上传上去。
在本次示例中 是把我的目录 /data/docker_test/mynginx
当作了上下文路径 也就是这个目录下的资源会上传Docker引擎然后生成镜像。
如果你在 Dockerfile 中有指定 路径的命令 比如 COPY ../index.php /usr/share/nginx/html/
这个其实是执行不成功的 即使你在 /data/docker_test
目录下 有 index.php
文件,因为它超出了你所指定的 上下文路径 也就是 mynginx
目录
|
|
可以看到是失败的
然后我们可以把 COPY ../index.php /usr/share/nginx/html/
换成 COPY ./index.php /usr/share/nginx/html/
然后指定上下文路径(ps:-f是指定当前使用的Dockerfile文件路径)
|
|
这样就OK了
容器操作
创建容器
以Nginx容器和Mysql容器为例
docker run --name webserver -d -p 80:80 -v /data/website/blog:/usr/share/nginx/html nginx
docker run --name mysql8 -d -p 3306:3306 -v /data/mysql:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root123456 mysql
docker run
是一个启动容器的命令 参数 --name xxx
是给容器起个名字 这个不是必须也可以默认镜像的名字。 -d
表示容器做后台运行,-p port:port
参数表示 指定端口号映射 冒号前面的时候本机的端口号,冒号后面的是容器里的端口号 可以保持不一致, 参数 -v path:path
表示目录映射,冒号前面的是主机的目录,冒号后面的容器里的目录 一般是用来存储数据的 这样容器销毁了数据还在本机(建议写绝对路径) 最后的就是镜像的名字了 表示使用该镜像创建容器
另外在Mysql创建的容器中还有个 -e
参数 这个是运行一个命令 后面的表示给mysql创建默认的root用户密码
查看容器
|
|
都可以列出运行的容器 参数 -a
的话可以列出所有状态的容器 包括停止的,有时候我们只列出了运行中的容器时 在创建容器会提示你容器已经存在 其实可能是容器只是 不是运行状态 而已
终止容器
可以是用命令 docker container stop name/container_id
最后的名字可以是启动时的名字 也可以是启动后的容器ID
删除容器
可以使用命令 docker container rm name
最后是容器的名字 同时可以使用 docker container prune
来删除无主的容器
数据卷
数据卷 是一个可供一个或多个容器使用的特殊目录,它绕过 UFS,可以提供很多有用的特性:
数据卷 可以在容器之间共享和重用
对 数据卷 的修改会立马生效
对 数据卷 的更新,不会影响镜像
数据卷 默认会一直存在,即使容器被删除
注意:数据卷 的使用,类似于 Linux 下对目录或文件进行 mount,镜像中的被指定为挂载点的目录中的文件会隐藏掉,能显示看的是挂载的 数据卷。
查看和创建 数据卷
可以使用命令 docker volume create vol_name
来创建数据库。 使用 docker volume ls
或者 docker volume inspect vol_name
来查看数据卷
删除数据卷
可是使用命令 docker volume rm vol_name
来删除数据卷 同时可以使用 docker volume prune
来删除无主数据卷
使用数据卷
已启动Nginx容器为例 增加数据卷使用
docker run --name webserver -d -p 80:80 -v vol_name:/usr/share/nginx/html nginx
或者把其中的 -v vol_name:path
换成 --mount source=vol_name,target=path
注意path是容器里的路径
挂载主机目录
使用
这个同挂载数据卷差不多,我还是比较喜欢挂载主机目录这种形式 使用形式 还是用Nginx容器为例
docker run --name webserver -d -p 80:80 -v /data/website/blog:/usr/share/nginx/html nginx
其中 -v path1:path2
就是把主机的目录path1挂载到了容器里的目录path2中了 还可以使用 --mount type=bind,source=path1,target=path2,readonly
来指定,最后的 readonly
不是必填参数 因为默认挂载的目录 在Docker容器中是 读写
权限 加了 readonly 后就变为了只读权限了。
查看容器挂载信息
docker inspect container_name
最后是容器的名字 挂载主机目录 的配置信息在 “Mounts” Key 下面
|
|
容器网络
端口设置
一般在容器启动的时候我们通常会使用 -p
(注意这是 小写 的 p) 来指定端口号,我们还可以使用 -P
(注意这是 大写 的 P) 使用这个的时候 Docker 会随机映射一个 49000~49900 的 本机端口 到内部容器开放的网络端口(也就是到容器默认开放的端口,比如Mysql的默认端口是3306 他就会自动映射到容器的3306端口上)。
在使用 -p port:container_port
的时候 还可以使用多个 -p
参数一次指定多个端口映射 比如
|
|
还可以映射指定IP地址的到容器
|
|
如果不限制IP上的端口到容器里端口的映射可以
|
|
容器互联
每个容器都有自己的网络环境 要让容器之间的互相连接可以通过创建一个Docker网络来实现
docker network create -d bridge my-net
-d
参数指定 Docker 网络类型,有 bridge overlay。其中 overlay 网络类型用于 Swarm mode.
在运行容器的时候指定使用的网络 还是以Nginx容器启动为例
docker run --name webserver -d -p 80:80 -v /data/website/blog:/usr/share/nginx/html --network my-net nginx
其中 参数 --network my-net
就是指定使用网络 网络名字是 my-net
打开新的终端,再运行一个容器并加入到 my-net 网络
docker run --name webserver2 -d -p 80:80 -v /data/website/blog2:/usr/share/nginx/html --network my-net nginx
然后可以分别进入到容器里使用 ping
对方来查看是否 ping 的通
比如进入 webserver 容器中 docker exec -it webserver sh
进入容器后然后执行
|
|
同理进入第二个容器来ping第一个容器 也可以成功连接,这样2个容器就建立了互联
如果需要多个容器之间的互联 推荐使用 Docker Compose
原书
上面的总结全部自来 《Docker — 从入门到实践》 一书 自己总结了一些适合快速上手并使用的内容 更深的内容需要自己去看去发掘
原文地址:https://yeasy.gitbooks.io/docker_practice/content/