Container Orchestration/Kubernetes

Kubernetes Secret이란?

Somaz 2023. 5. 9. 20:07
728x90
반응형

Overview

오늘은 Kubernetes Secret에 대해서 공부해보려고 한다.

https://spacelift.io/blog/kubernetes-secrets


Kubernetes Secret이란?

Kubernetes 시크릿은 비밀번호, API 키, 토큰 또는 인증서와 같은 민감한 정보를 Kubernetes 클러스터 내에 안전하게 저장하는 데 사용된다. 민감한 데이터를 애플리케이션 코드 및 구성 파일과 분리하는 데 도움이 된다. 시크릿은 클러스터의 포드 및 컨테이너에서 사용할 파일 또는 환경 변수로 마운트할 수 있다.

Kubernetes Secrets으로 저장할 수 있는 아래의 리소스에 대해 알아보려고 한다.

  • Opaque Secrets
  • Service account token Secrets
  • Docker config Secrets
  • Basic authentication Secret
  • SSH authentication secrets
  • TLS secrets
  • External Secrets

https://kubernetes.io/docs/concepts/configuration/secret/#secret-types


Opaque Secrets

Opaque Secrets 은 Kubernetes secret 구성 중 기본 유형이다.

 

응용 프로그램은 종종 인증이 필요한 데이터베이스에 액세스해야 한다. 데이터베이스 비밀번호를 Kubernetes 시크릿으로 저장하고 애플리케이션에서 환경 변수로 사용할 수 있도록 할 수 있다. 이렇게 하면 비밀번호가 애플리케이션 코드 및 구성과 안전하게 분리할 수 있다.

apiVersion: v1
kind: Secret
metadata:
  name: somaz-server-db-secret
  namespace: somaz-server-dev1
  labels:
    app: somaz-server-dev1
type: Opaque
data:
  DB_USERNAME: c29tYXoK # echo -n "somaz" | base64
  DB_PASSWORD: c29tYXo5NAo= # echo -n "somaz94" | base64
  DB_ROOT_PASSWORD: YWRtaW4K # echo -n "admin" | base64

 

apiVersion: apps/v1
kind: Deployment
metadata:
  name: somaz-server-db-dev1
  labels:
    app: somaz-server-db-dev1
spec:
  selector:
    matchLabels:
      app: somaz-server-db-dev1
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: somaz-server-db-dev1
    spec:
      containers:
        - image: mysql:8.0
          name: mysql
          env:
            # Use secret in real usage
            # - name: MYSQL_ALLOW_EMPTY_PASSWORD
            #   value: 'yes'
            - name: MYSQL_USER
              valueFrom:
                secretKeyRef:
                  name: somaz-server-db-secret
                  key: DB_USERNAME
            - name: MYSQL_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: somaz-server-db-secret
                  key: DB_PASSWORD
            - name: MYSQL_ROOT_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: somaz-server-db-secret
                  key: DB_ROOT_PASSWORD
          ports:
            - containerPort: 3306
              protocol: TCP
              name: mysql
          volumeMounts:
            - name: mysql-persistent-storage-dev1
              mountPath: /var/lib/mysql
            - name: config-volume
              mountPath: /etc/mysql/conf.d
      volumes:
        - name: mysql-persistent-storage-dev1
          persistentVolumeClaim:
            claimName: somaz-server-db-dev1-pv-claim
        - name: config-volume
          configMap:
            name: somaz-server-db-config

 

MetalLB memberlist key 생성 방법(랜덤방식)

kubectl create secret generic -n metallb-system memberlist --from-literal=secretkey="$(openssl rand -base64 128)" -o yaml > metallb-secret.yaml

 


Service account token Secrets

Secret 유형 kubernetes.io/service-account-token은 ServiceAccount를 확인하는 token credential을 저장한다.

서비스 계정이 생성될 때 자동으로 생성되며, 서비스 계정과 연결되어 있다. 서비스 계정 토큰 시크릿을 사용하면, Pod는 Kubernetes API에 대한 인증을 위해 토큰을 사용할 수 있다. 토큰은 자동으로 쿠버네티스 클러스터의 API 서버로 전달되어 인증 및 권한 부여 프로세스에 사용된다.

apiVersion: v1
kind: Secret
metadata:
  name: secret-sa-sample
  annotations:
    kubernetes.io/service-account.name: "sa-name"
type: kubernetes.io/service-account-token
data:
  # You can include additional key value pairs as you do with Opaque Secrets
  extra: YmFyCg==

 

Docker config Secrets

다음 type값 중 하나를 사용하여 컨테이너 이미지 레지스트리에 액세스하기 위한 자격 증명을 저장할 비밀을 만들 수 있다.

  • kubernetes.io/dockercfg
  • kubernetes.io/dockerconfigjson

 

Docker Hub 또는 Google Container Registry, Harbor 같은 컨테이너 레지스트리에서 프라이빗 컨테이너 이미지를 가져오려면 인증 자격 증명이 필요하다. 이러한 자격 증명을 Kubernetes 보안 비밀로 저장하고 포드 사양에서 사용하여 레지스트리로 인증할 수 있다.

$ cat harbor-secret.yaml
apiVersion: v1
data:
  .dockerconfigjson: e2F1dGhzOntodHRwOi8vaGFyYm9yLnRlc3Q6e3VzZXJuYW1lOmFkbWluLHBhc3N3b3JkOmFkbWluLGVtYWlsOnRlc3RAdGVzdC5jb20sYXV0aDpZV1J0YVc0NlNHRnlZbTlYWFhYWFhYWFg9fX19Cg==
kind: Secret
metadata:
  creationTimestamp: null
  name: harbor-secret
type: kubernetes.io/dockerconfigjson

$ echo "e2F1dGhzOntodHRwOi8vaGFyYm9yLnRlc3Q6e3VzZXJuYW1lOmFkbWluLHBhc3N3b3JkOmFkbWluLGVtYWlsOnRlc3RAdGVzdC5jb20sYXV0aDpZV1J0YVc0NlNHRnlZbTlYWFhYWFhYWFg9fX19Cg==" | base64 --decode
{auths:{http://harbor.test:{username:admin,password:admin,email:test@test.com,auth:YWRtaW46SGFyYm9XXXXXXXXX=}}}

 

Harbor key 생성 방법

kubectl create secret docker-registry <secret_name> --docker-username=<private_registry_user_name> --docker-password=<private_registry_user_password> --docker-email=<private_registry_email> --docker-server=<private_registry_url> --dry-run=client -o yaml > secret.yaml

 


Basic authentication Secret

kubernetes.io/basic-auth유형은 기본 인증에 필요한 자격 증명을 저장하기 위해 제공된다.  

data secret 필드에는 다음 두 키 중 하나가 포함되어야 한다.

  • username: 인증을 위한 사용자 이름
  • password: 인증을 위한 암호 또는 토큰
apiVersion: v1
kind: Secret
metadata:
  name: secret-basic-auth
type: kubernetes.io/basic-auth
stringData:
  username: admin      # required field for kubernetes.io/basic-auth
  password: t0p-Secret # required field for kubernetes.io/basic-auth

 


 

SSH authentication secrets

SSH 인증에 사용되는 데이터를 저장하기 위해 builtin type이 kubernetes.io/ssh-auth제공한다.

원격 서버에 대한 SSH 액세스가 필요한 애플리케이션이 있을 수 있다. 비공개 SSH 키를 Kubernetes 보안 비밀로 저장하고 액세스가 필요한 컨테이너 내부에 파일로 탑재할 수 있다. 이렇게 하면 SSH 키가 안전하게 관리되며 컨테이너 이미지나 애플리케이션 코드에 노출되지 않는다.

apiVersion: v1
kind: Secret
metadata:
  name: secret-ssh-auth
type: kubernetes.io/ssh-auth
data:
  # the data is abbreviated in this example
  ssh-privatekey: |
     MIIEpQIBAAKCAQEAulqb/Y ...

 


TLS secrets

kubernetes.io/tlsKubernetes는 일반적으로 TLS에 사용되는 인증서 및 관련 키를 저장하기 위한 기본 보안 비밀 유형을 제공한다.

apiVersion: v1
kind: Secret
metadata:
  name: secret-tls
type: kubernetes.io/tls
data:
  # the data is abbreviated in this example
  tls.crt: |
    MIIC2DCCAcCgAwIBAgIBATANBgkqh ...    
  tls.key: |
    MIIEpgIBAAKCAQEA7yn3bRHQ5FHMQ ...

 


External Secrets

External-secrets 는 외부 API에서 AWS Secrets Manager , HashiCorp Vault , Google Secrets Manager , Azure Key Vault와 같은 외부 보안 관리 시스템을 통합하고 해당 값을 Kubernetes Secret 에 자동으로 동기화하는 Kubernetes operator이다.

 

External Secrets은 Kubernetes 컨트롤러를 사용하여 작동하여 External Secrets 저장소와 Kubernetes 간에 비밀을 자동으로 동기화한다. External Secrets 저장소에서 Secret이 추가되거나 업데이트되면 컨트롤러는 변경 사항을 감지하고 해당 Kubernetes 비밀 개체를 업데이트 한다.

https://medium.com/adevinta-tech-blog/managing-kubernetes-secrets-like-a-pro-93283fb4f06d

# yaml 파일
...
externalSecrets:
  - name: somaz-database
    backendType: secretsManager
    region: ap-northeast-2
    namespace: somaz-db
    datas:
      - key: somaz-database
        property: username
        name: ADMIN_DB_ID
      - key: somaz-database
        property: password
        name: ADMIN_DB_PW
      - key: somaz-database
        property: username
...

$ k get secret -n somaz-db somaz-database -o yaml
apiVersion: v1
data:
  ADMIN_DB_ID: YWRtaW4K # echo "admin" | base64
  ADMIN_DB_PW: c29tYXoK # echo "somaz" | base64
kind: Secret
metadata:
  creationTimestamp: "2023-03-23T06:47:38Z"
  name: somaz-database
  namespace: somaz-db
  ownerReferences:
  - apiVersion: kubernetes-client.io/v1
    controller: true
    kind: ExternalSecret
    name: somaz-database
    uid: dab4xxxxx-88xx-4axx-aaxx-6dxxxxxxxxx
  resourceVersion: "75617647"
  uid: 82axxxx-ebxx-49xx-97xx-0881xxxxxxx
type: Opaque
  • AWS SecretsManager 예시이다.
  • SecretsManager에 미리 값을 넣어놓고 가져와서 쓸 수 있다.

Kubernetes Secret 생성 방법

Kubernetes에서 시크릿을 생성하는 방법은 아래와 같다.

  • Command-Line and Text Files
  • Command-Line and Literal Input
  • Definition Files
  • Base64 and The Data Parameter
  • Clear Text and The StringData Parameter

 

 


 

Command-Line and Text Files

-n 옵션과 함께 echo를 사용하여 텍스트에 개행 문자가 추가되지 않도록 했다.

app-user-cred 라는 secret을 생성하는 예시이다.

echo -n 'superuser' > ./username.txt
echo -n 'Q%FvqS$*F$k^6i' > ./password.txt
kubectl create secret generic app-user-cred --from-file=./username.txt --from-file=./password.txt

 


 

Command-Line and Literal Input

secret 텍스트에 특수 문자가 포함될 때마다 각 고유 문자 앞에 \\를 붙여서 이스케이프 처리해야 한다.

-from-literal 옵션을 통해 쉽게 secret을 생성할 수 있다.

kubectl create secret generic app-user-cred --from-literal=username=devuser 
--from-literal=password=Q\\%FvqS\\$\\*F\\$k\\^6i

 


 

Definition Files

YAML 또는 JSON으로 작성된 정의 파일을 사용하여 생성할 수 있다.

 


 

Base64 and The Data Parameter

비밀 텍스트를 base64 로 인코딩된 문자열로 정의가 가능하다. YAML 파일을 생성하고 사용하여 자격 증명을 저장할 비밀을 생성한다.

$ echo -n 'superuser' | base64
c3VwZXJ1c2Vy
$ echo -n 'Q%FvqS$*F$k^6i' | base64
USVGdnFTJCpGJGteNmk=

 

자격 증명이 base64로 인코딩되었다. 정의 파일 mysecret.yaml을 생성한다.

apiVersion: v1
kind: Secret
metadata:
  name: mysecret
type: Opaque
data:
  superuser: YWRtaW4=
  password: USVGdnFTJCpGJGteNmk=

 


 

Clear Text and The StringData Parameter

 

문자열 인코딩을 건너뛰고 Kubernetes가 자동으로 인코딩하도록 할 수 있다.

apiVersion: v1
kind: Secret
metadata:
  name: mysecret
type: Opaque
stringData:
  superuser: 'superuser'
  password: 'Q%FvqS$*F$k^6i'

$ k apply -f mysecret.yaml -n <namespace>

$ k get secret -n <namespace> mysecret -o yaml
apiVersion: v1
data:
  password: USVGdnFTJCpGJGteNmk=
  superuser: c3VwZXJ1c2Vy
kind: Secret
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"v1","kind":"Secret","metadata":{"annotations":{},
"name":"mysecret","namespace":"default"},
"stringData":{"password":"Q%FvqS$*F$k^6i","superuser":"superuser"},"type":"Opaque"}
  creationTimestamp: "2019-07-21T14:14:56Z"
  name: mysecret
  namespace: default
  resourceVersion: "708718"
  selfLink: /api/v1/namespaces/default/secrets/mysecret
  uid: eaddc88c-abc1-11e9-8bff-025000000001
type: Opaque

Kubernetes Secret Data Access

다음 이미지에 설명된 대로 컨테이너는 configMap 볼륨과 거의 동일한 방식으로 볼륨을 통해 Secret에 액세스 한다.

https://www.weave.works/blog/kubernetes-secrets-101

apiVersion: apps/v1
kind: Deployment
metadata:
  name: somaz-admin-dev
  labels:
    app: somaz-admin-dev
spec:
  revisionHistoryLimit: 1
  selector:
    matchLabels:
      app: somaz-admin-dev
  replicas: 1
  template:
    metadata:
      labels:
        app: somaz-admin-dev
    spec:
      imagePullSecrets:
        - name: secret
      volumes:
        - name: data
          persistentVolumeClaim:
            claimName: somaz-admin-dev-data-pv-claim

 


Reference

 

쿠버네티스 공식 문서(Secret)

 

How to Create, Use, and Access Kubernetes Secrets

 

Managing Kubernetes secrets like a Pro

728x90
반응형