- 投稿日:2021-01-14T17:59:57+09:00
【個人的に】Dockerがはかどる小技
初めて知ったときは感動したけど 自分の中で知ってて当然になってしまった小技をまとめました
まだこの小技を知らない人に届いてくれるとうれしいDockerfile
RUNを1つにまとめる
DockerfileRUN echo '1つ目のコマンド' RUN echo '2つ目のコマンド'
&&
を使って1つにまとめるDockerfileRUN echo '1つ目のコマンド' && echo '2つ目のコマンド'
&&
はDockerの小技というよりシェルの機能です
不用意にイメージレイヤーを増やすと イメージサイズが大きくなってしまうので RUNはなるべく1つにまとめた方が良いRUNで条件分岐
DockerfileARG HOGE="hoge" RUN if [ "$HOGE" = "hoge" ]; then \ echo 'hoge'; \ fiこれもDockerの小技というよりシェルの機能です
特定のビルド引数が入ってきたときにのみ実行したい処理があるときに便利です使いどころに注意
そのイメージの本質が変化してしまうような使い方はあんまり良くないです。
ちょっとしたツールを入れたりオプショナルな使い方がおすすめです別のイメージからファイルをCOPYする
DockerfileCOPY --from=composer:2.0 /usr/bin/composer /usr/bin/composer特定のコマンドを持ってくるときに便利
自前でインストールするコマンドを書かなくても 公式のイメージから持ってこれる安心感環境によってCOPYするファイルを変える
DockerfileARG TARGET_ENV COPY ./docker/nginx/$TARGET_ENV/nginx.conf /etc/nginx/nginx.confdocker/ nginx/ dev/ nginx.conf ci/ nginx.conf pro/ nginx.confただビルド引数を使っているだけですが ディレクトリを分けて環境ごとの設定を書いておくことで 開発環境、テスト環境、本番環境などの切り替えが楽になります
マルチステージビルド
DockerfileFROM nginx AS MOUNT # some code FROM MOUNT AS BUNDLE # カレントディレクトリを丸ごと /usr/share/nginx/html にコピーする COPY . /usr/share/nginx/htmlイメージをビルドするときに
--target string
を指定してどこまでビルドするのか選べます
docker build --target MOUNT .
にすると/usr/share/nginx/html
にはなにも入ってない状態
コンテナ起動するときにマウントして開発できる
docker build --target BUNDLE .
にするとイメージにコードが含まれているのでそのままコンテナを実行できるみたいな使い方できます
DockerCompose
.env
.envNGINX_PORT=80docker-compose.yml は 環境変数を使用することができ、 .env ファイルにも対応しています
docker-compose.ymlversion: '3.8' services: nginx: image: nginx ports: - ${NGINX_PORT}:80人によって設定を変えたいような項目は .env に書き出しておくと便利
「80番ポート他でもう使ってるよ」ってことがあるのでホスト側のポートは 変数 にしがち
docker-compose.override.yml
docker-compose.ymlの設定を上書きできるファイル
docker-compose.yml
docker-compose.ymlversion: '3.8' services: php: image: php ports: - 80:80docker-compose.override.yml
docker-compose.override.ymlversion: '3.8' services: php: volumes: - ${APP_DIR}:/app - php_vendor:/app/vendor depends_on: - mysql mysql: image: mysql volumes: - mysql_data:/var/lib/mysql environment: - MYSQL_ROOT_PASSWORD=${DB_PASS} volumes: mysql_data: php_vendor:ローカルだけ
docker-compose.override.yml
を作ってデータベースのコンテナを用意する
みたいな使い方ができますその他
.dockerignore
COPY
するときに除外したいファイルやフォルダを指定するファイル.dockerignore.vscode .env .git .gitignore .gitattributes **/.gitkeep **/Dockerfile docker-compose.yml docker-compose.override.ymlhost.docker.internal
コンテナからホストマシンのIPアドレスを指定したいときに使う
XDebug のようなデバッグツールの設定でつかったり
php.ini[xdebug] xdebug.client_host=host.docker.internal
- 投稿日:2021-01-14T16:25:38+09:00
【AWS ECR】Dockerイメージの保存と取得
目標
AWS ECRを利用したDockerコンテナレジストリ上にDokcerイメージの保存及び取得を実施する。
はじめに
以下Youtube動画(by くろかわこうへい氏)に沿ってハンズオンを実施した結果をアウトプットとして記載致しました。
AWS ECRに関する基本事項は以下のリンクより学習することが出来ます。今から追いつくDocker講座!AWS ECSとFargateで目指せコンテナマスター!〜シリーズ3回目〜
前提
・Dockerデーモンが起動しているEC2インスタンス(Amazon Linux2)が構築済みであること(※)。
※以下記事の手順1「Dockerデーモン起動」までを完了すれば前提は整います。
【Docker】dockerfileを利用してEC2にApacheコンテナを構築(Dockerデーモン起動)作業の流れ
項番 タイトル 1 ECRの構築 2 ECRアクセス用IAMロールアタッチ 3 ECRにDockerイメージを保存する 4 ECRからDockerイメージを取得する 手順
1.ECRの構築
ECRコンソールからレポジトリ作成を開始します。
レポジトリ名を入力し(本記事では
testrepo
としました)、下段にあるレポジトリ作成実行ボタンをクリック
2.ECRアクセス用IAMロールアタッチ
EC2からECRへアクセスするための権限を付与するため、IAMロールの作成、及び対象EC2インスタンスへのアタッチを実施します。
IAMロールコンソールからロールの作成をクリック
今回はIAMロールをEC2にアタッチするため、EC2を信頼されたエンティティとして設定します。
ECRへのフルアクセス権を付与するIAMポリシー
AmazonEC2ContainerRegistryFullAccess
をIAMロールに埋め込みます。
IAMロール名を記載(本記事では
ecr-access
と設定)しロールの作成を実行します。作成したIAMロールを対象のEC2インスタンスへアタッチします。
3.ECRにDockerイメージを保存する
対象のEC2インスタンスへOSログイン(ルートユーザ前提として記載します)し、
dockerfile
の記載を行います。サンプルとして、httpdをインストールし、コンテナ起動時にhttpdを自動起動するDockerイメージを作成するような処理を記述します。
dockerfileFROM centos:centos7 RUN yum -y install httpd CMD ["/usr/sbin/httpd","-DFOREGROUND"]次にECRコンソールに戻り、作成したECRレポジトリを選択し
プッシュコマンドの表示
をクリックします。
すると対象のECRレポジトリにプッシュを行うために一連のコマンドが表示されます。
これらを順に実行していく流れとなります。まずは上記プッシュコマンド群の1番目をコピーして実行します。
内容はECRレポジトリへのログインパスワードを取得し、そのパスワードを標準入力としてdocker login
を実行するという内容です。Login Succeededと表示されればOKです。(IAMロールの設定等が誤っているとcredential系のエラーが表示されます)
[root@ip-172-31-35-94 ~]# aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin 932699493995.dkr.ecr.ap-northeast-1.amazonaws.com WARNING! Your password will be stored unencrypted in /root/.docker/config.json. Configure a credential helper to remove this warning. See https://docs.docker.com/engine/reference/commandline/login/#credentials-store Login Succeeded2番目のコマンドは通常の
docker build
コマンドです。docker build -t testrepo .3番目のコマンドでECRレポジトリプッシュに必要なタグ付けを
docker tag
で実施します。[root@ip-172-31-35-94 ~]# docker tag testrepo:latest 932699493995.dkr.ecr.ap-northeast-1.amazonaws.com/testrepo:latest [root@ip-172-31-35-94 ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE 932699493995.dkr.ecr.ap-northeast-1.amazonaws.com/testrepo latest 306adf672fc7 10 minutes ago 330MB testrepo latest 306adf672fc7 10 minutes ago 330MB centos centos7 8652b9f0cb4c 2 months ago 204MB4番目のコマンドで実際に
docker push
を実行します。[root@ip-172-31-35-94 ~]# docker push 932699493995.dkr.ecr.ap-northeast-1.amazonaws.com/testrepo:latest The push refers to repository [932699493995.dkr.ecr.ap-northeast-1.amazonaws.com/testrepo] 9cdaef33df63: Pushed 174f56854903: Pushed latest: digest: sha256:33f3b20422ea489ca61be9a5b4334b0a68572989b4143bca3cb6d55825c2c07c size: 741
aws ecr describe-images --repository-name リポジトリ名 --region ap-northeast-1
を実行し、プッシュしたイメージが確認出来ればOKです。[root@ip-172-31-35-94 ~]# aws ecr describe-images --repository-name testrepo --region ap-northeast-1 { "imageDetails": [ { "artifactMediaType": "application/vnd.docker.container.image.v1+json", "imageSizeInBytes": 135861914, "imageDigest": "sha256:33f3b20422ea489ca61be9a5b4334b0a68572989b4143bca3cb6d55825c2c07c", "imageManifestMediaType": "application/vnd.docker.distribution.manifest.v2+json", "imageTags": [ "latest" ], "registryId": "932699493995", "repositoryName": "testrepo", "imagePushedAt": 1610607670.0 } ] }4.ECRからDockerイメージを取得する
ECRコンソールから、ECR内に保存されているDockerイメージのURLをコピーします。
コピーしたURLを
docker pull
コマンドの引数として実行します。[root@ip-172-31-35-94 ~]# docker pull 932699493995.dkr.ecr.ap-northeast-1.amazonaws.com/testrepo:latest latest: Pulling from testrepo Digest: sha256:33f3b20422ea489ca61be9a5b4334b0a68572989b4143bca3cb6d55825c2c07c Status: Downloaded newer image for 932699493995.dkr.ecr.ap-northeast-1.amazonaws.com/testrepo:latest 932699493995.dkr.ecr.ap-northeast-1.amazonaws.com/testrepo:latest
- 投稿日:2021-01-14T12:40:20+09:00
Rails6にDockerを導入したのでまとめてみた(初学者)
目的
ポートフォリオ実装してdockerを導入したのでアウトプットします。
Dockerがなんなのかわからなかったので色々な方のQiitaを参考にしております
Dockerのインストール
私はこの方の記事を見てインストールしました!!
https://qiita.com/kurkuru/items/127fa99ef5b2f0288b81
インストールできたら以下コマンドを実行します。% docker run -d -p 80:80 docker/getting-startedインストールの確認
% docker -vこのようなコマンドが出たらインストール完了です。
Docker version 20.10.2, build 2291f61
% docker-compose -vこちらも同様に
docker-compose version 1.27.4, build 40524192
が出力されたら完了です。Docker導入に渡って
メリットとしては
ローカル環境に構築したrailsとmysqlを1コマンド叩くだけで実行できるようになる。
と記載されていたのですが、初学者の私には理解が難しかったです。dockerを導入した後にこの意味がわかったのでまずは手を動かした方がいいです。開発中のアプリでdockerを導入
早速ですが導入していきます。
フレームワークはRubyonRails6を使用しています。Dockerfileの作成
手順としてDockerを導入したい開発中のアプリに移動します
~ % cd アプリ名アプリ名 % touch DockerfileDockerfileが作成されたので下記を記載してください。
FROM ruby:2.6.5 RUN apt-get update -qq && \ apt-get install -y build-essential \ libpq-dev \ nodejs RUN mkdir /アプリ名 WORKDIR /アプリ名 ADD ./Gemfile /アプリ名/Gemfile ADD ./Gemfile.lock /アプリ名/Gemfile.lock RUN gem install bundler RUN bundle install ADD . /アプリ名アプリ名を自身の開発しているアプリ名に変えましょう。
Docker-compose.ymlを作成しましょう。
アプリ名 % touch docker-compose.yml下記を記述しましょう。
docker-compose.ymlversion: '3' services: db: image: mysql:5.7 environment: MYSQL_ROOT_PASSWORD: 'password' # このままpasswordとしても問題なく動く ports: - "4306:3306" #DockerコンテナとSequelpro接続の為に必要な設定 web: build: . command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'" volumes: - .:/アプリ名 ports: - "3000:3000" depends_on: - dbconfig/database.ymlを編集
config/database.ymldefault: &default adapter: mysql2 encoding: utf8 pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> username: root password: password socket: /tmp/mysql.sock host: db development: <<: *default database: アプリ名_development production. test: <<: *default database: アプリ名_test追加されたのは、
password
とhost: db
のみdocker-compose.yml buildでコンテナの作成
アプリ名 % docker-compose buildエラーがなかったら成功です。
コンテナ上でDB作成とmigrateの実行
アプリ名 % docker-compose run web bundle exec rails db:createRails6だとこのコマンドを実行するとエラーが出てしますので編集します。
config/webpacker.yml# Verifies that correct packages and versions are installed by inspecting package.json, yarn.lock, and node_modules check_yarn_integrity: falseおよそ56行目あたり
check_yarn_integrity: true
になっているのでこれをfalse
に変えます。編集が終わったら、もう一度同じコマンドを実行しましょう。
続いてmigrateしましょう。アプリ名 % docker-compose run web bundle exec rake db:migrateこれでコンテナ上でdb設計ができました。最後にコンテナを起動しましょう。
アプリ名 % docker-compose uplocalhost:3000にアクセスし起動できていたら導入完了です。
docker hubから起動
複数のアプリをコンテナに積んだのでコマンドを打たずクリック一つでアプリを起動できます。
赤字のRANをクリックすると起動できます。
もう一回クリックすれば停止できます。
単語集
①dockerfileって何
コンテナを作成する材料。
docker-compose build
のコマンドを実行するとステップに分けた読み込みをしていたと思います。読み込みが成功したらコンテナが作成されたよの意味。②docker-composeって何
複数のコンテナを同時に動かすためのツールのこと
こんな感じです!
もっと詳しく書けるように頑張ります。
- 投稿日:2021-01-14T10:13:49+09:00
プロセスとスレッド、シングルプロセスとマルチプロセスの違い
Dockerの勉強を進めるにあたって、Docker Engineの仕組みを理解するには、プロセスの概念を理解する必要がありましたので、プロセスの詳細について調べてみました。
コンテナは、コンテナの作成、起動、削除を管理するDocker Daemonと同じく、ホストOS上でプロセスとしての存在になります。ホストOS上のプロセスということで、他のホストOS上で単独実行アプリケーションと同様に、CPU、メモリ、ネットワークなどのリソースをホストOS経由でアクセスできますし、また、プロセスが終了すると、メモリに保持されているコンテナ上の操作データも一緒に消えるが当然なことがよく理解できました。
■プロセスとスレッドの違いについて
1プログラム⇒1プロセス
1プロセスに複数のスレッドを動かすことが出来る(シングルスレッドとマルチスレッドがある)
スレッドがプロセス内の命令を実行する
1スレッドが1CPUコア使用する
1CPUに複数のCPUコアを含むことが出来る。メモリー空間はプロセス単位で割り当てられる
スレッドが属するプロセスのメモリ空間を共有する■シングルプロセスとマルチプロセスの違い
シングルプロセス:
スレッド①:料理開始⇒ご飯を炊く⇒カレーを煮込む⇒お皿に盛る⇒料理終了
マルチプロセス:
スレッド①:料理開始⇒プロセス②を起動⇒ご飯を炊く⇒プロセス②完了を待つ⇒料理終了
スレッド②:カレーを炊く
- 投稿日:2021-01-14T10:13:49+09:00
Dockerの仕組みを理解するためのプロセスの概念を調べてみました
Dockerの勉強を進めるにあたって、Docker Engineの仕組みを理解するには、プロセスの概念を理解する必要がありましたので、プロセスの詳細について調べてみました。
コンテナは、コンテナの作成、起動、削除を管理するDocker Daemonと同じく、ホストOS上でプロセスとしての存在になります。ホストOS上のプロセスということで、他のホストOS上で単独実行アプリケーションと同様に、CPU、メモリ、ネットワークなどのリソースをホストOS経由でアクセスできますし、また、プロセスが終了すると、メモリに保持されているコンテナ上の操作データも一緒に消えるが当然なことがよく理解できました。
■プロセスとは
プロセスとは、HDDなどに格納されているバイナリーコードをOSのスケジューラーにより、メモリにロードされ、CPUを実行可能な状態となる、OS上でのCPUなどのリソース実行管理単位のこと。■プロセスとスレッドの違いについて
1プログラム⇒1プロセス
1プロセスに複数のスレッドを動かすことが出来る(シングルスレッドとマルチスレッドがある)
スレッドがプロセス内の命令を実行する
1スレッドが1CPUコア使用する
1CPUに複数のCPUコアを含むことが出来る。メモリー空間はプロセス単位で割り当てられる
スレッドが属するプロセスのメモリ空間を共有する■シングルプロセスとマルチプロセスの違い
シングルプロセス:
スレッド①:料理開始⇒ご飯を炊く⇒カレーを煮込む⇒お皿に盛る⇒料理終了
マルチプロセス:
スレッド①:料理開始⇒プロセス②を起動⇒ご飯を炊く⇒プロセス②完了を待つ⇒料理終了
スレッド②:カレーを炊く
- 投稿日:2021-01-14T10:02:48+09:00
【Docker Network 第1章】Dockerネットワーキングについて解説
はじめに
Dockerのエコシステムを理解するには、コンテナネットワーキングについての十分な知識が必要です。
これから3章にわたる記事を投稿しますが、この第1章では最も重要なコンテナネットワーキングの概念について説明します。ここで紹介するさまざまな概念を理解するには、Dockerの専門家である必要はありませんが、ネットワーク、Docker、およびKubernetesの基本的な知識が必要になるものかと思います。Dockerは、コンテナー内で実行される分離された環境を作成、構築、実行するために設計されたツールです。アプリケーションをコンテナ化して軽量コンテナ内で実行できるようにするために広く使用されています。 Dockerをマスターするには、イメージの作成方法、実行方法、コンテナの保護方法、Dockerファイルシステムの操作方法、Dockerネットワークの管理方法に精通している必要があります。
そして、その中のDockerネットワーキングは、学習の過程で最も混乱する部分かもしれません。ここ数年の間に、このテクノロジーを中心にダイナミックなエコシステム全体が開発されました。 Docker Compose、Docker Swarm、Kubernetesなどのテクノロジーは、コンテナー化エコシステムの多くの問題を解決しましたが、特にネットワーキングに新しい課題をもたらしました。 Dockerエコシステムをよく理解するためには、ネットワーキングについての十分な知識が必要となってくるということです。
コンテナ:1つのことを実行し、うまく実行する
コンテナー(Wordpressなど)を実行すると、イメージを構築してWebサーバー(NginxまたはApache)+ PHPまたは(PHP FPM)+ Mysql / MariaDBデータベースを使用できます。
このソリューションは、多くのネットワークの問題を解消します。また、supervisordなどのプロセスマネージャーを使用して、プロセスが実行されていることを確認できます。ただし、イメージにレイヤーを追加することになるので、これは良い方法ではありません。supervisordを使用するには、それをインストールし、その構成をコンテナーに同梱する必要があります。重要なプロセスとは、重要なプロセスとソフトウェアパッケージのみを含む軽量コンテナを構築して実行することです。
さらに、単一のコンテナで複数のプロセスを実行することは良くないパターンです。コンテナー内で独自のプロセスを実行することをお勧めします。
Wordpressの場合、Webサーバー(ApacheまたはNginx)用のコンテナー、PHP用のコンテナー、およびデータベース用の別のコンテナーが必要です。これらのコンテナーは相互に通信する必要があります。Webサーバーは要求を受信し、要求をPHPコンテナーに送信します。後者がデータを必要とする場合は、データベースコンテナーに要求します。逆の経路も方程式に取り入れなければなりません。これらのコンテナーを異なるホストで実行する場合、それらが同じホストにない場合でも、それらは互いにトラフィックを送受信できるはずです。複数のホスト間のトラフィックについては、最低限のセキュリティ標準を検討する必要があります。また、ウェブサーバーまたはアプリケーションコンテナーをスケーリングし、ロードバランサーを使用してそれらにトラフィックをルーティングする必要があるいくつかのケースに直面することもあります。
この使用例が基本的なように見えても、スタック全体を実行する上でネットワークがどのように重要な役割を果たすかがわかります。
オーケストレーション:複雑な層?
スタンドアロンコンテナを実行することは可能ですが、高可用性環境、特に本番環境では、これらのコンテナを管理するためにオーケストレーションプラットフォームが必要になります。
Kubernetesのようなオーケストレーションシステムを使用すると、コンテナだけでは満足のいく解決策を提供できない多くの問題が間違いなく解決されます。
それらのいくつかを識別しましょう:
- サービスを構成するコンテナーの数のスケールアップ/ダウン
- 同じサービスの異なるコンテナー間での負荷分散
- あるノード(VM)から別のノードへのコンテナーの転送
- 他のサービスおよびインターネットへのサービスの公開
- コンテナーとサービス間のサービス検出
- コンテナの配備
これらのユースケースと機能のほとんどを見ると、ネットワークが共通のポイントであることがわかります。
オーケストレーションは必須ですが、ネットワークの追加レイヤーも同時に追加されていきます。同じノード内のコンテナー間ネットワークの他に、マスターからクラスターへのネットワーク、クラスターからマスターへのネットワーク、インターネットからサービスへのネットワーク、サービスからポッドへのネットワーク、ポッドからポッドへのネットワーク、コンテナーからコンテナーへのネットワークなど、Kubernetesには複数のタイプのネットワークがあります。さらに詳しく説明したい場合は、ノード、kubelet、Kube-proxy、およびDNSネットワーキングも検討できます。
Kubernetesは最新のデータセンターオペレーティングシステムと見なされています。この大きさのプラットフォームでこのネットワークの複雑さを目にすると驚く人も多いでしょうが、Kubernetesで最も複雑でおそらく最も重要な部分の1つはネットワークです。ネットワーキングシステムを採用しない限り、Kubernetesを習得することはできません。
コンテナネットワークは複雑ですが難易度は高くありません
Zen of Pythonには次のような格言があります。
「Simple is better than complex. Complex is better than complicated.」
ITでは、Complexとは、システムのコンポーネントの数と、コンポーネント間の相互作用のレベルを指します。 一方,Complicatedとは、難易度が高いことを意味します。
特にオーケストレーションされたシステムでのコンテナーのネットワーキングはComplex(複雑)ですが、Complicated(難解)ではありません。 さらに、このComplexは、一般的な問題に対する抽象的なシステムと一般的なソリューションを作成するために必要な場合があります。 これは、Kubernetes開発者の1人であるJoe Bedaが宣言したものです
「KubernetesはComplexシステムです。これは多くのことを行い、エンジニアとして新しい抽象化をもたらします。私たちは自分で構築するComplexに対して、私たちが学ぶ必要があるComplicatedを無視する傾向があります。」
Bedaはさらに、Jenkins、Bash、Puppet / Chef / Salt / Ansible、AWS、Terraformなどを使用して複雑なデプロイメントシステムを作成すると、独自のComplexのブランドに慣れてしまうと言いました。それは有機的に成長したのでそれは複雑に感じませんが、このような有機的に成長したシステムで新しい人々を助けることは困難です。彼らはいくつかのツールを知っているかもしれませんが、それらを組み立てる方法は独特です。
ここは、Kubernetesが付加価値を提供する場所です。一般的な一連の問題を解決する一連の抽象化を提供します。人々がこれらの問題について理解とスキルを構築するにつれて、より多くの状況でより生産的になります。
コンテナーのネットワーキングは一見Complicatedですが、ネットワーキングに関する基本的な知識と新しいスキルの学習に投資する時間がある場合は、近づきやすいでしょう。
この次の章の記事では、技術的な詳細について詳しく説明します。スタンドアロンモードで実行した場合のDockerコンテナネットワークの仕組み、マルチコンテナネットワークの仕組み、スタンドアロンコンテナネットワークの違い、マルチコンテナネットワークについて理解します。また、複数のホストと魅力的なKubernetesネットワーキングの世界でネットワーキングを管理する方法についても説明します。
- 投稿日:2021-01-14T02:05:50+09:00
GCP上でGPUコンテナを構築してみる。
はじめに
GPUコンテナの作成を試したかったのだが、そのためにGPUを買う選択肢はなかったので、クラウド上でGPUインスタンスを作成して、そこでGPUコンテナを構築してみた。
以外に時間を要したので、自分用のメモとして手順やコマンドをまとめておく。事前準備
・Google Cloudのアカウントを作成してGCPコンソールの画面に入れる状態にしておく。
・アップグレードする。(無料トライアルの状態だと、GPUの割当申請ができない)環境
【ホストOS】
・Ubuntu 20.04 LTS(GCP上)
・Nvidia-driver 460.
・docker 19.03.14
・Nvidia-driver2 2.5.0GPUコンテナの作成手順
1.GPUインスタンスの作成
2.ホストの設定
3.GPUコンテナの作成1.GPUインスタンスの作成
GPUの割当申請をする
GPUを搭載したVMインスタンスを作成する場合、初回のみ割り当て(クオータ)申請が必要。
まずはGCPのコンソールからIAMと管理 > 割り当て
を選択する。、
申請は2つする必要があり、【全体における割り当て数】と、【各GPUのリージョン毎の割り当て数】の申請が必要。【全体における割り当て数】
フィルタにGPUsと入れて、下図のサービスを選択する。グローバルにチェックを入れて、『割り当て編集』をクリック。上限と理由を記入して次へ進む。
次の画面で、【名前】、【メールアドレス】、【電話番号】を入力してリクエストを送信する。
5分程で承認が下りるため、次はGPUインスタンスを作成する。【各GPUのリージョン毎の割り当て数】
適当にフィルタをかけて、今回は
NVIDIA T4
を選ぶ。
※利用料金の詳細はこちらを参考に ⇒ https://cloud.google.com/compute/gpus-pricing?hl=ja割り当てはリージョン単位になるため、GPUインスタンスを立てる予定のリージョンを選択し、次にGPU数の上限を指定する。
ここで指定した数値は上限値なので、この時点で課金が発生することはない。今回はGPUコンテナの構築が目的のため1個。GPUインタスタンスの作成
GCPのコンソールから
Compute Engine > VMインスタンス
を選択。
[作成] をクリックし、以下のスペックで作成。<右側は今回の設定値>
●リージョン:us-central1(アイオワ)
●ゾーン :us-central1-a●マシン構成
マシンファミリー:GPU
シリーズ :N1
マシンタイプ :n1-standard-1(1vCPU、3.75GBメモリ)
※試しに申請したリージョン以外を選択すると、GPUのタグは出てこない。
●GPUのタイプ
GPUのタイプ:NVIDIA Tesla T4
GPUの数 :1
●ブートディスク
OS :Ubuntu
バージョン :Ubuntu 20.04 LTS
ディスクの種類:標準の永続ディスク
サイズ :20GB●ファイアウォール
HTTPトラフィックを許可
HTTPSトラフィックを許可起動に数分かかった。。。
サーバー環境の確認
OSの確認$ cat /etc/lsb-release DISTRIB_ID=Ubuntu DISTRIB_RELEASE=20.04 DISTRIB_CODENAME=focal DISTRIB_DESCRIPTION="Ubuntu 20.04.1 LTS"GPU(NVIDIA製)の確認$ lspci -vv | grep -i nvidia 00:04.0 3D controller: NVIDIA Corporation TU104GL [Tesla T4] (rev a1) Subsystem: NVIDIA Corporation TU104GL [Tesla T4] Kernel modules: nvidiafb2.ホストの設定
nouveauグラフィックスドライバの無効化
linuxにデフォルトで入っているnouveauグラフィックスドライバというのを無効化する必要があるらしい。$ lsmod | grep -i nouveau※今回のVM環境は入っていなかったため、特に何も返ってこなかった。
パッケージ管理ツールのアップデート
$ sudo apt update $ sudo apt upgradeNvidiaドライバーのインストール
NVIDIAのDriverバージョンは、こちらのサイトより確認できる。https://www.nvidia.co.jp/Download/index.aspx?lang=jp
リポジトリを追加してアップデート
$ sudo add-apt-repository ppa:graphics-drivers/ppa $ sudo apt updateインストール推奨Driverを確認
$ sudo apt ubuntu-drivers-common $ ubuntu-drivers devices == /sys/devices/pci0000:00/0000:00:04.0 == modalias : pci:v000010DEd00001EB8sv000010DEsd000012A2bc03sc02i00 vendor : NVIDIA Corporation model : TU104GL [Tesla T4] driver : nvidia-driver-418-server - distro non-free driver : nvidia-driver-460 - distro non-free recommended driver : nvidia-driver-440-server - distro non-free driver : nvidia-driver-450 - distro non-free driver : nvidia-driver-450-server - distro non-free driver : xserver-xorg-video-nouveau - distro free builtinドライバーのインストール
$ sudo apt install nvidia-driver-460再起動をして問題なくインストールされたか確認
GPU(NVIDIA製)の確認$ lspci -vv | grep -i nvidia 00:04.0 3D controller: NVIDIA Corporation TU104GL [Tesla T4] (rev a1) Subsystem: NVIDIA Corporation TU104GL [Tesla T4] Kernel driver in use: nvidia Kernel modules: nvidiafb, nvidia_drm, nvidia※ドライバー情報が追加されていればOK。
nvidia-smiコマンドの動作確認$ nvidia-smi
dockerのインストール
【Dockerコンテナ内のUbuntuではsystemctlは使えない】の手順1を参考に。
※dockerバージョンはdocker-ce=5:19.03.14~3-0~ubuntu-focal
とするnvidia-docker2をインストール
GPUコンテナを作成・起動するために必要なパッケージをインストール。
リポジトリを追加してアップデート
https://nvidia.github.io/nvidia-docker# GPG鍵の登録 $ curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add - # リポジトリを追加 $ distribution=$(. /etc/os-release;echo $ID$VERSION_ID) $ curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list $ sudo apt updatenvidia-docker2のインストール
インストール可能なパッケージバージョンを確認$ apt-cache madison nvidia-docker2
# 最新版のインストール(今回はこちらを実行) $ sudo apt -y install nvidia-docker2 # バージョン指定をしてインストールする場合はこんな感じ $ sudo apt -y install nvidia-docker2=2.0.3+docker18.09.7-3 # 古いバージョンだと事前に他のパッケージもインストールが必要となる場合がある。(以下参考) $ sudo apt install nvidia-container-runtime-hook $ sudo apt install nvidia-container-runtime=2.0.0+docker18.09.7-3※現在は
nvidia-docker2
をインストールすると、nvidia-container-toolkit
も依存関係があり一緒にインストールされる。(nvidia-container-toolkit
の方が新しいパッケージ。)
nvidia-container-toolkit
パッケージのみをインストールした場合は、DockerがGPU にネイティブ対応したため、--runtime=nvidia
やnvidia-docker
コマンドは使えない。dockerのデーモン設定をリロード
$ sudo pkill -SIGHUP dockerd$ sudo nvidia-docker version NVIDIA Docker: 2.5.0 Client: Docker Engine - Community Version: 20.10.2 API version: 1.40 Go version: go1.13.15 Git commit: 2291f61 Built: Mon Dec 28 16:17:43 2020 OS/Arch: linux/amd64 Context: default Experimental: true Server: Docker Engine - Community Engine: Version: 19.03.14 ・・・・ ・・・・3.GPUコンテナの作成
GPUコンテナのイメージ取得
詳細はこちら https://hub.docker.com/r/nvidia/cuda/
$ docker image pull nvidia/cuda:11.1-base-ubuntu20.04
GPUコンテナの起動確認
最新コマンド(docker19.03以降でサポートされた`--gpus`オプションを使う場合)# 全てのGPUを使用する場合 $ docker container run --gpus all --rm nvidia/cuda nvidia-smi # 使用するGPUを指定したい場合 $ docker container run --gpus '"device=0,1"'--rm nvidia/cuda nvidia-smi※nvidia-docker2のバージョンが新し過ぎたせいか、
devices
などのオプション(環境変数?)の設定が足りてなくてnvidia-smi
実行ができなかった。旧コマンド(docker19.03以前+nvidia-docker2パッケージが入っている場合)$ docker container run --runtime=nvidia --rm nvidia/cuda:11.1-base-ubuntu20.04 nvidia-smi # or $ nvidia-docker run --rm nvidia/cuda:11.1-base-ubuntu20.04 nvidia-smi # 使用するGPUを指定したい場合 $ docker container run --runtime=nvidia NVIDIA_VISIBLE_DEVICES=0,1 --rm nvidia/cuda:11.1-base-ubuntu20.04 nvidia-smi