Overview
오늘은 Kubernetes Secret에 대해서 공부해보려고 한다.
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
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 비밀 개체를 업데이트 한다.
# 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에 액세스 한다.
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
How to Create, Use, and Access Kubernetes Secrets
'Container Orchestration > Kubernetes' 카테고리의 다른 글
Helm 이란? (Kubernetes Package manager) (2) | 2023.05.16 |
---|---|
Kuberntes Service Account란? (0) | 2023.05.10 |
MetalLB란? (2) | 2023.05.03 |
Kubernetes Resources(쿠버네티스 리소스) (0) | 2023.05.02 |
Kubernetes 플러그인 매니저 Krew란? (0) | 2023.04.30 |