Docker


Docker简介

Docker的出现

一款产品从开发到上线,从操作系统,到运行环境,再到应用配置。作为开发+运维之间的协作需要关心很多西,这也是很多互联网公司都不得不面对的问题,特别是各种版本的迭代之后,不同版本环境的兼容,对运维人员都是考验。

Docker之所以发展如此迅速,也是因为它对此给出了一个标准化的解决方案。开发人员利用 Docker 可以消除协作编码时“在我的机器上可正常工作”的问题。透过镜像(images)将作业系统核心,运作应用程式所需要的系统环境,由下而上打包,达到应用程式跨平台间的无缝接轨运作。

Docker是基于Go语言实现的云开源项目。Docker的主要目标是“Build,Ship and Run Any App, Anywhere”。运行环境能够做到“一次封装,到处运行”。

容器对比虚拟机

虚拟机(virtual machine)就是带环境安装的一种解决方案,虚拟机的缺点:资源占用多、冗余步骤多 、启动慢。

Linux 容器不是模拟一个完整的操作系统,而是对进程进行隔离。有了容器,就可以将软件运行所需的所有资源打包到一个隔离的容器中。容器与虚拟机不同,**不需要捆绑一整套操作系统,只需要当前软件工作所需的库资源和设置。**系统因此而变得高效轻量并保证部署在任何环境中的软件都能始终如一地运行。

二者的不同之处:

传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程;

而容器内的应用进程直接运行于宿主的内核,容器内没有自己的内核,而且也没有进行硬件虚拟。因此容器要比传统虚拟机更为轻便。每个容器之间互相隔离,每个容器有自己的文件系统 ,容器之间进程不会相互影响,能区分计算资源。

Docker基础架构

Docker有三个重要的概念:仓库、镜像和容器 ,它们是Docker的三大基础组件。

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

Docker安装

安装以CentOS6.8为例

step1:安装EPEL包

yum install -y epel-release

step2:安装Docker

yum install -y docker-io

安装后的配置文件在:/etc/sysconfig/docker

step3:启动Docker

service docker start

docker version

step4:配置阿里云镜像加速

https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors

找到自己的加速器地址:https://xxxx.mirror.aliyuncs.com

vim /etc/sysconfig/docker

将获得的自己账户下的阿里云加速地址配置进:

other_args="--registry-mirror=https://自己的账号加速信息.mirror.aliyuncs.com"

重启Dockerservice docker restart即可

step5:测试HelloWorld

docker run hello-world

Docker运行原理:

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

当新建一个虚拟机时,虚拟机软件需要加载Guest OS,返个新建过程是分钟级别的。而Docker由于直接利用宿主机的操作系统,则省略了返个过程,因此新建一个Docker容器只需要几秒钟

Docker的常用命令

帮助命令

docker version

docker info

docker --help

镜像命令

docker images

REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
hello-world         latest              9f5834b25059        14 months ago       1.84 kB
  • REPOSITORY:表示镜像的仓库源
  • TAG:镜像的标签
  • IMAGE ID:镜像ID
  • CREATED:镜像创建时间
  • SIZE:镜像大小

docker search搜索某个镜像名称(从http://hub.docker.com)

>> docker search tomcat
NAME                  DESCRIPTION                         STARS     OFFICIAL   AUTOMATED
tomcat                Apache Tomcat is an open source implementa...   2659      [OK]       
tomee                 Apache TomEE is an all-Apache Java EE cert...   75        [OK]       
dordoka/tomcat        Ubuntu 14.04, Oracle JDK 8 and Tomcat 8 ba...   53        [OK]
bitnami/tomcat        Bitnami Tomcat Docker Image                     31        [OK]
kubeguide/tomcat-app  Tomcat image for Chapter 1                      28        [OK]

docker pull 镜像名称[:TAG]下载镜像

[root@hadoop1 /]# docker pull tomcat
latest: Pulling from tomcat
ed7bc7435c95: Pull complete
......
Digest: sha256:613e0884313f0da2e3b536c0c1c1850a9df405055e78320eb24b1559b708fa3c
Status: Downloaded newer image for tomcat:latest

docker rmi 镜像名称[:TAG]删除镜像

容器命令

docker run -it -p 8888:8888 --name test (-v id:文件 文件) jiang/centostest (/bin/bash,dockerfile后面已有CMD)
docker run -p 8888:8888 --name test (-v 宿主机文件路径 容器文件路径) -d jaing/centostest (在后台运行,但是如果这个镜像或者dockerfile文件后由/bin/bash,就会先执行这个再执行-d,相当于直接退出exit)

有镜像才能创建容器

docker run [OPTION] IMAGE [COMMAND][ARG...]新建并启动容器

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

​ ip:hostPort:containerPort

​ ip::containerPort

​ hostPort:containerPort

​ containerPort

>> docker run -it --mycentos 2f5f33207762
[root@hadoop1 桌面]# docker run -it efa3cf
[root@a596cb0250f4 /]# ll

docker ps [OPTIONS]列出正在运行的容器

OPTIONS说明(常用):

  • -a : 列出当前所有正在运行的容器+历史上运行过的
  • -l : 显示最近创建的容器。
  • -n:显示最近n个创建的容器。
  • -q : 静默模式,只显示容器编号。
  • –no-trunc : 不截断输出。
[root@hadoop1 桌面]# docker ps
CONTAINER ID      IMAGE     COMMAND    CREATED          STATUS     PORTS       NAMES
a596cb0250f4     efa3cf   "/bin/bash"  5 minutes ago    Up 5 minutes    desperate_turing 

exit 容器停止并退出

Ctrl + P + Q 容器不停止退出

docker start 容器ID 启动容器

docker restart 容器ID 重启容器

docker stop 容器ID 停止容器

docker kill 容器ID 强制停止容器

docker rm 容器ID 删除已停止容器

docker run -d centos /bin/sh -c "while true;do echo hello zzyy;sleep 2;done"

上面命令是启动守护式容器,不显示终端,可以通过查日志了解运行情况

docker logs -f -t --tail 倒数几条 容器ID

查看容器内运行的进程:docker top 容器ID

查看容器内部细节:docker inspect 容器ID

进入正在运行的容器并以命令行交互:

  1. 直接进入容器启动命令的终端,不会启动新的进程

    docker attach 容器ID

  2. 是在容器中打开新的终端,并且可以启动新的进程

    docker exec -it 容器ID bashShell

从容器内拷贝文件到主机上:docker cp 容器ID:容器内路径 目标主机路径

Docker镜像

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

分层结构

UnionFS(联合文件系统):Union文件系统(UnionFS)是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directories into a single virtual filesystem)。Union 文件系统是 Docker 镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。

特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录。

在下载的过程中我们可以看到docker的镜像好像是在一层一层的在下载。

为什么一个Tomcat镜像500Mb:因为它有很多层依赖

分层的原因:

分层最大的一个好处就是共享资源

有多个镜像都从相同的base镜像构建而来,那么宿主机只需在磁盘上保存一份base镜像;

同时内存中也只需加载一份base镜像,就可以为所有容器服务了,而且镜像的每一层都可以被共享。

镜像的特点

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

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

镜像Commit

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

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

以删除Tomcat中的docs目录并打包镜像为例:

  1. 以8888端口运行Tomcat:docker run -it -p 8888:8080 tomcat:6.0

  1. 打开命令行:docker exec -it dd48eb572cfa /bin/bash
  2. 删除webapps目录下的docs文件
  3. 打包镜像:docker commit -a="tulong" -m="del tomcat docs" dd48eb572cfa tulong/mytomcat:1.2
REPOSITORY          TAG             IMAGE ID            CREATED             VIRTUAL SIZE
tulong/mytomcat     1.2             5af170c2e5bd        5 seconds ago       354.7 MB

容器数据卷

Docker容器产生的数据,如果不通过docker commit生成新的镜像,使得数据做为镜像的一部分保存下来,那么当容器删除后,数据自然也就没有了。为了能保存数据在docker中我们使用容器数据卷。

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

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

数据卷

直接命令添加

将容器与宿主机之间文件绑定:

docker run -it -v /宿主机目录:/容器内目录 centos /bin/bash

查看数据卷是否挂在成功:

docker inspect 容器ID

容器与宿主机之间数据共享:

容器停止退出后,主机修改后数据同步。

只读权限:docker run -it -v /宿主机绝对路径目录:/容器内目录 ro 镜像名

Dockerfile添加

Dockerfile为Image的描述文件

可在Dockerfile中使用VOLUME指令来给镜像添加一个或多个数据卷:

# volume test
FROM centos
VOLUME ["/dataVolumeContainer1","/dataVolumeContainer2"] #在容器中创建这两个文件。并且当run的时候会自动在宿主机中某个路径下创建两个文件进行挂载,具体用inspect查看
CMD echo "finished,--------success1"
CMD /bin/bash

build后生成新镜像:

docker build -f /mydocker/dockerfile -t tulong/centos . #注意后面有个小点

run容器后自动挂载了两个目录/dataVolumeContainer1/dataVolumeContainer2

数据卷容器

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

dc02继承自dc01:

docker run -it --name dc02 --volumes-from dc01 tulong/centos

dc03继承自dc02

在dc01、dc02、dc03任意一个添加文件其它两个都会存在。

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

Dockerfile

概念

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

构建步骤:

  1. 编写DockerFile文件
  2. docker build 创建镜像
  3. docker run 运行镜像

CentOS6.8 的 Dockerfile:

FROM scratch 
MAINTAINER The CentOS Project 
ADD c68-docker.tar.xz 
LABEL name="CentOS Base Image" 
    vendor="CentOS" 
    license="GPLv2" 
    build-date="2016-06-02"
#Default command
CMD ["/bin/bash"]

Dockerfile构建解析过程

Dockerfile文件内容:

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

Docker执行Dockerfile的大致流程:

  1. Docker从基础镜像运行一个容器;
  2. 执行一条指令并对容器作出修改;
  3. 执行类似Docker commit的操作提交一个新的镜像层;
  4. Docker再基于刚提交的镜像运行一个新容器;
  5. 执行Dockerfile中的下一条指令直到所有指令都执行完成。

Dockerfile保留字指令

FROM:基础镜像,当前镜像是基于那个镜像的;

MAINTAINER(maintainer):作者、邮箱;

RUN:容器构建时需要运行的命令;

EXPOSE:暴露端口号,启动容器的时候还需使用 –p 指定端口;

WORKDIR(workdir):指定在创建容器后,终端默认登录后进来的工作目录,一个落脚点,默认根目录,通常绝对路径,CMD ENTRYPOINT 都会在这个目录下执行;

ENV:构建镜像的过程中设置环境变量, 构建和运行时都有效可以使用$引用;

ADD:将宿主机目录下的文件拷贝到镜像且会自动处理URL和解压tar压缩包

COPY:拷贝文件和目录到镜像中,将从构建上下文目录中<源路径>的文件/复制到新的一层镜像内<目标路径>的位置。语法:COPY src dest COPY [“src”, “desc”];

VOLUME:容器数据卷, 数据保存和持久化;

USER:指定该镜像由什么用户运行,不指定由root 运行;

CMD:指定容器启动时要运行默认的命令,Dockerfile中可以有多个cmd , 但只有最后一个生效;

ENTRYPOINT(entrypoint):指定容器启动时要运行的命令。

ONBUILD RUN 当子Dockerfile执行构建build的命令时,会触发父镜像的这个命令

案例一:封装CentOS

自定义mycentos目的使镜像具备:登陆后的默认路径、vim编辑器、查看网络配置ifconfig支持。

FROM centos
MAINTAINER zzyy

ENV MYPATH /usr/local
WORKDIR $MYPATH

RUN yum -y install vim
RUN yum -y install net-tools

EXPOSE 80

CMD echo $MYPATH
CMD echo "success--------------ok"
CMD /bin/bash

案例二:自定义Tomcat

step1: 首先创建文件夹存放jdk与tomcat的安装包

mkdir -p /tulong/mydockerfile/tomcat9

step2:将jdk和tomcat安装的压缩包拷贝进上一步目录

apache-tomcat-9.0.8.tar.gzjdk-8u171-linux-x64.tar.gz

step3:在/tulong/mydockerfile/tomcat9目录下新建Dockerfile文件

FROM         centos
MAINTAINER    zzyy
#把宿主机当前上下文的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
# ENTRYPOINT ["/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 
#["catalina.sh", "run"] 可以运行一个服务,而不至于-d创建一个容器后台运行时因为没有事可做直接退出

step4:构件镜像

docker build -t mytomcat

step5:运行容器

docker run -d -p 9080:8080 --name myt9 
-v /zzyyuse/mydockerfile/tomcat9/test:/usr/local/apache-tomcat-9.0.8/webapps/test 
-v /zzyyuse/mydockerfile/tomcat9/tomcat9logs/:/usr/local/apache-tomcat-9.0.8/logs
--privileged=true zzyytomcat9

注:test目录中加入war包可以挂载到容器内,容器中logs文件中产生的日志可以同步到主机上。

Docker全流程示意图:


文章作者: 迷雾总会解
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 迷雾总会解 !
评论
  目录