Docker/Kubernetes 実践コンテナ開発入門 (2018)
https://gyazo.com/2efbb073291fb4980378cbc61cde54d9
タイトル
Docker/Kubernetes 実践コンテナ開発入門
著者
年
2018年8月25日
リソース
概要
ローカル環境での検証はもちろん,Google Kubernetes EngineへのデプロイやFargateの活用などクラウドでの実践にも触れています。Docker/Kubernetesをきちんと本番で使うための王道的な解説を中心としつつ,CLIツールとしてDockerを導入したい,オンプレでKuberentesを使いたいといったニーズにも答えます。 内容
Dockerの得意
アプリケーションをデプロイすることに特化したコンテナ
例えばこんなことができる
インストールがめんどいCLIツールをホストを汚さず実行する
実行環境をまとめてshipできる
Dockerの苦手
Linux系のOSの振る舞いを完全にエミュレーションできているわけではない
非Linux環境は動作できない
Dockerの歴史
Dockerはデプロイにフォーカスしたので再現性が保てる
ホストOSに依存しないランタイムの標準化(Docker Engine)
DSL, image周りの扱い、API
Docker1.11からrunCランタイムで動作する 抽象化がすすんで標準化もされてきたということと理解kadoyau.icon
DockerCon2017でMobyプロジェクトが発表 “Mobyが開発プロジェクト、DockerはMobyのコンポーネントやツール群を用いてアセンブルされたプロダクトであるという位置づけ”
アプリケーション実行までの流れ
アプリを書く
ベースのOSを指定する
イメージをビルドする
docker image build
Dockerコンテナを実行する
docker container run
アプリとOSがコンテナに展開される
Dockerを採用する意義
冪等性(ランタイムが変わらない)
ランタイムとアプリケーション構成をコードで管理できる
ポータビリティ向上
ランタイム+アプリケーションがパックになる(アプリとインフラがセットで管理できるということ)
開発環境でもローカルでもDockerが入っていれば実行できる
アプリやミドルウェアの構成管理が楽になる
サービスは複数のアプリやミドルウェアを組み合わせてつくる
依存関係や実行順序順序の保証が必要
単一のサーバ(?)でコンテナを管理するyaml
大規模システムではDockerが入ったサーバを複数用意して、それらにアプリケーションを複数デプロイする。Docker Composeを複数サーバ間で複数コンテナ管理できるようにしたのがDocker Swarm 複数サーバで多くのコンテナを管理する手法がコンテナオーケストレーション。デファクトはKubernetes コンテナ型とホスト型
コンテナ型:Docker
ホスト型:物理マシン上でVMを実行
kernelを共有する分Dockerのほうが早い
本番でも使えるDocker
世界的にプロダクション利用が進んだ
スケールアウトのしやすさなどのメリットがかつ
運用も難しくないレベルになってきた
主要プラットフォームで運用環境がある
Azure: Azure Container Service
Dockerの向き不向き
Dockerが得意
ステートレスなもの(アプリ、APIサーバ)
Dockerの運用はむずい
ステートフルなもの(データストア)
managed DBも検討したほうがいい
開発スタイルへの影響
インフラ/サーバサイドの領域が曖昧に
Dockerではインフラとアプリがコンテナで共存するため
Dockerは小さいアプリとの親和性がある
CIの高速化
1.3 ローカルDocker環境を構築する
VirtualBoxでOSを作った上でDockerを構築する
BIOSの設定で仮想化をenabledにする必要あり
Hyper-Vは無効にする
2 Dockerコンテナのデプロイ
2.1
GoでHTTPレスポンスを返すだけのアプリを作る
Dockerのポートフォワーディング
Dockerイメージからコンテナを作る操作
イメージのダウンロード
docker image pull gihyodocker/echo:latest
コンテナの起動
docker container run -t -p 9000:8080 gihyodocker/echo:latest
:の右側(8080)はコンテナポート。コンテナ内からのみアクセスできる
アプリケーションが8080を開けていたとしてもDocker外部からはアクセスできない。このためホストのポートをコンテナポートに割り当てるPort Fowardingをする必要がある docker runと同じだが、Dockerコミュニティ的には(?)長いコマンドが理解しやすさの観点から推奨らしい。
リクエストを送る
code:zsh
HTTP/1.1 200 OK
Content-Length: 14
Content-Type: text/plain; charset=utf-8
Date: Wed, 24 Apr 2019 17:11:19 GMT
Hello Docker!!
停止
docker container stop $(docker container ls -q)
GoのHTTPサーバを作る
アプリとDockerfileを書く
イメージのビルド
docker image build -t example/echo .
.はDockerfileのあるディレクトリ
実行しているコンテナの一覧
docker container ls
指定した場合、CMDの引数がENTRYPOINTで指定したものの引数になる
docker container run -d example/echo:latest
コマンド
RUN:コンテナ内で実行するコマンドを書く
アプリケーション更新や配置につかう
CMD:コンテナ起動時に1度だけ実行する
アプリケーションの起動につかう
2.2 - 2.3
Dockerの基本操作を大別すると2種類ある
ヘルプの出し方
docker help
docker image --help
docker image build --help
2.4 運用管理向けコマンド
不要なイメージやコンテナの一括削除
docker container prune
docker image prune
実行中のコンテナイメージとかは削除されない
docker system prune
container, image, volume, networkなどのすべてのリソースを一括削除
利用状況の取得
docker container stats
2.5 Docker Composeでマルチコンテナを実行する
Dockerコンテナは単一のアプリケーションのようなもの
複数のアプリケーションの連携をのためには複数コンテナの依存性や協調が必要になる
yamlで複数コンテナの実行を管理できる
実際にやってみる
docker-compose.ymlを作る
docker-compose up -dで起動
docker-compose downで停止
container idとかいちいち調べなくて楽
Dockerfileのpathをbulidで指定するとコンテナをビルドして実行できる
2.6 Composeによる複数コンテナの実行
効率化できそうなポイント
コマンドが長い
docker container stop $(docker container ls --filter"ancestor=example/echo" -q)とかいちいちうちたくない
docker-composeを使うようになると頻度が減る
3.実用的なコンテナの構築とデプロイ
3.1 アプリケーションとコンテナの粒度
3.1.1 1コンテナ=1プロセス?
3.1.2 1コンテナに1つの関心事
3.2 コンテナのポータビリティ
3.2.1 Kernel・アーキテクチャの違い
3.2.2 ライブラリ・ダイナミックリンクの課題
3.3 Dockerフレンドリなアプリケーション
3.3.1 環境変数を活用する
コラム Dockerフレンドリなプロダクトばかりじゃない
3.4 永続化データをどう扱うか
3.4.1 Data Volume
3.4.2 Data Volumeコンテナ
3.5 コンテナ配置戦略
3.5.1 Docker Swarm
3.5.2 Service
3.5.3 Stack
3.5.4 ServiceをSwarmクラスタ外から利用する
コラム Swarmクラスタの構成管理
4.Swarmによる実践的なアプリケーション構築
4.1 Webアプリケーションの構成
4.1.1 アプリケーションの仕様
4.1.2 アーキテクチャ
4.1.3 TODOアプリケーション構築の全体像
4.2 MySQL Serviceの構築
4.2.1 データベース・コンテナ構成
4.2.2 認証情報
4.2.3 MySQLの設定 ― etc/mysql/mysql.conf.d/mysqld.cnf
4.2.4 レプリケーションを設定する
4.2.5 MySQL(mysql_master/mysql_slave)のDockerle
4.2.6 Swarm上でMaster/Slaveサービスを実行する
4.2.7 MySQLコンテナを確認し,初期データを投入する
4.3 API Serviceの構築
4.3.1 todoapiの基本構造
4.3.2 アプリケーションでの環境変数の制御
4.3.3 MySQL接続,テーブルマッピング
4.3.4 Handlerを実装する
4.3.5 APIのDockerle
4.3.6 Swarm上でtodoapiサービスを実行する
4.4 Nginxの構築
4.4.1 nginx.confを構築する
コラム 環境変数を積極的に使う
4.4.2 NginxのDockerle
4.4.3 Nginxを通してアクセスできるようにする
4.5 Webの構築
4.5.1 TODO APIを呼び出し,ページのHTMLを返却する
4.5.2 WebのDockerle
4.5.3 静的ファイルの扱いを工夫する
4.5.4 Nginxを通してアクセスできるようにする
4.5.5 Ingressで公開する
4.6 コンテナオーケストレーションによる開発スタイル
5.1 Kubernetesとは
5.1.1 Dockerの隆盛とKubernetesの誕生
5.1.2 Kubernetesの位置づけ
5.2 ローカル環境でKubernetesを実行する
5.2.1 Docker for Windows/MacでローカルKubenetes環境を構築する
5.3 Kubernetesの概念
5.4 KubernetesクラスタとNode
コラム Masterを構成する管理コンポーネント
5.5 Namespace
5.6 Pod
5.6.1 Podを作成してデプロイする
5.6.2 Podを操作する
コラム PodとPod内コンテナのアドレス
5.7 ReplicaSet
5.8 Deployment
5.8.1 ReplicaSetライフサイクル
5.8.2 ロールバックを実行する
5.9 Service
コラム Serviceの名前解決
5.9.1 ClusterIP Service
5.9.2 NodePort Service
5.9.3 LoadBalancer Service
5.9.4 ExternalName Service
5.10 Ingress
5.10.1 Ingressを通じたアクセス
コラム freshpodでイメージの更新を検知し,Podを自動更新する
コラム kube-prompt
コラム Kubernetes API
6.Kubernetesのデプロイ・クラスタ構築
6.1 Google Kubernetes Engineのセットアップ
6.1.1 GCPプロジェクトの作成
6.1.2 Google Cloud SDK(gcloud)のセットアップ
6.1.3 Kubernetesクラスタの作成
6.2 GKE上にTODOアプリケーションを構築する
6.3 Master Slave構成のMySQLをGKE上に構築する
6.3.1 PersistentVolumeとPersistentVolumeClaim
6.3.2 StorageClass
6.3.3 StatefulSet
6.4 TODO APIをGKE上に構築する
6.5 TODO WebアプリケーションをGKE上に構築する
6.6 IngressでWebアプリケーションをインターネットに公開する
6.7 オンプレミス環境でのKubernetesクラスタの構築
6.8.1 クラスタとして構築するサーバの準備
6.8.2 opsのSSH公開鍵の登録
6.8.3 IPv4フォワーディングを有効にする
6.8.4 クラスタの設定
6.8.5 クラスタ構築の実行
7.Kubernetesの発展的な利用
7.1 Kubernetesの様々なリソース
7.1.1 Job
7.1.2 CronJob
7.1.3 Secret
コラム 認証情報をセキュアに環境変数へ設定する
7.2 ユーザー管理とRole-Based Access Control (RBAC)
7.2.1 RBACを利用して権限制御を実現する
7.2.2 ServiceAccount
7.3.1 Helmのセットアップ
7.3.2 Helmの概念
7.3.3 Chartをインストールする
7.3.4 Chartでアプリケーションをアンインストールする
7.3.5 RBACに対応したアプリケーションをインストールする
7.3.6 独自のChartを作成する
7.4 Kubernetesにおけるデプロイ戦略
7.4.1 RollingUpdate
7.4.2 コンテナ実行時のヘルスチェックを設定する
コラム 安全にアプリケーションを停止してからPodを削除する
7.4.3 BlueGreen Deployment
8.コンテナの運用
8.1.1 コンテナにおけるロギング
8.1.2 コンテナログの運用
8.1.3 FluentdとElasticsearchによるログ収集・検索機構の構築
8.1.4 fluentd logging driverの運用イメージ
コラム 可用性・信頼性のあるログストレージを選ぶ
8.1.5 Kubernetesにおけるログの管理
8.1.6 その他のログ収集ツール
8.2 Dockerホストやデーモンの運用
8.2.1 コンテナのライブリストア
8.2.2 dockerdのチューニング
コラム Docker/Kubernetesの運用はマネージド?非マネージド?
8.3 障害対策
8.3.1 Docker運用での障害対策
8.3.2 Kubernetes運用での障害対策
コラム その他のラベル付け
9.より軽量なDockerイメージを作る
9.1 なぜ軽量なイメージを作るべきなのか
9.1.1 イメージサイズの増大で発生する弊害
9.2 軽量なベースイメージ
コラム Alpine Linuxを採用する例
コラム Alpine Linuxベースのイメージを採用するべきか否か
9.3 軽量なDockerイメージをつくる
9.3.1 デプロイするアプリケーションのサイズを削減する
9.3.2 Dockerイメージのレイヤー構造を意識する
9.4 multi-stage builds
9.4.1 ビルドコンテナと実行コンテナを分ける
コラム 言語にフォーカスしたdistrolessイメージ
10.Dockerの様々な活用方法
10.1 チーム開発で開発環境を統一・共有する
10.1.1 利用するソフトウェア・ツールを統一する
10.1.2 開発環境は集合知
コラム DockerはVagrantの代替となるか?
10.2 コマンドラインツール(CLI)をDockerコンテナで利用する
10.2.1 イメージによって利用するツールのバージョンを切り替える
10.2.2 シェルスクリプトをDockerコンテナで実行する
10.3 負荷テスト
10.3.1 実験環境のセットアップ
10.3.2 master/slave構成で複数コンテナから負荷テストを実行する
Appendix-A セキュリティ
A.1 公開Dockerイメージの安全性
A.1.1 Docker Hub
A.1.2 Quay.io
A.2 安全なDockerイメージと運用体制をつくる
A.2.1 Docker Bench Security
A.2.2 コンテナへのファイル追加におけるリスク
A.2.3 適切なアクセス制御
A.2.4 クレデンシャル(機密情報)の扱い
Appendix-B Dockerでの開発を支援するツール・サービス
B.1 独自Dockerレジストリの構築
B.1.1 Registry(Docker Distribution)
コラム Docker Trusted Registry
B.2 DockerとCI/CDサービスの連携
B.2.1 CircleCI
B.3 AWS Fargateを用いたECSでのコンテナオーケストレーション B.3.1 FargateでECS Clusterを構築する
B.3.2 ECSを操作してアプリケーションをデプロイする
Appendix-C 主要コマンドまとめ
C.1 dockerコマンド
C.2 Dockerfile
C.3 docker-composeコマンド
C.4 docker swarm/stackコマンド
C.5 helmコマンド