티스토리 뷰
서론
Knative는 Kubernetes 환경에서 동작하는 서버리스 클라우드 네이티브 애플리케이션(Severless CNA)을 배포, 실행, 관리하기 위한 오픈소스 소프트웨어이다. Knative의 구성 요소는 Kubernetes를 기반으로 구축되어 복잡한 세부 사항을 추상화하고 개발자가 비즈니스 개발에만 집중할 수 있도록 하여, 개발자의 생산성을 높일 수 있다.
또한 Knative는 Serverless Computing으로 요청이 있을 때만 코드를 실행하고, 요청이 많을 경우에는 그에 비례하는 자원을 동적으로 Scale In-Out 또는 Zero 상태까지 유지하도록 하여 사용률과 확장성을 극대화할 수 있으며, 인프라 비용을 효과적으로 절감할 수 있다.
Public Cloud의 대표적인 Serverless Computing 기술은 AWS Lambda, Azure Functions, Google Cloud Functions 등이 있다. 이와 같이 Public Cloud의 Managed Service로 Serverless Computing을 적용할 경우 Service Lock In 요소가 되기 때문에 이를 오픈소스로 개발한 Knative가 하나의 대안으로 떠오르고 있다.
Knative 구성 과정
Knative 구성 과정은 크게 다음과 같이 구분해 볼 수 있다.
1) Knative 아키텍처
2) Knative 구축
3) Knative Build
4) Knative Serving
Knative 아키텍처
Knative를 활용하면, 개발자가 개발이외에 고려해야 하는 Docker 이미지 관리, Registry 통합, 서비스 배포, 로드밸런싱 구성, 모니터링, 로깅, Scale Out, CI/CD와 같은 문제를 완벽하게 해소해 줄 수 있다.
Knative의 다양한 기능 중 핵심 기능이라고 볼 수 있는 Build - Serving - Event에 대해 알아보도록 하자.
1. Build (소스에서 이미지를 빌드하는 기능)
Knative Build는 Kubernetes 기능을 기반으로 표준화되고 이식 가능하며 재사용 가능한 컨테이너 이미지 빌드 방법을 제공한다. Build를 적용하면, 개발자가 코드를 레지스트리로 보내기 전에 컴파일하고 패키징하는 일관된 방법을 정의 할 수 있다.
Build를 활용하여 Git에서 소스코드를 Clone하고 Docker Image를 빌드하고, Tagging - Registry Push 등을 수행한다. 빌드가 완료된 결과를 기반으로 serving를 수행하게 된다.
Serverless가 아닌 일반 클라우드 환경을 예를 든다면, 이 Build 기능이 Jenkins의 CI 부분과 매칭되는 형태라고 볼 수 있다.
2. Serving (스냅 샷 및 Scale In-Out을 관리하고 처리하며, K8S 클러스터에 애플리케이션 배포)
Knative Serving 구성 요소를 사용하면 K8S 클러스터에 컨테이너 이미지로 애플리케이션을 배포 할 수 있다. 또한 배포 가능한 스냅 샷을 유지하고 라우팅 및 모든 네트워킹 상호 작용을 처리한다. 마지막으로 애플리케이션 배포를 위한 확장 (확장 및 축소)을 제공한다.
a. Service : 워크로드의 전체 수명주기를 자동으로 관리하고 Route 생성, Configuration 및 Revision 제어한다. 항상 최신 Revision 또는 고정 Revision으로 트래픽을 라우팅하도록 서비스를 정의 할 수 있다.
b. Route : 네트워크 엔드 포인트를 하나 이상의 Revision에 매핑한다.
c. Configuration : 배포에 대해 원하는 상태를 유지하도록 한다.
d. Revision : 워크로드에 대한 특정 시점의 스냅 샷이다.
이 과정이 Jenkins의 CD 부분과 매칭된다고 볼 수 있다.
3. Event (메시지 수신을 위한 이벤트 중심의 Pub/Sub 지원)
Event는 MQ를 사용하여 서비스간 결합도를 낮추는 개발 방법이다. 이를 이용하여 이기종 간의 솔루션 연계 및 독립적인 애플리케이션 개발 등을 지원한다.
Knative 구축
Knative는 크게 두가지 형태의 구성을 지원한다. 대표적인 Service Mesh인 Isitio와 함께 구성하는 방법과 Gloo와 함께 구성하는 방법이다.
Knative는 Istio의 Virtual Gateway 기능만 사용하기 때문에 Istio가 제공하는 CRD 수십가지를 모두 활용할 필요가 없다. 따라서 Istio를 Service Mesh로 사용하기 위해 기 구성되어 있는 경우에는 Istio를 사용하되 Serverless만을 위해 구축할 경우 Light Weight한 Gloo를 사용하여 Knative를 구축하는 것을 권고한다.
다만 Gloo는 Knative의 Event 컴포넌트를 지원하지 않는다. 이번 포스팅에서는 다소 익숙하지 않은 Gloo를 사용하여 Knative를 적용해 보도록 하자.
Gloo : https://docs.solo.io/gloo-edge/latest/installation/gateway/kubernetes/
1. glooctl 설치
curl -sL https://run.solo.io/gloo/install | sh
export PATH=$HOME/.gloo/bin:$PATH
먼저 Gloo 및 Knative를 설치하기 위한 glooctl을 설치한다.
> 버전 확인
[root@ip-192-168-114-198 ~]# glooctl version
Client: {"version":"1.5.14"}
Server: version undefined, could not find any version of gloo running
[root@ip-192-168-114-198 ~]#
2. Installing on Kubernetes with glooctl
glooctl로 knative를 설치한다. 이때 Gloo와 Knative Serving이 함께 구성된다.
> glooctl install knative
[root@ip-192-168-114-198 ~]# glooctl install knative
installing Knative CRDs...
installing Knative...
Knative successfully installed!
Creating namespace gloo-system... Done.
Starting Gloo Edge installation...
Gloo Edge was successfully installed!
[root@ip-192-168-114-198 ~]#
3. knative 구축 확인
> kubectl get all -n gloo-system
[root@ip-192-168-114-198 ~]# kubectl get all -n gloo-system
NAME READY STATUS RESTARTS AGE
pod/discovery-5dc96cbb4d-94fbn 1/1 Running 0 2m3s
pod/gloo-6d86dc87c8-hb58b 1/1 Running 0 2m3s
pod/ingress-6f95fd7dc-bj65l 1/1 Running 0 2m3s
pod/knative-external-proxy-f4f67644d-drzps 1/1 Running 0 2m3s
pod/knative-internal-proxy-7cd8448b58-qcfgs 1/1 Running 0 2m3s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/gloo ClusterIP 10.100.230.54 <none> 9977/TCP,9976/TCP,9988/TCP,9979/TCP 2m3s
service/knative-external-proxy LoadBalancer 10.100.68.120 afe2c222e1558413d8e8acfd0ef74357-1341022058.ap-northeast-2.elb.amazonaws.com 80:30247/TCP,443:32732/TCP 2m3s
service/knative-internal-proxy ClusterIP 10.100.212.181 <none> 80/TCP,443/TCP 2m3s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/discovery 1/1 1 1 2m3s
deployment.apps/gloo 1/1 1 1 2m3s
deployment.apps/ingress 1/1 1 1 2m3s
deployment.apps/knative-external-proxy 1/1 1 1 2m3s
deployment.apps/knative-internal-proxy 1/1 1 1 2m3s
NAME DESIRED CURRENT READY AGE
replicaset.apps/discovery-5dc96cbb4d 1 1 1 2m3s
replicaset.apps/gloo-6d86dc87c8 1 1 1 2m3s
replicaset.apps/ingress-6f95fd7dc 1 1 1 2m3s
replicaset.apps/knative-external-proxy-f4f67644d 1 1 1 2m3s
replicaset.apps/knative-internal-proxy-7cd8448b58 1 1 1 2m3s
[root@ip-192-168-114-198 ~]#
> kubectl get all -n knative-serving
[root@ip-192-168-114-198 ~]# kubectl get all -n knative-serving
NAME READY STATUS RESTARTS AGE
pod/activator-77fc555665-q4sf9 1/1 Running 0 3m21s
pod/autoscaler-5c98b7c9b6-dvbt9 1/1 Running 0 3m21s
pod/autoscaler-hpa-5cfd4f6845-l2jvx 1/1 Running 0 3m21s
pod/controller-7fd74c8f67-nthjj 1/1 Running 0 3m21s
pod/webhook-74847bb77c-v4h2l 1/1 Running 0 3m21s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/activator-service ClusterIP 10.100.212.5 <none> 80/TCP,81/TCP,9090/TCP 3m21s
service/autoscaler ClusterIP 10.100.106.32 <none> 8080/TCP,9090/TCP,443/TCP 3m21s
service/controller ClusterIP 10.100.203.250 <none> 9090/TCP 3m21s
service/webhook ClusterIP 10.100.103.172 <none> 443/TCP 3m21s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/activator 1/1 1 1 3m21s
deployment.apps/autoscaler 1/1 1 1 3m21s
deployment.apps/autoscaler-hpa 1/1 1 1 3m21s
deployment.apps/controller 1/1 1 1 3m21s
deployment.apps/webhook 1/1 1 1 3m21s
NAME DESIRED CURRENT READY AGE
replicaset.apps/activator-77fc555665 1 1 1 3m21s
replicaset.apps/autoscaler-5c98b7c9b6 1 1 1 3m21s
replicaset.apps/autoscaler-hpa-5cfd4f6845 1 1 1 3m21s
replicaset.apps/controller-7fd74c8f67 1 1 1 3m21s
replicaset.apps/webhook-74847bb77c 1 1 1 3m21s
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
horizontalpodautoscaler.autoscaling/activator Deployment/activator <unknown>/100% 1 20 1 3m21s
[root@ip-192-168-114-198 ~]#
gloo로 knative를 설치하면 gloo 컴포넌트와 함께 serving 컴포넌트가 설치된다.
4. Knative Serving 설치
추가로 knative build 컴포넌트를 설치한다. 이를 이용하여 배포 이미지를 빌드할 수 있다.
> kubectl apply -f https://github.com/knative/build/releases/download/v0.7.0/build.yaml
[root@ip-192-168-114-198 knative]# kubectl apply -f https://github.com/knative/build/releases/download/v0.7.0/build.yaml
namespace/knative-build unchanged
podsecuritypolicy.policy/knative-build configured
clusterrole.rbac.authorization.k8s.io/knative-build-admin configured
serviceaccount/build-controller unchanged
clusterrolebinding.rbac.authorization.k8s.io/build-controller-admin unchanged
customresourcedefinition.apiextensions.k8s.io/builds.build.knative.dev unchanged
customresourcedefinition.apiextensions.k8s.io/buildtemplates.build.knative.dev unchanged
customresourcedefinition.apiextensions.k8s.io/clusterbuildtemplates.build.knative.dev unchanged
customresourcedefinition.apiextensions.k8s.io/images.caching.internal.knative.dev configured
service/build-controller unchanged
service/build-webhook configured
image.caching.internal.knative.dev/creds-init configured
image.caching.internal.knative.dev/git-init configured
image.caching.internal.knative.dev/gcs-fetcher unchanged
image.caching.internal.knative.dev/nop configured
configmap/config-logging unchanged
configmap/config-observability created
deployment.apps/build-controller configured
deployment.apps/build-webhook configured
[root@ip-192-168-114-198 knative]#
Knative build 모듈을 배포하다 아래와 같은 에러가 나올 경우에는 현재 지원하는 버전을 확인하여 최신 Release 버전을 설치하도록 한다.
[Error Message]
{
"level":"error",
"logger":"webhook",
"caller":"webhook/webhook.go:315",
"msg":"failed to register webhook",
"knative.dev/controller":"webhook",
"error":"failed to fetch our deployment: the server could not find the requested resource",
"stacktrace":"github.com/knative/build/vendor/github.com/knative/pkg/webhook.(*AdmissionController).Run/go/src/github.com/knative/build/vendor/github.com/knative/pkg/webhook/webhook.go:315main.main /go/src/github.com/knative/build/cmd/webhook/main.go:92runtime.main /usr/local/go/src/runtime/proc.go:200"
}
[Release 확인]
Knative Build Release - https://github.com/knative/build/releases
설치가 완료되면 아래와 같이 gloo-system, knative-build, knative-serving namespace에 Pod 들이 기동되어 있는 것을 확인할 수 있다.
[root@ip-192-168-114-198 knative]# kubectl get pods --all-namespaces
NAMESPACE NAME READY STATUS RESTARTS AGE
gloo-system discovery-5dc96cbb4d-94fbn 1/1 Running 0 10h
gloo-system gloo-6d86dc87c8-hb58b 1/1 Running 0 10h
gloo-system ingress-6f95fd7dc-bj65l 1/1 Running 0 10h
gloo-system knative-external-proxy-f4f67644d-drzps 1/1 Running 0 10h
gloo-system knative-internal-proxy-7cd8448b58-qcfgs 1/1 Running 0 10h
knative-build build-controller-766fdf748f-wrqjx 1/1 Running 0 35s
knative-build build-webhook-68d987cd9f-fpwmj 1/1 Running 0 35s
knative-serving activator-77fc555665-q4sf9 1/1 Running 0 10h
knative-serving autoscaler-5c98b7c9b6-dvbt9 1/1 Running 0 10h
knative-serving autoscaler-hpa-5cfd4f6845-l2jvx 1/1 Running 0 10h
knative-serving controller-7fd74c8f67-nthjj 1/1 Running 0 10h
knative-serving webhook-74847bb77c-v4h2l 1/1 Running 0 10h
kube-system aws-node-gkrkk 1/1 Running 0 12h
kube-system aws-node-wbq5b 1/1 Running 0 12h
kube-system coredns-7dd7f84d9-9f97n 1/1 Running 0 12h
kube-system coredns-7dd7f84d9-brzqd 1/1 Running 0 12h
kube-system kube-proxy-j2np9 1/1 Running 0 12h
kube-system kube-proxy-vglbj 1/1 Running 0 12h
[root@ip-192-168-114-198 knative]#
위와 같이 Pod가 정상 기동되었는지 여부를 확인하고 정상적이면 Serverless Cloud Native Application을 빌드 및 배포해 보도록 하자.
Knative Build
앞서 살펴본 바와 같이 Gloo는 Knative의 핵심 기능 중 Build와 Serving을 지원하지만, Event는 지원하지 않는다. 따라서 가이드에서는 Build와 Serving만 살펴보도록 하자.
먼저 Knaive Build를 수행하는 과정이다. 이 과정에서는 다음과 같은 Step이 진행된다.
1) Git Clone
2) Docker Build
3) Docker Tagging
4) Docker Login
5) Docker Push
위와 같은 과정이 수행되는 것은 실제 클라우드 환경에 배포를 진행하는 CI 단계와 동일하다는 것을 알 수 있다. 이는 CLI 상에서 진행되기 때문에 최근에는 Knative Build가 Deprecated 되고 Tekton이라는 CI Tool이 그 대처 솔루션으로 권고되고 있다.
다만 이번 가이드에서는 Knative Build를 사용하여 빌드를 진행해 보도록 하자. (이후에 기회가 된다면 Tekton에 대해서도 다뤄볼 예정이다.)
1. Docker Registry Credential 등록
Docker Image를 Push하기 위한 Secret과 ServiceAccount를 다음과 같이 각각 생성한다.
> secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: dockerhub-credential
annotations:
build.knative.dev/docker-0: https://index.docker.io/v1/
type: kubernetes.io/basic-auth
data:
username: USERNAME_ENCODE_BASE64
password: PASSWORD_ENCODE_BASE64
Docker image를 저장할 Registry(DockerHub, Nexus, ECR 등)의 ID/PW를 BASE64로 인코딩한 정보를 data에 등록한다. (본 예시는 dockerhub에 저장한다.)
> sa.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: build-serverless
secrets:
- name: dockerhub-credential
위와 같이 작성 후 각각 반영한다.
[root@ip-192-168-114-198 knative]# kubectl apply -f secret.yaml
secret/dockerhub-credential created
[root@ip-192-168-114-198 knative]# kubectl apply -f sa.yaml
serviceaccount/build-serverless created
[root@ip-192-168-114-198 knative]#
2. Test Code & Dockerfile 작성
> app.py
import os
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
target = os.environ.get('TARGET', 'NOT SPECIFIED')
return 'Hi!! Serverless: {}!\n'.format(target)
if __name__ == "__main__":
app.run(debug=True, host='0.0.0.0', port=int(os.environ.get('PORT', 8080)))
target 변수를 받아 출력하는 간단한 Python 코드이다.
> Dockerfile
FROM python:alpine
ENV APP_HOME /app
COPY . $APP_HOME
WORKDIR $APP_HOME
RUN pip install Flask
ENTRYPOINT ["python"]
CMD ["app.py"]
Python을 빌드하는 Dockerfile을 작성한다.
위와 같이 작성한 파일을 github 등에 저장한 후 Knative Build에서 참조하도록 한다.
> https://github.com/sonnaraon/knative-sample
3. build.yaml 작성
build object를 생성하기 위한 build.yaml 파일을 작성한다.
> build-python.yaml
apiVersion: build.knative.dev/v1alpha1
kind: Build
metadata:
name: python-build
spec:
serviceAccountName: build-serverless
source:
git:
url: https://github.com/sonnaraon/knative-sample.git
revision: master
steps:
- name: build-and-push
image: gcr.io/kaniko-project/executor:v0.1.0
args:
- --dockerfile=/workspace/Dockerfile
- --destination=docker.io/nara0617/hello-python:latest
- spec.source.git : Git Clone
- spec.steps : Docker build & push
4. Knative Build 수행
작성한 build-python.yaml 파일을 적용하면 아래와 같이 build object가 생성되며, 일정 시간 후 build 상태가 True로 변경되는 것을 확인할 수 있다.
[root@ip-192-168-114-198 knative]# kubectl apply -f build-python.yaml
build.build.knative.dev/python-build created
[root@ip-192-168-114-198 knative]# kubectl get build -w
NAME SUCCEEDED REASON STARTTIME COMPLETIONTIME
python-build Unknown Pending 5s
python-build Unknown Pending 5s
python-build Unknown Pending 6s
python-build Unknown Pending 27s
python-build True 28s
만약 이 Step이 False가 나올 경우에는 아래 Pod의 Log와 Describe 등을 점검한다.
[root@ip-192-168-114-198 knative]# kubectl get pods
NAME READY STATUS RESTARTS AGE
python-build-pod-2744b6 0/1 Completed 0 3m56s
[root@ip-192-168-114-198 knative]#
위와 같이 정상적으로 완료되었을 경우 Completed 상태가 나온다. 정상적으로 Build Step이 완료되면, 아래와 같이 spec.steps.args --destination에 정의한 Repository에 이미지가 저장된다.
사실 이 과정은 앞서 Jenkins에서 CI 과정을 통해 수행한 내용과 거의 같다고 볼 수 있다. Git Clone & Docker Image를 생성하는 과정까지가 CNA에서 CI 과정이라고 볼 수 있으며, Knative Build는 동일한 과정을 담당한다고 볼 수 있다. 사실 이 과정은 Knative Build를 사용하지 않고 다른 CI 도구를 사용해도 상관이 없으며, Knative 진영에서는 Tekton을 권고하고 있다.
이제 여기까지 구성이 완료되면, 다음으로 Knative Serving 단계를 진행한다.
Knative Serving
1. Knative Service 생성 및 배포
먼저 Build 단계에서 생성한 Docker Image를 기반으로 Knative Service를 생성한다.
> ksvc.yaml
apiVersion: serving.knative.dev/v1alpha1
kind: Service
metadata:
name: helloworld-python
namespace: default
spec:
runLatest:
configuration:
revisionTemplate:
spec:
container:
image: nara0617/hello-python:latest
env:
- name: TARGET
value: "Python Sample v1"
생성 후 배포를 진행한다.
[root@ip-192-168-114-198 knative]# kubectl apply -f ksvc.yaml
service.serving.knative.dev/helloworld-python created
[root@ip-192-168-114-198 knative]#
2. 배포 상태 확인
[root@ip-192-168-114-198 knative]# kubectl get all
NAME READY STATUS RESTARTS AGE
pod/python-build-pod-2744b6 0/1 Completed 0 26m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/helloworld-python ExternalName <none> knative-internal-proxy.gloo-system.svc.cluster.local <none> 96s
service/helloworld-python-f8j5n ClusterIP 10.100.11.213 <none> 80/TCP 105s
service/helloworld-python-f8j5n-metrics ClusterIP 10.100.235.122 <none> 9090/TCP,9091/TCP 105s
service/helloworld-python-f8j5n-private ClusterIP 10.100.241.241 <none> 80/TCP,8022/TCP 105s
service/kubernetes ClusterIP 10.100.0.1 <none> 443/TCP 33h
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/helloworld-python-f8j5n-deployment 0/0 0 0 105s
NAME DESIRED CURRENT READY AGE
replicaset.apps/helloworld-python-f8j5n-deployment-5754869ffc 0 0 0 105s
NAME URL READY REASON
route.serving.knative.dev/helloworld-python http://helloworld-python.default.example.com True
NAME URL LATESTCREATED LATESTREADY READY REASON
service.serving.knative.dev/helloworld-python http://helloworld-python.default.example.com helloworld-python-f8j5n helloworld-python-f8j5n True
NAME CONFIG NAME K8S SERVICE NAME GENERATION READY REASON
revision.serving.knative.dev/helloworld-python-f8j5n helloworld-python helloworld-python-f8j5n 1 True
NAME LATESTCREATED LATESTREADY READY REASON
configuration.serving.knative.dev/helloworld-python helloworld-python-f8j5n helloworld-python-f8j5n True
NAME SUCCEEDED REASON STARTTIME COMPLETIONTIME
build.build.knative.dev/python-build True 26m
NAME AGE
image.caching.internal.knative.dev/helloworld-python-f8j5n-cache 106s
[root@ip-192-168-114-198 knative]#
위와 같이 Knative Service를 배포하면, ksvc, configuration, route, revision Object가 생성된다.
3. knctl 활용
위와 같이 yaml 파일로 ksvc 생성 시 자동으로 route, configuration, revision 등이 생성된다. 이를 knctl 명령어를 활용하여 보다 세부적으로 각 Object를 생성하고 확인할 수 있다.
a. knctl 설치
[root@ip-192-168-114-198 ~]# wget https://github.com/cppforlife/knctl/releases/download/v0.3.0/knctl-linux-amd64
--2020-12-26 23:17:21-- https://github.com/cppforlife/knctl/releases/download/v0.3.0/knctl-linux-amd64
Resolving github.com (github.com)... 15.164.81.167
Connecting to github.com (github.com)|15.164.81.167|:443... connected.
HTTP request sent, awaiting response... 302 Found
Location: https://github-production-release-asset-2e65be.s3.amazonaws.com/143948317/78456200-508b-11e9-81d1-539559b46c3a?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIWNJYAX4CSVEH53A%2F20201226%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20201226T231721Z&X-Amz-Expires=300&X-Amz-Signature=85f7515634d659f92d0ca367a684def0cc32aeefc6b1f9ba0faa978147308cc0&X-Amz-SignedHeaders=host&actor_id=0&key_id=0&repo_id=143948317&response-content-disposition=attachment%3B%20filename%3Dknctl-linux-amd64&response-content-type=application%2Foctet-stream [following]
--2020-12-26 23:17:21-- https://github-production-release-asset-2e65be.s3.amazonaws.com/143948317/78456200-508b-11e9-81d1-539559b46c3a?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIWNJYAX4CSVEH53A%2F20201226%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20201226T231721Z&X-Amz-Expires=300&X-Amz-Signature=85f7515634d659f92d0ca367a684def0cc32aeefc6b1f9ba0faa978147308cc0&X-Amz-SignedHeaders=host&actor_id=0&key_id=0&repo_id=143948317&response-content-disposition=attachment%3B%20filename%3Dknctl-linux-amd64&response-content-type=application%2Foctet-stream
Resolving github-production-release-asset-2e65be.s3.amazonaws.com (github-production-release-asset-2e65be.s3.amazonaws.com)... 52.217.48.156
Connecting to github-production-release-asset-2e65be.s3.amazonaws.com (github-production-release-asset-2e65be.s3.amazonaws.com)|52.217.48.156|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 36744648 (35M) [application/octet-stream]
Saving to: [22;13Hknctl-linux-amd64[24;1H100%[=====================================================================================================================================================================>] 36,744,648 6.26MB/s in 6.8s
2020-12-26 23:17:29 (5.13 MB/s) - [26;36Hknctl-linux-amd64[26;55Hsaved [36744648/36744648]
[root@ip-192-168-114-198 ~]# mv knctl-* /usr/local/bin/knctl
[root@ip-192-168-114-198 ~]# chmod +x /usr/local/bin/knctl
[root@ip-192-168-114-198 ~]# knctl version
Client Version: 0.3.0
Succeeded
[root@ip-192-168-114-198 ~]#
b. knctl 활용
아래와 같이 knctl을 활용하여 knative 관련 Object 정보를 확인할 수 있다.
[root@ip-192-168-114-198 knative]# knctl service list
Services in namespace 'default'
Name Domain Annotations Conditions Age
helloworld-python - - 3 OK / 3 45m
1 services
Succeeded
[root@ip-192-168-114-198 knative]# knctl route list
Routes in namespace 'default'
Name Domain Traffic Annotations Conditions Age
helloworld-python - 100% -> helloworld-python - 3 OK / 3 46m
1 routes
Succeeded
[root@ip-192-168-114-198 knative]# knctl revision list
Revisions
Service Name Tags Annotations Conditions Age Traffic
helloworld-python helloworld-python-f8j5n - - 4 OK / 4 46m 100% ->
1 revisions
Succeeded
[root@ip-192-168-114-198 knative]#
4. 테스트
호출은 다음과 같은 도메인으로 접근할 수 있다.
[root@ip-192-168-114-198 knative]# kubectl get service -n gloo-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
gloo ClusterIP 10.100.230.54 <none> 9977/TCP,9976/TCP,9988/TCP,9979/TCP 31h
knative-external-proxy LoadBalancer 10.100.68.120 afe2c222e1558413d8e8acfd0ef74357-1341022058.ap-northeast-2.elb.amazonaws.com 80:30247/TCP,443:32732/TCP 31h
knative-internal-proxy ClusterIP 10.100.212.181 <none> 80/TCP,443/TCP 31h
[root@ip-192-168-114-198 knative]# kubectl get ksvc
NAME URL LATESTCREATED LATESTREADY READY REASON
helloworld-python http://helloworld-python.default.example.com helloworld-python-f8j5n helloworld-python-f8j5n True
[root@ip-192-168-114-198 knative]#
gloo의 External IP를 ksvc host로 호출하면 아래와 같이 호출할 수 있다.
> curl -H "Host: helloworld-python.default.example.com" http://afe2c222e1558413d8e8acfd0ef74357-1341022058.ap-northeast-2.elb.amazonaws.com
gloo는 Public Cloud 상에 배치 될 경우 LoadBalancerType으로 자동으로 External Proxy를 생성한다.
a. pod 확인
테스트 전 default namespace에 pod를 확인해 보자.
[root@ip-192-168-114-198 knative]# kubectl get pods -w
NAME READY STATUS RESTARTS AGE
python-build-pod-2744b6 0/1 Completed 0 36m
위와 같이 현재 Knative Build Pod 이외에 기동되어 있는 Pod는 없는 상태이다.
b. curl 호출
[root@ip-192-168-114-198 knative]# curl -H "Host: helloworld-python.default.example.com" http://afe2c222e1558413d8e8acfd0ef74357-1341022058.ap-northeast-2.elb.amazonaws.com
Hi!! Serverless: Python Sample v1!
[root@ip-192-168-114-198 knative]#
위와 같이 호출 시 Cold Start로 인해 약간의 Delay(약 3~5초) 발생 후 호출이 된다.
마찬가지로 hosts 파일 또는 Route 53 등을 이용하여 브라우저를 통해 호출할 수도 있다.
# 참조 (Cold Start)
새로운 요청 또는 더 많은 동시 처리를 위해 새로운 함수를 생성해야 하는 경우 배포 패키지의 크기와 코드 실행 시간 및 코드의 초기화 시간에 따라 새 실행 환경으로 호출을 라우팅할 때 지연 시간이 발생할 수 있다. 이 지연 시간을 일반적으로 "콜드 스타트(Cold start)"라고 한다.
> http://aws.amazon.com/ko/blogs/korea/new-provisioned-concurrency-for-lambda-functions/
c. Serverless Pod 기동 종료 확인
[root@ip-192-168-114-198 knative]# kubectl get pods -w
NAME READY STATUS RESTARTS AGE
python-build-pod-2744b6 0/1 Completed 0 36m
helloworld-python-f8j5n-deployment-5754869ffc-txvdh 0/2 Pending 0 0s
helloworld-python-f8j5n-deployment-5754869ffc-txvdh 0/2 Pending 0 0s
helloworld-python-f8j5n-deployment-5754869ffc-txvdh 0/2 ContainerCreating 0 0s
helloworld-python-f8j5n-deployment-5754869ffc-txvdh 1/2 Running 0 3s
helloworld-python-f8j5n-deployment-5754869ffc-txvdh 2/2 Running 0 4s
helloworld-python-f8j5n-deployment-5754869ffc-txvdh 2/2 Terminating 0 64s
helloworld-python-f8j5n-deployment-5754869ffc-txvdh 1/2 Terminating 0 85s
helloworld-python-f8j5n-deployment-5754869ffc-txvdh 0/2 Terminating 0 85s
helloworld-python-f8j5n-deployment-5754869ffc-txvdh 0/2 Terminating 0 93s
helloworld-python-f8j5n-deployment-5754869ffc-txvdh 0/2 Terminating 0 93s
위와 같이 호출 시작 후 약 4초 뒤 Pod가 생성 및 기동이 완료되고, 비즈니스 처리가 완료된 후 60초 후(Container 생성 후 64초 후) Pod가 자동으로 Terminating 되는 것을 알 수 있다.
d. 반복 호출
다음으로 아래와 같이 동일한 호출을 다섯번 반복적으로 호출해 보자.
[root@ip-192-168-114-198 knative]# curl -H "Host: helloworld-python.default.example.com" http://afe2c222e1558413d8e8acfd0ef74357-1341022058.ap-northeast-2.elb.amazonaws.com
Hi!! Serverless: Python Sample v1!
[root@ip-192-168-114-198 knative]# curl -H "Host: helloworld-python.default.example.com" http://afe2c222e1558413d8e8acfd0ef74357-1341022058.ap-northeast-2.elb.amazonaws.com
Hi!! Serverless: Python Sample v1!
[root@ip-192-168-114-198 knative]# curl -H "Host: helloworld-python.default.example.com" http://afe2c222e1558413d8e8acfd0ef74357-1341022058.ap-northeast-2.elb.amazonaws.com
Hi!! Serverless: Python Sample v1!
[root@ip-192-168-114-198 knative]# curl -H "Host: helloworld-python.default.example.com" http://afe2c222e1558413d8e8acfd0ef74357-1341022058.ap-northeast-2.elb.amazonaws.com
Hi!! Serverless: Python Sample v1!
[root@ip-192-168-114-198 knative]# curl -H "Host: helloworld-python.default.example.com" http://afe2c222e1558413d8e8acfd0ef74357-1341022058.ap-northeast-2.elb.amazonaws.com
Hi!! Serverless: Python Sample v1!
[root@ip-192-168-114-198 knative]#
위와 같이 반복적으로 호출할 경우의 Pod를 확인해 보면 다음과 같다.
[root@ip-192-168-114-198 knative]# kubectl get pods -w
NAME READY STATUS RESTARTS AGE
python-build-pod-2744b6 0/1 Completed 0 44m
helloworld-python-f8j5n-deployment-5754869ffc-rwqvh 0/2 Pending 0 0s
helloworld-python-f8j5n-deployment-5754869ffc-rwqvh 0/2 Pending 0 0s
helloworld-python-f8j5n-deployment-5754869ffc-rwqvh 0/2 ContainerCreating 0 0s
helloworld-python-f8j5n-deployment-5754869ffc-rwqvh 1/2 Running 0 2s
helloworld-python-f8j5n-deployment-5754869ffc-rwqvh 2/2 Running 0 2s
helloworld-python-f8j5n-deployment-5754869ffc-rwqvh 2/2 Terminating 0 86s
helloworld-python-f8j5n-deployment-5754869ffc-rwqvh 1/2 Terminating 0 106s
helloworld-python-f8j5n-deployment-5754869ffc-rwqvh 0/2 Terminating 0 107s
helloworld-python-f8j5n-deployment-5754869ffc-rwqvh 0/2 Terminating 0 111s
helloworld-python-f8j5n-deployment-5754869ffc-rwqvh 0/2 Terminating 0 111s
위와 같이 현재 기동되어 있는 Serverless Pod가 종료되기 전 상태일 경우 Pod를 추가로 기동하지 않고 재 활용된다.
결론
AWS Lambda는 이미 유명한 Serverless Computing으로 다양한 비즈니스에서 활용되고 있다. 이와 같은 Public Cloud 상의 Serverless Computing 기술은 다양하게 활용되고 있지만, 종족성을 갖고 있어 Multi/Hybrid Cloud 환경에 적용하기에는 제약이 있다.
Knative 프로젝트를 활용하면 특정 Public Cloud에 종속적인 서비스와 다르게 Public Cloud는 물론 On-Prem Kubernetes 기반에서 이와 같은 Serverless Cloud Native Application을 개발하도록 지원할 수 있으며, Lock-In 요소를 최소화 할 수 있다.
현재 Knative는 Serverless Computing을 이끌어가는 대표적인 오픈소스 소프트웨어로써 자리잡고 있으며, 앞으로 지속적인 성장을 예고하고 있다. 가이드에서 다룬 내용은 Knative Build / Serving 정도이지만, Monitoring, Eventing 등 다양한 방법으로 Knative를 적용해 볼 수 있으며, 이에 대한 활용 방법들은 차차 알아보도록 하자.
'③ 클라우드 > ⓚ Kubernetes' 카테고리의 다른 글
Kubernetes 환경변수 구성하기 (ConfigMap, Secret) (2) | 2021.01.03 |
---|---|
Podman, Buildah, Skopeo를 활용하여 Docker CLI 대체하기 (4) | 2020.12.30 |
Kubernetes CronJob 활용 (1) | 2020.09.27 |
Kubernetes Init Container & PodInitializing 트러블슈팅 (2) | 2020.09.26 |
Helm Best Practices (0) | 2020.07.26 |
- Total
- Today
- Yesterday
- webtob
- Docker
- OpenStack
- Da
- git
- 쿠버네티스
- 마이크로서비스 아키텍처
- wildfly
- 오픈스택
- aa
- k8s
- SWA
- JEUS7
- aws
- openstack tenant
- API Gateway
- nodejs
- JEUS6
- apache
- TA
- Architecture
- node.js
- jeus
- 아키텍처
- SA
- openstack token issue
- JBoss
- kubernetes
- MSA
- 마이크로서비스
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |