-
pod는 클러스터 외부의 요청이나 클러스터 내부의 다른 파드의 요청에 응답해야한다.
-
pod가 다른 pod에서 제공하는 애플리케이션을 사용하기 위해서는 다른 pod를 찾을 수 있어야 한다.
-
정적 IP를 할당할수 없다. -> 서비스를 통해서 통신한다.
-
서비스는 IP를 가지고 있고 이름으로도 통신이 가능하다.
-
-
pod --------> service --------> pod
-
service에서 replicaset이나 replicationcontroller로 연결되는것이 아니라 pod에 연결된다.
-
-
service는 pod들과 연결이 되는데 서비스와 파드가 연결되면 Endpoint가 만들어진다.
-
label을 기준으로 통신한다.
1. 서비스 소개
- 서비스는 쿠버네티스 시스템에서 같은 애플리케이션을 실행하고 있는 컨트롤러의 파드 그룹에 단일 네트워크 진입점을 제공하는 리소스이다.
- 서비스에 부여된 IP는 해당 서비스가 종료될 때까지 변경되지 않는다.
- 서비스에 부여된 IP = pod에 접근할 유일한 주소
- 클라이언트는 서비스가 제공하는 고정 IP 및 포트를 통해 pod에 접근하게 된다.
- kubernetes service
- default namespace에 처음부터 항상 존재하던 서비스.
- 이 서비스는 쿠버네티스 아키텍처에서 살펴본 마스터의 API 서버(Kube-apiserver)로 접근할 수 있는 서비스이다.
2. 서비스 생성법
- 서비스 생성에는 두가지 방법이 있다.
- kubectl expose 명령을 이용하는 방법
- YAML 파일로 리소스를 생성하는 방법
1) 명령을 이용하는 방법
kubectl expose <CONTROLLER_TYPE> <CONTROLLER_NAME> [--type=<SVC_TYPE>] --name <SVC_NAME>
2) YAML 파일을 이용하는 방법
# myapp-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: myapp-svc
spec:
ports:
- port: 80
targetPort: 8080
selector:
app: myapp-rs
- type을 지정하지 않으면 clusterIP가 default
- service.spec.ports.port -> 클라이언트가 접근할 서비스의 노출 포트
- 해당 포트로 접근하면 서비스는 service.spec.ports.targetPort 필드에 지정된 파드의 서비스 포트로 포워딩
- service.spec.selector -> 서비스에 연결할 pod를 레이블 셀렉터를 이용하여 매칭한다.
- 서비스 생성
kubectl create -f myapp-svc.yaml
3. 서비스 및 엔드포인트 확인
1) 서비스 목록 확인
- 서비스 타입 : ClusterIP
- ClusterIP : 쿠버네티스 클러스터 내에서만 접근할 수 있는 타입.
- 클러스터 외부에서 접근할 때는 외부 IP(EXTERNAL-IP)를 사용해야한다.
2) endpoint 확인
- endpoint : 서비스의 레이블 셀렉터에 의해 연결된(포워딩할) 파드의 IP 목록.
- endpoint 이름은 서비스의 이름과 동일하다.
- 현재 app=myapp-rs 레이블을 가진 파드가 없기 때문에 엔드포인트 목록도 가지고 있지 않다.
- 서비스의 클러스터 IP로 접속하더라도 포워딩 할 파드가 없다.
4. pod 생성 및 endpoint 연결
- 해당되는 레이블을 가진 파드를 생성하면 서비스는 자동으로 엔드포인트를 추가한다.
- 나중에 파드가 추가되거나 제거되더라도 레이블 셀렉터에 의해 매칭되는 파드는 엔드포인트가 자동으로 추가 및 제거된다.
- 앞서 만든 myapp-rs.yaml 파일을 이용하여 파드를 생성. 해당 컨트롤러 및 파드는 app=myapp-rs 레이블을 사용한다.
kubectl create -f myapp-rs.yaml
- pod를 생성한 후 엔드포인트 다시 확인.
- pod의 목록과 엔드포인트 비교
- -o wide 옵션을 사용하여 파드에 할당된 IP를 확인할 수 있다.
5. 서비스 접근 테스트
- 클러스터 내의 서비스에 접근하기 위한 테스트용 파드를 생성해 서비스 접근을 확인kubectl run 명령을 이용하여 테스트용 파드를 실행.
- 파드의 이름 -> nettool
- 사용한 이미지 -> c1t1d0s7/network-multitool. 테스트를 위한 이미지
- --generator=run/v1 -> 파드만 생성. 이 옵션이 없으면 기본적으로 deployment object로 파드 생성.
- --rm=true -> 애플리케이션(여기서는 bash)이 종료되면 파드를 자동 삭제
- 파드를 실행 후 bash 쉘이 실행된다.
- curl 명령으로 서비스에 할당된 IP로 접근하면 기본적으로 부하분산이 이루어지며, 파드 그룹에 접근할 수 있다.
6. 서비스의 session affinity 구성
- 서비스 접근 테스트에서 특정한 하나의 클라이언트가 웹 요청을 할 때마다 부하분산을 통해 다른 파드로 연결되는 것을 확인하였다.
- 그러나 클라이언트 요청을 매번 똑같은 파드로 연결하고 싶은 경우나 그렇게 해야할 경우가 있다.
- 세션을 계속 유지해야할 때
# myapp-svc-session-affinity.yaml
apiVersion: v1
kind: Service
metadata:
name: myapp-svc-ses-aff
spec:
sessionAffinity: ClientIP
ports:
- port: 80
targetPort: 8080
selector:
app: myapp-rs
- service.spec.sessionAffinity 필드로 구성 가능.
- 속성 값으로None, ClientIP 두가지 종류가 있다.
- 기본값은 None
- None : 세션 어피니티 없음.
- ClientIP : 클라이언트의 IP를 확인해 같은 파드로 연결된다.
- ClientIP -> 쿠버네티스 클러스터의 프록시는 클라이언트의 IP를 확인하여 매번 같은 파드로 연결해 준다.
7. 서비스 다중 포트 구성
- 파드의 애플리케이션은 항상 하나의 포트로만 서비스 하는것이 아니다.
- 여러 포트를 사용하여 서비스를 할 수 있다.
- 파드의 서비스 포트가 다중 포트인 경우, 노출할 서비스 포트 역시 다중 포트로 구성할 수 있다.
# myapp-svc-multiport.yaml
apiVersion: v1
kind: Service
metadata:
name: myapp-svc-mp
spec:
ports:
- name: myapp-http
port: 80
targetPort: 8080
- name: myapp-https
port: 443
targetPort: 8443
selector:
app: myapp-rs
- 다중 포트를 설정할 때는 반드시 포트의 이름을 부여하야한다.
8. 포트 이름 참조
- 서비스 포트에 이름을 부여할 수 있다.
- pod나 pod를 생성하는 컨트롤러 -> pod 템플릿 -> 컨테이너 포트에도 이름을 부여할 수 있다.
- pod(컨테이너)의 포트 이름을 이용하여 서비스 생성 시 pod의 대상포트(targetPort)에 이름을 이용하여 연결할 수 있다.
- 이는 이름으로 참조 하기 때문에 pod의 포트 번호가 변경되더라도 포트 이름이 변경되지 않는다면 계속 연결이 가능하다.
1) 포트 이름을 사용한 레플리카셋 및 서비스 생성
- pod 및 컨트롤러에서 컨테이너의 포트에 이름을 부여하는 구성.
# myapp-rs-namedport.yaml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: myapp-rs-nport
spec:
replicas: 3
selector:
matchLabels:
app: myapp-rs-nport
template:
metadata:
labels:
app: myapp-rs-nport
spec:
containers:
- name: myapp
image: httpd
ports:
- name: port-http
containerPort: 8080
- 컨테이너의 8080 port에 port-http 라는 이름을 부여.
- 이름을 서비스 생성 시 참조할 수 있다.
- port 이름을 참조하는 서비스 구성
# myapp-svc-namedport.yaml
apiVersion: v1
kind: Service
metadata:
name: myapp-svc-nport
spec:
ports:
- name: port-http
port: 80
targetPort: port-http
selector:
app: myapp-rs-nport
- targetPort는 이름으로 지정하는게 best.
- 작성한 레플리카셋 컨트롤러와 서비스를 생성.
kubectl create -f myapp-rs-namedport.yaml -f myapp-svc-namedport.yaml
2) 오브젝트 확인
- 레플리카셋 컨트롤러 확인.
- endpoint 확인
- 8080 port를 참조하는 것을 확인할 수 있다.
- pod 목록 및 pod IP 확인.
3) port 변경 및 확인.
- kubectl edit 명령을 이용하여 레플리카셋의 포트를 8081로 변경해보자.
kubectl edit rs myapp-rs-nport
- 포트를 변경하고 난 후, 현재 동작중인 pod의 포트는 변경되지않으므로 기존의 파드를 삭제한다.
- 새로운 pod가 생성된 것을 확인
- endpoint 다시 확인.
'Containers > Kubernetes' 카테고리의 다른 글
클러스터 외부 서비스 - NodePort (0) | 2020.08.22 |
---|---|
5.2. Service 탐색 (1) | 2020.08.10 |
4.4. DaemonSet (0) | 2020.07.29 |
4.3. ReplicaSet (0) | 2020.07.28 |
4.2. Replication Controller (0) | 2020.07.24 |
댓글