Docker 是什么
Docker 是一个听从 Apache2.0 开源协定的利用容器引擎。她能够让开发者们打包他们本人的利用以及依赖包到一个轻量级、可移植的容器中,而后公布到任何风行的 Linux 容器上,也能够实现虚拟化。容器是齐全应用沙箱机制,相互之间不会有任何接口,开销极低。
Docker 的利用场景
- Web 利用的自动化打包和公布
- 自动化测试和继续集成、公布
Docker 的长处
- 提供隔离的运行环境:文件系统隔离、网络隔离、过程号隔离、过程间通信隔离。
- 容器性能开销极低:Docker 技术尽管是虚拟化技术,却简直不耗费除容器中应用程序外的其余资源,能够达到近乎裸机的运行能力,达到秒级 / 微秒级的部署,一台实体机能够运行几百个 docker 容器。
- 容易移植:有很高的移植性,能够在任何平台运行。
Docker 的毛病
Docker 容器收到资源的限度蕴含:cpu、内存资源、磁盘 I / O 资源等。
Docker 装置
curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun
执行命令
docker -v
看到
即可阐明 docker 装置胜利
Docker 罕用的相干概念解释
container:容器,是指 image 运行时,蕴含了文件资源(image 开展)和系统资源。容器就是运行起来的镜像。
image:镜像,是指将利用打包好之后的存储形式,一个 image 蕴含多个 layer。
layer:在 Dockerfile 中每一步都会产生一层 layer,每一步的后果产出变成文件。
Dockerfile:一种构建 image 的文件的 DSL。
Docker 的应用
搜寻镜像
docker search imageName
能够看到可用的 image 列表
而后能够抉择须要的镜像进行装置。
拉取镜像
docker pull redis:latest
看到
阐明装置实现了。
运行镜像
开启 redis 服务
docker run -itd --name redis -p 6379:6379 redis
参数阐明:-p 6379:6379 映射容器服务的 6379 端口映射到宿主机的 6379 端口。内部能够通过宿主机 ip:6379 拜访到 redis 的服务。
docker 常用命令
搜寻镜像
docker search
拉取镜像到本地
docker pull image:tag
查看本地镜像
docker images
删除镜像
docker rmi imageName
运行
docker run
给镜像打标签
docker tag oldTag newTag
运行容器
docker run
进入容器
docker exec attach
封装容器为镜像
docker commit containeName iamgeName:tagName
暂停容器的运行
docker pause containeName
复原容器的运行
docker unpause containeName
进行容器的运行
docker stop containeName
开始运行容器
docker start containeName
查问所有的容器
docker ps -a
查问查问 run 状态的和 pause 状态的容器
docker ps
查看这个容器里的各项信息
docker inspect containeName
删除容器
docker rm containeName
删除所有容器
docker rm `docker ps -a -q` -f
Docker 的构造
Docker 应用的是客户端 - 服务器 (c/s) 的架构模式,应用近程 API 来治理和创立 Docker 容器。Docker 容器通过 Docker 镜像来创立。
相干概念:
Docker 守护过程 (daemon) 是 Docker 架构中运行在后盾的守护过程,运行在宿主机上,用户不能间接操作 daemon,只能通过 docker client 转达。
Docker 客户端 (client) 通过命令行或者其余工具应用 Docker API
Docker 仓库 (registry) 用来保留镜像,能够了解为代码管制中的代码仓库
Docker 核心技术和原理
咱们晓得 Docker 外围是一个操作系统的虚拟化办法,那么从虚拟化的四个方面:隔离性、可配额 / 可度量、便携性、安全性来具体介绍。
隔离性
每个用户实例之间相互隔离,互不影响。个别的硬件虚拟化办法给出的是 VM,而 LXC 给出的是 container,就是 kernel namespace。其中 pid、net、ipc、mnt、uts、user 等 namespace 将 container 的过程、网络、音讯、文件系统、UTS(“UNIX Time-sharing System”)和用户空间隔离开来。
Pid namespace
不同的用户过程就是通过 pid namespace 隔离开来,且不同的 namespace 中能够有雷同的 pid。所有的 LXC 过程在 Docker 中的父过程为 docker 过程,每一个 LXC 都有不同的 namespace。同时容许嵌套,很容易实现 docker in docker.
- 每个 namespace 中的 pid 是有本人的 pid=1 的过程(相似 /sbin/init 过程)
- 每个 namespace 中的过程只能影响本人的同一个 namespace 或子 namespace 中的过程
- 因为 /proc 蕴含正在运行的过程,因而在 container 中的 pseudo-filesystem 的 /proc 目录只能看到本人 namespace 中的过程
- 因为 namespace 容许嵌套,父 namespace 能够影响子 namespace 的过程,所以子 namespace 的过程能够在父 namespace 中看到,然而具备不同的 pid
Net namespace
有了 pid namespace 之后,每一个 namespace 中的 pid 可能相互隔离,然而网络端口还是共享 host 的端口。网络隔离是通过 net namespace 实现的,每个 net namespace 有独立的 network devices, IP addresses, IP routing tables, /proc/net 目录。这样每个 container 的网络就能隔离开来。docker 默认采纳 veth 的形式将 container 中的虚构网卡同 host 上的一个 docker bridge 连贯在一起。
Ipc namespace
container 中过程交互还是采纳的 Linux 的罕用的过程间的交互方式(interprocess communication-IPC),包含常见的信号量、音讯队列和共享内存。
Mnt namespace
相似 chroot,将一个过程放到另一个特定的目录执行。mnt namespace 容许不同 namespace 的过程看到的文件构造不同,这样每个 namespace 中的过程所看到的文件目录就被隔离开了。
Uts namespace
UTS (“UNIX Time-sharing System”) namespace 容许每个 container 领有独立的 hostname 和 domain name, 使其在网络上能够被视作一个独立的节点而非 Host 上的一个过程。
user namespace
每一个 container 能够有不同的 user 和 group ID,也就是说能够在 container 外部用 container 外部的用户执行程序而非 host 上的用户。
可配额 / 可度量 - control groups(cgroups)
cgroups 实现了对资源的配额和度量。cgroups 的应用非常简单,提供相似文件的接口,在 /cgroups 目录下新建一个文件夹即可新建一个 group,在此文件夹中新建 task 文件,并将 pid 写入该文件,即可实现对该过程的资源管制。
groups 能够限度 blkio、cpu、cpuacct、cpuset、devices、freezer、memory、net_cls、ns 九大子系统的资源,以下是每个子系统的具体阐明:
- blkio — 块存储配额 » this subsystem sets limits on input/output access to and from block devices such as physical drives (disk, solid state, USB, etc.).
- cpu — CPU 工夫调配限度 » this subsystem uses the scheduler to provide cgroup tasks access to the CPU.
- cpuacct — CPU 资源报告 » this subsystem generates automatic reports on CPU resources used by tasks in a cgroup.
- cpuset — CPU 绑定限度 » this subsystem assigns individual CPUs (on a multicore system) and memory nodes to tasks in a cgroup.
- devices — 设施权限限度 » this subsystem allows or denies access to devices by tasks in a cgroup.
- freezer — cgroup 进行 / 复原 » this subsystem suspends or resumes tasks in a cgroup.
- memory — 内存限度 » this subsystem sets limits on memory use by tasks in a cgroup, and generates automatic reports on memory resources used by those tasks.
- net_cls — 配合 tc 进行网络限度 » this subsystem tags network packets with a class identifier (classid) that allows the Linux traffic controller (tc) to identify packets originating from a particular cgroup task.
- net_prio — 网络设备优先级 » this subsystem provides a way to dynamically set the priority of network traffic per network interface.
- ns — 资源命名空间限度 » the namespace subsystem.
便携性:AUFS
AUFS(AnotherUnionFS)是一种 Union FS,简略来说就是反对将不同目录挂载到同一个虚构文件系统 (unite several directories into a single virtual filesystem) 下的文件系统。在 Docker 中,初始化时将 rootfs 以 readonly 形式加载并查看,接下来利用 union mount 的形式将一个 readwrite 文件系统挂载在 readonly 的 rootfs 之上,并且容许再次将上层的 FS(file system) 设定为 readonly 并且向上叠加, 这样一组 readonly 和一个 writeable 的构造形成一个 container 的运行时态, 每一个 FS 被称作一个 FS 层。
安全性
There are four major areas to consider when reviewing Docker security:
- the intrinsic security of the kernel and its support for namespaces and cgroups;
- the attack surface of the Docker daemon itself;
- loopholes in the container configuration profile, either by default, or when customized by users.
- the“hardening”security features of the kernel and how they interact with containers.
因为安全性术语十分具体的技术,这里不再班门弄斧了,请间接参阅 Docker 官网文档
Docker 的利用场景
场景一:
不同的应用程序可能会有不同的应用环境,比方.net 开发的网站和 php 开发的网站依赖的软件就不一样,如果把他们依赖的软件都装置在一个服务器上就要调试很久,而且很麻烦,还会造成一些抵触。比方 IIS 和 Apache 拜访端口抵触。这个时候你就要隔离.net 开发的网站和 php 开发的网站。惯例来讲,咱们能够在服务器上创立不同的虚拟机在不同的虚拟机上搁置不同的利用,然而虚拟机开销比拟高。docker 能够实现虚拟机隔离应用环境的性能,并且开销比虚拟机小,小就意味着省钱了!
场景二:
咱们在本地测试部署 hadoop 或者 ceph 存储集群的时候用的是 centos,然而生产环境服务器上的零碎都是 Ubuntu,运维在依照咱们的装置文档从开发测试环境转移到生产环境的时候就会遇到一些 centos 转 Ubuntu 的问题。这时候咱们应用 docker 就能够把开发环境间接封装给运维,运维间接部署你给的 docker 就好了,而且部署速度快,能够帮忙咱们疾速交付。
Dockerfile
Docker 能够通过 Dockerfile 的内容来主动构建镜像。Dockerfile 是一个蕴含创立镜像所有命令的文本文件。通过 docker build 命令能够依据 Dockerfile 的内容构建镜像。
上面一一介绍 Dockerfile 的指令选项
-
FROM
用法:
FROM <image>
FROM 指定构建镜像的根底镜像,如果本地没有指定的镜像,则会主动从 Docker 的公共库 pull 镜像下来。
FROM 必须是 Dockerfile 中非正文的第一个指令,即 Dockerfile 从 FROM 语句开始。
FROM 语句能够呈现屡次,即创立多个镜像。
-
MAINTAINER
用法:
MAINTAINER <name>
指定创立镜像的用户
-
RUN
用法:
RUN RUN "executable", "param1", "param2"
每条 RUN 指令将在以后镜像根底上执行指定命令,并提交为新的镜像,后续的 RUN 都在之前 RUN 提交后的镜像为根底,镜像是分层的,能够通过一个镜像的任何一个历史提交点来创立,相似源码的版本控制。
exec 形式会被解析为一个 JSON 数组,所以必须应用双引号而不是单引号。exec 形式不会调用一个命令 shell,所以也就不会继承相应的变量,如:
RUN ["echo", "$HOME"]
这种形式是不会达到输入 HOME 变量的,正确的形式应该是这样的
RUN ["sh", "-c", "echo", "$HOME"]
RUN 产生的缓存在下一次构建的时候是不会生效的,会被重用,能够应用 –no-cache 选项,即 docker build –no-cache,如此便不会缓存。
-
CMD
CMD 有三种应用形式:
CMD "executable","param1","param2" CMD "param1","param2" CMD command param1 param2 (shell form)
CMD 指定在 Dockerfile 中只能应用一次,如果有多个,则只有最初一个会失效。
CMD 的目标是为了在启动容器时提供一个默认的命令执行选项。如果用户启动容器时指定了运行的命令,则会笼罩掉 CMD 指定的命令。
-
EXPOSE
用法:
EXPOSE <port> [<port>...]
通知 Docker 服务端容器对外映射的本地端口,须要在 docker run 的时候应用 - p 或者 - P 选项失效。
-
ENV
用法:
ENV <key> <value> # 只能设置一个变量 ENV <key>=<value> ... # 容许一次设置多个变量
指定一个环节变量,会被后续 RUN 指令应用,并在容器运行时保留。
例子:
ENV myName="John Doe" myDog=Rex\ The\ Dog \ myCat=fluffy
等同于
ENV myName John Doe ENV myDog Rex The Dog ENV myCat fluffy
-
ADD
用法:
DD <src>... <dest>
ADD 复制本地主机文件、目录或者近程文件 URLS 从 并且增加到容器指定门路中。
反对通过 GO 的正则含糊匹配,具体规定可参见 Go filepath.Match
ADD hom* /mydir/ # adds all files starting with "hom" ADD hom?.txt /mydir/ # ? is replaced with any single character
- 门路必须是绝对路径,如果 不存在,会主动创立对应目录
- 门路必须是 Dockerfile 所在门路的相对路径
- 如果是一个目录,只会复制目录下的内容,而目录自身则不会被复制
-
COPY
用法:
COPY <src>... <dest>
COPY 复制新文件或者目录从 并且增加到容器指定门路中。用法同 ADD,惟一的不同是不能指定近程文件 URLS。
-
ENTRYOINT
ENTRYPOINT "executable", "param1", "param2" ENTRYPOINT command param1 param2 (shell form)
配置容器启动后执行的命令,并且不可被 docker run 提供的参数笼罩,而 CMD 是能够被笼罩的。如果须要笼罩,则能够应用 docker run –entrypoint 选项。
每个 Dockerfile 中只能有一个 ENTRYPOINT,当指定多个时,只有最初一个失效。
-
VOLUME
用法:
VOLUME ["/data"]
创立一个能够从本地主机或其余容器挂载的挂载点。
-
USER
用法:
USER daemon
指定运行容器时的用户名或 UID,后续的 RUN、CMD、ENTRYPOINT 也会应用指定用户。
-
WORKDIR
WORKDIR /path/to/workdir
为后续的 RUN、CMD、ENTRYPOINT 指令配置工作目录。能够应用多个 WORKDIR 指令,后续命令如果参数是相对路径,则会基于之前命令指定的门路。
WORKDIR /a WORKDIR b WORKDIR c RUN pwd
最终门路是
/a/b/c
WORKDIR 指令能够在 ENV 设置变量之后调用环境变量:
ENV DIRPATH /path WORKDIR $DIRPATH/$DIRNAME
最终门路则为
/path/$DIRNAME
-
ONBUILD
ONBUILD [INSTRUCTION]
配置当所创立的镜像作为其它新创建镜像的根底镜像时,所执行的操作指令。
Dockerfile Example
# Nginx
#
# VERSION 0.0.1
FROM ubuntu
MAINTAINER Victor Vieux <victor@docker.com>
RUN apt-get update && apt-get install -y inotify-tools nginx apache2 openssh-server
# Firefox over VNC
#
# VERSION 0.3
FROM ubuntu
# Install vnc, xvfb in order to create a 'fake' display and firefox
RUN apt-get update && apt-get install -y x11vnc xvfb firefox
RUN mkdir ~/.vnc
# Setup a password
RUN x11vnc -storepasswd 1234 ~/.vnc/passwd
# Autostart firefox (might not be the best way, but it does the trick)
RUN bash -c 'echo"firefox">> /.bashrc'
EXPOSE 5900
CMD ["x11vnc", "-forever", "-usepw", "-create"]
# Multiple images example
#
# VERSION 0.1
FROM ubuntu
RUN echo foo > bar
# Will output something like ===> 907ad6c2736f
FROM ubuntu
RUN echo moo > oink
# Will output something like ===> 695d7793cbe4
# You᾿ll now have two images, 907ad6c2736f with /bar, and 695d7793cbe4 with
# /oink.
参考目录:
https://docs.docker.com/engin…
https://tiewei.github.io/post…
欢送关注我的公众号
本文由博客群发一文多发等经营工具平台 OpenWrite 公布