Cloudnet AWES 6주차 스터디를 진행하며 정리한 글입니다.
하..... 여담이지만 2시간 넘게 걸려 작성한 포스팅이 날라가서 다시 작성하니 속상합니다..... 처음 쓴 글보다 느낌상 짧은 포스팅이 될 것 같은 느낌이 드네요......
쿠버네티스는 RESTful API 서버를 사용하여 클러스터 리소스 관리, 인증 인가 및 클러스터 상태 저장을 합니다.
이번 포스팅에서는 쿠버네티스 API 서버가 무엇인지, API 요청이 어떻게 처리되는지, 그리고 kubectl을 이용해 직접 API 요청을 실습하는 내용을 소개하겠습니다.
Kubernetes API의 구조

1. 리소스와 동사
쿠버네티스 API는 리소스와 동사를 기반으로 동작합니다.
- 리소스 : 쿠버네티스에서 관리하는 객체 - Pod, Deployment, Service 등
- 동사: API 요청의 유형 - get, list, create, update, delete 등
2. API 그룹 및 버전
쿠버네티스 API는 시간이 지남에 따라 독립적인 버전이 개발되기 때문에 API 그룹은 여러 단계가 존재합니다.
Core Group
- 기본 API 그룹이며 api/v1에서 사용
- 파드나, 컨피그맵 등 기본 쿠버네티스 컴포넌트에서 사용
- ex) /api/v1/pods, /api/v1/nodes
Named Group
- 확장 API 그룹이며 /apis/ 하위에 위치
- 사용자 정의 리소스를 포함한 모든 리소스에서 사용
- ex) /apis/apps/v1/deployments, /apis/batch/v1/jobs
API 그룹 상태
- alpha실험적이며 잠재적으로 불안정함.
- beta더 많은 테스트를 거쳤지만 아직 변경될 수 있음.
- stable또는 GA(일반 제공) - 안정적이며 프로덕션에 바로 사용할 수 있습니다.
3. Kind
kind는 API에서 다루는 특정 리소스 유형의 구조와 동작을 나타냅니다.
사용자가 쿠버네티스 오브젝트를 만들 때 리소스의 유형을 구분하는 키워드로, API 서버에서 리소스를 저장하고 처리하는 방식 결정합니다.
Kubernetes API 호출하기
kubectl을 사용한 API 리소스 조회
아래 명령어를 실행하면 API 서버에서 지원하는 모든 리소스 목록을 확인할 수 있습니다.
❯ kubectl api-resources
NAME SHORTNAMES APIVERSION NAMESPACED KIND
bindings v1 true Binding
componentstatuses cs v1 false ComponentStatus
configmaps cm v1 true ConfigMap
endpoints ep v1 true Endpoints
events ev v1 true Event
limitranges limits v1 true LimitRange
namespaces ns v1 false Namespace
nodes no v1 false Node
persistentvolumeclaims pvc v1 true PersistentVolumeClaim
persistentvolumes pv v1 false PersistentVolume
pods po v1 true Pod
podtemplates v1 true PodTemplate
replicationcontrollers rc v1 true ReplicationController
resourcequotas quota v1 true ResourceQuota
secrets v1 true Secret
serviceaccounts sa v1 true ServiceAccount
services svc v1 true Service
mutatingwebhookconfigurations admissionregistration.k8s.io/v1 false MutatingWebhookConfiguration
validatingadmissionpolicies admissionregistration.k8s.io/v1 false ValidatingAdmissionPolicy
validatingadmissionpolicybindings admissionregistration.k8s.io/v1 false ValidatingAdmissionPolicyBinding
validatingwebhookconfigurations admissionregistration.k8s.io/v1 false ValidatingWebhookConfiguration
customresourcedefinitions crd,crds apiextensions.k8s.io/v1 false CustomResourceDefinition
apiservices apiregistration.k8s.io/v1 false APIService
controllerrevisions apps/v1 true ControllerRevision
daemonsets ds apps/v1 true DaemonSet
deployments deploy apps/v1 true Deployment
replicasets rs apps/v1 true ReplicaSet
statefulsets sts apps/v1 true StatefulSet
selfsubjectreviews authentication.k8s.io/v1 false SelfSubjectReview
tokenreviews authentication.k8s.io/v1 false TokenReview
localsubjectaccessreviews authorization.k8s.io/v1 true LocalSubjectAccessReview
selfsubjectaccessreviews authorization.k8s.io/v1 false SelfSubjectAccessReview
selfsubjectrulesreviews authorization.k8s.io/v1 false SelfSubjectRulesReview
subjectaccessreviews authorization.k8s.io/v1 false SubjectAccessReview
horizontalpodautoscalers hpa autoscaling/v2 true HorizontalPodAutoscaler
cronjobs cj batch/v1 true CronJob
jobs batch/v1 true Job
certificatesigningrequests csr certificates.k8s.io/v1 false CertificateSigningRequest
leases coordination.k8s.io/v1 true Lease
eniconfigs crd.k8s.amazonaws.com/v1alpha1 false ENIConfig
endpointslices discovery.k8s.io/v1 true EndpointSlice
events ev events.k8s.io/v1 true Event
flowschemas flowcontrol.apiserver.k8s.io/v1 false FlowSchema
prioritylevelconfigurations flowcontrol.apiserver.k8s.io/v1 false PriorityLevelConfiguration
nodes metrics.k8s.io/v1beta1 false NodeMetrics
pods metrics.k8s.io/v1beta1 true PodMetrics
policyendpoints networking.k8s.aws/v1alpha1 true PolicyEndpoint
ingressclasses networking.k8s.io/v1 false IngressClass
ingresses ing networking.k8s.io/v1 true Ingress
networkpolicies netpol networking.k8s.io/v1 true NetworkPolicy
runtimeclasses node.k8s.io/v1 false RuntimeClass
poddisruptionbudgets pdb policy/v1 true PodDisruptionBudget
clusterrolebindings rbac.authorization.k8s.io/v1 false ClusterRoleBinding
clusterroles rbac.authorization.k8s.io/v1 false ClusterRole
rolebindings rbac.authorization.k8s.io/v1 true RoleBinding
roles rbac.authorization.k8s.io/v1 true Role
priorityclasses pc scheduling.k8s.io/v1 false PriorityClass
csidrivers storage.k8s.io/v1 false CSIDriver
csinodes storage.k8s.io/v1 false CSINode
csistoragecapacities storage.k8s.io/v1 true CSIStorageCapacity
storageclasses sc storage.k8s.io/v1 false StorageClass
volumeattachments storage.k8s.io/v1 false VolumeAttachment
volumeattributesclasses vac storage.k8s.io/v1beta1 false VolumeAttributesClass
cninodes cnd vpcresources.k8s.aws/v1alpha1 false CNINode
securitygrouppolicies sgp vpcresources.k8s.aws/v1beta1 true SecurityGroupPolicy
1) kubectl 명령어를 통한 조회 (단, 디버그 모드를 켜서 상세 호출 흐름 확인)
kubectl을 통해 조회하면 다음과 같은 흐름으로 API 서버에 호출이 보내집니다.
- kubectl 설정 로드 (~/.kube/config에서 API 서버 정보 로드)
- API 서버에 HTTP GET 요청 전송 (/api/v1/namespaces/default/pods?limit=500)
- API 요청 헤더 정보 확인 (Accept: application/json;as=Table → Table 형태 요청)
- API 응답 데이터 변환 (kubectl이 사람이 읽기 쉬운 Table 형식으로 가공하여 출력)
❯ kubectl get pod -v8
I0312 03:59:28.241564 66913 loader.go:402] Config loaded from file: /Users/yoo/.kube/config
I0312 03:59:28.244057 66913 envvar.go:172] "Feature gate default state" feature="WatchListClient" enabled=false
I0312 03:59:28.244069 66913 envvar.go:172] "Feature gate default state" feature="ClientsAllowCBOR" enabled=false
I0312 03:59:28.244074 66913 envvar.go:172] "Feature gate default state" feature="ClientsPreferCBOR" enabled=false
I0312 03:59:28.244077 66913 envvar.go:172] "Feature gate default state" feature="InformerResourceVersion" enabled=false
I0312 03:59:28.250394 66913 helper.go:113] "Request Body" body=""
I0312 03:59:28.251230 66913 round_trippers.go:470] GET https://8FA477A1B30E5E6D6E7473BD5FA8EA94.sk1.ap-northeast-2.eks.amazonaws.com/api/v1/namespaces/default/pods?limit=500
I0312 03:59:28.251237 66913 round_trippers.go:476] Request Headers:
I0312 03:59:28.251244 66913 round_trippers.go:480] Accept: application/json;as=Table;v=v1;g=meta.k8s.io,application/json;as=Table;v=v1beta1;g=meta.k8s.io,application/json
I0312 03:59:28.251248 66913 round_trippers.go:480] User-Agent: kubectl/v1.32.1 (darwin/arm64) kubernetes/e9c9be4
I0312 03:59:29.336667 66913 round_trippers.go:581] Response Status: 200 OK in 1085 milliseconds
I0312 03:59:29.336712 66913 round_trippers.go:584] Response Headers:
I0312 03:59:29.336718 66913 round_trippers.go:587] Audit-Id: abc59597-eaa7-44b7-9211-3c59d4afcddc
I0312 03:59:29.336730 66913 round_trippers.go:587] Cache-Control: no-cache, private
I0312 03:59:29.336733 66913 round_trippers.go:587] Content-Type: application/json
I0312 03:59:29.336735 66913 round_trippers.go:587] X-Kubernetes-Pf-Flowschema-Uid: f2eae594-9812-48f0-8003-3796638545c3
I0312 03:59:29.336737 66913 round_trippers.go:587] X-Kubernetes-Pf-Prioritylevel-Uid: 3a378eab-9e17-41df-ad0d-4fc68ef3bada
I0312 03:59:29.336745 66913 round_trippers.go:587] Date: Tue, 11 Mar 2025 18:59:29 GMT
I0312 03:59:29.336885 66913 helper.go:113] "Response Body" body="{\"kind\":\"Table\",\"apiVersion\":\"meta.k8s.io/v1\",\"metadata\":{\"resourceVersion\":\"421105\"},\"columnDefinitions\":[{\"name\":\"Name\",\"type\":\"string\",\"format\":\"name\",\"description\":\"Name must be unique within a namespace. Is required when creating resources, although some resources may allow a client to request the generation of an appropriate name automatically. Name is primarily intended for creation idempotence and configuration definition. Cannot be updated. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#names\",\"priority\":0},{\"name\":\"Ready\",\"type\":\"string\",\"format\":\"\",\"description\":\"The aggregate readiness state of this pod for accepting traffic.\",\"priority\":0},{\"name\":\"Status\",\"type\":\"string\",\"format\":\"\",\"description\":\"The aggregate status of the containers in this pod.\",\"priority\":0},{\"name\":\"Restarts\",\"type\":\"string\",\"format\":\"\",\"description\":\"The number of times the containers in this pod have been restarted and when the last container in this pod has restarted.\",\"priority\":0},{ [truncated 3936 chars]"
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 0 3h44m
2) kubectl 명령어로 raw 데이터 호출을 통한 조회
kubectl을 통해 raw 옵션을 통해 호출하면 API 서버의 RESTful 엔드포인트를 직접 호출하여 JSON 형식의 원본 API 응답을 출력합니다.
❯ kubectl get --raw /api/v1/namespaces/default/pods | jq
{
"kind": "PodList",
"apiVersion": "v1",
"metadata": {
"resourceVersion": "420807"
},
"items": [
{
"metadata": {
"name": "nginx",
"namespace": "default",
"uid": "662787b8-6863-4615-9457-a8fa98be8ee3",
"resourceVersion": "365442",
"creationTimestamp": "2025-03-11T15:15:02Z",
"labels": {
"run": "nginx"
},
"managedFields": [
{
"manager": "kubectl-run",
"operation": "Update",
"apiVersion": "v1",
"time": "2025-03-11T15:15:02Z",
"fieldsType": "FieldsV1",
"fieldsV1": {
"f:metadata": {
"f:labels": {
".": {},
"f:run": {}
}
},
"f:spec": {
"f:containers": {
"k:{\"name\":\"nginx\"}": {
".": {},
"f:image": {},
"f:imagePullPolicy": {},
"f:name": {},
"f:resources": {},
"f:terminationMessagePath": {},
"f:terminationMessagePolicy": {}
}
},
"f:dnsPolicy": {},
"f:enableServiceLinks": {},
"f:restartPolicy": {},
"f:schedulerName": {},
"f:securityContext": {},
"f:terminationGracePeriodSeconds": {}
}
}
},
...
3) curl 등 간단한 REST 호출을 통한 조회
해당 호출은 kubectl 명령줄 도구 없이 REST 호출을 통해 쿠버네티스 API 서버에 요청을 전송하였습니다.
하지만, 기존 1,2 번 방법과는 달리 왜 파드가 조회되지 않고 403 응답이 나왔을까요?
그것은 바로 API 서버가 사용자를 'system:anonymous'로 인증했지만, 해당 사용자에게는 Pods 조회 권한이 없어서 403 응답이 리턴한 것입니다. 하지만, 해당 호출은 API 서버에 인증은 성공했으나, 인가가 실패한 경우인데요.
API 서버는 기본적으로 클라이언트가 제공하는 인증 정보가 없을 경우 system:anonymous라는 기본 사용자로 인증을 처리합니다.
curl 요청을 보낼 때 별도 인증 정보를제공하지 않았기 때문에, API 서버는 자동으로 system:anonymous라는 익명 사용자로 요청을 처리했지만 이 사용자는 파드 조회 등 어떠한 권한도 없기 때문에 403 오류가 발생했습니다.
++ 참고)
- 401 Unauthorized → API 서버가 클라이언트의 신원을 확인할 수 없는 경우 (잘못된 토큰, 유효하지 않은 인증서 등)
- 403 Forbidden → 인증은 되었지만, 해당 사용자가 요청한 리소스에 대한 권한이 없는 경우
❯ curl -X GET $APISERVER/api/v1/namespaces/default/pods
--insecure
{
"kind": "Status",
"apiVersion": "v1",
"metadata": {},
"status": "Failure",
"message": "pods is forbidden: User \"system:anonymous\" cannot list resource \"pods\" in API group \"\" in the namespace \"default\"",
"reason": "Forbidden",
"details": {
"kind": "pods"
},
"code": 403
}
다음 포스팅에서는 이러한 쿠버네티스 API에 접근하기 위한 Kubeconfig 및 CSR을 통한 신규 인증서 발급 (사실 다음 포스팅이었지만, 포스팅 삭제 이슈로,, ㅠㅠ 이전 포스팅입니다.) Kubernetes API의 인증 인가 등 액세스 제어에 대해 자세히 다뤄보겠습니다.
'스터디 > AEWS' 카테고리의 다른 글
| [AEWS] 6주차 EKS 환경에서 인증/인가 (0) | 2025.03.12 |
|---|---|
| [AEWS] 6주차 쿠버네티스 인증(Authentication) 인가(Authorization) 어드미션 컨트롤 (Admission Contro (1) | 2025.03.12 |
| [AEWS] 6주차 Kubeconfig 이해하기 및 CSR을 통한 신규 인증서 발급 (0) | 2025.03.11 |
| [AEWS] 5주차 쿠버네티스 오토스케일링 이해하기 - Karpenter (0) | 2025.03.09 |
| [AEWS] 5주차 쿠버네티스 오토스케일링 이해하기 - 클러스터 오토스케일러 (CAS, CPA) (0) | 2025.03.09 |