Docker镜像和仓库

Doker 镜像是由文件系统叠加而成

当Docker第一次启动一个容器时,初始的读写层是空的。当文件系统发生变化时,这些变化都会应用到这一层上。如果,你修改一个文件,这个文件首先会从该读写层下面的只读层复制到该读写层。该文件的只读版本依然存在,但是已经被读写层中该文件副本所隐藏。
这种机制被称为写时复制。每个只读镜像层都是只读的,并且以后永远不会变化。每当创建一个新容器时,Docker会构建出一个镜像栈,并栈的最顶端添加一个读写层。这个读写层再加上其下面的镜像层以及一些配置数据,就构成了一个容器。

列出容器

 docker images

docker pull ubuntu // 下载或获取ubuntu仓库下所有内容
docker pull centos:5.11 //下载指定版本的centos

镜像都是从仓库里下载下来的
Docker Hub 仓库有两种类型,用户仓库(个人管理)和顶层仓库(由Docker内部人来管理)

查找镜像

docker search  centos

构建镜像

有两种方式:

  • 使用docker commit 命令(不推荐使用)
  • 使用docker build命令和Dockerfile文件(功能强大且更灵活)

一般来说,我们并不是真正「创建镜像」,而是基于一个已经有基础镜像,如ubuntu或fedora等,构建新镜像而己

先在Docker Hub上注册个账号

dcoker login

使用commit命令创建镜像

我们先创建一个容器,并在容器内修改,然后提交为一个新镜像

docker run -i -t centos /bin/bash

  yum -y update //更新源
 yum install httpd  //安装 apache
 exit //退出容器
 ps -l -q 查到最新容器的id

docker commit 99289abe5d1a keithfu/apache //提交镜像

docker images keithfu/apache  //查看已经创建的容器

docker commit只会提交差异的部分。

提交的时候,可以添加更多的参数

docker commit -m="说明" --author="作者" 99289abe5d1a keithfu/apache:webserver
docker inspect keithfu/apache:webserver
docker push  //提交到hub上

用Dockerfile构建镜像

创建Dockerfile文件如下:
touch Dockerfile

#version 0.0.1
FROM ubuntu:14.04
MAINTAINER Keith Fu "[email protected]"
RUN apt-get update
RUN apt-get install -y nginx
RUN echo 'Hi I am in your container' >/usr/share/nginx/html/index.html
EXPOSE 80

执行build命令

docker build -t "keithfu/static_web" .

-t用来设置 新镜像的仓库和名称,也可添加标签
docker build -t "keithfu/static_web:v1" .
最后的.是告诉Docker 去当前目录去找Dockerfile文件

docker build -t "keithfu/static_web:v1" [email protected]:studay/css-exercise.git

Dockerfile由一系列指定和参数组成,每个指令都必须 为大写且后面紧跟一个参数,这些指定会安顺序执行。
每条指令都会创建一个新的镜像层对镜像提交

开表示注释

每个Dockerfile的第一条指令都应该是FROM,指定一个已经在存在的镜像,称之为基础镜像
MAINTAINER 指令,会告诉Docker该镜像的作者是谁,以及作者的电子邮件地址。

EXPOSE 告诉Docker该容器内的应用程序将会使用容器的指定端口,但Docker并不会自动打开该端口,需要在run运行容器时来指定需要打开哪些端口。

Docker镜像和仓库_第1张图片
Paste_Image.png

每一步都产生一个镜像,且有ID

Docker镜像和仓库_第2张图片
Paste_Image.png

还是很兴奋,push成功了,网速还是可以的

从新镜像启动容器

docker run -d -p 80 --name static_web keithfu/static_web nginx -g "daemon off"

上面 -d选项告诉Docker以分离的方式在后台运行。这种方式非常适合类似Nginx守护进程这样需要长期运行的里程。同时我们也指定了需要在容器中运行的命令:nginx -g "daemon off"。这将以前台运行的方式启动Nginx,来用作web服务器。

-p标志,用来控制Docker在运行时应该公开哪些网络端口给外部的宿主机。运行一个容器时,Docker可以通用两种方式来在宿主机上分配端口:

  • Docker可以在宿主机上随机选择一个19000~49900的一个比较大的端口号来映射到容器中的80端口上
  • 可以在Docker宿主机中指定一个具体的端口号来映射到容器中的80端口上。
    我们上面的例子是在随机打一个端口,这个端口会连接到80端口上,可以使用 docker ps命令来看一下容器的端口分配情况:
Paste_Image.png

我们也可以使用docker poort来查看容器的端口映射情况。

docker port  keithfu/static_web

docker port keithfu/static_web 80  //查看具体的端口的绑定情况
docker run -d -p 127.0.0.1:80:80 --name static_web keithfu/static_web nginx -g "daemon off;"

按上面的方式,我们可以具体指明宿主的端口号,但这样,如果多个容器运行,只能有一个能成功。
如果 -p 不指定任何,则会公开Dockerfile中的EXPOSE指指令中设置的所有端口

Paste_Image.png

成功运行

Dockerfile 和构建缓存

每一步 的构建过程都会将结果提交为镜像,所以Docker的构建镜像过程就显得非常聪明,它会将之前的镜像层看做缓存。如上例子,如会只 在4步发生了变化 ,那么前3步不会重新构建 ,而是直接进行第四步。那么说第三步中的apt-get update ,不会在刷新APT包的缓存。但有的时候,你f却不想这样,需要略过缓存。可以使用 docker build --no-cache标起

基于构建缓存的Dockerfile模板

看如下:

FROM ubuntu:14.04
MAINTAINER  KeithFu
ENV REFRESHED_AT 2016-12-07
RUN apt-get -qq update

我们用ENV设置环境变量,如果刷新一个构建,只需要修改ENV指令中的日期,这样后续指令而无须依赖缓存。

你可能感兴趣的:(Docker镜像和仓库)