1 - kubectl을 사용한 시크릿 관리

kubectl 커맨드를 사용하여 시크릿 오브젝트를 생성.

시작하기 전에

쿠버네티스 클러스터가 필요하고, kubectl 커맨드-라인 툴이 클러스터와 통신할 수 있도록 설정되어 있어야 한다. 이 튜토리얼은 컨트롤 플레인 호스트가 아닌 노드가 적어도 2개 포함된 클러스터에서 실행하는 것을 추천한다. 만약, 아직 클러스터를 가지고 있지 않다면, minikube를 사용해서 생성하거나 다음의 쿠버네티스 플레이그라운드 중 하나를 사용할 수 있다.

시크릿 생성

시크릿에는 파드가 데이터베이스에 접근하는 데 필요한 사용자 자격 증명이 포함될 수 있다. 예를 들어 데이터베이스 연결 문자열은 사용자 이름과 암호로 구성된다. 사용자 이름은 로컬 컴퓨터의 ./username.txt 파일에, 비밀번호는 ./password.txt 파일에 저장할 수 있다.

echo -n 'admin' > ./username.txt
echo -n '1f2d1e2e67df' > ./password.txt

이 명령에서 -n 플래그는 생성된 파일의 텍스트 끝에 추가 개행 문자가 포함되지 않도록 해 준다. 이는 kubectl이 파일을 읽고 내용을 base64 문자열로 인코딩할 때 개행 문자도 함께 인코딩될 수 있기 때문에 중요하다.

kubectl create secret 명령은 이러한 파일들을 시크릿으로 패키징하고 API 서버에 오브젝트를 생성한다.

kubectl create secret generic db-user-pass \
  --from-file=./username.txt \
  --from-file=./password.txt

출력은 다음과 유사하다.

secret/db-user-pass created

기본 키 이름은 파일 이름이다. 선택적으로 --from-file=[key=]source를 사용하여 키 이름을 설정할 수 있다. 예제:

kubectl create secret generic db-user-pass \
  --from-file=username=./username.txt \
  --from-file=password=./password.txt

파일에 포함하는 암호 문자열에서 특수 문자를 이스케이프하지 않아도 된다.

--from-literal=<key>=<value> 태그를 사용하여 시크릿 데이터를 제공할 수도 있다. 이 태그는 여러 키-값 쌍을 제공하기 위해 두 번 이상 지정할 수 있다. $, \, *, =!와 같은 특수 문자는 shell에 해석하고 처리하기 때문에 이스케이프할 필요가 있다.

대부분의 셸에서 암호를 이스케이프하는 가장 쉬운 방법은 암호를 작은따옴표(')로 둘러싸는 것이다. 예를 들어, 비밀번호가 S!B\*d$zDsb=인 경우, 다음 커맨드를 실행한다.

kubectl create secret generic db-user-pass \
  --from-literal=username=devuser \
  --from-literal=password='S!B\*d$zDsb='

시크릿 확인

시크릿이 생성되었는지 확인한다.

kubectl get secrets

출력은 다음과 유사하다.

NAME                  TYPE                                  DATA      AGE
db-user-pass          Opaque                                2         51s

다음 명령을 실행하여 시크릿에 대한 상세 사항을 볼 수 있다.

kubectl describe secrets/db-user-pass

출력은 다음과 유사하다.

Name:            db-user-pass
Namespace:       default
Labels:          <none>
Annotations:     <none>

Type:            Opaque

Data
====
password:    12 bytes
username:    5 bytes

kubectl getkubectl describe 명령은 기본적으로 시크릿의 내용을 표시하지 않는다. 이는 시크릿이 실수로 노출되거나 터미널 로그에 저장되는 것을 방지하기 위한 것이다.

시크릿 디코딩

생성한 시크릿을 보려면 다음 명령을 실행한다.

kubectl get secret db-user-pass -o jsonpath='{.data}'

출력은 다음과 유사하다.

{"password":"MWYyZDFlMmU2N2Rm","username":"YWRtaW4="}

이제 password 데이터를 디코딩할 수 있다.

echo 'MWYyZDFlMmU2N2Rm' | base64 --decode

출력은 다음과 유사하다.

1f2d1e2e67df

삭제

생성한 시크릿을 삭제하려면 다음 명령을 실행한다.

kubectl delete secret db-user-pass

다음 내용

2 - 환경 설정 파일을 사용하여 시크릿을 관리

환경 설정 파일을 사용하여 시크릿 오브젝트를 생성.

시작하기 전에

쿠버네티스 클러스터가 필요하고, kubectl 커맨드-라인 툴이 클러스터와 통신할 수 있도록 설정되어 있어야 한다. 이 튜토리얼은 컨트롤 플레인 호스트가 아닌 노드가 적어도 2개 포함된 클러스터에서 실행하는 것을 추천한다. 만약, 아직 클러스터를 가지고 있지 않다면, minikube를 사용해서 생성하거나 다음의 쿠버네티스 플레이그라운드 중 하나를 사용할 수 있다.

환경 설정 파일 생성

먼저 새 파일에 JSON 이나 YAML 형식으로 시크릿(Secret)에 대한 상세 사항을 기록하고, 이 파일을 이용하여 해당 시크릿 오브젝트를 생성할 수 있다. 이 시크릿 리소스에는 datastringData 의 두 가지 맵이 포함되어 있다. data 필드는 base64로 인코딩된 임의의 데이터를 기입하는 데 사용된다. stringData 필드는 편의를 위해 제공되며, 이를 사용해 시크릿 데이터를 인코딩되지 않은 문자열로 기입할 수 있다. datastringData은 영숫자, -, _ 그리고 .로 구성되어야 한다.

예를 들어 시크릿에 data 필드를 사용하여 두 개의 문자열을 저장하려면 다음과 같이 문자열을 base64로 변환한다.

echo -n 'admin' | base64

출력은 다음과 유사하다.

YWRtaW4=
echo -n '1f2d1e2e67df' | base64

출력은 다음과 유사하다.

MWYyZDFlMmU2N2Rm

다음과 같이 시크릿 구성 파일을 작성한다.

apiVersion: v1
kind: Secret
metadata:
  name: mysecret
type: Opaque
data:
  username: YWRtaW4=
  password: MWYyZDFlMmU2N2Rm

시크릿 오브젝트의 이름은 유효한 DNS 서브도메인 이름이어야 한다.

참고: 시크릿 데이터의 직렬화된(serialized) JSON 및 YAML 값은 base64 문자열로 인코딩된다. 이러한 문자열에는 개행(newline)을 사용할 수 없으므로 생략해야 한다. Darwin/macOS에서 base64 도구를 사용할 경우, 사용자는 긴 줄을 분할하는 -b 옵션을 사용해서는 안 된다. 반대로, 리눅스 사용자는 -w 옵션을 사용할 수 없는 경우 base64 명령어 또는 base64 | tr -d '\n' 파이프라인에 -w 0 옵션을 추가해야 한다.

특정 시나리오의 경우 stringData 필드를 대신 사용할 수 있다. 이 필드를 사용하면 base64로 인코딩되지 않은 문자열을 시크릿에 직접 넣을 수 있으며, 시크릿이 생성되거나 업데이트될 때 문자열이 인코딩된다.

이에 대한 실제적인 예로, 시크릿을 사용하여 구성 파일을 저장하는 애플리케이션을 배포하면서, 배포 프로세스 중에 해당 구성 파일의 일부를 채우려는 경우를 들 수 있다.

예를 들어 애플리케이션에서 다음 구성 파일을 사용하는 경우:

apiUrl: "https://my.api.com/api/v1"
username: "<user>"
password: "<password>"

다음 정의를 사용하여 이를 시크릿에 저장할 수 있다.

apiVersion: v1
kind: Secret
metadata:
  name: mysecret
type: Opaque
stringData:
  config.yaml: |
    apiUrl: "https://my.api.com/api/v1"
    username: <user>
    password: <password>    

시크릿 오브젝트 생성

kubectl apply를 이용하여 시크릿 오브젝트를 생성한다.

kubectl apply -f ./secret.yaml

출력은 다음과 유사하다.

secret/mysecret created

시크릿 확인

stringData 필드는 쓰기 전용 편의 필드이다. 시크릿을 조회할 때 절대 출력되지 않는다. 예를 들어 다음 명령을 실행하는 경우:

kubectl get secret mysecret -o yaml

출력은 다음과 유사하다.

apiVersion: v1
data:
  config.yaml: YXBpVXJsOiAiaHR0cHM6Ly9teS5hcGkuY29tL2FwaS92MSIKdXNlcm5hbWU6IHt7dXNlcm5hbWV9fQpwYXNzd29yZDoge3twYXNzd29yZH19
kind: Secret
metadata:
  creationTimestamp: 2018-11-15T20:40:59Z
  name: mysecret
  namespace: default
  resourceVersion: "7225"
  uid: c280ad2e-e916-11e8-98f2-025000000001
type: Opaque

kubectl getkubectl describe 명령은 기본적으로 시크릿의 내용을 표시하지 않는다. 이는 시크릿이 실수로 구경꾼에게 노출되거나 터미널 로그에 저장되는 것을 방지하기 위한 것이다. 인코딩된 데이터의 실제 내용을 확인하려면 다음을 참조한다. 시크릿 디코딩.

하나의 필드(예: username)가 datastringData에 모두 명시되면, stringData에 명시된 값이 사용된다. 예를 들어 다음과 같은 시크릿인 경우:

apiVersion: v1
kind: Secret
metadata:
  name: mysecret
type: Opaque
data:
  username: YWRtaW4=
stringData:
  username: administrator

결과는 다음과 같은 시크릿이다.

apiVersion: v1
data:
  username: YWRtaW5pc3RyYXRvcg==
kind: Secret
metadata:
  creationTimestamp: 2018-11-15T20:46:46Z
  name: mysecret
  namespace: default
  resourceVersion: "7579"
  uid: 91460ecb-e917-11e8-98f2-025000000001
type: Opaque

여기서 YWRtaW5pc3RyYXRvcg==administrator으로 디코딩된다.

삭제

생성한 시크릿을 삭제하려면 다음 명령을 실행한다.

kubectl delete secret mysecret

다음 내용

3 - kustomize를 사용하여 시크릿 관리

kustomization.yaml 파일을 사용하여 시크릿 오브젝트 생성.

쿠버네티스 v1.14부터 kubectlKustomize를 이용한 쿠버네티스 오브젝트의 선언형 관리를 지원한다. Kustomize는 시크릿 및 컨피그맵을 생성하기 위한 리소스 생성기를 제공한다. Kustomize 생성기는 디렉토리 내의 kustomization.yaml 파일에 지정되어야 한다. 시크릿 생성 후 kubectl apply를 통해 API 서버에 시크릿을 생성할 수 있다.

시작하기 전에

쿠버네티스 클러스터가 필요하고, kubectl 커맨드-라인 툴이 클러스터와 통신할 수 있도록 설정되어 있어야 한다. 이 튜토리얼은 컨트롤 플레인 호스트가 아닌 노드가 적어도 2개 포함된 클러스터에서 실행하는 것을 추천한다. 만약, 아직 클러스터를 가지고 있지 않다면, minikube를 사용해서 생성하거나 다음의 쿠버네티스 플레이그라운드 중 하나를 사용할 수 있다.

Kustomization 파일 생성

kustomization.yaml 파일에 다른 기존 파일을 참조하는 secretGenerator를 정의하여 시크릿을 생성할 수 있다. 예를 들어 다음 kustomization 파일은 ./username.txt./password.txt 파일을 참조한다.

secretGenerator:
- name: db-user-pass
  files:
  - username.txt
  - password.txt

kustomization.yaml 파일에 리터럴을 명시하여 secretGenerator를 정의할 수도 있다. 예를 들어 다음 kustomization.yaml 파일에는 각각 usernamepassword에 대한 두 개의 리터럴이 포함되어 있다.

secretGenerator:
- name: db-user-pass
  literals:
  - username=admin
  - password=1f2d1e2e67df

kustomization.yaml 파일에 .env 파일을 명시하여 secretGenerator를 정의할 수도 있다. 예를 들어 다음 kustomization.yaml 파일은 .env.secret 파일에서 데이터를 가져온다.

secretGenerator:
- name: db-user-pass
  envs:
  - .env.secret

모든 경우에 대해, 값을 base64로 인코딩하지 않아도 된다.

시크릿 생성

다음 명령을 실행하여 시크릿을 생성한다.

kubectl apply -k .

출력은 다음과 유사하다.

secret/db-user-pass-96mffmfh4k created

시크릿이 생성되면 시크릿 데이터를 해싱하고 이름에 해시 값을 추가하여 시크릿 이름이 생성된다. 이렇게 함으로써 데이터가 수정될 때마다 시크릿이 새롭게 생성된다.

생성된 시크릿 확인

시크릿이 생성된 것을 확인할 수 있다.

kubectl get secrets

출력은 다음과 유사하다.

NAME                             TYPE                                  DATA      AGE
db-user-pass-96mffmfh4k          Opaque                                2         51s

다음 명령을 실행하여 시크릿에 대한 상세 사항을 볼 수 있다.

kubectl describe secrets/db-user-pass-96mffmfh4k

출력은 다음과 유사하다.

Name:            db-user-pass-96mffmfh4k
Namespace:       default
Labels:          <none>
Annotations:     <none>

Type:            Opaque

Data
====
password.txt:    12 bytes
username.txt:    5 bytes

kubectl getkubectl describe 명령은 기본적으로 시크릿의 내용을 표시하지 않는다. 이는 시크릿이 실수로 구경꾼에게 노출되는 것을 방지하기 위한 것으로, 또는 터미널 로그에 저장되지 않는다. 인코딩된 데이터의 실제 내용을 확인하려면 다음을 참조한다. 시크릿 디코딩.

삭제

생성한 시크릿을 삭제하려면 다음 명령을 실행한다.

kubectl delete secret db-user-pass-96mffmfh4k

다음 내용