반응형

 

작성일: 2024년 4월 9일

 

Amazon AWS, Microsoft Azure, Google GCP, Oracle Cloud Infra 등 CSP에서 Compute resource를 생성하려고 보면,

이 Compute instance(또는 VM instance)를 생성한 것 때문에 비용이 얼마나 되는지 감을 잡기가 어렵다.

 

마침, Oracle Cloud의 연간 Credit 구입한 것이 많이 남아 있고, 5일 후에 Expire되기 때문에 남는 Credit을 소진해볼겸

VM instnace를 Scale-up, Scale-down하면서 비용 증가/감소 정도를 체크해봤다.

 

1개 VM instance를 대상으로 CPU/Memory Scale-up 수행 후 비용 증감을 체크

초기 VM instance의 Spec Scale-up 이후의 Spec 비용 증가분(Delta)
CPU: 1 core (2 thread)
MEM: 2GB
Storage: 50 GB (Boot volume)
CPU: 8 core (16 thread)
MEM: 128 GB
Storage: 50 GB (Boot volume)
11,479 원   (Daily Cost)

 

참고:
  CPU 종류: AMD EPYC 7J13
  CPU Caches: 
      L1d:  512 KiB (8 instances)
      L1i:   512 KiB (8 instances)
      L2:   4 MiB (8 instances)
      L3:   32 MiB (2 instances)

 

 

 

위에 내가 실제로 VM instance를 Scale-up한 이후의 비용 증가분을 계산한 것은
클라우드 테넌트 계약 조건과 현재 원/달러 환율 따라 30% 정도 차이가 날 것이다.
특히 클라우드 테넌트 계약시, 3년 이상 장기 계약한 경우 많은 할인율이 적용되서  Scale-up에 대한 증가분이 크지 않을 수 있다.
1년 단위로 단기 계약한 테넌트라면, CPU/Memory를 Scale-up할 때 비용 증가분이 위의 계산 결과보다 클 수 있다.

 

 

반응형
작성일: 2024년 4월 9일

 

Microsoft Azure, AWS(Amazon), GCP(Google Cloud Platform), Oracle Cloud Infra 등 Cloud Infra 서비스를 사용하다보면

예상한 것보다 비용이 더 지출되는 경우가 있다.

내 경우, Cloud Infra를 1년간 사용하는 중에 Storage(Block Volume)과 VCN(Virtual Cloud Network) 리소스 사용 비용이 계속 증가만 하길래 이 비용 증가 원인을 찾는 작업을 했다.

 


 

나는 회사 업무 때문에 CSP(Cloud Service Provider)가 제공하는 Managed Kubernetes를 종종 이용하는데, 

이 Managed Kubernetes의 cluster를 생성하고 삭제하는 과정에서 찌꺼기 리소스가 계속 발생하고 있었다.

찌꺼기 리소스가 발생하게 된 이유에 대해 좀더 자세히 설명하면 아래와 같다.

 

  1. Managed Kubernetes 서비스를 이용하여 Cluster-A를 생성한다.
  2. Cluster-A에 Pod, LoadBalancer Type의 Service 리소스 등을 생성한다.
  3. 몇달 동안 사용 후 Cluster-A를 삭제한다.    <-- 이 순간부터 찌꺼기 리소스에 대한 과금이 시작된다 (일명, 숨겨진 비용 발생)

 

위와 같은 순서로 Managed Kubernetes Cluster를 사용하면,

Pod가 사용했던 Storage(즉, PV)와 Public IP Address를 사용했던 LoadBalancer 리소스가 찌꺼기로 남게 된다.

즉, 실제로는 K8s Cluster가 없지만 Storage와 Public IP address는 내 테넌트 내의 자원으로 할당된 상태로 남게 된다.

이 찌꺼기 자원이 계속 비용을 유발하므로, 발견한 즉시 삭제해야 한다.

내 경우, 1년 동안 사용하면서 Pod, PVC, PV, Service Resoruce(LB Type) 등을 먼저 삭제하지 않은 상태에서

K8s cluster를 삭제한 경우가 2번 있었는데... 이것들을 정리하고 나니까 Cloud 사용 요금이 50% 수준으로 떨어졌다. ㅠㅠ

그 동안 쓰지 않아도 될 돈을 지출하고 있었던 것이다.

 

Cloud 서비스를 사용할 때는 Kubernetes cluster를 삭제하는 순서에 대해서 꼭 주의하자!

 

  1. Kubernetes cluster 내부에서 사용했던 Pod, PVC, PV, Service Resoruce를 모두 삭제한다.
  2. PV, Service Resource가 삭제되었는지 여부를 반드시 확인한 후,
  3. Kubernetes cluster를 삭제한다.

 


 

반응형

 


작성일: 2024년 3월 27일

 

 

Oracle Cloud Infra(OCI) 그리고 Kubernetes Engine(OKE)를 사용하면서 참고하기 좋은 블로그를 찾았다.

타이틀은 개인 기술 블로그이지만, 거의 Oracle Cloud Infra의 공식 사용 매뉴얼 같은 느낌이다.

Oracle Cloud Infra의 공식 문서보다 사용자 입장에서 잘 작성된 글이다.

 

https://thekoguryo.github.io/

 

TheKoguryo's 기술 블로그

 

thekoguryo.github.io

 

공식 홈피에는 너무 많은 자료가 있어서 다 읽기 부담스러운데, 이 블로그는 딱 필요한 부분만 설명되어 있고

대부분 시간순으로 글이 진행되니까 따라서 실행하면 되는지라...

처음 OCI를 접하는 사람이 한번 쭉~ 읽고 OCI를 사용하면 좋을 것 같다.

 

반응형

Oracle의 Official blog인지는 모르겠는데, 꽤 유용한 정보를 담고 있어서 종종 참고하는 블로그이다.

 

 

https://oracle-cloud.tistory.com/entry/cloud-shell-connects-to-private-instance

 

클라우드 쉘과 Bastion 서비스 사용한 Private 인스턴스 연결

OCI 클라우드 쉘은 OCI 콘솔에서 액세스 할 수 있는 웹 브라우저 기반 터미널입니다. OCI Bastion은 Public 엔드포인트가 없는 대상 리소스에 대한 제한적이고 시간제한이 있는 액세스를 제공합니다.

oracle-cloud.tistory.com

 

반응형

Public Cloud의 Kubernetes(예: AWS AKS, Azure AKS, Oracle OKE 등)을 사용하다보면,

Public Network에서 들어오는 UDP 트래픽을 Network LB(NLB)가 처리하지 못하는 것처럼 보일 때가 있다.

 

예를 들어 아래와 같은 Service Manifest를 적용했다고 가정해보자.

 

apiVersion: v1
kind: Service
metadata:
  name: almighty
  annotations:
    oci.oraclecloud.com/load-balancer-type: "nlb"  # <- 이 내용을 추가해야 한다.
spec:
  selector:
    app: almighty
  ports:
    - name: myweb
      protocol: TCP
      port: 8080
      targetPort: 8080
    - name: yourweb
      protocol: TCP
      port: 80
      targetPort: 80
    - name: myudp
      protocol: UDP       # <- 테스트를 위해 UDP를 추가한다.
      port: 9090
      targetPort: 9090
  type: LoadBalancer      # <- Service Type을 LoadBalancer로 설정한다.

 

위 Service Manifest를 적용하면, External-IP 항목이 Public IP 값으로 설정되지만 실제로 Pod로 UDP 트래픽이 전달되지 못하는 현상이 생길 것이다.

 

왜 이런 문제가 생길까?

 

Public Network에서 유입되는 UDP 트래픽이 Pod에 전달되지 못하는 정확한 원인은 아래와 같다.

Public Cloud Service 제공사가 제공하는 NLB(Network Load Balancer)는 제대로 UDP 트래픽을 처리한 것이 맞다.

단지, Cloud Infra가 제공하는 K8S Node의 Security Rule에 의해서 UDP 트래픽이 Block되는 것이다.

따라서 Security Rule에 UDP 트래픽이 Pass 되도록 Rule을 추가하기만 하면 된다. (즉, Linux Firewall 설정 하듯이~)

 

AWS AKS, Azure AKS, Oracle OKE 모두 비슷하게 NLB가 UDP 트래픽을 처리하고 Security Rule도 비슷하기 때문에 Oracle의 OCI OKE만 이용해서 설명하면 아래와 같다.

 

아래의 순서로 메뉴/화면을 찾아서 들어간다.

[ Kubernetes Clusters (OKE) ]

-> Clusters 화면에서 특정 Cluster의 VCN을 선택/클릭한다.

-> VCN을 클릭하면, 여러개의 Subnets이 목록이 보여지는데 oke-svclbsubnet-xxxxoke-nodesubnet-yyyy을 선택하여 Security Lists를 확인한다.

-> [ Security Lists ] 화면에 있는 Rule 이름을 선택한다.

-> [ Ingress Rules ]와 [ Egress Rules ] 화면에서 UDP, TCP 트래픽을 모두 허용하도록 Rule을 추가한다.

     예를 들어, 115.33.55.0/24, 특정 UDP 포트(예: 9090), 특정 TCP 포트(예: 8080) 허용으로 설정하면 된다.

 

아래 화면을 참고~~~

 

 

 

이렇게 Security Rule을 추가하고, 다시 Public IP와 UDP 포트를 이용하여 트래픽을 보내보면, Pod 내부까지 UDP 트래픽이 잘 전달되는 것을 확인할 수 있다.

 

 


조심해야 할 사항:
  Security Rule 설정하고, 40초 후에 Traffic Test해야 한다.
  Node Security Rule이 적용되기 까지 40초가 걸리기 때문에 그 이후에 Traffic Test를 해야 제대로 Traffic이 Pod까지 전달된다.
  

 


생각해볼 내용:
  Node Security List에 TCP Rule을 추가할 때, 왜 Egress Rule도 추가해야 하는지 잘 이해가 안 된다.
  Cluster 외부에서 Ingress Rule에 따라 TCP Traffic을 허용해주면, ConnTrack DB에 Pin Hole 같은게 생기면서
  TCP의 응답 패킷도 알아서 Pass(Forward)시켜주는게 일반적인 Traffic 처리가 아닐까라고 생각했는데... 이게 아닌가 보다.
  아무튼 귀찮지만 Ingress에 추가한 Rule을 Egress에도 꼭 추가해야 한다. (잊지 말자 !!!)

 

 

 

 

참고하면 좋은 Web Docs

Oracle OCI Network Load Balancer 사용하기

https://thekoguryo.github.io/release-notes/20220315-support-for-oci-network-load-balancers/

 

Support for OCI Network Load Balancers

OKE에서 Service Type을 Load Balancer를 사용할때 이제는 OCI Network Load Balancer을 추가적으로 지원합니다.

thekoguryo.github.io

 

위 문서는 간단하게 사용법 위주로 설명되어 있고, 아래 문서는 내부 동작에 관해 자세하게 내용을 다루고 있다.

특히, Service Manifest의 externalTrafficPolicy: local 방식에 관해 궁금하다면 아래 문서를 보는 것이 좋다.

 

https://blogs.oracle.com/cloud-infrastructure/post/network-load-balancer-support-on-oracle-kubernetes-engine

 

Using a network load balancer for Kubernetes services

Announcing network load balancer support on Oracle Container Engine for Kubernetes.

orasites-prodapp.cec.ocp.oraclecloud.com

 

더 자세히 파고 들어가고 싶다면, Oracle 공식 Web Docs를 보길~~~

 

https://docs.oracle.com/en-us/iaas/Content/ContEng/Tasks/contengcreatingloadbalancer.htm

 

Defining Kubernetes Services of Type LoadBalancer

Include in the backend set:

docs.oracle.com

 

반응형

 

준비 작업: Oracle Cloud 사용을 위한 계정 생성

아래 Web Page에서 Oracle Cloud 사용을 위해서 Account를 생성한다.

https://cloud.oracle.com/

 

내 경우, 계정 생성하다가 마지막 "검증" 단계에서 실패했는데  Oracle에 전화해서 물어보니 

요즘 Block Chain Mining을 위해 Cloud Infra를 악용하는 사례가 있어서

계정 생성시 입력한 정보 중에서 블랙 해커로 의심되는 정보가 있으면, Oracle Machine Learning이 계정 생성을 Blocking 한다고 설명해줬다.

혹시 계정 생성하다 실패하면, 계정 정보를 다르게 해서 다시 생성하는 것이 정신 건강에 좋다.

 

 

OKE Cluster 생성하기

Oracle Cloud의 TOP 메뉴에서

[ Developer Services ] -> [ Kubernetes Cluters (OKE) ]

순서로 메뉴를 클릭하고, Quick Start 방식로 몇 가지 기본 설정 값만 정해주면 너무나 간단하게 Kubernetes Cluster가 생성된다.

 

주의: 
동일한 Spec의 Cluster 구축이라고 하더라도 Cluster Infra 상황에 따라 어떤 경우는 5분만에 Cluster가 생성되고,
어떤 경우는 15분이 넘도록 Cluster 생성이 완료되지 않는다.
그래서 마음편하게, Cluster 생성 버튼을 누르고 20분 정도 다른 업무를 하다가 오는 것이 좋다.

 

내 PC (Macbook)에서 OKE Cluster에 접근하기 (Bastion 구성)

Oracle이 너무 간단하게 만들어 놓아서 굳이 장황하게 설명할게 없다.

아래 Web Page에서 아래 빨간 번호 순서로 따라 하기만 하면 된다.

당연한 말이겠지만, 내 Macbook은 Public Network을 통해서 Oracle Cloud Infra에 접근해야 하니까, 아래 그림의 (6)번 절차에서 "VNC-Native public endpoint"와 관련된 명령을 복사해서 내 Macbook의 iTerm에 붙여 넣어야 한다.

 

 

위 절차를 끝낸 후, 내 Macbook의 iTerm 터미널에서 아래와 같이 명령을 수행하면 명령이 잘 수행되는 것을 확인할 수 있다.

 

$  kubectl  get node
NAME          STATUS   ROLES   AGE     VERSION
10.0.10.121   Ready    node    3m7s    v1.24.1
10.0.10.124   Ready    node    2m59s   v1.24.1
10.0.10.127   Ready    node    2m55s   v1.24.1
$

 

 

주의:
위 절차를 따라할 때, (5) ~ (6) 단계 사이에서 아래의 명령을 한번 수행해야 한다.
기존에 사용하던 KUBECONFIG 환경 변수가 설정된 경우라면, (6) 단계가 실패한다.
$  unset KUBECONFIG

 

 

 

Tip:
  [ Multi cluster를 운영하는 경우 ]
  예를 들어서 OKE kubernetes에서 cluster2, cluster3 등 2개의 cluster를 생성하여 운영하는 경우라면
  아래와 같이 .kube/config 파일 이름을 변경해서 사용하는 것을 추천.

 

$ mv $KUBECONFIG/config $KUBECONFIG/config.cluster2


$ cat .bashrc

... 중간 생략 ...

function use-oke-cluster2() {
  AA=$(printf "\033[")
  export KUBECONFIG=~/.kube/config.cluster2
  echo "${AA}32m"
  echo "Cluster Name      :" $(cat $KUBECONFIG | yq '.clusters[0].name')
  echo "Cluster API Server:" $(cat $KUBECONFIG | yq '.clusters[0].cluster.server')
  echo "${AA}0m"
}

... 중간 생략 ...

$ use-oke-cluster2

Cluster Name      : cluster-cja9kqodr9l
Cluster API Server: https://193.135.212.37:6443

$ kubectl get node
NAME          STATUS   ROLES   AGE    VERSION
10.0.10.115   Ready    node    11d    v1.25.4
10.0.10.117   Ready    node    11d    v1.25.4
$

+ Recent posts