2021. 11. 22. 08:55ㆍKubernetes/Kubernetes_Service
안녕하세요, 달콤한달팽이입니다.🐌🙂
이번 시간에는 Service와 Ingress에 대한 개념을 알아보고,
이를 통해 Pod를 외부로 노출시키는 방법에 대하여 알아보겠습니다.
Service란?
Service란, Pod에 실행중인 애플리케이션을 접근할 수 있도록 노출하는 방법입니다.
즉, 생성/삭제되는 Pod에 고정 IP를 갖는 Service를 제공하여
Service는 크게 3가지(Cluster IP, NodePort, LoadBalancer)로 구성되어 있으며,
차례대로 하나씩 실습하며 무슨 특징이 있는지 알아보도록 하겠습니다!
1) Cluster IP
ClusterIP란, Service의 기본 타입으로 Pod가 클러스터 내부에서만 통신할 수 있도록 해주는 방식입니다.
yaml 파일의 spec 상에 별도 type을 지정하지 않았을 경우 default로 생성되는 방식이며,
ClusterIP로 들어온 내부 트래픽을 Pod IP:target Port로 전달될 수 있도록 설정합니다.
[동작 방식]
생성: Service 생성 → apiserver → kubelet → kube-proxy → iptables 수정
동작: Pod의 ClusterIP 접속 → iptables 룰 확인 → Pod와 통신
이제 실습을 위해 Deployment(Pod이어도 무관), ClusterIP를 생성해봅시다!
# clusterip.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-clusterip
spec:
type: ClusterIP
selector:
name: nginx-test
ports:
- name: nginx-clusterip-port
port: 8080
targetPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
name: nginx-deployment
spec:
replicas: 3
selector:
matchLabels:
name: nginx-test
template:
metadata:
labels:
name: nginx-test
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
이제 적용을 한 후, 정상 생성을 확인해봅시다!
kubectl get svc -o wide
ClusterIP 서비스가 정상적으로 동작하는지 확인하기 위해 Pod에 접속한 후, 서비스를 테스트해주세요!
kubectl exec -it {Pod 이름} -- /bin/bash
curl {CLUSTER-IP}:{Port}
Pod에 띄운 Nginx가 정상적으로 실햄함으로써, ClusterIP가 정상동작함을 확인하였습니다.
ClusterIP 방식은 애플리케이션을 외부로 노출시키지는 못하지만, Pod로의 부하분산을 수행시켜줍니다.
이제 다음 실습을 위해 ClusterIP를 지워주세요!
kubectl delete -f clusterip.yaml
2) NodePort
NodePort란, 외부에서 전달받은 트래픽을 노드 IP의 특정 포트로 전달하는 방식입니다.
범위 내의 포트(30000 ~ 32767) 하나당 하나의 서비스를 사용합니다.
하지만 노드의 IP로 접근하기 때문에 노드가 사라졌을 떄 다른 노드를 통해 접근이 불가능하다는 특징이 있습니다.
[동작 방식]
동작: 외부에서의 Node IP 접속 → iptables 룰 확인 → Pod와 통신
# nodeport.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-nodeport
spec:
type: NodePort
selector:
name: nginx-test
ports:
- name: nginx-nodeport-port
port: 8080
targetPort: 80
nodePort: 30008
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
name: nginx-deployment
spec:
replicas: 3
selector:
matchLabels:
name: nginx-test
template:
metadata:
labels:
name: nginx-test
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
이제 적용을 한 후, 정상 생성을 확인해봅시다!
kubectl get svc,pods
이제 노드그룹의 보안그룹을 수정해주세요!
저는 NodePort의 30080으로 들어오는 트래픽에 대한 Service를 생성했으므로,
TCP 프로토콜에 대한 30080 포트를 열어주도록 하겠습니다!
이제 NodePort 방식으로 {NodeIP}:{Port}로 접속을 시도하면,
애플리케이션(Nginx)이 정상적으로 노출됨을 확인할 수 있습니다!
** 만약 nginx 페이지가 정상적으로 뜨지 않는다면 아래 사항을 참고해보세요!
1) Deployment, Service가 정상적으로 생성되었는지 확인
2) 노드그룹의 보안그룹이 열려있는지 확인
3) 노드그룹이 인터넷 통신이 되는지 확인
이제 다음 실습을 위해 NodePort와 Deployment를 지워주세요!
kubectl delete -f nodeport.yaml
3) LoadBalaner
LoadBalancer란, 클라우드 서비스를 사용할 때 쿠버네티스의 Cloud Provider가 인그레스 컨트롤를 통해 LB와 Pod를 연결한 후 해당 LB의 IP를 이용해 Pod에 접근하는 방식입니다.
[동작 방식]
동작: 외부에서의 Node IP 접속 → iptables 룰 확인 → Pod와 통신
apiVersion: v1
kind: Service
metadata:
name: nginx-loadbalancer
annotations:
service.beta.kubernetes.io/aws-load-balancer-type: "nlb"
service.beta.kubernetes.io/aws-load-balancer-subnets: {subnet-ID-a}, {subnet-ID-c}
spec:
type: LoadBalancer
selector:
app: nginx-loadbalancer
ports:
- port: 80
이제 적용을 한 후, 정상 생성을 확인해봅시다!
kubectl get svc
이를 AWS 콘솔의 로드 밸런서 탭에서도 확인이 가능합니다.
지금까지 알아본 Service는 하나의 IP로 여러 애플리케이션을 노출시킬 수 없다는 특징이 있습니다.
때문에 애플리케이션 개수만큼 Service의 수도 증가해야하는 단점이 있습니다.
다음 글에서는 이를 보완한 Ingress라는 서비스를 사용하여 게임을 외부로 노출시켜 보도록 하겠습니다.
(실무에서 애플리케이션 외부 노출을 위해 가장 많이 사용하는 기능인 만큼 꼭 읽어보셨으면 좋겠습니다.)
감사합니다!
'Kubernetes > Kubernetes_Service' 카테고리의 다른 글
[Kubernetes] 노드 자원 보호하기(Drain, Cordon, Uncordon) (0) | 2024.09.26 |
---|---|
[Kubernetes] EKS 다루기(3) - Ingress(ALB Ingress) (0) | 2024.08.28 |
[Kubernetes] EKS 다루기(1) - Pod, Replicaset, Deployment (0) | 2021.11.19 |
[Kubernetes] EKS 생성하기 (0) | 2021.11.18 |
[Kubernetes] kubeadm 설치하기 (0) | 2021.11.17 |