社会人インターンシップ制度を利用してDockerをやってみた
https://gyazo.com/2224b4828ce0002c917cc91d12625196
https://www.docker.com/sites/default/files/d8/styles/role_icon/public/2019-07/Moby-logo.png?itok=sYH_JEaJ
はじめに
むとうは現在、日本仮想化技術株式会社の社会人インターシップ制度を利用してDockerやKubernetesについての実習を行なっています。 今回は、以下のようなことについてまとめてみました。
この社会人インターシップ制度の詳細
むとうが現在のところの理解しているDockerについてのお話
自己紹介:むとうについて
所属コミュニティ
日本仮想化技術株式会社
仮想化技術のエキスパート集団
進取の精神
豊富な検証機材で新技術を追求
自由な雰囲気の職場
そのほかにも、以下のような特徴があります。
日本仮想化技術株式会社の社会人インターシップ制度
インターンシップの特徴は、以下の通りです。
必ずしも採用目的ではない
社会的貢献の一つの方法(≒寄付講座など)
本人がやりたいと思うことを支援するポリシー
まとめ方法に関しても、特に縛りはない
社会人インターシップの受け入れもあり
スキルアップやキャリアアップのお手伝い
遠方でもOK
インターンシップを受けるために準備する書類は以下のようなものです。
書式に特に指定はありません。
履歴書
職務経歴書
インターンシップの進め方は以下のようになります。
目標の設定
技術的な研究、スキル修得のためのテーマ設定や計画
実際の作業
必要な都度、情報提供などのメンタリング(指導、助言)
(必要に応じて)作業のまとめ
必要に応じて、機材の貸し出しや提供などもあります。
作業用端末(MacBookなど)貸し出し
Jetson NanoやRaspberry Piの貸し出し
高価な機材も可能な限り、調達、貸与
書籍の購入なども
むとうの場合、macOS Catalina での Docker Desktop for Macの検証のために、Mac mini (Late 2014)をいただいた
申し込み:むとうの場合
以下のような手順で申込を行います。
recruit@virtualtech.jpに申し込みメールを送る
用意する書類
履歴書
職務経歴書: 職務ごとに分けたものだけで十分です。
作成する書類など: 特になし(契約書類はなし)
目標の設定:むとうの場合
インターンシップを進めるにあたって、目標を設定する必要があります。
私の場合、以下のようなやり取りで、目標の設定を行いました。
むとうがはじめに提案した内容(趣味に走り過ぎていて、無謀)は以下の通りです。
1. 以下のような、仮想化技術を試してみたい。
その結果をまとめて得失表を作りたい
- chroot
- FreeBSD jail
- FreeBSD bhyve
- フリーのVM環境(VirtualBoxなど)
- Xen
- Docker
- Kubernetes
2. Raspberry Piで、どこまでどのような仮想環境が利用できるのか試してみたい
これに対して、メンターから現実的な内容を提案してもらいました。
・Dockerについての調査
・Kubernetesについての調査
・Kubernetes on Raspberry Piについての調査
また、目標とは別に、これからの仕事に関する要望や、将来的な展望などの明確化も行いました。
奈良在住なので、リモートワークが可能なこと。
時短(午前中-14:00程度)でできる仕事であること。
障害者(むとう)に理解のある仕事であること。
作業の進め方:むとうの場合
むとうの作業の進め方は、以下のような感じです。
インターンシップ期限: 特に定めず
作業時間: 専業主夫なので平日9:00-14:00ぐらい
必ずしも平日全部を使うわけではなく、作業をしない日もある
作業内容
興味のおもむくままに作業する
必ずしも、最小手数で作業を進めようとは考えていない: 寄り道することも多い
作業がまとまってからの報告書では、なかなか文章化が難しい
日々の作業進捗をまとめておくことで、後に同じようなことをする人にも役にたつかも
キーワードなどごとにまとめた報告書は、まとまるたびに作成
作業報告書に基づいて、今回の作業についてのコメントや、これからの作業の方針などをもらう
今のところ、オフィスを訪ねたり、Zoomなどによるリモート会議での打ち合わせなどは無し
仮想化いろいろ
仮想化とはなんでしょうか?
仮想化とは、コンピュータ上にあたかも別のコンピュータが動作しているかのようにする技術です。
大きくわけて、以下の二つの仮想化方法がよく用いられます。
仮想マシン型仮想化
コンテナ型仮想化
以下、Docker社の提供する図を元に説明していきます。
仮想マシン型仮想化の動作の様子を以下の図に示します。
ここでは、ハイパーバイザー(Hypervisor)層が物理的なコンピュータそのもののように振舞うことで、その上に好きなゲストOS(Guest Operating System)を動作させることができます。
この時、OSは、ホストOSと同じLinuxだけではなく、WindowsやFreeBSDなどを実行することも可能です。
https://www.docker.com/sites/default/files/d8/2018-11/container-vm-whatcontainer_2.png
これに対して、Dockerをはじめとするコンテナ型仮想化の動作の様子は以下の図のようになります。
ホストOS(Host Operating Sysytem)上に、Dockerコンテナサポート層があり、この上でLinuxのアプリケーション(Containerized Application: AppA-F)が動いています。
このアプリケーション同士は隔離されており、アプリケーション毎にファイルシステムやユーザ、プロセスなどの情報は参照できなくなっています。
仮想マシン方式に比べて、ゲストOSを動かすためのハードウエアエミュレーションなどが必要ない分、オーバーヘッドは小さくなります。
https://www.docker.com/sites/default/files/d8/2018-11/docker-containerized-appliction-blue-border_2.png
まとめると、コンテナ仮想化の特徴は、以下のようになります。
仮想マシンに比べて動作が軽い
ファイルシステム、ネットワーク、ユーザ、プロセスなどの資源の仮想化と分離が可能
不要なアプリケーションを動かさない/入れないようにすることで、セキュリティー向上が可能
Dockerってなんぞや?
Dockerは、Linuxで利用できるコンテナ型仮想化技術です。 Linux用のコンテナ仮想化技術ですが、ホストOSで仮想マシン(VM)を利用してLinux kernelを動かすことで、macOS(HyperKit)やWindows(Hyper-V)でも利用可能です。
Dockerでは、単にコンテナ型仮想化を実現するだけではなく、作成したコンテナイメージを共有したり、そのイメージを元に新たなイメージを作成したりが簡単にできるようになっています。
コンテナイメージの作成には、Dockerfileというファイルを利用しますが、このファイルはサーバなどの構築指示書となるため、共同作業者間でサーバに関する情報の共有をするためにも役立ちます。
Docker DesktopでDockerを試してみる
Docker Desktop以外にもDocker環境を作成する方法はありますが、手軽さと利便性の面で、初めてDocker環境を構築するためには、Docker Desktopを使った方が良いと思います。
Docker Desktopは、以下のようなソフトウエアを含んだ、オールインワンパッケージです。
このため、DockerからKubernetesへのステップアップも可能になっています。
Docker Engine
Docker CLI クライアント
Notary
Docker Desktopには、コンテナイメージの操作からコンテナの起動/終了、ログの確認などを行えるGUIがあります。
Linux用コンテナを利用するための仮想マシン(VM)としては、以下のようなものを利用しています。
Windows: Hyper-VとWindowsコンテナ/Linuxコンテナ
たった4ステップで時間2分のチュートリアルがありますが、これにはDocker Hubへのコンテナイメージアップロードまでの作業が行えるようになっています。
dockerコマンドラインインターフェース(CLI)について
Dockerの操作のために、dockerというコマンドがあります。
dockerコマンドを引数なしで実行すると、利用できるコマンド一覧が表示されます。
docker help cmdもしくはdocker cmd --helpとすることで、各コマンドの利用方法が表示されます。
dockerコマンドでよく使われるものは、以下のようなものです。
table:docker command
コマンド 機能 備考
pull <イメージ名> イメージの取得
run Dockerコンテナを起動 -it /bin/sh
ps 動いているDockerコンテナを確認
exec <コンテナID> -it <cmd> コンテナ内で任意のコマンドcmdを実行 シェルなどを使う場合は-it必須
stop <コンテナID> コンテナを停止
attach <コンテナID> コンテナに接続
images pullされているイメージの一覧
rmi <イメージ名> -f イメージの削除
inspect <コンテナID> コンテナの詳しい情報を出力
build -t <リポジトリ>:<tag> <dir> Dockerfileに基づいてイメージを作成 詳細は後述
おまけ: dockerコマンドがスーパユーザやsudoを使ってしか動かない場合、利用しているユーザがdockerグループに所属していないことがあげられます。
この場合、以下のように/etc/groupを修正することで、sudoなしでdockerコマンドが利用可能になります。
code:/etc/group
docker:x:994:<your_username>
My dockerイメージを作る:Dockerfile
Dockerは、他人が作成しdocker hubなどで公開されているイメージを使うだけでも便利ですが、自分好みのイメージを作成することもできます。
このために使われる設定ファイルがDockerfileです。
Dockerfileを作成することで、サーバ構築のための指示書を作成したのと同じ効果があり、同じイメージに関する情報を共有することが容易になります。
Dockerfileには、以下のような項目を設定することが可能です。
table:Dockerfile
コマンド 意味
FROM ベースとなるイメージ
MAINTAINER メンテナンスをしている人
ENV 環境変数の定義
RUN イメージを作るために実行するコマンド
ADD ファイルをイメージに追加
EXPOSE 外部に公開するポート
ENTRYPOINT イメージを実行した時に実行されるコマンド
以下は、Dockerfileの例です。
code:Dockerfile
FROM centos:latest
MAINTAINER Takeshi MUTOH <takeshi.mutoh@gmail.com>
ENV container docker
RUN yum update -y && yum clean all
RUN yum install -y httpd && yum clean all
RUN echo "Hello Apache." > /var/www/html/test.html
EXPOSE 80
このDockerfileファイルでは、以下のようなステップでイメージが作成されます。
Step 1:FROM centos:latestの記述に従って、最新のCentOSコンテナイメージのcentos:latestを取する。
Step 2:MAINTAINERの記述に従って、メンテナを設定する。
Step 3:ENVの記述に従って、環境変数を設定する。
Step 4:一つ目のRUNの記述に従って、yum update -y && yum clean allを実行し、OSの最新版への更新を行う。
Step 5:二つ目のRUNの記述に従って、yum install -y httpd && yum clean allを実行し、httpdをインストールする。
Step 6:三つ目のRUNの記述に従って、/index.htmlの内容をHello Apache.にする。
Step 7:EXPOSE 80の記述に従って、
Step 8:ENTRYPOINT ["/usr/sbin/httpd","-DFOREGROUND"]の記述に従って、コンテナ起動時に実行されるコマンドを/usr/sbin/httpdにする。
Dockerfileからコンテナイメージを作成するためには、docker buildコマンドを使います。
docker buildには、CPUやメモリなどの資源のためのコマンドラインオプションがたくさんあるのですが、基本的には以下のように使います。
code:shell
$ sudo docker build -t centos:httpd .
ここで特徴的なのは、docker buildコマンド結果がキャッシュされており、Dockerfileが更新された場合は変更された箇所からの更新となるため、高速に更新作業が可能となることです。
例題:最新CentOSのイメージで作業する
はじめに、最新のCentOSイメージであるcentos:latestを実行してみましょう。
docker pullでこれから作業するイメージを取得します。
code:shell
% docker pull centos:latest
latest: Pulling from library/centos
7a0437f04f83: Already exists
Digest: sha256:5528e8b1b1719d34604c87e11dcd1c0a20bedf46e83b5632cdeac91b8c04efc1
Status: Downloaded newer image for centos:latest
docker.io/library/centos:latest
docker runコマンドを以下のように実行します。
これで、このコンテナイメージでシェル/bin/bashを実行して、起動します。
code:shell
% docker run -it centos:latest /bin/bash
この時、ホスト側でdocker psを実行すると、コンテナが動作していることがわかります。
code:shell
% docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
dd5bacc215b3 centos:latest "/bin/bash" About a minute ago Up About a minute dazzling_matsumoto
このイメージでは、パッケージは173個インストールされているようです。
code:shell
Failed to set locale, defaulting to C.UTF-8
173 518 13951
例題:コンテナイメージ内で作業する
このコンテナで、httpdをインストールして実行してみましょう。
後でのネットワーク情報の調査のために、net-toolsもインストールしておきます。
code:shell
(snip)
(snip)
(snip)
(snip)
この状態で、ネットワークの構成は、以下のようになります。
code:shell
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.2 netmask 255.255.0.0 broadcast 172.17.255.255
ether 02:42:ac:11:00:02 txqueuelen 0 (Ethernet)
RX packets 8687 bytes 12432854 (11.8 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 5583 bytes 309664 (302.4 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN
code:shell
Hello my httpd
このコンテナを終了します。
今回の例では、シェルを終了すればいいので、Ctrl-Dを使うか、exitコマンドを使います。
code:shell
再度、このイメージを実行すると、前回起動後にインストールしたパッケージが消えているなど、作業がリセットされていることがわかります。
これは、docker runでは、毎回初期のコンテナイメージからコンテナを作成するためです。
code:shell
Failed to set locale, defaulting to C.UTF-8
173 518 13951
これでは、起動する度に設定を繰り返さなければなりません。
そこで、登場するのがDockerfileです。
例題:Dockerfileによるコンテナイメージの作成
Dockerfileによる新規コンテナイメージの作成の手順は、以下のようになります。
はじめに、今回の作業をなぞった以下のようなDockerfileを作成します。
また、EXPOSEを使って、TCP/IPポート80を外部に公開しています。
さらに、ENTRYPOINTで、コンテナイメージの起動時に実行されるコマンド/usr/sbin/httpdを指定します。
code:Dockerfile
FROM centos:latest
MAINTAINER Takeshi MUTOH <takeshi.mutoh@gmail.com>
ENV container docker
RUN yum update -y
RUN yum install -y net-tools
RUN yum install -y httpd
RUN yum clean all
RUN echo "Hello my httpd." > /var/www/html/test.html
EXPOSE 80
このDockerfileから、My Dockerイメージを以下のようにdocker buildコマンドを用いて作成します。
code:shell
% docker build -t centos:my_httpd .
+ Building 0.1s (10/10) FINISHED => internal load build definition from Dockerfile 0.1s => => transferring dockerfile: 38B 0.0s
=> => transferring context: 2B 0.0s
=> internal load metadata for docker.io/library/centos:latest 0.0s => 1/6 FROM docker.io/library/centos:latest 0.0s => CACHED 2/6 RUN yum update -y 0.0s => CACHED 3/6 RUN yum install -y net-tools 0.0s => CACHED 4/6 RUN yum install -y httpd 0.0s => CACHED 5/6 RUN yum clean all 0.0s => CACHED 6/6 RUN echo "Hello my httpd." > /var/www/html/test.html 0.0s => exporting to image 0.0s
=> => exporting layers 0.0s
=> => writing image sha256:1c60b5bb05935dab6b37055fdc7cf58283244f5f06259 0.0s
=> => naming to docker.io/library/centos:my_httpd 0.0s
このイメージを実行すると、名前解決に関するエラーが出ますが、httpdが起動します。
code:shell
% docker run centos:my_httpd
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.3. Set the 'ServerName' directive globally to suppress this message
他の端末から、docker execでシェルを実行することで、コンテナ内部で操作が可能になります。
code:shell
% docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
85ac38da56d6 centos:my_httpd "/usr/sbin/httpd -DF…" 11 seconds ago Up 10 seconds 80/tcp objective_carson
% docker exec -it 85ac38da56d6 bash
シェルを使って、コマンドを利用して、以下のように情報を得ることができます。
code:shell
PID TTY STAT TIME COMMAND
1 ? Ss 0:00 /usr/sbin/httpd -DFOREGROUND
6 ? S 0:00 /usr/sbin/httpd -DFOREGROUND
7 ? Sl 0:00 /usr/sbin/httpd -DFOREGROUND
8 ? Sl 0:00 /usr/sbin/httpd -DFOREGROUND
9 ? Sl 0:00 /usr/sbin/httpd -DFOREGROUND
221 pts/0 Ss 0:00 bash
235 pts/0 R+ 0:00 ps ax
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN
code:shell
Hello my httpd.
そしてKubernetesへ
Dockerを利用する場合、各コンテナは問題の切り分けや、セキュリティ的な観点から、単一の機能を持ったものに限定することが多くなります。
例えば、外部に公開している方Webサービスなどを考えると、以下のような要素から構成されることになります。
Webサーバ(httpd): 負荷分散のために複数動かすことも多い。
データベースサーバ: Webサーバ用のデータなどを記録する。
ロードバランサ: Webサーバへのアクセスを各Webサーバに振り分ける。
これらのサーバ群を手動で実行したり、調整したりするのは大変な作業です。
このような作業を指揮(オーケストレーション)といいますが、これを行うためのソフトウエアがKubernetesになります。 Kubernetesには、他にも以下のような機能があります。
サービスディスカバリーと負荷分散
ストレージ オーケストレーション
自動化されたロールアウトとロールバック
自動ビンパッキング
自己修復
機密情報と構成管理
おわりに
社会人インターンシップを初めて1ヶ月ちょっとですが、とても楽しい毎日です。
Dockerについて何も知らない状態からはじめましたが、「チョットワカル」程度には成れたかと。
さあ、次はKubernetesだ!!
参考文献
社会人インターンシップに関するむとうの文章には、以下のようなものがあります。
他で提供されていて、役にたった文章としては、以下のようなものがあります。