쿠버네티스

[쿠버네티스] 쿠버네티스 서비스 객체 사용 하기

트리스탄1234 2024. 3. 7. 05:40
728x90
반응형

안녕하세요 이웃님들 ^.^
좋은 아침 입니다. 
 
오늘은 쿠버 네티스의 서비스 객체의 종류 및 생성과 관리 방법에 대해서 포스팅 해보겠습니다.
우선 Deplpoyment를 이용해 Pod를 생성하고 Service를 이용해 Pod를 연결 해보겠습니다.
 
Service는 Pod로 실행중인 애플리케이션을 네트워크 서비스로 노출하는 추상화 방법입니다. Pod는 생성되면 고유의 IP를 가지지만 수시로 생성/삭제/확장되는 환경을 감안하면, 주어진 Pod의 IP로 서비스를 이용하는것은 불가능합니다. 그래서, Kubernetes에서는 Service라는 리소스를 사용하여

  • 고정된 IP
  • 여러개의 Pod에 대한 Loadbalancing

을 제공합니다.
Service는 외부사용자나 시스템이 접근할 때도, 클러스터 내부의 Pod들 간에도 적용됩니다.
 
서비스 객체의 종류는 아래와 같이 3가지가 있습니다.

  • ClusterIP: 클러스터 내부용으로 사용하는 서비스 객체 입니다. 외부에서는 접속이 불가능 합니다.
  • NodePort: 외부에서 Worker Node로 접속시 특정 Port로 접속이 가능하게 해줍니다. 
  • Loadbalance : 클라우드 공급자의 로드 밸런서를 사용해서 서비스를 외부에 노출 시킵니다. 
  • Ingress:   NodePortLoadBalancer 와 마찬가지로 애플리케이션의 Service를 외부로 노출할때 사용되는 리소스입니다. 외부에서 들어온 HTTP와 HTTPS 트래픽을 ingress resouce를 생성하여 Cluster내부의 Service로 L7영역에서 라우팅하며 로드밸런싱, TLS, 도메인 기반의 Virtual Hosting을 제공합니다

그림으로 간단히 나타내면 아래와 같습니다. 

 
 
1. Deployment yaml 을 아래의 내용으로 생성을 합니다..

ubuntu@ip-172-31-31-84:~/dockertext2/chap07$ vi test-deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-nginx-deployment
  labels:
    app: my-nginx
    tier: frontend
spec:
  replicas: 3
  strategy:
    type: RollingUpdate
  selector:
    matchLabels:
      app: my-nginx
  template:
    metadata:
      labels:
        app: my-nginx
    spec:
      containers:
      - image: nginx:1.19.3
        name: my-nginx
        ports:
        - containerPort: 80

 
2. 아래와 같이 만든 Deployment를 이용해 Pod를 생성하고 조회를 합니다.

ubuntu@ip-172-31-31-84:~/dockertext2/chap07$ kubectl apply -f test-deployment.yaml
deployment.apps/my-nginx-deployment created
ubuntu@ip-172-31-31-84:~/dockertext2/chap07$ kubectl get pod -o wide
NAME                                   READY   STATUS    RESTARTS   AGE   IP           NODE              NOMINATED NODE   READINESS GATES
my-nginx-deployment-55985c7fcf-q7p7t   1/1     Running   0          8s    172.17.0.6   ip-172-31-31-84   <none>           <none>
my-nginx-deployment-55985c7fcf-t7m69   1/1     Running   0          8s    172.17.0.7   ip-172-31-31-84   <none>           <none>
my-nginx-deployment-55985c7fcf-v55d4   1/1     Running   0          8s    172.17.0.3   ip-172-31-31-84   <none>           <none>

 
3. 이제 다른 Pod를 아래 명령을 통해 생성을 합니다. 

ubuntu@ip-172-31-31-84:~/dockertext2/chap07$ kubectl run curlpod --image=radial/busyboxplus:curl --command -- /bin/sh -c "while true; do echo hi; sleep 10; done"
pod/curlpod created

ubuntu@ip-172-31-31-84:~/dockertext2/chap07$ kubectl get pod -o wide
NAME                                   READY   STATUS    RESTARTS   AGE    IP           NODE              NOMINATED NODE   READINESS GATES
curlpod                                1/1     Running   0          22s    172.17.0.8   ip-172-31-31-84   <none>           <none>
my-nginx-deployment-55985c7fcf-q7p7t   1/1     Running   0          102s   172.17.0.6   ip-172-31-31-84   <none>           <none>
my-nginx-deployment-55985c7fcf-t7m69   1/1     Running   0          102s   172.17.0.7   ip-172-31-31-84   <none>           <none>
my-nginx-deployment-55985c7fcf-v55d4   1/1     Running   0          102s   172.17.0.3   ip-172-31-31-84   <none>           <none>
ubuntu@ip-172-31-31-84:~/dockertext2/chap07$

 
4. 그럼 이제 Service객체 중 ClusterIP Type의 서비스 하나를 생성해서 앞서 Deployment로 생성된 Pod들로 서비스가 요청될 경우 생성한 Service객체를 통해서 접속 가능하게 만듭니다. 
1) VI를 통해 아래 내용의 YAML 파일을 만들고 생성 후 조회를 합니다. 

ubuntu@ip-172-31-31-84:~/dockertext2/chap07$ kubectl apply -f test-service.yaml
service/nginx-clusterip-service created

ubuntu@ip-172-31-31-84:~/dockertext2/chap07$ kubectl get service -o wide
NAME                      TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE   SELECTOR
kubernetes                ClusterIP   10.96.0.1      <none>        443/TCP   23h   <none>
nginx-clusterip-service   ClusterIP   10.98.129.94   <none>        80/TCP    13s   app=my-nginx
ubuntu@ip-172-31-31-84:~/dockertext2/chap07$

 
5. 그럼 이제 Service의 IP를 통해 Pod로 서비스를 요청을 해보겠습니다. 

ubuntu@ip-172-31-31-84:~/dockertext2/chap07$ kubectl exec -it curlpod -- curl http://10.98.129.94
<!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>
ubuntu@ip-172-31-31-84:~/dockertext2/chap07$

 
kubectl exec -it curlpod -- curl http://10.98.129.94
위 명령은 curlpod에서 curl 명령으로 service에 http 요청 메세지를 보내는 명령 입니다. 
조회 결과는 정상적으로 http 응답을 받았습니다. 그리고 Cluster IP대신 service객체의 이름을 통해서도 가능 합니다. 
 
이름으로 접속이 가능한 이유는 클러스터 내부에서 K8S DNS에서 Name을 IP로 변환해 주기 때문 입니다. 
cirlpod에서 /etc/resolv.conf 파일을 아래와 같이 조회를 해보면 search부분에서 서비스 객체가 지정이 되어 있기 때문입니다.

ubuntu@ip-172-31-31-84:~/dockertext2/chap07$ kubectl exec -it curlpod -- cat /etc/resolv.conf
nameserver 10.96.0.10
search default.svc.cluster.local svc.cluster.local cluster.local ec2.internal
options ndots:5
ubuntu@ip-172-31-31-84:~/dockertext2/chap07$

 
6. 이제 NodePort Type의 Service객체를 아래와 yaml을 통해 생성해 봅시다.
  1) yaml파일을 아래와 같이 생성 합니다.

ubuntu@ip-172-31-31-84:~/dockertext2/chap07$ vi test-nodeport.yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx-nodeport-service
spec:
  type: NodePort
  selector:
    app: my-nginx
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
      nodePort: 30007

 
  2) yaml 파일로 service를 생성하고 조회를 해봅니다.

ubuntu@ip-172-31-31-84:~/dockertext2/chap07$ kubectl apply -f test-nodeport.yaml
service/nginx-nodeport-service created
ubuntu@ip-172-31-31-84:~/dockertext2/chap07$ kubectl get svc -o wide
NAME                      TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE   SELECTOR
kubernetes                ClusterIP   10.96.0.1       <none>        443/TCP        24h   <none>
nginx-clusterip-service   ClusterIP   10.98.129.94    <none>        80/TCP         13m   app=my-nginx
nginx-nodeport-service    NodePort    10.97.173.120   <none>        80:30007/TCP   14s   app=my-nginx

ClusterIP Type과 다른 부분을 찾아 보면 PORT부분 입니다. 외부에서 80 포트로 들어 오면 30007번으로 내부로 전달 합니다. 이제 http://Node IP:30007로 접속을 시도를 해보면 아래와 같이 정상적으로 접속이 되는 것을 확인 할수 있습니다. 

7. 그럼 이제 Ingress형태의 Service를 생성해 보겠습니다. 
  1) 아래 내용의 YAML파일을 생성 합니다. 

ubuntu@ip-172-31-31-84:~$ vi test-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-nginx-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
  rules:
    - host: my-nginx.io
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: nginx-clusterip-service
                port:
                  number: 80

host: my-nginx.io로 접속을 시도를 하면 DNS에서 Node의 IP를 Client에게 전달해 주고 클라이언트는 MY-NGINX.IO로 접속이 가능하게 되는데요. DNS에 등록을 하면 등록비가 드니까.. host파일에 수동으로 입력 하여 시험 하는 방식으로 진행을 하겠습니다.
 
  2) 생성한 YAML파일을 이용해 Ingress를 생서하고 조회를 합니다. 

ubuntu@ip-172-31-31-84:~$ kubectl apply -f test-ingress.yaml
ingress.networking.k8s.io/my-nginx-ingress created
ubuntu@ip-172-31-31-84:~$
ubuntu@ip-172-31-31-84:~$
ubuntu@ip-172-31-31-84:~$ kubectl get ingress
NAME               CLASS   HOSTS         ADDRESS   PORTS   AGE
my-nginx-ingress   nginx   my-nginx.io             80      20s

 3) 그럼 이제 본인이 사용하는 pc의 host파일에 아래의 정보를 입력 합니다. 

  • Windows라면 C:\Windows\System32\drivers\etc\hosts 파일에,
  • Linux계열은 /etc/hosts 파일에 추가하면 됩니다.
11.22.33.44  my-nginx.io

4)http://my-nginx.io 주소를 웹 브라우저에 입력하여 접속을 하면 아래와 같이 정상 접속이 됨을 확인 할수 있습니다. 

728x90
반응형