Open7

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

MasaHeroMasaHero

参考文献

書籍

  • イラストでわかるDockerとKubernetes 初版
  • Docker/Kubernets実践コンテナ開発入門 2版

URL

  • Docker Docs AI
MasaHeroMasaHero

イラストでわかるDockerとKubernetes

コンテナ技術の概要

1-1 コンテナを見てみよう


Linuxカーネルのnamespacesの技術を利用して、システムリソースを隔離して、仮想化する。
同じnamespaceに制限されたプロセスは、同じnamespaceの一部であるリソースまたはプロセスとのみ相互作用する。

「Linuxのしくみ」を読めば、Dockerの基本構成を理解できそう。

1-2 コンテナ技術の基本的な特徴

コンテナの特徴

  • 軽量な実行環境
    • ハイパーバイザー上でOSを立てる仮想マシンと比較して軽量
  • 高い携行性
    • Dockerfile,docker-compose.yml, DockerHubなど
  • エコシステム
    • OCI・CNCF・DockerHubなど
MasaHeroMasaHero

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!"
   3exec 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!"
   3exec sleep infinity
───────┴──────────────────────────────────────────────────────────────────
MasaHeroMasaHero

3. Kubernetesの概要

複数マシンからなる基盤上でコンテナ群を管理するのに用いられる、オーケストレーションエンジン。

Kuberntesの特徴

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

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.
MasaHeroMasaHero

マニフェストファイル

# 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を一つのまとまりとして管理するために、ラベル機能がある。