본문 바로가기

Cloud-native/Kubernetes

[Kubernetes]How to create Kubernetes Secret from Json/Yaml/Literal

Concept

비밀번호, OAuth 토큰, SSH 키 같은 민감한 정보들을 저장하는 용도로 사용한다.

이런한 정보들은 컨테이너 안에 저장하지 않고 별도로 보관했다가 실제 파드를 실행할 때의 템플릿으로 컨테이너에 제공한다.

Secret Type

내장 시크릿

쿠버네티스 클러스터 안에서 쿠버네티스 API에 접근할 때 사용.

클러스터 안에서 사용하는 ServiceAccount 라는 계정을 생성하면 자동으로 관련 시크릿을 만든다.

이 시크릿으로 ServiceAccount가 사용 권한을 갖는 API에 접근할 수 있다.

사용자 정의 시크릿

How to

There are 3 ways to create secret

  • file
    • k create secret generic [file-secret-name] --from-file=file.json
  • yaml
    • k apply -f secret.yaml
  • literal
    • k create secret generic [literal-secret-name] --from-literal=DB_Host=sql01

1. Json file

Json file sample - json-for-secret.json

{
  "type": "service_account",
  "project_id": "json-for-secret",
  "private_key_id": "82ea8##중략",
  "client_email": "jm-han@json-for-secret",
  "client_id": "11121##중략",
  "auth_uri": "https://accounts.google.com/o/oauth2/auth",
  "token_uri": "https://oauth2.googleapis.com/token",
  "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
  "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/"
}

Create secret with json

k create secret generic secret-from-json --from-file=./json-for-secret.json
k describe secrets secret-from-json

Name:         secret-from-json
Namespace:    default
Labels:       <none>
Annotations:  <none>

Type:  Opaque

Data
====
json-for-secret.json:  1878 bytes
  • Data에 json 파일이 통째로 secret으로 들어간것을 확인할 수 있다.
  • 인코딩된 데이터를 확인해보면 아래와 같이 json 파일 자체가 인코딩되어 secret에 저장된다.
k get secrets secret-from-json -o yaml

>>>
apiVersion: v1
data:
  json-for-secret.json: ewogICJ0eXBlIjogInNlc##중략
kind: Secret
metadata:
  name: secret-from-json
  namespace: default
  resourceVersion: "13548"
type: Opaque
  • json-for-secret.json: ewogICJ0eXBlIjogInNlc##중략 내용을 디코딩하면 위의 json-for-secret.json 내용을 그대로 얻을 수 있다. (Decode 방법은 아래에서 설명)

Create secret with seperate keys and values

json의 key, value 값을 각각 secret으로 저장하고 싶은 경우 아래와 같이 진행할 수 있다.

# Install jq
sudo apt install jq -y
kubectl create secret generic separate-json --from-env-file <(jq -r "to_entries|map(\"\(.key)=\(.value|tostring)\")|.[]" json-for-secret.json)
  • json-for-secret.json 부분에 본인의 json 파일명 작성

2. yaml file

시크릿 생성시 인코딩

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

data 아래 keys, values를 바로 표시하고 싶은 경우

apiVersion: v1
kind: Secret
metadata:
  name: mysecret
type: Opaque
stringData:
    username: adminUser
    password: adminPassword
k get secrets secret-from-yaml -o yaml

>>>
apiVersion: v1
data:
  username: ewogICJ0eXBlIjogInNlc##중략
  password: ewogICJ0eXBlIjogInNlc##중략
kind: Secret
metadata:
  name: secret-from-yaml
  namespace: default
type: Opaque

data 아래 yaml로 표시하고 싶은 경우

apiVersion: v1
kind: Secret
metadata:
  name: mysecret
type: Opaque
stringData:
  config.yaml: |
    username: adminUser
    password: adminPassword
k get secrets secret-from-yaml -o yaml

>>>
apiVersion: v1
data:
  config.yaml: ewogICJ0eXBlIjogInNlc##중략
kind: Secret
metadata:
  name: secret-from-yaml
  namespace: default
type: Opaque

config.yaml에 작성된 값을 decode하면 위에 따로 작성한 key, value값을 그대로 얻을 수 있다.

둘다 작성 한다면?

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

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

직접 Encode 하여 secret 생성

  • data 필드는 base64로 인코딩된 임의의 데이터를 기입하는 데 사용된다
  • stringData 필드는 편의를 위해 제공되며, 이를 사용해 시크릿 데이터를 인코딩되지 않은 문자열로 기입할 수 있다
echo -n 'adminUsername' | base64
>>>
YWRtaW5Vc2VybmFtZQ==
echo -n 'adminPassword' | base64
>>>
YWRtaW5QYXNzd29yZA==
apiVersion: v1
kind: Secret
metadata:
  name: mysecret
type: Opaque
data:
  username: YWRtaW5Vc2VybmFtZQ==
  password: YWRtaW5QYXNzd29yZA==
k apply -f secret.yaml

3. Literal

kubectl create secret generic literal-secret-name --from-literal=DB_Host=sql01 --from-literal=DB_User=root --from-literal=DB_Password=password123

아래와 같이 Secret에 저장할 데이터를 --from-literal=key=value 형식으로 작성할 수 있다.

  • secret name: literal-secret-name
  • --from-literal=DB_Host=sql01
  • --from-literal=DB_User=root
  • --from-literal=DB_Password=password123

4. Decode Secret

Decoding directly from secret data

k get secret -o yaml 명령어로 얻은 암호화된 데이터를 아래 명령어로 바로 Decode할 수 있다.

k get secrets separate-json -o yaml
## 중략
  client_email: am0taGFuQGpzb24tZm9yLXNlY3JldA==
## 중략
echo "am0taGFuQGpzb24tZm9yLXNlY3JldA==" | base64 --decode

>>>
jm-han@json-for-secret

A shortcut to decoding secret data

$ kubectl get secret <SECRET_NAME> -o jsonpath="{.data.<DATA>}" | base64 --decode
k get secrets separate-json -o jsonpath="{.data.client_email}" | base64 --decode
>>>
jm-han@json-for-secret