[CKA] 1주차 Day 4

강아람·2023년 2월 16일
0

CKA

목록 보기
4/22
post-thumbnail

3일차의 Service Part와 이어지는 내용입니다.

Services

ClusterIP

웹 애플리케이션에는 프론트엔드 웹서버 파드, 백엔드 웹서버 파드, 데이터베이스 서버 파드(Redis, MySQL, ...) 세트들이 존재할 수 있다.
프론트엔드 서버는 백엔드 서버와 통신해야 하고, 백엔드 서버는 DB 서버와 통신해야 한다.

노드 내 모든 파드에는 IP 주소가 할당된다. 그러나 이 IP 주소는 동적인 주소이고, 파드가 삭제되고 생성되며 새로운 IP 주소가 할당될 것이다.

🎈 부가 설명
쿠버네티스의 파드 오브젝트는 생성과 삭제가 자유롭다. 파드의 IP 주소는 파드가 생성될 때마다 새로 부여되기 때문에 IP 주소로 통신하는 경우 통신 성공을 보장할 수 없다.


애플리케이션 계층 간 연결을 확립하는 올바른 방법은 무엇일까?

만약 프론트엔드 서버 파드가 백엔드 서버에 요청을 전달해야 한다면 3개의 백엔드 파드 중 어떤 파드에 요청을 전달해야 할까?

이런 상황에서 쿠버네티스 서비스를 통해 백엔드 파드를 하나로 묶고 하나의 인터페이스(Virtual IP)를 통해 파드 세트에 접속할 수 있다. 요청은 무작위로 한 파드에 전달된다.

Service를 통해 쿠버네티스 클러스터에 MSA 구조의 애플리케이션을 쉽고 효과적으로 배포할 수 있다. 또한 다른 계층에 영향을 주지 않고 파드의 개수를 조정하거나 이동시킬 수 있다.


ClusterIP 서비스 생성 방법

🎈 부가 설명

  • Service 타입을 지정하지 않으면 기본적으로 ClusterIP로 설정된다.
  • 이 타입의 서비스는 클러스터 내부에 존재하는 파드 간 통신만 지원한다. (외부에서 접근 불가)

1) 구성 파일 생성

vim service-definition.yml

2) 필수 항목 작성

apiVersion: v1
kind: Service
metadata:
  name: back-end
spec:
  type: ClusterIP
  ports:
  - targetPort: 80
    port: 80
  selector:
    app: myapp
    type: back-end
  • targetPort : 대상 포트
  • port : 서비스가 노출하는 포트

3) 서비스 생성

kubectl create -f service-definition.yml


서비스 생성 확인

kubectl get services



LoadBalancer

앞서 이야기 했던 NodePort 타입 서비스는 외부에서 파드에 접근하기 위해 Node의 특정 Port와 파드에 매핑하는 방식의 서비스이다.

노드 포트 서비스는 노드 포트에 들어오는 트래픽을 각각의 파드로 라우팅 해준다.

그러나 결국에는 사용자가 단일 url로 프로그램에 접속할 수 있도록 해야 한다. 이를 위해서는 새 VM을 생성하여 로드밸런서를 설치하는 방법이 있다.

또 다른 방법으로는 AWS, GCP, Azure 등 클라우드 플랫폼에서 제공하는 LoadBalancer 서비스를 사용하는 것이다.
LoadBalancer 타입 서비스는 노드 포트 서비스의 부하분산을 돕는 서비스이다.

LoadBalancer 사용 방법

서비스 타입에 LoadBalacner를 기입해주면 된다.

apiVersion: v1
kind: Service
metadata:
  name: myapp-service
spec: 
  type: LoadBalancer
  ports:
  - targetPort: 80
    port: 80
    nodePort: 30008

LoadBalacer 타입 서비스는 AWS, GCP, Azure에서는 지원하지만, VM에서 사용할 경우 NodePort 와 같은 서비스를 지원한다. 부하 분산 기능은 수행하지 않는다.



Namespace

우리가 만든 모든 오브젝트는 네임스페이스에 생성되고 있다.

1) Default

지금까지 네임스페이스를 지정하지 않았지만 이 경우에는 쿠버네티스가 자동으로 생성한 Default 네임스페이스를 사용하게 된다.

2) kube-sytstem
쿠버네티스는 내부에 네트워킹 솔루션이나 DNS 서비스에 요구되는 시스템 파드와 서비스들을 생성한다.

사용자가 이 오브젝트들을 삭제하거나 수정하는 것을 막기 위해, 클러스터 생성 시 kube-system이라는 이름의 네임스페이스를 생성해 파드와 서비스를 보호한다.

3) kube-public
모든 사용자가 사용할 수 있는 자원을 구분하는 영역이다.


소규모 시스템이라면 네임스페이스를 신경쓰지 않아도 된다.
하지만 기업에서 사용하는 클러스터 또는 상업용 클러스터의 경우에는 네임스페이스 사용을 고려해야 한다.


Namespace 기능

1) Isolation

예를 들어 개발 및 프로덕션 환경에서 동일한 클러스터를 사용하려는 경우에는 리소스 격리를 위해 각 환경에 대한 고유 네임스페이스를 생성할 수 있다.

이렇게 하면 개발 환경에서 작업하는 동안 프로덕션 리소스를 실수로 수정할 일은 없다.

2) Resource Limits

각 네임스페이스 별로 역할과 정책을 정의할 수 있다.

사용자마다 네임스페이스 별 역할을 지정할 수 있고, 네임스페이스마다 리소스 할당량을 지정할 수 있다.

네임스페이스는 리소스의 일정량을 보장받고, 허용된 한도 이상을 사용하지 않는다.

3) DNS

같은 네임스페이스 내에 존재하는 리소스 간에는 이름으로 통신할 수 있다.

만약 파드가 다른 네임스페이스의 서비스와 통신하려면 서비스 이름에 네임스페이스 이름을 추가하여 접근할 수 있다.

이름으로 통신이 가능한 이유는 서비스가 생성될 때 DNS 항목이 자동으로 추가되기 때문이다.

현재 접근하려는 db 서비스의 전체 이름 중 끝부분을 확인해보면 .cluster.local이라고 되어 있다. 이는 클러스터의 기본 도메인 이름이다.

서비스 이름 다음에 네임스페이스 이름이 나오고, 그 뒤 하위 도메인svc는 서비스 타입을 나타낸다.



Namespace 운영

kubectl get

kubectl get pods

위의 명령은 모든 파드를 출력하는 명령이지만 Default 네임스페이스 내에 있는 파드만 출력한다.

다른 네임스페이스에 있는 파드를 확인하고 싶다면 --namespace 또는 -n 옵션을 사용하면 된다.

kubectl get pods --namespace kube-system


kubectl create

파드를 생성하는 구성 파일이다.
이 파드를 kubectl create 명령으로 생성하는 경우 Default 네임스페이스에 생성될 것이다.
네임스페이스를 지정하여 생성하려는 경우에도 --namespace 옵션을 사용하면 된다.

kubectl create -f pod-definition.yml --namespace=dev

--namespace 옵션을 사용하지 않고, 구성 파일의 metadata 하위 항목에 namespace를 지정할 수 있다.


Namespace 생성

방법 1) 구성 파일

apiVersion: v1
kind: Namespace
metadata:
  name: dev

kubectl create -f namespace-dev.yml

방법 2) kubectl create

kubectl create namespace dev


기본 네임스페이스 변경

우리가 더이상 Default 네임스페이스를 사용하고 싶지 않다면 쿠버네티스가 기본으로 생성, 설정한 네임스페이스를 변경할 수 있다.


만약 dev 네임스페이스를 기본으로 설정하고 싶다면

kubectl config set-context $(kubectl config current-context) --namespace=dev

명령으로 기본 네임스페이스를 dev로 변경할 수 있다.


모든 네임스페이스 리소스 출력

  • pod 출력
kubectl get pods --all-namespaces
  • service 출력
kubectl get services --all-namespaces

Resource Quota (리소스 제한)

네임스페이스 별로 리소스 할당량을 지정하려면 ResourceQuota를 생성하면 된다.

구성파일을 작성하여,

apiVersion: v1
kind: ResourceQuota
metadata: 
  name: compute-quota
  namespace: dev
spec:
  hard:
    pods: "10"
    requests.cpu: "4"
    requests.memory: 5Gi
    limits.cpu: "10"
    limits.memory: 10Gi

오브젝트를 생성한다.

kubectl create -f compute-quota.yaml



Imperative vs Declarative

지금까지 쿠버네티스 오브젝트를 생성, 관리하는 다양한 방법을 알아보았다.

코드로 인프라를 관리하는 방법은 명령적 접근 방식(imperative)선언적 접근 방식(declarative)으로 나뉜다.


접근법

비교를 통해 이해해보자!

명령적 접근 방식 (Imperative)

예전에는 택시 기사님께 목적지까지 가는 방법을 단계별로 알려야 했다.
즉, "B 거리에서 우회전, C 거리에서 좌회전, 다시 D 거리에서 우회전" 이라고 알려야 했다.


선언적 접근 방식 (Declarative)

반면에 요즘에는 택시 기사님께 "~로 가주세요." 한 마디만 하면 택시 기사님이 알아서 목적지까지 데려다준다.


명령적 접근 방식은 어떻게(how) 해야할지에 대해 명시하는 것이고, 선언적 접근 방식은 무엇(What)을 해야할 지 명시하는 것이다.


IaC에서의 접근법

명령적 접근 방식 (Imperative)

무엇이 요구되는지, 어떻게 작업을 수행해야 하는지에 대한 내용이다.


선언적 접근 방식 (Declarative)

요구사항이 선언되어 있다.


인프라에 요구되는 기능을 갖추기 위한 모든 작업은 시스템이나 소프트웨어가 하는 일이므로, 우리는 직접 상세하게 설명하지 않아도 된다.

요구사항을 선언하기만 하면 시스템이 알아서 다 해줄 것이기 때문이다! 😎


쿠버네티스에서의 접근법

명령적 접근 방식 (Imperative)

쿠버네티스의 imperative 방식은 kubectl 커맨드를 사용하는 것이다.

오브젝트를 생성, 수정, 삭제하기 위해 우리의 요구 사항을 쿠버네티스에게 정확히 어떻게 적용해야 하는지 명령한다.

Create Objects

  • kubectl run --image=nginx nginx
  • kubectl create depoyment --image=nginx nginx
  • kubectl expose deployment nginx --port 80

Update Objects

  • kubectl edit deployment nginx
  • kubectl scale deployment nginx --replicas=5
  • kubectl set image deployment nginx nginx=nginx:1.18

장점
생성(Create)과 수정(Update)에 관한 명령은 yaml 파일 없이 오브젝트 생성과 수정을 빠르게 할 수 있게 해준다.

단점
그러나 기능에 한계가 있기 때문에 추가적인 옵션이 많다면 명령이 길고 복잡해진다.

또한 이 명령은 한 번 실행하는 일회성 명령이기 때문에 사용자의 세션 히스토리에서만 다시 볼 수 있고, 어떻게 생성되었는지 알아내기 힘들다.

Manifest

따라서 매니페스트(오브젝트 정의 파일, 구성 파일이라고 불리는)를 사용할 수 있다. 파일 형태이기 때문에 git과 같은 레포지토리에 저장할 수 있다.

매니페스트에 yaml 포맷으로 오브젝트의 정보를 입력하고, kubectl 생성 명령으로 생성할 수 있다.

또한 오브젝트의 상태를 수정하려면 매니페스트의 내용을 수정한 후 kubectl replace 명령으로 수정된 내용을 적용하면 된다.

  • kubectl create -f nginx.yml
  • kubectl replace -f nginx.yml
  • kubectl delete -f nginx.yml

명령정 접근은 관리자에게 매우 까다로운 접근법이다.
항상 현재 환경에 대해 인지하고 변경하기 전에 확인해야 하기 때문이다.


선언적 접근 방식 (Declarative)

쿠버네티스의 declarative 방식은 클러스터에 애플리케이션 및 서비스의 상태를 정의하는 파일을 생성하여 kubectl apply 커맨드로 쿠버네티스에게 선언하는 것이다.

Create Objects

  • kubectl apply -f nginx.yaml
  • kubectl apply -f /path/to/config-files

Update Objects

  • kubectl apply -f nginx.yaml

kubectl apply 명령을 사용할 경우, 파일에 정의된 오브젝트를 생성, 수정할 수 있다.

오브젝트 구성 파일이 여러 개라면 파일이 아닌 디렉터리 경로를 지정하여 한번에 생성할 수 있다.

오브젝트를 수정할 때에도 구성 파일을 수정한 후 다시 kubectl apply 명령을 실행하면 이미 존재하는 오브젝트를 업데이트 한다. 오브젝트의 존재를 알고 있기 때문에 오류가 발생하지 않는다.



💯 시험 팁!

시험에서는 명령적 접근을 사용하면 시간을 절약할 수 있다.

주어진 이미지로 파드나 디플로이를 생성해야 하는 경우, 존재하는 오브젝트의 속성을 수정해야 하는 경우 명령적 접근으로 빠르게 풀 수 있다.

복잡한 요구사항을 만족해야 하는 경우에는 매니페스트를 사용하는 것이 더 좋을 수 있다.

0개의 댓글