docker 学习笔记

什么是容器

容器是一种轻量级,可移植、自包含的软件的打包技术,使应用程序可以在几乎任何地方以相同的方式运行。
容器由以下两部分组成

  • 应用程序本身
  • 依赖:应用程序需要的库或者其他软件容器在host操作系统的用户空间中运行与操作系统中的其他进程隔离

虚拟机与docker的比较:


虚拟机与docker的比较

为什么需要容器

容器使软件具备了超强的可移植能力
采用集装箱的思想为代码提供一个基于容器的标准化运输系统。docker可以将任何应用及其依赖打包成一个轻量级、可移植,自包含的容器,容器几乎可以运行在所有的操作系统上
集装箱和容器的对比


集装箱和容器的对比

容器的优势

对开发人员:build once,runAnywhere
对运维人员:configure once runAnything(只需要配置好标准的runtime环境,就可以运行任何容器,容器消除了开发、测试、生产环境的不一致)

容器的架构

docker 架构

  • docker的核心组件
    Docker 客户端:client
    Docker 服务端:docker daemon
    Docker镜像:image
    Registry
    Docker 容器:Container
  • 架构图:


    Docker 架构图

    docker采用client/service 架构,客户端向服务端发送请求,服务器负责构建、运行、分发容器。客户的和服务端可以在同一个Host上运行,也可以通过REST API和socket与远程的服务器通信。

docker客户端

最常用的是docker命令,通过docker命令我们可以很方便的在Host上构建和运行容器

docker服务端

Docker Daemon是服务器组件,运行在docker host上,负责创建、运行
监控容器、构建,存储镜像。
默认配置只能响应来自本地Host的客户端请求,允许远程访问需要打开tcp监听:
编辑配置文件/etc/systemd/system/multi-user.target.wants/docker.service,环境变量ExecStart后添加-H tcp://0.0.0.0,允许来自任意ip的客户端连接
重启docker容器:
systemctl daemon-reload
systemctl restart docker.service
与远程服务器通信
docker -H ip [docker命令]

Docker 镜像

可将docker镜像看做只读模板,通过它可以创建Docker容器
镜像有多种生成方式
重无到有的创建镜像、下载别人制作好的镜像、在现有的镜像上创建新的镜像。将镜像的创建过程和内容写在一个描述文件中,这个文件被称为Dockerfile,通过执行docker build <Dockerfile>来创建镜像。

docker容器

就是镜像的运行实例,镜像就像是docker的构建打包阶段,而容器则是启动和运行阶段

Registry

是存放镜像的仓库
docker pull 可以从Registry上下载镜像
docker run则是先下载镜像,然后再启动容器

Docker 镜像

镜像的内部结构

从hello-world说起

  • 从docker hub下载它
    docker pull hello-world
    下载hello-world
  • docker images | grep 容器名 查看它
    Screen Shot 2018-04-26 at 11.31.48 PM.png
  • 通过docker run hello-world来运行他
    docker run

基础镜像

基础镜像通常是指其他进行可以基于此镜像进行扩展的镜像或者从scratch(0)开始构建
比如centos镜像


centos

该镜像才199MB,该镜像有Linux的用户空间和内核空间组成,比我们的centos系统小很多
centos镜像的Dockerfile

FROM scratch
ADD centos-7-docker.tar.xz /
CMD['bin/bash']

第二行的ADD指令是添加centos的tar包,在制作镜像时会自动将这个tar包解压到 / 路径,生成 /dev,/bin等目录,可以在docker hub查看dockerfile文件描述

docker的分层结构

Docker可以通过扩展现有的镜像创建新的镜像
例如:

FROM debian
RUN apt-get emacs
RUN apt-get install tomcat 
CMD['/bin/bash']

过程如下:
直接在debian基础镜像进行构建
安装emacs
安装tomcat
容器启动时执行bash
构建过程


构建过程

新的镜像就这一层层叠加生成,采用这种叠加最大的好处就是共享资源,当有多个镜像从同一个基础镜像构建出来时,磁盘上仅保留一份基础镜像即可。
当多个容器镜像修改了同一个基础镜像内容时,基础镜像内容并不会被改变。

容器的copyOnWrite特性

当容器启动时一个新的容器可写层被加载到镜像的顶层,这一层被称作可写层,该层下面的叫做镜像层,所有对容器的改动都只发生在容器层,镜像层只是可读的,在镜像层中用户看到的是一个叠加后的文件系统,上层会覆盖下层。
添加文件: 在容器中创建文件时,新的文件会被添加到容器层。
读取文件:在容器中读取某个文件时 ,Docker会从上往下依次在各个容器层中查找,一旦找到就打开读入内存。
修改文件:在容器中修改已经存在的文件,会先从上往下依次寻找,找到后复制到容器层,然后修改。
删除文件:从上往下查找,找到后在容器中记录该删除操作。
只有修改时才会发生CopyOnWrite。

构建镜像

通常有很多的镜像可以直接用别人制作好的,比如数据库,web服务器等,只有当我们找不到相关的镜像,或者想在某个镜像基础上加入特定的功能时才需要我们去制作镜像。通常我们自己开发的软件是需要制作镜像的。
docker提供了两种方式来制作镜像,docker commit和Dockerfile。

docker commit

通过三个步骤创建

  • 运行容器
  • 修改容器
  • 将容器保存为新的镜像
    例如:
    1、运行容器并进入容器终端
docker run -it ubuntu

如图,先在本地查找镜像,没找到然后再下载


Screen Shot 2018-04-27 at 8.44.07 PM.png

2、对容器进行修改

apt-get update 

对apt-get进行更新


Screen Shot 2018-04-27 at 8.49.53 PM.png

3、退出容器

exit

4、blissful_bassi是系统分配的名字


Screen Shot 2018-04-27 at 9.00.04 PM.png

5、接下来将运行中的容器保存为新的镜像

docker commit blissful_bassi new-ubuntu
ubuntu

6、查看new-ubuntu 的history,可以看见是一分钟我们刚刚创建的

docker history new-ubuntu
new-ubuntu

综上,这是通过手工创建的方式,仅在学习的时候用,在真实的项目中都是使用Dockerfile来进行创建的,因为手工创建的方式容易出错。

使用Dockerfile创建

Dockerfile是一个文本文件,用来记录镜像的所有构建步骤
自定义如下Dockerfile

FROM ubuntu
RUN apt-get update
RUN apt-get install -y vim

然后运行

docker build -t new-ubuntu2 . 

输入整个构建过程如下(截取部分)


Screen Shot 2018-04-27 at 10.38.37 PM.png

Screen Shot 2018-04-27 at 10.39.05 PM.png

使用docker history看构建过程


Screen Shot 2018-04-27 at 10.40.47 PM.png

镜像的缓存特性

Docker会缓存已有的镜像层,构建新的镜像时,如果某镜像层已经存在则直接使用,无需重新创建(下载镜像的时候也会使用)

Dockerfile的调试

  • 从基础镜像运行一个容器(1)
  • 执行一条指令对容器进行修改(2)
  • 执行docker commit 生成新的镜像层(3)
  • docker再基于刚刚提交的镜像运行一个新的容器(4)
    然后重复2-4步骤就可以找出问题

Dockerfile常用指令

  • FROM
    指定基础镜像
  • MAINTAINER
    设置镜像的作者
  • COPY
    将文件从build context中复制到镜像 COPY src dest
  • ADD
    从build context 复制文件到镜像,不同的是,如果src是归档文件(tar,zip,tgz,xz等),那么文件会被自动解压到dest
  • ENV
    环境变量 比如 ENV HE="HELLO WORLD"
    echo $HE 就会输出HELLO WORLD
  • EXPOSE
    指定容器中的进程会监听某个端口,docker可以将该端口暴露出来
  • VOLUME
    将文件或者目录申明为VOLUME
  • WORKDIR
    为后面的RUN,CMD,ENTRYPOINT,ADD或COPY指令设置镜像中的当前
    工作目录
  • RUN
    在容器中运行指令的指令
  • CMD
    容器启动时运行指定的命令,Dockerfile中可以有多个CMD命令但是只有最后一个生效,CMD可以被docker run 之后的参数替换
  • ENTRYPOINT
    设置容器启动时运行的命令,Dockerfile 中可以有多个ENTRYPOINT 指令,CMD的参数或者docker run 之后的参数就会交给ENTRYPOINT
    RUN & CMD & ENTRYPOINT 区别
    RUN:执行命令并创建新的容器层。经常用于安装软件包
    CMD:设置容器启动后默认执行的命令及其参数,但CMD能被docker run后面的参数替换
    ENTRYPOINT 配置容器启动时的命令

shell 和exec交互模式

shell <instruction><commond>
exec <instruction>["executable","param1","param2"],当指令执行时会直接使用[] 里面的内容不会被shell解析,当使用CMD和ENTRYPOINT时推荐使用此种方式
使用RUN apt-get && apt-get install (避免分开使用,保证apt-get是最新的)

常用命令

docker images 查看镜像

Screen Shot 2018-04-26 at 11.22.50 PM.png

docker ps或者docker container ls 显示正在运行的容器
Screen Shot 2018-04-26 at 11.24.00 PM.png

删除镜像

docker rmi imageId

持续更新中-----------------------------

笔记摘自《5分钟玩转docker容器技术》

推荐阅读更多精彩内容

  • 转载自 http://blog.opskumu.com/docker.html 一、Docker 简介 Docke...
    极客圈阅读 6,280评论 0 115
  • Docker学习笔记(一)Docker初体验 什么是Docker Docker是一个虚拟环境容器,可以将开发环境、...
    陈丰尧阅读 221评论 0 1
  • 简介 容器与管理程序虚拟化有所不同,管理程序虚拟化通过中间层将一台或多台独立的机器虚拟运行于物理硬件之上,而容器则...
    Gundy_阅读 117评论 0 4
  • 微信红包,支付宝红包,红包太常见了,太多人现了!人那么多做个广告免费拿红包怎么样? 领个红包按屏幕给的文字念一遍录...
    yaokui阅读 28评论 0 0
  • 配方:低粉,杂粮粉,黄油,鸡蛋,糖粉。 上下火180度,烤18分钟。 感悟:加入杂粮粉后,口感明显不如以前,以后为...
    真峥阅读 37评论 0 0