目前已经更新完《Java并发编程》,《Docker教程》和《JVM性能优化》,欢迎关注【后端精进之路】,轻松阅读全部文章。

Java并发编程:

Docker教程:

JVM性能优化:

上篇文章引入了Docker的基本原理和操作,本节文章主要介绍如何制作Docker镜像和发布。

镜像文件结构

Docker镜像的本质是一系列文件的集合,这些文件依次叠加,形成了最后的镜像文件,类似于下图所示的结构,

从底层往上,依次是文件系统层,操作系统层,专有镜像层,读写层。

  • 启动文件层:Docker启动时的用到的文件系统,启动完成后会自动脱离,用户不会与这一层直接打交道。

  • 操作系统层:这一层主要是操作系统相关的一些文件,根据发行版本的不同,可能有CentsOS、Ubuntu等等。文件包含dev,/proc,/bin,/etc 等目录, 是一个最小化的操作系统,很多工具都没有提供,包括vi、wget、curl等。注意这一层不包含linux内核,只是可在任何满足要求的linux内核上运行。

  • 专有镜像层:一般各大软件都会基于上面两层制作专有的镜像,比如nginx、tomcat等,都有专门的官方镜像,可以直接在docker hub上下载。

  • 读写层:这是我们制作自己的镜像时需要操作的层,是一个动态的运行环境,在后续镜像制作中的比如ENV, Volume,cmd等操作最终落实到此运行环境中。

制作镜像的实质就是修改读写层。当需要修改镜像内的某个文件时,只对处于最上方的读写层进行了变动,不复写下层已有文件系统的内容,已有文件在只读层中的原始版本仍然存在,但会被读写层中的新版本文件所隐藏,当 docker commit 这个修改过的容器文件系统为一个新的镜像时,保存的内容仅为最上层读写文件系统中被更新过的文件。

可以通过history命令查看镜像层,

制作镜像

制作镜像有两种通用的方法,第一种是直接通过配置好的Container来生成镜像;另外一种是通过Dockerfile的方式,基于已有的镜像来生成新的镜像,这种方法更为常用。

配置Container制作镜像

这里以制作nginx的镜像为例,介绍整个制作流程。

1)下载基础镜像,这里以Ubuntu作为基础镜像。由于本地没有镜像可以先利用docker search获取官方镜像的名称,然后docker pull将镜像下载到本地。

2)以交互方式启动镜像,方便在容器中安装软件。-it表示交互方式,/bin/bash为指定启动的终端。下图可以看到已经成功进入到容器内部了。

docker run -it ubuntu:latest /bin/bash

3)现在按照Nginx正常的安装流程安装即可,由于Ubuntu镜像只是一个最小化的系统,可能你需要通过apt-get install来安装一些需要的软件。

4)退出容器,使用commit指令生成新的镜像。

注意退出容器的时候,也有两种方法,通常直接exit就可以,但是这样容器也会关闭。如果不想关闭容器,只是退出终端,可以使用Ctrl+P+Q快捷键,此时退出后,容器依然在后台运行。

直接运行docker commit同时指定容器id或者name,以及镜像名就可以了,新的镜像制作完成了。

docker commit e0c618df0979 ubuntu-nginx

接下来可以通过正常的方式启动镜像了。

使用Dockerfile制作

上面介绍了手动进入容器内部,制作Docker镜像的方式,一般比较繁琐。通常我们会使用Dockerfile的方式制作镜像,这种方式下我们需要编写Dockerfile文件。

Dockerfile文件

Dockerfile是一个文本格式的配置文件,用户可以使用Dockerfile快速创建自定义镜像。

下面是一个简单的Dockerfile文件,先将编译生成的jar文件复制到容器,然后声明容器暴露的端口,最后指定在启动容器时需要运行的指令。

FROM openjdk:8
ADD ["target/bazaar-1.0.0.jar", "bazaar.jar"]
EXPOSE 1234
ENTRYPOINT ["java", "-jar", "/bazaar.jar"]

Dockerfile中常用的指令集有:

  • FROM: 第一条指令必须为FROM指令,用于指定基础镜像。
  • MAINTAINER: 指定维护者信息。
  • RUN: 会在shell终端运行命令。
  • EXPOSE: 格式为 EXPOSE [ ...],声明容器需要暴露的端口号。镜像启动可以通过 –P 或 -p 进行端口映射的绑定。
  • ENV: 指定一个环境变量,可以被后续的RUN引用,并且在容器中记录该环境变量。
  • ADD: 该命令将复制指定的到容器中的。其中可以是Dockerfile所在目录的一个相对路径;也可以是tar文件(自动解压)。
  • VOLUME: 格式为 VOLUME [path]。创建一个可以从本地主机或其他容器挂载点,一般用来存放需要保持的数据。
  • USER: 指定运行容器时的用户名,后续的RUN也会指定该用户。
  • WORKDIR: 指定工作空间,后续命令都在此目录下执行。

比较复杂的是CMD与ENTRYPOINT的对比,两者都可以运行指令,但是稍有不同。

  • CMD给出的是一个容器的默认的可执行体,可以被覆盖。
  • ENTRYPOINT才是正统地用于定义容器启动以后的执行体,这个执行体一定会被执行。

(1) CMD单独使用

FROM debian:wheezy
CMD ["/bin/ping", "localhost"]

启动后不指定任何参数,将会ping localhost,

$ docker run -it test
PING localhost (127.0.0.1): 48 data bytes
56 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.076 ms
56 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.087 ms
56 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.090 ms
^C--- localhost ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.076/0.084/0.090/0.000 ms

但是如果启动容器的同时带有新的指令,则原有的CMD会被新的指令覆盖

docker run -it test bash
root@e8bb7249b843:/#

(2)CMD和ENTRYPOINT同时使用

CMD通常用作传递参数给ENTRYPOINT,如下例子所示:

FROM debian:wheezy
ENTRYPOINT ["/bin/ping"]
CMD ["localhost"]

直接运行镜像并不指定任何参数,将会一直ping localhost

$ docker run -it test
PING localhost (127.0.0.1): 48 data bytes
56 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.096 ms
56 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.088 ms
56 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.088 ms
^C--- localhost ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.088/0.091/0.096/0.000 ms

如果直接运行的同时,指定一个参数,将会ping对应的参数,此时CMD被覆盖。

$ docker run -it test google.com
PING google.com (173.194.45.70): 48 data bytes
56 bytes from 173.194.45.70: icmp_seq=0 ttl=55 time=32.583 ms
56 bytes from 173.194.45.70: icmp_seq=2 ttl=55 time=30.327 ms
56 bytes from 173.194.45.70: icmp_seq=4 ttl=55 time=46.379 ms
^C--- google.com ping statistics ---
5 packets transmitted, 3 packets received, 40% packet loss
round-trip min/avg/max/stddev = 30.327/36.430/46.379/7.095 ms

如果你想要制作的容器更加通用一些,可以在Dockerfile中使用CMD ["/path/dedicated_command"],这样你可以在运行容器的同时,根据需求来覆盖已有的指令。

利用Dockerfile制作容器

上面介绍了Dockerfile中常用的指令,一般我们写好Dockerfile之后,直接进入到Dockerfile所在的目录,运行docker build即可,Docker会根据Dockerfile中指定的步骤来生成我们的镜像。

$ docker build -t your_image_name .

以上就是制作镜像的所有流程,接下来介绍镜像的发布。

镜像发布

镜像发布有两种选择,可以直接push到官方的docker hub,你只需要注册一个docker账号即可;也可以自己在本地创建私有仓库,将镜像push这里。

Docker Hub

打开 https://hub.docker.com/ 注册好账户后,记住好自己的账户名,待会需要将本地的镜像打tag带上用户名,然后进行push。

首先使用如下的指令就给本地镜像打tag,

docker tag myImage:v1 your_user_name/myImage:v1

接下来直接push就行,会自动push到官方仓库,注意可能会需要docker login一下,这里直接输入用户名密码即可。

docker push your_user_name/myImage:v1

这样官方仓库就有你的Image了, 以后直接docker pull就行了。

本地私有仓库

(1) 首先下载registry镜像:docker pull registry.

(2) 接着在5000端口启动,docker run -d --name reg -p 5000:5000 registry.

(3) 配置http传输,私服默认只能使用https,需要配置开放http.

以centos上的配置为例,

注意图中的ip根据实际registry的ip来进行设置,可以通过docker inspect reg来找到。

配置完毕重启下docker服务

systemctl daemon-reload
systemctl restart docker

以上就完成了私有仓库的创建。

接下来直接push Image到仓库即可,流程和push到官方仓库类似,只是打tag的用户名改成私有仓库的地址。

(1)打tag

docker tag hello-world http://192.168.244.7:5000/hello-world

(2)push镜像

docker push 192.168.244.7:5000/hello-world

(3)查询镜像:

(4)查询镜像版本:

以上就是镜像制作和发布的全部内容,下节会介绍实际部署中,docker-compose的使用以及docker的网络通信。

参考链接:


本文由『后端精进之路』原创,首发于博客 http://teckee.github.io/ , 转载请注明出处

搜索『后端精进之路』关注公众号,立刻获取最新文章和价值2000元的BATJ精品面试课程

Docker系列-(2) 镜像制作与发布的更多相关文章

  1. Docker Java程序镜像制作

    Docker Java程序镜像制作 制作前的准备 jre:不需要完整的jdk,jre即可,到Oracle进行下载即可,下载链接,根据自己的情况进行选择,这里选择jre-8u221-linux-x64. ...

  2. docker镜像制作及发布

    以centos为例. 主要内容:安装docker,制作镜像,发布镜像. 安装docker 1. 安装docker yum install -y docker 等待一会,安装成功,查看安装列表 2. 启 ...

  3. 利用docker进行基础镜像制作

    前言 最近想通过Javaee来开发博客,但是不想因为环境配置问题总是耗时间配置相关配置,所以萌生出用docker镜像来搭建web的系统环境,也是作为docker学习实践的笔记. docker hub注 ...

  4. Docker2 docker commit方法镜像制作

    一.前期准备 1.下载一个centos镜像,进入容器,安装wget docker pull centos docker run -it centos bash [root@web1 ~]# docke ...

  5. Docker学习以及镜像制作流程

    一.何为Docker Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从Apache2.0协议开源. Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级.可移植的容器中,然后 ...

  6. Docker笔记——jenkins镜像制作

    jenkins官方路径:https://hub.docker.com/_/jenkins/ 最新Dockerfile路径:https://github.com/jenkinsci/docker/blo ...

  7. Docker笔记——jdk镜像制作

    openjdk镜像依赖如下: openjdk:8-jdk -> buildpack-deps:jessie-scm -> buildpack-deps:jessie-curl -> ...

  8. docker 系列 - 基础镜像环境和Docker常用命令整理

    =======================docker 基础镜像环境 alpine=======================可以使用 docker search 命令搜索指定的 image, ...

  9. docker 系列 - Java程序制作Docker Image推荐方案(转载)

    本文转自 https://segmentfault.com/a/1190000016449865  , 感谢作者! 本文的源代码在:https://github.com/chanjarste... 这 ...

随机推荐

  1. windows 2008 服务器优化:停powershell,卸载不相干软件,开启防火墙

    windows 2008 作为 全录 的服务器,经常cpu达到100%,查看是powershell.exe占cpu有98%.影响 全录 软件进行电话录音.所以想禁止powershell.exe程序启动 ...

  2. PHP程序员-常用工具

    三连问 经常有社区的同学问: “我的PHP程序有没有阻塞,我的PHP程序有没有开启协程(对自己写好的代码表示不自信),我的PHP程序有没有问题”.然后贴出了自己的程序,然后进入了愉快的灌水环节,随着时 ...

  3. VS Code 中使用 GitHub pull request 插件提交代码

    VS Code作为一个代码编辑器,受到很多人的喜爱:其中有很多非常有用的插件/扩展功能,也会极大的提高我们的工作效率. 这里介绍一下GitHub pull request,用来向GitHub提交在VS ...

  4. 前端 vue单页面应用刷新网页后vuex的state数据丢失的解决方案(转载)

    最近接手了一个项目,前端后端都要做,之前一直在做服务端的语言.框架和环境,前端啥都不会啊. 突然需要前端编程,两天速成了JS和VUE框架,可惜还是个半吊子.然后遇到了一个困扰了一整天的问题.一直调试都 ...

  5. Elasticsearch系列---简单入门实战

    概要 本篇主要介绍一下Elasticsearch Document的数据格式,在Java应用程序.关系型数据库建模的对比,介绍在Kibana平台编写Restful API完成基本的集群状态查询,Doc ...

  6. ZeroC ICE的远程调用框架 AMI与AMD -Why?

    在Ice有两种异步使用的方式,AMI和AMD.AMI是异步方法调用,AMD是异步方法调度(分派).前者用在代理端,后者用在饲服实现端. AMI其实就是在代理端,使用Future机制进行异步调用,而不阻 ...

  7. 关于手机微信端ios的input不能选中问题解决方案

    最近在做一个微信端的商城,以前做web端的比较多,手机端做的相对来说要少点,老板说让我用俗称”靠谱的移动前端框架”—-AUI来搭建项目. 当时觉得用不用框架无所谓啦.结果后来写到一半把项目发布到手机上 ...

  8. 无法优化的O(n!) 算法

    旅行商问题: 有一位旅行商,他需要前往5个城市. 要前往这5个城市,同时要确保旅程最短. 对于每种顺序,他都计算总旅程,再挑选出旅程最短的路线.5个城市有120种不同的排列方式.因此,在涉及5个城市时 ...

  9. H3C交换机DHCP基础配置案例 v7版本

    一.需求 要求在Switch A上配置DHCP服务器功能实现:• 为网络内的客户端动态分配 10.1.1.0/24 网段内的 IP 地址.租用有效期限. DNS 信息.网关地址等配置信息:• 根据 S ...

  10. 题解-洛谷P2010-回文日期

    原题链接: https://www.luogu.org/problem/P2010 题目简述: 牛牛习惯用8位数字表示一个日期,其中,前4位代表年份,接下来2位代表月份,最后22位代表日期.显然:一个 ...