일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- login
- EMR
- fastcampus
- Docker
- 간단
- hive
- Zeppelin
- 설정
- Kafka
- 예제
- aws
- 로그인
- 머신러닝
- 클러스터
- ec2
- 자바
- redash
- gradle
- Mac
- Redis
- Cluster
- vue
- 자동
- 젠킨스
- SpringBoot
- config
- 레디스
- java
- spring
- Jenkins
- Today
- Total
코알못
[kubernetes] Service - NodePort로 Pod 노출 실습 본문
저번 시간에는 ClusterIP로 Pod 통신하는 방법을 배워봤다!
이번 시간에는 NodePort로 Pod 통신하는 실습을 진행해보자!
order 서비스 오브젝트는 주문을 위해 외부 통신을 할 예정이며 NodePort 타입으로 지정한다.
payment 서비스 오브젝트는 order 파드와 통신 용도이기에 외부 통신 하지 않으므로 ClusterIP 타입으로 지정한다.
이제 실습을 위해 order, payment의 Service 오브젝트와 Deployment 를 생성하는 yaml 파일을 만들도록 한다.
# service-v3.yaml
apiVersion: v1
kind: Service
metadata:
name: order
namespace: snackbar
labels:
service: order
project: snackbar
spec:
type: NodePort
selector:
service: order
project: snackbar
ports:
- port: 80
targetPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: payment
namespace: snackbar
labels:
service: payment
project: snackbar
spec:
type: ClusterIP
selector:
service: payment
project: snackbar
ports:
- port: 80
targetPort: 8080
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: order
namespace: snackbar
labels:
service: order
project: snackbar
annotations:
kubernetes.io/change-cause: "image 1.0"
spec:
replicas: 3
selector:
matchLabels:
service: order
project: snackbar
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 2
maxSurge: 1
template:
metadata:
labels:
service: order
project: snackbar
spec:
containers:
- name: order
image: yoonjeong/order:1.0
ports:
- containerPort: 8080
resources:
limits:
memory: "64Mi"
cpu: "50m"
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: payment
namespace: snackbar
labels:
service: payment
project: snackbar
annotations:
kubernetes.io/change-cause: "image 1.0"
spec:
replicas: 3
selector:
matchLabels:
service: payment
project: snackbar
strategy:
type: Recreate
template:
metadata:
labels:
service: payment
project: snackbar
spec:
containers:
- name: payment
image: yoonjeong/payment:1.0
ports:
- containerPort: 8080
resources:
limits:
memory: "64Mi"
cpu: "50m"
클러스터에 적용한다.
$ kubectl apply -f service-v3.yaml
service/order created
service/payment created
deployment.apps/order created
deployment.apps/payment created
네임스페이스 snackbar 에서 레이블중 project가 snackbar 인 모든 오브젝트를 검색하면 모두 정상적으로 뜬것을 볼 수 있다.
$ kubectl get all -l project=snackbar -n snackbar
NAME READY STATUS RESTARTS AGE
pod/order-55468df7b9-kgqsl 1/1 Running 0 49s
pod/order-55468df7b9-sm5j6 1/1 Running 0 49s
pod/order-55468df7b9-zp52t 1/1 Running 0 49s
pod/payment-5cb8974b5f-ct7m7 1/1 Running 0 48s
pod/payment-5cb8974b5f-kgl9z 1/1 Running 0 48s
pod/payment-5cb8974b5f-vt4wz 1/1 Running 0 48s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/order NodePort 10.104.10.55 <none> 80:30140/TCP 52s
service/payment ClusterIP 10.104.6.180 <none> 80/TCP 51s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/order 3/3 3 3 51s
deployment.apps/payment 3/3 3 3 50s
NAME DESIRED CURRENT READY AGE
replicaset.apps/order-55468df7b9 3 3 3 52s
replicaset.apps/payment-5cb8974b5f 3 3 3 51s
스낵바 네임스페이스에 있는 모든 서비스를 조회하면 order 서비스는 NodePort 타입이기에 포트 30140이 할당 된것을 볼 수 있다.
$ kubectl get svc -n snackbar -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
order NodePort 10.104.10.55 <none> 80:30140/TCP 2m14s project=snackbar,service=order
payment ClusterIP 10.104.6.180 <none> 80/TCP 2m13s project=snackbar,service=payment
이제 생성한 서비스에 대해 endpoint를 조회하여 파드가 잘 매핑 되었는지 확인하면 정상적으로 매핑 되었다.
$ kubectl get endpoints -n snackbar
NAME ENDPOINTS AGE
order 10.100.0.35:8080,10.100.2.39:8080,10.100.3.47:8080 2m49s
payment 10.100.0.36:8080,10.100.2.40:8080,10.100.3.48:8080 2m48s
이제 노드 포트 타입으로 호출 하기 위해서는 노드 IP 를 알아야 하므로 아래와 같이 노드 정보를 조회하고, 노드 중 External-ip 하나를 복사한다.
$ kubectl get node -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
gke-corin-cluster-default-pool-123-w610 Ready <none> 18d v1.25.8-gke.500 10.128.0.7 34.12.12.1 Container-Optimized OS from Google 5.15.89+ containerd://1.6.18
gke-corin-cluster-default-pool-123-xq03 Ready <none> 18d v1.25.8-gke.500 10.128.0.6 34.12.12.2 Container-Optimized OS from Google 5.15.89+ containerd://1.6.18
gke-corin-cluster-default-pool-123-zy02 Ready <none> 18d v1.25.8-gke.500 10.128.0.8 34.12.12.3 Container-Optimized OS from Google 5.15.89+ containerd://1.6.18
이제 'curl [노드 IP]:[노드 PORT]' 로 호출한다.
그러나 통신이 되지 않는다. 이는 해당 노드에 대해 포트가 방화벽으로 막혀 있기 때문이다.
이를 위해 오픈을 해주도록 하자!
$ curl 34.12.12.1:30140
^C
아래와 같이 gcloud 명령어를 이용하여 노드 포트인 30140 포트에 대해 방화벽을 오픈 한다.
$ gcloud compute firewall-rules create order --allow tcp:30140
Creating firewall...⠹Created [https://www.googleapis.com/compute/v1/projects/indigo-kiln-123/global/firewalls/order].
Creating firewall...done.
NAME NETWORK DIRECTION PRIORITY ALLOW DENY DISABLED
order default INGRESS 1000 tcp:30140 False
다시 통신히면 정상적으로 데이터를 가져온다.
$ curl 34.12.12.1:30140
Welcome to Snackbar!
Order what you want!
===== Host Info =====
HostIP: 10.100.0.35
HostName: order-55468df7b9-sm5j6
이제 export 로 환경 변수 설정을 하고 메뉴를 조회하면 정상적으로 order 과 통신하여 데이터를 가져오며
$ export ORDER=34.134.43.91:30140
$ curl http://$ORDER/menus
We have 4 snacks!
1. Pizza: 10,000
2. Burger: 5,000
3. Coke: 1,000
4. Juice: 1000
===== Host Info =====
HostIP: 10.100.2.39
HostName: order-55468df7b9-kgqsl
order 파드에 checkout 을 던지면 order 파드에서 payment 도메인(clusterIP)으로 payment 파드와 통신하여 데이터를 정상적으로 가져온다.
$ curl --request POST http://$ORDER/checkout \
> --header 'Content-Type: application/json' \
> --data-raw '{
quote> "Pizza": 1,
quote> "Coke": 1,
quote> "Burger": 0,
quote> "Juice": 0
quote> }'
Received from http://payment/receipt
Server is running on
- HostName: payment-5cb8974b5f-kgl9z
- HostIP: 10.100.2.40
=== Here is Your Receipt! ===
[영수증]
주문한 메뉴
--------------------------
Pizza - 10000원
Coke - 1000원
Burger - 0원
Juice - 0원
--------------------------
주문금액 11000
부가세(10%) 1100
합계 12100
이제 방화벽 리스트를 확인하며
$ gcloud compute firewall-rules list
order default INGRESS 1000 tcp:30140
실습을 종료하며 생성한 방화벽을 삭제한다.
$ gcloud compute firewall-rules delete order
다음 생성한 오브젝트를 모두 삭제한다.
$ kubectl delete all -l project=snackbar -n snackbar
pod "order-55468df7b9-kgqsl" deleted
pod "order-55468df7b9-sm5j6" deleted
pod "order-55468df7b9-zp52t" deleted
pod "payment-5cb8974b5f-ct7m7" deleted
pod "payment-5cb8974b5f-kgl9z" deleted
pod "payment-5cb8974b5f-vt4wz" deleted
service "order" deleted
service "payment" deleted
deployment.apps "order" deleted
deployment.apps "payment" deleted
끝!
# 오류
권한 거절 오류가 발생하였고 gcloud 설정이 해당 프로젝트로 되지 않아 발생하는 이슈일 수 있다고 하여
$ gcloud compute firewall-rules create order --allow tcp:30140
Creating firewall...API [compute.googleapis.com] not enabled on project [..]. Would you like to enable and retry
(this will take a few minutes)? (y/N)? y
Enabling service [compute.googleapis.com] on project [..]...
Creating firewall...failed.
ERROR: (gcloud.compute.firewall-rules.create) PERMISSION_DENIED: Permission denied to enable service [compute.googleapis.com]
아래와 같이 프로젝트 ID 를 확인한 뒤 설정 하였더니 정상적으로 설정 되었다.
$ gcloud projects list
PROJECT_ID NAME PROJECT_NUMBER
indigo-kiln-123 My First Project 123
$ gcloud config set project indigo-kiln-123
Updated property [core/project].
'ETC' 카테고리의 다른 글
[kubernetes] Ingress 소개 및 실습 (0) | 2023.05.28 |
---|---|
[kubernetes] Service - LoadBalancer로 Pod 노출 실습 (1) | 2023.05.28 |
[kubernetes] Service 소개 및 ClusterIP로 Pod 노출 실습 (1) | 2023.05.27 |
[kubernetes] Deployment - 배포 전략 Recreate, RollingUpdate 및 롤백 (1) | 2023.05.26 |
[kubernetes] Deployment 란? (0) | 2023.05.20 |