서비스를 사용하여 애플리케이션 노출

이 페이지에서는 Google Kubernetes Engine 클러스터에서 Kubernetes 서비스를 만드는 방법을 보여줍니다. 서비스 개념 설명 및 여러 가지 서비스 유형 설명은 서비스를 참조하세요.

소개

서비스의 개념은 일련의 포드 엔드포인트를 단일 리소스로 그룹화하는 것입니다. 그룹화는 여러 방법으로 구성할 수 있습니다. 기본적으로는 클러스터 내부의 클라이언트가 서비스에서 포드에 연락하기 위해 사용할 수 있는 안정적인 클러스터 IP 주소를 사용합니다. 클라이언트는 안정적인 IP 주소로 요청을 전송하고, 요청이 서비스에 있는 포드 중 하나로 라우팅됩니다.

서비스의 5가지 유형은 다음과 같습니다.

  • ClusterIP(기본값)
  • NodePort
  • LoadBalancer
  • ExternalName
  • Headless

이 문서에는 몇 가지 연습이 포함되어 있습니다. 각 연습에서는 서비스를 만들어서 배포를 만들고 포드를 노출합니다. 그런 후 서비스에 HTTP 요청을 전송합니다.

시작하기 전에

이 작업을 준비하려면 다음 단계를 수행하세요.

  • Google Kubernetes Engine API가 사용 설정되었는지 확인합니다.
  • Google Kubernetes Engine API 사용 설정
  • Cloud SDK가 설치되었는지 확인합니다.
  • 기본 프로젝트 ID를 설정합니다.
    gcloud config set project [PROJECT_ID]
  • 영역 클러스터를 사용하는 경우 기본 컴퓨팅 영역을 설정합니다.
    gcloud config set compute/zone [COMPUTE_ZONE]
  • 지역 클러스터를 사용하는 경우 기본 컴퓨팅 지역을 설정합니다.
    gcloud config set compute/region [COMPUTE_REGION]
  • gcloud를 최신 버전으로 업데이트합니다.
    gcloud components update

ClusterIP 유형의 서비스 만들기

kubectl apply

배포 매니페스트는 다음과 같습니다.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-deployment
spec:
  selector:
    matchLabels:
      app: metrics
      department: sales
  replicas: 3
  template:
    metadata:
      labels:
        app: metrics
        department: sales
    spec:
      containers:
      - name: hello
        image: "gcr.io/google-samples/hello-app:2.0"

이름이 my-deployment.yaml인 파일에 매니페스트를 복사하고 배포를 만듭니다.

kubectl apply -f my-deployment.yaml

3개의 포드가 실행 중인지 확인합니다.

kubectl get pods

출력에는 실행 중인 3개의 포드가 표시됩니다.

NAME                              READY     STATUS    RESTARTS   AGE
service-how-to-76699757f9-h4xk4   1/1       Running   0          4s
service-how-to-76699757f9-tjcfq   1/1       Running   0          4s
service-how-to-76699757f9-wt9d8   1/1       Running   0          4s

ClusterIP 유형 서비스의 매니페스트는 다음과 같습니다.

apiVersion: v1
kind: Service
metadata:
  name: my-cip-service
spec:
  type: ClusterIP
  selector:
    app: metrics
    department: sales
  ports:

  • protocol: TCP port: 80 targetPort: 8080

이 서비스에는 2개의 라벨을 지정하는 선택기가 있습니다.

  • app: metrics
  • department: sales

이전에 생성한 배포의 각 포드에는 다음 두 개의 라벨이 포함됩니다. 따라서 배포에 있는 포드가 이 서비스의 구성원이 됩니다.

이름이 my-cip-service.yaml인 파일에 매니페스트를 복사하고 서비스를 만듭니다.

kubectl apply -f my-cip-service.yaml

Kubernetes가 안정적인 내부 주소를 서비스에 할당할 때까지 기다린 후 서비스를 확인합니다.

kubectl get service my-cip-service --output yaml

출력에는 clusterIP의 값이 표시됩니다.

spec:
  clusterIP: 10.59.241.241

나중을 위해 clusterIP 값을 기록해 둡니다.

콘솔

배포 만들기

  1. GCP 콘솔에서 Google Kubernetes Engine 작업 부하 메뉴로 이동합니다.

    작업 부하 메뉴로 이동

  2. 배포를 클릭합니다.

  3. 컨테이너 상자에서 컨테이너 이미지gcr.io/google-samples/hello-app:2.0을 입력하고 완료를 클릭합니다.

  4. 애플리케이션 이름my-deployment를 입력합니다.

  5. 라벨 아래에 2개의 라벨을 만듭니다. 하나의 라벨에 대해 app으로 설정하고 metrics로 설정합니다. 다른 라벨에 대해서는 department로 설정하고 sales로 설정합니다.

  6. 클러스터 드롭다운 메뉴에서 원하는 클러스터를 선택합니다.

  7. 배포를 클릭합니다.

  8. 배포가 준비되었으면 배포 세부정보 페이지가 열리고 배포에 하나 이상의 실행 중인 포드가 포함된 것을 확인할 수 있습니다.

배포를 노출하기 위한 서비스 만들기

  1. 배포 세부정보 페이지의 서비스 아래에서 노출을 클릭합니다.

  2. 새 포트 매핑 상자에서 포트80으로 설정하고 대상 포트8080으로 설정합니다. 프로토콜TCP로 설정된 상태로 둡니다. 완료를 클릭합니다.

  3. 서비스 유형 드롭다운 메뉴에서 클러스터 IP를 선택합니다.

  4. 서비스 이름my-cip-service를 입력합니다.

  5. 노출을 클릭합니다.

  6. 서비스가 준비되었으면 서비스 세부정보 페이지가 열리고 서비스 세부정보를 확인할 수 있습니다. 특히 Kubernetes가 서비스에 할당한 클러스터 IP 값을 확인할 수 있습니다. 이것은 내부 클라이언트가 서비스 호출을 위해 사용할 수 있는 IP 주소입니다. 나중을 위해 클러스터 IP 값을 기록해 둡니다.

서비스 액세스

실행 중인 포드를 나열합니다.

kubectl get pods

출력에서 my-deployment로 시작하는 포드 이름 중 하나를 복사합니다.

NAME                               READY     STATUS    RESTARTS   AGE
my-deployment-6897d9577c-7z4fv     1/1       Running   0          5m

실행 중인 컨테이너 중 하나에 셸로 들어갑니다.

kubectl exec -it [YOUR_POD_NAME] -- sh

여기서 [YOUR_POD_NAME]my-deployment에 있는 포드 중 하나의 이름입니다.

셸에서 curl을 설치합니다.

apk add --no-cache curl

컨테이너에서 클러스터 IP 주소 및 포트 80을 사용하여 서비스에 요청을 수행합니다. 80이 해당 서비스의 port 필드 값인지 확인합니다. 이것은 서비스의 클라이언트로 사용하는 포트입니다.

curl [CLUSTER_IP]:80

여기서 [CLUSTER_IP]는 서비스에 있는 clusterIP의 값입니다.

요청이 targetPort 필드의 값인 TCP 포트 8080의 구성원 포드 중 하나로 전달됩니다. 서비스의 각 구성원 포드에는 포트 8080으로 수신 대기하는 컨테이너가 있어야 합니다.

응답에는 hello-app 출력이 표시됩니다.

Hello, world!
Version: 2.0.0
Hostname: service-how-to-76699757f9-hsb5x

컨테이너에서 셸을 종료하기 위해 exit를 입력합니다.

NodePort 유형의 서비스 만들기

kubectl apply

배포 매니페스트는 다음과 같습니다.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-deployment-50000
spec:
  selector:
    matchLabels:
      app: metrics
      department: engineering
  replicas: 3
  template:
    metadata:
      labels:
        app: metrics
        department: engineering
    spec:
      containers:
      - name: hello
        image: "gcr.io/google-samples/hello-app:2.0"
        env:
        - name: "PORT"
          value: "50000"

매니페스트에서 env 객체를 확인합니다. env 객체는 실행 중인 컨테이너의 PORT 환경 변수가 50000 값을 갖도록 지정합니다. hello-app 애플리케이션은 PORT 환경 변수로 지정된 포트에서 수신 대기합니다. 따라서 이 연습에서는 컨테이너가 포트 50000에서 수신 대기하도록 지정합니다.

이름이 my-deployment-50000.yaml인 파일에 매니페스트를 복사하고 배포를 만듭니다.

kubectl apply -f my-deployment-50000.yaml

3개의 포드가 실행 중인지 확인합니다.

kubectl get pods

NodePort 유형 서비스의 매니페스트는 다음과 같습니다.

apiVersion: v1
kind: Service
metadata:
  name: my-np-service
spec:
  type: NodePort
  selector:
    app: metrics
    department: engineering
  ports:

  • protocol: TCP port: 80 targetPort: 50000

이름이 my-np-service.yaml인 파일에 매니페스트를 복사하고 서비스를 만듭니다.

kubectl apply -f my-np-service.yaml

서비스를 확인합니다.

kubectl get service my-np-service --output yaml

출력에 nodePort 값이 표시됩니다.

...
  spec:
    ...
    ports:
    - nodePort: 30876
      port: 80
      protocol: TCP
      targetPort: 50000
    selector:
      app: metrics
      department: engineering
    sessionAffinity: None
    type: NodePort
...

클러스터의 노드에 외부 IP 주소가 있으면 노드 중 하나의 외부 IP 주소를 찾습니다.

kubectl get nodes --output wide

출력에 노드의 외부 IP 주소가 표시됩니다.

NAME          STATUS    ROLES     AGE    VERSION        EXTERNAL-IP
gke-svc-...   Ready     none      1h     v1.9.7-gke.6   203.0.113.1

모든 클러스터가 노드에 대해 외부 IP 주소를 갖지는 않습니다. 예를 들어 비공개 클러스터의 노드에는 외부 IP 주소가 없습니다.

노드 포트에서 TCP 트래픽을 허용하도록 방화벽 규칙을 만듭니다.

gcloud compute firewall-rules create test-node-port --allow tcp:[NODE_PORT]

여기서 [NODE_PORT]는 서비스의 nodePort 필드 값입니다.

콘솔

배포 만들기

  1. GCP 콘솔에서 Google Kubernetes Engine 작업 부하 메뉴로 이동합니다.

    작업 부하 메뉴로 이동

  2. 배포를 클릭합니다.

  3. 컨테이너 상자에서 컨테이너 이미지gcr.io/google-samples/hello-app:2.0을 입력합니다. 환경 변수 추가를 클릭합니다. PORT를 입력하고 50000을 입력합니다. 완료를 클릭합니다.

  4. 애플리케이션 이름my-deployment-50000를 입력합니다.

  5. 라벨 아래에 2개의 라벨을 만듭니다. 하나의 라벨에 대해 app으로 설정하고 metrics로 설정합니다. 다른 라벨에 대해서는 department로 설정하고 engineering로 설정합니다.

  6. 클러스터 드롭다운 메뉴에서 원하는 클러스터를 선택합니다.

  7. 배포를 클릭합니다.

  8. 배포가 준비되었으면 배포 세부정보 페이지가 열리고 배포에 하나 이상의 실행 중인 포드가 포함된 것을 확인할 수 있습니다.

배포를 노출하기 위한 서비스 만들기

  1. 배포 세부정보 페이지의 서비스 아래에서 노출을 클릭합니다.

  2. 새 포트 매핑 상자에서 포트80으로 설정하고 대상 포트50000으로 설정합니다. 프로토콜TCP로 설정된 상태로 둡니다. 완료를 클릭합니다.

  3. 서비스 유형 드롭다운 메뉴에서 노드 포트를 선택합니다.

  4. 서비스 이름my-np-service를 입력합니다.

  5. 노출을 클릭합니다.

  6. 서비스가 준비되었으면 서비스 세부정보 페이지가 열리고 서비스 세부정보를 확인할 수 있습니다. 특히 포트 아래에서 Kubernetes가 서비스에 할당한 노드 포트 값을 확인할 수 있습니다. 나중을 위해 노드 포트 값을 기록해 둡니다.

노드 포트의 방화벽 규칙 만들기

  1. GCP 콘솔에서 방화벽 규칙 메뉴로 이동합니다.

    방화벽 규칙 메뉴로 이동

  2. 방화벽 규칙 만들기를 클릭합니다.

  3. 이름test-node-port를 입력합니다.

  4. 대상 드롭다운 메뉴에서 네트워크의 모든 인스턴스를 선택합니다.

  5. 소스 IP 범위0.0.0.0/0을 입력합니다.

  6. 지정된 프로토콜 및 포트 아래에서 tcp를 선택하고 노드 포트 값을 입력합니다.

  7. 만들기를 클릭합니다.

클러스터 노드 중 하나의 외부 IP 주소를 찾습니다.

  1. GCP 콘솔에서 Google Kubernetes Engine 메뉴로 이동합니다.

    Google Kubernetes Engine 메뉴로 이동

  2. 이 연습에서 사용 중인 클러스터의 이름을 클릭합니다.

  3. 노드 풀 아래에서 인스턴스 그룹의 이름을 클릭합니다. 노드 목록이 표시됩니다. 노드 중 하나의 외부 IP 주소를 기록해 둡니다.

서비스 액세스

브라우저의 주소 표시줄에 [NODE_IP_ADDRESS]:[NODE_PORT]을 입력합니다.

각 항목의 의미는 다음과 같습니다.

  • [NODE_IP_ADDRESS]는 노드 중 하나의 외부 IP 주소입니다.
  • [NODE_PORT]는 노드 포트 값입니다.

응답에는 hello-app 출력이 표시됩니다.

Hello, world!
Version: 2.0.0
Hostname: service-how-to-50000-695955857d-q76pb

LoadBalancer 유형의 서비스 만들기

kubectl apply

배포 매니페스트는 다음과 같습니다.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-deployment-50001
spec:
  selector:
    matchLabels:
      app: products
      department: sales
  replicas: 3
  template:
    metadata:
      labels:
        app: products
        department: sales
    spec:
      containers:
      - name: hello
        image: "gcr.io/google-samples/hello-app:2.0"
        env:
        - name: "PORT"
          value: "50001"

이 배포의 컨테이너는 포트 50001에서 수신 대기합니다.

이름이 my-deployment-50001.yaml인 파일에 매니페스트를 복사하고 배포를 만듭니다.

kubectl apply -f my-deployment-50001.yaml

3개의 포드가 실행 중인지 확인합니다.

kubectl get pods

LoadBalancer 유형 서비스의 매니페스트는 다음과 같습니다.

apiVersion: v1
kind: Service
metadata:
  name: my-lb-service
spec:
  type: LoadBalancer
  selector:
    app: products
    department: sales
  ports:

  • protocol: TCP port: 60000 targetPort: 50001

이름이 my-lb-service.yaml,인 파일에 매니페스트를 복사하고 서비스를 만듭니다.

kubectl apply -f my-lb-service.yaml

LoadBalancer 유형의 서비스를 만들면 Google Cloud 컨트롤러가 작동하여 네트워크 부하 분산기를 구성합니다. 컨트롤러가 네트워크 부하 분산기를 구성하고 안정적인 IP 주소를 생성할 때까지 1분 정도 기다립니다.

서비스를 확인합니다.

kubectl get service my-lb-service --output yaml

출력의 loadBalancer:ingress: 아래에 안정적인 외부 IP 주소가 표시됩니다.

...
spec:
  ...
  ports:
  - ...
    port: 60000
    protocol: TCP
    targetPort: 50001
  selector:
    app: products
    department: sales
  sessionAffinity: None
  type: LoadBalancer
status:
  loadBalancer:
    ingress:
    - ip: 203.0.113.10

콘솔

배포 만들기

  1. GCP 콘솔에서 Google Kubernetes Engine 작업 부하 메뉴로 이동합니다.

    작업 부하 메뉴로 이동

  2. 배포를 클릭합니다.

  3. 컨테이너 상자에서 컨테이너 이미지gcr.io/google-samples/hello-app:2.0을 입력합니다. 환경 변수 추가를 클릭합니다. PORT를 입력하고 50001을 입력합니다. 완료를 클릭합니다.

  4. 애플리케이션 이름my-deployment-50001를 입력합니다.

  5. 라벨 아래에 2개의 라벨을 만듭니다. 하나의 라벨에 대해 app으로 설정하고 products로 설정합니다. 다른 라벨에 대해서는 department로 설정하고 sales로 설정합니다.

  6. 클러스터 드롭다운 메뉴에서 원하는 클러스터를 선택합니다.

  7. 배포를 클릭합니다.

  8. 배포가 준비되었으면 배포 세부정보 페이지가 열리고 배포에 하나 이상의 실행 중인 포드가 포함된 것을 확인할 수 있습니다.

배포를 노출하기 위한 서비스 만들기

  1. 배포 세부정보 페이지에서 노출을 클릭합니다.

  2. 새 포트 매핑 상자에서 포트60000으로 설정하고 대상 포트50001으로 설정합니다. 프로토콜TCP로 설정된 상태로 둡니다. 완료를 클릭합니다.

  3. 서비스 유형 드롭다운 메뉴에서 부하 분산기를 선택합니다.

  4. 서비스 이름my-lb-service를 입력합니다.

  5. 노출을 클릭합니다.

  6. 서비스가 준비되었으면 서비스 세부정보 페이지가 열리고 서비스 세부정보를 확인할 수 있습니다. 특히 부하 분산기의 외부 IP 주소를 확인할 수 있습니다. 나중을 위해 부하 분산기의 IP 주소를 기록해 둡니다.

서비스 액세스

GKE가 부하 분산기를 구성할 때까지 몇 분 정도 기다립니다.

브라우저의 주소 표시줄에 [LOAD_BALANCER_ADDRESS]:60000을 입력합니다.

여기서 [LOAD_BALANCER_ADDRESS]는 부하 분산기의 외부 IP 주소입니다.

응답에는 hello-app 출력이 표시됩니다.

Hello, world!
Version: 2.0.0
Hostname: service-how-to-50001-644f8857c7-xxdwg

서비스의 port 값이 임의 값인지 확인합니다. 이전 예에서는 port 값 60000을 사용해서 이를 표시합니다.

ExternalName 유형의 서비스 만들기

ExternalName 유형의 서비스는 외부 DNS 이름에 대한 내부 별칭을 제공합니다. 내부 클라이언트는 내부 DNS 이름을 사용하여 요청을 수행하고, 요청이 외부 이름으로 리디렉션됩니다.

ExternalName 유형 서비스의 매니페스트는 다음과 같습니다.

apiVersion: v1
kind: Service
metadata:
  name: my-xn-service
spec:
  type: ExternalName
  externalName: example.com

이전 예에서 DNS 이름은 my-xn-service.default.svc.cluster.local입니다. 내부 클라이언트가 my-xn-service.default.svc.cluster.local에 요청을 수행하면 요청이 example.com으로 리디렉션됩니다.

kubectl expose를 사용하여 서비스 만들기

서비스 매니페스트를 작성하는 방법의 대안으로, kubectl expose를 사용해서 배포를 노출하도록 서비스를 만들 수 있습니다.

이 문서의 앞 부분에 표시된 my-deployment를 노출하기 위해서는 다음 명령어를 입력할 수 있습니다.

kubectl expose deployment my-deployment --name my-cip-service \
    --type ClusterIP --protocol TCP --port 80 --target-port 8080

이 문서의 앞 부분에 표시된 my-deployment-50000을 노출하기 위해서는 다음 명령어를 입력할 수 있습니다.

kubectl expose deployment my-deployment-50000 --name my-np-service \
    --type NodePort --protocol TCP --port 80 --target-port 50000

이 문서의 앞 부분에 표시된 my-deployment-50001을 노출하기 위해서는 다음 명령어를 입력할 수 있습니다.

kubectl expose deployment my-deployment-50001 --name my-lb-service \
    --type LoadBalancer --port 60000 --target-port 50001

삭제

이 페이지의 연습을 완료한 후에는 다음 단계에 따라 자신의 계정에 원치 않는 비용이 발생하지 않도록 리소스를 삭제합니다.

kubectl apply

서비스 삭제

kubectl delete services my-cip-service my-np-service my-lb-service

배포 삭제

kubectl delete deployments my-deployment my-deployment-50000 my-deployment-50001

방화벽 규칙 삭제

gcloud compute firewall-rules delete test-node-port

콘솔

서비스 삭제

  1. GCP 콘솔에서 Google Kubernetes Engine 서비스 메뉴로 이동합니다.

    서비스 메뉴로 이동

  2. my-cip-service를 클릭하고 삭제를 클릭합니다.

  3. my-np-service를 클릭하고 삭제를 클릭합니다.

  4. my-lb-service를 클릭하고 삭제를 클릭합니다.

배포 삭제

  1. GCP 콘솔에서 Google Kubernetes Engine 작업 부하 메뉴로 이동합니다.

    작업 부하 메뉴로 이동

  2. my-deployment를 클릭하고 삭제를 클릭합니다. Delete horizontal pod autoscaler my-deployment-hpa 상자를 선택한 상태로 두고 삭제를 클릭합니다.

  3. my-deployment-50000을 클릭하고 삭제를 클릭합니다. Delete horizontal pod autoscaler my-deployment-50000-hpa 상자를 선택한 상태로 두고 삭제를 클릭합니다.

  4. my-deployment-50001을 클릭하고 삭제를 클릭합니다. Delete horizontal pod autoscaler my-deployment-50001-hpa 상자를 선택한 상태로 두고 삭제를 클릭합니다.

방화벽 규칙 삭제

  1. GCP 콘솔에서 방화벽 규칙 메뉴로 이동합니다.

    방화벽 규칙 메뉴로 이동

  2. test-node-port를 클릭하고 삭제를 클릭합니다.

다음 단계

이 페이지가 도움이 되었나요? 평가를 부탁드립니다.

다음에 대한 의견 보내기...

Kubernetes Engine