파드는 다음과 같은 문제를 가지고 있다.
이런 문제를 해결하기 위해서 사용하는 기능이 서비스
이다
쿠버네티스 서비스는 동일한 서비스를 제공하는 파드 그룹에 지속적인 단일 접점을 만들려고 할때 생성하는 리소스이다.
각 서비스는 서비스가 존재하는 동안 절대 바뀌지 않는 아이피 주소와 포트가 있다.
서비스를 생성하는 방법에는 2가지 방법이 있다.
https://kubernetes.io/ko/docs/tutorials/stateless-application/expose-external-ip-address/
kubectl expose deployment hello-world --type=LoadBalancer --name=my-service
kube-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: kubia
spec:
ports:
- port: 80
targetPort: 8080
selector:
app: kubia
kubectl apply -f kube-svc.yaml
이 서비스를 생성해보면 서비스에 Cluster IP
가 할당된 것을 볼수 있다.
Cluster IP
는 쿠버네티스 내부에서만 액세스 할 수 있는 아이피이다.
실행중인 컨테이너에 원격으로 통신 테스트를 해볼려면 일단 파드를 띄워주고
kube-pods.yaml
apiVersion: v1
kind: Pod
metadata:
name: kubia
labels:
app: kubia
spec:
containers:
- image: luksa/kubia
name: kubia
kubectl exec 로 통신 테스트를 해보자
위의 명령어를 그림으로 표현하면 다음과 같다. kubia 라는 파드에 10.98.167.164 라는 내부 클러스터 아이피로 접근하여 서비스가 로드벨런싱을 하여 파드로 접근 시키는 것이다.
이렇게 서비스는 임의의 파드로 연결을 전달하는데 서비스 프록시가 임의의 파드를 선택해 전송해서 위의 파드 3개중 어떤 파드에 갈지 모른다.
만약 특정 클라이언트의 모든 요청을 매번 같은 파드로 리다이렉션 하려면 sessionAffinity
옵션을 사용하면 된다.
apiVersion: v1
kind : Service
spec:
sessionAffinity : ClientIP
apiVersion: v1
kind: Service
metadata:
name: kubia
spec:
ports:
- name: http
port: 80
targetPort: 8080
- name: https:
port: 443
targetPort: 8443
selector:
app: kubia
apiVersion: v1
kind: Service
spec:
ports:
- name: http
port: 80
targetPort: http
- name: https
port: 443
targetPort: https
클라이언트 파드는 서비스 아이피와 서비스 포트를 어떻게 알수 있을까?
쿠버네티스는 클라이언트 파드가 서비스의 IP와 포트를 검색할 수 있는 기능을 제공한다.
주로 3가지 방법을 사용하는데 환경변수 검색, dns 검색, FQDN 이 있다.
kubectl exec {pod} env
지금까지의 방식은 클러스터 내에서 서비스가 통신하기 위한 방법들을 알아보았다. 하지만 우리가 흔히 아는 웹 화면은 외부에서 접근해야한다. 그렇게 쿠버네티스 내에서 외부로 서비스 노출을 하려면 어떻게 해야할까?
방법은 3가지이다
1) NodePort : 각 클러스터 노드는 노드 자체에서 포트를 열과 해당 포트로 수신된 트래픽을 서비스로 전달한다.
2) LoadBalaner : 클라우드 인프라에서 프로비저닝 된 로드밸런서로 서비스에 액세스
3) Ingress : 단일 IP 로 여러 서비스를 노출하는 인그레스 리소스를 만들기
가 있다. 각각의 방법에 대해 알아보자
서비스 yaml 파일을 type에 NodePort로 하고 30000 - 32767 포트를 지정해서 사용한다.