Создание минимального контейнера для программы Go

Я хочу создать крошечный образ контейнера с нуля, используя Buildah для запуска приложения Go. Помимо самого приложения, какие другие библиотеки и т. Д. Должны быть включены. Я думаю, что glibc нужен - есть что-нибудь еще?

Итак, в заключение, я думаю, что я спрашиваю: "Каковы все внешние зависимости, которые нужны скомпилированному приложению Go в Linux?"

3 ответа

Решение

@ Дэйв С дал информацию, чтобы правильно ответить на это. Использование 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 МБ для простого микросервиса! Нет никаких дополнительных файлов, чтобы беспокоиться об уязвимостях и т. Д.

У меня есть небольшой дефект, который я не могу обработать на точках входа, поэтому я перезаписываю точку входа при запуске, но чтобы проверить ее выполнение:

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

Затем просто введите следующее в сеансе терминала:

curl http://localhost:8000

Так что спасибо Дейв C!

Я знаю, что это довольно поздний ответ, но он рассказывает, как создать самый тонкий образ для программ Golang. Он основан на вопросе. Развертывание с использованием образа с нуля не запускается.

Хитрость заключается в том, чтобы создать статически связанный исполняемый файл и поместить его в пустой образ с именемscratch. Образ содержит только один файл, то есть исполняемый файл. Это минимально возможное изображение.

Докер-файл:

      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

Всего один файл, минимальное изображение.

Я предполагаю, что вы включили зависимости приложения в свой образ докера.

Вам не потребуется какая-либо внешняя зависимость для построения образа докера. Достаточно просто базового образа из 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
Другие вопросы по тегам