明日から研究で使えるDockerハンズオン2019/03/13ERTL@名古屋大学岡野兼也
View Slide
$ whoaminame:- 岡野兼也- @ジュジュbelonging:- 名古屋大学interest:- CloudNative- SREdream:- 働かないことhobbies:- 登山- キャンプ2
注意事項- 本講義はわからないことは検索しながら進めていくことが前提となっています- 質問タイムは適当に設けているので適宜質問してください- 別途ハンズオン中に個別の質問も受け付けます- ハンズオン終わった人はメンターを手伝ってください3
本ハンズオンで得られる知識- コンテナ技術やDockerの概要- Dockerの基本コマンドの使い方- Dockerfileの基本命令の使い方- 研究用途としてのDockerfileの書き方- ほかの研究者が作成したDockerのコンテナでデバッグ、一部改変の方法4
本ハンズオンで得られない知識- Dockerfileベストプラクティス- コンテナの運用知識- コンテナ上でGPUを使う方法- CloudNativeな環境が今どのようになっているのか- コンテナそのものの実装レベルでの知識5
機械学習についてはこちらhttps://speakerdeck.com/juju62q/machine-learning-environment-made-by-rancher6
事前セットアップ(Docker)Linuxの方Macの方curl -fsSL https://get.docker.com -o get-docker.shsh get-docker.shsudo gpasswd -a ${USER} dockersudo systemctl enable dockersudo systemctl restart dockerbrew install dockerbrew cask install dockeropen /Application/Docker.app7
事前セットアップ(docker-compose)Linuxの方Macの方sudo curl -L"https://github.com/docker/compose/releases/download/1.23.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-composesudo chmod +x /usr/local/bin/docker-compose(brew install sl)sl -l && sl -a && sl -alF(brew uninstall sl)8
事前セットアップ(確認)共通docker versiondocker container lsdocker-compose --version9
Dockerの世界にようこそ!10
本日やること- Dockerってなんで便利なの?- コンテナやDockerの概要- Dockerfileを書いてみる- デバッグ用途でdockerコマンドを利用する- docker-composeを使って複数のコンテナを管理する11
本日やること- Dockerってなんで便利なの?- コンテナやDockerの概要- Dockerfileを書いてみる- デバッグ用途でdockerコマンドを利用する- docker-composeを使って複数のコンテナを管理する12
アンケート他人の研究環境を再現するのは大変だと思う13
アンケート自分の研究環境が正直よくわからない14
アンケート正直、明日研究室のマシンが壊れたら一週間は進捗が出ない自信がある15
アンケート研究環境が何もしてないのに壊れた経験がある16
アンケート自分のPCが汚れると闇堕ちしてしまう17
そんなあなたに!18
19
Dockerを使ってできる世界- 自分の開発環境をテキストにして管理できる- 一度動いたものはDockerさえ動くならOSやマシンをまたいでもほぼ動作する- 引継ぎ資料がとても簡単になる- 他の人もすぐに使うことができる環境を作れる20
本日やること- Dockerってなんで便利なの?- コンテナやDockerの概要- Dockerfileを書いてみる- デバッグ用途でdockerコマンドを利用する- docker-composeを使って複数のコンテナを管理する21
仮想化おさらい 1/4①非仮想化環境22ハードウェアホストOSアプリケーション
仮想化おさらい 3/4②ゲストOS型仮想23ハードウェアVMware Workstation, VirtualBoxホストOS仮想化アプリケーション仮想マシンAアプリケーションゲストOS仮想マシンBアプリケーションゲストOS仮想マシンCアプリケーションゲストOS
仮想化おさらい 3/4③ハイパーバイザ型仮想(ソフトウェア)※厳密には完全仮想化と準仮想化で区別すべき。とくに Xenは異なるアーキテクチャを採用している。24ハードウェアVMware ESXi, Xen/Citrix XenServer, Microsoft Hyper-Vハイパーバイザ仮想マシンAアプリケーションゲストOS仮想マシンBアプリケーションゲストOS仮想マシンCアプリケーションゲストOS
仮想化おさらい 4/4④ハイパーバイザ型仮想(カーネルモジュール)25ハードウェアLinux KVMホストOSハイパーバイザ仮想マシンAアプリケーションゲストOS仮想マシンBアプリケーションゲストOS アプリケーション
コンテナ型”仮想化”詳しくは後述しますがいわゆる仮想化ではない26ハードウェアDocker, LXC, rkt, haciniwaホストOSコンテナエンジンコンテナAアプリケーションコンテナエンジン アプリケーションコンテナBアプリケーション
違いはなに?27
コンテナ型”仮想化”のメリット- 起動が速い- オーバヘッドが小さい- 小さなリソースに分割できる28OSが各個で動かないためにメリットが生まれる
コンテナ型”仮想化”のデメリット- ほぼ同一のカーネルでしか動かない- 分離が比較的弱い29OSが共通で動くためにデメリットが生じる
結局コンテナってどんなもの?30
31実際に動かしてみるホストから見るとプロセス(仮想化じゃない)
しかしながら…?32- コンテナでは自身のコンテナ以外へのアクセスを制限している- コンテナに与えるリソースを制限できるどうやって…?
Linux Namespace33ファイルシステム、プロセステーブル、ネットワークを分割するLinuxカーネルの機能ハードウェアホストOSユーザプロセスNamespace AユーザプロセスユーザプロセスNamespace Bユーザプロセスユーザプロセス…ユーザプロセス…
Linux Namespace34ファイルシステム、プロセステーブル、ネットワークを分割するLinuxカーネルの機能ハードウェアホストOSユーザプロセスNamespace AユーザプロセスユーザプロセスNamespace Bユーザプロセスユーザプロセス…ユーザプロセス…これがコンテナ!
Linux Namespace35namespace 説明Mount namespace ファイルシステムの分離UTS namespace ホストネームの分離IPC namespace IPC(プロセス間通信)の分離User namespace ユーザ(UID/GID)の分離PID namespace プロセステーブルの分離Network namespace ネットワーク設定の分離namespaceにいくつか種類があるので紹介します
cgroup36cgroups機能は、それぞれのグループに対してCPUやメモリ割り当てを制御する機能ハードウェアホストOSコンテナ Aユーザプロセスユーザプロセスコンテナ BユーザプロセスユーザプロセスCPU: 2コアメモリ: 4GBCPU: 1コアメモリ: 512MB
ここまでLinuxコンテナ。じゃあってなんなのさ?37
Dockerとは38Linuxカーネルの機能を統合し、コンテナを作り上げる管理ツール
Dockerの基本機能39Dockerfileと呼ばれる手順書に- どのイメージから始めるか- どんな操作を行うか- 起動時に何をするかを記述してDocker Imageを作る- DockerHubには公式で作られたImageが多数ある- これを元にして環境を作るのが好ましい(nvidia/cuda等例外もある)ベースImageImage層Image作成操作書き込み可能Image
Dockerの基本機能40リポジトリからpullしたイメージをコンテナに当てることで欲しいコンテナが起動できるハードウェアホストOSコンテナ Aユーザプロセスユーザプロセスコンテナ Bユーザプロセスレジストリhttps://hub.docker.com 等CentOSリポジトリUbuntuリポジトリtag: latesttag: 7tag: latesttag: 18.04Ubuntutag: 18.04pushpull
Dockerの基本機能41Dockerfileを書いてビルドを行い、Imageをリポジトリにpushしておけば誰でも同一環境が手に入る!レジストリhttps://hub.docker.com 等自分の研究リポジトリ他人の研究リポジトリtag: latest tag: latestpushpull
つまり…42Dockerとは- コンテナの構築手順をレイヤとして保持- 完成したコンテナイメージを登録- 他人の作ったコンテナイメージを実行&追加書き込み- LinuxNamespaceで実行環境を分離- cgroupでリソースを分割できるツール
質疑&休憩43
もっと詳しく知りたい人はこちら- コンテナ未経験新人が学ぶコンテナ技術入門NTTの方が作ったコンテナの基礎について丁寧に記述した資料( https://www.slideshare.net/KoheiTokunaga/ss-122754942 )- コンテナ技術入門 - 仮想化との違いを知り、要素技術を触って学ぼうはてなの方が作ったハンズオン形式でコンテナの構成技術に触れあえる資料( https://employment.en-japan.com/engineerhub/entry/2019/02/05/103000 )- コンテナのセキュリティを中身から理解しようペパボの方が作ったコンテナを攻撃して遊んでみる資料( https://speakerdeck.com/udzura/inside-out-container-and-its-security )どれも面白いのでぜひ!44
本日やること- Dockerってなんで便利なの?- コンテナやDockerの概要- Dockerfileを書いてみる- デバッグ用途でdockerコマンドを利用する- docker-composeを使って複数のコンテナを管理する45
問題集取得方法答えの確認方法git clone https://github.com/Juju-62q/docker-handson.gitgit checkout answer46
まずはコンテナを動かしてみようdocker image pull ubuntu:18.04docker container run -it ubuntu:18.0447bashに入れた!ユーザ名も変わった!
まずはコンテナを動かしてみようdocker image pull ubuntu:18.04docker container run -it ubuntu:18.0448DockerImageをDockerHubから引っ張る引っ張ったコンテナイメージでコンテナを動かす-i インタラクティブ-t ttyを割り当てる
Dockerfileをちらっとみてみよう# base imageの指定FROM python:3.7.2# ファイルの追加COPY requirements.txt ./# 環境構築の処理を書くRUN pip install -r requirements.txt# プログラムを追加COPY app.py ./# ポート開放EXPOSE 5000# 起動コマンドの指定CMD ["python", "app.py"]49
自前Dockerfileの動かし方50docker image build -t Juju-62q/hoge .docker container run Juju-62q/hogeカレントディレクトリのDockerfileをビルドする-t imageに名前を付ける(DockerHubの名前と対応させる)ビルドしたコンテナイメージでコンテナを動かす※こちらやらなくていいです
自前DockerfileをDockerHubに保存51docker image build -t Juju-62q/hoge:20190313 .docker image push Juju-62q/hoge:20190313カレントディレクトリのDockerfileをビルドする-t “ : ”以降でバージョンを管理できるビルドしたコンテナイメージをpushする※こちらやらなくていいです 要DockerHubのアカウントとリポジトリ
Dockerfileのコマンドまとめ52コマンド名 説明FROM ベースイメージの指定RUN コマンドを実行する(レイヤ作る)COPY ローカルのファイル/ディレクトリをコピーする(レイヤ作る)CMD 起動時のコマンド指定WORKDIR カレントディレクトリの変更ADD COPYより機能が豪華(レイヤ作る)EXPOSE ポートの開放ENV 環境変数の追加VOLUME ボリュームの作成USER ユーザの変更ARG ビルド時に変数を使うONBUILD 毎回ビルド時に実行するENTRYPOINT docker runのときの基本実行コマンド
Dockerfileのコマンドまとめ53コマンド名 説明FROM ベースイメージの指定RUN コマンドを実行する(レイヤ作る)COPY ローカルのファイル/ディレクトリをコピーする(レイヤ作る)CMD 起動時のコマンド指定WORKDIR カレントディレクトリの変更ADD COPYより機能が豪華(レイヤ作る)EXPOSE ポートの開放ENV 環境変数の追加VOLUME ボリュームの作成USER ユーザの変更ARG ビルド時に変数を使うONBUILD 毎回ビルド時に実行するENTRYPOINT docker runのときの基本実行コマンドとても覚えてほしい
Dockerfileのコマンドまとめ54コマンド名 説明FROM ベースイメージの指定RUN コマンドを実行する(レイヤ作る)COPY ローカルのファイル/ディレクトリをコピーする(レイヤ作る)CMD 起動時のコマンド指定WORKDIR カレントディレクトリの変更ADD COPYより機能が豪華(レイヤ作る)EXPOSE ポートの開放ENV 環境変数の追加VOLUME ボリュームの作成USER ユーザの変更ARG ビルド時に変数を使うONBUILD 毎回ビルド時に実行するENTRYPOINT docker runのときの基本実行コマンドやや覚えてほしい
Dockerfileのコマンドまとめ55コマンド名 説明FROM ベースイメージの指定RUN コマンドを実行する(レイヤ作る)COPY ローカルのファイル/ディレクトリをコピーする(レイヤ作る)CMD 起動時のコマンド指定WORKDIR カレントディレクトリの変更ADD COPYより機能が豪華(レイヤ作る)EXPOSE ポートの開放ENV 環境変数の追加VOLUME ボリュームの作成USER ユーザの変更ARG ビルド時に変数を使うONBUILD 毎回ビルド時に実行するENTRYPOINT docker runのときの基本実行コマンド使うととてもおしゃれなDockerfileが作れる
ではさっきクローンした問題のex4までやりましょう!56
問題について- Pythonで作っています- インタプリタのほうが実行が楽- RubyとPythonなら研究室ではPythonのほうがつかえる人多そう- 遊びたい人はほかの言語使ってもOK- ちょっと難しいかもしれないです- 適宜呼んでいただければ対応します- 助け合ったりググったりして解いてください57
質疑58
もっと詳しく知りたい人はこちら- Best practices for writing DockerfilesDocker公式が書いているベストプラクティス( https://docs.docker.com/develop/develop-images/dockerfile_best-practices )- 改めてDockerfileのベストプラクティスを振り返ろうオイシックス・ラ・大地の方が作った上の資料を圧縮した資料(https://www.slideshare.net/ssuser1f3c12/introduce-that-best-practices-for-writing-dockerfiles )- The Twelve-Factor AppPaaSやコンテナを動作させるときに注意することまとめ( https://12factor.net/ja/ )実運用で大事になる書き方がまとめられているのでよければ59
本日やること- Dockerってなんで便利なの?- コンテナやDockerの概要- Dockerfileを書いてみる- デバッグ用途でdockerコマンドを利用する- docker-composeを使って複数のコンテナを管理する60
でもでも…?61他人の研究のコンテナイメージ引っ張ってコマンドがbashとかじゃなかったらデバッグできなくない?
例えば…Pythonのコンテナを実行するdocker container run -it python:3.7.262そらみたことか!
起動コマンドを変えてみるPythonのコンテナを実行するdocker container run -it python:3.7.2 bash63ここに起動コマンドを記述可能
まだまだ…?64僕の研究機密情報扱ってるからDockerHubにpushできない!あと、機械学習とかでデータがでかいとそもそもそのデータイメージに含めたら地獄じゃない?
Data Volume- ホストと共有- ホストマシンのデータをイメージに含めずにコンテナ内部からも扱えるようにする- 認証情報とかを扱うときに利用- コンテナに作成- コンテナの内部に永続ボリュームを作る- DBの中身とかを扱うときに便利- コンテナを跨いで共有65
Data Volume- ホストと共有- ホストマシンのデータをイメージに含めずにコンテナ内部からも扱えるようにする- 認証情報とかを扱うときに利用- コンテナに作成- コンテナの内部に永続ボリュームを作る- DBの中身とかを扱うときに便利- コンテナを跨いで共有66研究用途だとこれが割と便利
ホストのディレクトリをマウントするディレクトリを作ってコンテナと共有するmkdir testecho "hello volume from host" > data_volume/from_hostdocker container run -it \-v "$(pwd)/test":/data_volume python:3.7.2 bashcat data_volume/from_hostecho "hello volume from container" \> data_volume/from_containerexitcat test/from_containerrm -rf test67
ホストのディレクトリをマウントする結果68コンテナで作ったものがホスト側にあるホストで作ったものがコンテナ側にある
コンテナにポートフォワードするホストの8080をコンテナの80にフォワードするdocker container run -p 8080:80 nginx(別ターミナルを開く)curl localhost:808069
問題のex6までやりましょう!70
質疑71
本日やること- Dockerってなんで便利なの?- コンテナやDockerの概要- Dockerfileを書いてみる- デバッグ用途でdockerコマンドを利用する- docker-composeを使って複数のコンテナを管理する72
まだいける…?73でもでも、僕dockerコマンドなんて多すぎて覚えられないんだけど?どうにかならんの?
docker-compose- コンテナの動かし方をyamlで記述できる- どのイメージをどの名前で使うかを記述できる- 各オプションをどのように記述するかを定義できる- 複数のコンテナを一括で管理できる- コンテナネットワークをいい感じに貼ってくれる- どういう関係なのかも定義できる74
docker-compose.ymlを覗いてみようversion: '3'services:klee:image: klee/klee:latestvolumes:- ./target_files:/home/klee/klee_src/target- ./shells:/home/klee/shellsulimits:stack:soft: -1hard: -175
docker-compose.ymlを覗いてみようversion: '3'services:klee:image: klee/klee:latestvolumes:- ./target_files:/home/klee/klee_src/target- ./shells:/home/klee/shellsulimits:stack:soft: -1hard: -176Data Volumeの記述docker-composeでは相対パスの記述が可能イメージの記述が宣言的に可能
docker-composeの動かし方77docker-compose up --builddocker-compose run klee bashコンテナ群を起動させる--build コンテナをビルドしながら起動するコンテナで任意の命令を動かす※こちらやらなくていいです
少し細かいプラクティス781つのコンテナでは、1つだけプロセスを動かすべきハードウェアホストOSコンテナ APythonコンテナ BMySQLコンテナ BNginx
複数のコンテナも管理できるversion: '3'services:api:build: .ports:- "5000:5000"volumes:- "./src:/src"tty: trueenvironment:TZ: Asia/TokyoFLASK_APP: run.pyFLASK_ENV: developmentcommand: flask run -h 0.0.0.0db:build: ./mysql/volumes:- ./mysql/mysql_data:/var/lib/mysql- ./mysql/sqls:/docker-entrypoint-initdb.denvironment:- MYSQL_ROOT_PASSWORD=hoge79※こちらやらなくていいです
複数のコンテナも管理できるversion: '3'services:api:build: .ports:- "5000:5000"volumes:- "./src:/src"tty: trueenvironment:TZ: Asia/TokyoFLASK_APP: run.pyFLASK_ENV: developmentdepends_on:- dbdb:build: ./mysql/volumes:- ./mysql/mysql_data:/var/lib/mysql- ./mysql/sqls:/docker-entrypoint-initdb.denvironment:- MYSQL_ROOT_PASSWORD=hoge80指定ディレクトリのDockerfileを対象とする(もっと細かく指定もできる)ポートフォワードの記述環境変数の記述(.envファイルを作って管理するのが一般的)※こちらやらなくていいです
問題のex7をやりましょう!(DB面倒くさいのでNginxです)81
質疑82
もっと詳しく知りたい人はこちら- Docker Compose 徹底解説さくらインターネットの方が書いている資料( https://www.slideshare.net/zembutsu/docker-compose-guidebook )Docker Composeの使い方から実運用まで簡単に書かれています83
ここまででハンズオンは終了です84
まとめ- Dockerfileを使うことで自分の研究環境が明らかになる- Docker使うと他人の研究環境の再現が簡単- コンテナの中でデバッグもできる- ホストのディレクトリも読むことができる- 起動コマンドも簡単に管理できる- プロセスたくさんあっても一括処理できる85
お越しいただきありがとうございました&長丁場、お疲れさまでした86