Cloud Controller Manager 운영
Cloud Controller Manager 운영 (Cloud Controller Manager Administration)
기능 상태: Kubernetes v1.11부터 Beta.
클라우드 제공업체는 쿠버네티스 프로젝트와는 다른 속도로 개발하고 릴리스해요. 그래서 제공업체-specific 코드를 cloud-controller-manager 바이너리로 추상화하면 클라우드 벤더가 코어 쿠버네티스 코드와 독립적으로 발전할 수 있어요.
cloud-controller-manager는 cloudprovider.Interface를 충족하는 어떤 클라우드 제공업체에든 연결할 수 있어요. 하위 호환성을 위해 코어 쿠버네티스 프로젝트가 제공하는 cloud-controller-manager는 kube-controller-manager와 동일한 클라우드 라이브러리를 사용해요. 쿠버네티스 코어에서 이미 지원되는 클라우드 제공업체는 in-tree cloud-controller-manager를 사용해 쿠버네티스 코어에서 이전(transition)하는 것이 예상되는 방식이에요.
출처: 문서
본문
운영 (Administration)
요구 사항 (Requirements)
모든 클라우드는 자체 클라우드 제공업체 연동을 실행하기 위한 나름의 요구 사항이 있어요. kube-controller-manager를 실행할 때의 요구 사항과 크게 다르지는 않아요. 일반적인 기준으로 대략 다음이 필요해요.
- 클라우드 인증/인가: 클라우드 제공업체의 API에 접근하려면 토큰이나 IAM 규칙이 필요할 수 있어요.
- 쿠버네티스 인증/인가: cloud-controller-manager가 쿠버네티스 apiserver와 통신하려면 RBAC 규칙이 설정돼 있어야 해요.
- 고가용성(high availability): kube-controller-manager와 마찬가지로, 리더 선출(leader election, 기본적으로 켜져 있음)을 사용해 cloud controller manager를 고가용성으로 구성하고 싶을 거예요.
cloud-controller-manager 실행 (Running cloud-controller-manager)
cloud-controller-manager를 성공적으로 실행하려면 클러스터 구성에 몇 가지 변경이 필요해요.
- 사용자가 외부 CCM을 사용한다면
kubelet과kube-controller-manager를 그에 맞춰 설정해야 해요. 외부 CCM(쿠버네티스 Controller Manager 내부의 클라우드 컨트롤러 루프가 아닌)을 사용한다면--cloud-provider=external을 지정해야 해요. 그렇지 않으면 지정하지 말아야 해요.
cloud controller manager를 사용하도록 클러스터를 설정하면 클러스터 동작이 몇 가지 방식으로 바뀐다는 점을 명심하세요.
--cloud-provider=external을 지정한 컴포넌트는 초기화 중에NoScheduleeffect를 가진node.cloudprovider.kubernetes.io/uninitialized테인트(taint)를 추가해요. 이는 해당 노드가 작업을 스케줄링받기 전에 외부 컨트롤러의 두 번째 초기화가 필요함을 표시해요. cloud controller manager를 사용할 수 없는 경우 클러스터의 새 노드는 스케줄할 수 없는 상태로 남게 돼요. 스케줄러는 노드의 리전이나 유형(고CPU, GPU, 고메모리, 스팟 인스턴스 등) 같은 클라우드 관련 정보가 필요할 수 있기 때문에 이 테인트는 중요해요.- 클러스터에 있는 노드의 클라우드 정보는 더 이상 로컬 메타데이터로 조회되지 않아요. 대신 노드 정보를 조회하는 모든 API 호출이 cloud controller manager를 거쳐요. 이는 보안을 위해 kubelet의 클라우드 API 접근을 제한할 수 있다는 뜻이에요. 대규모 클러스터의 경우, cloud controller manager가 이제 클러스터 내부에서 발생하는 거의 모든 클라우드 API 호출을 담당하게 되므로 API rate limit에 걸릴지 고려해 볼 필요가 있어요.
cloud controller manager는 다음을 구현할 수 있어요.
- Node controller - 클라우드 API를 사용해 쿠버네티스 노드를 업데이트하고, 클라우드에서 삭제된 쿠버네티스 노드를 삭제해요.
- Service controller - LoadBalancer 유형의 서비스에 대해 클라우드의 로드밸런서를 담당해요.
- Route controller - 클라우드에 네트워크 라우트를 설정해요.
- out-of-tree 제공업체를 실행 중이라면 원하는 다른 기능도 구현할 수 있어요.
예시 (Examples)
쿠버네티스 코어에서 지원되는 클라우드를 사용하면서 cloud controller manager를 도입하고 싶다면, 쿠버네티스 코어에 있는 cloud controller manager를 참고하세요.
쿠버네티스 코어에 없는 cloud controller manager의 경우, 클라우드 벤더나 SIG가 유지 관리하는 저장소에서 각 프로젝트를 찾을 수 있어요.
이미 쿠버네티스 코어에 있는 제공업체라면, in-tree cloud controller manager를 클러스터에서 DaemonSet으로 실행할 수 있어요. 다음을 가이드라인으로 사용하세요.
# 이 예시는 클러스터에서 cloud-controller-manager를 DaemonSet으로 설정하는 방법을 보여줍니다.
# 마스터가 파드를 실행할 수 있고 node-role.kubernetes.io/master 역할을 가진다고 가정합니다.
# 참고: 이 DaemonSet은 여러분의 클라우드에서 바로 동작하지 않을 수 있으며, 가이드라인입니다.
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: cloud-controller-manager
namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: system:cloud-controller-manager
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: cloud-controller-manager
namespace: kube-system
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
labels:
k8s-app: cloud-controller-manager
name: cloud-controller-manager
namespace: kube-system
spec:
selector:
matchLabels:
k8s-app: cloud-controller-manager
template:
metadata:
labels:
k8s-app: cloud-controller-manager
spec:
serviceAccountName: cloud-controller-manager
containers:
- name: cloud-controller-manager
# in-tree 제공업체의 경우 registry.k8s.io/cloud-controller-manager 사용
# out-of-tree 제공업체의 경우 다른 이미지로 교체 가능
image: registry.k8s.io/cloud-controller-manager:v1.8.0
command:
- /usr/local/bin/cloud-controller-manager
- --cloud-provider=[YOUR_CLOUD_PROVIDER] # 여기에 자신의 클라우드 제공업체를 넣으세요!
- --leader-elect=true
- --use-service-account-credentials
# 이 플래그들은 클라우드 제공업체마다 다릅니다
- --allocate-node-cidrs=true
- --configure-cloud-routes=true
- --cluster-cidr=172.17.0.0/16
tolerations:
# CCM이 스스로 부트스트랩할 수 있어야 하므로 필요합니다
- key: node.cloudprovider.kubernetes.io/uninitialized
value: "true"
effect: NoSchedule
# 아래 톨러레이션은 데몬셋이 컨트롤 플레인 노드에서 실행되도록 하기 위한 것입니다
# 컨트롤 플레인 노드가 파드를 실행하면 안 된다면 제거하세요
- key: node-role.kubernetes.io/control-plane
operator: Exists
effect: NoSchedule
- key: node-role.kubernetes.io/master
operator: Exists
effect: NoSchedule
# CCM이 마스터 노드에서만 실행되도록 제한합니다
# 노드 셀렉터는 클러스터 구성에 따라 다를 수 있습니다
nodeSelector:
node-role.kubernetes.io/master: ""
admin/cloud/ccm-example.yaml 제한 사항 (Limitations)
cloud controller manager를 실행하면 몇 가지 잠재적인 제한 사항이 따라올 수 있어요. 이 제한 사항들은 향후 릴리스에서 해결되고 있지만, 프로덕션 워크로드에서는 이 제한 사항들을 알고 있는 것이 중요해요.
볼륨 지원 (Support for Volumes)
cloud controller manager는 kube-controller-manager에 있는 볼륨 컨트롤러를 구현하지 않아요. 볼륨 통합은 kubelet과의 조정도 필요하기 때문이에요. CSI(container storage interface)가 발전하고 flex volume 플러그인 지원이 강화되면서, 클라우드가 볼륨과 완전히 통합될 수 있도록 필요한 지원이 cloud controller manager에 추가될 거예요. out-of-tree CSI 볼륨 플러그인에 대해 자세히 알아보세요.
확장성 (Scalability)
cloud-controller-manager는 모든 노드의 정보를 조회하기 위해 클라우드 제공업체의 API를 호출해요. 매우 큰 클러스터에서는 리소스 요구 사항이나 API rate limit 같은 가능한 병목 지점을 고려하세요.
닭과 달걀 문제 (Chicken and Egg)
cloud controller manager 프로젝트의 목표는 클라우드 기능 개발을 코어 쿠버네티스 프로젝트에서 분리하는 것이에요. 안타깝게도 쿠버네티스 프로젝트의 많은 부분은 클라우드 제공업체 기능이 프로젝트에 긴밀하게 통합돼 있다고 가정해요. 그래서 이 새로운 아키텍처를 도입하면, 클라우드 제공업체에 정보를 요청했지만 cloud controller manager가 원래 요청이 완료되지 않으면 그 정보를 반환하지 못하는 상황이 여러 번 발생할 수 있어요.
대표적인 예가 Kubelet의 TLS 부트스트래핑 기능이에요. TLS 부트스트래핑은 Kubelet이 클라우드 제공업체(또는 로컬 메타데이터 서비스)에 자신의 모든 주소 유형(사설, 공용 등)을 물어볼 수 있다고 가정해요. 하지만 cloud controller manager는 kubelet이 apiserver와 통신할 TLS 인증서를 가지고 있어야 초기화될 수 있기 때문에, 노드의 주소 유형을 먼저 설정해 줄 수 없어요.
이 계획이 발전하면서 향후 릴리스에서 이러한 문제를 해결하기 위한 변경이 이루어질 거예요.
다음 단계 (What's next)
자체 cloud controller manager를 빌드하고 개발하려면, Developing Cloud Controller Manager를 읽어 보세요.