NCloud Kubernetes Service 요약
Config
-
NKS는 CNI로 Cilium을 사용하며 컨테이너 런타임으로 containerd를 사용한다.
-
kube config를 등록하기 전에 sub account accesskey를 사용하게 된다면 클러스터에 Sub account 사용자에 대한 configmap을 우선 등록해주어야 한다. 즉, 우선 접근 가능한 main 계정의 accesskey로 로그인한 이후에 클러스터에 접근하여 configmap을 등록하여야 한다. 여기서 NKS의
~/.kube/config
설정을 가져올 때 ncp-iam-authenticator를 사용한다.ncp-iam-authenticator 설치 가이드에서 ncp-iam-authenticator를 사용할 수 있으며 naver에서 go로 만든 cli 프로그램이며 이 도구를 사용해서 NKS의 kube config 정보를 로컬로 다운로드 받을 수 있다.
config 정보 로컬로 내려받기
$ ncp-iam-authenticator create-kubeconfig --region=[리전] --clusterUuid=[클러스터uuid]
# example
$ ncp-iam-authenticator create-kubeconfig --region=KR --clusterUuid=1b1a2ddd-cae8-4c20-9k91-53ccef322d24ncp-auth 컨피그맵에 서브 계정 등록하기
apiVersion: v1
kind: ConfigMap
metadata:
name: ncp-auth
namespace: kube-system
data:
mapSubAccounts: |
- subAccountIdNo: 서브어카운트아이디
username: 유저명
groups:
- system:masters -
NKS의 서브넷 구성은 각 서브넷마다 라우팅 테이블을 분리하며 일반 서브넷에 존재하는 워커 노드의 ACG 설정에서 퍼블릭 로드밸런서 서브넷 대역을 소스 아이피로 80 (HTTP), 443 (HTTPS), 30000-32767 (노드포트 범위) 허용, 프라이빗 로드밸런서 서브넷 대역은 모든 포트 범위를 허용한다. 때에 따라서 퍼블릭 로드밸런서 서브넷 대역에 포트가 추가되면 특정 포트를 기준으로 하나씩 추가한다.
-
NKS의 InitScript 사용시에 DaemonSet으로 동작하므로 CRI, Kubelet의 설정에는 관여하지 않아야 하며 InitScript는 Kubernetes에서 동작하므로 서버 생성 스크립트와 유사하지만 다른 방식이다.
-
생성 가능한 워커 노드의 갯수는 KVM이 XEN보다 많다.
XEN
: 최대 50개KVM
: 최대 250개
-
NKS 노드의 최신 지원 OS
XEN
: Ubuntu 20.04KVM
: Ubuntu 22.04
Storage
-
CSI를 통해 할당할 수 있는 블록 스토리지의 크기는 10GB 단위로 할당이 가능하다.
- [최소] XEN -
10GB
, KVM -10GB
- [최대] XEN -
2TB
, KVM -16TB
- 기본값:
20GB
- [최소] XEN -
-
storageClass의 volumeBindingMode
Immediate
: 볼륨 바인딩과 동적 프로비저닝이 PVC가 생성되는 시점에 동작WaitForFirstConsumer
: 볼륨 바인딩과 동적 프로비저닝이 PVC를 이용하는 Pod가 생성될 때 동작- 기본 동작은 WaitForFirstConsumer로 PVC를 이용하는 Pod가 생성될 때가 되서야 PV가 생성되고 PVC가 PV에 바인딩되며 대시보드에서 [Server- Storage] 스토리지가 생성되는 것을 확인할 수 있다.
-
storageClass의 reclaimPolicy
Retain
: PVC가 삭제되면 사용 중이던 PV는 재사용이 가능한 상태로 변경되며 스토리지 내부의 데이터는 그대로 유지Delete
: PVC가 삭제되면 사용 중이던 PV 또한 삭제되며 연계되어 있던 블록 스토리지 또한 반납
스토리지 클래스에는 nks-block-storage와 nks-nas-csi가 존재한다.
$ k describe storageclass nks-block-storage
Name: nks-block-storage
IsDefaultClass: Yes
Annotations: kubectl.kubernetes.io/last-applied-configuration={"allowVolumeExpansion":true,"apiVersion":"storage.k8s.io/v1","kind":"StorageClass","metadata":{"annotations":{"storageclass.kubernetes.io/is-default-class":"true"},"name":"nks-block-storage"},"parameters":{"type":"SSD"},"provisioner":"blk.csi.ncloud.com","reclaimPolicy":"Delete","volumeBindingMode":"WaitForFirstConsumer"}
,storageclass.kubernetes.io/is-default-class=true
Provisioner: blk.csi.ncloud.com
Parameters: type=SSD
AllowVolumeExpansion: True
MountOptions: <none>
ReclaimPolicy: Delete
VolumeBindingMode: WaitForFirstConsumer
Events: <none>
$ k describe storageclass nks-nas-csi
Name: nks-nas-csi
IsDefaultClass: No
Annotations: kubectl.kubernetes.io/last-applied-configuration={"allowVolumeExpansion":true,"apiVersion":"storage.k8s.io/v1","kind":"StorageClass","metadata":{"annotations":{},"name":"nks-nas-csi"},"mountOptions":["hard","nolock","nfsvers=3"],"provisioner":"nas.csi.ncloud.com","reclaimPolicy":"Delete","volumeBindingMode":"WaitForFirstConsumer"}
Provisioner: nas.csi.ncloud.com
Parameters: <none>
AllowVolumeExpansion: True
MountOptions:
hard
nolock
nfsvers=3
ReclaimPolicy: Delete
VolumeBindingMode: WaitForFirstConsumer
Events: <none> -
storageClass의 기본 설정은
WaitForFirstConsumer
과Delete
이며 가장 동적으로 사용할 수 있는 동작방식으로 동작하므로 기본 설정 그대로 사용하는 것이 좋을 것 같다. -
파드가 emptyDir을 사용하여 로컬 데이터를 저장하는 경우 이 파드를 삭제시 데이터도 함께 삭제되므로 파드에 마운트할 때는 볼륨을 사용하자.
-
사용하는 클러스터 노드의 하이퍼바이저 종류에 따라 XEN 블록 스토리지 또는 KVM 블록 스토리지가 제공되며 XEN 블록 스토리지는 볼륨 리사이징시에 볼륨이 마운트된 파드 및 디플로이먼트(레플리카 0개로 조정)의 중단이 필요하지만 KVM 블록 스토리지는 볼륨 리사이징시에 다운타임 없이 볼륨을 리사이징할 수 있으므로 무중단 볼륨 리사이징이 필요한 경우 노드의 하이퍼바이저를 KVM으로 선택하여 KVM 블록 스토리지를 사용하도록 해야한다.
-
XEN 하이퍼바이저로 구성된 NKS에서 helm chart로 작성된 alertmanager의 PVC 스토리지 사이즈를 20GB에서 10GB로 변경하여 적용하였더니 모든 alertmanager 파드가 종료되고 PVC를 재할당하였지만 여전히 기존에 생성되었던 20GB 스토리지를 그대로 물고 재시작되는 것을 확인하였고 이를 보아 XEN 하이퍼바이저로 구성된 클러스터에서는 모든 볼륨을 수동으로 재할당해줘야 하는 불편함이 있었다.
-
일본 리전의 경우 NKS 워커노드 하이퍼바이저 선택시 XEN 하나로 고정되어 있지만 한국 리전은 XEN가 KVM 모두 사용이 가능하다. (2024.5.11 기준)
-
NKS 사용시에 노드의 하이퍼바이저 타입을 KVM으로 사용하는 것이 이점이 많아 보이며 여기에는 동적 볼륨 리사이징과 더불어 클러스터의 워커 노드들의 최대 생성 수도 XEN은 50개이지만 KVM은 최대 250개이다.
-
NKS의 볼륨 드라이버는 k8s와 연동되어 블록 스토리지 생성, 삭제, 리사이징 등의 작업을 지원한다.
Loadbalancer
-
ingress-nginx를 통해 client의 실제 IP를 온전하게 취득하기 위해서는 LoadBalancer의 proxy protocol 설정과 ingress-nginx의
use-proxy-protocol: true
ConfigMap이 설정되어 있어야 합니다. -
로드 밸런서에 공인 아이피 및 사설 아이피를 부여하기 위해서 로드밸런서 전용 Public 서브넷과 Private 서브넷 두 유형이 필요하며 로드밸런서를 생성할 때 kube-system 네임스페이스 내의 ncloud-config ConfigMap에서 정의된 lbPublicSubnetNo(로드밸런서 전용 퍼블릭 서브넷)와 lbSubnetNo(로드밸런서 전용 프라이빗 서브넷)에 있는 Subnet ID를 사용한다. 또한 로드밸런서 생성시
service.beta.kubernetes.io/ncloud-load-balancer-subnet-id
annotation을 이용하여 다른 Subnet ID를 사용하도록 지정할 수 있다. -
NKS 서비스 사용시에 외부로 서비스를 노출할 때 로드밸런서가 많이 사용되므로 로드밸런서 전용 퍼블릭 서브넷은 넉넉하게 대역을 잡아주자.
-
로드밸런서 생성시 어노테이션
service.beta.kubernetes.io/ncloud-load-balancer-layer-type
의 값을 지정해주지 않으면 기본값인 nplb (네트워크 프록시 로드밸런서)로 생성된다. -
Kubernetes에서 생성한 네이버 클라우드 플랫폼의 로드밸런서를 Kubernetes의 Service 리소스가 아닌 콘솔 및 API를 통해 설정하는 경우, 상태 동기화에 문제가 발생할 수 있으므로 로드밸런서에 대한 설정 변경은 반드시 Kubernetes에서 생성된 Service 리소스 수정을 통해 이루어져야 한다.
-
하이퍼바이저가 KVM인 클러스터는 ALB Ingress Controller를 기본으로 포함하고 있기 때문에 별도 설치 없이 바로 사용할 수 있습니다. 위에서 언급한 PV 리사이징시에 다운타임없이 사이즈 조정이 가능한 KVM 하이퍼바이저를 사용하는 것이 XEN 하이퍼바이저를 사용하는 것보다 이점이 많다.
-
Ingress를 통해 노 출시킬 서비스는 모두 NodePort type으로 생성해야 하며 매니페스트상 타겟은 number로 지정하는 것이 아니라 서비스 네임으로 지정해야 한다. 노드 포트로 지정하는 것은 로드밸런서와 워커 노드는 인프라적으로 분리되어 있기 때문에 로드밸런서의 타겟그룹으로 워커 노드의 노드 포트를 등록하여 연결시켜줘야 한다.
-
클러스터에서 오류없이 Ingress와 서비스를 잘 연결시켰다면 NCP 대시보드에서 로드밸런서와 타겟그룹이 생성 및 연결된 것을 확인할 수 있다.
-
Default Rule이 매칭되는 Rule이 없을 때 적용되는 Rule이며, spec.defaultBackend에 설정할 수 있고 별도의 rule 및 use-annotation 설정은 불가능하며, 설정하지 않았을 경우 80포트로 설정된 기본 타깃 그룹이 생성된다.
-
Ingress에서 정의한 Rule의 순서에 따라 우선 순위가 결정되며 가장 위에 있는 Rule의 우선 순위가 1로 설정된다.
-
NKS의 타겟 그룹에 대응되는 k8s Service는 ingress를 배포해야만 NCP 콘솔에 등록이 시작된다.
-
NKS의 ALB ingress는 rewrite-target를 지원하지 않으므로 ingress-nginx를 사용해야 한다. ingress-nginx는 기본적으로 설치되어 있지 않기 때문에 설치가 추가적으로 필요하다. 예를 들어 외부에서 각 서비스를 /naver, /platform으로 경로로 라우팅하고 서비스에 연결된 파드도 /naver, /platform 경로에 컨텐츠가 존재하면 rewrite-target이 필요없지만 파드의 컨텐츠가 /처럼 루트 경로로 라우팅하려고 할 경우 외부에서 /naver 경로로 라우팅되고 다시 내부에서 파드로 라우팅할 때 루트 경로로 연결하는 작업이 필요하므로 rewrite-target을 사용한다.
ingress-nginx 컨트롤러 설치
# 설치
$ k apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.1/deploy/static/provider/cloud/deploy.yaml
# ingressclass 확인
# alb의 경우 NCP 내의 Application Load Balancer로 생성
# nginx의 경우 NCP 내의 Network Proxy Load Balancer, Network Load Balancer로 생성
$ k get ingressclasses.networking.k8s.io
NAME CONTROLLER PARAMETERS AGE
alb ncloud.com/alb <none> 3h27m
nginx k8s.io/ingress-nginx <none> 9m43s -
ngress-nginx 컨트롤러는 NCP내에서 Network Proxy LoadBalancer 타입으로 생성되며 ALB 인그레스클래스와 다르게 ingress가 로드밸런서로 등록되는 것이 아니라 ingress-nginx 컨트롤러가 로드밸런서로 등록된다. 즉, ingree-nginx 컨트롤러가 로드밸런서이고 ingress는 로드밸런서의 동작만 정의하게 된다.
-
동시에 NCP 내의 두 개의 타겟그룹도 생성되는데 하나는 로드밸런서IP 80 포트로 들어오면 노드의 특정nodePort로 라우팅되는 1개의 타겟그룹과 로드밸런서IP 443 포트로 들어오면 노드의 특정 nodePort로 라우팅되는 다른 1개의 타겟 그룹이다. 이는 https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.1/deploy/static/provider/cloud/deploy.yaml 매니페스트 파일 중 ingress-nginx-controller 서비스에 80 포트와 443 포트를 등록했기 때문이다.
-
ingress-nginx 컨트롤러의 로드밸런서 타입을 바꾸기 위해서 매니페스트 파일의 어노테이션에 인스턴스 속성을 설정한다.
-
NKS Load Balancer
ingressclass: alb
- KVM 하이퍼바이저를 사용할 경우 ALB 컨트롤러가 사전 설치됨
- alb-ingress-controller에서 실행하며 이 파드의 로그에서 로드밸런서 생성 과정을 확인
- Ingress를 등록하면 로드밸런서 등록과 Ingress에 연결된 서비스가 타겟그룹으로 등록
- rewrite-target 기능 미지원
- Application Load Balancer
ingressclass: nginx
- Nginx 인그레스 컨트롤러를 수동으로 설치해야 함
- ingress-nginx 네임스페이스 내의 ingress-nginx-controller이 직접 로드밸런서에 등록
- Ingress를 등록하면 로드밸런서의 동작을 정의하며 ingress-nginx 컨트롤러의 등록된 타겟그룹으로 라우팅
- rewrite-target 기능 지원
- Network Proxy Load Balancer, Network Load Balancer
-
service.beta.kubernetes.io/ncloud-load-balancer-inbound-source로 Network Loadbalancer 타입은 접근제어가 가능하며 로드밸런서 배포 이후에도 위 어노테이션의 값을 변경하면 설정 적용까지 약 10초 정도 소요된다. 오직 Network Loadbalancer 타입만 적용되며 Network Proxy LoadBalancer 타입은 적용되지 않는다.
-
프라이빗 클러스터에서 서비스를 외부로 노출시키기 위해서는 퍼블릭 로드밸런서 서브넷에 위치한 로드밸런서를 통해서 외부로 노출하게 되는데 이때 로드밸런서가 ALB 타입일 경우 퍼블릭 로드 밸런서 서브넷에 적용된 NACL을 통해서 접근제어를 할 수 있고 인그레스의 어노테이션에
service.beta.kubernetes.io/ncloud-load-balancer-subnet-id
을 지정하여 퍼블릭 서브넷으로 지정한다. -
인그레스에 어노테이션으로 적용된 로드밸런서 타입은 한번 생성하고 난뒤에 변경해도 적용되지 않는다.