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
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