5장. 개발
5.1. 서버리스 애플리케이션
서버리스 애플리케이션은 경로와 구성으로 정의되고 YAML 파일에 포함된 Kubernetes 서비스로 생성 및 배포됩니다. OpenShift Serverless를 사용하여 서버리스 애플리케이션을 배포하려면 Knative Service
오브젝트를 생성해야 합니다.
Knative Service
오브젝트 YAML 파일의 예
apiVersion: serving.knative.dev/v1 kind: Service metadata: name: hello 1 namespace: default 2 spec: template: spec: containers: - image: docker.io/openshift/hello-openshift 3 env: - name: RESPONSE 4 value: "Hello Serverless!"
다음 방법 중 하나를 사용하여 서버리스 애플리케이션을 생성합니다.
- OpenShift Container Platform 웹 콘솔에서 Knative 서비스를 생성합니다. 개발자 화면을 사용하여 애플리케이션 생성에 대한 설명서를 참조하십시오.
-
Knative(
kn
) CLI를 사용하여 Knative 서비스를 생성합니다. -
oc
CLI를 사용하여 KnativeService
오브젝트를 YAML 파일로 생성하고 적용합니다.
5.1.1. Knative CLI를 사용하여 서버리스 애플리케이션 생성
Knative(kn
) CLI를 사용하여 서버리스 애플리케이션을 생성하면 YAML 파일을 직접 수정하는 것보다 더 간소화되고 직관적인 사용자 인터페이스를 제공합니다. kn service create
명령을 사용하여 기본 서버리스 애플리케이션을 생성할 수 있습니다.
사전 요구 사항
- OpenShift Serverless Operator 및 Knative Serving이 클러스터에 설치되어 있습니다.
-
Knative(
kn
) CLI가 설치되어 있습니다. - 프로젝트를 생성했거나 OpenShift Container Platform에서 애플리케이션 및 기타 워크로드를 생성하는 데 적절한 역할 및 권한이 있는 프로젝트에 액세스할 수 있습니다.
프로세스
Knative 서비스를 생성합니다.
$ kn service create <service-name> --image <image> --tag <tag-value>
다음과 같습니다.
-
--image
는 애플리케이션의 이미지 URI입니다. --tag
는 서비스로 생성된 초기 버전에 태그를 추가하는 데 사용할 수 있는 선택적 플래그입니다.명령 예
$ kn service create event-display \ --image quay.io/openshift-knative/knative-eventing-sources-event-display:latest
출력 예
Creating service 'event-display' in namespace 'default': 0.271s The Route is still working to reflect the latest desired specification. 0.580s Configuration "event-display" is waiting for a Revision to become ready. 3.857s ... 3.861s Ingress has not yet been reconciled. 4.270s Ready to serve. Service 'event-display' created with latest revision 'event-display-bxshg-1' and URL: http://event-display-default.apps-crc.testing
-
5.1.2. 오프라인 모드를 사용하여 서비스 생성
오프라인 모드에서 kn service
명령을 실행할 수 있으므로 클러스터에서 변경 사항이 발생하지 않고 로컬 시스템에서 서비스 설명자 파일이 생성됩니다. 설명자 파일이 생성되면 클러스터에 대한 변경 사항을 전파하기 전에 파일을 수정할 수 있습니다.
Knative CLI의 오프라인 모드는 기술 프리뷰 기능 전용입니다. 기술 프리뷰 기능은 Red Hat 프로덕션 서비스 수준 계약(SLA)에서 지원되지 않으며 기능적으로 완전하지 않을 수 있습니다. 따라서 프로덕션 환경에서 사용하는 것은 권장하지 않습니다. 이러한 기능을 사용하면 향후 제품 기능을 조기에 이용할 수 있어 개발 과정에서 고객이 기능을 테스트하고 피드백을 제공할 수 있습니다.
Red Hat 기술 프리뷰 기능의 지원 범위에 대한 자세한 내용은 https://access.redhat.com/support/offerings/techpreview/를 참조하십시오.
사전 요구 사항
- OpenShift Serverless Operator 및 Knative Serving이 클러스터에 설치되어 있습니다.
-
Knative(
kn
) CLI가 설치되어 있습니다.
프로세스
오프라인 모드에서 로컬 Knative 서비스 설명자 파일을 생성합니다.
$ kn service create event-display \ --image quay.io/openshift-knative/knative-eventing-sources-event-display:latest \ --target ./ \ --namespace test
출력 예
Service 'event-display' created in namespace 'test'.
--target ./
플래그는 오프라인 모드를 활성화하고 새 디렉터리 트리를 저장하는 디렉토리로./
를 지정합니다.기존 디렉터리를 지정하지 않고
--target my-service.yaml
과 같은 파일 이름을 사용하면 디렉터리 트리가 생성되지 않습니다. 대신 서비스 설명자 파일my-service.yaml
만 현재 디렉터리에 생성됩니다.파일 이름에는.
.yaml
,.yml
, 또는.json
확장을 사용할 수 있습니다..json
을 선택하면 JSON 형식으로 서비스 설명자 파일을 생성합니다.--namespace test
옵션은 새 서비스를test
네임스페이스에 배치합니다.--namespace
를 사용하지 않고 OpenShift 클러스터에 로그인한 경우 현재 네임스페이스에 설명자 파일이 생성됩니다. 그렇지 않으면 설명자 파일이default
네임스페이스에 생성됩니다.
생성된 디렉터리 구조를 확인합니다.
$ tree ./
출력 예
./ └── test └── ksvc └── event-display.yaml 2 directories, 1 file
-
--target
에서 지정된 현재./
디렉터리에는 지정된 네임스페이스를 바탕으로 이름이 지정된test/
디렉터리가 포함되어 있습니다. -
test/
디렉터리에는 리소스 유형의 이름에 따라 이름이 지정된ksvc
디렉터리가 포함되어 있습니다. -
ksvc
디렉터리에는 지정된 서비스 이름에 따라 이름이 지정된 기술자 파일event-display.yaml
이 포함되어 있습니다.
-
생성된 서비스 기술자 파일을 확인합니다.
$ cat test/ksvc/event-display.yaml
출력 예
apiVersion: serving.knative.dev/v1 kind: Service metadata: creationTimestamp: null name: event-display namespace: test spec: template: metadata: annotations: client.knative.dev/user-image: quay.io/openshift-knative/knative-eventing-sources-event-display:latest creationTimestamp: null spec: containers: - image: quay.io/openshift-knative/knative-eventing-sources-event-display:latest name: "" resources: {} status: {}
새 서비스에 대한 정보를 나열합니다.
$ kn service describe event-display --target ./ --namespace test
출력 예
Name: event-display Namespace: test Age: URL: Revisions: Conditions: OK TYPE AGE REASON
target ./
옵션은 네임스페이스 하위 디렉터리를 포함하는 디렉터리 구조의 루트 디렉터리를 지정합니다.또는
--target
옵션을 사용하여 YAML 또는 JSON 파일 이름을 직접 지정할 수 있습니다. 허용된 파일 확장자는.yaml
,.yml
,.json
입니다.--namespace
옵션은 필요한 서비스 기술자 파일을 포함하는 하위 디렉터리를kn
와 통신하는 네임스페이스를 지정합니다.--namespace
를 사용하지 않고 OpenShift 클러스터에 로그인한 경우kn
은 현재 네임스페이스의 이름이 지정된 하위 디렉터리에서 서비스를 검색합니다. 그렇지 않으면kn
은default/
하위 디렉터리에서 검색합니다.
서비스 설명자 파일을 사용하여 클러스터에 서비스를 생성합니다.
$ kn service create -f test/ksvc/event-display.yaml
출력 예
Creating service 'event-display' in namespace 'test': 0.058s The Route is still working to reflect the latest desired specification. 0.098s ... 0.168s Configuration "event-display" is waiting for a Revision to become ready. 23.377s ... 23.419s Ingress has not yet been reconciled. 23.534s Waiting for load balancer to be ready 23.723s Ready to serve. Service 'event-display' created to latest revision 'event-display-00001' is available at URL: http://event-display-test.apps.example.com
5.1.3. YAML을 사용하여 서버리스 애플리케이션 생성
YAML 파일을 사용하여 Knative 리소스를 생성하면 선언적 방식으로 애플리케이션을 재현할 수 있으며 재현 가능한 방식으로 애플리케이션을 설명할 수 있습니다. YAML을 사용하여 서버리스 애플리케이션을 생성하려면 Knative Service
오브젝트를 정의하는 YAML 파일을 생성한 다음 oc apply
를 사용하여 적용해야 합니다.
서비스가 생성되고 애플리케이션이 배포되면 Knative에서 이 버전의 애플리케이션에 대해 변경할 수 없는 버전을 생성합니다. Knative는 또한 네트워크 프로그래밍을 수행하여 애플리케이션의 경로, 수신, 서비스 및 로드 밸런서를 생성하고 트래픽에 따라 Pod를 자동으로 확장합니다.
사전 요구 사항
- OpenShift Serverless Operator 및 Knative Serving이 클러스터에 설치되어 있습니다.
- 프로젝트를 생성했거나 OpenShift Container Platform에서 애플리케이션 및 기타 워크로드를 생성하는 데 적절한 역할 및 권한이 있는 프로젝트에 액세스할 수 있습니다.
-
OpenShift CLI(
oc
)를 설치합니다.
프로세스
다음 샘플 코드를 포함하는 YAML 파일을 생성합니다.
apiVersion: serving.knative.dev/v1 kind: Service metadata: name: event-delivery namespace: default spec: template: spec: containers: - image: quay.io/openshift-knative/knative-eventing-sources-event-display:latest env: - name: RESPONSE value: "Hello Serverless!"
YAML 파일이 포함된 디렉터리로 이동한 후 YAML 파일을 적용하여 애플리케이션을 배포합니다.
$ oc apply -f <filename>
5.1.4. 서버리스 애플리케이션 배포 확인
서버리스 애플리케이션이 성공적으로 배포되었는지 확인하려면 Knative에서 생성한 애플리케이션 URL을 가져와서 해당 URL로 요청을 보낸 후 출력을 관찰해야 합니다. OpenShift Serverless에서는 HTTP 및 HTTPS URL을 모두 사용할 수 있지만 oc get ksvc
출력에서는 항상 http://
형식을 사용하여 URL을 출력합니다.
사전 요구 사항
- OpenShift Serverless Operator 및 Knative Serving이 클러스터에 설치되어 있습니다.
-
oc
CLI를 설치했습니다. - Knative 서비스를 생성했습니다.
사전 요구 사항
-
OpenShift CLI(
oc
)를 설치합니다.
프로세스
애플리케이션 URL을 찾습니다.
$ oc get ksvc <service_name>
출력 예
NAME URL LATESTCREATED LATESTREADY READY REASON event-delivery http://event-delivery-default.example.com event-delivery-4wsd2 event-delivery-4wsd2 True
클러스터에 요청한 후 출력을 확인합니다.
HTTP 요청의 예
$ curl http://event-delivery-default.example.com
HTTPS 요청의 예
$ curl https://event-delivery-default.example.com
출력 예
Hello Serverless!
선택 사항입니다. 인증서 체인에서 자체 서명된 인증서와 관련된 오류가 발생하면
--insecure
플래그를 curl 명령에 추가하여 오류를 무시할 수 있습니다.$ curl https://event-delivery-default.example.com --insecure
출력 예
Hello Serverless!
중요프로덕션 배포에는 자체 서명된 인증서를 사용해서는 안 됩니다. 이 방법은 테스트 목적으로만 사용됩니다.
선택 사항입니다. OpenShift Container Platform 클러스터가 CA(인증 기관)에서 서명한 인증서로 구성되어 있지만 아직 시스템에 전역적으로 구성되지 않은 경우
curl
명령으로 이 인증서를 지정할 수 있습니다. 인증서 경로는--cacert
플래그를 사용하여 curl 명령에 전달할 수 있습니다.$ curl https://event-delivery-default.example.com --cacert <file>
출력 예
Hello Serverless!
5.1.5. HTTP2 및 gRPC를 사용하여 서버리스 애플리케이션과 상호 작용
OpenShift Serverless에서는 비보안 또는 엣지 종료 경로만 지원합니다. 비보안 또는 엣지 종료 경로에서는 OpenShift Container Platform에서 HTTP2를 지원하지 않습니다. 또한 이러한 경로는 gRPC가 HTTP2에 의해 전송되기 때문에 gRPC를 지원하지 않습니다. 애플리케이션에서 이러한 프로토콜을 사용하는 경우 수신 게이트웨이를 사용하여 애플리케이션을 직접 호출해야 합니다. 이를 위해서는 수신 게이트웨이의 공용 주소와 애플리케이션의 특정 호스트를 찾아야 합니다.
이 메서드는 LoadBalancer
서비스 유형을 사용하여 Kourier Gateway를 노출해야 합니다. KnativeServing
CRD(사용자 정의 리소스 정의)에 다음 YAML을 추가하여 이를 구성할 수 있습니다.
... spec: ingress: kourier: service-type: LoadBalancer ...
사전 요구 사항
- OpenShift Serverless Operator 및 Knative Serving이 클러스터에 설치되어 있습니다.
-
OpenShift CLI(
oc
)를 설치합니다. - Knative 서비스를 생성했습니다.
절차
- 애플리케이션 호스트를 찾습니다. 서버리스 애플리케이션 배포 확인에 있는 지침을 참조하십시오.
수신 게이트웨이의 공용 주소를 찾습니다.
$ oc -n knative-serving-ingress get svc kourier
출력 예
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kourier LoadBalancer 172.30.51.103 a83e86291bcdd11e993af02b7a65e514-33544245.us-east-1.elb.amazonaws.com 80:31380/TCP,443:31390/TCP 67m
공용 주소는
EXTERNAL-IP
필드에 있으며 이 경우a83e86291bcdd11e993af02b7a65e514-33544245.us-east-1.elb.amazonaws.com
입니다.HTTP 요청의 호스트 헤더를 애플리케이션의 호스트로 수동으로 설정하되 요청 자체는 수신 게이트웨이의 공개 주소로 지정합니다.
$ curl -H "Host: hello-default.example.com" a83e86291bcdd11e993af02b7a65e514-33544245.us-east-1.elb.amazonaws.com
출력 예
Hello Serverless!
수신 게이트웨이에 대한 요청을 직접 지시하는 동안 애플리케이션 호스트에 기관을 설정하여 gRPC 요청을 생성할 수도 있습니다.
grpc.Dial( "a83e86291bcdd11e993af02b7a65e514-33544245.us-east-1.elb.amazonaws.com:80", grpc.WithAuthority("hello-default.example.com:80"), grpc.WithInsecure(), )
참고위 예제와 같이 각 포트(기본값 80)를 두 호스트 모두에 추가해야 합니다.
5.1.6. 제한적인 네트워크 정책을 사용하여 클러스터에서 Knative 애플리케이션과의 통신 활성화
여러 사용자가 액세스할 수 있는 클러스터를 사용하는 경우 클러스터는 네트워크 정책을 사용하여 네트워크를 통해 서로 통신할 수 있는 pod, 서비스 및 네임스페이스를 제어할 수 있습니다. 클러스터에서 제한적인 네트워크 정책을 사용하는 경우 Knative 시스템 Pod가 Knative 애플리케이션에 액세스할 수 없습니다. 예를 들어 네임스페이스에 모든 요청을 거부하는 다음 네트워크 정책이 있는 경우 Knative 시스템 Pod가 Knative 애플리케이션에 액세스할 수 없습니다.
네임스페이스에 대한 모든 요청을 거부하는 NetworkPolicy 오브젝트의 예
kind: NetworkPolicy apiVersion: networking.k8s.io/v1 metadata: name: deny-by-default namespace: example-namespace spec: podSelector: ingress: []
Knative 시스템 Pod에서 애플리케이션에 액세스할 수 있도록 하려면 각 Knative 시스템 네임스페이스에 레이블을 추가한 다음 이 레이블이 있는 다른 네임스페이스의 네임스페이스에 액세스할 수 있는 애플리케이션 네임스페이스에 NetworkPolicy
오브젝트를 생성해야 합니다.
클러스터의 비Knative 서비스에 대한 요청을 거부하는 네트워크 정책은 이러한 서비스에 대한 액세스를 계속 차단합니다. 그러나 Knative 시스템 네임스페이스에서 Knative 애플리케이션으로의 액세스를 허용하면 클러스터의 모든 네임스페이스에서 Knative 애플리케이션에 액세스할 수 있습니다.
클러스터의 모든 네임스페이스에서 Knative 애플리케이션에 대한 액세스를 허용하지 않으려면 Knative 서비스에 JSON 웹 토큰 인증을 사용할 수 있습니다. Knative 서비스에 대한 JSON 웹 토큰 인증에는 Service Mesh가 필요합니다.
사전 요구 사항
-
OpenShift CLI(
oc
)를 설치합니다. - OpenShift Serverless Operator 및 Knative Serving이 클러스터에 설치되어 있습니다.
절차
애플리케이션에 액세스해야 하는 각 Knative 시스템 네임스페이스에
knative.openshift.io/system-namespace=true
레이블을 추가합니다.knative-serving
네임스페이스에 레이블을 지정합니다.$ oc label namespace knative-serving knative.openshift.io/system-namespace=true
knative-serving-ingress
네임스페이스에 레이블을 지정합니다.$ oc label namespace knative-serving-ingress knative.openshift.io/system-namespace=true
knative-eventing
네임스페이스에 레이블을 지정합니다.$ oc label namespace knative-eventing knative.openshift.io/system-namespace=true
knative-kafka
네임스페이스에 레이블을 지정합니다.$ oc label namespace knative-kafka knative.openshift.io/system-namespace=true
애플리케이션 네임스페이스에
NetworkPolicy
오브젝트를 생성하여knative.openshift.io/system-namespace
레이블이 있는 네임스페이스에서 액세스를 허용합니다.NetworkPolicy
오브젝트 예apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: <network_policy_name> 1 namespace: <namespace> 2 spec: ingress: - from: - namespaceSelector: matchLabels: knative.openshift.io/system-namespace: "true" podSelector: {} policyTypes: - Ingress
5.1.7. init 컨테이너 구성
Init 컨테이너 는 Pod의 애플리케이션 컨테이너보다 먼저 실행되는 특수 컨테이너입니다. 일반적으로 애플리케이션에 대한 초기화 논리를 구현하는 데 사용됩니다. 이 논리에는 설정 스크립트를 실행하거나 필요한 구성을 다운로드하는 작업이 포함될 수 있습니다.
Init 컨테이너는 애플리케이션 시작 시간이 길어질 수 있으며 서버리스 애플리케이션에 주의해서 사용해야 합니다. 이 경우 자주 확장 및 축소할 것으로 예상됩니다.
여러 init 컨테이너가 단일 Knative 서비스 사양에서 지원됩니다. Knative는 템플릿 이름을 제공하지 않은 경우 구성 가능한 기본 이름 지정 템플릿을 제공합니다. init 컨테이너 템플릿은 Knative Service
오브젝트 사양에 적절한 값을 추가하여 설정할 수 있습니다.
사전 요구 사항
- OpenShift Serverless Operator 및 Knative Serving이 클러스터에 설치되어 있습니다.
-
Knative 서비스에 init 컨테이너를 사용하려면 관리자가
KnativeServing
CR(사용자 정의 리소스)에kubernetes.podspec-init-containers
플래그를 추가해야 합니다. 자세한 내용은 OpenShift Serverless "Global configuration" 설명서를 참조하십시오.
프로세스
initContainers
사양을 KnativeService
오브젝트에 추가합니다.서비스 사양 예
apiVersion: serving.knative.dev/v1 kind: Service ... spec: template: spec: initContainers: - imagePullPolicy: IfNotPresent 1 image: <image_uri> 2 volumeMounts: 3 - name: data mountPath: /data ...
5.1.8. 서비스당 HTTPS 리디렉션
networking.knative.dev/http-option
주석을 구성하여 서비스의 HTTPS 리디렉션을 활성화하거나 비활성화할 수 있습니다. 다음 예제에서는 Knative Service
YAML 오브젝트에서 이 주석을 사용하는 방법을 보여줍니다.
apiVersion: serving.knative.dev/v1 kind: Service metadata: name: example namespace: default annotations: networking.knative.dev/http-option: "redirected" spec: ...