千家信息网

Docker 镜像的创建与构建私有库

发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,一、Docker镜像的创建方法docker镜像是除了docker的核心技术之外,也是应用发布的标准格式。一个完整的docker镜像可以支撑一个docker容器的运行,在docker的整个使用过程中,进
千家信息网最后更新 2026年11月01日Docker 镜像的创建与构建私有库

一、Docker镜像的创建方法
docker镜像是除了docker的核心技术之外,也是应用发布的标准格式。一个完整的docker镜像可以支撑一个docker容器的运行,在docker的整个使用过程中,进入一个已经定型的容器之后,就可以在容器中进行操作,最常见的操作就是在容器中安装应用服务,如果要把已经安装的服务进行迁移,就需要把环境及搭建的服务生成新的镜像。

创建镜像的方法有三种,分别是基于已有镜像创建、基于本地模板创建及基于dockerfile创建。

1、基于已有镜像创建
基于已有镜像创建主要使用 docker commit 命令,其实质就是把一个容器里面运行的程序及该程序的运行环境打包起来生成新的镜像。

命令格式:docker commit [选项] 容器ID/名称 仓库名称:[标签]
常用选项
-m:说明信息;
-a:作者信息;
-p:生成过程中停止容器的运行;

启动一个镜像,在容器里做修改,然后将修改后的容器提交为新的镜像,需要记住该容器的ID号

[root@test /]# docker ps -a                   # 查看当前容器CONTAINER ID        IMAGE                         COMMAND                  CREATED             STATUS              PORTS               NAMESbdd5bb814008        docker.io/networkboot/dhcpd   "/entrypoint.sh /b..."   5 seconds ago       Created                                 stupefied_ptolemy[root@test /]# docker exec -it bdd5bb814008 /bin/bash            # 进入到该容器,创建一个测试文件root@bdd5bb814008:/# lsbin  boot  core  dev  entrypoint.sh  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  varroot@bdd5bb814008:/# touch test.txtroot@bdd5bb814008:/# exitexit[root@test /]# docker commit -m "newdhcp" -a "test" bdd5bb814008 docker:mydhcp          # 将已有容器创为镜像sha256:d6197c6e3f650d3ef69d13324634759705821b0ed516e8fe631fded72acb9d54[root@test /]# docker images  | grep docker              # 查看刚刚创建好的镜像docker                        mydhcp              d6197c6e3f65        24 seconds ago      125 MBdocker.io/networkboot/dhcpd   latest              6f98b6b9b486        19 months ago       125 MB[root@test /]# docker create -it docker:mydhcp /bin/bash               # 添加为容器ea434b08d511867be662704ee81d0b5876e922efa50f5f52843daa762185c16a[root@test /]# docker ps -aCONTAINER ID        IMAGE                         COMMAND                  CREATED             STATUS              PORTS               NAMESea434b08d511        docker:mydhcp                 "/entrypoint.sh /b..."   25 seconds ago      Created                                 compassionate_shirleybdd5bb814008        docker.io/networkboot/dhcpd   "/entrypoint.sh /b..."   5 minutes ago       Up 4 minutes                            stupefied_ptolemy[root@test /]# docker start ea434b08d511                        # 启动该容器ea434b08d511[root@test /]# docker exec -it ea434b08d511 /bin/bash             # 进入到该容器,查看刚刚所创建的测试文件root@ea434b08d511:/# lsbin  boot  core  dev  entrypoint.sh  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  test.txt  tmp  usr  var

2、基于本地模板创建
通过导入操作系统模板文件可以生成镜像,模板可以从 OPENVZ 开源项目下载,下载地址为:http://openvz.org/Download/template/precreated

[root@test /]# wget http://download.openvz.org/template/precreated/ubuntu-14.04-x86_64-minimal.tar.gz# 下载一个迷你版的Ubuntu模板[root@test /]# cat ubuntu-14.04-x86_64-minimal.tar.gz | docker import - docker:newsha256:7457fecee0fb28ab06d935e7a9a5a040d9d6ec8931959b752f596cde76a5d647# 将模板导入[root@test /]# docker images |grep new              # 查看已经导入docker                        new                 7457fecee0fb        About a minute ago   215 MB

3、基于 Dockerfile 创建
dockerfile是由一组指令组成的文件,其中每条指令对应Linux中的一条命令,docker程序将读取dockerfile中的指令生成指定镜像。

dockerfile结构大致分为四个部分:基础镜像信息、维护者信息、镜像操作指令和容器启动时执行指令。dockerfile每行支持一条指令,每条指令可携带多个参数,支持使用"#"号开头的注释。
dockerfile中的配置项介绍:

[root@localhost ~]# docker tag docker:new centos7:system            #将上面下载的centos 7迷你镜像更改下名字及标签,以便区分[root@localhost ~]# docker images | grep system             #确认基础镜像已经准备好(就是一个centos 7的迷你系统进行)centos7                       system              c065d5c0571d        About an hour ago   435 MB[root@localhost ~]# vim Dockerfile   #编辑一个Dockerfile文件,注意:文件名最好就是DockerfileFROM centos           #第一行必须指明基于的基础镜像(该镜像必须存在)MAINTAINER The centos project     #维护该镜像的用户信息#以下是镜像的操作指令RUN yum -y update      RUN yum -y install openssh-serverRUN sed -i 's/UsePAM yes/UsePAM no/g' /etc/ssh/sshd_configRUN ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_keyRUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_keyEXPOSE 22       #开启22端口CMD ["/usr/sbin/sshd","-D"]     #启动容器时执行指令

在编写dockerfile时,有严格的格式需要遵循:第一行必须使用FROM指令指明所基于的镜像名称;之后使用MAINTAINER指令说明维护该镜像的用户信息;然后是镜像操作相关指令,如RUN指令,每运行一条指令,都会给基础镜像添加新的一层;最后使用CMD指令来指定启动容器时要运行的命令操作。

dockerfile有十几条命令可用于构建镜像,其中常见的指令如下:


例:使用dockerfile创建apache镜像并在容器中运行

[root@test /]# mkdir apache                        # 创建工作目录[root@test /]# cd /apache/[root@test apache]# vim Dockerfile                # 创建并编写 Dockerfile文件FROM    centos                               # 基于的基础镜像centosMAINTAINER      the centos            # 维护该镜像的用户信息RUN     yum -y update                     # 镜像操作指令安装 Apache 软件包RUN     yum -y install httpd EXPOSE  80                                    # 开启80端口ADD     index.html /var/www/html/index.html               # 复制网站首页文件ADD     run.sh /run.sh                     # 将执行脚本复制到镜像中RUN     chmod 775 /run.sh             RUN     systemctl disable httpd           # 设置Apache服务不自行启动CMD     ["/run.sh"]                     # 启动容器时执行脚本[root@test apache]# vim run.sh                     # 编写执行脚本内容#!/bin/bashrm -rf /run/httpd/*                           # 清理 httpd 缓存exec /usr/sbin/apachectl -D FOREGROUND                # 启动Apache服务[root@test apache]# echo "www.test.com" > index.html                 # 创建测试页面[root@test apache]# lsDockerfile  index.html  run.sh[root@test apache]# docker build -t httpd:centos .               ............................               // 省略部分内容# 注意注意注意:这条命令后面有一个"."    代表当前路径,否则会报错,切记千万不要忘记
[root@test apache]# docker run -d -p 12345:80 httpd:centos               # 使用新的镜像运行容器,-p 选项实现从本地端口12345到容器的80端口映射0721b1641ce0651d618a393b85d34606180dd33d4795621db320865cda8f3a0a[root@test apache]# docker ps -a             # 查看容器CONTAINER ID        IMAGE                         COMMAND                  CREATED             STATUS              PORTS                   NAMES0721b1641ce0        httpd:centos                  "/run.sh"                6 seconds ago       Up 6 seconds        0.0.0.0:12345->80/tcp   sad_mcclintock

访问容器中的apache服务

二、搭建私有库及其使用方法
随着创建的镜像增多,就需要有一个保存镜像的地方,这就是仓库,目前有两种仓库:公共仓库和私有仓库,公司的生产环境中大多数都是保存到私有仓库的,最简单的还是在公共仓库上下载镜像,若是上传镜像至公共仓库,还需要注册并登陆,关于公共仓库的上传,可以参考https://blog.51cto.com/14227204/2453408
怎么构建私有仓库呢?可以使用registry来搭建本地私有仓库

[root@test ~]# docker search registry               #查询关键字"registry"INDEX       NAME                                          DESCRIPTION                                     STARS     OFFICIAL   AUTOMATEDdocker.io   docker.io/registry                            The Docker Registry 2.0 implementation for...   2679      [OK]                        ..................#省略部分内容[root@localhost ~]# docker pull docker.io/registry     #下载排名靠前的镜像                 ..................#省略部分内容Status: Downloaded newer image for docker.io/registry:latest    #下载成功[root@localhost ~]# vim /etc/sysconfig/docker           #修改docker配置文件指定私有仓库URL,否则在自定义的私有仓库中上传镜像时会报错# /etc/sysconfig/docker# Modify these options if you want to change the way the docker daemon runsOPTIONS='--selinux-enabled --insecure-registry=192.168.1.1:5000'#更改上面一行内容,其中的IP地址是作为私有仓库服务器的IP地址,这里就是本机的IP地址。                           ..................#省略部分#修改完毕后保存退出[root@test ~]# systemctl restart docker      #重启docker

使用下载好的registry镜像启动一个容器,默认情况下仓库存放于容器内的/tmp/registry目录下,使用-v选项可以将本地目录挂载到容器内的/tmp/registry目录下使用,这样就不怕容器被删除后镜像也会随之丢失。在本地启动一个私有仓库服务,监听端口号为5000。

注意:我本地有一个/data/registry目录(挂载的是一个高可用的GFS文件系统,也可以使用NFS,自行选择即可,但是建议对于重要的数据存放目录,一定要保证容量的动态扩展以及磁盘损坏造成数据丢失的问题),将要挂载到私有仓库容器中的/tmp/registry目录中用于存放上传到私有仓库的镜像文件。

[root@test ~]# df -hT /data/registry/             #查看我这个目录所使用的文件系统文件系统         类型            容量  已用  可用 已用% 挂载点node4:dis-stripe fuse.glusterfs   80G  130M   80G    1% /data/registry[root@test ~]# docker run -d -p 5000:5000 -v /data/registry/:/tmp/registry docker.io/registry#启动私有仓库,并做端口映射到主机的5000端口,将本地的/data/registry目录挂载到容器中的/tmp/registry目录#docker.io/registry是刚才下载的私有仓库镜像。a6bf726c612b826e203d6a5bc9eaba26c36195913d3ea546c2111ce290a5524d[root@test ~]# docker tag docker.io/registry 192.168.1.1:5000/registry     #使用docker  tag命令将要上传的镜像docker.io/registry改一下标记,其中的IP及端口为固定的,否则无法连接到私有仓库#因为在上面运行容器时,做了端口映射,将私有仓库的端口号映射到了宿主机的5000端口,#所以直接访问宿主机的5000端口,就相当于访问了私有仓库。[root@test ~]# docker images | grep 5000            #找到要上传的镜像192.168.1.1:5000/registry     latest              f32a97de94e1        6 months ago        25.8 MB[root@test ~]# docker push 192.168.1.1:5000/registry            #上传至刚刚运行的私有仓库The push refers to a repository [192.168.1.1:5000/registry]73d61bf022fd: Pushed 5bbc5831d696: Pushed d5974ddb5a45: Pushed f641ef7a37ad: Pushed d9ff549177a9: Pushed latest: digest: sha256:b1165286043f2745f45ea637873d61939bff6d9a59f76539d6228abf79f87774 size: 1363#下面再上传一个镜像,进行测试。[root@test ~]# docker images | grep mynamed            #就上传它了docker                        mynamed             e178f320e482        4 hours ago         323 MB[root@test ~]# docker tag docker:mynamed 192.168.1.1:5000/named:test    #老规矩,必须改仓库名,注意:若标签不是默认的latest,那么还需要在仓库名后面接上标签名[root@test ~]# docker images | grep 192.168.1.1:5000/named     #确定更改成功192.168.1.1:5000/named        test                e178f320e482        4 hours ago         323 MB[root@test ~]# docker push 192.168.1.1:5000/named:test       #上传至私有仓库The push refers to a repository [192.168.1.1:5000/named]c756b9ec7fb0: Pushed 7d8d01394159: Pushed 72b7cd87d69b: Pushed 3be48ef75683: Pushed 9b28c58ad64b: Pushed 75e70aa52609: Pushed dda151859818: Pushed fbd2732ad777: Pushed ba9de9d8475e: Pushed test: digest: sha256:44894a684eac72a518ae5fa66bcbe4e4a9429428ef7ac6f4761022f8ac45ac5f size: 2403

至此,测试就完毕了,但是,如何证明私有仓库使用的是本地的/data/registry这个目录呢?以及如何查看上传的镜像呢?(上传至私有仓库的镜像是无法使用普通的ls命令查看的)。

[root@test ~]# df -hT /data/registry/           #先查看本地/data/registry/ 挂载的文件系统文件系统         类型            容量  已用  可用 已用% 挂载点node4:dis-stripe fuse.glusterfs   80G  130M   80G    1% /data/registry[root@test ~]# docker exec -it a6bf726c612b /bin/sh #进入私有仓库的容器中,该容器没有/bin/bash,所以使用的是/bin/sh。/ # df -hT /tmp/registry/   #查看发现,该目录挂载的和宿主机挂载的文件系统是同一个,说明没问题。Filesystem           Type            Size      Used Available Use% Mounted onnode4:dis-stripe     fuse.glusterfs                                    80.0G    129.4M     79.8G   0% /tmp/registry                   ----------------------#那么如何查看上传至私有仓库的镜像呢?请看下面:[root@test ~]# curl -XGET http://192.168.1.1:5000/v2/_catalog   #查看已经上传的镜像,可以看到刚刚上传的那两个镜像{"repositories":["named","registry"]}#只知道镜像名还不够,若要下载,还需要镜像对应的标签,那么怎么查看某个镜像的标签呢?[root@test ~]# curl -XGET http://192.168.1.1:5000/v2/named/tags/list#就这样查看咯,上面URL路径中的named就是镜像名,查看的就是镜像named对应的标签{"name":"named","tags":["test"]}[root@test ~]# docker pull 192.168.1.1:5000/named:test      #将私有仓库中的镜像下载下来#前面必须指定私有仓库的访问地址,就是上传时的名字是什么,下载时就是什么,哪怕查询的镜像名中没有IP地址。Trying to pull repository 192.168.1.1:5000/named ... sha256:44894a684eac72a518ae5fa66bcbe4e4a9429428ef7ac6f4761022f8ac45ac5f: Pulling from 192.168.1.1:5000/namedDigest: sha256:44894a684eac72a518ae5fa66bcbe4e4a9429428ef7ac6f4761022f8ac45ac5fStatus: Downloaded newer image for 192.168.1.1:5000/named:test

若需要在其他服务器上下载私有仓库的镜像,需要在那个其他服务器上执行以下命令,以便指定私有仓库服务器地址:

[root@node1 ~]# echo '{ "insecure-registries":["xxx.xxx.xxx.xxx:5000"] }' > /etc/docker/daemon.json#其中xxx.xxx.xxx.xxx:5000代表访问私有仓库的IP地址及端口,根据自己的服务器情况来定[root@node1 ~]#systemctl restart docker          #重启docker服务
镜像 仓库 容器 私有 指令 文件 服务 目录 端口 就是 运行 命令 地址 系统 信息 标签 模板 内容 基础 服务器 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 互联网科技海报 科技赋能下的互联网金融 科技股互联网 互联网科技保险 致聘互联网科技 有木互联网科技 科技伦理 互联网公司 深圳国际航运科技和互联网 宁夏科技产业互联网案例 宝灵互联网科技有限公司 花神(南京)互联网科技有限公司 新兴科技互联网创新大赛颁奖典礼 互联网科技与大数据专业 中和天地互联网科技有限公司 南通创西澳互联网科技有限公司 深圳互联网科技的发展 互联网硬科技公司 广州梦谷互联网科技有限公司领导 北京品多多互联网科技有限公司 杭州科技互联网公司有哪些 百单网互联网科技有限公司怎么样 为想互联网科技怎么样 麻工互联网科技 兼蜜互联网科技 深圳卡尔迅互联网科技有限公司怎么样 海南科技产业互联网平台 迪庆互联网科技招生 厦门江牛科技互联网 互联网科技平台产品运营 盐城市攀科互联网科技有限公司
0