후니의 IT인프라 사전

1주차 - 쿠버네티스 주요 리소스(쿠버네티스 네트워크) 본문

프로젝트&&스터디/DOIK 스터디

1주차 - 쿠버네티스 주요 리소스(쿠버네티스 네트워크)

james_janghun 2022. 6. 24. 09:35

1. Service 개요

  - 기본적으로 pod를 생성하면 클러스터 내부에서만 소통이 가능합니다. pod를 외부로 노출시키려면 service를 이용해야합니다.

  - Cluster Type : 다수의 파드에 접속할 수 있는 Pod-LB역할을 하는 service를 생성합니다.

  - NodePort Type : 실제 외부 클라이언트가 클러스터 내부로 접속할 수 있도록 하는 서비스 입니다.

 

 

2. cluster IP 실습

- 목적지로 사용할 3개의 pod를 yaml로 생성합니다.

cat <<EOT> 3pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: webpod1
  labels:
    app: webpod
spec:
  nodeName: k8s-w1
  containers:
  - name: container
    image: traefik/whoami
  terminationGracePeriodSeconds: 0
---
apiVersion: v1
kind: Pod
metadata:
  name: webpod2
  labels:
    app: webpod
spec:
  nodeName: k8s-w2
  containers:
  - name: container
    image: traefik/whoami
  terminationGracePeriodSeconds: 0
---
apiVersion: v1
kind: Pod
metadata:
  name: webpod3
  labels:
    app: webpod
spec:
  nodeName: k8s-w3
  containers:
  - name: container
    image: traefik/whoami
  terminationGracePeriodSeconds: 0
EOT

- cluster IP로 사용할 클라이언트 TEST Pod를 생성합니다.

cat <<EOT> netpod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: net-pod
spec:
  nodeName: k8s-m
  containers:
  - name: netshoot-pod
    image: nicolaka/netshoot
    command: ["tail"]
    args: ["-f", "/dev/null"]
  terminationGracePeriodSeconds: 0
EOT

- 총 4개의 pod를 생성했습니다.

- 이제 pod 생성이 완료되면 service를 통해서 clusterIP를 생성하고, 해당 IP를 통해서 pod를 호출할 수 있는 service를 생성합니다.

cat <<EOT> svc-clusterip.yaml
apiVersion: v1
kind: Service
metadata:
  name: svc-clusterip
spec:
  ports:
    - name: svc-webport
      port: 9000
      targetPort: 80
  selector:
    app: webpod
  type: ClusterIP
EOT

 

- 이제 실제로 net-pod에 고루 잘 호출되는지 service IP를 호출해보겠습니다.

# 해당 파드를 호출하기 편하도록 변수지정
POD1=$(kubectl get pod webpod1 -o jsonpath={.status.podIP})
POD2=$(kubectl get pod webpod2 -o jsonpath={.status.podIP})
POD3=$(kubectl get pod webpod3 -o jsonpath={.status.podIP})
SVC1=$(kubectl get svc svc-clusterip -o jsonpath={.spec.clusterIP})


# svc에 1개의 요청보내기
kubectl exec -it net-pod -- curl -s $SVC1:9000

# 100번의 요청 결과 받기
kubectl exec -it net-pod -- bash -c "for i in {1..100}; do curl -s $SVC1:9000 | grep Hostname; done | sort | uniq -c | sort -nr"


# 100번 1초에 한번씩 호출하면서 결과받기 (호스트 네임만)
kubectl exec -it net-pod -- bash -c "for i in {1..100}; do curl -s $SVC1:9000 | grep Hostname; sleep 1 ; done"

일단 clusterIP의 서비스와 서비스 endpoint 정보를 호출하여 확인합니다.

clusterIP는 10.200.1.252:9000으로 호출이 가능합니다.

그리고 172.16.1.4:80은 pod2 / 172.16.2.6:80은 pod1 / 172.16.3.3:80은 pod3입니다.

일단 1개의 요청만 테스트 해보겠습니다.

저의 경우는 webpod3가 먼저 응답을 받았습니다.

다음은 총 100번의 요청을 어떻게 분배하는지 확인해 보겠습니다. pod2가 많이 받긴했지만 전체적으로 고루 요청해주는 것을 볼 수 있습니다.

아래와 같이 1초마다 요청 값을 보여주면서 로드밸런싱 하는 모습을 확인할 수도 있습니다.

3. node port 실습

- 목적지가 될 pod를 deploy로 배포해보겠습니다.

cat <<EOT> echo-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deploy-echo
spec:
  replicas: 3
  selector:
    matchLabels:
      app: deploy-websrv
  template:
    metadata:
      labels:
        app: deploy-websrv
    spec:
      terminationGracePeriodSeconds: 0
      containers:
      - name: ndks-websrv
        image: k8s.gcr.io/echoserver:1.5
        ports:
        - containerPort: 8080
EOT

- 서비스 nodeport로 활용할 yaml로 제작합니다.  type이 nodeport로 구성되어 있고 deploy-websrv로 연결시켰습니다.

  또한 svc-webport의 경우 포트 9000으로 요청을 받고, 8080을 리턴합니다.

cat <<EOT> svc-nodeport.yaml
apiVersion: v1
kind: Service
metadata:
  name: svc-nodeport
spec:
  ports:
    - name: svc-webport
      port: 9000
      targetPort: 8080
  selector:
    app: deploy-websrv
  type: NodePort
EOT

- deploy와 nodeport를 배포합니다. 아래와 같이 deploy와 service가 생성됨을 확인했습니다.

# NodePort 확인
kubectl get service svc-nodeport -o jsonpath='{.spec.ports[0].nodePort}' ;echo
30332

# NodePort 를 변수에 지정
export NPORT=$(kubectl get service svc-nodeport -o jsonpath='{.spec.ports[0].nodePort}')

# 노드 포트 Listen 확인 : ss 옵션 -4(ipv4) -t(TCP) -l(Listen) -n(숫자로 출력) -p(프로세스)
# 모든 노드(마스터, 워커들)에서 노드 포트가 Listen
ss -4tlnp | egrep "(Process|$NPORT)"


# 파드 로그 실시간 확인 (웹 파드에 접속자의 IP가 출력)
kubetail -l app=deploy-websrv -f
kubectl logs -l app=deploy-websrv -f

 

제 PC를 통해서 NodePort 접속 확인을 실시해보겠습니다. curl을 통한 호출을 진행합니다.

PC에서 MasterNode로 요청한 화면

 

마스터 노드로 들어온 요청에 대해서 kubernetes 상에 log로 작성되는 화면
PC에서 Node1으로 요청한 화면
node1 요청에 대해 로드밸런싱 되면서 응답 받고 있습니다.

 

이상으로 Service 실습을 마치겠습니다.