컨테이너 오케스트레이션을 위한 Kubernetes (22.05.24)

박민선·2022년 5월 24일
0

ConfigMap & Secret

환경변수

pods.spec.containers.env

  • name
  • value
apiVersion: v1
kind: Pod
metadata:
  name: myweb-env
spec:
  containers:
    - name: myweb
      image: ghcr.io/c1t1d0s7/go-myweb:alpine
      env:
        - name: MESSAGE
          value: "Customized Hello World"

ConfigMap

사용 용도:

  • 환경 변수
  • 볼륨/파일
    - 설정파일
    - 암호화 키/인증서

환경 변수

mymessage.yaml

apiVersion: v1
kind: ConfigMap
metadata:
  name: mymessage
data:
  MESSAGE: Customized Hello ConfigMap

myweb-env.yaml

apiVersion: v1
kind: Pod
metadata:
  name: myweb-env
spec:
  containers:
    - name: myweb
      image: ghcr.io/c1t1d0s7/go-myweb:alpine
      envFrom:
        - configMapRef:
            name: mymessage
apiVersion: v1
kind: Pod
metadata:
  name: myweb-env
spec:
  containers:
    - name: myweb
      image: ghcr.io/c1t1d0s7/go-myweb:alpine
      env:
        valueFrom:
          configMapKeyRef:
            name: mymessage
            key: MESSAGE

configMapRef 와 configMapKeyRef의 차이
configMapRef은 환경변수 전체를 읽음
configMapKeyRef에 지정한 키값만 읽음

파일

myweb-cm-vol.yaml

apiVersion: v1
kind: Pod
metadata:
  name: myweb-cm-vol
spec:
  containers:
    - name: myweb
      image: ghcr.io/c1t1d0s7/go-myweb:alpine
      volumeMounts:
        - name: cmvol
          mountPath: /myvol

  volumes:
    - name: cmvol
      configMap:
        name: mymessage

Secret

value --base64--> encoded data
(base64로 인코딩하다보니 암호화되지 않아 안전하지 않음)

안전을 위해 다른 서비스와 같이 사용
Hashicorp Vault
AWS KMS
...

환경 변수

mydata.yaml

apiVersion: v1
kind: Secret
metadata:
  name: mydata
type: Opaque
data:
  id: YWRtaW4K          #base64 인코딩한 값 (ex. admin)
  pwd: UEBzc3cwcmQK     #base64 인코딩한 값 (ex. password)
base64
admin
(값)  #이 값을 id와 pwd에 복사
kubectl describe secret mydata      #안보임
kubectl get secret mydata -o yaml   #보임 (인코딩된 값)
apiVersion: v1
kind: Pod
metadata:
  name: myweb-secret
spec:
  containers:
    - name: myweb
      image: ghcr.io/c1t1d0s7/go-myweb:alpine
      envFrom:
        - secretRef:
            name: mydata
apiVersion: v1
kind: Pod
metadata:
  name: myweb-env
spec:
  containers:
    - name: myweb
      image: ghcr.io/c1t1d0s7/go-myweb:alpine
      env:
        valueFrom:
          secretKeyRef:
            name: mydata 
            key: id

파일

apiVersion: v1
kind: Pod
metadata:
  name: myweb-sec-vol
spec:
  containers:
    - name: myweb
      image: ghcr.io/c1t1d0s7/go-myweb:alpine
      volumeMounts:
        - name: secvol
          mountPath: /secvol

  volumes:
    - name: secvol
      secret:
        secretName: mydata

Deployments (deploy)

Pod와 ReplicaSet에 대한 선언적 업데이트 제공

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myweb-deploy
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
        - name: myweb
          image: ghcr.io/c1t1d0s7/go-myweb:v1
          ports:
            - containerPort: 8080

Deployments에서 사용 가능한 스토리지

recreate

  • 장점
    셋업이 쉽다
    애플리케이션은 완전히 갱신됨

  • 단점
    다운타임이 발생한다

ramped(rolling-update)

  • 장점
    무중단 24//7
    버전이 천천히 배포
    db쉽게 이동

  • 단점
    롤아웃/롤백이 시간이 걸림
    다중api 지원이 어렵다
    트래픽 컨트롤방법이 없다

blue/green

  • 특징
    recreate와 차이 - 리소스가 더 많이 필요하다
    다운타임 최소화
    비싸다

canary

  • lb에 일정비율로 배포할 수 있는 기능이 있어야함

a/b testing

  • browser,user-agent등의 정보를 통한 접속 분리 (client 구별)

shadow

  • 고급 기술이 필요

apiVersion: v1
kind: Service
metadata:
  name: myweb-svc-lb
spec:
  type: LoadBalancer
  selector:
    app: web
  ports:
    - port: 80
      targetPort: 8080
kubectl rollout status deploy myweb-deploy
kubectl rollout history deploy myweb-deploy

image 변경 시
replace, apply, edit, patch, set

kubectl set image deployments myweb-deploy myweb=ghcr.i
o/c1t1d0s7/go-myweb:v2.0 --record

--record: 명령을 히스토리에 저장

record를 붙여야 history에서 사유가 작성됨(change case)

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myweb-deploy
  annotations:
    kubernetes.io/change-cause: "Change Go Myweb version from 3 to 4"
    ...
kubectl apply -f myweb-deploy.yaml

(apply 할때 레코드를 작성하면 history에서 변경 된 파일의 수정 내용을 모르지만 annotaion을 작성하면 알 수 있음)
-단 annotaion 작성하면 record는 붙이지 않음

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myweb-deploy
  annotations:
    kubernetes.io/change-cause: "Change Go Myweb version from 3 to 4"
spec:
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
  replicas: 3
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
        - name: myweb
          image: ghcr.io/c1t1d0s7/go-myweb:v4.0
          ports:
            - containerPort: 8080

max surge

(default: 25%) replicas기본3개 서지1개
롤아웃 시 3+1 =4 개 파드가 생성 가능
기본값은 절대값 및 퍼센트로 지정가능

max unavailable

(default: 25%) 파드 삭제 개수
(rs는 지우지 않음 rollback을 위해)

minReadySeconds

최소대기시간
기본값:0
파드가 준비상태까지의 대기시간 설정

revisionHistoryLimit

기본값:10
히스토리 개수


TLS/SSL Termination with Ingress

SSL3.0과 TLS 1.0은 호환 가능
SSL은 취약점이 발견되어 사용하지 않음

client <-->LB<-->nginx pod https
      https   https
       <--------->
      end to end 방식
                  < Private networ >
           Esposed SSL
client <-> Termination <--> webservice
             Proxy
       https           http
      <---->
   이 구간만 암호화

Proxy 에서만 인증서 인증을 할 수 있음
webservice가 인증 받을 필요가 없음

비암호화 구간이 있어야 공격을 탐지할 수 있음
암호화 구간에서는 공격도 암호화가 되어 탐지가 어려움

암복호화가 메모리를 많이 사용함

ingress-tls-secret.yaml

apiVersion: v1
kind: Secret
metadata:
  name: ingress-tls-secret
type: kubernetes.io/tls
data:
  # base64 x509/nginx-tls.crt -w 0
  tls.crt: |
    LS0tLS1CRUd...
  # base64 x509/nginx-tls.key -w 0
  tls.key: |
    LS0tLS1CRUdJ...

myweb-rs.yaml

apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: myweb-rs
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web
      env: dev
  template:
    metadata:
      labels:
        app: web
        env: dev
    spec:
      containers:
        - name: myweb
          image: ghcr.io/c1t1d0s7/go-myweb
          ports:
            - containerPort: 8080
              protocol: TCP

myweb-svc-np.yaml

apiVersion: v1
kind: Service
metadata:
  name: myweb-svc-np
spec:
  type: NodePort
  selector:
    app: web
  ports:
    - port: 80
      targetPort: 8080

myweb-ing-tls.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: myweb-ing-tls
spec:
  tls:
    - hosts:
        - '*.nip.io'
      secretName: ingress-tls-secret
  rules:
    - host: '*.nip.io'
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: myweb-svc-np
                port:
                  number: 80
curl -k https://192-168-100-100.nip.io
profile
클라우드신생아

0개의 댓글