공부하고 기록하는, 경제학과 출신 개발자의 노트

학습일지/Knative

Knative Series 4 - Eventing Deep Dive

inspirit941 2022. 1. 25. 14:45
반응형

Knative Eventing Deep Dive

https://youtu.be/XEkctUsVl5I

 

강연자: Ahmed Abdalla

  • Redhat Openshift serverless team 소속. knative eventing 담당

 

cf.

이 강의를 끝까지 들어보면, github 소스코드를 따로 보여주지 않는다.

강의에서 사용한 github 레포도 따라가보고 강연자 @devguyio 의 깃허브 링크를 확인했지만, 이 실습에 사용한 yaml코드는 없었다.

 

 

스크린샷 2022-01-16 오후 4 57 49

Knative Eventing이란 무엇인가.

뜯어보려면 꽤 복잡한 구조. 미리 정의하고 출발하자면

Opinionated way of building Event Driven Architeucture / Event Driven Application using K8s.

  • Opinionated (framework / software): 해당 프레임워크나 소프트웨어 디자이너가 '개발자가 쉽고 빠르게 사용할 수 있도록 모범지침을 만들어둔 것을 의미함. "Happy Path"
  • 프레임워크나 소프트웨어에서 가정하거나 규정한 몇 가지 요건을 충족한다면, 빠르게 개발하고 적용할 수 있다는 뜻.
  • knative의 경우 kubernetes에서 구축한 design concept를 토대로 동작한다.

 

특징

  • K8s의 디자인 원칙을 계승함.
    • Declarative API 형식, k8s와 유사한 개념 (specs, status), Desired status와 current status의 차이를 reactive하게 수정할 수 있는 controller와 reconciler의 존재.
  • EDA 개발에 필요한 building blocks 제공
  • 독립적인 형태의 producer / consumer 제공. 선후관계 없이 생성할 수 있고, 생성된 것들을 연결하면 됨.
  • CloudEvent 표준을 준수함.
  • Eventing / Messaging을 위한 여러 tech를 지원함. kafka, NATS, RabbitMQ, GCP PubSub 등

 

 


Event Driven Application을 개발할 때 해결해야 할 세 가지 이슈. Knative Eventing은 어떻게 해결했는가?

스크린샷 2022-01-18 오후 9 02 10

How to Get your Event? -> Source

  • Source라는 abstract concept 도입. Source: 클러스터 외부에서 이벤트를 받고, 외부로 이벤트를 보낼 수 있는 Concept.
  • Ingress events into the eventing mesh.

 

 

스크린샷 2022-01-18 오후 9 08 46

How do I route my Events? -> Broker / Channel

  • Broker / Channel이라는 building block / Logical Concept 을 제공함.
  • 이벤트를 필요한 곳에 전달하고, 다양한 방식 (style) 으로 이벤트를 받아서 목적지에 전달할 수 있게 되어 있음.
    • broker : content-based Routing
    • channel : topology-based Routing

 

스크린샷 2022-01-18 오후 9 13 15

How do I egress My events? -> Sink

  • 이벤트를 클러스터로 받아서 external destination으로 보내는 방법.
  • Sink 제공. cloudEvent를 받아서 처리하게 될 목적지를 의미하는 Logical Concept. final off-cluster system.

 


 

Example Cases

사실 Event Driven Architecture는 문제를 해결하는 여러 방법 중 하나일 뿐이다.

EDA 방식으로 문제를 해결한 몇 가지 좋은 예시를 소개하는 편이 좋을 것 같다.

1. Extensibility Problem

대략 상황을 가정하면

  • External System이 존재함. 레거시 시스템이거나 외부 솔루션이거나... External System 자체를 변경하기 위한 비용이 매우 크다.
  • 이 External System 자체를 따로 손대거나 변경하지 않은 채 functionality를 확장하고 싶다. 새로운 기능을 추가하려고 한다.

스크린샷 2022-01-18 오후 9 16 32

 

예컨대 github와 연동을 생각한다면, github API에서 보내는 이벤트를 기반으로 Extension 기능을 추가할 수 있다.

  • github라는 서비스와 기존 레거시 서비스 자체를 건드리지 않고도 새로운 기능을 제공할 수 있는 셈.

 

2. Integration

스크린샷 2022-01-18 오후 11 34 30

heterogenous solutions를 이벤트 기반으로 연결할 수 있다.

  • 예시처럼 github / slack / legacy system 세 개의 서비스를 이벤트 기반으로 연결해서 사용할 수 있음.

 

예시

스크린샷 2022-01-18 오후 11 41 20

해결하고 싶은 Problem: github 기능의 확장

  • github Contributer가
  • 자신의 github repo에 부정적인 comment가 달렸을 경우
  • 이메일을 받을 수 있도록 하고 싶다.

스크린샷 2022-01-19 오후 4 46 13

외부 github 요청을 받아들일 knative Source를 정의한다.

  • spec: desired State를 의미함.
    • 예시의 경우 github에서 어떤 종류의 이벤트를 받을 것인지 정의한 eventTypes
    • 이벤트가 발생할 repository를 정의한 ownerAndREpository
    • sink uri : 이벤트를 전송할 uri

어떻게 동작하는가?

스크린샷 2022-01-19 오후 8 42 52

kubernetes 언어로 표현하면

  • Control plane: the way that you are trying to declare "Desired States". 원하는 상태를 정의하기 위한 영역
    • a set of controllers that exist in k8s.
  • Data plane: set of components in the path of actual data that are live and running in your system.

 

 

예시. 만약 새로운 pod을 띄우고 싶다면

 

Control-Plane

  1. interact with a set of controllers from k8s
  2. create the actual container

Data-Plane

  1. service와 통신하기 위한 ingress / routing traffic to actual container & correct Node 생성

Knative Eventing 동작과정에서 각 plane이 어떻게 적용되는지 체크.

 

다운로드 (7)

 

  1. Controller: install one time inside your cluster.
    • 예시의 경우 githubSourceController. interact / reconciles all objects that are kind "GithubSource"
  2. Adapter: pod. 실제로 github과 통신하는 역할. githubSource에서 정의한 eventType, repo url 등의 정보를 토대로 작동한다.
    • github API로 webhook 등록. github에서 제공하는 이벤트를 받아들이는 component.
    • 필요한 곳에 맞게 Cloud Event를 emit.
  3. Sink: adapter에게서 이벤트를 받아 처리하는 Object.

 

그림의 파란색 배경 (GithubSourceController)은 Control Plane 영역이다.

  • source를 생성할 때 controller가 만들어지고, controller는 adapter를 설정함. 어떤 api를 사용할 것인지, 어떤 동작에 반응하도록 할 것인지 세팅함.

 

초록색 배경 (Adapter)는 Data Plane 영역이다.

  • 모든 이벤트의 lifeCycle은 Adapter를 거쳐간다.
  • Adapter를 어떻게 배치할 것인지? -> 다양한 디자인 패턴에 의해 결정할 수 있다.

스크린샷 2022-01-19 오후 4 46 13

위 설정을 보면, Source와 Sink 간 coupling이 확인된다.

service의 uri가 Source의 sink값과 일치해야 하기 때문. 이런 형태의 디자인은 Eventing에서 권장하지 않는다.

 

 

스크린샷 2022-01-20 오후 9 27 33

 

단순히 uri만 저장하는 것보다는 Sink Type을 지정하는 편이 Decoupling에는 유리하다.

knative에는 sink type을 매번 정적으로 지정하는 대신 duck type으로 사용할 수 있다.

 

 

 

스크린샷 2022-01-21 오전 10 36 49

위 사진의 경우 Service와 InMemoryChannel이라는 별개의 sink type이지만,

address.url을 입력하는 것만으로도 sink type을 판별해서 적용할 수 있다.

 

 

 

스크린샷 2022-01-21 오전 10 37 46

이 방식을 Addressable Duck Type이라고 하며, knative에서 sink decoupling을 위해 지원하고 있다.

  • 사용자가 Object 형식보다는 object의 동작과정이나 로직에 집중할 수 있도록.
  • sink는 uri값이 아예 정해져 있거나, addressable 형태로 주어진다.
  • addressable duck type을 제공하는 객체는 url에 접근할 수 있도록 설계되어 있다.

 

 

스크린샷 2022-01-21 오후 2 04 45

addressable sink는 ready 상태인지 아닌지 k8s에서 제공하는 healthCheck 기능을 지원한다.

GithubSource 활용한 실습 - github 이벤트를 Service와 연결하기

1. GithubSouce로 github Webhook 받도록 세팅하기.

스크린샷 2022-01-21 오후 2 08 01

https://knative.dev/docs/samples/eventing/ 에서도 확인할 수 있다.

  • github에서 personal access token 생성하기
  • 웹훅 등록하기

 

 

 

실습에 필요한 yaml 오브젝트는
https://github.com/inspirit941/knative-eventing-example 에서 확인할 수 있다.

 

  • githubSource 객체를 사용하기 위해 eventing-github 설정파일을 k8s에 적용해야 한다.

kubectl apply -f <github 클론 경로>

스크린샷 2022-01-23 오후 12 59 21

kubectl get pods -n integration 으로 pod를 확인하면,
githubSource가 배포되어 있다. 이 deployment가 앞에서 설명한 Adapter 역할을 함.

 

 

watch kubectl -n dev get pods

stern -n dev --json-pp github-message-dumper-0001-deployment -c user-container
# 내 로컬에서는 --json-pp 옵션을 인식하지 못했다. k9s로 로그 확인이 충분히 가능하므로, 강의의 코드를 가능한 그대로 가져왔다.
  • webhook을 생성할 때, 요청을 보낼 url은 githubSource여야 한다. kn service list -n integration 으로 확인할 수 있는 githubSource의 url (http://endgamesource-7wngz.integration....) 으로 이벤트를 보내도록 webhook을 세팅한다.
  • github webhook을 생성하면, 연결 확인을 위해 ping 이벤트가 호출된다.

스크린샷 2022-01-23 오후 10 45 49

 

stern으로 확인해보면 webhook을 통해 ping 요청이 githubSource로 전달되고,githubSource는 해당 요청을 Service에 전달한다.
따라서 Service에서 cloudEvent 로그가 만들어지는 걸 확인할 수 있다.

 

 

 


반응형