Docker的镜像和容器

Docker的镜像和容器

1. 架构与底层技术支持

Docker的总体架构:

底层技术支持:

  • Namespaces:做隔离pid,net,ipc,mnt,uts
  • Control Groups:做资源限制
  • Union File System:Container和Image的分层

2. Image

  • Image是文件和meta data的集合(root filesystem)
  • image是分层的,并且每一层都可以添加改变,删除文件,成为一个新的image
  • 不同的image可以共享相同的layer
  • image本身是只读的

查看本地的Image

docker image ls
或者
docker images

删除image

docker image rm IMAGE-ID
或者
docker rmi IMAGE-ID

2.1 通过DockerFile方式获取Docker Image

通过创建Dockerfile的方式来生成Image,比如我们要写一个helloworld的程序,那么我们现在Linux上用gcc生成一个可执行程序,然后创建一个名为Dockerfile的文件,并将下面的内入复制进去

FROM scratch
ADD hello /
CMD ["/hello"]

然后执行build命令进行构建:

docker build -t liuyao/hello-world .

最后我们可以执行:

docker run liuyao/hello-world

最后输出为:

上面就是我们通过一个Dockerfile的方式创建了一个image

2.2 从Registry从拉取Docker Image

我们可以从 Docker Hub中获取到官方和第三方的Docker Image,然后通过下面命令拉取,比如我们要获取ubuntu 16.04的

sudo docker pull ubuntu:16.04

3. Container

  • Container是通过Image创建的,故我们得先有一个image,才能有Container
  • Container是在Image layer(只读)之上建立的一个Container layer,是可读可写的。
  • 如果按照面向对象来类比的话,image相当于类,container相当于实例。
  • Image负责app的存储和分发,Container负责运行app

下面是几个Container的命令:

查看正在运行的Container容器

docker container ls

查看所有Container容器,包括已经退出的

docker container ls -a
或者
docker ps -a

交互式的运行Container,这样会进入到centos操作系统里面

docker run -it centos

删除container

docker container rm CONTAINER-ID
或者
docker rm CONTAINER-ID

查看所有container的id

docker container ls -aq

删除所有container

docker rm $(docker container ls -aq)

删除所有的已退出的container,-q参数只会列出id

docker rm $(docker container ls -f "status=exited" -q)

基于container的改变创建一个新的image

docker container commit
或者
docker commit

4. 创建Image

4.1 基于现有的image创建新的image

前期准备:

[vagrant@localhost ~]$ docker run -it centos
[root@adcdfae1c2bc /]# ls
anaconda-post.log  dev  home  lib64  mnt  proc  run   srv  tmp  var
bin                etc  lib   media  opt  root  sbin  sys  usr
[root@adcdfae1c2bc /]# touch liuyao
[root@adcdfae1c2bc /]# exit
exit
[vagrant@localhost ~]$ docker container ls -a
CONTAINER ID        IMAGE                COMMAND             CREATED             STATUS                          PORTS               NAMES
adcdfae1c2bc        centos               "/bin/bash"         18 seconds ago      Exited (0) 7 seconds ago                            nostalgic_benz

通过上面的命令,我们运行了一个centos,然后在里面touch了一个文件,然后我们退出,查看已关闭的容器是我们刚刚运行的。

然后我们通过下面的命令创建一个image

docker commit centos centos/liuyao

commit后跟原来的image名字和新的image名字

再次查看就会发现我们自己创建的image

[vagrant@localhost ~]$ docker images
REPOSITORY           TAG                 IMAGE ID            CREATED             SIZE
centos/liuyao        latest              7374a05632a1        7 seconds ago       200MB

接下来我们查看image的层

[vagrant@localhost ~]$ docker history centos/liuyao
IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
7374a05632a1        24 seconds ago      /bin/bash                                       21B                 
75835a67d134        2 weeks ago         /bin/sh -c #(nop)  CMD ["/bin/bash"]            0B                  
<missing>           2 weeks ago         /bin/sh -c #(nop)  LABEL org.label-schema.sc…   0B                  
<missing>           2 weeks ago         /bin/sh -c #(nop) ADD file:fbe9badfd2790f074…   200MB               
[vagrant@localhost ~]$ docker history centos
IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
75835a67d134        2 weeks ago         /bin/sh -c #(nop)  CMD ["/bin/bash"]            0B                  
<missing>           2 weeks ago         /bin/sh -c #(nop)  LABEL org.label-schema.sc…   0B                  
<missing>           2 weeks ago         /bin/sh -c #(nop) ADD file:fbe9badfd2790f074…   200MB 

我们发现新的image和原来的image有很多共用的,故这样是不安全的,容易将一些数据给泄漏出去。

4.3 基于Dockerfile创建iamge

编写Dockerfile文件

FROM centos
RUN touch liuyao

执行docker build

[vagrant@localhost centos-liuyao]$ docker build -t centos/liuyao-new .
Sending build context to Docker daemon  2.048kB
Step 1/2 : FROM centos
 ---> 75835a67d134
Step 2/2 : RUN touch liuyao
 ---> Running in 00d91cc9640d
Removing intermediate container 00d91cc9640d
 ---> 29fb43541a47
Successfully built 29fb43541a47
Successfully tagged centos/liuyao-new:latest
[vagrant@localhost centos-liuyao]$ docker images
REPOSITORY           TAG                 IMAGE ID            CREATED             SIZE
centos/liuyao-new    latest              29fb43541a47        11 seconds ago      200MB

可见我们基于centos自己创建了一个image

5. Dockerfile语法

官网链接:Dockerfile语法

Docker-library:官方Dockerfile

FROM :初始化新的构建平台和设置base image

尽量使用官方的image作为base image(安全)

FROM centos
FROM scratch
FROM ubuntu:14.04

LABEL :可以用来包含作者、版本、描述等信息

LABEL maintainer="liuyao"
LABEL version="1.0"
LABEL description="This is description"

RUN :执行一些命令

每执行一次RUN,都会增加新的一层,为了避免无用的分层,将多条命了合并成一行,并且为了美观,复杂的RUN用反斜线换行

RUN yum update && yum install -y vim\
	python-dev

WORKDIR :设定当前的工作目录

尽量使用WORKDIR不要使用RUN cd

尽量使用绝对目录,不要使用相对目录

WORKDIR /test #如果没有会自动创建test目录

ADD and COPY

ADD 将本地文件添加到指定目录,会自动解压,COPY不会自动解压。大部分情况,COPY优于ADD,添加远程文件/目录请使用curl或者wget

ADD hello /
ADD test.tar.gz /.  #添加到根目录并解压

WORKDIR /root
ADD hello test/  #/root/test/hello

ENV :设置常量

尽量使用ENV增加可维护性

ENV MYSQL_VERSION 5.6
RUN apt-get install -y mysql-server="${MYSQL_VERSION}" \
	&& rm -rf /var/lib/apt/lists/*  引用常量

下面对RUNCMDENTRYPOINT进行区别一下

  • RUN:执行命令并创建新的Image Layer
  • CMD:设置容器启动后默认执行的命令和参数
    • 容器启动时默认执行的命令
    • 如果docker run指定了其它命令,CMD命令被忽略
    • 如果定义了多个CMD,只有最后一个会执行
  • ENTRYPOINT:设置容器启动时运行的命令
    • 让容器以应用程序或者服务的形式运行
    • 不会被忽略,一定会执行
    • 我们可以写一个shell脚本作为entrypoint
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值