ConfigMap: 컨테이너 구성 정보를 한 곳에 모아서 관리
Secret: 컨테이너가 사용하는 민감한 데이터(ex: password, auth token, ssh key)와 같은 중요한 정보를 안전하게 저장하기 위한 리소스. 애플리케이션 코드와 민감한 데이터를 분리하고, 보안을 강화할 수 있다.
Secrets의 주요 특징
- 보안 데이터 저장: 비밀번호, API 토큰, SSH 키와 같은 민감한 데이터를 저장하고 관리
- 즉, 민감하지 않은 일반 설정파일은 configMap을 사용하고, 민감한 데이터는 secret을 사용한다.
- 민감한 데이터를 저장할 때 Kubernetes Encryption at Rest를 활성화 권장
- Base64 인코딩: 데이터는 Base64로 인코딩되어 저장됩니다. ( base64는 누구나 쉽게 decode할 수 있기 때문에 추가 보안 조치가 필요)
- Pod와 통합: Secrets는 환경 변수, 볼륨 마운트, 커맨드라인 인수를 통해 Pod에 전달 가능.
- RBAC과 통합: Role-Based Access Control(RBAC)을 통해 접근 권한을 세부적으로 관리 가능.
- 변경 가능: Secrets의 데이터를 수정하면 이를 참조하는 Pod에서 즉시 반영 가능.
apiVersion: v1
kind: Secret
metadata:
name: my-secret
type: Opaque
data:
username: bXl1c2VybmFtZQ==
password: cGFzc3dvcmQ=
Secrets의 종류
- Opaque (기본):
- 일반적으로 사용되는 Secret 유형. 임의의 키-값 데이터를 저장.
- 예: API 키, 데이터베이스 비밀번호.
- Service Account Token:
- Kubernetes API와 통신하는 데 사용되는 서비스 계정 토큰.
- Docker Registry:
- Docker 이미지 풀링에 필요한 자격 증명 저장. (예: kubernetes.io/dockerconfigjson 유형)
- TLS Secret:
- TLS 인증서와 키 저장. (예: HTTPS 인증서 및 프라이빗 키)
- secret 데이터 전달 방법
- Command-line Argument
- Environment Variable
- Volume Mount
Secret 만들기
# kubectl create secret <Available Commands> name [flags] [options]
√ docker-registry
√ generic # user defined data
√ tls
→ <Available Commands> 에 따라서 들어가는 옵션이 달라진다.
$ kubectl create secret tls my-secret --cert=path/to/cert/file --key=path/to/key/file
$ kubectl create secret docker-registry reg-secret --docker-username=tiger --docker-password=pass --docker-email=tiger@acme.com
$ kubectl create secret generic soyun-secret --from-literal=INTERVAL=2 --from-file=./genid-web-config/
Type | 의미 |
Opaque | 임의의 사용자 정의 데이터 |
kubernetes.io/service-account-token | 서비스 어카운트 토큰 |
kubernetes.io/dockercfg | 직렬화된 ~/.dockercfg 파일 |
kubernetes.io/dockerconfigjson | 직렬화된 ~/.docker/config.json 파일 |
kubernetes.io/basic-auth | 기본 인증을 위한 자격 증명 |
kubernetes.io/ssh-auth | SSH를 위한 자격 증명 |
kubernetes.io/tls | TLS 클라이언트나 서버를 위한 데이터 |
bootstrap.kubernetes.io/token | 부트스트랩 토큰 데이터 |
root@master:~/configMap# kubectl create secret generic soyun-secret --from-literal=INTERVAL=2 --from-file=./genid-web-config/
secret/soyun-secret created
root@master:~/configMap# kubectl get secrets
NAME TYPE DATA AGE
soyun-secret Opaque 2 10s #Opaque는 사용자 정의 secret
# default-token- # (K8S가 내부적으로 사용) default라는 service account로 사용되는 것
[master ~/secret]$ kubectl describe secret soyun-secret
Name: soyun-secret
Namespace: default
Labels: <none>
Annotations: <none>
Type: Opaque
Data
====
INTERVAL: 1 bytes
nginx-config.conf: 218 bytes
[master ~/secret]$kubectl get secrets soyun-secret -o yaml # base64로 인코딩된 값 확인 가능
apiVersion: v1
data:
INTERVAL: Mg==
nginx-config.conf: c2VydmVyIHsKICAgIGxpc3RlbiAgIDgwOwogICAgc2VydmVyX25hbWUgIHd3dy5leGFtcGxlLmNvbTsKCiAgICBnemlwIG9uOwogICAgZ3ppcF90eXBlcyB0ZXh0L3BsYWluIGFwcGxpY2F0aW9uL3htbDsKCiAgICBsb2NhdGlvbiAvIHsKICAgICAgICByb290ICAgL3Vzci9zaGFyZS9uZ2lueC9odG1sOwogICAgICAgIGluZGV4ICBpbmRleC5odG1sIGluZGV4Lmh0bTsKICAgIH0KfQo=
kind: Secret
metadata:
creationTimestamp: "2024-03-24T14:46:05Z"
name: soyun-secret
namespace: default
resourceVersion: "18637"
uid: 72be9de1-b595-4e30-8b0c-3a71826b8ace
type: Opaque
# Secret 사용하기
정의된 Secret을 Pod의 Container에 전달하는 방법
- environment variable(env)로 전달
- Command-line Argument로 전달
- Volume에 secret을 사용하여 컨테이너 디렉토리에 Mount
# env로 Secret 데이터 전달
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: my-container
image: nginx
env:
- name: USERNAME
valueFrom:
secretKeyRef:
name: my-secret
key: username
# Secret의 username 값을 환경 변수 USERNAME으로 전달.
root@master:~/configMap# cat genid-env-secret.yaml
apiVersion: v1
kind: Pod
metadata:
name: genid-env-secret
spec:
containers:
- image: smlinux/genid:env
env: # 여기
- name: INTERVAL
valueFrom:
secretKeyRef:
name: soyun-secret
key: INTERVAL
name: fakeid-generator
volumeMounts:
- name: html
mountPath: /webdata
- image: nginx:1.14
name: web-server
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html
readOnly: true
ports:
- containerPort: 80
volumes:
- name: html
emptyDir: {}
root@master:~/configMap# kubectl create -f genid-env-secret.yaml
pod/genid-env-secret created
root@master:~/configMap# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
genid-env-secret 2/2 Running 0 16s 10.36.0.1 node2.example.com <none> <none>
root@master:~/configMap# curl 10.36.0.1 # 2초마다 fakeid생성되는 것 확인
+------------------------+
| Audrey Rose |
| 47 Buncaneer Dr |
| Minneapolis, MN 55401 |
| (612) xxx-xxxx |
+------------------------+
# Volume-mount로 전달하기
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: my-container
image: nginx
volumeMounts:
- name: secret-volume
mountPath: /etc/secret # Secret 데이터를 파일 형태로 /etc/secret에 마운트.
readOnly: true
volumes:
- name: secret-volume
secret:
secretName: my-secret
root@master:~/configMap# cat genid-volume-secret.yaml
apiVersion: v1
kind: Pod
metadata:
name: genid-volume-secret
spec:
containers:
- image: smlinux/genid:env
env:
- name: INTERVAL
valueFrom:
secretKeyRef:
name: soyun-secret
key: INTERVAL
name: fakeid-generator
volumeMounts:
- name: html
mountPath: /webdata
- image: nginx:1.14
name: web-server
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html
readOnly: true
- name: config
mountPath: /etc/nginx/conf.d
readOnly: true
ports:
- containerPort: 80
volumes:
- name: html
emptyDir: {}
- name: config
secret:
secretName: soyun-secret
items:
- key: nginx-config.conf
path: nginx-config.conf
root@master:~/configMap# kubectl create -f genid-volume-secret.yaml
pod/genid-volume-secret created
root@master:~/configMap# kubectl get pods
NAME READY STATUS RESTARTS AGE
genid-env-secret 2/2 Running 0 10m
genid-volume-secret 2/2 Running 0 10s
# 컨테이너 접속
root@master:~/configMap# kubectl exec -it genid-volume-secret -c web-server -- /bin/bash
root@genid-volume-secret:/# cd /etc/nginx/conf.d/
root@genid-volume-secret:/etc/nginx/conf.d# ls -al
total 4
drwxrwxrwt 3 root root 100 Mar 24 15:10 .
drwxr-xr-x 3 root root 4096 Mar 26 2019 ..
drwxr-xr-x 2 root root 60 Mar 24 15:10 ..2024_03_24_15_10_34.3846287265
lrwxrwxrwx 1 root root 32 Mar 24 15:10 ..data -> ..2024_03_24_15_10_34.3846287265
lrwxrwxrwx 1 root root 24 Mar 24 15:10 nginx-config.conf -> ..data/nginx-config.conf
# 진짜 파일이 아닌 symbolic link로 되어 있다.
root@genid-volume-secret:/etc/nginx/conf.d# cat nginx-config.conf # 애플리케이션 안에서는 디코딩 되어서 TEXT형식으로 보여준다.
server {
listen 80;
server_name www.example.com;
gzip on;
gzip_types text/plain application/xml;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
}
# 마운트 확인하기
root@genid-volume-secret:/etc/nginx/conf.d# df -h
Filesystem Size Used Avail Use% Mounted on
overlay 20G 9.0G 9.6G 49% /
tmpfs 64M 0 64M 0% /dev
tmpfs 994M 0 994M 0% /sys/fs/cgroup
/dev/sda1 20G 9.0G 9.6G 49% /etc/hosts
shm 64M 0 64M 0% /dev/shm
tmpfs 1.9G 4.0K 1.9G 1% /etc/nginx/conf.d # 이렇게
tmpfs 1.9G 12K 1.9G 1% /run/secrets/kubernetes.io/serviceaccount
tmpfs 994M 0 994M 0% /proc/asound
tmpfs 994M 0 994M 0% /proc/acpi
tmpfs 994M 0 994M 0% /proc/scsi
tmpfs 994M 0 994M 0% /sys/firmware
# Secret 데이터 용량 제한
- Secret etcd에 암호화하지 않은 텍스트로 저장되므로, secret value가 커지면 메모리 용량을 많이 사용하게 된다.
- secret의 최대 크기는 1MB
- 참고 영상 : https://www.youtube.com/watch?v=aW2RAVnOHFY&t=596s
- 참고 자료: https://kubernetes.io/docs/concepts/configuration/secret/
반응형
'Container > Kubernetes' 카테고리의 다른 글
[K8S] Taint & Toleration (0) | 2024.04.12 |
---|---|
[K8S] Affinity & antiAffinity (0) | 2024.03.25 |
[K8S] Canary Deployment (0) | 2024.03.20 |
[K8S] Annotation (0) | 2024.03.17 |
[K8S] Node Label & Selector (0) | 2024.03.17 |