Google Distributed Cloud(에어 갭 적용형) API 개요

Google Distributed Cloud (GDC) 에어 갭 애플리케이션 프로그래밍 인터페이스 (API)는 GDC 플랫폼 서비스의 프로그래매틱 인터페이스입니다. Google은 Kubernetes 리소스 모델 (KRM)을 사용하여 Kubernetes를 기반으로 컨트롤 플레인 API를 빌드합니다. 컨트롤 플레인은 생성, 삭제, 업데이트와 같은 서비스의 리소스 관리를 수행합니다.

특정 서비스에는 이러한 API와 자체 데이터 플레인 API(XML, JSON 또는 gRPC 기반)가 있습니다. 이 페이지에서는 이러한 서비스를 각각의 섹션에서 다룹니다.

GDC API 정보

GDC API에는 Kubernetes 기반 API와 Kubernetes 기반이 아닌 API의 두 가지 유형이 있습니다. 많은 GDC API는 오픈소스 Kubernetes API의 확장 프로그램입니다. Kubernetes 커스텀 리소스를 사용하고 KRM을 사용합니다. 이러한 API는 Kubernetes API와 마찬가지로 HTTP 기반 RESTful API이며 JSON을 기본값으로 또는 Protobuf로 수락하고 반환합니다. API 엔드포인트는 관련 Kubernetes 서버입니다.

Vertex 사전 학습된 AI API와 같은 Kubernetes 기반이 아닌 다른 GDC API에는 자체 엔드포인트가 있습니다. HTTP를 지원하는 것 외에도 이러한 API 중 일부는 오픈소스 원격 프로시저 호출 프레임워크인 gRPC를 통해 액세스할 수도 있습니다. 특정 API에 대한 자세한 내용은 세로 탐색 메뉴에서 전용 문서를 참조하세요.

GDC API에 액세스하려면 gdcloud CLI 도구 또는 GDC 콘솔을 사용하세요.

Kubernetes API 및 KRM 정보

많은 GDC API가 Kubernetes API의 확장 프로그램이고 KRM을 사용하므로 이러한 개념을 이해하면 GDC API를 최대한 활용할 수 있습니다.

Kubernetes API는 완전히 선언적이며 Kubernetes API의 모든 항목은 KRM을 따르는 리소스입니다. 사람과 머신 모두 API 클라이언트는 이러한 리소스에 대해 작업하며, 주로 만들기, 읽기, 업데이트, 삭제(CRUD) 작업을 수행합니다. Kubernetes 데이터베이스는 리소스를 저장하고 시스템의 상태를 나타냅니다. Kubernetes는 이러한 리소스를 지속적으로 감시하고 시스템의 실제 상태를 원하는 상태와 조정합니다. 예를 들어 Deployment 리소스를 업데이트하여 컨테이너의 복제본을 4개가 아닌 5개로 지정하면 Kubernetes는 원하는 복제본 수의 변경사항을 감지하고 컨테이너를 추가로 만듭니다.

핵심 Kubernetes API의 경우 Kubernetes는 원하는 상태와 실제 상태 간의 조정을 직접 수행합니다. Kubernetes API 확장 프로그램은 핵심 Kubernetes API에 포함되지 않은 커스텀 리소스입니다. 커스텀 소프트웨어는 Kubernetes API를 지속적으로 감시하고 상호작용하며 조정을 수행합니다.

Kubernetes API 및 Kubernetes 리소스 모델에 대해 자세히 알아보려면 공식 Kubernetes 문서를 읽어보세요.

전역 및 영역별 API

GDC 에어 갭의 리소스는 영역별 리소스 또는 전역 리소스입니다. 영역별 리소스는 단일 영역 내에서 독립적으로 작동하며 영역별 서비스 중단은 해당 영역의 일부 또는 모든 리소스에 영향을 줄 수 있습니다. 전역 리소스는 내결함성을 위해 여러 영역에서 중복으로 작동합니다.

GDC 에어 갭은 전역 API와 영역별 API라는 두 가지 수준의 관리 플레인 API를 제공하여 두 가지 GDC 리소스 유형을 모두 만들고 관리합니다.

전역 API와 영역별 API는 모두 서로 다른 엔드포인트에서 제공되는 Kubernetes 선언적 API이며 GDC 리소스는 API 서버에서 Kubernetes 커스텀 리소스로 표시됩니다. 전역 API 서버는 영역별 API 서버에 비해 지연 시간이 길고 초당 쓰기 쿼리 (QPS)가 줄어드는 대신 내결함성과 강력한 일관성을 제공하기 위해 영역에 분산된 단일 etcd 클러스터를 공유합니다. 모든 조직에서 영역별 관리 API 서버는 관리자와 개발자가 영역별 리소스를 관리할 수 있는 영역별 API를 제공하고 전역 관리 API 서버는 다중 영역 리소스를 관리할 수 있는 전역 API를 제공합니다.

GDC API 액세스

gdcloud CLI 도구와 GDC 콘솔은 모두 GDC API를 활용합니다. Google은 GDC를 탐색하거나 일회성 작업을 수행하는 데 이러한 도구를 사용하는 것이 좋습니다. 하지만 GDC에 자동 또는 프로그래매틱 액세스를 사용하는 경우 Google은 GDC API를 직접 사용하는 것이 좋습니다.

HTTP 및 gRPC 지원

대부분의 GDC API는 직접 호출하는 JSON HTTP 인터페이스를 제공합니다. Kubernetes 기반 API는 Kubernetes 클라이언트 라이브러리를 사용합니다. Kubernetes가 아닌 일부 GDC API에는 성능과 사용성이 개선된 gRPC 인터페이스가 있습니다. Google은 Kubernetes를 기반으로 하지 않는 GDC API용 클라이언트 라이브러리도 제공합니다. gRPC에 대해 자세히 알아보려면 https://grpc.io/로 이동하세요.

TLS 암호화

모든 GDC API는 전송 계층 보안 (TLS) 암호화를 사용하여 요청을 수락합니다.

  • Kubernetes 또는 GDC 클라이언트 라이브러리 중 하나를 사용하는 경우 라이브러리에서 전송 중인 데이터 암호화를 처리합니다.
  • 자체 HTTP 또는 gRPC 클라이언트를 사용하는 경우 TLS가 필요한 GDC로 인증해야 합니다. gRPC의 경우 https://grpc.io/docs/guides/auth/의 gRPC 인증 가이드에 있는 안내를 따르세요.

Kubernetes API 및 Kubernetes 기반 API에 액세스

kubectl Kubernetes CLI는 Kubernetes API 및 Kubernetes 기반 API와 직접 작업하는 기본 방법입니다.

kubectl을 사용한 액세스

Kubernetes API에 처음 액세스할 때는 Kubernetes 명령줄 도구인 kubectl을 사용하세요.

클러스터에 액세스하려면 클러스터 위치 정보와 액세스 사용자 인증 정보가 필요합니다. 이러한 사용자 인증 정보에 액세스하는 방법을 알아보려면 로그인 섹션을 참고하세요.

현재 kubectl 구성을 검토하고 액세스할 수 있는 클러스터를 확인합니다.

kubectl config view

API 엔드포인트 설명 생성

GDC 에어 갭의 모든 서비스 API에 사용할 수 있는 API 엔드포인트 목록을 보려면 JSON 형식의 OpenAPI 사양에 따라 API 설명을 생성하면 됩니다. Swagger와 같은 도구에서 API 엔드포인트에 대해 생성된 JSON을 볼 수 있습니다.

JSON 형식으로 관리 및 데이터 플레인 API 엔드포인트 설명을 생성하려면 다음 단계를 완료하세요.

  1. 환경과 관리 API 서버 간에 프록시 서버를 만듭니다.

    kubectl proxy --kubeconfig MANAGEMENT_API_SERVER
    

    MANAGEMENT_API_SERVER를 관리 API 서버의 kubeconfig 파일 경로로 바꿉니다. 자세한 내용은 영역별 Management API 서버 리소스를 참고하세요.

  2. JSON 형식으로 API 엔드포인트 설명 목록을 다운로드합니다.

    curl -s http://127.0.0.1:8001/openapi/v2 | jq 'if .paths then .paths = (.paths \
        | with_entries(select(.key | contains(".private") | not))) else . end' > k8s_swagger.json
    
  3. Swagger와 같은 도구에서 생성된 k8s_swagger.json 파일을 열어 API 엔드포인트 설명을 확인합니다.

HTTP 클라이언트를 사용하여 API에 직접 액세스

다음은 curl, wget 또는 브라우저와 같은 HTTP 클라이언트를 사용하여 REST API에 직접 액세스하는 방법입니다.

  • kubectl을 프록시 모드에서 사용하여 인증을 처리합니다.
  • 인증을 직접 처리합니다.
kubectl 프록시 실행

kubectl proxy 명령어는 역방향 프록시 역할을 하는 모드에서 kubectl을 실행합니다. 이 명령어는 apiserver에 연결하고 인증을 관리합니다.

프록시 모드에서 kubectl을 실행하면 저장된 API 서버 위치를 사용하고 인증서를 사용하여 API 서버의 ID를 확인합니다. 이 메서드는 중간자 (MITM) 공격을 방지합니다.

다음 예시는 kubectl proxy 명령어를 사용하는 방법을 보여줍니다.

kubectl proxy --port=8080 &

kubectl 프록시가 실행되면 다음과 같이 curl, wget 또는 브라우저를 사용하여 API를 탐색할 수 있습니다.

$ curl http://localhost:8080/api/
{
  "versions": [
    "v1"
  ],
  "serverAddressByClientCIDRs": [
    {
      "clientCIDR": "0.0.0.0/0",
      "serverAddress": "10.0.1.149:443"
    }
  ]
}
kubectl 프록시 없이 실행

프록시 모드에서 kubectl을 실행하지 않으려면 인증 토큰을 API 서버에 직접 전달하면 됩니다.

  1. kubeconfig 파일에 여러 컨텍스트가 있을 수 있으므로 액세스할 수 있는 모든 Kubernetes 클러스터를 나열합니다.

    kubectl config view \
        -o jsonpath='{"Cluster name\tServer\n"}{range.clusters[*]}{.name}{"\t"}{.cluster.server}{"\n"}{end}'
    
  2. 이전 출력에서 상호작용할 Kubernetes 클러스터의 이름을 내보냅니다.

    export CLUSTER_NAME="CLUSTER_NAME"
    
  3. Kubernetes 클러스터 이름을 참조하는 API 서버를 설정합니다.

    APISERVER=$(kubectl config view -o jsonpath="{.clusters[?(@.name==\"$CLUSTER_NAME\")].cluster.server}")
    
  4. 기본 서비스 계정의 토큰을 보관할 보안 비밀을 만듭니다.

    kubectl apply -n NAMESPACE -f - <<EOF
    apiVersion: v1
    kind: Secret
    metadata:
      name: default-token
      annotations:
        kubernetes.io/service-account.name: default
    type: kubernetes.io/service-account-token
    EOF
    
  5. 토큰 컨트롤러가 토큰으로 보안 비밀을 채울 때까지 기다립니다.

    while ! kubectl describe secret default-token | grep -E '^token' >/dev/null; do
      echo "waiting for token..." >&2
      sleep 1
    done
    
  6. 토큰 값을 설정합니다.

    TOKEN=$(kubectl get secret $(kubectl get secrets | grep default | cut -f1 -d ' ')  \
        -o jsonpath='{.data.token}' | base64 --decode)
    
  7. API에 액세스하려면 다음 예시와 같이 HTTP 헤더 Authorization: Bearer $TOKEN을 추가하여 curl과 같은 도구와 함께 토큰을 사용합니다.

    $ curl -k $APISERVER/api --header "Authorization: Bearer $TOKEN"
    

    출력은 다음과 비슷합니다.

    {
      "kind": "APIVersions",
      "versions": [
        "v1"
      ],
      "serverAddressByClientCIDRs": [
        {
          "clientCIDR": "0.0.0.0/0",
          "serverAddress": "10.0.1.149:443"
        }
      ]
    }