slakcbot 아재개그봇의 경우 일반적인 application 이므로 Deployment
를 생성해 관리한다.
github image registry
에 접근해서 생성한 이미지를 pull 하기 위해 secret
을 생성한다.
kubectl create secret docker-registry <secret이름> --docker-server=<your-registry-server> --docker-username=<your-name> --docker-password=<your-pword> --docker-email=<your-email>
docker-registry
type의 secret
을 생성한다.<your-registry-server>
= github registry 사용하기 위해 https://ghcr.io
<your-name>
= github user name<your-pword>
= pakage 권한이 있는 access token
<your-email>
= github emailkubectl get secret/<secret이름> --output=yaml
결과:
apiVersion: v1
data:
.dockerconfigjson:...
metadata:
creationTimestamp: "2022-12-06T13:33:23Z"
name: juyoung-github
namespace: default
resourceVersion: "988"
uid: 90324fa8-3a86-410b-a99e-4b526251bdaa
type: kubernetes.io/dockerconfigjson
.dockerconfigjson
: 생성할 때 입력한 github registry credentials 의 값들이 base64
로 인코딩 되어 들어있다.kubectl get secret <secret명> --output="jsonpath={.data.\.dockerconfigjson}" | base64 --decode
결과
{"auths":{"https://ghcr.io":{"username":"juyoung810","password":"..","email":"..","auth":...}}}
auth
: 해당 필드의 값은 다음의 명령어로 파악한다.
echo <auth 필드의 값> | base64 --decode
결과⇒ <username>:<password>
따라서 auth
값은 <username>:<password>
를 base64로 인코딩한 값임을 알 수 있다.
Base64 encoding is not an encryption method, it provides no additional confidentiality over plain text.
Secret
은 Base64로 인코딩된 값들이 저장된다.Secret
을 암호화해서 public(git) 에 올려야 한다.Problem:
"I can manage all my K8s config in git, except Secrets."
secret
은 git 과 같은 public 에서 관리할 수 있도록 돕는다.secret
을 SealedSecret
을 통해 암호화할 경우 target cluster
에서 작동하는 controller
에 의해서만 복호화 가능하다.SealedSecret
은 누구나 어떠한 Secret
을 통해 생성할 수 있다. 따라서 cluster 에서 의도된 SealedSecret
만 upload 되도록 설정해야한다.Secret
의 내용이 cluster 바깥에서는 감춰진다는 점이다.Sealed Secrets
은 두 부분으로 구성된다.
controller
/ operator
kubeseal
암호화된 secret 은 SealedSecret
리소스로 생성된다.
apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
name: mysecret
namespace: mynamespace
spec:
encryptedData:
foo: AgBy3i4OJSWK+PiTySYZZA9rO43cGDEq.....
해당 파일을 secret
으로 복호화할 경우
apiVersion: v1
kind: Secret
metadata:
name: mysecret
namespace: mynamespace
data:
foo: YmFy # <- base64 encoded "bar"
SealedSecret
과 Secret
은 반드시 같은 namespace 와 name 을 가진다. 이를 통해 같은 cluster 의 다른 사용자가 sealedsecret 을 재사용하는 것을 방지한다.SealedSecret
- Secret
은 Deployment
- Pod
관계와 비슷하다. SealedSecret
으로 부터 생성된 Secret
은 “dependent object” 이다. 따라서 SealedSecret
이 업데이트 또는 삭제될 경우 Secret
또한 업데이트 또는 삭제된다.1.1 server : 복호화 위한 controller 설치
yaml
파일로 작성된 service
이다.kube-system
namespace 에 sealed-secrets-controlle
가 생성된다.kubectl apply -f https://github.com/bitnami-labs/sealed-secrets/releases/download/v0.19.2/controller.yaml
1.2 client : 암호화 위한 kubeseal 설치
macOS:
brew install kubeseal
linux:
wget https://github.com/bitnami-labs/sealed-secrets/releases/download/<release-tag>/kubeseal-<version>-linux-amd64.tar.gz
tar -xvzf kubeseal-<version>-linux-amd64.tar.gz kubeseal
sudo install -m 755 kubeseal /usr/local/bin/kubeseal
kubeseal
이 알아서 SealedSecret Controller 에 들어있는 인증서를 이용해 SealedSecret
을 만든다.cat 생성한 secret | kubeseal -oyaml > 생성할 sealedsecret 명.yaml
결과 ⇒ sealed secret type 의 파일이 생성된다.
🚫 앞서 sealedsecret 을 생성할 때 사용한 secret
yaml 파일이 그대로 존재할 경우 따로 복호화 되지 않는다.
secret
yaml 파일이 그대로 존재할 경우kubectl get pods --all-namespaces
kubectl logs sealed-secrets-controller-fdc7498d9-4xxxx -n kube-system
kubectl apply -y <sealedsecret.yaml 파일>
결과
sealedsecret
생성secret
생성scp -v <username@원격주소>:~/juya/sealed-juyoung-github.yaml <로컬 주소>
sealed-secret-controller
설치 kubeseal
설치→ controller 를 찾을 수 없어 이런 오류가 발생하는 듯?
cat <secret.yaml 파일> | kubeseal --controller-name=sealed-secrets-controller -oyaml > <생성할 sealed secret 파일명>
apiVersion: apps/v1
kind: Deployment
metadata:
name: ajae-deployment
labels:
app: ajae-bot
spec:
replicas: 1
selector:
matchLabels:
app: ajae-bot
template:
metadata:
labels:
app: ajae-bot
spec: # Pod spec
containers:
- name: ajae-container
image: ghcr.io/cloud-club/gitops-ajaebot # application image
imagePullSecrets: # image pull 받기 위한 github token file (secret)
- name: juyoung-github # github credentials 로 생성한 secret
imagePullSecrets
: kubelet
에게 image registry 접근 정보를 담은 secret
을 전달한다. kubelet
은 pod
를 위해 private image를 pull 할 때 이 정보를 사용한다.💡
imagePullSecrets
필드에 들어가는Secret
은 반드시kubernetes.io/dockercfg
orkubernetes.io/dockerconfigjson
타입이어야한다.
kubectl create secret generic <secret명> --from-literal=<key>=<value>
결과
apiVersion: v1
data:
<key>: <value>
kind: Secret
metadata:
creationTimestamp: "2022-12-06T14:00:55Z"
name: <secret명>
namespace: default
resourceVersion: "2148"
uid: 2302cf1b-082d-4605-b03f-5fb367a10ef9
type: Opaque
spec:
containers:
- name: mycontainer
image: redis
env:
- name: SECRET_USERNAME
valueFrom:
secretKeyRef:
name: <secret명>
key: <key>
optional: false
optional
: 반드시 존재해야함을 명시한다.