为Go语言程序构建最小容器

h6my8fg2  于 2022-12-07  发布在  Go
关注(0)|答案(3)|浏览(110)

我想使用Buildah从头开始构建一个小容器映像来运行Go应用。除了应用本身,还需要包括哪些其他库等。我认为需要glibc-还有其他东西吗?
所以总的来说,我想我在问“编译后的Go应用程序在Linux上需要哪些外部依赖项?”

ftf50wuq

ftf50wuq1#

@Dave C给出了正确回答这个问题的信息。使用ldd和测试应用程序返回:

[bryon@localhost resttest]$ ldd restest
    linux-vdso.so.1 (0x00007fff139fe000)
    libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fbad6ce2000)
    libc.so.6 => /lib64/libc.so.6 (0x00007fbad691f000)
    /lib64/ld-linux-x86-64.so.2 (0x00007fbad6f02000)
[bryon@localhost resttest]$

因此,对于那些希望使用Buildah构建一个最小容器的人来说,生成它的BASH脚本看起来像这样:

#!/bin/bash
#
# Run this shell script after you have run the command: "buildah unshare"
#
git clone https://github.com/bryonbaker/resttest.git
cd resttest
go build restest.go

container=$(buildah from scratch)
mnt=$(buildah mount $container)
mkdir $mnt/bin
mkdir $mnt/lib64
buildah config --workingdir /bin $container
buildah copy $container restest /bin/restest
buildah copy $container /lib64/libpthread.so.0 /lib64
buildah copy $container /lib64/libc.so.6 /lib64
buildah copy $container /lib64/ld-linux-x86-64.so.2 /lib64
buildah config --port 8000 $container
#
# This step is not working properly.
# Need to run with podman -p 8000:8000 --entrypoint /bin/restest restest:latest
buildah config --entrypoint /bin/restest $container
buildah commit --format docker $container restest:latest

**这会为简单的微服务生成一个14 MB的容器!**没有其他文件需要担心漏洞等。

我有一个小缺陷,我不能在入口点上工作,所以我在开始时覆盖入口点,但要测试它的运行:

podman -p8000:8000 --entrypoint /bin/restest restest:latest

然后,只需在终端会话中键入以下内容:

curl http://localhost:8000

所以感谢戴夫C!

nhn9ugyo

nhn9ugyo2#

我知道这是一个很晚的答案,但它确实告诉了如何为Golang程序构建最瘦的映像。
诀窍是构建静态链接的可执行文件,并将其放入名为scratch的空映像中。该映像只包含一个文件,即完全相同的可执行文件。它是最小的映像。
Docker文件:

FROM golang:latest as builder
# The Dockerfile expects the source code of the application
# to reside in ./src/ directory
COPY src /src

WORKDIR /src

# Build statically linked file and strip debug information
# The Dockerfile expects the `main` package to be at the root of the module
RUN CGO_ENABLED=0 go build -ldflags="-extldflags=-static -s -w" -o executable

# scratch is an empty image
FROM scratch
# If you need /bin/sh and a few utilities, uncomment
# the following line. It increases the image by 5.5 MB
# FROM alpine:latest

COPY --from=builder /src/executable /executable
# copy other files if needed

ENTRYPOINT ["/executable"]

Dockerfile要求源代码位于src目录中

<project_root>
 |_ Dockerfile
 |_ src/
     |_ go.mod
     |_ package_main.go # file with `package main` and `func main()`
     |_ other source files

命令docker build ./ -t my-minimal-go生成名为my-minimal-go:latest的映像
为了证明它是最小图像,将其保存到TAR并研究其内容:

docker image save my-minimal-go:latest > my-minimal-go.tar
tar tf my-minimal-go.tar

内容类似于

84ebda22f9b32043fdcb7bb70c559f0ee91cac60b4b92f1ce424662afec6d4b9.json
e622775ad65d50bc0b9f30e6ce58ee7670f752c63c3ca70caba4f9165efdca80/
e622775ad65d50bc0b9f30e6ce58ee7670f752c63c3ca70caba4f9165efdca80/VERSION
e622775ad65d50bc0b9f30e6ce58ee7670f752c63c3ca70caba4f9165efdca80/json
e622775ad65d50bc0b9f30e6ce58ee7670f752c63c3ca70caba4f9165efdca80/layer.tar
manifest.json
repositories

并查看图像中的文件列表:

docker image save my-minimal-go:latest | tar x --wildcards '*layer.tar' -O | tar t

输出量:

executable

只有一个文件,最小的图像。

lg40wkob

lg40wkob3#

我假设您已经在Docker映像中包含了应用程序依赖项。
构建docker映像不需要任何外部依赖,只需要Go语言的基础映像就足以在Linux机器上构建和运行。

# Start from the latest Go base image
FROM golang:latest

# Set the Current Working Directory inside the container
WORKDIR /app

# Copy go mod and sum files
COPY go.mod go.sum ./

# Download all dependencies. Dependencies will be cached if the go.mod and go.sum files are not changed
RUN go mod download

相关问题