Go + Docker: Golang アプリケーションに最適な Docker イメージを作成する方法

WBOY
リリース: 2024-08-14 22:49:02
オリジナル
263 人が閲覧しました

自分のアプリケーションに適切な Docker イメージを作成しているかどうかについて疑問を抱いたことがない人はいないでしょうか?そうですね、私はこの質問を何度か受けましたが、ほとんどの場合、自分のやり方が正しいのか間違っているのかわかりませんでした。

この記事では、Go アプリケーション用に効率的で最適化された Docker イメージを作成するための高度な実践方法について説明します。アルパイン ベース イメージとスクラッチ ベース イメージの使用など、さまざまなアプローチを比較し、コード例とそれぞれの利点について説明します。分析パフォーマンス

プロジェクトの構造

まず、コンテナ化された Go アプリケーションの典型的なプロジェクト構造を確立しましょう。

例として、私は URL 短縮アプリであるこのアプリケーションを使用しています:


リーリー

1. Dockerfileの作成

ほとんどの人が知っていることですが、運用環境で「完全な」イメージを実行する必要はないということです。たとえば、すべてのパッケージ、ソース、拡張機能、および言語の SDK を備えた Ubuntu です。 SDK を使用してシステム内でアプリをビルドし、そのビルドのみを実行する、より小さく最適化されたイメージにそのビルドをコピーするだけです。そこで、

マルチステージが登場します。

マルチステージビルド

Dockerfile では、それぞれが FROM ステートメントで始まる複数のビルド ステージを定義できます。最初のステージは、コードのコンパイル、依存関係のインストール、テストの実行などに使用できます。後続の段階では、必要なアーティファクト (コンパイルされたバイナリなど) のみを最終イメージにコピーし、アプリケーションの実行に必要でないものはすべて破棄できます。


リーリー

うわー、ラファ、でも「この2枚の画像」で何をしているの?まず、イメージをビルダーとして使用し、ここでアプリケーションの実行可能ファイルを作成します。

最初のステージ (

ビルドステージ):

ベースイメージとして golang:1.22-alpine を使用します。
  • ソースコードをコンテナにコピーします。
  • 依存関係をダウンロードし、Go アプリケーションのバイナリをコンパイルします。
  • 次に、最初のステップで生成したこの実行可能ファイルを実行するだけの小さなイメージを使用します:

セカンドステージ (

ファイナルステージ):

ベースイメージとして alpine:latest を使用します。これははるかに小さく、バイナリを実行するために必要なツールのみが必要です。
  • 前のステージ (ビルダー) からコンパイルされたバイナリを新しいイメージにコピーします。
  • アプリケーション実行コマンドを定義します。
  • 実際に何が起こっているのかを確認したい場合は、Docker Desktop 内でイメージの階層を分析する可能性があります。内部ではあなたが何を使用しているかを見ることができます:

Go + Docker: Como criar as melhores imagens Docker para aplicações Golang今度は、生成したばかりのこの画像のサイズも分析できます。この場合、url-shortener:alpine は ~30mb:

リーリー
でもアルパインって何?

Alpine は、最小限で安全かつ軽量な Linux ディストリビューションであり、その効率性とシンプルさによりコンテナ環境で広く使用されています。他の重い Linux ディストリビューションのようなオーバーヘッドを発生させずに、スケーラブルなアプリケーションを構築するための強固な基盤を提供します。

アプリで Alpine を使用する利点のいくつかは、主に次の 3 つの柱に関連しています:

    柔軟性
  • : アルパイン イメージ (~5MB) は小さく、apk パッケージ マネージャーが含まれているため、必要な追加の依存関係をインストールできます。
  • 互換性
  • : 動的ライブラリをサポートし、外部ライブラリに依存するアプリケーションに適しています。
  • セキュリティ
  • : 定期的に更新される alpine にはセキュリティ パッチが含まれており、脆弱性のリスクを軽減します。
  • それでは、同じ SDK バージョン (この場合は golang:1.22-alpine) を使用した場合はどうなるでしょうか。私のアプリケーションのサイズはどれくらいですか?

リーリー
そうですね、この場合、最終的には最大 250 MB の画像になりました...アルパインと比較すると、純粋に最大 30 MB になりましたが、これはすでに大きな違いです。そしてそれをさらに改善することはできるのでしょうか?

答えは「はい」です。詳細を見ていきましょう

2. 高度な最適化

2.1 スクラッチ

Scratch は、Docker の特別で非常にシンプルなイメージです。実際、これは使用できる最も単純で空の基本イメージです。これには、オペレーティング システム、ライブラリ、ツールなど、まったく何も含まれていません。文字通り、空のコンテナです。

Essa abordagem minimalista traz benefícios significativos, especialmente em termos de segurança. Ao usar Scratch, você minimiza drasticamente a superfície de ataque, já que não há pacotes ou ferramentas adicionais que possam introduzir vulnerabilidades. Seu contêiner contém apenas o essencial para a execução do aplicativo, garantindo um ambiente imutável e previsível em qualquer situação.

# syntax=docker/dockerfile:1

# Build stage
FROM golang:1.22-alpine AS builder
WORKDIR /app
COPY . .
RUN go mod download
RUN go build -o url-shortener ./cmd

# Final stage with Scratch
FROM scratch
WORKDIR /app
COPY --from=builder /app/url-shortener .
CMD ["./url-shortener"]
ログイン後にコピー

E o resultado após criar as 3 imagens, nosso ranking de menor imagem ficou assim:

  1. url-shortener:scratch - 21.1MB
  2. url-shortener:alpine - 29.9MB
  3. url-shortener:golang-alpine - 251MB

O Scratch conseguiu baixar mais alguns megas no tamanho final de nossa aplicação. Isso impacta no tamanho de arquivos transferidos pela rede, hoje algumas empresas cobram pela banda que trafegamos dentro dos servidores, e também pode influenciar em nosso Horizontal Scaling da aplicação.

Deixei os 3 Dockerfiles dentro do repositório do github caso você queira testar em seu próprio pc ?

Quando devo usar o scratch

A resposta mais tranquila para essa é "quase sempre", uma dica de cara é: ele vai muito bem com linguagens como Go, Rust, ou C/C++. Mas qui estão alguns pontos para levar em consideração na hora de escolher se deve ou não usar o scratch:

  • Aplicações Statically Linked: Se sua aplicação não depende de bibliotecas dinâmicas e pode ser compilada de forma estática, Scratch é uma excelente escolha.
  • Segurança: Quando a segurança é uma prioridade e você quer minimizar a quantidade de software no contêiner.
  • Eficiência: Para criar imagens Docker extremamente pequenas e eficientes.

2.2 Reduzindo o Tempo de Build (Cache)

Usar o cache do Docker para otimizar o tempo de build é uma técnica essencial para evitar recompilar ou baixar dependências desnecessariamente em cada build. O Docker armazena em cache as camadas de cada etapa do Dockerfile, reutilizando-as sempre que possível.

Em projetos Go, baixar dependências com go mod download pode ser um processo demorado, especialmente se houver muitas dependências. Se você recompilar todas as dependências em cada build, isso aumenta significativamente o tempo de build.

Como arrumar isso?

Ao copiar apenas os arquivos go.mod e go.sum em uma etapa separada antes de copiar o código-fonte completo, você permite que o Docker use o cache dessa etapa se os arquivos go.mod e go.sum não tiverem mudado. Veja como fica nosso Docker file com as mudanças:

# syntax=docker/dockerfile:1

# Build stage
FROM golang:1.22-alpine AS builder
WORKDIR /app

COPY go.mod go.sum ./
RUN go mod download

COPY . .
RUN go build -o url-shortener ./cmd

# Final stage
FROM scratch
WORKDIR /app
COPY --from=builder /app/url-shortener .
CMD ["./url-shortener"]
ログイン後にコピー

Só de fazer esta pequena mudança já ganhamos dois pontos bem interessantes quando se trata de desenvolvimento de software, que são:
Menor tempo de build: Se não houver alterações nos arquivos go.mod e go.sum, o Docker reutiliza o cache, evitando o download das dependências e economizando tempo.
Eficiência no CI/CD: Em pipelines de integração contínua, essa técnica reduz o tempo de execução dos pipelines, aumentando a eficiência do desenvolvimento e entrega.

Então bora usar isso a nosso favor no dia-a-dia :)

2.3 Melhorando a Segurança (Docker Scout)

Docker Scout é uma ferramenta da Docker integrada ao Docker Desktop que analisa suas imagens para identificar vulnerabilidades de segurança. Ele fornece insights sobre as dependências presentes em suas imagens e alerta sobre possíveis problemas, permitindo que você tome medidas corretivas antes de implantar suas aplicações.

Por que é importante? Manter suas imagens Docker seguras é fundamental para proteger suas aplicações contra ataques e exploração de vulnerabilidades. O Docker Scout automatiza o processo de análise, tornando mais fácil manter suas imagens seguras e atualizadas.

Como funciona?

O Scout funciona praticamente com 2 passos, ele examina a imagem Docker, mapeia todas as dependências incluídas na imagem e verifica essas dependências em uma base de dados de vulnerabilidades conhecidas. Por fim, classifica as vulnerabilidades encontradas por severidade e fornece recomendações para corrigir ou mitigar os problemas.

Contoh Praktikal: Menggunakan Pengakap Docker pada Desktop Docker

  1. Akses Desktop Docker: Buka Desktop Docker dan pergi ke tab "Imej". Di sini anda akan melihat senarai semua imej yang anda miliki secara tempatan. Dalam contoh ini saya menggunakan imej postgres:16-alpine, kerana ia mengandungi kelemahan yang boleh kita gunakan sebagai contoh. Go + Docker: Como criar as melhores imagens Docker para aplicações Golang
  2. Lakukan Analisis Keterdedahan: Pilih imej yang ingin anda analisis. Pengakap Docker secara automatik akan memaparkan kelemahan yang diketahui dalam imej yang dipilih. Anda akan melihat ikon status keselamatan di sebelah setiap imej, menunjukkan sama ada terdapat kelemahan yang perlu ditangani. Go + Docker: Como criar as melhores imagens Docker para aplicações Golang
  3. Lihat Butiran Kerentanan: Klik pada imej untuk melihat papan pemuka terperinci tentang kelemahan yang ditemui. Ini termasuk versi pakej yang terjejas, perihalan CVE dan keterukan. Anda juga boleh melihat sejarah imbasan dan perubahan, membantu anda menjejaki cara keselamatan imej telah berkembang dari semasa ke semasa. Go + Docker: Como criar as melhores imagens Docker para aplicações Golang
  4. Gunakan Pembetulan: Berdasarkan cadangan Pengakap Docker, anda boleh memutuskan untuk mengemas kini pakej, membina semula imej dengan asas yang lebih selamat atau mengambil tindakan pengurangan yang lain. Pembetulan boleh digunakan terus pada saluran paip Dockerfile atau CI/CD anda. Go + Docker: Como criar as melhores imagens Docker para aplicações Golang

Dan dengan cara ini, kami akan mempunyai pencegahan proaktif yang akan mengenal pasti dan membetulkan kelemahan sebelum imej digunakan dalam pengeluaran, membantu melindungi daripada kemungkinan eksploitasi keselamatan dan kami juga memperoleh kecekapan operasi, apakah yang saya maksudkan dengan itu? Kami boleh mengautomasikan analisis kerentanan, membenarkan DevOps atau pasukan keselamatan menumpukan pada tindakan pembetulan dan bukannya penyiasatan manual.

Kesimpulan

Dengan amalan yang telah kami terokai, anda kini mempunyai laluan yang jelas untuk membina imej Docker untuk aplikasi Go anda Menggunakan teknik seperti Binaan Berbilang Peringkat yang mengurangkan saiz imej, memilih imej asas seperti alpine atau scratch untuk meningkatkan keselamatan dan kecekapan. dengan menggunakan Docker Scout untuk memantau kelemahan, anda boleh memastikan aplikasi anda berjalan dengan cekap dan selamat.

Amalan ini bukan sahaja meningkatkan prestasi teknikal, tetapi juga membawa manfaat langsung kepada kehidupan harian anda dan kepada syarikat, menjimatkan masa dan sumber.

Jadi pada kali seterusnya anda membina imej Docker, ingatlah strategi ini. Gunakannya dan perhatikan hasilnya. ?

以上がGo + Docker: Golang アプリケーションに最適な Docker イメージを作成する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:dev.to
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!