개요
k8s에서 service의 개념이 무엇인지 알아보고 어떻게 구현이 되는지 알아보겠습니다.
Serivce란?
pod들을 Network에 노출시키는 Object입니다.
그리고 개념적으로 virtual server와 비슷하다고 생각하면 더 쉽게 이해할 수 있습니다.
이를 그림으로 표현하면 아래와 같습니다.
Service 영향 범위
service의 설정은 cluster 전체에 적용이 됩니다. 그래서 cluster node 어디서나 접근이 가능합니다.
Service 종류
크게 2개의 분류로 나눠지고 각 분류 별로 4개 및 2개의 종류가 존재합니다.
분류방식은 k8s에서 기본 제공 하는 Default Service와 plugin으로 제공되는 Service로 구분이 됩니다. 이는 공식적인 것은 아니고 제가 생각했하기에 그렇습니다.
Default Serivce
ClusterIP
NodePort
Port forwarding
ExternalName
Plugin Service
loadbalancer
ingress
Default Service
ClusterIP
목적
k8s Cluster 내부에서 사용된 Load balancer입니다.
구조
장점
Cluster내부에만 존재하는 pod들 대상으로 기본적으로 load balancing 해줍니다.
단점
Cluster내부에서 밖에 사용을 못 합니다.
생성
command 이용
kubectl expose pod my-pod --name=my-service --port=8080 --target-port=80
이 명령을 해석하면 다음과 같습니다.
- pod는 pod를 대상으로 Service를 만들겠다는 뜻입니다. deployment로 변경도 가능합니다
- my-pod는 Service를 연결하고 하는 Pod의 이름입니다.
- --name=my-service는 만들어질 Service의 이름입니다.
- --port=8080는 Service가 open할 포트입니다.
- --target-port=80는 Pod가 open한 포트입니다.
위의 명령을 실행하면 my-service라는 이름의 Service가 생성되고, 이는 자동으로 ClusterIP를 할당받게 됩니다.
이렇게 만들어진 Service의 세부 정보를 보려면 아래와 같은 명령을 사용하면 됩니다:
kubectl describe service my-service
이 명령의 출력 내용 중에는 할당받은 ClusterIP의 정보도 포함되어 있습니다.
YAML 이용
YAML 파일을 만들기 힘들 때는 위에 명령에서 --dry-run=client -o yaml 만 붙이면 됩니다.
kubectl expose pod my-pod --name=my-service --port=8080 --target-port=80 --dry-run=client -o yaml
을 실행하면 됩니다.
apiVersion: v1
kind: Service
metadata:
creationTimestamp: null
labels:
app: nginx
name: my-service
spec:
ports:
- port: 8080
protocol: TCP
targetPort: 80
selector:
app: cluster-nginx
status:
loadBalancer: {}
삭제
kubectl delete service <service name>
Service 설정 구조
아래 명령어는 생성된 service의 설정은 보는 것입니다.
#kubectl describe service <service name>
Name: my-service
Namespace: default
Labels: app=nginx
Annotations: <none>
Selector: app=cluster-nginx
Type: ClusterIP
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.98.102.216
IPs: 10.98.102.216
Port: <unset> 8080/TCP
TargetPort: 80/TCP
Endpoints: 10.32.0.22:80,10.32.0.23:80,10.40.0.25:80 + 1 more...
Session Affinity: None
Events: <none>
여기서 중요한 것은 Endpoint입니다. Endpoint는 해당 service에 어떠한 Pod들이 연결되어 있는지를 표기합니다.
그런데 만약 위에처럼 +1 more라고 뜬다면 아래 명령어를 사용해서 endpints 부분만 따로 보시면 됩니다.
endpoint 상세하게 보기
#kubectl get endpoints <service-name> -o json > endpoints.json
NodePort
목적
portforwarding과 유사한 방식을 사용하여 Pod를 Networking에 노출시키는 압법입니다.
구조
장점
pod들 대상으로 기본적으로 load balancing 해줍니다.
단점
- IP:port를 통해서만 접속이 가능합니다.
- 외부로 서비스 노출 시 30000-32767 사이 port 밖에 할당을 못합니다.
생성
command
kubectl expose deployment myapp --type=NodePort --name=my-service --port=8080 --target-port=80
* 유의 사항 NodePort의 값은 Random이 됩니다.
이를 설정하기 위해서는 yaml 파일로 만든 후 설정이 필요합니다.
YAML
아래 명령을 사용하여 YAML 파일의 기본을 만들 수 있습니다
kubectl expose deployment cluster-nginx-deployment --type=NodePort --name=my-service --port=8080 --target-port=80 --dry-run=client -o yaml
apiVersion: v1
kind: Service
metadata:
creationTimestamp: null
labels:
app: nginx
name: my-service
spec:
ports:
- nodePort: 30000 # host에서 외부에 노출할 NodePort
port: 8080 # service의 port
protocol: TCP
targetPort: 80 # pod에서 open된 port
selector:
app: cluster-nginx
type: NodePort # 서비스 타입
status:
loadBalancer: {}
Yaml 파일과 deployment 파일 mapping
삭제
kubectl delete service <service name>
Service 설정 구조
Nodeport가 추가된 것 뒤에는 ClusterIP와 형태가 동일합니다.
#kubectl describe service my-service
Name: my-service
Namespace: default
Labels: app=nginx
Annotations: <none>
Selector: app=cluster-nginx
Type: NodePort
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.98.102.216
IPs: 10.98.102.216
Port: <unset> 8080/TCP
TargetPort: 80/TCP
NodePort: <unset> 32538/TCP
Endpoints: 10.32.0.22:80,10.32.0.23:80,10.40.0.25:80 + 1 more...
Session Affinity: None
External Traffic Policy: Cluster
Events: <none>
Port forwarding
목적
- master node에서 접속할 pod를 대상으로 port forwarding을 해주는 것입니다.
- process레벨로 돌아가기 때문에 매번 설정을 해줘야 돼서 테스트할 때만 사용하는 게 좋음
생성
배포할 Pod
root@master:~/k8s_yaml# cat nginx-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
spec:
containers:
- name: nginx
image: nginx:1.14.2
명령어
#kubectl port-forward --address 0.0.0.0 nginx-pod 80:80
external name
목적
DNS를 통하여 외부 서비스를 연결하기 위해서 사용합니다.
아래 yaml 설정에 metedata의 name의 이용하여 pod 내부의 container들이 www.google.com 과 통신을 할 수 있습니다.
생성
command
#kubelet create service externalname my-external-service --external-name www.google.com
YAML
yaml 파일의 생성은 command 명령에 --dry-run=client -o yaml을 추가하여 만들었습니다.
apiVersion: v1
kind: Service
metadata:
creationTimestamp: null
labels:
app: my-external-service
name: my-external-service
spec:
externalName: www.google.com
type: ExternalName
status:
loadBalancer: {}
삭제
kubectl delete service <service name>
Service 설정 구조
#kubectl describe service ex-name
Name: my-external-service
Namespace: default
Labels: app=my-external-service
Annotations: <none>
Selector: app=my-external-service
Type: ExternalName
IP Families: <none>
IP:
IPs: <none>
External Name: www.google.com
Session Affinity: None
Events: <none>
확인
busybox 이미지를 이용하여 my-external-service으로 ping이 가는지 확인합니다.
Plugin Service
다른 Post에서....
정리
k8s에서 service란 Pod를 외부로 노출시키기 위한 Object입니다.
Service의 종류는 다음과 같습니다.
ClusterIP : cluster 내부에서만 사용 가능
NodePort : cluster 외부에서 특정 Port 대역대로만 접속 가능하게 하는 용도
Portforwarding : Pod 하나만 테스트 용도로 외부에서 접속 가능하게 하고 싶을 때 사용
ExternalName : 외부 URL와 연동을 위한 용도
Next Post
'Cloud > k8s-CKA' 카테고리의 다른 글
[CKA] 30. CoreDNS (0) | 2023.07.25 |
---|---|
[CKA] - network 문제 해결 tip (0) | 2023.07.25 |
[CKA] 28. Pod의 Networking 과 Weave CNI (0) | 2023.07.20 |
[CKA] - 시험 틀린 문제 (0) | 2023.07.19 |
[CKA] 27. CNI란? (0) | 2023.07.16 |