ClusterIP - "단일 진입점 생성(내부)"
- selector의 label가 동일한 파드들의 그룹으로 묶어 단일 진입점(Virtual IP)을 생성
- 클러스터 내부에서만 사용 가능
- type 생략 시 default 값으로 10.96.0.0/12 범위에 할당됨
- ClusterIP는 고정 시켜도 되고, 고정 시키지 않아도 되지만 고정시키지 않는 이유는 충돌을 예방하기 위함
deploy-nginx.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: webui
spec:
replicas: 3
selector:
matchLabels:
app: webui
template:
metadata:
name: nginx-pod
labels:
app: webui
spec:
containers:
- name: nginx-container
image: nginx:1.14
ClusterIP 테스트 전 먼저 pod를 생성한다.
# kubectl create -f deploy-nginx.yaml
deployment.apps/webui created
# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
webui-5cfbcf5f65-plpx6 1/1 Running 0 7s 10.36.0.2 node1.example.com <none> <none>
webui-5cfbcf5f65-q9tc8 1/1 Running 0 7s 10.44.0.1 node2.example.com <none> <none>
webui-5cfbcf5f65-w94c5 1/1 Running 0 7s 10.36.0.1 node1.example.com <none> <none>
clusterip-nginx.yaml
- 10.100.100.100 ClusterIP를 생성하여 webui의 단일진입점으로 사용
- clusterip:protocal → pod:port 로 통신
apiVersion: v1
kind: Service
metadata:
name: clusterip-service
spec:
type: ClusterIP
clusterIP: 10.100.100.100
selector:
app: webui
ports:
- protocol: TCP
port: 80
targetPort: 80
ClusterIP 생성
# kubectl create -f clusterip-nginx.yaml
service/clusterip-service created
# kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
clusterip-service ClusterIP 10.100.100.100 <none> 80/TCP 6s
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 20d
mydb ClusterIP 10.104.64.225 <none> 80/TCP 14d
myservice ClusterIP 10.97.82.81 <none> 80/TCP 14d
ClusterIP를 describe로 확인하면 Endpoints 에 ClusterIP에 연결되는 pod 확인 가능
# kubectl describe service clusterip-service
Name: clusterip-service
Namespace: default
Labels: <none>
Annotations: <none>
Selector: app=webui
Type: ClusterIP
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.100.100.100
IPs: 10.100.100.100
Port: <unset> 80/TCP
TargetPort: 80/TCP
Endpoints: 10.36.0.1:80,10.36.0.2:80,10.44.0.1:80
Session Affinity: None
Events: <none>
curl 명령어로 pod 연결 확인
# curl 10.100.100.100
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
ClusterIP를 통해 pod 접근시 라운드 로빈으로 접근하는지 체크하기 위해서 pod에 직접 접근해서 index.html 수정
# kubectl exec webui-5cfbcf5f65-plpx6 -it -- /bin/bash
# cd /usr/share/nginx/html/
# echo "webui #1" > index.html
# kubectl exec webui-5cfbcf5f65-q9tc8 -it -- /bin/bash
# cd /usr/share/nginx/html/
# echo "webui #2" > index.html
# kubectl exec webui-5cfbcf5f65-w94c5 -it -- /bin/bash
# cd /usr/share/nginx/html/
# echo "webui #3" > index.html
curl 명령어를 이용하여 ClusterIP 호출 테스트하면 라운드로빈으로 1개씩 순차적으로 호출하지는 않고 균등하게 랜덤으로 호출
# curl 10.100.100.100
webui #2
# curl 10.100.100.100
webui #1
# curl 10.100.100.100
webui #2
# curl 10.100.100.100
webui #1
# curl 10.100.100.100
webui #3
# curl 10.100.100.100
webui #2
pod를 3개에서 5개 늘릴 경우 ClusterIP의 Endpoints에 알아서 조절이됨
# kubectl scale deployment webui --replicas=5
deployment.apps/webui scaled
# kubectl describe svc clusterip-service
Name: clusterip-service
Namespace: default
Labels: <none>
Annotations: <none>
Selector: app=webui
Type: ClusterIP
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.100.100.100
IPs: 10.100.100.100
Port: <unset> 80/TCP
TargetPort: 80/TCP
Endpoints: 10.36.0.1:80,10.36.0.2:80,10.36.0.3:80 + 2 more...
Session Affinity: None
Events: <none>
Nodeport - "CluserIP + 외부접속"
- 모든 노드를 대상으로 외부 접속 가능한 포트를 예약
- Default NodePort 범위 : 30000-32767
- ClusterIP를 생성 후 NodePort를 예약
nodeport-nginx.yaml
- ClusterIP, nodeport는 입력하지 않으면 랜덤으로 들어감
apiVersion: v1
kind: Service
metadata:
name: nodeport-service
spec:
type: NodePort
clusterIP: 10.100.100.200
selector:
app: webui
ports:
- protocol: TCP
port: 80
targetPort: 80
nodePort: 30200
nodeport-nginx.yaml 실행 후 PORT 부분 확인 80:32000
# kubectl create -f nodeport-nginx.yaml
service/nodeport-service created
# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 39s
nodeport-service NodePort 10.100.100.200 <none> 80:30200/TCP 4s
노드 서버에 접속해서 30200 port가 오픈되어 있는지 확인
netstat 명렁어를 통해 확인시 아무것도 나오지 않는다. 1.25 버전에서는 이전 버전과 다르게 매커니즘이 달라졌다고 한다.
(kube-proxy → dnat 포워딩)
# netstat -napt | grep 30200
아래 명령어로 다시 확인시 port가 오픈되어 있는것을 확인 가능
node1:~# iptables -t nat -L KUBE-NODEPORTS | column -t
Chain KUBE-NODEPORTS (1 references)
target prot opt source destination
KUBE-EXT-QATUYZLPU4I4HE4S tcp -- anywhere anywhere /* default/nodeport-service */ tcp dpt:30200
node2:~# iptables -t nat -L KUBE-NODEPORTS | column -t
Chain KUBE-NODEPORTS (1 references)
target prot opt source destination
KUBE-EXT-QATUYZLPU4I4HE4S tcp -- anywhere anywhere /* default/nodeport-service */ tcp dpt:30200
노드 ip:port를 이용하여 접근
# kubectl get nodes -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
master.example.com Ready control-plane 20d v1.25.4 10.100.0.104 <none> Ubuntu 20.04.3 LTS 5.15.0-56-generic containerd://1.4.9
node1.example.com Ready <none> 20d v1.25.4 10.100.0.101 <none> Ubuntu 20.04.3 LTS 5.15.0-56-generic containerd://1.4.9
node2.example.com Ready <none> 20d v1.25.4 10.100.0.102 <none> Ubuntu 20.04.3 LTS 5.15.0-56-generic containerd://1.4.9
# curl 10.100.0.101:30200
webui #2
# curl 10.100.0.101:30200
webui #2
# curl 10.100.0.101:30200
webui #3
LoadBalancer - "NodePort + LoadBalancer 지원"
- Public 클라우드(AWS, Azure, GCP 등)에서 운영 가능
- LoadBalancer를 자동으로 구성 요청
- NodePort를 예약 후 해당 nodeport로 외부 접근을 허용
loadbalancer-nginx.yaml
apiVersion: v1
kind: Service
metadata:
name: loadbalancer-service
spec:
type: LoadBalancer
selector:
app: webui
ports:
- protocol: TCP
port: 80
targetPort: 80
Public 클라우드였다면 외부에서 접근할 수 있는 IP가 EXTERNAL-IP에 구성
# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 27s
loadbalancer-service LoadBalancer 10.111.228.226 <pending> 80:30728/TCP 7s
ExternalName
- 클러스터 내부에서 External(외부)의 도메인을 설정
- DNS를 지원
- /etc/hosts와 같은 역할
external-exam.yaml
apiVersion: v1
kind: Service
metadata:
name: externalname-svc
spec:
type: ExternalName
externalName: google.com
root@master:~/7# cat external-name.yaml
apiVersion: v1
kind: Service
metadata:
name: externalname-svc
external-name.yaml 실행
- externalname-svc 으로 호출하면 google.com을 호출
# kubectl create -f external-name.yaml
service/externalname-svc created
# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
externalname-svc ExternalName <none> google.com <none> 47s
pod 생성한 후에 생성한 pod에 접근한 다음에 curl externalname-svc.default.svc.cluster.local 호출시 구글 페이지 호출
- default.svc.cluster.local : 쿠버네티스가 내부적으로 사용하는 도메인 이름
# kubectl run testpod -it --image=centos:7
If you don't see a command prompt, try pressing enter.
[root@testpod /]# curl externalname-svc.default.svc.cluster.local
<!DOCTYPE html>
<html lang=en>
<meta charset=utf-8>
<meta name=viewport content="initial-scale=1, minimum-scale=1, width=device-width">
<title>Error 404 (Not Found)!!1</title>
<style>
*{margin:0;padding:0}html,code{font:15px/22px arial,sans-serif}html{background:#fff;color:#222;padding:15px}body{margin:7% auto 0;max-width:390px;min-height:180px;padding:30px 0 15px}* > body{background:url(//www.google.com/images/errors/robot.png) 100% 5px no-repeat;padding-right:205px}p{margin:11px 0 22px;overflow:hidden}ins{color:#777;text-decoration:none}a img{border:0}@media screen and (max-width:772px){body{background:none;margin-top:0;max-width:none;padding-right:0}}#logo{background:url(//www.google.com/images/branding/googlelogo/1x/googlelogo_color_150x54dp.png) no-repeat;margin-left:-5px}@media only screen and (min-resolution:192dpi){#logo{background:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) no-repeat 0% 0%/100% 100%;-moz-border-image:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) 0}}@media only screen and (-webkit-min-device-pixel-ratio:2){#logo{background:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) no-repeat;-webkit-background-size:100% 100%}}#logo{display:inline-block;height:54px;width:150px}
</style>
<a href=//www.google.com/><span id=logo aria-label=Google></span></a>
<p><b>404.</b> <ins>That’s an error.</ins>
<p>The requested URL <code>/</code> was not found on this server. <ins>That’s all we know.</ins>
[참고]
- https://www.youtube.com/watch?v=WaJyY5KvZj8&list=PLApuRlvrZKohaBHvXAOhUD-RxD0uQ3z0c&index=26
'Kubernetes' 카테고리의 다른 글
[Kubernetes] Ingress 개념과 Ingress Controller 설치 (0) | 2022.12.14 |
---|---|
[Kubernetes] Headless Service와 Kube Proxy (0) | 2022.12.14 |
[Kubernetes] Service 개념과 종류 (0) | 2022.12.13 |
[Kubernetes] CronJob (0) | 2022.12.13 |
[Kubernetes] Job Controller (0) | 2022.12.12 |