Docker安装及容器管理

一、Docker 简介

Docker是什么?

     Docker的英语本意是“搬运工”,在程序员的世界里,Docker搬运的是集装箱(Container),集装箱里装的是任意类型的App,开发者通过Docker可以将APP变成一种标准化的、可移植的、自管理的组件,可以在任何主流中开发、调试和运行。

     说白了,docker是一种用了新颖式实现的轻量级虚拟机,类似于VM,但是在原理上和应用和VM的差别还是很大的,并且docker的专业叫法是一应用容器(Application  Container)。 

为什么要用容器?

      应用容器是个什么样子呢,一个做好的应用容器就像一个装好了一组特定的应用的虚拟机一样,比如我现在想用MySQL,那我就找个装好了MySQL的容器就可以了,然后运行起来,我就能使用MySQL了。

      为什么不直接安装一个MySQL?安装一个SQL Server也可以啊,可是有的时候根据每个人电脑的不同,在安装的时候可能会出现各种各样的错误,万一你的电脑中毒了,你的电脑挂了,你所有的服务都需要重新安装,但是有了docker,或者说有了容器就不同了,你就相当于有了一个可以运行起来的虚拟机,只要运行容器,MySQL的配置就可以省了,而且如果你想换个电脑,直接把容器“搬过来”就可以使用容器里面的服务。

     Docker基于Go语言开发的,代码托管在Github上,并遵循Apache2.0开原协议。Docker容器可以封装任何有效负载,几乎可以在任何服务器之间进行一致性运行。话句话说,开发者构建的应用只需一次构建,即可多平台运行。运营人员只需要配置他们的服务,即可运行所有的应用。

     若是利用容器的话,那么开发直接在容器里开发,测试的时候把整个容器给测试,测试好了把测试后容器再上线就好了,通过容器,整个开发,测试和生产环境可以保持高度一致。

     此外容器也像VM一样具有一定的隔离性,各个容器之间的数据和内存空间相互隔离,可以保证一定的安全性。

     Hyper-v、KVM和Xen等虚拟机管理程序都“基于虚拟化硬件仿真机制”, 这意味着,他们对系统的要求很高,然而容器却使用共享的操作系统。这意味他们在使用系统资源方面比虚拟机管理程序要高效的多。容器 不是对硬件进行虚拟化处理,而是驻留在一个Linux实例上。

     Docker 可以解决虚拟机能够解决的问题,同时也能够解决虚拟机由于资源要求过高而无法解决的问题。

为什么使用Docker?

     1. 快速支付应用程序

      * 开发者使用一个 标准的image 来构建开发容器,开发完成之后,系统管理员就可以使用这个容器来部署代码。

      * docker可以快速创建容器,快速迭代应用程序,并让整个过程可见,使团队中的其他成员更容易理解应用程序是如何创建和工作的。

        *docker容器很轻!很快!容器的启动是秒级的,节约开发、测试、部署的时间

     2.更容易部署和扩展

     *docker容器可以在几乎所有的环境中运行 ,物理机、虚拟机、公有云、私有云、个人电脑、服务器等。

     * docker容器兼容很多平台,这样就可以把一个应用程序从一个平台迁移到另外一个。

     3.效率更高

     *docker 容器不需要hypervisor,他是内核级的虚拟化。

     4.快速部署也意味着更简单的管理

      *通常只需要小小的改变就可以替代以往巨型和大量的更新工作

Docker的常用案例包括:

      * 自动打包和部署应用

      * 创建轻量、私有的PaaS环境

      * 自动化测试和持续集成/部署

      * 部署并扩展Web应用、数据库和后端服务器

那么为何不用VM?

那么既然容器和VM这么类似为啥不用VM? docker容器相对于VM还是有很多优点的:

       1 启动速度快,容器通常一秒内可以启动

       2 资源利用率高,一台普通的服务器可以跑上千个容器

       3 性能开销小,

为什么相似的功能在性能上会有如此大的差距?接下来看一下他们的各自设计图。

Docker安装及容器管理

   可见容器是在操作系统层面上实现虚拟化,直接复用本地主机的操作系统,而传统的方式则是在硬件层面实现。

Docker与传统虚拟机对比总结:

Docker安装及容器管理

二、Docker的体系结构

        docker使用c/s架构,docker daemon 作为server端接受client的请求,并处理(创建、运行、分发容器),他们可以运行在一个机器中,也通过socket或者RESTful API通信

Docker安装及容器管理

   docker daemon 一般在宿主机后台运行。

   docker client 以系统命令的形式存在,用户用docker命令来跟docker daemon 交互。

   docker守护进程(docker daemon)

     如上图所示,docker守护进程运行在一台主机上。用户并不直接和守护进程进行交互,而是通过docker 客户端间接和其他通信。

docker 客户端(docker client)

docker 客户端,实际上是docker的二进制程序,是用户与docker交互方式。它接受用户指令并且与背后的docker守护进程通信。

Docker安装及容器管理

  docker 内部:

  要理解docker内部结构,需要理解以下三种部件:

   docker 镜像----docker  images

   docker 仓库----docker  registeries

   docker 容器----docker  containers

docker  镜像

   docker镜像是docker容器运行时的只读模板,镜像可以用来创建docker 容器。每一个镜像由一系列的层(layers)组成。docker使用UnionFS (联合文件系统)来将这些层联合到单独的镜像中。UnionFS允许独立文件系统中的文件和文件夹(称之为分支)被透明覆盖,形成一个单独连贯的文件系统。正因为有了这些层的存在,docker是如此的轻量。当你改变了一个docker镜像,比如升级到某个程序的新版本,一个新的层会被创建。因此,不用替换整个原先的镜像或重新建立(在使用虚拟机时你可能会这么做),只是一个新的层被添加或升级了。现在你不用重新发布镜像,只需要升级,层使得分发docker镜像变得简单和快速。

    每个docker都有很多层次构成,docker使用 union systems 将这些不同的层结合到一个image中去。

例如:centos镜像中安装了Nginx,就成了Nginx镜像,其实在此时docker镜像的层级概念就体现出来了。底层一个centos操作系统镜像,上面叠加一个Nginx层,就完成了一个Nginx镜像的构建。层级概念就不难理解,此时我们一般centos操作系统镜像称为Nginx镜像层的父镜像。

Docker安装及容器管理

docker 仓库

    docker 仓库用来保存镜像,可以理解为代码控制中的代码仓库。同样的,docker 仓库也有公有和私有的概念。公有的docker仓库名字是docker Hub。docker Hub提供了庞大的镜像集合供使用。这些镜像可以是自己创建,或者在别人的镜像基础上创建。

   仓库是集中存放镜像文件的场所。有时候会把仓库和仓库注册服务器(Registry)混为一谈,并不严格区分。实际上,仓库注册服务器上往往存放着多个仓库,每个仓库中又包含了多个镜像,每个镜像由不同的标签(teg)。

   仓库分为公开仓库(Public)和私有仓库(Private)两种模式。

    最大的公开仓库是docker Hub,存放数量庞大的镜像供用户下载。国内的公开仓库包括docker Pool等,可以提供大陆用户更稳定快速的访问。

    当然,用户也可以在本地网络内创建一个私有仓库。

     当用户创建了自己的镜像之后就可以使用 push命令将他上传到共有或私有仓库,这样下次在另外一台机器上使用这个镜像时候,只需要从仓库上 pull 下来就可以了。

* 注 : docker仓库的概念跟Git类似,注册服务器可以理解为GitHub这样的托管服务。

docker 容器

   docker利用容器来运行应用,一个docker容器包含了所有的某个应用运行所需要的坏境。每一个docker容器都是从镜像创建的运行实例。它可以被启动、开始、停止、删除。每一个docker容器都是独立和安全的应用平台。

   容器是从镜像创建的运行实例。它可以被启动、开始、停止、删除、每个容器都是相互隔离的、保证安全的平台。

    可以把容器看做是一个简易版的Linux环境(包括root用户权限、进程空间、用户空间和网络空间等)和运行在其中的应用程序。

* 注:镜像是只读的,容器在启动的时候创建一层可写层作为上层。

Docker安装及容器管理

    与虚拟机相比,容器有一个很大的差异,它们被设计用来运行“单进程”,无法很好地模拟一个完整的环境。docker设计师极力推崇“一个容器一个进程的方式”,如果你要选择在一个容器中运行多个进程,那唯一情况是:出于调试目的。

    容器是设计来运行一个应用的,而非一台机器。你可能会把容器当虚拟机用,但你将失去很多灵活性,因为docker提供了用于分离应用于数据的工具,使得你可以快捷地更新运行中的代码/系统,而不影响数据。

    docker 从0.9版本开始使用libcontainer替代lxc,libcontainer和linux系统的交互图如下:


Docker安装及容器管理


docker 底层技术

   docker 底层的2个核心技术分别是 Namespaces和Control groups

   Namespaces用来隔离各个容器

   1)pid namespace

         不同用户的进程就是通过不同的pid namespace隔离开的 namespace中可以有相同的pid。所有的LXC进程在docker中的父进程为docker进程,每个lxc进程具有不同的namespace。

   2)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:docker0

    3) ipc namespace

         container 中进程交互还是采用Linux 常见的进程交互方法(interprocess communication -IPC),包括常见的信息量、消息队列和共享内存。container 的进程间交互实际上还是host上具有相同pid namespace中的进程间交互。

   4)mnt namespace

         类似chroot,将一个进程放到一个特定的目录执行。mnt namespace 允许不同namespace的进程看到的文件结构不同,这样每个namespace中的进程所看到的文件目录就被隔离开了。在container里头,看到的文件系统,就是一个完整的Linux系统,有/etc 、/lib等,通过chroot实现。

    5)uts namespace

          UTS(“UNIX  time-sharing  System”)namespace 允许每个container 拥有独立的hostname 和 domain name, 使其在网络上可以被视作一个独立的节点而非host上的一个进程。

    6)user namespace

          每个container 可以有不同的user 和 group id, 也就是说可以在container 内部用container 内部的用户执行程序而非host上的用户。

   有了以上6种namespace从进程、网络、IPC、文件系统、UTS和用户角度的隔离,一个container 就可以对外展现出一个独立计算机的能力,并且不同container从OS层面实现了隔离。然而不同namespace之间资源还是相互竞争的,仍然需要类似ulimit来管理每个container 所能使用的资源--cgroup

      cgroups(Control  groups)实现了对资源的配额和度量。

三、 docker 安装

docker官网:https://docs.docker.com

docker 的特性:

             *  文件系统隔离性:每个进程容器运行在一个完全独立的根文件系统里。

             *  资源隔离: 系统资源,像CPU和内存等可以分配到不同的容器中,使用cgroup。

             *  网络 隔离: 每个进程容器 运行在自己的网络空间,虚拟接口和IP地址。

             *  日志记录: docker将进会收集和记录每个进程容器的标准流(stdout/stderr/stdin),用于实时检索或批量检索。

             *变更管理:容器文件系统的变更可以提交到新的映像中,并可重复使用以创建更多的容器,无需使用模板或手动配置。

             *交互式shell:docker可以分配一个虚拟终端并关联到任何容器的标准输入上。

centos系列安装docker,docker支持centos6及以后的版本 ,官方文档要求Linux  kernel 至少3.8以上,且只能运行在64位系统中。

   以下是centos7安装docker   

1  查看内核

Docker安装及容器管理

2  安装docker  (可以使用RPM 或者YUM安装,这里用YUM装)

   docker软件包已经包括在默认的Centos-Extras 软件源。因此想要安装docker,只需要使用下面yum命令(前提需要连接外网)。



[[email protected] ~]# yum -y install docker

Docker安装及容器管理

3  安装完成后,启动docker ,并设置为开机自启

[[email protected] ~]# systemctl start docker
[[email protected] ~]# systemctl enable docker

Docker安装及容器管理

4  查看docker版本

[[email protected] ~]# docker version 

Docker安装及容器管理

或者  [[email protected] ~]# docker info 

Docker安装及容器管理

docker默认使用Unix  socket

Docker安装及容器管理

5   查找images

      docker的一个特点是很多人因为各种不同的用途创建了各种不同的images。它们都被上传到了docker Hub 共有仓库上,我们可以在docker hub的网站上来查找它们。使用docker search命令

这里以查找centos7为例:

[[email protected] ~]# docker search centos7

Docker安装及容器管理

我们看到了很多包含centos7的images。其中包括images名字、描述、星级(表示受欢迎程度)、是否官方创建、是否自动创建。官方的images是stackbrew项目组创建和维护的,automated资源允许你的验证image的来源和内容。

6  获取images(以上图第一个centos7为例)

Docker安装及容器管理

7 下载完成后 使用docker  images 显示本机上的images

Docker安装及容器管理

     * REPOSITORY: 来自于那个仓库

     * TAG 的标记,比如latest(最新版)

     *   IMAGE ID :镜像是它的ID

     *   CREATED:创建时间

     *  SIZE:镜像的大小

8  创建自己的images (有两种方法)

   1)第一种方法:使用 docker  commit来扩展一个image

         先使用image启动容器,更新后提交到新的image。

[[email protected] ~]# docker run -i -t docker.io/centos  /bin/bash
[[email protected]a07160d8b1d1 /]# 
       注意:记住容器ID,稍后还会用到

        在容器中添加mariadb-server应用
[[email protected] /]# yun -y install mariadb-server

 结束后,我们使用exit退出,现在我们的容器已经被改变了。使用docker commit命令来提交相应的副本。


[[email protected] ~]# docker commit -m "added mariadb app" -a "gy" a07160d8b1d1 centos:mariadb
sha256:250372101ecbe48a1d642a4ac85bfb6e5e5558fd497ebaf072c7d147285a9947
    -m:指定提交的说明信息,跟我们使用的版本控制工具一样;
-a:指定更新的用户信息;之后是用来创建镜像的容器ID;最后是指定目标镜像的仓库名和tag信息。创建成功后会返回这个镜像的ID信息。

使用docker images查看新创建的镜像

Docker安装及容器管理

现在,可以使用新的镜像来启动容器

Docker安装及容器管理

     2)第二种方法:从dockerfile来创建image

使用docker commit来扩展一个image比较简单,但它不容易在一个团队中分享它。我们使用docker build来创建一个新的image。。为此我们需要创建一个dockerfile,包含一些如何创建我们的image的指令。现在我们来创建一个目录和一个dockerfile

[[email protected] ~]# mkdir -p /docker/httpd
[[email protected] ~]# cd /docker/httpd/
[[email protected] httpd]# vim  Dockerfile

内容如下:

Docker安装及容器管理

编写完,使用docker bulid来生成镜像

Docker安装及容器管理

* 注意:一个镜像不能超过127层

   查看生成的镜像

Docker安装及容器管理

9  修改镜像的标签  docker  tag

例如;修改下图标签Docker安装及容器管理

[[email protected] ~]# docker tag centos:mariadb mariadb:v1 

Docker安装及容器管理

10   存出和载入镜像

       当需要把一台机器上的镜像迁移到另一台上,就需要存出和载入镜像。

       1)存出   docker  save

例如:存出下图docker.io/centos

[[email protected] ~]# docker save -o centos7.tar docker.io/centos:latest

Docker安装及容器管理

可以使用[[email protected] ~]# sz centos7.tar 将压缩的包下载到本地目录,在本地电脑的“下载”中可以看到。

       2)载入 镜像    docker  load

            先使用rz上传镜像Docker安装及容器管理

再使用docker   load 载入

[[email protected] ~]# docker load < centos7.tar

Docker安装及容器管理

之后可使用  [[email protected] ~]# docker images 查看

11  用docker  rmi移除本地镜像

[[email protected] ~]# docker rmi  [容器  ID] 

12  查看容器 

    docker  ps :只查看运行的容器

    docker   ps  -a  :显示所有容器

13  终止容器

     docker   stop  [容器   ID]

     docker   kill     [容器  ID]