使用Jib快速简便地创建Docker镜像
source link: http://dockone.io/article/9934
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
在本文中,我们将看看Jib,它是Google提供的一个工具,可以轻松快速地创建Docker镜像。无需创建Dockerfile文件,也无需安装Docker守护进程,Jib可直接使用。
- 简介
到目前为止,我们一直使用来自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 Blog 和 GitHub
- 创建应用程序
第一步,我们将创建一个简单的Spring Boot应用程序。我们将Spring Actuator和Spring Web MVC依赖项添加到pom文件中。 Spring Actuator 将为我们提供添加运行状况检查的方法。
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
我们的应用程序由一个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
- 设置Jib和Docker Hub
在本节中,我们将添加Jib Maven插件,并确保成功连接到Docker Hub注册中心。要使其正常工作是相当困难的,主要是由于缺乏文档。Jib官方文档对安全身份验证方法相当模糊。大多数示例都包括向pom或Maven配置文件中添加纯文本凭证。但这不是我们想要的。我们想要一种通过Docker Credential Helper连接到Docker Hub的安全方法。
为了测试连接,我们将Jib Maven插件添加到pom中并对其进行配置,以便检索基础镜像和将该镜像推送到Docker Hub。
<plugin> <groupId>com.google.cloud.tools</groupId> <artifactId>jib-maven-plugin</artifactId> <version>1.8.0</version> <configuration> <!-- openjdk:11.0.5-jre --> <from> <image>openjdk:11.0.5-jre</image> </from> <to> <image>docker.io/${docker.image.prefix}/${project.artifactId}</image> <credHelper>pass</credHelper> </to> </configuration> </plugin>
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-jre
为 openjdk@sha256:b3e19d27caa8249aad6f90c6e987943d03e915bbf3a66bc1b7f994a4fed668f6
(sha256格式)值来轻松解决。
The credential helper (docker-credential-pass) has nothing for server URL: https://index.docker.io/v1
这是一个奇怪的警告,因为此URL的凭据已解析并用于推送镜像。
- 为我们的应用程序配置Jib
现在我们已经以安全的方式配置了身份认证,我们可以继续为应用程序配置Jib Maven插件。我们在镜像中添加标签并指定主类。
<to> <image>docker.io/${docker.image.prefix}/${project.artifactId}</image> <credHelper>pass</credHelper> <tags> <tag>${project.version}</tag> </tags> </to> <container> <mainClass>com.mydeveloperplanet.myjibplanet.MyJibPlanetApplication</mainClass> </container>
不要将标签 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文件中:
<container> <mainClass>com.mydeveloperplanet.myjibplanet.MyJibPlanetApplication</mainClass> <user>nobody</user> </container>
再次构建镜像,拉取并运行它。使用 docker inspect
检验是否是使用 nobody
作为用户。
... "Config": { "Hostname": "76b3afaca3af", "Domainname": "", "User": "nobody", ... } ...
在pom中,我们还添加了Spring Actuator。没有方法通过Jib添加Docker运行状态检查,必须通过在Kubernetes配置中的存活探针和就绪探针来解决,另请参阅此 issue
- 结论
我们尝试了使用Jib Maven插件来创建我们的Docker镜像。为Docker Hub注册表配置凭据非常困难,但是一旦设置好了,这个插件就非常容易使用了。除此之外,不需要Docker守护进程,也不需要编写单独的Dockerfile。最后不能不提的是,它确实非常快。我们肯定会在不久的将来使用这个插件。
相关链接:
- 使用Docker和Jib容器化Spring Boot应用程序
【原文链接】: Create Fast and Easy Docker Images With Jib 翻译:冯旭松
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK