쿠버네티스를 통한 배포를 위해 설정해야 하는 세 가지(Deployment, Service, Ingress)의 개념과 사용법을 정리한 포스트입니다. 🧩
쿠버네티스 디플로이먼트
디플로이먼트(deployment)는 파드와 레플리카셋에 대한 업데이트를 선언하는 영역입니다. Desired state(이상적인 상태)를 디플로이먼트에 기술하고 디플로이먼트 컨트롤러가 현재 상태를 desired state로 변경합니다.
다음은 디플로이먼트 예시 코드로, 3개의 nginx 파드를 불러오기 위한 레플리카셋을 생성합니다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
.metadata.name
생성할 디플로이먼트의 이름을 지정합니다. (nginx-deployment).spec.replicas
이 디플로이먼트가 생성할 레플리카 파드의 개수를 지정합니다. (3개).spec.selector
디플로이먼트가 관리할 파드를 찾는 방법을 정의합니다. 이 사례에서는 파드 템플릿에 정의된 레이블(app: nginx)을 선택합니다. 파드 템플릿 자체의 규칙을 만족한다면 이것보다 더 정교한 선택 규칙을 적용할 수 있습니다..spec.template
다음 하위 필드들이 포함되어 있습니다..metadata.labels
파드에 레이블을 붙입니다. (app: nginx).spec
파드가 실행할 도커 컨테이너의 이름, 사용하는 도커 이미지, 컨테이너가 사용할 포트 번호를 지정합니다. (컨테이너 이름: nginx, 도커 이미지: nginx:1.14.2, 컨테이너 포트 번호: 80)쿠버네티스 서비스
파드셋에서 실행중인 애플리케이션을 네트워크 서비스로 노출시키는 추상화 방법입니다. 파드는 클러스터 상태와 일치하도록 생성/삭제되기 때문에, 각 파드가 고유한 IP를 가지긴 하지만 디플로이먼트를 사용해 앱을 실행하면 어느 한 시점에서 실행된 파드 셋이 잠시 후 실행되는 해당 파드 셋과 다를 수 있습니다.
따라서 쿠버네티스에서는 서비스라는 개념을 이용해 파드의 논리적 집합과 그것들에 접근할 수 있는 정책을 정의합니다. 서비스 추상화를 이용하면 백엔드를 구성하는 실제 파드는 변경되더라도 프론트엔드 클라이언트는 이를 인식할 필요가 없습니다.
다음은 서비스 예시 코드로, TCP 9376번 포트에서 수신하고 app=MyApp 레이블을 가지고 있는 파드셋이 있다고 가정합니다.
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: MyApp
ports:
- protocol: TCP
port: 80
targetPort: 9376
.metadata.name
생성할 서비스 이름을 지정합니다. (my-service).spec.selector
셀렉터와 일치하는 파드를 지속적으로 검색하고, 해당 이름(위 경우 my-service)을 가지는 엔드포인트 오브젝트에 대한 모든 업데이트를 POST합니다.쿠버네티스 인그레스
쿠버네티스 인그레스(Ingress)란
클러스터 외부에서 클러스터 내부 서비스로 HTTP, HTTPS 경로를 노출합니다. 인그레스 리소스에 정의된 규칙에 의해 트래픽 라우팅을 컨트롤할 수 있습니다.
Ingress가 없다면 | Ingress Controller가 있다면 |
인그레스는 단지 인그레스 규칙을 정의하는 선언적인 오브젝트(혹은 리소스)일 뿐 실제로 외부 요청을 받아들이는 서버가 아니므로, 인그레스를 Ingress Controller라고 하는 특수한 서버 컨테이너에 적용해야만 인그레스 규칙이 활성화됩니다.
쿠버네티스 인그레스 컨트롤러
인그레스 컨트롤러가 외부로부터 네트워크 요청을 수신하면, 인그레스 규칙에 기반하여 이 요청을 어떻게 처리할 것인지를 결정합니다.
쿠버네티스에서는 AWS, GCE, nginx 인그레스 컨트롤러를 지원하고 유지하고 있습니다.
다음은 최소한의 인그레스 정보를 담은 리소스 예시 코드입니다.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: minimal-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: / # 트래픽이 리다이렉트될 타겟 URI
spec:
rules: # host를 명시하지 않았으므로 ip로 연결
- http:
paths: # 각 puth는 백엔드와 연결됨
- path: /testpath
pathType: Prefix
backend: # 연결될 서비스 이름과 포트
service:
name: test
port:
number: 80
쿠버네티스를 통해 애플리케이션을 배포하기 위해서는 세 가지 영역을 설정해야 합니다. 클러스터의 desired state를 기술한 Deployment, 이를 네트워크 서비스로 노출시키는 Service, 그리고 클러스터 외부에서 클러스터 내부의 서비스로 접근할 수 있게 만들어주는 Ingress가 바로 그것입니다!
Ingress를 작성하지 않더라도 서비스 자체를 띄우고 포트 포워딩을 통해 서비스에 접속할 수는 있습니다. 하지만 프로덕션 단계에서는 클러스터 외부에서도 서비스에 접속이 가능해야하기 때문에 이때 Ingress 설정이 필요합니다. 🏅