Docker

没有太多灵魂,上手参考,Docker简单基础的使用


Docker简介

背景

1、出现原因:

解决开发和部署之间因环境和配置导致的项目部署不成功的问题

理念

docker是基于Go语言实现的云开源项目

Build,Ship and Run Any App, Anywhere

作用

解决了运行环境和配置问题的软件容器,方便做持续集成并有助于整体发布的容器虚拟化技术。

更轻量:基于容器的虚拟化,仅包含业务运行所需的runtime环境

更高效:无操作系统虚拟化开销

  • 计算:轻量、无额外开销
  • 存储
  • 网络:宿主机网络,NS隔离

更敏捷、灵活:

  • 封层的存储和包管理,devops理念
  • 支持多种网络配置

Docker和传统虚拟化方式的不同之处

  1. 传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整的操作系统,在该操作系统上再运行所需要的应用进程
  2. 而容器内的应用进程直接运行于宿主的内容,容器内没有自己的内核,而且也没有进行硬件虚拟。因此容器要比传统虚拟机更为轻便
  3. 每个容器之间相互隔离,每个容器有自己的文件系统,容器之间进程不会相互影响,能区分计算机资源

开发/运维

一次构建、随处运行

  • 更快速的应用交付和部署
  • 更便捷的升级和扩缩容
  • 更简单的系统运维
  • 更高效的计算资源利用

Docker的基本组成

https://yeasy.gitbooks.io/docker_practice/content/basic_concept/image.html

镜像(image)

镜像就是一个只读的模板,镜像可以用来创建Docker容器,一个镜像可以创建很多容器

容器(container)

Docker利用容器独立运行的一个或一组应用。容器就是用镜像创建的运行实例。

它可以被启动、开始、停止、删除。每个容器都是相互隔离的、保证安全的平台。

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

容器的定义和镜像几乎一模一样,也是一堆层的统一视角,唯一区别在于容器的最上面是可读可写的。

仓库(repository)

仓库是集中存放镜像文件的场所

仓库(Repository)和仓库注册服务器(Registry)是有区别的。仓库注册服务器上往往存放着多个仓库,每个仓库又包含多个镜像,每个镜像有不同的标签(tag)。

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

最大的公开仓库是Docker hub

存放了数量庞大的镜像供用户下载。国内的公开仓库包括阿里云、网易云

总结

Docker 本身是一个容器运行载体或称之为管理引擎。我们把应用程序和配置依赖打包好形成一个可交付的运行环境,这个打包好的运行环境就是image镜像文件。只有通过这个镜像文件才能生成Docker容器。image文件可以看作是容器的模板。Docker根据image文件生成容器的实例。同一个image文件,可以生成多个同时运行的容器实例。

  • image文件生成的容器实例,本身已是一个文件,称之为镜像文件。
  • 一个容器运行一种服务,当我们需要的时候,就可以通过docker客户端创建一个对应的运行实例,也即是我们的容器
  • 至于仓库,就是存放一堆镜像的地方,我们可以把镜像发布到仓库中,需要的时候从仓库中拉下来就可以

安装Docker

centos6

  1. yum install -y epel-release
  2. yum install -y docker-io
  3. 配置文件 /etc/sysconfig/docker
  4. 启动Docker后台服务 service docker start
  5. docker version

看官网!!!

centos7

systemctl start docker

Docker底层原理

Docker是怎么工作的

Docker是一个Client-Server结构的系统,Docker守护进程运行在主机上,然后通过Socket连接从客户端访问,守护进程从客户端接受命令并管理运行在主机上的容器。容器,是一个运行时环境。

为什么Docker比虚拟机快

  1. docker有着比虚拟机更少的抽象层。由于不需要Hypervisor实现硬件资源虚拟化,运行在docker容器上的程序直接使用的都是实际物理机的硬件资源。因此在CPU、内存利用率上docker将会在效率上有明显的优势
  2. docker利用的是宿主机的内核,而不需要GusetOS。因此,当新建一个容器是,docker不需要和虚拟机一样重新加载一个操作系统内核。
Docker容器 虚拟机(VM)
操作系统 与宿主机共享OS 宿主机OS上运行虚拟机OS
存储大小 镜像小,便于存储与传输 镜像庞大(vmdk、vdi等)
运行性能 几乎无额外性能损失 操作系统额外的CPU、内存消耗
移植性 轻便、灵活,适应于Linux 笨重,与虚拟化技术耦合度高
硬件亲和性 面向软件开发者 面向硬件维护者
部署速度 快速、秒级 较慢

Docker命令

帮助命令

  1. docker version

  2. docker info

  3. docker –help

镜像命令

  1. docker images
    • 列出本地的镜像
      • -a : 列出本地所有的镜像(含中间印象层)
      • -q : 只显示镜像ID
      • –digests : 显示镜像的摘要信息
      • –no-trunc : 显示完整的镜像信息
  2. docker search 某个镜像的名字
    • –no-trunc : 显示完整的镜像描述
    • -s : 列出收藏数不小于指定值的镜像
    • –automated : 只列出automated build类型的镜像
  3. docker pull 某个镜像的名字
  4. docker rmi 某个镜像的名字
    • 删除全部 docker rmi -f $(docker images -qa)

容器命令

  • 新建并启动容器

    ​ docker run [OPTIONS] IMAGE [COMMAND]【ARG…】

    • –name=”容器新名字”:为容器指定一个名称;
    • -d:后台运行容器,并返回容器ID,也即启动守护式容器
    • -i:以交互模式运行容器,通常与-t同时使用
    • -t:为容器重新分配一个伪输入终端,通常与-i同时使用;
    • -P:随机端口映射;
    • -p:指定端口映射,有一下四种格式
      • ip:hostPort:containerPort
      • ip::containerPort
      • hostPort:containerPort
      • containerPort
  • 列出当前所有正在运行的容器

    ​ docker ps [OPTIONS]

    • -a:列出当前所有正在运行的容器+历史上运行过的
    • -l:显示最近创建的容器
    • -n:显示最近n个创建的容器
    • -q:静默模式,只显示容器编号
    • –no-trunc:不截断输出
  • 退出容器

    • exit 容器停止退出
    • ctrl+P+Q 容器不停止退出
  • 启动容器

    • docker start 容器名/容器ID
  • 重启容器

    • docker restart 容器ID
  • 停止容器

    • docker stop 容器ID
  • 强制停止

    • docker kill 容器ID
  • 删除已停止的容器

    • docker rm 容器ID
    • docker rm -f $(docker ps -a -q) docker ps -a -q | xargs docker rm : 一次删除多个容器
  • 重要命令

    • 启动守护式容器 docker run -d centos

      通过docker ps -a 进行查看,会发现容器已经退出

      很重要的说明一点:Docker容器后台运行,就必须有一个前台进程

      容器运行的命令如果不是那些一直挂起的命令(比如运行top,tail),就会自动退出。

      这个是docker的机制问题,比如web容器,以nginx威力,正常情况下,我们配置启动服务只需要启动响应的服务service即可,例如:service nginx start

      但是,这样做,nginx为后台进程模式运行,就导致docker前台没有运行的应用,这样的容器后台启动后,会立即自杀,因为它觉得它没事可做,所以,最佳方案是将要运行的程序以前台进程的形式运行。

    • 查看容器日志

      docker logs -f -t –tail 容器ID

      -t : 加入时间戳

      -f : 跟随最新的日志打印

      –tail 数字:显示最后多少条

    • 查看容器内运行的进程

      docker top 容器ID

    • 查看容器内部的细节

      docker inspect 容器ID

    • 进入正在运行的程序 并以命令行交互

      docker exec -it 容器ID bashShell :是在容器中打开新的终端,并且可以启动新的进程

      docker attach 容器ID :直接进入容器启动命令的终端,不会启动新的进程

    • 从容器内拷贝文件到主机上

      docker cp 容器ID:容器内路径 目的主机路径

Docker镜像

是什么:是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的原件,它包含运行某个软件所需的所有内容,包括代码、运行时 库、环境变量和配置文件

  • UnionFS(联合文件系统)

  • Docker镜像加载原理

    docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统UnionFS。

    bootfs(boot file system)主要包含bootloader 和 kernel,bootloader主要是引导加载kernel,Linux刚启动时会加载bootfs文件系统,在Docker镜像的最底层bootfs。这一层与我们典型的linux/unix系统是一样的,包含boot加载器的内核。当boot加载完成之后整个内核就都在内存中,此时内存的使用权已由bootfs交给内核,此时系统也会西在bootfs。

    rootfs(root file system),在bootfs之上,包含的就是典型linux系统中的/dev,/proc,/bin等标准目录和文件。rootfs就是各种不同的操作系统发行版,比如ubuntu、centos

  • 分层的镜像

  • 为什么Docker镜像要采用这种分层结构

    利于共享资源

镜像特点

docker镜像都是只读的

当容器启动时,一个新的可写层被加载到镜像的顶部。这一层通常被称作为”容器层”,”容器层”之下的都叫镜像层

docker commit 提交容器副本使之成为一个新的镜像

docker commit -m=”提交的描述信息” -a=”作者” 容器ID 要创建的目标镜像名:[标签名]

Docker容器数据卷

卷就是目录或者文件,存在于一个或多个容器中,由docker挂在到容器,但不属于联合文件系统,因此可以绕过Union File System提供的一些用于持续存储或共享数据的特性。

卷的设计目的就是数据的持久化,完全独立于容器的生存周期,因此Docker不会在容器删除时删除其挂在的数据卷

特点:

  • 数据卷可在容器之间共享或重用数据
  • 卷中的更改可以直接生效
  • 数据卷的更改不会包含在镜像的更新中
  • 数据卷的生命周期一直持续到没有容器使用他为止

容器内添加

  • 直接命令添加

    命令 —— docker run -it -v /宿主机绝对路径目录:/容器内目录 镜像名

    查看数据卷是否挂载成功

    容器和宿主机之间数据共享

    容器停止退出后,主机修改后数据是否同步(同步)

    命令(带权限)—— docker run -it -v /宿主机绝对路径目录:/容器内目录:ro镜像名

  • dockerFile添加

数据卷容器

命名的容器挂在数据卷,其它容器通过挂在这个(父容器)实现数据共享,挂在数据卷的容器,称之为数据卷容器

容器之间配置信息的传递,数据卷的生命周期一直持续倒没有容器使用它为止。

DockerFile解析

  1. 手动编写一个dockerfile文件,必须符合file的规范
  2. 有了这个文件后,直接docker bulid命令执行,获得一个自定义的镜像
  3. run

DockerFile是什么

用来构建docker镜像的构建文件,是由一系列命令和参数构成的脚本

DockerFile构建过程解析

dockerfile内容基础知识

  • 每条保留字指令都必须为大写字幕且后面要跟随至少一个参数
  • 指令按照从上到下,顺序执行
  • #表示注释
  • 每条指令都会创建一个新的镜像层,并对镜像进行提交

dockerfile执行的的大致流程

  • docker从基础镜像运行一个容器
  • 执行一条指令并对容器做出修改
  • 执行类似docker commit的操作提交一个新的镜像层
  • docker再基于刚提交的镜像运行一个新容器
  • 执行dockerfile中的下一条指令知道所有指令都执行完成

总结

从应用软件的角度来看,Dockerfile、Docker镜像和Docker容器分别代表软件的三个不同阶段

  • Dockerfile是软件的原材料
  • Docker镜像是软件的交付品
  • Dokcer容器则可以认为是软件的运行态

Dockerfile面向开发,Docker镜像成为交付标准,Docker容器则涉及部署与运维,三者缺一不可,合力充当Docker体系的基石。

  1. Dockerfile,需要定义一个Dockerfile,Dockerfile定义了进程需要的一切东西。Dockerfile涉及的内容包括执行代码或者是文件,环境变量、依赖包、运行时环境、动态链接库、操作系统的发行版、服务进程和内核进程(当应用进程需要和系统服务和内核进程打交道,这时需要考虑如何设计namespace的权限控制)等等。
  2. Docker镜像,在用Dockerfile定义一个文件之后,docker build时会产生一个Docker镜像,当运行Docker镜像时,会真正开始提供服务;
  3. Docker容器,容器是直接提供服务的。

Dockerfile体系结构(保留字指令)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
FROM —— 基础镜像,当前新镜像是基于哪个镜像的
MAINTAINER —— 镜像维护者的姓名和邮箱地址
RUN —— 容器构建时候需要运行的命令
EXPOSE —— 当前容器对外暴露出的端口
WORKDIR —— 指定在创建容器后,终端默认登陆进来的工作目录,一个落脚点
ENV —— 用来在构建镜像过程中设置环境变量
ADD —— 将宿主机目录下的文件拷贝进镜像且ADD命令会自动处理URL和解压tar压缩包
COPY —— 类似ADD,拷贝文件和目录到镜像中。
将从构建上下文目录中<源路径>的文件/目录复制到新的一层的镜像内的<目标路径>位置
VOLUME —— 容器数据卷,用于数据保存和持久化工作
CMD —— 指定一个容器启动时要运行的命令
dockerfile中可以有多个CMD指令,但只有最后一个生效,CMD会被docker run之后的参数替换
ENTRYPOINT —— 指定一个容器启动时要运行的命令
ENTRYPOINT的目的和CMD一样,都是在指定容器启动程序及参数
ONBUILD —— 当构建一个被继承的Dockerfile时运行命令,父镜像在被子继承后父镜像的onbuild被处罚

案例

Base镜像(scratch)

Docker Hub中99%的镜像都是通过在base镜像中安装和配置需要的软件构建出来的

自定义tomcat

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
FROM   centos
MAINTAINER kokio<ykkwpp@163.com>
#把宿主机当前上下文的c.txt拷贝到容器/usr/local/路径下
COPY c.txt /usr/local/cincontainer.txt
#把java与tomcat添加到容器中
ADD jdk-8u171-linux-x64.tar.gz /usr/local/
ADD apache-tomcat-9.0.8.tar.gz /usr/local/
#安装vim编辑器
RUN yum -y install vim
#设置荣作访问时候的WORKDIR路径,登陆落脚点
ENV MYPATH /usr/local
WORKDIR $MYPATH
#配置java与tomcat环境变量
ENV JAVA_HOME /usr/local/jdk1.8.0_171
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.8
ENV CATALINA_BASE /usr/local/apache-tomcat-9.0.8
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
#容器运行时监听的端口
EXPOSE 8080
#启动时运行tomcat
#ENTRYPOING["/usr/local/apache-tomcat-9.0.8/bin/startup.sh"]
#CMD["/usr/local/apache-tomcat-9.0.8/bin/catalina.sh","run"]
CMD /usr/local/apache-tomcat-9.0.8/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.8/bin/logs/catalina.out

docker常用安装

  • 搜索镜像
  • 拉取镜像
  • 查看镜像
  • 启动镜像
  • 停止容器
  • 移除容器
------------- 感谢阅读-------------