[BUG] cilium operator missing node selector for system nodepool
- Dominant language
- TypeScript
- Stars
- 2.1k
- Forks
- 395
- Avg merge
- 2d 22h
- Merged PRs (30d)
- 13
Description
**Describe the bug**
When enabling Cilium as the network policy engine on an AKS cluster (managed mode via `--network-policy cilium`), the `cilium-operator` Deployment in `kube-system` is deployed without a `nodeSelector` binding it to the system node pool. Although the Deployment includes tolerations for `CriticalAddonsOnly`, `NoExecute`, and `NoSchedule` taints, the absence of a `nodeSelector` means the operator can be freely scheduled on user node pools, which is unexpected for a critical infrastructure component.
This is inconsistent with the AKS best practice of running critical add-ons exclusively on the system node pool, and may cause resource contention on user workload nodes.
**To Reproduce**
1. Create an AKS cluster with Cilium as the network policy engine:
```
az aks create \
--network-plugin azure \
--network-plugin-mode overlay \
--network-policy cilium \
...
```
2. Inspect the cilium-operator Deployment:
```
kubectl get deployment -n kube-system cilium-operator \
-o jsonpath='{.spec.template.spec.nodeSelector}'
```
3. Output is empty — no nodeSelector is set.
4. Inspect tolerations:
```
kubectl get deployment -n kube-system cilium-operator \
-o jsonpath='{.spec.template.spec.tolerations}'
```
5. Output shows wildcard tolerations with no key for NoExecute and NoSchedule, allowing scheduling on any node in the cluster.
**Expected behavior**
The `cilium-operator` Deployment should include a `nodeSelector` targeting the system node pool, for example:
```yaml
nodeSelector:
kubernetes.azure.com/mode: system
```
This would ensure the operator is always scheduled on system nodes, consistent with how other critical AKS add-ons (e.g. `coredns`, `metrics-server`) are pinned to the system pool via the `CriticalAddonsOnly` taint and matching tolerations.
**Screenshots**
```
$ kubectl get pods -n kube-system -o wide | grep cilium
cilium-6mj84 2/2 Running 0 50m 10.64.20.13 aks-infra-18178210-vmss00002e
cilium-787vl 2/2 Running 0 49m 10.64.20.4 aks-dev-11121799-vmss00002f
cilium-crlt9 2/2 Running 0 49m 10.64.20.11 aks-system-54696451-vmss00002e
cilium-h4vcs 2/2 Running 0 49m 10.64.20.12 aks-system-54696451-vmss00002f
**cilium-operator-b5b978c-nmbvt 1/1 Running 0 50m 10.64.20.12 aks-system-54696451-vmss00002f
cilium-operator-b5b978c-qg74p 1/1 Running 0 50m 10.64.20.14 aks-infra-18178210-vmss00002f **
cilium-p6tbm 2/2 Running 0 50m 10.64.20.14 aks-infra-18178210-vmss00002f
cilium-vnfdk 2/2 Running 0 49m 10.64.20.5 aks-dev-11121799-vmss00002e
```
**Environment (please complete the following information):**
- CLI Version:
```
$ az --version
azure-cli 2.77.0 *
core 2.77.0 *
telemetry 1.1.0
Extensions:
monitor-control-service 1.2.0
Dependencies:
msal 1.34.0b1
azure-mgmt-resource 23.3.0
Python (Linux) 3.12.12 (main, Jan 19 2026, 00:00:00) [GCC 11.5.0 20240719 (Red Hat 11.5.0-11)]
Legal docs and information: aka.ms/AzureCliLegal
```
- Kubernetes version:
```
$ kubectl version
Client Version: v1.34.1
Kustomize Version: v5.7.1
Server Version: v1.35.0
```
- CLI Extension version (`aks-preview`):
```
$ az extension show -n aks-preview
The extension aks-preview is not installed. Please install the extension via `az extension add -n aks-preview`.
```
- OS: Linux
**Additional context**
Current tolerations observed on the `cilium-operator` Deployment:
```json
[
{"key": "CriticalAddonsOnly", "operator": "Exists"},
{"effect": "NoExecute", "operator": "Exists"},
{"effect": "NoSchedule", "operator": "Exists"}
]
```
The last two entries are wildcard tolerations (no `key` field), meaning the operator tolerates **any** taint in the cluster and can land on user node pools. Adding a `nodeSelector` for `kubernetes.azure.com/mode: system` would fix the placement without changing the toleration configuration.
Contributor guide
Assessment
This issue has not been assessed yet.