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

    用法:

    RUNRUN "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 DoeENV myDog Rex The DogENV 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 /aWORKDIR bWORKDIR cRUN pwd

    最终门路是

    /a/b/c

    WORKDIR指令能够在ENV设置变量之后调用环境变量:

    ENV DIRPATH /pathWORKDIR $DIRPATH/$DIRNAME

    最终门路则为

    /path/$DIRNAME
  • ONBUILD

    ONBUILD [INSTRUCTION]

    配置当所创立的镜像作为其它新创建镜像的根底镜像时,所执行的操作指令。

Dockerfile Example

# Nginx## VERSION               0.0.1FROM      ubuntuMAINTAINER Victor Vieux <victor@docker.com>RUN apt-get update && apt-get install -y inotify-tools nginx apache2 openssh-server# Firefox over VNC## VERSION               0.3FROM ubuntu# Install vnc, xvfb in order to create a 'fake' display and firefoxRUN apt-get update && apt-get install -y x11vnc xvfb firefoxRUN mkdir ~/.vnc# Setup a passwordRUN 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 5900CMD    ["x11vnc", "-forever", "-usepw", "-create"]# Multiple images example## VERSION               0.1FROM ubuntuRUN echo foo > bar# Will output something like ===> 907ad6c2736fFROM ubuntuRUN echo moo > oink# Will output something like ===> 695d7793cbe4# Youll now have two images, 907ad6c2736f with /bar, and 695d7793cbe4 with# /oink.

参考目录:

https://docs.docker.com/engin...

https://tiewei.github.io/post...

欢送关注我的公众号

本文由博客群发一文多发等经营工具平台 OpenWrite 公布