Network

Single Node 상황

  • 쿠버네티스에서는 내부 IP 주소가 Pod에 할당됨.
  • 쿠버네티스 클러스터는 처음 설정될 때, internal private network 를 생성함
    • 모든 pods는 이 네트워크의 레인지 내에서 IP를 부여받음
  • Pod가 재생성될 때는 또 새로운 IP를 부여받음
    • 따라서, Pod에 부여된 IP로 접근하는 것은 적절한 방법이 아님

Multiple Nodes in a Cluster 상황

  • 각 Node 의 IP는 다르지만, 각 노드 내 Pod의 네트워크가 같을 수 있음
  • 하지만,
    • 모든 Container / Pod는 NAT 없이도 서로 networking 가능
    • 모든 Node는 NAT 없이도 서로 networking 가능
  • 따라서 IP conflict 을 피하기 위한 조치가 필요함
  • pre-built solution 존재하기도 함
    • cisco
    • big cloud fabric
    • flannel
    • vmware nsx
    • calico
    • cilium … etc

Service

  • helps connecting applications together with other applications OR userss
  • ex)
    • backend server
    • frontend application
    • external datasource
    • etc …

Service 개념

  • Service는 Kubernetes를 기반으로 하는 어플리케이션 내외의 통신과 접근을 위한 obejct
  • Service 유형
    • Node Port service
      • node의 port 에서부터 listen(응답대기) → request 를 pod로 전달하는 역할
    • Cluster IP
      • 클러스터 내 virtual IP를 생성하여 제각기 다른 service들 간의 통신을 가능케 함.
      • ex) frontend server 와 backend server가 서로 접근할 수 있도록 사용
    • LoadBalance
      • 클라우드 서비스의 로드밸런서 사용을 위한 service

Node Port Service

Service 관점에서 …

  • TargetPort : 액세스 하고자 하는 POD의 Port
  • Port : TargetPort와 매핑되는 Service의 Port (Cluster IP)
  • NodePort : 외부 클라이언트에서 액세스할 때 사용하는 노드의 Port (노드는 30000 ~ 32767 사이의 포트만 가질 수 있도록 설정 됨)

Node Port 생성하기

# ex) service-definition.yml

apiVersion: v1

kind: Service

metadata: 
	name: myapp-service

spec: # Service를 정의하는 가장 중요한 부분
	type: NodePort
	port: 
		# 하나의 Service에 여러개의 포트 매핑이 가능함. 하나의 매핑 묶음은 array로 표현
		- targetPort: 80
			port: 80
			nodePort: 30004
			# port는 필수
			# nodePort를 명시하지 않으면 30000~32767 사이에서 놀고 있는 포트 아무거나 쓰게 됨
			# targetPort를 명시하지 않으면 port와 같은 것으로 간주함

	# 해당 service를 Pod에 연결하기
	selector:
		# 기존에 pod를 정의하면서 사용한 label를 동일하게 기입하면 해당 pod에 매핑됨
		# ex)
		app: myapp
		type: front-end

  • kubectl create -f service-definition.yml
  • kubectl get services
    • kubectl get svc
  • 외부에서 액세스 할 수 있는 url 표기 (아래 minikube일 경우) : minikube service [SERVICE_NAME] --url

Node Port - Single / Multi 상황

Multiple Pods in Single Node 상황

  • Service가 매핑된 여러개 Pod에 알아서 잘 뿌려줌 (ㄷ ㄷ ㄷ)
  • 빌트인 로드밸런서라고 생각하면 됨
  • 이 때 로드밸런싱 알고리즘: 랜덤 알고리즘

Multiple Nodes in Cluster 상황

  • 서비스를 생성하게 되면, 클러스터 내 노드를 관통하는 서비스를 자동으로 생성함
  • 각 노드의 포트를 묶어 하나의 노드 포트로 매핑하는 서비스
    • 이렇게 하면 어느 노드 IP로 해도 포트가 같기 때문에 동일하게 액세스 가능

ClusterIP

  • 백엔드, 프론트엔드, 데이터베이스, 레디스 등으로 “티어”를 구분 짓는다면 … 각 티어를 서로 연결시켜주는 service 가 필요해짐
  • Pod는 내리고 올리고 하면서 새로운 IP가 재부여 되기 때문에, 여기에 기댈 수 없음.

ClusterIP를 사용하게 되면

  • 각 티어를 분리시켜 따로 개발 / 수정 / 배포 / 스케일링이 가능함. 그리고 서로 연결은 스무스해짐

ClusterIP 생성

# service-definition.yml

apiVersion: v1

kind: Service

metadata:
	name: back-end

spec:
	type: ClsuterIP  # service 정의할 때 명시하지 않으면 default로 ClusterIP로 정의 됨.
	ports:
	- targetPort: 80  # 티어의 port
		port: 80  # service 의 포트
		
	selector:  # 마찬가지로 pod의 select에 매핑
		app: myapp 
		type: back-end
  • kubectl create -f service-definition.yml
  • kubectl get services

LoadBalancer

  • 개별 인프라라면 nginx와 같은 로드밸런서를 세팅하겠지만,
  • 클라우드 환경이라면, K8s에서 자체적으로 클라우드 플랫폼의 네이티브 로드밸랜서에 통합될 수 있도록 지원함
    • AWS, GCP, Azure 또는 그 외 supported cloud provider 일 때만 유효한 기능임

LoadBalancer 적용

# service-definition.yml

apiVersion: v1

kind: Service

metadata:
	name: myapp-service

spec:
	type: LoadBalancer
	port:
	- targetPort: 80
		port: 80
		nodePort: 30008

Reference