Docker基础

2020-03-05  本文已影响0人  陈科羽

镜像

Image的生命周期

Docker Image lifecycle.PNG

常用操作

docker save -o busybox.tar busybox
docker load -i busybox.tar

docker load一般只用于导入由docker save导出的镜像,导入后的镜像跟原镜像完全一样,包括拥有相同的镜像ID和分层等内容.

Docker image的组织结构

Docker image包含着数据及必要的元数据。数据由一层层的image layer组成,元数据则是一些JSON文件,用来描述数据(image layer)之间的关系以及容器的一些配置信息

查看镜像的历史:

docker history victor0217/numberone
IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
51b41265c9d9        25 hours ago        /bin/sh -c #(nop)  ENTRYPOINT ["java" "-jar"…   0B                  
0724e6967b63        25 hours ago        /bin/sh -c #(nop) COPY multi:9f7f512ecc1933e…   63.4MB              
cdf26cc71b50        7 days ago          /bin/sh -c set -eux;   dpkgArch="$(dpkg --pr…   205MB               
<missing>           7 days ago          /bin/sh -c #(nop)  ENV JAVA_URL_VERSION=8u24…   0B                  
<missing>           7 days ago          /bin/sh -c #(nop)  ENV JAVA_BASE_URL=https:/…   0B                  
<missing>           7 days ago          /bin/sh -c #(nop)  ENV JAVA_VERSION=8u242       0B                  
<missing>           7 days ago          /bin/sh -c { echo '#/bin/sh'; echo 'echo "$J…   27B                 
<missing>           7 days ago          /bin/sh -c #(nop)  ENV PATH=/usr/local/openj…   0B                  
<missing>           7 days ago          /bin/sh -c #(nop)  ENV JAVA_HOME=/usr/local/…   0B                  
<missing>           7 days ago          /bin/sh -c #(nop)  ENV LANG=C.UTF-8             0B                  
<missing>           7 days ago          /bin/sh -c set -eux;  apt-get update;  apt-g…   11.1MB              
<missing>           8 days ago          /bin/sh -c apt-get update && apt-get install…   145MB               
<missing>           8 days ago          /bin/sh -c set -ex;  if ! command -v gpg > /…   17.5MB              
<missing>           8 days ago          /bin/sh -c apt-get update && apt-get install…   16.5MB              
<missing>           8 days ago          /bin/sh -c #(nop)  CMD ["bash"]                 0B                  
<missing>           8 days ago          /bin/sh -c #(nop) ADD file:e05e45c33042db4ec…   114MB     

镜像被本地存储在:/var/lib/docker
查看镜像的元数据信息: docker inspect busybox

仓库

Hub和Repository以及Image的关系如下图:


仓库组织图

仓库的名字通常由两部分组成,中间以斜线分开。斜线之前是用户名,斜线之后是镜像名。如tom/ubuntu表示属于用户tom的Ubuntu镜像。这也是社区上区分公有仓库和私有仓库的方法.

上面的示例中是向本地私有仓库上传镜像。如果不写服务器地址,则默认上传到官方DockerHub(https://hub.docker.com

可以通过Docker Private Registry搭建一个本地的镜像仓库:

docker run -d --hostname localhost --name registry-v2 \
-v /opt/data/distribution:/var/lib/registry/docker/registry/v2 \
-p 5000:5000 registry:2.0

网络

CNM概念模型


CNM

Libnetwork提出了新的容器网络模型(Container Network Model,简称CNM),定义了标准的API用于为容器配置网络,其底层可以适配各种网络驱动

Libnetwork已经实现了五种驱动(driver):

常用命令

docker network disconnect bridge mysql
docker network connect numberone-net mysql

5种容器网络模式

docker run --net=none -it ubuntu ip addr show
docker run -h dockernet --dns 8.8.4.4 -itd ubuntu bash
docker run --net=container:{target container id} -it ubuntu bash
docker run -it --net=host ubuntu bash

Docker daemon启动时会在主机创建一个Linux网桥(默认为docker0,可通过-b参数手动指定)。容器启动时,Docker会创建一对veth pair(虚拟网络接口)设备,veth设备的特点是成对存在,从一端进入的数据会同时出现在另一端。Docker会将一端挂载到docker0网桥上,另一端放入容器的Network Namespace内,从而实现容器与主机通信的目的


Bridge

在桥接模式下,Docker容器与Internet的通信,以及不同容器之间的通信,都是通过iptables规则控制的
总之,Docker网络的初始化动作包括:创建docker0网桥、为docker0网桥新建子网及路由、创建相应的iptables规则等

如图5-3所示,每创建一个网络,Docker会在主机上创建一个单独的沙盒,沙盒的实现实质上是一个Network Namespace。在沙盒中,Docker会创建名为br0的网桥,并在网桥上增加一个vxlan接口,每个网络占用一个vxlan ID,当前Docker创建vxlan隧道的ID范围为256~1000,因而最多可以创建745个网络。当添加一个容器到某一个网络上时,Docker会创建一对veth网卡设备,一端连接到此网络相关沙盒内的br0网桥上,另一端放入容器的沙盒内,并设置br0的IP地址作为容器内路由默认的网关地址,从而实现容器加入网络的目的
以图5-3为例,容器1和容器4同属一个网络,容器1需要通过256号vxlan隧道访问另一台主机的容器4。Docker通过vxlan和Linux网桥实现了跨主机的虚拟子网功能。

容器卷

Docker容器里产生的数据,如果不通过docker commit生成新的镜像,使数据作为镜像的一部分保存下来,就会在容器删除后丢失。
为了能够持久化保存和共享容器的数据,Docker提出了(volume)的概念。简单来讲,卷就是目录或文件,由Docker daemon挂载到容器中,因此不属于联合文件系统,卷中的数据在容器被删除后仍然可以访问

数据卷

docker run -d -v /tmp/data --name busyboxtest busybox

其中,-v参数会在容器的/tmp/data目录下创建一个新的数据卷
用户可以通过docker inspect命令查看数据卷在主机中的位置: docker inspect busyboxtest

docker run -d -v /host/data:/data --name busyboxtest busybox

上述命令可以将Docker daemon所在主机的/host/data目录挂载到容器的/data路径下
-v参数的主机目录必须使用绝对路径,如果指定路径不存在,Docker会自动创建该目录。
以只读的方式挂载一个数据卷: docker run -it -v /host/data:/data:ro --name busyboxtest busybox

数据卷容器

如果用户需要在容器之间共享一些需要永久存储的数据,或者想要使用一个临时容器中的相关数据,可以创建一个数据卷容器,然后使用该容器进行数据共享。

docker create -v /dbdata --name dbdata training/postgress /bin/true
docker run -d --volumes-from dbdata --name db1 training/postgress
docker run -d --volumes-from dbdata --name db2 training/postgress
docker run -d --name db3 --volumes-from db1 training/postgress

数据卷的备份,转储和迁移

docker run --rm --volumes-from dbdata -v $(pwd):/backup ubuntu tar cvf /backup/backup.tar /dbdata

上述命令创建了一个容器,该容器挂载了dbdata数据卷,并将主机的当前目录挂载到了容器的/backup目录中;然后在容器中使用tar命令将dbdata数据卷中的内容打包存放到/backup目录的backup.tar文件中。待容器执行结束后,备份文件就会出现在主机的当前目录。之后可以将该备份文件恢复到当前容器或新创建的容器中,完成数据的备份和迁移工作

Docker API

目前Docker提供如下三类RESTful API:

RestAPI应用实例

如果没有进行特殊配置,Docker会监听本机的一个unix socket,默认为unix:///var/run/docker.sock

本地访问:

echo -e "GET /images/json HTTP/1.0\r\n" | nc -U /var/run/docker.sock

远程访问

curl -XGET localhost:5678/images/ubuntu/history

使用python格式化json输出

curl -XGET localhost:5678/images/ubuntu/history | python -mjson.tool

启动Docker暴露HTTP访问接口

docker -d -H unix:///var/run/docker.sock -H tcp://0.0.0.0.:5678

安全性

Cgroup

Cgroup用于限制容器对CPU、内存等关键资源的使用,防止某个容器由于过度使用资源,导致host或者其他容器无法正常运作

限制CPU

Docker能够指定一个容器的CPU权重,这是一个相对权重,与实际的处理速度无关。事实上,没有办法限制一个容器只可以获得1GHZ的CPU。每个容器默认的CPU权重是1024,简单地说,假设只有两个容器,并且这两个容器竞争CPU资源,那么CPU资源将在这两个容器之间平均分配。如果其中一个容器启动时设置的CPU权重是512,那它相对于另一个容器只能得到一半的CPU资源,因此这两个容器可以得到的CPU资源分别是33.3%和66.6%。但如果另外一个容器是空闲的,第一个容器则会被允许使用100%的CPU。也就是说,CPU资源不是预先硬性分配好的,而是跟各个容器在运行时对CPU资源的需求有关

选项 描述
--cpuset-cpus="" 允许使用的 CPU 集,值可以为 0-3,0,1
-c,--cpu-shares=0 CPU 共享权值(相对权重)
--cpu-period=0 限制 CPU CFS 的周期,范围从 100ms~1s,即[1000, 1000000]
--cpu-quota=0 限制 CPU CFS 配额,必须不小于1ms,即 >= 1000
--cpuset-mems="" 允许在上执行的内存节点(MEMs),只对 NUMA 系统有效
docker run --rm -it -c 100 ubuntu bash
 docker run --rm -it --cpu--period=500000 --cpu-quota=250000 ubuntu /bin/bash
docker run --rm -it --cpuset--cpus=0,1 ubuntu /bin/bash

限制内存

选项 描述
-m,--memory 内存限制,格式是数字加单位,单位可以为 b,k,m,g。最小为 4M
--memory-swap 内存+交换分区大小总限制。格式同上。必须必-m设置的大
--memory-reservation 内存的软性限制。格式同上
--oom-kill-disable 是否阻止 OOM killer 杀死容器,默认没设置
--oom-score-adj 容器被 OOM killer 杀死的优先级,范围是[-1000, 1000],默认为 0
--memory-swappiness 用于设置容器的虚拟内存控制行为。值为 0~100 之间的整数
--kernel-memory 核心内存限制。格式同上,最小为 4M
docker run --rm -it -m 200M ubuntu /bin/bash

这个例子将容器可使用的内存限制在200MB。不过事实上还不是这么简单,我们知道系统在发现内存不足时,会将部分内存置换到swap分区里,因此如果只限制内存使用量,可能会导致swap分区被用光。通过--memory-swap参数可以限制容器对内存和swap分区的使用,如果只是指定-m而不指定--memory-swap,那么总的虚拟内存大小(也即memory加上swap)是-m参数的两倍

Dockerfile

Dockerfile的注释都是以“#”开始的,每一行是一个指令。一般情况下,Dockerfile由4部分组成:

  1. 基础镜像信息
  2. 维护者信息
  3. 镜像操作指令
  4. 容器启动指令
# This Dockerfile uses the ubuntu image
# Version 2 - EDITION 1
# Author: tester
# Command format: Instruction [arguments / command] ..
# Base image to use, this must be set as the first line
From ubuntu
#Maintainer: tester tester@email.com
MAINTAINER tester tester@hotmail.com
#Commands to update the image
RUN echo "deb http://archive.ubuntu.com/ubuntu/ raring main universe" >> /etc/apt/sources.list
RUN apt-get update && apt-get install -y nginx
RUN echo "\ndaemon off;" >> /etc/nginx/nginx.conf
#Commands when creating a new container
CMD /usr/sbin/nginx

Dockerfile指令

Docker集群管理

Compose

Compose是用来定义和运行一个或多个容器应用的工具。使用Compose可以简化容器镜像的建立及容器的运行。
Compose是使用YML文件来定义多容器应用的,它还会用docker-compose up命令把完整的应用运行起来.
从本质上来讲,Compose把YML文件解析成docker命令的参数,然后调用相应的docker命令行接口,从而把应用以容器化的方式管理起来。它通过解析容器间的依赖关系来顺序地启动容器。而容器间的依赖关系则可以通过在docker-compose.yml文件中使用“links”标记来指定.

实例

web:
      build: ./web
      ports:
      - "5000":"5000"
      volumes:
      - .:/code
      links:
      - redis
redis:
     image: redis
  • 每个定义的服务都至少要包含build或image两个命令中的一个,其他的命令都是可选的.
  • build命令指定了包含Dockerfile的目录,可以是绝对目录也可以是相对目录,相对目录指的是相对于docker-compose.yml文件所在位置的目录
  • docker-compose.yml文件中的“ports”标记对应docker run命令中的“-p”选项
  • “volumes”标记对应docker run命令中的“-v”选项
  • “links”标记对应docker run命令中的“--links”选项
  • 通过运行docker-compose build和docker-compose up命令,上述docker-compose.yml文件中定义的Web和Redis服务都会成功运行起来

Machine

上一篇 下一篇

猜你喜欢

热点阅读