본문 바로가기
자바 , 기타 공부/클라우드 공부

쿠버네티스 네트워킹

by 임지혁코딩 2024. 2. 4.

1. 컨테이너를 Networking 하기

ex) application을 배포한, container를 생성했다. 

이때 해당 application이 db에 crud를 진행한다. 

Container1엔 application을 2에는 db를 작성하고, pod로 이 container 두개를 관리한다 .

*이 방식은, 동일 pod에서 db와 application을 동작시키면 문제 식별이 어렵다. 

 

주로, application을 1개의 container,pod,service로, db또한 1개의 container,pod,service로 분할한다.

Service의 ip주소를 확인하기는 쉽지 않다.

 

그 이유는 , 쿠버네티스는 kube-dns service를 자체 운용, 자동 실행하기 때문이다. 

service이름:ip주소의 key-value를 가진다. 

 

즉, application은 database service의 key로 그 ip인 value를 kube-dns service에서 찾는다.

그 이후 해당 ip로 db의 정보를 요청하거나 변경하는 crud를 진행한다. 

(application service -> kube-dns-> database service) 구조

 

*핵심은! Container에 db를 포함하는 것이 좋지 않다. DB용 CONTAINER를 생성하는것이 좋고 kube-dns로 찾아 통신한다.

 

<kube - dns를 찾아보자>

Namespace라는 개념을 알아야한다. 

이는 쿠버네티스의 리소스를 별도 영역으로 관리하는 개념이다. 

 

주로 API GATEWAY (POD, SERVICE를 모두 의미한다), WEB CONTAINER, ADMINCONSOLE은

크게 묶어서 FRONT END NAMESAPCE에, 외의 SECURITY,USER 등은 BACK END NAMESPACE에 

묶인다. 

 

즉, 큰 BACKEND와 FRONTEND같은 개념을, 패키지처럼 분할하는 큰 단위가 된다.

(별도 설정하지않으면, 기본 NAMESPACE에서 관리된다) (KUBECTL GET ALL만 쓰면, 기본 NAMESPACE만 확인한다)

 

kubectl 의 namespace들을 확인할 수 있다. 

 

이를 보자, 단순한 po만(기본 namespace)검색해선 존재하지 않았던 pods들을 찾아냈다.

 

이렇게도 확인할 수 있다. 

 

반면, kube-public은 아무것도 나오지 않는다. 

kube-public은 모두가 읽기 권한으로 볼 수 있는 namespace지만, 잘 사용하지 않는다. 

 

다른 namespace에서는 , -n을 추가해줘야 함에 주의하자. 

 

 

*<다른 pod의 db container를 참조하기>*

 

구조는 dns container에서 servicename을 key로, value 인 db의 ip를 받아오는 구조임을 기억하자

 

생성한 yaml 파일.

 

1. img는 내부적으로 재공하는 mysql:5를 활용. 

2. name:MYSQL_ROOT_PASSWORD등은, value에 내가 원하는 값을 넣음으로써 해당 pw or db를 지정해줄 수 있다.

 

해당 database service의, cluster-ip를 얻을 수 있었다. 

 

내부 pod을, 임의적으로 실행하였다. (명령어의 입력을 위해 shell 또한 생성하였다)

 

이제, webapp service가 database service에 연결해야한다. 

 

/ # cat /etc/resolv.conf
nameserver 10.96.0.10
search default.svc.cluster.local svc.cluster.local cluster.local
options ndots:5

 

이렇게 확인하여, IP를 확인할 수 있다. 해당 ip는, kube-dns의 ip 주소이다.

database의 주소도, nslookup database로 얻을 수 있다. 

 

<이제 db를 담당하는 service 의 주소를 알았다!>

mysql-client를 설치하였다. (다만 아직 mysql과 연결되지 않아, 오류가 발생한다)

 

컨테이너 위에서 설치하였던, mysql의 pw와 id를 활용해 접속하였다

mysql -h database -uroot -p(비밀번호) (db이름)

DB와 연결되었고, QUERY도 날려 TABLE을 생성했다.

 

<도메인 이름 검색 TIP>

SHELL의 위에서 nslookup외의 방법으로도 확인할 수 있다.

 

다른 NAMESPACE의 것을 조회하기 위해선

nsookup database.mynamespace와 같이 전체 주소 도메인이름을 확인하는 것이 좋다. 

(현재는 FQDN이 저절로 이름을 알려준다 DNS처럼.)

 

 

 

(내가 프로젝트를 다 개발하고, 해당 DB와 동일 혹은 해당 DB를 POD에 넣는 방법은 고민해봐야 될 것 같다.)

 

 

---복습 ---

 

NAT? : ROUTER에서 번호를 붙여, PRIVATE IP를 PUBLIC IP처럼 사용하는 방법을 의미한다. 

 

IPV4를 기본으로 판단하자.

PUBLIC IP ADDRESS의 영역과, SUBNET에서의 PRIVATE IP ADDRESS가 존재한다.

(PRIVATE는 192.168.0.0.~192.168.255.255)

K8S는 PRIVATE IP로 할당하지만, NODE의 PUBLIC 주소로 들어와서 NAT를 통해 최종 POD의 PRIVATE IP 주소로 접속해야 한다. 

 

POD 간 통신에는 SWITCH BRIDGE(EX)192.168.25~~ 로 동일한 주소 끼리는 쉽게 연결이 가능하지만,

그렇지 않다면 ROUTER가 필요하다 (컴퓨터통신과 같은 개념)) 

 

NAMESPACE는 여러 POD들을 포함하며, 패키지와 유사한 개념임을 복습하자.

(그 목표가, 역할의 범위와 리소스의 분리를 위함을 기억하자)

 

NAMESPACE가 다를때는 추가적인 기능이 필요했다 . (한 예시로, DB를 다른 NAMESPACE로 두어 DB POD의 IP를 얻어서 다시 접속했던 예시를 기억하자)

 

각 CONTAINER들은, NAT없이도 IP를 가진다.

핵심은 . 같은 CLUSTER내부에서는 ROUTER 없이도 통신이 가능하다. (하지만 확인은 필요하다)

 

EX) NODEA에 POD1,POD2. NODE B에 POD3, POD4가 있다면?

POD1은 10.43.2.1,POD 2는 10.43.2.2 

 

CLUSTER는 10.43.0.0/16, 각 POD들의 IP 할당은 10.43.0.0~10.43.1.0~~10.43.4.0과 같이

마치 SUBNET처럼 할당된다. (허나 PUBLIC IP보다 작은 PRIVATE IP 보다 작은 단위임을 기억하자)

 

NODE의 IP는? 192.168.1.2/24 , 192.168.1.3/24 처럼 . NODE 별로 다르게 할당된다.

허나 이러한 NODE도 크게 보면, 클라우드로 할당받은 주소의 SUBNET이다. 

NODE들도 IP ADDRESS를 상호간 알아야 통신이 가능하다!

(여태까지 MINIKUBE만을 사용해 하나의 CLUSTER에 하나의 NODE만을 사용해서 이러한 상황을 겪지 못한 것)

 

SERVICE는 POD간 통신을 지원하는 것으로 기억하는데, 이것을 다시 복습해보자.

 

POD는 언제든 사라지고 다시 생성될 수 있음을 기억하자. 그렇다면 POD IP로 연결하는 것은

문제가 있을 수 있다. 

 

LABEL을 보고, SERVICE가 어떤 POD과 연결할지를 MAPPING함도 기억하자. 

 

SERVICE가 진행했던 외부와, 각 POD들과의 통신은 사실은 

POD들을 LABEL에 따라 SERVICE의 단위로 묶어, 동일한 IP주소(외부적으로)로 묶어주는 역할을 한다고 할 수 있다. 

이는 POD의 생성과 삭제에 상관없이 외부와의 통신을 지원할 것이다. 

 

SERVICE를 REPLICASET으로 묶는데, 그 REPLICA의 수를 변경하여 POD의 문제를 해결할 수 있다.

 

CLUSTERIP는, SERVICE 내부적으로만 사용하는 IP를 의미한다. 

Nodeport는, NodePort는 외부에 노출되는, port는 내부의 pod의 port number를 설정한다. 

LoadBalancer는, 별도의 software를 사용해서 이러한 service의 역할을 진행할 수 있다. 

사용하기엔 유리할 수 있다.

위에 진행한 예시처럼, dns server를 활용할 수도 있다. 

 

*허나 그렇다고 사용하는 모든 pod를 같은 service로 묶어버리면, traffic의 문제가 생길 수 있다.  

 

-NodePort 개념 복습 -

 

  1. Pod 1:
    • 라벨: app=backend, tier=app1
  2. Pod 2:
    • 라벨: app=backend, tier=app2
  3. Pod 3:
    • 라벨: app=backend, tier=app3
    • 이와 같이 설정할 수 있다. (특정 POD에게만 요청할 수 있다.)

 

외부는 NODEPORT(30000~32767), SERVICE는 PORT , 특정 POD에 대한 PORT.NUMBER를 TARGETPORT

 

*즉, 한 SERVICE내의 다른 기능의 POD들을 포함하는 방향은 지양 하자. 

 

만약, 다른 NODE 1,2,3의 다른 POD A,B,C,를 한개의 SERVICE로 묶으면 어떻게될까?

일단 LABEL에 따라서 가능하다.

허나 이때 주의 할 것이, NODE1로 접속해도 SERVICE를 통해 POD B로 전송될 수 있다는 것이다.

이때는 별도의 PLUGIN, MASTER NODE의 SETTING을 통해서 진행해야 한다. 

 

(TARGETPORT는 POD .YAML에도 정의해야 함에 주의)