Kubernetes Secret
ConfigMap은 별도의 인코딩없이 값이 저장되지만 Secret은 base64로 인코딩되어 값이 저장된다.
ConfigMap과 Secret etcd의 메모리에 저장된다. 저장 용량은 1MB까지이다.
secret을 생성하는 방법은 3가지가 있다.
- kubectl create secret <3가지 커멘트> name [flags] [options]
- docker-registry
- generic
- tls
1. docker-registry
$ kubectl create secret docker-registry private-reg-cred \
--docker-username=dock_user \
--docker-password=dock_password --docker-server=myprivateregistry.com:5000 \
--docker-email=dock_user@myprivateregistry.com
deploy앱 yaml 파일에
spec.template.spec.imagePullSecrets에
- name: ( 값입력 )
2. generic
1) 명령어로 생성하기
$ echo -n 'alice' > ./username.txt
$ echo -n 'password' > ./password.txt
$ kubectl create secret generic user-pass-secret \
--from-file=./username.txt --from-file=./password.txt
$ kubectl get secrets
$ kubectl get secret user-pass-secret -o yaml
$ echo YWxpY2U= | base64 -d
$ echo cGFzc3dvcmQ= | base64 -d
2) yaml 파일로 생성하기
$ cat > user-pass.yaml
apiVersion: v1
kind: Secret
metadata:
name: user-pass-secret2
type: Opaque
data:
username: YWxpY2U=
password: cGFzc3dvcmQ=
생성한 Secret 사용하기
$ cat > user-env.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: secretapp
labels:
app: secretapp
spec:
replicas: 1
selector:
matchLabels:
app: secretapp
template:
metadata:
labels:
app: secretapp
spec:
containers:
- name: secret-app
image: arisu1000/simple-container-app:latest
ports:
- containerPort: 8080
env:
- name: SECRET_USERNAME
valueFrom:
secretKeyRef:
name: user-pass-secret2
key: username
- name: SECRET_PASSWORD
valueFrom:
secretKeyRef:
name: user-pass-secret2
key: password
---
apiVersion: v1
kind: Service
metadata:
labels:
app: secretapp
name: secretapp-svc
namespace: default
spec:
ports:
- nodePort: 30900
port: 8080
protocol: TCP
targetPort: 8080
selector:
app: secretapp
type: NodePort
k apply -f user-env.yaml
spec.template.spec.containers.env.valueFrom.secretKeyRef 안에
네임과 사용할 키 값을 입력한다.
볼륨으로 Pod에 Secret 제공하기
볼륨으로 마운트해서 파일 형식으로 Pod에 Secret을 제공하는 것도 가능하다.
앞의 파일에서 deployment부분을 아래처럼 변경한다.
Pod내 컨테이너의 env부분이 사라지고 Pod에 볼륨으로 Secret을 선언한 다음
그 볼륨을 다시 컨테이너의 /etc/volume-secret 경로에 마운트한 것을 확인할 수 있다.
$ cat > secret-volume.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: secretapp
labels:
app: secretapp
spec:
replicas: 1
selector:
matchLabels:
app: secretapp
template:
metadata:
labels:
app: secretapp
spec:
containers:
- name: secretapp
image: arisu1000/simple-container-app:latest
ports:
- containerPort: 8080
volumeMounts:
- name: volume-secret
mountPath: "/etc/volume-secret"
readOnly: true
volumes:
- name: volume-secret
secret:
secretName: user-pass-secret2
$ kubectl apply -f secret-volume.yaml
$ kubectl get svc -o wide
$ kubectl get deploy -o wide
$ curl localhost:30900/volume-config?path=/etc/volume-secret/username
$ k get pods
$ k exec -it secretapp-69dd54b7f5-5htjk -- sh
~ # cd /etc/volume-secret
$ ls -al
3. TLS
Secret으로 https 인증서를 저장하는 용도로 사용할 수 있다. 여기서는 공인된 기관에서 발급된 인증서 대신
사설 인증서를 만들어사용한다.
$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout tls.key -out tls.crt -subj "/CN=foo.bar.com"
$ kubectl create secret tls secret-tls \
--key tls.key --cert tls.crt
$ k get secret secret-tls -o yaml
Secret 데이터는 etcd에 암호화되지 않은 평문으로 저장 된다.
만약 누군가 etcd에 직접 접근한다면 Secret의 내용을 확인할 수 있다.
etcd에는 이외에도 중요한 데이터가 많이 있으므로 중요한 서비스에 Kubernetes를
사용 중이라면 etcd에 대한 접근을 제한하는 것이 필요하다.
etcd에 저장되는 Secret을 암호화해서 저장도 가능하지만
Kubernetes 클러스터를 직접 설치해서 사용할 때 옵션으로 별도로 지정해야 한다.