본문 바로가기

About/Kubernetes

[k8s] Service - ExternalName 사용하기

쿠버네티스에서 ExternalName 유형의 서비스는 일반적인 셀렉터에 대한 서비스가 아니라 DNS 이름에 대한 서비스에 매핑합니다.

 

ExternalName 서비스 생성

다음은 ExternalName 타입의 서비스를 설정하는 예시 입니다.

1
2
3
4
5
6
7
8
# externalname.yaml
apiVersion: v1
kind: Service
metadata: 
  name: externalname1
spec:
  type: ExternalName 
  externalName: google.com
cs

6번 라인에서 .spec.type을 ExternaName으로 지정했으며, .spec.externalName 필드를 google.com으로 설정하였습니다. 연결할려는 외부 도메인 값을 설정한 것입니다.

externalname.yaml로 저장하고 kubectl apply -f externalname.yaml 명령어로 클러스터에 적용합니다. 그 후 kubectl get svc 명령어를 실행해 서비스의 상태를 확인합니다.

1
2
3
4
5
6
7
[root@k8s-master jh]# kubectl apply -f exernalname.yaml 
service/externalname1 created
[root@k8s-master jh]# kubectl get svc
NAME            TYPE           CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
externalname1   ExternalName   <none>       google.com    <none>    2m28s
kubernetes      ClusterIP      10.96.0.1    <none>        443/TCP   27m
 
cs

externalname1이라는 서비스가 만들어진 것을 확인할 수 있으며 이 서비스의 TYPEExternalName입니다. 클러스터 안에서 IPPORT를 사용하지 않기 때문에 해당 항목은 <none>입니다.

EXTERNAL-IP 항목은 위에서 설정한 google.com입니다.

ExternalName 서비스 동작 확인

우선 파드를 하나 생성합니다. nicolaka/netshoot 이미지를 사용하였는데, 다양한 네트워크 진단 툴을 제공하는 도커 이미지 입니다.

1
kubectl run -it --image nicolaka/netshoot testnet bash
cs

그리고 다음과 같이 ExternalName의 서비스 이름으로 curl 명령어를 실행합니다.

1
2
3
4
5
6
7
8
9
10
11
12
bash-5.1# curl externalname1
<!DOCTYPE html>
<html lang=en>
  <meta charset=utf-8>
  <meta name=viewport content="initial-scale=1, minimum-scale=1, width=device-width">
  <title>Error 404 (Not Found)!!1</title>
  <style>
    *{margin:0;padding:0}html,code{font:15px/22px arial,sans-serif}html{background:#fff;color:#222;padding:15px}body{margin:7% auto 0;max-width:390px;min-height:180px;padding:30px 0 15px}> body{background:url(//www.google.com/images/errors/robot.png) 100% 5px no-repeat;padding-right:205px}p{margin:11px 0 22px;overflow:hidden}ins{color:#777;text-decoration:none}a img{border:0}@media screen and (max-width:772px){body{background:none;margin-top:0;max-width:none;padding-right:0}}#logo{background:url(//www.google.com/images/branding/googlelogo/1x/googlelogo_color_150x54dp.png) no-repeat;margin-left:-5px}@media only screen and (min-resolution:192dpi){#logo{background:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) no-repeat 0% 0%/100% 100%;-moz-border-image:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) 0}}@media only screen and (-webkit-min-device-pixel-ratio:2){#logo{background:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) no-repeat;-webkit-background-size:100% 100%}}#logo{display:inline-block;height:54px;width:150px}
  </style>
  <a href=//www.google.com/><span id=logo aria-label=Google></span></a>
  <p><b>404.</b> <ins>That’s an error.</ins>
  <p>The requested URL <code>/</code> was not found on this server.  <ins>That’s all we know.</ins>
cs

externalname1으로 연결하면 자동으로 google.com의 HTML 마크업이 출력됩니다.(예제에서는 인터넷 게이트웨이가 없기 때문에 404 에러가 나옵니다.)

사실 현재 파드가 ExternalName 서비스와 같은 namespace에 존재하기 때문에 externalname1 이라는 이름으로 접근할 수 있었으며, 다른 namespace의 경우 해당 Domain의 풀네임인  externalname1.default.svc.cluster.local로 접근하여야 합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
bash-5.1# curl externalname1.default.svc.cluster.local
<!DOCTYPE html>
<html lang=en>
  <meta charset=utf-8>
  <meta name=viewport content="initial-scale=1, minimum-scale=1, width=device-width">
  <title>Error 404 (Not Found)!!1</title>
  <style>
    *{margin:0;padding:0}html,code{font:15px/22px arial,sans-serif}html{background:#fff;color:#222;padding:15px}body{margin:7% auto 0;max-width:390px;min-height:180px;padding:30px 0 15px}> body{background:url(//www.google.com/images/errors/robot.png) 100% 5px no-repeat;padding-right:205px}p{margin:11px 0 22px;overflow:hidden}ins{color:#777;text-decoration:none}a img{border:0}@media screen and (max-width:772px){body{background:none;margin-top:0;max-width:none;padding-right:0}}#logo{background:url(//www.google.com/images/branding/googlelogo/1x/googlelogo_color_150x54dp.png) no-repeat;margin-left:-5px}@media only screen and (min-resolution:192dpi){#logo{background:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) no-repeat 0% 0%/100% 100%;-moz-border-image:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) 0}}@media only screen and (-webkit-min-device-pixel-ratio:2){#logo{background:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) no-repeat;-webkit-background-size:100% 100%}}#logo{display:inline-block;height:54px;width:150px}
  </style>
  <a href=//www.google.com/><span id=logo aria-label=Google></span></a>
  <p><b>404.</b> <ins>That’s an error.</ins>
  <p>The requested URL <code>/</code> was not found on this server.  <ins>That’s all we know.</ins>
 
cs

이 때  externalname1.default.svc.cluster.local 를 살펴보면 다음과 같이 구성되어 있습니다.

위와 같은 규칙을 가지는 Domain Name을 FQDN(Fully Qualified Domain Name)이라고 합니다.

 externalname1.default.svc.cluster.local 로 요청이 이루어지는 구조는 다음과 같습니다.

이를 확인하기 위해 DNS의 설정이 올바른지 확인하는 dig 명령어를 실행해봅니다.

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
bash-5.1dig externalname1.default.svc.cluster.local
 
<<>> DiG 9.16.22 <<>> externalname1.default.svc.cluster.local
;; global options: +cmd
;; Got answer:
;; WARNING: .local is reserved for Multicast DNS
;; You are currently testing what happens when an mDNS query is leaked to DNS
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 5013
;; flags: qr aa rd; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available
 
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
; COOKIE: 33c1ab542b5e69c5 (echoed)
;; QUESTION SECTION:
;externalname1.default.svc.cluster.local. IN A
 
;; ANSWER SECTION:
externalname1.default.svc.cluster.local30 IN CNAME google.com.
google.com.        30    IN    A    172.217.31.174
 
;; Query time: 4 msec
;; SERVER: 10.96.0.10#53(10.96.0.10)
;; WHEN: Wed Jan 26 05:33:38 UTC 2022
;; MSG SIZE  rcvd: 169
 
cs

19번 줄에서 externalname1.default.svc.cluster.localCNAME은 google.com임을 알 수 있습니다.


쿠버네티스 서비스의 ExternalName에 대하여 알아보았습니다.

참고

https://kubernetes.io/ko/docs/concepts/services-networking/service/#externalname

 

서비스

파드 집합에서 실행중인 애플리케이션을 네트워크 서비스로 노출하는 추상화 방법 쿠버네티스를 사용하면 익숙하지 않은 서비스 디스커버리 메커니즘을 사용하기 위해 애플리케이션을 수정할

kubernetes.io

http://www.yes24.com/Product/Goods/85578606

 

쿠버네티스 입문 - YES24

현업의 운영 경험을 바탕으로 엄선한 쿠버네티스 입문 A~Z현재 다양한 인프라 구축의 핵심 기술은 컨테이너이다. 운영체제, 데이터베이스, 웹 서버 등 인프라 구축에 필요한 컨테이너 이미지 각

www.yes24.com