Post

Kubernetes FQDN 개념, 실습

FQDN 개념

FQDN(Fully Qualified Domain Name)은 네트워크에서 특정 호스트의 정확한 위치를 나타내는 도메인 이름입니다. Kubernetes 환경에서 FQDN은 서비스, 파드 등의 네트워크 식별자 역할을 합니다. FQDN은 CoreDNS가 해석하고 관리하며, 클라이언트가 FQDN을 요청하면 CoreDNS는 해당 도메인 이름을 IP 주소로 변환하여 클라이언트에 응답합니다.

Kubernetes에서 FQDN

Kubernetes 클러스터 내에서 서비스나 pod의 FQDN은 다름과 같은 형식을 가집니다.

  • 서비스: {서비스이름}.{namespace}.svc.cluster.local
  • Pod: {pod-ip-addr}.{namespace}.pod.cluster.local

예시

web-service라는 서비스가 apps 네임스페이스에 있다면

  • FQDN: web-service.apps.svc.cluster.local

Pod의 IP 주소가 10.2.44.105이고 default 네임스페이스에 있다면

  • FQDN: 10-2-44-105.default.pod.cluster.local

실습

실습은 a, b 네임스페이스를 생성하고, 해당 네임스페이스에 속한 Pod가 FQDN을 기반으로 다른 네임스페이스의 Pod나 Service에 연결을 확인하는 절차로 진행하겠습니다.

1. a, b namespace 생성하기

1
2
3
4
5
6
7
8
9
10
11
12
13
❯ kubectl create namespace a
namespace/a created

❯ kubectl create namespace b
namespace/b created

❯ kubectl get namespaces
NAME              STATUS   AGE
a                 Active   8s
b                 Active   6s
default           Active   33h
...
...

2. a, b namespace에 pod, service 생성하기

이미지는 nginx:latest를 사용했으며 initContainer를 사용해 /mnt 볼륨에 index.html을 생성한 뒤 해당 볼륨을 nginx의 Document Root 폴더인 /usr/share/nginx/html에 마운드 해주었습니다. 또한 해당 pod를 외부에 노출 시킬 필요가 없기 때문에 ClusterIP Type의 서비스를 생성했습니다. nginx의 index.html을 수정하거나 추가하는 작업은 initContainer를 사용하지 않고, command만 사용해도 가능합니다.

a - pod, service definition

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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
  namespace: a
  labels:
    app: nginx
spec:
  containers:
  - name: nginx
    image: nginx:latest
    ports:
    - containerPort: 80
    volumeMounts:
    - name: html-volume
      mountPath: /usr/share/nginx/html
  volumes:
  - name: html-volume
    emptyDir: {}
  initContainers:
  - name: init-nginx
    image: busybox
    command: ['sh', '-c', 'echo "this is a namespace nginx" > /mnt/index.html']
    volumeMounts:
    - name: html-volume
      mountPath: /mnt
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
  namespace: a
spec:
  type: ClusterIP
  selector:
    app: nginx
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80

b - pod, service definition

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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
  namespace: b
  labels:
    app: nginx
spec:
  containers:
  - name: nginx
    image: nginx:latest
    ports:
    - containerPort: 80
    volumeMounts:
    - name: html-volume
      mountPath: /usr/share/nginx/html
  volumes:
  - name: html-volume
    emptyDir: {}
  initContainers:
  - name: init-nginx
    image: busybox
    command: ['sh', '-c', 'echo "this is b namespace nginx" > /mnt/index.html']
    volumeMounts:
    - name: html-volume
      mountPath: /mnt
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
  namespace: b
spec:
  type: ClusterIP
  selector:
    app: nginx
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80

a, b pod, service 생성 및 확인

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
❯ kubectl create -f a-pod-service.yaml
pod/nginx-pod created
service/nginx-service created

❯ kubectl create -f b-pod-service.yaml
pod/nginx-pod created
service/nginx-service created

❯ kubectl get pods,svc -n a
NAME            READY   STATUS    RESTARTS   AGE
pod/nginx-pod   1/1     Running   0          17s

❯ kubectl get pods,svc -n a -o wide
NAME            READY   STATUS    RESTARTS   AGE   IP           NODE     NOMINATED NODE   READINESS GATES
pod/nginx-pod   1/1     Running   0          75s   10.1.14.26   kkamji   <none>           <none>

NAME                    TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE   SELECTOR
service/nginx-service   ClusterIP   10.152.183.179   <none>        80/TCP    75s   app=nginx

❯ kubectl get pods,svc -n b -o wide
NAME            READY   STATUS    RESTARTS   AGE   IP           NODE     NOMINATED NODE   READINESS GATES
pod/nginx-pod   1/1     Running   0          78s   10.1.14.27   kkamji   <none>           <none>

NAME                    TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE   SELECTOR
service/nginx-service   ClusterIP   10.152.183.207   <none>        80/TCP    78s   app=nginx

3. 연결 테스트

각각의 네임스페이스에 존재하는 nginx pod의 터미널에 접속해서 curl 명령어를 사용해 테스트 했습니다. 다른 네임스페이스에 존재하는 Service와 Pod에 FQDN 형식으로 접근이 가능한 것을 확인할 수 있습니다.

FQDN을 통해 a namespace에서 b namespace로 접근

1
2
3
4
5
6
❯ k exec -itn a nginx-pod -c nginx -- sh
# curl nginx-service.b.svc.cluster.local
this is b namespace nginx
# curl 10-1-14-27.b.pod.cluster.local
this is b namespace nginx
# exit

FQDN을 통해 b namespace에서 a namespace로 연결

1
2
3
4
5
❯ k exec -itn b nginx-pod -c nginx -- sh
# curl nginx-service.a.svc.cluster.local
this is a namespace nginx
# curl 10-1-14-26.a.pod.cluster.local
this is a namespace nginx

결론

이번 실습에서는 Kubernetes 클러스터 내에서 FQDN(Fully Qualified Domain Name)이 어떻게 사용되는지 살펴보았습니다. FQDN을 이용하여 서로 다른 네임스페이스에 있는 서비스와 파드 간 통신을 원할하게 할 수 있습니다.


궁금하신 점이나 추가해야 할 부분은 댓글이나 아래의 링크를 통해 문의해주세요.
Written with KKam._.Ji

This post is licensed under CC BY 4.0 by the author.