본문 바로가기
DevOps/k8s

[쿠버네티스 교과서] k8s 스터디 2주차 - 3장, 4장

by 민트맛녹차 2024. 8. 27.
24.08.21 ~24.08.27
k8s 사내 스터디에서 쿠버네티스 교과서 3, 4 장을 읽으며 공부한 내용

 

3. 네트워크를 통해서 서비스에 파드 연결하기

 

쿠버네티스 내부의 통신 방법

쿠버네티스 내에서는 모든 파드끼리 통신이 가능해야 함

파드끼리의 통신을 위해 IP 를 사용하는데, 파드 대체시 IP 가 변경되는 문제를 해결하기 위해 서비스(Service)라는 통신 트래픽의 라우팅을 맡는 리소스를 사용

 

변경되는 파드의 IP 주소를 사용하는 통신 대신, 도메인 네임과 클러스터 내 DNS 서버를 사용해 파드간 통신 구현

 

서비스 생성 시, 서비스에 정적 ip 주소인 클러스터IP(ClusterIP) 가 할당되며 서비스 마다 고유한 클러스터 도메인이 설정됨

클러스터IP 는 클러스터 DNS 에 등록됨

클러스터 도메인 네임을 통해 파드간 통신을 할 때 아래와 같이 동작

  • 출발지 파드는 클러스터 내 DNS 를 통해 서비스의 도메인의 클러스터IP 가져옴
  • 목적지 주소가 클러스터IP 로 설정되어 트래픽 보내려 함
  • 트래픽이 노드를 나가기 전, 노드 내 kube-proxy 가 목적지 주소를 목적지 파드 IP 주소로 설정해줌
  • (kube-proxy가 클러스터 IP 와 엔드포인트를 모니터링하여, 적절한 워커노드 내 목적지 파드IP 주소를 가져옴)
  • 트래픽이 목적지 파드로 전달
1. 출발지 파드는 클러스터 내 DNS(CoreDNS)를 통해 서비스 도메인 주소를 조회하고, 해당 서비스의 ClusterIP를 얻는다.
2. 출발지 파드는 목적지 주소로 받은 ClusterIP로 트래픽을 전송한다.
   - ClusterIP는 가상 IP로, 실제 파드가 아니라 kube-proxy가 처리하는 중간 주소이다.
3. 트래픽은 출발지 파드가 위치한 노드의 kube-proxy에 의해 가로채진다.
   - kube-proxy는 ClusterIP에 대응하는 실제 파드 IP(엔드포인트) 목록을 Kubernetes API 서버로부터 받아 캐시하고 있음
   - kube-proxy는 로드밸런싱 알고리즘을 통해 엔드포인트 중 하나를 선택
   - 선택된 엔드포인트 (파드 IP) 로 목적지 IP 를 변경하는 DNAT(Network Address Translation) 처리를 수행
4. 트래픽은 선택된 파드 IP 를 목적지로 설정하여 전달한다.
   - 목적지 파드가 동일 노드에 있다면 로컬로, 다른 노드에 있다면 클러스터 네트워크 (CNI 플러그인) 에 의해 적절히 처리
5. 트래픽은 선택된 목적지 파드로 도달한다.

 

 

 

외부 트래픽을 파드로 전달하는 방법

로드밸런서(LoadBalancer)

  • k8s 는 클러스터 외부에서 접근이 가능한 로드밸런서 주소/ip 를 만들어줌
  • 내부적으로는 NodePort 를 사용하여 동작
    • k8s 는 자동으로 노드포트 생성되어, 로드밸런서와 매핑
    • 클라이언트 -> [Cloud LoadBalancer] ->  [Node external IP]:[NodePort] -> kube-proxy -> Cluster IP Service-> 파드
    • 클러스터 환경에 여러 개의 노드로 구성된 경우, 트래픽을 처리할 노드는 Cloud LoadBalancer 의 로드밸런싱 알고리즘을 통해 선택됨

노드포트(NodePort)

  • 모든 노드에서 접근이 가능한 고정 포트 (NodePort) 를 열어둠
  • 클라이언트 -> [Node external IP]:[NodePort] -> kube-proxy -> Cluster IP Service-> 파드

 

 

클러스터 외부로 트래픽 전달하는 방법

익스터널네임 (ExternalName) 서비스

  • 외부도메인에 대한 로컬 도메인 네임을 생성해줌
  •  CNAME 을 사용하여 익스터널네임 서비스 구현 (

헤드리스 서비스 ()

 

 

 

4. 컨피그맵과 비밀값으로 어플리케이션 설정하기

쿠버네티스에서 컨테이너에 설정값을 주입하는데 쓰는 리소스는 컨피그맵(ConfigMap) 과 비밀값(Secret)

 

컨피그맵 (ConfigMap)

컨피그맵은 파드에서 읽어 들이는 데이터를 저장하는 리소스

데이터의 형태로는 키-값 쌍, 텍스트, 바이너리 파일 등을 보관 가능

다른 리소스와 독립적인 장소에 보관되어,컨피그맵과 파드는 N-M 관계를 가짐

  • 여러 파드가 하나의 컨피그맵 참조 가능
  • 하나의 파드가 여러 컨피그맵 참조 가능

 

컨피그맵 생성 방법

kubectl 명령어로 데이터 직접 입력

  • kubectl create configmap {name} --from-literal={key}={value}

env 파일로을 통해 생성

  • kubectl create configmap {name} --from-env-file={}.env

configmap 을 정의한 메니페스트 (yml 파일) 을 통해 생성

  • kubectl apply -f {}.yml

 

컨테이너 내에 환경변수를 전달할 뿐 만 아니라, 볼륨(volume) 과 볼륨 마운트(volume mount) 를 사용하면 컨테이너 안으로 설정 파일 주입 가능

컨테이너는 컨피그맵이 가진 데이터 항목의 일부만 사용 가능

볼륨을 사용하면 어플리케이션 재시작 없이 설정 파일 변경 가능

다만, 민감한 데이터를 다룰 때 컨피그맵은 데이터를 보호할 수단이 없으므로 사용하지 말아야 함

 

비밀값 (Secret)

비밀값은 컨피그 맵과 달리 아래와 같은 속성을 가짐

  • 해당 값을 사용해야하는 노드에만 전달
  • 노드에서 비밀값을 디스크에 저장하지 않고 메모리에 저장
  • 전달 과정과 저장할 때 모두 암호화가 적용
  • 비밀값 객체에 접근할 권한이 있다면 비밀값의 평문 읽을 수 있음

 

비밀값이 파드 컨테이너에 전달되면, 컨테이너 내에서는 평문이 담긴 텍스트 파일이 됨

 

비밀값도 환경변수 선언뿐 만 아니라,  볼륨(volume) 과 볼륨 마운트(volume mount) 를 사용한 설정 파일 주입 가능

비밀값을 사용하는 두 가지 방법

  • 컨테이너 환경에 환경 변수로 직접 전달
  • (추천) 컨테이너 환경에 파일 형태로 전달 후, 설정 파일의 경로를 환경 변수에 지정

 

주입 방식

주입 방식 configmap 변경 시 적용 방법
환경 변수 자동 반영 X -> 파드 재기동 시켜야함
볼륨 마운트 자동 반영됨 (단, 컨테이너가 파일을 다시 읽어야 적용됨)

 

 

 

 

 

 

문제 (2개)

 

 

 

#25.07.27, 08.03 수정

댓글