Docker 实践
目标
创建一个基于最新版Ubuntu的镜像,在该镜像中更新apt包源并安装NTP package,最后将该新镜像提交到本地私有的registry中。
本地创建私有Registry
有N种方法创建私有Registry,这里选择最方(tou)便(lan)的,利用官方Registry镜像来构建。在你需要创建Registry的主机上运行:
docker run -d -e SETTINGS_FLAVOR=dev -e STORAGE_PATH=/tmp/registry -v /opt/data/registry:/tmp/registry -p 5000:5000 registry
制作目标镜像
当然,创建镜像的方法也有N种。用户可以从 Docker Hub 获取已有镜像并更新,也可以利用本地文件系统创建一个。
那么是否可以利用一个container创建镜像呢?答案是可以滴。具体可以参考创建Dockerfile
最好是创建一个新的空目录,然后在该空目录下创建Dockerfile
# This dockerfile uses the ubuntu image
# Version 0.0.1
# Author: Andy WU
FROM ubuntu:latest
MAINTAINER AndyWu zewei@nfs-qd.com
# 更新apt包源
RUN echo "deb http://archive.ubuntu.com/ubuntu/ raring main universe">>/etc/apt/sources.list
# 添加一行文字到文件/andy/test
RUN echo "hello world">>/andy/test
# 安装NTP
RUN apt-get install ntp -y
# 将 src 目录拷贝到目标镜像目录/opt/data下
ADD src /opt/data
在Dockerfile同一目录下执行镜像创建命令:
docker build -t 10.50.200.248:5000/andy/new_image .
注意,如果是要将镜像上传到私有的Registry中,必须将
repository
写全,格式是:registry/user/tag,这样当你push
的时候,docker才能正确提交。
但是很不幸,提交时出现 error:
...
Step3: RUN echo "hello world">>/andy/test
--->Runningin8ae55dfb7dd7
/bin/sh:1: cannot create /andy/test:Directory nonexistent
什么问题?为什么能正确更新/etc/apt/souce.list而不能更新/andy/test呢?我明明在刚刚利用Ubuntu镜像创建的容器里新建了这个文件啊?
提示没有/andy/test这个文件,那应该是Ubuntu这个base的镜像不存在这个文件,那么怎么来理解这个 base image 呢?Base 镜像就是那个最原始,没有经过任何修改,这里的修改通常指的是添加其他package等。镜像 VS 容器
造成这个错误的另一个根本原因是没有弄清image和container之间的关系。
image是死的,container是活的,我们利用image启动一个container,在container中所做的工作一旦退出,就不存在了container不可重复,即利用image创建container,不可能创建出与之前一直的container。这可以从container ID看出:CONTAINER ID | IMAGE | COMMAND | CREATED | STATUS | PORTS | NAMES |
---|---|---|---|---|---|---|
16616512db82 | 10.50.200.248:5000/andy/new_mage:latest | /bin/bash | About a minute ago | Exited (0) 5 seconds ago | cocky_heisenberg | |
b759a51351ba | 10.50.200.248:5000/andy/new_mage:latest | /bin/bash | 9 minutes ago | Exited (0) 2 minutes ago | sleepy_mclean |
用户通过 exit 命令或 Ctrl+d 来退出终端时,所创建的容器立刻终止。
当然,你也可以通过docker start 来重新启动一个退出的container。docker start -i b759a51351ba
没有修改Dockerfile,无论你怎么修改tag,创建的总是同一个image.
上传镜像
docker push 10.50.200.248:5000/andy/new_image
上传之后你可以去Registry查看是否成功:
root@nfs:/opt/data/registry/repositories# tree --charset ASCII
.
`-- andy
|-- new_image
| |-- _index_images
| |-- json
| |-- tag_latest
| `-- taglatest_json
`-- test
|-- _index_images
|-- json
|-- tag_latest
`-- taglatest_json
验证
docker pull 10.50.200.248:5000/andy/new_image
docker run -it 10.50.200.248:5000/andy/new_image /bin/bash
root@b759a51351ba:/# ntpq
ntpq>
Bingo!
最后,上图。