✔️ Service - NodePort
svc.spec.type
- ClusterIP: 클러스터 내에서 사용하는 LB
- NodePort: 클러스터 외부에서 접근하는 포인트
- LoadBalancer: 클러스터 외부에서 접근하는 LB
vagrant@k8s-node1 ~ kubectl explain svc.spec.type
"NodePort" builds on ClusterIP and allocates a port on every node which
routes to the same endpoints as the clusterIP. "LoadBalancer" builds on
NodePort and creates an external load-balancer (if supported in the current
cloud) which routes to the same endpoints as the clusterIP. "ExternalName"
aliases this service to the specified externalName. Several other fields do
not apply to ExternalName services. More info:
https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types
vagrant@k8s-node1 ~ kubectl explain svc.spec.ports
nodePort <integer>
The port on each node on which this service is exposed when type is
NodePort or LoadBalancer. Usually assigned by the system. If a value is
specified, in-range, and not in use it will be used, otherwise the
operation will fail. If not specified, a port will be allocated if this
Service requires one. If this field is specified when creating a Service
which does not need it, creation will fail. This field will be wiped when
updating a Service to no longer need it (e.g. changing type from NodePort
to ClusterIP). More info:
https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport
NodePort
타입을 지정할 수 있다.
myweb-svc-np.yaml
apiVersion: v1
kind: Service
metadata:
name: myweb-svc-np
spec:
type: NodePort
selector:
app: web
ports:
- port: 80
targetPort: 8080
#NodePort: 생략 가능한 필드
myweb-svc.yaml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: myweb-rs
spec:
replicas: 3
selector:
matchLabels: # 달라지는 부분
app: web
env: dev
template:
metadata:
labels:
app: web
env: dev
spec:
containers:
- name: myweb
image: ghcr.io/c1t1d0s7/go-myweb
ports:
- containerPort: 8080
protocol: TCP
vagrant@k8s-node1 ~/svc/nodeport kubectl get rs,po,svc
NAME DESIRED CURRENT READY AGE
replicaset.apps/myweb-rs 3 3 3 16h
NAME READY STATUS RESTARTS AGE
pod/myweb-rs-6mzrh 1/1 Running 1 (9m16s ago) 16h
pod/myweb-rs-sw2m7 1/1 Running 1 (8m43s ago) 16h
pod/myweb-rs-vjkjc 1/1 Running 1 (8m18s ago) 16h
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.233.0.1 <none> 443/TCP 16h
service/myweb-svc-np NodePort 10.233.21.104 <none> 80:30532/TCP 23s
NodePort
타입이며 서비스의 ip(10.233.21.104
)가 존재한다.EXTERNAL-IP
는 별도로 없으며 포트의 정보가 다르다.
✔️ NodePort의 범위
vagrant@k8s-node1 /etc/kubernetes/manifests pwd
/etc/kubernetes/manifests
vagrant@k8s-node1 /etc/kubernetes/manifests sudo grep node-port kube-apiserver.yaml
- --service-node-port-range=30000-32767
kube-apiserver.yaml
파일에서 --service-node-port-range
설정을 볼 수 있으며,NodePort
에 사용가능한 포트 번호의 범위가 30000-32767 인 것을 확인할 수 있다.
필요하다면 kubespray
또는 kubeadm
으로 설치할 때 옵션을 통해 NodePort
의 범위를 지정할 수 있다.
하지만 0 ~ 1023 포트는 WellKnown Port
로 일반적으로 서비스에 사용하는 포트 범위이므로 포트 충돌이 발생할 수 있다.
https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xhtml
포트 범위에 대해 세가지 범위로 세팅해 놓은 것이 있다.
System Ports(WellKnown Ports)
: 0 ~ 1023 / 시스템이 사용하는 포트 /반드시 root 권한이 있어야 함/ 대부분의 주요 서비스 할당User Ports(Registered Ports)
: 1024 ~ 49151 / 등록해서 사용 가능한 포트, 강제 사항 없음 / 주요하지 않은 서비스 할당 / 관리자 권한 필요 없음Dynamic and/or Private
: 49152 ~ 65535 / 클라이언트가 사용하는 포트 /
Web Browser가 Web Server에 접근할 때는 HTTP는 80 포트, HTTPS는 443 포트를 사용한다.
웹 브라우저(크롬, 파이어폭스, 엣지, 사파리 등)가 사용하는 포트가 있다.
일반적으로 Dynamic and/or Private
범위 내에 있는 포트를 사용한다.
(참고로 Windows는 위의 내용을 지키지 않으며 1024번 이상 임의의 포트를 사용한다.)
따라서 Source Port(출발지 포트)범위인 49152 ~ 65535 사이의 포트는 사용할 수 없고 User Ports(Registered Ports)
의 일부분을 사용하기로 정한 것이 30000-32767 포트인 것이다.
이 범위는 조정할 수 있으며 현재 설정으로는 2768개만 만들 수 있다. 외부에 노출시킬 더 많은 서비스가 있다면 처음부터 범위를 크게 잡아야 한다.
vagrant@k8s-node1 /etc/kubernetes/manifests sudo ss -tnlp
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 4096 0.0.0.0:30532 0.0.0.0:* users:(("kube-proxy",pid=2349,fd=14))
kube-proxy
에 의해 서버가 열려있음을 확인할 수 있다.
vagrant@k8s-node1 /etc/kubernetes/manifests ssh node2 sudo ss -tnlp | grep proxy
LISTEN 0 4096 0.0.0.0:30532 0.0.0.0:* users:(("kube-proxy",pid=2266,fd=14))
LISTEN 0 4096 127.0.0.1:10249 0.0.0.0:* users:(("kube-proxy",pid=2266,fd=13))
LISTEN 0 4096 *:10256 *:* users:(("kube-proxy",pid=2266,fd=12))
vagrant@k8s-node1 /etc/kubernetes/manifests ssh node3 sudo ss -tnlp | grep proxy
LISTEN 0 4096 0.0.0.0:30532 0.0.0.0:* users:(("kube-proxy",pid=1432,fd=12))
LISTEN 0 4096 127.0.0.1:10249 0.0.0.0:* users:(("kube-proxy",pid=1432,fd=15))
LISTEN 0 4096 *:10256 *:* users:(("kube-proxy",pid=1432,fd=13))
node2, 3에도 마찬가지로 30532 포트가 열려있다.
모든 node에 포트가 열린다. 그림으로 그리면 이런 형태가 된다.
NodePort = NodePort + ClusterIP
우리는 NodePort
라는 서비스를 사용하지만 NodePort
는 결국 ClusterIP
기반이 구성이되고 그 위에 해당되는 node의 port가 추가적으로 열리게 된다.
NodePort
라는 것은 ClusterIP
와 다른 것이 아니라 CluterIP
기능에 NodePort
기능이 추가된 형태이다.
그래서 외부로 노출시킬 수 있는 것이다.
vagrant@k8s-node1 ~/svc/nodeport curl 192.168.100.100:30532
Hello World!
myweb-rs-sw2m7
vagrant@k8s-node1 ~/svc/nodeport curl 192.168.100.100:30532
Hello World!
myweb-rs-vjkjc
vagrant@k8s-node1 ~/svc/nodeport curl 192.168.100.100:30532
Hello World!
myweb-rs-6mzrh
vagrant@k8s-node1 ~/svc/nodeport curl 192.168.100.101:30532
Hello World!
myweb-rs-sw2m7
vagrant@k8s-node1 ~/svc/nodeport curl 192.168.100.101:30532
Hello World!
myweb-rs-vjkjc
vagrant@k8s-node1 ~/svc/nodeport curl 192.168.100.101:30532
Hello World!
myweb-rs-6mzrh
vagrant@k8s-node1 ~/svc/nodeport curl 192.168.100.102:30532
Hello World!
myweb-rs-sw2m7
vagrant@k8s-node1 ~/svc/nodeport curl 192.168.100.102:30532
Hello World!
myweb-rs-vjkjc
vagrant@k8s-node1 ~/svc/nodeport curl 192.168.100.102:30532
Hello World!
myweb-rs-6mzrh
기본적으로 라운드 로빈 방식으로 로드 밸런싱이 되며, 어떤 node의 port로 가던지 해당되는 서비스로 연결된다.
myweb-svc-np.yaml
apiVersion: v1
kind: Service
metadata:
name: myweb-svc-np
spec:
type: NodePort
selector:
app: web
ports:
- port: 80
targetPort: 8080
nodePort: 31313 # 커스텀 포트 변경
포트를 변경한 후 다시 생성하면,
vagrant@k8s-node1 ~/svc/nodeport kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.233.0.1 <none> 443/TCP 17h
myweb-svc-np NodePort 10.233.1.140 <none> 80:31313/TCP 19s
vagrant@k8s-node1 ~/svc/nodeport curl 192.168.100.100:31313
Hello World!
myweb-rs-sw2m7
어떤 노드로 접근하던 상관없이 클러스터 외부에서 접근할 수 있는 것을 확인할 수 있다.
'DevOps > Kubernetes' 카테고리의 다른 글
[Kubernetes] Service - ExternalName (0) | 2022.05.23 |
---|---|
[Kubernetes] Service - LoadBalancer ( + METALLB : on-prem 환경의 LB) (0) | 2022.05.23 |
[Kubernetes] Service - Service Discovery (2) (0) | 2022.05.21 |
[Kubernetes] Service - Service Discovery (1) (0) | 2022.05.21 |
[Kubernetes] Service - ClusterIP (0) | 2022.05.20 |
영차영차 성장 블로그
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!