https://andrewpage.tistory.com/256
Kubernetes에 ceph cluster 구축하기 (rook를 이용하여 ceph 설치)
Rook를 이용하여 Ceph 설치한 날짜: 2024년 8월 7일Rook version: 1.10.10Ceph version: 17.2.5(quincy) and 15.2.17 (octopus) ## 이 두 버전 모두 잘 동작했다. 지난 2년 동안 NFS server를 이용하여 Kubernetes PV(Persistent
andrewpage.tistory.com
https://rook.io/docs/rook/v1.10/Getting-Started/quickstart/#prerequisites
Quickstart - Rook Ceph Documentation
Quickstart Welcome to Rook! We hope you have a great experience installing the Rook cloud-native storage orchestrator platform to enable highly available, durable Ceph storage in your Kubernetes cluster. If you have any questions along the way, please don'
rook.io
공식 문서 보고 진행
공식 문서에는 1.10.13인데 최신이 1.18.2 버전이고 그냥 1.17.8로 진행해봄
$ git clone --single-branch --branch v1.17.8 https://github.com/rook/rook.git
cd rook/deploy/examples
# Rook operator 운영에 필요한 custom resource definition을 생성
# Rook operator 리소스를 kubernetes cluster에 배포
kubectl create -f crds.yaml -f common.yaml -f operator.yaml
# rook-ceph-operator pod가 running 상태인지 확인
kubectl -n rook-ceph get pod
# Ceph cluster를 생성
kubectl create -f cluster.yaml
# rook-ceph-operator 로그 보기
kubectl -n rook-ceph logs -l app=rook-ceph-operator -f
kubectl -n rook-ceph get pods
kubectl -n rook-ceph get cephcluster
rook-ceph-tools 배포
ceph cli를 쓸 수 있도록 한다.
kubectl apply -f toolbox.yaml
1️⃣ CephFS 생성 (파일 시스템, RWX용)
apiVersion: ceph.rook.io/v1
kind: CephFilesystem
metadata:
name: jootest-filesystem # 원하는 파일 시스템 이름
namespace: rook-ceph # Rook-Ceph 클러스터가 설치된 네임스페이스
spec:
metadataPool:
replicated:
size: 3 # 데이터 복제본 수. 마스터 노드 3개에 각각 디스크가 1개씩 있으므로 3으로 설정
dataPools:
- replicated:
size: 3
metadataServer:
activeCount: 2 # 활성화된 메타데이터 서버 수 (최소 2개)
activeStandby: true # 장애 발생 시 대기 중인 MDS가 활성화되도록 설정
kubectl apply -f cephfilesystem.yaml
kubectl -n rook-ceph get cephfilesystem
kubectl -n rook-ceph get pods
2️⃣ RWX StorageClass 생성
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: rook-cephfs-rwx
provisioner: rook-ceph.cephfs.csi.ceph.com
parameters:
clusterID: rook-ceph
fsName: jootest-filesystem # << 이거 이름을 fs 이름으로 수정
pool: jootest-filesystem-data0 # << 확인해야 함. name 입력 안했으면 디폴트로 이렇게 들어감.
csi.storage.k8s.io/provisioner-secret-name: rook-csi-cephfs-provisioner
csi.storage.k8s.io/provisioner-secret-namespace: rook-ceph
csi.storage.k8s.io/node-stage-secret-name: rook-csi-cephfs-node
csi.storage.k8s.io/node-stage-secret-namespace: rook-ceph
mounter: fuse
reclaimPolicy: Delete
volumeBindingMode: Immediate
kubectl apply -f cephfs-sc.yaml
kubectl get sc
예전에는 hostpath로 pv를 만들고 pvc를 만들었는데 이제는 동적 프로비저닝이 되어서 pvc를 만들면 storage class에서 pv를 만든다.
pvc만들기
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: test-pvc
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi
storageClassName: rook-cephfs-rwx # 위에서 만든 스토리지 클래스 이름
만들어진 pvc를 마운트하기
예전에 만든 statefulset에 마운트하자.
기존에는 hostpath로 만든 pv에 pvc를 마운트했는데 replica가 1개만 마운트 된다.
이걸 ceph으로 만든 storageclass로 수정하자.
아니 이거 수정이 안되네...
Kubernetes 구조상 StatefulSet의 volumeClaimTemplates는 한 번 생성하면 변경이 불가능해요. 😅
- 이미 PVC가 만들어졌기 때문에, storageClassName이나 accessModes를 바꾸는 건 직접 수정 불가
- 따라서 RWX CephFS를 쓰려면 새 PVC와 새 StatefulSet을 만들어야 합니다.
새 PVC 만들기
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nginx-shared-pvc
namespace: app
spec:
accessModes:
- ReadWriteMany # 여러 Pod에서 공유
resources:
requests:
storage: 1Gi
storageClassName: rook-cephfs-rwx
volumeMode: Filesystem
kubectl -n app apply -f pvc-shared.yaml
kubectl -n app get pvc
만들어진 pvc를 statefulset으로 파드 만들 때 마운트하기
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: nginx-stateful
namespace: app
spec:
serviceName: "nginx"
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
volumeMounts:
- name: nginx-storage
mountPath: /usr/share/nginx/html
volumes:
- name: nginx-storage
persistentVolumeClaim:
claimName: nginx-shared-storage # ✅ 공유 PVC 연결
podManagementPolicy: OrderedReady
updateStrategy:
type: RollingUpdate
생성된 nginx 파드 내 /usr/share/nginx/html에 접속해서 index.html을 만들어보자
ubuntu@master1:~$ kubectl -n app exec -it nginx-stateful-0 -- df -h /usr/share/nginx/html
Filesystem Size Used Avail Use% Mounted on
ceph-fuse 1.0G 0 1.0G 0% /usr/share/nginx/html
파드에 접속해서 vim 설치
kubectl -n app exec -it nginx-stateful-0 -- /bin/bash
# Pod 내부에서 root 권한으로
apt update
apt install -y vim
원래는 index.html 파일이 있는데 마운트해서 다 사라짐. 새로 만들어야 함.
vim /usr/share/nginx/html/index.html
아래 내용을 넣고 접속하면 나오는데 새로고침 하면 안나옴.
다른 파드에서는 이 index.html에 접근 못하기 때문. 권한 설정을 해야 함.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>테스트 페이지</title>
</head>
<body>
<h1>안녕하세요!</h1>
<p>이것은 Nginx 서버의 간단한 테스트 페이지입니다.</p>
</body>
</html>
Pod 안에서 권한과 소유자를 nginx 유저로 바꿔주는 것이 안전:
# html 디렉토리와 index.html 권한 맞추기
chown -R nginx:nginx /usr/share/nginx/html
chmod 755 /usr/share/nginx/html
chmod 644 /usr/share/nginx/html/index.html
다른 파드에서 접근 가능한지 확인
kubectl -n app exec -it nginx-stateful-1 -- cat /usr/share/nginx/html/index.html
안된다. 왜냐면 파드 생성할 때 동기화하기 때문. 파드 삭제 후 재생성해야 함.
statefulset 재시작해서 파드 다시 생성
실시간 동기화 되는 것 같다.
kubectl -n app rollout restart sts
ceph 상태 확인하기
# rook-ceph 네임스페이스에 있는 toolbox Pod 확인
kubectl -n rook-ceph get pod -l "app=rook-ceph-tools"
# toolbox Pod 접속
kubectl -n rook-ceph exec -it <toolbox-pod-name> -- bash
# 내부에서 Ceph 상태 확인
ceph status
ceph osd tree
ceph osd df
각 마스터노드에 5GB 씩 볼륨이 추가되어 있는데 이게 cephFS로 잡혀있다.
ID CLASS WEIGHT REWEIGHT SIZE RAW USE DATA OMAP META AVAIL %USE VAR PGS STATUS
0 hdd 0.00490 1.00000 5 GiB 50 MiB 1.8 MiB 1 KiB 48 MiB 5.0 GiB 0.97 1.00 65 up
1 hdd 0.00490 1.00000 5 GiB 50 MiB 1.8 MiB 1 KiB 48 MiB 5.0 GiB 0.97 1.00 65 up
2 hdd 0.00490 1.00000 5 GiB 50 MiB 1.8 MiB 1 KiB 48 MiB 5.0 GiB 0.97 1.00 65 up
TOTAL 15 GiB 149 MiB 5.3 MiB 4.7 KiB 144 MiB 15 GiB 0.97
nginx 로그 저장용 pvc 만들기
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nginx-access-logs
namespace: app
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi
storageClassName: rook-cephfs-rwx
kubectl apply -f nginx-access-logs-pvc.yaml
kubectl get pvc -n app
statefulset 수정하기
volumeMounts, volumes를 추가하면 된다.
volumeMounts:
- mountPath: /usr/share/nginx/html
name: nginx-storage
- name: nginx-access-logs
mountPath: /var/log/nginx # 공유 로그
volumes:
- name: nginx-storage
persistentVolumeClaim:
claimName: nginx-shared-storage
- name: nginx-access-logs
persistentVolumeClaim:
claimName: nginx-access-logs # 새 PVC 마운트
서로 다른 파드에서 같은 로그가 보인다.
kubectl exec -it nginx-stateful-0 -n app -- bash
ls -l /var/log/nginx
tail -f /var/log/nginx/access.log
kubectl exec -it nginx-stateful-1 -n app -- bash
ls -l /var/log/nginx
tail -f /var/log/nginx/access.log
https://mokpolar.tistory.com/10
쿠버네티스에서 Ceph dashboard, CephFS 설치해 본 후기 (Ceph dashboard, CephFS on Kubernetes)
글 작성일: 2021.05.30 사전 정보 Ceph Dashboard Ceph Cluster의 상태를 모니터링하기 위해 Ceph Dashboard를 설치하면 아래와 같이 Ceph 클러스터의 상태를 한 눈에 보면서 관리 기능을 사용할 수 있다. CephFS Cep
mokpolar.tistory.com
ceph 대시보드 설치하기
# rook-ceph-tools Pod 접속
kubectl -n rook-ceph exec -it rook-ceph-tools-xxxx -- /bin/bash
# Dashboard 활성화
ceph mgr module enable dashboard
# 비밀번호 확인하기
# 시크릿이 자동으로 만들어져 있다.
kubectl -n rook-ceph get secret rook-ceph-dashboard-password -o jsonpath="{['data']['password']}" | base64 --decode && echo
접속용 서비스 만들기
apiVersion: v1
kind: Service
metadata:
name: rook-ceph-mgr-dashboard-external-https
namespace: rook-ceph
spec:
type: NodePort
selector:
app: rook-ceph-mgr
rook_cluster: rook-ceph
mgr_role: active
ports:
- name: dashboard
port: 8443 # 서비스 내부 포트
targetPort: 8443 # Pod 컨테이너 포트
nodePort: 32443 # 외부 접속 포트
이미 CephCluster + CephFS는 있으신 상태고, 여기에 CephBlockPool(RBD) 를 추가
Ceph는 한 클러스터 안에서 CephFS, RBD(Block), RGW(Object) 를 동시에 구성할 수 있기 때문에 가능
1️⃣ 전체 흐름
- CephBlockPool CR 생성 → Ceph에서 RBD Pool 생성
- StorageClass 생성 → 쿠버네티스 PVC와 연결
- PVC 생성 → Pod에서 사용
2️⃣ CephBlockPool CR 예시
apiVersion: ceph.rook.io/v1
kind: CephBlockPool
metadata:
name: replicapool
namespace: rook-ceph
spec:
failureDomain: host
replicated:
size: 3 # 복제본 개수 (클러스터 OSD 상황에 맞게 조정)
3️⃣ StorageClass 예시
xfs 1개, ext4 1개 만들 예정
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: rook-ceph-block-xfs # StorageClass 이름 (PVC에서 지정할 때 사용)
provisioner: rook-ceph.rbd.csi.ceph.com # Ceph RBD CSI 드라이버
parameters:
clusterID: rook-ceph # CephCluster 이름/네임스페이스
pool: replicapool # CephBlockPool 이름 (데이터 저장 위치)
imageFormat: "2" # RBD 이미지 포맷 버전 (항상 2 권장)
imageFeatures: layering # RBD 기능: snapshot/clone 지원
csi.storage.k8s.io/provisioner-secret-name: rook-csi-rbd-provisioner
csi.storage.k8s.io/provisioner-secret-namespace: rook-ceph
csi.storage.k8s.io/node-stage-secret-name: rook-csi-rbd-node
csi.storage.k8s.io/node-stage-secret-namespace: rook-ceph
csi.storage.k8s.io/fstype: xfs # 볼륨 파일시스템 (ext4도 가능)
reclaimPolicy: Delete # PVC 삭제 시 PV도 삭제할지 여부
allowVolumeExpansion: true # PVC 크기 확장 허용 여부
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: rook-ceph-block-ext4
provisioner: rook-ceph.rbd.csi.ceph.com
parameters:
clusterID: rook-ceph
pool: replicapool
imageFormat: "2"
imageFeatures: layering
csi.storage.k8s.io/fstype: ext4
csi.storage.k8s.io/provisioner-secret-name: rook-csi-rbd-provisioner # rook 설치 시 자동 생성
csi.storage.k8s.io/provisioner-secret-namespace: rook-ceph # rook 설치 시 자동 생성
csi.storage.k8s.io/node-stage-secret-name: rook-csi-rbd-node # rook 설치 시 자동 생성
csi.storage.k8s.io/node-stage-secret-namespace: rook-ceph # rook 설치 시 자동 생성
reclaimPolicy: Delete
allowVolumeExpansion: true
4️⃣ PVC 예시 (비교용)
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: rbd-xfs-pvc
namespace: test-tekton
spec:
accessModes:
- ReadWriteOnce
storageClassName: rook-ceph-block-xfs
resources:
requests:
storage: 10Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: rbd-ext4-pvc
namespace: test-tekton
spec:
accessModes:
- ReadWriteOnce
storageClassName: rook-ceph-block-ext4
resources:
requests:
storage: 10Gi
테스트용 pod 2개 생성
apiVersion: v1
kind: Pod
metadata:
name: fio-test-xfs
namespace: test-tekton
spec:
containers:
- name: fio
image: xridge/fio:latest
command: ["/bin/sh", "-c"]
args: ["while true; do sleep 3600; done"]
volumeMounts:
- mountPath: /data
name: vol
volumes:
- name: vol
persistentVolumeClaim:
claimName: rbd-xfs-pvc
apiVersion: v1
kind: Pod
metadata:
name: fio-test-ext4
namespace: test-tekton
spec:
containers:
- name: fio
image: xridge/fio:latest
command: ["/bin/sh", "-c"]
args: ["while true; do sleep 3600; done"]
volumeMounts:
- mountPath: /data
name: vol
volumes:
- name: vol
persistentVolumeClaim:
claimName: rbd-ext4-pvc
pod 접속해서 빈치마크 실행하기
kubectl exec -it fio-test-xfs -n test-tekton -- sh
kubectl exec -it fio-test-ext4 -n test-tekton -- sh
fio --name=randrw \
--filename=/data/testfile \
--size=1G \
--rw=randrw \
--bs=4k \
--direct=1 \
--numjobs=4 \
--iodepth=16 \
--runtime=60 \
--group_reporting
fio-test-cephfs.yaml
cephfs로 만들어서 테스트하기
apiVersion: v1
kind: Pod
metadata:
name: fio-test-cephfs
namespace: test-tekton
spec:
containers:
- name: fio
image: xridge/fio:latest
command: ["/bin/sh", "-c"]
args: ["while true; do sleep 3600; done"]
volumeMounts:
- mountPath: /data
name: vol
volumes:
- name: vol
persistentVolumeClaim:
claimName: tekton-cache-pvc
kubectl exec -it fio-test-cephfs -n test-tekton -- /bin/sh
fio --name=randrw --filename=/data/testfile --size=1G --rw=randrw \
--bs=4k --direct=1 --numjobs=4 --iodepth=16 --runtime=60 --group_reporting
fio --name=randrw --filename=/data/testfile --size=1G --rw=randrw --bs=4k --direct=1 --numjobs=4 --iodepth=16 --runtime=60 --group_reporting
kubectl run fio-test --rm -i --tty --image=appropriate/fio -- \
fio --name=randrw --filename=/data/testfile --size=1G --rw=randrw --bs=4k --direct=1 --numjobs=4 --iodepth=16 --runtime=60 --group_reporting
'배운 내용 > Kubernetes' 카테고리의 다른 글
| [Kubernetes]Metrics Server 설치 (0) | 2025.09.26 |
|---|---|
| 실무과제5 tekton 설치 (0) | 2025.09.24 |
| (1)자체 구축(Self-Managed / On-Prem 스타일) 쿠버네티스 (1) | 2025.09.22 |
| Ubuntu 환경에서 K9S 설치 / 명령어 자동완성 (0) | 2025.09.18 |
| [web]deployment - pod - service - ingress 설정 - aws route53 (1) | 2025.08.18 |
