티스토리 뷰

 

kubernetes

 

1. [IaC] vagrant로 virtualbox의 VM 관리하기 (tistory.com)
2. [K8S] Kubernetes 설치 (VirtualBox + Vagrant + K8S:v1.31) (tistory.com)
3. [K8S] Kubernetes Nodeport로 서비스 테스트 하기

 

A. 개요

K8S가 되고 나면 Application들을 Container 이미지로 만들고, POD라는 단위로 만들어서 배포할 수 있습니다.
파드 | Kubernetes

 

파드

파드(Pod) 는 쿠버네티스에서 생성하고 관리할 수 있는 배포 가능한 가장 작은 컴퓨팅 단위이다. 파드 (고래 떼(pod of whales)나 콩꼬투리(pea pod)와 마찬가지로)는 하나 이상의 컨테이너의 그룹이다.

kubernetes.io

 
그리고 Service라는 네트워크 구성요소를 사용해서 통신 설정을 할 수 있습니다.
서비스 | Kubernetes

 

서비스

외부와 접하는 단일 엔드포인트 뒤에 있는 클러스터에서 실행되는 애플리케이션을 노출시키며, 이는 워크로드가 여러 백엔드로 나뉘어 있는 경우에도 가능하다.

kubernetes.io

 
어찌 보면 이 2가지 구성요소가 가장 기본적이고 단순한 서비스 구성 요소입니다.
이전에 만든 Cluster에 이 2개의 구성요소를 배포하고 통신 NodePort를 구성해서 브라우져로 접속 해 보는 테스트를 해 보겠습니다.
 

B. 샘플 코드

 

1. POD 샘플

apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    app.kubernetes.io/name: proxy
spec:
  containers:
  - name: nginx
    image: nginx:stable
    ports:
      - containerPort: 80
        name: http-web-svc

 
 
POD 정의에 대한 설명은 펼쳐서 보시면 될겁니다.

더보기
apiVersion: v1
kind: Pod

 POD를 정의하는 yaml 입니다.

이 POD의  API버젼은 V1 입니다.

api-resources에서 PODs 의 버젼 확인

 

spec:
  containers:
  - name: nginx
    image: nginx:stable
    ports:
      - containerPort: 80
        name: http-web-svc

 이 문서의 spec 부분을 먼저 보면 POD에 포함할 Container들의 정의가 들어 있습니다.

  • name : Container의 이름입니다.
  • image : 사용할 Image입니다. 
  • ports: 노출할 Port를 지정합니다. 여기서 지정한 port는 POD외부에서 접근 가능한 구성입니다.
              (Cluster 외부에서 볼수 있는 구성은 아닙니다.) 
metadata:
  name: nginx
  labels:
    app.kubernetes.io/name: proxy

 POD 구성에 대한  metadata를 설정합니다.

  • name : pod의 이름입니다. 이 이름 뒤에 랜덤한 문자가 더 붙을 수 있습니다.
                ex : calico-kube-controllers-6879d4fcdc-b9mrg
  • labels: 이 POD를 구분하기 위한 label들을 지정할 수 있습니다.

pod 의 이름은 변경될 수 있습니다. 그리고 replica설정이 되면 동일한 이름의 pod가 여러개 생성될 수 있습니다.

그래서 pod의 이름으로는 객체를 특정할 수 없습니다. label은 이 pod들을 특정하기 위한 값으로 사용 됩니다.

 

2. Service 샘플

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

 

서비스

외부와 접하는 단일 엔드포인트 뒤에 있는 클러스터에서 실행되는 애플리케이션을 노출시키며, 이는 워크로드가 여러 백엔드로 나뉘어 있는 경우에도 가능하다.

kubernetes.io

 

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  type: NodePort
  selector:
    app.kubernetes.io/name: proxy
  ports:
      # 기본적으로 그리고 편의상 "targetPort" 는 "port" 필드와 동일한 값으로 설정된다.
    - name: http
      port: 80
      targetPort: 80
      # 선택적 필드
      # 기본적으로 그리고 편의상 쿠버네티스 컨트롤 플레인은 포트 범위에서 할당한다(기본값: 30000-32767)

 

더보기
apiVersion: v1
kind: Service

Service 객체를 정의하는 문서입니다.

Service는 API version이 V1으로 정의되어 있습니다.

api-resources에서 services의 버젼 확인

 

metadata:
  name: my-service

Service 의 이름이 my-service 입니다...

이 Service의 Spec은 다음과 같습니다.

spec:
  type: NodePort
  selector:
    app.kubernetes.io/name: MyApp
  ports:
      # 기본적으로 그리고 편의상 `targetPort` 는 `port` 필드와 동일한 값으로 설정된다.
    - port: 80
      targetPort: 80
      # 선택적 필드
      # 기본적으로 그리고 편의상 쿠버네티스 컨트롤 플레인은 포트 범위에서 할당한다(기본값: 30000-32767)
      nodePort: 30007

먼저, 이 Service의 Sepc을 살펴 보면, 

  • type이 NodePort입니다. 아래에 추가 설명을 더 하겠습니다.
  • selector는 어느 Pod를 선택해서 패킷을 전달할 것인가를 지정합니다. pod의 label을 명시 합니다.
  • ports 는 어떻게 네트워크 구성을 할 것인가 입니다.
    • port는 이 서비스기준 Input Port입니다.
    • targetPort는 Pod로 전달할 Output Port 입니다.
    • NodePort는 30007 번으로 Node에 포트를 개방하겠다는 의미입니다. 

 

추가로 Service의 Type에 대한 자세한 내용은 API 문서를 참고하시면 됩니다.

Kubernetes API Reference Docs

 

Kubernetes API Reference Docs

 

kubernetes.io

(Service에 대한 설명의 맨 끝쪽에 있습니다....)

Service Type 설명

ExternalName, ClusterIP, NodePort LoadBalancer 이 4개의 타입이 있고, 그에 대한 설명이 적혀 있습니다.

유형은 서비스가 노출되는 방식을 결정합니다.
기본값은 ClusterIP입니다. 유효한 옵션은 외부 이름, ClusterIP, NodePort 및 LoadBalancer입니다.

"ClusterIP"는 엔드포인트에 대한 부하 분산을 위해 클러스터 내부 IP 주소를 할당합니다. 엔드포인트는 선택기에 의해 결정되거나 지정되지 않은 경우 Endpoints 개체 또는 EndpointSlice 개체의 수동 구성에 의해 결정됩니다. ClusterIP가 "None"이면 가상 IP가 할당되지 않으며 엔드포인트는 가상 IP가 아닌 엔드포인트 집합으로 게시됩니다.
"NodePort"는 ClusterIP를 기반으로 하며 ClusterIP와 동일한 엔드포인트로 라우팅되는 모든 노드에 포트를 할당합니다.
"LoadBalancer"는 NodePort를 기반으로 하며 ClusterIP와 동일한 엔드포인트로 라우팅되는 외부 로드 밸런서(현재 클라우드에서 지원되는 경우)를 생성합니다.
"ExternalName"은 이 서비스의 별칭을 지정된 externalName으로 지정합니다. 다른 여러 필드는 ExternalName 서비스에 적용되지 않습니다.

 

 

C. 설치

 
현재 my-service.yaml과 nginx.yaml 이 있습니다.

pod와 service의 정의가 된 파일 목록

kubectl apply -f nginx.yaml
kubectl apply -f my-service.yaml

정의된 yaml을 순차적으로 실행 해서 K8S에 배포

 
설치 한 객체를 조회 해 봅니다.

kubectl get pods,service

배포된 리소스를 확인

 

더보기

만약에... POD가 정상적으로 생성이 되지 않고 Pending 이 될 경우에..

Master Node에 POD 생성을 하지 못하게 구성되어 있을 수 있습니다.

 

비정상적으로 생성된 모습(Pending)

 

kubectl describe node k8s | grep Taints

 

Node의 설정 되어 있는 Taint 조회 모습

 

이렇게 Taints 가 구성되어 있다면

kubectl taint nodes k8s node-role.kubernetes.io/control-plane:NoSchedule-
Taint 제거 방법

이렇게 "-"  를 붙여서 설정을 제거해 줍니다.

 

D. 설치 확인 및 접근

 

1. 설치 확인

kubectl get po,svc,ep -o wide

NodePort Type의 Service 및 EndPoint 조회

정상적으로 Service가 설정 되면, 저렇게 endpoints가 설정 되게 됩니다.
pod는 172.17.77.4 라는 ip를 할당 받게 되었고, svc는 30007번 포트로 수신된 패킷을 172.17.77.4:80 으로 전송 하게 구성 되었습니다.
 

인프라 구성도
허접한 그림... 죄송합니다.

 

2. 호출

http://192.168.0.156:3007 주소를 브라우져로 열어봅니다.
 
현재 Vagrant Box의 Network가 Public Network 이므로, 같은 공유기 안에 있는 모든 PC, 휴대폰에서 접속 가능합니다.
아무데서나 붙어 보시면 되요.
 

완성! 브라우져로 POD에 접근 성공

 
잘 동작 되는것을 확인 했습니다.
 


1. [IaC] vagrant로 virtualbox의 VM 관리하기 (tistory.com)
2. [K8S] Kubernetes 설치 (VirtualBox + Vagrant + K8S:v1.31) (tistory.com)
3. [K8S] Kubernetes Nodeport로 서비스 테스트 하기