우리는 이제 Deployments를 사용해서 팟을 업그레이드하고싶을때 문제없이 roll out 할 수 있고, Replica sets을 사용해서 팟 하나가 죽어도 새로운 팟이 뜨도록 할 수 있습니다. 하지만 각각의 컨테이너는 서로 다른 IP 주소를 갖고 있다는것을 다시 떠올려 보세요. 팟에 접근하기 위해서는 정확한 IP주소가 필요한데 팟이 교체될때마다 접속할 IP 주소를 확인해야합니다. 이 포스트는 이러한 문제를 해결하기 위해 만들어진 쿠버네티스 Services 에 대해 다룰 예정입니다. 이 문서를 다 보고 난후에는 우리는 드디어 우리 팟중 한 녀석에 접근하게 될 것입니다.
이론
넓은 의미에서 쿠버네티스의 Services는 여러 팟들을 하나로 묶고, 그것들에 접근할 수 있는 엔드 포인트를 제공한다고 할 수 있습니다. 자동으로 어느 서버로 로드 밸런싱 되어야 하는지 알고있는 로드 밸런서와 같다고 생각할 수 있습니다. 팟들은 우리의 조작이 없을 때도 만들어지고 제거될 수 있기 때문에, 항상 그것들에 안정적으로 접근할 수 있는 하나의 IP 주소가 필요합니다. Services는 팟의 묶음을 추상화해서 그것들에 접근할 수 있는 정적인 자원을 제공합니다.
Services 가 팟들 앞에서 들어오는 요청을 분배한다는 사실을 이해하기 어렵지는 않을 것입니다. 하지만 Service에 팟을 어떻게 연결하는지는 궁금할 수 있습니다. 우리 클러스터에는 무슨이유에서든 동작하고 있는 팟이 있을것이고, 그 팟들에 어떻게든 서비스를 연결해야 할 것입니다. Labels 라는 멋진 스펙이 그것을 도와줍니다. 이전 포스트에 관심을 좀 기울였다면 우리 팟에 이미 Labels 가 있었다는 사실을 알 수 있을 겁니다. Labels는 우리 오브젝트에 메타데이터를 제공하는 키벨류 쌍 혹은 태그입니다. 쿠버네티스 Service는 label selector를 통해 엔드포인트로 제공할 팟을 선정합니다. 아주 깔끔한 구조입니다.
아래의 다이어그램을 봅시다. 두개의 팟을 연결하고 있는 하나의 서비스가 있습니다. 두개의 팟은 app: nginx라는 이름의 라벨을 가지고 있습니다. 서비스는 그와 같은 라벨을 찾는 label selector를 가지고 있습니다. 팟들의 주소가 변경될 지라도 라벨만 제대로 달려있다면 고정된 주소로 유지되는 Service가 그 친구들에게 보내야 되는 요청을 잘 전달해 줄것입니다.
Pod 3이 다른 라벨을 가지고 있다는 사실을 알아챌 수 있을 것 입니다. Service 1은 Pod 3으로 연결해주지 않을 것이기 때문에 우리는 그 녀석으로 연결할 다른 Service가 필요합니다. 이제 우리는 Service를 nginx 팟에 연결할 것입니다. 하지만 많은 앱들은 여러개의 계층을 가지고 있다는 사실을 기억해주세요. 웹은 앱에게 물어보고 앱은 데이터베이스에게 물어봅니다. 이런 상황에서 이 3개의 계층은 팟의 상태와 상관없이 다른 친구들과 잘 소통하기 위해 일관성있는 Service를 필요로 할 겁니다.
Services는 kube-proxy를 통해서 뒷단의 팟에게 요청을 보낼 수 있습니다. 쿠버네티스 클러스터의 모든 노드들은 kube-proxy라고 불리는 프록시를 가지고 있습니다. 이 프록시는 Services 와 Endpoints 에 대한 마스터노드의 API를 받습니다. 새로운 service가 나타나면 kube-proxy는 자신이 속한 노드에 랜덤한 포트를 개방합니다. 이 포트는 백엔드 포트에 대한 연결을 프록시 하게 됩니다.
실전
우리 모두 클러스터가 진짜로 잘 동작하는지 아닌지 궁금해하고 있습니다. 이전 포스트에서 했었던 것처럼 우리 deployment 매니페스트를 배포해봅시다. 그리고 service 하나를 그 deployment에 연결할 겁니다. 모두 끝나면 브라우저 웹페이지에서 연결이 되는지 확인해봅시다.
새로운 매니페스트 파일을 만들고 쿠버네티스 클러스터에 배포하는 것으로 시작해봅시다. 한 파일 아래 Deployment 와 Service 2개의 오브젝트가 있습니다.
apiVersion: apps/v1 #사용하는 API 버젼
kind: Deployment #배포하려는 오브젝트의 종류
metadata: #배포하려는 오브젝트의 정보
name: nginx-deployment #deployment의 이름
labels: #만들어진 deployments의 태그
app: nginx
spec: #오브젝트의 명세
replicas: 2 #항상 떠있어야하는 팟의 갯수
selector: #replica set이 책임질 팟이 무엇인가
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 #서비스의 이름
spec: #오브젝트의 명세
type: NodePort #여기선 무시하자 다음에 가르쳐줌
ports: #여기선 무시하자 다음에 가르쳐줌
- name: http
port: 80
targetPort: 80
nodePort: 30001
protocol: TCP
selector: #팟을 식별하기위한 라벨 셀렉터
app: nginx
이 시점에서 아주 익숙한 커맨드를 통해 이걸 배포해야합니다.
kubectl apply -f [manifest file].yml
매니페스트가 배포된 이후에는 예전처럼 pod과 replica sets, deployments을 볼 수 있고 services도 돌고 있는걸 확인 할 수 있습니다.
kubectl get services
훌륭합니다. 이제 우리는 매니페스트 파일에서 정의한대로 ingress-nginx라는 이름의 서비스를 가지게 되었습니다. Kubernetes Service도 있지만 지금은 무시합니다. 그냥 이게 클러스터를 위해 필요한거라고만 알아두세요. ingress-nginx의 포트는 80:30001/TCP 로 확인됩니다. 이것도 나중에 다룰겁니다. 하지만 중요한 것은 : 뒤에있는 포트번호가 우리가 접속할 서비스의 포트라는 점입니다.
이제 진짜로 테스트를 해봅시다. 웹 브라우저를 열어서 우리 쿠버네티스 노드의 주소로 30001 번 포트를 통해 연결해 봅시다. nginx 페이지를 확인 할수 있습니다.
요약
결과는 그렇게 까지 흥미진진하지는 않았습니다. 우리는 그렇게 놀랍지는 않은 기본적인 nginx welcome 페이지를 갖게 되었습니다. 하지만 우리는 그동안 배워왔던 팟과 라벨 서비스를 통해 드디어 쿠버네티스 클러스터의 앱에 접근할 수 있었습니다. 다음 페이지에서는 쿠버네티스에 더 깊숙히 들어가 보려고합니다. 채널 고정!
'컴퓨터 > Getting Started With Kubernetes' 카테고리의 다른 글
Endpoints (0) | 2019.12.25 |
---|---|
Deployments (3) | 2019.12.18 |
Replica Sets (0) | 2019.12.11 |
Pods (0) | 2019.12.05 |
Introduce (0) | 2019.12.04 |