*유데미에서 진행하는 Kubernetes for the Absolute Beginners - Hands-on 강의를 바탕으로 제작되었습니다.
쿠버네티스 서비스란 무엇이고 왜 필요하며 어떤 역할을 하는지 알아보겠습니다.
쿠버네티스 서비스: 쿠버네티스 어플리케이션 안팎의 다양한 구성요소 간의 통신을 가능하게 해줌, 서비스는 앱 내 마이크로 서비스 간의 느슨한 연결을 가능하게 해준다
1. 쿠버네티스 서비스가 없을 때
쿠버네티스 서비스가 없을 때 위 사진처럼 사용자는 curl http://10.244.0.2로 직접 접속해 파드 속 응용 프로그램을 실행시켜야 했습니다.
2. 쿠버네티스 서비스가 있을 때
쿠버네티스 서비스가 있으면 사용자는 노드포트(30008)과 노드의 ip(192.18.1.2)를 이용해 노드 속 응용 프로그램을 실행하는 파드에 접속할 수 있습니다.
사진에서 보이는 것 처럼 1, 2, 3 세 개의 포트가 보이는데 1번은 Target Port로 타겟 포트는 응용 프로그램을 실행하는 파드의 포드번호입니다. 2번은 Port인데 쿠버네티스 서비스의 포트번호입니다. 그리고 3번은 NodePort로 노드포트는 외부 사용자가 쿠버네티스 서비스와 연결할 수 있게 해주는 역할을 합니다.
*쿠버네티스 서비스에는 클러스터ip도 나오는데 클러스터ip란 클러스터 내부에서 사용하기 위한 가상의 ip입니다.
즉, 외부 사용자는 노드포트(30008)을 거쳐서 쿠버네티스 서비스를 거치고 마지막으로 타겟노드에 도달하게 됩니다.
왜 이렇게 연결할까?(노드 포트 서비스, Node Port Service)
이렇게 한 단계 거치는 작업을 하는 이유는 deployment에서 업데이트를 실행하면 기존의 파드가 삭제되고 새로운 파드로 교체되는데 새로운 파드는 새로운 ip를 가지게 됩니다. 그렇게 되면 업데이트를 할 때마다 각 파드의 ip를 다시 알아와서 연결해야 하는 번거로움이 생기게 되는데 쿠버네티스 서비스는 selector에 있는 라벨을 기준으로 파드들을 식별해서 자신이 관리할 파드들과 자동으로 연결해줍니다.
즉, 업데이트를 진행해도 새로운 파드에 쿠버네티스 서비스와 같은 라벨이 있다면 자동으로 연결이 되는 것이죠 그렇게 되면 사용자는 노드의 ip와 노드 포트(NodePort)만 알고 있으면 deployment에서 업데이트를 진행해도 서비스에 쉽게 접근할 수 있습니다.
이러한 방식을 노드 포트 서비스(Node Port Service)라고 합니다
그리고 NodePort는 30000 ~ 32767 사이의 범위를 가지고 있어서 definition 파일에서 유효 범위 사이의 값을 지정해주면 됩니다.
타켓포트(Target Port)를 지정해주지 않으면 포트(Port)와 동일하게 지정됩니다 또한 노드 포트도 지정해주지 않으면 유효 범위 사이의 랜덤값을 자동으로 지정받습니다.
쿠버네티스 서비스 정의 파일예시
# service-definition.yaml
apiVersion: v1
kind: Service
metadata:
name: myapp-service
spec:
type: NodePort
ports:
- targetPort: 80
port: 80
nodePort: 30008
selector:
app: myapp
type: front-end
# deployment.yaml
..<생략>..
spec:
selector:
matchLabels:
app: myapp
..<생략>..
ports는 배열이라서 복수개의 포트 매핑을 가질 수 있습니다. 리스트의 시작은 -로 시작합니다. 여기서는 타겟포트 80, 포트도 동일하게 80, 그리고 노드포트는 30008로 지정해주었습니다.
위에서 설명했지만 service-definiton에서는 selector를 이용해 파드를 식별합니다. 그래서 selector 섹션을 원하는 파드와 매치시켜주어야 합니다.
쿠버네티스 서비스는 selector 부분 작성시 deployment 정의 파일에서 복사 붙여넣기를 하는데 deployment 파일에서 matchLabels 부분은 빼고 selector.app: myapp 처럼 바로 적어주어야 합니다.
service-definition에서 라벨은 deployment와 다르게 matchLabels를 붙이지 않습니다. 그냥 키-값쌍만 넣어주면 됩니다.
서비스 생성
# 서비스 생성
kubectl create -f service-definition.yaml
>>>
service/myapp-service created
서비스 확인
kubectl get services
>>>
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 6d23h
myapp-service NodePort 10.111.248.2 <none> 80:30008/TCP 73s
TYPE을 보시면 클러스터ip랑 노드포트 2가지가 생긴것을 볼 수 있습니다. NodePort를 보시면 PORT(S) 부분에 80:30008/TCP를 확인할 수 있는데 여기서 80은 Target Port이고(서비스의 Port가 아님), 30008은 노드포트 번호입니다.
매핑된 포트를 명시할 때 "내부 포트 : 외부 포트"를 기준으로 하는 것이 일반적이며 내부에서 외부로 나가는 것만 표현했다고 외부(노드포트)에서 내부(타겟 포트)로 들어노는 것도 매핑되어 있어 안되는 건 아닙니다.
NAME 'kubernetes'는 kubernetes api 서버에 대한 접근을 위한 것 443/tcp로 kubernetes api서버에 접근을 위한 것입니다. 따로 생성하지 않아도 기본으로 쿠버네티스 서비스에 포함되어 있는 서비스이며 delete 명령어로 삭제해도 지워지지 않고 다시 생성됩니다.
3. 파드가 여러개인 경우
지금까지는 파드가 1개인 경우를 살펴봤는데 노드에 파드가 여러개인 경우가 존재할 수 있습니다.
하나의 노드 속 파드가 여러개라해도 selector와 라벨을 기준으로 파드를 식별하여 관리하며, 서비스의 수가 늘지 않습니다. 여기서 파드 1, 2, 3의 포트 번호는 모두 동일합니다.
*파드로 오는 부하를 어떻게 분산시키는지 알고 싶다면 Random Algorithm을 보면 알 수 있다고 합니다
4. 노드가 여러개인 경우(다중 노드)
노드가 여러개인 경우에도 쿠버네티스 서비스는 하나입니다. 각 노드는 ip 주소는 달라도 통일된 노드포트(30008)을 가지고 외부 사용자가 클러스터에 접근할 수 있고, 서비스는 각 노드에 있는 파드와 연결됩니다.
사용자는 특정 파드를 접속할 때 서비스가 selector를 통해 파드를 찾아 연결해주기 때문에 파드의 세부정보(포트랑, 타겟포트)를 알 필요없이 노드의 ip와 노드포트(NodePort)만 알면 됩니다.
'[Cloud] > [Kubernetes]' 카테고리의 다른 글
[Kubernetes] 쿠버네티스 서비스 - 3. 로드밸런서(LoadBalancer) (0) | 2024.05.29 |
---|---|
[Kubernetes] 쿠버네티스 서비스 - 2. 클러스터ip(ClusterIP) (0) | 2024.05.28 |
[Kubenetes] 쿠버네티스 업데이트 & 롤백 2 (0) | 2024.05.25 |
[Kubernetes] 쿠버네티스 업데이트 & 롤백 (0) | 2024.05.24 |
[Kubernetes] deployment 기본 (0) | 2024.05.24 |