쿠버네티스 클러스터를 쓰고 있는사람들은 Endpoints가 뭔지 어떻게 동작하는지 몰라도 그걸 뒤에서 쓰고 있습니다. 이 포스트에선 Endpoints를 직접사용하거나 문제가 발생할때 필요한 경우에 대비하여 쿠버네티스의 endpoints에 대해 다루어 볼 예정입니다.
이론
쿠버네티스의 Services에 대해서 처음 다룬 포스트에서 이야기 했듯, 뒷단의 pod의 label을 사용해서 selector가 자동적으로 앞단의 service에 매칭한다는 사실을 알고 있을 것입니다. 만약 새로운 팟들이 해당하는 label을 달게 되었다면, service는 트래픽을 그 팟으로 보내는 방법을 알게 됩니다. 이러한 매핑을 endpoint에 추가하는 것으로 service가 이러한 일들을 할 수 있는 것 입니다. Endpoints는 service가 트래픽을 보낼 오브직트의 IP주소를 추적합니다. service의 selector가 pod의 라벨을 매칭시켰다면, 그 IP 주소가 당신의 endpoints들에 추가됩니다. 필요한 service 가 이것뿐이라면, 우리가 endpoints에 대해서 해야할 일은 별로 없습니다. 하지만 클러스터의 바깥이나 다른 namespace(아직 다루진 않았지만)에 service를 연결해야 하는 경우도 있습니다.
service는 endpoints를 통해 트래픽을 보내는 주소의 목록을 관리합니다. endpoints는 labels와 selectors를 통해 자동으로 업데이트 될 수 있습니다. 그리고 경우에 따라 수동으로 endpoints를 설정할 수 있습니다.
실전
이전 매니페스트에서 우리가 사용했던 endpoints를 살펴봅시다. 이전 포스트에서 우리가 했던 매니페스트를 배포하고 endpoints들이 무엇을 하는지 살펴보도록 합시다.
apiVersion: apps/v1 #사용할 API 버젼
kind: Deployment #우리가 배포할 오브젝트의 종류
metadata: #배포할 오브젝트의 정보
name: nginx-deployment #deployment의 이름
labels: #deployment의 태ㄱㄱ
app: nginx
spec: #배포할 오브젝트의 명세
replicas: 2 #항상 떠있을 팟의 개수
selector: #어떤 팟을 항상 떠 있게 할 것인지
matchLabels:
app: nginx #이것과 매칭되는 라벨을 소유한 팟을 책임진다
template: #배포할 팟의 템플릿
metadata:
labels: #팟의 라벨
app: nginx
spec:
containers:
- name: nginx-container #팟에 들어갈 컨테이너의 이름
image: nginx #컨테이너로 받아올 이미지
ports:
- containerPort: 80 #팟에서 이 컨테이너가 사용할 포트번호
---
apiVersion: v1 #사용할 API 버젼
kind: Service #우리가 배포할 오브젝트의 종류
metadata: #배포할 오브젝트의 정보
name: ingress-nginx #service의 이름
spec: #배포할 오브젝트의 명세
type: NodePort #나중에 다룰예정 무시할 것
ports: #나중에 다룰예정 무시할 것
- name: http
port: 80
targetPort: 80
nodePort: 30001
protocol: TCP
selector: #팟을 구분할 셀렉터
app: nginx
이 매니페스트를 배포합시다.
kubectl apply -f [manifest file].yml
service selector가 팟의 label에 매칭되면 endpoints가 자동으로 만들어지는 것을 볼 수 있을 것 입니다. kubectl을 통해 endpoints를 조회할 수 있습니다.
kubectl get endpoints
당신의 결과창은 이것과 다른 주소를 가지겠지만, 참고용으로 여기 엔드포인트 조회 결과를 보여드리겠습니다.
우리가 봐야하는 것은 ingress-nginx입니다. 두개의 endpoints를 가지고 있으며 모두 80 포트라는것을 확인 할 수 있습니다. 이 endpoint들은 매니페스트로 배포한 pod들의 ip 주소여야 합니다. 이것을 확인하기위해 get pods 커맨드를 -o wide 옵션과 함께 확인해보도록 합시다.
kubectl get pods -o wide
팟의 IP 주소들이 엔드포인트의 주소들과 매칭된다는 것을 확인할 수 있습니다. 보이지 않는 곳에서 endpoints가 매칭된다는 사실을 확인했습니다.
selector가 없는 경우 endpoints를 수동으로 수정하려면 어떻게 해야될까요? 쿠버네티스 클러스터에 없는 외부의 서비스에 접근할 수 있는 자원이 필요할지도 모릅니다. 이를 위한 자체 endpoint를 만들 수 있습니다. web 혹은 app 컨테이너가 사용할 외부 database service가 좋은 예 입니다.
endpoint를 사용해서 컨테이너에서 외부 리소스에 접근하는 예시를 살펴보겠습니다. 이 예시에서는 테스트만을 위한 간단한 웹페이지에 접근할 것입니다. 참고로 저는 제 노트북으로 이 서비스에 접근해서 작동하는지 확인했습니다. 당신의 실험실에서 이 작업을 수행하려면, 웹서버를 가동하고 그에 맞는 IP 주소로 수정해줘야 합니다.
그렇게 흥미로운 결과가 아니라는것은 알고 있습니다. 하지만 그 일을 끝내야 넘어갈 수 있습니다. 다음엔 selector가 없는 service와 endpoint를 배포할 것입니다. 다음 매니페스트가 그 일을 수행합니다. IP 주소와 사용된 포트번호를 endpoint 명세에서 확인하세요.
kind: "Service"
apiVersion: "v1"
metadata:
name: "external-web"
spec:
ports:
-
name: "apache"
protocol: "TCP"
port: 80
targetPort: 80
---
kind: "Endpoints"
apiVersion: "v1"
metadata:
name: "external-web"
subsets:
-
addresses:
-
ip: "10.10.50.53" #외부 web server의 ip 주소
ports:
-
port: 80
name: "apache"
service와 endpoint를 얻기 위해 매니페스트를 배포합시다.
kubectl apply -f [manifest file]
endpoint가 제대로 동작하는지 확인해봅시다.
kubectl apply -f [manifest file]
service와 endpoint가 배포되고 난 다음 클러스터안에 작은 컨테이너를 배포할 것 입니다. 우리는 그것을 웹페이지에 curl을 하는 테스트 용도로 사용할 것 입니다. 이번엔 매니페스트 파일 대신 명령형 command를 사용할 것 입니다.
kubectl create -f https://k8s.io/examples/application/shell-demo.yaml
kubectl exec -it shell-demo -- /bin/bash
apt-get update
apt-get install curl
curl external-web
external-web으로 요청한 curl 명령이 잘 동작합니다. external-web endpoint가 잘 동작한다는 것을 알 수 있습니다.
정리
이 시리즈를 따라오는 사람들은 몰랐을뿐, 이미 endpoints를 사용하고 있었습니다. 만약 데이터베이스 등의 외부 서비스에 접근해야되는 경우 수동으로 자체 endpoint를 추가할 수 있습니다. 하지만 당장은 endpoints가 존재하고 필요한 경우 수정할 수 있다는 사실만 알고 있어도 충분합니다.
'컴퓨터 > Getting Started With Kubernetes' 카테고리의 다른 글
Services and Labels (0) | 2019.12.19 |
---|---|
Deployments (3) | 2019.12.18 |
Replica Sets (0) | 2019.12.11 |
Pods (0) | 2019.12.05 |
Introduce (0) | 2019.12.04 |