Kubernetes - kube-apiserver와 REST API 통신하는 방법 (Docker Desktop for Windows 환경)
k8s의 apiserver 주소는 다양하게 구할 수 있습니다.
c:\temp> kubectl config view
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: DATA+OMITTED
server: https://kubernetes.docker.internal:6443
name: docker-desktop
contexts:
- context:
cluster: docker-desktop
user: docker-desktop
name: docker-desktop
current-context: docker-desktop
kind: Config
preferences: {}
users:
- name: docker-desktop
user:
client-certificate-data: REDACTED
client-key-data: REDACTED
c:\temp> kubectl cluster-info
Kubernetes master is running at https://kubernetes.docker.internal:6443
Heapster is running at https://kubernetes.docker.internal:6443/api/v1/namespaces/kube-system/services/heapster/proxy
KubeDNS is running at https://kubernetes.docker.internal:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
monitoring-grafana is running at https://kubernetes.docker.internal:6443/api/v1/namespaces/kube-system/services/monitoring-grafana/proxy
monitoring-influxdb is running at https://kubernetes.docker.internal:6443/api/v1/namespaces/kube-system/services/monitoring-influxdb/proxy
참고로, Docker Desktop for Windows의 경우 C:\Windows\system32\drivers\etc\HOSTS 파일에 kubernetes.docker.internal 이름을 다음과 같이 등록해 두고 있습니다.
127.0.0.1 kubernetes.docker.internal
그리고, 별다른 인증 정보를 제공하지 않는다면 기본적으로는 API 사용이 불가능합니다.
// curl https://localhost:6443/api/ --insecure
c:\temp> curl https://kubernetes.docker.internal:6443/api/ --insecure
{
"kind": "Status",
"apiVersion": "v1",
"metadata": {
},
"status": "Failure",
"message": "forbidden: User \"system:anonymous\" cannot get path \"/api/\"",
"reason": "Forbidden",
"details": {
},
"code": 403
}
재미있는 것은, 해당 인증 정보를 알고 있는 응용 프로그램이 있는데 그것이 바로 kubectl입니다. 즉, kubectl은 내부적으로 (연결 정보를 담고 있는 %USERPROFILE%\.kube\config 파일을 이용해) kube-apiserver와 자유롭게 통신할 수 있습니다. 물론, 외부에서도 kubectl이 하듯이 인증 정보를 제공하면 kube-apiserver와 통신을 할 수 있습니다.
단지, k8s는 그렇게 하지 않고도 외부 프로그램이 kubectl을 경유해 kube-apiserver와 통신하는 방법을 제공하는데,
Kubernetes Documentation / Tasks / Access Applications in a Cluster / Accessing Clusters
- Directly accessing the REST API
; https://kubernetes.io/docs/tasks/access-application-cluster/access-cluster/#directly-accessing-the-rest-api
이를 위해 kubectl을 proxy 모드로 실행할 수 있습니다.
c:\temp> kubectl proxy
Starting to serve on 127.0.0.1:8001
위와 같이 proxy가 실행 중이면, 이제 우리는 그 프락시 서버로 요청을 날릴 수 있고, kubectl은 그 요청을 받아 적절한 인증 정보와 함께 kube-apiserver에 전달해 그 결과를 반환해 줍니다.
c:\temp> curl http://127.0.0.1:8001/api/
{
"kind": "APIVersions",
"versions": [
"v1"
],
"serverAddressByClientCIDRs": [
{
"clientCIDR": "0.0.0.0/0",
"serverAddress": "192.168.65.3:6443"
}
]
}
물론, kubectl을 경유하지 않고 인증 정보를 직접 제공하는 것도 가능합니다. 그러려면 service account token 값을 알아야 하는데요, 다음과 같은 절차를 거쳐 값을 구하는 것이 가능합니다.
c:\temp> kubectl get secrets
NAME TYPE DATA AGE
default-token-qnwbl kubernetes.io/service-account-token 3 50d
c:\temp> kubectl describe secret default-token-qnwbl
Name: default-token-qnwbl
Namespace: default
Labels: <none>
Annotations: kubernetes.io/service-account.name: default
kubernetes.io/service-account.uid: 6a8f5d0c-db54-4018-b060-f311583546c0
Type: kubernetes.io/service-account-token
Data
====
namespace: 7 bytes
token: eyJhbGciOiJSUzI...[생략]...lzn1lGmAh1w
ca.crt: 1025 bytes
이후 token을 REST API 요청의 Authorization 헤더로 함께 보내면 끝!
c:\temp> curl https://localhost:6443/api/ --insecure --header "Authorization: Bearer eyJhbGciOiJSUzI...[생략]...lzn1lGmAh1w"
{
"kind": "APIVersions",
"versions": [
"v1"
],
"serverAddressByClientCIDRs": [
{
"clientCIDR": "0.0.0.0/0",
"serverAddress": "192.168.65.3:6443"
}
]
}
[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]