使用Jib快速简便地创建Docker镜像

标签: jib docker 镜像 | 发表时间:2020-03-23 20:57 | 作者:dummy
出处:http://weekly.dockone.io

在本文中,我们将看看Jib,它是Google提供的一个工具,可以轻松快速地创建Docker镜像。无需创建Dockerfile文件,也无需安装Docker守护进程,Jib可直接使用。
  1. 简介


到目前为止,我们一直使用来自Spotify的 dockerfile-maven-plugin来构建和推送Docker镜像。这要求我们根据 最佳实践来编写Dockerfile,安装Docker守护进程并将插件添加到构建过程中。Jib将为我们提供一种更简便的方式来创建Docker镜像。我们只需要添加并配置Maven插件即可。当然,只有当我们自己亲自尝试了,我们才会相信它更轻便,这正是接下来要做的。

我们将创建一个简单的Spring Boot应用程序,使用 Jib Maven插件将其容器化并将其推送到DockerHub。接着我们将拉取镜像并运行容器。这些资源可在 Github获取。

我们正在使用:
  • Ubuntu 18.04
  • Spring Boot 2.2.1
  • Java 11
  • Jib Maven插件1.8.0
  • Docker Hub账号


有关Jib的更多信息请访问 Google Cloud Platform BlogGitHub
  1. 创建应用程序


第一步,我们将创建一个简单的Spring Boot应用程序。我们将Spring Actuator和Spring Web MVC依赖项添加到pom文件中。 Spring Actuator将为我们提供添加运行状况检查的方法。
  
org.springframework.boot
spring-boot-starter-actuator


org.springframework.boot
spring-boot-starter-web



我们的应用程序由一个Rest控制器组成,该控制器返回问候消息和机器地址。
@RestController  
public class HelloController {
@RequestMapping("/hello")
public String hello() {
    StringBuilder message = new StringBuilder("Hello Jib Maven Plugin!");
    try {
        InetAddress ip = InetAddress.getLocalHost();
        message.append(" From host: " + ip);
    } catch (UnknownHostException e) {
        e.printStackTrace();
    }
    return message.toString();
}
}


在本地运行:
$ mvn spring-boot:run  


成功启动之后,我们调用URL http//localhost8080/hello,它将返回以下消息:

Hello Jib Maven Plugin! From host: gunter-Latitude-5590/127.0.1.1  

  1. 设置Jib和Docker Hub


在本节中,我们将添加Jib Maven插件,并确保成功连接到Docker Hub注册中心。要使其正常工作是相当困难的,主要是由于缺乏文档。Jib官方文档对安全身份验证方法相当模糊。大多数示例都包括向pom或Maven配置文件中添加纯文本凭证。但这不是我们想要的。我们想要一种通过Docker Credential Helper连接到Docker Hub的安全方法。

为了测试连接,我们将Jib Maven插件添加到pom中并对其进行配置,以便检索基础镜像和将该镜像推送到Docker Hub。
  
com.google.cloud.tools
jib-maven-plugin
1.8.0



  openjdk:11.0.5-jre


  docker.io/${docker.image.prefix}/${project.artifactId}
  pass





from标签包含我们的基础镜像,就像Dockerfile中的 FROM语句。 to标签包含我们想要推送的镜像。 ${docker.image.prefix}设置为 mydeveloperplanet(我们的Docker Hub账号),你需要对应修改为你自己的账号。 ${project.artifactId}包含 1.0-SNAPSHOT版本。为了使用Credential Helper,我们将标签 credHelper设置为 pass

在开始之前,如果你尚未设置GPG密钥,则需要设置它,请参阅 Ubuntu帮助页面
$ gpg --gen-key  


为方便使用,你可以将生成的密钥作为环境变量添加到配置文件中。将以下行添加到你的 .profile文件中,注意替换 Your_GPG_Key内容。
export GPGKEY=Your_GPG_Key  


执行source以使环境变量生效。
$ source .profile  


你也可以选择将你的密钥发送到Ubuntu密钥服务器,但不是必要的。
$ gpg --send-keys --keyserver keyserver.ubuntu.com $GPGKEY  


安装 pass并使用你的GPG密钥初始化密码存储。
$ sudo apt install pass  
$ pass init Your_GPG_Key
mkdir: created directory '/home/gunter/.password-store/'
Password store initialized for My Password Storage Key


接下来要做的是下载并解压缩Docker Credential Helper,并赋予可执行权限。
$ wget https://github.com/docker/docker-credential-helpers/releases/download/v0.6.3/docker-credential-pass-v0.6.3-amd64.tar.gz  
$ tar xvzf docker-credential-pass-v0.6.3-amd64.tar.gz
$ mv docker-credential-pass /usr/bin
$ chmod +x docker-credential-pass


Docker Credential Helper需要正确配置,而这部分文档是缺失的。

创建包含以下内容的 config.json文件。在文档中说明要添加内容 { "credStore": "pass" },但是使用此配置,Jib将无法连接到Docker Hub注册表。我们发现该Issue中提及到 credStore已不再支持Google Cloud Registry。
"credHelpers": {  
"https://index.docker.io/v1": "pass"
}


初始化Docker Credential Helper。当pass初始化并要求输入密码时输入密码。
$ pass insert docker-credential-helpers/docker-pass-initialized-check  
mkdir: created directory '/home/gunter/.password-store/docker-credential-helpers'
Enter password for docker-credential-helpers/docker-pass-initialized-check:
Retype password for docker-credential-helpers/docker-pass-initialized-check:


检查密码设置是否正确:
$ pass show docker-credential-helpers/docker-pass-initialized-check  
pass is initialized


使用你的Docker凭证登陆。这里会出现警告提示你的密码以非加密方式保存在 config.json文件中。不清楚为何会出现该提示,因为凭证已经是以加密形式保存在 config.json中。
$ 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 https://hub.docker.com to create one.
Username: your_user_name
Password: 
WARNING! Your password will be stored unencrypted in /home/gunter/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded


从现在开始, docker login无需输入凭证即可执行。
$ docker login  
Authenticating with existing credentials...
WARNING! Your password will be stored unencrypted in /home/gunter/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded


你可以使用 docker logout再次注销
$ docker logout  
Removing login credentials for https://index.docker.io/v1/


确保你已再次登陆,然后运行Maven Jib构建命令:
$ mvn compile jib:build  


镜像会成功被构建并推送到Docker Hub。构建过程中将引发两个警告:

Base image 'openjdk:11.0.5-jre' does not use a specific image digest - build may not be reproducible
这可以通过替换基础镜像 openjdk:11.0.5-jreopenjdk@sha256:b3e19d27caa8249aad6f90c6e987943d03e915bbf3a66bc1b7f994a4fed668f6(sha256格式)值来轻松解决。

The credential helper (docker-credential-pass) has nothing for server URL: https://index.docker.io/v1
这是一个奇怪的警告,因为此URL的凭据已解析并用于推送镜像。
  1. 为我们的应用程序配置Jib


现在我们已经以安全的方式配置了身份认证,我们可以继续为应用程序配置Jib Maven插件。我们在镜像中添加标签并指定主类。
  
docker.io/${docker.image.prefix}/${project.artifactId}
pass

${project.version}



com.mydeveloperplanet.myjibplanet.MyJibPlanetApplication



不要将标签 format和OCI值添加到容器配置中。Docker Hub尚未完全支持OCI,将会显示 An error occurred while loading the tags. Try reloading the page错误信息。

再次构建镜像并拉取Docker镜像:
$ docker pull mydeveloperplanet/myjibplanet  
Using default tag: latest
latest: Pulling from mydeveloperplanet/myjibplanet
844c33c7e6ea: Pull complete 
ada5d61ae65d: Pull complete 
f8427fdf4292: Pull complete 
a5217f27a28f: Pull complete 
176e83ebae4f: Pull complete 
800204250483: Pull complete 
492e142ab90b: Pull complete 
7c8e6198cd4b: Pull complete 
c49bb7f02774: Pull complete 
Digest: sha256:b7144bfdf6ee47d6b38914a84789ef9f7e2117320080b28ce39c385ee399a0c8
Status: Downloaded newer image for mydeveloperplanet/myjibplanet:latest
docker.io/mydeveloperplanet/myjibplanet:latest


运行该镜像并映射8080端口:
$ docker run -p 127.0.0.1:8080:8080/tcp mydeveloperplanet/myjibplanet  
...
2019-12-25 09:57:13.196 INFO 1 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2019-12-25 09:57:13.205 INFO 1 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 9 ms


查看Docker容器列表:
$ docker ps  
CONTAINER ID    IMAGE                           COMMAND                  CREATED                 STATUS           PORTS                      NAMES
c05e431b0bd1    mydeveloperplanet/myjibplanet   "java -cp /app/resou…"   13 seconds ago    Up 12 seconds    127.0.0.1:8080->8080/tcp   recursing_meninsky


我们只需要检索Docker容器的IP地址。
$ docker inspect c05e431b0bd1  
...
"NetworkSettings": {
...
"IPAddress": "172.17.0.2",
...
}
...


现在可以使用 http://172.17.0.2:8080/hello调用我们应用程序的URL 。

这将向我们返回欢迎信息:
Hello Jib Maven Plugin! From host: c05e431b0bd1/172.17.0.2  


我们还有一个问题要解决:我们的应用程序在Docker容器中以root用户运行。由于安全性原因,这不是我们想要的。首先,我们将检查Docker容器中有哪些用户可用:
$ docker exec -it -u root c05e431b0bd1 cat /etc/passwd  
...
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
...


可发现该Docker容器包含了一个 nobody用户,我们可以用它来运行应用程序。添加 user标签到pom文件中:
  
com.mydeveloperplanet.myjibplanet.MyJibPlanetApplication
nobody



再次构建镜像,拉取并运行它。使用 docker inspect检验是否是使用 nobody作为用户。
...  
"Config": {
"Hostname": "76b3afaca3af",
"Domainname": "",
"User": "nobody",
...
}
...


在pom中,我们还添加了Spring Actuator。没有方法通过Jib添加Docker运行状态检查,必须通过在Kubernetes配置中的存活探针和就绪探针来解决,另请参阅此 issue
  1. 结论


我们尝试了使用Jib Maven插件来创建我们的Docker镜像。为Docker Hub注册表配置凭据非常困难,但是一旦设置好了,这个插件就非常容易使用了。除此之外,不需要Docker守护进程,也不需要编写单独的Dockerfile。最后不能不提的是,它确实非常快。我们肯定会在不久的将来使用这个插件。

相关链接:
- Docker镜像和容器
- 使用Docker和Jib容器化Spring Boot应用程序

【原文链接】: Create Fast and Easy Docker Images With Jib 翻译:冯旭松

相关 [jib docker 镜像] 推荐:

使用Jib快速简便地创建Docker镜像

- - DockOne.io
在本文中,我们将看看Jib,它是Google提供的一个工具,可以轻松快速地创建Docker镜像. 无需创建Dockerfile文件,也无需安装Docker守护进程,Jib可直接使用. 到目前为止,我们一直使用来自Spotify的 dockerfile-maven-plugin来构建和推送Docker镜像.

Docker镜像仓库Harbor

- - 灰狐博客
Habor是由VMWare公司开源的容器镜像仓库. Habor是在Docker Registry上进行了相应的企业级扩展,这些企业级特性包括:管理用户界面,基于角色的访问控制 ,AD/LDAP集成以及审计日志等. 京东使用了Harbor搭建了自己的私有Dockr镜像仓库. 用Harbor实现容器镜像仓库的管理和运维.

几款 Shadowsocks 的 Docker 镜像

- - Shadowsocks非官方网站
Docker 是一个开放源代码软件项目,让应用程序布署在软件容器下的工作可以自动化进行,借此在 Linux 操作系统上,提供一个额外的软件抽象层,以及操作系统层虚拟化的自动管理机制. Docker 利用 Linux 核心中的资源分脱机制,例如 cgroups,以及 Linux 核心名字空间(name space),来创建独立的软件容器(containers).

解决Docker镜像爆满的问题

- - holmofy
使用过docker的人都知道,在正常情况下. 我们使用multi-stage构建利用docker镜像缓存机制,可以加快构建速度. 但是缓存的镜像一多,没有及时释放磁盘空间,磁盘就容易爆满. 容量 已用 可用 已用% 挂载点. 如果每次构建完手动 docker rmi又达不到加快构建速度的效果.

mdblog/Docker镜像中心.md at master · downgoon/mdblog · GitHub

- -
手把手体验DockerHelloWorld. Docker Image: 它是用来运行出. Docker Container的. nodejs image等. Docker Registry Mirrors: 为了让大家方便使用,不需要每个人都去制作. Docker Image,我们可以分享:你制作一个.

Docker 最佳实践:构建最小镜像

- - IT瘾-dev
镜像大小其实是衡量我们容器打包技术的重要指标,我们应该在不影响应用正常运行的情况下,尽量让我们的容器镜像变得更小,这样,不管是从安全还是维护效率角度来讲,都是最佳实践. 本文我们从两种情况阐述我们的问题和解决方案,我们从实现我们的application的编程语言角度,按照语言是解释型还是编译型语言来演示如何解决容器镜像体积大的问题.

docker/kubernetes国内源/镜像源解决方式

- - Xinkun Blog
最近在使用kubeadm时,被各种连接不上搞到崩溃. 这里统一整理了国内的一些镜像源,apt源,kubeadm源等,以便查阅. Azure China提供了目前用过的质量最好的镜像源. 而且都支持匿名拉取,也就是不需要登录. 这里,我开发了一个小的脚本azk8spull,这个脚本可以自动根据镜像名称进行解析,转换为azure的mirror镜像源域名.

Docker 最佳实践:5 个方法精简镜像

- - IT瘾-dev
本文记录了精简Docker镜像尺寸的必要性及好处. 上篇文章回顾: HBase实战:记一次Safepoint导致长时间STW的踩坑之旅. 精简Docker镜像的好处很多,不仅可以节省存储空间和带宽,还能减少安全隐患. 优化镜像大小的手段多种多样,因服务所使用的基础开发语言不同而有差异. 本文将介绍精简Docker镜像的几种通用方法.

Docker镜像优化:如何从1.16GB优化到22.4MB

- - DockOne.io
图源  www.docker.com. Docker是软件开发者和系统管理员用容器构建、运行和共享应用程序的平台. 一个 容器是一个运行在隔离环境中、拥有自己的文件系统上的进程;这个文件系统是使用 docker镜像构建的. 镜像文件包括运行应用程序所需的一切(编译后的代码、依赖关系、库等). 镜像可以使用一个名为 Dockerfile的文件来定义.

Docker 多平台构建指南:构建 WebAssembly 镜像

- - Jimmy Song - 专注于探索后 Kubernetes 时代的云原生新范式 – 博客
Docker 多平台构建是一种用于构建 Docker 镜像以在多种 CPU 架构和操作系统上运行的技术. 它可以让用户在一个 Dockerfile 中定义一个通用的构建过程,然后使用 Docker CLI 命令将其构建为多个不同平台的镜像. 这些镜像可以在不同的计算机、云平台和容器编排系统上运行,从而为用户提供更广泛的部署选项.