본문 바로가기

Kubenetes/Kubernetes API

Kubernetes API 서버와 통신

Downward AI가 특정 포드 및 컨테이너 메타 데이터를 내부에서 실행되고 있는 프로세스로 간단하게 전달 가능

이는 포드 자체의 메타 데이터와 모든 포드 데이터의 하위 집합만 노출 가능

 

Downward API로는 애플리케이션이 다른 포드와 심지어는 클러스터에 정의된 다른 리소스에 대해서 더 많이 알아야 할 필요가 있을 경우 유용하지 않음

다른 API 객체의 정보를 얻기 위해 포드 내부에서 API 서버와 통신하기

[쿠버네티스 REST API 탐색]

 

kubectl cluster-info를 통해 쿠버네티스 API 서버 URL을 얻을 수 있다.

 

$ kubectl cluster-inf

kubernetes master is running at https://192.168.99.100:8443

 

서버는 HTTPS를 사용하고 인증이 필요하기 때문에 curl을 통한 통신이 되지 않는다.

$ curl https://192.168.99.100:8443 -k

Unauthorized

 

[KUBECTL PROXY를 통한 API 서버 접근]

 

kubectl proxy 명령은 로컬 시스템에서 HTTP 연결을 허용하고 인증을 처리하는 동안 API 서버로 프록시하는 프록시 서버를 실행하므로 요청할 때마다 인증 토큰을 전달할 필요가 없다.

또한 중간에 있는 사람이 아닌 실제 API 서버와 통신하고 있는지 확인(각 요청에서 서버의 인증서를 확인)

 

$ kubectl proxy

Starting to server on 127.0.0.1:8001

 

[kubectl proxy를 통한 쿠버네티스 API 탐험]

 

$ curl http://localhost:8001
{
  "path": [
    "/api",
    "/api/v1",
    "/apis",
    "/apis/apps",
    "/apis/apps/v1beta1",
    . . .
    "apis/batch",
    "apis/batch/v1",
    "/apis/

이 경로는 포드 ,서비스 등과 같은 리소스를 생성할 때 리소스 정의에 지정한 API  그룹 및 버전에 해당

/apis/batch/v1 rㅕㅇ로의 배치 /v1은 API 그룹 및 4장에서 배운 잡 리소스의 버전으로 인식 가능

 

[batch API 그룹의 REST 엔드포인트 탐험]

 

$ curl http://localhost:8001/apis/batch
{
   "kind": "APIPGroup",
   "apiVersion": "v1",
   "name": "batch",
   "versions": [
     {
       "groupVersion": "batch/v1",            # 배치 API 그룹에는 두가지 버전이 있다.
       "version": "v1"
     },
     {
       "groupVersion": "batch/v2alpha1",      # 배치 API 그룹에는 두가지 버전이 있다.
       "version": "v2alpha1"
     }
   ],
   "preferredVersion": {                      # 클라이언트는 v2alph1 대신 v1 버전을 사용해야 함.
     "groupVersion": "batch/v1",
     "version": "V1"
     },
     "serverAddressByClientCIDRs": null
}

 

[/api/batch/v1 경로 뒤에 무엇이 있는지 확인]

batch/v1의 리소스 유형 http://localhost:8001/apis/batch/v1

 

$ curl http://localhost:8001/apis/batch/v1
{
  "kind": "APIResourceList",      # batch/v1 API 그룹의 API 리소스 예제
  "apiVersion": "v1",
  "groupVersion": "batch/v1",
  "resources": [                  # 이 그룹의 모든 리소스 유형을 포함하는 배열이 있다.
  {
    "name": "jobs",               # namespace인 잡 리소스를 설명
    "namespaced": true,
    "kind": "Job",
    "verb": [                     # 다음은 이 리소스와 함께 사용할 수 있는 동사
      "create",                   # (사용자는 작업을 생성하고 개별 프로젝트나
      "delete",                   #  컬렉션을 삭제하고 검색, 감시, 업데이트 할 수 있다.
      "deletecollection",
      "get",
      "list",
      "patch",
      "update",
      "watch"
    ]
  },
  {
    "name": "jobs/status",       # 또한 리소스에는 상태를 수정하기 위한 특별한 REST 엔드포인트가 있다.
    "namespaced": true,          
    "kind": "Job",
    "verbs": [                   # 상태를 검색, 패치 또는 업데이트 할 수 있다.
      "get",
      "patch",
      "update"
      ]
    }
  ]
}

 

API 서버는 batch/v1 API 그룹에서 리소스 유형 및 REST 엔드포인트 목록을 반환한다.

그 중 하나가 잡리소스임

 

[클러스터에 있는 모든 잡 인스턴스 목록]

 

http://localhost:8001/apis/batch/v1/jobs

$ curl http://localhost:8001/apis/batch/v1/jobs
{
  "kind": "JobList",
  "apiVersion": "batch/v1",
  "metadata": {
    "selfLink": "/apis/batch/v1/jobs",
    "resourceVersion": "225162"
  },
  "items": [
    {
      "metadata": {
        "name": "my-job",
        "namespace": "default",
        . . .

 

[이름으로 특정한 잡 인스턴스 가져오기]

 

URL에 이름과 네임스페이스를 지정 

ㅇ 이름: my-job

ㅇ namespace: default

$ curl http://localhost:8001/apis/batch/v1/namespaces/default/jobs/my-job
{
  "kind": "job",
  "apiVersion": "batch/v1"
  "metadata": {
    "name": "my-job",
    "namespace": "default",
    . . .

 

ㅁ 포드 내에서 API 서버와 통신

 

 포드 내에서 API 서버와 통신하려면 다음 세 가지를 처리해야 함

 ㅇ API 서버의 위치를 찾아야 함

 ㅇ API 서버를 가장하지 않고 API 서버에게 이야기해야 함

 ㅇ 서버와 인증 (그렇지 않으면 아무것도 볼수도 실행할 수도 없다.)

 

[API 서버와의 통신을 시도하는 포드: curl.yaml]

apiVersion: v1
kind: Pod
metadata:
   name: curl
spec:
   containers:
   - name: main
     image: tutum/curl             # 컨테이너에서 사용할 수 있는 curl이 필요하므로 tutum/curl 이미지 사용
     command: ["sleep", "9999999"] # 컨테이너를 계속 실행하려면 sleep 명령을 오래 실행해야 함

$ kubectl exec -it curl bash

root@curl: /#

  --> 이제 API 서버와 통신할 준비가 됨

 

[API 서버 주소 찾기]

 

$ kubectl get svc

 

root@curl:/# env | grep KUBERNETES_SERVICE

KUBERNETS_SERVICE_PORT=444

KUBERNETS_SERVICE_HOST=10.0.0.1

KUBERNETS_SERVICE_PORT_HTTPS=443

 

root@curl:/# curl https://kubernetes

을 수행하면 SSL Certificate problem error가 발생함

 

따라서 시크릿을 통해 우선 확인이 필요

root@curl:/# ls /var/run/secrets/kubernetes.io/serviceaccount/

ca.crt namespace token

 

root@curl:/# curl --cacert /var/run/secrets/kubernetes.io/serviceaccount /ca.crt https://kubernetes

Unauthorized

 

root@curl:/# export CURL_CA_BUNDLE=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt

Unauthorized

 

[API 서버로 인증]

 

서버에서 인증해야 하므로 클러스터에 배포된 API 객체를 읽고 또한 업데이트하거나 삭제 가능

인증을 하기 위해 인증 토큰이 필요하다.

 

root@curl:/# TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)

이제 토큰이 TOKEN 환경 변수에 저장되어 API 서버로 요청을 보낼때 사용 가능

root@curl:/# curl -H "Authroization: Bearer $TOKEN" https://kubernetes
{
  "paths": [
    "/api",
    "/api/v1",
    "/apis",
    "/apis/apps",
    "/apis/apps/v1beta1",
    "/apis/authroization.k8s.io",
    . . .
    "/ui/",
    "/version"
  ]
}

 

[실행 중인 포드의 네임스페이스 가져오기]

 

root@curl:/# NS=$(cat /var/run/secrets/kubernetes.io/serrviceaccount/namespace)
root@curl:/# curl-H "AUthorization: Bearer $TOKEN" https://kubernetes/api/v1/namespaces/$NS/pods
{
  "kind": "PodList",
  "apiVersion": "v1",
  . . .

 

[포드가 쿠버네티스와 통신하는 방법]

 

ㅇ API 서버의 인증서가 ca.crt 파일에 있는 certificate 기관에 의해 서명되었는지 여부를 확인

ㅇ 애플리케이션은 토큰 파일에서 무기명 토큰과 함께 권한 부여 헤더를 보내 자신을 인증

ㅇ 네임스페이스 파일은 포드의 네임스페이스 안에 있는 API 객체에 대해 CRUD 작업을 수행할 때 네임스페이스르 API 서버로 전달하는데 사용

 

 정의 CRUD는 Create, Read, Update, Delete이며 해당 HTTP 메소드는 각각 POST, GET, PATCH/PUT 및 DELETE 이다.

defaul-token Secret 파일을 사용해 API 서버와 통신

 

ㅁ 엠배서더 컨테이너와의 API 서버 통신 간소화

 

[앰배서더 컨테이너 패턴]

 

- API 서버에 직접 통신하는 대신 주 컨테이너의 애플리케이션은 HTTPS 대신 HTTP를 통해 앰배서더에 연결

- 보안 역할을 담당하는 앰배서더 프록시가 API 서버에 HTTPS 연결을 처리할 수 있게 한다.

앰배서더를 사용해 API 서버에 연결

 

[추가적인 앰배서더 컨테이너로 curl 포드 실행하기

 

curl-with-ambassador.yaml

apiVersion: v1
kind: Pod
metadata:
   name: curl-with-ambassador
spec:
   containers:
   - name: main
     image: tutum/curl
     command: ["sleep", "99999999"]
   - name: ambassador                  #kubectl-proxy 이미지를 실행하는 앰배서더 컨테이너
     image: luksa/kubectl-proxy:1.6.2

포드에는 이제 두개의 컨테이너가 있으며 main 컨테이너에서 bash를 실행하려는 경우 -c main 옵션을 사용

 

$ kubectl exec -it curl-with-ambassador -c main bash

root@curl-with-ambassador:/#

 

앰배서더 컨테이너의 kubectl 프록시로 암호화, 인증, 서버 검증 부하 줄이기

ㅁ 클라이언트 라이브러리를 사용한 API 서버와 통신

 

 현재 API MAchinery SIG(Special Interest Group)에서 지원하는 두 개의 공식적인 쿠버네티스 API 클라이언트 라이브러리가 있다.

ㅇ 고랭 클라이언트(Golang Client): http://github.com/kubernetes/client-go 

 

kubernetes/client-go

Go client for Kubernetes. Contribute to kubernetes/client-go development by creating an account on GitHub.

github.com

ㅇ 파이썬(Python): https://github.com/kubernetes-incubator/client-python 

 

kubernetes-client/python

Official Python client library for kubernetes. Contribute to kubernetes-client/python development by creating an account on GitHub.

github.com

공식적으로 지원되는 두 개의 라이브러리 외에도 다음과 같은 많은 언어의 사용자 제공 클라이언트 라이브러리 목록이 있다.

ㅇ Fabric8 자바 클라이언트: https://github.com/fabric8io/kubernetes-client 

 

fabric8io/kubernetes-client

Java client for Kubernetes & OpenShift . Contribute to fabric8io/kubernetes-client development by creating an account on GitHub.

github.com

ㅇ Amdatu 자바 클라이언트: https://bitbucket.org/amdatulabs/amdatu-kubernetes 

 

Bitbucket

 

bitbucket.org

ㅇ Tenxcloud Node.js 클라이언트: https://github.com/tenxcloud/node-kubernetes-client 

 

tenxcloud/node-kubernetes-client

kubernetes client of Node.js. Contribute to tenxcloud/node-kubernetes-client development by creating an account on GitHub.

github.com

ㅇ GoDaddy Node.js 클라이언트: https://github.com/godaddy/kubernetes-client 

 

godaddy/kubernetes-client

Simplified Kubernetes API client for Node.js. Contribute to godaddy/kubernetes-client development by creating an account on GitHub.

github.com

[스웨거와 OpenAPI를 사용해 자신만의 라이브러리 구축]

 

프로그래밍 언어를 사용할 수 있는 클라이언트가 없다면 스웨거(Swagger) API 프레임워크를 사용해 클라이언트 라이브러리 및 문서의 생성이 가능

쿠버네티스 API 서버는 /swaggerapi에서 스웨거 API 정의를, /swagger.json에서 OpenAPI 스펙을 제공함.

'Kubenetes > Kubernetes API' 카테고리의 다른 글

Downward API  (0) 2021.02.12