✔️ Service - ExternalName
클러스터 내부에서 클러스터 외부의 특정 서비스에 접속하기 위해 DNS CNAME을 설정한다.
vagrant@k8s-node1 ~/svc/exname kubectl explain svc.spec.type
"ExternalName"
aliases this service to the specified externalName. Several other fields do
not apply to ExternalName services. More info:
https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types
vagrant@k8s-node1 ~/svc/exname kubectl explain svc.spec.
externalName <string>
externalName is the external reference that discovery mechanisms will
return as an alias for this service (e.g. a DNS CNAME record). No proxying
will be involved. Must be a lowercase RFC-1123 hostname
(https://tools.ietf.org/html/rfc1123) and requires `type` to be
"ExternalName".
ExternalName
은 externalName
필드와 결합해서 작동한다.
weather-ext-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: weather-ext-svc
spec:
type: ExternalName
externalName: wttr.in
vagrant@k8s-node1 ~/svc/exname kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.233.0.1 <none> 443/TCP 18h
myweb-svc-lb LoadBalancer 10.233.47.233 192.168.100.240 80:31313/TCP 50m
weather-ext-svc ExternalName <none> wttr.in <none> 13s
ExternalName
의 EXTERNAL-IP
가 wttr.in
이며 CLUSTER-IP
와 PORT(S)
도 없다.
vagrant@k8s-node1 ~/svc/exname kubectl run nettool -it --image ghcr.io/c1t1d0s7/network-multitool --rm
If you don't see a command prompt, try pressing enter.
/ # host weather-ext-svc
weather-ext-svc.default.svc.cluster.local is an alias for wttr.in.
wttr.in has address 5.9.243.187
wttr.in mail is handled by 10 chub.in.
nettool을 띄워 DNS에 weather-ext-svc
서비스명으로 질의해보면 응답해준다.
/ # curl weather-ext-svc
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
/ #
웹 서버가 응답해준다.
/ # host -v weather-ext-svc
Trying "weather-ext-svc.default.svc.cluster.local"
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 36266
;; flags: qr aa rd; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;weather-ext-svc.default.svc.cluster.local. IN A
;; ANSWER SECTION:
weather-ext-svc.default.svc.cluster.local. 5 IN CNAME wttr.in.
wttr.in. 5 IN A 5.9.243.187
QUESTION SECTION
- DNS 서버에 질의한 내용weather-ext-svc.default.svc.cluster.local.
의 A 레코드는 무엇인가?
ANSWER SECTION
- 질의에 대한 응답weather-ext-svc.default.svc.cluster.local.
의 CNAME(별칭)은 wttr.in.
이며 wttr.in.
의 ip는 5.9.243.187이다.
Received 144 bytes from 169.254.25.10#53 in 11 ms
Trying "wttr.in"
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 52167
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 0
;; QUESTION SECTION:
;wttr.in. IN AAAA
;; AUTHORITY SECTION:
wttr.in. 30 IN SOA nsa3.srv53.net. support.dnshosting.org. 1647504680 1800 600 2419200 1800
바로 아래에 wttr.in
에 대한 질의와 응답을 해주는 것을 확인할 수 있다.
파드가 속한 쿠버네티스 클러스터 외부에 연결되어 있는 인터넷에 서비스가 있으며
파드가 항상 외부의 서비스를 참조(ex. weather)한다면 API를 호출할 때 path가 바뀌는 경우가 존재한다.
해당 주소(path)를 파드가 연결해야 하는데 파드에서 동작하는 코드 안에서 wttr.in ~ 주소를 참조해서 그 값을 가져와야 한다.
만약 주소를 wttr.in ~ 고정시켜버리면 외부의 주소가 바뀌었을 때 코드의 이미지를 다시 빌드해서 올려야한다.
그런 경우에 weather-ext-svc
라는 고정된 이름으로 사용하게 되면 파드의 어플리케이션에서 코드를 바꾸지 않고 weather-ext-svc
서비스를 요청하면 쿠버네티스의 coreDNS가 해당 이름을 리턴시킨다.
예를 들어 만약 나중에 서비스의 주소가 바뀌었다면
apiVersion: v1
kind: Service
metadata:
name: weather-ext-svc
spec:
type: ExternalName
externalName: www.google.com
다음과 같이 수정하고
vagrant@k8s-node1 ~/svc/exname kubectl replace -f weather-ext-svc.yaml
service/weather-ext-svc replaced
vagrant@k8s-node1 ~/svc/exname kubectl run nettool -it --image ghcr.io/c1t1d0s7/network-multitool --rm
If you don't see a command prompt, try pressing enter.
/ # host weather-ext-svc
weather-ext-svc.default.svc.cluster.local is an alias for www.google.com.
www.google.com has address 172.217.31.132
www.google.com has IPv6 address 2404:6800:4004:801::2004
host weather-ext-svc 로 질의하면 다시 www.google.com로 연결시킨다.
즉, 어플리케이션에서는 외부 서비스에 대한 코드를 변경시킬 필요없다.
또 다른 예로는 파드가 RDS를 사용한다고 하면 RDS DB에 접근하기 위한 엔드포인트 주소가 있다.
만약 엔드포인트 주소가 a.rds.com이라고 하면 파드가 해당 주소로 접근했을 때 RDS로 접근하게 된다.
만약 RDS를 교체했고 주소가 b.rds.com으로 변경됐다고하자 만약 파드에서 ExternalName
을 사용하지 않으면
코드 수준에서 a.rds.com
를 b.rds.com
로 변경해야 한다.
그렇게 하지 않고 RDS 라는 이름의 ExternalName
SVC를 만들어 놓으면 파드는 RDS 이름만을 바라보며
RDS는 처음에는 a.rds.com
이었다가 b.rds.com
로 바꿔 주기만 하면 된다.
결과적으로 파드는 RDS라는 이름으로만 매핑하면 외부의 다른 서비스의 경로를 바꿀 수 있게되는 것이다.
apiVersion: v1
kind: Service
metadata:
name: weather-ext-svc
spec:
type: ExternalName
externalName: www.naver.com
즉 externalName
을 www.google.com 에서 www.naver.com으로 변경한다면 SVC명은 weather-ext-svc
로 고정되지만 coreDNS에 canonical Name 형태로 지정된다.
vagrant@k8s-node1 ~/svc/exname kubectl replace -f weather-ext-svc.yaml
service/weather-ext-svc replaced
vagrant@k8s-node1 ~/svc/exname kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.233.0.1 <none> 443/TCP 18h
myweb-svc-lb LoadBalancer 10.233.47.233 192.168.100.240 80:31313/TCP 84m
weather-ext-svc ExternalName <none> www.naver.com <none> 34m
vagrant@k8s-node1 ~/svc/exname host weather-ext-svc
weather-ext-svc.default.svc.cluster.local is an alias for www.naver.com.
www.naver.com is an alias for www.naver.com.nheos.com.
www.naver.com.nheos.com has address 223.130.200.107
www.naver.com.nheos.com has address 223.130.195.200
이렇게 변경된다.
📌 그림으로 이해해보기
ExternalName이라는 Service를 만들 수 있고 이 안에 특정 외부 도메인 주소를 넣을 수 있다.
이미지처럼 google.com 이라는 구글 도메인 이름을 넣으면 DNS를 타고가서 외부망의 DNS Server에서 Google IP 주소를 가져올 수 있다.
Pod가 이 Service를 통해서 데이터를 가져오도록 해놓으면 추후 데이터를 Google → Github로 변경했을 경우 Pod의 수정없이 ExternalName의 이름만 변경해주면 된다.
✔️ 그외 추가적인 서비스들
✔️ 셀렉터가 없는 서비스
셀렉터를 지정하지 않으면 엔드포인트에 아무것도 없다.
그리고 우리가 엔드포인트를 직접 만든다.
apiVersion: v1
kind: Endpoints
metadata:
name: my-service
subsets:
- addresses:
- ip: 192.0.2.42 # 파드의 ip 지정
ports:
- port: 9376 # 접속 포트 지정
사용 이유는 SVC 자체만 만들고 SVC가 바라보는 백엔드가 파드가 아닌 다른 무언가일 때 사용한다. 다른 무언가는 ip와 port를 가진 무엇이든 가능하다.
이 SVC로 접근하면 지정한 ip와 port로 접속하도록 엔드포인트를 직접 지정한다.
✔️ 헤드리스 서비스
헤드리스(Headless) 서비스는 StatefulSet과 함께 사용한다.
결론적으로 StatefulSet
는 SVC의 ClusterIP
를 None이라고 설정한다.
✔️ 로드밸런서 NodePort 할당 비활성화
일반적으로 외부에 LB가 있고 노드에 NodePort가 열려야 하며 LB는 NodePort를 바라보고 있고 NodePort가 SVC로 SVC가 파드를 바라보는 형태를 띈다.
일부 퍼블릭 클라우드의 네트워크 타입에서는 LB가 있고 NodePort를 사용하지 않고 SVC를 직접 연결한다.
✔️ 외부 IP
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: MyApp
ports:
- name: http
protocol: TCP
port: 80
targetPort: 9376
externalIPs:
- 80.11.12.10
ClusterIP
타입의 SVC이며 외부로 노출되지 않는다.externalIPs
라고 하면 노드에 연결된 Switch가 있을 것이다.
만약 네트워크 대역이 80.11.12.0/24 이라면 그중에 사용하지 않는 ip(ex. 80.11.12.10)를 하나 지정하면 호스트가 해당 ip(80.11.12.10)를 가지게 된다.
그리고 그 ip로 접근하면 SVC로 연결시킨다. kube-proxy
에 의해 iptables에 세팅되기 때문이다.
NodePort
나 LoadBalancer
타입의 SVC를 만들지 않고 ClusterIP
타입의 서비스로 외부에 노출시킬 수 있기는 하다. 하지만 해당 ip(80.11.12.10) 자체를 쿠버네티스에서 관리해주지 않는다.
위험성이 존재하므로 선호되는 방법은 아니지만 NodePort
사용을 하지 못할 때 외부에서 포트를 치고 들어올 수 있는 방법이다.
AWS 같은 경우 ALB에서 ClusterIP SVC로 바로 연결하는 기능도 있다.
'DevOps > Kubernetes' 카테고리의 다른 글
[Kubernetes] Ingress Challenge (0) | 2022.05.29 |
---|---|
[Kubernetes] Ingress (인그레스) (0) | 2022.05.29 |
[Kubernetes] Service - LoadBalancer ( + METALLB : on-prem 환경의 LB) (0) | 2022.05.23 |
[Kubernetes] Service - NodePort (1) | 2022.05.23 |
[Kubernetes] Service - Service Discovery (2) (0) | 2022.05.21 |
영차영차 성장 블로그
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!