kubectl에서 할 일을 curl로하고 싶습니다.

개요



kubernetes를 운용할 때 애드온적인 느낌으로 동적으로 Pod(Kubernetes Resource)를 생성한다는 유스 케이스를 알았다. 그 때문에 예를 들면 Pod내로부터 새롭게 Pod를 생성하는 등이라고 하는 경우가 생각되어, 그 때에 kubectl를 Pod내로부터 사용하는 케이스나 curl등의 범용적인 툴을 간이적으로 사용할 수 있는지를 확인하고 싶어졌다.

아래에서는 kubectl proxy를 사용하여 kubernetes 클러스터 외부에서 Kubernetes API를 curl을 통해 실행하여 동일한 것을 확인했습니다. 포드 내에서 동일한 작업을 수행 할 때 Kubernetes API를 실행하기위한 토큰 획득 방법이 다르므로주의가 필요합니다.

Kubernetes API란?



Kubernetes 내의 컴포넌트 간의 통신과 수사는 모두 API를 통해 이루어지며 REST 형식의 API가 되고 있습니다.

kubectl을 사용하면 대부분의 작업을 수행 할 수 있으며 직접 REST API를 curl로 두드리는 것도 비슷한 작업을 수행 할 수 있습니다.

직접 Kubernetes API 두드려보세요



kubectl 프록시 없는 경우



그렇지 않으면 클러스터 시작
kind create cluster

클러스터 목록 확인
kubectl config view -o jsonpath='{"Cluster name\tServer\n"}{range .clusters[*]}{.name}{"\t"}{.cluster.server}{"\n"}{end}'

액세스 할 클러스터 이름 선택 (내 경우에는 kind를 사용하고 있으므로이 클러스터 이름 선택)
export CLUSTER_NAME="kind-kind"

클러스터 이름에서 액세스 대상 검색
APISERVER=$(kubectl config view -o jsonpath="{.clusters[?(@.name==\"$CLUSTER_NAME\")].cluster.server}")

액세스 토큰 획득
TOKEN=$(kubectl get secrets -o jsonpath="{.items[?(@.metadata.annotations['kubernetes\.io/service-account\.name']=='default')].data.token}"|base64 --decode)

kubernetes API 실행
curl -X GET $APISERVER/api --header "Authorization: Bearer $TOKEN" --insecure
{
  "kind": "APIVersions",
  "versions": [
    "v1"
  ],
  "serverAddressByClientCIDRs": [
    {
      "clientCIDR": "0.0.0.0/0",
      "serverAddress": "172.17.0.2:6443"
    }
  ]
}

kubectl 프록시가있는 경우



kubectl 프록시 시작

8001번 포트에서 작동하는지 확인
kubectl proxy
Starting to serve on 127.0.0.1:8001

Kubernetes API를 두드리면 이전과 비슷한 결과를 얻을 수 있습니다.
curl -X GET 127.0.0.1:8001/api 
{
  "kind": "APIVersions",
  "versions": [
    "v1"
  ],
  "serverAddressByClientCIDRs": [
    {
      "clientCIDR": "0.0.0.0/0",
      "serverAddress": "172.17.0.2:6443"
    }
  ]
}

시험에 nginx의 Pod를 작동시킨 다음 Kubernetes API에서 Pod를 확인해보십시오.
k run nginx --image=nginx --restart=Never --dry-run -oyaml > nginx.yaml

k apply -f nginx.yaml 

k get po
NAME    READY   STATUS              RESTARTS   AGE
nginx   0/1     ContainerCreating   0          1s


curl에서 Pod 목록을 검색하면 json 형식으로 유사한 정보를 얻을 수 있습니다.
curl -X GET http://127.0.0.1:8001/api/v1/namespaces/default/pods
{
  "kind": "PodList",
  "apiVersion": "v1",
  "metadata": {
    "selfLink": "/api/v1/namespaces/default/pods",
    "resourceVersion": "5973"
  },
  "items": [
    {
      "metadata": {
        "name": "nginx",
        "namespace": "default",
        "selfLink": "/api/v1/namespaces/default/pods/nginx",
        "uid": "119f6219-5ff3-4542-b785-e7532301a972",
        "resourceVersion": "5891",
        "creationTimestamp": "2020-03-21T06:08:56Z",
        "labels": {
          "run": "nginx"
        },
        "annotations": {
          "kubectl.kubernetes.io/last-applied-configuration": "{\"apiVersion\":\"v1\",\"kind\":\"Pod\",\"metadata\":{\"annotations\":{},\"creationTimestamp\":null,\"labels\":{\"run\":\"nginx\"},\"name\":\"nginx\",\"namespace\":\"default\"},\"spec\":{\"containers\":[{\"image\":\"nginx\",\"name\":\"nginx\",\"resources\":{}}],\"dnsPolicy\":\"ClusterFirst\",\"restartPolicy\":\"Never\"},\"status\":{}}\n"
        }
      },
      "spec": {
        "volumes": [
          {
            "name": "default-token-lh646",
            "secret": {
              "secretName": "default-token-lh646",
              "defaultMode": 420
            }
          }
        ],
        "containers": [
          {
            "name": "nginx",
            "image": "nginx",
            "resources": {

            },
~中略~
      }
    }
  ]
}


json이라고 kubectl의 결과보다 보기 어려운 것은 어쩔 수 없지만, 아래와 같은 툴로 json 결과도 어느 정도 취급하기 쉽게 할 수 있다.

Mac의 경우 아래의 명령으로 도입할 수 있다.
brew install jid

curl -X GET http://127.0.0.1:8001/api/v1/namespaces/default/pods | jid


아래와 같이 대화적으로 json 파일을 깊은 파고 할 수 있다.



curl로 포드를 만들어보십시오.



엔드포인트는 Kubernetes API에서 확인할 수 있습니다.



Hwllo World로만 출력하는 포드 만들기
curl -X POST -H 'Content-Type: application/yaml'  -d '
apiVersion: v1
kind: Pod
metadata:
  name: pod-example
spec:
  containers:
  - name: ubuntu
    image: ubuntu:trusty
    command: ["echo"]
    args: ["Hello World"]
  restartPolicy: Never
'  http://127.0.0.1:8001/api/v1/namespaces/default/pods 


실행 결과
{
  "kind": "Pod",
  "apiVersion": "v1",
  "metadata": {
    "name": "pod-example",
    "namespace": "default",
    "selfLink": "/api/v1/namespaces/default/pods/pod-example",
    "uid": "4ac7cf5c-69b7-40f9-806d-582cafebd590",
    "resourceVersion": "8977",
    "creationTimestamp": "2020-03-21T06:50:46Z"
  },
  "spec": {
    "volumes": [
      {
        "name": "default-token-lh646",
        "secret": {
          "secretName": "default-token-lh646",
          "defaultMode": 420
        }
      }
    ],
    "containers": [
      {
        "name": "ubuntu",
        "image": "ubuntu:trusty",
        "command": [
          "echo"
        ],
        "args": [
          "Hello World"
        ],
        "resources": {

        },
~中略~
}


포드가 만들어졌는지 확인


방금 만든 nginx 포드 외에도,

로그에 Hello World가 출력되고 있는 것도 확인할 수 있다
k logs pod-example 
Hello World


포드 내에서 Kubernetes API를 두드리는 방법



필요한 권한을 가진 SeriveAccount 작성 (이어서 namespace 등도 작성)
k apply -f api.yaml 


네임스페이스 전환

kubens는 별도 install 필요( htps : // 기주 b. 코 m / 아 h tb / 쿠베 ctx )
kubens mynamespace

Curl을 두드리는 포드 yaml 생성
k run fedora --image=fedora --restart=Never --dry-run -oyaml -- /sbin/init  > fedora.yaml

출력한 yaml에 일부 추가(tty, stdin, serviceAccountName)
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: fedora
  name: fedora
spec:
  containers:
  - args:
    - /sbin/init
    image: fedora
    name: fedora
    resources: {}
  dnsPolicy: ClusterFirst
  restartPolicy: Never
  tty: true
  stdin: true
  serviceAccountName: mysa
status: {}

포드 배포
k apply -f fedora.yaml

포드에 액세스
k exec -it fedora bash

토큰을 얻고 Kubernetes API 실행

아래는이 명령을 실행하는 Pod 정보를 얻습니다.
KUBE_TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)
NAMESPACE=mynamespace
curl -sSk -H "Authorization: Bearer $KUBE_TOKEN" \
https://$KUBERNETES_SERVICE_HOST:$KUBERNETES_PORT_443_TCP_PORT/api/v1/namespaces/$NAMESPACE/pods/$HOSTNAME

json으로 취득하기 때문에 확실히 알기 힘들지만, k get po 와 같은 내용을 취득할 수 있다.
{
  "kind": "Pod",
  "apiVersion": "v1",
  "metadata": {
    "name": "fedora",
    "namespace": "mynamespace",
    "selfLink": "/api/v1/namespaces/mynamespace/pods/fedora",
    "uid": "7c918fc0-f194-4729-896a-f52167c4a803",
    "resourceVersion": "17841",
    "creationTimestamp": "2020-03-21T08:51:57Z",
    "labels": {
      "run": "fedora"
    },
    "annotations": {
      "kubectl.kubernetes.io/last-applied-configuration": "{\"apiVersion\":\"v1\",\"kind\":\"Pod\",\"metadata\":{\"annotations\":{},\"creationTimestamp\":null,\"labels\":{\"run\":\"fedora\"},\"name\":\"fedora\",\"namespace\":\"mynamespace\"},\"spec\":{\"containers\":[{\"args\":[\"/sbin/init\"],\"image\":\"fedora\",\"name\":\"fedora\",\"resources\":{},\"stdin\":true,\"tty\":true}],\"dnsPolicy\":\"ClusterFirst\",\"restartPolicy\":\"Never\",\"serviceAccountName\":\"mysa\"},\"status\":{}}\n"
    }
  },
  "spec": {
    "volumes": [
      {
        "name": "mysa-token-lt4gh",
        "secret": {
          "secretName": "mysa-token-lt4gh",
          "defaultMode": 420
        }
      }
    ],
    "containers": [
      {
        "name": "fedora",
        "image": "fedora",
        "args": [
          "/sbin/init"
        ],
        "resources": {

        },
~中略~
}

요약



Kubernetes API를 아는 것으로 kubectl에서 하고 있는 것을 curl에서도 마찬가지로 할 수 있는 것을 확인했다.
새롭게 Pod등을 만드는 처리는 Pod내에서도 걸리기 때문에, 동적으로 증가하는 자원을 제어·감시하는 방법을 검토하고 싶다.

좋은 웹페이지 즐겨찾기