Rook์ด๋ƒ ์•„๋‹ˆ๋ƒ-๊ทธ๊ฒƒ์ด ๋ฌธ์ œ๋กœ๋‹ค

Rook์ด๋ƒ ์•„๋‹ˆ๋ƒ-๊ทธ๊ฒƒ์ด ๋ฌธ์ œ๋กœ๋‹ค

์ด๋‹ฌ ์ดˆ์ธ 3์›” XNUMX์ผ '์ฟ ๋ฒ„๋„คํ‹ฐ์Šค์˜ ๋ถ„์‚ฐ ๋ฐ์ดํ„ฐ ์ €์žฅ์„ ์œ„ํ•œ ๊ด€๋ฆฌ ์‹œ์Šคํ…œ'์˜ ์ฃผ์š” ๋ฆด๋ฆฌ์Šค๊ฐ€ ๋ฐœํ‘œ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋ฃจํฌ 1.0.0. XNUMX๋…„์—ฌ ์ „์— ์šฐ๋ฆฌ๋Š” ์ด๋ฏธ ์ถœํŒ Rook์˜ ์ผ๋ฐ˜์ ์ธ ๊ฐœ์š”. ๊ทธ๋Ÿฐ ๋‹ค์Œ ์šฐ๋ฆฌ๋Š” ๊ทธ์˜ ๊ฒฝํ—˜์— ๋Œ€ํ•ด ์ด์•ผ๊ธฐํ•ด ๋‹ฌ๋ผ๋Š” ์š”์ฒญ์„ ๋ฐ›์•˜์Šต๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ ์‚ฌ์šฉ โ€” ๊ทธ๋ฆฌ๊ณ  ์ด์ œ ํ”„๋กœ์ ํŠธ ์—ญ์‚ฌ์ƒ ์ค‘์š”ํ•œ ์ด์ •ํ‘œ๊ฐ€ ๋˜๋Š” ์‹œ์ ์— ์šฐ๋ฆฌ๋Š” ์ถ•์ ๋œ ์ธ์ƒ์„ ๊ณต์œ ํ•˜๊ฒŒ ๋˜์–ด ๊ธฐ์˜๊ฒŒ ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

๊ฐ„๋‹จํžˆ ๋งํ•ด์„œ Rook์€ ์„ธํŠธ์ž…๋‹ˆ๋‹ค. ์—ฐ์‚ฐ์ž Ceph, EdgeFS, Minio, Cassandra, CockroachDB์™€ ๊ฐ™์€ ๋ฐ์ดํ„ฐ ์Šคํ† ๋ฆฌ์ง€ ์†”๋ฃจ์…˜์˜ ๋ฐฐํฌ, ๊ด€๋ฆฌ, ์ž๋™ ๋ณต๊ตฌ๋ฅผ ์™„์ „ํžˆ ์ œ์–ดํ•˜๋Š” โ€‹โ€‹Kubernetes์šฉ์ž…๋‹ˆ๋‹ค.

ํ˜„์žฌ ๊ฐ€์žฅ ๋ฐœ์ „๋œ (๊ทธ๋ฆฌ๊ณ  ์œ ์ผํ•œ ะฒ ์•ˆ์ •๋œ ๋‹จ๊ณ„) ํ•ด๊ฒฐ์ฑ…์€ ๋ฃจํฌ ์„ธํ”„ ์šด์˜์ž.

์ฃผ์˜: Ceph์™€ ๊ด€๋ จ๋œ Rook 1.0.0 ๋ฆด๋ฆฌ์Šค์˜ ์ค‘์š”ํ•œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ ์ค‘ Ceph Nautilus์— ๋Œ€ํ•œ ์ง€์›๊ณผ CephFS ๋˜๋Š” RGW ๋ฒ„ํ‚ท์— NFS๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์ฃผ๋ชฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฌด์—‡๋ณด๋‹ค๋„ ๋ˆˆ์— ๋„๋Š” ์ ์€ EdgeFS ์ง€์›์ด ๋ฒ ํƒ€ ์ˆ˜์ค€์œผ๋กœ ์„ฑ์ˆ™๋˜์—ˆ๋‹ค๋Š” ์ ์ž…๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ ์ด ๊ธฐ์‚ฌ์—์„œ๋Š” ๋‹ค์Œ์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

  • Rook์„ ์‚ฌ์šฉํ•˜์—ฌ Kubernetes ํด๋Ÿฌ์Šคํ„ฐ์— Ceph๋ฅผ ๋ฐฐํฌํ•  ๋•Œ ์–ด๋–ค ์ด์ ์ด ์žˆ๋Š”์ง€์— ๋Œ€ํ•œ ์งˆ๋ฌธ์— ๋‹ตํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.
  • ํ”„๋กœ๋•์…˜์—์„œ Rook์„ ์‚ฌ์šฉํ•œ ๊ฒฝํ—˜๊ณผ ์ธ์ƒ์„ ๊ณต์œ ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.
  • ์šฐ๋ฆฌ๊ฐ€ Rook์—๊ฒŒ โ€œ์˜ˆ!โ€๋ผ๊ณ  ๋งํ•˜๋Š” ์ด์œ ์™€ ๊ทธ๋ฅผ ์œ„ํ•œ ์šฐ๋ฆฌ์˜ ๊ณ„ํš์— ๋Œ€ํ•ด ์ด์•ผ๊ธฐํ•ด ๋ด…์‹œ๋‹ค.

์ผ๋ฐ˜์ ์ธ ๊ฐœ๋…๊ณผ ์ด๋ก ๋ถ€ํ„ฐ ์‹œ์ž‘ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

โ€œ๋‚˜์—๊ฒ ํ•œ ๋ฃจํฌ์˜ ์žฅ์ ์ด ์žˆ์–ด์š”!โ€ (์•Œ ์ˆ˜ ์—†๋Š” ์ฒด์Šค ํ”Œ๋ ˆ์ด์–ด)

Rook์ด๋ƒ ์•„๋‹ˆ๋ƒ-๊ทธ๊ฒƒ์ด ๋ฌธ์ œ๋กœ๋‹ค

Rook์˜ ์ฃผ์š” ์žฅ์  ์ค‘ ํ•˜๋‚˜๋Š” ๋ฐ์ดํ„ฐ ์ €์žฅ์†Œ์™€์˜ ์ƒํ˜ธ ์ž‘์šฉ์ด Kubernetes ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ํ†ตํ•ด ์ˆ˜ํ–‰๋œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๋Š” ๋” ์ด์ƒ Ceph๋ฅผ ๊ตฌ์„ฑํ•˜๊ธฐ ์œ„ํ•ด ์‹œํŠธ์—์„œ ์ฝ˜์†”๋กœ ๋ช…๋ น์„ ๋ณต์‚ฌํ•  ํ•„์š”๊ฐ€ ์—†์Œ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

โ€” CephFS๋ฅผ ํด๋Ÿฌ์Šคํ„ฐ์— ๋ฐฐํฌํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ? YAML ํŒŒ์ผ์„ ์ž‘์„ฑํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค!
- ๋ฌด์—‡? S3 API๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ์ฒด ์ €์žฅ์†Œ๋„ ๋ฐฐํฌํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ? ๋‘ ๋ฒˆ์งธ YAML ํŒŒ์ผ์„ ์ž‘์„ฑํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค!

Rook์€ ์ผ๋ฐ˜์ ์ธ ์—ฐ์‚ฐ์ž์˜ ๋ชจ๋“  ๊ทœ์น™์— ๋”ฐ๋ผ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. ๊ทธ์™€์˜ ์ƒํ˜ธ ์ž‘์šฉ์€ ๋‹ค์Œ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. CRD(์‚ฌ์šฉ์ž ์ •์˜ ๋ฆฌ์†Œ์Šค ์ •์˜), ํ•„์š”ํ•œ Ceph ์—”ํ„ฐํ‹ฐ์˜ ํŠน์„ฑ์„ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค. (์ด๊ฒƒ์€ ์œ ์ผํ•˜๊ฒŒ ์•ˆ์ •์ ์ธ ๊ตฌํ˜„์ด๋ฏ€๋กœ ๋‹ฌ๋ฆฌ ๋ช…์‹œ์ ์œผ๋กœ ์–ธ๊ธ‰ํ•˜์ง€ ์•Š๋Š” ํ•œ ๊ธฐ๋ณธ์ ์œผ๋กœ ์ด ๊ธฐ์‚ฌ์—์„œ๋Š” Ceph์— ๋Œ€ํ•ด ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค.). ์ง€์ •๋œ ๋งค๊ฐœ๋ณ€์ˆ˜์— ๋”ฐ๋ผ ์šด์˜์ž๋Š” ๊ตฌ์„ฑ์— ํ•„์š”ํ•œ ๋ช…๋ น์„ ์ž๋™์œผ๋กœ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

๊ฐ์ฒด ์ €์žฅ์†Œ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ์˜ˆ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์„ธ๋ถ€ ์‚ฌํ•ญ์„ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. CephObjectStoreUser.

apiVersion: ceph.rook.io/v1
kind: CephObjectStore
metadata:
  name: {{ .Values.s3.crdName }}
  namespace: kube-rook
spec:
  metadataPool:
    failureDomain: host
    replicated:
      size: 3
  dataPool:
    failureDomain: host
    erasureCoded:
      dataChunks: 2
      codingChunks: 1
  gateway:
    type: s3
    sslCertificateRef:
    port: 80
    securePort:
    instances: 1
    allNodes: false
---
apiVersion: ceph.rook.io/v1
kind: CephObjectStoreUser
metadata:
  name: {{ .Values.s3.crdName }}
  namespace: kube-rook
spec:
  store: {{ .Values.s3.crdName }}
  displayName: {{ .Values.s3.username }}

๋ชฉ๋ก์— ํ‘œ์‹œ๋œ ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” ๋งค์šฐ ํ‘œ์ค€์ ์ด๋ฉฐ ์ฃผ์„์ด ๊ฑฐ์˜ ํ•„์š”ํ•˜์ง€ ์•Š์ง€๋งŒ ํ…œํ”Œ๋ฆฟ ๋ณ€์ˆ˜์— ํ• ๋‹น๋œ ๋งค๊ฐœ๋ณ€์ˆ˜์—๋Š” ํŠน๋ณ„ํ•œ ์ฃผ์˜๋ฅผ ๊ธฐ์šธ์ผ ๊ฐ€์น˜๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

์ผ๋ฐ˜์ ์ธ ์ž‘์—… ๊ณ„ํš์€ YAML ํŒŒ์ผ์„ ํ†ตํ•ด ๋ฆฌ์†Œ์Šค๋ฅผ "์ฃผ๋ฌธ"ํ•œ๋‹ค๋Š” ์‚ฌ์‹ค๋กœ ๊ท€๊ฒฐ๋ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ์œ„ํ•ด ์šด์˜์ž๋Š” ํ•„์š”ํ•œ ๋ช…๋ น์„ ์‹คํ–‰ํ•˜๊ณ  ์ถ”๊ฐ€ ์ž‘์—…์„ ํ•  ์ˆ˜ ์žˆ๋Š” "๊ทธ๋ ‡์ง€ ์•Š์€" ๋น„๋ฐ€์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. (์•„๋ž˜ ์ฐธ์กฐ). ๊ทธ๋ฆฌ๊ณ  ์œ„์— ๋‚˜์—ด๋œ ๋ณ€์ˆ˜์—์„œ ๋ช…๋ น๊ณผ ๋น„๋ฐ€ ์ด๋ฆ„์ด ์ปดํŒŒ์ผ๋ฉ๋‹ˆ๋‹ค.

์ด ํŒ€์€ ์–ด๋–ค ํŒ€์ธ๊ฐ€์š”? ๊ฐ์ฒด ์Šคํ† ๋ฆฌ์ง€์šฉ ์‚ฌ์šฉ์ž๋ฅผ ์ƒ์„ฑํ•  ๋•Œ ํฌ๋“œ ๋‚ด๋ถ€์˜ Rook ์šด์˜์ž๋Š” ๋‹ค์Œ์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

radosgw-admin user create --uid="rook-user" --display-name="{{ .Values.s3.username }}"

์ด ๋ช…๋ น์„ ์‹คํ–‰ํ•œ ๊ฒฐ๊ณผ๋Š” JSON ๊ตฌ์กฐ์ž…๋‹ˆ๋‹ค.

{
    "user_id": "rook-user",
    "display_name": "{{ .Values.s3.username }}",
    "keys": [
        {
           "user": "rook-user",
           "access_key": "NRWGT19TWMYOB1YDBV1Y",
           "secret_key": "gr1VEGIV7rxcP3xvXDFCo4UDwwl2YoNrmtRlIAty"
        }
    ],
    ...
}

Keys - S3 API๋ฅผ ํ†ตํ•ด ๊ฐ์ฒด ์Šคํ† ๋ฆฌ์ง€์— ์•ก์„ธ์Šคํ•˜๋ ค๋ฉด ํ–ฅํ›„ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ํ•„์š”ํ•œ ๊ฒƒ์ด ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? Rook ์šด์˜์ž๋Š” ์นœ์ ˆํ•˜๊ฒŒ ์ด๋ฅผ ์„ ํƒํ•˜์—ฌ ์ด๋ฆ„์ด ์žˆ๋Š” ๋น„๋ฐ€ ํ˜•์‹์œผ๋กœ ๋„ค์ž„์ŠคํŽ˜์ด์Šค์— ๋„ฃ์Šต๋‹ˆ๋‹ค. rook-ceph-object-user-{{ $.Values.s3.crdName }}-{{ $.Values.s3.username }}.

์ด ๋น„๋ฐ€์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋กœ ์ปจํ…Œ์ด๋„ˆ์— ์ถ”๊ฐ€ํ•˜๊ธฐ๋งŒ ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ๊ฐ ์‚ฌ์šฉ์ž ํ™˜๊ฒฝ์— ๋Œ€ํ•œ ๋ฒ„ํ‚ท์„ ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•˜๋Š” Job์šฉ ํ…œํ”Œ๋ฆฟ์„ ์ œ๊ณตํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

{{- range $bucket := $.Values.s3.bucketNames }}
apiVersion: batch/v1
kind: Job
metadata:
  name: create-{{ $bucket }}-bucket-job
  annotations:
    "helm.sh/hook": post-install
    "helm.sh/hook-weight": "2"
spec:
  template:
    metadata:
      name: create-{{ $bucket }}-bucket-job
    spec:
      restartPolicy: Never
      initContainers:
      - name: waitdns
        image: alpine:3.6
        command: ["/bin/sh", "-c", "while ! getent ahostsv4 rook-ceph-rgw-{{ $.Values.s3.crdName }}; do sleep 1; done" ]
      - name: config
        image: rook/ceph:v1.0.0
        command: ["/bin/sh", "-c"]
        args: ["s3cmd --configure --access_key=$(ACCESS-KEY) --secret_key=$(SECRET-KEY) -s --no-ssl --dump-config | tee /config/.s3cfg"]
        volumeMounts:
        - name: config
          mountPath: /config
        env:
        - name: ACCESS-KEY
          valueFrom:
            secretKeyRef:
              name: rook-ceph-object-user-{{ $.Values.s3.crdName }}-{{ $.Values.s3.username }}
              key: AccessKey
        - name: SECRET-KEY
          valueFrom:
            secretKeyRef:
              name: rook-ceph-object-user-{{ $.Values.s3.crdName }}-{{ $.Values.s3.username }}
              key: SecretKey
      containers:
      - name: create-bucket
        image: rook/ceph:v1.0.0
        command: 
        - "s3cmd"
        - "mb"
        - "--host=rook-ceph-rgw-{{ $.Values.s3.crdName }}"
        - "--host-bucket= "
        - "s3://{{ $bucket }}"
        ports:
        - name: s3-no-sll
          containerPort: 80
        volumeMounts:
        - name: config
          mountPath: /root
      volumes:
      - name: config
        emptyDir: {}
---
{{- end }}

์ด ์ž‘์—…์— ๋‚˜์—ด๋œ ๋ชจ๋“  ์ž‘์—…์€ Kubernetes ํ”„๋ ˆ์ž„์›Œํฌ ๋‚ด์—์„œ ์ˆ˜ํ–‰๋˜์—ˆ์Šต๋‹ˆ๋‹ค. YAML ํŒŒ์ผ์— ์„ค๋ช…๋œ ๊ตฌ์กฐ๋Š” Git ์ €์žฅ์†Œ์— ์ €์žฅ๋˜๋ฉฐ ์—ฌ๋Ÿฌ ๋ฒˆ ์žฌ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ์ด๊ฒƒ์ด DevOps ์—”์ง€๋‹ˆ์–ด์™€ CI/CD ํ”„๋กœ์„ธ์Šค ์ „์ฒด์— ํฐ ์žฅ์ ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

Rook๊ณผ Rados์— ๋งŒ์กฑํ•จ

Ceph + RBD ์กฐํ•ฉ์„ ์‚ฌ์šฉํ•˜๋ฉด ํฌ๋“œ์— ๋ณผ๋ฅจ์„ ๋งˆ์šดํŠธํ•˜๋Š” ๋ฐ ํŠน์ • ์ œํ•œ์ด ์ ์šฉ๋ฉ๋‹ˆ๋‹ค.

ํŠนํžˆ, ์ƒํƒœ ์ €์žฅ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์ž‘๋™ํ•˜๋ ค๋ฉด ๋„ค์ž„์ŠคํŽ˜์ด์Šค์— Ceph์— ์•ก์„ธ์Šคํ•˜๊ธฐ ์œ„ํ•œ ๋น„๋ฐ€์ด ํฌํ•จ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋„ค์ž„์ŠคํŽ˜์ด์Šค์— 2~3๊ฐœ์˜ ํ™˜๊ฒฝ์ด ์žˆ์–ด๋„ ๊ดœ์ฐฎ์Šต๋‹ˆ๋‹ค. ๊ฐ€์„œ ๋น„๋ฐ€์„ ์ˆ˜๋™์œผ๋กœ ๋ณต์‚ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๊ฐ ๊ธฐ๋Šฅ์— ๋Œ€ํ•ด ์ž์ฒด ๋„ค์ž„์ŠคํŽ˜์ด์Šค๊ฐ€ ์žˆ๋Š” ๋ณ„๋„์˜ ํ™˜๊ฒฝ์ด ๊ฐœ๋ฐœ์ž๋ฅผ ์œ„ํ•ด ์ƒ์„ฑ๋œ๋‹ค๋ฉด ์–ด๋–ป๊ฒŒ ๋ ๊นŒ์š”?

์šฐ๋ฆฌ๋Š” ๋‹ค์Œ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ด ๋ฌธ์ œ๋ฅผ ์Šค์Šค๋กœ ํ•ด๊ฒฐํ–ˆ์Šต๋‹ˆ๋‹ค. ์‰˜ ์—ฐ์‚ฐ์ž, ๋น„๋ฐ€์„ ์ƒˆ ๋„ค์ž„์ŠคํŽ˜์ด์Šค์— ์ž๋™์œผ๋กœ ๋ณต์‚ฌํ•ฉ๋‹ˆ๋‹ค(์ด๋Ÿฌํ•œ ํ›„ํฌ์˜ ์˜ˆ๋Š” ์ด ๊ธฐ์‚ฌ).

#! /bin/bash

if [[ $1 == โ€œ--configโ€ ]]; then
   cat <<EOF
{"onKubernetesEvent":[
 {"name": "OnNewNamespace",
  "kind": "namespace",
  "event": ["add"]
  }
]}
EOF
else
    NAMESPACE=$(kubectl get namespace -o json | jq '.items | max_by( .metadata.creationTimestamp ) | .metadata.name')
    kubectl -n ${CEPH_SECRET_NAMESPACE} get secret ${CEPH_SECRET_NAME} -o json | jq ".metadata.namespace="${NAMESPACE}"" | kubectl apply -f -
fi

๊ทธ๋Ÿฌ๋‚˜ Rook์„ ์‚ฌ์šฉํ•˜๋ฉด ์ด ๋ฌธ์ œ๊ฐ€ ์ „ํ˜€ ๋ฐœ์ƒํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์žฅ์ฐฉ ํ”„๋กœ์„ธ์Šค๋Š” ๋‹ค์Œ์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜๋Š” ์ž์ฒด ๋“œ๋ผ์ด๋ฒ„๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ˆ˜ํ–‰๋ฉ๋‹ˆ๋‹ค. ํ”Œ๋ ‰์Šค๋ณผ๋ฅจ ๋˜๋Š” CSI (์•„์ง ๋ฒ ํƒ€ ๋‹จ๊ณ„์ž„) ๋”ฐ๋ผ์„œ ๋น„๋ฐ€์ด ํ•„์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

Rook์€ ๋งŽ์€ ๋ฌธ์ œ๋ฅผ ์ž๋™์œผ๋กœ ํ•ด๊ฒฐํ•˜๋ฏ€๋กœ ์ƒˆ๋กœ์šด ํ”„๋กœ์ ํŠธ์—์„œ ์ด๋ฅผ ์‚ฌ์šฉํ•˜๋„๋ก ๊ถŒ์žฅ๋ฉ๋‹ˆ๋‹ค.

๋ฃจํฌ ๊ณต์„ฑ์ „

์ž์ฒด์ ์œผ๋กœ ์‹คํ—˜์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก Rook ๋ฐ Ceph๋ฅผ ๋ฐฐํฌํ•˜์—ฌ ์‹ค์Šต์„ ์™„๋ฃŒํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ์ด ๋‚œ๊ณต๋ถˆ๋ฝ์˜ ํƒ€์›Œ๋ฅผ ๋” ์‰ฝ๊ฒŒ ์Šต๊ฒฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ฐœ๋ฐœ์ž๋Š” Helm ํŒจํ‚ค์ง€๋ฅผ ์ค€๋น„ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์šด๋กœ๋“œํ•˜์ž:

$ helm fetch rook-master/rook-ceph --untar --version 1.0.0

ํŒŒ์ผ์—์„œ rook-ceph/values.yaml ๋‹ค์–‘ํ•œ ์„ค์ •์„ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ€์žฅ ์ค‘์š”ํ•œ ๊ฒƒ์€ ์—์ด์ „ํŠธ์™€ ๊ฒ€์ƒ‰์— ๋Œ€ํ•œ ํ—ˆ์šฉ ๋ฒ”์œ„๋ฅผ ์ง€์ •ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ์˜ค์—ผ/๊ด€์šฉ ๋ฉ”์ปค๋‹ˆ์ฆ˜์ด ์–ด๋–ค ์šฉ๋„๋กœ ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ๋Š”์ง€ ์ž์„ธํžˆ ์„ค๋ช…ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ธฐ์‚ฌ.

๊ฐ„๋‹จํžˆ ๋งํ•ด์„œ, ์šฐ๋ฆฌ๋Š” ํด๋ผ์ด์–ธํŠธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ํฌ๋“œ๊ฐ€ ๋ฐ์ดํ„ฐ ์Šคํ† ๋ฆฌ์ง€ ๋””์Šคํฌ์™€ ๋™์ผํ•œ ๋…ธ๋“œ์— ์œ„์น˜ํ•˜๋Š” ๊ฒƒ์„ ์›ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด์œ ๋Š” ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด Rook ์—์ด์ „ํŠธ์˜ ์ž‘์—…์ด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ž์ฒด์— ์˜ํ–ฅ์„ ๋ฏธ์น˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿผ ํŒŒ์ผ์„ ์—ด์–ด๋ณด์„ธ์š” rook-ceph/values.yaml ์ข‹์•„ํ•˜๋Š” ํŽธ์ง‘๊ธฐ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋์— ๋‹ค์Œ ๋ธ”๋ก์„ ์ถ”๊ฐ€ํ•˜์‹ญ์‹œ์˜ค.

discover:
  toleration: NoExecute
  tolerationKey: node-role/storage
agent:
  toleration: NoExecute
  tolerationKey: node-role/storage
  mountSecurityMode: Any

๋ฐ์ดํ„ฐ ์ €์žฅ์šฉ์œผ๋กœ ์˜ˆ์•ฝ๋œ ๊ฐ ๋…ธ๋“œ์— ๋Œ€ํ•ด ํ•ด๋‹น taint๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

$ kubectl taint node ${NODE_NAME} node-role/storage="":NoExecute

๊ทธ๋Ÿฐ ๋‹ค์Œ ๋‹ค์Œ ๋ช…๋ น์„ ์‚ฌ์šฉํ•˜์—ฌ Helm ์ฐจํŠธ๋ฅผ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค.

$ helm install --namespace ${ROOK_NAMESPACE} ./rook-ceph

์ด์ œ ํด๋Ÿฌ์Šคํ„ฐ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์œ„์น˜๋ฅผ ์ง€์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. OSD:

apiVersion: ceph.rook.io/v1
kind: CephCluster
metadata:
  clusterName: "ceph"
  finalizers:
  - cephcluster.ceph.rook.io
  generation: 1
  name: rook-ceph
spec:
  cephVersion:
    image: ceph/ceph:v13
  dashboard:
    enabled: true
  dataDirHostPath: /var/lib/rook/osd
  mon:
    allowMultiplePerNode: false
    count: 3
  network:
    hostNetwork: true
  rbdMirroring:
    workers: 1
  placement:
    all:
      tolerations:
      - key: node-role/storage
        operator: Exists
  storage:
    useAllNodes: false
    useAllDevices: false
    config:
      osdsPerDevice: "1"
      storeType: filestore
    resources:
      limits:
        memory: "1024Mi"
      requests:
        memory: "1024Mi"
    nodes:
    - name: host-1
      directories:
      - path: "/mnt/osd"
    - name: host-2
      directories:
      - path: "/mnt/osd"
    - name: host-3
      directories:
      - path: "/mnt/osd"

Ceph ์ƒํƒœ ํ™•์ธ ์ค‘ - ํ™•์ธ ๊ฐ€๋Šฅ HEALTH_OK:

$ kubectl -n ${ROOK_NAMESPACE} exec $(kubectl -n ${ROOK_NAMESPACE} get pod -l app=rook-ceph-operator -o name -o jsonpath='{.items[0].metadata.name}') -- ceph -s

๋™์‹œ์— ํด๋ผ์ด์–ธํŠธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์žˆ๋Š” ํฌ๋“œ๊ฐ€ Ceph์šฉ์œผ๋กœ ์˜ˆ์•ฝ๋œ ๋…ธ๋“œ์— ์žˆ์ง€ ์•Š์€์ง€ ํ™•์ธํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

$ kubectl -n ${APPLICATION_NAMESPACE} get pods -o custom-columns=NAME:.metadata.name,NODE:.spec.nodeName

๋˜ํ•œ ์›ํ•˜๋Š” ๋Œ€๋กœ ์ถ”๊ฐ€ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ ์„ ์  ์„œ๋ฅ˜ ๋น„์น˜. ๊ด€๋ฆฌ๋ฅผ ์œ„ํ•ด์„œ๋Š” ๋Œ€์‹œ๋ณด๋“œ์™€ ๋„๊ตฌ ์ƒ์ž๋ฅผ ์„ค์น˜ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

๋ฃจํฌ์™€ ํ›„ํฌ: ๋ฃจํฌ๋Š” ๋ชจ๋“  ๊ฒƒ์— ์ถฉ๋ถ„ํ•ฉ๋‹ˆ๊นŒ?

๋ณด์‹œ๋‹ค์‹œํ”ผ Rook์˜ ๊ฐœ๋ฐœ์ด ๋ณธ๊ฒฉํ™”๋˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ Ceph์˜ ์ˆ˜๋™ ๊ตฌ์„ฑ์„ ์™„์ „ํžˆ ํฌ๊ธฐํ•  ์ˆ˜ ์—†๋Š” ๋ฌธ์ œ๊ฐ€ ์—ฌ์ „ํžˆ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ๋ฃจํฌ ๋“œ๋ผ์ด๋ฒ„ ์—†์Œ ํ•  ์ˆ˜ ์—†๋‹ค ๋งˆ์šดํŠธ๋œ ๋ธ”๋ก ์‚ฌ์šฉ์— ๋Œ€ํ•œ ์ธก์ •ํ•ญ๋ชฉ์„ ๋‚ด๋ณด๋‚ด๋ฉด ๋ชจ๋‹ˆํ„ฐ๋ง์ด ๋ถˆ๊ฐ€๋Šฅํ•ด์ง‘๋‹ˆ๋‹ค.
  • Flexvolume ๋ฐ CSI ๋ฐฉ๋ฒ•์„ ๋ชจ๋ฅด๊ฒ ์–ด (๋™์ผํ•œ RBD์™€ ๋ฐ˜๋Œ€๋กœ) ๋ณผ๋ฅจ ํฌ๊ธฐ๋ฅผ ๋ณ€๊ฒฝํ•˜๋ฏ€๋กœ Rook์—๋Š” ์œ ์šฉํ•œ(๋•Œ๋กœ๋Š” ๋งค์šฐ ํ•„์š”ํ•œ) ๋„๊ตฌ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.
  • Rook์€ ์—ฌ์ „ํžˆ โ€‹โ€‹์ผ๋ฐ˜ Ceph๋งŒํผ ์œ ์—ฐํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. CephFS ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ์šฉ ํ’€์„ SSD์— ์ €์žฅํ•˜๊ณ  ๋ฐ์ดํ„ฐ ์ž์ฒด๋ฅผ HDD์— ์ €์žฅํ•˜๋„๋ก ๊ตฌ์„ฑํ•˜๋ ค๋ฉด CRUSH ๋งต์— ๋ณ„๋„์˜ ์žฅ์น˜ ๊ทธ๋ฃน์„ ์ˆ˜๋™์œผ๋กœ ๋“ฑ๋กํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • rook-ceph-operator๊ฐ€ ์•ˆ์ •์ ์ธ ๊ฒƒ์œผ๋กœ ๊ฐ„์ฃผ๋œ๋‹ค๋Š” ์‚ฌ์‹ค์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  ํ˜„์žฌ Ceph๋ฅผ ๋ฒ„์ „ 13์—์„œ 14๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•  ๋•Œ ๋ช‡ ๊ฐ€์ง€ ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

์กฐ์‚ฌ ๊ฒฐ๊ณผ

"์ง€๊ธˆ์€ Rook์ด ํฐ์— ์˜ํ•ด ์™ธ๋ถ€ ์„ธ๊ณ„์™€ ์ฐจ๋‹จ๋˜์–ด ์žˆ์ง€๋งŒ ์–ธ์  ๊ฐ€๋Š” Rook์ด ๊ฒŒ์ž„์—์„œ ๊ฒฐ์ •์ ์ธ ์—ญํ• ์„ ํ•˜๊ฒŒ ๋  ๊ฒƒ์ด๋ผ๊ณ  ๋ฏฟ์Šต๋‹ˆ๋‹ค!" (์ด ๊ธฐ์‚ฌ๋ฅผ ์œ„ํ•ด ํŠน๋ณ„ํžˆ ๊ณ ์•ˆ๋œ ์ธ์šฉ๋ฌธ)

Rook ํ”„๋กœ์ ํŠธ๋Š” ์˜์‹ฌํ•  ์—ฌ์ง€์—†์ด ์šฐ๋ฆฌ์˜ ๋งˆ์Œ์„ ์‚ฌ๋กœ์žก์•˜์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” [๋ชจ๋“  ์žฅ๋‹จ์ ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ ] ํ™•์‹คํžˆ ์—ฌ๋Ÿฌ๋ถ„์˜ ๊ด€์‹ฌ์„ ๋ฐ›์„ ๊ฐ€์น˜๊ฐ€ ์žˆ๋‹ค๊ณ  ๋ฏฟ์Šต๋‹ˆ๋‹ค.

์šฐ๋ฆฌ์˜ ํ–ฅํ›„ ๊ณ„ํš์€ rook-ceph๋ฅผ ๋‹ค์Œ ๋ชจ๋“ˆ๋กœ ๋งŒ๋“œ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์• ๋“œ์˜จ ์—ฐ์‚ฐ์ž, ์ด๋ฅผ ํ†ตํ•ด ์ˆ˜๋งŽ์€ Kubernetes ํด๋Ÿฌ์Šคํ„ฐ์—์„œ ๋”์šฑ ๊ฐ„๋‹จํ•˜๊ณ  ํŽธ๋ฆฌํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

PS

๋ธ”๋กœ๊ทธ์—์„œ๋„ ์ฝ์–ด๋ณด์„ธ์š”.

์ถœ์ฒ˜ : habr.com

์ฝ”๋ฉ˜ํŠธ๋ฅผ ์ถ”๊ฐ€