-
kubernetes Tutorials 4. 서비스를 사용해서 App을 공개하기DevOps/Kubernetes 2020. 5. 6. 02:29
지금까지 App은 컨테이너 안에서 돌며 굉장히 private 한 IP를 쓰고 네트워크 역시 isolated 된 상태였다.
따라서 밖에서 쉽게 접근할 수가 없었고 콘솔에다가 kubectl 프락시를 붙이고 그 프락시가 준 IP와
포트 뒤에다가 어떤 특정 API를 통해 POD이름을 주고 이를 통해 접속할 수 있었다.
학습목표
1. 쿠버네티스에서 말하는 서비스란?
2. 레이블과 레이블셀렉터 오브젝트들이 서비스와 어떻게 연관이 있는지 이해하기
3. 서비스를 사용해서 쿠버네티스 클러스터 밖으로 App을 노출시키기
Pods는 언젠가는 죽는다. Pods는 라이프사이클을 가진다고 한다. 어떤 워커 노드가 죽으면
그 노드에서 돌고있는 Pods 역시 사라지게 된다. 그렇게 되면 ReplicationController는 동적으로
클러스터를 새로운 Pods를 만들고 App을 다시 실행함으로써 원래 상태로 복구하려 할 것이다.
예를 들면 이미지를 처리하는 백앤드를 생각해보고 3개의 replica가 있다고 생각해보자.
Pods가 없어졌는지 생겼는지 상관없이 프런트엔드는 동작해야 한다. 즉 쿠버 네티스 클러스터
에 있는 각각의 Pods는 유니크한 IP 주소를 가지고 있는데 동일 노드에 있는 Pods라 할지라도 IP는
다르다. 그래서 App이 계속해서 동작할수 있도록 자동으로 Pods들끼리의 변경을 감지할 방법이 필요하다.
쿠버 네티스 서비스는 Pod들에 set을 논리적 개념으로 정의한 것이라고 한다. 서비스는 Pod들 간에 의존도를
낮춰준다. 하나의 서비스는 야믈이나 제이슨 등으로 정의할 수 있고 하나의 서비스 안에 들어있는 여러 개의
pods들에 set은 보통 LabelSelector로 판단이 된다고 한다.
비록 각각의 Pod는 제각각의 IP를 가지지만 클러스터 밖으로 노출되지는 않았다. 즉 서비스 없이는 노출
되지 않는다는 말이고 서비스가 노출시킬 수 있게 해주나 보다. 서비스는 App이 실질적으로 트래픽을 받게끔 해
주고 서비스 스펙 안에 타입을 명시함으로써 여러 방법으로 노출 가능하다고 한다.
type :
ClusterIP ( 기본값 ) : 서비스를 클러스터 내부에 IP로 노출시키는 방법. 이 방법은 서비스를
클러스터 안에서만 사용할 수 있게끔 해준다. 클러스터 내부 IP이니 당연한 것 같다.
NodePort : 서비스를 클러스터 안에 선택된 노드들과 동일한 포트로 내보내 주는 것 ( NAT 사용 )
이렇게 되면 서비스는 클러스터 밖에서 노드 IP와 포트를 사용해서 접근이 가능하다.
LoadBalancer : 현재 클라우드에 외부 로드 밸런서를 만들어서 고정된 외부 IP를 배정하는 방법
노드 포트의 SuperSet.
ExternalName : 임의의 이름을 사용해서 노출하는 방법. 이 이름을 스펙에 정의한다.
( 여기서 스펙이란 서비스를 정의하는 yaml이나 json 파일 같다. )
서비스에다 위에 실렉터를 지정하지 않은 경우도 있다. 그렇게 함으로써 유저들로 하여금
직접 서비스를 특정 End Point에다 맵핑할 수 있도록 해준다. 즉 쿠버 네티스가 하는 게 아닌 유저들이
직접 해주는 것.
가운데 칠각형 : 매니저
육각형 : 노드들
동그라미들 : Pod
위에 그림에서 Pods들의 set인 서비스를 볼 수 있다. 이 서비스는 하나의 IP로 묶인다. IP는 Pod에 할당된 IP 그리고
서비스에 할당된 IP가 있다. 서비스에 IP로 해당 IP에 접속이 가능하며 클러스터 밖에 노출된 IP나 내부로 노출된 IP가
될 수 있을 것 같다. 아래 노드는 Pod하나를 서비스로 감싼 모양이다.
서비스는 파드 셋에 걸쳐서 트래픽을 라우팅 한다.서비스라는 추상화 개념으로 Pod를 감싸고
Pod가 App에 영향을 주지 않고 제각각 알아서 죽거나 다시 만들어질 수 있게끔 해준다. 이는 Kubernetes Service에
의해서 관리된다.
서비스는 쿠버 네티스의 객체들에 대해 논리 연산을 허용해주는 기본 그룹핑 단위인, 레이블과 실렉터를 이용하여 파드
셋과 매치시킨다. 레이블은 오브젝트들에 붙여진 키/밸류 쌍으로 다양한 방식으로 이용 가능하다:
레이블은 오브젝트의 생성 시점 또는 이후 시점에 붙여질 수 있다. 언제든지 수정이 가능하다. 이제 서비스를 이용하여
우리의 애플리케이션을 노출도 시켜보고 레이블도 적용해 보자.
- 일단 Kubectl get Pods로 Pods가 잘 돌고 있는지 확인해보자.
- 서비스를 돌린 적은 없지만 하나의 서비스가 돌고 있다.
쿠버 네티스란 서비스가 있고 미니큐브를 실행하면 자동으로 만들어지는 서비스이다.
- 새로운 서비스를 만들어서 밖으로 노출시키고 외부 트래픽을 받으려면 노드 포트를 파라미터로 준 뒤 expose 명령어
를 써야 한다. 이 App이 쓰는 포트를 적어주어야 하고 포트랑 맞물리는 외부에 공개되는 포트는 랜덤으로 생성되는 듯
싶다. 쿠버 네티스에서 NodePort를 오픈 시 Range가 30000~32767 사이에서 자동으로 생성된다고 한다.
- 그다음에 다시 한번 서비스를 실행해보면 하나 더 돌게 되고 있다. 노드 포트 타입으로 kubernetes-bootcamp라는 서
비스가 하나 생겼다. 32246은 내부 포트인 것 같다.
- 이제 kubernetes-bootcamp 라는 서비스가 돌고 있고 describe 해보자. Port는 내부 포트 NodePort는 외부 포트인 것 같다.
- 32246 노드 포트가 밖으로 공개가 됐다.
-미니큐브에서 돌고 있는 IP에다가 32246에 curl을 보내면 서비스로 노출된 end point를 사용해서 다음과 같이 접근 가능하다.
- 해당 레이블을 사용해서 Pod 리스트를 쿼리 해보자. pod를 다시 한번 가져오니 이름이 찍히고
레이블을 가지고 있는 서비스와 Pod를 조회할 수 있다.
- 다음과 같이 kubernetes-bootcamp라는 서비스를 죽이는 것도 가능하다.
- 더 이상 라우팅이 되지 않는 것을 확인할 수 있다. 즉 더 이상 이 클러스터 밖에서 접근이 안 되는 것
정리 :
Pods는 컨테이너들의 묶음, 컨테이너들이 공유해서 사용하는 리소스들의 묶음. Pod는 고유한
IP를 가진다.
Node라는 것은 워커 머신이다. 실제 Pod를 실행하며 VM일수도 있고 물리 서버일 수도 있다. 하나의 노드 안
에는 여러 개의 Pod가 올라갈 수도 있고 각각의 Pod당 Ip는 따로 존재한다.
노드에 Kubelet은 클러스터에 있는 매니저와 소통한다.
이전에는 Pod안에서 돌고 있는 private 한 App을 kubectl 프락시를 만들어서 그 프락시가 제공하는 Api 뒤에 Pod Name
을 줘서 접속할 수 있었다.
하지만 Pod들의 묶음인 서비스를 사용한다면 외부에서 접근할 수 있는 방법들을 제공해준다.
이 접근방법 중 NodePort를 써봤고 노드 포트를 쓰면 미니큐브가 자동으로 생성해준 포트로 외부에서 요청을 받을 수
있다. 이 자동으로 만든 포트를 매핑할, 라우팅 할 IP를 8080으로 지정해주었고 이동해주었다.
이 Pod들을 하나로 묶은 서비스이고 서비스에 노출된 IP는 실습에서는 미니큐브에 IP였다.
이 Pod에 App들이 돌고 있고 8080 포트 쪽으로 라우팅을 해준다.
레이블을 사용해서 Pod를 조회, 특정 레이블을 가진 서비스를 조회한다거나 또는 어떤 Pod에 있는 레이블을
변경하는 일등을 해봤다.
https://kubernetes.io/docs/tutorials/kubernetes-basics/expose/expose-intro/
'DevOps > Kubernetes' 카테고리의 다른 글
clusterRole, clusterRoleBinding (0) 2021.10.29 Kubernetes 인그레스 요청 흐름 (0) 2021.07.19 kubernetes Tutorials 3. Pods 와 Nodes (0) 2020.05.01 kubernetes Tutorials 2. kubectl을 사용해서 배포하기 (0) 2020.04.27 kubernetes Tutorials 1. 미니큐브 사용해보기 (0) 2020.04.22