专栏往期文章
- 《Docker是什么?Docker从介绍到Linux安装图文详细教程》
- 《30条Docker常用命令图文举例总结》
本期目录
- 专栏往期文章
- 1. 构建镜像
- 2. 本地镜像发布到公有云
- 3. 本地镜像发布到私有云
1. 构建镜像
提交构建镜像的命令如下:
$ docker commit -m="提交描述信息" -a="作者" 容器ID 目标镜像名称:[TAG]
举例:本节我们将自己构建一个带 Vim 编辑工具的 Ubuntu 镜像。从官网下载的 base Ubuntu 镜像,里面是没有 Vim 工具的,那么我可以在 base Ubuntu 镜像的基础上,增加 Vim 工具,再构建出一个带 Vim 的 Ubuntu 镜像,使其天生带有 Vim ,在这个镜像创建的容器都会带有 Vim 。
前台交互式启动一个 Ubuntu 容器。
$ docker run -it ubuntu:latest /bin/bash
尾号 5731
的 Ubuntu 容器是不带 Vim 编辑工具的。
$ vim
安装 Vim 之前,先更新包管理工具 apt-get ( Ubuntu 一般用的是 apt-get ) 。
$ apt-get update
然后,在这个容器中安装 Vim 。
$ apt-get -y install vim
安装完成后,测试 Vim 。
$ vim a.txt
能够进入编辑页面,Vim 安装成功。
键盘按下 Ctrl + P + Q 让 Ubuntu 容器保持运行退出容器。
接下来是本节的核心内容,把带 Vim 的 Ubuntu 容器 Commit 成镜像。镜像构建成功后,返回镜像 ID 。
$ docker commit -m="add vim cmd" -a="xiesh" 45ce35485731 ouc/myubuntu:1.0
此时列出所有镜像,可以看到成功构建了镜像。由于添加了 Vim 编辑工具,我们构建的 Ubuntu 镜像大小已经从官方原来的 72.8 MB 扩大到 181 MB 。这就是镜像分层带来的好处,可以基于最简单的 base 镜像,像搭积木一样一层一层往上加自己需要的程序和软件,最终构建出功能越来越强大的镜像。
【总结】Docker 中的镜像分层,支持通过扩展现有的镜像,创建新的镜像。类似于 Java 继承于一个 Base 基础类,自己再按需扩展。新镜像是从 base 镜像一层一层叠加生成的。每安装一个软件,就在现有镜像的基础上增加一层。
2. 本地镜像发布到公有云
本节把刚刚构建的带 Vim 的 Ubuntu 镜像发布到阿里云 (公有云) ,这样别的开发者就可以拉取你制作的镜像使用了,服务广大人民群众。
首先登录阿里云官网 https://www.aliyun.com/ ,点击【控制台】。
点击【容器镜像服务】。
进入【个人实例】。
设置密码。
先创建命名空间,点击【命名空间】,点击【创建命名空间】。
设为【公开】开源给大家。
点击【镜像仓库】。
点击【创建镜像仓库】。
然后选择【本地仓库】上传,直接【创建镜像仓库】。
把本地镜像推送到阿里云镜像仓库,推送脚本可从上面的管理页面复制。首先登录到阿里云的远程仓库。
$ docker login --username=xiesh registry.cn-hangzhou.aliyuncs.com
设置 Tag 。
$ docker tag [ImageId] registry.cn-hangzhou.aliyuncs.com/ouc-xsh/myubuntu1.0:[镜像版本号]
推送到阿里云远程库。
$ docker push registry.cn-hangzhou.aliyuncs.com/ouc-xsh/myubuntu1.0:[镜像版本号]
到此就成功把本地镜像推送到阿里云了。
为了验证,我们接下来从阿里云镜像仓库拉取镜像到本地仓库。先把本地仓库中的 Ubuntu 镜像删除。
$ docker rmi -f b9b636ea0a65
拉取镜像到本地。
$ docker pull registry.cn-hangzhou.aliyuncs.com/ouc-xsh/myubuntu1.0:1.0
拉取成功。创建容器,并尝试使用 Vim 编辑文本。
$ docker run -it b9b636ea0a65 /bin/bash
$ vim a.txt
说明我们构建的带 Vim 的 Ubuntu 镜像成功推送到阿里云远程库,并可以正常拉取镜像和创建容器。
3. 本地镜像发布到私有云
在企业中,为了安全,构建的镜像绝大部分都是推送到企业内部的私有云镜像仓库中。Docker Registry 是官方提供的工具,可以用于构建私有镜像仓库。
本节把刚刚构建的带 Vim 的 Ubuntu 镜像发布到私有云作为演示。
- 首先下载镜像 Docker Registry 。
$ docker pull registry
- 运行私有库 Registry 容器,相当于本地有个私有的 Docker Hub。
$ docker run -d -p 5000:5000 -v /root/myregistry/:/tmp/registry --privileged=true registry:latest
其中,-d
表示后台守护式运行;-p 5000:5000
表示把容器的 5000 端口映射到宿主机的 5000 端口端口上;-v
表示把容器中 /tmp/registry
目录下的数据同步到宿主机的 /root/myregistry
目录中;--priviledged=true
表示扩大容器的权限解决挂载目录没有权限的问题 。
默认情况下,仓库被创建在容器的 /var/lib/registry
目录下,建议自行用容器卷映射,方便与宿主机联调。
- 创建一个新 Ubuntu 镜像,Ubuntu 安装 ifconfig 命令。
$ docker run -it --name=u1 ubuntu:latest /bin/bash
安装 ifconfig 之前,先更新包管理工具 apt-get ( Ubuntu 一般用的是 apt-get ) 。
$ apt-get update
然后,在这个容器中安装 ifconfig 命令。
$ apt-get -y install net-tools
安装完成后,测试 ifconfig 。能看到这个 Ubuntu 容器内部的 IP 信息。
$ ifconfig
安装完成后,commit 我们自己构建的新镜像。
$ docker commit -m="add ifconfig cmd" -a="xiesh" cbcc904f1be5 ouc/myubuntu:1.1
- Curl 验证私服库上有什么镜像。
接下来我们是想把构建的带 ifconfig 命令的 Ubuntu 镜像推送到本地的 Docker Registry 私有仓库中。首先我们要查看该私有库中有什么镜像。
$ curl -XGET http://192.168.168.101:5000/v2/_catalog
可以看到私服仓库是空的,里面没有任何镜像。
- 将新镜像
ouc/myubuntu:1.1
修改成符合私服规范的 Tag 。
$ docker tag 镜像:Tag Host:Port/Registry:Tag
注意,这里要写自己的 host 主机 IP 地址。
使用该命令将 ouc/myubuntu:1.1
这个镜像修改为 192.168.168.101:5000/ouc/myubuntu:1.1
。
$ docker tag ouc/myubuntu:1.1 192.168.168.101:5000/ouc/myubuntu:1.1
- 修改配置文件使之支持 HTTP 协议。
由于 Docker Registry 做了安全加固,默认不支持 HTTP 协议的推送。因此我们要取消此限制。
$ cat /etc/docker/daemon.json
registry-mirrors
配置的是国内阿里云提供的镜像加速地址,不用的话访问官网会很慢。
我们要在这个文件中新增内容。注意 JSON 格式要加逗号分隔。
$ vim /etc/docker/daemon.json
按 :wq
保存退出,如果修改完后不生效,建议重启 Docker 和 registry 容器。
$ systemctl restart docker
$ docker start d035810c65ef
- push 推送到私服库。
$ docker push 192.168.168.101:5000/ouc/myubuntu:1.1
- curl验证私服上有什么镜像。这次私服仓库中就有刚刚推送的镜像了。
$ curl -XGET http://192.168.168.101:5000/v2/_catalog
- pull 拉取到本地并运行。
先删除本地仓库的镜像。
$ docker rmi -f 192.168.168.101:5000/ouc/myubuntu:1.1
从私服仓库中拉取镜像到本地。
$ docker pull 192.168.168.101:5000/ouc/myubuntu:1.1
运行这个镜像,创建容器。并使用 ifconfig
命令。
$ docker run -it a73412a51b67 /bin/bash
$ ifconfig
拉取的镜像创建的容器可以成功运行 ifconfig 命令。至此,我们又获得了一个增加了 ifconfig 命令的 Ubuntu 镜像。
从此以后,你编写的微服务就可以打包成镜像,推送到公司的私服仓库中。如果新入职的同事来了,可以装个逼,我们公司一切在云端,处处是容器,在容器下进行云原生的开发。