본문 바로가기

Infrastructure/Kubernetes

[클러스터 아키텍처] 컨트롤 플레인-노드 간 통신

쿠버네티스 공식문서를 확인하며 컨트롤 플레인-노드 간 통신에 대해서 기억해야 하는 부분을 기록한다.

API 서버와 클러스터 사이에 대한 통신 경로의 목록을 알아본다. 사용자가 신뢰할 수 없는 네트워크나 클라우드 공급자의 완전 퍼블릭 IP에서 클러스터를 실행할 수 있도록 네티워크 구성을 강화하기 위한 설비를 할 수 있도록 한다.


노드에서 컨트롤 플레인으로의 통신

  • 쿠버네티스에는 “허브 앤 스포크(hub-and-spoke)” API 패턴을 가지고 있다.
  • 노드와 파드의 모든 API 사용은 API 서버에서 종료된다.
  • 다른 컨트롤 플레인 컴포넌트 중 어느 것도 원격 서비스를 노출하도록 설계되지 않았다.
  • API 서버는 하나 이상의 클라이언트 인증 형식이 활성화된 보안 HTTPS 포트에서 원격 연결을 수신하도록 구성된다.
  • 특히 익명의 요청 또는 서비스 어카운트 토큰이 허용되는 경우, 하나 이상의 권한 부여 형식을 사용해야 한다.
  • 노드는 유효한 클라이언트 자격 증명과 함께 API 서버에 안전하게 연결할 수 있도록 클러스터에 대한 공개 루트 인증서(root certificate, RootCA)로 프로비전해야 한다.
  • 클라이언트 인증서(client certificate) 형식으로 kubelet의 클라이언트 자격 증명을 사용하는 것은 좋은 방법이다.
  • API 서버에 연결하려는 파드는 서비스 어카운트를 활용하여 안전하게 쿠버네티스가 공개 루트 인증서(root certificate)와 유효한 베어러 토큰(bearer token)을 파드가 인스턴스화될 때 파드에 자동으로 주입할 수 있다.
  • default 네임스페이스의 kubernetes 서비스는 API 서버의 HTTPS 엔드포인트로 리디렉션되는 가상 IP 주소(kube-proxy를 통해) 구성되어 있다.
  • 컨트롤 플레인 컴포넌트는 보안 포트를 통해 클러스터 API 서버와도 통신한다.
  • 노드 및 파드에서 컨트롤 플레인으로 연결하기 위한 기본 작동 모드는 기본적으로 보호되며 신뢰할 수 없는 네트워크 및 공용 네트워크에서 실행될 수 있다.

[정리]

노드와 파드가 컨트롤 플레인과 통신은 보안이 적용되어 있어야 하며 인증서 또는 베어러 토큰을 사용할 수 있다. 보안이 적용되어 있다면 신뢰할 수 없는 네트워크나 공용 네트워크에서 실행될 수 있다.


컨트롤 플레인에서 노드로의 통신

  • 컨트롤 플레인(API 서버)에서 노드로는 두 가지 기본 통신 경로가 있다.
    1. API 서버에서 클러스터의 각 노드에서 실행되는 kubelet 프로세스다.
    2. API 서버의 프록시 기능을 통해 API 서버에서 모든 노드, 파드, 서비스에 이르는 것

API 서버에서 kubelet으로의 통신

  • API 서버에서 kubelet으로의 연결은 아래의 용도로 사용되며 kubelet의 HTTPS 엔드포인트에서 종료된다.
    • 파드에 대한 로그를 가져온다.
    • 실행 중인 파드에 kubectl을 통해 연결한다.
    • kubelet의 포트-포워딩 기능을 제공한다.
  • API 서버는 kubelet의 제공(serving) 인증서를 확인하지 않는다. 이는 연결이 중간자 공격(man-in-the-middle)에 시달리게 하며, 신뢰할 수 없는 네트워크 및 공용 네트워크 에서 실행하기에 안전하지 않다.
  • --kubelet-certificate-authority 플래그를 사용하여 API 서버에 kubelet의 제공(serving) 인증서를 확인하는데 사용할 루트 인증서 번들을 제공한다.
  • 이러한 선택이 불가능한 경우 신뢰할 수 없는 네트워크 또는 공용 네트워크를 통한 연결을 피하기 위해 API 서버와 kubelet 간 SSH 터널링을 사용한다.
  • kubelet API를 보호하려면 Kubelet 인증 및 인가를 활성화해야 한다.

API 서버에서 노드, 파드 및 서비스로의 통신

  • API 서버에서 노드, 파드 또는 서비스로의 연결은 기본적으로 일반 HTTP 연결로 연결되므로 인증되거나 암호화되지 않는다.
  • 이러한 연결에서 URL을 노드, 파드 또는 서비스 이름에 접두어 https: 을 붙여 보안 HTTPS 연결이 되도록 실행할 수 있지만, HTTPS 엔드포인트가 제공한 인증서의 유효성을 검증하지 않으며 클라이언트 자격 증명도 제공하지 않는다.
  • 연결이 암호화되는 동안 어떠한 무결성도 보장되지 않으며 신뢰할 수 없는 네트워크 및 공용 네트워크에서 실행하기에 안전하지 않다.

[정리]

컨트롤 플레인과 노드가 통신하는 방식은 두 가지가 있다.

“API 서버와 kubelet의 통신”은 API 서버가 인증서를 확인하지 않기 때문에 보안에 취약하며 보안 취약점을 보완하기 위해서 루트 인증서 번들을 제공받거나 SSH 터널링을 사용해야 한다.

“API 서버와 노드 및 파드와의 통신”은 HTTPS를 사용하더라도 인증서의 유효성을 검증하지 않기 때문에 신뢰할 수 없는 네트워크에서 실행하기에 안전하지 않다.


SSH 터널 (Deprecated)

  • 쿠버네티스는 SSH 터널을 지원하여 컨트롤 플레인에서 노드로의 통신 경로를 보호한다.
  • API 서버는 각 노드에 SSH 터널을 시작하고 터널을 통해 kubelet, 노드, 파드, 서비스로 향하는 모든 트래픽을 전달한다.
  • 터널은 노드가 실행 중인 네트워크의 외부로 트래픽이 노출되지 않도록 한다.

Konnectivity 서비스(SSH 터널 대체)

  • SSH 터널은 v1.25 기준에서 더 이상 사용되지 않으며 Konnectivity 서비스가 SSH 통신 채널을 대체한다.
  • Konnectivity 는 SSH 터널을 대체로 컨트롤 플레인과 클러스터 간 통신에 TCP 레벨 프록시를 제공한다.
  • 컨트로로 플레인 네트워크의 “Konnectivity 서버”와 노드 네트워크의 “Konnectivity 에이전트”, 두 부분으로 구성된다.
  • Konnectivity 서비스를 활성화한 후, 모든 컨트롤 플레인에서 노드로의 트래픽은 이 연결을 통과한다.

[정리]

“SSH 터널”을 통해 컨트롤 플레인과 노드와의 통신을 보호할 수 있다.

v1.25 기준으로 SSH 터널은 더 이상 사용되지 않으며 이를 대체하는 Konnectivity 서비스가 출시되었다.

Konnectivity 서비스는 서버와 에이전트로 구성되어 있으며 컨트롤 플레인과 노드와의 모든 트래픽은 이 연결을 통과한다.


참고 자료