Kubernetes #4

임상규·2023년 12월 13일
1

Kubernetes

목록 보기
4/19
post-thumbnail

Kubernetes Object

Ingress

  • Service type은 아니지만 Service 앞에서 Smart router 및 entry point 역할을 하는 오브젝트
  • 외부에서 접근 가능한 URL, Load Balancing, SSL Termination 등을 통해
    Service에 대한 HTTP 기반 접근을 제공
  • 클러스터에 하나 이상의 실행중인 Ingress Controller가 필요
    (e.g. aws-al-controller, nginx ingress)
  • 대외 webapp을 만들었다고 가정했을때, 단순히 nodePort를 이용해 서비스를 노출하면
    사용자가 30000이상의 포트 넘버를 기억하고 접근해야 함.
  • 따라서 일반적으로 proxy를 두고 80 > 3xxxx 포워딩을 하는 layer를 생성

ingress YAML 구조

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  namespace: app
  name: ingress-myapp
  annotations:
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/target-type: ip
spec:
  ingressClassName: alb
  rules:
    - http:
        paths:
        - path: /
          pathType: Prefix
          backend:
            service:
              name: service-1234
              port:
                number: 80

Cluster Autoscaler

Cluster Autoscaler on AWS

  • Amazon EC2 Autoscaling Group의 기능을 이용해 Cluster Autoscaler 구현
  • Cluster Autoscaler가 Deployment 형태로 기동되어 EC2 Autoscaling Group과 상호작용

metricserver_hpa_vpa

metricserver

  • kubernetes 클러스터 리소스 사용량 데이터를 집계하는 역할
  • kubelets에서 리소스 메트릭(예: 컨테이너의 CPU 및 메모리 메트릭)을 수집하고 이를 Metrics API를 통해 apiserver에 노출하여 Horizontal Pod Autoscaler 및 Vertical Pod Autoscaler에서 활용
  • 클러스터 내에 Deployment 형태로 설치
  • Linux에서 top같은 역할

Horizontal Pod Autoscaler

  • Deployment / Replicaset의 레플리카 수를 CPU / 메모리 부하등에 따라 자동으로 스케일 해주는 오브젝트
  • Pod의 Resource Requests를 기준으로 동작
  • metric-server에서 가져온 각 파드의 1분 평균값

Horizontal Pod Autoscaler의 기준

  • cpu (resource)
  • memory (resource)
  • packets-per-second (pod)
  • requests-per-second (ingress)

Horizontal Pod Autoscaler와 Cluster Autoscaler의 상호작용

  • 컨테이너(Pod)의 로드가 증가하면 HPA는 우선 클러스터에 충분한 공간이 있든 없든
    새 replica를 생성
  • 리소스가 충분하지 않은 경우 CA는 HPA에서 생성한 Pod가 실행될 노드를 새로 기동
  • 반대로 로드가 감소하면 HPA는 일부 replica를 삭제하고, 결과적으로 활용되지 않는 노드가 생기면 CA가 이러한 노드를 종료

Horizontal Pod Autoscaler YAML 구조

apiVersion: apps/v1
kind: Deployment
...
spec:
  template:
    metadata:
      name: myapp-deploy
    spec:
      containers:
      - name: nginx
        image: nginx
        resources:
          requests:
            cpu: 1
            memory: "1Gi"
          limits:
            cpu: 3
            memory: "2Gi"
  replicas: 3
  selector:
    matchLabels:
      type: front-end
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: sample-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: myapp-deploy
  minReplicas: 1
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target: 
        type: Utilization
        averageUtilization: 50

Vertical Pod Autoscaler

  • 컨테이너에 할당하는 CPU / 메모리 리소스의 할당을 자동으로 스케일링 해주는 오브젝트
    (= scale up)
  • 서비스 적용 전 Pod resource request에 어떤 값이 적정한지 명확하지 없을 때 유용
  • VPA > HPA > CA 순으로 스케일링 동작

Vertical Pod Autoscaler YAML 구조

apiVersion: apps/v1
kind: Deployment
...
spec:
  template:
    metadata:
      name: myapp-deploy
    spec:
      containers:
      - name: nginx
        image: nginx
        resources:
          requests:
            cpu: 180m
            memory: 50Mi
          limits:
            cpu: 600m
            memory: 100Mi
  replicas: 3
  selector:
    matchLabels:
      type: front-end
apiVersion: 
autoscaling.k8s.io/v1beta2
kind: VerticalPodAutoscaler
metadata:
  name: nginx-vpa
  namespace: vpa
spec:
  TargetRef:
    apiVersion: "apps/v1"
    kind: Deployment
    name: nginx
  updatePolicy:
    updateMode: "Auto"
  resourcePolicy:
    containerPolicies:
    - containerName: "nginx"
      minAllowed:
        cpu: "250m"
        memory: "100Mi"
      maxAllowed:
        cpu: "500m"
        memory: "600Mi"

환경 변수

  • 개별 컨테이너에 설정해야하는 내용을 환경 변수로 전달
  • 예: Timezone, DB 접속 정보 등
  • pod 정의 파일에 환경 변수를 지정하거나 설정파일을 마운트하여 전달

pod에 설정된 환경변수 (env)

apiVersion: v1
kind: Pod
metadata:
  name: nginx-env
spec:
  containers:
    - name: nginx-env
      image: nginx
      ports:
        - containerPort:8080
      env:
        - name: APP_COLOR
          value: pink
# env가 설정된 pod 생성
$ k apply -f env-pod.yaml

# env 확인
$ k exec nginx-env -it -- /bin/sh
$ (pod shell) env

Configmap

  • 워크로드에 필요한 설정 정보를 key-value 형태로 저장할 수 있는 데이터 오브젝트
  • 간단한 환경변수 부터 nginx.conf와 같은 설정 파일도 저장 가능

Configmap 타입 YAML 구조

apiVersion: v1
kind: Configmap
metadata:
  name: test-config
data:
  APP_COLOR: blue
  APP_MODE: prod

configmap 전체를 injection

apiVersion: v1
kind: Pod
metadata:
  name: myapp
spec:
  containers:
    - name: myapp
      image: nginx
      ports:
        - containerPort: 8080
      envFrom:
        - configMapRef:
            name: test-config

configmap 일부를 injection

apiVersion: v1
kind: Pod
metadata:
  name: myapp
spec:
  containers:
    - name: myapp
      image: nginx
      ports:
        - containerPort: 8080
      env:
        - name: APP_COLOR
          valueFrom:
            configMapKeyRef:
              name: test-config
              key: APP_COLOR

Configmap 생성

# 직접 값을 전달하여 생성
$ k create configmap --save-config test2-config --from-literal=app=pink --from-literal=connection.max=100
$ k get cm test2-config -o yaml | yq .data

# 파일에서 값을 참고하여 생성
$ k create configmap --save-config test3-config --from-file=nginx.conf
$ k get cm test3-config -o yaml | yq .data

Configmap 타입 YAML 구조

apiVersion: v1
kind: Configmap
metadata:
  name: test3-config
data:
  nginx.conf: ...

configmap 전체를 injection

apiVersion: v1
kind: Pod
metadata:
  name: myapp
spec:
  containers:
    - name: myapp
      image: nginx
      volumeMounts:
      - name: config-volume
        mountPath: /config
      volumes:
      - name: config-volume
        configMap:
          name: test3-config

configmap 일부를 injection

apiVersion: v1
kind: Pod
metadata:
  name: myapp
spec:
  containers:
    - name: myapp
      image: nginx
      volumeMounts:
      - name: config-volume
        mountPath: /config
    volumes:
    - name: config-volume
      configMap:
        name: test3-config
        items:
        - key: nginx.conf
          path: nginx-sample.conf

Secret

  • 워크로드에 필요한 민감 정보를 key-value 형태로 저장할 수 있는 데이터 오브젝트
  • base64 인코딩 상태로 저장

secret 타입 YAML 구조

apiVersion: v1
kind : Secret
metadata: test-secret
data:
  DB_Host: xxxxx
  DB_User: xxxxxx
  DB_Password: xxxxxx

secret 전체를 injection

apiVersion: v1
kind : Pod
metadata:
  name: myapp
spec:
  containers:
    - name: myapp
      image: nginx
      ports:
        - containerPort: 8080
      envFrom:
        - secretKeyRef:
            name: test-secret

secret 일부를 injection

apiVersion: v1
kind : Pod
metadata:
  name: myapp
spec:
  containers:
    - name: myapp
      image: nginx
      ports:
        - containerPort: 8080
      env:
        - name: DB_Password
          valueFrom:
            secretKeyRef:
              name: test-secret
              key: DB_Password

secret 생성

# 직접 값을 전달하여 생성
$ k create secret generic --save-config test2-secret --from-literal password=test123
$ k get secret test2-secret -o yaml | yq .data
$ echo -n '<인코드값>' | base64 -d

# env 파일 값을 전달하여 생성
$ k create secret generic --save-config test3-secret --from-env-file db-secret.txt
$ k get secret test3-secret -o yaml | yq .data
$ echo -n '<인코드값>' | base64 -d

Volume

  • 스토리지 볼륨을 추상화하여 pod와 느슨하게 결합시킨 리소스
  • 오브젝트의 형태가 아닌 pod 내에서 정의
  • 볼륨 플러그인
    • hostPath
    • nfs
    • iscsi
    • cephfs
    • emptyDir

Volume YAML 구조

emptyDir

apiVersion: v1
kind: Pod
metadata:
  name: test-pd
spec:
  container:
  - image: 
registry.k8s.io/test-webserver
    name: test-container
    volumeMounts:
    - mountPath: /cache
      name: cache-volume
  volumes:
  - name: cache-volume
    emptyDir:
      sizeLimit: 500Mi

hostPath

apiVersion: v1
kind: Pod
metadata:
  name: test-pd
spec:
  container:
  - image: 
registry.k8s.io/test-webserver
    name: test-container
    volumeMounts:
    - mountPath: /test-pd
      name: test-volume
  volumes:
  - name: test-volume
    hostPath:
      # directory location on host path: /data
      # this field is optional type: Directory

Volume의 한계

  • 컨테이너 자신만 접근 가능한 비영구적 볼륨이기 때문에 컨테이너가 재시작할때 유지할 수 없음
  • kubernetes 클러스터 레벨에서 볼륨을 관리하기 어려움
  • volume이 변경될 때마다 해당 volume을 사용하는 모든 pod의 설정 변경 필요

Persistent Volume (PV)

  • 추상화된 가상의 volume 오브젝트로, 별도로 정의 및 생성하여 pod와 연결

Persistent Volume Claim (PVC)

  • PV를 요청하는 오브젝트
  • 용량, label 등을 기반으로 PV에 대한 요청이 들어오면 스케줄러가 현재 가지고 있는 PV에서
    적당한 볼륨을 할당

StorageClass

  • 사용할 스토리지의 "클래스"를 정의
  • 각 프로바이더 (ex.AWS, GCP 등)가 제공하는 볼륨의 종류에 따라 고유한 파라미터를 가짐
# AWS EBS

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: slow
provisioner: kubernetes.io/aws-ebs
parameters:
  type: io1
  iopsPerGB: "10"
  fsType: ext4
profile
Cloud Engineer / DevOps Engineer

0개의 댓글