1.9.4 Virtual Nodes
OKE Virtual Nodes
쿠버네티스의 사용이 늘어나고 있습니다. 하지만, 관리 유저들은 다음 항목에 대한 관리상의 어려움이 많다고 합니다.
- Infrastructure right-sizing: 쿠버네티스는 대규모 애플리케이션을 관리하고, 스케일할 수 있도록 설계되어 있습니다. 스케일과 관련된 운영작업으로 CPU, 메모리 같은 인프라 자원에 적정량의 배분, 사이징하는 것에 대한 어려움이 발생합니다.
- Upgrades and maintenance: 쿠버네티스를 최신버전으로 유지하거나, 서포트 범위 내 버전을 유지하기 위해서도 주기적으로 업그레이드가 필요합니다. 또 그 업데이트 주기도 짧은 편입니다.
- Infrastructure security: 쿠버네티스 클러스터의 인프라가 노출되면, 해당 클러스터에 수행중인 모든 애플리케이션에 대해서도 위험이 발생합니다. 해당 인프라에 대한 보안이 강화되어야 하며, 접근은 통제되어야 하며, 지속적으로 보안 패치가 적용되어야 합니다.
이런 쿠버네티스 관리상의 어려움을 단순화하기 위해 OKE에서 Virtual Nodes을 출시하게 되었다고 합니다. OKE Virtual Nodes는 Serverless Kubernetes로써 유저가 Worker Nodes 인프라를 관리할 필요가 없습니다. Pod 레벨에서 탄력성을 제공하고, Pod 기준으로 비용이 발생합니다. 유저가 Worker Nodes를 스케일하거나, 업그레이드 하거나, 트러블 슈팅할 필요가 없습니다. 유저가 지속적인 보안 패치를 적용할 필요도 없으며, Virtual Nodes(Worker Nodes)에 접근 자체가 불가합니다. OKE 클러스터의 Control Plane, Data Plane을 OCI가 관리하고, 유저는 Kubernetes API를 통해 애플리케이션을 배포하고, 관리하면 됩니다.
- 참고 문서 - OCI Blog > OKE virtual nodes deliver a serverless Kubernetes experience
Serverless Kubernetes 클러스터 만들기 - Virtual Nodes
OCI IAM Policy 만들기
OKE Serverless 서비스가 Virtual Nodes 생성할 있도록 권한을 줍니다. 사용중인 테넌시내에서 Virtual Nodes을 사용하겠다고 알려주는 것이기 때문에, 아래 내용을 변경없이 그대로 복사해서 Policy를 만들면 됩니다. 각자 테넌시 환경에 맞게 변경하는 내용이 아닙니다.
- OCI Documentation > Container Engine > Required IAM Policies for Using Virtual Nodes
- Name: 예, oke-virtual-nodes-policy
define tenancy ske as ocid1.tenancy.oc1..aaaaaaaacrvwsphodcje6wfbc3xsixhzcan5zihki6bvc7xkwqds4tqhzbaq define compartment ske_compartment as ocid1.compartment.oc1..aaaaaaaa2bou6r766wmrh5zt3vhu2rwdya7ahn4dfdtwzowb662cmtdc5fea endorse any-user to associate compute-container-instances in compartment ske_compartment of tenancy ske with subnets in tenancy where ALL {request.principal.type='virtualnode',request.operation='CreateContainerInstance',request.principal.subnet=2.subnet.id} endorse any-user to associate compute-container-instances in compartment ske_compartment of tenancy ske with vnics in tenancy where ALL {request.principal.type='virtualnode',request.operation='CreateContainerInstance',request.principal.subnet=2.subnet.id} endorse any-user to associate compute-container-instances in compartment ske_compartment of tenancy ske with network-security-group in tenancy where ALL {request.principal.type='virtualnode',request.operation='CreateContainerInstance'}
OKE Serverless 클러스터 만들기
OCI 콘솔에 로그인합니다.
좌측 상단 햄버거 메뉴에서 Developer Services > Containers & Artifacts > Kubernetes Clusters (OKE)로 이동합니다.
클러스터 생성을 위해 Create Cluster 버튼을 클릭합니다.
빠른 클러스터 생성을 위해 기본선택된 Quick Create 모드를 이용하여 생성합니다.
Name
- 예) oke-serverless-cluster-1
Kubernetes API Endpoint
- Public API로 접속할 수 있게 기본 선택된 Public Endpoint를 그대로 사용
Kuberentes version
Virtual Nodes는 v1.25.4 이상에서 지원됩니다.
Virtual Nodes는 아직 버전 업그레이드를 지원하지 않으므로, 사용을 원하는 버전을 선택합니다.
Node type: Virtual을 선택합니다.
Node count: 기본값인 3을 그대로 사용합니다.
Pod shape: Pod개 배포될 Shape을 선택합니다. E3.Flex, E4.Flex Shape 중에 선택합니다.
- Managed Nodes 처럼 Worker Node의 Compute 인스턴스의 Shape을 고정하는 것이 아닙니다.
- Pod 자원 요청시 지정하는 requests, limits에 따라 자원이 할당되며, Serverless로 OKE가 관리합니다.
입력한 정보를 리뷰하고 클러스터를 생성합니다.
Quick Create로 클러스터를 생성시 기본 네트워크 자원이 함께 생성됩니다.
클러스터 생성 확인
생성된 클러스터 상세정보를 그림과 같이 Enhanced Cluster이며, Network 타입은 VCN-Native Pod Networking을 사용합니다. Flannel CNI는 지원하지 않습니다.
Node Pool 상세 정보에서 Resources > Nodes 정보를 보면 생성된 Worker Nodes를 확인할 수 있습니다. Virtual Nodes로 Pod가 위치할 가상 노드로, Compute 인스턴스가 따라 생성되지 않습니다.
OKE Serverless 클러스터 연결하기
연결하는 방법은 기존 OKE 클러스터를 연결하는 방법과 동일합니다.
생성한 OKE 클러스터 상세 페이지로 이동하여, Access Cluster를 클릭합니다. 가이드에 따라 사용환경에서 클러스터에 연결합니다.
노드 정보를 조회해 봅니다.
$ kubectl get nodes -o wide NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME 10.0.10.12 Ready <none> 3m52s v1.26.2-0.2.169-230516185737 10.0.10.12 <none> <unknown> <unknown> <unknown> 10.0.10.78 Ready <none> 3m47s v1.26.2-0.2.169-230516185737 10.0.10.78 <none> <unknown> <unknown> <unknown> 10.0.10.85 Ready <none> 3m53s v1.26.2-0.2.169-230516185737 10.0.10.85 <none> <unknown> <unknown> <unknown>
앱 배포 및 Load Balancer 사용하기
1.4 앱 배포 및 Load Balancer 사용하기에서 한 과정을 동일하게 OKE Serverless 클러스터에서 수행해 봅니다.
Docker Hub 이미지 배포
가장 흔한 형태인 Public Container Registry에 이미지를 가져와서 OKE 클러스터에 배포를 해봅니다.
kubectl create deployment nginx-docker-hub --image=nginx:latest
배포 결과를 확인합니다.
- VCN-Native Pod Networking을 사용하고 있어, Pod의 IP로 Worker Nodes 서브넷 상의 IP를 사용하고 있습니다.
$ kubectl create deployment nginx-docker-hub --image=nginx:latest deployment.apps/nginx-docker-hub created $ kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-docker-hub-67c59cc7d5-gkjxg 1/1 Running 0 86s 10.0.10.220 10.0.10.85 <none> <none>
- ContainerCreating 상태로 멈춘경우, Policy 적용여부를 확인합니다. 적용후 Pod를 재생성합니다.
Load Balancer 타입으로 서비스 만들기
클라이언트 서비스를 위해 LoadBalancer Type으로 서비스를 생성합니다.
kubectl expose deployment nginx-docker-hub --port 80 --type LoadBalancer --name nginx-docker-hub-svc
서비스 생성 결과를 확인하면 아래와 같이 LoadBalancer 타입으로 생성되어 Public IP가 할당 된 것을 볼 수 있습니다.
$ kubectl expose deployment nginx-docker-hub --port 80 --type LoadBalancer --name nginx-docker-hub-svc service/nginx-docker-hub-svc exposed $ kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP,12250/TCP 10m nginx-docker-hub-svc LoadBalancer 10.96.210.192 152.69.xxx.xx 80:31809/TCP 38s
서비스 주소인 Public IP로 접속하면, 다음과 같이 연결 오류가 발생합니다.
$ curl http://152.69.xxx.xx curl: (56) Recv failure: Connection reset by peer
Comparing Virtual Nodes with Managed Nodes에서 Virtual Nodes상의 Load Balancing의 설명을 보면, 기존 OKE 클러스터에서 Load Balancer를 생성하면, 자동으로 Security List에 규칙에 추가가 되었지만, Virtual Nodes에서는 매뉴얼하게 해주어야 합니다.
VCN-Native Pod Networking을 사용하기 때문에 생성되는 <pod-ip>:<nodeport>에 대한 보안 규칙을 매뉴얼하게 추가합니다.
또한 생성되는 Load Balancer가 Pod의 대한 Health Check시 사용하는 kube-proxy health port(10256)에 대한 보안 규칙 또한 추가해 줘야 합니다.
Security List를 업데이트합니다.
pod-ip와 nodeport를 확인합니다.
$ kubectl describe svc nginx-docker-hub Name: nginx-docker-hub-svc Namespace: default ... NodePort: <unset> 31440/TCP Endpoints: 10.0.10.25:80 ...
<pod-ip>:<nodeport>, <pod-ip>:10256만 매번 추가하거나, Pod가 속한 Worker Node 서브넷상의 모든 Node Port 범위(30000-32767)와 kube-proxy health port(10256)을 한번에 미리 추가해 놓는 방법이 있습니다. 여기서는 후자를 사용합니다.
Load Balancer -> Pod: oke-svclbseclist-~~ Security List 업데이트
- Egress Rules:
Stateless Destination IP Protocol Source Port Range Destination Port Range No 10.0.10.0/24 TCP All 30000-32767 No 10.0.10.0/24 TCP All 10256 Load Balancer -> Pod: oke-nodeseclist-~~ Security List 업데이트
- Ingress Rules:
Stateless Source IP Protocol Source Port Range Destination Port Range No 10.0.20.0/24 TCP All 30000-32767 No 10.0.20.0/24 TCP All 10256
Load Balancer IP로 다시 테스트하면 정상적으로 연결됩니다.
$ curl http://152.69.xxx.xx <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> ... </html>
Virtual Nodes에서 Pod에 대한 CPU, 메모리 할당
OCI Documentation > CPU and Memory Resources Allocated to Pods Provisioned by Virtual Nodes에서 pod spec에 정의된 requests와 limits 값을 기준으로 할당하며, 둘 다 없는 경우, 최소값으로 0.125 OCPU, 0.5GB 메모리를 할당합니다.
사용한 비용 추정
위 테스트 내용을 기준으로 가격 산정에 들어가는 항목은 아래와 같습니다. 아래 내용에 대해 시간당 비용이 발생할 것으로 추정됩니다.
- Enhanced Cluster: 1개
- Virtual Nodes: 3개
- 1개 Pod 총 CPU: 0.125 OCPU -> Virtual Nodes의 최소 OCPU인 1 OCPU
- 1개 Pod 총 Memory: 0.5 GB -> Virtual Nodes의 최소 메모리인 1 GB
- 그외 Load Balancer 비용 등
가격 비교는 OCI Blog > Kubernetes cloud cost comparison: Who provides the best value? 참조
Virtual Nodes에서 지원하지 않는 기능
features and capabilities not supported when using virtual nodes에서 설명하고 있는 것처럼, Kuberbernetes 기능 중 지원하지 않거나, 지원 예정이나 아직 지원하지 않습니다. 또한 OKE Managed Nodes에서 지원하는 기능 중 일부에 대해서도 지원하지 않거나, 지원 예정이나 아직 지원하지 않으니, 해당 문서를 살펴보시기 바랍니다.
그 중 일부 눈에 들어오는 내용을 보면 다음 기능에 대해서 지원하지 않거나, 지원 예정이나 아직 지원하지 않는 기능이 있습니다.
- Liveness and readiness probes can only use HTTP (not HTTPS)
- Kubernetes daemonsets 미지원
- Persistent volume claims (PVCs) 미지원
- Service mesh products 미지원
- 그외 추가 사항은 features and capabilities not supported when using virtual nodes 참조
이 글은 개인으로서, 개인의 시간을 할애하여 작성된 글입니다. 글의 내용에 오류가 있을 수 있으며, 글 속의 의견은 개인적인 의견입니다.