쿠버네티스 Service [1]

yoongyum·2022년 6월 5일
0
post-thumbnail

♾️Service

Service 리소스는 쿠버네티스에서 네트워크를 담당합니다.

Pod리소스 자체에서도 IP를 할당받아서 자체적으로 네트워크 통신을 할 수 있는데 굳이 Service리소스를 사용하여 네트워크 통신을 하는 이유는 Pod리소스는 불안정한 자원으로 여기기 때문입니다.

Pod는 필요할때 생성하고 필요가 없어지면 쉽게 삭제할 수 있는 리소스입니다.

Pod의 IP를 사용하여 서비스를 호출하게 되면 사용자는 서비스의 끝점의 이상 여부와 바뀐IP를 계속 추적해야합니다. 따라서 Pod의 생명주기와 상관없이 안정적으로 서비스 EndPoint를 제공하는 Service리소스를 사용합니다.

Service리소스는 Pod앞단에서 클라이언트의 요청을 Pod로 전달하는 Reverse Proxy와 같은 역할을 수행합니다.

Pod가 변경되더라도 사용자 입장에서는 동일한 IP로 서비스에 접근할 수 있고 1개의 Pod가 죽더라도 멀쩡한 Pod로 트래픽을 전달하기 때문에 안정성과 가용성을 높히는 장점이 있습니다.

reverse proxy란?
앱서버 앞단에서 위치하며, 클라이언트가 서버를 요청할 때 리버스 프록시가 대신 받아서, 리버스 원래의 서버로부터 응답을 전달하는 대리 서버를 의미합니다. 서버를 직접 호출하는 것이 아니기 때문에 서버를 감춰 보안을 높이는 용도로 쓰입니다. ex) Nginx, Apache Web Server




🔎Service 탐색

Service리소스는 안정적인 IP뿐만 아니라, 서비스 탐색 기능을 수행하는 도메인 이름 기반의 서비스 끝점을 제공합니다.

사용자는 쿠버네티스 클러스터 내에서 Service리소스 이름 기반으로 DNS 참조가 가능합니다.
이를 통해서 myservice라는 이름의 Service리소스를 생성하면 사용자는 myservice라는 도메인 주소로 해당 service에 요청할 수 있습니다.


💡Service 생성 및 작동

myservice.yml

apiversion: v1
kind: Service
metadata:
	labels:
    	hello: world
    name: myservice
spec:
	ports:
    - port: 8080
      	protocol: TCP
      	targetPort: 80
    selector:
    	run: mynginx

spec properties에서 Service리소스의 고유 명세를 합니다.

-port: 해당 Service리소스의 포트를 정합니다.
targetPort: 트래픽을 전달할 컨테이너의 포트를 지정합니다.
-selector: 트래픽을 전달한 컨테이너의 라벨을 선택합니다.

Service의 트래픽을 전달한 Pod를 선택할때 라벨 셀렉터를 사용합니다.

단순히 Pod의 이름이나 IP로 하지 않는 이유는 쿠버네티스는 각 리소스의 관계를 느슨한 연결 관계로 표현하려고 합니다.

느슨한 연결 관계란 특정 리소스를 직접 참조하는 것이 아닌, 간접 참조한다는 의미입니다.

Service에서 Pod의 이름이나 IP로 참조하게 된다면 Pod 생명주기에 따라 매번 새로운 값을 등록하고 삭제 해야합니다.

하지만 라벨링 시스템으로 관계를 유지하면 특정 라벨을 갖고있는 Pod라면 트래픽을 전달할 수 있습니다.

Pod 또한 Service와 연결하기 위해서 라벨만 특정해준다면 쉽게 트래픽을 받을 수 있습니다.

get 명령을 통해 Service를 나열할 수 있습니다.

kubernetes Service는 쿠버네티스 API 서버로 트래픽을 전송하는 서비스 끝점(End Point)입니다.
쿠버네티스 설치 시 기본적으로 생성됩니다.

myservicemynginx의 IP를 비교해보면 서로 다른 고유 값을 할당받는 것을 확인할 수 있습니다.


1. Pod IP로 접근


2. Service IP로 접근

(포트번호도 붙여주셔야합니다.)


3. Service DNS로 접근

전부 동일한 mynginx서버 결과를 확인할 수 있습니다.


🪃DNS lookup

myservice의 IP주소를 확인하기 위해 DNS lookup을 수행해야합니다.

DNS lookup을 실행하려면 nslookup명령 패키지를 설치해야합니다.

$ kubectl exec client -- sh -c "apt-get update && apt-get install -y dnsutils"

마지막줄의 Address의 아이피가 myservice의 CLUSTER-IP와 동일한 것을 확인할 수 있습니다.

또한, Name을 보시면 myservice.default.svc.cluster.local로 나와있습니다.

이것은 Service리소스 전체 도메인 주소를 나타내는 것입니다.




🧩Service 도메인 주소 법칙

Service리소스의 도메인 포맷입니다.

<서비스 이름>.<네임스페이스>.svc.cluster.local

생략 규칙 예시

<서비스 이름>.<네임스페이스> = <서비스 이름>.<네임스페이스>.svc.cluster.local
<서비스 이름> = <서비스 이름>.<네임스페이스>.svc.cluster.local

예제 코드




✴️Cluster DNS 서버

쿠버네티스에는 DNS서버가 존재하기 때문에 Service 이름을 도메인 주소로 사용할 수 있습니다.

리눅스에서 DNS 서버 설정 파일인 /etc/resolv.conf를 확인해보겠습니다.

쿠버네티스의 모든 Pod들은 nameserver: 10.43.0.10로 DNS를 조회합니다.

kube-system의 네임스페이스의 Service리소스를 확인해보면 해당IP와 동일한 것을 확인할 수 있습니다.

kube-dns Service10.43.0.10의 주인입니다.
kube-dns가 포함하는 label들을 확인할 수 있습니다. 이 라벨 정보들로 매핑된 Pod가 어떤 것이 있는 지 알 수 있습니다.

k8s-app=kube-dns라벨로 Pod를 검색하면, coredns-xxx.. Pod가 조회됩니다.

coredns는 쿠버네티스에서 제공하는 클러스터 DNS서버입니다.

모든 Pod는 클러스터 내부, 외부 DNS 질의를 coredns를 통해서 수행합니다.

쿠버네티스 클러스터 안에서 자체적인 도메인 시스템을 갖을 수 있는 이유입니다.




다음 포스트에 이어서 Service 리소스를 알아보겠습니다.🖐️

0개의 댓글