[Kubernetes Configmap] 컨피그맵이란? (1)
목차 컨피그맵(Configmap) 컨피그맵 생성 kubectl create configmap으로 생성 파일 내용으로 컨피그맵 생성 디렉터리에 있는 파일로 컨피그맵 생성 다양한 옵션 결합 컨피그맵 항목을 환경변수로 컨테이너에 전달 파드에 존재하지 않는 컨피그맵 참조한다면? 컨피그맵의 모든 항목을 한 번에 환경변수로 전달 컨피그맵 항목을 명령줄 인자로 전달 컨피그맵(Configmap) ConfigMap은 Kubernetes에서 사용되는 리소스로, key-value 쌍으로 비민감성 구성 데이터를 저장하는 데 사용됩니다. 이를 사용하면 구성 정보를 컨테이너 이미지에서 분리하여 응용 프로그램을 더 이식성이 좋고 유지 관리가 용이하며 관리가 쉬워집니다. ConfigMap은 응용 프로그램에서 필요한 구성 파일, 환경..
2023.04.16
[Kubernetes] 2. 도커 컨테이너 환경 변수 설정
목차 환경변수로 이미지 안에 간격 설정 컨테이너 정의에 환경변수 지정 변숫값에서 다른 환경변수 참조 하드코딩된 환경변수의 단점 환경변수로 이미지 안에 간격 설정 컨테이너화된 애플리케이션은 종종 환경변수를 설정 옵션의 소스로 사용합니다. 쿠버네티스는 파드의 각 컨테이너를 위한 환경변수 리스트를 지정할 수 있습니다. 파드 수준에서 환경변수를 설정하고 컨테이너에서 상속받는 것도 유용하지만 안타깝게도 이러한 옵션은 지원하지 않습니다. 컨테이너 명령이나 인자와 마찬가지로 환경변수 목록또한 파드 생성 후에는 업데이트할 수 없다는 점도 명심해야 합니다. fortuneloop.sh 스크립트를 다음 예제처럼 수정해서 환경변수로 애플리케이션을 설정하는 방법을 살펴봅시다. #!/bin/bash trap "exit" SIGI..
2023.04.16
[Kubernetes] 1. 도커 컨테이너 명령줄(command line) 인자 설정법
목차 들어가며 도커에서 명령어와 인자 정의 shell과 exec 형식 간의 차이점 fortune 이미지에서 간격을 설정할 수 있도록 만들기 쿠버네티스에서 명령과 인자 재정의 사용자 정의 주기로 fortune 파드 실행 쿠버네티스 컨피그맵과 시크릿을 다루기 전에 일반적으로 컨테이너화된 애플리케이션이 어떻게 구성되는지 살펴보려고 합니다. 이번 포스팅과 다음 포스팅에서는 컨테이너에 명령줄 인자를 전달하고 환경변수 설정에 대해 다뤄보도록 하겠습니다. 이전 쿠버네티스 포스팅들에서 컨테이너 이미지에 정의된 기본 명령을 실행하는 컨테이너를 만들었지만, 쿠버네티스는 파드 컨테이너 정의에 지정된 실행 명령 대신 다른 실행파일을 실행하거나 다른 명령줄 인자를 사용해 실행하는 것이 가능합니다. 어떻게 하는지 살펴보겠습니다...
2023.04.16
[Kubernetes Volume] 6. 프로비저닝(Provisioner)의 정의와 스토리지 클래스(StorageClass)
목차 프로비저닝(provisioning)이란? 퍼시스턴트볼륨의 동적 프로비저닝 스토리지클래스 리소스를 통한 스토리지 유형 정의 퍼시스턴트볼륨클레임에서 스토리지 클래스 요청 동적 프로비저닝된 PV와 생성된 PVC 검사하기 다른 클러스터에도 동일하게 적용하기 스토리지 클래스 조회하기 기본 스토리지 클래스 확인하기 스토리지 클래스를 지정하지 않고 PVC 생성하기 퍼시스턴트볼륨클레임을 미리 프로비저닝된 퍼시스턴트볼륨으로 바인딩 강제화하기 프로비저닝(provisioning)이란? 쿠버네티스에서 프로비저닝은 일반적으로 저장소와 관련하여 특정 애플리케이션이나 서비스의 요구 사항을 충족시키기 위해 필요한 저장소 자원을 할당하고 구성하는 과정을 의미합니다. 때문에 이번 Volume을 다루는 과정에서 많이 언급되었었죠. ..
2023.04.15
no image
[Kubernetes Volume] 5. 기반 스토리지 기술과 파드 분리(PV, PVC)
목차 들어가며 PV, PCV 원리 퍼시스턴트볼륨(PV) 생성 퍼시스턴트볼륨클레임(PVC) 생성 PVC, PV 조회 파드에서 퍼시스턴트볼륨클레임 사용 PV, PCV 장점 퍼시스턴트볼륨 재사용 들어가며 지금까지 살펴본 모든 퍼시스턴트 볼륨 유형은 파드 개발자가 실제 네트워크 스토리지 인프라스트럭처에 관한 지식을 갖추고 있어야 합니다. NFS 기반의 볼륨을 생성하려면 개발자는 NFS 익스포트가 위치하는 실제 서버를 알아야 합니다. 이는 인프라스트럭처의 세부 사항 에 대한 걱정을 없애고, 클라우드 공급자나 온프레미스 데이터센터를 걸쳐 이식 가능한 애플리케이션을 만들고, 애플리케이션과 개발자로부터 실제 인프라스트럭처를 숨긴다는 쿠 버네티스의 기본 아이디어에 반합니다. 이상적으로는 쿠버네티스에 애플리케이션을 배포하..
2023.04.14
[Kubernetes Volume] 4. 퍼시스턴트 스토리지(Persistent storage)와 사용법
목차 퍼시스턴트 스토리지 GCE 퍼시스턴트 디스크 생성하기 GCE 퍼시스턴트 디스크 볼륨을 사용하는 파드 생성 데이터베이스에 도큐먼트를 추가해 퍼시스턴트 스토리지에 데이터 쓰기 파드를 다시 생성하도 이전 데이터를 읽을 수 있는지 확인 다른 유형의 볼륨 사용 NFS 볼륨 사용 다른 스토리지 기술 사용 퍼시스턴트 스토리지 퍼시스턴트 스토리지는 개별 컨테이너, Pod 또는 Kubernetes 클러스터의 노드 수명 주기를 넘어서 데이터가 지속적으로 유지되는 저장소 솔루션을 의미합니다. 컨테이너나 Pod가 종료되거나 다시 생성되더라도 상태, 구성 파일 또는 유지해야하는 기타 데이터를 저장해야하는 애플리케이션에 필수적인 요소입니다. 이전에 다루었던 볼륨들은 파드에서 실행 중인 애플리케이션이 디스크에 데이터를 유지해..
2023.04.14
반응형

목차

  1. 컨피그맵(Configmap)
  2. 컨피그맵 생성
    • kubectl create configmap으로 생성
    • 파일 내용으로 컨피그맵 생성
    • 디렉터리에 있는 파일로 컨피그맵 생성
    • 다양한 옵션 결합
  3. 컨피그맵 항목을 환경변수로 컨테이너에 전달
  4. 파드에 존재하지 않는 컨피그맵 참조한다면?
  5. 컨피그맵의 모든 항목을 한 번에 환경변수로 전달
  6. 컨피그맵 항목을 명령줄 인자로 전달

컨피그맵(Configmap)

ConfigMap은 Kubernetes에서 사용되는 리소스로, key-value 쌍으로 비민감성 구성 데이터를 저장하는 데 사용됩니다. 이를 사용하면 구성 정보를 컨테이너 이미지에서 분리하여 응용 프로그램을 더 이식성이 좋고 유지 관리가 용이하며 관리가 쉬워집니다. ConfigMap은 응용 프로그램에서 필요한 구성 파일, 환경 변수 또는 다른 구성 데이터를 저장하는 데 사용할 수 있습니다.

ConfigMap을 사용하면 컨테이너 이미지를 다시 빌드하거나 재배포하지 않고도 구성 데이터를 쉽게 업데이트하고 수정할 수 있습니다. 즉, 애플리케이션은 컨피그맵을 직접 읽거나 심지어 존재하는 것을 몰라도 됩니다. 대신 맵 의 내용은 컨테이너의 환경변수 또는 볼륨 파일로 전달됩니다. 또한 환경변수는 $(ENV_VAR) 구문을 사용해 명령줄 인수에서 참조할 수 있기 때문에, 컨피그맵 항목을 프로세스의 명령 줄 인자로 전달할 수도 있습니다.

 

애플리케이션은 필요한 경우 쿠버네티스 REST API 엔드포인트를 통해 컨피그맵의 내 용을 직접 읽을 수 있지만, 반드시 필요한 경우가 아니라면 애플리케이션은 쿠버네티스와는 무관하도록 유지해야 합니다.

 

애플리케이션이 컨피그맵을 사용하는 방법에 관계없이, 별도의 독립적인 오브젝트에 설정을 포함하면 각각 다른 환경(개발, 테스트, QA, 프로덕션 등)에 관해 동일한 이름으로 컨 피그맵에 관한 여러 매니페스트를 유지할 수 있습니다. 파드는 컨피그맵을 이름으로 참조하기 때문에, 모든 환경에서 동일한 파드 정의를 사용해 각 환경에서 서로 다른 설정을 사용할 수 있습니다.


컨피그맵 생성

앞에서 만든 파드에 컨피그맵을 사용하는 방법을 알아봅시다. 가장 간단한 예제로, 단일 키를 가진 맵을 생성하고 이를 사용해 이전 예제의 INTERVAL 환경변수를 채워 넣는 것입니다. kubectl create -f 명령어로 YAML 파일을 게시하는 대신에 kubectl create configmap 명령으로 컨피그맵을 생성할 수 있습니다.


1. kubectl create configmap으로 생성

문자열 literal 값을 kubectl 명령에 전달하거나 디스크에 저장된 파일에서 컨피그맵을 정의할 수 있습니다. 이 때 컨피그맵 키는 유효한 DNS 서브도메인(subdomain)이어야 합니다(영숫자, 대시, 밑줄, 점만 포함 가능). 필요한 경우 점이 먼저 나올 수 있습니다. 이제 간단한 문자열을 이용해봅시다.

$ kubectl create configmap fortune-config --from-literal=sleep-interval=25
configmap "fortune-config" created

 

위 명령을 통해 sleep-interval=25라는 단일 항목을 가진 fortune-config 컨피그맵 을 생성합니다. 컨피그맵은 일반적으로 두 개 이상의 항목을 포함합니다. 여러 문자열 항목을 가진 컨피 그맵을 생성하려면 여러 개의 --from-literal 인자를 추가합니다.

 

$ kubectl create configmap myconfigmap --from-literal=foo=bar --from-literal=bar=baz --from-literal=one=two

 

앞에서 생성한 컨피그맵을 kubectl get 명령으로 YAML 정의를 출력해 살펴봅시다.

$ kubectl get configmap fortune-config -o yaml

apiVersion: v1
data:
  sleep-interval: "25"               <  이 맵의 단일 항목
kind: ConfigMap                     <  이 디스크립터는 컨피그맵을 설명합니다.
metadata:
  creationTimestamp: 2016-08-11T20:31:08Z3000ging steans d
  name: fortune-config             <  이 맵의 이름(해당 이름으로 참조)
  namespace: default
  resourceVersion: "910025"
  selfLink: /api/v1/namespaces/default/configmaps/fortune-config
  uid: 88c4167e-6002-11e6-a50d-42010af00237

특별한 것 없으므로 이 YAML 파일을 쉽게 작성할 수 있을 것입니다. 여기서 메타데이터(metadata) 섹션에 name을 뺀 나머지를 지정할 필요는 없습니다. 그리고 이 파일을 쿠버네티스 API에 게시합니다.

 

$ kubectl create -f fortune-config.yaml


2. 파일 내용으로 컨피그맵 생성

 

컨피그맵에는 전체 설정 파일 같은 데이터를 통째로 저장하는 것도 가능합니다. kubectl create configmap 명령을 이용해 파일을 디스크에서 읽어 개별 항목으로 저장할 수 있습니다.

 

$ kubectl create configmap my-config --from-file=config-file.conf

 

앞의 명령을 실행하면, kubectl을 실행한 디렉터리에서 config-file.conf 파일을 찾습니다. 그리고 파일 내용을 컨피그맵의 config-file.conf 키 값으로 저장합니다. 물론 키 이름을 직접 지정할 수도 있습니다.

 

$ kubectl create configmap my-config --from-file=customkey=config-file.conf

 

이 명령은 파일 내용을 customkey라는 키 값으로 저장합니다. --from-file 인수를 여러 번 사용해 여러 파일을 추가할 수 있습니다.


3. 디렉터리에 있는 파일로 컨피그맵 생성

각 파일을 개별적으로 추가하는 대신, 디렉터리 안에 있는 모든 파일을 가져올 수도 있습니다.

 

$ kubectl create configmap my-config --from-file=/path/to/dir :qm6329mino1690

 

이 명령에서 kubectl은 지정한 디렉터리 안에 있는 각 파일을 개별 항목으로 작성한 다. 이때 파일 이름이 컨피그맵 키로 사용하기에 유효한 파일만 추가합니다.


4. 다양한 옵션 결합

컨피그맵을 생성할 때 여기에서 언급한 모든 옵션을 조합해 사용할 수 있습니다(이 파일들은 책 코드 저장소에 포함돼 있지 않습니다. 명령어를 시도해보려면 직접 작성해야 합니다).

 

$ kubectl create configmap my-config

  • --from-file=foo.json: 단일 파일
  • --from-file=bar=foobar.conf: 사용자 정의 키 밑에 파일 저장 
  • --from-file=config-opts/: 전체 디렉터리
  • --from-literal-some=thing: 문자열 값

컨피그맵 항목을 환경변수로 컨테이너에 전달

이렇게 생성한 맵의 값을 어떻게 파드 안의 컨테이너로 전달할 수 있을까? 여기에는 세 가지 옵션이 있습니다. 가장 간단한 환경변수를 설정하는 것부터 시작하자. 이를 위해서 valueFrom 필드를 사용합니다. 파드 정의는 다음 예제와 비슷할 것입니다.

apiVersion: v1
kind: Pod
metadata:
  name: fortune-env-from-configmap
spec:
  containers:
  - image: luksa/fortune:env
    env:                                   <     INTERVAL 환경변수를 설정하는 중
    - name: INTERVAL
      valueFrom:                         <  고정 값을 설정하는 대신 컨피그맵 키에서 값을 가져와 초기화합니다.
        configMapKeyRef:
          name: fortune-config      <  참조하는 컨피그맵 이름
          key: sleep-interval               < 컨피그맵에서 해당 키 아래에 저장된 값으로 변수 설정

INTERVAL 환경변수를 선언하고 fortune-config 컨피그맵에 안에 있는 sleep-interval 키를 이용해 가져온 값으로 설정했습니다. html-generator 컨테이너 안에서 실행 중 인 프로세스는 INTERVAL 환경변수를 읽을 때 25를 가져옵니다.


파드에 존재하지 않는 컨피그맵 참조한다면?

파드를 생성할 때 존재하지 않는 컨피그맵을 지정하면 어떻게 되는지 궁금할 것입니다. 쿠버 네티스는 파드를 스케줄링하고 그 안에 있는 컨테이너를 실행하려고 시도합니다. 컨테이너가 존재하지 않는 컨피그맵을 참조하려고 하면 컨테이너는 시작하는 데 실패합니다. 하지만 참조하지 않는 다른 컨테이너는 정상적으로 시작됩니다. 그런 다음 누락된 컨피그맵을 생성 하면 실패했던 컨테이너는 파드를 다시 만들지 않아도 시작됩니다.

 

매니페스트에 config MapKeyRef.optional: true로 지정하면 컨피그맵 참조를 옵션으로 표시할 수도 있습니다. 이런 경우에는 컨피그맵이 존재하지 않아도 컨테이너는 시작합니다. 


컨피그맵의 모든 항목을 한 번에 환경변수로 전달

컨피그맵에 여러 항목이 포함돼 있을 때 각 항목을 일일이 환경변수로 생성하는 일은 지루하고 오류가 발생하기 쉽습니다. 다행히 쿠버네티스 버전 1.6부터는 컨피그맵의 모든 항목을 환경변수로 노출하는 방법을 제공합니다.

 

FOO, BAR, FOO-BAR라는 세 개의 키를 갖고 있는 컨피그맵을 생각해봅시다. 이전 예제에 서 사용한 env 속성 대신 envFrom 속성을 사용해 환경변수로 모두 노출할 수 있습니다. 다음 예제에서 그 내용을 보여줍니다.

spec:
  containers:
  - image: some-image
    envFrom:                                >   env대신 envFrom 사용
    - prefix: CONFIG_                >  모든 환경변수는 CONFIG_ 접두사를 가짐
      configMapRef:                        >  my-config-map이란 이름의 컨피그맵 참조
        name: my-config-map

위와 같이 환경변수 앞에 붙을 접두사를 지정할 수 있습니다(여기에서는 CONFIG). 이 때 접두사는 선택 사항이고 이를 생략하면 환경변수의 이름은 키와 동일한 이름을 갖게 됩니다. 결과적으로 이 컨테이너 안에는 두 개의 환경변수가 존재하게 됩니다. 바로 CONFIG_FOO와 CONFIG_BAR입니다. 

 

앞에서 두 개의 변수가 있습니다고 얘기했지만, 이 컨피그맵은 세 개의 항목(FOO, BAR, FOO- BAR)을 가지고 있다고도 말했습니다. 컨피그맵에 있는 FOO-BAR 항목은 왜 환경변수로 존재하지 않을까요?

 

CONFIG_FOO-BAR는 대시dash를 가지고 있어 올바른 환경변수 이름이 아니기 때문입니다. 이런 경우에 쿠버네티스는 어떤 형태로든 임의로 키로 변환하지 않습니다(예를 들자면 대시를 밑 줄로 변환하지 않습니다). 컨피그맵의 키가 올바른 형식이 아닌 경우 항목을 건너뜁니다(단, 건너뛰 었다는 것을 알려주는 이벤트가 기록됩니다).


컨피그맵 항목을 명령줄 인자로 전달

이제 컨피그맵 값을 컨테이너 안에서 실행되는 프로세스의 인자로 전달하는 방법을 살펴 봅시다. pod.spec.containers.args 필드에서 직접 컨피그맵 항목을 참조할 수는 없지만 컨피그맵 항목을 환경변수로 먼저 초기화하고 이 변수를 인자로 참조하도록 지정할 수 있습니다.

 

다음 예제는 YAML 안에서 이 작업을 수행하는 예를 보여줍니다.

apiVersion: v1
kind: Pod
metadata:
  name: fortune-args-from-configmap
spec:
  containers:
  - image: luksa/fortune:args    > 환경변수가 아닌 첫 번째 인자에서 간격(interval)을 가져오는 이미지 사용
    env:                                                  >  컨피그맵에서 환경변수 정의
    - name: INTERVAL
      valueFrom:
        configMapKeyRef:
          name: fortune-config
          key: sleep-interval
    args: ["$(INTERVAL)"]          >  인자에 앞에서 정의한 환경변수 지정

앞에서 한 것과 동일하게 환경변수를 정의했지만 $(ENVARIABLENAME) 문법을 사용해 쿠버네티스가 해당 변수의 값을 인자에 주입합니다.


configmap 내용이 많아서 나머지는 다음 포스팅에 마저 올리도록 하겠습니다!

 

 

반응형
반응형

목차

  1. 환경변수로 이미지 안에 간격 설정
  2. 컨테이너 정의에 환경변수 지정
  3. 변숫값에서 다른 환경변수 참조
  4. 하드코딩된 환경변수의 단점

 

환경변수로 이미지 안에 간격 설정

컨테이너화된 애플리케이션은 종종 환경변수를 설정 옵션의 소스로 사용합니다. 쿠버네티스는 파드의 각 컨테이너를 위한 환경변수 리스트를 지정할 수 있습니다. 파드 수준에서 환경변수를 설정하고 컨테이너에서 상속받는 것도 유용하지만 안타깝게도 이러한 옵션은 지원하지 않습니다. 컨테이너 명령이나 인자와 마찬가지로 환경변수 목록또한 파드 생성 후에는 업데이트할 수 없다는 점도 명심해야 합니다.

 

fortuneloop.sh 스크립트를 다음 예제처럼 수정해서 환경변수로 애플리케이션을 설정하는 방법을 살펴봅시다.

#!/bin/bash
trap "exit" SIGINT
echo Configured to generate new fortune every $INTERVAL seconds
mkdir -p /var/htdocs
while :
do
    echo $(date) Writing fortune to/var/htdocs/index.html
    /usr/games/fortune>/var/htdocs/index.html
    sleep $INTERVAL
done

INTERVAL 변수를 초기화하는 행을 제거하면 됩니다. 파드의 애플리케이션app은 간단한 bash 스크립트이기 때문에 다른 작업을 할 필요가 없습니다. 애플리케이션이 자바로 작성된 경 우에는 System.getenv("INTERVAL"), NodeJS로 작성된 경우에는 process.env.INTERVAL, 파이썬으로 작성된 경우에는 os.environ['INTERVAL']을 사용하면 됩니다.


컨테이너 정의에 환경변수 지정

새로운 이미지(luksa/fortune: env 태그를 붙인 이미지)를 생성한 뒤에 도커 허브로 푸시한 후, 새 파드를 만들 때 예제 7.6처럼 환경변수를 컨테이너 정의에 포함해 스크립트에 전달할 수 있습니다.

kind: Pod
spec:
  containers:
  - image: luksa/fortune:env
    env:                                                     >  환경변수 목록에 단일 변수 추가
    - name: INTERVAL
      value: "30"
    name: html-generator
...

이 때 환경변수는 파드 레벨이 아닌 컨테이너 정의 안에 설정합니다. 각 컨테이너를 설정할 때, 쿠버네티스는 자동으로 동일한 네임스페이스에 안에 있는 각 서 비스에 환경변수를 노출합니다는 것을 잊지 말아야 합니다. 이러한 환경변수는 기본적으로 자동 주입식 (auto-injected) 설정입니다.


변숫값에서 다른 환경변수 참조

이전 예에서는 환경변수에 고정 값을 설정했지만, $(VAR) 구문을 사용해 이미 정의된 환경변수나 기타 기존 변수를 참조할 수도 있습니다. 두 개의 환경변수를 정의할 때, 두 번째 환경변수는 다음 예제와 같이 첫 번째 변숫값을 포함할 수 있습니다.

env:
- name: FIRST_VAR
  value: "foo"
- name: SECOND_VAR
  value: "$(FIRST_VAR)bar"

이 경우 SECOND_VAR의 값은 "foobar"가 됩니다. 마찬가지로 이전 포스팅에서 다룬 command와 args 속성 모두 이렇게 환경변수를 참조할 수 있습니다. 이후 컨피그맵을 다룰 때에도 이 방법을 알려드릴 것입니다.


하드코딩된 환경변수의 단점

파드 정의에 하드코딩된 값을 가져오는 것은 효율적이지만, 이는 프로덕션과 개발을 위해 서로 분리된 파드 정의가 필요하다는 것을 뜻합니다. 여러 환경에서 동일한 파드 정의를 재사용하려면 파드 정의에서 설정을 분리하는 것이 좋습니다. 다행히 컨피그맵 리소스를 이런 목적으로 사용할 수 있고, value 필드 대신 valueFrom으로 환경변수값의 원본 소스로 사용할 수 있습니다.

 

반응형
반응형

목차

  1. 들어가며
  2. 도커에서 명령어와 인자 정의
  3. shell과 exec 형식 간의 차이점
  4. fortune 이미지에서 간격을 설정할 수 있도록 만들기
  5. 쿠버네티스에서 명령과 인자 재정의
  6. 사용자 정의 주기로 fortune 파드 실행

쿠버네티스 컨피그맵과 시크릿을 다루기 전에 일반적으로 컨테이너화된 애플리케이션이 어떻게 구성되는지 살펴보려고 합니다. 이번 포스팅과 다음 포스팅에서는 컨테이너에 명령줄 인자를 전달하고 환경변수 설정에 대해 다뤄보도록 하겠습니다.

 

이전 쿠버네티스 포스팅들에서 컨테이너 이미지에 정의된 기본 명령을 실행하는 컨테이너를 만들었지만, 쿠버네티스는 파드 컨테이너 정의에 지정된 실행 명령 대신 다른 실행파일을 실행하거나 다른 명령줄 인자를 사용해 실행하는 것이 가능합니다. 어떻게 하는지 살펴보겠습니다.


도커에서 명령어와 인자 정의

가장 먼저 설명해야 할 것은 컨테이너에서 실행하는 전체 명령이 명령어와 인자의 두 부분으로 구성돼 있다는 것입니다.

Dockerfile에서 두 부분은 다음과 같습니다.

 

  • ENTRYPOINT: 컨테이너가 시작될 때 호출될 명령어를 정의합니다.
  • CMD: ENTRYPOINT에 전달되는 인자를 정의합니다.

 

CMD 명령어를 사용해 이미지가 실행될 때 실행할 명령어를 지정할 수 있지만, 올바른 방법은 ENTRYPOINT 명령어로 실행하고 기본 인자를 정의하려는 경우에만 CMD를 지정하는 것입니다. 그러면 아무런 인자도 지정하지 않고 이미지를 실행할 수 있습니다.

 

$ docker run <image>

 

또는 추가 인자를 지정해 Dockerfile 안의 CMD에 정의된 값을 재정의합니다.

 

$ docker run <image> <arguments>


shell과 exec 형식 간의 차이점

두 명령어는 두 가지 서로 다른 형식을 지원합니다.

 

  • shell 형식 - 예: ENTRYPOINT node app.js
  • exec 형식 - 예: ENTRYPOINT ["node", "app.js"]

차이점은 내부에서 정의된 명령을 셸shell로 호출하는지 여부입니다. 

 

ENTRYPOINT ["node", "app.js"]

 

이렇게 하면 셸 내부가 아닌 컨테이너 내부에서 node 프로세스를 직접 실행합니다. 컨테이너 내부에서 실행 중인 프로세스 목록을 나열해 직접 실행된 것을 볼 수 있울 것입니다. 해당 명령어는 아래와 같습니다.

 

$ docker exec 4675d ps x
PID  TTY      STAT     TIME COMMAND
 1        ?         Ss1       0:00  node app.js
...

 

만약 shell 형식(ENTRYPOINT node app.js)을 사용했을 경우 컨테이너의 프로세스 목록 출력하는 명령어는 아래와 같습니다.

 

$ docker exec -it e4bad ps x
PID  TTY      STAT     TIME COMMAND
 1        ?         Ss        0:00  /bin/sh -c node app.js
 7        ?         S1        0:00  node app.js
...

위 예시에서 볼 수 있는 것처럼 메인 프로세스(PID 1)는 node 프로세스가 아닌 shell 프로세스입니다. 노드 프로세스(PID 7)는 shell에서 시작됩니다. shell 프로세스는 불필요하므로 ENTRYPOINT 명령에서 exec 형식을 사용해 실행합니다.


fortune 이미지에서 간격을 설정할 수 있도록 만들기

fortune 스크립트와 이미지에서 반복하는 주기를 변경할 수 있도록 수정해보겠습니다. INTERVAL변수를 추가하고 첫 번째 명령줄 인자의 값으로 초기화합니다.

#!/bin/bash
trap "exit" SIGINT
INTERVAL=$1
echo Configured to generate new fortune every $INTERVAL seconds
mkdir -p /var/htdocs
while :
do
    echo $(date) Writing fortune to /var/htdocs/index.html
    /usr/games/fortune>/var/htdocs/index.html
    sleep $INTERVAL
done

추가하거나 수정한줄을 굵은 글꼴로 표시했습니다. Dockerfile을 수정해 exec 버전 ENTRY POINT 명령을 사용하도록 하고 기본 간격으로 10초를 CMD 명령으로 지정합니다.

FROM ubuntu:latest
RUN apt-get update; apt-get-y install fortune
ADD fortuneloop.sh /bin/fortuneloop.sh
ENTRYPOINT ["/bin/fortuneloop.sh"]                 <  exec 형태의 ETNRYPOINT 명령
CMD ["10"]                                                          <  실행할 때 사용할 기본 인자

이제 이미지를 빌드하고 도커 허브에 푸시할 수 있습니다. 이번에는 이미지 태그를 latest 대신 args로 지정합니다.

 

$ docker build -t docker.io/luksa/fortune:args .    < 늘 강조하지만 빌드할 때 마지막에 .(온점)도 꼭 붙여 주셔야 합니다.

$ docker push docker.io/luksa/fortune:args

 

로컬에서 도커로 이미지를 실행해 테스트할 수 있습니다.

 

$ docker run -it docker.io/luksa/fortune:args

Configured to generate new fortune every 10 seconds

Fri May 19 10:39:44 UTC 2017 Writing fortune to /var/htdocs/index.html

  

또한 기본 sleep 시간 간격을 인자로 전달해 재정의할 수 있습니다.

 

$ docker run -it docker.io/luksa/fortune: args 15

Configured to generate new fortune every 15 seconds

 

이미지가 전달된 인자를 제대로 가져온 것을 확인했으니, 파드에서 이 인자들을 어떻 게 사용하는지 알아보겠습니다.


쿠버네티스에서 명령과 인자 재정의

쿠버네티스에서 컨테이너를 정의할 때, ENTRYPOINT와 CMD 둘 다 재정의할 수 있습니다. 그러기 위해 다음과 같이 컨테이너 정의 안에 command와 args 속성을 지정합니다. 이 때 command와 args 필드는 파드 생성 이후에 업데이트할 수 없다는 점을 주의해서 잘 작성해주어야 합니다.

kind: Pod
spec:
  containers:
  - image: some/image
    command: ["/bin/command"]
    args: ["arg1", "arg2", "arg3"]

대부분 사용자 정의 인자만 지정하고 명령을 재정의하는 경우는 거의 없습니다(ENTRYPOINT 를 정의하지 않는 busybox와 같은 범용 이미지는 제외).

 

두 개의 Dockerfile 명령과 그에 상응하는 파드 사양 필드는 아래 표에 정리했습니다.

도커 쿠버네티스 설명
ENTRYPOINT command 컨테이너 안에서 실행되는 실행 파일
CMD args 실행파일에 전달되는 인자

사용자 정의 주기로 fortune 파드 실행

fortune 파드를 사용자 정의 지연 간격으로 실행하려면 이름을 변경해 복사하고 다음 예제와 같이 수정합니다. 이름을 정의하실 때에는 fortune-pod.yaml이나 fortune-pod-args.yaml처럼 어떤 역할인지 이름을 명시하는 것이 좋습니다. 실제 업무를 진행할 때 작업을 혼자한다면 스스로 편하게 이름을 정해 사용하면 되지만 보통은 그렇지는 않을 것이고, 누군가에게 인수인계 해야할 상황이 올 수 있습니다. 때문에 이름은 세밀하고 어떤 역할인지 누가봐도 구분이 가능하게 해주면 좋습니다. 물론, 이름을 지정하는 법같은게 있는 것은 아닙니다. 사담은 여기까지하고 예제로 넘어가 봅시다.

 

해당 예제는 이 페이지에서 작성된 emptyDir 파드 생성 YAML을 기반으로 합니다.

apiVersion: v1
kind: Pod
metadata:
  name: fortune2s                      <  파드 이름 변경
spec:
  containers:
  - image: luksa/fortune:args      <  fortune:latest 대신에 fortune:args 이미지 사용
    args: ["2"]                                <  스크립트가 2초마다 새로운 fortune 메시지를 생성하도록 인자 지정
    name: html-generator
    volumeMounts:
    - name: html
      mountPath: /var/htdocs
...

 

컨테이너 정의에 args 배열을 추가했다. 파드를 생성하고 실행하면 배열 값들이 컨테이너에 명령줄 인자로 전달됩니다. 위 목록에서 사용한 배열 표기법은 하나 혹은 몇 개의 인자를 가진 경우 유용합니다. 여러 인자를 가졌을 때는 다음 표기법을 사용할 수 있습니다.

args:
- foo
- bar
- "15"

이 때 문자열 값을 따옴표로 묶을 필요는 없자만 숫자일 경우는 묶어야 합니다.

 

 

반응형
반응형

목차

  1. 프로비저닝(provisioning)이란?
  2. 퍼시스턴트볼륨의 동적 프로비저닝
  3. 스토리지클래스 리소스를 통한 스토리지 유형 정의
  4. 퍼시스턴트볼륨클레임에서 스토리지 클래스 요청
  5. 동적 프로비저닝된 PV와 생성된 PVC 검사하기
  6. 다른 클러스터에도 동일하게 적용하기
  7. 스토리지 클래스 조회하기
  8. 기본 스토리지 클래스 확인하기
  9. 스토리지 클래스를 지정하지 않고 PVC 생성하기
  10. 퍼시스턴트볼륨클레임을 미리 프로비저닝된 퍼시스턴트볼륨으로 바인딩 강제화하기

프로비저닝(provisioning)이란?

쿠버네티스에서 프로비저닝은 일반적으로 저장소와 관련하여 특정 애플리케이션이나 서비스의 요구 사항을 충족시키기 위해 필요한 저장소 자원을 할당하고 구성하는 과정을 의미합니다. 때문에 이번 Volume을 다루는 과정에서 많이 언급되었었죠. 쿠버네티스에서는 두 가지 유형의 프로비저닝이 있습니다. 이번 포스팅에서는 이 2가지 중 동적 포스팅을 위주로 다뤄보겠습니다.

  1. 정적 프로비저닝(Static Provisioning)
    정적 프로비저닝에서는 클러스터 관리자가 수동으로 Persistent Volume(PV)을 생성하며, 해당 PV의 용량, 액세스 모드 및 저장소 유형과 같은 하위 저장소의 세부 정보를 지정합니다. 이러한 PV는 사용자가 생성하는 Persistent Volume Claim(PVC)에서 요청될 수 있습니다. 사용자가 PVC를 생성하면 쿠버네티스는 해당 PVC의 요구 사항과 일치하는 사용 가능한 PV에 바인딩합니다.

  2. 동적 프로비저닝(Dynamic Provisioning)
    동적 프로비저닝에서는 PVC 요청에 대한 PV를 자동으로 생성하는 과정을 자동화합니다. 클러스터 관리자는 PV 생성을 위한 템플릿인 StorageClass를 정의합니다. 각 StorageClass는 PV를 생성하는 책임이 있는 프로비저너(Provisioner)를 지정합니다. 사용자가 특정 StorageClass를 참조하는 PVC를 생성하면 프로비저너는 PVC의 요구 사항과 일치하는 PV를 자동으로 생성하여 클러스터 관리자의 수동 개입을 없애줍니다.

퍼시스턴트볼륨의 동적 프로비저닝

이전 포스팅에서 퍼시스턴트볼륨(PV)과 퍼시스턴트볼륨클레임(PVC)을 사용함으로써 개발자가 내부적으로 사용된 실제 스토리지 기술을 처리할 필요 없이 얼마나 쉽게 퍼시스턴트 스토리지를 사용 할 수 있는지 살펴봤습니다. 그러나 클러스터 관리자는 실제 스토리지를 미리 프로비저 닝해둬야 합니다. 다행히 쿠버네티스는 퍼시스턴트볼륨의 동적 프로비저닝을 통해 이 작업을 자동으로 수행할 수 있습니다.

 

클러스터 관리자가 퍼시스턴트볼륨을 생성하는 대신 퍼시스턴트볼륨 프로비저너를 배포하고 사용자가 선택 가능한 퍼시스턴트볼륨의 타입을 하나 이상의 스토리지클래스 Storage Class 오브젝트로 정의할 수 있습니다. 사용자가 퍼시스턴트볼륨클레임에서 스토리지 클래스를 참조하면 프로비저너(provisioner)가 퍼시스턴트 스토리지를 프로비저닝할 때 이를 처리합니다. 퍼시스턴트볼륨과 비슷하게 스토리지클래스 리소스도 네임스페이스에 속하지 않습니다.

 

쿠버네티스는 대부분 인기 있는 클라우드 공급자의 프로비저너를 포함하므로 관리자가 항상 프로비저너를 배포하지 않아도 된다는 장점이 있습니다. 그러나 온-프레미스에 배포된 쿠버네티스는 사용자 정의 프로비저너가 배포돼야 합니다.

 

관리자가 많은 퍼시스턴트볼륨을 미리 프로비저닝하는 대신 하나 혹은 그 이상의 스토 리지클래스를 정의하면 시스템은 누군가 퍼시스턴트볼륨클레임을 통해 요청 시 새로운 퍼시스턴트볼륨을 생성합니다. 가장 큰 장점은 퍼시스턴트볼륨이 부족할 일이 없다는 것입니다. 물론, 스토리지 용량은 부족할 수 있습니다.


스토리지클래스 리소스를 통한 스토리지 유형 정의

사용자가 퍼시스턴트볼륨클레임을 생성하면 결과적으로 새로운 퍼시스턴트볼륨이 프로비저닝되므로 관리자는 하나 혹은 그 이상의 스토리지클래스 리소스를 생성해야 합니다.

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: fast
provisioner: kubernetes.io/gce-pd       >  퍼시스턴트볼륨 프로비저닝을 위해사용되는 볼륨 플러그인입니다.
parameters:
  type: pd-ssd                                       >  이런 파라미터가프로비저너로 전달됩니다.
  zone: europe-west1-b

스토리지클래스 리소스는 퍼시스턴트볼륨클레임이 스토리지클래스에 요청할 때 어떤 프로비저너가 퍼시스턴트볼륨을 프로비저닝하는 데 사용돼야 할지를 지정합니다. 스토리지 클래스에 정의된 파라미터들은 프로비저너에 전달되며, 파라미터는 각 프로비저너 플러그인마다 다릅니다.

 

이 스토리지클래스는 구글 클라우드 엔진GCE의 퍼시스턴트 디스크 프로비저너를 사용하므로 GCE에서 쿠버네티스가 실행 중일 때 사용할 수 있습니다는 뜻입니다. 다른 클라우드 공급자인 경우 다른 프로비저너를 사용해야 합니다.


퍼시스턴트볼륨클레임에서 스토리지 클래스 요청

스토리지클래스 리소스가 생성되면 사용자는 퍼시스턴트볼륨클레임의 이름에 스토리지클래스를 참조할 수 있습니다. 다음 매니페스트로 특정 스토리지클래스를 요청하는 PVC 정의 생성할 수 있습니다. Mongodb-pvc를 동적 프로비저닝을 사용하도록 정의했습니다.

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
    name: mongodb-pvc
spec:
    storageClassName: fast            >  PVC는 사용자 정의 스토리지클래스를 요청합니다.
    resources:
        requests:
            storage: 100Mi
        accessModes:
        - ReadWriteOnce

크기와 접근 모드를 지정하는 것 외에도 퍼시스턴트볼륨클레임에 사용할 스토리지클래스를 지정해야 합니다. 클레임을 생성하면 fast 스토리지클래스 리소스에 참조된 프로비저너가 퍼시스턴트볼륨을 생성합니다. 프로비저너는 수동으로 프로비저닝된 퍼시스턴트볼 륨과 퍼시스턴트볼륨클레임을 매핑하는 데도 사용됩니다.


동적 프로비저닝된 PV와 생성된 PVC 검사하기

위 방법으로 PVC를 생성하고 kubectl get을 사용해 확인합니다.

 

$ kubectl get pvc mongodb-pvc NAME

 

VOLUME 열은 클레임에 바인딩된 퍼시스턴트볼륨을 표시합니다. 이 때 표시되는 이름보다 실제 이름이 훨씬 깁니다. 다음으로 퍼시스턴트볼륨을 조회해서 실제로 PV가 자동으로 생성됐는지 확인해보겠습니다.

 

$ kubectl get pv

 

동적으로 프로비저닝된 퍼시스턴트볼륨을 볼 수 있습니다. 퍼시스턴트볼륨의 용량과 접근 모드가 PVC에서 요청한 것과 동일할 것입니다. 리클레임 정책(RECLAIMPOLICY 열)은 Delete로 PVC가 삭제되면 퍼시 스턴트볼륨이 삭제됨을 의미합니다. PV 외에 프로비저너는 실제 스토리지도 프로비저닝했습니다. fast 스토리지클래스는 GCE 퍼시스턴트 디스크를 프로비저닝하는 kubernetes.io/gce-pd 프로비저너를 사용하도록 설정됐습니다. 다음 명령으로 디스크를 확인합니다.

 

$ gcloud compute disks list

 

퍼시스턴트 디스크의 이름에 gke-kubia-dyn-pvc-...으로 출력됐을 것이고, 동적으로 프로비저닝됐음을 나타냅니다.


다른 클러스터에도 동일하게 적용하기

클러스터 관리자는 성능이나 기타 특성이 다른 여러 스토리지 클래스를 생성할 수 있습니다. 그런 다음 개발자는 생성할 각 클레임에 가장 적합한 스토리지 클래스를 결정합니다.

 

스토리지클래스의 좋은 점은 클레임 이름으로 이를 참조합니다는 사실입니다. 그러므로 다른 클러스터 간 스토리지클래스 이름을 동일하게 사용한다면 PVC 정의를 다른 클러스터로 이식 가능합니다.

 

PVC 정의를 다른 클러스터로 이동해야 할 경우, 동일한 YAML 파일을 대상 클러스터에 적용하기만 하면 됩니다.

kubectl apply -f pvc-yaml-name.yaml

이와 같이 각 클러스터에서 동일한 StorageClass 이름을 사용하면 클러스터마다 YAML 파일을 수정할 필요 없이 PVC 정의를 쉽게 이식할 수 있습니다. 단, 이 프로세스는 PV에 저장된 실제 데이터를 이동시키지는 않으므로, 스토리지 솔루션 및 요구 사항에 따라 데이터 복제 또는 백업 및 복원과 같은 다른 접근 방식을 사용해야 합니다.


스토리지 클래스 조회하기

fast라는 사용자 정의 스토리지 클래스를 생성할 때 클러스터에 스토리지 클래스가 이미 정의돼 있는지 확인하지 않았다. 지금 확인해봅시다. GKE에서 사용 가능한 스토리지 클래 스는 다음과 같습니다.  storageclass의 약어로 SC를 사용할 수 있습니다.

 

$ kubectl get sc

출력 내용

NAME                         TYPE
fast                              kubernetes.io/gce-pd
standard(default)         kubernetes.io/gce-pd

직접 생성한 fast 스토리지 클래스 외에 standard 스토리지 클래스가 기본값(default) o 로 표시돼 있습니다. 이것이 무슨 의미인지 Minikube에서 사용 가능한 스토리지 클래스를 조회해서 비교해보겠습니다.

 

$ kubectl get sc

출력 내용

NAME                         TYPE
fast                              k8s.io/minikube-hostpath
standard(default)         k8s.io/minikube-hostpath

여기에도 생성한 fast 스토리지 클래스가 있고 기본값으로 standard 스토리지 클래스 가 존재합니다. 두 조회 결과에서 TYPE 열을 비교해보면 GKE는 kubernetes.io/gce-pd 프로비저너를 사용하고 Minikube는 k8s.io/Minikube-hostpath를 사용합니다.


기본 스토리지 클래스 확인하기

다음과 같이 kubectl get을 사용해 GKE 클러스터의 standard 스토리지 클래스를 자세히 살펴보겠습니다. 이 때 끝에 " > (파일이름).yaml "을 입력하면 해당 내용의 yaml 파일을 생성할 수도 있습니다.

$ kubectl get sc standard -o yaml

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  annotations:
    storageclass.beta.kubernetes.io/is-default-class: "true"  >  이 어노테이션에서 스토리지 클래스를 기본값으로 
  creationTimestamp: 2017-05-16T15:24:117                          표시합니다.
  labels:
    addonmanager.kubernetes.io/mode: EnsureExists
    kubernetes.io/cluster-service: "true"
  name: standard
  resourceVersion: "180"
  selfLink:/apis/storage.k8s.io/v1/storageclassesstandard
  uid: b6498511-3a4b-11e7-ba2c-42010a840014
parameters:                                                       >    type 파라미터는 프로비저너가 어떤 유형의 GCE PD를 
  type: pd-standard                                                  생성할지 알려줍니다.
provisioner: kubernetes.io/gce-pd GCE            >  퍼시스턴트 디스크 프로비저너는 이 클래스의 PV 프로비저닝
                                                                              하는 데 사용합니다.

예제의 맨 위를 자세히 살펴보면 스토리지 클래스 정의에 어노테이션이 포함돼 있으므로 이 스토리지 클래스가 기본값이 됩니다. 기본 스토리지 클래스는 퍼시스턴트볼륨클레임 에서 명시적으로 어떤 스토리지 클래스를 사용할지 지정하지 않은 경우 퍼시스턴트볼륨을 동적 프로비저닝하는 데 사용됩니다.


스토리지 클래스를 지정하지 않고 PVC 생성하기

storageClassName 속성을 지정하지 않고 PVC를 생성하면 구글 쿠버네티스 엔진에서는 pd-standard 유형의 GCE 퍼시스턴트 디스크가 프로비저닝됩니다. 다음 YAML로 클레임을 생성할 수 있습니다.

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mongodb-pvc2
spec:                                             >  이전 예제와 다르게 storageClassName 속성을 지정하지 않았습니다.
  resources:
    requests:
      storage: 100mi
  accessModes:
  - ReadWriteOnce

 

이 PVC 정의는 단지 스토리지 사이즈와 의도된 접근 모드만을 지정하고 스토리지 클 래스를 포함하지 않는다. PVC를 생성하면 기본값으로 표시된 스토리지 클래스가 사용됩니다. 다음과 같이 확인할 수 있습니다.

 

$ kubectl get pvc mongodb-pvc2

$ kubectl get pv pvc-95a5ec12(이 문자 배열은 달라질 수 있습니다.)

$ gcloud compute disks list


퍼시스턴트볼륨클레임을 미리 프로비저닝된 퍼시스턴트볼륨으로 바인딩 강제화하기

PVC 정의에서 관련 있는 행을 다시 살펴 보겠습니다.

kind: PersistentVolumeClaim
spec:
  storageClassName:  ""           >  빈 문자열을 스토리지클래스 이름으로 지정하면 PVC가 새로운 PV를 동적
                                                     프로비저닝하는 대신 미리 프로비저닝된 PV에 바인딩됩니다.

storageClassName 속성을 빈 문자열로 지정하지 않으면 미리 프로비저닝된 퍼시스턴 트볼륨이 있다고 할지라도 동적 볼륨 프로비저너는 새로운 퍼시스턴트볼륨을 프로비저닝할 것입니다.

 

PVC를 미리 프로비저닝된 퍼시스턴트볼륨에 바인딩하려면 명시적으로 storageClassName 을 ""(큰따옴표)로 지정해야 합니다. 요약하면 파드에 퍼시스턴트 스토리지를 연결하는 최적의 방법은 (storageClassName을 명시적으로 지정한) PVC와 (PVC를 이름으로 참조한) 파드만 생성하는 것입니다. 이외의 다른 모든 것은 동적 퍼시스턴트볼륨 프로비저너가 처리합니다.

 

반응형
반응형

목차

  1. 들어가며
  2. PV, PCV 원리
  3. 퍼시스턴트볼륨(PV) 생성
  4. 퍼시스턴트볼륨클레임(PVC) 생성
  5. PVC, PV 조회
  6. 파드에서 퍼시스턴트볼륨클레임 사용
  7. PV, PCV 장점
  8. 퍼시스턴트볼륨 재사용

들어가며

지금까지 살펴본 모든 퍼시스턴트 볼륨 유형은 파드 개발자가 실제 네트워크 스토리지 인프라스트럭처에 관한 지식을 갖추고 있어야 합니다. NFS 기반의 볼륨을 생성하려면 개발자는 NFS 익스포트가 위치하는 실제 서버를 알아야 합니다. 이는 인프라스트럭처의 세부 사항 에 대한 걱정을 없애고, 클라우드 공급자나 온프레미스 데이터센터를 걸쳐 이식 가능한 애플리케이션을 만들고, 애플리케이션과 개발자로부터 실제 인프라스트럭처를 숨긴다는 쿠 버네티스의 기본 아이디어에 반합니다.

 

이상적으로는 쿠버네티스에 애플리케이션을 배포하는 개발자는 기저에 어떤 종류의 스토리지 기술이 사용되는지 알 필요가 없어야 하고, 동일한 방식으로 파드를 실행하기 위해 어떤 유형의 물리 서버가 사용되는지 알 필요가 없어야 합니다. 인프라스트럭처 관련 처리는 클러스터 관리자만의 영역이어야 합니다.

 

개발자가 애플리케이션을 위해 일정량의 퍼시스턴트 스토리지를 필요로 하면 쿠버네티스에 요청할 수 있어야 하고, 동일한 방식으로 파드 생성 시 CPU, 메모리와 다른 리소스를 요청할 수 있어야 합니다. 시스템 관리자는 클러스터를 구성해 애플리케이션이 요구한 것을 제공할 수 있어야 합니다.


PV, PCV 원리

인프라스트럭처의 세부 사항을 처리하지 않고 애플리케이션이 쿠버네티스 클러스터에 스토리지를 요청할 수 있도록 하기 위해 새로운 리소스 두 개가 도입됐습니다. 바로 퍼시스턴트 볼륨(PV, PersistentVolume)과 퍼시스턴트볼륨클레임(PVC, PersistentVolumeClaim)입니다. 이전 포스팅에서 살펴본 것과 같이 일반 쿠버네티스 볼륨도 영구적인 데이터를 저장하는 데 사용할 수 있기 때문에 이름에 오해의 소지가 있을 수 있습니다.

 

파드에서 퍼시스턴트볼륨을 사용하면 일반 파드 볼륨을 사용하는 것에 비해 조금 복잡 하므로 파드, 퍼시스턴트볼륨, 퍼시스턴트볼륨클레임과 실제 기반 스토리지가 어떻게 관 련되는지 다음 그림에서 살펴봅시다.

개발자가 파드에 기술적인 세부 사항을 기재한 볼륨을 추가하는 대신 클러스터 관리 자가 기반 스토리지를 설정하고 쿠버네티스 API 서버로 퍼시스턴트볼륨 리소스를 생성해 쿠버네티스에 등록합니다. 퍼시스턴트볼륨이 생성되면 관리자는 크기와 지원 가능한 접근 모드를 지정합니다.

 

클러스터 사용자가 파드에 퍼시스턴트 스토리지를 사용해야 하면 먼저 최소 크기와 필 요한 접근 모드를 명시한 퍼시스턴트볼륨클레임 매니페스트를 생성합니다. 그런 다음 사용 자는 퍼시스턴트볼륨클레임 매니페스트를 쿠버네티스 API 서버에 게시하고 쿠버네티스는 적절한 퍼시스턴트볼륨을 찾아 클레임에 볼륨을 바인딩합니다.

 

그런 다음 퍼시스턴트볼륨클레임은 파드 내부의 볼륨 중 하나로 사용될 수 있습니다. 퍼시스턴트 볼륨 클레임의 바인딩을 삭제해 릴리스될 때까지 다른 사용자는 동일한 퍼시스턴트 볼륨을 사용할 수 없습니다.


퍼시스턴트볼륨(PV) 생성

MongoDB 예제를 살펴보겠습니다. 이전과 달리 파드에서 직접 GCE 퍼시스턴트 볼륨을 참조하지 않습니다. 그 대신 여러분이 클러스터 관리자의 역할이라고 가정하고 GCE 퍼시스턴트 볼륨을 기반으로 한 퍼시스턴트 볼륨을 생성합니다. 그런 다음 애플리케이션 개발자의 역할이라 가정하고 퍼시스턴트볼륨을 클레임해서 이것을 파드에서 사용합니다.

 

gcePersistentDisk 퍼시스턴트볼륨 생성 매니패스트는 다음과 같습니다.

apiVersion: v1
kind: PersistentVolume
metadata:
    name: mongodb-pv
spec:
    capacity:                                                      >  PersistentVolume 사이즈를 지정합니다.
        storage: 1Gi
    accessModes:                                             >  이 PV는 단일 클라이언트의 읽기/쓰기용 (ReadWirteOnce)이나 
    - ReadWriteOnce                                            여러 클라이언트를 위한 읽기 전용(ReadOnlyMany)으로
    - ReadOnlyMany                                             마운트됩니다.
    persistentVolumeReclaimPolicy: Retain     >  클레임이 해제된 후 퍼시스턴트볼륨은 이전에 퍼시스턴트볼륨은 
    gcePersistentDisk:                                          유지돼야 합니다 (지워지거나 삭제되면 안 됩니다).
        pdName: mongodb                                 >  생성한 GCE 퍼시스턴트 디스크를 기반으로 합니다.
        fsType: ext4

퍼시스턴트볼륨을 생성할 때 관리자는 쿠버네티스에게 용량이 얼마가 되는지 단일 노드나 동시에 다수 노드에 읽기나 쓰기가 가능한지 여부를 알려야 합니다. 또한 쿠버네티스에게 퍼시스턴트볼륨이 해제되면 어떤 동작을 해야 할지 알려야 합니다(바인딩된 퍼시스턴트볼륨 클레임이 삭제되는 경우).

 

마지막으로 퍼시스턴트볼륨을 지원하는 실제 스토리지의 유형, 위치, 그 밖의 속성 정보를 지정해야 합니다. 자세히 살펴보면 마지막 부분은 앞서 파드 볼륨으로 GCE 퍼시스턴트 디스크를 직접 참조하는 것과 동일합니다. 이 예시는 다음과 같습니다.

spec:
    volumes:
    - name: mongodb-data
      gcePersistentDisk:
          pdName: mongodb
          fsType: ext4
...

kubectl create 명령어로 퍼시스턴트볼륨을 생성하고 나면 클레임할 준비가 됐습니다. 어떤 퍼시스턴트볼륨이 있는지 조회해봅시다.

 

$ kubectl get pv

 

아직 퍼시스턴트볼륨클레임을 생성하지 않았으므로 퍼시스턴트볼륨이 Available로 표시됩니다. 참고로 퍼시스턴트볼륨은 특정 네임스페이스에 속하지 않습니다. 퍼시스턴트볼륨은 노드와 같은 클러스터 수준 리소스입니다.


퍼시스턴트볼륨클레임(PVC) 생성

이제 개발자 입장이 돼서 퍼시스턴트 스토리지가 필요한 파드를 배포해야 할 차례입니다. 이전에 생성한 퍼시스턴트볼륨을 사용할 것입니다. 하지만 파드 에 직접 사용할 수는 없고 클레임을 먼저 해야 합니다. 파드가 재스케줄링되더라도 동일한 퍼시스턴트볼륨클레임이 사용 가능한 상태로 유지되기를 원하므로 퍼시스턴트볼륨에 대한 클레임은 파드를 생성하는 것과 별개의 프로세스입니다

  • 재스케줄링: 이전의 파드가 삭제되고 새로운 파드가 생성되는 것을 의미합니다.

 

이제 클레임을 생성합니다. 예제 6.11과 같이 퍼시스턴트볼륨클레임 매니페스트를 준비하고 kubectl create 명령으로 쿠버네티스 API에 게시합니다.

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
    name: mongodb-pvc              >  퍼시스턴트볼륨클레임의 이름으로 나중에 파드의 볼륨을 요청할 때 사용합니다.
spec:
    resources:
        requests:                            >  1GiB의 스토리지를 요청합니다.
            storage: 1Gi
    accessModes:                        >  단일 클라이언트를 지원하는 스토리지입니다(읽기/쓰기를 모두 수행합니다).
    - ReadWriteOnce
    storageClassName: ""            >  이 부분은 이후 '동적 프로비저닝'에서 자세히 다루도록 하겠다는 뜻입니다.

퍼시스턴트볼륨클레임이 생성되자마자 쿠버네티스는 적절한 퍼시스턴트볼륨을 찾고 클레임에 바인딩합니다. 퍼시스턴트볼륨의 용량은 퍼시스턴트볼륨클레임의 요청을 수용할 만큼 충분히 커야 합니다. 추가로 볼륨 접근 모드는 클레임에서 요청한 접근 모드를 포함해 야 합니다. 이 경우 퍼시스턴트볼륨클레임은 1GiB의 스토리지와 ReadWriteOnce 접근 모드 를 요청합니다. 이전에 요청한 퍼시스턴트볼륨은 두 가지 요구 사항을 만족하므로 퍼시스턴 트볼륨클레임에 바인딩됩니다. 퍼시스턴트볼륨클레임을 검사해 이를 확인할 수 있습니다.


PVC, PV 조회

PVC(PersistentVolumeClaim)의 상태를 보기 위해 모든 퍼시스턴트볼륨클레임을 조회합니다. 명령어를 사용할 때 PersistentVolumeClaim의 약어인 PVC를 사용할 수 있습니다.

 

$ kubectl get pvc NAME

 

클레임이 퍼시스턴트볼륨 mongodb-pv에 Bound 됐습니다고 나올 것입니다. 다음은 접근 모드로 사 용되는 약어입니다. 이 때 RWO, ROX, RWX는 파드 수가 아닌 볼륨을 동시에 사용할 수 있는 워커 노드 수와 관련이 있습니다.

  • RWO (ReadWriteOnce): 단일 노드만이 읽기/쓰기용으로 볼륨을 마운트할 수 있습니다.
  • ROX (ReadOnlyMany): 다수 노드가 읽기용으로 볼륨을 마운트할 수 있습니다.
  • RWX (ReadWriteMany): 다수 노드가 읽기/쓰기용으로 볼륨을 마운트할 수 있습니다.

kubectl get으로 확인해보면 퍼시스턴트볼륨이 Bound 상태가 돼 더 이상 Available로 표시되지 않습니다.

 

$ kubectl get pv

 

퍼시스턴트볼륨이 default/mongodb-pvc 클레임에 바인딩됨을 볼 수 있을 것입니다. 이 중 default 부분은 클레임이 있는 네임스페이스입니다(퍼시스턴트볼륨클레임을 default 네임스페이스에 생성했다). 퍼시스턴트볼륨은 클러스터 수준의 리소스이므로 특정 네임스페이스에 생성할 수 없습니다. 그리고 동일한 네임스페이스의 파드에서만 사용할 수 있습니다.


파드에서 퍼시스턴트볼륨클레임 사용

여기까지 진행했다면 퍼시스턴트볼륨을 사용 중에 있을 것입니다. 볼륨을 해제할 때까지 다른 사용자는 동일한 볼륨에 클레임을 할 수 없습니다. 파드 내부에서 볼륨을 사용하기 위해 다음과 같이 파드 볼륨에서 이름으로 퍼시스턴트볼륨클레임을 참조합니다.

apiVersion: v1
kind: Pod
metadata:
    name: mongodb
spec:
    containers:
    - image: mongo
      name: mongodb
      volumeMounts:
      - name: mongodb-data
        mountPath: /data/db
      ports:
      - containerPort: 27017
        protocol: TCP
    volumes:
    - name: mongodb-data
      persistentVolumeClaim:               >  파드 볼륨에서 이름으로 퍼시스턴트 볼륨클레임을 참조합니다.
          claimName: mongodb-pvc

이제 파드가 실제로 동일 퍼시스턴트볼륨과 기반 GCE PD(Google Compute Engine Persistent Disk)를 사용하는지 확인해봅니다. 예제 다음 예시와 같이 MongoDB 셸을 다시 실행해보면 이전에 저장한 데이터를 확인할 수 있어야 합니다.

$ kubectl exec-it mongodb mongo

MongoDB shell version: 3.2.8
connecting to: mongodb://127.0.0.1:27017
Welcome to the MongoDB shell.
...
>use mystore
switched to db mystore
>db.foo.find()
{"_id" : ObjectId("57a61eb9de0cfd512374cc75"), "name" : "foo" }

이렇게 이전에 MongoDB에 저장한 도큐먼트를 가져올 수 있습니다.


PV, PVC 장점

다음 그림은 파드가 GCE 퍼시스턴트 디스크를 직접 사용하는 방법과 퍼시스턴트볼륨과 퍼 시스턴트볼륨클레임으로 사용하는 방법을 보여줍니다.

애플리케이션 개발자(또는 클러스터 사용자)에게 인프라스트럭처에서 스토리지를 가져오는 간접적인 방식을 사용하는 것이 얼마나 간단한지 생각해봅시다. 퍼시스턴트볼륨과 퍼시스턴트볼륨클레임을 생성하는 추가 절차가 필요한 것은 맞지만 개발자는 기저에 사용된 실제 스토리지 기술을 알 필요가 없습니다.

 

게다가 동일한 파드와 클레임 매니페스트는 인프라스트럭처와 관련된 어떤 것도 참조 하지 않으므로 이제 다른 쿠버네티스 클러스터에서도 사용할 수 있습니다. 클레임은 “x만큼의 스토리지가 필요하고 한 번에 하나의 클라이언트에서 읽기와 쓰기를 할 수 있어야 합니다"라 고 말합니다. 그러면 파드는 볼륨 중 하나에서 해당 클레임을 이름으로 참조합니다.


퍼시스턴트볼륨 재사용

퍼시스턴트볼륨에 관해 마무리하기 전에 마지막으로 간단한 실험을 하나 해보겠습니다. 파드와 퍼시스턴트볼륨클레임을 삭제합니다.

$ kubectl delete pod mongodb
pod "mongodb" deleted

$ kubectl delete pvc mongodb-pvc
persistentvolumeclaim "mongodb-pvc" deleted

퍼시스턴트볼륨클레임을 다시 생성한 후 $ kubectl get pvc 명령어로 확인하면 클레임의 상태가 Pending으로 표시됩니다. 이전에 클레임을 생성했을 때는 클레임은 즉시 퍼시스턴트볼륨에 바인딩됐는데 이번엔 바인딩되지 않는 이유는 퍼시스턴트 볼륨을 조회해보면 이해할 수 있습니다.

$ kubectl get pv NAME C mongodb-pv 1Gi

STATUS 열은 퍼시스턴트볼륨을 Released로 표시되고 이전과 같은 Available이 아닙니다. 이미 볼륨을 사용했기 때문에 데이터를 가지고 있으므로 클러스터 관리자가 볼륨을 완전히 비우지 않으면 새로운 클레임에 바인딩할 수 없습니다. 클러스터 관리지가 볼륨을 비우지 않았다면 동일한 퍼시스턴트볼륨을 사용하는 새 파드는 다른 클러스터나 네임스페이스에서 클레임과 파드가 생성되었다 할지라도 이전 파드가 저장한 데이터를 읽을 수 있습니다.

 

  1. 퍼시스턴트볼륨을 수동으로 다시 클레임하기
    쿠버네티스에 persistentVolumeClaimPolicy를 Retain으로 설정하면 퍼시스턴트볼륨이 이러한 동작을 할 수 있습니다. 쿠버네티스가 클레임이 해제돼도 볼륨과 콘텐츠를 유지하도록 합니다. 퍼시스턴트볼륨을 수동으로 재사용할 수 있는 유일한 방법은 퍼시스턴트볼륨 리소 스를 삭제하고 다시 생성하는 것입니다. 이렇게 할 때 기반 스토리지의 파일을 어떻게 할지 결정해야 합니다. 삭제할 수도 있고 다음 파드에서 다시 사용하도록 남겨둘 수도 있습니다.

  2. 퍼시스턴트볼륨을 자동으로 다시 클레임하기
    스토리지 유럽 정의하기 지프스 다른 두 가지 리클레임 정책은 Recycle과 Delete다. Recycle은 볼륨의 콘텐츠를 삭제하 고 볼륨이 다시 클레임될 수 있도록 볼륨을 사용 가능하게 만듭니다. 이렇게 하면 퍼시스턴트볼륨은 여러 번 다른 퍼시스턴트볼륨클레임과 다른 파드에서 재사용할 수 있습니다.

    반대로 Delete 정책은 기반 스토리지를 삭제합니다. Recycle 옵션은 현재 GCE 퍼시스 턴트 디스크에서 사용할 수 없습니다. 이 유형의 퍼시스턴트볼륨은 Retain과 Delete 정책만 지원합니다. 다른 퍼시스턴트볼륨 유형도 이들 옵션을 지원할 수도 있고, 지원하지 않을 수 도 있으므로 퍼시스턴트볼륨을 생성하기 전에 볼륨으로 사용하는 특정 기반 스토리지에서 어떤 리클레임 정책을 지원하는지 확인해야 합니다.

    이 방식처럼 기존 퍼시스턴트볼륨의 리클레임 정책도 변경할 수 있습니다. 예를 들어 Delete로 초기 설정했을 경우 데이터의 손실을 방지하기 위해 Retain으로 쉽게 변경할 수 있습니다.

다만 한가지 주의할 것은 지금 공부중인 이 내용이 쓰이던 당시에는 recycle 정책이 유효했지만, 현재는 유지보수가 중단되었습니다. 따라서 이 내용을 적용하는 데 있어서 주의를 요합니다. 사담을 조금 더하자면 IT 업계는 점차 업그레이드 되는 속도가 빨라지는 것 같습니다. 하물며 이 속도를 감당할 수 없을 것 같다하여 전 세계에서 잠시 AI 개발을 6개월만 멈추자라는 이야기가 나왔을 정도니까요. 책을 쓰는데는 1년 정도가 걸린다고 합니다. 따라서 책으로 공부를 한다면 그 내용은 과거의 것으로 현재와 충분히 다룰 수 있습니다. 이를 유의하면 좋을 것 같습니다.

반응형
반응형

목차

  1. 퍼시스턴트 스토리지
  2. GCE 퍼시스턴트 디스크 생성하기
  3. GCE 퍼시스턴트 디스크 볼륨을 사용하는 파드 생성
  4. 데이터베이스에 도큐먼트를 추가해 퍼시스턴트 스토리지에 데이터 쓰기
  5. 파드를 다시 생성하도 이전 데이터를 읽을 수 있는지 확인
  6. 다른 유형의 볼륨 사용
  7. NFS 볼륨 사용
  8. 다른 스토리지 기술 사용

퍼시스턴트 스토리지

퍼시스턴트 스토리지는 개별 컨테이너, Pod 또는 Kubernetes 클러스터의 노드 수명 주기를 넘어서 데이터가 지속적으로 유지되는 저장소 솔루션을 의미합니다. 컨테이너나 Pod가 종료되거나 다시 생성되더라도 상태, 구성 파일 또는 유지해야하는 기타 데이터를 저장해야하는 애플리케이션에 필수적인 요소입니다.

 

이전에 다루었던 볼륨들은 파드에서 실행 중인 애플리케이션이 디스크에 데이터를 유지해야 하고 파드가 다른 노드로 재스케줄링된 경우에 동일한 데이터를 사용할 수 없었습니다. 이러한 데이터는 어떤 클러스터 노드에서도 접근이 필요하기 때문에 NAS(Network-Attached Storage) 유형에 저장돼야 합니다.


Kubernetes는 Persistent Volume (PV) 및 Persistent Volume Claim (PVC)을 사용하여 견고하고 유연한 지속적인 저장소 솔루션을 제공합니다. 이 내용은 이번 포스팅에서는 간단하게 짚고 넘어가지만, 다음 포스팅에서 자세히 다뤄보도록 하겠습니다.

  • Persistent Volume (PV)
    PV는 특정 Pod 또는 노드 수명 주기에 결합되지 않은 장기간 클러스터 전체의 저장소 리소스입니다. 클러스터 관리자가 수동으로 제공하거나 스토리지 클래스와 프로비저너를 사용하여 동적으로 프로비저닝 할 수 있습니다. PV는 블록 스토리지, 네트워크 연결 스토리지 (예: NFS, iSCSI) 또는 클라우드 기반 스토리지 (예: AWS EBS, Google Persistent Disk)로 백업될 수 있습니다.

  • Persistent Volume Claim (PVC)
    PVC는 PV로 충족 가능한 저장소 요청입니다. PVC는 크기, 액세스 모드 및 스토리지 클래스와 같은 저장소 요구 사항을 정의합니다. PVC가 생성되면 Kubernetes는 요구 사항을 충족하는 기존 PV에 바인딩하거나 지정된 스토리지 클래스를 사용하여 동적으로 새로운 PV를 프로비저닝합니다.

GCE 퍼시스턴트 디스크 생성하기

먼저 GCE 퍼시스턴트 디스크를 생성하는 것부터 시작하겠습니다. 쿠버네티스 클러스터가 있는 동일한 영역zone에 생성한다. 어떤 영역에 클러스터를 생성했는지 확인하기 위해 다음 gcloud 명령어로 쿠버네티스 클러스터를 조회합니다.

 

$ gcloud container clusters list

 

명령어를 입력하면 클러스터가 어느 영역에 생성됐다는 것을 표시하고 GCE 퍼시스턴트 디스크도 동일한 영역에 생성해야 합니다. 생성하는 명령어는 다음과 같습니다.

 

$ gcloud compute disks create --size=1GiB --zone=europe-west1-b mongodb

 

이 명령은 mongodb라고 이름 붙여진 1GiB 크기의 GCE 퍼시스턴트 디스크를 생성한 다. 수행하는 테스트에서 디스크 성능은 고려하지 않으므로 디스크 사이즈에 대한 경고는 무시할 수 있다.


GCE 퍼시스턴트 디스크 볼륨을 사용하는 파드 생성

이제 물리 스토리지가 적절하게 구성됐으므로 MongoDB 파드에서 볼륨으로 사용할 수 있습니다. 다음 예제와 같이 파드를 위한 YAML을 준비합니다.

apiVersion: v1
kind: Pod
metadata:
    name: mongodb
spec:
    volumes:
    - name: mongodb-data          < 볼륨의 이름(볼륨을 마운트할 때 참조한다)
      gcePersistentDisk:               < 볼륨의 유형은 GCE 퍼시스턴트 디스크다.
          pdName: mongod            <  퍼시스턴트 디스크의 이름은 반드시 이전에 생성한 실제 PD와 일치해야 한다.
          fsType: ext4                     <  파일시스템 유형은 EXT4(리눅스 파일시스템 유형 중 하나)이다.
  containers:
  - image: mongo
    name: mongodb
    volumeMounts:
    - name: mongodb-data
      mountPath: /data/db            <  MongoDB가 데이터를 저장할 경로다.
    ports:
    - containerPort: 27017
      protocol: TCP

파드는 생성한 GCE 퍼시스턴트 디스크를 기반으로 한 단일 볼륨과 단일 컨테이너로 이뤄집니다. 볼륨을 컨테이너 내부의 MongoDB가 데이터를 저장하는 /data/db에 마운트합니다.


데이터베이스에 도큐먼트를 추가해 퍼시스턴트 스토리지에 데이터 쓰기

파드를 생성해 컨테이너가 시작됐으므로 컨테이너 내부에 MongoDB 셸을 실행해 데이터 스토리지에 데이터를 쓰는 데 사용할 수 있습니다. 다음과 같이 셀을 실행 시킬 수 있습니다.

 

$ kubectl exec-it mongodb mongo

MongoDB shell version: 3.2.8
connecting to: mongodb://127.0.0.1:27017 Welcome to the MongoDB shell.
For interactive help, type "help".
For more comprehensive documentation, see
      http://docs.mongodb.org/
Questions? Try the support group
      http://groups.google.com/group/mongodb-user
>

MongoDB는 JSON 도큐먼트 저장을 허용하므로 한 건의 데이터를 저장해 영구적으 로 저장되는지와 파드가 다시 생성된 후에 데이터를 가져올 수 있는지 살펴볼 것입니다. 다음과 같이 JSON 도큐먼트를 추가합니다.

 

> use mystore

switched to db mystore

> db.foo.insert({name: 'foo'})

WriteResult({ "nInserted": 1 })

 

간단한 JSON 도큐먼트를 단일 속성(name: 'foo'')으로 추가했다. 이제 find() 명령으 로 추가한 도큐먼트를 확인합니다.

 

>db.foo.find()

{"_id" : ObjectId("57a61eb9de0cfd512374cc75"), "name" : "foo" }

 

이제 도큐먼트는 GCE 퍼시스턴트 디스크에 저장돼 있어야 합니다.


파드를 다시 생성하도 이전 데이터를 읽을 수 있는지 확인

Mongodb 셸을 종료하고(exit 입력 후 엔터 누름) 파드를 삭제하고 다시 생성해봅시다.

 

$ kubectl delete pod mongodb

pod "mongodb" deleted

$ kubectl create -f mongodb-pod-gcepd.yaml

pod "mongodb" created

 

새로운 파드가 이전 파드와 같이 정확히 동일한 GCE 퍼시스턴트 디스크를 사용하고 MongoDB 컨테이너가 실행 중이므로 파드가 다른 노드에 스케줄링됐다 할지라도 정확히 동일한 데이터를 볼 수 있어야 합니다. 컨테이너가 가동되면 다음에 표시된 것과 같이 다시 MongoDB 셸을 실행해 이전에 저장한 도큐먼트가 다시 검색되는지 확인합니다.

 

$ kubectl exec -it mongodb mongo

MongoDB shell version: 3.2.8
connecting to: mongodb://127.0.0.1:27017
Welcome to the MongoDB shell.
...
> use mystore
switched to db mystore
>db.foo.find()
{"_id" : ObjectId("57a61eb9dedcfd512374cc75"), "name" : "foo" }

다행히 파드를 삭제하고 재생성해도 데이터는 그대로 유지됐습니다. 이런 식으로 GCE 퍼시스턴트 디스크를 파드 인스턴스 여러 개에서 데이터를 유지하는 데 사용할수 있습니다.

MongoDB 파드를 모두 사용했으므로 다시 삭제하되 기반 GCE 퍼시스턴트 디스크는 삭제하지 않는다. 6장 후반부에서 다시 사용할 것이다.


다른 유형의 볼륨 사용

다른 곳에서 클러스터를 실행 중이라면 기반 인프라 스트럭처에 따라 다른 유형의 볼륨을 사용해야 합니다. 예를 들어 쿠버네티스 클러스터가 아마존 AWS EC2에서 실행 중이라면 파드에 퍼시스턴트 스토리지를 제공하기 위해 awsElasticBlock Store 볼륨을 사용할 수 있습니다.

 

마이크로 소프트 Azure에서 클러스터를 실행 중이라면 azureFile이나 azureDisk 볼륨을 사용할 수 있습니다. 여기서 어떻게 사용하는지를 상세히 다루진 않겠지만 이전 예제와 거의 같습니다. 먼 저 실제 기반 스토리지를 생성하고 파드 정의에서 적절한 속성을 지정합니다.

 

예를 들어 GCE 퍼시스턴트 볼륨 대신 awsElasticBlockStore를 사용하려면 다음과 같이 볼륨 정의를 변경해야 합니다.

apiVersion: v1
kind: Pod
metadata:
   name: mongodb
spec:
    volumes:
    - name: mongodb-data
      awsElasticBlockStore:        >  gcePersistentDisk 대신 awsElasticBlockStore 사용한다.
          volumeId: my-volume     >  생성한 EBS 볼륨의 ID를 지정한다.
          fsType: ext4                    >  파일시스템 유형은 EXT4로 이전과 같다.
    ontainers:
...

NFS 볼륨 사용

클러스터가 여러 대의 서버로 실행되는 경우 외장 스토리지를 볼륨에 마운트하기 위한 다 양한 지원 옵션이 제공됩니다. 예를 들어 NFS 공유를 마운트하기 위해서 다음과 같이 NFS 서버와 서버에서 익스포트 경로를 지정하면 됩니다.

volumes:
- name: mongodb-data
  nfs:                                  >  이 볼륨은 NFS 공유를 사용한다.
      server: 1.2.3.4             >  NFS 서버의 IP이다.
      path: /some/path         >  서버의 익스포트된 경로다.

다른 스토리지 기술 사용

지원되는 다른 옵션으로 ISCSI 디스크 리소스를 마운트하기 위한 iscsi, GlusterFS 마운트를 위한 glusterfs, RADOS 블록 디바이스를 위한 rdb, 그 외 flexVolume, cinder, cephfs, flocker, fc(Fiber Channel) 등이 있습니다. 사용하지 않는다면 모든 것을 알 필요는 없습니다. 

 

각 볼륨 유형별로 필요한 속성의 세부 정보를 보려면 쿠버네티스 API 레퍼런스의 API 정의를 확인하거나 kubectl explain을 통해 정보를 찾아봐야 합니다. 특정 스토리지 기술에 익숙하다면 explain 명령을 사용해 적절한 유형의 볼륨을 어떻 게 마운트하고 파드에서 사용하는지 쉽게 확인할 수 있습니다.

 

이런 유형의 인프라스트럭처 관련 정보를 파드 정의에 포함한다는 것은 파드 정의가 특정 쿠버네티스 클러스터에 밀접하게 연결됨을 의미합니다. 동일한 파드 정의를 다른 클러 스터에서는 사용할 수 없습니다. 이것이 바로 볼륨을 이런 방식으로 사용하는 것이 파드에 퍼 시스턴트 스토리지를 연결하는 최적의 방법이 아닌 이유입니다.

 

반응형