0. Kubernetes Services
서비스란? 외부에서 쿠버네티스 클러스터에 접속하는 방법
기존 인프라에서 로드밸런서, 게이트웨이와 비슷한 역할을 맡아 여러 개의 파드의 새로운 IP를 기존에 제공하는 기능과 연결해
쿠버네티스 외부에서 내부로 접속할 때 내부가 어떤 구조로 되어 있는지, 파드가 살았는지 죽었는지 신경 쓰지 않아도 이를 논리적으로 연결하게 해주는 것.
즉 컨트롤러를 공부하면서 알 수 있듯이, 파드들은 동적, 반영속적(ephemeral)이다. 노드들을 옮기면서 실행되기도 하고, 파드 안의 IP가 변경되기도 한다. 이런 파드들을 서비스를 사용하면 파드가 클러스터 안 어디에 있든 고정 주소를 통해 접근할 수 있다.
서비스 타입
서비스 유형은 크게 4가지로 분류된다. Type 값과 그 동작은 다음과 같다.
1. ClusterIP
- 기본 서비스 타입으로, 클러스터 안에서만 사용 가능. 서비스를 클러스터-내부 IP에 노출시킨다.
- 클러스터 안 노드, 파드에서는 클러스터 IP를 이용해 서비스에 연결된 파드에 접근한다. (내부 리소스간에만 통신이 가능함)
- 때문에 외부에서 접근하려고 할 시 NodePort 또는 LoadBalancer 서비스 적용 필요
2. NodePort
- 서비스 하나에 모든 노드의 지정된 포트 할당함. 고정 포트 (NodePort)로 각 노드의 IP에 서비스를 노출시킨다.
- 외부에서 클러스터 안 파드로 접근할 때 사용할 수 있는 가장 간단한 방법. NodePort 서비스가 라우팅되는 ClusterIP 서비스가 자동으로 생성
예) node1:8080, node2:8080 노드 상관없이 지정된 포트번호만 사용하여 파드 접근 (<NodeIP>:<NodePort>)
파드가 node1에만 실행되어 있고 node2에는 실행되지 않았을 때 node2:8080으로 접근하면 node1에 실행된 파드로 연결됨.
- 1) 클러스터 외부에서 워커노드IP와 포트로 접속 요청 2) 워커노드는 요청을 NodePort로 전달 3) NodePort는 selector에 맵핑된 파드로 전달
3. LoadBalancer
- AWS& GCP 퍼블릭 클라우드 서비스, 오픈스택 같은 프라이빗 클라우드, 쿠버네티스를 지원하는 로드밸런서 장비에서 사용함.
- 클라우드에서 제공하는 로드밸런서와 파드를 연결 후 해당 로드벨런서의 IP를 이용해 외부에서 파드 접근할 수 있게 함.
- 외부 로드 밸런서가 라우팅되는 NodePort와 ClusterIP 서비스가 자동으로 생성된다.
4. ExternalName (kube-dns 1.7 이상이어야한다.)
- 클러스터 내부에서 외부로 접근할 때 사용.
- .spec.externalName 항목에 설정한 DNS 주소로 포워딩
- 어떤 종류의 프록시도 설정되어 있지 않다.
1. 서비스의 기본적인 설정
'''이 명세는 "my-service"라는 새로운 서비스 오브젝트를 생성하고,
app.kubernetes.io/name=MyApp 레이블을 가진 파드의 TCP 9376 포트를 대상으로 한다.'''
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
type: ClusterIP # default값
ClusterIP: #설정하지 않으면 자동으로 IP값이 할당됨
selector:
app.kubernetes.io/name: MyApp # 라벨이 app=MyApp 인 모든 포드는 이 서비스에 속한다.
ports:
- protocol: TCP #기본 프로토콜
port: 80 # 서비스가 사용할 포트
targetPort: 9376 # 서비스가 포워드할 포트
전체 서비스 흐름으로 보면 NodePort --> Port --> targetPort
- port : 서비스를 클러스터 안에서 지정된 포트를 통해 내부적으로 노출
- targetPort : 서비스 객체로 들어온 요청을 해당 Pod(deployment)로 전달할때 사용하는 포트
2. Pod- Service 통신(ClusterIP)
기본적으로 클러스터 내부에서 서로 통신할 수 있는 IP가지고 있기 때문에, 외부에서 바로 클러스터에 접근할수가 없다.
때문에 외부와 통신하기 위해 Kube-Proxy를 이용해야한다. (네트워크를 관리하는 방법은 공식문서 참고)
clusterIP 타입의 서비스를 만드는 설정
1) 셀럭터 포함된 형태
apiVersion: v1
kind: Service
metadata:
name: clusterio-service
spec:
type: ClusterIP
selector:
app: nginx-for-svc
ports:
- name: http
port: 80
targetPort: 80
protocol: TCP
2) 셀렉터 제외된 형태
서비스는 일반적으로 셀렉터를 이용하여 쿠버네티스 파드에 대한 접근을 추상화하지만, 셀렉터 대신 매칭되는(corresponding) 엔드포인트와 함께 사용되면 다른 종류의 백엔드도 추상화할 수 있으며, 여기에는 클러스터 외부에서 실행되는 것도 포함된다. 예시는 다음과 같다.
이 서비스에는 셀렉터가 없으므로, 해당 엔드포인트 오브젝트가 자동으로 생성되지 않는다. 엔드포인트 오브젝트를 수동으로 추가하여, 서비스를 실행 중인 네트워크 주소 및 포트에 서비스를 수동으로 매핑한다.
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
ports:
- protocol: TCP
port: 80
targetPort: 9376
apiVersion: v1
kind: Endpoints
metadata:
# 여기서의 이름은 서비스의 이름과 일치해야 한다.
name: my-service
subsets:
- addresses:
- ip: 192.0.2.42
ports:
- port: 9376
3. 외부 - Pod 통신
쿠버네티스 클러스터 내부에서만 파드를 이용하려고 쿠버네티스를 배우는건 아니니까... 서비스가 외부에서 액세스 가능하게 하는 방법에 대해 알아보자
- 워커 노드의 노드포트를 통해 노드포트 서비스로 이동 후 다시 파드로 보내는 방법
- NodePort
- 동일한 IP 주소로 여러 서비스를 노출시킬 수 있는 인그레스(Ingress) 리소스
- LoadBalancer
NodePort
사용하는 오브젝트 스펙은 다음과 같다.
- 기존 파드 구조에서 kind가 Service로 바뀌었고, spec에 컨테이너에 대한 정보가 없다.
- 접속에 필요한 네트워크 관련 정보(protocol, port, targetPort, nodePort)와 서비스의 type을 NodePort로 지정.
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
type: NodePort
selector:
app.kubernetes.io/name: MyApp
ports:
# 기본적으로 그리고 편의상 `targetPort` 는 `port` 필드와 동일한 값으로 설정된다.
- port: 80
targetPort: 80
# 선택적 필드
# 기본적으로 그리고 편의상 쿠버네티스 컨트롤 플레인은 포트 범위에서 할당한다(기본값: 30000-32767)
nodePort: 30007
인그레스(Ingress)
nodeport 서비스는 포트를 중복으로 사용할 수 없기 때문에 1개의 nodeport에 1개의 deployment만 적용된다.
그렇다면 여러개의 deployment가 있을 때 노드포트 개수도 같이 늘려야되는 것이 아닌, 인그레스를 사용하면 된다.
인그레스는 서비스 유형이 아니지만, 클러스터의 진입점 역할을 한다.
- 고유한 주소를 제공해 사용 목적에 따른 다른 응답 제공. 사용자가 접속하는 경로에 따라 다른 결과값을 보여줌
LoadBalancer
쿠버네티스에서 자체적으로 로드 밸런서를 제공하지는 않고, 클라우드 프로바이더에서 제공하는 로드 밸런서를 쓰게 된다.
그러면 쿠버네티스 클러스터에 로드밸런서 서비스가 생성돼 외부와 통신할 수 있는 IP(EXTERNAL-IP)가
부여되고, 외부와 통신할 수 있으며 부하도 분산된다.
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app.kubernetes.io/name: MyApp
ports:
- protocol: TCP
port: 80
targetPort: 9376
clusterIP: 10.0.171.239
type: LoadBalancer
status:
loadBalancer:
ingress:
- ip: 192.0.2.127
그렇다면 가상환경(온프레미스)에서는 로드밸런서를 사용 못하는 것일까?
- Kubeflow on Minikube에서는 아래와 같은 방법으로 MetalLB를 사용하지 않고, Minikube에서 지원하는 Addons 기능인 MetalLB를 사용할 수 있다.
4. ExternalName
서비스에 selector 대신 DNS name을 직접 명시하고자 할 때에 쓰인다.
예를 들면, 이 서비스 정의는 prod 네임 스페이스의 my-service 서비스를 my.database.example.com에 매핑한다.
apiVersion: v1
kind: Service
metadata:
name: my-service
namespace: prod
spec:
type: ExternalName
externalName: my.database.example.com
참고
'STUDY > Data Engineering' 카테고리의 다른 글
8. CKA udemy 강의 정리 - Section 2 [명령형 접근법/선언형 접근법] (0) | 2023.01.06 |
---|---|
7. CKA udemy 강의 정리 - Section 2 [Namespace] (1) | 2023.01.06 |
5. CKA udemy 강의 정리 - Section 2 [Deployment & kodekloud] (0) | 2023.01.05 |
4. CKA udemy 강의 정리 - Section 2 [ReplicaSet & kodekloud] (0) | 2023.01.05 |
3. CKA udemy 강의 정리 - Section 2 [kodekloud PODs] (0) | 2023.01.04 |