最適化された画像ファイルを作成して移動し、ピットを強化

ドッカー上の画像ファイルを作成するために行くことは難しいことではありませんが、大きなファイルを使うのは不便、近く1G設立しました。大きな問題は、小さなミラーを作成し、ドッカーの画像を最適化する方法です。私たちは、それは複雑ではない、ドッカーイメージファイルを作成するために、マルチレベルの建物を使用することができます。しかし、この方法の使用は、Linux(アルパイン)の簡単なバージョンを必要とするため、それが一連​​の問題をもたらします。唯一の14Mこの記事ではこれらの問題を解決し、正常に最適化した後、最適化された画像ファイル移動を作成する方法について説明します。

シングルレベルの建物:

ここでは、例として、ゴーゴープログラムでミラーを作成する方法を示しています。ここでは、プログラムのディレクトリ構造があります。

ファイル

ライン上で実行する限り、プログラムの詳細は重要ではありません移動します。私たちは、「ドッキングウィンドウ」サブディレクトリ(ファイルの「kubernetes」サブディレクトリは、他の用途があり、別の記事で説明します)に焦点を当てます。これは3つのファイルが含まれています。「Docker-backend.shは、」コマンド・ファイルのミラーイメージを作成することで、「Dockerfile-k8sdemo-バックエンドは、」マルチステージビルドファイルで、「Dockerfile-k8sdemo-バックエンド・フル」は、単段ビルドファイルであります

FROM golang:latest # 从Docker库中获取标准golang镜像
WORKDIR /app # 设置镜像内的当前工作目录
COPY go.mod go.sum ./ # 拷贝Go的包管理文件
RUN go mod download # 下载依赖包中的依赖库
COPY . . #从宿主机拷贝文件到镜像
WORKDIR /app/cmd # 设置新的镜像内的当前工作目录
RUN GOOS=linux go build -o main.exe #编译Go程序,并在生成可执行文件
CMD exec /bin/bash -c "trap : TERM INT; sleep infinity & wait" # 保持镜像一直运行,容器不被停掉

上記「Dockerfile-k8sdemo-バックエンド・フル」の画像ファイルがあります。説明のためにファイルにコメントをお読みください。

ミラーリングされたコンテナを作成します

cd /home/vagrant/jfeng45/k8sdemo/
docker build -f ./script/kubernetes/backend/docker/Dockerfile-k8sdemo-backend-full -t k8sdemo-backend-full .

実行時には、コンテナの画像、「 - 名前k8sdemo-バックエンド・フル」(k8sdemo-バックエンドフル)コンテナに名前を与えることで、「k8sdemo-バックエンド・フル」の最後には、ミラーの名前です。

docker run -td --name k8sdemo-backend-full k8sdemo-backend-full

「a95c」は容器上位4のIDであるミラー容器を、ログ。

docker exec -it a95c /bin/bash

ファイルは、ミラーイメージはすでに「WORKDIRは、」現在の作業ディレクトリの、ホストを設定し使用特別な説明が必要な文の「COPYを..」、ミラーのホストからファイルをコピーしている「」(現在のディレクトリを)どのディレクトリにそれを?どこのファイルにはDockerfileディレクトリではありませんが、コマンドが「ドッカーが構築」ディレクトリを実行します。

私たちは、このコマンドを実行したときにドッキングウィンドウは、その後、「k8sdemo」ディレクトリでプログラムのルートディレクトリにある必要があり、プログラム全体がミラーにコピーされたいです。しかし、コンテナ関連の「スクリプト」サブディレクトリ内のファイルディレクトリで、その後、あなたはそれDocekrfile見つける方法である「ドッカーが構築」コマンドを実行すると?重要な概念は、それがデフォルトのディレクトリDockerfileによって決定される(建物コンテキスト)「cotextを構築」することであります。あなたは「-t k8sdemo-バックエンドドッキングウィンドウのビルド」を実行すると、ミラーを作成し、それが「cotextを構築する」ルートディレクトリからDockerfileファイルを移動します、デフォルト値を使用すると、ドッキングウィンドウのコマンドを実行したディレクトリです。しかし、別のディレクトリにある私たちのDockerfileのために、それは場所Dockerfileを指定するための「-f」オプションは、次のようにコマンドがあり、順番リガに必要です。「-t k8sdemo-バックエンド・フル」のイメージ名を指定されている場合、形式は「名前:タグ」で、我々は、唯一のミラー名をタグがありません。

docker build -f ./script/kubernetes/backend/docker/Dockerfile-k8sdemo-backend-full -t k8sdemo-backend-full .

詳細については、Dockerfile参照を

このようなミラーは1Gにおそらく近い完全なLinuxシステムのバージョン、およびそれゆえ、比較的大きな、で作成されます。あなたが最適化したい場合は、多段を構築することが必要です。

マルチステージは、(多段構成)を構築します。

シングルレベルの建物は声明「より」が、マルチレベルの建物の中に、複数ある各1を構成する「差出人」、「から」だけです。たとえば、「から」以下の二つの文書が存在し、それは2つの構築物です。塩基(塩基)を選択することができそれぞれが所望のレベルとして鏡像を提示するように構成されています。各レベルミラーが完了した後、ミラーは、それ自体に有用な最終的な文書に構築し、従ってスペースを節約する、中間生成物の全てを除去するために保持するように、次のレベルを選択することができます。詳細については、多段階のビルドを使用し

ここで、多段構成dockerfile( "Dockerfile-k8sdemo-バックエンド")です。

FROM golang:latest as builder # 本级镜像用“builder”标识
# Set the Current Working Directory inside the container
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
WORKDIR /app/cmd
# Build the Go app
#RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main.exe
RUN go build -o main.exe

######## Start a new stage from scratch #######
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
RUN mkdir /lib64 && ln -s /lib/libc.musl-x86_64.so.1 /lib64/ld-linux-x86-64.so.2
# Copy the Pre-built binary file from the previous stage
COPY --from=builder /app/cmd/main.exe . #把“/app/cmd/main.exe”文件从“builder”中拷贝到本级的当前目录
# Command to run the executable
CMD exec /bin/sh -c "trap : TERM INT; (while true; do sleep 1000; done) & wait"

ミラーを作成します。

cd /home/vagrant/jfeng45/k8sdemo/
docker build -f ./script/kubernetes/backend/docker/Dockerfile-k8sdemo-backend -t k8sdemo-backend .

ミラーログイン:

docker run -it --name k8sdemo-backend k8sdemo-backend /bin/sh

上記コンフィギュレーション・ファイルは、Linuxのフルバージョンを使用して、移動を二つの部分、最初のコンパイルされた実行可能ファイルに処理して生成する。第2の部分は適切なディレクトリに実行可能ファイルのコピーであり、実行中の単純化されたバージョンのを使用して、容器を保持しますLinuxの。単段指示コマンドから構成される第1の部分は基本的に同じである、コマンドの第二の部分は、後述します。

この方法を使用すると、大幅にドッカーのみ14Mのミラーを作成し、設置面積を減少させたが、それは、Linux(アルパイン)の簡易版を使用しているため、それを埋めるためにあるかを確認するには、以下のこれらのピット、ピットの多くを踏むために私を導きました。

段ピット:

1.ファイルが見つかりません

イメージが正常に作成された後、ミラーリングをログ:

docker run -it --name k8sdemo-backend k8sdemo-backend /bin/sh

、「MAIN.EXE」コンパイルされた実行可能ファイルを実行し、次のエラーメッセージを移動します:

~ # ./main.exe
./main.exe not found

Goはそれは場所にコンパイルされたプログラムを置くために必要なコンパイル時に在庫あり、静的にコンパイル言語であるので、他のダイナミックリンクライブラリを行うときに、それは非常に簡単にアップ実行することができますする必要はありません。しかし、すべての場合には、例えば、進行中であるが、あなたはCGOを(囲碁プログラムは、Cプログラムを呼び出すことができましょう)を使用する場合、通常は(Linuxではglibcのある)ダイナミックリンクライブラリlibcが必要です。ネットの内側に移動して、OS /ユーザーライブラリは、CGOを使用しました。しかし、そこにライブラリのlibc一切のLinuxバージョンAplineはありませんので、それは実行時のダイナミックリンク、したがってエラーで見つけることができないため。解決する方法は2つあります。

  • = 0 CGO_ENABLED:ゴーをコンパイルするときに時間がCGOを使用することはありませんコンパイルし、このパラメータを追加すると、当然のことながら、ライブラリCGOの使用は使用できないことを意味します。これは最も簡単な方法ですが、それはあなたのプログラムの制限を行います。
  • MUSLを使用してください:MUSLは、軽量のlibcライブラリです。LinuxバージョンはMUSLのAplineのライブラリが付属して、あなたは、単に行に次のコマンドを追加します。
RUN mkdir /lib64 && ln -s /lib/libc.musl-x86_64.so.1 /lib64/ld-linux-x86-64.so.2

MUSLの詳細については、を参照しても、常に、静的にコンパイルされた囲碁プログラムを MUSLを使用して、CGOで

このエラーについての議論は、参照インストール囲碁バイナリは、上のパスに見つからないアルパインのLinuxドッカー

2.ザップエラー

ザップは、私がプログラムに出力ログにそれを使用し、非常に人気のゴーロギングライブラリです。上記の文と組み合わせると、元のエラーは消えたが、私たちは、新たな障害を持っています。これは、ザップすることにより製造されます。

~ # ./main.exe
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x6a37ab]

goroutine 1 [running]:
github.com/jfeng45/k8sdemo/config.initLog(0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
        /app/config/zap.go:94 +0x1fb
github.com/jfeng45/k8sdemo/config.RegisterLog(0x0, 0x0)
        /app/config/zap.go:42 +0x42
github.com/jfeng45/k8sdemo/config.BuildRegistrationInterface(0x751137, 0x5, 0x43ab77, 0x984940, 0xc00002c750, 0xc000074f50)
        /app/config/appConfig.go:23 +0x26
main.testRegistration()
        /app/cmd/main.go:18 +0x3a
main.main()
        /app/cmd/main.go:11 +0x20

私は、エラーのために非常に明確な理由はないです、それはMUSLライブラリである必要があります。ザップ推定値は、ライブラリで使用されているMUSLと互換性がありません。私はLogrusの問題は存在しない別のライブラリにログインします。これは確かに少し後悔です、ザップGoはこれまでのところ、私はログデータベースを発見したベストです。あなたはザップに固執する場合は、のみ、Linuxのフルバージョンを使用して、大きな画像ファイルを置くことができ、またはあなたが小さな画像ファイルを楽しむことができるように、Logrusログインするライブラリを使用しています。

3. K8S失敗した展開

置換Logrus後、通常の操作手順に誤り、ドッカーは存在しません。しかし、あなたはK8S導入時間を作成するには、この画像を使用する場合は、問題のうち。

ここでK8Sは、展開コマンドを作成することです:

vagrant@ubuntu-xenial:~/jfeng45/k8sdemo/script/kubernetes/backend$ kubectl get pod k8sdemo-backend-deployment-6b99dc6b8c-2fwnm
NAME                                          READY   STATUS             RESTARTS   AGE
k8sdemo-backend-deployment-6b99dc6b8c-2fwnm   0/1     CrashLoopBackOff   42         3h10m

エラーメッセージは「CrashLoopBackOff」です。それはプログラムのコンテナ要件の内側に生成された理由は、コンテナが停止され、実行の終了後に、実行されています。K8S容器が停止した後に容器を再配置することが見出され、そして無限ループになるように、次いで、停止させました。
解決策は、画像ファイルに次のコマンドを追加することです:

CMD exec /bin/bash -c "trap : TERM INT; sleep infinity & wait"

详情请参见はどうすれば?Kubernetesにコンテナを実行し続けることができマイkubernetesポッドは「CrashLoopBackOff」でクラッシュしておくが、私はすべてのログを見つけることができません

4.ポッドエラー

コマンドに参加して、ミラーを再構築し、それは本当にK8S展開が与えられていない、死のサイクルの問題を解決するが、次のようにポッドが新しいエラーを持っている、「STATUS」の「k8sdemo-バックエンド展開6b99dc6b8c-n6bntは、」「エラー」であります。

vagrant@ubuntu-xenial:~/jfeng45/k8sdemo/script/kubernetes/backend$ kubectl get pod
NAME                                           READY   STATUS    RESTARTS   AGE
envar-demo                                     1/1     Running   8          16d
k8sdemo-backend-deployment-6b99dc6b8c-n6bnt    0/1     Error     1          6s
k8sdemo-database-deployment-578fc88c88-mm6x8   1/1     Running   2          4d21h
nginx-deployment-77fff558d7-84z9z              1/1     Running   3          10d
nginx-deployment-77fff558d7-dh2ms              1/1     Running   3          10d

その理由は、ドッカーファイルに次のコマンドを実行することです。

CMD exec /bin/bash -c "trap : TERM INT; sleep infinity & wait"

アルパインが、何の「/ bin / bash」と変更する必要があり、「/ binに/ SH」が存在しない、次のコマンドに変更する必要があります。

CMD exec /bin/sh -c "trap : TERM INT; (while true; do sleep 1000; done) & wait"

修正後、K8S展開が成功し、プログラムが正常に実行されます。

出典:

完全なソースコードgithubのリンク

指数

  1. Dockerfileリファレンス
  2. 多段階のビルドを使用し
  3. 静的MUSLを使用して、でもCGOで、常に、囲碁プログラムをコンパイル
  4. アルパインのLinuxドッカー上のパスに見つからないインストールされて行くのバイナリ
  5. どのように私はKubernetes上で実行されているコンテナを保つことができますか?
  6. マイkubernetesポッドは「CrashLoopBackOff」でクラッシュしておくが、私はすべてのログを見つけることができません
  7. ゴーアプリケーションの構築ドッカーコンテナ

ブログ記事複数のプラットフォームからこの記事OpenWriteリリース!

おすすめ

転載: www.cnblogs.com/code-craftsman/p/11730136.html