Service IP 범위 확장하기
Service IP 범위 확장하기 (Extend Service IP Ranges)
기능 상태: Kubernetes v1.33부터 Stable.
이 기능은 쿠버네티스에서 안정적이며 v1.33 버전부터 그래왔어요. v1.27 릴리스에서 처음 사용할 수 있었어요. 더 이상 이 기능이나 동작을 비활성화하거나 선택 해제할 수 없어요(잠겨 있음). 연관된 기능 게이트 MultiCIDRServiceAllocator에 값을 명시적으로 설정하면 쿠버네티스는 그것을 무시하지만 오류는 보고하지 않아요.
이 문서는 클러스터에 할당된 기존 Service IP 범위를 확장하는 방법을 공유해요.
출처: 문서
본문
시작하기 전에 (Before you begin)
쿠버네티스 클러스터가 필요하고, kubectl 명령줄 도구가 클러스터와 통신하도록 구성돼 있어야 해요. 이 튜토리얼은 컨트롤 플레인 호스트가 아닌 노드가 두 개 이상 있는 클러스터에서 실행하는 것을 권장해요. 아직 클러스터가 없다면 minikube로 만들거나 다음 쿠버네티스 플레이그라운드 중 하나를 사용할 수 있어요.
- iximiuz Labs
- Killercoda
- KodeKloud
쿠버네티스 서버가 최소 v1.29 버전이어야 해요. 버전을 확인하려면 kubectl version을 입력하세요.
참고: 더 이른 버전에서도 이 기능을 사용할 수 있지만, 이 기능은 v1.33부터 GA이며 공식적으로 지원돼요.
Service IP 범위 확장하기 (Extend Service IP Ranges)
컨트롤 플레인은 잘 알려진 이름 kubernetes를 가진 특별한 ServiceCIDR 객체가 있도록 보장하며, 이 객체는 kube-apiserver에 대한 --service-cluster-ip-range 명령줄 인자 값에 기반한 IP 주소 범위를 지정해요.
kubectl get servicecidr
NAME CIDRS AGE
kubernetes 10.96.0.0/28 17d
Pod에 kube-apiserver 엔드포인트를 노출하는 잘 알려진 kubernetes Service는 기본 ServiceCIDR 범위에서 첫 번째 IP 주소를 계산하고 그 IP 주소를 클러스터 IP 주소로 사용해요.
kubectl get service kubernetes
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 17d
이 경우 기본 Service는 해당 IPAddress 객체가 있는 ClusterIP 10.96.0.1을 사용해요.
kubectl get ipaddress 10.96.0.1
NAME PARENTREF
10.96.0.1 services/default/kubernetes
ServiceCIDR은 Service ClusterIP를 고아로 남기지 않도록 finalizer로 보호돼요. finalizer는 기존 IPAddress를 포함하는 다른 서브넷이 있거나 서브넷에 속한 IPAddress가 없는 경우에만 제거돼요.
Service에 사용 가능한 IP 수 확장하기 (Extend the number of available IPs for Services)
사용자가 Service에 사용 가능한 주소 수를 늘려야 하는 경우가 있어요. 이전에는 Service 범위를 늘리는 것이 중단을 일으키고 데이터 손실을 초래할 수도 있는 작업이었어요. 이 새 기능으로 사용자는 새 ServiceCIDR을 추가하기만 하면 사용 가능한 주소 수를 늘릴 수 있어요.
새 ServiceCIDR 추가하기 (Adding a new ServiceCIDR)
Service에 대해 10.96.0.0/28 범위가 있는 클러스터에는 2^(32-28) - 2 = 14개의 IP 주소만 사용 가능해요. kubernetes.default Service는 항상 생성돼요. 이 예시에서는 13개의 가능한 Service만 남게 돼요.
for i in $(seq 1 13); do kubectl create service clusterip "test-$i" --tcp 80 -o json | jq -r .spec.clusterIP; done
10.96.0.11
10.96.0.5
10.96.0.12
10.96.0.13
10.96.0.14
10.96.0.2
10.96.0.3
10.96.0.4
10.96.0.6
10.96.0.7
10.96.0.8
10.96.0.9
error: failed to create ClusterIP service: Internal error occurred: failed to allocate a serviceIP: range is full
Service에 사용 가능한 IP 주소 수를 늘리려면 기존 IP 주소 범위를 확장하거나 새 범위를 추가하는 새 ServiceCIDR을 만들어요.
cat <<EOF | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: ServiceCIDR
metadata:
name: newcidr1
spec:
cidrs:
- 10.96.0.0/24
EOF
servicecidr.networking.k8s.io/newcidr1 created
그러면 이 새 범위에서 선택될 ClusterIP로 새 Service를 만들 수 있어요.
for i in $(seq 13 16); do kubectl create service clusterip "test-$i" --tcp 80 -o json | jq -r .spec.clusterIP; done
10.96.0.18
10.96.0.4
10.96.0.19
10.96.0.20
(계속) 이후 섹션들에서 ServiceCIDR 삭제, 잘못된 CIDR 처리, ServiceCIDR 설정에 대한 승인 정책(ValidatingAdmissionPolicy) 예시를 다룬다.
서브넷 무결성, 가비지 컬렉션, 보안 (관리 예시)
ServiceCIDR을 보호하기 위한 VAP(ValidatingAdmissionPolicy) 예시:
기본 "kubernetes"가 아닌 ServiceCIDR의 생성을 특정 허용 범위로 제한하는 예시:
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicy
metadata:
name: "servicecidrs.default"
spec:
failurePolicy: Fail
matchConstraints:
resourceRules:
- apiGroups: ["networking.k8s.io"]
apiVersions: ["v1"]
operations: ["CREATE", "UPDATE"]
resources: ["servicecidrs"]
matchConditions:
- name: 'exclude-default-servicecidr'
expression: "object.metadata.name != 'kubernetes'"
variables:
- name: allowed
expression: "['10.96.0.0/16','2001:db8::/64']"
validations:
- expression: "object.spec.cidrs.all(newCIDR, variables.allowed.exists(allowedCIDR, cidr(allowedCIDR).containsCIDR(newCIDR)))"
# For all CIDRs (newCIDR) listed in the spec.cidrs of the submitted ServiceCIDR
# object, check if there exists at least one CIDR (allowedCIDR) in the `allowed`
# list of the VAP such that the allowedCIDR fully contains the newCIDR.
---
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicyBinding
metadata:
name: "servicecidrs-default-binding"
spec:
policyName: "servicecidrs.default"
validationActions: [Deny,Audit]
자체 검증 expression을 작성하려면 CEL 문서를 참고하세요.
ServiceCIDR API의 사용 제한 (Restrict any usage of the ServiceCIDR API)
다음 예시는 ValidatingAdmissionPolicy와 그 바인딩을 사용해 기본 "kubernetes" ServiceCIDR을 제외한 새 Service CIDR 범위의 생성을 제한하는 방법을 보여드려요.
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicy
metadata:
name: "servicecidrs.deny"
spec:
failurePolicy: Fail
matchConstraints:
resourceRules:
- apiGroups: ["networking.k8s.io"]
apiVersions: ["v1"]
operations: ["CREATE", "UPDATE"]
resources: ["servicecidrs"]
validations:
# Deny changes to all ServiceCIDRs except the default one
- expression: "object.metadata.name == 'kubernetes'"
message: "you can only create or update the default ServiceCIDR"
# Deny changes from all users except kube-apiserver
- expression: "request.userInfo.username == 'system:apiserver' && 'system:masters' in request.userInfo.groups"
message: "you can not create or update ServiceCIDR objects"
---
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicyBinding
metadata:
name: "servicecidrs-deny-binding"
spec:
policyName: "servicecidrs.deny"
validationActions: [Deny,Audit]