1. 소개

이 사용방법(예제)에서는 공식 클라이언트 라이브러리를 사용하여 Java 애플리케이션에서 Kubernetes API를 사용하는 방법을 보여줍니다.

2. Kubernetes API를 사용하는 이유는 무엇입니까?

요즘에는 쿠버네티스가 컨테이너화 된 애플리케이션을 관리하기 위한 사실상 의 표준이 되었다고 해도 과언이 아닙니다 . 스토리지, 비밀 및 환경 변수와 같은 애플리케이션 및 관련 리소스를 배포, 확장 및 모니터링할 수 있는 풍부한 API를 제공합니다. 실제로 이 API에 대해 생각하는 한 가지 방법은 일반 운영 체제에서 사용할 수 있는 시스템 호출의 분산 아날로그입니다.

대부분의 경우 애플리케이션은 Kubernetes에서 실행되고 있다는 사실을 무시할 수 있습니다. 이를 통해 로컬에서 개발하고 몇 가지 명령과 YAML 주문을 사용하여 사소한 변경만으로 여러 클라우드 Provider에 신속하게 배포할 수 있으므로 좋은 일입니다.

그러나 특정 기능을 달성하기 위해 Kubernetes API와 대화해야 하는 몇 가지 흥미로운 사용 사례가 있습니다.

  • 일부 작업을 수행하기 위해 외부 프로그램을 시작하고 나중에 완료 상태를 검색합니다.
  • 일부 고객 요청에 대한 응답으로 일부 서비스를 동적으로 생성/수정
  • 여러 Kubernetes 클러스터, 심지어 클라우드 Provider 간에 실행되는 솔루션에 대한 사용자 정의 모니터링 대시보드 생성

물론 이러한 사용 사례는 일반적이지 않지만 API 덕분에 달성하기가 매우 간단하다는 것을 알 수 있습니다.

또한 Kubernetes API는 개방형 사양이므로 인증된 구현에서 코드를 수정하지 않고도 코드가 실행될 것이라고 확신할 수 있습니다 .

3. 지역 개발 환경

애플리케이션 생성을 진행하기 전에 가장 먼저 해야 할 일은 작동하는 Kubernetes 클러스터에 액세스하는 것입니다. 이를 위해 퍼블릭 클라우드 Provider를 사용할 수 있지만 일반적으로 로컬 환경은 설정의 모든 측면에 대해 더 많은 제어를 제공합니다.

이 작업에 적합한 몇 가지 경량 배포판이 있습니다.

실제 설정 단계는 이 기사의 범위를 벗어나지만 어떤 옵션을 선택 하든 개발을 시작하기 전에 kubectl 이 제대로 실행되는지 확인하십시오.

4. 메이븐 의존성

먼저 프로젝트의 pom.xml 에 Kubernetes Java API 의존성을 추가해 보겠습니다 .

<dependency>
    <groupId>io.kubernetes</groupId>
    <artifactId>client-java</artifactId>
    <version>11.0.0</version>
</dependency>

최신 버전의 client-java 는 Maven Central에서 다운로드할 수 있습니다.

5. 안녕, 쿠버네티스

이제 사용 가능한 노드와 노드에 대한 정보를 나열하는 매우 간단한 Kubernetes 애플리케이션을 만들어 보겠습니다.

단순함에도 불구하고 이 애플리케이션은 실행 중인 클러스터에 연결하고 API 호출을 수행하기 위해 거쳐야 하는 필수 단계를 보여줍니다. 실제 애플리케이션에서 사용하는 API에 관계없이 해당 단계는 항상 동일합니다.

5.1. API 클라이언트 초기화

ApiClient 클래스 는 Kubernetes API 서버에 대한 호출을 수행하는 모든 논리를 포함하므로 API에서 가장 중요한 클래스 중 하나입니다 . 이 클래스의 인스턴스를 만드는 권장 방법은 Config 클래스에서 사용 가능한 정적 메서드 중 하나를 사용하는 것입니다. 특히 가장 쉬운 방법은 defaultClient() 메서드를 사용하는 것입니다.

ApiClient client = Config.defaultClient();

이 방법을 사용하면 코드가 원격 및 클러스터 내 시나리오 모두에서 작동합니다. 또한 구성 파일을 찾기 위해 kubectl 유틸리티에서 사용하는 것과 동일한 단계를 자동으로 따릅니다.

  • KUBECONFIG 환경 변수 에 의해 정의된 구성 파일
  • $HOME/.kube/config 파일
  • /var/run/secrets/kubernetes.io/serviceaccount 아래의 서비스 계정 토큰
  • http://localhost:8080 에 직접 액세스

세 번째 단계는 적절한 서비스 계정을 사용할 수 있는 한 앱이 모든 포드 의 일부로 클러스터 내에서 실행될 수 있도록 하는 것입니다.

또한 구성 파일에 정의된 여러 컨텍스트가 있는 경우 이 절차는 kubectl config set-context 명령을 사용하여 정의된 대로 "현재" 컨텍스트를 선택합니다.

5.2. API 스텁 생성

ApiClient  인스턴스를 확보 하면 이를 사용하여 사용 가능한 모든 API에 대한 스텁을 생성할 수 있습니다. 이 경우 사용 가능한 노드를 나열하는 데 필요한 메서드가 포함된 CoreV1Api 클래스를 사용합니다.

CoreV1Api api = new CoreV1Api(client);

여기서는 이미 존재하는  ApiClient 를 사용하여 API 스텁을 생성합니다.

인수가 없는 생성자도 사용할 수 있지만 일반적으로 사용을 자제해야 합니다 . 사용 하지 않는 이유 는 내부적으로 Configuration.setDefaultApiClient() 를 통해 이전에 설정해야  하는 전역 ApiClient 를 사용하기 때문입니다 . 이렇게 하면 스텁을 사용하기 전에 이 메서드를 호출하는 사람에 대한 암시적 의존성이 생성되어 런타임 오류 및 유지 관리 문제가 발생할 수 있습니다.

더 나은 접근 방식은 의존성 주입 프레임워크를 사용하여 이 초기 배선을 수행하고 필요할 때마다 결과 스텁을 주입하는 것입니다.

5.3. Kubernetes API 호출

마지막으로 사용 가능한 노드를 반환하는 실제 API 호출을 시작하겠습니다. CoreApiV1 스텁에는 정확히 이 작업을 수행하는 메서드가 있으므로 간단합니다 .

V1NodeList nodeList = api.listNode(null, null, null, null, null, null, null, null, 10, false);
nodeList.getItems()
  .stream()
  .forEach((node) -> System.out.println(node));

이 예에서는 선택 사항이므로 대부분의 메서드 매개 변수에 대해 null 을 전달  합니다. 마지막 두 매개변수는 호출 시간 제한과 이것이  Watch 호출 인지 여부를 지정하므로 모든 listXXX  호출과 관련이 있습니다. 메서드의 서명을 확인하면 나머지 인수가 표시됩니다.

public V1NodeList listNode(
  String pretty,
  Boolean allowWatchBookmarks,
  String _continue,
  String fieldSelector,
  String labelSelector,
  Integer limit,
  String resourceVersion,
  String resourceVersionMatch,
  Integer timeoutSeconds,
  Boolean watch) {
    // ... method implementation
}

이 빠른 소개에서는 페이징, 감시 및 필터 인수를 무시합니다. 이 경우 반환 값은 반환된 문서의 Java 표현이 포함된 POJO입니다 . 이 API 호출의 경우 문서에는 각 노드에 대한 여러 정보가 있는 V1Node  개체 List이 포함되어 있습니다. 다음은 이 코드에 의해 콘솔에서 생성되는 일반적인 출력입니다.

class V1Node {
    metadata: class V1ObjectMeta {
        labels: {
            beta.kubernetes.io/arch=amd64,
            beta.kubernetes.io/instance-type=k3s,
            // ... other labels omitted
        }
        name: rancher-template
        resourceVersion: 29218
        selfLink: null
        uid: ac21e09b-e3be-49c3-9e3a-a9567b5c2836
    }
    // ... many fields omitted
    status: class V1NodeStatus {
        addresses: [class V1NodeAddress {
            address: 192.168.71.134
            type: InternalIP
        }, class V1NodeAddress {
            address: rancher-template
            type: Hostname
        }]
        allocatable: {
            cpu=Quantity{number=1, format=DECIMAL_SI},
            ephemeral-storage=Quantity{number=18945365592, format=DECIMAL_SI},
            hugepages-1Gi=Quantity{number=0, format=DECIMAL_SI},
            hugepages-2Mi=Quantity{number=0, format=DECIMAL_SI},
            memory=Quantity{number=8340054016, format=BINARY_SI}, 
            pods=Quantity{number=110, format=DECIMAL_SI}
        }
        capacity: {
            cpu=Quantity{number=1, format=DECIMAL_SI},
            ephemeral-storage=Quantity{number=19942490112, format=BINARY_SI}, 
            hugepages-1Gi=Quantity{number=0, format=DECIMAL_SI}, 
            hugepages-2Mi=Quantity{number=0, format=DECIMAL_SI}, 
            memory=Quantity{number=8340054016, format=BINARY_SI}, 
            pods=Quantity{number=110, format=DECIMAL_SI}}
        conditions: [
            // ... node conditions omitted
        ]
        nodeInfo: class V1NodeSystemInfo {
            architecture: amd64
            kernelVersion: 4.15.0-135-generic
            kubeProxyVersion: v1.20.2+k3s1
            kubeletVersion: v1.20.2+k3s1
            operatingSystem: linux
            osImage: Ubuntu 18.04.5 LTS
            // ... more fields omitted
        }
    }
}

보시다시피 사용 가능한 정보가 상당히 많습니다. 비교를 위해 다음은 기본 설정이 있는 동등한 kubectl 출력입니다.

root@rancher-template:~# kubectl get nodes
NAME               STATUS   ROLES                  AGE   VERSION
rancher-template   Ready    control-plane,master   24h   v1.20.2+k3s1

6. 결론

이 기사에서는 Java용 Kubernetes API에 대한 간략한 소개를 제공했습니다. 향후 기사에서는 이 API를 자세히 살펴보고 다음과 같은 몇 가지 추가 기능을 살펴보겠습니다.

  • 사용 가능한 API 호출 변형 간의 차이점 설명
  • Watch 를 사용하여  클러스터 이벤트를 실시간으로 모니터링
  • 페이징을 사용하여 클러스터에서 대량의 데이터를 효율적으로 검색하는 방법

늘 그렇듯이 예제의 전체 소스 코드는 GitHub 에서 찾을 수 있습니다 .

Generic footer banner