博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
构建docker镜像
阅读量:6288 次
发布时间:2019-06-22

本文共 9002 字,大约阅读时间需要 30 分钟。

1.创建Docker Hub账号

网址: 注册.

  • 登录
$ sudo docker login

2.用docker commit命令创建镜像

  • 创建一个要进行修改的定制容器
$ sudo docker run -i -t ubuntu /bin/bash                   root@7dfcf4332617:/#
  • 在容器中安装apache软件包
root@7dfcf4332617:/# apt-get -yqq updateroot@7dfcf4332617:/# apt-get -y install apache2
  • 提交定制容器
$ sudo docker commit 7dfcf4332617 hiekay/apache2
  • 检查新创建的镜像
$ sudo docker images hiekay/apache2             REPOSITORY          TAG                 IMAGE ID            CREATED              SIZEhiekay/apache2      latest              d36fa6c04e5b        About a minute ago   205MB
  • 提交另一个新的定制容器
$ sudo docker commit -m="A new custom image" --author="hiekay" 7dfcf4332617 hiekay/apache2:webserver

解析:

-m 指定提交信息,--author指定作者信息, ID:7dfcf4332617 ,hiekay/apache2 用户名和仓库名, 标签:webserver

  • 查看镜像的详细信息
$ sudo docker inspect  hiekay/apache2:webserver                                                       [    {        "Id": "sha256:dfda6a2c29aac1aa25b188f5b5f1a8b0d6cf63c92df0bacb4f062be312ebe9c2",        "RepoTags": [            "hiekay/apache2:webserver"        ],........
  • 运行新容器
$ sudo docker run -i -t hiekay/apache2:webserver /bin/bashroot@b7a12bac939e:/#

3.用Dockerfile创建镜像

用Dockerfile的自定义文件和docker build 命令来构建镜像.Dockerfile使用基本的基于DSL语法的指令来构建一个Docker镜像,之后使用docker build命令基于该Dockerfile中的指令构建一个新的镜像.

创建第一个Dockerfile
  • 创建一个示例仓库
$ mkdir static_web$ cd static_web$ touch Dockerfile

目录static_web 用来保存Dockefile ,这个目录也是我们的构建环境, Docker称此环境为上下文或者构建上下文. Docker 会在构建镜像时将构建上下文和该上下文中的文件和目录上传到Docker守护进程.

  • 第一个Dockerfile
    例子: 创建一个空Dockerfile,通过Dockerfile 构建一个能作为Web服务器的Docker镜像.
#Version: 0.0.1FROM ubuntu:18.04MAINTAINER hiekay "hikay5230@gmail.com"RUN apt-get updateRUN apt-get install -y nginxRUN echo 'Hi,I am in your container' > /usr/share/nginx/html/index.htmlEXPOSE 80

该Dockerfile由一系列指令和参数组成.

每条指令,如FROM都必须大写,后面跟一个参数.
指令会按顺序从上到下执行.
每条指令都会去创建一个新的镜像层并对镜像进行提交.

流程:
  • Docker从基础镜像运行一个容器.
  • 执行一条指令,对容器做出修改.
  • 执行类似docker commit 的操作,提交一个新的镜像层.
  • Docker再基于刚提交的镜像运行一个新容器.
  • 执行Dockerfile中的下一个指令,直到所有指令都执行完毕.
    所以,如果Dockerfile某些原因(某指令失败了)没有正常结束.也将得到一个可以使用的镜像.
解析
  • 每个Docker的第一条指令都应该是FROM,FROM指令指定了一个已经存在的镜像,后续指令都将基于该镜像进行,这个镜像被称为基础镜像.
  • MAINTAINER指令设置作者和邮箱
  • RUN指令,会在当前镜像中运行指定的命令,默认RUN指令会在shell中使用命令包装器/bin/sh -c 运行. 如果是在一个不支持shell的平台或者不希望在shell中运行,可以用exec 格式的RUN指令
    如:
RUN [ "apt-get", " install ", "-y", "nginx" ]

在这种方式中,使用一个数组来指定要运行的命令和传递给该命令的每个参数.

  • EXPOSE指令,是设置容器的指定端口. 也可以指定多个端口.

4.基于Dockerfile构建新镜像

执行docker build 命令时,Dockerfile中的所有命令都会执行并提交,成功结束后返回一个新镜像.

  • 运行Dockerfile
$ cd static_web$ sudo docker build -t="hiekay/static_web" . //开始运行sending build context to Docker daemon  2.048kBStep 1/6 : FROM ubuntu:18.0418.04: Pulling from library/ubuntuDigest: sha256:29934af957c53004d7fb6340139880d23fb1952505a15d69a03af0d1418878cbStatus: Downloaded newer image for ubuntu:18.04 ---> ea4c82dcd15aStep 2/6 : MAINTAINER hiekay "hikay5230@gmail.com" ---> Running in 82ebf098abd8Removing intermediate container 82ebf098abd8 ---> b8405a62db26Step 3/6 : RUN apt-get update

其中 -t 选项设置了仓库和名称.

还可以设置标签:

sudo docker build -t="hiekay/static_web:v1" .

如果不设置标签,默认标签是latest标签.

命令最后的 . 告诉Docker到本地目录去找Dockerfile , 也可以指定一个git 仓库的源地址来指定Dockerfile的地址
如:

sudo docker build -t="hiekay/static_web:v1" git@github.com:hiekay/docker-static-_web

在该git仓库根目录下存折Dockerfile文件.

其中:
sending build context to Docker daemon 2.048kB
是将构建上下文上传到Docker守护进程.

  • 注意:
    如果在构建上下文的根目录下存在.dockerignore命名的文件, 这个该文件用来设置哪些文件不会被上传到构建上下文中.

5.指令失败时会怎样

假如在第四部写错了:ngin

$ cd static_web$ sudo docker build -t="hiekay/static_web" . //开始运行Sending build context to Docker daemon  2.048kBStep 1/6 : FROM ubuntu:18.04 ---> ea4c82dcd15aStep 2/6 : MAINTAINER hiekay "hikay5230@gmail.com" ---> Using cache ---> b8405a62db26Step 3/6 : RUN apt-get update ---> Using cache ---> a7b7791c3818Step 4/6 : RUN apt-get install -y ngin ---> Running in fabeeceeefe2Reading package lists...Building dependency tree...Reading state information...E: Unable to locate package nginThe command '/bin/sh -c apt-get install -y ngin' returned a non-zero code: 100

报错,E: Unable to locate package ngin

最后成功的一层ID是:a7b7791c3818

  • 基于最后成功步骤创建新容器
    再运行: apt-get install -y ngin 并指定正确的包名,进一步调试,解决问题.就可以退出容器了,使用正确的报名修改Dockerfile,之后再进行构建.
$ sudo docker run -i -t a7b7791c3818 /bin/bashroot@9988a4ab2845:/# root@9988a4ab2845:/# apt-get install -y ngin

6.Dockerfile 和构建缓存

因为每一步的构建过程都会将结果提交为镜像,所以它会将之前的镜像层看做缓存.

  • 忽略Dockerfile的构建缓存
$ sudo docker build --no-cache -t="hiekay/static_web" .

7.基于构建缓存的Dockerfile模板

构建缓存的好处是可以实现简单的Dockerfile模板.在自己的Dockerfile文件顶部使用相同的指令模板,比如Ubuntu.

  • Ubuntu系统的Dockerfile模板
#Version: 0.0.1FROM ubuntu:18.04MAINTAINER hiekay "hikay5230@gmail.com"ENV REFRESHED_AT 2018-11-1RUN apt-get -qq update
  • 解析:
    首先通过FROM指令为镜像设置基础镜像Ubuntu:18.04 , 然后使用MAINTAINER 添加自己的信息. 之后使用 ENV 设置 环境变量.设置REFRESHED_AT的环境变量用来表示该镜像模板最后的更新时间 .最后使用RUN指令运行apt-get -qq update 命令. 该指令运行时将会刷新APT包的缓存,用来确保我们能将要安装的每个软件包都更新到最新版本.

有了这个模板,如果想刷新一个构建,只需要修改ENV指令中的日期.这使Docker在命令ENV指令时开始重置这个缓存,并运行后续指令无须依赖该缓存. 也就是说, RUN apt-get update 这条指令将会被再次执行,包缓存也将会被刷新为最新内容.

可以扩展此模板,比如适配到不同的平台或者添加额外的需求.

  • 比如支持Fedora Dockerfile模板
FROM fedora:20MAINTAINER hiekay "hikay5230@gmail.com"ENV REFRESHED_AT 2018-11-1RUN yum -y -q upgrade

在Fedora中使用Yum实现了与上面的Ubuntu例子中非常类似的功能.

8.查看新镜像

  • 列出新的Docker镜像
$ sudo docker images hiekay/static_webREPOSITORY          TAG                 IMAGE ID            CREATED             SIZEhiekay/static_web   latest              7e35e0a7fc62        3 hours ago         169MB

深入探究镜像是如何构建出来的,使用docker history命令

  • 使用docker history 命令
$ sudo docker history 7e35e0a7fc62  IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT7e35e0a7fc62        3 hours ago         /bin/sh -c #(nop)  EXPOSE 80                    0B                  2f6d2e9be7ac        3 hours ago         /bin/sh -c echo 'Hi,I am in your container' …   26B                 4c7337c294ac        3 hours ago         /bin/sh -c apt-get install -y nginx             59.7MB              489c8164d6af        3 hours ago         /bin/sh -c apt-get update                       23.8MB              c8288775012d        3 hours ago         /bin/sh -c #(nop)  MAINTAINER hiekay "hikay5…   0B                  ea4c82dcd15a        13 days ago         /bin/sh -c #(nop)  CMD ["/bin/bash"]            0B                  
13 days ago /bin/sh -c mkdir -p /run/systemd && echo 'do… 7B
13 days ago /bin/sh -c rm -rf /var/lib/apt/lists/* 0B
13 days ago /bin/sh -c set -xe && echo '#!/bin/sh' > /… 745B
13 days ago /bin/sh -c #(nop) ADD file:bcd068f67af2788db… 85.8MB

9.从新镜像启动一个容器

$ sudo docker run -d -p 80 --name static_web hiekay/static_web nginx -g "daemon off;"09bb5531cbc24930ad35da95dd0acd52dd933c5996ae89e238b509053b7f8c1d
  • 解析:
  1. run命令运行一个名字为static_web的新容器, -d 选项,告诉Docker以分离(detached)的方式在后台运行.适合运行类似Nginx守护进程这样的需要长时间运行的进程. 并指定了需要在容器中运行的命令:nginx -g "daemon off;" 这将以前台运行的方式启动nginx 来作为我们的Web服务器.

其中-p标志,用来控制Docker公开哪些网络端口给外部宿主机.

两种方法分配端口:

  • Docker可以在宿主机上随机选择一个位于49153~65535的一个比较大的端口号来映射到容器中80端口上.
  • 可以在Docker宿主机中指定一个具体的端口号来映射到容器中的80端口上.
  • 查看Docker端口映射情况
$ sudo docker ps -l
  • dockerport 命令查看
$ sudo docker port 09bb5531cbc2 80                                                  80/tcp -> 127.0.0.1:32768
  • 通过-p选项映射到特定端口
$ sudo docker run -d -p 80:80 --name static_web hiekay/static_web nginx -g "daemon off;"
  • 绑定不同的端口
$ sudo docker run -d -p 8080:80 --name static_web hiekay/static_web nginx -g "daemon off;"
  • 绑定到特定的网络接口
$ sudo docker run -d -p 127.0.0.1:80:80 --name static_web hiekay/static_web nginx -g "daemon off;"

绑定到了宿主机127.0.0.1这个IP的80端口上.

  • 绑定到特定的网络接口的随机端口
$ sudo docker run -d -p 127.0.0.1::80 --name static_web hiekay/static_web nginx -g "daemon off;"
  • 扩展
    可以使用 /udp后缀指定UDP端口

其中提供参数-P 用来对外公开在Dockerfile中的EXPOSE指令中设置的所有端口

  • 使用docker run命令对外公开端口
$ sudo docker run -d -P --name static_web hiekay/static_web nginx -g "daemon off;"

该命令会将容器内的80端口对本地宿主机公开,绑定宿主机的随机端口. 会将用来构建该镜像的Dockerfile文件中EXPOSE指令指定的其他端口也公开.

有了这个端口号,我们可以用本地宿主机IP或者127.0.0.1的localhost 链接到运行中的容器了.

  • 使用curl连接到容器
$ curl localhost:32768//成功返回:Welcome to nginx!

Welcome to nginx!

If you see this page, the nginx web server is successfully installed andworking. Further configuration is required.

For online documentation and support please refer tonginx.org.

Commercial support is available atnginx.com.

Thank you for using nginx.

10.将镜像推送到Docker Hub

  • docker push
    推送Docker镜像
$ sudo docker push hiekay/static_webThe push refers to repository [docker.io/hiekay/static_web]......

成功后,可以在Docker Hub上看到我们上传的镜像.

image.png

11.删除镜像

sudo docker rmi hiekay/static_web

如果要删除一个Docker Hub上的镜像仓库,需要登录Docker Hub后使用Delete repository链接来删除.

image.png

  • 删除所有镜像
sudo docker rmi 'docker images -a -q'

12.运行自己的Docker Registry

  • 运行基于容器的Registry
sudo docker run -p 5000:5000 registry
  • 查看hiekay/static_web
sudo docker images hiekay/static_web
  • 使用新的Registry 为镜像打标签
sudo docker tag 某个ID docker.example.com:5000/hiekay/static_web
  • 将镜像推送到新Registry
sudo docker push docker.example.com:5000/hiekay/static_web
  • 从本地Registry构建新的容器
sudo docker run -t -i docker.example.com:5000/hiekay/static_web /bin/bash

转载地址:http://nuuta.baihongyu.com/

你可能感兴趣的文章