이 페이지에서는 Google Kubernetes Engine(GKE) 클러스터에서 Kubernetes 서비스를 만드는 방법을 보여줍니다. 서비스 개념 설명 및 여러 가지 서비스 유형 설명은 서비스를 참조하세요.
소개
서비스의 개념은 일련의 포드 엔드포인트를 단일 리소스로 그룹화하는 것입니다. 그룹화는 여러 방법으로 구성할 수 있습니다. 기본적으로는 클러스터 내부의 클라이언트가 서비스에서 포드에 연락하기 위해 사용할 수 있는 안정적인 클러스터 IP 주소를 사용합니다. 클라이언트는 안정적인 IP 주소로 요청을 전송하고, 요청이 서비스에 있는 포드 중 하나로 라우팅됩니다.
서비스의 5가지 유형은 다음과 같습니다.
- ClusterIP(기본값)
- NodePort
- LoadBalancer
- ExternalName
- Headless
Autopilot 클러스터는 기본적으로 공개됩니다. 비공개 Autopilot 클러스터를 선택할 경우 DockerHub에서 이미지를 가져올 때와 같이 아웃바운드 인터넷 연결을 위해 Cloud NAT를 구성해야 합니다.
이 문서에는 몇 가지 연습이 포함되어 있습니다. 각 연습에서는 서비스를 만들어서 배포를 만들고 포드를 노출합니다. 그런 후 서비스에 HTTP 요청을 전송합니다.
시작하기 전에
시작하기 전에 다음 태스크를 수행했는지 확인합니다.
- Google Kubernetes Engine API를 사용 설정합니다. Google Kubernetes Engine API 사용 설정
- 이 태스크에 Google Cloud CLI를 사용하려면 gcloud CLI를 설치한 후 초기화합니다. 이전에 gcloud CLI를 설치한 경우
gcloud components update
를 실행하여 최신 버전을 가져옵니다.
ClusterIP 유형의 서비스 만들기
이 섹션에서는 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: "us-docker.pkg.dev/google-samples/containers/gke/hello-app:2.0"
my-deployment.yaml
파일에 매니페스트를 복사하고 배포를 만듭니다.
kubectl apply -f my-deployment.yaml
3개의 포드가 실행 중인지 확인합니다.
kubectl get pods
출력에는 실행 중인 3개의 포드가 표시됩니다.
NAME READY STATUS RESTARTS AGE
my-deployment-dbd86c8c4-h5wsf 1/1 Running 0 7s
my-deployment-dbd86c8c4-qfw22 1/1 Running 0 7s
my-deployment-dbd86c8c4-wt4s6 1/1 Running 0 7s
ClusterIP
유형 서비스의 매니페스트는 다음과 같습니다.
apiVersion: v1
kind: Service
metadata:
name: my-cip-service
spec:
type: ClusterIP
# Uncomment the below line to create a Headless Service
# clusterIP: None
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
값을 기록해 둡니다.
콘솔
배포 만들기
Google Cloud 콘솔에서 워크로드 페이지로 이동합니다.
add_box 배포를 클릭합니다.
컨테이너 지정에서 기존 컨테이너 이미지를 선택합니다.
이미지 경로에 대해
us-docker.pkg.dev/google-samples/containers/gke/hello-app:2.0
을 입력합니다.완료를 클릭한 후 계속을 클릭합니다.
구성에서 애플리케이션 이름에
my-deployment
를 입력합니다.라벨에서 다음 라벨을 만듭니다.
- 키:
app
및 값:metrics
- 키:
department
및 값:sales
- 키:
클러스터에서 배포를 만들려는 클러스터를 선택합니다.
배포를 클릭합니다.
배포가 준비되면 배포 세부정보 페이지가 열립니다. 관리형 포드에서 배포에 하나 이상의 실행 중인 포드가 있는지 확인할 수 있습니다.
배포를 노출하기 위한 서비스 만들기
- 배포 세부정보 페이지에서 list작업 > 노출을 클릭합니다.
노출 대화상자의 포트 매핑에서 다음 값을 설정합니다.
- 포트:
80
- 대상 포트:
8080
- 프로토콜:
TCP
- 포트:
서비스 유형 드롭다운 목록에서 클러스터 IP를 선택합니다.
노출을 클릭합니다.
서비스가 준비되었으면 서비스 세부정보 페이지가 열리고 서비스 세부정보를 확인할 수 있습니다. 클러스터 IP에서 Kubernetes가 서비스에 할당한 IP 주소를 기록해 둡니다. 이것은 내부 클라이언트가 서비스 호출을 위해 사용할 수 있는 IP 주소입니다.
서비스 액세스
실행 중인 포드를 나열합니다.
kubectl get pods
출력에서 my-deployment
로 시작하는 포드 이름을 복사합니다.
NAME READY STATUS RESTARTS AGE
my-deployment-dbd86c8c4-h5wsf 1/1 Running 0 2m51s
실행 중인 컨테이너 중 하나에 셸로 들어갑니다.
kubectl exec -it POD_NAME -- sh
POD_NAME
을 my-deployment
에 있는 포드 중 하나의 이름으로 바꿉니다.
셸에서 curl
을 설치합니다.
apk add --no-cache curl
컨테이너에서 클러스터 IP 주소 및 포트 80을 사용하여 서비스에 요청을 수행합니다. 80은 서비스의 port
필드 값입니다. 이것은 서비스의 클라이언트로 사용하는 포트입니다.
curl CLUSTER_IP:80
CLUSTER_IP
를 서비스의 clusterIP
값으로 바꿉니다.
요청은 TCP 포트 8080의 구성원 포드 중 하나로 전달되며, 이는 targetPort
필드의 값입니다. 서비스의 각 구성원 포드에는 포트 8080으로 수신 대기하는 컨테이너가 있어야 합니다.
응답에 hello-app
의 출력이 표시됩니다.
Hello, world!
Version: 2.0.0
Hostname: my-deployment-dbd86c8c4-h5wsf
컨테이너의 셸에서 나오려면 exit
를 입력합니다.
NodePort 유형의 서비스 만들기
이 섹션에서는 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: "us-docker.pkg.dev/google-samples/containers/gke/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
...
노드 포트에서 TCP 트래픽을 허용하도록 방화벽 규칙을 만듭니다.
gcloud compute firewall-rules create test-node-port \
--allow tcp:NODE_PORT
NODE_PORT
를 서비스의 nodePort
필드 값으로 바꿉니다.
콘솔
배포 만들기
Google Cloud 콘솔에서 워크로드 페이지로 이동합니다.
add_box 배포를 클릭합니다.
컨테이너 지정에서 기존 컨테이너 이미지를 선택합니다.
이미지 경로에 대해
us-docker.pkg.dev/google-samples/containers/gke/hello-app:2.0
을 입력합니다.add 환경 변수 추가를 클릭합니다.
키에
PORT
를 입력하고 값에50000
을 입력합니다.완료를 클릭한 후 계속을 클릭합니다.
구성에서 애플리케이션 이름에
my-deployment-50000
를 입력합니다.라벨에서 다음 라벨을 만듭니다.
- 키:
app
및 값:metrics
- 키:
department
및 값:engineering
- 키:
클러스터에서 배포를 만들려는 클러스터를 선택합니다.
배포를 클릭합니다.
배포가 준비되면 배포 세부정보 페이지가 열립니다. 관리형 포드에서 배포에 하나 이상의 실행 중인 포드가 있는지 확인할 수 있습니다.
배포를 노출하기 위한 서비스 만들기
- 배포 세부정보 페이지에서 list작업 > 노출을 클릭합니다.
노출 대화상자의 포트 매핑에서 다음 값을 설정합니다.
- 포트:
80
- 대상 포트:
50000
- 프로토콜:
TCP
- 포트:
서비스 유형 드롭다운 목록에서 노드 포트를 선택합니다.
노출을 클릭합니다.
서비스가 준비되었으면 서비스 세부정보 페이지가 열리고 서비스 세부정보를 확인할 수 있습니다. 포트에서 Kubernetes가 서비스에 할당한 노드 포트를 기록해 둡니다.
노드 포트의 방화벽 규칙 만들기
Google Cloud 콘솔에서 방화벽 정책 페이지로 이동합니다.
add_box 방화벽 규칙 만들기를 클릭합니다.
이름에
test-node-port
를 입력합니다.대상 드롭다운 목록에서 네트워크의 모든 인스턴스를 선택합니다.
소스 IPv4 범위에
0.0.0.0/0
을 입력합니다.프로토콜 및 포트에서 지정된 프로토콜 및 포트를 선택합니다.
tcp 체크박스를 선택하고 기록한 노드 포트 값을 입력합니다.
만들기를 클릭합니다.
노드 IP 주소 가져오기
노드 중 하나의 외부 IP 주소를 찾습니다.
kubectl get nodes --output wide
출력은 다음과 비슷합니다.
NAME STATUS ROLES AGE VERSION EXTERNAL-IP
gke-svc-... Ready none 1h v1.9.7-gke.6 203.0.113.1
모든 클러스터가 노드에 대해 외부 IP 주소를 갖지는 않습니다. 예를 들어 비공개 클러스터의 노드에는 외부 IP 주소가 없습니다.
서비스 액세스
브라우저의 주소 표시줄에 다음을 입력합니다.
NODE_IP_ADDRESS:NODE_PORT
다음을 바꿉니다.
NODE_IP_ADDRESS
는 이전 작업에서 서비스를 만들 때 찾은 노드 중 하나의 외부 IP 주소입니다.NODE_PORT
: 노드 포트 값입니다.
출력은 다음과 비슷합니다.
Hello, world!
Version: 2.0.0
Hostname: my-deployment-50000-6fb75d85c9-g8c4f
LoadBalancer 유형의 서비스 만들기
이 섹션에서는 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: "us-docker.pkg.dev/google-samples/containers/gke/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
콘솔
배포 만들기
Google Cloud 콘솔에서 워크로드 페이지로 이동합니다.
add_box 배포를 클릭합니다.
컨테이너 지정에서 기존 컨테이너 이미지를 선택합니다.
이미지 경로에 대해
us-docker.pkg.dev/google-samples/containers/gke/hello-app:2.0
을 입력합니다.add 환경 변수 추가를 클릭합니다.
키에
PORT
를 입력하고 값에50001
을 입력합니다.완료를 클릭한 후 계속을 클릭합니다.
구성에서 애플리케이션 이름에
my-deployment-50001
를 입력합니다.라벨에서 다음 라벨을 만듭니다.
- 키:
app
및 값:products
- 키:
department
및 값:sales
- 키:
클러스터에서 배포를 만들려는 클러스터를 선택합니다.
배포를 클릭합니다.
배포가 준비되면 배포 세부정보 페이지가 열립니다. 관리형 포드에서 배포에 하나 이상의 실행 중인 포드가 있는지 확인할 수 있습니다.
배포를 노출하기 위한 서비스 만들기
- 배포 세부정보 페이지에서 list작업 > 노출을 클릭합니다.
노출 대화상자의 포트 매핑에서 다음 값을 설정합니다.
- 포트:
60000
- 대상 포트:
50001
- 프로토콜:
TCP
- 포트:
서비스 유형 드롭다운 목록에서 부하 분산기를 선택합니다.
노출을 클릭합니다.
서비스가 준비되었으면 서비스 세부정보 페이지가 열리고 서비스 세부정보를 확인할 수 있습니다. 부하 분산기에서 부하 분산기의 외부 IP 주소를 기록해 둡니다.
서비스 액세스
GKE가 부하 분산기를 구성할 때까지 몇 분 정도 기다립니다.
브라우저의 주소 표시줄에 다음을 입력합니다.
LOAD_BALANCER_ADDRESS:60000
LOAD_BALANCER_ADDRESS
를 부하 분산기의 외부 IP 주소로 바꿉니다.
응답에 hello-app
의 출력이 표시됩니다.
Hello, world!
Version: 2.0.0
Hostname: my-deployment-50001-68bb7dfb4b-prvct
서비스의 port
값은 임의적입니다. 앞의 예시에서 port
값 60000을 사용하여 이를 보여줍니다.
ExternalName 유형의 서비스 만들기
이 섹션에서는 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
콘솔
서비스 삭제
Google Cloud 콘솔의 서비스 페이지로 이동합니다.
이 연습에서 만든 서비스를 선택하고 delete 삭제를 클릭합니다.
확인 메시지가 나타나면 삭제를 클릭합니다.
배포 삭제
Google Cloud 콘솔에서 워크로드 페이지로 이동합니다.
이 연습에서 만든 배포를 선택한 후 delete 삭제를 클릭합니다.
확인 메시지가 표시되면 선택한 배포와 연관된 수평형 포드 자동 확장 처리 삭제 체크박스를 선택하고 삭제를 클릭합니다.
방화벽 규칙 삭제
Google Cloud 콘솔에서 방화벽 정책 페이지로 이동합니다.
test-node-port 체크박스를 선택한 후 delete 삭제를 클릭합니다.
확인 메시지가 나타나면 삭제를 클릭합니다.