Software Workshop

사전 준비

MiniKube로_Kubernetes_설치하기

deployment(배포작업) 생성

deployment 생성

deployment는 pod가 동작하게 만드는 규칙에 대한 정의라고 할 수 있다. 결국 service를 배포하는 작업을 의미하고 생성과 노출의 두 단계로 나눠져 있다.

kubectl create deployment hello-minikube --image=k8s.gcr.io/echoserver:1.4

deployment 조회

kubectl get deployments
NAME             READY   UP-TO-DATE   AVAILABLE   AGE
hello-minikube   1/1     1            1           5m44s

hello-minikube라는 deployment가 생성되어 있음을 확인할 수 있다.

kubectl get services
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   13m

아직 "hello-minikube" service는 생성되지 않았다.

kubectl get pods
NAME                              READY   STATUS    RESTARTS   AGE
hello-minikube-7bc9d7884c-flgk6   1/1     Running   0          6m

pod는 생성되었고 deployment 이름 뒤에 UUID를 붙여서 만들기 때문에 매 생성 시마다 달라진다.

1) NodePort를 이용한 배포작업 노출 및 서비스 생성

구조

actor client

cloud K8sCluster {
package Service {
package NodePort {
component NodePort_8080
component NodePort_3xxxx
}
}

node Node1 {
component Pod1 
component Pod2 
}

node Node2 {
component Pod3 
component Pod4
}
}

client --> Service: 7080, 3xxxx
NodePort_8080 --> Pod1: 8080
NodePort_8080 --> Pod3: 8080

Service --> NodePort_8080: 7080

Service --> NodePort_3xxxx: 3xxxx
NodePort_3xxxx --> Pod2: 3xxxx
NodePort_3xxxx --> Pod4: 3xxxx

NodePort란 각 node(서버)가 가지는 포트를 의미하고, 이렇게 열린 포트는 내부 서비스로 포트 포워딩을 해줘야 한다.

배포

우선, 다음과 같이 deployment를 노출시킨다.

kubectl expose deployment hello-minikube --type=NodePort --port=8080

자동으로 service가 생성/배포되며 같은 이름으로 존재하게 된다. 이 서비스는 8080이라는 포트에 바인딩된다.

service 확인

deployment를 노출하면 service가 자동 생성된다. 같은 이름의 서비스가 생성되어 있음을 확인할 수 있다.

kubectl get deployments
NAME             READY   UP-TO-DATE   AVAILABLE   AGE
hello-minikube   1/1     1            1           4m39s
kubectl get services 
NAME             TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
hello-minikube   NodePort    10.107.246.105   <none>        8080:30929/TCP   2m39s
kubernetes       ClusterIP   10.96.0.1        <none>        443/TCP          20m

deployments는 이미 생성된 상태여서 변화가 없지만, service는 동일한 이름으로 생성된다.
이 서비스에 할당된 IP와 포트로는 여전히 접근이 불가능하다.

deployment와 service와 pod의 차이

포트 포워딩

kubectl port-forward service/hello-minikube 7080:8080

이 명령은 background daemon으로 실행되지 않고 foreground로 실행된다.
이제부터 localhost:7080으로 접근 가능해진다.
위 구조도에서 NodePort1_7080에 대해 포트 포워딩을 켜준 것이다.

또는, minikube를 이용하여 포트 포워딩을 해줄 수 있다.

minikube service hello-minikube

이 경우에는 minikube가 임의의 포트를 부여해 준다.

|-----------|----------------|-------------|---------------------------|
| NAMESPACE |      NAME      | TARGET PORT |            URL            |
|-----------|----------------|-------------|---------------------------|
| default   | hello-minikube |        8080 | http://192.168.49.2:30079 |
|-----------|----------------|-------------|---------------------------|
🏃  hello-minikube 서비스의 터널을 시작하는 중
|-----------|----------------|-------------|------------------------|
| NAMESPACE |      NAME      | TARGET PORT |          URL           |
|-----------|----------------|-------------|------------------------|
| default   | hello-minikube |             | http://127.0.0.1:65393 |
|-----------|----------------|-------------|------------------------|
🎉  Opening service default/hello-minikube in default browser...
❗  Because you are using a Docker driver on darwin, the terminal needs to be open to run it.

서비스 접근 확인하기

curl localhost:7080
curl -X POST -d 'msg=hello%20world' localhost:7080

외부에 노출하는 포트는 7080으로 잡고 내부에서 nodeport가 잡은 8080에 연결되도록 설정한다.

2) LoadBalancer를 이용한 배포작업 노출 및 서비스 생성

구조

actor client


cloud K8sCluster {
cloud LoadBalancer
node Service

package Node1 {
component NodePort1_3xxxx
package Pod1 
package Pod2 
}

package Node2 {
component NodePort2_3xxxx
package Pod3 
package Pod4
}
}

client --> LoadBalancer: 8080
LoadBalancer --> Service: 8080
LoadBalancer --> Service: 8080

Service --> NodePort1_3xxxx: 3xxxx
Service --> NodePort2_3xxxx: 3xxxx

NodePort1_3xxxx --> Pod1
NodePort1_3xxxx --> Pod2
NodePort2_3xxxx --> Pod3
NodePort2_3xxxx --> Pod4

배포

kubectl expose deployment hello-minikube --type=LoadBalancer --port=8080
kubectl get services
NAME             TYPE           CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
hello-minikube   LoadBalancer   10.102.223.116   <pending>     8080:30389/TCP   2m
kubernetes       ClusterIP      10.96.0.1        <none>        443/TCP          51m

EXTERNAL-IP가 아직 설정되지 않은 것을 확인할 수 있다.

터널링

minikube가 제공하는 ssh 터널링 기능을 이용하여 service에 대한 접근이 가능하다.

minikube tunnel

8080 포트를 클러스터의 8080 포트로 터널링해 준다.

내부적으로는 ingress를 실행하고 여기에 외부 IP를 할당하고 동일한 포트번호로 터널링한다. (외부에 IP를 노출시키는 효과)

kubectl get serivce -o yaml hello-minikube
status:
  loadBalancer:
    ingress:
    - ip: 127.0.0.1

서비스 확인하기

kubectl get services
NAME             TYPE           CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
hello-minikube   LoadBalancer   10.102.223.116   127.0.0.1     8080:30389/TCP   11m
kubernetes       ClusterIP      10.96.0.1        <none>        443/TCP          60m

EXTERNAL-IP가 설정된 것을 확인할 수 있다.

curl localhost:8080

기존에 생성되어 있던 서비스와 배포작업 삭제가 필요하다면?

혹시 기존 deployment를 제거해야 한다면 다음과 같이 실행하면 된다. 우선 노출된 deployment를 비노출처리하고 service를 삭제한다.

kubectl delete service hello-minikube

생성되어 있던 deployment까지 삭제하려면 다음 명령을 수행하면 된다.

kubectl delete deployment hello-minikube

참고자료