본문 바로가기

Cloud/Oracle Cloud Infrastructure

OCI를 이용한 쿠버네티스, Wercker 쉬운 샘플 - 4. OKE 클러스터에 샘플 웹서버 배포

참고 사이트 - Kubernetes Tips: Create Pods With Imperative Commands in 1.18

쿠버네티스 클러스터에 자원을 생성하는 방식은 명령어 방식(Imperative) 선언 방식(Declarative) 있다.

선언 방식 접근 방식은 YAML 또는 JSON 형식으로 매니페스트(manifest) 파일로 “kubectl apply” 명령을 이용하여 클러스터 자원을 만드는 방식으로 주로 운영 환경에서 사용한다.

이에 반해 명령어 방식은 명령어를 통해 클러스터 자원을 관리하는 것으로 매니페스트 파일을 필요로 하지 않는다. 간편하고 빠른 접근 방식이다.

 

먼저 명령어 방식으로 클러스터 자원을 만들어 볼텐데, 클러스터 버전 1.18 기준으로 “kubectl run” 명령의 작동 방식이 변경되었다. 1.18 이전 버전에서는 아래 명령을 수행했을 파드와 함께 디플로이먼트가 생성되고 replicas 옵션도 사용이 가능했다. 일부 옵션에 대해 DEPRECATED 되었다는 경고 메시지와 Workaround 함께 출력되었다.

$ kubectl run nginx --image=nginx --port=80 --replicas=3
kubectl run --generator=deployment/apps.v1 is DEPRECATED and will be removed in a future version. Use kubectl run --generator=run-pod/v1 or kubectl create instead.
deployment.apps/nginx created

1.18 버전 이후의 경우, kubectl run 명령에 replicas 옵션 사용 “Flag --replicas has been deprecated, has no effect and will be removed in the future.” 같은 메시지가 출력되고 레플리카가 만들어지지 않는다. kubectl run 명령으로 파드 생성 디플로이먼트 역시 파드와 함께 생성되지 않는다. “kubectl run nginx  --image=nginx --port=80” 명령 수행 , 이제는 파드만 생성된다. 이는 “run” 서브 명령어 기능이 지나치게 커지는 것을 막기 위해 파드 자체만을 만들때 run 사용하도록 하고 있다.

[opc@inst-public ~]$ kubectl version --client
Client Version: version.Info{Major:"1", Minor:"20", GitVersion:"v1.20.4", GitCommit:"e87da0bd6e03ec3fea7933c4b5263d151aafd07c", GitTreeState:"clean", BuildDate:"2021-02-18T16:12:00Z", GoVersion:"go1.15.8", Compiler:"gc", Platform:"linux/amd64"}

 

먼저 kubectl run 명령으로 파드를 생성해 본다.

- --image: 컨테이너 이미지. 리포지토리 이름이 지정되지 않은 경우 Docker Hub에서 다운로드한다.

[opc@inst-public ~]$ kubectl run nginx  --image=nginx --port=80
pod/nginx created

 

kubectl get pod 명령으로 파드의 정보를 조회해 본다.

- -o wide: IP정보, 배치된 노드 등의 추가 정보를 표시

파드만 생성되어 있고 디플로이먼트는 생성되지 않았음을 있다.

[opc@inst-public ~]$ kubectl get pods -o wide
NAME    READY   STATUS    RESTARTS   AGE   IP           NODE        NOMINATED NODE   READINESS GATES
nginx   1/1     Running   0          12s   10.244.1.2   10.0.10.4   <none>           <none>
[opc@inst-public ~]$ kubectl get deployments
No resources found in default namespace.

 

이번에는 앞에서 생성된 파드를 삭제하고, kuberctl create 명령으로 디플로이먼트를 만들어 파드와 관련 자원을 생성해 본다. 이번에는 –replicas 옵션으로 레플리카도 함께 생성한다.

[opc@inst-public ~]$ kubectl delete pod nginx
pod "nginx" deleted
[opc@inst-public ~]$ kubectl create deployment nginx --image=nginx --port=80 --replicas=3
deployment.apps/nginx created

 

파드 관련 자원들이 생성되어 있음을 있다.

만들어진 디플로이먼트 오브젝트는 “nginx”이며 레플리카셋 컨트롤러와 함께 파드를 관리하여 이미지의 버전, 파드의 개수 등이 목표 상태가 되도록 관리한다.

레플리카셋 오브젝트의 이름은 nginx-d46f5678b 이며, 이는 디플로이먼트 오브젝트 이름 뒤에 해시 문자열을 붙여서 유일한 이름을 부여받는다. 디플로이먼트와 함께 파드의 수가 지정한 개수가 되도록 제어한다.

파드 안에는 하나 또는 여러 개의 컨테이너가 실행된다. 파드의 이름은 레플리카셋 오브젝트의 이름 뒤에 추가적인 해시 문자열이 추가되어 유일한 이름을 부여받는다.

[opc@inst-public ~]$ kubectl get pods -o wide
NAME                    READY   STATUS    RESTARTS   AGE   IP             NODE        NOMINATED NODE   READINESS GATES
nginx-d46f5678b-pfz6w   1/1     Running   0          11s   10.244.0.132   10.0.10.3   <none>           <none>
nginx-d46f5678b-qbch5   1/1     Running   0          11s   10.244.0.4     10.0.10.2   <none>           <none>
nginx-d46f5678b-w2xrk   1/1     Running   0          12s   10.244.1.3     10.0.10.4   <none>           <none>
[opc@inst-public ~]$ kubectl get deployments
NAME    READY   UP-TO-DATE   AVAILABLE   AGE
nginx   3/3     3            3           30s
[opc@inst-public ~]$ kubectl get all
NAME                        READY   STATUS    RESTARTS   AGE
pod/nginx-d46f5678b-pfz6w   1/1     Running   0          44s
pod/nginx-d46f5678b-qbch5   1/1     Running   0          44s
pod/nginx-d46f5678b-w2xrk   1/1     Running   0          45s
 
NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   5h24m
 
NAME                    READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/nginx   3/3     3            3           47s
 
NAME                              DESIRED   CURRENT   READY   AGE
replicaset.apps/nginx-d46f5678b   3         3         3       47s

 

파드의 상태는 kubectl get all 명령 뿐만 아니라 다음과 같은 명령으로도 확인할 있다.

kubectl get deployment(deploy) 명령 칼럼

- READY: 현재 실행 중인 파드 / 디플로이먼트를 만들 설정한 파드

- UP-TO-DATE: 업데이트된 파드 (컨트롤러에 의해 조정된 파드 )

- AVAILABLE: 사용 가능한 파드

[opc@inst-public ~]$ kubectl get deploy,po
NAME                    READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/nginx   3/3     3            3           72s
 
NAME                        READY   STATUS    RESTARTS   AGE
pod/nginx-d46f5678b-pfz6w   1/1     Running   0          71s
pod/nginx-d46f5678b-qbch5   1/1     Running   0          71s
pod/nginx-d46f5678b-w2xrk   1/1     Running   0          72s

 

컨테이너 nginx 로그는 아래와 같이 “kubectl logs 파드명명령으로 확인할 있다.

[opc@inst-public ~]$ kubectl logs pod/nginx-d46f5678b-pfz6w
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up

 

생성된 세개의 파드 하나를 삭제해 본다. 파드 하나를 삭제하게되면 잠시 새로운 파드가 새로운 이름으로 자동으로 만들어진다. Stateless 속성을 가진다.

[opc@inst-public ~]$ kubectl delete pod nginx-d46f5678b-pfz6w
pod "nginx-d46f5678b-pfz6w" deleted
[opc@inst-public ~]$ kubectl get deploy,po
NAME                    READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/nginx   3/3     3            3           4m3s
 
NAME                        READY   STATUS    RESTARTS   AGE
pod/nginx-d46f5678b-7cc5v   1/1     Running   0          14s
pod/nginx-d46f5678b-qbch5   1/1     Running   0          4m2s
pod/nginx-d46f5678b-w2xrk   1/1     Running   0          4m3s

 

디폴이먼트나 파드 정보를 조회할 “-o yaml” 옵션을 사용하면 해당 자원을 만들 사용된 매니페스트 파일 내용을 조회할 있다.

[opc@inst-public ~]$ kubectl get deployment nginx -o yaml
apiVersion: apps/v1
kind: Deployment
metadata:

observedGeneration: 1
  readyReplicas: 3
  replicas: 3
  updatedReplicas: 3
[opc@inst-public ~]$ kubectl get pod nginx-d46f5678b-7cc5v -o yaml
apiVersion: v1
kind: Pod
metadata:

hostIP: 10.0.10.3
  phase: Running
  podIP: 10.244.0.133
  podIPs:
  - ip: 10.244.0.133
  qosClass: BestEffort
  startTime: "2021-03-02T11:29:08Z"

 

디플로이먼트 삭제는 아래 명령으로 수행한다. 디프로이먼트 삭제 소속 레플리카셋, 파드들도 모두 삭제된다.

[opc@inst-public ~]$ kubectl delete deployment nginx
deployment.apps "nginx" deleted
[opc@inst-public ~]$ kubectl get deploy,po
No resources found in default namespace.

 

이번에는 YAML 형식의 매니페스트 파일을 이용한 선언 방식으로 클러스터 자원을 생성해 본다.

매니페스트는 쿠버네티스 오브젝트를 생성하기 위한 메타 정보를 YAML 또는 JSON 형식으로 기술한 파일이다. YAML   JSON 비해 간결하고 가독성이 좋기 때문에 YAML 많이 사용한다.

보통의 경우 디플로이먼트, 레플리카셋 등과 같은 컨트롤러에 대한 매니페스트를 작성하는데, 이때 파드에 대한 정보를 기술하는 부분이 포함된다.

앞서 명령어 방식으로 생성했던 디플로이먼트, 파드와 유사한 자원을 선언 방식으로 생성해 본다. 먼저 아래와 같이 YAML 형식의 매니매스트 파일을 kubectl 수행 호스트에 준비한다.

전체 매니페스트 작성 방법은 다음 문서를 참조한다.

Kubernetes API

아래 YAML 파일은 다음을 의미한다.

- apiVersion:  오브젝트를 생성하기 위해 사용하고 있는 쿠버네티스 API 버전이 어떤 것인지 지정

- kind: 어떤 종류의 오브젝트를 생성하고자 하는지 지정

- metadata: 이름 문자열, UID, 네임스페이스  오브젝트를 유일하게 구분지어  데이터 지정

- spec: 오브젝트에 대해 어떤 상태를 의도하는지 지정. 여기서는 디플로이먼트로 하여금 템플릿에 매칭되는 세개의 파드를 실행할 것을 지시함.

[opc@inst-public ~]$ vi ~/nginx-pod.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:latest
        ports:
        - containerPort: 80

[opc@inst-public ~]$

 

매니페스트 파일을 쿠버네티스 클러스터에 전송하여 오브젝트를 만드는 것은 아래와 같이 kubectl apply 명령으로 수행한다. 앞서 명령어 방식의 클러스터 자원 생성  사용했던 kubectl create 명령과의 차이점은 kubectl apply 경우, 동일한 이름의 오브젝트가 있으면 매니페스트 파일의 내용에 따라 오브젝트의 스펙을 변경하지만, kubectl create 명령은 “Error from server (AlreadyExists): pods "nginx" already exists” 같은 에러를 리턴하게된다.

-f 옵션에는 파일명을 기술하게 되는데 URL 사용할 수도 있기 때문에 GitHub YAML 파일을 그대로 사용할 수도 있다.

[opc@inst-public ~]$ kubectl apply -f ~/nginx-pod.yaml
deployment.apps/nginx-deployment created

 

매니페스트 파일에 기술된 대로 디플로이먼트, 서비스, 파드, 레플리카셋 등이 만들어진 것을   있다.

[opc@inst-public ~]$ kubectl get pods -o wide
NAME                               READY   STATUS    RESTARTS   AGE   IP             NODE        NOMINATED NODE   READINESS GATES
nginx-deployment-cc7df4f8f-dkk27   1/1     Running   0          16s   10.244.0.5     10.0.10.2   <none>           <none>
nginx-deployment-cc7df4f8f-q2scr   1/1     Running   0          17s   10.244.1.4     10.0.10.4   <none>           <none>
nginx-deployment-cc7df4f8f-zqkpx   1/1     Running   0          16s   10.244.0.134   10.0.10.3   <none>           <none>
[opc@inst-public ~]$ kubectl get all
NAME                                   READY   STATUS    RESTARTS   AGE
pod/nginx-deployment-cc7df4f8f-dkk27   1/1     Running   0          36s
pod/nginx-deployment-cc7df4f8f-q2scr   1/1     Running   0          37s
pod/nginx-deployment-cc7df4f8f-zqkpx   1/1     Running   0          36s
 
NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   5h33m
 
NAME                               READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/nginx-deployment   3/3     3            3           37s
 
NAME                                         DESIRED   CURRENT   READY   AGE
replicaset.apps/nginx-deployment-cc7df4f8f   3         3         3       37s

 

 클러스터 자원에 대한 상세정보는 아래와 같이 확인한다.

[opc@inst-public ~]$ kubectl describe deployments nginx-deployment
Name:                   nginx-deployment
Namespace:              default
CreationTimestamp:      Tue, 02 Mar 2021 11:34:28 +0000
Labels:                 app=nginx
Annotations:            deployment.kubernetes.io/revision: 1
Selector:               app=nginx
Replicas:               3 desired | 3 updated | 3 total | 3 available | 0 unavailable
StrategyType:           RollingUpdate
MinReadySeconds:        0
RollingUpdateStrategy:  25% max unavailable, 25% max surge
Pod Template:
  Labels:  app=nginx
  Containers:
   nginx:
    Image:        nginx:latest
    Port:         80/TCP
    Host Port:    0/TCP
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>
Conditions:
  Type           Status  Reason
  ----           ------  ------
  Available      True    MinimumReplicasAvailable
  Progressing    True    NewReplicaSetAvailable
OldReplicaSets:  <none>
NewReplicaSet:   nginx-deployment-cc7df4f8f (3/3 replicas created)
Events:
  Type    Reason             Age   From                   Message
  ----    ------             ----  ----                   -------
Normal  ScalingReplicaSet  58s   deployment-controller  Scaled up replica set nginx-deployment-cc7df4f8f to 3
[opc@inst-public ~]$ kubectl describe replicasets
Name:           nginx-deployment-cc7df4f8f
Namespace:      default
Selector:       app=nginx,pod-template-hash=cc7df4f8f
Labels:         app=nginx
                pod-template-hash=cc7df4f8f
Annotations:    deployment.kubernetes.io/desired-replicas: 3
                deployment.kubernetes.io/max-replicas: 4
                deployment.kubernetes.io/revision: 1
Controlled By:  Deployment/nginx-deployment
Replicas:       3 current / 3 desired
Pods Status:    3 Running / 0 Waiting / 0 Succeeded / 0 Failed
Pod Template:
  Labels:  app=nginx
           pod-template-hash=cc7df4f8f
  Containers:
   nginx:
    Image:        nginx:latest
    Port:         80/TCP
    Host Port:    0/TCP
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>
Events:
  Type    Reason            Age   From                   Message
  ----    ------            ----  ----                   -------
  Normal  SuccessfulCreate  107s  replicaset-controller  Created pod: nginx-deployment-cc7df4f8f-q2scr
  Normal  SuccessfulCreate  107s  replicaset-controller  Created pod: nginx-deployment-cc7df4f8f-zqkpx
Normal  SuccessfulCreate  107s  replicaset-controller  Created pod: nginx-deployment-cc7df4f8f-dkk27

 

참고 사이트: Understanding Services in Kubernetes with Examples

파드에 부여된 클러스터 네트웍은 노드간 통신을 위한 내부 네트웍이다. 생성된 파드의 Nginx 컨테이너에 클러스터 밖에서 접근하기 위해서는 서비스를 이용해야 한다.

파드의 경우 상태가 없기 때문에(Stateless) IP 랜덤하게 지정되고 Restart  마다 변경되기 때문에 쿠버네티스 클라이언트는 IP 아닌 서비스로 접근을 해야 한다. 또한 파드  로드밸런싱이 필요할  있는데 서비스가 로드밸런싱 역할을 수행한다. 서비스는 지정된 IP로도 생성할 수도 있고, 고유한 DNS 이름을 가질 수도 있다.

쿠버네티스 서비스에는 아래와 같은 타입이 있다.

서비스 타입 설명
ClusterIP - 별도 지정하지 않으면 ClusterIP 타입으로 설정
- 서비스에 클러스터 IP (내부 IP) 할당
- 클러스터 내부 파드에서는 서비스 이름으로 접근할  있으나 클러스터 외부에서는 외부 IP 할당받지 못했기 때문에 접근이 불가하다.
- 그림에서 POD1으로 이루어진 APP1 서비스 ClusterIP 타입의 서비스로 접근이 가능하며, POD2 이루어진 클러스터  다른 어플리케이션 APP2 해당 서비스에 접근할  있다.
- 클러스터 밖에서 ClusterIP 타입의 서비스에 대한 접근은 “kubectl proxy --port 8080” 같은 명령으로 프록시를 만들어 kubectl 로컬 환경에서 http://localhost:8080/api/v1/proxy/namespaces/<NAMESPACE>/services/<SERVICE-NAME>:<PORT-NAME>/” 으로 접근   있다.
- 주로 로컬 PC에서 디버깅을 하거나 클러스터 내부 네트웍으로 대쉬보드 등을 만들  이용
NodePort - 클러스터 외부에서 접근할  있는 서비스
- 클러스터의 모든 노드에 지정한 포트가 개방되고,  노드로 들어온 요청은 서비스를 통해 대상  파드들로 분산 전송. “Worker Node IP:nodePort” 파드에 접근할  있으며, 공개 가능한 노드 포트는 30000–32767. 노드로 들어온 트래픽은 서비스를 경유하여 설정된 파드의 포트와 타겟포트를 통해 파드로 포워딩됨.
- 특정 노드를 지정해서 접속한 상황에서 해당 노드가 셧다운되면 서비스를 이용할  없다. 따라서 운영 환경에서 사용은 추천되지 않는다.
LoadBalancer - 외부 IP 가진 로드밸런서와 연동하여 파드의 어플리케이션을 외부에 공개. 지정한 포트에 대해 모든 트래픽은 서비스로 포워딩. HTTP, TCP, UDP, Websocket, gRPC  거의 모든 트래픽을 로드밸런서 서비스로 보낼  있다.
- 클라우드 벤더에서 제공하는 방식
ExternalName - 클러스터  파드에서 클러스터 외부 엔드포인트에 접속할  있게  .
- NAT 같은 별도 설정이 필요 없이 파드에서 외부 IP주소에 서비스 이름으로 접근 가능케함.

 

참고. 인그레스(Ingress)

참고 사이트: Kubernetes NodePort vs LoadBalancer vs Ingress? When should I use what?

서비스를 클러스터 외부로 노출시키고자 할때 위에서 살펴본 NodePort 타입의 서비스를 사용하는 방식의 경우, L4 레벨까지만 제어를   있기 때문에 HTTP/HTTPS 처럼 경로를 기반으로 서비스를 전환하는 L7 레벨의 제어는   없다.

인그레스(Ingress) 어플리케이션을 쿠버네티스 클러스터 외부로의 노출시키고 경로 기반의 HTTP 라우팅을   있게  주는 API 오브젝트로서 SSL/TSL 암호화나 세션 어피니티(Session Affinity) 등의 기능을 갖고 있다.

인그레스는 IP 주소 기반이 아닌, URL 기반의 경로를 찾아준다. 이때  URL 경로 요청에 대해 특정 서비스로 연결을 정의하게 되는데 이것을 인그레스 규칙(IngressRule)이라고 한다. 또한 인그레스 규칙에 맞게 경로를 찾는 주체는 인그레스 컨트롤러(IngressController)라고 한다.

여러가지 형태의 인그레스 컨트롤러가 있는데 클라우드 벤더의 로드밸런서나, Nginx, Contour, Istio 등의 인그레스 컨트롤러가 있다. 인그레스는 여러개의 서비스를 하나의 IP 노출시키고자 할때 가장 유용하며, 서비스들은 L7 프로토콜 (주로 HTTP) 사용한다.

OCI 경우, 로드밸런서로 인그레스 컨트롤러의 기능을 제공하며 클러스터에 Nginx 같은 오픈소스 인그레스 컨트롤러를 구성해서 사용할 수도 있다. 상세한 내용은 샘플을 참조한다.

Example: Setting Up an Ingress Controller on a Cluster

 

이번 테스트에서는  서비스 타입  로드밸런서를 이용하여 서비스를 만들어 본다.

kubectl expose 명령으로 디플로이먼트를 외부로 노출시키는 서비스 오브젝트를 생성한다. OCI 쿠버네티스 클러스터는 OCI Cloud Controller Manager (CCM) 결합되어 있기 때문에 아래와 같이 서비스 타입을 로드밸런서로  경우, 파드를 OCI 로드밸런서로 인터넷에 노출시키게 된다.

아래 명령은 호스트 포트는 8080, 컨테이너 포트는 80으로 연결하는 “nginx-service” 라는 이름의 서비스로 “nginx-deployment” 디플로이먼트를 로드밸런서로 외부에 노출시킨다.

여기서는 명령어 방식으로 서비스를 생성해서 파드와 연결했으나, 선언 방식으로 서비스를 정의하는 별도 YAML 파일을 만들어 서비스 생성  파드 연결에 적용시킬 수도 있다. 서비스 YAML 파일의 spec에서selector 속성과 디플로이먼트 YAML 파일  template에서 metadata.label 라벨을 매핑시키고, 디플로이먼트 YAML 파일 kubectl apply -f 옵션 적용하면 된다.  부분은 이후 다시 테스트를 통해 확인할 것이다.

[opc@inst-public ~]$ kubectl expose deployment nginx-deployment --port=8080 --target-port=80 --type=LoadBalancer --name=nginx-service
service/nginx-service exposed

 

잠시 , OCI  콘솔에  보면 클러스터 VCN OCI 퍼블릭 로드밸런서가 프로비전되어 있다.

 

로드밸런서는 클러스터의 로드밸런서 서브넷에 생성되어 있다. 할당된 퍼블릭 IP 확인한다.

 

 브라우저를 열어서 http://lb-public-ip:8080 같이 로드밸런서의 퍼블릭IP 접속해 보면 Nginx 웰컴 페이지를   있다. 이번 테스트와 같이 OCI 쿠버네티스 클러스터를 사용자 지정이 아닌 Quick Create 옵션으로 설치한 경우, 로드밸런서 시큐리티 리스트에는 인터넷으로의 Ingress, Egress규칙들이 모두 허용되어 있기 때문에 별도 OCI 시큐리티 리스트 규칙을 추가할 필요는 없다.

 

생성된 서비스의 정보는 아래와 같이 확인한다.

[opc@inst-public ~]$ kubectl get services nginx-service
NAME            TYPE           CLUSTER-IP      EXTERNAL-IP      PORT(S)          AGE
nginx-service   LoadBalancer   10.96.168.149   193.122.207.65   8080:31405/TCP   5m33s
[opc@inst-public ~]$ kubectl describe services nginx-service
Name:                     nginx-service
Namespace:                default
Labels:                   app=nginx
Annotations:              <none>
Selector:                 app=nginx
Type:                     LoadBalancer
IP Families:              <none>
IP:                       10.96.168.149
IPs:                      <none>
LoadBalancer Ingress:     193.122.207.65
Port:                     <unset>  8080/TCP
TargetPort:               80/TCP
NodePort:                 <unset>  31405/TCP
Endpoints:                10.244.0.134:80,10.244.0.5:80,10.244.1.4:80
Session Affinity:         None
External Traffic Policy:  Cluster
Events:
  Type    Reason                Age   From                Message
  ----    ------                ----  ----                -------
  Normal  EnsuringLoadBalancer  6m6s  service-controller  Ensuring load balancer
  Normal  EnsuredLoadBalancer   5m8s  service-controller  Ensured load balancer

 

다음 테스트를 위해 앞서 만든 서비스와 디플로이먼트를 삭제한다. 서비스를 삭제하면 OCI 로드밸런서도 함께 삭제된다.

[opc@inst-public ~]$ kubectl delete service nginx-service
service "nginx-service" deleted
[opc@inst-public ~]$ kubectl delete deployments nginx-deployment
deployment.apps "nginx-deployment" deleted
[opc@inst-public ~]$ kubectl get deploy,po
No resources found in default namespace.

 

참고. 파드 네트웍

클러스터의 모든 파드는 단일 플랫 네트웍에 위치하게된다. 구성된다. 또한  파드에는 고유의 IP 주소가 할당되고, 클러스터 내에서 라우팅된다. 또한 해당 파드에 속하는 모든 컨테이너가 파드에 할당된 IP 공유한다.

같은 파드 안의 모든 컨테이너의 IP 주소가 같기 때문에 로컬호스트를 이용해서 컨테이너 간의 통신이 가능해진다. 예를 들어 파드에서 localhost:80으로 nginx 컨테이너의 80 포트에 접근할  있으며, localhost:8080으로 echo 컨테이너의 8080포트에 접근할  있다.

또한 모든 파드는 다른 파드의 IP 주소로 접근이 가능하다. 파드  통신은 LAN 환경의 서버  통신과 유사하다고   있다. 따라서 파드 안의 통신과 마찬가지로 파드 간에도 IP 주소와 포트를 가지고 통신을   있다.

 내용을 확인하기 위해 파드 세개의 복제본을 디플로이한다. 첫번째 파드를 실행해서 다른 파드와의 연결을 확인해 본다. 여기서 테스트한 파드에는 컨테이너가 하나밖에 없기 때문에 kubectl exec 명령에서 파드명만 지정해도 해당 nginx 컨테이너를 실행하게된다. 컨테이너에서 ping telnet 명령을 실행하기 위해 apt-get으로 해당 패키지를 설치하고, 다른 두개의 노드에 있는 파드에 ping telnet 연결을 수행해 본다. 80포트로는 연결이 정상 수행되나, 디플로이시 지정하지 않은 8080 포트로는 연결이 되지 않는 것을   있다.

[opc@inst-public ~]$ kubectl create deployment nginx-deployment --image=nginx --port=80 --replicas=3
deployment.apps/nginx-deployment created
[opc@inst-public ~]$ kubectl get pod -o wide
NAME                               READY   STATUS    RESTARTS   AGE   IP             NODE        NOMINATED NODE   READINESS GATES
nginx-deployment-76f4cbc5d-b8vqh   1/1     Running   0          10s   10.244.0.135   10.0.10.3   <none>           <none>
nginx-deployment-76f4cbc5d-cq6bv   1/1     Running   0          11s   10.244.1.5     10.0.10.4   <none>           <none>
nginx-deployment-76f4cbc5d-xk2gk   1/1     Running   0          10s   10.244.0.6     10.0.10.2   <none>           <none>
[opc@inst-public ~]$ kubectl exec -it nginx-deployment-76f4cbc5d-b8vqh -- sh
# apt-get update

# apt-get install iputils-ping -y

# apt-get install telnet -y

# ping -c 3 10.244.1.5
PING 10.244.1.5 (10.244.1.5) 56(84) bytes of data.
64 bytes from 10.244.1.5: icmp_seq=1 ttl=62 time=1.31 ms
64 bytes from 10.244.1.5: icmp_seq=2 ttl=62 time=1.01 ms
64 bytes from 10.244.1.5: icmp_seq=3 ttl=62 time=1.05 ms
 
--- 10.244.1.5 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 5ms
rtt min/avg/max/mdev = 1.010/1.121/1.307/0.132 ms
# telnet 10.244.1.5 80
Trying 10.244.1.5...
Connected to 10.244.1.5.
Escape character is '^]'.
^CConnection closed by foreign host.
# telnet 10.244.1.5 8080
telnet: Unable to connect to remote host: Connection refused
# ping -c 3 10.244.0.6
PING 10.244.0.6 (10.244.0.6) 56(84) bytes of data.
64 bytes from 10.244.0.6: icmp_seq=1 ttl=62 time=0.680 ms
64 bytes from 10.244.0.6: icmp_seq=2 ttl=62 time=0.587 ms
64 bytes from 10.244.0.6: icmp_seq=3 ttl=62 time=0.748 ms
 
--- 10.244.0.6 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 62ms
rtt min/avg/max/mdev = 0.587/0.671/0.748/0.072 ms
# telnet 10.244.0.6 80
Trying 10.244.0.6...
Connected to 10.244.0.6.
Escape character is '^]'.
^CConnection closed by foreign host.
# exit

 

다음 테스트를 위해 앞서 만든 서비스와 디플로이먼트를 삭제한다. 서비스를 삭제하면 OCI 로드밸런서도 함께 삭제된다.

[opc@inst-public ~]$ kubectl delete service nginx-service
service "nginx-service" deleted
[opc@inst-public ~]$ kubectl delete deployments nginx-deployment
deployment.apps "nginx-deployment" deleted
[opc@inst-public ~]$ kubectl get deploy,po
No resources found in default namespace.

 

글 순서

1. Introduction

2.쿠버네티스  OCI 쿠버네티스(OKE) 개요

3. OCI 쿠버네티스 배포, 사용 환경 설정

4. OKE 클러스터에 샘플 웹서버 배포

5. OCI 레지스트리에 이미지 업로드 & 다운로드 설정

6. Wercker 이용한 어플리케이션 빌드

7. Wercker 이용한 어플리케이션 배포

8. OKE 모니터링

여기에 정리한 내용은 오라클 제품을 다루고 있지만, 이는 개인적인 정리 및 테스트 결과일 뿐입니다. 오라클의 공식 문서는 오라클이 제공하는 매뉴얼과 기타 기술문서를 참조하셔야 합니다.