Docker入门技术与实战

《Docker技术入门与实战》


1. docker image

1.1 镜像

  • 容器的实质是进程,但是与直接在宿主执行的进程不同,容器进程运行于属于自己的独立的命名空间. 因此容器可以拥有自己的root文件系统,自己的网络配置,自己的进程空间,甚至自己的用户id空间。
  • 容器存储层 :容器运行时,是以镜像为基础层,在它上面创建一个当前容器的存储层,
  • 容器存储层的生命周期和容器一样,容器消亡时,容器存储层也随之消亡。因此任何存储在容器存储层的信息都会随之容器的删除人丢失
  • 按照Docker最佳实践要求,容器不应该向其容器存储层写入任何数据,容器存储层要保持无状态化

    1
    2
    3
    4
    $ docker run -it --rm ubuntu:14.04 bash
    -i : interactive
    -t : tty
    --rm : remove this container after exit
  • 镜像的分层下载

  • 镜像的分层存储
  • 虚悬镜像(dangling images)
  • 中间层镜像(docker images -a):其他镜像依赖的镜像
  • 顶级镜像

    1.2 filter

    1
    2
    3
    4
    5
    6
    #-f : filter
    $ docker images -f dangling=true

    $ docker images -f since/before=mongo:3.2

    $ docker images -f label=com.example.version=0.1

1.3 以特定格式显示

1
2
3
4
$ docker images --format "{{.ID}}: {{.Repository}}"

$ docker images --format "table {{.ID}}\t{{.Repository}}\t{{.Tag
}}"

镜像是多层存储,每一层是在前一层的基础上进行的修改. 而容器同样也是多层存储,是以镜像为基础层,在其基础上加一层作为容器运行时的存储层。

当我们运行一个容器的时候(如果不使用卷volume的话),我们任何修改都会被记录到容器的存储层。 docker commit命令可以将容器的存储层保存为镜像

  • docker diff
  • docker commit生成的叫做黑箱镜像,慎用
  • docker history

1.4 使用Dockerfile定制镜像

  • FROM指定基础镜像
  • RUN执行命令,对应于docker run?
  • docker build命令并非在本地构建镜像,而是在服务端运行
  • COPY
  • ADD
  • CMD:指定默认容器的主进程,对应于docker exec?
  • 对于容器而言,其启动程序就是容器的应用进程,容器就是为了主进程而生的,如果主进程退出,那么容器就失去了存在的意义,因此也会退出,不管其他辅助进程是怎样的
  • ENTRYPOINT : docker run –entrypoint
  • ENV
  • ARG : docker build –build-arg
  • VOLUME: 容器运行的时候尽量保持容器存储层不发生写操作 docker run -v
  • EXPOSE : 注意区分docker run -p
  • WORKDIR : docker中两行RUN命令执行的环境完全不同,是两个完全不同的容器。每一个RUN命令都是启动一个容器-执行命令-提交存储层文件变更
  • USER
  • HEALTHCHECK
  • CMD ENTRYPOINT HEALTHCHECK只可以出现一次,如果写了多个,只有最后一个生效
  • docker inspect
  • ONBUILD
  • docker save
  • docker load

2. 数据卷

  • 数据卷可以在容器之间共享和重用
  • 对数据卷的修改会立刻生效
  • 对数据卷的更新不会影响到镜像
  • 数据卷默认会一直存在, 即使容器被删除

2.1 创建数据卷并挂载到容器

1
2
3
4
5
6
7
8
9
10
11
12
#创建一个数据卷/data/mount(这个目录其实并不是本地目录)并且挂在到容器
#或者在DockerFile中使用VOLUME定义
$ docker run -d -v /data/mount imageId

#挂在一个本地目录到容器(首先需要在docker preference中设置)
$ docker run -d -v /local/directory:/container/dir imageId

#挂载目录默认为读写权限, 也可以自己指定权限(ro:read only)
$ docker run -d -v /local/directory:/container/dir:ro imageId

#查看容器的信息, 输出结果中有挂载相关信息
$ docker inspect containerId
  • 挂载之后如果不能在容器中进行写操作, 可以在本地修改文件和目录权限, 这样容器中就可以进行写操作,本地能够同步

  • 注意如果/local/directory在本地需要root权限才能操作, 那么挂载到容器之后同样需要root权限

  • 因此最好是挂在本地不需要root权限的目录, 这样容器中写操作就不需要root权限了

2.2 数据卷容器

单独创建一个容器, 专门作为提供数据卷供其他容器挂载使用

1
2
3
4
5
6
#创建一个容器专门挂载数据卷
$ sudo docker run -d -v /local/dir --name dataContainer imageId echo Data-only container for postgres

#其他容器使用--volumes-from来挂载dataContainer中的数据卷
$ sudo docker run -d --volumes-from dataContainer --name db1 imageID
$ sudo docker run -d --volumes-from dataContainer --name db2 imageId

2.3 利用数据卷来备份, 迁移, 恢复数据


3. Docker的网络功能

Docker可以通过外部访问容器或者容器互联的方式提供网络服务.

3.1 外部访问容器

通过使用-P或者-p来进行端口映射

  • 当使用-P的时候, docker会随机映射一个49000~49900的端口到内部容器的开放网络端口.
  • 当使用-p的时候, 则可以指定要映射的端口, 一个端口只能绑定到一个容器. -p一次可以配置多个端口
    1
    2
    #查看
    $ bash port containerId

注意: 容器有自己的内部网络和IP地址,使用docker inspect可以查看

1
$ docker inspect  a8ecd2400134 | grep IPAddress

3.2 容器互联

通过容器互联在source容器和target容器之间创建一个隧道

1
2
3
4
$ docker run --link name:alias 

#myhost---->>> mysql
/bin/bash /usr/local/bin/docker-entrypoint.sh /start-mysql.sh