summaryrefslogtreecommitdiffstats
path: root/doc/rbd/rbd-kubernetes.rst
blob: caaf77d648fa4067de2462016008d1ba6a0edc67 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
==============================
 Block Devices and Kubernetes
==============================

You may use Ceph Block Device images with Kubernetes v1.13 and later through
`ceph-csi`_, which dynamically provisions RBD images to back Kubernetes
`volumes`_ and maps these RBD images as block devices (optionally mounting
a file system contained within the image) on worker nodes running
`pods`_ that reference an RBD-backed volume. Ceph stripes block device images as
objects across the cluster, which means that large Ceph Block Device images have
better performance than a standalone server!

To use Ceph Block Devices with Kubernetes v1.13 and higher, you must install
and configure ``ceph-csi`` within your Kubernetes environment. The following
diagram depicts the Kubernetes/Ceph technology stack.

.. ditaa::
            +---------------------------------------------------+
            |                   Kubernetes                      |
            +---------------------------------------------------+
            |                    ceph--csi                      |
            +------------------------+--------------------------+
                                     |
                                     | configures
                                     v
            +------------------------+ +------------------------+
            |                        | |        rbd--nbd        |
            |     Kernel Modules     | +------------------------+
            |                        | |         librbd         |
            +------------------------+-+------------------------+
            |                   RADOS Protocol                  |
            +------------------------+-+------------------------+
            |          OSDs          | |        Monitors        |
            +------------------------+ +------------------------+


.. important::
   ``ceph-csi`` uses the RBD kernel modules by default which may not support all
   Ceph `CRUSH tunables`_ or `RBD image features`_.

Create a Pool
=============

By default, Ceph block devices use the ``rbd`` pool. Create a pool for
Kubernetes volume storage. Ensure your Ceph cluster is running, then create
the pool. ::

        $ ceph osd pool create kubernetes

See `Create a Pool`_ for details on specifying the number of placement groups
for your pools, and `Placement Groups`_ for details on the number of placement
groups you should set for your pools.

A newly created pool must be initialized prior to use. Use the ``rbd`` tool
to initialize the pool::

        $ rbd pool init kubernetes

Configure ceph-csi
==================

Setup Ceph Client Authentication
--------------------------------

Create a new user for Kubernetes and `ceph-csi`. Execute the following and
record the generated key::

    $ ceph auth get-or-create client.kubernetes mon 'profile rbd' osd 'profile rbd pool=kubernetes' mgr 'profile rbd pool=kubernetes'
    [client.kubernetes]
        key = AQD9o0Fd6hQRChAAt7fMaSZXduT3NWEqylNpmg==

Generate `ceph-csi` `ConfigMap`
-------------------------------

The `ceph-csi` requires a `ConfigMap` object stored in Kubernetes to define the
the Ceph monitor addresses for the Ceph cluster. Collect both the Ceph cluster
unique `fsid` and the monitor addresses::

        $ ceph mon dump
        <...>
        fsid b9127830-b0cc-4e34-aa47-9d1a2e9949a8
        <...>
        0: [v2:192.168.1.1:3300/0,v1:192.168.1.1:6789/0] mon.a
        1: [v2:192.168.1.2:3300/0,v1:192.168.1.2:6789/0] mon.b
        2: [v2:192.168.1.3:3300/0,v1:192.168.1.3:6789/0] mon.c

.. note::
   ``ceph-csi`` currently only supports the `legacy V1 protocol`_.

Generate a `csi-config-map.yaml` file similar to the example below, substituting
the `fsid` for "clusterID", and the monitor addresses for "monitors"::

        $ cat <<EOF > csi-config-map.yaml
        ---
        apiVersion: v1
        kind: ConfigMap
        data:
          config.json: |-
            [
              {
                "clusterID": "b9127830-b0cc-4e34-aa47-9d1a2e9949a8",
                "monitors": [
                  "192.168.1.1:6789",
                  "192.168.1.2:6789",
                  "192.168.1.3:6789"
                ]
              }
            ]
        metadata:
          name: ceph-csi-config
        EOF

Once generated, store the new `ConfigMap` object in Kubernetes::

        $ kubectl apply -f csi-config-map.yaml

Generate `ceph-csi` cephx `Secret`
----------------------------------

`ceph-csi` requires the cephx credentials for communicating with the Ceph
cluster. Generate a `csi-rbd-secret.yaml` file similar to the example below,
using the newly created Kubernetes user id and cephx key::

        $ cat <<EOF > csi-rbd-secret.yaml
        ---
        apiVersion: v1
        kind: Secret
        metadata:
          name: csi-rbd-secret
          namespace: default
        stringData:
          userID: kubernetes
          userKey: AQD9o0Fd6hQRChAAt7fMaSZXduT3NWEqylNpmg==
        EOF

Once generated, store the new `Secret` object in Kubernetes::

        $ kubectl apply -f csi-rbd-secret.yaml

Configure `ceph-csi` Plugins
----------------------------

Create the required `ServiceAccount` and RBAC `ClusterRole`/`ClusterRoleBinding`
Kubernetes objects. These objects do not necessarily need to be customized for
your Kubernetes environment and therefore can be used as-is from the `ceph-csi`
deployment YAMLs::

        $ kubectl apply -f https://raw.githubusercontent.com/ceph/ceph-csi/master/deploy/rbd/kubernetes/csi-provisioner-rbac.yaml
        $ kubectl apply -f https://raw.githubusercontent.com/ceph/ceph-csi/master/deploy/rbd/kubernetes/csi-nodeplugin-rbac.yaml

Finally, create the `ceph-csi` provisioner and node plugins. With the
possible exception of the `ceph-csi` container release version, these objects do
not necessarily need to be customized for your Kubernetes environment and
therefore can be used as-is from the `ceph-csi` deployment YAMLs::

        $ wget https://raw.githubusercontent.com/ceph/ceph-csi/master/deploy/rbd/kubernetes/csi-rbdplugin-provisioner.yaml
        $ kubectl apply -f csi-rbdplugin-provisioner.yaml
        $ wget https://raw.githubusercontent.com/ceph/ceph-csi/master/deploy/rbd/kubernetes/csi-rbdplugin.yaml
        $ kubectl apply -f csi-rbdplugin.yaml

.. important::
   The provisioner and node plugin YAMLs will, by default, pull the development
   release of the `ceph-csi` container (quay.io/cephcsi/cephcsi:canary).
   The YAMLs should be updated to use a release version container for
   production workloads.

Using Ceph Block Devices
========================

Create a `StorageClass`
-----------------------

The Kubernetes `StorageClass` defines a class of storage. Multiple `StorageClass`
objects can be created to map to different quality-of-service levels (i.e. NVMe
vs HDD-based pools) and features.

For example, to create a `ceph-csi` `StorageClass` that maps to the `kubernetes`
pool created above, the following YAML file can be used after ensuring that the
"clusterID" property matches your Ceph cluster's `fsid`::

        $ cat <<EOF > csi-rbd-sc.yaml
        ---
        apiVersion: storage.k8s.io/v1
        kind: StorageClass
        metadata:
           name: csi-rbd-sc
        provisioner: rbd.csi.ceph.com
        parameters:
           clusterID: b9127830-b0cc-4e34-aa47-9d1a2e9949a8
           pool: kubernetes
           csi.storage.k8s.io/provisioner-secret-name: csi-rbd-secret
           csi.storage.k8s.io/provisioner-secret-namespace: default
           csi.storage.k8s.io/node-stage-secret-name: csi-rbd-secret
           csi.storage.k8s.io/node-stage-secret-namespace: default
        reclaimPolicy: Delete
        mountOptions:
           - discard
        EOF
        $ kubectl apply -f csi-rbd-sc.yaml

Create a `PersistentVolumeClaim`
--------------------------------

A `PersistentVolumeClaim` is a request for abstract storage resources by a user.
The `PersistentVolumeClaim` would then be associated to a `Pod` resource to
provision a `PersistentVolume`, which would be backed by a Ceph block image.
An optional `volumeMode` can be included to select between a mounted file system
(default) or raw block device-based volume.

Using `ceph-csi`, specifying `Filesystem` for `volumeMode` can support both
`ReadWriteOnce` and `ReadOnlyMany` `accessMode` claims, and specifying `Block`
for `volumeMode` can support `ReadWriteOnce`, `ReadWriteMany`, and
`ReadOnlyMany` `accessMode` claims.

For example, to create a block-based `PersistentVolumeClaim` that utilizes
the `ceph-csi`-based `StorageClass` created above, the following YAML can be
used to request raw block storage from the `csi-rbd-sc` `StorageClass`::

        $ cat <<EOF > raw-block-pvc.yaml
        ---
        apiVersion: v1
        kind: PersistentVolumeClaim
        metadata:
          name: raw-block-pvc
        spec:
          accessModes:
            - ReadWriteOnce
          volumeMode: Block
          resources:
            requests:
              storage: 1Gi
          storageClassName: csi-rbd-sc
        EOF
        $ kubectl apply -f raw-block-pvc.yaml

The following demonstrates and example of binding the above
`PersistentVolumeClaim` to a `Pod` resource as a raw block device::

        $ cat <<EOF > raw-block-pod.yaml
        ---
        apiVersion: v1
        kind: Pod
        metadata:
          name: pod-with-raw-block-volume
        spec:
          containers:
            - name: fc-container
              image: fedora:26
              command: ["/bin/sh", "-c"]
              args: ["tail -f /dev/null"]
              volumeDevices:
                - name: data
                  devicePath: /dev/xvda
          volumes:
            - name: data
              persistentVolumeClaim:
                claimName: raw-block-pvc
        EOF
        $ kubectl apply -f raw-block-pod.yaml

To create a file-system-based `PersistentVolumeClaim` that utilizes the
`ceph-csi`-based `StorageClass` created above, the following YAML can be used to
request a mounted file system (backed by an RBD image) from the `csi-rbd-sc`
`StorageClass`::

        $ cat <<EOF > pvc.yaml
        ---
        apiVersion: v1
        kind: PersistentVolumeClaim
        metadata:
          name: rbd-pvc
        spec:
          accessModes:
            - ReadWriteOnce
          volumeMode: Filesystem
          resources:
            requests:
              storage: 1Gi
          storageClassName: csi-rbd-sc
        EOF
        $ kubectl apply -f pvc.yaml

The following demonstrates and example of binding the above
`PersistentVolumeClaim` to a `Pod` resource as a mounted file system::

        $ cat <<EOF > pod.yaml
        ---
        apiVersion: v1
        kind: Pod
        metadata:
          name: csi-rbd-demo-pod
        spec:
          containers:
            - name: web-server
              image: nginx
              volumeMounts:
                - name: mypvc
                  mountPath: /var/lib/www/html
          volumes:
            - name: mypvc
              persistentVolumeClaim:
                claimName: rbd-pvc
                readOnly: false
        EOF
        $ kubectl apply -f pod.yaml

.. _ceph-csi: https://github.com/ceph/ceph-csi/
.. _volumes: https://kubernetes.io/docs/concepts/storage/volumes/
.. _pods: https://kubernetes.io/docs/concepts/workloads/pods/pod-overview/
.. _Create a Pool: ../../rados/operations/pools#createpool
.. _Placement Groups: ../../rados/operations/placement-groups
.. _CRUSH tunables: ../../rados/operations/crush-map/#tunables
.. _RBD image features: ../rbd-config-ref/#image-features
.. _legacy V1 protocol: ../../rados/configuration/msgr2/#address-formats