Docker 概述
- 一种服务器,它是一种称为守护进程并且长时间运行的程序。
- REST API用于指定程序可以用来与守护进程通信的接口,并指示它做什么。
- 一个有命令行界面 (CLI) 工具的客户端。
系统架构
- 镜像(Image)
- 容器(Container)
- 仓库(Repository)
| Docker | 面向对象 | |——–|——| | 容器 | 对象 | | 镜像 | 类 |
容器与镜像的关系类似于面向对象编程中的对象与类。
标题 | 说明 |
---|---|
镜像(Images) | Docker 镜像是用于创建 Docker 容器的模板。 |
容器(Container) | 容器是独立运行的一个或一组应用。 |
客户端(Client) | Docker 客户端通过命令行或者其他工具使用 Docker API 与 Docker 的守护进程通信。 |
主机(Host) | 一个物理或者虚拟的机器用于执行 Docker 守护进程和容器。 |
仓库(Registry) | Docker 仓库用来保存镜像,可以理解为代码控制中的代码仓库。Docker Hub 提供了庞大的镜像集合供使用。 |
Docker Machine | Docker Machine是一个简化Docker安装的命令行工具,通过一个简单的命令行即可在相应的平台上安装Docker,比如VirtualBox、 Digital Ocean、Microsoft Azure。 |
Docker 镜像
获取镜像
1
docker pull ubuntu:16.04
从 Docker 镜像仓库获取镜像的命令是 docker pull。其命令格式为:
1
2
docker pull [选项] [Docker Registry 地址[:端口号]/]仓库名[:标签]
::: tip 帮助文档
具体的选项可以通过 docker pull –help 命令查询帮助。
:::
交互式运行
1
2
3
docker run -it --rm \
ubuntu:16.04 \
bash
列出镜像
1
2
3
docker image ls
docker images
镜像体积
docker image ls
列表中的镜像体积总和并非是所有镜像实际硬盘消耗。由于 Docker 镜像是多层存储结构,并且可以继承、复用,因此不同镜像可能会因为使用相同的基础镜像,从而拥有共同的层
查看镜像、容器、数据卷所占用的空间。
1
docker system df
虚悬镜像
镜像既没有仓库名,也没有标签,均为
none
。查询虚悬镜像
1 docker image ls -f dangling=true新旧镜像同名,旧镜像名称被取消,从而出现仓库名、标签均为
none
的镜像。这类无标签镜像也被称为 虚悬镜像(dangling image)
中间层镜像 查询中间层镜像:
1
docker image ls -a
为了加速镜像构建、重复利用资源,Docker 会利用 中间层镜像。
::: danger 警告
只要删除那些依赖它们的镜像后,这些依赖的中间层镜像也会被连带删除
:::
列出部分镜像
1
docker image ls ubuntu
删除本地镜像
1
docker image rm [选项] <镜像1> [<镜像2> ...]
commit 镜像构成新镜像
定制一个 nginx 服务器为例子
1
docker run --name nginx -d -p 80:80 nginx
直接访问:http://localhost
修改欢迎内容
1
docker exec -it nginx bash
进入容器后
1
echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html
然后exit
退出容器,再刷新浏览器的话,会发现内容被改变了。
docker diff
命令看到具体的改动。
1
docker diff nginx
将容器保存为新镜像
1
2
3
4
5
docker commit \
--author "Yuewei tang <[email protected]>" \
--message "修改了默认网页" \
nginx \
nginx:v2
我们可以在 docker image ls 中看到这个新定制的镜像
1
docker image ls nginx
慎用 docker commit
使用 docker commit 命令虽然可以比较直观的帮助理解镜像分层存储的概念,但是实际环境中并不会这样使用。推荐使用
Dockerfile
定制镜像
Dockerfile 定制镜像
官方文档参考
在一个空白目录中,建立一个文本文件,并命名为 Dockerfile。
1
2
3
mkdir mynginx
cd mynginx
touch Dockerfile
输入:
1
2
FROM nginx
RUN echo '<h1>Hello, mynginx!</h1>' > /usr/share/nginx/html/index.html
- FROM 指定基础镜像
- RUN 执行命令
构建镜像
在 Dockerfile 文件所在目录执行:
1
docker build -t nginx:v3 .
::: tip 提示
1
docker build [选项] <上下文路径/URL/->
::: 镜像构建上下文(Context) 如果在 Dockerfile 中这么写:
1
COPY ./package.json /app/
这并不是要复制执行
docker build
命令所在的目录下的package.json
,也不是复制 Dockerfile 所在目录下的package.json
,而是复制 上下文(context)目录下的package.json
。 一般来说,应该会将 Dockerfile 置于一个空目录下,或者项目根目录下。如果该目录下没有所需文件,那么应该把所需文件复制一份过来
其它 docker build 的用法
- 接用 Git repo 进行构建
1
docker build https://github.com/tangyuewei/gitlab-ce-zh.git#:0.1
这行命令指定了构建所需的
Git repo
,并且指定默认的 master 分支,构建目录为 /0.1/,然后 Docker 就会自己去 git clone 这个项目、切换到指定分支、并进入到指定目录后开始构建 - 指定
tar
压缩包构建1
docker build http://server/context.tar.gz
Dockerfile 指令详解
- COPY 复制文件
COPY <源路径>... <目标路径>目标路径>源路径>
1 2
COPY hom* /mydir/ COPY hom?.txt /mydir/
- ADD 更高级的复制文件
1
ADD package.tar.gz /usr/src/app/
如果 <源路径> 为一个 tar 压缩文件的话,压缩格式为 gzip, bzip2 以及 xz 的情况下,ADD 指令将会自动解压缩这个压缩文件到 <目标路径> 去。 最适合使用 ADD 的场合,就是所提及的需要自动解压缩的场合。目标路径>源路径>
- CMD 容器启动命令
1
2
CMD ["nginx", "-g", "daemon off;"]
CMD [ "sh", "-c", "echo $HOME" ]
CMD
指令的格式和RUN
相似
- ENTRYPOINT 入口点
当指定了 ENTRYPOINT 后,CMD 的含义就发生了改变,不再是直接的运行其命令,而是将 CMD 的内容作为参数传给 ENTRYPOINT 指令,换句话说实际执行时,将变为:
<ENTRYPOINT> "<CMD>"
- ENV 设置环境变量
1
ENV VERSION=1.0
- VOLUME 定义匿名卷
1
VOLUME /data
- EXPOSE 暴露端口
1
EXPOSE <端口1> [<端口2>...]
- WORKDIR 指定工作目录
1
WORKDIR <工作目录路径>。#如该目录不存在,WORKDIR 会帮你建立目录
- USER 指定当前用户
1 2
USER redis RUN [ "redis-server" ]
Docker 容器
容器操作
1 2 3 4 5 6 7 8 9
docker run nginx #启动 docker container start #已经终止的容器启动运行 docker container stop #终止一个运行中的容器 docker run -d nginx #后台守护启动 docker attach 567c #进入运行中的容器 567c为容器id docker exec -it 567c bash #进入运行中的容器 567c为容器id docker container rm nginx #要删除一个运行中的容器,可以添加 -f 参数 docker container prune #清理掉所有处于终止状态的容器 docker image prune #清理虚悬镜像
导出、导入容器
1
docker export 567c > nginx.tar
1
2
cat nginx.tar | docker import - test/nginx:v1.0
docker import https://example.com/exampleimage.tgz example/imagerepo
Docker 仓库
Docker Hub
1
2
docker login #登录
docker logout #退出
推送镜像
1
docker tag ubuntu:16.04 username/ubuntu:16.04 #username 为你的 Docker 账号用户名
自动创建
- 创建并登录 Docker Hub,以及目标网站;
- 在目标网站中连接帐户到 Docker Hub;
- 在 Docker Hub 中 配置一个自动创建;
- 选取一个目标网站中的项目(需要含 Dockerfile)和分支;
- 指定 Dockerfile 的位置,并提交创建。
Docker 私有仓库 安装运行 docker-registry
1
docker run -d -p 5000:5000 --restart=always --name registry registry
1
2
3
4
docker run -d \
-p 5000:5000 \
-v /opt/data/registry:/var/lib/registry \
registry
使用 docker tag
将nginx:latest
这个镜像标记为 127.0.0.1:5000/nginx:latest
1
2
3
4
5
6
docker tag nginx:latest 127.0.0.1:5000/nginx:latest
docker push 127.0.0.1:5000/nginx:latest #docker push 上传标记的镜像
curl 127.0.0.1:5000/v2/_catalog #用 curl 查看仓库中的镜像
docker image rm 127.0.0.1:5000/nginx:latest #先删除已有镜像,再尝试从私有仓库中下载这个镜像
docker pull 127.0.0.1:5000/nginx:latest
::: warning 注意
Docker 默认不允许非 HTTPS 方式推送镜像。我们可以通过 Docker 的配置选项来取消这个限制,或者查看下一节配置能够通过 HTTPS 访问的私有仓库。 :::