はじめに
OpenShift on OpenStackな環境にて、CSI Cinder Pluginを導入する手順。
基本的には公式ドキュメントのインストール手順に従えば問題ないのだが、一部うまくいかない箇所もあったため、備忘録的に書いておきたい。
環境
- RedHat OpenStack Platform v13(Queens)
- OpenShift v4.3.3
- Cinder CSI Plugin Version v1.2.0
CSI Cinder Pluginを使う理由
そもそも、OpenShiftもといKubernetesにはCinderというVolume Providerが存在している。
名前の如く、Cinderと連携してVolume操作を行ってくれる。つまり、わざわざCSI Cinder Pluginを導入する必要性が薄かった。
しかし、k8s v1.16からは上記のCinder Volume ProviderがDeprecated
となった。
つまりこれからCinderと連携させたいなら、別の方法を取る必要がある。というわけで、CSI Cinder Pluginを使う必要性が高まった。
さらに、Nova-AZとCinder-AZのゾーン名が異なる場合、Cinder Volume Providerだと問題が発生しやすい。
Podがどこで動くか?というスケジューリングを司るNode Affinity / Node Selectorにてゾーン(failure-domain.beta.kubernetes.io/zone)を指定した場合、Nova-AZとCinder-AZが異なるとPodの生成に失敗する。
※該当するノードがないよーとなってしまう
Cinder CSI pluginだとその辺も簡単にクリアでき、使い勝手が良い。
※理解に間違いがある可能性があります、詳しい方いらっしゃったら是非ご指摘ください
導入
細かいことは考えず、ひとまず導入 -> 基本動作確認までを行ってみる。
というか私が初心者なので、あまり凝ったことができない。今後を検証を重ねていきたい。
原則的に下記のドキュメントの通りに進めれば問題ない。
using-cinder-csi-plugin
準備
とにもかくにもgit cloneをする。
$ git clone git@github.com:kubernetes/cloud-provider-openstack.git
cloud.confを用意
様々なシーンでよく使うclouds.yaml
ではない。
私は最初勘違いしてclouds.yamlを用意して、あれーうまくかないなーとか唸ってた。
以下のようなファイルを用意する。特筆する点は少ない。
自己署名SSL証明書を使用したOpenStack環境の場合、必ずca-file
を定義すること。そうではない環境なら不要。
[Global]
auth-url = "https://[keystone_fqdn]/v3"
username = "[username]"
password = "[password]"
tenant-name = "[project_name]"
domain-name = "[openstack_domain_name]"
region = "[openstack_region_name]"
ca-file = /etc/config/ca-bundle.pem
[BlockStorage]
bs-version=v2
secretの準備
用意したcloud.confをbase64でエンコードして、元々用意されているcsi-secret-cinderplugin.yaml
-> data
-> cloud.conf
のvalueを置き換える。
$ cat cloud.conf | base64 -w 0
$ vim manifests/cinder-csi-plugin/csi-secret-cinderplugin.yaml
また、cloud.conf内でca-fileを定義している場合、そのパスでCA証明書を読み込むようにしてあげる必要がある。
同ファイル内にca-bundle.pem
キーを用意して、同じようにbase64エンコードしたvalueを設定する。
# This YAML file contains secret objects,
# which are necessary to run csi cinder plugin.
kind: Secret
apiVersion: v1
metadata:
name: cloud-config
namespace: kube-system
data:
cloud.conf: [base64_encoded_cloud.yaml]
ca-bundle.pem: [base64_encoded_ca-cert]
これでsecretの準備は完了。
ただ、実はOpenshift on OpenStackを作った時点でcloud.confの中身の情報やCA証明書の情報はOpenShiftは格納されている。
本来はその辺のSecretかConfigMapを充てがえたら一番良いのだと思う。いずれそういったもう少しスマートなやり方を検証して、ここに追記したい。
※公式ドキュメントの/etc/cacertをマウントしている手順が、本来そういった意図のはず
不要なvolumeを削除
これを削除しないとPodがうまく起動しなかった。
manifests/cinder-csi-plugin/cinder-csi-nodeplugin.yaml
内のvolume設定のpod-cloud-data
を削除する。
※使用するCSIのバージョンによって多少の差異はあるだろうが、73行目-75行目 / 95行目-98行目あたり
@@ -70,9 +70,6 @@ spec:
- name: kubelet-dir
mountPath: /var/lib/kubelet
mountPropagation: "Bidirectional"
- - name: pods-cloud-data
- mountPath: /var/lib/cloud/data
- readOnly: true
- name: pods-probe-dir
mountPath: /dev
mountPropagation: "HostToContainer"
@@ -92,10 +89,6 @@ spec:
hostPath:
path: /var/lib/kubelet
type: Directory
- - name: pods-cloud-data
- hostPath:
- path: /var/lib/cloud/data
- type: Directory
- name: pods-probe-dir
hostPath:
path: /dev
この対応で簡単な動作確認をした限り問題なく動作する。
知識不足過ぎて、本来何のためにこれが必要だったのか、どう修正すれば良いのかがわからない。
追って検証を続けて本記事に追記したい。
デプロイ
[oc|kubectl] -f manifests/cinder-csi-plugin apply
コマンドを実行する。これでデプロイ完了。
$ oc -f manifests/cinder-csi-plugin apply
serviceaccount/csi-cinder-controller-sa created
clusterrole.rbac.authorization.k8s.io/csi-attacher-role created
clusterrolebinding.rbac.authorization.k8s.io/csi-attacher-binding created
clusterrole.rbac.authorization.k8s.io/csi-provisioner-role created
clusterrolebinding.rbac.authorization.k8s.io/csi-provisioner-binding created
clusterrole.rbac.authorization.k8s.io/csi-snapshotter-role created
clusterrolebinding.rbac.authorization.k8s.io/csi-snapshotter-binding created
clusterrole.rbac.authorization.k8s.io/csi-resizer-role created
clusterrolebinding.rbac.authorization.k8s.io/csi-resizer-binding created
role.rbac.authorization.k8s.io/external-resizer-cfg created
rolebinding.rbac.authorization.k8s.io/csi-resizer-role-cfg created
service/csi-cinder-controller-service created
statefulset.apps/csi-cinder-controllerplugin created
serviceaccount/csi-cinder-node-sa created
clusterrole.rbac.authorization.k8s.io/csi-nodeplugin-role created
clusterrolebinding.rbac.authorization.k8s.io/csi-nodeplugin-binding created
daemonset.apps/csi-cinder-nodeplugin created
csidriver.storage.k8s.io/cinder.csi.openstack.org created
secret/cloud-config created
失敗パターン
Podが全く動いていない。
$ oc get pod -n kube-system
NAME READY STATUS RESTARTS AGE
csi-cinder-controllerplugin-0 4/5 CrashLoopBackOff 8 19m
csi-cinder-nodeplugin-72djh 0/2 ContainerCreating 0 19m
csi-cinder-nodeplugin-rqkqz 0/2 ContainerCreating 0 19m
csi-cinder-nodeplugin-xmc4f 0/2 ContainerCreating 0 19m
理由はいくつか考えられる。多くの場合、csi-cinder-controllerplugin内のコンテナであるcinder-csi-plugin
のログを見ると、原因を追いかけやすい。
こいつが正常に動作していないとcsi-cinder-controllerplugin内の他のコンテナも正常に動作しない。
例えばCA証明書を読み込めていないとき。
この場合はsecretの中身に何か問題があるかもしれない。cloud.confのca-fileのパスが間違っているとか。
W0317 07:30:29.038530 1 connection.go:170] Still connecting to unix:///var/lib/csi/sockets/pluginproxy/csi.sock
I0317 07:26:44.801192 1 driver.go:57] Driver: cinder.csi.openstack.org version: 1.2.0
I0317 07:26:44.801240 1 driver.go:91] Enabling controller service capability: LIST_VOLUMES
I0317 07:26:44.801244 1 driver.go:91] Enabling controller service capability: CREATE_DELETE_VOLUME
I0317 07:26:44.801247 1 driver.go:91] Enabling controller service capability: PUBLISH_UNPUBLISH_VOLUME
I0317 07:26:44.801249 1 driver.go:91] Enabling controller service capability: CREATE_DELETE_SNAPSHOT
I0317 07:26:44.801252 1 driver.go:91] Enabling controller service capability: LIST_SNAPSHOTS
I0317 07:26:44.801254 1 driver.go:91] Enabling controller service capability: EXPAND_VOLUME
I0317 07:26:44.801257 1 driver.go:91] Enabling controller service capability: CLONE_VOLUME
I0317 07:26:44.801260 1 driver.go:103] Enabling volume access mode: SINGLE_NODE_WRITER
I0317 07:26:44.801263 1 driver.go:113] Enabling node service capability: STAGE_UNSTAGE_VOLUME
I0317 07:26:44.801266 1 driver.go:113] Enabling node service capability: EXPAND_VOLUME
I0317 07:26:44.801508 1 openstack.go:85] Block storage opts: {0}
W0317 07:26:44.801562 1 main.go:121] Failed to GetOpenStackProvider: failed to read and parse /etc/kubernetes/static-pod-resources/configmaps/cloud-config/ca-bundle.pem certificate: open /etc/kubernetes/static-pod-resources/configmaps/cloud-config/ca-bundle.pem: no such file or directory
ちなみに不要なvolumeを削除の対応をしていないとこんなエラーが出る。
MountVolume.SetUp failed for volume "pods-cloud-data" : hostPath type check failed: /var/lib/cloud/data is not a directory
Warning FailedMount 5m26s (x23 over 36m) kubelet, openshift-c99ba-worker-19abc MountVolume.SetUp failed for volume "pods-cloud-data" : hostPath type check failed: /var/lib/cloud/data is not a directory
成功パターン
Podが全部起動状態。
$ oc get pods -n kube-system
NAME READY STATUS RESTARTS AGE
csi-cinder-controllerplugin-0 5/5 Running 0 70s
csi-cinder-nodeplugin-867jd 2/2 Running 0 69s
csi-cinder-nodeplugin-c782h 2/2 Running 0 60s
csi-cinder-nodeplugin-z4x5s 2/2 Running 0 64s
I0317 08:17:02.081919 1 driver.go:57] Driver: cinder.csi.openstack.org version: 1.2.0
I0317 08:17:02.081956 1 driver.go:91] Enabling controller service capability: LIST_VOLUMES
I0317 08:17:02.081960 1 driver.go:91] Enabling controller service capability: CREATE_DELETE_VOLUME
I0317 08:17:02.081963 1 driver.go:91] Enabling controller service capability: PUBLISH_UNPUBLISH_VOLUME
I0317 08:17:02.081969 1 driver.go:91] Enabling controller service capability: CREATE_DELETE_SNAPSHOT
I0317 08:17:02.081972 1 driver.go:91] Enabling controller service capability: LIST_SNAPSHOTS
I0317 08:17:02.081974 1 driver.go:91] Enabling controller service capability: EXPAND_VOLUME
I0317 08:17:02.081976 1 driver.go:91] Enabling controller service capability: CLONE_VOLUME
I0317 08:17:02.081979 1 driver.go:103] Enabling volume access mode: SINGLE_NODE_WRITER
I0317 08:17:02.081982 1 driver.go:113] Enabling node service capability: STAGE_UNSTAGE_VOLUME
I0317 08:17:02.081985 1 driver.go:113] Enabling node service capability: EXPAND_VOLUME
I0317 08:17:02.082287 1 openstack.go:85] Block storage opts: {0}
I0317 08:17:02.199969 1 server.go:108] Listening for connections on address: &net.UnixAddr{Name:"/csi/csi.sock", Net:"unix"}
I0317 08:17:02.681284 1 openstack.go:85] Block storage opts: {0}
I0317 08:17:02.894320 1 openstack.go:85] Block storage opts: {0}
I0317 08:17:02.907109 1 openstack.go:85] Block storage opts: {0}
I0317 08:17:03.111112 1 openstack.go:85] Block storage opts: {0}
$ oc describe csidrivers.storage.k8s.io
Name: cinder.csi.openstack.org
Namespace:
Labels: <none>
Annotations: kubectl.kubernetes.io/last-applied-configuration:
{"apiVersion":"storage.k8s.io/v1beta1","kind":"CSIDriver","metadata":{"annotations":{},"name":"cinder.csi.openstack.org"},"spec":{"attachR...
API Version: storage.k8s.io/v1beta1
Kind: CSIDriver
Metadata:
Creation Timestamp: 2020-03-15T07:09:48Z
Resource Version: 420507
Self Link: /apis/storage.k8s.io/v1beta1/csidrivers/cinder.csi.openstack.org
UID: 98aedf93-54ea0-4cfb-ad0e-85ed81f1052c
Spec:
Attach Required: true
Pod Info On Mount: true
Volume Lifecycle Modes:
Persistent
Ephemeral
Events: <none>
動作確認
ありがたいことに動作確認用のnginxが用意されている。
$ oc -f examples/cinder-csi-plugin/nginx.yaml create
storageclass.storage.k8s.io/csi-sc-cinderplugin created
persistentvolumeclaim/csi-pvc-cinderplugin created
pod/nginx created
PersistentVolumeClaimや実態のPersistentVolumeが作成されている。STATUSがBoundなので、正常にPodにアタッチされている。
$ oc get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
csi-pvc-cinderplugin Bound pvc-5bc0e35c-55ca-4de4-b880-9ac2012a1dd2 1Gi RWO csi-sc-cinderplugin 44s
$ oc get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pvc-5bc0e35c-55ca-4de4-b880-9ac2012a1dd2 1Gi RWO Delete Bound default/csi-pvc-cinderplugin csi-sc-cinderplugin 102s
Cinderと連携してPersistentVolumeを作成していることが確認できる。
$ oc describe pvc
Name: csi-pvc-cinderplugin
Namespace: default
StorageClass: csi-sc-cinderplugin
Status: Bound
Volume: pvc-70c0e35c-1289-4de4-b880-4bd2012a1ba1
Labels: <none>
Annotations: pv.kubernetes.io/bind-completed: yes
pv.kubernetes.io/bound-by-controller: yes
volume.beta.kubernetes.io/storage-provisioner: cinder.csi.openstack.org
Finalizers: [kubernetes.io/pvc-protection]
Capacity: 1Gi
Access Modes: RWO
VolumeMode: Filesystem
Mounted By: nginx
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ExternalProvisioning 82s persistentvolume-controller waiting for a volume to be created, either by external provisioner "cinder.csi.openstack.org" or manually created by system administrator
Normal Provisioning 82s cinder.csi.openstack.org_csi-cinder-controllerplugin-0_bb1af4ee-8a44-45a1-b48e-f197fdd3b430 External provisioner is provisioning volume for claim "default/csi-pvc-cinderplugin"
Normal ProvisioningSucceeded 80s cinder.csi.openstack.org_csi-cinder-controllerplugin-0_bb1af4ee-8a44-45a1-b48e-f197fdd3b430 Successfully provisioned volume pvc-70c0e35c-1289-4de4-b880-4bd2012a1ba1
Nginx自体も正常に稼働中。
$ oc get pod nginx
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 0 4m55s
$ oc describe pod nginx
Name: nginx
Namespace: default
Priority: 0
Node: openshift-c99ba-worker-19abc/10.0.0.31
Start Time: Tue, 17 Mar 2020 08:19:40 +0000
Labels: <none>
Annotations: k8s.v1.cni.cncf.io/networks-status:
[{
"name": "openshift-sdn",
"interface": "eth0",
"ips": [
"10.129.2.106"
],
"dns": {},
"default-route": [
"10.129.2.1"
]
}]
Status: Running
IP: 10.129.2.106
IPs:
IP: 10.129.2.106
Containers:
nginx:
Container ID: cri-o://d10ffef623ad45310f268996be0fdec865cb0733d4118ae8edbc389cc3d6d2c1
Image: nginx
Image ID: docker.io/library/nginx@sha256:2539d4344dd18e1df02be842ffc435f8e1f699cfc55516e2cf2cb16b7a9aea0b
Port: 80/TCP
Host Port: 0/TCP
State: Running
Started: Tue, 17 Mar 2020 08:20:14 +0000
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/lib/www/html from csi-data-cinderplugin (rw)
/var/run/secrets/kubernetes.io/serviceaccount from default-token-7zzsw (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
csi-data-cinderplugin:
Type: PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace)
ClaimName: csi-pvc-cinderplugin
ReadOnly: false
default-token-7zzsw:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-7zzsw
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s
node.kubernetes.io/unreachable:NoExecute for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedScheduling <unknown> default-scheduler pod has unbound immediate PersistentVolumeClaims (repeated 3 times)
Warning FailedScheduling <unknown> default-scheduler pod has unbound immediate PersistentVolumeClaims (repeated 3 times)
Normal Scheduled <unknown> default-scheduler Successfully assigned default/nginx to openshift-c99ba-worker-19abc
Normal SuccessfulAttachVolume 5m27s attachdetach-controller AttachVolume.Attach succeeded for volume "pvc-70c0e35c-1289-4de4-b880-4bd2012a1ba1"
Normal Pulling 5m10s kubelet, openshift-c99ba-worker-19abc Pulling image "nginx"
Normal Pulled 4m59s kubelet, openshift-c99ba-worker-19abc Successfully pulled image "nginx"
Normal Created 4m59s kubelet, openshift-c99ba-worker-19abc Created container nginx
Normal Started 4m59s kubelet, openshift-c99ba-worker-19abc Started container nginx
OpenStack側も確認してみる。バッチリ存在。
$ openstack volume list
+--------------------------------------+------------------------------------------+-----------+------+------------------------------------------------------------+
| ID | Name | Status | Size | Attached to |
+--------------------------------------+------------------------------------------+-----------+------+------------------------------------------------------------+
| a0606bf9-9ea8-494d-9ac4-15bdb145c5f1 | pvc-5bc0e35c-55ca-4de4-b880-9ac2012a1dd2 | in-use | 1 | Attached to openshift-c99ba-worker-19abc on /dev/vdb |
+--------------------------------------+------------------------------------------+-----------+------+------------------------------------------------------------+
$ openstack volume show pvc-70c0e35c-1289-4de4-b880-4bd2012a1ba1
+--------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Field | Value |
+--------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| attachments | [{u'server_id': u'9a7b76a4-d9f2-195e-ca9e-f2e66260159e', u'attachment_id': u'8457e214-61a9-43c2-bcae-ce9e6dc99ae', u'attached_at': u'2020-03-15T08:19:46.000000', u'host_name': u'compute01.example.local', u'volume_id': u'a0606bf9-9ea8-494d-9ac4-15bdb145c5f1', u'device': u'/dev/vdb', u'id': u'1abddd9-b323-494d-9ac4-5d954145c5f1'}] |
| availability_zone | nova |
| bootable | false |
| consistencygroup_id | None |
| created_at | 2020-03-15T08:19:38.000000 |
| description | Created by OpenStack Cinder CSI driver |
| encrypted | False |
| id | a0606bf9-b323-494d-9ac4-5d32b145c5f1 |
| migration_status | None |
| multiattach | False |
| name | pvc-5bc0e35c-55ca-4de4-b880-9ac2012a1dd2 |
| os-vol-host-attr:host | hostgroup@tripleo_ceph#tripleo_ceph |
| os-vol-mig-status-attr:migstat | None |
| os-vol-mig-status-attr:name_id | None |
| os-vol-tenant-attr:tenant_id | fcbca9ba19dc4adc810b84cba01123cb |
| properties | attached_mode='rw', cinder.csi.openstack.org/cluster='kubernetes' |
| replication_status | None |
| size | 1 |
| snapshot_id | None |
| source_volid | None |
| status | in-use |
| type | tripleo |
| updated_at | 2020-03-15T08:19:46.000000 |
| user_id | 99b506d9e6aacbb632c0af3e7340282fcf1bf6bb2f84f1f8156b7cb2f4e39e92 |
+--------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
あとがき
色々触った感じ、旧来のCinder Volume Providerは使う必要性がないぐらいまで完成度が高まってると思う。だからこそのDeprecatedなんだろうけれど。CSI Cinder Pluginに行き着くまで、AZの違いに本当に苦しめられた。回避策は色々あったけど、もっと楽にできないかなーと思った末にCSI Cinder Pluginに助けられた。今はまだ導入して簡単な動作確認をした程度でしかない。もっと検証を重ねていきたい。その中で有益な情報があれば、また記事として書いたり、あるいは本記事を更新したりしていきたい。