0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

k8s Tasksを通しでやってみる:Configure a Pod to Use a Volume for Storage

0
Last updated at Posted at 2019-08-08

参考資料

Configure a Pod to Use a Volume for Storage (kubernetes.io)
Declarative Management of Kubernetes Objects Using Kustomize (kubernetes.io)
Volumes emptyDir (kubernetes.io)

何を学べるか

  • コンテナでデータを保存するにはVolumeを使う
  • Volume種別毎に、データの生存期間が異なる

事前知識

  • コンテナが終了(再起動)した時、コンテナが持っているファイルシステム内の変更は全て失われる
    →コンテナ生成元のイメージと同等の状態に戻る
  • 上記の通りなので、コンテナをステートフルで使いたい(状態、データを保存したい)ならば、永続ストレージをコンテナへマウントしておく必要がある

前提条件

  • k8s v1.14以降 (Kustomizeが必要)
  • k8sクラスタ起動済み

環境情報

  • CNI実装: calico
  • CRI実装: Docker
  • ホストOS: Ubuntu 18.04

手順

1/5 : Podを作って状態を監視する

1.png

後続のコマンドを実行するにはC-zで監視をバックグラウンドジョブにするか、別シェルを立ち上げましょう(C-Shift-t等)

kubectl apply -f https://k8s.io/examples/pods/storage/redis.yaml && \
kubectl get pod redis --watch

pod/redis created
NAME    READY   STATUS              RESTARTS   AGE
redis   0/1     ContainerCreating   0          0s
redis   1/1     Running             0          17s

2/5 : 作ったPodでシェルを起動する

2.png

kubectl exec -it redis -- /bin/bash

root@redis:/data#

3/5 : 起動したシェルでファイルを作る

3.png

cd /data/redis/
echo Hello > test-file && ls

test-file

4/5 : シェルでUbuntuのリポジトリ情報を更新し、procpsパッケージをインストールし、ps auxで動いているプロセスの情報を見る

4.png

...失敗。。corednsがきちんと動いてませんでした。

apt-get update

Err:1 http://security.debian.org/debian-security buster/updates InRelease
  Temporary failure resolving 'security.debian.org'
Err:2 http://deb.debian.org/debian buster InRelease
  Temporary failure resolving 'deb.debian.org'
Err:3 http://deb.debian.org/debian buster-updates InRelease
  Temporary failure resolving 'deb.debian.org'
Reading package lists... Done
W: Failed to fetch http://deb.debian.org/debian/dists/buster/InRelease  Temporary failure resolving 'deb.debian.org'
W: Failed to fetch http://security.debian.org/debian-security/dists/buster/updates/InRelease  Temporary failure resolving 'security.debian.org'
W: Failed to fetch http://deb.debian.org/debian/dists/buster-updates/InRelease  Temporary failure resolving 'deb.debian.org'
W: Some index files failed to download. They have been ignored, or old ones used instead.

こっちの記事にて解決したので、以下は解決後です。

apt-get update

Get:1 http://security-cdn.debian.org/debian-security buster/updates InRelease [39.1 kB]
Get:2 http://cdn-fastly.deb.debian.org/debian buster InRelease [118 kB]
Get:3 http://cdn-fastly.deb.debian.org/debian buster-updates InRelease [46.8 kB]
Get:4 http://security-cdn.debian.org/debian-security buster/updates/main amd64 Packages [53.4 kB]
Get:5 http://cdn-fastly.deb.debian.org/debian buster/main amd64 Packages [7897 kB]
Fetched 8154 kB in 6s (1375 kB/s)
Reading package lists... Done
apt-get install procps

...
ps aux

USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
redis        1  0.3  0.2  40704  4124 ?        Ssl  06:26   0:06 redis-server *:6379
root       338  0.6  0.1   3868  2928 pts/0    Ss   07:02   0:00 /bin/bash
root       344  0.0  0.1   7640  2656 pts/0    R+   07:02   0:00 ps aux

5/5 : redisプロセスを落とし、Podでシェルを起動し、作ったファイル/data/redis/test-fileが存在する事を確かめる

5.png

kill 1

root@redis:/data# command terminated with exit code 137

kubectl get pod redis --watchのその後の状態

NAME    READY   STATUS    RESTARTS   AGE
redis   1/1     Running   0          41m
redis   0/1     Completed   0          42m
redis   0/1     CrashLoopBackOff   0          43m
redis   1/1     Running            1          43m
kubectl exec -it redis -- /bin/bash

root@redis:/data# ls /data/redis

test-file

test-fileは生きてますね、今回のタスクは成功です。

終わったらクリーンアップしましょう。

kubectl delete pod redis
NAME    READY   STATUS    RESTARTS   AGE
redis   1/1     Running            1          43m
redis   1/1     Terminating        1          53m
redis   0/1     Terminating        1          53m

疑問

/data/redis/はホストOSのどこのパスにマウントされたのでしょう?

今回使ったVolume種別のVolumes emptyDir (kubernetes.io)仕様を見てみましょう。

In this exercise, you create a Pod that runs one Container. This Pod has a Volume of type emptyDir that lasts for the life of the Pod, even if the Container terminates and restarts. Here is the configuration file for the Pod:

PodがスケジューリングされたNodeから追い出されるまでは、emptyDirVolumeは生きているらしいです。

By default, emptyDir volumes are stored on whatever medium is backing the node - that might be disk or SSD or network storage, depending on your environment. However, you can set the emptyDir.medium field to "Memory" to tell Kubernetes to mount a tmpfs (RAM-backed filesystem) for you instead

emptyDirは、デフォルトの動作ではNodeが持っているストレージを使い、emptyDir.mediumフィールドへ"Memory"を設定した場合は、Nodeのメモリ上にtmpfs(RAMディスク)を構築してくれるらしいです。
今回は何も設定していないので、やはりホストOS内のストレージのルート/パーティション以下にtest-fileが存在すると考えるのですが・・・locate kubernetesでホストOS内を探してみるも、作ったtest-file相当のファイルは見当たりません。
今回はこれ以上深堀りせず、ここまでとします。

現在のPodのVolume状態チェック

kubectl describe pod redis

...
Containers:
  redis:
    Mounts:
      /data/redis from redis-storage (rw)
...
  redis-storage:
    Type:       EmptyDir (a temporary directory that shares a pod's lifetime)
    Medium:
    SizeLimit:  <unset>

まとめ

今回はemptyDirというVolume種別について、簡単に触るタスクでした。
emptyDirは、基本的にPodがNodeから追い出されるまでは生きているVolume
という事で、Pod内のコンテナが死んでも、再度同じNode内で復活すれば、保存したデータも復旧できる、という事のようです。
(Node自体を信用出来ない状況になった際、別NodeへPodを移動したいケースには合わないな・・・と、k8sの運用では現実的でない感じがします)
いずれ、今回のタスクは「Pod内のコンテナにVolumeをマウントする事」がメインだったので、これは達成出来ました。

Volume, ストレージについては様々な知識を深堀りする必要はありますが、最低限

  • マウント、アンマウントの方法と場所(お互いのパス、紐付け方)
  • データの生存期間
  • Volumeの指定方法(メモリ、永続ストレージ等)

を抑えておけば大丈夫かなと考えています。
以上です。

補足:略語(慣習的な用語を除く)

  • k8s: Kubernetes
  • CNI: Container Networking Interface
  • CRI: Container Runtime Interface
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?