Linux 容器是用于以下方面的强大解决方案:
软件标准化
加速开发和测试
在应用程序的整个生命周期中进行有效的资源管理
在这里,我们将提供一个分步指南,介绍如何使用用于云部署的应用程序构建 Linux 容器。例如,我们将使用 BellSoft 的开源 Alpaquita Stream 容器托管在 Docker Hub 容器镜像库上。
要完成本指南,您必须安装并运行 docker 守护程序。我们将解释如何从仓库中拉取选定的容器镜像,并使用 Java、Python、基于 GCC 的应用程序和原生镜像运行它。您可以使用自己的应用程序或创建示例项目,如下所示。
用于 Java 应用程序的 Linux 容器
拉取 Docker 镜像
若要创建容器,请运行:
$ docker image pull docker bellsoft/:<image_tag>
使用以下命令启动容器:
$ docker run -it --rm bellsoft/:<image_tag>
或者,使用组合命令:
$ docker container run --rm -it bellsoft/:<image_tag>
假设您选择了 Liberica 运行时容器,其中包括基于 musl 的 Alpaquita Stream(也提供基于 glibc 的选项)和 Liberica JDK Lite 11。命令如下:
$ docker container run --rm -it bellsoft/liberica-runtime-container:jdk-11.0.17-musl
请注意,拉取映像不是强制性的,但如果您不想在每次重复生成过程时都拉取映像,则建议拉取映像。
编写 Dockerfile 并运行应用
通过使用 JRE 镜像而不是完整的 JDK 来运行 Java 应用程序,可以将容器大小减少约 50%。
因此,在应用程序的 Dockerfile 中,我们将指定两个镜像 — 一个用于构建应用程序,另一个用于运行它。我们将使用一个标准的 Spring Petclinic 项目作为示例。
编写以下 Dockerfile:
FROM bellsoft/liberica-runtime-container:jdk-17-stream-musl as builder
WORKDIR /home/myapp
RUN apk add git
RUN git clone https://github.com/spring-projects/spring-petclinic.git
RUN cd spring-petclinic && ./mvnw package
FROM bellsoft/liberica-runtime-container:jre-17-stream-musl
WORKDIR /home/myapp
COPY --from=builder /home/myapp/spring-petclinic/target .
CMD ["java", "-jar", "spring-petclinic-3.0.0-SNAPSHOT.jar"]
构建应用映像:
$ docker build --progress plain -t javaappimage .
现在,运行映像:
docker run -p 8080:8080 javaappimage
做!打开浏览器以访问 Petclinic 应用程序。
用于本机映像的 Linux 容器
拉取 Docker 镜像
我们使用 Liberica Native Image Kit (NIK) 提供图像,这是一个基于 GraalVM 的开源实用程序,用于将 JVM 应用程序转换为本机可执行文件。使用本机映像或考虑将该技术集成到其项目中的开发人员可以拉取以下映像:
$ docker container run --rm -it bellsoft/liberica-native-image-kit-container:jdk-11-nik-21.3.3-stream-musl
或者您认为合适的任何图像,具体取决于 JDK 和 NIK 版本以及 libc 实现(BellSoft 优化的 musl 或 glibc)。
创建原生镜像
首先,让我们编写一个简单的应用程序,将其转换为本机可执行文件。或者,使用您自己的项目。
public class Example {
public static void main(String[] args) {
String str = "Native Image is awesome";
String reversed = reverseString(str);
System.out.println("The reversed string is: " + reversed);
}
public static String reverseString(String str) {
if (str.isEmpty())
return str;
return reverseString(str.substring(1)) + str.charAt(0);
}
}
Dockerfile 必须包含以下信息:
FROM bellsoft/liberica-native-image-kit-container:jdk-11-nik-21.3.3-stream-musl
WORKDIR /home/myapp
COPY Example.java /home/myapp
RUN javac Example.java
RUN native-image Example
FROM bellsoft/alpaquita-linux-base:stream-musl
WORKDIR /home/myapp
COPY --from=0 /home/myapp/example.
CMD ["./example"]
进入应用目录,运行:
$ docker build.
以下是构建映像的过程:
[+] Building 370.9s (14/14) FINISHED
=> [internal] load build definition from Dockerfile 0.1s
=> => transferring dockerfile: 357B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for docker.io/bellsoft/alpaquita-linux-base:stream-musl 0.0s
=> [internal] load metadata for docker.io/bellsoft/liberica-native-image-kit-container:jdk-11-nik-21.3.3-stream-musl 4.8s
=> [internal] load build context 0.1s
=> => transferring context: 454B 0.0s
=> [stage-1 1/3] FROM docker.io/bellsoft/alpaquita-linux-base:stream-musl 0.1s
=> [stage-0 1/5] FROM docker.io/bellsoft/liberica-native-image-kit-container:jdk-11-nik-21.3.3-stream-musl@sha256:3c5a09abb2559cf0 293.4s
=> => resolve docker.io/bellsoft/liberica-native-image-kit-container:jdk-11-nik-21.3.3-stream-musl@sha256:3c5a09abb2559cf04e7527b81b 0.0s
=> => sha256:3c5a09abb2559cf04e7527b81bfa123ca52592ef2bce1512d837fbd0336440e9 951B / 951B 0.0s
=> => sha256:79998423fd609bb42881f8eb6721aa22451cdb46363b4fc5f49fc50390759138 2.72kB / 2.72kB 0.0s
=> => sha256:4f4293381c77f4d905cfa2034b4fe3adff4515508d08b0093a8db16728ba4879 3.34MB / 3.34MB 7.1s
=> => sha256:c3263c13b6f5c1ba5a386dc02047af54fdeefc8a92538ffc973915cdb0de9881 532.42kB / 532.42kB 7.0s
=> => sha256:f6c678d36153293dc6b01a73696b4ef60a9ecb44e62da72fd96b31e679f1ed2d 323.95MB / 323.95MB 284.4s
=> => extracting sha256:4f4293381c77f4d905cfa2034b4fe3adff4515508d08b0093a8db16728ba4879 0.1s
=> => extracting sha256:c3263c13b6f5c1ba5a386dc02047af54fdeefc8a92538ffc973915cdb0de9881 0.0s
=> => extracting sha256:f6c678d36153293dc6b01a73696b4ef60a9ecb44e62da72fd96b31e679f1ed2d 8.8s
=> [stage-1 2/3] WORKDIR /home/myapp 0.0s
=> [stage-0 2/5] WORKDIR /home/myapp 0.5s
=> [stage-0 3/5] COPY Example.java /home/myapp 0.0s
=> [stage-0 4/5] RUN javac Example.java 1.0s
=> [stage-0 5/5] RUN native-image Example 70.6s
=> [stage-1 3/3] COPY --from=0 /home/myapp/example . 0.1s
=> exporting to image 0.1s
=> => exporting layers 0.1s
=> => writing image sha256:f03df73515790f3ffe210fc139d5a0752c088fd242f571e19d111377f7703c6a 0.0s
验证是否已创建映像。
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
<none> <none> f03df7351579 About a minute ago 19MB
使用有意义的名称标记新生成的映像。
$ docker tag f03df7351579 bellsoft-nik:example-musl
$ docker run -it --rm f03df7351579
The reversed string is: emosewa si egamI evitaN
适用于 Python 的 Linux 容器
BellSoft 为 Alpaquita Linux 镜像提供 Python 3.10 和基本 Python 实用程序(pip、setuptools、wheel)。有两个 libc 选项(BellSoft 的 musl perf 和 glibc)可用。
首先,让我们编写一个简单的烧瓶应用程序:
$ cat requirements.txt
flask
markup
jinja2
$ cat test.py
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello, Docker!'
现在,编写一个包含以下内容的 Dockerfile:
FROM bellsoft/alpaquita-linux-python:3.10-stream-musl
WORKDIR /myapp
COPY requirements.txt .
RUN pip3 install -r requirements.txt
COPY test.py .
ENV PATH=/root/.local:$PATH
CMD ["python3", "-m" , "flask", "--app", "./test.py", "run", "--host=0.0.0.0"]
最后,使用此 Dockerfile 构建 Docker 镜像:
$ docker build -t flaskimage .
构建映像的过程将开始:
[+] Building 1.3s (10/10) FINISHED
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 38B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for docker.io/bellsoft/alpaquita-linux-python:3.10-stream-musl 1.2s
=> [internal] load build context 0.0s
=> => transferring context: 63B 0.0s
=> [1/5] FROM docker.io/bellsoft/alpaquita-linux-python:3.10-stream-musl@sha256:2d5656810f19f028b5992cbfcdd3e833cfb1839b5b6078b5a2a1 0.0s
=> CACHED [2/5] WORKDIR /myapp 0.0s
=> CACHED [3/5] COPY requirements.txt . 0.0s
=> CACHED [4/5] RUN pip3 install -r requirements.txt 0.0s
=> CACHED [5/5] COPY test.py . 0.0s
=> exporting to image 0.0s
=> => exporting layers 0.0s
=> => writing image sha256:9f9335b2d7339a656e1b860e0d0d293c528e06aa21d0be41ee46b67fbb9e9f12 0.0s
=> => naming to docker.io/library/flaskimage 0.0s
您现在可以在 Docker 中运行 Python 应用程序:
$ docker run -d -p 6000:5000 flaskimage
630ae5583186bf0a5d99c97bca68b41401cf6b4b1d22f770fa4f757d23dc240e
$ curl http://127.0.0.1:6000
Hello, Docker!
适用于 GCC 的 Linux 容器
BellSoft 为 Alpaquita Linux 镜像提供 GCC 编译器 12.2 版、工具和用于 C/C++ 开发的库。有两个 libc 选项(BellSoft 的 musl perf 和 glibc)可用。
我们将使用一个 C++ 示例来展示我们的 GCC 镜像可用于构建 C++ 和 C 项目。
我们的 GCC 映像包括以下包,这些包不是强制性的,但可能有助于构建:
C++
autoconf automake bash binutils bzip2 bzip2-dev curl curl-dev diffutils file findutils fortify-headers g++ gawk gcc gdb git grep hexdump jpeg-dev krb5-dev libevent-dev libffi-dev libjpeg-turbo-dev libpng-dev libtool libxml2-dev libxslt-dev make ncurses-dev openssl-dev patch pkgconf readline-dev sed subversion unzip xz xz-dev yaml-dev zlib-dev
首先,让我们编写一个简单的 C++ 程序:
$ cat hello.cpp
#include <iostream>
using namespace std;
int main()
{
cout << "Hello World" << endl;
return 0;
在 Dockerfile 中,指定用于构建应用的 Alpaquita 镜像,以及用于进一步处理容器的基础镜像:
FROM bellsoft/alpaquita-linux-gcc:12.2-stream-musl as builder
WORKDIR /home/myapp
COPY hello.cpp .
RUN g++ hello.cpp -o hello -static
FROM bellsoft/alpaquita-linux-base:stream-musl
WORKDIR /home/myapp
COPY --from=builder /home/myapp/hello .
CMD ["./hello"]
现在,构建 Docker 容器镜像:
$ docker build -t cppappimage .
Run it with the following command:
$ docker run --rm cppappimage
Hello World
结论
在本文中,我们学习了如何使用 Java、Python、C/C++ 应用程序和 Native Image 构建 Linux 容器。我们使用 Alpaquita Stream 作为基础 Linux 发行版。
如您所见,使用 Alpaquita 进行容器化既快速又轻松,最后,您将获得一个高性能的微容器,可以按原样使用或进一步配置为特定目的。