Secret

  • 보안유지가 필요한 자격증명 및 개인 암호화 키 같은 중요한 정보를 저장하고 분류하기 위해 제공되는 리소스

1) 특징

  • 패스워드 같은 기밀 정보를 Base64 인코딩으로 만들 수 있다.
  • key=value 쌍으로 사용한다.
  • 환경 변수로 secret 정보를 컨테이너에 전달할 수 있다.
  • 볼륨의 파일로서 시크릿 정보를 저장할 수 있다.
  • 메모리에 저장된다.
  • 시크릿 크기가 너무 커지면 쿠버네티스의 apiserver나 kubelet의 메모리를 많이 차지하게되기 때문에 개별 시크릿의 최대 크기는 1MB까지 정의한다.

 

2) 종류

  • Built in 시크릿(default-token secret)
    : 클러스터 내부에서 API 이용 시 사용됨
    : 내부에서 사용되는 계정인 Service account를 생성하면 자동으로 secret 생성
    : 만들어진 secret으로 해당 service account가 권한을 가지고 있는 API 접근 가능

  • 사용자 정의 시크릿
    : 말그대로 사용자가 정의한 시크릿
    : create 명령어를 사용하여 생성할 수 있고, yaml 파일에 정의해서 생성할 수도 있음

 

3) Secret vs ConfigMap

  • 민감하지 않은 일반 데이터는 configMap 리소스를 사용한다.
  • 중요 데이터가 포함되어 있으면 Secret 리소스를 사용하는 것이 좋다.

 

4) Built in Secret

  • 모든 Pod에는 자동으로 연결된 secret 볼륨이 존재한다.

 

$ kubectl describe pod [name]

Mounts:

      /var/run/secrets/kubernetes.io/serviceaccount from default-token-kf7wl (ro)


---------------------------

Volumes:

  default-token-kf7wl:

    Type:        Secret (a volume populated by a Secret)

    SecretName:  default-token-kf7wl

    Optional:    false

$kubectl describe secret default-token-kf7wl

Name:         default-token-kf7wl

Namespace:    default

Labels:       <none>

Annotations:  kubernetes.io/service-account.name=default

              kubernetes.io/service-account.uid=7223520f-e519-11e9-876a-025000000001


Type:  kubernetes.io/service-account-token


Data

====

ca.crt:     1025 bytes

namespace:  7 bytes

token:      eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6ImRlZmF1bHQtdG9rZW4ta2Y3d2wiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoiZGVmYXVsdCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6IjcyMjM1MjBmLWU1MTktMTFlOS04NzZhLTAyNTAwMDAwMDAwMSIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpkZWZhdWx0OmRlZmF1bHQifQ.P4FnIdYC_JHXCM-RyboMkotOEkf2sRhRgXkyS9nUezIOddQ3lQGdsPI8ZXiIq1PPZN2KrXUMjq6B7rDJw3_A-zN2e1UwQfemPqllhrSNduy1WWwJTCsv71rjZmLrmrA5klmgW7DzizfLNgKY6hLpK7lSlA3pxIDzkdtYhG9AQ4oXPTym6LUCgPCO2DhonMVbbkQtRI2JoWvCdxS6geea-Kne4Op82lWFErv5zP0hmUhb5vyiFXGWBQYp-CZehiwAuNNg44_cyz3d6r_51oJAwcKiovxPRkqjJqiJfxG5gjDlPu6GT9Enbbh5Jo2x3hHYXwBqOV8CV0iT7ZyU_p2eEA


 

 

 

 

 

=> secret volume을 통해 제공되는 3가지 항목은 kubenetes API 서버와 안전하게 통신하기 위해 필요하다.

=> 즉 https 통신을 하기 위함

key

설명

ca-crt

certificate-authority , 인증서

 

 

5) 사용자 정의 시크릿

  • mac이나 linux에서 다음과 같은 명령어로 문자열을 base64로 인코딩 할 수 있다.

  • base64로 인코딩하는 이유는 ssl인증서나 binary 데이터의 지원을 위해 사용된다.

 

$ echo password | base64

cGFzc3dvcmQK

 

 

5.1) 시크릿 생성 - 명령어

$ echo -n ‘sa’ > ./username.txt
$ kubectl create secret generic h2-user-name --from-file=./username.txt

 

 

5.2) 시크릿 생성 - yaml 파일

apiVersion: v1
kind: Secret
metadata:
 name: mysqlsecret
type: Opaque
data:
 MYSQL_USER: cm9vdAo=
 MYSQL_PASSWORD: cm9vdAo=
in:/sbin:/bin



 

$ kubectl describe secret mysqlsecret

Name:         mysqlsecret
Namespace:    default
Labels:       
Annotations:  
Type:         Opaque

Data
====
MYSQL_PASSWORD:  5 bytes
MYSQL_USER:      5 bytes


Opaque 및 타입에 대해 알아보기

https://github.com/kubernetes/kubernetes/blob/7693a1d5fe2a35b6e2e205f03ae9b3eddcdabc6b/pkg/apis/core/types.go#L4394-L4478

 

 

5.3) 시크릿 적용

<simple-database-secret.yaml>

apiVersion: v1
kind: Secret
metadata:
 name: mysqlsecret
type: Opaque
data:
 MYSQL_USER: cm9vdAo=
 MYSQL_PASSWORD: cm9vdAo=in:/sbin:/bin

apiVersion: v1
kind: ConfigMap
metadata:
 name: database-config
data:
 MH_ADDR: "192.168.137.100"
 MYSQL_PORT: "3306"
 MYSQL_DATABASE: "sample"

---

apiVersion: apps/v1
kind: Deployment
metadata:
 name: health-check-app
 labels:
   app: healthcheck-test
spec:
 replicas: 1
 selector:
   matchLabels:
     app: healthcheck-test
 template:
   metadata:
     labels:
       app: healthcheck-test
   spec:
     containers:
       - name: health-check-app
         image: chulm/health-check-app:latest
         envFrom:
           - configMapRef:
               name: database-config
         env:
           - name: MYSQL_USER
             valueFrom:
               secretKeyRef:
                 name: mysqlsecret
                 key: MYSQL_USER
           - name: MYSQL_PASSWORD
             valueFrom:
               secretKeyRef:
                 name: mysqlsecret
                 key: MYSQL_PASSWORD
         ports:
           - containerPort: 8080

 

 

5.4) 환경변수 조회

$ kubectl exec health-check-app-86758956dd-lqb2t -- env | sort

 

....

KUBERNETES_PORT_443_TCP_PORT=443
KUBERNETES_PORT_443_TCP_PROTO=tcp
KUBERNETES_SERVICE_PORT=443
KUBERNETES_SERVICE_PORT_HTTPS=443
LANG=C.UTF-8
MH_ADDR=192.168.137.100
MYSQL_DATABASE=sample
MYSQL_PASSWORD=root
MYSQL_PORT=3306
MYSQL_USER=root

 

 

참조: https://kubernetes.io/docs/concepts/configuration/secret/

+ Recent posts