Практика работы с докером Go Service — уменьшение размера образа

Go
Практика работы с докером Go Service — уменьшение размера образа

Сяо Чжан начал изучать язык го, начнем с сервисного релиза
Предыстория: Мне нужно опубликовать сервис GO, поэтому я начал редактировать dockerfile, и столкнулся с некоторыми проблемами.Я записал его здесь, давайте учиться вместе, документ был обновлен до публичного аккаунта заодно, вы можете добавить подписку , укажите неправильное место, 3Q

1 сказал впереди

Среда этой статьи основана на установленной службе Docker, сначала подготовьте среду Docker.

2 требования к образу докера

Давайте сначала подумаем о различных требованиях облачных приложений к среде выполнения:

Меньший размер. Для распределенной архитектуры микросервисов меньший размер означает меньшую пропускную способность загрузки и более высокую скорость загрузки дистрибутива.

Более быстрый запуск. Для традиционных монолитных приложений скорость запуска не является критическим показателем по сравнению с эффективностью работы. Причина в том, что эти приложения перезапускаются и выпускаются относительно редко. Однако для микросервисных приложений, требующих быстрой итерации и горизонтального расширения, более высокая скорость запуска означает более высокую эффективность доставки и более быстрый откат. Особенно, когда вам нужно опубликовать приложение сотнями копий, медленный запуск — это убийца времени. Для бессерверных приложений сквозная скорость холодного запуска еще более критична.Даже если базовая технология контейнеров может обеспечить готовность ресурсов за 100 миллисекунд, если приложение не может быть запущено в течение 500 мс, пользователи будут ощущать задержки доступа.

Занимайте меньше ресурсов: более низкое использование ресурсов во время выполнения означает более высокую плотность развертывания и более низкие вычислительные затраты.

(На этот раз мы обсуждаем, как уменьшить размер)

3 Создайте первую версию dockerfile

В этом dockerfile я в основном делаю следующие вещи

1 упаковка

Чтобы избавиться от влияния среды разработки на упаковку, я решил поместить процесс упаковки в dockerfile.

2 Старт

После завершения первого этапа упаковки мы можем непосредственно выполнить упакованный исполняемый файл.

Давайте взглянем на первую версию dockerfile.


    FROM golang
    MAINTAINER  天南
    WORKDIR /go/src/git.liebaopay.com/cm/cm_ad_free
    COPY . .
    RUN go build main.go
    EXPOSE 20020 20021 20022
    CMD ["./main","./config_local.ini",":20020",":20021",":20022"]

Давайте разберем этот dockerfile шаг за шагом:


    # 我们以官方golang镜像为基础镜像,官方golang的gopath默认在 /go/src中,所以可以直接把我们的项目放在此# # gopath中
    FROM golang
    # 指定维护者名称
    MAINTAINER  天南
    # 指定容器内的工作目录,不存在目录会自动创建
    WORKDIR /go/src/git.liebaopay.com/cm/cm_ad_free
    # 把dockerfile当前目录下的所有目录和文件都复制到上步指定的工作目录下
    COPY . .
    # 开始打包
    RUN go build main.go
    # 暴露服务端口
    EXPOSE 20020 20021 20022
    # 使用cmd执行命令,这个命令映射到容器内部的命令为  ./main ./config_local.ini :20020 :20021 :20022
    CMD ["./main","./config_local.ini",":20020",":20021",":20022"]

Создайте образ и начните


    docker build -t cm_ad_free_img_v1 .

Создайте образ и укажите имя тега как cm_ad_free_img_v1.

Как видно на рисунке ниже, процесс построения изображения

После успешной сборки образа запускаем службу контейнера

    docker run --name cm_ad_free_container_v1  -it  -p 9988:20022 cm_ad_free_img_v1

Следующая информация о параметрах


--name 指定容器名称

-t 让docker分配一个伪终端并绑定到容器的标准输入上

-i 则让容器的标准输入保持打开 

-d 会采用后台进行

-p 为端口映射,宿主机端口:容器端口

Проверьте сгенерированный образ докера

Я пойду! Это изображение занимает слишком много места, занимая 890 Мб, в чем причина? Получается, что когда мы собирали образ, мы ввели базовый образ golang и проделали много операций, в процессе которых было сгенерировано много временных файлов, и эти временные файлы не нужны во время выполнения.

4 Зеркальное похудение

Docker предоставляет Multi-stage Build (многоэтапную сборку), что позволяет добиться прореживания образа.

Мы можем просто разделить процесс создания dockerfile на два этапа:

  • Первый этап — это этап генерации исполняемых файлов с использованием базового образа golang и выполнения операции сборки.
  • Второй этап — это выполнение исполняемого файла.Фактически второй этап использует исполняемый файл и базовую конфигурацию первого этапа.Процесс выполнения не зависит от базового образа golang.

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

Посмотрим на вторую версию dockerfile, комментируя только команду добавления

    # 引入golang作为基础命令并起别名为 build
    FROM golang as build
    MAINTAINER  天南
    WORKDIR /go/src/git.liebaopay.com/cm/cm_ad_free
    COPY . .
    RUN go build main.go
    # 引入alphine最小linux镜像
    FROM alpine
    # 设置工作目录
    WORKDIR /data/app
    # 复制生成的可执行命令和一些配置文件
    COPY --from=build /go/src/git.liebaopay.com/cm/cm_ad_free/main .
    COPY --from=build /go/src/git.liebaopay.com/cm/cm_ad_free/config_local.ini .
    COPY --from=build /go/src/git.liebaopay.com/cm/cm_ad_free/logformat_local.xml .
    # !!! 注意,经测试发现alpine中缺少动态库,经查询后的解决方式为创建一个软链
    RUN  mkdir /lib64 && ln -s /lib/libc.musl-x86_64.so.1 /lib64/ld-linux-x86-64.so.2
    EXPOSE 20020 20021 20022
    CMD ["./main","./config_local.ini",":20020",":20021",":20022"]

После построения образа проверьте занятый диск и сразу уменьшите до 26Мб.Кажется, толстяк похудел, ха-ха

Создайте контейнер, успешно запустите службу и получайте удовольствие~