Edited at

Kubernetes サイドカーの作り方とファイル共有

More than 1 year has passed since last update.

ポッドの中で二つのコンテナが動作して、ストレージを共有しながら動作するポッドを指して、サイドカー(Sidecar) と呼ぶ様です。

この様なサイドカーの主な用途として、ログを転送する目的や、ウェブ・アプリのコンテンツを共有する目的があります。この様な目的の場合、外部の永続ディスクを利用するとディスクアクセスのためのiSCSIがボトルネックとなる恐れがあります。 一方、ポッドを収容するノードの仮想サーバーのストレージはSSDが使われている(IBM Cloudのケース)ため、永続ストレージを利用せず、ノードのストレージを利用する事が得策と思います。


比較の図


IBM Cloud のワーカーノードは Local Disk(SSD)が利用される

そこで、サイドカーを構成する方法について、そして、特徴について確認しました。


サイドカー構成のポッド作成

一つのポッドに2つのコンテナを設定するYAMLで、ストレージの持ち方が、それぞれ異なっています。前者はノードのストレージのパスを指定する方法、後者は専用に確保する方法です。


ノードのストレージをパス指定で利用

ノードのディスクのパスを指定してマウントします。

次の様に、hostPathを設定します。 ノードのパスを指定しているので、同一ノードにポッドのレプリカが存在する場合、それらともストレージが共有されます。

  volumes:

- name: host-volume
hostPath:
path: /www
type: DirectoryOrCreate

コンテナで、それぞれ volumeMounts を指定します。 ここでは、ログインした時に判別できる様に、意図的にマウント先を変えてあります。 tc-1 は /var/www1、 tc-2 は /var/www2 としています。


t080_host_vol.yml

apiVersion: v1

kind: Pod
metadata:
name: test-pod-1
spec:
containers:
- image: ubuntu:latest
name: tc-1
volumeMounts:
- mountPath: /var/www1
name: host-volume
command: ["tail", "-f", "/dev/null"]
- image: ubuntu:latest
name: tc-2
volumeMounts:
- mountPath: /var/www2
name: host-volume
command: ["tail", "-f", "/dev/null"]
volumes:
- name: host-volume
hostPath:
path: /www
type: DirectoryOrCreate


専用の一時的なディレクトリを利用する方法

こちらは、emptyDirを利用して、ポッド専用のディレクトを利用します。 前述の様なノードで共有にはなりません。

  volumes:

- name: cache-volume
emptyDir: {}

1ポッドに2つのコンテナを動作させるYAMLファイルの全体です。


t081_host_vol.yml

apiVersion: v1

kind: Pod
metadata:
name: test-pod-2
spec:
containers:
- image: ubuntu:latest
name: tc-1
volumeMounts:
- mountPath: /var/www1
name: cache-volume
command: ["tail", "-f", "/dev/null"]
- image: ubuntu:latest
name: tc-2
volumeMounts:
- mountPath: /var/www2
name: cache-volume
command: ["tail", "-f", "/dev/null"]
volumes:
- name: cache-volume
emptyDir: {}


ポッド内のコンテナを指定してコマンドを実行する方法

ポッド内のコンテナを指定してログインするには、-c オプションで、コンテナ名を指定します。

二つのポッドは、同じIPアドレスを共有して、ホスト名も同じになります。 しかし、プロセス空間は異なります。


コンテナを指定してログインする例

$ kubectl exec -c tc-1 -it test-pod-1 bash

root@test-pod-1:/# df -h
Filesystem Size Used Avail Use% Mounted on
overlay 99G 6.7G 87G 8% /
tmpfs 2.0G 0 2.0G 0% /dev
tmpfs 2.0G 0 2.0G 0% /sys/fs/cgroup
/dev/xvda2 24G 4.7G 20G 20% /var/www1
/dev/mapper/docker_data 99G 6.7G 87G 8% /etc/hostname
shm 64M 0 64M 0% /dev/shm
tmpfs 2.0G 12K 2.0G 1% /run/secrets/kubernetes.io/serviceaccount
tmpfs 2.0G 0 2.0G 0% /sys/firmware

$ kubectl exec -c tc-2 -it test-pod-1 bash

root@test-pod-1:/# df -h
Filesystem Size Used Avail Use% Mounted on
overlay 99G 6.7G 87G 8% /
tmpfs 2.0G 0 2.0G 0% /dev
tmpfs 2.0G 0 2.0G 0% /sys/fs/cgroup
/dev/xvda2 24G 4.7G 20G 20% /var/www2
/dev/mapper/docker_data 99G 6.7G 87G 8% /etc/hostname
shm 64M 0 64M 0% /dev/shm
tmpfs 2.0G 12K 2.0G 1% /run/secrets/kubernetes.io/serviceaccount
tmpfs 2.0G 0 2.0G 0% /sys/firmware


プロセス空間が独立していることを確認

プロセス番号が異なっていることに注目してください。

$ kubectl exec -c tc-1 -it test-pod-1 bash

root@test-pod-1:/# ps -ax
PID TTY STAT TIME COMMAND
1 ? Ss 0:00 tail -f /dev/null
62 pts/0 Ss 0:00 bash
71 pts/0 R+ 0:00 ps -ax
root@test-pod-1:/# exit

$ kubectl exec -c tc-2 -it test-pod-1 bash
root@test-pod-1:/# ps -ax
PID TTY STAT TIME COMMAND
1 ? Ss 0:00 tail -f /dev/null
56 pts/0 Ss 0:00 bash
65 pts/0 R+ 0:00 ps -ax


ホスト名とIPが同じことを確認

プロセス空間は異なるのですが、ホスト名とIPアドレスは、ポッド内のコンテナで同じです。 これは2つで一つとして利用されることを前提にしていると言っても良いでしょう。

$ kubectl exec -c tc-1 -it test-pod-1 bash

root@test-pod-1:/# hostname
test-pod-1
root@test-pod-1:/# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
2: tunl0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN group default qlen 1
link/ipip 0.0.0.0 brd 0.0.0.0
4: eth0@if55779: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1480 qdisc noqueue state UP group default
link/ether b2:32:c0:5c:d7:cc brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.30.170.194/32 scope global eth0
valid_lft forever preferred_lft forever
root@test-pod-1:/# exit

$ kubectl exec -c tc-2 -it test-pod-1 bash
root@test-pod-1:/# hostname
test-pod-1
root@test-pod-1:/# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
2: tunl0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN group default qlen 1
link/ipip 0.0.0.0 brd 0.0.0.0
4: eth0@if55779: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1480 qdisc noqueue state UP group default
link/ether b2:32:c0:5c:d7:cc brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.30.170.194/32 scope global eth0
valid_lft forever preferred_lft forever


参考資料