OVN-Kubernetes Node Identity¶
Introduction¶
The OVN-Kubernetes node identity feature introduces a per-node client certificate for ovnkube-node pods, together with a validating admission webhook, enabling granular permission enforcement specific to ovn-kubernetes. Previously, all ovnkube-node pods shared a common service account, with their API permissions managed only through Kubernetes RBAC rules.\ The goal of this feature is to limit ovnkube-node permissions to the minimum required for networking management on a specific Kubernetes node. We will mimic the approach used by kubelet in which every node has a unique identity, and its API write requests are verified using a NodeRestriction validating admission webhook.
Always check the dependencies on the Requirements page
Per-node client certificates¶
This process mimics the bootstrap initialization in kubelet. When the ovnkube-node starts for the first time, it uses the host's kubeconfig to create a CertificateSigningRequest that requests a client certificate for the system:ovn-node:<nodeName> user in the system:ovn-nodes group. This request is then signed by the kubernetes.io/kube-apiserver-client signer.
For the certificate to be signed, it must first be approved. The newly introduced OVNKubeCSRController component approves or denies CertificateSigningRequests created for users with the system:ovn-node prefix. The OVNKubeCSRController performs several checks to validate the requested certificate, including: - Ensuring that the node name extracted from the request matches the node name of the user that sent it. - Verifying that the group is set to system:ovn-nodes. - Checking that the certificate expiration does not exceed the maximum allowed duration.
Once the certificate is approved and signed, ovnkube-node uses it to communicate with the API server and request a new certificate upon expiration. The RBAC rules are consistent across all ovnkube-node pods, we use the system:ovn-nodes group as the subject for Role/ClusterRole bindings to avoid duplication:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: ovnkube-node
roleRef:
name: ovnkube-node
kind: ClusterRole
apiGroup: rbac.authorization.k8s.io
subjects:
- kind: Group
name: system:ovn-nodes
apiGroup: rbac.authorization.k8s.io
Validating Admission Webhook¶
The feature introduces a validating webhook for updates to pod/status and node/status.\ The ovnkube-node pod exclusively updates the status on both resources, so it is sufficient to verify only update requests.\ The webhooks include the following checks for each ovnkube-node pod: - Modifying annotations on pods hosted on its own node. - Modifying annotations on its own node. - Modifying only allowed annotations. - Not modifying anything other than annotations.
The allowed annotations list contains both common and feature specific values: - By default, the webhook will verify common node annotations and pod/node annotations set by the ovnkube-node component. - When enable-hybrid-overlay parameter is provided the webhook will validate additional node annotations set by the ovnkube-node component for hybrid overlay.
The specific annotation values can be found in go-controller/pkg/ovnwebhook/nodeadmission.go and go-controller/pkg/ovnwebhook/podadmission.go files.
Some of the allowed annotations have additional checks; for instance, the IP addresses in k8s.ovn.org/pod-networks must match the node's k8s.ovn.org/node-subnets networks.
DaemonSet¶
In Kind, the feature is enabled by default and can be disabled with --disable-ovnkube-identity when creating the cluster.\ By default, the webhook listens on the nodes localhost address so there has to be an instance running on the control-plane node:
kubectl get pod -lname=ovnkube-identity -n ovn-kubernetes -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
ovnkube-identity-57f9778d99-llfqz 1/1 Running 0 30m 172.18.0.3 ovn-control-plane <none> <none>