Docker


Docker是什么:
1、Docker是一个开源的应用容器引擎。
2、Docker使用容器引擎解决平台依赖问题
3、Docker具有类似Github的版本控制功能
4、Docker具有自己的生态圈,应用以镜像的形式发布
5、使用Golang编写 采用C/S架构,包含Docker Server和Docker client

Docker 使用 Google 公司推出的 Go 语言 进行开发实现,基于 Linux 内核的
cgroup,namespace,以及 AUFS 类的 Union FS 等技术,对进程进行封装隔离,属于 操作
系统层面的虚拟化技术。由于隔离的进程独立于宿主和其它的隔离的进程,因此也称其为容
器。最初实现是基于 LXC,从 0.7 版本以后开始去除 LXC,转而使用自行开发的
libcontainer,从 1.11 开始,则进一步演进为使用 runC 和 containerd。


Docker 和传统虚拟化方式的不同之处:
传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程;而容器内的应用进程直接运行于宿主的内核,容器内没有自己的内核,而且也没有进行硬件虚拟。因此容器要比 传统虚拟机更为轻便


为什么要使用Docker:
更高效的利用系统资源
由于容器不需要进行硬件虚拟以及运行完整操作系统等额外开销,Docker 对系统资源的利用率更高。无论是应用执行速度、内存损耗或者文件存储速度,都要比传统虚拟机技术更高
效。因此,相比虚拟机技术,一个相同配置的主机,往往可以运行更多数量的应用。
更快速的启动时间
传统的虚拟机技术启动应用服务往往需要数分钟,而 Docker 容器应用,由于直接运行于宿主内核,无需启动完整的操作系统,因此可以做到秒级、甚至毫秒级的启动时间。大大的节约了开发、测试、部署的时间
一致的运行环境
开发过程中一个常见的问题是环境一致性问题。由于开发环境、测试环境、生产环境不一
致,导致有些 bug 并未在开发过程中被发现。而 Docker
的镜像提供了除内核外完整的运行时环境,确保了应用运行环境一致性,从而不会再出现
「这段代码在我机器上没问题啊]这类问题。
更轻松的迁移
更轻松的维护和扩展

Docker 镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含任何动态数据,其内容在构建之后也不会被改变。

镜像( Image )和容器( Container )的关系,就像是面向对象程序设计中的 类 和 实例一样,镜像是静态的定义,容器是镜像运行时的实体


在仓库中的应用都是以镜像形式存在的,把镜像从Docker仓库中下拉到本机,以这个镜像为启动模板启动应用,就叫容器。

镜像指的是以分层的、可以被LXC/libcontainer理解的文件存储格式。

把应用镜像从Docker仓库下载到本地机器上,以镜像为模板,在一个容器类虚拟机中把这个应用启动,这个虚拟机叫容器

支持几乎所有的linux系统,非linux系统需要通过Docker ToolBox来支持运行docker

安装方法一:yum -y install docker-io
安装方法二(安装最新版本):curl -sSL https://get.docker.com/ | sh

在中国访问docker官方源那速度堪比乌龟,是在受不利,我们可以使用中科大的镜像源替代
对于使用 systemd 的系统(Ubuntu 16.04+、Debian 8+、CentOS 7), 可以在配置文件 /etc/docker/daemon.json 中加入:

{
"registry-mirrors": ["https://docker.mirrors.ustc.edu.cn/"]
}

然后重启systemctl restart docker

其他源的帮助可以访问中科大的镜像源网站帮助:

http://mirrors.ustc.edu.cn/help/

docker rmi $(docker images -q) 删除全部镜像

docker search <string> 从镜像仓库中查询镜像

docker pull [选项] [Docker Registry 地址[:端口号]/]仓库名[:标签] 拉取镜像

docker ps 可以查看本机上所有正在运行的容器

docker inspect + CONTAINERID 可以查看单个容器的详细信息

docker images 显示当前主机上所有的镜像

docker push learn/ping 把镜像推送到docker官方仓库

docker commit +容器ID +镜像名(如:learn/ping)把容器提交为新镜像

docker ps -l 查询最近运行的容器

docker image ls --format "{{.ID}}: {{.Repository}}" 使用go的模板语法

docker image ls --format "table {{.ID}} {{.Repository}} {{.Tag}}"

docker image rm $(docker image ls -q redis) 删除所有仓库名为 redis 的镜像:

docker image rm $(docker image ls -q -f before=mongo:3.2) 删除所有在 mongo:3.2 之前的镜像:

docker commit --author "template" --message "change index.html" webserver
nginx:v2 镜像提交

docker diff webserver 我们修改了容器的文件,也就是改动了容器的存储层。我们可以通过 docker diff 命令看到具体的改动。


Dockerfile命令:


docker build -t nginx:v3 .

COPY <源路径>... <目标路径>
COPY ["<源路径1>",... "<目标路径>"]


镜像构建上下文(Context)

如果注意,会看到 docker build 命令最后有一个 . 。 . 表示当前目录,而 Dockerfile
就在当前目录,因此不少初学者以为这个路径是在指定 Dockerfile 所在路径,这么理解其
实是不准确的。如果对应上面的命令格式,你可能会发现,这是在指定上下文路径。那么什
么是上下文呢?

首先我们要理解 docker build 的工作原理。Docker 在运行时分为 Docker 引擎(也就是服
务端守护进程)和客户端工具。Docker 的引擎提供了一组 REST API,被称为 Docker
Remote API,而如 docker 命令这样的客户端工具,则是通过这组 API 与 Docker 引擎交
互,从而完成各种功能。因此,虽然表面上我们好像是在本机执行各种 docker 功能,但实
际上,一切都是使用的远程调用形式在服务端(Docker 引擎)完成。也因为这种 C/S 设计,
让我们操作远程服务器的 Docker 引擎变得轻而易举。
当我们进行镜像构建的时候,并非所有定制都会通过 RUN 指令完成,经常会需要将一些本地
文件复制进镜像,比如通过 COPY 指令、 ADD 指令等。而 docker build 命令构建镜像,其
实并非在本地构建,而是在服务端,也就是 Docker 引擎中构建的。那么在这种客户端/服务
端的架构中,如何才能让服务端获得本地文件呢?


这就引入了上下文的概念。当构建的时候,用户会指定构建镜像上下文的路径, docker
build 命令得知这个路径后,会将路径下的所有内容打包,然后上传给 Docker 引擎。这样
Docker 引擎收到这个上下文包后,展开就会获得构建镜像所需的一切文件。
如果在 Dockerfile 中这么写:
COPY ./package.json /app/

这并不是要复制执行 docker build 命令所在的目录下的 package.json ,也不是复制
Dockerfile 所在目录下的 package.json ,而是复制 上下文(context) 目录下的
package.json 。

因此, COPY 这类指令中的源文件的路径都是相对路径。这也是初学者经常会问的为什么
COPY ../package.json /app 或者 COPY /opt/xxxx /app 无法工作的原因,因为这些路径已经
超出了上下文的范围,Docker 引擎无法获得这些位置的文件。如果真的需要那些文件,应该
将它们复制到上下文目录中去。

现在就可以理解刚才的命令 docker build -t nginx:v3 . 中的这个 . ,实际上是在指定上下
文的目录, docker build 命令会将该目录下的内容打包交给 Docker 引擎以帮助构建镜像。
如果观察 docker build 输出,我们其实已经看到了这个发送上下文的过程:
$ docker build -t nginx:v3 .
Sending build context to Docker daemon 2.048 kB
...

理解构建上下文对于镜像构建是很重要的,避免犯一些不应该的错误。比如有些初学者在发
现 COPY /opt/xxxx /app 不工作后,于是干脆将 Dockerfile 放到了硬盘根目录去构建,结果
发现 docker build 执行后,在发送一个几十 GB 的东西,极为缓慢而且很容易构建失败。那
是因为这种做法是在让 docker build 打包整个硬盘,这显然是使用错误。
一般来说,应该会将 Dockerfile 置于一个空目录下,或者项目根目录下。如果该目录下没
有所需文件,那么应该把所需文件复制一份过来。如果目录下有些东西确实不希望构建时传
给 Docker 引擎,那么可以用 .gitignore 一样的语法写一个 .dockerignore ,该文件是用于
剔除不需要作为上下文传递给 Docker 引擎的。
那么为什么会有人误以为 . 是指定 Dockerfile 所在目录呢?这是因为在默认情况下,如果
不额外指定 Dockerfile 的话,会将上下文目录下的名为 Dockerfile 的文件作为
Dockerfile。

这只是默认行为,实际上 Dockerfile 的文件名并不要求必须为 Dockerfile ,而且并不要求
必须位于上下文目录中,比如可以用 -f ../Dockerfile.php 参数指定某个文件作为
Dockerfile 。

当然,一般大家习惯性的会使用默认的文件名 Dockerfile ,以及会将其置于镜像构建上下文
目录中。

docker attach -it +containerID 进去后退出会导致容器停止

docker exec -it +containerID bash exec 不会导致容器停止

推荐使用exec


docker container prune 清理掉所有处于终止状态的容器

docker ps --no-trunc 查看完整的container ID


docker logs + containerID 打印日志 加-f 实时打印


docker stats 实时查看容器所占用系统资源


docker-compose 下载
curl -L https://github.com/docker/compose/release/download/1.6.0/docker-compose-`uname -s`-`uname -r` > /usr/local/bin/docker-compose


cat docker-compose.yml

wordpress:
image: wordpress
links:
- db:mysql
ports:
- 8080:80

db:
image: mariadb
environment:
MYSQL_ROOT_PASSWORD: example


docker-compose 默认配置文件名为docker-compose.yml 可以通过-f指定文件

docker run --name gitlab-postgresql -d
--env 'DB_NAME=gitlab'
--env 'DB_USER=gitlab'
--env 'DB_PASS=password'
sameersbn/postgresql:9.4-12

写成yaml

gitlab-postgresql:
image: sameersbn/postgresql:9.4-12
environment:
- DB_NAME=gitlab
- DB_USER=gitlab
- DB_PASS=password

docker history --no-trunc sameersbn/redis 查询镜像分了多少层,每一层具体做了什么操作


docker 数据卷
Docker中有两个与数据卷有关的参数:
-v
--volumes-from

-v 有三个变量:
host-dir:表示Host上的目录,如果不存在Docker会自动创建该目录
container-dir:表示容器内部对应的目录,如果该目录不存在,Docker会自动创建
rw|ro:用于控制卷的读写权限
docker run -it --rm -v /template:/template:rw --name test ubuntu:14.04 /bin/bash


挂载host的template目录到容器内部的/template目录,赋予读写权限(ro只读权限) 容器删除,host目录不会自动删除

还可以挂载文件作为数据卷:
docker run -it --rm --name test -v ~/.bash_history:/root/.bash_historyubuntu ubuntu:16.04 /bin/bash
这样就能在容器中查看host的历史命令了,在我们退出容器后,在host中也能看到容器执行的历史命令

1、备份数据卷

通过参数--volumes-from 从数据卷挂载数据卷,然后备份数据卷中的数据,例如:

docker run -d --name dbdata -v /dbdata training/postgres 创建数据卷

docker run --volumes-from dbdata -v $(pwd):/backup ubuntu tar cvf /backup/backup.tar /dbdata 备份数据卷

原文地址:https://www.cnblogs.com/Template/p/9402750.html