4. Deployment.yaml 파일 작성하기

jjuyaa·2023년 4월 17일
0

GitOps

목록 보기
4/7

slakcbot 아재개그봇의 경우 일반적인 application 이므로 Deployment 를 생성해 관리한다.

1. private registry 접근 위한 k8s secret 만들기

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 email

yaml 파일로 확인하기

kubectl 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 로 인코딩 되어 들어있다.

base64 로 decoding 해 값 확인해보기

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로 인코딩한 값임을 알 수 있다.

1.2 Sealed Secrets

Sealed Secrets 사용하는 이유

Base64 encoding is not an encryption method, it provides no additional confidentiality over plain text.

  • Secret 은 Base64로 인코딩된 값들이 저장된다.
  • Base64 인코딩은 암호화가 아니기 때문에 public 에 공개할 경우 모든 사람이 디코딩해 접근할 수 있다.
  • 따라서 Secret 을 암호화해서 public(git) 에 올려야 한다.

Sealed Secrets 이란?

Problem:
"I can manage all my K8s config in git, except Secrets."

  • secret 은 git 과 같은 public 에서 관리할 수 있도록 돕는다.
  • secretSealedSecret 을 통해 암호화할 경우 target cluster 에서 작동하는 controller 에 의해서만 복호화 가능하다.
  • SealedSecret 은 누구나 어떠한 Secret 을 통해 생성할 수 있다. 따라서 cluster 에서 의도된 SealedSecret 만 upload 되도록 설정해야한다.
  • 기존 k8s 와 유일한 다른 점은 Secret 의 내용이 cluster 바깥에서는 감춰진다는 점이다.

https://cloudyuga.guru/rails/active_storage/blobs/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaEpJaWsyWkRJMk1qa3dPUzB5TnpZMExUUTFaVGN0T1RNMU55MDBaVFUzTXprMk1qSmpNalVHT2daRlZBPT0iLCJleHAiOm51bGwsInB1ciI6ImJsb2JfaWQifX0=--f423a1e8dc5b4ef5efdedd6ba33c93ee9f753be7/Blog_image-2.jpg

SealedSecret

Sealed Secrets 은 두 부분으로 구성된다.

  • cluster 에서 사용하는 controller / operator
  • client 가 사용하는 암호화 도구 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"
  • SealedSecretSecret 은 반드시 같은 namespace 와 name 을 가진다. 이를 통해 같은 cluster 의 다른 사용자가 sealedsecret 을 재사용하는 것을 방지한다.
  • SealedSecret - SecretDeployment - Pod 관계와 비슷하다. SealedSecret 으로 부터 생성된 Secret 은 “dependent object” 이다. 따라서 SealedSecret 이 업데이트 또는 삭제될 경우 Secret 또한 업데이트 또는 삭제된다.

사용 방법

1. 설치

1.1 server : 복호화 위한 controller 설치

  • 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

2. Controller 내부 인증서 사용해 암호화

  • 특별한 옵션 사용하지 않을 경우 kubeseal 이 알아서 SealedSecret Controller 에 들어있는 인증서를 이용해 SealedSecret 을 만든다.
cat 생성한 secret | kubeseal -oyaml > 생성할 sealedsecret 명.yaml

결과 ⇒ sealed secret type 의 파일이 생성된다.

3. 복호화 해보기


🚫 앞서 sealedsecret 을 생성할 때 사용한 secret yaml 파일이 그대로 존재할 경우 따로 복호화 되지 않는다.

  • secret yaml 파일이 그대로 존재할 경우
    1. controller 확인 : kubectl get pods --all-namespaces
    2. controller 의 log 확인 : kubectl logs sealed-secrets-controller-fdc7498d9-4xxxx -n kube-system
kubectl apply -y <sealedsecret.yaml 파일> 

결과

  1. sealedsecret 생성
  2. controller 에 의해 복호화된 secret 생성

local 로 sealed-* yaml 옮기기

scp -v <username@원격주소>:~/juya/sealed-juyoung-github.yaml <로컬 주소>

local 에서 sealedsecret 생성하기

  1. docker & minikube start
  2. minikube 에 sealed-secret-controller 설치
  3. mac 에 kubeseal 설치
  4. sealed-secret 생성
  • controller 명을 명시하지 않을 경우
    error: cannot fetch certificate: error trying to reach service: dial tcp 172.17.0.2:8080: connect: connection refused

→ controller 를 찾을 수 없어 이런 오류가 발생하는 듯?

cat <secret.yaml 파일> | kubeseal --controller-name=sealed-secrets-controller -oyaml > <생성할 sealed secret 파일명>

2. Deployment yaml 파일 작성하기

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 을 전달한다. kubeletpod 를 위해 private image를 pull 할 때 이 정보를 사용한다.

💡 imagePullSecrets 필드에 들어가는 Secret 은 반드시 kubernetes.io/dockercfg
or kubernetes.io/dockerconfigjson 타입이어야한다.

3. secret 환경 변수로 넣기

generic key 생성하기

 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

yaml 파일에 작성

spec:
  containers:
  - name: mycontainer
    image: redis
    env:
      - name: SECRET_USERNAME
        valueFrom:
          secretKeyRef:
            name: <secret명>
            key: <key>
            optional: false

optional: 반드시 존재해야함을 명시한다.

4. 결과

참고

  1. 프라이빗 레지스트리에서 이미지 받아오기
  2. Deployments
  3. 이미지
  4. kubectl을 사용한 시크릿 관리
  5. GitHub - bitnami-labs/sealed-secrets: A Kubernetes controller and tool for one-way encrypted Secrets

0개의 댓글