docker 学习笔记

什么是容器

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

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

虚拟机与docker的比较:


docker 学习笔记_第1张图片
虚拟机与docker的比较

为什么需要容器

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


docker 学习笔记_第2张图片
集装箱和容器的对比

容器的优势

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

容器的架构

docker 架构

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


    docker 学习笔记_第3张图片
    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 来创建镜像。

docker容器

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

Registry

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

Docker 镜像

镜像的内部结构

从hello-world说起

  • 从docker hub下载它
    docker pull hello-world
    docker 学习笔记_第4张图片
    下载hello-world
  • docker images | grep 容器名 查看它
    Screen Shot 2018-04-26 at 11.31.48 PM.png
  • 通过docker run hello-world来运行他
    docker 学习笔记_第5张图片
    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
构建过程


docker 学习笔记_第6张图片
构建过程

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

容器的copyOnWrite特性

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

构建镜像

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

docker commit

通过三个步骤创建

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

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


docker 学习笔记_第7张图片
Screen Shot 2018-04-27 at 8.44.07 PM.png

2、对容器进行修改

apt-get update 

对apt-get进行更新


docker 学习笔记_第8张图片
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
docker 学习笔记_第9张图片
new-ubuntu

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

使用Dockerfile创建

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

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

然后运行

docker build -t new-ubuntu2 . 

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


docker 学习笔记_第10张图片
Screen Shot 2018-04-27 at 10.38.37 PM.png

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

使用docker history看构建过程


docker 学习笔记_第11张图片
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
exec ["executable","param1","param2"],当指令执行时会直接使用[] 里面的内容不会被shell解析,当使用CMD和ENTRYPOINT时推荐使用此种方式
使用RUN apt-get && apt-get install (避免分开使用,保证apt-get是最新的)

常用命令

docker images 查看镜像

docker 学习笔记_第12张图片
Screen Shot 2018-04-26 at 11.22.50 PM.png

docker ps或者 docker container ls 显示正在运行的容器
docker 学习笔记_第13张图片
Screen Shot 2018-04-26 at 11.24.00 PM.png

删除镜像

docker rmi imageId

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

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

你可能感兴趣的:(docker 学习笔记)