使用Docker和Buildah创建并部署Java 8运行时容器镜像

本文详细介绍了如何基于RHEL系统构建Java 8运行时容器镜像,包括Dockerfile编写、使用Docker/Buildah构建镜像、推送到Quay仓库,以及在OpenShift平台上的完整部署流程。

创建和部署Java 8运行时容器镜像

Java运行时环境应能够运行已编译的源代码,而开发工具包(如OpenJDK)则包含编译和运行源代码所需的所有库/二进制文件。本质上,后者是运行时环境的超集。关于OpenJDK支持和生命周期的更多详细信息可在此处找到。

红帽提供并支持包含OpenJDK的Java 8和11容器镜像。更多详情请参阅此处。如果您使用红帽中间件,附带的s2i镜像也适用于部署,例如在红帽OpenShift容器平台上。

请注意,红帽仅提供基于OpenJDK的Java 8和11镜像。尽管如此,开发者肯定会有需要创建自己的Java运行时镜像的情况。例如,可能出于最小化运行时镜像存储空间的考虑。另一方面,还需要手动设置许多库(如Jolokio或Hawkular)甚至安全参数。如果您不想深入这些细节,我建议使用红帽提供的OpenJDK容器镜像。

在本文中,我们将:

  • 使用Docker和Buildah构建镜像。
  • 在本地主机上使用Docker和Podman运行该镜像。
  • 将镜像推送到Quay。
  • 最后,通过将流导入OpenShift来运行我们的应用。

本文适用于OpenShift 3.11和4.0 beta。让我们直接开始。

设置

为了使用我们的镜像并了解其工作原理,我们将使用一个Web应用作为捆绑包的一部分。最近Microprofile.io推出了MicroProfile Starter测试版,它通过创建可下载的包帮助您开始使用MicroProfile。前往Microprofile.io获取带有Thorntail V2的MicroProfile包。

点击下载按钮获取归档文件。

在我的红帽企业Linux(RHEL)机器上,我首先创建一个临时目录(例如demoapp),并将下载的工件解压到其中。

在我的临时目录中,运行:

1
$ mvn clean compile package

现在我们应该有一个构建好的演示应用,其中包含一个fat jar,可以调用它来运行Thorntail。

将target/demo-thorntail.jar复制到临时目录。

以下是带有各层注释的Dockerfile。该文件的源代码也可以在GitHub上找到。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
# Java 8运行时示例
# 官方红帽注册表和基础镜像
FROM registry.access.redhat.com/rhel7-minimal
USER root
# 安装Java运行时
RUN microdnf --enablerepo=rhel-7-server-rpms \
install java-1.8.0-openjdk --nodocs ;\
microdnf clean all
# 设置JAVA_HOME变量以明确Java的位置
ENV JAVA_HOME /etc/alternatives/jre
# 我的应用目录
RUN mkdir -p /app
# 暴露要监听的端口
EXPOSE 8080
# 复制MicroProfile启动器应用
COPY demo-thorntail.jar /app/
# 从源复制脚本;run-java.sh具有特定参数,用于在容器中从命令行运行Thorntail应用。关于脚本的更多信息可在https://github.com/sshaaf/rhel7-jre-image/blob/master/run-java.sh找到
COPY run-java.sh /app/
# 设置脚本运行权限
RUN chmod 755 /app/run-java.sh
# 最后,运行脚本
CMD [ "/app/run-java.sh" ]

现在我们有了Dockerfile的详细信息,让我们继续构建镜像。

需要注意的重要一点是,OpenJDK Java运行时打包为“java-1.8.0-openjdk”;这不包括编译器和-devel包中的其他开发库。

上述Dockerfile基于RHEL构建,这意味着我不需要使用subscription-manager注册,因为主机已经附加了订阅。

下面您将找到两种构建方法。如果您像我一样运行RHEL,可以选择两种二进制文件中的任何一种进行部署。两者都应该在rhel7-server-extras-rpms中。

您可以这样启用extras仓库:

1
# subscription-manager repos --enable rhel-7-server-extras-rpms 

本地构建和运行镜像

使用docker构建镜像:

1
$ docker build -t quay.io/sshaaf/rhel7-jre8-mpdemo:latest .

使用docker运行镜像,并将localhost:8080指向容器端口8080:

1
$ docker run -d -t -p 8080:8080 -i quay.io/sshaaf/rhel7-jre8-mpdemo:latest

我们也可以使用buildah命令,它有助于从工作容器、Dockerfile或从头开始创建容器镜像。生成的镜像符合OCI标准,因此它们可以在任何符合OCI运行时规范(如Docker和CRI-O)的运行时上工作。

使用buildah构建:

1
$ buildah bud -t rhel7-jre8-mpdemo .

使用buildah创建容器:

1
$ buildah from rhel7-jre8-mpdemo

现在我们也可以使用Podman运行容器,它通过提供类似于Docker命令行的体验来补充Buildah和Skopeo:允许用户运行独立(非编排的)容器。而且Podman不需要守护进程来运行容器和pod。Podman也是extras通道的一部分,以下命令应该运行容器。

1
$ podman run -d -t -p 8080:8080 -i quay.io/sshaaf/rhel7-jre8-mpdemo:latest

关于Podman的更多详细信息可以在《无守护进程的容器:RHEL 7.6和RHEL 8 Beta中的Podman和Buildah》以及《Docker用户的Podman和Buildah》中找到。

现在我们有了一个镜像,我们也希望将其部署到OpenShift并测试我们的应用。为此,我们需要oc客户端库。我有自己的集群设置;您可以选择使用红帽容器开发工具包(CDK)/minishift、红帽OpenShift Online或您自己的集群。过程应该相同。

部署到OpenShift

要部署到OpenShift,我们需要以下一些构造:

  • 为我们新创建的容器镜像创建一个镜像流
  • OpenShift的部署配置
  • 服务和路由配置

镜像流

要创建镜像流,我的OpenShift集群应该能够从某个地方拉取容器镜像。到目前为止,镜像一直驻留在我自己的机器上。让我们将其推送到Quay。红帽Quay容器和应用注册表提供在任何基础设施上安全存储、分发和部署容器。它可作为独立组件或与OpenShift结合使用。

首先我需要登录Quay,我可以这样做:

1
$ docker login -u="sshaaf" -p="XXXX" quay.io

然后将我们新创建的镜像推送到Quay:

1
$ docker push quay.io/sshaaf/rhel7-jre8-mpdemo

在部署之前,让我们看一下构造。对于急切的人,您可以跳过部署模板的细节,直接转到项目创建。

现在我们有了镜像,我们定义我们的流:

1
2
3
4
5
6
- apiVersion: v1
  kind: ImageStream
  metadata:
    name: rhel7-jre8-mpdemo
  spec:
    dockerImageRepository: quay.io/sshaaf/rhel7-jre8-mpdemo

再次,您可以看到上面我们直接指向我们在Quay.io的镜像仓库。

部署配置

接下来是部署配置,它设置我们的pod和触发器,并指向我们新创建的流等。

如果您是容器和OpenShift部署的新手,您可能想查看这本有用的电子书。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
- apiVersion: v1
  kind: DeploymentConfig
  metadata:
    name: rhel7-jre8-mpdemo
  spec:
    template:
      metadata:
        labels:
          name: rhel7-jre8-mpdemo
      spec:
        containers:
        - image: quay.io/sshaaf/rhel7-jre8-mpdemo:latest
          name: rhel7-jre8-mpdemo
          ports:
          - containerPort: 8080
            protocol: TCP
    replicas: 1
    triggers:
    - type: ConfigChange
    - imageChangeParams:
        automatic: true
        containerNames:
        - rhel7-jre8-mpdemo
        from:
          kind: ImageStreamTag
          name: rhel7-jre8-mpdemo:latest
      type: ImageChange

服务

现在我们有了部署,我们还希望定义一个服务,以确保内部负载平衡、pod的IP地址等。如果我们希望新创建的应用最终暴露给外部流量,服务很重要。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
- apiVersion: v1
  kind: Service
  metadata:
    name: rhel7-jre8-mpdemo
  spec:
    ports:
    - name: 8080-tcp
      port: 8080
      protocol: TCP
      targetPort: 8080
    selector:
      deploymentconfig: rhel7-jre8-mpdemo

路由

我们部署的最后一部分是路由。是时候用路由将我们的应用暴露给外部世界了。我们可以定义此路由指向哪个内部服务以及目标端口。OpenShift将给它一个友好的URL,我们将能够指向并看到我们新创建的基于Java 8运行时的部署上运行的MicroProfile应用。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
- apiVersion: v1
  kind: Route
  metadata:
    name: rhel7-jre8-mpdemo
  spec:
    port:
      targetPort: 8080-tcp
    to:
      kind: Service
      name: rhel7-jre8-mpdemo
      weight: 100

上述的完整模板可以在GitHub上找到。

让我们也在OpenShift中创建一个项目:

1
$ oc new-project jredemos

现在处理模板并在OpenShift上获得我们的Java 8运行时演示。要这样做,运行以下命令:

1
$ oc process -f deployment.yaml  | oc create -f -

这将创建整个部署,您应该能够看到类似这样的内容。

现在运行以下命令:

1
$ oc get routes

这将显示路由,如下所示。

让我们将路由复制到浏览器中,我们应该看到部署在RHEL 7上运行的Web应用,使用Java 8运行时。(下面的地址仅用于测试集群,每个集群会有所不同。)

1
http://rhel7-jre8-mpdemo-jredemos.apps.cluster-1fda.1fda.openshiftworkshop.com/

总结

我们已成功使用Docker或Buildah构建和创建了Java 8运行时容器镜像。请注意以下事项:

重要的是要注意,此镜像旨在展示如何完成此操作;它不包括如Jolokio或Hawkular等可能对部署必要的内容。

此外,它没有考虑在容器中运行Java应用所需的参数,这些在Rafael Benevides的文章中有详细解释。

而且,当部署您自己的容器镜像时,如果您运行红帽的OpenJDK构建,请始终检查支持和生命周期政策。

然后,我们使用来自MicroProfile Starter测试版的基本MicroProfile演示应用将其部署到OpenShift。

如果您正在寻找创建更全面的演示应用,以下是很好的资源:

  • 使用Azure Open Service Broker在Microsoft Azure上部署MicroProfile应用
  • 这里的MicroProfile电子书

本文的完整资源可以在这里找到。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计