목차

Kubernetes Foundation #2

🗓️

실습 환경 구성에 kind 활용할것

HPA (Horizontal Pod Scaler)

https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough/
https://kubernetes.io/docs/reference/kubectl/generated/kubectl_autoscale/

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: apache-serevr
  namespace: autoscale
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: apache-serevr
  minReplicas: 1
  maxReplicas: 4
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 50
behavior:
  scaleDown:
    stabilizationWindowSeconds: 30

만약 명령어로 한다면..

kubectl autoscale deployment apache-server \
--namespace autoscale \
--cpu-percent=50 \
--min=1 \
--max=4 
kubectl get hpa -n autoscale

NodePort

https://kubernetes.io/docs/concepts/services-networking/service/#nodeport-custom-port

서비스에는 3가지 유형이 있음.
ClusterIP, NodePort, Loadbalancer

kubectl edit deployment front-end -n spline-reticulator
## or..
kubectl get deplotment front-end -n spline-reticulator -o yaml > frontend.yaml

1. spec – container – image에 포트 추가

ports:
- containerPort: 80
  protocol: TCP

2. 명령어

kubectl set container-port deployment/front-end \
nginx=80 -n spline-reticulator

Side-car

https://kubernetes.io/docs/reference/kubectl/generated/kubectl_set/kubectl_set_image

쿠버네티스에서 Sidecar(사이드카)는 한 파드(Pod) 안에서 메인 컨테이너와 함께 실행되며, 보조 역할을 수행하는 컨테이너

  • Sidecar도 컨테이너 하나이므로 리소스 제한, 로그, 상태 관리를 따로 해야 함.
  • Pod 내 컨테이너 간에는 localhost, volume 등 리소스를 공유하므로 동기화와 권한 관리에 주의
  • Pod가 재시작되면 모든 컨테이너가 함께 재시작됨 (즉, 사이드카 실패도 영향을 줄 수 있음).

선언

apiVersion: apps/v1
kind: Deployment
metadata:
  name: synergy-leverafer
  labels:
    app: synergy-leverafer
spec:
  replicas: 1
  selector:
    matchLabels:
      app: synergy-leverager
    spec:
      containers:
      - name: app
        image: nginx:latest
        volumeMounts:
        - name: log-volume
        mountPath: /var/log
      - name: sidecar
        image: busybox:stable
        command: ["..."]
        volumeMounts:
        - name: log-volume
          mountPath: /var/log
      volumes:
      - name: log-volume
        emptyDir: {}

명령

kubectl set image deployment/synergy-leverager \
sidecar=busybox:stable --record

확인

kubectl get deployment
kubectl describe deployment synergy-leverager

사이드카 확인

kubectl logs -f synergy-leverager-AAAAA -c sidecar

PriorityClass

Pod의 우선순위를 정의하기 위해 사용되는 리소스
이는 노드 리소스가 부족한 상황에서 어떤 Pod을 먼저 종료(evict)하고, 어떤 Pod을 유지할지를 결정하는 데 중요한 역할을 함.

  1. Pod 생성 시 우선순위 평가
    Pod이 생성되면 priorityClassName에 따라 정수 우선순위(value)가 설정됨.
  2. 스케줄러 동작에 영향
    스케줄러는 리소스 부족 시 낮은 우선순위 Pod보다 높은 우선순위 Pod을 먼저 배치하려 함.
  3. Preemption (선점)
    만약 노드에 충분한 리소스가 없어도 높은 우선순위 Pod이 생성되면,
    낮은 우선순위의 Pod을 종료(evict) 시키고 공간을 확보함.

선언형

apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
  name: critical-priority
value: 1000000 ## 정수값. 값이 높을수록 우선순위가 높음
globalDefault: false ## true인 경우 명시적으로 priorityClassName이 없는 Pod에 기본 적용됨
description: "Critical priority class for system components"
apiVersion: v1
kind: Pod
metadata:
  name: critical-pod
spec:
  priorityClassName: critical-priority
  containers:
    - name: nginx
      image: nginx

명령형

kubectl create priorityclass <name> \
--value=1000 --description="description" 

확인

kubectl get priorityclass
kubectl describe priorityclass <name>

시험환경

kubectl create deployment busybox-logger --image=busybox \
--namespace=priority --replicas=2 \
-- sh c "while true; do echo 'logging.."; sleep 10; done"

시험

https://kubernetes.io/docs/reference/kubectl/generated/kubectl_patch

StorageClass

쿠버네티스에서 동적 볼륨 프로비저닝(Dynamic Volume Provisioning)을 가능하게 해주는 스토리지의 “템플릿”

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: fast
provisioner: kubernetes.io/aws-ebs     # 스토리지를 생성해줄 플러그인
parameters:
  type: gp2                            # EBS 볼륨 타입
reclaimPolicy: Retain                 # 삭제 시 동작 (Retain / Delete)
volumeBindingMode: WaitForFirstConsumer  # 바인딩 시점
  • reclaimPolicy: PVC 삭제 시 PV를 삭제할지(Delete) 보존할지(Retain) 결정
  • volumeBindingMode: Immediate(즉시 바인딩) 또는 WaitForFirstConsumer(Pod이 배치될 때까지 대기)

PersistentVolumeClaim / PersistentVolume

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: local-storage
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mariadb-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 64Mi              # PV보다 작거나 같아야 함
  storageClassName: standard 
apiVersion: v1
kind: PersistentVolume
metadata:
  name: mariadb-pv
spec:
  capacity:
    storage: 128Mi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  storageClassName: standard
  hostPath:
    path: "/tmp/var/lib/mysql"
kubectl get pvc mariadb-pvc
kubectl describe pvc mariadb-pvc
kubectl get pv mariadb-pv

Helm

  • helm install, helm upgrade, helm uninstall 사용법
  • -f values.yaml 옵션을 통한 설정값 오버라이딩
  • helm repo add, helm search, helm list 등 CLI 활용
  • 간단한 Helm chart 구조 이해 (templates, values.yaml, Chart.yaml)
  • 실습 환경에서 nginx 또는 redis 등 chart로 배포

CRD

 CRD (CustomResourceDefinition)는 사용자가 쿠버네티스에 새로운 리소스 타입을 정의할 수 있도록 해주는 기능.

  • kubectl explain <resource> 명령으로 CRD 확인
  • kubectl apply -f <crd.yaml> 으로 CRD 생성
  • CRD 기반 리소스를 생성하는 방법 (kubectl apply -f <custom-resource>.yaml)
  • Operator 패턴에서의 CRD 역할 이해
helm repo list
helm repo add arrgo http://~~~
helm repo update

ArgoCD 배포

helm template argocd argo/argo-cd --version=7.3 \
--namespace argocd --set crds.install=false \
> ~/argo-helm.yaml

Recovery deployment and assure data continuous

MariaDB namespace 복구

  • PVC 생성
kubectl apply -f pvc.yaml
kubectl get pv -n mariadb # request
kubectl get pvc -n mariadb # pending..

mariadb deployment 작성시 spec – volumes 내 persistentVolumeClaim 항목 추가

volumes:
- name: mariadb-storage
  persistentVolumeClaim:
    claimName: mariadb
kubectl apply -f mariadb-deployment.yml
kubectl get deployment -n mariadb
kubectl get pvc -n mariadb # bound! 

Gateway and HTTPRoute

https://kubernetes.io/docs/concepts/services-networking/gateway
  • GatewayClass : 어떤 종류의 Gateway를 사용할지 정의하는 클러스터 전체 리소스. (클래스 개념, IngressClass와 유사)
  • Gateway : 실제 로드밸런서와 유사한 리소스. 특정 네임스페이스에 배치되며 트래픽을 수신함.
  • HTTPRoute : Gateway가 수신한 HTTP 요청을 어떤 서비스로 라우팅할지 정의. (Ingress와 유사)
  • TCPRoute/GRPCRoute : HTTP 이외의 프로토콜 라우팅용.
kubectl create deployment web-app --image=nginx --replicas=1
kubectl get deployment
kubectl expose deployment web-app --name=web-service --port=80
kubectl get svc
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: web-gateway
spec:
  gatewayClassName: nginx
  listeners:
  - name: https
    protocol: HTTPS
    port: 443
    hostname: gateway.web.k8s.local
    tls:
      mode: Terminate
      sertificateRefs:
      - kind: Secret
        name: web-tls
kubectl get gateway web-gateway
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: web-route
spec:
  parentRefs:
  - name: web-gateway
  hostnames:
  - gateway.web.k8s.local
  rules:
  - matches:
    - path:
        type: PathPrefix
        value: /
    backendRefs:
    - name: web-service
      port: 80
kubectl get httproute

CNI Container Network Interface

Pod 간 통신을 가능하게 해주는 네트워크 플러그인 시스템. CNI는 Kubernetes 자체 기능이 아니라 CNCF에서 정의한 표준 인터페이스로, 다양한 네트워크 구현체들이 이 CNI 사양을 따름

  • Flannel
  • Calico
  • 등등.

필요한 CNI를 apply로 설치한다.

kubectl apply -f ~
kubectl get pod -n kube-system

두 개의 Pod가 서로 통신할 수 없습니다. 원인을 파악하고 해결하세요.

  1. kubectl get pods -A로 CNI 관련 Pod 상태 확인
  2. kubelet 로그에서 CNI 관련 에러 확인
  3. /etc/cni/net.d/가 비었는지 확인
  4. 필요 시 CNI 플러그인 설치

Web application Troubleshooting

  • Divide node resources evenly across all 3 pods.
  • Give each pod a fair share of CPU and memory.
  • Add enough overhead to keep the node stable.
  • Use exact same requests for both containers and init containers.
    Scale down the wordpress deployment to 0 replicas while updating the resource requests.
  • After updates, confirm: wordpress keeps 3 replicas, All pods are running and ready.

환경 준비

apiVersion: apps/v1
kind: Deployment
metadata:
  name: wordpress
spec:
  replicas: 3
  selector:
    matchLabels:
      app: wordpress
  template:
    metadata:
      labels:
        app: wordpress
    spec:
      initContainers:
      - name: init-wordpress
        image: busybox
        command: ["sh", "-c" "echo Init.. && sleep 5"]
      containers:
      - name: wordpress
        image: wordpress:latest
        ports:
        - containerPort: 80
kubectl apply -f wordpress.yml
kubectl get deployment

문제풀이과정

https://kubernetes.io/docs/reference/kubectl/generated/kubectl_scale
kubectl scale deployment wordpress --replicas=0
kubectl get deployment

가용 가능한 리소스 확인

kubectl describe node <NODE> 
  • CPU
  • Memory
kubectl patch deployment wordpress -p \
'{"spec": {"template": {"spec": {"containers": [{"name": "wordpress", "resources": {"requests": {"cpu": "1000m", "memory": "1Gi"}}]}}}}'

혹은..

kubectl get deployment wordress -o yaml > wordpress.yaml
# 수정
kubectl apply -f wordpress.yaml

이때 주의할점

  • status
  • metadata.creationTimestamp
  • metadata.generation
  • metadata.resourceVersion
  • metadata.uid
  • metadata.managedFields
  • metadata.annotations.kubectl.kubernetes.io/last-applied-configuration

CRI-DOCKERD

https://kubernetes.io/docs/setup/production-environment/container-runtimes

cri-dockerd 적용

  1. 이미 패지키 파일을 제공함
  2. 커널 수정

ubuntu

dpkg -i <DEB_FILE>
systemctl enable --now cri-docker

kernel

# sysctl params required by setup, params persist across reboots
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.ipv4.ip_forward = 1
EOF

# Apply sysctl params without reboot
sudo sysctl --system
sysctl net.ipv4.ip_forward

CRD describe 추출 관련

kubectl get crd | grep cert
## cert-manager.crds.yaml..
kubectl get grd | grep gert
## 특정 crd 지정해줄것..
kubectl get crd <CRD_NAME> \
-o jsonpath={.spec.versions[*].schema.openAPIV3Schema.properties.spec.properties.subject}

🏷️