docker镜像
1.安装docker,这个pass,注意centos6只能用老版本吧得docker-io
2.docker镜像了解
# 列出本地镜像,在列出信息中,可以看到几个字段信息
# 来自于哪个仓库,比如 ubuntu
# TAG 信息, 标记同一仓库得不通镜像,比如 14.04, 12.10 等
# 它的 ID 号(唯一)
# 创建时间
# 镜像大小
$ docker images
#下载一个ubuntu1404镜像
#该命令实际上相当于 $ sudo docker pull registry.hub.docker.com/ubuntu:12.04 命令,即从注册服
务器 registry.hub.docker.com 中的 ubuntu 仓库来下载标记为 12.04 的镜像。
$ docker pull ubuntu:12.04
#有时候官方仓库注册服务器下载较慢,可以从其他仓库下载。 从其它仓库下载时需要指定完整的仓库注册服务器地址。例如
$ sudo docker pull dl.dockerpool.com:5000/ubuntu:12.04
完成后,即可随时使用该镜像了,例如创建一个容器,让其中运行 bash 应用。
$ sudo docker run -t -i ubuntu:12.04 /bin/bash
root@38dacc618e58:/# ls
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
#启动并执行 hello world,注意run [仓库:tag],如果tag不指定则默认使用 latest 标记信息。
$ sudo docker run ubuntu:14.04 /bin/echo 'Hello world'
3.创建镜像
创建镜像有很多方法,用户可以从 Docker Hub 获取已有镜像并更新,也可以利用本地文件系统创建一个。
可以直接用上面这种/bin/bash登陆进入镜像,然后安装应用。然后再commit,但是更多得还是推荐用Dockerfile来创建。
---1.手动创建的例子---
$ sudo docker run -t -i training/sinatra /bin/bash
$ root@0b2616b0e5a8:/# gem install json
#其中, -m 来指定提交的说明信息,跟我们使用的版本控制工具一样; -a 可以指定更新的用户信息;之后是用来创建镜像的容器的 ID;最后指定目标镜像的仓库名和 tag 信息。创建成功后会返回这个镜像的 ID信息。
$ sudo docker commit -m "Added json gem" -a "Docker Newbee" 0b2616b0e5a8 ouruser/sinatra:v2
4f177bd27a9ff0f6dc2a830403925b5360bfe0b93d476f7fc3231110e7f71b1c
$ sudo docker images #这就可以看到我们新建的容器了
$ sudo docker run -t -i ouruser/sinatra:v2 /bin/bash #之后,可以使用新的镜像来启动容器
---2.利用 Dockerfile 来创建镜像---
#新建一个目录和一个 Dockerfile
$ mkdir sinatra
$ cd sinatra
$ touch Dockerfile
#Dockerfile 中每一条指令都创建镜像的一层,例如:
# This is a comment
FROM ubuntu:14.04
MAINTAINER Docker Newbee
RUN apt-get -qq update
RUN apt-get -qqy install ruby ruby-dev
RUN gem install sinatra
Dockerfile 基本的语法是
#使用 # 来注释
#FROM 指令告诉 Docker 使用哪个镜像作为基础
#接着是维护者的信息
#RUN 开头的指令会在创建中运行,比如安装一个软件包,在这里使用 apt-get 来安装了一些软件
#编写完成 Dockerfile 后可以使用 docker build 来生成镜像。
#其中 -t 标记来添加 tag,指定新的镜像的用户信息。 “.” 是 Dockerfile 所在的路径(当前目录),也可以替换为一个具体的 Dockerfile 的路径。
$ sudo docker build -t="ouruser/sinatra:v2" .
#此外,还可以利用 ADD 命令复制本地文件到镜像;用 EXPOSE 命令来向外部开放端口;用 CMD 命令来描述容器启动后运行的程序等。
---3.从本地系统导入---
#要从本地文件系统导入一个镜像,可以使用 openvz(容器虚拟化的先锋技术)的模板来创建: openvz 的模板下载地址为 templates 。
#比如,先下载了一个 ubuntu-14.04 的镜像,之后使用以下命令导入:
sudo cat ubuntu-14.04-x86_64-minimal.tar.gz |docker import - ubuntu:14.04
4.上传下载镜像,存出和载入镜像
#用户可以通过 docker push 命令,把自己创建的镜像上传到仓库中来共享。例如,用户在 Docker Hub 上完成注册后,可以推送自己的镜像到仓库中。
$ sudo docker push ouruser/sinatra
The push refers to a repository [ouruser/sinatra] (len: 1)
----存出镜像----
#如果要导出镜像到本地文件,可以使用 docker save 命令。
$sudo docker save -o ubuntu_14.04.tar ubuntu:14.04
---载入镜像---
#可以使用 docker load 从导出的本地文件中再导入到本地镜像库,例如
$ sudo docker load --input ubuntu_14.04.tar
#或
$ sudo docker load < ubuntu_14.04.tar
#这将导入镜像以及其相关的元数据信息(包括标签等)。
4.移除本地镜像
#如果要移除本地的镜像,可以使用 docker rmi 命令。注意 docker rm 命令是移除容器。
$ sudo docker rmi training/sinatra
镜像的实现原理
Docker 镜像是怎么实现增量的修改和维护的? 每个镜像都由很多层次构成,Docker 使用 Union FS 将这些不同的层结合到一个镜像中去。
通常 Union FS 有两个用途, 一方面可以实现不借助 LVM、RAID 将多个 disk 挂到同一个目录下,另一个更常用的就是将一个只读的分支和一个可写的分支联合在一起,Live CD 正是基于此方法可以允许在镜像不变的基础上允许用户在其上进行一些写操作。 Docker 在 AUFS 上构建的容器也是利用了类似的原理。
Docker 容器
简单的说,容器是独立运行的一个或一组应用,以及它们的运行态环境。对应的,虚拟机可以理解为模拟运行的一整套操作系统(提供了运行态环境和其他系统环境)和跑在上面的应用。
1.容器的创建,启动,停止
dockers run/sopt/restart/ps/ps -a
启动容器有两种方式,一种是基于镜像新建一个容器并启动,另外一个是将在终止状态(stopped)的容器重新启动。
当利用 docker run 来创建容器时,Docker 在后台运行的标准操作包括:
1) 检查本地是否存在指定的镜像,不存在就从公有仓库下载
2) 利用镜像创建并启动一个容器
3) 分配一个文件系统,并在只读的镜像层外面挂载一层可读写层
4) 从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中去
5) 从地址池配置一个 ip 地址给容器
6) 执行用户指定的应用程序
7) 执行完毕后容器被终止
8) 用伪终端在容器查看,一般就只有一个/bin/sh和其他你运行的程序
9)-d daemon, 然后dockers logs xxxx可以看日志
10)docker attach可以连接
root@baoan:/home/baoan/workspace/teleport_install# docker run -d ubuntu:14.04 /bin/sh -c "while true; do echo 'hello world'; sleep 1; done"
fc3fac12b979363a3547acc47f662603694c996f8c8edf342d285c0472878413
root@baoan:/home/baoan/workspace/teleport_install# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
fc3fac12b979 ubuntu:14.04 "/bin/sh -c 'while t…" 19 seconds ago Up 18 seconds pedantic_davinci
root@baoan:/home/baoan/workspace/teleport_install# docker logs pedantic_davinci
hello world
2.连接容器
#这里的baoan是容器名字
$ docker attach baoan
#使用nsenter
#nsenter 可以访问另一个进程的名字空间。nsenter 要正常工作需要有 root 权限。 很不幸,Ubuntu 14.04仍然使用的是 util-linux 2.20。安装最新版本的 util-linux(2.24)版,请按照以下步骤:
$ wget https://www.kernel.org/pub/linux/utils/util-linux/v2.24/util-linux-2.24.tar.gz; tar xzvf util-linux-2.24.tar.gz
$ cd util-linux-2.24
$ ./configure --without-ncurses && make nsenter
$ sudo cp nsenter /usr/local/bin
#为了连接到容器,你还需要找到容器的第一个进程的 PID,可以通过下面的命令获取。
PID=$(docker inspect --format "{{ .State.Pid }}" )
通过这个 PID,就可以连接到这个容器:
$ nsenter --target $PID --mount --uts --ipc --net --pid
3.删除容器
$ docker rm xxxx
仓库
仓库(Repository)是集中存放镜像的地方。
一个容易混淆的概念是注册服务器(Registry)。实际上注册服务器是管理仓库的具体服务器,每个服务器上可以有多个仓库,而每个仓库下面有多个镜像。从这方面来说,仓库可以被认为是一个具体的项目或目录。例如对于仓库地址 dl.dockerpool.com/ubuntu 来说, dl.dockerpool.com 是注册服务器地
址, ubuntu 是仓库名。
1.Docker Hub
目前 Docker 官方维护了一个公共仓库 Docker Hub,其中已经包括了超过 15,000 的镜像。大部分需求,都可以通过在 Docker Hub 中直接下载镜像来实现。
1.1 登录
可以通过执行 docker login 命令来输入用户名、密码和邮箱来完成注册和登录。 注册成功后,本地用户目录的 .dockercfg 中将保存用户的认证信息。
1.2 基本操作
用户无需登录即可通过 docker search 命令来查找官方仓库中的镜像,并利用 docker pull 命令来将它下载到本地。
$ docker search centos
$ docker pull centos
1.3 私有仓库
有时候使用 Docker Hub 这样的公共仓库可能不方便,用户可以创建一个本地仓库供私人使用。
docker-registry 是官方提供的工具,可以用于构建私有的镜像仓库。
#在安装了 Docker 后,可以通过获取官方 registry 镜像来运行。
$ sudo docker run -d -p 5000:5000 registry
这部分更加详细的暂不做收集,可以后面研究一下,很简单,就是建个本地仓库。
1.4
在私有仓库上传、下载、搜索镜像
#创建好私有仓库之后,就可以使用 docker tag 来标记一个镜像,然后推送它到仓库,别的机器上就可以下载下来了。例如私有仓库地址为 192.168.7.26:5000 。
#使用 docker tag 将 ba58 这个镜像标记为 192.168.7.26:5000/test (格式为 docker tagIMAGE[:TAG] [REGISTRYHOST/][USERNAME/]NAME[:TAG] )。
$ sudo docker tag ba58 192.168.7.26:5000/test
$ docker push 192.168.7.26:5000/test
#用 curl 查看仓库中的镜像。
$ curl http://192.168.7.26:5000/v1/search
Dockerfile
1.概要
一般的,Dockerfile 分为四部分:基础镜像信息、维护者信息、镜像操作指令和容器启动时执行指令。
# 一开始必须指明所基于的镜像名称,接下来推荐说明维护者信息。
# 一个Dockerfile可以创建多个镜像,下一个FROM命令开始是新得镜像
FROM ubuntu
# 后面则是镜像操作指令,例如 RUN 指令, RUN 指令将对镜像执行跟随的命令。每运行一条 RUN 指令,镜像添加新的一层,并提交。
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
# 最后是 CMD 指令,来指定运行容器时的操作命令。
CMD /usr/sbin/nginx
2.命令总结
FROM 第一条指令必须为 FROM 指令。并且,如果在同一个Dockerfile中创建多个镜像时,可以使用多个 FROM指令(每个镜像一次)。
MAINTAINER
RUN
格式为 RUN
后者则使用 exec 执行。指定使用其它终端可以通过。第二种方式实现,例如 RUN ["/bin/bash", "-c", "echo hello"] 。
每条 RUN 指令将在当前镜像基础上执行指定命令,并提交为新的镜像。当命令较长时可以使用 \ 来换
行。
CMD
支持三种格式
CMD ["executable","param1","param2"] 使用 exec 执行,推荐方式;
CMD command param1 param2 在 /bin/sh 中执行,提供给需要交互的应用;
CMD ["param1","param2"] 提供给 ENTRYPOINT 的默认参数;
指定启动容器时执行的命令,每个 Dockerfile 只能有一条 CMD 命令。如果指定了多条命令,只有最后一条
会被执行。
如果用户启动容器时候指定了运行的命令,则会覆盖掉 CMD 指定的命令。
EXPOSE
格式为 EXPOSE
告诉 Docker 服务端容器暴露的端口号,供互联系统使用。在启动容器时需要通过 -P,Docker 主机会自动
分配一个端口转发到指定的端口。
ENV
格式为 ENV
例如
ENV PG_MAJOR 9.3
ENV PG_VERSION 9.3.4
RUN curl -SL http://example.com/postgres-PG_MAJOR/bin:$PATH
ADD
格式为 ADD
该命令将复制指定的
径;也可以是一个 URL;还可以是一个 tar 文件(自动解压为目录)。
COPY
格式为 COPY
复制本地主机的
当使用本地目录为源目录时,推荐使用 COPY 。
ENTRYPOINT
两种格式:
ENTRYPOINT ["executable", "param1", "param2"]
ENTRYPOINT command param1 param2 (shell中执行)。
配置容器启动后执行的命令,并且不可被 docker run 提供的参数覆盖。
每个 Dockerfile 中只能有一个 ENTRYPOINT ,当指定多个时,只有最后一个起效。
VOLUME
格式为 VOLUME ["/data"] 。
创建一个可以从本地主机或其他容器挂载的挂载点,一般用来存放数据库和需要保持的数据等。
USER
格式为 USER daemon 。
指定运行容器时的用户名或 UID,后续的 RUN 也会使用指定用户。
当服务不需要管理员权限时,可以通过该命令指定运行用户。并且可以在之前创建所需要的用户,例
如: RUN groupadd -r postgres && useradd -r -g postgres postgres 。要临时获取管理员权限可以
使用 gosu ,而不推荐 sudo 。
WORKDIR
格式为 WORKDIR /path/to/workdir 。
为后续的 RUN 、 CMD 、 ENTRYPOINT 指令配置工作目录。
可以使用多个 WORKDIR 指令,后续命令如果参数是相对路径,则会基于之前命令指定的路径。例如
WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd
则最终路径为 /a/b/c 。
ONBUILD
格式为 ONBUILD [INSTRUCTION] 。
配置当所创建的镜像作为其它新创建镜像的基础镜像时,所执行的操作指令。
例如,Dockerfile 使用如下的内容创建了镜像 image-A 。
[...]
ONBUILD ADD . /app/src
ONBUILD RUN /usr/local/bin/python-build --dir /app/src
[...]
如果基于 image-A 创建新的镜像时,新的Dockerfile中使用 FROM image-A 指定基础镜像时,会自动执行
ONBUILD 指令内容,等价于在后面添加了两条指令。
FROM image-A
Automatically run the following
ADD . /app/src
RUN /usr/local/bin/python-build --dir /app/src
使用 ONBUILD 指令的镜像,推荐在标签中注明,例如 ruby:1.9-onbuild 。
3.创建
编写完成 Dockerfile 之后,可以通过 docker build 命令来创建镜像。
常见问题总结:
1.启动得时候Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock:
权限问题,你可能是用root启动得docker,自己切换到root