Open7
DockerとKubernetesを体系的に学び直すスレ

参考文献
書籍
- イラストでわかるDockerとKubernetes 初版
- Docker/Kubernets実践コンテナ開発入門 2版
URL
- Docker Docs AI

イラストでわかるDockerとKubernetes
コンテナ技術の概要
1-1 コンテナを見てみよう
Linuxカーネルのnamespacesの技術を利用して、システムリソースを隔離して、仮想化する。
同じnamespaceに制限されたプロセスは、同じnamespaceの一部であるリソースまたはプロセスとのみ相互作用する。
「Linuxのしくみ」を読めば、Dockerの基本構成を理解できそう。
1-2 コンテナ技術の基本的な特徴
コンテナの特徴
- 軽量な実行環境
- ハイパーバイザー上でOSを立てる仮想マシンと比較して軽量
- 高い携行性
- Dockerfile,docker-compose.yml, DockerHubなど
- エコシステム
- OCI・CNCF・DockerHubなど

2.Dockerの概要
DockerによるBuild, Ship, Run
Dockerの機能としてBuild, Ship, Runがある
- Build
- Dockerfileやコマンドオプションからコンテナイメージを作成
- コンテクスト(ビルドに必要なファイル群)
- Run
- コンテナの実行
- Ship
- コンテナをDockerHubに上げる
- コンテナイメージを配布
コンテナのレイヤ構造
コンテナは変更差分の集まり
bat <<EOF > ./myimage/hello.sh
heredoc> #!/bin/bash
heredoc> echo "Hello, World!"
heredoc> exec sleep infinity
heredoc> EOF
chmod +x ./myimage/hello.sh
exa -l myimage/
.rwxr-xr-x 53 masahero 1 7 22:07 hello.sh
nvim myimage/Dockerfile
tree ./myimage/
./myimage/
├── Dockerfile
└── hello.sh
1 directory, 2 files
bat myimage/Dockerfile
───────┬────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
│ File: myimage/Dockerfile
───────┼────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
1 │ FROM ubuntu:20.04
2 │ COPY ./hello.sh /hello.sh
3 │ ENTRYPOINT [ "/hello.sh" ]
4 │
───────┴────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
docker build -t myimage:v1 ./myimage
[+] Building 4.2s (7/7) FINISHED docker:desktop-linux
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 146B 0.0s
=> [internal] load metadata for docker.io/library/ubuntu:20.04 2.4s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load build context 0.0s
=> => transferring context: 88B 0.0s
=> [1/2] FROM docker.io/library/ubuntu:20.04@sha256:0b897358ff6624825fb50d20ffb605ab0eaea77ced0adb8c6a4b756513dec6fc 1.6s
=> => resolve docker.io/library/ubuntu:20.04@sha256:0b897358ff6624825fb50d20ffb605ab0eaea77ced0adb8c6a4b756513dec6fc 0.0s
=> => sha256:f02209be4ee528c246399de81af4552e52adb005a8a499815607b6b0d42746bf 25.97MB / 25.97MB 0.9s
=> => sha256:0b897358ff6624825fb50d20ffb605ab0eaea77ced0adb8c6a4b756513dec6fc 1.13kB / 1.13kB 0.0s
=> => sha256:6edb9576e2a2080a42e4e0e9a6bc0bd91a2bf06375f9832d400bf33841d35ece 424B / 424B 0.0s
=> => sha256:583f1722e16e377baf906fee1ec6a9fda85ff7f3d13f536f912998601fd85ed8 2.31kB / 2.31kB 0.0s
=> => extracting sha256:f02209be4ee528c246399de81af4552e52adb005a8a499815607b6b0d42746bf 0.6s
=> [2/2] COPY ./hello.sh /hello.sh 0.1s
=> exporting to image 0.0s
=> => exporting layers 0.0s
=> => writing image sha256:2b01cd45f4a27a12ce06b4b811407b28357c4d6526fbe2bb57b7975b271f226b 0.0s
=> => naming to docker.io/library/myimage:v1 0.0s
What's Next?
1. Sign in to your Docker account → docker login
2. View a summary of image vulnerabilities and recommendations → docker scout quickview
docker image ls myimage:v1
REPOSITORY TAG IMAGE ID CREATED SIZE
myimage v1 2b01cd45f4a2 42 seconds ago 65.7MB
mkdir dumpimage
docker save myimage:v1 | tar -xC ./dumpimage/
tree ./dumpimage/
./dumpimage/
├── blobs
│ └── sha256
│ ├── 2b01cd45f4a27a12ce06b4b811407b28357c4d6526fbe2bb57b7975b271f226b
│ ├── 452dd1ab72baae7cb717598f7aa69a9813c58a8ed479b694153368810c7759fd
│ ├── 957f21b893b7bb0fe251fc9adf621ac124de4067637c6d85e4964fc45b300ef2
│ ├── a86403a1d89a6d4a524c2b655b1752254f7d20504ab38118935c96ff26690579
│ ├── a8c68591d421fc2d4bdda704f67a796edf5ff880c59358d75107eb5261821650
│ └── daf05a4b298bbd31a158c074e6c7f218aec3bb2a2e497d29ed8f27e70b3ac14b
├── index.json
├── manifest.json
├── oci-layout
└── repositories
3 directories, 10 files
前回のビルドから得られる結果が異なるステップは実行される
tree ./hello/
./hello/
├── Dockerfile
└── hello.sh
1 directory, 2 files
bat hello/Dockerfile
───────┬──────────────────────────────────────────────────────────────────
│ File: hello/Dockerfile
───────┼──────────────────────────────────────────────────────────────────
1 │ FROM ubuntu:20.04
2 │ RUN apt update && apt install -y figlet
3 │ COPY ./hello.sh /hello.sh
4 │ ENTRYPOINT [ "/hello.sh" ]
───────┴──────────────────────────────────────────────────────────────────
bat hello/hello.sh
───────┬──────────────────────────────────────────────────────────────────
│ File: hello/hello.sh
───────┼──────────────────────────────────────────────────────────────────
1 │ #!/bin/bash
2 │ figlet "Hello, World!"
3 │ exec sleep infinity
───────┴──────────────────────────────────────────────────────────────────
docker build -t hello:v1 ./hello
[+] Building 15.3s (8/8) FINISHED docker:desktop-linux
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 148B 0.0s
=> [internal] load metadata for docker.io/library/ubuntu:20.04 1.8s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> CACHED [1/3] FROM docker.io/library/ubuntu:20.04@sha256:0b89735 0.0s
=> [internal] load build context 0.0s
=> => transferring context: 90B 0.0s
=> [2/3] RUN apt update && apt install -y figlet 13.4s
=> [3/3] COPY ./hello.sh /hello.sh 0.0s
=> exporting to image 0.1s
=> => exporting layers 0.1s
=> => writing image sha256:0a562c8397143d4a28626454136fae273f8a8ff 0.0s
=> => naming to docker.io/library/hello:v1 0.0s
hello.shの中身を変更する
bat hello/hello.sh
───────┬──────────────────────────────────────────────────────────────────
│ File: hello/hello.sh
───────┼──────────────────────────────────────────────────────────────────
1 │ #!/bin/bash
2 │ figlet "It works!"
3 │ exec sleep infinity
───────┴──────────────────────────────────────────────────────────────────

3. Kubernetesの概要
複数マシンからなる基盤上でコンテナ群を管理するのに用いられる、オーケストレーションエンジン。
Kuberntesの特徴
- ファイルを用いた宣言的管理
- 理想状態をマニフェストファイルで宣言する
- 広範なデプロイ形式のサポート
- ステートレス・ステートフルを選択可能
- ステートフルの場合でも、常駐で実行or特定の時間間隔で実行
- コンテナの自動復旧・自動スケーリング・アップデート
- 拡張性の高いアーキテクチャ
- k8sは多数の独立したコンポーネントで構成されているので、更新や交換が可能
- API拡張性
- KubernetesAPIを拡張できる
- KubernetesAPIを参照・操作できる、コントローラを独自に実装できて、サードパーティとしても利用できる
- KubernetesAPIを拡張できる
- プラグイン機構
- ストレージ・ネットワーキング・認証などの領域でプラグインをサポート

Kubernetesクラスタとkubectl
書籍ではGKEだが、ローカルでタダで動かしたいので、minikubeで試す。
brew install minikube
# Minikubeの起動
minikube start
# クラスター状態確認
kubectl get nodes
# Minikubeの停止
minikube stop
全体像
- クラスタ・・・コンテナ群を実行するマシンの集合
- ノード・・・各コンテナが実行されるマシン
- ノードコンポーネント・・・ノード上で複数稼働して、そのノード上のコンテナ群の実行管理・イメージ管理・通信管理
- ノード・・・各コンテナが実行されるマシン
- コントロールプレーン・・・クラスタ全体を管理を担う。
- コントローラ(kube-controller-manager)
- コンポーネント(kube-scheduler)
- APIサーバ(kube-apiserver)
公式ドキュメントより引用
実際にやってみた
nginxのデプロイ
kubectl create deployment nginx-deployment --image=nginx:1.19
deployment.apps/nginx-deployment created
# deploymentsのステータス確認
kubectl get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
hello-minikube 0/1 1 0 39m
nginx-deployment 1/1 1 1 30s
# .apps つけても同じ
kubectl get deployments.apps
NAME READY UP-TO-DATE AVAILABLE AGE
hello-minikube 0/1 1 0 39m
nginx-deployment 1/1 1 1 33s
# 個別のPod(アプリケーション)を指定
kubectl get deployments.apps nginx-deployment
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 1/1 1 1 45s
# Podを削除
kubectl delete deployments.apps hello-minikube
deployment.apps "hello-minikube" deleted
kubectl get deployments.apps
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 1/1 1 1 68s
# Podを削除
kubectl delete deployments.apps nginx-deployment
deployment.apps "nginx-deployment" deleted
kubectl get deployments.apps
No resources found in default namespace.

マニフェストファイル
# KubernetesAPIバージョン指定
apiVersion: apps/v1
# リソースの種類の指定
kind: Deployment
# リソースのメタデータ設定
metadata:
name: nginx-deployment
# Deploymentの仕様を定義
spec:
# 作成するPodの数を指定
replicas: 1
# Podを選択するためのラベルセレクタを定義
selector:
matchLabels:
app: nginx
# Podのテンプレートを定義
template:
metadata:
labels:
app: nginx
spec:
# Pod内のコンテナを定義
containers:
- name: nginx
image: nginx:1.19
ports:
- containerPort: 80
実行
kubectl apply -f nginx-deployment.yml
deployment.apps/nginx-deployment created
kubectl get deployments.apps
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 1/1 1 1 19s
kubectl get deploy,pods
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/nginx-deployment 1/1 1 1 28s
NAME READY STATUS RESTARTS AGE
pod/nginx-deployment-795bc5cd8b-2hvch 1/1 Running 0 28s
Podとコンテナ
Kubernetes上では、複数のコンテナ群を一まとめにしたものをPod
という基本的なデプロイ単位である。
Podを一つのまとまりとして管理するために、ラベル機能がある。

コラム
DockerDesktop Version4.33からDocker Build Checkが追加。
Dockerfileの構文チェックから最適化までしてくれる。