Docker镜像管理基础

Docker镜像管理基础

1、镜像的概念

镜像可以理解为应用程序的集装箱,而docker用来装卸集装箱。

docker镜像含有启动容器所需要的文件系统及其内容,因此,其用于创建并启动容器。

docker镜像采用分层构建机制,最底层为bootfs,其上为rootfs

  • bootfs:用于系统引导的文件系统,包括bootloader和kernel,容器启动完成后会被卸载以节约内存资源
  • rootfs:位于bootfs之上,表现为docker容器的根文件系统
    • 传统模式中,系统启动之时,内核挂载rootfs会首先将其挂载为“只读”模式,完整性自检完成后将其重新挂载为读写模式
    • docker中,rootfs由内核挂载为“只读”模式,而后通过“联合挂载”技术额外挂载一个“可写”层

注意:当删除容器时,这个容器自有的“可写”层会一起被删除

2、Docker镜像层

位于下层的镜像称为父镜像(parrent image),最底层的称为基础镜像(base image);
最上层为“可读写”层,其下的均为“只读”层。

3、Docker存储驱动

docker提供了多种存储驱动来实现不同的方式存储镜像,下面是常用的几种存储驱动:

  • AUFS
  • OverlayFS
  • Devicemapper
  • Btrfs
  • VFS

3.1 AUFS

AUFS(AnotherUnionFS)是一种Union FS,是文件级的存储驱动。AUFS能透明覆盖一或多个现有文件系统的层状文件系统,把多层合并成文件系统的单层表示。简单来说就是支持将不同目录挂载到同一个虚拟文件系统下的文件系统。这种文件系统可以一层一层地叠加修改文件。无论底下有多少层都是只读的,只有最上层的文件系统是可写的。当需要修改一个文件时,AUFS创建该文件的一个副本,使用CoW将文件从只读层复制到可写层进行修改,结果也保存在可写层。在Docker中,底下的只读层就是image,可写层就是Container。结构如下图所示:

3.2 OverlayFS

Overlay是Linux内核3.18后支持的,也是一种Union FS,和AUFS的多层不同的是Overlay只有两层:一个upper文件系统和一个lower文件系统,分别代表Docker的镜像层和容器层。当需要修改一个文件时,使用CoW将文件从只读的lower复制到可写的upper进行修改,结果也保存在upper层。在Docker中,底下的只读层就是image,可写层就是Container。目前最新的OverlayFS为Overlay2。结构如下图所示:

3.3 Device mapper

Device mapper是Linux内核2.6.9后支持的,提供的一种从逻辑设备到物理设备的映射框架机制,在该机制下,用户可以很方便的根据自己的需要制定实现存储资源的管理策略。前面讲的AUFS和OverlayFS都是文件级存储,而Device mapper是块级存储,所有的操作都是直接对块进行操作,而不是文件。Device mapper驱动会先在块设备上创建一个资源池,然后在资源池上创建一个带有文件系统的基本设备,所有镜像都是这个基本设备的快照,而容器则是镜像的快照。所以在容器里看到文件系统是资源池上基本设备的文件系统的快照,并不有为容器分配空间。当要写入一个新文件时,在容器的镜像内为其分配新的块并写入数据,这个叫用时分配。当要修改已有文件时,再使用CoW为容器快照分配块空间,将要修改的数据复制到在容器快照中新的块里再进行修改。Device mapper 驱动默认会创建一个100G的文件包含镜像和容器。每一个容器被限制在10G大小的卷内,可以自己配置调整。结构如下图所示:

4、Docker registry

启动容器时,docker daemon会试图从本地获取相关的镜像,本地镜像不存在时,其将从Registry中下载该镜像并保存到本地。

Registry用于保存docker镜像,包括镜像的层次结构和元数据。用户可以自建Registry,亦可使用官方的Docker Hub。

docker registry的分类:

  • Sponsor Registry:第三方的Registry,供客户和Docker社区使用
  • Mirror Registry:第三方的Registry,只让客户使用
  • Vendor Registry:由发布docker镜像的供应商提供的registry
  • Private Registry:通过设有防火墙和额外的安全层的私有实体提供的registry

docker registry的组成:

  • Repository
    • 由某特定的docker镜像的所有迭代版本组成的镜像仓库
    • 一个Registry中可以存在多个Repository
      • Repository可分为“顶层仓库”和“用户仓库”
      • 用户仓库名称格式为“用户名/仓库名”
    • 每个仓库可包含多个Tag(标签),每个标签对应一个镜像
  • Index
    • 维护用户帐户、镜像的检验以及公共命名空间的信息
    • 相当于为Registry提供了一个完成用户认证等功能的检索接口

Docker Registry中的镜像通常由开发人员制作,而后推送至“公共”或“私有”Registry上保存,供其他人员使用,例如“部署”到生产环境。

5、Docker镜像的制作

多数情况下,我们做镜像是基于别人已存在的某个基础镜像来实现的,我们把它称为base image。 比如一个纯净版的最小化的centos、ubuntu或debian。

那么这个最小化的centos镜像从何而来呢? 其实这个基础镜像一般是由Docker Hub的相关维护人员,也就是Docker官方手动制作的。 这个基础镜像的制作对于Docker官方的专业人员来说是非常容易的,但对于终端用户来说就不是那么容易制作的了。

5.1 Docker Hub

Docker Hub 是一项基于云的注册表服务,允许您链接到代码存储库、构建映像并对其进行测试、存储手动推送的映像以及指向 Docker Cloud 的链接,以便将映像部署到主机。

它为容器映像发现、分发和更改管理、用户和团队协作以及整个开发管道中的工作流自动化提供了集中式资源。

Docker Hub 提供以下主要功能:

  • 图像存储库
    • 从社区和官方库中查找和提取映像,以及管理、推送到您有权访问的私有映像库以及从中拉取映像库。
  • 自动构建
    • 在对源代码存储库进行更改时自动创建新映像。
  • 网络钩子
    • Webhooks 是自动构建的一项功能,可让您在成功推送到存储库后触发操作。
  • 组织
    • 创建工作组以管理对映像存储库的访问。
  • GitHub 和 Bitbucket 集成
    • 将中心和 Docker 映像添加到当前工作流。

5.2 Docker镜像的获取

要从远程注册表(例如您自己的 Docker 注册表)获取 Docker 映像并将其添加到本地系统,请使用 docker pull 命令:

# docker pull <registry>[:<port>]/[<namespace>/]<name>:<tag>

是一个在 TCP 上提供 docker 分发服务的主机(默认值:5000)

一起 识别由 注册表控制的特定映像

  • 一些注册表也支持原始;对于这些, 是可选的
  • 但是,当它被包括在内时,提供的附加层次结构级别对于区分具有相同图像是有用的

层次结构的附加层次

命名域 示例(<命名空间>/<名称>)
组织(organization) redhat/kubernetes, google/kubernetes
用户(username) Alice/application, bob/application
角色(role) 开发/数据库,测试/数据库,生产/数据库

5.3镜像的生成

镜像的生成途径:

  • Dockerfile
  • 基于容器制作
  • Docker Hub 自动构建

5.4基于容器制作镜像

根据容器的更改创建新映像

用法:

docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
选项 默认值 说明
—author, -a 作者(例如,“约翰·汉尼拔·史密斯[email protected]“)
-c, –change list 对创建的映像应用Dockerfile指令
-m, –message string 提交消息
-p, –pause true 提交期间暂停容器

准备工作:安装启动docker并配置加速器(详情见Docker基础用法

# 使用pull命令拉网上的busybox镜像
[root@localhost ~]# docker pull busybox
Using default tag: latest
latest: Pulling from library/busybox
50783e0dfb64: Pull complete 
Digest: sha256:ef320ff10026a50cf5f0213d35537ce0041ac1d96e9b7800bafd8bc9eff6c693
Status: Downloaded newer image for busybox:latest
docker.io/library/busybox:latest
[root@localhost ~]# docker images
REPOSITORY   TAG       IMAGE ID       CREATED      SIZE
busybox      latest    7a80323521cc   6 days ago   1.24MB

# 使用镜像busybox创建并运行一个名叫bus1容器并使用交互模式进去编辑,创建一个index.html文件
[root@localhost ~]# docker run -it --name bus1 busybox
/ # ls
bin   dev   etc   home  proc  root  sys   tmp   usr   var
/ # mkdir /data
/ # echo 'hellow world' > /data/index.html
/ # cat /data/index.html 
hellow world

# 创建镜像的时候不能关闭容器,必须使其处于运行状态,所以我们必须要另起一个终端
[root@localhost ~]# docker commit -a "[email protected]" -p -m "first commit" bus1
sha256:c476706b4b674189c8c47342398195108dfab017006d0351b31196f2d83aed47
[root@localhost ~]# docker images
REPOSITORY   TAG       IMAGE ID       CREATED       SIZE
<none>       <none>    c476706b4b67   8 seconds ago   1.24MB
busybox      latest    beae173ccac6   7 months ago    1.24MB

# 替换信息,名称为web,版本为v1
[root@localhost ~]# docker tag c476706b4b67 web:v1
[root@localhost ~]# docker images
REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
web        v1        c476706b4b67   44 seconds ago   1.24MB
busybox      latest    beae173ccac6   7 months ago     1.24MB

# 复制web镜像,名称为483607723,版本为v2
[root@localhost ~]# docker tag web:v1 483607723/web:v2
[root@localhost ~]# docker images
REPOSITORY      TAG       IMAGE ID       CREATED          SIZE
483607723/web    v2        c476706b4b67   About a minute ago   1.24MB
web           v1        c476706b4b67   About a minute ago   1.24MB
busybox        latest    beae173ccac6   7 months ago         1.24MB

打开Docker官网(Home – Docker)右上角Sign in。

在首页选择Create a Repository

输入仓库名称web,然后点击Create

这里有上传方法

# 登陆我们dockerhub账号
[root@localhost ~]# docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to //hub.docker.com to create one.
Username: 483607723
Password: 
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
//docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded

# 上传刚才修改的镜像webv2
[root@localhost ~]# docker push 483607723/web:v2
The push refers to repository [docker.io/483607723/web]
af1fc705554b: Pushed 
01fd6df81c8e: Mounted from library/busybox 
v2: digest: sha256:e7ffae293a2b4ad19dcbd821198769af4b7abde789ec2109af6f71628e7ef730 size: 734

上传成功

# 删除刚刚上传的镜像web:v2
[root@localhost ~]# docker rmi -f 483607723/web:v2 
Untagged: 483607723/web:v2
Untagged: 483607723/web@sha256:e7ffae293a2b4ad19dcbd821198769af4b7abde789ec2109af6f71628e7ef730
[root@localhost ~]# docker images
REPOSITORY   TAG       IMAGE ID       CREATED          SIZE
web          v1        c476706b4b67   12 minutes ago   1.24MB
busybox      latest    beae173ccac6   7 months ago     1.24MB

# 在网上下载我们刚上传的镜像web:v2
[root@localhost ~]# docker pull 483607723/web:v2
v2: Pulling from 483607723/web
Digest: sha256:e7ffae293a2b4ad19dcbd821198769af4b7abde789ec2109af6f71628e7ef730
Status: Downloaded newer image for 483607723/web:v2
docker.io/483607723/web:v2
[root@localhost ~]# docker images
REPOSITORY      TAG       IMAGE ID       CREATED          SIZE
483607723/web     v2        c476706b4b67   14 minutes ago   1.24MB
web            v1        c476706b4b67   14 minutes ago   1.24MB
busybox         latest    beae173ccac6   7 months ago     1.24MB

# 查看里面的内容是否一样,rm可以在退出镜像后自动删除容器
[root@localhost ~]# docker run -it --rm 483607723/web:v2 
/ # ls
bin   data  dev   etc   home  proc  root  sys   tmp   usr   var
/ # ls /data/
index.html
/ # cat /data/index.html 
hello world
/ # exit
[root@localhost ~]# docker ps -a
CONTAINER ID   IMAGE     COMMAND   CREATED          STATUS          PORTS     NAMES

由此可见,新生成的镜像中是包含了新增的内容的,但是此时有一个问题,那就是容器默认要启动的进程是什么?在这里,默认情况下是启动的sh进程,但我们是要启动一个http站点,所以我们要在创建镜像时将容器默认启动的进程设为httpd,这样一来我们就可以通过新生成的镜像来快速构建一个简单的http站点了。

5.5快速构建一个简单的http站点

# 使用交互模式临时进入web:v2
[root@localhost ~]# docker run -it --rm 483607723/web:v2

(另起一个终端)
[root@localhost ~]# docker ps
CONTAINER ID   IMAGE          COMMAND   CREATED          STATUS       PORTS     NAMES
2a77d42276da   483607723/web:v2   "sh"      37 seconds ago   Up 36 seconds          agitated_turing

# 把镜像web:v2的启动进程修改为httpd,另存为web:v3
[root@localhost ~]# docker ps
CONTAINER ID   IMAGE              COMMAND                  CREATED          STATUS          PORTS     NAMES
baa76767998e   483607723/web:v3   "/bin/httpd -f -h /d…"   49 seconds ago   Up 48 seconds             gifted_sinoussi
(-a是作者信息,-c为修改默认启动命令,/bin/httpd为启动进程,-f是不让它在后台运行,-c修改默认启动命令,-h指定目录)
[root@localhost ~]# docker commit -a "[email protected]" -c 'CMD ["/bin/httpd","-f","-h","/data"]' -p 2a77d42276da 483607723/web:v3
sha256:886b2b24d0bf1c9b2bc19a17b88d9cae4817fe334d704ab3069a6643b7d2e8d7
[root@localhost ~]# docker images
REPOSITORY      TAG       IMAGE ID       CREATED          SIZE
483607723/web   v3        886b2b24d0bf   6 seconds ago    1.24MB
483607723/web   v2        c476706b4b67   26 minutes ago   1.24MB
web             v1        c476706b4b67   26 minutes ago   1.24MB
busybox         latest    beae173ccac6   7 months ago     1.24MB

# 上传镜像web:v3
[root@localhost ~]# docker push 483607723/web:v3 
The push refers to repository [docker.io/483607723/web]
af1fc705554b: Layer already exists 
01fd6df81c8e: Layer already exists 
v3: digest: sha256:c7c0f6d6bdfba9a744a04a8f807ce33a19bdcbb96d428ce09bbd92ed20f47afc size: 734

# 使用交互模式临时进入web:v3
[root@localhost ~]# docker run -it --rm 483607723/web:v3

(另起一个终端)
[root@localhost ~]# docker ps
CONTAINER ID   IMAGE              COMMAND                  CREATED          STATUS          PORTS     NAMES
baa76767998e   483607723/web:v3   "/bin/httpd -f -h /d…"   49 seconds ago   Up 48 seconds             gifted_sinoussi

# 使用inspect命令查看它的IP地址
[root@localhost ~]# docker inspect baa76767998e
......
"Networks": {
                "bridge": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": null,
                    "NetworkID": "3c24f137381af6bee978bf7087e142784d622cf7ef9271be5528048d4263be96",
                    "EndpointID": "84f33913c45e60c599a15b1bf6237c51ab368f5320ac4c5833569b09681a7605",
                    "Gateway": "172.17.0.1",
                    "IPAddress": "172.17.0.3",
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "02:42:ac:11:00:03",
                    "DriverOpts": null
......

# 访问这个IP地址,测试是否成功构成站点
[root@localhost ~]# curl 172.17.0.3
hello world

6、镜像的导入与导出

假如有2台主机,我们在主机1上做了一个镜像,主机2想用这个镜像怎么办呢?

我们可以在主机1上push镜像到镜像仓库中,然后在主机2上pull把镜像拉下来使用,这种方式就显得比较麻烦,假如我只是测试用的,在一台主机上做好镜像后在另一台主机上跑一下就行了,没必要推到仓库上然后又把它拉到本地来。

此时我们可以在已有镜像的基础上把镜像打包成一个压缩文件,然后拷贝到另一台主机上将其导入,这就是镜像的导入和导出功能。

docker中我们使用docker save进行导出,使用docker load进行导入。

[root@localhost ~]# docker images
REPOSITORY      TAG       IMAGE ID       CREATED          SIZE
483607723/web   v3        886b2b24d0bf   10 minutes ago   1.24MB
483607723/web   v2        c476706b4b67   36 minutes ago   1.24MB
web             v1        c476706b4b67   36 minutes ago   1.24MB
busybox         latest    beae173ccac6   7 months ago     1.24MB

# 用save命令保存所有本地的镜像,导出到web.tar.gz中(不指定版本的话为所有版本)
[root@localhost ~]# docker save -o web.tar.gz 483607723/web
[root@localhost ~]# ls
anaconda-ks.cfg  web.tar.gz
[root@localhost ~]# file web.tar.gz 
web.tar.gz: POSIX tar archive

# 删除保存的2个镜像(模拟新的主机)
[root@localhost ~]# docker rmi 483607723/web:v2 483607723/web:v3 
[root@localhost ~]# docker images
REPOSITORY   TAG       IMAGE ID       CREATED          SIZE
web          v1        c476706b4b67   39 minutes ago   1.24MB
busybox      latest    beae173ccac6   7 months ago     1.24MB

# 用load导入web.tar,恢复两个web镜像
[root@localhost ~]# docker load -i web.tar.gz 
Loaded image: 483607723/web:v2
Loaded image: 483607723/web:v3
[root@localhost ~]# docker images
REPOSITORY      TAG       IMAGE ID       CREATED          SIZE
483607723/web   v3        886b2b24d0bf   14 minutes ago   1.24MB
web             v1        c476706b4b67   41 minutes ago   1.24MB
483607723/web   v2        c476706b4b67   41 minutes ago   1.24MB
busybox         latest    beae173ccac6   7 months ago     1.24MB

作业练习

在Docker Hub上获取一个centos基础镜像并创建容器,然后在容器里源码安装httpd服务,并将该容器重新制作成镜像,并上传到Docker Hub

# 使用pull命令拉网上的centos镜像
[root@localhost ~]# docker pull centos
Using default tag: latest
latest: Pulling from library/centos
a1d0c7532777: Pull complete 
Digest: sha256:a27fd8080b517143cbbbab9dfb7c8571c40d67d534bbdee55bd6c473f432b177
Status: Downloaded newer image for centos:latest
docker.io/library/centos:latest
[root@localhost ~]# docker images
REPOSITORY      TAG       IMAGE ID       CREATED         SIZE
483607723/web   v3        886b2b24d0bf   2 hours ago     1.24MB
483607723/web   v2        c476706b4b67   2 hours ago     1.24MB
web             v1        c476706b4b67   2 hours ago     1.24MB
busybox         latest    beae173ccac6   7 months ago    1.24MB
centos          latest    5d0da3dc9764   10 months ago   231MB

# 使用镜像centos创建并运行一个名叫centos1容器
[root@localhost ~]# docker run -it --name centos1 centos /bin/bash
[root@2f0c1da981f3 /]# ls
bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

# 在容器centos1中配置yum源
[root@2f0c1da981f3 /]# rm -rf /etc/yum.repos.d/*
[root@2f0c1da981f3 /]# curl -o /etc/yum.repos.d/CentOS-Base.repo //mirrors.aliyun.com/repo/Centos-vault-8.5.2111.repo
[root@2f0c1da981f3 /]# sed -i -e '/mirrors.cloud.aliyuncs.com/d' -e '/mirrors.aliyuncs.com/d' /etc/yum.repos.d/CentOS-Base.repo
[root@2f0c1da981f3 /]# yum install -y //mirrors.aliyun.com/epel/epel-release-latest-8.noarch.rpm
[root@2f0c1da981f3 /]# sed -i 's|^#baseurl=//download.example/pub|baseurl=//mirrors.aliyun.com|' /etc/yum.repos.d/epel*[root@2f0c1da981f3 /]# sed -i 's|^metalink|#metalink|' /etc/yum.repos.d/epel*

# 开发工具准备
[root@2f0c1da981f3 /]# dnf groups mark install -y "Development Tools"

# 创建apache服务的用户和组
[root@2f0c1da981f3 /]# useradd -r -M -s /sbin/nologin apache
[root@2f0c1da981f3 /]# id apache
uid=998(apache) gid=996(apache) groups=996(apache)

# 安装依赖包
[root@2f0c1da981f3 /]#  yum -y install openssl-devel pcre-devel expat-devel libtool gcc gcc-c++

# 下载apr、apr-util、httpd安装包至/usr/src/下
[root@2f0c1da981f3 /]# cd /usr/src/
[root@2f0c1da981f3 src]# wget //downloads.apache.org/apr/apr-1.6.5.tar.bz2
[root@2f0c1da981f3 src]# wget //downloads.apache.org/apr/apr-util-1.6.1.tar.bz2
[root@2f0c1da981f3 src]# wget //downloads.apache.org/httpd/httpd-2.4.54.tar.bz2
[root@2f0c1da981f3 src]# ls
apr-1.6.5.tar.bz2  apr-util-1.6.1.tar.bz2  debug  httpd-2.4.54.tar.bz2	kernels

# 解压和安装apr
[root@2f0c1da981f3 src]# tar -xf apr-1.6.5.tar.bz2 
[root@2f0c1da981f3 src]# ls
apr-1.6.5  apr-1.6.5.tar.bz2  apr-util-1.6.1.tar.bz2  debug  httpd-2.4.54.tar.bz2  kernels
[root@2f0c1da981f3 src]# cd apr-1.6.5
[root@2f0c1da981f3 apr-1.6.5]# vim configure
 cfgfile="${ofile}T"
    trap "$RM \"$cfgfile\"; exit 1" 1 2 15
    # $RM "$cfgfile"        //将此行加上注释,或者删除此行
    
[root@2f0c1da981f3 apr-1.6.5]# ./configure --prefix=/usr/local/apr
配置过程略...
[root@2f0c1da981f3 apr-1.6.5]#make && make install
配置过程略...

# 解压和安装apr-util
[root@2f0c1da981f3 src]# tar -xf apr-util-1.6.1.tar.bz2 
[root@2f0c1da981f3 src]# cd apr-util-1.6.1
[root@2f0c1da981f3 apr-util-1.6.1]# ./configure --prefix=/usr/local/apr-util --with-apr=/usr/local/apr
配置过程略...
[root@2f0c1da981f3 apr-util-1.6.1]#  make && make install
配置过程略...

# 编译安装httpd
[root@2f0c1da981f3 httpd-2.4.54]# ./configure --prefix=/usr/local/apache --enable-so --enable-ssl --enable-cgi --enable-rewrite --with-zlib --with-pcre --with-apr=/usr/local/apr --with-apr-util=/usr/local/apr-util/ --enable-modules=most --enable-mpms-shared=all --with-mpm=prefork
[root@2f0c1da981f3 httpd-2.4.54]# make && make install

# 编辑apache启动脚本
[root@2f0c1da981f3 /]# vim httpd.sh
#!/bin/bash
/usr/local/apache/bin/apachectl
sleep 5d
[root@2f0c1da981f3 /]# chmod +x httpd.sh 		#给脚本执行权限
[root@2f0c1da981f3 /]# ls -l | grep httpd.sh
-rwxr-xr-x. 1 root root   53 Aug  6 15:56 httpd.sh

(另起一个终端)
# 基于容器centos1制作镜像
[root@localhost ~]# docker commit -a 'zsl <[email protected]>' -c 'CMD ["/httpd.sh"]' -p centos1 483607723/centos-httpd:v1
sha256:ca1d47fbafabae0791a9ce96c4052a90522c734ff1a434fa9e2d21a642de0a4d
[root@localhost ~]# docker images
REPOSITORY               TAG       IMAGE ID       CREATED          SIZE
483607723/centos-httpd   v1        ca1d47fbafab   18 seconds ago   776MB
centos                   latest    5d0da3dc9764   10 months ago    231MB

# 用新生成的镜像创建容器
[root@localhost ~]# docker run -d -it --name web1 483607723/centos-httpd:v1 
50efb3b77296224ec572ded4c65a349abb726e90d6af26e8d431c64b75984a78
[root@localhost ~]# docker ps
CONTAINER ID   IMAGE                       COMMAND       CREATED         STATUS         PORTS     NAMES
50efb3b77296   483607723/centos-httpd:v1   "/httpd.sh"   9 seconds ago   Up 7 seconds             web1
2f0c1da981f3   centos                      "/bin/bash"   3 hours ago     Up 3 hours               centos1
[root@localhost ~]# docker inspect web1
......
"Networks": {
                "bridge": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": null,
                    "NetworkID": "3c24f137381af6bee978bf7087e142784d622cf7ef9271be5528048d4263be96",
                    "EndpointID": "6611f8535de660d6f74efb36925faf3ff02153283e4f417abad5cd2d8005db3a",
                    "Gateway": "172.17.0.1",
                    "IPAddress": "172.17.0.3",
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "02:42:ac:11:00:03",
                    "DriverOpts": null
                }
......
[root@localhost ~]# curl 172.17.0.3
<html><body><h1>It works!</h1></body></html>

# 配置端口映射
[root@localhost ~]# docker run -d -it --name web2 -p 8080:80 483607723/centos-httpd:v1 
fd7563facbe81ad04343cfb6488ade3781cbe87d5510002edef00c7e3581f54c
[root@localhost ~]# docker ps
CONTAINER ID   IMAGE                       COMMAND       CREATED          STATUS          PORTS                                   NAMES
fd7563facbe8   483607723/centos-httpd:v1   "/httpd.sh"   12 seconds ago   Up 11 seconds   0.0.0.0:8080->80/tcp, :::8080->80/tcp   web2
50efb3b77296   483607723/centos-httpd:v1   "/httpd.sh"   6 minutes ago    Up 6 minutes                                            web1
2f0c1da981f3   centos                      "/bin/bash"   3 hours ago      Up 3 hours                                              centos1
[root@localhost ~]# ss -anlt | grep 80
LISTEN 0      128          0.0.0.0:8080      0.0.0.0:*          
LISTEN 0      128             [::]:8080         [::]:*     

# 

进入Docker Hub创建仓库

# 登陆我们dockerhub账号
[root@localhost ~]# docker login
Authenticating with existing credentials...
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
//docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded

# 修改上传镜像的名称
[root@localhost ~]# docker tag 483607723/centos-httpd:v1 483607723/httpd:v1
[root@localhost ~]# docker images
REPOSITORY               TAG       IMAGE ID       CREATED          SIZE
483607723/centos-httpd   v1        ca1d47fbafab   38 minutes ago   776MB
483607723/httpd          v1        ca1d47fbafab   38 minutes ago   776MB
centos                   latest    5d0da3dc9764   10 months ago    231MB

# 使用push命令将镜像上传
[root@localhost ~]# docker push 483607723/httpd:v1 
The push refers to repository [docker.io/483607723/httpd]
c76332ad693c: Mounted from 483607723/centos-httpd 
74ddd0ec08fa: Mounted from 483607723/centos-httpd 
v1: digest: sha256:43698f0ad872c35669c61feb19f3568b25a7ef4c9271518c945f0b3cc68f9800 size: 742

上传成功

Tags: