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 "18612352157@163.com"
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" git@git.oschina.net:studay/css-exercise.git

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

开表示注释

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

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

Paste_Image.png

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

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 — 云时代的程序分发方式 要说最近一年云计算业界有什么大事件?Google Compute Engi...
    ahohoho阅读 15,628评论 15 147
  • 转载自 http://blog.opskumu.com/docker.html 一、Docker 简介 Docke...
    极客圈阅读 10,544评论 0 120
  • 五、Docker 端口映射 无论如何,这些 ip 是基于本地系统的并且容器的端口非本地主机是访问不到的。此外,除了...
    R_X阅读 1,798评论 0 7
  • docker基本概念 1. Image Definition 镜像 Image 就是一堆只读层 read-only...
    慢清尘阅读 8,816评论 1 21
  • 一个不分昼夜打lol的人 被称作大神 满脑子的qwer 他以此为荣 一个废寝忘食学习的人 满脑子的之乎者也 方程公...
    生命是场幻觉阅读 233评论 0 0