Openshift / Kubernetes 컨테이너 권한 설정하기

리눅스/OpenShift|2023. 6. 20. 09:13
반응형

Openshift 또는 Kubernetes 에서 컨테이너 생성시 권한을 제한하여 보안을 강화하는 방법이 있습니다.

Pod 생성시 컨테이너 권한 제한 예제입니다.

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
  - name: container1
    image: docker.io/php
    securityContext:
      capabilities:
        add: ["ALL"]
        remove: ["SYS_ADMIN", "SETUID", "SETGID", "SETPCAP", "SYS_MODULE", "SYS_BOOT", "NET_ADMIN", "SYS_RAWIO"]
...

 

위 예제에서 container1 컨테이너의 securityContext 에서 SYS_ADMIN 외 여러개의 권한을 제한하도록 설정하였습니다. 이렇게 하면 container1 에서만 시스템 관리 작업과 기타 작업을 위한 명령어 사용이 제한됩니다. 아래는 securityContext의 capabilities 섹션에서 remove 필드에 사용할 수 있는 종류 중 일부 목록입니다. 아래 항목을 remove 필드에 추가하여 사용을 제한하면, 컨테이너 보안 강화에 도움이 됩니다.

"SETPCAP": 프로세스의 임의의 캐퍼빌리티 설정을 방지합니다.
"SYS_MODULE": 커널 모듈의 적재 및 언로드를 방지합니다.
"SYS_RAWIO": 장치에 대한 원시 입출력을 방지합니다.
"SYS_PACCT": 프로세스 계정 정보에 대한 접근을 제한합니다.
"SYS_ADMIN": 시스템 관리 작업을 수행할 수 있는 권한을 제한합니다.
"SYS_NICE": 프로세스에 대한 우선 순위 설정을 방지합니다.
"SYS_RESOURCE": 자원 제한에 대한 설정을 방지합니다.
"SYS_TIME": 시스템 시간 설정을 방지합니다.
"SYS_PTRACE": 다른 프로세스에 대한 추적 기능을 제한합니다.
"SYS_BOOT": 부팅 설정을 제한합니다.
"DAC_READ_SEARCH": 파일의 소유권 및 검색 설정에 대한 권한을 제한합니다.
"LINUX_IMMUTABLE": 파일의 변경 및 수정을 방지합니다.
"NET_ADMIN": 네트워크 설정에 대한 권한을 제한합니다.
"IPC_LOCK": 공유 메모리 세그먼트에 대한 락 설정을 방지합니다.

 

반응형

댓글()

리눅스 CLI 에서 Github 원격지 리포지토리 (repogitory) 소스코드 다운로드하기 (Public / Private)

리눅스/OS 일반|2023. 6. 16. 14:39
반응형

Github 에 올려진 소스 코드를 다운로드 하는 방법입니다.

CentOS 7 환경에서 테스트하였습니다.

1. 패키지 설치
우선 소스 코드를 다운로드 하기위해 github 패키지를 설치합니다.
# yum -y install git


2. Public 코드 다운로드
공개 코드는 아무나 접근하여 다운로드가 가능하므로 아래와 같이 실행할 수 있습니다.
# git clone https://github.com/sysdocu/html-sample.git

리포지토리 이름으로 생성된 디렉토리로 이동합니다.
# cd html-sample

파일 내용을 확인합니다.
# ls -al

3. Private 코드 다운로드
1) 직접 계정 입력
Private 리포지토리 URL 을 공개 코드 다운로드와 같이 명령을 실행하면 Username, Password 를 입력하는 절차가 출력됩니다. 하지만 CLI 에서 명령 한줄로 처리하고자 할때 아래와 같이 사용이 가능합니다.
# git clone https://<username>:<password>@github.com/sysdocu/html-secret.git

CLI 한줄에 계정 정보 입력시 <username> 이나 <password> 에 특수문자가 들어가게 될 경우 아래와 같은 문자로 치환해주어야 합니다.

[이미지 출처] https://stackoverflow.com/questions/10054318/how-do-i-provide-a-username-and-password-when-running-git-clone-gitremote-git/10056098#10056098

2) Git 자격 증명 사용
직접 계정을 입력하는 방법은 history 에도 남고 패스워드가 탈취될 가능성이 있기 때문에 안전한 방법이 아닙니다. 하지만 강화된 보안 방법인 'Git 자격 증명' 을 사용하면 계정이 아닌 토큰으로 인증이 가능하며, 계정에 대한 작업 권한도 제어가 가능하고, 일정 시간이 지나 토큰의 효력이 상실되기 때문에 패스워드 탈취에 대한 부담도 줄일 수 있습니다.

 

우선 Github 에 로그인을 하고 토큰 생성 페이지 (바로가기 : https://github.com/settings/tokens) 로 이동합니다.

페이지 내에서 'Generate a personal access token' 링크 또는 'Generate new token' > 'Generate new token (classic)' 을 누르고, 토큰 발급 이유를 'Note' 에 적당히 입력 후, 토큰의 만료 기간을 선택합니다. repo 의 모든 기능에만 체크하고, 하단의 [Generate token] 를 누르면 토큰이 출력됩니다. 이것을 복사하여 CLI 명령어에 사용하도록 합니다.

# git clone https://<token>@github.com/sysdocu/html-secret.git


다운로드가 확인되었으며, 리포지토리 이름으로 생성된 디렉토리로 이동합니다.
# cd html-secret

파일 내용을 확인합니다.
# ls -al

 

반응형

댓글()

C/C++ 프로그레스바 (ProgressBar)

프로그래밍/C, C++|2023. 6. 16. 07:57
반응형

C/C++의 콘솔 환경에서 프로그레스바 (진행바) 구현 소스입니다.

아래와 같이 심플하게 개수, 프로그레스바, 진행률 이 출력됩니다.

 

10/10 [==================================================] 100%

 

#include <stdio.h>
#include <stdlib.h>  
#include <windows.h> // Sleep 함수 

int main() {
        const char bar = '='; // 프로그레스바 문자  
        const char blank = ' '; // 비어있는 프로그레스바 문자  
        const int LEN = 20; // 프로그레스바 길이  
        const int MAX = 1000; // 진행작업 최대값 
        const int SPEED = 50; // 카운트 증가 대기시간  
        int count = 0; // 현재 진행된 작업  
        int i; // 반복문 전용 변수  
        float tick = (float)100/LEN; // 몇 %마다 프로그레스바 추가할지 계산 
        printf("%0.2f%% 마다 bar 1개 출력\n\n", tick); 
        int bar_count; // 프로그레스바 갯수 저장 변수  
        float percent; // 퍼센트 저장 변수  
        while(count <= MAX) {
                printf("\r%d/%d [", count, MAX); // 진행 상태 출력  
                percent = (float)count/MAX*100; // 퍼센트 계산  
                bar_count = percent/tick; // 프로그레스바 갯수 계산  
                for(i=0; i<LEN; i++) { // LEN길이의 프로그레스바 출력  
                        if(bar_count > i) { // 프로그레스바 길이보다 i가 작으면 
                                printf("%c", bar);
                        } else { // i가 더 커지면  
                                printf("%c", blank);
                        }
                }
                printf("] %0.2f%%", percent); // 퍼센트 출력  
                count++; // 카운트 1증가  
                Sleep(SPEED); // SPEEDms 대기  
        }
        printf(" done!\n\n");
        system("pause"); // 프로그램 종료 전 일시정지  
        return 0; 
}

 

1000개의 전체 작업량 중 1개가 완료되었다면 진행률은 0.1%가 됩니다.
현재 진행량/전체 진행량 * 100 = 진행률(%)
100분율 계산법입니다.
해당 연산은 코드의 19행에서 진행하고 있습니다.
현재 진행량은 코드상에서 count 변수
전체 진행향은 코드상에서 MAX 변수입니다.

진행률을 계산했으면 해당 진행률을 기준으로 프로그레스바(진행바)를 출력해야합니다.
100(%)/프로그레스바 길이 = 몇 %마다 프로그레스바 1개 출력
만약 프로그레스바의 길이가 20이라고 하면
100/20 = 5
[====================] 100%
위의 모습일겁니다.

길이는 고정되어있음으로 진행률 퍼센트에 따라 = 문자를 출력해줘야 하죠
코드의 13행에서 해당 계산을 진행하고 있습니다.
계산 후 tick 이라는 변수에 저장해두었습니다.

20길이의 프로그레스바는 5% 마다 = 한개를 출력합니다.
10%라고 하면 == 를 출력하겠죠?

17~31행의 while 문은 0~전체 진행량까지 반복하는 반복문입니다.
19행에서 매번 반복마다 진행률(%)을 계산하여
20행에서 프로그레스바 = 문자를 몇개 출력할지 계산한 후
그 아래 21행 for문에서 출력을 합니다.

for문은 0~LEN 까지 반복을 하는데 LEN은 프로그레스바의 길이가 저장되있는 변수이름입니다.
20이라고 가정하면 0~20까지 반복하계되죠
bar_count는 20행에서 현재 %는 몇개의 =문자를 출력할지 저장되어있습니다.

만약 프로그레스바 길이가 20이고 진행률이 7%라고 가정합시다.

1 - 13행처럼 먼저 몇 %마다 =문자를 출력할지 계산
100/20 = 5(%)
tick = 5

2 - bar_count에 현재 퍼센트는 몇개의 =를 출력할지 계산
percent/tick = 갯수
7/5 = 1(나머지 버림)
bar_count = 1

3 - for문에서 출력
LEN이 20이므로 i = 0~20
if(bar_count > i) 
0~20까지 i가 증가하면서 bar_count와 비교하여 출력
bar_count는 현재 1이 저장되어있으므로 i가 0일때만 참
20번 반복하면서 =하나를 출력하게 되고
거짓인 경우에는 else 로 가서 공백을 출력합니다.

4 - for문으로 출력 후 퍼센트 출력 및 count 증가
count(현재 진행량)를 1 증가

위의 과정을 현재 진행량~전체 진행량까지 반복하여 100%가 되면 종료합니다.
출력하는데 왜 이어서 출력이 되지않고 원래 위치 그대로에서 출력될까요?
그 문제는 18행에 있습니다.
printf("\r")

\r 이스케이프 시퀀스는 해당 라인의 첫 번째 위치로 이동합니다.
첫 번째로 이동한 후 다시 출력을 하게되어 위치가 바뀌지않고 진행되는이유입니다.

 

[출처] https://geundung.dev/43

 

 

반응형

댓글()

Openshift 4.12.0 PV, PVC (GlusterFS) 를 이용한 Volume 추가

리눅스/OpenShift|2023. 6. 8. 14:59
반응형

GlusterFS Cluster 정보를 이용하여 Endpoint 를 작성합니다.

# vi endpoint.yaml

apiVersion: v1
kind: Endpoints
metadata:
  name: glusterfs-cluster
subsets:
  - addresses:
      - ip: 115.68.249.122
      - ip: 115.68.248.172
      - ip: 115.68.249.106
    ports:
      - port: 1

 

* 설명

subsets: address: ip: 는 GlusterFS 클러스터를 구성하는 서버의 실제 IP 주소여야 합니다.

subsets: ports: port: 에 입력하는 포트번호는 무시해도 됩니다.

 

작성한 yaml 파일을 적용합니다.

# oc apply -f endpoint.yaml
endpoints/glusterfs-cluster created

 

적용된 Endpoint 를 확인합니다.

# oc get ep
NAME                          ENDPOINTS                                            AGE
endpoints/glusterfs-cluster   115.68.249.122:1,115.68.248.172:1,115.68.249.106:1   12m

 

PV (Persistent Volume) 생성을 위한 yaml 파일을 작성합니다.

# vi pv.yaml

apiVersion: v1
kind: PersistentVolume
metadata:
  name: glusterfs-pv
spec:
  storageClassName: ""
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteMany
  glusterfs:
    endpoints: glusterfs-cluster
    path: /gv0
    readOnly: false
  persistentVolumeReclaimPolicy: Retain

 

storageClassName: 빈 문자열을 명시적으로 사용해야 합니다. 그렇지 않으면 기본 StorageClass 가 설정됩니다.

glusterfs: endpoints: 에는 먼저 생성했던 Endpoint 이름 입니다.

glusterfs: path: 에는 마운트할 GlusterFS 의 볼륨입니다. 앞에 슬래시를 꼭 붙여줘야 합니다. 그리고 /gv0/apple 과 같이 쿼터 적용된 디렉토리로도 마운트 가능합니다.

persistentVolumeReclaimPolicy: 의 Retain 값은 PV 가 삭제되어도 GlusterFS 내의 데이터는 삭제하지 않겠다는 뜻입니다.

작성한 yaml 파일을 적용합니다.

# oc apply -f pv.yaml

persistentvolume/glusterfs-pv created

 

Pod 와 PV 를 연결하기 위한 PVC (PersistentVolumeClaim) yaml 파일을 작성합니다.

# vi pvc.yaml

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: glusterfs-pvc
spec:
  storageClassName: ""
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 1Gi
  volumeName: glusterfs-pv

 

작성한 yaml 파일을 적용합니다.

# oc apply -f pvc.yaml

persistentvolumeclaim/glusterfs-pvc created

 

Deployment yaml 를 작성하여 Pod 가 생성되도록 합니다.

# vi deployment_volume.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: glusterfs-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: glusterfs-pod
  template:
    metadata:
      labels:
        app: glusterfs-pod
    spec:
      securityContext:
        seccompProfile:
          type: RuntimeDefault
      containers:
      - name: glusterfs-pod
        image: default-route-openshift-image-registry.apps.az1.sysdocu.kr:5000/project412/python
        ports:
        - containerPort: 8080
          protocol: TCP
        securityContext:
          allowPrivilegeEscalation: false
          capabilities:
            drop: ["ALL"]
          runAsNonRoot: true
        volumeMounts:
        - name: my-volume
          mountPath: /data
      volumes:
      - name: my-volume
        persistentVolumeClaim:
          claimName: glusterfs-pvc
      imagePullSecrets:
      - name: sysdocu

 

volumeMounts: mountPath: 는 Pod 내에서 마운트 될 디렉토리를 의미하며 디렉토리가 없는 경우 자동으로 생성됩니다.

작성한 yaml 파일을 적용합니다.

# oc apply -f deployment_volume.yaml

 

Pod 에 Volume 이 잘 연결되었는지 확인합니다.

# oc get pod
NAME                                    READY   STATUS        RESTARTS   AGE
glusterfs-deployment-7c45b99b7c-pstl5   1/1     Running       0          7s

 

# oc rsh glusterfs-deployment-7c45b99b7c-pstl5

$ df -h
Filesystem                Size  Used Avail Use% Mounted on
overlay                   233G   36G  197G  16% /
tmpfs                      64M     0   64M   0% /dev
tmpfs                     7.8G     0  7.8G   0% /sys/fs/cgroup
shm                        64M     0   64M   0% /dev/shm
tmpfs                     7.8G   53M  7.7G   1% /etc/passwd
115.68.249.122:/gv0   10G  135M  9.9G   2% /data
/dev/sda4                 233G   36G  197G  16% /etc/hosts
tmpfs                      15G   20K   15G   1% /run/secrets/kubernetes.io/serviceaccount
tmpfs                     7.8G     0  7.8G   0% /proc/acpi
tmpfs                     7.8G     0  7.8G   0% /proc/scsi
tmpfs                     7.8G     0  7.8G   0% /sys/firmware

 

* 참고

마운트가 되지 않을 경우 Pod 부터 정상 가동 (Running) 되지 않습니다. 그런 경우에 GlusterFS 를 구성하는 노드가 DNS 에서 질의되지 않는 호스트명으로 되어있는지 확인해 볼 필요가 있습니다. gnode1, gnode2, gnode3 등의 호스트명으로 GlusterFS 노드가 구성 되어 있다면 worker 노드에서 마운트 하지 못하므로 모든 스케쥴링 되는 Openshift 노드 (worker node) 에 /etc/hosts 파일을 수정하여 GlusterFS 를 구성하는 노드의 IP 와 호스트명을 등록해놔야 합니다.

 

반응형

댓글()

CentOS 7 에서 GlusterFS 를 yum 으로 설치하기 (각종 구성 방법)

리눅스/OS 일반|2023. 6. 7. 11:41
반응형

GlusterFS 는 분산 파일 시스템으로써 여러 대의 서버를 클러스터로 구성하여 대용량의 데이터를 분산 저장하고 관리할 수 있는 기술입니다. RAID 와 같이 각각의 노드에 데이터를 따로 저장하거나 (Distributed), 복제 저장하거나 (Replicated), 분산 저장 (Disperse) 이 가능합니다. GlusterFS 는 Redhat 이 개발하고 오픈 소스로 제공되며, 다양한 용도의 분산 스토리지 및 파일 공유에 이용됩니다.

 

본 매뉴얼에서의 테스트 환경은 CentOS 7 이며, 다양한 볼륨 구성을 예제로 다루었습니다.

CentOS 6 또는 8 버전은 설치 방법에 약간 차이가 있으니 아래 Documents 를 참고해 주세요.

https://wiki.centos.org/SpecialInterestGroup/Storage/gluster-Quickstart

 

[사전 작업]
각 노드에 추가 Disk 를 연결하고 /data 디렉토리로 마운트 했습니다.
그리고 각 마운트 디렉토리 안에 gv0 이라는 Brick 디렉토리를 생성해 두었습니다.

Brick 디렉터리는 GlusterFS 볼륨에서 데이터를 저장하는 디렉터리를 뜻합니다.
- /data/gv0

 

 

1. GlusterFS 서버 구축

 

1) hostname 설정

호스트 명을 변경합니다.
# hostnamectl set-hostname gnode1  // 1번 노드에서
# hostnamectl set-hostname gnode2  // 2번 노드에서

# hostnamectl set-hostname gnode3  // 3번 노드에서

 

(모든 노드에서)
호스트를 등록 합니다.
# vi /etc/hosts

127.0.0.1   localhost localhost.localdomain gnode1
192.168.10.20 gnode2
192.168.10.30 gnode3

 

위는 gnode1 의 hosts 내용인데, 자신의 노드는 따로 행을 추가하지 말고 127.0.0.1 라인에 기록해 둡니다.

gnode2, gnode3 노드에서의 hosts 는 각각 다음과 같습니다.

127.0.0.1   localhost localhost.localdomain gnode2
192.168.10.10 gnode1
192.168.10.30 gnode3

 

127.0.0.1   localhost localhost.localdomain gnode3
192.168.10.10 gnode1
192.168.10.20 gnode2

 

2) 패키지 설치
GlusterFS 설치를 위한 Repository 를 등록해줍니다.
등록은 yum 로 간단히 할 수 있습니다.
# yum -y install centos-release-gluster

 

GlusterFS 패키지를 설치합니다.
# yum -y install glusterfs glusterfs-libs glusterfs-server

서버 부팅시 glusterd 데몬이 자동 구동 되도록 하고, 현재 세션에서도 구동시켜줍니다.
# systemctl enable --now glusterd

 

설치된 버전을 확인합니다.

# glusterd --version
glusterfs 9.6
Repository revision: git://git.gluster.org/glusterfs.git
Copyright (c) 2006-2016 Red Hat, Inc. <https://www.gluster.org/>
GlusterFS comes with ABSOLUTELY NO WARRANTY.
It is licensed to you under your choice of the GNU Lesser
General Public License, version 3 or any later version (LGPLv3
or later), or the GNU General Public License, version 2 (GPLv2),
in all cases as published by the Free Software Foundation.

 

서버간 통신이 이루어져야 하므로 firewalld 또는 iptables 와 같은 방화벽에서 서로의 IP 를 허용해주거나, 데이터가 없는 테스트 서버일 경우 방화벽을 잠시 내려 테스트 합니다.

 

 

2. 복제 (Replica) 볼륨 구성

 

replica 볼륨은 데이터를 여러 브릭에 복제하여 데이터의 안정성과 내구성을 제공합니다.

RAID 시스템의 1 (mirror) 과 유사합니다. 노드 2대로만 구성하는 것이 아니고 여러대로 복제가 가능합니다.

GlusterFS 에서는 기본 3대 이상으로 구성할 것을 권하고 있으며, 2대로 구성을 원할경우 아래 '8. 판사 (Arbiter) 볼륨 구성' 을 참고하세요.

여기에서는 3대의 노드로 구성해 보겠습니다.

패키지 설치와 호스트네임 등록 이후의 설정은 하나의 노드에서만 합니다.

 

1) Pool 연결

(gnode1 노드에서)

Cluster Pool 을 구성합니다.

# gluster peer probe gnode2

peer probe: success

# gluster peer probe gnode3
peer probe: success

 

연결된 노드를 확인합니다.

gnode1 에서 명령 실행시 연결된 두개의 노드 (gnode2, gnode3) 가 보입니다.

# gluster peer status
Number of Peers: 2

 

Hostname: gnode2
Uuid: edea03f3-472b-47b5-a711-ed06763631c4
State: Peer in Cluster (Connected)

 

Hostname: gnode3
Uuid: 0771cb09-89d3-4a5b-8e7d-3980473ffc0e
State: Peer in Cluster (Connected)

 

다른 노드에서도 같은 명령을 사용해보면 자신의 노드를 제외한 총 2개의 노드 정보가 확인됩니다.

참고로 peer 노드 제거 명령은 'gluster peer detach <노드명>' 을 사용합니다.

 

Pool 리스트를 확인합니다.

# gluster pool list
UUID Hostname  State
edea03f3-472b-47b5-a711-ed06763631c4 gnode2    Connected 
0771cb09-89d3-4a5b-8e7d-3980473ffc0e gnode3    Connected 
25d3f6cb-b2ed-4aa1-add7-0a27890ed5ed localhost Connected 

 

이 명령에서는 자신의 노드를 포함한 총 3개의 노드 정보가 확인됩니다.

 

2) 볼륨 생성

데이터를 저장할 수 있도록 GlusterFS 볼륨을 생성합니다.

(gnode1 노드에서)

3대의 노드를 하나의 볼륨으로 묶습니다. (볼륨명 : gv0, 복제본 : 3)

# gluster volume create gv0 replica 3 gnode1:/data/gv0 gnode2:/data/gv0 gnode3:/data/gv0

volume create: gv0: success: please start the volume to access data

 

여기에서 volume create: gv0: failed: /data/gv0 is already part of a volume 에러가 출력되는 분은 아래 '5. 볼륨 재구성' 을 참고하세요.

노드 서버 3대로 복제 저장 구성을 한 이유는 2대로만 복제 구성하면 스플릿 브레인에 취약할 수 있기 때문입니다. 스플릿 브레인은 분산 파일 시스템에서 복제된 데이터의 일관성을 유지하기 위해 중요한 개념입니다. 복제된 볼륨이 스플릿 브레인에 취약하다는 것은 데이터의 불일치가 발생할 수 있는 가능성이 있다는 것을 의미합니다. 복제 2 볼륨은 두 개의 복제본을 가지고 있으므로 데이터의 일관성을 유지하기 위해 두 복제본이 동기화되어야 합니다. 그러나 네트워크 문제, 장애 등의 이유로 복제본 간의 통신이 중단되면 각각의 복제본이 독립적으로 운영되는 상황이 발생할 수 있습니다. 이는 데이터의 일관성을 해치는 스플릿 브레인 상태를 초래할 수 있습니다.

 

gv0 볼륨을 시작합니다.

# gluster volume start gv0

volume start: gv0: success

 

gv0 볼륨 상태를 확인합니다.

# gluster volume info gv0

 
Volume Name: gv0
Type: Replicate
Volume ID: 09540703-2a84-4dce-bb6c-af156cf1813d
Status: Started
Snapshot Count: 0
Number of Bricks: 1 x 3 = 3
Transport-type: tcp
Bricks:
Brick1: gnode1:/data/gv0
Brick2: gnode2:/data/gv0
Brick3: gnode3:/data/gv0
Options Reconfigured:
cluster.granular-entry-heal: on
storage.fips-mode-rchecksum: on
transport.address-family: inet
nfs.disable: on
performance.client-io-threads: off

 

* 중요 : 볼륨 생성 후 옵션을 하나 설정합니다.

볼륨 구성이 어떠한 형태이던 (비록 replica 일지라도) GlusterFS Cluster 를 구성하는 한 개의 peer 가 장애가 났을때 Client 는 42초간 (default) GlusterFS 의 응답을 기다리느라 데이터를 읽거나 쓰지 못하게 됩니다. 서비스 제공시 42초는 긴 시간이기 때문에 장애 서버의 다운을 감지하고 해당 peer 를 빠르게 제거하기 위한 옵션 network.ping-timeout 을 설정해 주어야 합니다.

여기에서는 서버 응답 대기시간을 0초로 적용합니다. 이렇게 하면 peer 다운시 찰나의 지연 (delay) 이 있지만 끊어지지 않으며 데이터 유실또한 발생하지 않습니다.

# gluster volume set gv0 network.ping-timeout 0

volume set: success

# gluster volume info | grep timeout
network.ping-timeout: 0

추후 장애 peer 복구시 파티션 (Brick Directory) 연결 및 glusterd 데몬이 순자적으로 이루어진다면, 다른 peer 에서 생성, 변경된 파일이 자동으로 동기화되어 최신 데이터를 유지하게 됩니다.

 

사용가능한 옵션 종류는 아래 URL 에서 확인 가능합니다.

https://access.redhat.com/documentation/ko-kr/red_hat_gluster_storage/3.5/html/administration_guide/volume_option_table

 

* 데이터 저장 형태

데이터가 어느 노드에 어떻게 저장되는지 확인하고 싶어서 적당한 크기의 파일을 하나씩 입력해 보았고 아래 내용으로 확인되었습니다.

- 파일을 저장하면 replica 3 으로 구성된 gnode1, gnode2, gnode3 노드에 동일한 데이터 저장

 

 

3. Quota 설정

 

Brick 디렉토리에 하위 디렉토리를 생성하여 용량을 제한을 할 수 있습니다.

공식 Document : https://docs.gluster.org/en/v3/Administrator%20Guide/Directory%20Quota/

 

gv0 볼륨 쿼터 설정을 활성화 합니다.

# gluster volume quota gv0 enable

volume quota : success

 

참고로 비활성화는 enable 대신 disable 을 입력합니다.

그리고 Client 가 마운트하여 사용하던 중 쿼터 제한을 걸때 사용하는 옵션이 있는데 이에 대한 설명은 아래와 같습니다. (Default : on)

# gluster volume set gv0 quota-deem-statfs on

 

* 참고

- on: GlusterFS는 디렉토리의 용량 제한을 강제로 적용하고, 해당 디렉토리에서 사용 가능한 실제 용량을 디렉토리의 용량 제한으로 간주합니다. 즉, 사용자가 설정한 용량 제한보다 실제 사용 중인 용량이 크더라도 GlusterFS는 해당 디렉토리의 용량 제한을 적용합니다. 이는 사용자가 실제 사용 중인 용량을 고려하지 않고 일관된 용량 제한을 유지하고자 할 때 유용합니다.

(예 : 2GB 데이터 사용중에 쿼터를 1GB 로 제한하면, 제한값은 1GB 에 머물러 있음)
- off: GlusterFS는 디렉토리의 용량 제한을 강제로 적용하지 않고, 실제 사용 중인 용량을 기준으로 디렉토리의 용량 제한을 판단합니다. 즉, 사용자가 설정한 용량 제한보다 실제 사용 중인 용량이 크다면 GlusterFS는 해당 디렉토리의 용량 제한을 초과로 간주합니다. 이는 실제 사용 중인 용량을 기준으로 용량 제한을 적용하고자 할 때 유용합니다.

(예 : 2GB 데이터 사용중에 쿼터를 1GB 로 제한하면, 제한값은 2GB 에 머물러 있음)

 

하위 디렉토리를 그냥 만들면 mkdir 명령을 내린 노드에서만 디렉토리가 생성되기때문에 쿼터 적용이 되지 않습니다.

볼륨을 마운트하고 디렉토리를 만들어 놓아야 합니다.

Client 또는 아무 node 에서나 마운트 명령을 내려도 상관없습니다.

# mkdir /imsi

# mount -t glusterfs gnode1:/gv0 /imsi

# mkdir /imsi/{apple,banana,grape}

# umount /imsi

 

하위 디렉토리에 각 1G 씩 용량 제한을 합니다.

디렉토리를 지정할때는 Brick 디렉토리 (/data/gv0) 를 제외하고 하위 디렉토리만 입력합니다.

# gluster volume quota gv0 limit-usage /apple 1GB

volume quota : success
# gluster volume quota gv0 limit-usage /banana 1GB
volume quota : success
# gluster volume quota gv0 limit-usage /grape 1GB
volume quota : success

 

gv0 볼륨의 쿼터 설정값을 확인합니다.

# gluster volume quota gv0 list

                  Path                   Hard-limit  Soft-limit      Used  Available  Soft-limit exceeded? Hard-limit exceeded?
-------------------------------------------------------------------------------------------------------------------------------
/apple                                     1.0GB     80%(819.2MB)   0Bytes   1.0GB              No                   No
/banana                                    1.0GB     80%(819.2MB)   0Bytes   1.0GB              No                   No
/grape                                     1.0GB     80%(819.2MB)   0Bytes   1.0GB              No                   No

 

Hard-limit 는 1GB 로 원하는 용량이 제한 되었지만, Soft-limit 는 80% 선으로 설정된 것이 보입니다.

- Hard-limit : 사용자 또는 프로세스가 설정된 최대 제한을 초과하지 못하도록 하는 제한하는 값입니다.

- Soft-limit : 사용자 또는 프로세스가 현재 사용 중인 리소스의 제한으로, 사용자가 시스템 리소스를 임시로 초과할 수 있는 한계를 설정합니다. Soft-limit은 Hard-limit 보다 작거나 같아야 합니다. Soft-limit 을 초과하려는 경우에는 경고가 발생하지만 작업을 계속할 수 있습니다. 시스템의 안정성을 고려하기 위해 용량이 거의 채워져간다는 알림을 주기 위한 용도 정도로 보면 됩니다.

 

Soft-limit 도 100% 까지 사용하기 위해 아래와 같이 변경 설정 해줍니다.

# gluster volume quota gv0 limit-usage /apple 1GB 100
volume quota : success
# gluster volume quota gv0 limit-usage /banana 1GB 100
volume quota : success
# gluster volume quota gv0 limit-usage /grape 1GB 100
volume quota : success

 

변경 내용을 확인합니다.

# gluster volume quota gv0 list
                  Path                   Hard-limit  Soft-limit      Used  Available  Soft-limit exceeded? Hard-limit exceeded?
-------------------------------------------------------------------------------------------------------------------------------
/apple                                     1.0GB    100%(1.0GB)   0Bytes   1.0GB              No                   No
/banana                                    1.0GB    100%(1.0GB)   0Bytes   1.0GB              No                   No
/grape                                     1.0GB    100%(1.0GB)   0Bytes   1.0GB              No                   No

 

 

4. Client 마운트

 

GlusterFS 에서는 몇가지 마운트 방법을 제공합니다. GlusterFS (FUSE), NFS, iSCSI, SMB 방식인데 여기에서는 일반적인 FUSE 방식을 설명하겠습니다.

Client 에서 마운트에 필요한 패키지를 설치하고 마운트를 합니다.

GlusterFS 서버를 찾을 수 있도록 도메인을 연결하면 좋겠지만 현재 테스트 환경에서는 hosts 파일을 이용하였으므로 Client 에서도 찾을 수 있도록 /etc/hosts 파일에 아래 내용을 작성해 줍니다.

# vi /etc/hosts

127.0.0.1   localhost localhost.localdomain
192.168.10.10 gnode1
192.168.10.20 gnode2
192.168.10.30 gnode3

 

그리고 마운트 할때는 gnode1 부터 gnode3 까지 아무 서버로 연결해도 상관없습니다.

# yum -y install glusterfs-client

# mkdir /backup

# mount -t glusterfs gnode1:/gv0 /backup

 

또는 쿼터 적용된 디렉토리로 마운트가 가능합니다.

# mount -t glusterfs gnode1:/gv0/apple /backup

 

마운트 디렉토리에 파일을 쓰면 모든 노드에 동일하게 복제되어 저장됩니다.

 

 

-------------------- 여기부터 다양한 스토리지 구성 테스트 --------------------

 

 

5. 볼륨 재구성 (볼륨 완전 삭제, 재생성)

 

볼륨을 삭제하고 다시 구성할때 에러가 발생하는데 어떻게 해결하는지 알아봅니다.

볼륨을 중지해야 삭제가 가능하기 때문에 먼저 중지 명령을 내립니다.

# gluster volume stop gv0
Stopping volume will make its data inaccessible. Do you want to continue? (y/n) y
volume stop: gv0: success

 

볼륨을 삭제합니다.
# gluster volume delete gv0
Deleting volume will erase all information about the volume. Do you want to continue? (y/n) y
volume delete: gv0: success

 

이 상태에서 동일한 디렉토리로 볼륨 설정을 하면 아래와 같이 에러가 발생합니다.

# gluster volume create gv0 replica 3 gnode1:/data/gv0 gnode2:/data/gv0 gnode3:/data/gv0
volume create: gv0: failed: /data/gv0 is already part of a volume

 

이는 볼륨을 생성하려는 디렉토리에 메타데이터가 있거나 구성의 흔적 때문인데, 해결책은 아래와 같습니다.

 

(모든 노드에서 : 볼륨 구성했던 이력이 있는 모든 서버)

# setfattr -x trusted.glusterfs.volume-id /data/gv0
# setfattr -x trusted.gfid /data/gv0
# rm -rf /data/gv0/.glusterfs*

 

그리고 하나의 노드에서 아래와 같이 명령을 내리면 볼륨이 정상적으로 생성됩니다.

# gluster volume create gv0 replica 3 gnode1:/data/gv0 gnode2:/data/gv0 gnode3:/data/gv0
volume create: gv0: success: please start the volume to access data

 

 

6. 장애 노드 (peer) 교체

 

replica 3 (peer 3개) 으로 구성된 cluster 에서 1개의 노드 (peer) 가 장애나면 2개의 peer 에서 무정지로 서비스가 가능합니다. 이때 장애난 peer 를 새로운 서버로 변경한다고 했을때 cluster 를 재구성 하는 방법 입니다.

gnode1, gnode2, gnode3 중에서 gnode2 가 장애 났다고 가정합니다.

 

사전작업으로 gnode2 노드에 추가 Disk 를 연결하고 /data 디렉토리로 마운트 했습니다.
그리고 마운트 디렉토리 안에 gv0 이라는 Brick 디렉토리를 생성해 두었습니다..
- /data/gv0

 

(gnode1 또는 gnode3 에서)

remove-brick 명령을 이용해 장애난 peer 를 replica cluster 에서 제외합니다. (replica 3 -> 2)
# gluster volume remove-brick gv0 replica 2 gnode2:/data/gv0 force
Remove-brick force will not migrate files from the removed bricks, so they will no longer be available on the volume.
Do you want to continue? (y/n) y
volume remove-brick commit force: success

 

peer 목록에서 제외합니다.
# gluster peer detach gnode2
All clients mounted through the peer which is getting detached need to be remounted using one of the other active peers in the trusted storage pool to ensure client gets notification on any changes done on the gluster configuration and if the same has been done do you want to proceed? (y/n) y
peer detach: success

볼륨 정보를 확인합니다.
# gluster volume info
 
Volume Name: gv0
Type: Replicate
Volume ID: 8e2fbb51-5f00-43f3-9d09-0655cac39dfb
Status: Started
Snapshot Count: 0
Number of Bricks: 1 x 2 = 2
Transport-type: tcp
Bricks:
Brick1: gnode1:/data/gv0
Brick2: gnode3:/data/gv0
Options Reconfigured:
performance.client-io-threads: off
nfs.disable: on
transport.address-family: inet
storage.fips-mode-rchecksum: on
cluster.granular-entry-heal: on
network.ping-timeout: 0

gnode2 라는 peer 가 cluster 에서 제거된 것이 확인되었습니다.
다시 peer 를 추가 하고 replica 3 으로 재설정하여 데이터를 동기화 합니다. 

# gluster peer probe gnode2
peer probe: success

add-brick 명령으로 새로운 노드 하나만 기입하여 replica 3 으로 재구성 합니다.
# gluster volume add-brick gv0 replica 3 gnode2:/data/gv0
volume add-brick: success

 

이렇게 작업은 마무리 되었습니다.
참고로 success 메세지가 출력되어도 데이터가 동기화 되는 것에는 시간이 걸리므로 상태를 잘 지켜보시기 바랍니다.

 

 

7. 복제 (Replica) 볼륨 확장

 

1) Replica 증설 및 축소

3개의 노드가 replica 3 으로 구성된 상태에서 노드를 한대 더 추가하여 replica 4 로 구성해보겠습니다. (replica 3 -> 4)

먼저 추가되는 노드 (gnode4) 에서 사전 작업을 해주세요.

- 추가디스크 mount (/data) 및 디렉토리 생성 (/data/gv0)

- hostname 및 hosts 설정 (기존 노드 포함)

- glusterfs 패키지 설치 및 가동

 

기존 노드 서버에서 피어를 추가하고 재구성 명령을 실행합니다.

# gluster peer probe gnode4
peer probe: success

# gluster volume add-brick gv0 replica 4 gnode4:/data/gv0
volume add-brick: success

 

볼륨 정보를 출력합니다.

# gluster volume info
 
Volume Name: gv0
Type: Replicate
Volume ID: 63328573-90cc-4272-8094-9fd7b9d74821
Status: Started
Snapshot Count: 0
Number of Bricks: 1 x 4 = 4
Transport-type: tcp
Bricks:
Brick1: gnode1:/data/gv0
Brick2: gnode2:/data/gv0
Brick3: gnode3:/data/gv0
Brick4: gnode4:/data/gv0
Options Reconfigured:
features.quota-deem-statfs: on
features.inode-quota: on
features.quota: on
cluster.granular-entry-heal: on
storage.fips-mode-rchecksum: on
transport.address-family: inet
nfs.disable: on
performance.client-io-threads: off

 

추가했던 노드를 제거하는 방법은 다음과 같습니다. (replica 4 -> 3)

# gluster volume remove-brick gv0 replica 3 gnode4:/data/gv0 force
Remove-brick force will not migrate files from the removed bricks, so they will no longer be available on the volume.
Do you want to continue? (y/n) y
volume remove-brick commit force: success

 

# gluster peer detach gnode4
All clients mounted through the peer which is getting detached need to be remounted using one of the other active peers in the trusted storage pool to ensure client gets notification on any changes done on the gluster configuration and if the same has been done do you want to proceed? (y/n) y
peer detach: success

 

볼륨 정보를 확인합니다.

# gluster volume info
 
Volume Name: gv0
Type: Replicate
Volume ID: 63328573-90cc-4272-8094-9fd7b9d74821
Status: Started
Snapshot Count: 0
Number of Bricks: 1 x 3 = 3
Transport-type: tcp
Bricks:
Brick1: gnode1:/data/gv0
Brick2: gnode2:/data/gv0
Brick3: gnode3:/data/gv0
Options Reconfigured:
features.quota-deem-statfs: on
features.inode-quota: on
features.quota: on
cluster.granular-entry-heal: on
storage.fips-mode-rchecksum: on
transport.address-family: inet
nfs.disable: on
performance.client-io-threads: off

 

2) Replica 용량 증설

replica 3 은 복제본이 3개 있다는 뜻이므로 데이터 안정성을 어느정도 확보 했다고 볼 수 있습니다. 하지만 노드의 용량이 줄어들 경우에는 또다른 노드를 마련해서 데이터 저장 공간을 확보해야 하는데요. 추가할 노드 수는 복제본 수의 배수여야 합니다. (예: replica 3 의 볼륨 확장시 3의 배수인 6, 9, 12, ... 의 개수로만 추가 가능)

추가된 노드를 GlusterFS 클러스터에 포함 시키는 방법은 아래와 같습니다.

먼저 추가되는 노드 (gnode4, gnode5, gnode6) 에서 사전 작업을 해주세요.

- 추가디스크 mount (/data) 및 디렉토리 생성 (/data/gv0)

- hostname 및 hosts 설정 (기존 노드 포함)

- glusterfs 패키지 설치 및 가동

 

그리고 기존 노드에서 peer 를 추가합니다.

# gluster peer probe gnode4

# gluster peer probe gnode5

# gluster peer probe gnode6

 

볼륨 상태를 출력하여 추가된 노드를 확인합니다.

# gluster volume status
Status of volume: gv0
Gluster process                             TCP Port  RDMA Port  Online  Pid
------------------------------------------------------------------------------
Brick gnode1:/data/gv0                      49152     0          Y       11850
Brick gnode2:/data/gv0                      49152     0          Y       9917 
Brick gnode3:/data/gv0                      49152     0          Y       29859
Self-heal Daemon on localhost               N/A       N/A        Y       12991
Quota Daemon on localhost                   N/A       N/A        Y       13185
Self-heal Daemon on gnode2                  N/A       N/A        Y       10432
Quota Daemon on gnode2                      N/A       N/A        Y       10537
Self-heal Daemon on gnode5                  N/A       N/A        Y       9175 
Quota Daemon on gnode5                      N/A       N/A        Y       9186 
Self-heal Daemon on gnode6                  N/A       N/A        Y       9173 
Quota Daemon on gnode6                      N/A       N/A        Y       9184 
Self-heal Daemon on gnode4                  N/A       N/A        Y       6471 
Quota Daemon on gnode4                      N/A       N/A        Y       6483 
Self-heal Daemon on gnode3                  N/A       N/A        Y       30817
Quota Daemon on gnode3                      N/A       N/A        Y       30979
 
Task Status of Volume gv0
------------------------------------------------------------------------------
There are no active volume tasks

 

위에서 노드가 추가되었지만 아직 Brick 사용 상태는 아닌것으로 확인됩니다.

추가한 노드에도 데이터가 쓰여질 수 있도록 볼륨을 확장해야 합니다.

이를 위해 gluster volume add-brick 명령을 사용합니다.

볼륨명과 replica 구성은 그대로 하고, 추가할 노드만 적어주면 됩니다.

# gluster volume add-brick gv0 replica 3 gnode4:/data/gv0 gnode5:/data/gv0 gnode6:/data/gv0
volume add-brick: success

 

볼륨 상태를 확인합니다.

# gluster volume info
 
Volume Name: gv0
Type: Distributed-Replicate
Volume ID: 24463284-fb20-4d4b-9d13-0b891c2f892f
Status: Started
Snapshot Count: 0
Number of Bricks: 2 x 3 = 6
Transport-type: tcp
Bricks:
Brick1: gnode1:/data/gv0
Brick2: gnode2:/data/gv0
Brick3: gnode3:/data/gv0
Brick4: gnode4:/data/gv0
Brick5: gnode5:/data/gv0
Brick6: gnode6:/data/gv0
Options Reconfigured:
features.quota-deem-statfs: on
features.inode-quota: on
features.quota: on
cluster.granular-entry-heal: on
storage.fips-mode-rchecksum: on
transport.address-family: inet
nfs.disable: on
performance.client-io-threads: off

 

'replica 3 구성이 2세트로, 총 6개의 brick 이 구성되어 있다' 라는 뜻인데 아래와 같이 Brick 상태를 보면 추가된 brick 3개는 아직 활성화되지 않은 것으로 출력됩니다.

# gluster volume status |grep Brick
Brick gnode1:/data/gv0                      49152     0          Y       30890
Brick gnode2:/data/gv0                      49152     0          Y       23376
Brick gnode3:/data/gv0                      49152     0          Y       16274
Brick gnode4:/data/gv0                      N/A       N/A        N       N/A  
Brick gnode5:/data/gv0                      N/A       N/A        N       N/A  
Brick gnode6:/data/gv0                      N/A       N/A        N       N/A 

 

볼륨을 확장 (add-brick) 하거나 축소 (remove-brick) 할 때는 서버 간에 데이터 균형을 재조정해야 하는데, 이때 필요한 패키지가 glusterfs-geo-replication 입니다. 데이터 균형을 맞추기 전에 패키지 설치를 해야합니다.

# yum -y install glusterfs-geo-replication

 

rebalance 명령으로 데이터 균형 작업을 진행합니다.

# gluster volume rebalance gv0 start
volume rebalance: gv0: success: Rebalance on gv0 has been started successfully. Use rebalance status command to check status of the rebalance process.
ID: df6c2123-04d7-4b45-9311-e05430db6cac


rebalance 상태는 다음 명령으로 확인할 수 있습니다.

status 항목에 모든 작업이 completed 된것과 volume rebalance 작업이 성공되었다는 메세지를 확인할 수 있습니다.
# gluster volume rebalance gv0 status
                                    Node Rebalanced-files          size       scanned      failures       skipped               status  run time in h:m:s
                               ---------      -----------   -----------   -----------   -----------   -----------         ------------     --------------
                                  gnode2                0        0Bytes             2             0             0            completed        0:00:00
                                  gnode3                0        0Bytes             2             0             0            completed        0:00:00
                                  gnode4                0        0Bytes             0             0             0            completed        0:00:00
                                  gnode5                0        0Bytes             1             0             0            completed        0:00:00
                                  gnode6                0        0Bytes             1             0             0            completed        0:00:00
                               localhost                0        0Bytes             2             0             0            completed        0:00:00
volume rebalance: gv0: success

 

Client 에서는 마운트 되어 있던 GlusterFS 파티션 가용 공간이 자동으로 두 배 늘어난 것이 확인됩니다.

(용량 확장 전)

# df -h
Filesystem      Size  Used Avail Use% Mounted on
devtmpfs        889M     0  889M   0% /dev
tmpfs           907M   84K  907M   1% /dev/shm
tmpfs           907M   97M  810M  11% /run
tmpfs           907M     0  907M   0% /sys/fs/cgroup
/dev/vda1        25G   17G  9.0G  65% /
tmpfs           182M     0  182M   0% /run/user/0
gnode1:/gv0      10G  135M  9.9G   2% /backup

 

(용량 확장 후)

# df -h
Filesystem      Size  Used Avail Use% Mounted on
devtmpfs        889M     0  889M   0% /dev
tmpfs           907M   84K  907M   1% /dev/shm
tmpfs           907M   97M  810M  11% /run
tmpfs           907M     0  907M   0% /sys/fs/cgroup
/dev/vda1        25G   17G  9.0G  65% /
tmpfs           182M     0  182M   0% /run/user/0
gnode1:/gv0      20G  270M   20G   2% /backup

 

* 데이터 저장 형태

데이터가 어느 노드에 어떻게 저장되는지 확인하고 싶어서 적당한 크기의 파일을 하나씩 입력해 보았고 아래 내용으로 확인되었습니다.

- 파일을 저장하면 처음 replica 3 으로 구성된 gnode1, gnode2, gnode3 노드에 데이터 저장

- 추가 파일을 저장하면 나중 replica 3 으로 구성된 gnode4, gnode5, gnode6 노드에 데이터 저장

- 디렉토리는 모든 노드에서 생성

- Client 에서는 모든 노드의 데이터가 합쳐져 보임

즉, gnode1 (또는 gnode2 또는 gnode3) 의 데이터와 gnode4 (또는 gnode5 또는 gnode6) 의 데이터를 합치면 온전한 사용자 데이터가 된다는 것을 확인하였습니다.

 

3) Replica 구성 및 볼륨 제거

볼륨을 제거하면 구성 방식 (replica, stripe 등) 정보가 같이 삭제 됩니다.

우선 마운트 되어있는 Client 에서 모두 unmount 하여 스토리지를 분리합니다.

# umount /backup

 

운영중인 볼륨을 중지합니다.

# gluster volume stop gv0
Stopping volume will make its data inaccessible. Do you want to continue? (y/n) y
volume stop: gv0: success

 

볼륨을 삭제 합니다.

gluster volume delete gv0
Deleting volume will erase all information about the volume. Do you want to continue? (y/n) y
volume delete: gv0: success

 

아직 테스트하던 peer 는 연결되어진 상태입니다. 볼륨을 재구성 할 예정이므로 peer 연결 해제 및 데이터 삭제 방법만 알아두고 넘어가기로 합니다.

* 노드 분리 방법

# gluster peer detach <노드 이름>

* 데이터 삭제 (각 노드에서 실행)

# setfattr -x trusted.glusterfs.volume-id /data/gv0
# setfattr -x trusted.gfid /data/gv0
# rm -rf /data/gv0/.glusterfs*

 

 

8. 분산 (Disperse) 볼륨 구성 - with Parity peer

 

disperse 볼륨은 데이터와 패리티를 사용하여 데이터를 분산 저장하고, 손상된 브릭의 데이터를 복구할 수 있는 내구성을 제공합니다.

RAID 시스템의 5 구성과 매우 유사한 기능을 제공하고 있어서 파일을 쓸 경우 모든 Brick 에 동시 분산 저장이 되기 때문에 파일 I/O 속도가 빠르며 peer 한 대가 다운되어도 나머지 peer 에서 데이터 조합이 가능하기 때문에 무정지 서비스가 가능합니다. 하지만 peer 두 대 이상이 다운될 경우 Client 에서는 모든 데이터를 읽지 못하게 됩니다.

그럼 disperse 형식으로 볼륨을 생성해 보겠습니다.

먼저 gnode1 노드에서 peer 를 추가 합니다.

# gluster peer probe gnode2

# gluster peer probe gnode3

 

볼륨을 생성합니다.

# gluster volume create gv0 disperse 3 gnode1:/data/gv0 gnode2:/data/gv0 gnode3:/data/gv0
volume create: gv0: success: please start the volume to access data

disperse 3 옵션은 3개의 노드 (peer) 로 분산 저장 구성한다는 의미입니다. 결국 2개의 데이터 peer 와 1개의 패리티 peer 로 자동 구성됩니다.

 

생성한 볼륨을 시작합니다.

# gluster volume start gv0
volume start: gv0: success

 

볼륨에 서버 응답 대기시간을 0초로 적용합니다.

# gluster volume set gv0 network.ping-timeout 0

volume set: success

 

볼륨 정보를 확인합니다.

# gluster volume info
 
Volume Name: gv0
Type: Disperse
Volume ID: fb35eca2-9c54-4768-9ea9-eb27c0fd223d
Status: Started
Snapshot Count: 0
Number of Bricks: 1 x (2 + 1) = 3
Transport-type: tcp
Bricks:
Brick1: gnode1:/data/gv0
Brick2: gnode2:/data/gv0
Brick3: gnode3:/data/gv0
Options Reconfigured:

network.ping-timeout: 0
storage.fips-mode-rchecksum: on
transport.address-family: inet
nfs.disable: on

 

여기에서 'Number of Bricks: 1 x (2 + 1) = 3' 를 볼 수 있는데, 위에서 설명한대로 (2 + 1) 은 2개의 데이터 Brick 과 1개의 Parity Brick 으로 구성되어 있음을 나타냅니다. 앞에 1 x 는 '이런 세트가 하나있다' 라고 이해하시면 됩니다.

Parity Brick 은 데이터 안정성을 위해 자동 생성되는 Brick 으로, 구성하는 서버 수량에 따라 아래와 같이 자동 할당 됩니다. 그리고 각각의 Brick 이 10GB 의 용량을 가지고 있을때 사용가능한 최종 데이터 저장 용량은 아래와 같습니다.

- 노드가 2개 일때 : 구성 불가. 최소한 3대가 필요합니다.

- 노드가 3개 일때 : 1 x (2 + 1) = 3  # 총 20GB

- 노드가 4개 일때 : 1 x (3 + 1) = 4  # 총 30GB

- 노드가 5개 일때 : 1 x (4 + 1) = 5  # 총 40GB

특이사항으로, 4대로 구성할때만 아래와 같은 메세지가 출력됩니다.

There isn't an optimal redundancy value for this configuration. Do you want to create the volume with redundancy 1 ? (y/n) y

 

* 데이터 저장 형태

데이터가 어느 노드에 어떻게 저장되는지 확인하고 싶어서 적당한 크기의 파일을 하나씩 입력해 보았고 아래 내용으로 확인되었습니다.

- 데이터 노드 (peer) 에 나뉘어져 저장

   > 데이터 노드가 2대 일때 : 10MB 파일 저장시 gnode1 에 5M, gnode2 에 5M 저장

   > 데이터 노드가 3대 일때 : 10MB 파일 저장시 gnode1 에 3.4M, gnode2 에 3.4M, gnode3 에 3.4M 저장

- 1대의 데이터 peer 에 저장되는 용량만큼 Parity Peer 에 저장

- 디렉토리는 모든 노드에서 생성

- 데이터 peer 에 생성되는 용량은 512 byte 단위로 생성됌

   > 이용자가 10 byte 텍스트 파일을 생성하더라도 데이터 peer 마다 512 byte 크기의 파일이 생성

   > 데이터 peer 가 2대 일때, 이용자가 1000 byte 파일을 생성한다면 각 peer 마다 512 byte 크기의 파일이, 이용자가 1200 byte 파일을 생성하면 각 peer 마다 1024 byte 크기의 파일이 생성 됌.

- peer 1대 장애 : Client 에서 데이터 및 서비스 유지 가능

- peer 2대 장애 : Client 에서 '입력/출력 오류' 상태로 빠짐. 추후 서버가 부팅되어 peer 파티션이 연결되고 glusterd 데몬이 구동되면 자동 연결 됌

 

참고로 disperse 볼륨에서는 패리티 파편을 명시적으로 지정하지 않습니다. GlusterFS 에서는 disperse 볼륨에 대한 패리티 파편의 위치를 추적하지 않습니다. 대신, disperse 볼륨은 데이터와 패리티를 조합하여 고유한 분산 방식으로 데이터를 보관합니다. 따라서, disperse 볼륨에서는 특정 peer 가 패리티 peer 인지를 명확하게 알 수 없습니다. 데이터와 패리티 파편은 모든 peer 에 균등하게 분산되므로 각 peer 는 동시에 데이터와 패리티를 저장합니다.

 

 

9. 판사 (Arbiter) 볼륨 구성

 

Arbiter 는 GlusterFS 의 Replica 구성에서 사용되는 옵션 중 하나입니다. Replica 구성은 데이터를 여러 Brick 에 복제하여 내구성과 가용성을 제공하는 방식입니다. 일반적으로 Replica 구성은 세 개의 복제 Brick 을 사용하지만, Arbiter 를 사용하면 세 번째 복제 Brick 대신에 판사 (Arbiter) Brick 을 사용합니다.
Arbiter 의 역할은 데이터의 복제를 수행하는 것이 아니라 복제 집합의 일부로서 데이터의 일관성을 유지하는 역할을 합니다. 각 복제 Brick 은 데이터를 가지고 있지만, 판사 Brick 은 실제 데이터를 저장하지 않고, 오로지 복제 그룹 내의 데이터 일관성을 확인하는 역할을 수행합니다. 따라서 Arbiter 를 사용하면 세 번째 Brick 으로 저장할 데이터 용량을 절약할 수 있습니다.
Arbiter 를 사용하는 Replica 구성은 데이터의 내구성과 가용성을 유지하면서 용량 효율성을 개선할 수 있습니다. 예를 들어, 10GB 의 데이터를 저장해야 할 때, 일반적인 Replica 구성은 3개의 10GB Brick 을 필요로 합니다. 그러나 Arbiter 를 사용하는 Replica 구성에서는 2개의 10GB Brick 과 1개의 Arbiter Brick 만으로도 같은 수준의 내구성을 제공할 수 있습니다. (Replica 2 를 구성하는 2개의 Brick 에 데이터 차이가 있어도 Arbiter 때문에 어떤게 최신 peer 인지 구분 가능)

 

gnode1 노드에서 peer 를 추가 합니다.

# gluster peer probe gnode2

# gluster peer probe gnode3

 

Arbiter 볼륨을 생성합니다.

# gluster volume create gv0 replica 2 arbiter 1 gnode1:/data/gv0 gnode2:/data/gv0 gnode3:/data/gv0
volume create: gv0: success: please start the volume to access data

 

볼륨을 시작합니다.

# gluster volume start gv0
volume start: gv0: success

 

볼륨에 서버 응답 대기시간을 0초로 적용합니다.

# gluster volume set gv0 network.ping-timeout 0

volume set: success

 

볼륨 정보를 확인합니다.

# gluster volume info
 
Volume Name: gv0
Type: Replicate
Volume ID: 2b88b6dd-c50d-4752-96fd-7acb98ce0d53
Status: Started
Snapshot Count: 0
Number of Bricks: 1 x (2 + 1) = 3
Transport-type: tcp
Bricks:
Brick1: gnode1:/data/gv0
Brick2: gnode2:/data/gv0
Brick3: gnode3:/data/gv0 (arbiter)
Options Reconfigured:

network.ping-timeout: 0
cluster.granular-entry-heal: on
storage.fips-mode-rchecksum: on
transport.address-family: inet
nfs.disable: on
performance.client-io-threads: off

 

2대의 Replica 서버와 1대의 Arbiter 서버가 구성 되었습니다.

각 peer 가 10GB 일때, Client 에서 사용 가능한 최대 용량은 10G 입니다.

 

* 데이터 저장 형태

데이터가 어느 노드에 어떻게 저장되는지 확인하고 싶어서 적당한 크기의 파일을 하나씩 입력해 보았고 아래 내용으로 확인되었습니다.

- 10MB 파일 저장시 gnode1, gnode2 에 각각 10MB 파일 생성되고 gnode3 에는 0 Byte 의 파일 생성

- 디렉토리는 모든 노드에서 생성

- peer 1대 장애 : Client 에서 데이터 및 서비스 유지 가능

- peer 2대 장애 : Client 에서 '전송 종료지점이 연결되어 있지 않습니다' 상태로 빠짐. 추후 다운되었던 Replica 서버 또는 Arbiter 서버가 1대라도 부팅되어 peer 파티션이 연결되고 glusterd 데몬이 구동되면 자동 연결 됌

 

 

10. 통합 (Distributed) 볼륨 구성

 

Distributed 는 GlusterFS 의 기본 볼륨 구성값으로써 모든 peer 의 용량을 합하여 제공되는 방식입니다. disperse 볼륨과 같이 다량의 peer 에 동시에 데이터를 읽고 쓸 수 있는 구성이 아닌, 단순히 용량만 합하여 제공하기 때문에 peer 에 순차적으로 데이터를 저장하는 특징을 보입니다. 모든 peer 에 동시에 데이터를 읽고 쓰지 않으므로 속도가 disperse 보다 빠르지 않으며 parity peer 도 없기 때문에 하나의 peer 가 다운될 경우 데이터를 읽거나 쓰지 못하는 상황이 발생되며, peer 의 서버 대수가 많이 늘어날 수록 장애가 발생할 확률도 높아지게 됩니다.

distributed 볼륨 구성을 위해 gnode1 노드에서 peer 를 추가 합니다.

# gluster peer probe gnode2

 

중간에 아무런 옵션을 주지 않으면 기본 Distributed 상태로 볼륨이 생성됩니다.

# gluster volume create gv0 gnode1:/data/gv0 gnode2:/data/gv0
volume create: gv0: success: please start the volume to access data

 

볼륨을 시작합니다.

# gluster volume start gv0
volume start: gv0: success

 

볼륨에 서버 응답 대기시간을 0초로 적용합니다.

# gluster volume set gv0 network.ping-timeout 0

volume set: success

 

볼륨 정보를 확인합니다.

# gluster volume info
 
Volume Name: gv0
Type: Distribute
Volume ID: 77a483c0-479e-4237-91af-aa76058a3f2d
Status: Started
Snapshot Count: 0
Number of Bricks: 2
Transport-type: tcp
Bricks:
Brick1: gnode1:/data/gv0
Brick2: gnode2:/data/gv0
Options Reconfigured:

network.ping-timeout: 0
storage.fips-mode-rchecksum: on
transport.address-family: inet
nfs.disable: on

 

2대의 Brick 이 Distribute 로 구성 되었습니다.

각 peer 가 10GB 일때, Client 에서 사용 가능한 최대 용량은 20G 입니다.

 

* 데이터 저장 형태

데이터가 어느 노드에 어떻게 저장되는지 확인하고 싶어서 적당한 크기의 파일을 하나씩 입력해 보았고 아래 내용으로 확인되었습니다.

- gnode1 로 마운트하고 파일 저장시 gnode1 노드에 생성되고 계속 저장시 gnode1 노드 용량 (10GB) 까지만 저장 가능

- gnode2 로 마운트하고 파일 저장시 gnode2 노드에 생성되고 계속 저장시 gnode2 노드 용량 (10GB) 까지만 저장 가능

- Client 에서는 20GB 용량으로 보이고 gnode1, gnode2 에 저장된 데이터가 모두 보임

- 디렉토리는 모든 노드에서 생성

- peer 1대 장애 : 장애난 peer 의 데이터는 보이지 않고 남아있는 peer 내의 데이터만 보임. 추후 서버가 부팅되어 peer 파티션이 연결되고 glusterd 데몬이 구동되면 모든 파일들이 잘 보이게 됌

 

 

11. NFS 서비스 제공하기 (with NFS-Ganesha) --- 작성중

 

GlusterFS 를 일반적인 fuse 형식이 아닌 NFS 형식으로 마운트 할 수 있게 기능을 제공합니다.

볼륨 정보를 보면 아래와 같은 nfs 기본 옵션이 출력됩니다.

# gluster volume info
 
Volume Name: gv0
Type: Replicate
Volume ID: 563a8023-dc1c-4b2d-a86c-af8dcf21c5da
Status: Started
Snapshot Count: 0
Number of Bricks: 1 x 3 = 3
Transport-type: tcp
Bricks:
Brick1: gnode1:/data/gv0
Brick2: gnode2:/data/gv0
Brick3: gnode3:/data/gv0
Options Reconfigured:
cluster.granular-entry-heal: on
storage.fips-mode-rchecksum: on
transport.address-family: inet
nfs.disable: on
performance.client-io-threads: off

 

여기에서 NFS 를 사용하지 않는 옵션이 켜져 (on) 있습니다. 이것을 off 하고 몇가지 설정을 더 하면, GlusterFS 에서 제공하는 NFS 서버를 사용할 수 있습니다. 하지만 GlusterFS 에서 제공하는 NFS 서버 방식은 NFSv3 이고, 요새는 NFSv4 를 지원하는 NFS-Ganesha 가 별도 배포되고 있습니다. NFS-Ganesha 는 GlusterFS 와의 통합을 용이하게 하기 위해 개발된 것으로 기존의 GlusterFS NFS 서버 대신 NFS-Ganesha 를 사용하면 GlusterFS 와 NFS 간의 상호 운용성이 향상되고 다양한 기능과 유연성을 제공할 수 있습니다.
- 다양한 NFS 버전 지원 : NFSv3, NFSv4, NFSv4.1 및 NFSv4.2 를 지원하므로 다양한 클라이언트와의 상호 운용성이 높아집니다.
- 고급 기능 : 파일 시스템 관리, 보안, 액세스 제어, 성능 튜닝 등의 고급 기능을 제공합니다.
- 확장성 : 다중 프로토콜 지원, 클러스터링, 로드 밸런싱 등의 기능을 통해 GlusterFS 클러스터의 확장성을 향상시킵니다.
- 유연한 구성 : 다양한 구성 옵션과 플러그인 아키텍처를 제공하여 사용자의 요구에 맞게 유연하게 구성할 수 있습니다.

 

이러한 이유로 NFS-Ganesha 를 이용해 GlusterFS 의 NFS 서비스를 구성해 보겠습니다.

 

1) 설치

(모든 노드에서)

# yum -y install centos-release-nfs-ganesha30
# sed -i -e "s/enabled=1/enabled=0/g" /etc/yum.repos.d/CentOS-NFS-Ganesha-30.repo
# yum --enablerepo=centos-nfs-ganesha30 -y install nfs-ganesha-gluster

 

기본 설정 파일은 별도로 백업해놓고 새로운 설정을 추가 합니다.

# mv /etc/ganesha/ganesha.conf /etc/ganesha/ganesha.conf.ori
# vi /etc/ganesha/ganesha.conf

NFS_CORE_PARAM {
    mount_path_pseudo = true; # 가상 경로 사용 여부
    Protocols = 4;                       # 제공할 NFS 프로토콜 버전
}
EXPORT_DEFAULTS {
    Squash = "No_root_squash"; # Client 가 root 면 root 권한으로 파일 액세스 가능하도록
    FSAL {
        name = GLUSTER;     # 이름
        hostname = "gnode1"; # 현재 노드의 호스트명 또는 IP 주소
        volume = "gv0";           # GlusterFS 볼륨명
    }
}
EXPORT {
    Export_Id = 1;             # Client 식별자 : uniq ID (No)
    Path = "/data/gv0";      # GlusterFS 볼륨 마운트 경로 (여기에서는 최상위 디렉토리 제한) 
    Pseudo = "/gv0";         # 가상 경로 (마운트할때 명시되는 이름)
    Access_Type = None; # 접근 형식 (None : 접근불가, RO : 읽기전용, RW : 읽고쓰기)
}
EXPORT {
    Export_Id = 2;
    Path = "/data/gv0/apple";
    Pseudo = "/apple";
    Access_Type = RW;
}
LOG {
    Default_Log_Level = WARN; # 기본 로그 레벨
}

 

데몬 부팅 설정과 함께 데몬을 시작합니다.

# systemctl enable --now nfs-ganesha

 

서비스 포트 열린것이 확인되었습니다.

# netstat -nltp |grep ganesha
tcp6       0      0 :::875                  :::*                    LISTEN      18997/ganesha.nfsd  
tcp6       0      0 :::2049                 :::*                    LISTEN      18997/ganesha.nfsd 

 

2) Client 에서 마운트하기

마운트 하려는 디렉토리를 생성합니다.

# mkdir /backup

 

볼륨 전체는 마운트가 안되고,

# mount -t nfs gnode1:/gv0 /backup

 

하위 디렉토리는 마운트 가능합니다.

# mount -t nfs gnode1:/gv0/apple /backup

 

 

반응형

댓글()

Rocky Linux 9 에서 iSCSI 서비스 구축하기

리눅스/OS 일반|2023. 6. 2. 14:10
반응형

iSCSI 는 서버 간에 SCSI 명령을 TCP/IP 네트워크를 통해 전송하기 위한 프로토콜입니다. 이를 통해 원격 스토리지 장치에 접근하여 데이터를 전송하고 저장할 수 있습니다. iSCSI는 LAN 또는 WAN 을 통해 스토리지 리소스를 공유하고, 데이터 센터에서 스토리지 자원을 효율적으로 활용할 수 있도록 도와줍니다. iscsi-initiator (client) 와 target (server or storage) 간의 설정을 통해 iSCSI 를 사용하여 스토리지를 관리하고 데이터를 전송할 수 있습니다.

본 매뉴얼은 Rocky Linux 9 환경 (IP : 192.168.10.2) 에서 테스트 후 작성되었습니다.

 

 

1. iSCSI 서버 설치

 

1) targetcli 패키지 설치

targetcli 패키지를 설치합니다.

# dnf -y install targetcli

 

서버 부팅시 데몬이 자동으로 실행될 수 있도록 하고, 현재 세션에서도 데몬을 가동 시킵니다.

# systemctl enable target
# systemctl start target

 

이미지 파일이 저장될 디렉토리를 생성합니다.

볼륨이 큰 파티션이나 추가 장치를 마운트 해서 연결해도 됩니다.

# mkdir /storage

 

2) iSCSI target 만들기

targetcli 에 진입하면 IQN, LUN 등의 생성 및 관리 작업을 할 수 있습니다.

# targetcli
Warning: Could not load preferences file /root/.targetcli/prefs.bin.
targetcli shell version 2.1.53
Copyright 2011-2013 by Datera, Inc and others.
For help on commands, type 'help'.

/> 

 

targetcli 에 진입하면 위와 같이 Warning 메세지를 볼 수 있는데, 별도의 사용자 환경 설정 파일을 생성하지 않아서 로드하지 못했다는 경고 메세지 입니다. 이 메시지는 문제를 일으키지 않으며, targetcli 의 기능에 지장을 주지 않습니다.

다음과 같이 1G 짜리 저장소 파일 (taget) 을 생성합니다.

형식) backstores/fileio create <backstore_fileio_이름> <이미지파일_전체_경로> <용량> <기록 방식>

/> backstores/fileio create disk01 /storage/1GB_image.img 1G write_back=false

Created fileio disk01 with size 1073741824

 

[ 스토리지 개체 생성 방식 ]

위 예시에서 이미 fileio 타입으로 파일을 생성했지만, 스토리지 개체를 생성하는 방식에는 두가지가 있으며 차이점은 아래와 같습니다.
- backstores/fileio : 파일을 사용하여 스토리지를 제공합니다. 이 방법은 이미지 파일이나 기존 파일 시스템을 사용하여 스토리지를 만들 수 있습니다. 파일 시스템 이미지 파일을 사용하면 가상의 블록 디바이스가 생성되어 iSCSI 타겟에 연결될 수 있습니다.
- backstores/block : 블록 장치 (파티션) 를 사용하여 스토리지를 제공합니다. 실제 블록 장치 (예: 하드 디스크) 나 루프백 장치를 사용하여 스토리지를 만들 수 있습니다. 블록 백스토어를 사용하면 블록 디바이스가 직접 iSCSI 타겟에 연결될 수 있습니다.

 

[ 쓰기 방식 ]

- write_back=true : 데이터를 메모리에 캐시한 후 비동기적으로 디스크에 기록합니다. 이는 성능을 향상시킬 수 있는 방식이지만, 시스템이 갑작스럽게 종료되는 경우 데이터 손실의 위험성이 있습니다.
- write_back=false : 데이터를 직접 디스크에 기록하며, 동기적인 방식으로 수행됩니다. 데이터의 일관성과 안정성이 보장됩니다. 그러나 성능은 약간 저하될 수 있습니다.

 

3) IQN 설정

IQN 은 반드시 형식에 맞게 작성해주어야 합니다.

형식) iqn.<연도>-<월>.<도메인 이름 역순>:<고유 이름>

/> iscsi/ create iqn.2023-06.kr.sysdocu:target01

Created target iqn.2023-06.kr.sysdocu:target01.
Created TPG 1.
Global pref auto_add_default_portal=true
Created default portal listening on all IPs (0.0.0.0), port 3260.

 

4) LUN 만들기

LUN (Logical Unit Number) 은 iSCSI target 에 연결된 논리적인 디스크 단위입니다.

LUN 을 만들기 위해 다음과 같이 명령을 실행합니다.

/> iscsi/iqn.2023-06.kr.sysdocu:target01/tpg1/luns create /backstores/fileio/disk01

Created LUN 0.

 

위 명령어는 target01 이라는 IQN 을 가진 target 의 TPG (Target Portal Group) 1 에 LUN 을 생성하고, 해당 LUN 을 /backstores/fileio/disk01 에 연결한다는 의미입니다.

 

5) IQN 의 ACL 생성

IQN ACL 을 생성하여 iSCSI 대상에 대한 액세스를 허용할 IQN 식별자를 명시적으로 지정합니다.

/> iscsi/iqn.2023-06.kr.sysdocu:target01/tpg1/acls create iqn.2023-06.kr.sysdocu:initiator01
Created Node ACL for iqn.2023-06.kr.sysdocu:initiator01
Created mapped LUN 0.

 

6) 계정 생성

target 에 계정을 생성하여 접근을 강화 할 수 있습니다.

본 항목을 건너뛰어도 Client 에서 마운트 가능하지만, Openshift 등 필요로 하는 곳이 있습니다.

계정 생성을 위해 target 의 initiator 로 이동합니다.

/> cd iscsi/iqn.2023-06.kr.sysdocu:target01/tpg1/acls/iqn.2023-06.kr.sysdocu:initiator01/

 

계정과 패스워드를 설정합니다.

/iscsi/iqn.20...u:initiator01> set auth userid=sysdocu
Parameter userid is now 'sysdocu'.
/iscsi/iqn.20...u:initiator01> set auth password=12345678
Parameter password is now '12345678'.

 

설정된 정보를 확인합니다.

/iscsi/iqn.20...u:initiator01> info
chap_password: 12345678
chap_userid: sysdocu
wwns:
iqn.2023-06.kr.sysdocu:initiator01

 

7) 정보 확인 및 저장

다음 명령어를 사용하여 생성한 IQN 과 LUN 정보를 확인할 수 있습니다.

/> ls iscsi/iqn.2023-06.kr.sysdocu:target01/tpg1/luns
o- luns .................................................................................................................. [LUNs: 1]
  o- lun0 .............................................................. [fileio/disk01 (/storage/1GB_image.img) (default_tg_pt_gp)]

 

그리고 exit 명령을 이용해 현재 상태를 저장하고 targetcli 를 빠져나갈 수 있습니다.

/> exit
Global pref auto_save_on_exit=true
Configuration saved to /etc/target/saveconfig.json

 

 

2. Client 에서 마운트 하기

 

1) client 패키지 설치

# yum install iscsi-initiator-utils  // CentOS

# apt-get install open-iscsi         // Ubuntu

 

2) iSCSI 시작

아래 파일에 IQN ACL 이름을 작성합니다.

# vi /etc/iscsi/initiatorname.iscsi

InitiatorName=iqn.2023-06.kr.sysdocu:initiator01

 

iscsi 와 iscsid 데몬이 시스템 부팅시 자동 구동되게 설정하고 현재 세션에서도 구동 합니다.

# systemctl enable iscsi

# systemctl enable iscsid

# systemctl start iscsi

# systemctl start iscsid

 

추후에 /etc/iscsi/initiatorname.iscsi 파일이 변경된 경우 iscsid 데몬을 재시작 해주어야 합니다.

 

3) Target 검색 및 연결

연결할 iSCSI Target 을 검색합니다.

# iscsiadm -m discovery -t st -p 192.168.10.2
192.168.10.2:3260,1 iqn.2023-06.kr.sysdocu:target01

 

iSCSI 장치를 연결합니다.

# iscsiadm -m node -T iqn.2023-06.kr.sysdocu:target01 -p 192.168.10.2:3260 -l

 

연결된 장치를 확인합니다.

# fdisk -l

...

Disk /dev/sda: 1 GiB, 1073741824 bytes, 2097152 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 8388608 bytes

 

4) 해제 방법

사용을 하지 않을때 해제하는 방법은 아래와 같습니다.

연결 명령 마지막 옵션 l 을 u 로만 바꾸면 됩니다.

# iscsiadm -m node -T iqn.2023-06.kr.sysdocu:target01 -p 192.168.10.2:3260 -u

 

반응형

댓글()

정규표현식 연속된 문자 검색

프로그래밍/BASH SHELL|2023. 6. 2. 08:16
반응형

시스템 운영을하며 많이 접하는 명령이 grep 이기도 한데 구체적인 문자열 검색을 위해 정규표현식이 사용됩니다.

어떤 행에서 '몇개의 숫자, 점, 몇개의 숫자' 로 이루어진 문자열은 아래와 같이 출력합니다.

 

grep '[0-9]*[.][0-9]*'

 

 

반응형

댓글()

[Openshift] 웹 UI 대시보드 Grafana 설치

리눅스/OpenShift|2023. 5. 26. 09:20
반응형

본 매뉴얼은 '[Openshift] 미터링 도구 Prometheus + AlertManager 알람' 에 이어서 작성되었습니다.

 

1. Grafana 설치

Grafana 는 수집한 metrics 값을 보기좋게 시각화 해주는 웹 GUI 환경의 대시보드 입니다.

아래 파일을 생성하고 적용해 줍니다.

 

# vi grafana.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: grafana
  namespace: monitoring
spec:
  replicas: 1
  selector:
    matchLabels:
      app: grafana
  template:
    metadata:
      name: grafana
      labels:
        app: grafana
    spec:
      securityContext:
        seccompProfile:
          type: RuntimeDefault
      containers:
      - name: grafana
        image: grafana/grafana:latest
        ports:
        - name: grafana
          containerPort: 3000
        env:
        - name: GF_SERVER_HTTP_PORT
          value: "3000"
        - name: GF_AUTH_BASIC_ENABLED
          value: "false"
        - name: GF_AUTH_ANONYMOUS_ENABLED
          value: "true"
        - name: GF_AUTH_ANONYMOUS_ORG_ROLE
          value: Admin
        - name: GF_SERVER_ROOT_URL
          value: /
        securityContext:
          allowPrivilegeEscalation: false
          capabilities:
            drop: ["ALL"]
          runAsNonRoot: true
---
apiVersion: v1
kind: Service
metadata:
  name: grafana
  namespace: monitoring
  annotations:
      prometheus.io/scrape: 'true'
      prometheus.io/port:   '3000'
spec:
  selector:
    app: grafana
  type: NodePort
  ports:
    - port: 3000
      targetPort: 3000
      nodePort: 30004

 

# oc apply -f grafana.yaml

deployment.apps/grafana created
service/grafana created

 

Grafana 의 호스트명을 확인하고 30004 포트를 이용하여 웹 GUI 환경으로 접속합니다.

# oc get pod -n monitoring -o wide
NAME                                     READY   STATUS    RESTARTS   AGE     IP             NODE                    NOMINATED NODE   READINESS GATES
alertmanager-689f68c448-88v92            1/1     Running   0          3d3h    10.128.2.254   worker01.az1.sysdocu.kr   <none>           <none>
grafana-577cc7fbdd-rdtcc                 1/1     Running   0          3m55s   10.128.3.41    worker01.az1.sysdocu.kr   <none>           <none>
node-exporter-57djp                      1/1     Running   0          8d      10.131.0.184   worker02.az1.sysdocu.kr   <none>           <none>
node-exporter-w5s8d                      1/1     Running   0          8d      10.128.2.239   worker01.az1.sysdocu.kr   <none>           <none>
prometheus-deployment-859bc6d5c7-mjhvk   1/1     Running   0          25m     10.128.3.37    worker01.az1.sysdocu.kr   <none>           <none>

 

웹브라우저 접속 URL :http://worker01.az1.sysdocu.kr:30004

 

2. Prometheus 연동 (데이터 추가)

Prometheus 에 수집된 데이터를 가져와 그래프로 그려보도록 합니다.

 

좌측 상단 토글 메뉴 > Administration > Data sources > [Add data source] > Prometheus 선택

 

HTTP 의 URL 항목에 입력해야 할 정보는 아래 명령으로 확인이 가능합니다.

# oc get service -n monitoring
NAME                 TYPE       CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
alertmanager         NodePort   172.30.25.192    <none>        9093:30005/TCP   7d19h
grafana              NodePort   172.30.24.162    <none>        3000:30004/TCP   18m
node-exporter        NodePort   172.30.65.240    <none>        9100:31672/TCP   8d
prometheus-service   NodePort   172.30.191.143   <none>        8080:30003/TCP   59m

 

URL 항목에 http://172.30.191.143:8080 이라고 입력하고 페이지 맨 아래 'Save & test' 버튼을 눌러 저장합니다.

Grafana 에서 Prometheus 데이터를 가져오도록 설정하였습니다.

 

3. 템플릿 적용

연동된 Prometheus 데이터를 PromQL 쿼리로 디자인해야 하는데, 손이 많이 가므로 Grafana 사이트에서 공유하고 있는 템플릿을 가져와 적용 시켜봅니다.

 

(Grafana 홈페이지에서)

대시보드 페이지 접속 https://grafana.com/grafana/dashboards/ > 페이지 가운데 'Search dashboards' 에 'kubernetes' 입력 및 검색 > 원하는 템플릿 클릭 > 'Download JSON' 선택하고 다운로드 받은 JSON 파일의 내용을 '전체 복사' 해둡니다.

 

(Grafana 설치 페이지에서)

좌측 상단 토글 메뉴 > Dashboards 선택 > 좌측 풀다운 메뉴 [New] 를 클릭으로 펼쳐서 'Import' 선택 > 중간에 'Import via panel json' 입력란에 붙여넣기 (Ctrl + V) 및 [Load] 클릭 > 맨 아래 'Select a Prometheus data source' 에서 Prometheus (default) 선택 후 [Import] 클릭

 

초기화면으로 자동 이동되면서 예쁜 템플릿으로 구성된 대시보드를 볼 수 있습니다.

반응형

댓글()

[OC & Kubernetes] Kubernetes 관리도구 helm 3.12 설치하기

리눅스/OpenShift|2023. 5. 19. 15:02
반응형

helm 은 OC 또는 Kubernetes 클러스터에서 Kubernetes 애플리케이션을 관리하기 위한 패키지 관리 도구입니다.

helm 설치 방법은 다음과 같습니다.

helm 공식 웹사이트에서 운영 체제에 맞는 helm 바이너리 파일을 다운로드합니다.

다음 링크를 사용하면 최신 버전의 helm을 다운로드할 수 있습니다.

URL : https://github.com/helm/helm/releases

페이지 중간부에 Download 섹션이 있고, 64bit 리눅스 OS 를 사용하기 때문에 'Linux arm64' 항목의 주소를 복사하여 리눅스 쉘에서 다운로드 하였습니다.

# wget https://get.helm.sh/helm-v3.12.0-linux-amd64.tar.gz

# tar xvzf helm-v3.12.0-linux-amd64.tar.gz

 

실행파일을 PATH 경로에 포함된 디렉토리로 이동시킵니다.

# mv linux-amd64/helm /usr/local/bin/

 

버전을 확인합니다.

# helm version

WARNING: Kubernetes configuration file is group-readable. This is insecure. Location: /root/installation_directory/auth/kubeconfig
version.BuildInfo{Version:"v3.12.0", GitCommit:"c9f554d75773799f72ceef38c51210f1842a1dea", GitTreeState:"clean", GoVersion:"go1.20.3"}

 

반응형

댓글()

Rocky Linux 8 에서 Ceph 17 (Quincy) 설치하기

리눅스/Ceph|2023. 5. 15. 17:02
반응형

여기에서는 Rocky Linux 8 환경에서 Ceph 17.x (Quincy) 버전을 설치하는 방법을 기술하였습니다.

Ceph 는 역할에 따라 MON, OSD, MDS 서버 등 여러대로 나뉘어 운영되므로, 각각의 역할이 이해 된다면 프로젝트에 맞는 적절한 구성을 직접 구현하는것이 좋습니다. 서비스에 적용하실 분은 데이터 망실 방지 또는 무정지 시스템 구축을 목적으로 반드시 이중화 구성을 권장합니다.

 

- MON (Ceph monitor) : 클러스터의 모든 노드 상태를 추적하는 클러스터 모니터 서버입니다.
- OSD (Object Storage Device) : 데이터를 저장하고 클라이언트 요청을 처리하는 서버입니다.
- MDS (Metadata Server Daemon) : 메타데이터 서버입니다. CephFS 파일 시스템 작동에 사용됩니다.

 

 

[테스트 환경]

- H/W : CPU 2 Core & 메모리 4GB

- OS : Rocky Linux 8

- 추가 Disk : 50GB

* 이 구성으로 서버 3대를 준비하였습니다.

 

 

1. 설치

 

1) 환경 업데이트

(모든 서버에서)

# dnf -y update

# dnf -y upgrade

 

2) 호스트명 설정

서버에서 사용할 호스트명을 설정해줍니다.

(모든 서버에서)

# vi /etc/hosts

127.0.0.1 localhost
10.101.0.8 ceph-1
10.101.0.12 ceph-2
10.101.0.22 ceph-3

 

# hostnamectl set-hostname ceph-1    // ceph-1 서버에서

# hostnamectl set-hostname ceph-2    // ceph-2 서버에서

# hostnamectl set-hostname ceph-3    // ceph-3 서버에서

 

3) SSH key copy

(ceph-1 서버에서)

# ssh-keygen    // 패스워드 없이 생성

# ssh-copy-id ceph-1

# ssh-copy-id ceph-2

# ssh-copy-id ceph-3

 

4) chrony 설치

(모든 서버에서)

# dnf -y install chrony

# systemctl enable --now chronyd

 

5) Python 설치

(모든 서버에서)

# dnf -y install python39
# python3 --version

Python 3.9.16

 

6) Podman 설치

(모든 서버에서)

# dnf -y install podman
# podman -v

podman version 4.4.1

 

7) cephadm 설치
클러스터를 생성하고 구성하는데 사용할 cephadm 도구를 설치합니다.

(모든 서버에서)
# curl --silent --remote-name --location https://github.com/ceph/ceph/raw/quincy/src/cephadm/cephadm
# chmod +x cephadm
# ./cephadm add-repo --release quincy
# ./cephadm install

Ceph 클러스터를 만들기 위해 cephadm 부트스트랩이 사용됩니다.

이 명령어는 지정된 노드에서 Ceph 서비스와 첫 번째 모니터를 시작하고 클러스터를 만들고 키, 구성 파일 등을 생성합니다.

 

모니터 데몬을 생성합니다. 명령 실행시 모니터 데몬이 생성될 서버의 IP 를 기입해줍니다.

만약, OSD 간 복제 트래픽을 위해 별도의 네트워크를 사용하고자 하는 경우 아래와 같은 옵션을 같이 사용하시기 바랍니다.

--cluster-network 192.168.1.0/24

(ceph-1 서버에서)

# cephadm bootstrap --mon-ip 10.101.0.8

...

Ceph Dashboard is now available at:
      URL: https://ceph-1:8443/
      User: admin
      Password: vqyeyu0il6

...

 

설치가 완료되면 위와 같이 Ceph 대시보드 접속 정보가 출력됩니다.

웹브라우저를 이용하여 접속, 로그인을 하면 관리 페이지가 잘 출력되는 것을 확인할 수 있습니다.

처음 로그인시 패스워드를 변경하는 절차가 있고, 로그인을 다시 하면 대시보드에 접속 됩니다.

대시보드가 설치 되었지만 앞으로의 설정과 사용 방법은 CLI 환경에서 이어 나가도록 하겠습니다.

 

8) ceph-common 설치

설치된 cephadm 파일로 ceph-common 패키지 설치를 이어갑니다.

(모든 서버에서)

# cephadm install ceph-common

 

설치된 버전을 확인합니다.

# ceph -v
ceph version 17.2.6 (d7ff0d10654d2280e08f1ab989c7cdf3064446a5) quincy (stable)

 

관리 작업에 첫 번째 노드를 사용하므로 SSH 키를 설치하고 나머지 노드의 /etc/ceph 에 배치해야 합니다.

(ceph-1 서버에서)
# ssh-copy-id -f -i /etc/ceph/ceph.pub root@ceph-2
# ssh-copy-id -f -i /etc/ceph/ceph.pub root@ceph-3

 

Ceph 클러스터에 호스트를 추가 합니다.
# ceph orch host add ceph-2

Added host 'ceph-2' with addr '10.101.0.12'
# ceph orch host add ceph-3

Added host 'ceph-3' with addr '10.101.0.22'

 

호스트 목록을 확인합니다.
# ceph orch host ls

HOST    ADDR         LABELS  STATUS  
ceph-1  10.101.0.8   _admin          
ceph-2  10.101.0.12                  
ceph-3  10.101.0.22                  
3 hosts in cluster

 

Ceph Monitor 데몬은 클러스터 구성원 자격, 구성 및 상태에 대한 매우 안정적이고 지속적인 저장을 제공하기 위하여 모든 노드에 MON 역할을 부여합니다.

# ceph orch apply mon --placement="ceph-1,ceph-2,ceph-3"

 

Ceph Manager 데몬은 모니터 데몬과 함께 실행되어 외부 모니터링 및 관리 시스템에 추가적인 모니터링 및 인터페이스를 제공합니다.

역시 모든 노드에 MGR 역할을 부여합니다.

# ceph orch apply mgr --placement="ceph-1,ceph-2,ceph-3"

 

CephRBD 뿐 아니라 CephFS 도 사용하기 위해 MDS 를 생성합니다. 미리 모든 노드에 MDS 역할을 부여 합니다.

여기에서는 파일시스템을 식별하기 위해 myfs 라는 이름으로 생성 하였습니다.

# ceph orch apply mds myfs --placement="ceph-1,ceph-2,ceph-3"

 

OSD 저장소를 추가 합니다. Ceph 저장에 사용할 수 있는 디스크를 하나씩 추가해 줍니다.

형식) # ceph orch daemon add osd {호스트명}:{디스크},{디스크},...

# ceph orch daemon add osd ceph-1:/dev/vdb
# ceph orch daemon add osd ceph-2:/dev/vdb
# ceph orch daemon add osd ceph-3:/dev/vdb

 

Ceph 및 OSD 상태를 확인합니다.

# ceph -s

  cluster:
    id:     17bddd2a-5b78-11ee-b774-fa163ed3a133
    health: HEALTH_OK
 
  services:
    mon: 3 daemons, quorum ceph-1,ceph-3,ceph-2 (age 14h)
    mgr: ceph-1.ieznfl(active, since 14h), standbys: ceph-3.hfrlpp, ceph-2.vgyqhd
    osd: 3 osds: 3 up (since 13h), 3 in (since 13h)
 
  data:
    pools:   1 pools, 1 pgs
    objects: 2 objects, 449 KiB
    usage:   63 MiB used, 150 GiB / 150 GiB avail
    pgs:     1 active+clean

 

# ceph osd tree

ID  CLASS  WEIGHT   TYPE NAME        STATUS  REWEIGHT  PRI-AFF
-1         0.14639  root default                              
-3         0.04880      host ceph-1                           
 0    hdd  0.04880          osd.0        up   1.00000  1.00000
-5         0.04880      host ceph-2                           
 1    hdd  0.04880          osd.1        up   1.00000  1.00000
-7         0.04880      host ceph-3                           
 2    hdd  0.04880          osd.2        up   1.00000  1.00000

 

9) 라벨링

호스트에 라벨 할당하는 것을 지원합니다. 라벨은 자유 형식이며 그 자체로는 특별한 의미가 없습니다.

각 호스트는 여러 개의 라벨을 가질 수 있으므로 데몬의 배치를 기록해 두는데 사용하면 편리합니다.
# ceph orch host label add ceph-1 osd
# ceph orch host label add ceph-2 osd
# ceph orch host label add ceph-3 osd
# ceph orch host label add ceph-1 mon
# ceph orch host label add ceph-2 mon
# ceph orch host label add ceph-3 mon
# ceph orch host label add ceph-1 mgr
# ceph orch host label add ceph-2 mgr
# ceph orch host label add ceph-3 mgr

 

* 참고 : 라벨 삭제는 add 대신 rm 옵션 사용

 

전체 라벨을 확인합니다.

# ceph orch host ls
HOST    ADDR         LABELS              STATUS  
ceph-1  10.101.0.8   _admin osd mon mgr          
ceph-2  10.101.0.12  osd mon mgr                 
ceph-3  10.101.0.22  osd mon mgr                 
3 hosts in cluster

 

 

2. 설정

 

1) Pool 생성

Pool 은 데이터를 저장하고 관리하는 논리적인 저장 공간을 나타내며, Pool 안에 여러개의 블록 레벨 스토리지 이미지를 생성할 수 있으므로 그룹이라고 생각해도 좋습니다. Pool 생성 및 삭제에 관한 기본 명령은 아래와 같습니다.

- 생성 : ceph osd pool create {pool-name} {pg-num} {pgp-num}

- 확인 : ceph osd lspools

- 데이터 복사 : rados cppool {old-pool-name} {new-pool-name}    // 새로운 Pool 생성 후 데이터 복사 가능

- 삭제 : ceph osd pool delete {pool-name} {pool-name} --yes-i-really-really-mean-it    // 하단 선행작업 필요

- 이름 변경 : ceph osd pool rename {old-pool-name} {new-pool-name}

- 제한 : ceph osd pool set-quota {pool-name} max_bytes {limit-size}    // 예 : 10G (제한 해제값 : 0)

- 제한 확인 : ceph osd pool get-quota {pool-name}

 

* 삭제시 선행작업

pool 삭제시 그 안에 생성한 여러 volume 들은 함께 삭제가 됩니다.

이와 같이 실수로 삭제하는것을 방지하기 위하여 pool 이름을 두 번 쓰고, 명령을 인지하고 있다는 옵션 (문장) 도 적어줘야 합니다. 그리고 사전 작업으로 아래 옵션을 적용하고 삭제 명령을 실행해야 합니다.

# ceph config set mon mon_allow_pool_delete true

삭제 이후에는 다른 실수가 없도록 다시 delete 명령을 비활성화 합니다.

# ceph config set mon mon_allow_pool_delete false

 

Pool 생성시 기본 pg_num 을 정하는 기준은 아래를 권장합니다.

(참고 : 2016년도에 기록한 내용으로 사용)
- OSD 가 5개 미만일 경우 pg_num 128
- 5~10 개는 pg_num 512
- 10~50 개는 pg_num 4096 이 적절 합니다.
- 50개 이상은 pgcalc 계산을 참조하여 설정하면 됩니다.

Pool 이름은 sysdocu 로 하고, 준비된 OSD 개수가 3개 였으므로, pg_num 을 128 로 설정하여 진행할 것입니다.

pgp-num 은 생략하겠습니다.
# ceph osd pool create sysdocu 128
pool 'sysdocu' created

 

2) CephRBD 이미지 생성

블록 레벨 스토리지 이미지를 생성합니다.

# rbd create sysdocu/volume01 --size 1G --image-feature layering

 

생성된 볼륨 리스트를 확인합니다.

# rbd ls sysdocu
volume01

 

하나의 볼륨 정보를 확인하는 방법은 아래와 같습니다.

# rbd info sysdocu/volume01
rbd image 'volume01':
size 1 GiB in 256 objects
order 22 (4 MiB objects)
snapshot_count: 0
id: 5e94b120cbea
block_name_prefix: rbd_data.5e94b120cbea
format: 2
features: layering
op_features: 
flags: 
create_timestamp: Tue Sep 26 07:40:53 2023
access_timestamp: Tue Sep 26 07:40:53 2023
modify_timestamp: Tue Sep 26 07:40:53 2023

 

참고로, 아래는 볼륨 삭제하는 명령 형식입니다.

# rbd rm {pool-name}/{volume-name}

 

3) CephFS 생성

파일시스템으로 사용 가능한 CephFS 를 생성합니다.

아래와 같이 실행시 자동으로 MDS 가 구동됩니다.

# ceph fs volume create myfs

* MDS 상태 확인
# ceph -s
또는
# ceph orch ls

* CephFS 리스트 확인
# ceph fs ls
name: myfs, metadata pool: cephfs.myfs.meta, data pools: [cephfs.myfs.data ]
또는
# ceph mds stat
myfs:1 {0=myfs.ceph-2.bmzpdd=up:active} 1 up:standby

 

반응형

댓글()

[참고] Openshift 에서 PV 에 연결된 PVC 정보 확인 및 PV 삭제하기

리눅스/OpenShift|2023. 5. 11. 08:48
반응형

다음과 같이 출력되는 PV 를 삭제하려고 합니다.

# oc get pv
NAME         CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS        CLAIM                    STORAGECLASS   REASON   AGE
pv-example   1Gi        RWO            Retain           Terminating   project412/pvc-example   standard                17h

 

PV 를 삭제할때 아래와 같이 메세지 출력 후 한참동안 쉘 프롬프트가 출력되지 않는다면

# oc delete pv pv-example
persistentvolume "pv-example" deleted

 


^C[root@ocp ~]# 

 

연결된 PVC 정보를 확인해봐야 합니다.

# oc get pv pv-example -o jsonpath='{.spec.claimRef.name}' | xargs -n1 oc get pvc
NAME          STATUS   VOLUME       CAPACITY   ACCESS MODES   STORAGECLASS   AGE
pvc-example   Bound    pv-example   1Gi        RWO            standard       17h

 

연결된 PVC 가 확인되어 삭제를 선진행하고 PV 를 삭제하면 깔끔히 제거됩니다.

# oc delete pvc pvc-example
persistentvolumeclaim "pvc-example" deleted

 

# oc delete pv pv-example
persistentvolume "pv-example" deleted

 

반응형

댓글()