ΠŸΡ€Π°ΠΊΡ‚ΠΈΡ‡Π΅ΡΠΊΠΈΠΉ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π° Π½Π° Π±Π°Π·Π΅ Ceph Π² кластСр Kubernetes

Container Storage Interface (CSI) β€” это ΡƒΠ½ΠΈΡ„ΠΈΡ†ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ интСрфСйс взаимодСйствия Kubernetes ΠΈ систСм хранСния Π΄Π°Π½Π½Ρ‹Ρ…. Π’ΠΊΡ€Π°Ρ‚Ρ†Π΅ ΠΎ Π½Ρ‘ΠΌ ΠΌΡ‹ ΡƒΠΆΠ΅ рассказывали, Π° сСгодня ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½Π΅Π΅ рассмотрим связку CSI ΠΈ Ceph: ΠΏΠΎΠΊΠ°ΠΆΠ΅ΠΌ, ΠΊΠ°ΠΊ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π΅ Ceph ΠΊ кластСру Kubernetes.
Π’ ΡΡ‚Π°Ρ‚ΡŒΠ΅ ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Ρ‹ Ρ€Π΅Π°Π»ΡŒΠ½Ρ‹Π΅, хотя ΠΈ Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ ΡƒΠΏΡ€ΠΎΡ‰Ρ‘Π½Π½Ρ‹Π΅ для удобства восприятия ΠΏΡ€ΠΈΠΌΠ΅Ρ€Ρ‹. Установку ΠΈ настройку кластСров Ceph ΠΈ Kubernetes Π½Π΅ рассматриваСм.

Π’Π°ΠΌ интСрСсно, ΠΊΠ°ΠΊ это Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚?

ΠŸΡ€Π°ΠΊΡ‚ΠΈΡ‡Π΅ΡΠΊΠΈΠΉ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π° Π½Π° Π±Π°Π·Π΅ Ceph Π² кластСр Kubernetes

Π˜Ρ‚Π°ΠΊ, Ρƒ вас ΠΏΠΎΠ΄ Ρ€ΡƒΠΊΠΎΠΉ Π΅ΡΡ‚ΡŒ кластСр Kubernetes, Ρ€Π°Π·Π²Π΅Ρ€Π½ΡƒΡ‚Ρ‹ΠΉ, ΠΊ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Ρƒ, kubespray. Рядом Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ кластСр Ceph β€” Π΅Π³ΠΎ ΠΌΠΎΠΆΠ½ΠΎ Ρ‚Π°ΠΊΠΆΠ΅ ΠΏΠΎΡΡ‚Π°Π²ΠΈΡ‚ΡŒ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Π²ΠΎΡ‚ этим Π½Π°Π±ΠΎΡ€ΠΎΠΌ ΠΏΠ»Π΅ΠΉΠ±ΡƒΠΊΠΎΠ². НадСюсь, Π½Π΅ Π½ΡƒΠΆΠ½ΠΎ ΡƒΠΏΠΎΠΌΠΈΠ½Π°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ для ΠΏΡ€ΠΎΠ΄Π°ΠΊΡˆΠ΅Π½Π° ΠΌΠ΅ΠΆΠ΄Ρƒ Π½ΠΈΠΌΠΈ Π΄ΠΎΠ»ΠΆΠ½Π° Π±Ρ‹Ρ‚ΡŒ ΡΠ΅Ρ‚ΡŒ с пропускной ΡΠΏΠΎΡΠΎΠ±Π½ΠΎΡΡ‚ΡŒΡŽ Π½Π΅ ΠΌΠ΅Π½Π΅Π΅ 10 Π“Π±ΠΈΡ‚/с.

Если всё это Ρƒ вас Π΅ΡΡ‚ΡŒ, ΠΏΠΎΠ΅Ρ…Π°Π»ΠΈ!

Π‘Π½Π°Ρ‡Π°Π»Π° Π·Π°ΠΉΠ΄Π΅ΠΌ Π½Π° ΠΎΠ΄Π½Ρƒ ΠΈΠ· Π½ΠΎΠ΄ кластСра Ceph ΠΈ провСряСм, Ρ‡Ρ‚ΠΎ всё Π² порядкС:

ceph health
ceph -s

Π”Π°Π»Π΅Π΅ Ρ‚ΡƒΡ‚ ΠΆΠ΅ создадим ΠΏΡƒΠ» для RBD дисков:

ceph osd pool create kube 32
ceph osd pool application enable kube rbd

ΠŸΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ΠΈΠΌ Π² кластСр Kubernetes. Π’Π°ΠΌ ΠΏΠ΅Ρ€Π²Ρ‹ΠΌ Π΄Π΅Π»ΠΎΠΌ установим Ceph CSI Π΄Ρ€Π°ΠΉΠ²Π΅Ρ€ для RBD. Π‘Ρ‚Π°Π²ΠΈΡ‚ΡŒ Π±ΡƒΠ΄Π΅ΠΌ, ΠΊΠ°ΠΊ ΠΈ ΠΏΠΎΠ»ΠΎΠΆΠ΅Π½ΠΎ, Ρ‡Π΅Ρ€Π΅Π· Helm.
ДобавляСм Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΉ с Ρ‡Π°Ρ€Ρ‚ΠΎΠΌ, ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ Π½Π°Π±ΠΎΡ€ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ… Ρ‡Π°Ρ€Ρ‚Π° ceph-csi-rbd:

helm repo add ceph-csi https://ceph.github.io/csi-charts
helm inspect values ceph-csi/ceph-csi-rbd > cephrbd.yml

Π’Π΅ΠΏΠ΅Ρ€ΡŒ Π½ΡƒΠΆΠ½ΠΎ Π·Π°ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ Ρ„Π°ΠΉΠ» cephrbd.yml. Для этого ΡƒΠ·Π½Π°Π΅ΠΌ ID кластСра ΠΈ IP-адрСса ΠΌΠΎΠ½ΠΈΡ‚ΠΎΡ€ΠΎΠ² Π² Ceph:

ceph fsid  # Ρ‚Π°ΠΊ ΠΌΡ‹ ΡƒΠ·Π½Π°Π΅ΠΌ clusterID
ceph mon dump  # Π° Ρ‚Π°ΠΊ ΡƒΠ²ΠΈΠ΄ΠΈΠΌ IP-адрСса ΠΌΠΎΠ½ΠΈΡ‚ΠΎΡ€ΠΎΠ²

ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½Π½Ρ‹Π΅ значСния заносим Π² Ρ„Π°ΠΉΠ» cephrbd.yml. ΠŸΠΎΠΏΡƒΡ‚Π½ΠΎ Π²ΠΊΠ»ΡŽΡ‡Π°Π΅ΠΌ созданиС ΠΏΠΎΠ»ΠΈΡ‚ΠΈΠΊ PSP (Pod Security Policies). ΠžΠΏΡ†ΠΈΠΈ Π² Ρ€Π°Π·Π΄Π΅Π»Π°Ρ… nodeplugin ΠΈ provisioner ΡƒΠΆΠ΅ Π΅ΡΡ‚ΡŒ Π² Ρ„Π°ΠΉΠ»Π΅, ΠΈΡ… ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ Ρ‚Π°ΠΊ, ΠΊΠ°ΠΊ ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΎ Π½ΠΈΠΆΠ΅:

csiConfig:
  - clusterID: "bcd0d202-fba8-4352-b25d-75c89258d5ab"
    monitors:
      - "v2:172.18.8.5:3300/0,v1:172.18.8.5:6789/0"
      - "v2:172.18.8.6:3300/0,v1:172.18.8.6:6789/0"
      - "v2:172.18.8.7:3300/0,v1:172.18.8.7:6789/0"

nodeplugin:
  podSecurityPolicy:
    enabled: true

provisioner:
  podSecurityPolicy:
    enabled: true

Π”Π°Π»Π΅Π΅ всё Ρ‡Ρ‚ΠΎ Π½Π°ΠΌ остаётся β€” ΡƒΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ Ρ‡Π°Ρ€Ρ‚ Π² кластСр Kubernetes.

helm upgrade -i ceph-csi-rbd ceph-csi/ceph-csi-rbd -f cephrbd.yml -n ceph-csi-rbd --create-namespace

ΠžΡ‚Π»ΠΈΡ‡Π½ΠΎ, RBD Π΄Ρ€Π°ΠΉΠ²Π΅Ρ€ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚!
Π‘ΠΎΠ·Π΄Π°Π΄ΠΈΠΌ Π² Kubernetes Π½ΠΎΠ²Ρ‹ΠΉ StorageClass. Для этого снова потрСбуСтся Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ ΠΏΠΎΡ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ с Ceph.

Π‘ΠΎΠ·Π΄Π°Ρ‘ΠΌ Π½ΠΎΠ²ΠΎΠ³ΠΎ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ Π² Ceph ΠΈ Π²Ρ‹Π΄Π°Ρ‘ΠΌ Π΅ΠΌΡƒ ΠΏΡ€Π°Π²Π° Π½Π° запись Π² ΠΏΡƒΠ» kube:

ceph auth get-or-create client.rbdkube mon 'profile rbd' osd 'profile rbd pool=kube'

А Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ посмотрим ΠΊΠ»ΡŽΡ‡ доступа всё Ρ‚Π°ΠΌ ΠΆΠ΅:

ceph auth get-key client.rbdkube

Команда выдаст Π½Π΅Ρ‡Ρ‚ΠΎ ΠΏΠΎΠ΄ΠΎΠ±Π½ΠΎΠ΅:

AQCO9NJbhYipKRAAMqZsnqqS/T8OYQX20xIa9A==

ЗанСсём это Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π² Secret Π² кластСрС Kubernetes β€” Ρ‚ΡƒΠ΄Π°, Π³Π΄Π΅ Π½ΡƒΠΆΠ΅Π½ userKey:

---
apiVersion: v1
kind: Secret
metadata:
  name: csi-rbd-secret
  namespace: ceph-csi-rbd
stringData:
  # ЗначСния ΠΊΠ»ΡŽΡ‡Π΅ΠΉ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‚ ΠΈΠΌΠ΅Π½ΠΈ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ ΠΈ Π΅Π³ΠΎ ΠΊΠ»ΡŽΡ‡Ρƒ, ΠΊΠ°ΠΊ ΡƒΠΊΠ°Π·Π°Π½ΠΎ Π²
  # кластСрС Ceph. ID ΡŽΠ·Π΅Ρ€Π° Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΈΠΌΠ΅Ρ‚ΡŒ доступ ΠΊ ΠΏΡƒΠ»Ρƒ,
  # ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠΌΡƒ Π² storage class
  userID: rbdkube
  userKey: <user-key>

И создаём наш сСкрСт:

kubectl apply -f secret.yaml

Π”Π°Π»Π΅Π΅ Π½Π°ΠΌ Π½ΡƒΠΆΠ΅Π½ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π½ΠΎ Ρ‚Π°ΠΊΠΎΠΉ манифСст StorageClass:

---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
   name: csi-rbd-sc
provisioner: rbd.csi.ceph.com
parameters:
   clusterID: <cluster-id>
   pool: kube

   imageFeatures: layering

   # Π­Ρ‚ΠΈ сСкрСты Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΡΠΎΠ΄Π΅Ρ€ΠΆΠ°Ρ‚ΡŒ Π΄Π°Π½Π½Ρ‹Π΅ для Π°Π²Ρ‚ΠΎΡ€ΠΈΠ·Π°Ρ†ΠΈΠΈ
   # Π² ваш ΠΏΡƒΠ».
   csi.storage.k8s.io/provisioner-secret-name: csi-rbd-secret
   csi.storage.k8s.io/provisioner-secret-namespace: ceph-csi-rbd
   csi.storage.k8s.io/controller-expand-secret-name: csi-rbd-secret
   csi.storage.k8s.io/controller-expand-secret-namespace: ceph-csi-rbd
   csi.storage.k8s.io/node-stage-secret-name: csi-rbd-secret
   csi.storage.k8s.io/node-stage-secret-namespace: ceph-csi-rbd

   csi.storage.k8s.io/fstype: ext4

reclaimPolicy: Delete
allowVolumeExpansion: true
mountOptions:
  - discard

НуТно Π·Π°ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ clusterID, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΌΡ‹ ΡƒΠΆΠ΅ ΡƒΠ·Π½Π°Π»ΠΈ ΠΊΠΎΠΌΠ°Π½Π΄ΠΎΠΉ ceph fsid, ΠΈ ΠΏΡ€ΠΈΠΌΠ΅Π½ΠΈΡ‚ΡŒ этот манифСст Π² кластСрС Kubernetes:

kubectl apply -f storageclass.yaml

Π§Ρ‚ΠΎΠ±Ρ‹ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒ Ρ€Π°Π±ΠΎΡ‚Ρƒ кластСров Π² связкС, создадим Π²ΠΎΡ‚ Ρ‚Π°ΠΊΠΎΠΉ PVC (Persistent Volume Claim):

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: rbd-pvc
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
  storageClassName: csi-rbd-sc

Π‘Ρ€Π°Π·Ρƒ посмотрим, ΠΊΠ°ΠΊ Kubernetes создал Π² Ceph Π·Π°ΠΏΡ€ΠΎΡˆΠ΅Π½Π½Ρ‹ΠΉ Ρ‚ΠΎΠΌ:

kubectl get pvc
kubectl get pv

Π’Ρ€ΠΎΠ΄Π΅ Π±Ρ‹ всё ΠΎΡ‚Π»ΠΈΡ‡Π½ΠΎ! А ΠΊΠ°ΠΊ это выглядит Π½Π° сторонС Ceph?
ΠŸΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ список Ρ‚ΠΎΠΌΠΎΠ² Π² ΠΏΡƒΠ»Π΅ ΠΈ просматриваСм ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ ΠΎ нашСм Ρ‚ΠΎΠΌΠ΅:

rbd ls -p kube
rbd -p kube info csi-vol-eb3d257d-8c6c-11ea-bff5-6235e7640653  # Ρ‚ΡƒΡ‚, ΠΊΠΎΠ½Π΅Ρ‡Π½ΠΎ ΠΆΠ΅, Π±ΡƒΠ΄Π΅Ρ‚ Π΄Ρ€ΡƒΠ³ΠΎΠΉ ID Ρ‚ΠΎΠΌΠ°, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π²Ρ‹Π΄Π°Π»Π° прСдыдущая ΠΊΠΎΠΌΠ°Π½Π΄Π°

Π’Π΅ΠΏΠ΅Ρ€ΡŒ Π΄Π°Π²Π°ΠΉΡ‚Π΅ посмотрим, ΠΊΠ°ΠΊ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ Ρ€Π°Π·ΠΌΠ΅Ρ€Π° Ρ‚ΠΎΠΌΠ° RBD.
ИзмСняСм Ρ€Π°Π·ΠΌΠ΅Ρ€ Ρ‚ΠΎΠΌΠ° Π² манифСстС pvc.yaml Π΄ΠΎ 2Gi ΠΈ примСняСм Π΅Π³ΠΎ:

kubectl apply -f pvc.yaml

ΠŸΠΎΠ΄ΠΎΠΆΠ΄Ρ‘ΠΌ, ΠΏΠΎΠΊΠ° измСнСния вступят Π² силу, ΠΈ Π΅Ρ‰Ρ‘ Ρ€Π°Π· посмотрим Π½Π° Ρ€Π°Π·ΠΌΠ΅Ρ€ Ρ‚ΠΎΠΌΠ°.

rbd -p kube info csi-vol-eb3d257d-8c6c-11ea-bff5-6235e7640653

kubectl get pv
kubectl get pvc

Π’ΠΈΠ΄ΠΈΠΌ, Ρ‡Ρ‚ΠΎ Ρ€Π°Π·ΠΌΠ΅Ρ€ Ρƒ PVC Π½Π΅ измСнился. Π§Ρ‚ΠΎΠ±Ρ‹ ΡƒΠ·Π½Π°Ρ‚ΡŒ ΠΏΡ€ΠΈΡ‡ΠΈΠ½Ρƒ, ΠΌΠΎΠΆΠ½ΠΎ Π·Π°ΠΏΡ€ΠΎΡΠΈΡ‚ΡŒ Ρƒ Kubernetes описаниС PVC Π² Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π΅ YAML:

kubectl get pvc rbd-pvc -o yaml

А Π²ΠΎΡ‚ ΠΈ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ°:

message: Waiting for user to (re-)start a pod to finish file system resize of volume on node. type: FileSystemResizePending

Π’ΠΎ Π΅ΡΡ‚ΡŒ диск увСличился, Π° файловая систСма Π½Π° Π½Ρ‘ΠΌ β€” Π½Π΅Ρ‚.
Π§Ρ‚ΠΎΠ±Ρ‹ ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΡ‚ΡŒ Ρ„Π°ΠΉΠ»ΠΎΠ²ΡƒΡŽ систСму, Π½Π°Π΄ΠΎ ΡΠΌΠΎΠ½Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Ρ‚ΠΎΠΌ. Π£ нас ΠΆΠ΅ созданный PVC/PV сСйчас Π½ΠΈΠΊΠ°ΠΊ Π½Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ.

МоТСм ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ тСстовый Pod, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Π²ΠΎΡ‚ Ρ‚Π°ΠΊ:

---
apiVersion: v1
kind: Pod
metadata:
  name: csi-rbd-demo-pod
spec:
  containers:
    - name: web-server
      image: nginx:1.17.6
      volumeMounts:
        - name: mypvc
          mountPath: /data
  volumes:
    - name: mypvc
      persistentVolumeClaim:
        claimName: rbd-pvc
        readOnly: false

И Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ посмотрим Π½Π° PVC:

kubectl get pvc

Π Π°Π·ΠΌΠ΅Ρ€ измСнился, всё Π² порядкС.

Π’ ΠΏΠ΅Ρ€Π²ΠΎΠΉ части ΠΌΡ‹ Ρ€Π°Π±ΠΎΡ‚Π°Π»ΠΈ с Π±Π»ΠΎΡ‡Π½Ρ‹ΠΌ устройством RBD (ΠΎΠ½ΠΎ Ρ‚Π°ΠΊ ΠΈ Ρ€Π°ΡΡˆΠΈΡ„Ρ€ΠΎΠ²Ρ‹Π²Π°Π΅Ρ‚ΡΡ – Rados Block Device), Π½ΠΎ Ρ‚Π°ΠΊ нСльзя Π΄Π΅Π»Π°Ρ‚ΡŒ, Ссли трСбуСтся одноврСмСнная Ρ€Π°Π±ΠΎΡ‚Π° с этим диском Ρ€Π°Π·Π½Ρ‹Ρ… микросСрвисов. Для Ρ€Π°Π±ΠΎΡ‚Ρ‹ с Ρ„Π°ΠΉΠ»Π°ΠΌΠΈ, Π° Π½Π΅ с ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ диска, Π½Π°ΠΌΠ½ΠΎΠ³ΠΎ Π»ΡƒΡ‡ΡˆΠ΅ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ΠΈΡ‚ CephFS.
На ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ кластСров Ceph ΠΈ Kubernetes настроим CSI ΠΈ ΠΎΡΡ‚Π°Π»ΡŒΠ½Ρ‹Π΅ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹Π΅ сущности для Ρ€Π°Π±ΠΎΡ‚Ρ‹ с CephFS.

ΠŸΠΎΠ»ΡƒΡ‡ΠΈΠΌ значСния ΠΈΠ· Π½ΡƒΠΆΠ½ΠΎΠ³ΠΎ Π½Π°ΠΌ Π½ΠΎΠ²ΠΎΠ³ΠΎ Helm-Ρ‡Π°Ρ€Ρ‚Π°:

helm inspect values ceph-csi/ceph-csi-cephfs > cephfs.yml

Π‘Π½ΠΎΠ²Π° Π½ΡƒΠΆΠ½ΠΎ Π·Π°ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ Ρ„Π°ΠΉΠ» cephfs.yml. Как ΠΈ Ρ€Π°Π½Π΅Π΅, ΠΏΠΎΠΌΠΎΠ³ΡƒΡ‚ ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ Ceph:

ceph fsid
ceph mon dump

ЗаполняСм Ρ„Π°ΠΉΠ» со значСниями ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π½ΠΎ Ρ‚Π°ΠΊ:

csiConfig:
  - clusterID: "bcd0d202-fba8-4352-b25d-75c89258d5ab"
    monitors:
      - "172.18.8.5:6789"
      - "172.18.8.6:6789"
      - "172.18.8.7:6789"

nodeplugin:
  httpMetrics:
    enabled: true
    containerPort: 8091
  podSecurityPolicy:
    enabled: true

provisioner:
  replicaCount: 1
  podSecurityPolicy:
    enabled: true

ΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, Ρ‡Ρ‚ΠΎ адрСса ΠΌΠΎΠ½ΠΈΡ‚ΠΎΡ€ΠΎΠ² ΡƒΠΊΠ°Π·Ρ‹Π²Π°ΡŽΡ‚ΡΡ Π² простой Ρ„ΠΎΡ€ΠΌΠ΅ address:port. Для монтирования cephfs Π½Π° ΡƒΠ·Π»Π΅ эти адрСса ΠΏΠ΅Ρ€Π΅Π΄Π°ΡŽΡ‚ΡΡ Π² ΠΌΠΎΠ΄ΡƒΠ»ΡŒ ядра, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π΅Ρ‰Ρ‘ Π½Π΅ ΡƒΠΌΠ΅Π΅Ρ‚ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ с ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»ΠΎΠΌ ΠΌΠΎΠ½ΠΈΡ‚ΠΎΡ€ΠΎΠ² v2.
ΠŸΠΎΡ€Ρ‚ для httpMetrics (Ρ‚ΡƒΠ΄Π° Π±ΡƒΠ΄Π΅Ρ‚ Ρ…ΠΎΠ΄ΠΈΡ‚ΡŒ Prometheus Π·Π° ΠΌΠ΅Ρ‚Ρ€ΠΈΠΊΠ°ΠΌΠΈ для ΠΌΠΎΠ½ΠΈΡ‚ΠΎΡ€ΠΈΠ½Π³Π°) ΠΌΡ‹ мСняСм для Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠ½ Π½Π΅ ΠΊΠΎΠ½Ρ„Π»ΠΈΠΊΡ‚ΠΎΠ²Π°Π» с nginx-proxy, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ устанавливаСтся Kubespray’См. Π’Π°ΠΌ это, Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, Π½Π΅ потрСбуСтся.

УстанавливаСм Helm-Ρ‡Π°Ρ€Ρ‚ Π² кластСр Kubernetes:

helm upgrade -i ceph-csi-cephfs ceph-csi/ceph-csi-cephfs -f cephfs.yml -n ceph-csi-cephfs --create-namespace

ΠŸΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ΠΈΠΌ ΠΊ Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Ρƒ Π΄Π°Π½Π½Ρ‹Ρ… Ceph, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ Ρ‚Π°ΠΌ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎΠ³ΠΎ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ. Π’ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ ΡƒΠΊΠ°Π·Π°Π½ΠΎ, Ρ‡Ρ‚ΠΎ ΠΏΡ€ΠΎΠ²ΠΈΠ·ΠΈΠΎΠ½Π΅Ρ€Ρƒ CephFS Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹ ΠΏΡ€Π°Π²Π° доступа администратора кластСра. Но ΠΌΡ‹ создадим ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎΠ³ΠΎ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ fs с ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½Π½Ρ‹ΠΌΠΈ ΠΏΡ€Π°Π²Π°ΠΌΠΈ:

ceph auth get-or-create client.fs mon 'allow r' mgr 'allow rw' mds 'allow rws' osd 'allow rw pool=cephfs_data, allow rw pool=cephfs_metadata'

И сразу ΠΆΠ΅ посмотрим Π΅Π³ΠΎ ΠΊΠ»ΡŽΡ‡ доступа, ΠΎΠ½ Π½Π°ΠΌ пригодится Π΄Π°Π»Π΅Π΅:

ceph auth get-key client.fs

Π‘ΠΎΠ·Π΄Π°Π΄ΠΈΠΌ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹Π΅ Secret ΠΈ StorageClass.
НичСго Π½ΠΎΠ²ΠΎΠ³ΠΎ, ΠΌΡ‹ это ΡƒΠΆΠ΅ Π²ΠΈΠ΄Π΅Π»ΠΈ Π½Π° ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ RBD:

---
apiVersion: v1
kind: Secret
metadata:
  name: csi-cephfs-secret
  namespace: ceph-csi-cephfs
stringData:
  # НСобходимо для динамичСски создаваСмых Ρ‚ΠΎΠΌΠΎΠ²
  adminID: fs
  adminKey: <Π²Ρ‹Π²ΠΎΠ΄ ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰Π΅ΠΉ ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹>

ΠŸΡ€ΠΈΠΌΠ΅Π½ΡΠ΅ΠΌ манифСст:

kubectl apply -f secret.yaml

А Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ – ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΉ StorageClass:

---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: csi-cephfs-sc
provisioner: cephfs.csi.ceph.com
parameters:
  clusterID: <cluster-id>

  # Имя Ρ„Π°ΠΉΠ»ΠΎΠ²ΠΎΠΉ систСмы CephFS, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ Π±ΡƒΠ΄Π΅Ρ‚ создан Ρ‚ΠΎΠΌ
  fsName: cephfs

  # (Π½Π΅ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ) ΠŸΡƒΠ» Ceph, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ Π±ΡƒΠ΄ΡƒΡ‚ Ρ…Ρ€Π°Π½ΠΈΡ‚ΡŒΡΡ Π΄Π°Π½Π½Ρ‹Π΅ Ρ‚ΠΎΠΌΠ°
  # pool: cephfs_data

  # (Π½Π΅ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ) Π Π°Π·Π΄Π΅Π»Π΅Π½Π½Ρ‹Π΅ запятыми ΠΎΠΏΡ†ΠΈΠΈ монтирования для Ceph-fuse
  # Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€:
  # fuseMountOptions: debug

  # (Π½Π΅ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ) Π Π°Π·Π΄Π΅Π»Π΅Π½Π½Ρ‹Π΅ запятыми ΠΎΠΏΡ†ΠΈΠΈ монтирования CephFS для ядра
  # Π‘ΠΌ. man mount.ceph Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡƒΠ·Π½Π°Ρ‚ΡŒ список этих ΠΎΠΏΡ†ΠΈΠΉ. НапримСр:
  # kernelMountOptions: readdir_max_bytes=1048576,norbytes

  # Π‘Π΅ΠΊΡ€Π΅Ρ‚Ρ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΡΠΎΠ΄Π΅Ρ€ΠΆΠ°Ρ‚ΡŒ доступы для Π°Π΄ΠΌΠΈΠ½Π° ΠΈ/ΠΈΠ»ΠΈ ΡŽΠ·Π΅Ρ€Π° Ceph.
  csi.storage.k8s.io/provisioner-secret-name: csi-cephfs-secret
  csi.storage.k8s.io/provisioner-secret-namespace: ceph-csi-cephfs
  csi.storage.k8s.io/controller-expand-secret-name: csi-cephfs-secret
  csi.storage.k8s.io/controller-expand-secret-namespace: ceph-csi-cephfs
  csi.storage.k8s.io/node-stage-secret-name: csi-cephfs-secret
  csi.storage.k8s.io/node-stage-secret-namespace: ceph-csi-cephfs

  # (Π½Π΅ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ) Π”Ρ€Π°ΠΉΠ²Π΅Ρ€ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π»ΠΈΠ±ΠΎ ceph-fuse (fuse), 
  # Π»ΠΈΠ±ΠΎ ceph kernelclient (kernel).
  # Если Π½Π΅ ΡƒΠΊΠ°Π·Π°Π½ΠΎ, Π±ΡƒΠ΄Π΅Ρ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ ΠΌΠΎΠ½Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Ρ‚ΠΎΠΌΠΎΠ² ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ,
  # это опрСдСляСтся поиском ceph-fuse ΠΈ mount.ceph
  # mounter: kernel
reclaimPolicy: Delete
allowVolumeExpansion: true
mountOptions:
  - debug

Π—Π°ΠΏΠΎΠ»Π½ΠΈΠΌ Ρ‚ΡƒΡ‚ clusterID ΠΈ ΠΏΡ€ΠΈΠΌΠ΅Π½ΠΈΠΌ Π² Kubernetes:

kubectl apply -f storageclass.yaml

ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ°

Для ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ, ΠΊΠ°ΠΊ ΠΈ Π² ΠΏΡ€ΠΎΡˆΠ»ΠΎΠΌ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅, создадим PVC:

---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: csi-cephfs-pvc
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 5Gi
  storageClassName: csi-cephfs-sc

И ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΠΌ Π½Π°Π»ΠΈΡ‡ΠΈΠ΅ PVC/PV:

kubectl get pvc
kubectl get pv

Если хочСтся ΠΏΠΎΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ Π½Π° Ρ„Π°ΠΉΠ»Ρ‹ ΠΈ ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³ΠΈ Π² CephFS, ΠΌΠΎΠΆΠ½ΠΎ ΠΏΡ€ΠΈΠΌΠΎΠ½Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ эту Ρ„Π°ΠΉΠ»ΠΎΠ²ΡƒΡŽ систСму ΠΊΡƒΠ΄Π°-Π½ΠΈΠ±ΡƒΠ΄ΡŒ. НапримСр, ΠΊΠ°ΠΊ ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΎ Π½ΠΈΠΆΠ΅.

Π‘Ρ…ΠΎΠ΄ΠΈΠΌ Π½Π° ΠΎΠ΄Π½Ρƒ ΠΈΠ· Π½ΠΎΠ΄ кластСра Ceph ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΠΌ Ρ‚Π°ΠΊΠΈΠ΅ дСйствия:

# Π’ΠΎΡ‡ΠΊΠ° монтирования
mkdir -p /mnt/cephfs

# Π‘ΠΎΠ·Π΄Π°Ρ‘ΠΌ Ρ„Π°ΠΉΠ» с ΠΊΠ»ΡŽΡ‡ΠΎΠΌ администратора
ceph auth get-key client.admin >/etc/ceph/secret.key

# ДобавляСм запись Π² /etc/fstab
# !! ИзмСняСм ip адрСс Π½Π° адрСс нашСго ΡƒΠ·Π»Π°
echo "172.18.8.6:6789:/ /mnt/cephfs ceph name=admin,secretfile=/etc/ceph/secret.key,noatime,_netdev    0       2" >> /etc/fstab

mount /mnt/cephfs

ΠšΠΎΠ½Π΅Ρ‡Π½ΠΎ ΠΆΠ΅, Π²ΠΎΡ‚ Ρ‚Π°ΠΊΠΎΠ΅ ΠΌΠΎΠ½Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ FS Π½Π° Π½ΠΎΠ΄Π΅ Ceph ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ΠΈΡ‚ ΠΈΡΠΊΠ»ΡŽΡ‡ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ для Ρ†Π΅Π»Π΅ΠΉ обучСния, Ρ‡Π΅ΠΌ ΠΌΡ‹ ΠΈ занимаСмся Π½Π° Π½Π°ΡˆΠΈΡ… курсах Π‘Π»Ρ‘Ρ€ΠΌ. НС Π΄ΡƒΠΌΠ°ΡŽ, Ρ‡Ρ‚ΠΎ ΠΊΡ‚ΠΎ-Ρ‚ΠΎ станСт это Π΄Π΅Π»Π°Ρ‚ΡŒ Π² ΠΏΡ€ΠΎΠ΄Π°ΠΊΡˆΠ΅Π½Π΅, Π²Π΅Π»ΠΈΠΊ риск случайно Π·Π°Ρ‚Π΅Ρ€Π΅Ρ‚ΡŒ Π²Π°ΠΆΠ½Ρ‹Π΅ Ρ„Π°ΠΉΠ»Ρ‹.

Ну ΠΈ напослСдок Π΄Π°Π²Π°ΠΉΡ‚Π΅ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΠΌ, ΠΊΠ°ΠΊ Π² случаС с CephFS обстоят Π΄Π΅Π»Π° с ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€ΠΎΠ² Ρ‚ΠΎΠΌΠ°. ВозвращаСмся Π² Kubernetes ΠΈ ΠΎΡ‚Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΈΡ€ΡƒΠ΅ΠΌ наш манифСст для PVC β€” ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠΌ Ρ‚Π°ΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€, ΠΊ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Ρƒ, Π΄ΠΎ 7Gi.

ΠŸΡ€ΠΈΠΌΠ΅Π½ΠΈΠΌ ΠΎΡ‚Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ Ρ„Π°ΠΉΠ»:

kubectl apply -f pvc.yaml

ΠŸΠΎΡΠΌΠΎΡ‚Ρ€ΠΈΠΌ Π½Π° ΠΏΡ€ΠΈΠΌΠΎΠ½Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠΌ ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³Π΅, ΠΊΠ°ΠΊ измСнилась ΠΊΠ²ΠΎΡ‚Π°:

getfattr -n ceph.quota.max_bytes <ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³-с-Π΄Π°Π½Π½Ρ‹ΠΌΠΈ>

Для Ρ€Π°Π±ΠΎΡ‚Ρ‹ этой ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹, Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, Π²Π°ΠΌ потрСбуСтся ΡƒΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ Π² систСму ΠΏΠ°ΠΊΠ΅Ρ‚ attr.

Π“Π»Π°Π·Π° боятся, Π° Ρ€ΡƒΠΊΠΈ Π΄Π΅Π»Π°ΡŽΡ‚

Π‘ Π²ΠΈΠ΄Ρƒ всС эти заклинания ΠΈ Π΄Π»ΠΈΠ½Π½Ρ‹Π΅ манифСсты YAML каТутся слоТными, Π½ΠΎ Π½Π° ΠΏΡ€Π°ΠΊΡ‚ΠΈΠΊΠ΅ студСнты Π‘Π»Ρ‘Ρ€ΠΌΠ° Ρ€Π°Π·Π±ΠΈΡ€Π°ΡŽΡ‚ΡΡ с Π½ΠΈΠΌΠΈ довольно быстро.
Π’ этой ΡΡ‚Π°Ρ‚ΡŒΠ΅ ΠΌΡ‹ Π½Π΅ ΡƒΠ³Π»ΡƒΠ±Π»ΡΠ»ΠΈΡΡŒ Π² Π΄Π΅Π±Ρ€ΠΈ β€” для этого Π΅ΡΡ‚ΡŒ ΠΎΡ„ΠΈΡ†ΠΈΠ°Π»ΡŒΠ½Π°Ρ докумСнтация. Если вас ΠΈΠ½Ρ‚Π΅Ρ€Π΅ΡΡƒΡŽΡ‚ Π΄Π΅Ρ‚Π°Π»ΠΈ настройки Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π° Ceph совмСстно с кластСром Kubernetes, ΠΏΠΎΠΌΠΎΠ³ΡƒΡ‚ Π²ΠΎΡ‚ эти ссылки:

ΠžΠ±Ρ‰ΠΈΠ΅ ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏΡ‹ Ρ€Π°Π±ΠΎΡ‚Ρ‹ Kubernetes c Ρ‚ΠΎΠΌΠ°ΠΌΠΈ
ДокумСнтация ΠΏΠΎ RBD
Π˜Π½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΡ RBD ΠΈ Kubernetes с Ρ‚ΠΎΡ‡ΠΊΠΈ зрСния Ceph
Π˜Π½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΡ RBD ΠΈ Kubernetes с Ρ‚ΠΎΡ‡ΠΊΠΈ зрСния CSI
ΠžΠ±Ρ‰Π°Ρ докумСнтация ΠΏΠΎ CephFS
Π˜Π½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΡ CephFS ΠΈ Kubernetes с Ρ‚ΠΎΡ‡ΠΊΠΈ зрСния CSI

На курсС Π‘Π»Ρ‘Ρ€ΠΌ Kubernetes Π‘Π°Π·Π° Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΏΠΎΠΉΡ‚ΠΈ Π΅Ρ‰Ρ‘ Ρ‡ΡƒΡ‚ΡŒ дальшС ΠΈ Ρ€Π°Π·Π²Π΅Ρ€Π½ΡƒΡ‚ΡŒ Π² Kubernetes Ρ€Π΅Π°Π»ΡŒΠ½ΠΎΠ΅ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ Π±ΡƒΠ΄Π΅Ρ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ CephFS Π² качСствС Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π° для Ρ„Π°ΠΉΠ»ΠΎΠ². ΠŸΠΎΡΡ€Π΅Π΄ΡΡ‚Π²ΠΎΠΌ GET/POST запросов Π²Ρ‹ смоТСтС ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Ρ‚ΡŒ Ρ„Π°ΠΉΠ»Ρ‹ ΠΈ ΠΏΠΎΠ»ΡƒΡ‡Π°Ρ‚ΡŒ ΠΈΡ… ΠΈΠ· Ceph.

А Ссли Π²Π°ΠΌ большС интСрСсно Ρ…Ρ€Π°Π½Π΅Π½ΠΈΠ΅ Π΄Π°Π½Π½Ρ‹Ρ…, Ρ‚ΠΎ Π·Π°ΠΏΠΈΡΡ‹Π²Π°ΠΉΡ‚Π΅ΡΡŒ Π½Π° Π½ΠΎΠ²Ρ‹ΠΉ курс ΠΏΠΎ Ceph. Пока ΠΈΠ΄Ρ‘Ρ‚ Π±Π΅Ρ‚Π°-тСст, курс ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ со скидкой ΠΈ ΠΏΠΎΠ²Π»ΠΈΡΡ‚ΡŒ Π½Π° Π΅Π³ΠΎ содСрТаниС.

Автор ΡΡ‚Π°Ρ‚ΡŒΠΈ: АлСксандр Π¨Π²Π°Π»ΠΎΠ², ΠΏΡ€Π°ΠΊΡ‚ΠΈΠΊΡƒΡŽΡ‰ΠΈΠΉ ΠΈΠ½ΠΆΠ΅Π½Π΅Ρ€ Southbridge, Certified Kubernetes Administrator, Π°Π²Ρ‚ΠΎΡ€ ΠΈ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ курсов Π‘Π»Ρ‘Ρ€ΠΌ.

Π˜ΡΡ‚ΠΎΡ‡Π½ΠΈΠΊ: habr.com