4.5. 외부 및 인그레스 라우팅

4.5.1. 라우팅 개요

Knative에서는 OpenShift Container Platform TLS 종료를 활용하여 Knative 서비스에 대한 라우팅을 제공합니다. Knative 서비스가 생성되면 서비스에 대해 OpenShift Container Platform 경로가 자동으로 생성됩니다. 이 경로는 OpenShift Serverless Operator에서 관리합니다. OpenShift Container Platform 경로는 OpenShift Container Platform 클러스터와 동일한 도메인을 통해 Knative 서비스를 표시합니다.

OpenShift Container Platform 라우팅에 대한 Operator의 제어를 비활성화하여 대신 TLS 인증서를 직접 사용하도록 Knative 경로를 구성할 수 있습니다.

또한 Knative 경로를 OpenShift Container Platform 경로와 함께 사용하면 트래픽 분할과 같은 세분화된 라우팅 기능을 추가로 제공할 수 있습니다.

4.5.1.1. 추가 리소스

4.5.2. 레이블 및 주석 사용자 정의

OpenShift Container Platform 경로는 사용자 정의 레이블 및 주석을 사용할 수 있으며 Knative 서비스의 metadata 사양을 수정하여 구성할 수 있습니다. 사용자 정의 레이블 및 주석은 서비스에서 Knative 경로로 전달된 다음 Knative Ingress로 전달되고 마지막으로 OpenShift Container Platform 경로로 전달됩니다.

4.5.2.1. OpenShift Container Platform 경로에 대한 레이블 및 주석 사용자 정의

사전 요구 사항

  • OpenShift Serverless Operator 및 Knative Serving 구성 요소가 OpenShift Container Platform 클러스터에 설치되어 있습니다.
  • OpenShift CLI(oc)를 설치합니다.

절차

  1. OpenShift Container Platform 경로에 전달할 레이블 또는 주석이 포함된 Knative 서비스를 생성합니다.

    • YAML을 사용하여 서비스를 생성하려면 다음을 수행합니다.

      YAML을 사용하여 생성한 서비스 예

      apiVersion: serving.knative.dev/v1
      kind: Service
      metadata:
        name: <service_name>
        labels:
          <label_name>: <label_value>
        annotations:
          <annotation_name>: <annotation_value>
      ...

    • Knative(kn) CLI를 사용하여 서비스를 생성하려면 다음을 입력합니다.

      kn 명령을 사용하여 생성된 서비스 예

      $ kn service create <service_name> \
        --image=<image> \
        --annotation <annotation_name>=<annotation_value> \
        --label <label_value>=<label_value>

  2. 다음 명령의 출력을 확인하여 추가한 주석 또는 레이블을 사용하여 OpenShift Container Platform 경로가 생성되었는지 확인합니다.

    확인을 위한 명령 예

    $ oc get routes.route.openshift.io \
         -l serving.knative.openshift.io/ingressName=<service_name> \ 1
         -l serving.knative.openshift.io/ingressNamespace=<service_namespace> \ 2
         -n knative-serving-ingress -o yaml \
             | grep -e "<label_name>: \"<label_value>\""  -e "<annotation_name>: <annotation_value>" 3

    1
    서비스 이름을 사용합니다.
    2
    서비스가 생성된 네임스페이스를 사용합니다.
    3
    레이블 및 주석 이름과 값의 값을 사용합니다.

4.5.3. Knative 서비스의 경로 구성

OpenShift Container Platform에서 TLS 인증서를 사용하도록 Knative 서비스를 구성하려면 OpenShift Serverless Operator의 서비스 경로 자동 생성 기능을 비활성화하고 대신 해당 서비스에 대한 경로를 수동으로 생성해야 합니다.

참고

다음 절차를 완료하면 knative-serving-ingress 네임스페이스의 기본 OpenShift Container Platform 경로가 생성되지 않습니다. 그러나 애플리케이션의 Knative 경로는 이 네임스페이스에 계속 생성됩니다.

4.5.3.1. Knative 서비스에 대한 OpenShift Container Platform 경로 구성

사전 요구 사항

  • OpenShift Serverless Operator 및 Knative Serving 구성 요소가 OpenShift Container Platform 클러스터에 설치되어 있어야 합니다.
  • OpenShift CLI(oc)를 설치합니다.

절차

  1. serving.knative.openshift.io/disableRoute=true 주석이 포함된 Knative 서비스를 생성합니다.

    중요

    serving.knative.openshift.io/disableRoute=true 주석은 OpenShift Serverless에서 경로를 자동으로 생성하지 않도록 지시합니다. 그러나 서비스는 여전히 URL을 표시하며 Ready 상태에 도달합니다. 이 URL은 URL의 호스트 이름과 동일한 호스트 이름으로 자체 경로를 생성할 때까지 외부에서 작동하지 않습니다.

    1. Knative 서비스 리소스를 생성합니다.

      리소스 예

      apiVersion: serving.knative.dev/v1
      kind: Service
      metadata:
        name: <service_name>
        annotations:
          serving.knative.openshift.io/disableRoute: "true"
      spec:
        template:
          spec:
            containers:
            - image: <image>
      ...

    2. Service 리소스를 적용합니다.

      $ oc apply -f <filename>
    3. 선택 사항입니다. kn service create 명령을 사용하여 Knative 서비스를 생성합니다.

      kn 명령 예제

      $ kn service create <service_name> \
        --image=gcr.io/knative-samples/helloworld-go \
        --annotation serving.knative.openshift.io/disableRoute=true

  2. 서비스에 OpenShift Container Platform 경로가 생성되지 않았는지 확인합니다.

    명령 예

    $ $ oc get routes.route.openshift.io \
      -l serving.knative.openshift.io/ingressName=$KSERVICE_NAME \
      -l serving.knative.openshift.io/ingressNamespace=$KSERVICE_NAMESPACE \
      -n knative-serving-ingress

    다음 출력이 표시됩니다.

    No resources found in knative-serving-ingress namespace.
  3. knative-serving-ingress 네임스페이스에 Route 리소스를 생성합니다.

    apiVersion: route.openshift.io/v1
    kind: Route
    metadata:
      annotations:
        haproxy.router.openshift.io/timeout: 600s 1
      name: <route_name> 2
      namespace: knative-serving-ingress 3
    spec:
      host: <service_host> 4
      port:
        targetPort: http2
      to:
        kind: Service
        name: kourier
        weight: 100
      tls:
        insecureEdgeTerminationPolicy: Allow
        termination: edge 5
        key: |-
          -----BEGIN PRIVATE KEY-----
          [...]
          -----END PRIVATE KEY-----
        certificate: |-
          -----BEGIN CERTIFICATE-----
          [...]
          -----END CERTIFICATE-----
        caCertificate: |-
          -----BEGIN CERTIFICATE-----
          [...]
          -----END CERTIFICATE----
      wildcardPolicy: None
    1
    OpenShift Container Platform 경로에 대한 타임아웃 값입니다. max-revision-timeout-seconds 설정과 동일한 값으로 설정해야 합니다(기본값: 600s).
    2
    OpenShift Container Platform 경로의 이름입니다.
    3
    OpenShift Container Platform 경로의 네임스페이스입니다. knative-serving-ingress여야 합니다.
    4
    외부 액세스를 위한 호스트 이름입니다. 이 값을 <service_name>-<service_namespace>.<domain>으로 설정할 수 있습니다.
    5
    사용할 인증서입니다. 현재는 edge 종료만 지원됩니다.
  4. Route 리소스를 적용합니다.

    $ oc apply -f <filename>

4.5.4. 글로벌 HTTPS 리디렉션

HTTPS 리디렉션은 들어오는 HTTP 요청에 대한 리디렉션을 제공합니다. 이러한 리디렉션된 HTTP 요청은 암호화됩니다. KnativeServing CR(사용자 정의 리소스)에 httpProtocol 사양을 구성하여 클러스터의 모든 서비스에 대해 HTTPS 리디렉션을 활성화할 수 있습니다.

4.5.4.1. HTTPS 리디렉션 전역 설정

HTTPS 리디렉션을 활성화하는 KnativeServing CR의 예

apiVersion: operator.knative.dev/v1beta1
kind: KnativeServing
metadata:
  name: knative-serving
spec:
  config:
    network:
      httpProtocol: "redirected"
...

4.5.5. 외부 경로에 대한 URL 스키마

보안을 강화하기 위해 외부 경로의 URL 스키마는 기본적으로 HTTPS로 설정됩니다. 이 스키마는 KnativeServing CR(사용자 정의 리소스) 사양의 default-external-scheme 키로 결정됩니다.

4.5.5.1. 외부 경로의 URL 스키마 설정

기본 사양

...
spec:
  config:
    network:
      default-external-scheme: "https"
...

default-external-scheme 키를 수정하여 HTTP를 사용하도록 기본 사양을 덮어쓸 수 있습니다.

HTTP 덮어쓰기 사양

...
spec:
  config:
    network:
      default-external-scheme: "http"
...

4.5.6. 서비스당 HTTPS 리디렉션

networking.knative.dev/http-option 주석을 구성하여 서비스의 HTTPS 리디렉션을 활성화하거나 비활성화할 수 있습니다.

4.5.6.1. 서비스의 HTTPS 리디렉션

다음 예제에서는 Knative Service YAML 오브젝트에서 이 주석을 사용하는 방법을 보여줍니다.

apiVersion: serving.knative.dev/v1
kind: Service
metadata:
  name: example
  namespace: default
  annotations:
    networking.knative.dev/http-option: "redirected"
spec:
  ...

4.5.7. 클러스터 로컬 가용성

기본적으로 Knative 서비스는 공용 IP 주소에 게시됩니다. 공용 IP 주소에 게시된다는 것은 Knative 서비스가 공용 애플리케이션이 되어 공개적으로 액세스할 수 있는 URL이 있음을 의미합니다.

공개적으로 액세스할 수 있는 URL은 클러스터 외부에서 액세스할 수 있습니다. 그러나 개발자는 클러스터 내부에서만 액세스할 수 있는 백엔드 서비스(비공개 서비스)를 빌드해야 할 수 있습니다. 개발자는 클러스터의 개별 서비스에 networking.knative.dev/visibility=cluster-local 레이블을 지정하여 비공개로 설정할 수 있습니다.

중요

OpenShift Serverless 1.15.0 및 최신 버전의 경우 serving.knative.dev/visibility 레이블을 더 이상 사용할 수 없습니다. 대신 networking.knative.dev/visibility 레이블을 사용하려면 기존 서비스를 업데이트해야 합니다.

4.5.7.1. 클러스터 로컬로 클러스터 가용성 설정

사전 요구 사항

  • OpenShift Serverless Operator 및 Knative Serving이 클러스터에 설치되어 있습니다.
  • Knative 서비스를 생성했습니다.

절차

  • networking.knative.dev/visibility=cluster-local 레블을 추가하여 서비스 가시성을 설정합니다.

    $ oc label ksvc <service_name> networking.knative.dev/visibility=cluster-local

검증

  • 다음 명령을 입력하고 출력을 검토하여 서비스의 URL이 http://<service_name>.<namespace>.svc.cluster.local 형식인지 확인합니다.

    $ oc get ksvc

    출력 예

    NAME            URL                                                                         LATESTCREATED     LATESTREADY       READY   REASON
    hello           http://hello.default.svc.cluster.local                                      hello-tx2g7       hello-tx2g7       True

4.5.7.2. 클러스터 로컬 서비스에 대한 TLS 인증 활성화

클러스터 로컬 서비스의 경우 Kourier 로컬 게이트웨이 kourier-internal 이 사용됩니다. Kourier 로컬 게이트웨이에 대해 TLS 트래픽을 사용하려면 로컬 게이트웨이에서 자체 서버 인증서를 구성해야 합니다.

사전 요구 사항

  • OpenShift Serverless Operator 및 Knative Serving이 설치되어 있습니다.
  • 관리자 권한이 있어야 합니다.
  • OpenShift(oc) CLI를 설치했습니다.

절차

  1. knative-serving-ingress 네임스페이스에 서버 인증서를 배포합니다.

    $ export san="knative"
    참고

    이러한 인증서가 < app_name>.<namespace>.svc.cluster.local 에 대한 요청을 제공할 수 있도록 SAN(Subject Alternative Name) 검증이 필요합니다.

  2. 루트 키 및 인증서를 생성합니다.

    $ openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 \
        -subj '/O=Example/CN=Example' \
        -keyout ca.key \
        -out ca.crt
  3. SAN 검증을 사용하는 서버 키를 생성합니다.

    $ openssl req -out tls.csr -newkey rsa:2048 -nodes -keyout tls.key \
      -subj "/CN=Example/O=Example" \
      -addext "subjectAltName = DNS:$san"
  4. 서버 인증서를 생성합니다.

    $ openssl x509 -req -extfile <(printf "subjectAltName=DNS:$san") \
      -days 365 -in tls.csr \
      -CA ca.crt -CAkey ca.key -CAcreateserial -out tls.crt
  5. Kourier 로컬 게이트웨이의 시크릿을 구성합니다.

    1. 이전 단계에서 생성한 인증서에서 knative-serving-ingress 네임스페이스에 보안을 배포합니다.

      $ oc create -n knative-serving-ingress secret tls server-certs \
          --key=tls.key \
          --cert=tls.crt --dry-run=client -o yaml | oc apply -f -
    2. Kourier 게이트웨이에서 생성한 보안을 사용하도록 KnativeServing CR(사용자 정의 리소스) 사양을 업데이트합니다.

      KnativeServing CR의 예

      ...
      spec:
        config:
          kourier:
            cluster-cert-secret: server-certs
      ...

Kourier 컨트롤러는 서비스를 재시작하지 않고 인증서를 설정하므로 Pod를 다시 시작할 필요가 없습니다.

클라이언트의 ca.crt 를 마운트하고, 포트 443 을 통해 TLS를 사용하여 Kourier 내부 서비스에 액세스할 수 있습니다.

4.5.8. Kourier Gateway 서비스 유형

Kourier 게이트웨이는 기본적으로 ClusterIP 서비스 유형으로 노출됩니다. 이 서비스 유형은 KnativeServing CR(사용자 정의 리소스)의 서비스 유형 Ingress 사양에 따라 결정됩니다.

기본 사양

...
spec:
  ingress:
    kourier:
      service-type: ClusterIP
...

4.5.8.1. Kourier Gateway 서비스 유형 설정

service-type 사양을 수정하여 로드 밸런서 서비스 유형을 대신 사용하도록 기본 서비스 유형을 덮어쓸 수 있습니다.

LoadBalancer 덮어쓰기 사양

...
spec:
  ingress:
    kourier:
      service-type: LoadBalancer
...

4.5.9. HTTP2 및 gRPC 사용

OpenShift Serverless에서는 비보안 또는 엣지 종료 경로만 지원합니다. 비보안 또는 엣지 종료 경로에서는 OpenShift Container Platform에서 HTTP2를 지원하지 않습니다. 또한 이러한 경로는 gRPC가 HTTP2에 의해 전송되기 때문에 gRPC를 지원하지 않습니다. 애플리케이션에서 이러한 프로토콜을 사용하는 경우 수신 게이트웨이를 사용하여 애플리케이션을 직접 호출해야 합니다. 이를 위해서는 수신 게이트웨이의 공용 주소와 애플리케이션의 특정 호스트를 찾아야 합니다.

4.5.9.1. HTTP2 및 gRPC를 사용하여 서버리스 애플리케이션과 상호 작용

중요

이 메서드는 LoadBalancer 서비스 유형을 사용하여 Kourier Gateway를 노출해야 합니다. KnativeServing CRD(사용자 정의 리소스 정의)에 다음 YAML을 추가하여 이를 구성할 수 있습니다.

...
spec:
  ingress:
    kourier:
      service-type: LoadBalancer
...

사전 요구 사항

  • OpenShift Serverless Operator 및 Knative Serving이 클러스터에 설치되어 있습니다.
  • OpenShift CLI(oc)를 설치합니다.
  • Knative 서비스를 생성했습니다.

절차

  1. 애플리케이션 호스트를 찾습니다. 서버리스 애플리케이션 배포 확인에 있는 지침을 참조하십시오.
  2. 수신 게이트웨이의 공용 주소를 찾습니다.

    $ 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입니다.

  3. 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)를 두 호스트 모두에 추가해야 합니다.