[gRPC 시작에서 운영까지] 2장_gRPC 시작

위와 같은 온라인 판매 시스템을 만들어보자.

서비스 정의 작성

gRPC 애플리케이션을 개발할 때, 가장 먼저 할 일은 클라이언트가 원격으로 호출할 수 있는 메서드와 메서드의 파라미터, 사용자 메시지 포맷 등을 포함하는 서비스 인터페이스를 정의하는 것이다.
서비스 정의는 gRPC 에서 사용되는 인터페이스 정의 언어 (==IDL) 인 프로토콜 버퍼 정의로 작성된다.

메세지 정의

1
2
3
4
5
6
7
8
9
10
message Product {
string id = 1;
string name = 2;
string description = 3;
float price = 4;
}

message ProductID {
string value = 1;
}

위에서, 각 메세지 필드에 정의된 번호는 메세지에서 필드를 고유하게 식별하는데 사용된다.

서비스 정의

서비스는 클라이언트에게 제공되는 원격 메서드의 모임이다.
위에서 작성한 Product message, ProductID message 와 같이 작성하자.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package ecommerce;

service ProductInfo {
rpc addProduct(Product) returns (ProductID);
rpc getProduct(ProductID) returns (Product);
}

message Product {
string id = 1;
string name = 2;
string description = 3;
float price = 4;
}

message ProductID {
string value = 1;
}
Read more

[gRPC 시작에서 운영까지] 1장_gRPC 소개

gRPC

gRPC 는 로컬 함수를 호출하는 것 만큼 쉽게 분산된 이기종 애플리케이션을 연결, 호출, 운영, 디버깅할 수 있는 프로세스 간 통신 기술이다.
gRPC 애플리케이션을 개발할 때 가장 먼저 해야할 일은, 서비스 인터페이스를 정의하는 것이다.
이 때, 인터페이스 정의 언어 (==IDL) 을 사용한다.
서비스 정의를 사용해 Server Skeleton 이라는 server side code 를 생성할 수 있고, Stub 이라는 client side code 도 생성할 수 있다.

위 예시를 통해 살펴보자.
서비스 정의는 ProductInfo.proto 파일에 정의하고, 서버 측과 클라이언트 측 코드를 생성하는데 사용된다.
서비스 정의부터 자세히 보자.

서비스 정의

gRPC 는 프로토콜 버퍼를 IDL 로 사용해서 서비스 인터페이스를 정의한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package ecommerce;

service ProductInfo {
rpc addProduct(Product) returns (ProductID);
rpc getProduct(ProductID) returns (Product);
}

message Product {
string id = 1;
string name = 2;
string description = 3;
float price = 4;
}

message ProductID {
string value = 1;
}

gRPC Server

위와 같이 서비스 정의가 완료되면, 이를 사용해 프로토콜 버퍼 컴파일러인 protoc 를 사용해 서버 측이나 클라이언트 측 코드를 생성할 수 있다.
그리고, 서버는 아래 처리가 필요하다.

  1. 상위 서비스 클래스를 overriding 함으로써 생성된 서버 스켈레톤의 서비스 로직을 구현
  2. gRPC 서버를 실행해 클라이언트 요청을 수신하고 응답
Read more

[도커/쿠버네티스] 8장_인그레스

ingress 는 일반적으로 외부에서 내부로 향하는 것을 지칭한다.
쿠버네티스 인그레스는, 외부 요청을 어떻게 처리할 것인지 네트워크 7 계층 레벨에서 정의하는 오브젝트이다.

사용 이유

어플리케이션이 3 개의 디플로이먼트로 생성되어 있다고 하자.
디플로이먼트를 외부에 노출하려면 위 그림 처럼,
NodePort or LoadBalancer 타입의 서비스 3 개를 각각 디플로이먼트에 연결해주면 된다.
그런데, 이 방식은 서비스마다 세부적인 설정을 할 때 추가적인 복잡성이 발생한다.
예를 들면, 아래와 같은 내용을 구현하려면, 서비스와 디플로이먼트에 대해 일일이 설정해야한다.

  1. SSL / TLS 보안 연결
  2. 접근 도메인 및 클라이언트 상태에 기반한 라우팅

그래서 인그레스가 필요하다.
인그레스 오브젝트를 이용하면, URL 엔드포인트를 단 하나만 생성해서 이런 번거로움을 해결할 수 있다.

위 그림처럼, 3 개의 서비스에 대해 3 개 URL 이 각각 존재하는 것이 아니라
인그레스에 접근하기 위한 하나의 URL 만 존재한다.
핵심은, 라우팅 정의나 보안 연결 같은 세부 설정은 서비스와 디플로이먼트가 이니라 인그레스에 의해 수행

구조

ingress-example.yaml 파일을 작성하자.

Read more

[도커/쿠버네티스] 7장_쿠버네티스 리소스 관리와 설정

효율적으로 애플리케이션을 관리하기 위해 사용되는
Namespace / ConfigMap / Secret 오브젝트를 정리한다.

Namespace

네임스페이스는 포드, 레플리카셋, 디플로이먼트, 서비스 등과 같은 쿠버네티스 리소드들이 묶여 있는
하나의 가상 공간 또는 그룹이다.
하지만, 네임스페이스의 리소스들은 논리적으로 구분된 것일 뿐, 물리적으로 격리된 것은 아니다.
즉, 서로 다른 네임스페이스에 생성된 포드가 같은 노드에 존재할 수 있다.

리눅스의 네임스페이스와는 완전히 다르다.
리눅스의 네임스페이스는, 리눅스 커널 자체 기능

Namespace 사용하기

아래와 같이 production-namespace.yaml 파일을 정의하자.

1
2
3
4
apiVersion: v1
kind: Namespace
metadata:
name: production

그리고 네임스페이스를 생성하자.

1
kubectl apply -f production-namespace.yaml

특정 네임스페이스에 리소스를 생성하려면
hostname-deploy-svc-ns.yaml 파일에 아래와 같이 작성하고,

Read more

쿠버네티스 오브젝트

Pod / Replica Set / Service / Deployment 오브젝트를 정리한다.

쿠버네티스의 고유 특징

모든 리소스는 오브젝트 형태로 관리된다.

컨테이너의 집합 (Pods), 컨테이너의 집합을 관리하는 컨트롤러 (Replica Set), 사용자 (Service Account), 노드 (Node) … 등 하나의 오브젝트로 관리된다.
쿠버네티스에서 사용할 수 있는 오브젝트는 아래 명령어로 확인 가능하다.

명령어를 사용할 수 있지만, YAML 파일을 더 많이 사용한다.

kubectl 이라는 명령어로 쿠버네티스를 사용할 수 있지만,
YAML 파일로 컨테이너 뿐만 아니라 모든 리소스 오브젝트들에 사용될 수 있다.

여러 개의 컴포넌트로 구성되어 있다.

쿠버네티스 노드는 마스터 노드와 워커 노드로 나뉘어 있다.
마스터 노드는 클러스터를 관리하는 역할을 하고, 워커 노드에는 애플리케이션 컨테이너가 생성된다.
쿠버네티스는 도커를 포함한 많은 컴포넌트들이 도커 컨테이너로서 실행된다. 예를 들어,
마스터 노드에는 kube-apiserver, kube-controller-manager, kube-schueduler, coreDNS 등이 실행된다.

그리고, kubelet 이라는 에이전트가 모든 노드에 실행된다.
kubelet 은 컨테이너의 생성/삭제 뿐만 아니라 마스터와 워커 노드 간 통신 역할을 담당한다.

쿠버네티스 입장에서, 도커 데몬 또한 하나의 컴포넌트이다.
도머 스웜 모드는 도커에 내장된 기능인 반면, 쿠버네티스는 그렇지 않다.
오히려, 쿠버네티스가 도커를 이용하는 방식이다.

Read more