実践! Kubernetes 入門|研修コースに参加してみた
今回参加したコースは 実践! Kubernetes 入門 です。
IT インフラにおいてコンテナや Docker はすっかり定着しました。 ただ、クラウドでコンテナをオーケストレーションさせる Kubernetes はまだスキルを持った人が少ないのが現状です。
学習コストが高いと評判なので、私も「 Kubernetes の用途は大規模運用なんでしょ」と参加前は学習しない言い訳していたのですが、講師の大澤さんが Kubernetes の特徴を上手くわかるようにコース設計されていたので、 “宣言的” で “自律的” という感覚を掴めて、「 サーバ 1 台でも全然やったらええやん」と、学習する気持ちになりました!
では、どんなコースだったのか、レポートします!
もくじ
コース情報
想定している受講者 | Docker の知識があるとより理解が深まりますが、はじめての人でも問題ありません |
---|---|
受講目標 |
|
講師紹介
このコースで登壇されたのは 大澤 文孝 さんです。
Web システムの設計・開発とともに、長年の執筆活動のなかで、電子工作、 Web システム、プログラミング、データベースシステム、パブリッククラウドに関する書籍を多数執筆している。
-
主な著書
- 「さわって学ぶクラウドインフラ docker 基礎からのコンテナ構築」(共著 日経 BP 社刊)
- 「Amazon Web Services 基礎からのネットワーク&サーバー構築 改訂 3 版」(共著 日経 BP 社刊)
- 「ハンズオンで分かりやすく学べる Google Cloud 実践活用術 データ分析・システム基盤編 Google 監修」(日経 BP 社刊)
- 「ハンズオンで分かりやすく学べる Google Cloud 実践活用術 AI・機械学習編 Google 監修」(日経 BP 社刊)
- 「UI まで手の回らないプログラマのための Bootstrap 3 実用ガイド」(翔泳社 刊)
- 「ゼロからわかる Amazon Web Services 超入門 はじめてのクラウド」(技術評論社 刊) など
Kubernetes とは
Kubernetes はなにをするものかというと、ざっくりいうと「複数台のサーバで複数のコンテナをオーケストレーションするツール」です。
ちなみに大澤さんに読み方を質問したところ、 「クーバネテス」だそうです。
- 複数台のサーバを使う
- 全台に kubernetes を動かす構成を組む
- まとめたものを Kubernetes クラスタと呼ぶ
- 仮想ネットワークでつなぐ
- 物理的に離れていようが関係ない
- ロードバランサや DNS (ラウンドロビン) などを配置する
- 負荷分散する
- サーバ 1 台でも OK
物理的に離れていようが関係ない、というのがクラウドらしい技術ですよね。 またサーバ 1 台でも OK というのはオーバーな気もしたのですが、実はそんなことはありませんでした。
Kubernetes と Docker Compose の違いとメリット
同じように複数のコンテナを動かす仕組みとして Docker Compose があります。 その違いと Kubernetes のメリットは何でしょうか。
- Docker Compose はサーバ 1 台で管理する
- ex. WordPress コンテナと DB コンテナを 1 台で動かす
- 複数台では使えない
- Kubernetes は自律的に動く
- コンテナを自動で復旧したり、自動でコンテナに負荷分散する
- サーバ 1 台から n 台にスケールできる
なるほど、 Kubernetes は学習コストの高いので、「大規模運用のときに使うものでしょ」と勝手にフィルターをかけていましたが、 1 台でもちゃんとそのコストに見合ったメリットがあるのですね。
Kubernetes の種類
Kubernetes と一口に言っても実は複数の OSS があります。 伺っていると、 Linux のディストリビューションのような印象を受けました。
- Google が開発し、それを CNCF (Cloud Native Computing Foundation) に寄贈
- いろいろな Kubernetes がある
- 標準は kubeadm から入れる
- 1 台で使う場合
- minikube (このコースで使用)
- 1 台~数台で使う場合
Kubernetes そのものは巨大なソフトウェアなので、構成しやすいように、試しやすいように派生したのかも知れませんね。
Kubernetes の仕組み
では、 Kubernetes はどのように動いているのか、その構成を紹介いただきました。
- Kubernetes クラスタの中にあるサーバはマスターノードとワーカーノードにわかれる
- マスターノードはワーカーノードをコントロールする
- Kubernetes を操作する kubectl コマンドはマスターノードに対して行う
- マスターノードは冗長構成にすることが普通
- ワーカーノードにコンテナがある
- サーバの処理能力やスケール状況によって台数などは変化
- マスターノードとワーカーノードを 1 台におさめても OK
- 開発環境やテストなどにはよい
- マスターノードはワーカーノードをコントロールする
- マスターノードの中に kube-apiserver (kubectl とのインターフェイス) や Kubescheduler (ワーカーノードのスケジューラ) などがある
- cloud-controller-manager がクラウドとのインターフェイスになっている(クラウド事業者が提供する)
- 要は使うには、管理者が kuberctl コマンドを打てるように設定する必要がある
マスターノードの中にあるソフトウェアは OS のような役割が与えられているとイメージすると良いかも知れませんね(ワーカーノードが OS で動く各種ソフトウェアというイメージ)。
このほか、改めて「コンテナ」について解説いただきましたが、他コースでも触れていますので、ここでは割愛します。
Kubernetes を動かしてみよう
ここから実際に Kubernetes を使ってみましょう!
研修では SE カレッジで用意した Microsoft Azure の仮想マシンにインストールされた minikube を使って演習します。
読者の方で試したいという方がいらっしゃれば、下のドキュメントをもとに進めてみてください。
minikube を起動
SSH で入り、早速 minikube を動かしてみましょう!
$ minikube start --driver=none
minikube v1.22.0 on Ubuntu 20.04
✨ Using the none driver based on user configuration
Starting control plane node minikube in cluster minikube
Running on localhost (CPUs=2, Memory=7954MB, Disk=29598MB) ...
ℹ️ OS release is Ubuntu 20.04.2 LTS
minikube 1.25.2 is available! Download it: https://github.com/kubernetes/minikube/releases/tag/v1.25.2
To disable this notice, run: 'minikube config set WantUpdateNotification false'
# 中略
Done! kubectl is now configured to use "minikube" cluster and "default" namespace by default
動作確認がてら、設定ファイルを見てみます。
$ kubectl config view
apiVersion: v1
clusters:
- cluster:
certificate-authority: /home/username/.minikube/ca.crt
extensions:
- extension:
last-update: Wed, 20 Apr 2022 05:56:57 UTC
provider: minikube.sigs.k8s.io
version: v1.22.0
name: cluster_info
server: https://10.0.0.4:8443
name: minikube
# 中略
current-context: minikube
kind: Config
preferences: {}
users:
- name: minikube
user:
client-certificate: /home/username/.minikube/profiles/minikube/client.crt
client-key: /home/username/.minikube/profiles/minikube/client.key
動作確認できました!
kubectl コマンド
続いて、 Kubernetes クラスタを操作する kubectl コマンドの前に操作の基本を紹介いただきました。
- Kubernetes のポイントは “望ましい状態 (desired state)” を伝えること
- ex. kubectl から “Web のコンテナは 3 つあるべき” とコマンドを出す
- あとはマスターノードがよしなにやってくれる
- 障害が発生して 1 台死んでも、マスターノードがワーカーノードに新しいコンテナを作るように指示する
- ちなみにクラスタが死ぬとデータも消えるので、永続化は必須
- kubectl で指示を出してからしばらく時間がかかる
なるほど、普通コマンドは「~をせよ。 次に~」と人間が命令を考えるところ、 Kubernetes では「これが正常だから、あとはいい感じに」(雑な表現でスイマセン … )ということを伝えるのですね。 これは面白い! 冒頭にあった “自律的に” というのはこういうことですね。
code kubectl の書式
$ kubectl config view
# kubectl コマンド サブコマンド オプション
Kubernetes オブジェクトと Pod
その “望ましい状態” を定義して、 Kubernetes が管理する対象が Kubernetes オブジェクトです。
- 望ましい状態を管理するすべて(コンテナやネットワークやストレージ)
- イメージ名とか環境変数とかいろいろ
- Kubernetes API リファレンス に載っている
- Pod と呼ばれるコンテナとボリューム(コンテナ間で使えるディレクトリ)のセット
- Pod には IP アドレスがある
- だいたいの Pod はコンテナ 1 つだけ
- 1 つの Pod に複数のコンテナを使うのはコンテナ同士が連動する場合(ログの処理やバッチ処理など)
- 間違った Pod の使い方
- clear 1 つの Pod に WordPress コンテナと MySQL コンテナがある
- なぜなら、複数の WP と MySQL が出来てしまう
この Pod はマニフェスト( Manifest )ファイルと呼ばれるもので定義します。 どんなものか見てみましょう。
- YAML で書く
- 利用できるのは空白でタブは NG
-
や:
の次は空白を入れる- サンプル( Apache で Web サーバを立てる)
apiVersion: v1 kind: Pod metadata: name: my-pod labels: app: my-app spec: containers: - name: my-container image: httpd ports: - containerPort: 80
このマニフェストで作られた Pod は以下のようなイメージで生成されます。
マニフェストを書いて Pod を作ってみよう
では、 Pod を作ってみましょう。
- マニフェストファイルを作ろう(上記の YAML ファイル)
- 実行してみよう
$ kubectl apply -f podexample.yaml pod/my-pod created
- 確認してみよう
$ kubectl get pods NAME READY STATUS RESTARTS AGE my-pod 1/1 Running 0 2m15s
- オプションで IP アドレスなどを見てみよう
$ kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES my-pod 1/1 Running 0 3m55s 172.17.0.3 username <none> <none>
- さらに詳しく見てみよう
$ kubectl describe pods my-pod Name: my-pod Namespace: default Priority: 0 Node: username/10.0.0.4 Start Time: Wed, 20 Apr 2022 06:19:11 +0000 Labels: app=my-app Annotations: <none> Status: Running IP: 172.17.0.3 IPs: IP: 172.17.0.3 Containers: my-container: Container ID: docker://e0552e1d3a73262372cbde322ad8bdcbd9ae54d35364bff6a4261ba80e689030 Image: httpd # 中略 Mounts: /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-jxdlt (ro) Conditions: Type Status # 中略 PodScheduled True Volumes: kube-api-access-jxdlt: Type: Projected (a volume that contains injected data from multiple sources) # 中略 Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 4m51s default-scheduler Successfully assigned default/my-pod to username Normal Pulling 4m51s kubelet Pulling image "httpd" Normal Pulled 4m48s kubelet Successfully pulled image "httpd" in 2.150908329s Normal Created 4m48s kubelet Created container my-container Normal Started 4m48s kubelet Started container my-container
- オプションで IP アドレスなどを見てみよう
- Pod に接続してみよう
$ curl http://172.17.0.3 <html><body><h1>It works!</h1></body></html>
- アクセスログも見てみよう
$ kubectl logs my-pod 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 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 [Wed Apr 20 06:19:14.686070 2022] [mpm_event:notice] [pid 1:tid 140038973480256] AH00489: Apache/2.4.53 (Unix) configured -- resuming normal operations [Wed Apr 20 06:19:14.711492 2022] [core:notice] [pid 1:tid 140038973480256] AH00094: Command line: 'httpd -D FOREGROUND' 172.17.0.1 - - [20/Apr/2022:06:25:56 +0000] "GET / HTTP/1.1" 200 45
- コンテナの機能を使ってアクセスログを確認している
外部から接続できるようにしよう
先程はコンテナの機能を使ってアクセスログを出しましたが、今度は外部からアクセスしてみます。
- Pod はワーカーノードの内部ネットワークで生きている
- Service オブジェクトを使って外部アクセスできるようにする
- Service がポートを結ぶ
- ややこしいが、 Kubernetes クラスタごとに IP アドレスがある
- ここから Service の IP をたどる
- 方法は 3 つ
- ワーカーノードの IP を経由して Sevice のポートにアクセスする NodePort
- ロードバランサから Service のポートにアクセスする
- 物理のロードバランサではなくクラウドが用意するロードバランサを使う
- HTTPS プロキシを使う Ingress (アプリケーションレイヤ)
- 使っている Kubernetes によって指定がある
- 今回は汎用的に使える NodePort を使う
Docker と違ってもう一層 Kubernetes クラスタがあるので、このあたりはややこしい … 。
Service を作ってアクセスしてみよう
では、 Service を作ってアクセスしてみましょう。
- Service のマニフェストを作ってみよう
apiVersion: v1 kind: Service metadata: name: my-service spec: type: NodePort ports: - nodePort: 30000 port: 8080 targetPort: 80 protocol: TCP selector: app: my-app
- my-app は pod 作成時に使った app: my-app を指定したから
- 「イメージすることが大事です」と大澤さんのコメント
- 動かしてみよう
$ kubectl apply -f serviceexample.yaml service/my-service created
- 確認してみよう
$ kubectl get services NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 45m my-service NodePort 10.96.136.173 <none> 8080:30000/TCP 50s
- 詳細を確認してみよう
$ kubectl get services NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 45m my-service NodePort 10.96.136.173 <none> 8080:30000/TCP 50s $ kubectl describe services my-service Name: my-service Namespace: default # 中略 Port: <unset> 8080/TCP TargetPort: 80/TCP NodePort: <unset> 30000/TCP Endpoints: 172.17.0.3:80 Session Affinity: None External Traffic Policy: Cluster Events: <none>
- 接続してみよう
$ curl 172.17.0.3:80 <html><body><h1>It works!</h1></body></html>
- ログを確認してみよう
$ kubectl logs my-pod 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 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 [Wed Apr 20 06:19:14.686070 2022] [mpm_event:notice] [pid 1:tid 140038973480256] AH00489: Apache/2.4.53 (Unix) configured -- resuming normal operations [Wed Apr 20 06:19:14.711492 2022] [core:notice] [pid 1:tid 140038973480256] AH00094: Command line: 'httpd -D FOREGROUND' 172.17.0.1 - - [20/Apr/2022:06:25:56 +0000] "GET / HTTP/1.1" 200 45 172.17.0.1 - - [20/Apr/2022:06:44:13 +0000] "GET / HTTP/1.1" 200 45 172.17.0.1 - - [20/Apr/2022:06:45:45 +0000] "GET / HTTP/1.1" 200 45 172.17.0.1 - - [20/Apr/2022:06:45:45 +0000] "GET /favicon.ico HTTP/1.1" 404 196
- ブラウザからアクセスしてみよう
Kubernetes を使ったサービスの外部公開の設定は、これまでとはちょっと違って複雑です。 大澤さんのイメージが無いと、どこのポートを使うのかわからなくなってしまうところでした。
Pod のデプロイ Deployment オブジェクト
先程は Pod を 1 つで作成したり、操作していましたが、 Pod を作る度に、 kubectl apply
コマンドを個数分だけ実行することになってしまいます。
そこで登場するのがデプロイのためのオブジェクトです。
- Pod は直接操作しない、作らない
- そもそも 3 つ Pod を起動することはない
- 自律的にならない
- デプロイ用のオブジェクトがある
- Deployment オブジェクト
- Pod の更新時は新しく作り直す
- 捨てやすくなるので、こっちを使うのが常道
- スケールしやすくなる
- Stateful オブジェクト
- Pod のデータを保とうとする
- あまり使わない
- Deployment オブジェクト
この Deployment オブジェクトがどのように動くのか、見てみましょう。
- Deployment オブジェクトが実体の ReplicaSet オブジェクトを作る
- Pod の更新が入ると、今の ReplicaSet を捨てて新しく作る
- ただし一斉に変わるわけではなく、だんだん Pod を新しくしていく
こういうところがクラウドネイティブらしく、イミュータブルで自律的ですね!
なお、大澤さんから補足があり、「この Deployment から Pod を作るので、先程触れた Pod を 1 つ作るやり方は忘れてください」とのことでした。
Deployment オブジェクトを使ってみよう
では、 Deployment オブジェクトを使って、 Pod を作成してみましょう!
- Deployment オブジェクトのマニフェストを書こう
- レプリカ数やコンテナの定義(イメージやポートなどの設定)などを書く
apiVersion: apps/v1 kind: Deployment metadata: name: my-deployment spec: replicas: 3 selector: matchLabels: app: my-app template: metadata: labels: app: my-app spec: containers: - name: my-container image: httpd ports: - containerPort: 80
- 動かしてみよう
$ kubectl apply -f deployexample.yaml deployment.apps/my-deployment created
- 確認してみよう
$ kubectl get deployments NAME READY UP-TO-DATE AVAILABLE AGE my-deployment 3/3 3 3 45s
- ReplicaSet があるか確認してみよう
$ kubectl get replicasets NAME DESIRED CURRENT READY AGE my-deployment-5bc688cdbf 3 3 3 94s $ kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES my-deployment-5bc688cdbf-5vnsh 1/1 Running 0 2m7s 172.17.0.4 se0830-m <none> <none> my-deployment-5bc688cdbf-9kgqx 1/1 Running 0 2m7s 172.17.0.3 se0830-m <none> <none> my-deployment-5bc688cdbf-9sgzb 1/1 Running 0 2m7s 172.17.0.5 se0830-m <none> <none>
- Service を作ってみよう
- もともと selector で指定しているので 3 つの my-app の上にあたる
$ kubectl get services NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 83m my-service NodePort 10.100.105.10 <none> 8080:30000/TCP 10s
- 確認してみよう
$ kubectl describe services my-service Name: my-service Namespace: default Labels: <none> Annotations: <none> Selector: app=my-app Type: NodePort IP Family Policy: SingleStack IP Families: IPv4 IP: 10.100.105.10 IPs: 10.100.105.10 Port: <unset> 8080/TCP TargetPort: 80/TCP NodePort: <unset> 30000/TCP Endpoints: 172.17.0.3:80,172.17.0.4:80,172.17.0.5:80 Session Affinity: None External Traffic Policy: Cluster Events: <none>
- 今の状態
- 今の状態
動作確認ができたところで、今度は Deployment オブジェクトを使うと、スケールと更新がカンタンなことを試してみましょう!
まずはスケールです。
- Pod の数を増やしてみよう
$ kubectl scale --replicas=5 deployment/my-deployment deployment.apps/my-deployment scaled
- 確認してみよう
$ kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES my-deployment-5bc688cdbf-5vnsh 1/1 Running 0 9m57s 172.17.0.4 se0830-m <none> <none> my-deployment-5bc688cdbf-9d6tr 1/1 Running 0 27s 172.17.0.7 se0830-m <none> <none> my-deployment-5bc688cdbf-9kgqx 1/1 Running 0 9m57s 172.17.0.3 se0830-m <none> <none> my-deployment-5bc688cdbf-9sgzb 1/1 Running 0 9m57s 172.17.0.5 se0830-m <none> <none> my-deployment-5bc688cdbf-d2s5s 1/1 Running 0 27s 172.17.0.6 se0830-m <none> <none>
今度は更新です。
- apache から nginx に変えてみよう
apiVersion: apps/v1 kind: Deployment metadata: name: my-deployment spec: replicas: 3 selector: matchLabels: app: my-app template: metadata: labels: app: my-app spec: containers: - name: my-container image: nginx ports: - containerPort: 80
- 動かしてみよう
$ kubectl apply -f deployexample_nginx.yaml deployment.apps/my-deployment configured se0830-m@se0830-m:~$ kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES my-deployment-5bc688cdbf-5vnsh 1/1 Terminating 0 12m 172.17.0.4 se0830-m <none> <none> my-deployment-5bc688cdbf-9d6tr 0/1 Terminating 0 3m14s 172.17.0.7 se0830-m <none> <none> my-deployment-5bc688cdbf-9kgqx 1/1 Running 0 12m 172.17.0.3 se0830-m <none> <none> my-deployment-5d4f4fc997-nvbjw 1/1 Running 0 4s 172.17.0.6 se0830-m <none> <none> my-deployment-5d4f4fc997-nzfk7 0/1 Pending 0 0s <none> se0830-m <none> <none> my-deployment-5d4f4fc997-x7t4f 1/1 Running 0 8s 172.17.0.8 se0830-m <none> <none>
- 徐々に変わっている
このあと、ロールバックもやってみましたが、とてもカンタンにできました。
こうやってマニフェストで “望ましい状態” を定義・更新して実行するのは、フロントエンドなどでも出てくる「宣言的」と同じように感じてきました。 と思ったら、 Kubernetes も同じ言葉を使っていたのですね。
3位 宣言的なAPIと自動化
Kubernetesの基本的なコンセプトの1つに、APIが命令的(Imperative)ではなく宣言的(Declarative)であることがあります。
いわば命令的というのはマニュアル運転で、宣言的というのは自動運転のようなものです。
Kubernetesが注目され続ける5つの理由。 KubeCon + CloudNativeCon North America 2018 - Publickey より
永続ボリューム(PersistentVolume)
では、最後のテーマです。 Docker も同じですがコンテナは捨てると、データを保持できないので永続化が必要です。 Kubernetes も同様に必要です。
- Docker のボリュームマウントと同じ
- 2 つのディスクを定義する
- PersistentVolume
- 実際使用するディスク
- PersistantVolumeClaim
- 使用したいディスクの定義を書く
- インターフェイスの役割
- それに合致したディスクを割り当てる
- PersistentVolume
永続ボリュームを作ってみよう
では、実際永続ボリュームを作ってみましょう。 なお設定は Kubernetes の種類によって変わります。 今回は minikube での設定です。
- PersistentVolume マニフェストを作ってみよう
apiVersion: v1 kind: PersistentVolume metadata: name: my-volume spec: accessModes: - ReadOnlyMany capacity: storage: 5Mi storageClassName: standard hostPath: path: /data/example
- PersistentVolumeClaim マニフェストを作ってみよう
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: my-volume-claim spec: accessModes: - ReadOnlyMany resources: requests: storage: 5Mi storageClassName: standard volumeName: my-volume
- Pod での定義例
apiVersion: apps/v1 kind: Deployment metadata: name: my-deployment spec: replicas: 3 selector: matchLabels: app: my-app template: metadata: labels: app: my-app spec: containers: - name: my-container image: httpd ports: - containerPort: 80 volumeMounts: - name: my-volume-storage mountPath: /usr/local/apache2/htdocs volumes: - name: my-volume-storage persistentVolumeClaim: claimName: my-volume-claim
- 作ってみよう
$ kubectl apply -f persistent.yaml persistentvolume/my-volume created $ kubectl apply -f deployexample_persistent.yaml deployment.apps/my-deployment created
- 確認してみよう
$ kubectl get pods NAME READY STATUS RESTARTS AGE my-deployment-8584ffd4dd-m26sv 1/1 Running 0 66s my-deployment-8584ffd4dd-pwj7g 1/1 Running 0 66s my-deployment-8584ffd4dd-vgxsc 1/1 Running 0 66s # 中略 Volumes: my-volume-storage: Type: PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace) ClaimName: my-volume-claim ReadOnly: false kube-api-access-qq95g: Type: Projected (a volume that contains injected data from multiple sources) # 中略 Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 84s default-scheduler Successfully assigned default/my-deployment-8584ffd4dd-vgxsc to se0830-m Normal Pulling 83s kubelet Pulling image "httpd" Normal Pulled 81s kubelet Successfully pulled image "httpd" in 2.104436267s Normal Created 81s kubelet Created container my-container Normal Started 81s kubelet Started container my-container
では、永続化できているか確認してみましょう。
- ファイルを置いてみよう
$ sudo sh -c "echo '<html><body>Hello k8s</body></html>'" > /data/example/index.html
マウントされていることを確認したところで、このコースは修了しました。
まとめ
Kubernetes を動かしながら、その特徴と仕組みを学びました。
コース中、何度も大澤さんがおっしゃったように Kubernetes では直接コンテナを操作するというより、「望ましい状態」を定義して、それを保つように自律的に動きます。 “自律” や “宣言的” というのがピンときていませんでしたが、自分で体験して動作を確認すると、具体的にイメージできるようになりました。
Kubernetes だけでなく、クラウドネイティブな技術の特徴を掴むのに、とてもおすすめのコースでした!
label SEカレッジを詳しく知りたいという方はこちらから !!
IT専門の定額制研修 月額 28,000 円 ~/ 1社 で IT研修 制度を導入できます。
年間 670 講座をほぼ毎日開催中!!
SEプラスにしかないコンテンツや、研修サービスの運営情報を発信しています。