1 - HostAliases로 파드의 /etc/hosts 항목 추가하기
파드의 /etc/hosts
파일에 항목을 추가하는 것은 DNS나 다른 방법들이 적용되지 않을 때 파드 수준의 호스트네임 해석을 제공한다. PodSpec의 HostAliases 항목을 사용하여 이러한 사용자 정의 항목들을 추가할 수 있다.
HostAliases를 사용하지 않은 수정은 권장하지 않는데, 이는 호스트 파일이 kubelet에 의해 관리되고, 파드 생성/재시작 중에 덮어쓰여질 수 있기 때문이다.
기본 호스트 파일 내용
파드 IP가 할당된 Nginx 파드를 시작한다.
kubectl run nginx --image nginx
pod/nginx created
파드 IP를 확인해보자.
kubectl get pods --output=wide
NAME READY STATUS RESTARTS AGE IP NODE
nginx 1/1 Running 0 13s 10.200.0.4 worker0
호스트 파일의 내용은 아래와 같을 것이다.
kubectl exec nginx -- cat /etc/hosts
# Kubernetes-managed hosts file.
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
fe00::0 ip6-mcastprefix
fe00::1 ip6-allnodes
fe00::2 ip6-allrouters
10.200.0.4 nginx
기본적으로, hosts
파일은 localhost
와 자기 자신의 호스트네임과 같은 IPv4와 IPv6
상용구들만 포함하고 있다.
hostAliases를 사용하여 추가 항목들 추가하기
기본 상용구 이외에, 추가 항목들을 hosts
파일에
추가할 수 있다.
예를 들어, foo.local
, bar.local
이 127.0.0.1
로,
foo.remote
, bar.remote
가 10.1.2.3
로 해석될 수 있도록, .spec.hostAliases
항목에서 정의하여 파드에
HostAliases를 추가하면 가능하다.
apiVersion: v1
kind: Pod
metadata:
name: hostaliases-pod
spec:
restartPolicy: Never
hostAliases:
- ip: "127.0.0.1"
hostnames:
- "foo.local"
- "bar.local"
- ip: "10.1.2.3"
hostnames:
- "foo.remote"
- "bar.remote"
containers:
- name: cat-hosts
image: busybox:1.28
command:
- cat
args:
- "/etc/hosts"
다음을 실행하여 해당 구성으로 파드를 실행할 수 있다.
kubectl apply -f https://k8s.io/examples/service/networking/hostaliases-pod.yaml
pod/hostaliases-pod created
파드의 세부 정보를 검토하여 IPv4 주소와 상태를 확인해보자.
kubectl get pod --output=wide
NAME READY STATUS RESTARTS AGE IP NODE
hostaliases-pod 0/1 Completed 0 6s 10.200.0.5 worker0
hosts
파일 내용은 아래와 같다.
kubectl logs hostaliases-pod
# Kubernetes-managed hosts file.
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
fe00::0 ip6-mcastprefix
fe00::1 ip6-allnodes
fe00::2 ip6-allrouters
10.200.0.5 hostaliases-pod
# Entries added by HostAliases.
127.0.0.1 foo.local bar.local
10.1.2.3 foo.remote bar.remote
가장 마지막에 추가 항목들이 정의되어 있는 것을 확인할 수 있다.
왜 Kubelet이 호스트 파일을 관리하는가?
컨테이너가 이미 시작되고 난 뒤에
컨테이너 런타임이 hosts
파일을 수정하는 것을 방지하기 위해,
Kubelet이 파드의 각 컨테이너의 hosts
파일을 관리한다.
역사적으로, 쿠버네티스는 컨테이너 런타임으로 계속 도커 엔진을 사용해 왔으며,
각 컨테이너가 시작된 뒤에 도커 엔진이 /etc/hosts
파일을 수정할 수 있었다.
현재 쿠버네티스는 다양한 컨테이너 런타임을 사용할 수 있으며,
kubelet이 각 컨테이너 내의 hosts
파일을 관리하므로
어떤 컨테이너 런타임을 사용하는지에 상관없이 동일한 결과를 얻을 수 있다.
주의:
컨테이너 내부의 호스트 파일을 수동으로 변경하면 안된다.
호스트 파일을 수동으로 변경하면, 컨테이너가 종료되면 변경 사항이 손실된다.
2 - IPv4/IPv6 이중 스택 검증
이 문서는 IPv4/IPv6 이중 스택이 활성화된 쿠버네티스 클러스터들을 어떻게 검증하는지 설명한다.
시작하기 전에
- 이중 스택 네트워킹을 위한 제공자 지원 (클라우드 제공자 또는 기타 제공자들은 라우팅 가능한 IPv4/IPv6 네트워크 인터페이스를 제공하는 쿠버네티스 노드들을 제공해야 한다.)
- 이중 스택 네트워킹을 지원하는 네트워크 플러그인
- 이중 스택 활성화 클러스터
버전 확인을 위해서, 다음 커맨드를 실행 kubectl version
.
참고:
v1.23 이전 버전에서도 검증을 수행할 수 있지만 GA 기능으로만 제공되며, v1.23부터 공식적으로 지원된다.어드레싱 검증
노드 어드레싱 검증
각각의 이중 스택 노드는 단일 IPv4 블록 및 단일 IPv6 블록을 할당받아야 한다. IPv4/IPv6 파드 주소 범위를 다음 커맨드를 실행하여 검증한다. 샘플 노드 이름을 클러스터 내 검증된 이중 스택 노드로 대체한다. 본 예제에서, 노드 이름은 k8s-linuxpool1-34450317-0
이다.
kubectl get nodes k8s-linuxpool1-34450317-0 -o go-template --template='{{range .spec.podCIDRs}}{{printf "%s\n" .}}{{end}}'
10.244.1.0/24
2001:db8::/64
단일 IPv4 블록과 단일 IPv6 블록이 할당되어야 한다.
노드가 IPv4 및 IPv6 인터페이스를 가지고 있는지 검증한다. 노드 이름을 클러스터의 검증된 노드로 대체한다. 본 예제에서 노드 이름은 k8s-linuxpool1-34450317-0
이다.
kubectl get nodes k8s-linuxpool1-34450317-0 -o go-template --template='{{range .status.addresses}}{{printf "%s: %s\n" .type .address}}{{end}}'
Hostname: k8s-linuxpool1-34450317-0
InternalIP: 10.0.0.5
InternalIP: 2001:db8:10::5
파드 어드레싱 검증
파드가 IPv4 및 IPv6 주소를 할당받았는지 검증한다. 파드 이름을 클러스터에서 검증된 파드로 대체한다. 본 예제에서 파드 이름은 pod01
이다.
kubectl get pods pod01 -o go-template --template='{{range .status.podIPs}}{{printf "%s\n" .ip}}{{end}}'
10.244.1.4
2001:db8::4
status.podIPs
fieldPath를 통한 다운워드(downward) API로 파드 IP들을 검증할 수도 있다. 다음 스니펫은 컨테이너 내 MY_POD_IPS
라는 환경 변수를 통해 파드 IP들을 어떻게 노출시킬 수 있는지 보여준다.
env:
- name: MY_POD_IPS
valueFrom:
fieldRef:
fieldPath: status.podIPs
다음 커맨드는 컨테이너 내 MY_POD_IPS
환경 변수의 값을 출력한다. 해당 값은 파드의 IPv4 및 IPv6 주소를 나타내는 쉼표로 구분된 목록이다.
kubectl exec -it pod01 -- set | grep MY_POD_IPS
MY_POD_IPS=10.244.1.4,2001:db8::4
파드의 IP 주소는 또한 컨테이너 내 /etc/hosts
에 적힐 것이다. 다음 커맨드는 이중 스택 파드의 /etc/hosts
에 cat을 실행시킨다. 출력 값을 통해 파드의 IPv4 및 IPv6 주소 모두 검증할 수 있다.
kubectl exec -it pod01 -- cat /etc/hosts
# Kubernetes-managed hosts file.
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
fe00::0 ip6-mcastprefix
fe00::1 ip6-allnodes
fe00::2 ip6-allrouters
10.244.1.4 pod01
2001:db8::4 pod01
서비스 검증
.spec.ipFamilyPolicy
를 명시적으로 정의하지 않은 다음의 서비스를 생성한다. 쿠버네티스는 처음 구성된 service-cluster-ip-range
에서 서비스에 대한 클러스터 IP를 할당하고 .spec.ipFamilyPolicy
를 SingleStack
으로 설정한다.
apiVersion: v1
kind: Service
metadata:
name: my-service
labels:
app.kubernetes.io/name: MyApp
spec:
selector:
app.kubernetes.io/name: MyApp
ports:
- protocol: TCP
port: 80
kubectl
을 사용하여 서비스의 YAML을 확인한다.
kubectl get svc my-service -o yaml
이 서비스에서 .spec.ipFamilyPolicy
를 SingleStack
으로 설정하고 .spec.clusterIP
를 kube-controller-manager의 --service-cluster-ip-range
플래그를 통해 설정된 첫 번째 구성 범위에서 IPv4 주소로 설정한다.
apiVersion: v1
kind: Service
metadata:
name: my-service
namespace: default
spec:
clusterIP: 10.0.217.164
clusterIPs:
- 10.0.217.164
ipFamilies:
- IPv4
ipFamilyPolicy: SingleStack
ports:
- port: 80
protocol: TCP
targetPort: 9376
selector:
app.kubernetes.io/name: MyApp
sessionAffinity: None
type: ClusterIP
status:
loadBalancer: {}
.spec.ipFamilies
의 첫 번째 배열 요소로 IPv6
을 명시적으로 정의하는 다음 서비스를 생성한다. Kubernetes는 service-cluster-ip-range
로 구성된 IPv6 범위에서 서비스용 클러스터 IP를 할당하고 .spec.ipFamilyPolicy
를 SingleStack
으로 설정한다.
apiVersion: v1
kind: Service
metadata:
name: my-service
labels:
app.kubernetes.io/name: MyApp
spec:
ipFamilies:
- IPv6
selector:
app.kubernetes.io/name: MyApp
ports:
- protocol: TCP
port: 80
kubectl
를 사용하여 서비스의 YAML을 확인한다.
kubectl get svc my-service -o yaml
이 서비스에서 .spec.ipFamilyPolicy
를 SingleStack
으로 설정하고 .spec.clusterIP
를 kube-controller-manager의 --service-cluster-ip-range
플래그를 통해 설정된 IPv6 범위에서 IPv6 주소로 설정한다.
apiVersion: v1
kind: Service
metadata:
labels:
app.kubernetes.io/name: MyApp
name: my-service
spec:
clusterIP: 2001:db8:fd00::5118
clusterIPs:
- 2001:db8:fd00::5118
ipFamilies:
- IPv6
ipFamilyPolicy: SingleStack
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
app.kubernetes.io/name: MyApp
sessionAffinity: None
type: ClusterIP
status:
loadBalancer: {}
PreferDualStack
에 .spec.ipFamilyPolicy
을 명시적으로 정의하는 다음 서비스를 생성한다. 쿠버네티스는 IPv4 및 IPv6 주소를 모두 할당하고 (이 클러스터에는 이중 스택을 사용하도록 설정되었으므로) .spec.ipFamilies
배열에 있는 첫 번째 요소의 주소 계열을 기반으로.spec.ClusterIP
목록에서 .spec.ClusterIPs
를 선택한다.
apiVersion: v1
kind: Service
metadata:
name: my-service
labels:
app.kubernetes.io/name: MyApp
spec:
ipFamilyPolicy: PreferDualStack
selector:
app.kubernetes.io/name: MyApp
ports:
- protocol: TCP
port: 80
참고:
kubectl get svc
명령어는 오직 CLUSTER-IP
필드에 주요 IP만 표시한다.
kubectl get svc -l app.kubernetes.io/name: MyApp
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
my-service ClusterIP 10.0.216.242 <none> 80/TCP 5s
서비스가 kubectl describe
를 사용하여 IPv4 및 IPv6 주소 블록에서 클러스터 IP를 가져오는지 확인한다. 그런 다음 IP 및 포트를 통해 서비스에 대한 접속을 확인할 수 있다.
kubectl describe svc -l app.kubernetes.io/name: MyApp
Name: my-service
Namespace: default
Labels: app.kubernetes.io/name: MyApp
Annotations: <none>
Selector: app.kubernetes.io/name: MyApp
Type: ClusterIP
IP Family Policy: PreferDualStack
IP Families: IPv4,IPv6
IP: 10.0.216.242
IPs: 10.0.216.242,2001:db8:fd00::af55
Port: <unset> 80/TCP
TargetPort: 9376/TCP
Endpoints: <none>
Session Affinity: None
Events: <none>
이중 스택 로드 밸런싱 서비스 생성
만약 클라우드 제공자가 IPv6 기반 외부 로드 밸런서 구성을 지원한다면 .spec.ipFamilyPolicy
의 PreferDualStack
과 .spec.ipFamilies
배열의 첫 번째 요소로 IPv6
및 LoadBalancer
로 설정된 type
필드를 사용하여 다음 서비스를 생성한다.
apiVersion: v1
kind: Service
metadata:
name: my-service
labels:
app.kubernetes.io/name: MyApp
spec:
ipFamilyPolicy: PreferDualStack
ipFamilies:
- IPv6
type: LoadBalancer
selector:
app.kubernetes.io/name: MyApp
ports:
- protocol: TCP
port: 80
Check the Service:
kubectl get svc -l app.kubernetes.io/name: MyApp
서비스가 IPv6 주소 블록에서 CLUSTER-IP
주소 및 EXTERNAL-IP
주소를 할당받는지 검증한다. 그리고 나서 IP 및 포트로 서비스 접근이 가능한지 검증할 수 있다.
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
my-service LoadBalancer 2001:db8:fd00::7ebc 2603:1030:805::5 80:30790/TCP 35s
3 - 서비스 IP 범위 확장
Kubernetes v1.33 [stable]
(enabled by default: true)이 문서는 클러스터에 할당된 기존 서비스 IP 범위를 확장하는 방법을 설명한다.
시작하기 전에
쿠버네티스 클러스터가 필요하고, kubectl 커맨드-라인 툴이 클러스터와 통신할 수 있도록 설정되어 있어야 한다. 이 튜토리얼은 컨트롤 플레인 호스트가 아닌 노드가 적어도 2개 포함된 클러스터에서 실행하는 것을 추천한다. 만약, 아직 클러스터를 가지고 있지 않다면, minikube를 사용해서 생성하거나 다음 쿠버네티스 플레이그라운드 중 하나를 사용할 수 있다.
쿠버네티스 서버의 버전은 다음과 같거나 더 높아야 함. 버전: v1.29.버전 확인을 위해서, 다음 커맨드를 실행 kubectl version
.
참고:
이 기능은 이전 버전에서도 사용할 수 있지만, v1.33부터 안정 버전(GA)으로 제공되며 공식 지원한다.서비스 IP 범위 확장
쿠버네티스 클러스터에서 MultiCIDRServiceAllocator
기능 게이트를
활성화한 kube-apiserver를 사용하고 networking.k8s.io/v1beta1
API 그룹이 활성화된 경우,
kubernetes
라는 잘 알려진 이름을 가진 ServiceCIDR 오브젝트를 생성하며,
이는 kube-apiserver의 --service-cluster-ip-range
명령줄 인자 값에 기반하여 IP 주소 범위를 지정한다.
kubectl get servicecidr
NAME CIDRS AGE
kubernetes 10.96.0.0/28 17d
잘 알려진 kubernetes
서비스는 파드에 kube-apiserver 엔드포인트를 노출시키며,
기본 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
이 경우 기본 서비스는 해당 IPAdress 오브젝트와 연결된 ClusterIP 10.96.0.1을 사용한다.
kubectl get ipaddress 10.96.0.1
NAME PARENTREF
10.96.0.1 services/default/kubernetes
ServiceCIDR는 파이널라이저로 보호되어 서비스 ClusterIP가 고아 상태로 남는 것을 방지한다. 파이널라이저(finalizer)는 다른 서브넷에 해당 IPAddress가 포함되어 있거나 해당 서브넷에 속한 IPAddress가 전혀 없는 경우에만 제거된다.
서비스에 사용 가능한 IP 수 확장
사용자가 서비스에 사용 가능한 주소 수를 늘려야 하는 경우가 있는데, 이전에는 서비스 범위를 늘리는 작업이 데이터 손실을 초래할 수 있는 파괴적인 작업이었다. 이 새로운 기능을 통해 사용자는 사용할 수 있는 주소 수를 늘리기 위해 단순히 새로운 ServiceCIDR을 추가하면 된다.
새로운 ServiceCIDR 추가
서비스에 10.96.0.0/28 대역을 사용하는 클러스터에서는 2^(32-28) - 2 = 14개의
IP 주소만 사용할 수 있다. kubernetes.default
서비스는 항상 생성되므로, 이 예시에서는
실제로 13개의 서비스만 만들 수 있다.
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
서비스에서 사용할 수 있는 IP 주소 수를 늘리려면, IP 주소 범위를 확장하거나 새 IP 주소 범위를 추가하는 새 ServiceCIDR을 생성하면 된다.
cat <EOF | kubectl apply -f -
apiVersion: networking.k8s.io/v1beta1
kind: ServiceCIDR
metadata:
name: newcidr1
spec:
cidrs:
- 10.96.0.0/24
EOF
servicecidr.networking.k8s.io/newcidr1 created
이렇게 하면 새 범위에서 ClusterIP를 할당받는 새로운 서비스를 생성할 수 있다.
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.48
10.96.0.200
10.96.0.121
10.96.0.144
ServiceCIDR 삭제
해당 ServiceCIDR에 의존하는 IPAddresses가 존재하는 경우 해당 ServiceCIDR을 삭제할 수 없다.
kubectl delete servicecidr newcidr1
servicecidr.networking.k8s.io "newcidr1" deleted
쿠버네티스는 이러한 종속 관계를 추적하기 위해 ServiceCIDR에 파이널라이저를 사용한다.
kubectl get servicecidr newcidr1 -o yaml
apiVersion: networking.k8s.io/v1beta1
kind: ServiceCIDR
metadata:
creationTimestamp: "2023-10-12T15:11:07Z"
deletionGracePeriodSeconds: 0
deletionTimestamp: "2023-10-12T15:12:45Z"
finalizers:
- networking.k8s.io/service-cidr-finalizer
name: newcidr1
resourceVersion: "1133"
uid: 5ffd8afe-c78f-4e60-ae76-cec448a8af40
spec:
cidrs:
- 10.96.0.0/24
status:
conditions:
- lastTransitionTime: "2023-10-12T15:12:45Z"
message: There are still IPAddresses referencing the ServiceCIDR, please remove
them or create a new ServiceCIDR
reason: OrphanIPAddress
status: "False"
type: Ready
ServiceCIDR 삭제를 막고 있는 IP 주소를 포함하는 서비스를 제거함으로써
for i in $(seq 13 16); do kubectl delete service "test-$i" ; done
service "test-13" deleted
service "test-14" deleted
service "test-15" deleted
service "test-16" deleted
컨트롤 플레인이 해당 제거를 감지한다. 이어서, 컨트롤 플레인은 파이널라이저를 삭제하므로, 삭제 대기 상태였던 ServiceCIDR이 실제로 제거된다.
kubectl get servicecidr newcidr1
Error from server (NotFound): servicecidrs.networking.k8s.io "newcidr1" not found
쿠버네티스 ServiceCIDR 정책
클러스터 관리자는 클러스터 내에서 ServiceCIDR 리소스의 생성과 수정을 제어하는 정책을 구현할 수 있다. 이를 통해 서비스에 사용되는 IP 주소 범위를 중앙에서 관리하고 의도치 않거나 충돌하는 구성을 방지할 수 있다. 쿠버네티스는 이러한 규칙을 강제하기 위해 Validating Admission Policy와 같은 메커니즘을 제공한다.
Validating Admission Policy로 무단 ServiceCIDR 생성/수정 방지
클러스터 관리자는 허용할 수 있는 범위를 제한하거나, 클러스터 서비스 IP 범위에 대한 변경을 완전히 차단하고자 하는 상황이 있을 수 있다.
참고:
기본 "kubernetes" ServiceCIDR는 클러스터의 일관성을 유지하기 위해
kube-apiserver에 의해 생성되며, 클러스터가 동작하기 위해 필요하므로
항상 허용되어야 한다. ValidatingAdmissionPolicy
가 기본 ServiceCIDR을
제한하지 않도록 하려면, 다음과 같이 절을 추가하면 된다.
matchConditions:
- name: 'exclude-default-servicecidr'
expression: "object.metadata.name != 'kubernetes'"
아래 예시에서처럼 적용할 수 있다.
특정 범위로 ServiceCIDR 제한
다음은 allowed
로 지정한 범위의 서브넷인 경우에만 ServiceCIDR을 생성할 수 있도록
허용하는 ValidatingAdmissionPolicy
예시이다. (예를 들어, 이 정책에서는
cidrs: ['10.96.1.0/24']
또는 cidrs: ['2001:db8:0:0:ffff::/80', '10.96.0.0/20']
를
가진 ServiceCIDR은 허용되지만, cidrs: ['172.20.0.0/16']
를
가진 ServiceCIDR은 허용되지 않는다.) 이 정책을 복사하여 환경에 맞게
allowed
값을 변경해 사용할 수 있다.
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicy
metadata:
name: "servicecidrs.default"
spec:
failurePolicy: Fail
matchConstraints:
resourceRules:
- apiGroups: ["networking.k8s.io"]
apiVersions: ["v1","v1beta1"]
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-binding"
spec:
policyName: "servicecidrs.default"
validationActions: [Deny,Audit]
자체 검증 expression
을 작성하려면
CEL 문서를 참고하면 된다.
ServiceCIDR API 사용 전면 제한
아래 예시는 기본 "kubernetes" ServiceCIDR을 제외하고,
새로운 ServiceCIDR 범위 생성을 제한하기 위해 ValidatingAdmissionPolicy
와 해당 바인딩을 사용하는 방법을 보여준다.
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicy
metadata:
name: "servicecidrs.deny"
spec:
failurePolicy: Fail
matchConstraints:
resourceRules:
- apiGroups: ["networking.k8s.io"]
apiVersions: ["v1","v1beta1"]
operations: ["CREATE", "UPDATE"]
resources: ["servicecidrs"]
validations:
- expression: "object.metadata.name == 'kubernetes'"
---
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicyBinding
metadata:
name: "servicecidrs-deny-binding"
spec:
policyName: "servicecidrs.deny"
validationActions: [Deny,Audit]