쿠버네티스 서비스
쿠버네티스 서비스란
Pod는 IP가 랜덤하게 지정하되고 restart가 될때마다 변하기때문에 고정된 엔트포인트를 호출이 어렵다.
여러 pod를 운영할 때 Pod 간의 로드밸런싱을 지원해줘야하는데 , 서비스가 이런 역할을 한다.
서비스는 지정된 IP로 생성, 여러 Pod를 묶어 로드 밸런싱, 고유 DNS값을 가질 수 있게해준다.
서비스는 라벨 셀렉터를 이영하여 관리하고자 하는 Pod를 정의할 수 있다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
apiVersion: v1
kind: Service
metadata:
name: hello-node-svc
spec:
selector:
app: hello-node
ports:
- port: 80
protocol: TCP
targetPort: 8080
type: LoadBalancer
|
멀티 포트 지원
동시에 하나의 포트 뿐 아니라 여러개의 포트를 동시에 지원할 수 있다. http,https포트를 예로 정의하자면
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
apiVersion: v1
kind: Service
metadata:
name: hello-node-svc
spec:
selector:
app: hello-node
ports:
- name: http
port: 80
protocol: TCP
targetPort: 8080
- name: https
port: 443
protocol: TCP
targetPort: 8082
type: LoadBalancer
|
로드밸런싱 알고리즘
pod들에 부하를 분산할때 디폴트 알고리즘은 pod간에 랜덤으로 부하하도록 한다.
특정 클라이언트가 특정 pod로 지속적으로 열결이 되게 하려면 Session Affinity를 사용하면된다.
spec에 sessionAffinity: Client 로 설정
1 2 3 4 5 6 7 8 9 |
apiVersion: v1
kind: Service
spec:
sessionAffinity:ClientIP
|
웹에서 http session을 사용하는 경우와 같이 각 서버와 각 클라이언트의 상태정보가 저장되어 있는 경우에는 유용하게 사용가능하다.
Server Type
서비스 IP 주소 할방방식과 연동 서비스등에 따라 구분한다.
Cluster IP : 디폴트 설정으로, 서비스에서 내부Ip를 할당한다. 쿠버네티스 클러스터 내에는 이 서비스에 접근이 가능하지마느 클러스터 외부에서는 외부IP할당을 받지 못 했기 때문에 접근이 불가하다.
Load Balancer : 클라우드 벤더에서 제공하는 설정 방식으로 외부ip를 가지고 있는 로드벨런서를 할당한다. 외부 IP를 가지고 있기 때문에 클러스터 외부에서 접근 가능하다.
Node Ip : 클러스터 IP로만 접근이 가능한 것이 아니라 모든 노드의 IP와 포트를 통해서 접근이 가능하게된다 .
hello-node-svc라는 서비스를 NodePort 타입으로 선언을하고 nodeport를 33036으로 설정하면 설정에따라 IP 80포트로도 접근이 가능하지만 모든 노드의 33036포트로도 서비스가능하다
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
apiVersion: v1
kind: Service
metadata:
name: hello-node-svc
spec:
selector:
app: hello-node
type: NodePort
ports:
- name: http
port: 80
protocol: TCP
targetPort: 8080
nodePort: 33036
|
External name
외부서비스를 쿠버네티스 내부서비스에서 호줄하고자 할때 사용한다.
클러스터내의 pod들은 클러스터 IP를 가지고 있기 때문에 클러스터 IP대역 뱎의 서비스를 호출하고자하면 NAT설정등 복잡한 설정이 필요하다.
aws나 GCP같은 클라우드환경에서는 데이터베이스나 매니지드 서비스를 사용하고자 할 경우 쿠버네티스 클러스터 밖이기 때문에 호출시에 Externalname을 사용한다.
예를들면 exernalname 타입으로 설정하고 주소를 DNS로 asd.database.example.com로 설정해주면 asd는 들어오는 모든 요청은
asd.database.example.com으로 포워딩해준다.
1 2 3 4 5 6 7 8 9 |
kind: Service apiVersion: v1 metadata: name: my-service namespace: prod spec: type: ExternalName externalName: my.database.example.com
|
DNS가 아닌 직접 IP를 이용하는 방식
DNS를 이용하엿는데 DNS가 아닌 직접 IP를 이용하는 방법도 있다
ClusterIP을 한다
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
apiVersion: v1
kind: Service
metadata:
name: external-svc-nginx
spec:
ports:
- port: 80 |
이후 Endpoint를 별도로 지정해주면된다 .\
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
apiVersion: v1
kind: Endpoints
metadata:
name: external-svc-nginx
subsets:
- addresses:
- ip: 35.225.75.124
ports:
- port: 80 |
이때 서비스명과 서비스 endpoint의 이름을 동일하게 해야한다.
서비스명: external-svc-nginx
서비스 : 35.225.75.124:80
35.225.75.124:80 은 eginx 웹서버가 떠있는 외부 서비스이다.
Headless Service
서비스는 접근을 위해서 Cluster ip 또는 external IP를 지정받는다.
즉 서비스를 통해서 제공되는 기능들에 대한 엔트포인트를 쿠버네티스 서비스를 통해서 통제하는 개념인데, 마이크로 서비스 아키텍처에서는 기능 컴포넌트에대한 엔드포인트를 찾는 기능을 서비스 디스커버리라고하고 ㅡ 서비스의 위치를 등록해놓는 더비스 디스커버리 솔류션을 제공한다. etxc, hashcorp의 consul과 같은 솔루션이 대표적인 사레이다. 쿠버네티스 서비스를 통해서 마이크로 서비스 컴포넌트를 관리하는 것이 아니라 서비스 디스커버리 솔루션을 사용하기 때문에 서비스에 대한 IP주소가 필요하다. 이런 것을 지원하는 서비스를 headless service라하고 특징으로 clusterIP를 가지지 않는다. 단 DNS이름을 가지게 되는데 DNS의 이름을 lookup을해보면 서비스의 ip를 리턴하지않고 열결된 Pod들에 ip를 리턴하게된다.
확인 명령문
kubectl get pod //pod 확인
kubectl get pods --template='{{rang.items}}HostIP': :{{.status.HostIP}} PodIP: {{.status.podIP}}{{end}}{{"/n"}}' // pod 아피조회
headless service 만들기
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
apiVersion: v1
kind: Service
metadata:
name: hello-node-svc-headless
spec:
clusterIP: None
selector:
app: hello-node
ports:
- name: http
port: 80
protocol: TCP
targetPort: 8080 |
서비스 확인해보기
kubectl get svc
쿠버네티스 클러스터내의 다른 pod에서 nslookup으로 해당 서비스의 dns를 조히회보면
nslookup hello-node-svc-headless
파드의 아이피주소를 알아볼수잇다