K&8에 배포한 애플리케이션(Pod)을 외부에서 접근하기 쉽게
추상화한 리소스
- Pod는 IP를 할당받고 생성되지만, 언제든지 terminate 됐다가, live할 수 있으며, 그 과정에서 IP는 재할당 되기 때문에 고정된 EIP로 원하는 Pod에 접근 할 수가 없다.
- 따라서 클러스터 외부 혹은 내부에서 Pod에 접근할 때는, Pod의 IP가 아닌,
Service를 통해 접근하는 방식을 거친다.
- 따라서 클라이언트가 Service의 주소로 접근하면, 실제로는 Service에 매칭된 Pod에 접속할 수 있다.
apiVersion: apps/v1 # kubernetes resouce의 API Version
kind: Deployment # kubernetes resource name
metadata: # 메타데이터 : name, namespace, labels, annotations 등
name: nginx-deployment
labels:
app: nginx
spec: # 메인파트 : resource의 desired state 를 명시
replicas: 3 # 동일한 template의 pod를 3개 복제본으로 생성
selector:
matchLabels:
app: nginx
template: # Pod의 템플릿을 의미
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx # container name
image: nginx:1.14.2 # container image
ports:
- containerPort: 80 # container 내부 포트
생성된 Pod의 IP를 확인하고 접속을 시도
$ kubectl apply -f deployment.yaml $ kubectl get pod -o wide # Pod의 Ip 확인 $ curl -X GET <POD IP> -vvv $ ping <POD-IP> # 통신 불가능
할당된 Pod IP는 클러스터 내부에서만 접근할 수 있기 때문에,
외부에서는 접근 불가
minikube 내부로 접속하면 통신이 되는지 확인$ minikube ssh # minikube 내부로 접속 $ curl -X GET <POD-IP> -vvv $ ping <POD-IP> # 통신 가능
apiVersion: v1
kind: Service
metadata:
name: my-nginx
labels:
run: my-nginx
spec:
type: NodePort # Service의 Type을 명시하는 부분.
ports:
- port: 80
protocol: TCP
selector: # 아래 label을 가진 Pod를 매핑한다.
app: nginx
Service 생성
$ kubectl apply -f service.yaml $ kubectl get service # PORT 80:<PORT> 숫자 확인 $ curl -X GET $(minikube ip):<PORT> # 서비스를 통해 클러스터 외부에서도 정상적으로 Pod에 접속
NodePort라는 type을 위에 사용했기 때문에,
minikube라는 K&8 클러스터 내부에 배포된 서비스에 클러스터 외부에서 접근 할 수 있었다.
접근하는 IP는 Pod가 떠있는 노드(머신)의 IP를 사용하고,
Port는 할당받은 port를 사용한다.
LoadBalancer 라는 type을 사용해도, 마찬가지로 클러스터 외부에서 접근할 수 있지만, LoadBalancer를 사용하기 위해서는 LoadBalancer 역할을 하는 모듈이 추가적으로 필요하다.
ClusterIP라는 type은 고정된 IP, PORT를 제공하지만, 클러스터 내부에서만 접근할 수 있는 대역의 주소가 할당된다.
실무에서는 주로 kubernetes cluster에 MetalLB와 LoadBalancing 역할을 하는 모듈을 설치한 후, LoadBalancer type으로 서비스를 expose하는 방식을 사용.
NodePort는 Pod가 어떤 Node에 스케쥴링될 지 모르는 상황에서,
Pod가 Node의 IP를 알아야 한다는 단점이 존재한다.