본문 바로가기
  • 오늘처럼
소프트웨어 아키텍처/Kubernetes

Kubectl 명령어의 Proxy, Port-Forward 기능

by bluefriday 2022. 7. 15.
반응형

Kubernetes Cluster 에서 수행되는 모든 작업은 kube-api server 에 의해서 이루어진다. 그렇기에 사용자는 kube-api server와 통신하기 위해 다음의 2가지 방식을 사용한다.

  • kubectl client tool 을 사용하여 kube-api server 와 상호작용(interaction)
  • curl 명령을 사용하여 kube-api server 에 REST API 통신

여기서 1번째 방식인 kubectl 클라이언트 툴을 사용할 경우, 별도의 authentication 이나 authorization 에 해당하는 설정을 할 필요가 없다. 이미 사용자 홈 디렉토리(root 유저일 경우 /root/.kube)에 config 설정 파일이 있고, kubectl 명령이 수행 될 때 자동으로 이 파일을 참조하기 때문이다. 이러한 방식의 장점은 1)kubectl 바이너리 파일과, 2)사용자의 정보와 Credential 값이 포함되어 있는 config 파일만 준비되어 있으면 어디에서나 kube-api server 와 통신할 수 있다는 점이다. 굳이 같은 cluster 의 master 노드 등이 아니어도, 가령 개인 사용자의 랩탑 같은 private 한 VM환경이나, public network 에서도 통신이 가능하다.

2번째 방식인 curl 을 사용하는 경우에는, curl 자체에서 어떤 인증이나 권한 처리가 되어 있지 않으므로, client 의 인증 파일들이 curl 명령의 파라미터로 필요하다. 권한 처리를 하지 않고 단순하게 curl 명령을 api server 에 전송할 경우 다음과 같은 403 에러가 발생한다.

# 인증 처리를 하지 않은 curl 요청
curl -sk https://kube-api-server:6443/api/v1/pods
<결과>
{
  "kind": "Status",
  "apiVersion": "v1",
  "metadata": {

  },
  "status": "Failure",
  "message": "pods is forbidden: User \"system:anonymous\" cannot list resource \"pods\" in API group \"\" at the cluster scope",
  "reason": "Forbidden",
  "details": {
    "kind": "pods"
  },
  "code": 403
}



# 인증처리를 수행한 curl 요청
curl -sk https://kube-api-server:6443/api/v1/pods
  --key admin.key
  --cert admin.crt
  --cacert ca.crt
<결과>
pod 정보 조회

kubectl proxy

위와 같이 curl 통신으로 kube apiserver 와 통신하기 위해, 인증서 파일들을 실행 파라미터로 전달하는 이외에 다른 방법도 있다. kubectl 명령어에서 제공하는 proxy 모드를 사용하는 것이다.

Creates a proxy server or application-level gateway between localhost and the Kubernetes API server.
It also allows serving static content over specified HTTP path. 
All incoming data enters through one port and gets forwarded to the remote Kubernetes API server port, 
except for the path matching the static content path.

kubectl proxy 명령어의 도움말 모드 (kubectl proxy -h) 를 보면 위와 같은 내용들을 확인할 수 있다. proxy 모드를 사용하면 kubectl 이 하나의 프록시 서버로 구동이 되어 kubeconfig 파일을 가지고 kube-api server 와 통신하여 인증을 대신 수행해 준다. 사용자는 별도의 인증 없이 이 proxy 서버에 curl 요청을 수행할수 있다.

# 프록시 서버의 커스텀 포트(8001)로 curl 명령 전달
curl -sk http://localhost:8001/api/v1/pods

이러한 kubectl 의 프록시 서버 기능은, 127.0.0.1 의 loopback 모드만 허용한다는 제약사항도 있다.


위 kubectl proxy 명령어의 도움말 모드를 더 보면, 정적 컨텐츠에 대한 HTTP path를 명시해준다고 되어 있다. kubernetes cluster 안에서 사용자가 파드를 생성할 경우, Nodeport 나 Loadbalancer 를 사용하지 않고 ClusterIp만 사용할 경우 외부에서는 접근이 불가능하다. 이 때 kubectl 의 proxy 기능을 이용할 수 있다. 

다음과 같이 간단한 nginx 파드를 구동해본다.

cat pod.yaml

apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
  - name: nginx
    image: nginx:1.13.6
    ports:
    - containerPort: 80
 ----
kubectl get po

NAME                          READY   STATUS             RESTARTS   AGE
nginx                         1/1     Running            0          2m57s

그 후에 proxy 서버에서 아래와 같은 경로 표기 방식으로 curl 통신을 수행하면 NodePort 나 LB를 노출하지 않은 정적 파드 자원에 접근할 수 있다. 

curl http://localhost:8001/api/v1/namespaces/<네임스페이스 이름>/pods/<파드 이름>/proxy

사용 예는 다음과 같다.

curl http://localhost:8001/api/v1/namespaces/default/pods/nginx/proxy/

<결과>
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

kubectl port -forward

다음으로 kubectl port-forward 명령을 확인해본다. 이 기능은 위에서 설명한 kubectl proxy 기능의 두 번째 기능과 유사하다. 클러스터 내에 대상 deployment / pod / service 등에 대한 포트를, 호스트 노드의 사용자 포트와 매핑하여 준다.

사용 방식은 다음과 같다.

kubectl port-forward <리소스타입>/<리소스명> <호스트포트>:<타겟포트>

예로, 클러스터의 default namespace 에 구동된 nginx 파드의 80포트에 대하여, 호스트 노드의 28000번 포트로 매핑하는 port-forward 기능의 명령은 아래와 같다.

kubectl port-forward pod/nginx 28000:80

<결과>
Forwarding from 127.0.0.1:28000 -> 80
Forwarding from [::1]:28000 -> 80

이제 curl 통신으로 localhost의 28000번 포트로 접속하여, 클러스터 노드의 nginx 파드와의 통신이 정상 수행됨을 확인한다.

curl http://localhost:28000

<결과>
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

kubectl proxy, port-forward 기능은 다음과 같이 정리할 수 있다.

   kubectl proxy    kube-api server 로 (인증없이) 접근 가능한 포트 노출 (기본값 8001)
   kubectl port-forward    cluster 내 정적 자원(deployments, pods) 에 대한 포트를 노출

 

댓글