Docker & Kubernetes基礎
Daisuke Hiraoka(平岡 大祐)
• IBM Champion for Cloud 2019
• 2013年からオンプレミスシステムからIBM Cloudへの移行を支援
• 2016年からIBM CloudでOpenShift/Kubernetes/Dockerの運用を開始
• 書籍「コンテナ・ベース・オーケストレーション Docker/Kubernetes
で作るクラウド時代のシステム基盤」第9章 OpenShift Developerにて
OpenShiftでDevOpsをやるためのチュートリアルを執筆
• Red Hat Certified Specialist in OpenShift Administration(EX280)
Twitter: @HiraokaDaisuke
Linkedin: @Daisuke Hiraoka
• デモ環境について
• コンテナとは
• Dockerとは
• Dockerデモ
• Kubernetesとは
• Kubernetesデモ
デモ環境
• CentOS7にIBM Cloud CLIツールをインストール
DockerはIBM Cloud CLIツールをで導入されるものを使用
※インストール後、dockerの起動を実施
# systemctl start docker
• Kubernetesは IBM Cloud Kubernetes Serviceの無料クラスタを使用
• デモ環境は「IBM Cloud Kubernetes Service ワークショップ」セット
アップガイドで作成できます。
https://ibm-cloud-labs.github.io/iks-handson-setup/
コンテナとは?
• コンテナは、ランタイム環境全体(バイナリ、ファイル、依存
関係など)でアプリケーションをパケージ化、分離できる技術
です。
• ホストから見ると、プロセスが立ち上がるだけなので起動が早
い。
• コンテナ化されたアプリケーションを環境間で簡単に移動しな
がら完全な機能を維持できる。
• DockerHubやベンダーが提供するコンテナイメージを利用する
ことができる
コンテナと仮想マシン
ハードウェア
ハイパーバイザー
・OS/Kernelを占有
・仮想マシン毎に隔離
・コンテナはOS/Kernelを共有、プロセスとし
て起動
・プロセスをグループ(コンテナ)化して隔離
・コンテナ毎にファイルシステムを持つ
ハードウェア
OS/Kernel
コンテナエンジン
仮想マシン
ミドルウェア
アプリ
OS/Kernel
空き領域
仮想マシン
ミドルウェア
アプリ
OS/Kernel
空き領域
コンテナ
ミドルウェア
アプリ
必要最低限のファ
イルシステム
コンテナ
ミドルウェア
アプリ
必要最低限のファ
イルシステム
OS/Kernel
/, /boot ,/dev,
/etc /home, …
/, /boot ,/dev,
/etc /home, …
• コンテナはホストOSのLinuxカーネル技術を使ってLinuxで動くプロセスをコンテナのように隔離し
た状態で分離する技術
- 仮想マシンと違い、プロセスレベルで管理
- 全てのプロセスは、ホストOSのKernelでで実行される
• 名前空間(namespace)の機能を使ってコンテナ毎の隔離、分離を実現
→コンテナ化
• cgroups(コントロールグループ)の機能を使ってコンテナが利用する
物理マシンのリソース(CPU、メモリなど)の割り当てを管理
• 名前空間(namespace)毎に下記のリソースを持つ
• PID - プロセスID
• USER - ユーザーおよびグループID
• NS - マウントポイント
• NET - IPアドレス、ポート番号、ルーティングなどのネットワーク
• IPC – メッセージキューなどのプロセス間通信に関して
• cgroups
• コンテナ毎に分離したファイルシステムを持つ
コンテナとは(もう少し深掘りすると…)
コンテナ
ハードウェア
OS/Kernel
コンテナエンジン
コンテナ
コンテナ毎に分離された名前空間
コンテナ毎に分離されたファイルシステム
PID,USER,NS,NET
,IPC,cgroups
PID,USER,NS,NET
,IPC,cgroups
Dockerとは
• Docker はアプリケーションを開発(developing)・移動
(shipping)・実行(running)するための、プラットフォーム
です。
• Dockerはイメージの管理、Dockerイメージを使ったコンテナ
の作成から実行までライフサイクルを管理
Build
(イメージの作成)
Ship
(イメージの共有)
Run
(イメージの実行)
Docker Hub
リポジトリ
ソース
コード
Docker
イメージ
開発環境 本番環境
初めてのコンテナの実行(1)
# docker run ubuntu echo Hello World
# docker run ubuntu echo Hello World
Docker EngineDockerクライアント Docker Hub
① run
② pull
Ubuntu
イメージ
Ubuntu
イメージ
Ubuntu
イメージ
ルートファイ
ルシステム
③ ubuntuイメージ(read-only)に
read/write可能なルートファイルシステム
を追加してコンテナ化
④コンテナ起動、echo Hello Worldを実行
その結果を出力する
もしローカルにイメージが
なければ、ダウンロード
初回はイメージの容量に
よってはダウンロードに時
間がかかる
⑤echo Hello Worldコマンド終了とともに
コンテナ停止
コンテナを実行
するコマンド
実行するイ
メージ名
コンテナ内で実行する
コマンド
Dockerコンテナが実行されるの
は、指定したコマンドを処理し
ていた間のみ(プロセス)
latest
イメージ名にタグの指定がなければ
latestのイメージを取得
例) ubuntu:タグ名 -> ubuntu:v1
タグで履歴管理
read-only
read/write
初めてのコンテナの実行(2)
# docker run ubuntu echo Hello World <- ubuntuのコンテナを起動してechoコマンドを実行
Unable to find image ‘ubuntu:latest’ locally <- ローカルにubuntuのイメージがない
latest: Pulling from library/ubuntu<- DockerHubのからlibrary/ubuntuのlatestイメージを取得
35c102085707: Pull complete
251f5509d51d: Pull complete
8e829fe70a46: Pull complete
6001e1789921: Pull complete
Digest: sha256:d1d454df0f579c6be4d8161d227462d69e163a8ff9d20a847533989cf0c94d90
Status: Downloaded newer image for ubuntu:latest <- ローカルにubuntuのイメージ取得終了
Hello World <- echo Hello Worldの実行結果が出力
# <- Hello Worldの出力後、コンテナ終了し、Dockerホストのシェルに戻る
コンテナ内部の端末操作(1)
# docker run –it ubuntu bash
コンテナのプロセスに対して tty を割り当てる
コンテナ内で実行するコマンド
実行するイ
メージ名
# docker run –it ubuntu bash
Docker EngineDockerクライアント Docker Hub
① run
Ubuntu
イメージ
ルートファイ
ルシステム
②ubuntuイメージにルートファイル
システムを追加してコンテナ化
③コンテナ起動、bashを実行
コンテナのプロセスに対してttyを割り
当ててbashプロンプトを出力
ローカルにUbuntuのイメー
ジがあるので、DockerHub
にpullしない
④bashもプロセスなので、こ
のコンテナはbashを終了する
までDockerコンテナが実行さ
れる
Dockerホスト
Ubuntu
イメージ
bash /dev/pts/0
コンテナを実行するコマンド
Dockerコンテナ
/dev/console bash
引用: https://teratail.com/questions/19477
コンテナのプロセスに
対してのtty割当て
ホストとコンテナのttyの関係
read-only
read/write
コンテナ内部の端末操作(2)
# docker run -it ubuntu bash <- 今回は実行するコマンドがecho から bash に変わった
root@fb21c0b378de:/# pwd <- コンテナのシェルが出力される
/ <- 初期はルートディレクトリ
root@fb21c0b378de:/# ls <-ルートディレクトリの内容が出力される
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
root@fb21c0b378de:/# ps –ef <- プロセスの一覧を出力
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 11:12 pts/0 00:00:00 bash <- rootユーザで実行される PID1で実行
root 10 1 0 11:12 pts/0 00:00:00 ps –ef
※コンテナは自分の所有するプロセスのみ表示される。
root@fb21c0b378de:/# exit <-exitでコンテナのbashを抜けるまで、 コンテナは実行される。
exit
# <- Dockerホストのシェルに戻る
ルートファイルシステムは分離
(chroot)されているので rm –rf
/etc/passwdなどしても、ホストOS
には影響しない
Docker イメージ
・Dockerコンテナ作成時に必要となるファイル群の総称です。
・DockerコンテナはDockerイメージを元に作成される。
・Dockerイメージは必要最低限のルートファイルシステム(/etc、
/bin、/varなど)とアプリやミドルのデータとコンテナ実行時のメタ
データから構成される
・メータデータは、コンテナ実行時に実行するコマンド、環境変数や
ポート番号の公開が定義されている
- イメージの特徴
読み込み専用である
イメージレイヤ(層)の積み重ねでできている ミドルウェア
アプリ
必要最低限のファ
イルシステム
メタデータ
イメージとコンテナの関係
・Dockerイメージを構成するのは、イメージレイヤ(層)の積み重ね [ copy-on-write(union)ファイル
システムを採用]
・Dockerは複数のイメージレイヤを積み重ねて1つのファイルシステムとして見えるようにする
・Dockerコンテナ起動時にDockerエンジンは書き込み可能なコンテナ用の新しいイメージレイヤを追加
・Dockerfileを使ってDockerイメージをビルドする場合は、Dockerfileの1行が1レイヤでビルドされ
る
書き込み可能
(Read/Write)
読み取り専用
(Read-Only)
イメージレイヤ
イメージレイヤ
イメージレイヤ
コンテナ用の
新しいイメージレイヤ
FROM centos:latest
RUN yum install –y nginx
CMD echo “Hello World”
Dockerコンテナ起動時のファ
イルシステム
Dockerイメージ
Dockerfile
FROM centos:latest
RUN yum install –y nginx
CMD echo “Hello World”
初めてのDocker イメージ作成 (1)
# docker build -t nginx-image .
# git clone https://github.com/daihiraoka/docker-nginx.git
# cd docker-nginx
# ls
Dockerfile index.html
# docker build -t nginx-image .
Docker EngineDockerクライアント Docker Hub
① build ② pull CentOS
イメージ
CentOS
イメージ
③Dockerfileに基づいて
Dockerイメージ [ nginx-image ]
を作成
もしローカルにイメージが
なければ、ダウンロード
初回はイメージの容量に
よってはダウンロードに時
間がかかる
Dockerイメージを作成
するコマンド
作成するイメージ名:タグ名を記述
作成するイメージ名:タグを指定するオプション
Dockerfile
FROM centos:7
RUN yum install -y epel-release && yum install -y nginx && yum clean all -y
ADD index.html /usr/share/nginx/html/index.html
CMD ["nginx", "-g", "daemon off;"]
index.html
Hello World
index.html
nginx-image:latest
Dockerfile
FROM CentOSイメージ
RUN nginxのインストール
CMD nginxの起動
ADD index.htmlの追加
Dockerfileのある
ディレクトリを指定
7
環境構築の一連の作業
は全てDockerfileに
コード化
# git clone https://github.com/daihiraoka/docker-nginx.git <- githubからイメージ作成に必要なファイルを取得
# cd docker-nginx
# ls
Dockerfile index.html <- Dockerfileは Dockerイメージ作成に利用するファイル、index.htmlはnginxのDocumentRootに配置
# docker build -t nginx-image . <- Dockerビルドを実行、Dockerfileを読み込みイメージ作成
Sending build context to Docker daemon 3.072kB
Step 1/4 : FROM centos:7 <- centos:7イメージをFROMで指定
7: Pulling from library/centos <- ローカルにcentos:7のイメージがないのでDockerHubより取得
Digest: sha256:307835c385f656ec2e2fec602cf093224173c51119bbebd602c53c3653a3d6eb
Status: Downloaded newer image for centos:7
---> 67fa590cfc1c
Step 2/4 : RUN yum install -y epel-release && yum install -y nginx && yum clean all –y <- Nginxパッケージのインストール --->
Running in 914f5b889acc
Removing intermediate container 914f5b889acc
---> ae8c2e10e527
Step 3/4 : ADD index.html /usr/share/nginx/html/index.html <- index.htmlの追加
---> b993c7807881
Step 4/4 : CMD [“nginx”, “-g”, “daemon off;”] <- nginxの起動
---> Running in 577e488a9cc3
Removing intermediate container 577e488a9cc3
---> dccac80ac10e
Successfully built dccac80ac10e <- image id として dccac80ac10eがアサインされた
Successfully tagged nginx-image:latest <- nginx-image:latest (イメージ名 : タグ ) としてタグ付けされた
# docker images <- docker imageコマンドでDockerイメージの一覧出力
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx-image latest dccac80ac10e 38 minutes ago 281MB <-今回ビルドで生成されたDockerイメージ
centos 7 67fa590cfc1c 15 hours ago 202MB <- DockerfileのFROMで指定したイメージ
初めてのDocker イメージ作成 (2)
nginx-imageコンテナの実行(1)
# docker run -d -p 8080:80 nginx-image
# docker run -d -p 8080:80 nginx-image
Docker EngineDockerクライアント
① run
nginx-image
イメージ
ルートファイ
ルシステム
② nginx-imageイメージ(read-only)に
read/write可能なルートファイルシステム
を追加してコンテナを起動
コンテナを実行
するコマンド
バックグラウンド
実行コマンド
コンテナのポートを指定するオプション
80(コンテナー内のポート):8080(外部公開ポート)
今回は、コンテナ起動後にブラウ
ザで http://localhost:8080 にアク
セスし、Nginxの起動を確認する
read-only
read/write
nginx-image
イメージ
# curl http://<<DockerEngineのIP>>:8080/
実行するイメージ名
③コンテナ内のポートを80
外部公開用にポート8080を起動して
httpのアクセスを受け付ける
nginx-imageコンテナの実行(2)
# docker run -d -p 8080:80 nginx-image:latest <- docker runでコンテナ実行
86c214c975ed94f7986b12639b9f87542ca759ef6f44a12e6ce8f0f756e690a4
# curl http://localhost:8080/index.html <- Dockerホストの8080番ポートにhttpアクセス
Hello World!
# docker ps <- 現在起動中のコンテナ一覧を出力
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
86c214c975ed nginx-image:latest "nginx -g 'daemon of…" 18 seconds ago Up 17 seconds 0.0.0.0:8080->80/tcp nice_bell
# docker stop 86c214c975ed <- 「 doker stop コンテナID 」でコンテナの終了
86c214c975ed
# docker ps <- 現在起動中のコンテナ一覧を出力
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
Docker デモ
デモ動画 https://jwp.io/s/SBxKXirk
コンテナ/Docker まとめ
コンテナとは
• ホストOSのLinuxカーネル技術を使ってLinuxで動くプロセスをコンテナのように隔離した状態で分離することができる
• ランタイム環境全体(バイナリ、ファイル、依存関係など)でアプリケーションをパケージ化できる。
• ホストから見ると、プロセスが立ち上がるだけなので起動が早い。
Dockerとは
• Dockerはイメージの管理、Dockerイメージを使ったコンテナの作成から実行までライフサイクルを管理するプラット
フォーム
• 様々な環境への同じ内容をデプロイすることができる
• コンテナはプロセスが起動すれば、起動終了なので軽量でスピーディーに開発ができる
• 作成したDockerイメージは共有できる(Docker Hub)
しかし
1つのホストに1つのコンテナを起動をするのは簡単
「 複数コンテナを一括で起動 」、「複数のDockerEngineクラスタを使ってコンテナのスケール」は Dockerだけでは
できない
このような条件を解決するためにはオーケストレーションツールが必要です。
Kubernetesとは
• コンテナオーケストレーションツールの1つ
• クラスタ上でコンテナ化されたアプリケーションを実行および管理
- Dockerでは大変なコンテナが大量になった時の管理をカバー
- 複数のDockerホストの管理
- 死活監視
- スケジューリング
- 障害時のリカバリー
Kubernetesでできること(抜粋)
コンテナの実行 スケールアウト/ダウン負荷分散 ローリングアップデート
api:v1の
コンテナを
3個起動
api:v1コンテナの
前に内部ロードバ
ランサーを設置
v1 v2
プログラム更新など
コンテナを新しいイメージ
api:v2に置き換え
アップデート中もリクエストを処理
し続ける。コンテナを1つずつ更新。
v1 v2
季節やイベントによる
処理状況に対してのコンテナの
スケールアウト/スケールダウン
ノード(マシン)のスケールアウ
ト/スケールダウン
nginx:v1の
コンテナを
10個起動
nginx:v1コンテナ
の前に外部公開用
のロードバラン
サーを設置
• コンテナ(Pod)の負荷によって自動的にコンテナ(Pod)の数を増減(auto scaling)
• ブルー/グリーン デプロイメント、カナリアリリース
• 1回だけのバッチジョブ( Job)
• クラスターがオーバコミットした場合(メモリやディスク不足など)に優先度の低いコンテナ(Pod)を停止(Pod QOS)
• どのリソースを誰が何を実行できるかアクセス制御(RBAC)
Kubernetesコアコンセプト(抜粋)
• ユーザは命令型(imperative)および宣言型(declarative)のコマンドラインインターフェイスを介
してKubernetesクラスターを管理
- 命令型とは目的を達成するのに1つ1つ手順を実行しなければならない
- 宣言型とは望ましい状態をシステムに伝えてあげると、あとは勝手にシステムがやってくれる。
- 命令型 -> kubectl run のようにコマンドで実行して伝える
- 宣言型 -> jsonやyamlで「望ましい状態を実現するために必要なこと」を記述して伝える
• 望ましい状態(Desired state) はKubernetesのコアコンセプトの一つで、命令型(imperative)お
よび宣言型(declarative)のAPIを使用してコンテナーを実行するオブジェクト(Pod、
ReplicatSet、Deploymentなど)の状態を記述
• 常に「望ましい状態(Desired state)」と「現在の状態」(Current state)を突合していて、変更を検
出した場合は、「望ましい状態(Desired state)」に増減してくれます。
例)コンテナやノードがダウンした時に自動的に戻る(オートヒーリング機能)
Kubernetesリソース
• Pod
- コンテナを実行
- Podの中には1つ以上のコンテナが含まれる。
- Pod単位でスケールアウトする
- Pod単位でIPアドレスが割り当て
• ReplicaSet
- Podの実行数を管理
-(指示された場合)必要なPodの数を増減で
きます。
• Deployment
- アプリケーションデプロイするための定
義体、ReplicaSetを管理し、アプリケー
ションを更新する方法(Strategy)を指示。
ローリングアップデート(rollingUpdate)、
再作成(recreate)が選択できる
• Service
-Podにアクセスするための受け口を作るリ
ソース Podは常に増減していて、その度に
IPアドレス変わるので、ServiceはPodを抽
象化して、Podと通信する方法を提供
ServiceはLayer4で動作
Deployment
ReplicaSetの内容
strategy:
rollingUpdate
ReplicaSet
template: <- 新しく起動するPodのテンプレート
image: ibmcom/guestbook:v1
replicas: 2 <- 稼働すべきPodの数を記述
selector: <-監視対象特定のためのLabelセレクタ
matchLabels:
app: guestbook
Pod
label: app=guestbook
Pod
label: app=guestbook
Pod
label: app=guestbook
node node
Service
selector: app=guestbook
ClusterIP: 111.111.111.111
Kubernetesアーキテクチャ
Master
DB(etcd)
API ServerUser(kubectl)
Controller
Manager
(Deployment
Controller)
デプロイ要求
- コンテナイメージ
- コンテナ数
(1)
(1) Userは”kubectl”を使ってコンテナをデプロイするため必要な情報(コンテナイメージ、個数など)を送信する。
(2) APIサーバは受け取った内容をDB(etcd)に保存する
(3) Controllerはリソースの変更を検出すると、変更内容に状態がなるように実行する
(4) (Deploymentの場合)Deployment Controllerは検出すると個数などあるべき状態の新しいPodを
API Server経由でDB(etcd)に保存
(5) Schedulerは情報に基づいて配属先のNode決定する
(6) Kubletは変更を検出し、DockerEngineを使ってPodを作成する
(7) Kube-Proxyはクラスターの内部または外部からPodへのネットワークルールを作成
(2)
(3)
監視送信
保存
Node
Pod/Service
kublet
Scheduler
(4)
(5)
(6)
kube-
Proxy
DockerEngine
OS/Kernel
Images
(7)
ubuntu
CentOS
✳️全ての操作はAPI Server経由で行われる。
Sampleリソース YAML
apiVersion: v1
kind: Pod
metadata:
name: guestbook-pod
spec:
containers:
- name: guestbook
image: ibmcom/guestbook:v1
# kubectl create –f pod.yaml
pod.yaml apiVersion: apps/v1
kind: Deployment
metadata:
name: guestbook-deployment
spec:
replicas: 2
selector:
matchLabels:
app: guestbook
template:
metadata:
labels:
app: guestbook
spec:
containers:
- name: guestbook
image: ibmcom/guestbook:v1
deployment.yaml
# kubectl create –f deployment.yaml
Kubernetesデモ
デモ動画1 https://jwp.io/s/cIV0C3PV
デモ動画2 https://jwp.io/s/yeERACuK
kubernetesまとめ
kubernetesはコンテナオーケストレーションプラットフォーム
望ましい状態(Desired state)を宣言するとKubernetesはその状
態を維持しようとしてくれる
ラーニング・パス: Docker / Kubernetes
• Dockerについて学ぶ(公式ドキュメント:日本語)
http://docs.docker.jp/
• ラーニング・パス: Kubernetes
Kubernetes の基礎から高度なネットワークとワークロードまで
https://developer.ibm.com/jp/kubernetes-learning-path/
• Dockerハンズオン
https://github.com/ibm-cloud-labs/docker-handson
• IKSを通してKubernetesを使ってみよう! Kubernetesハンズオン
http://ibm.biz/iks-labs
Thank you!

Docker & Kubernetes基礎