checked in Azure networking policy samples

This commit is contained in:
Howard Hao 2023-05-22 13:42:08 -07:00
Родитель 8da8f837a2
Коммит c94534af44
5 изменённых файлов: 519 добавлений и 0 удалений

Просмотреть файл

@ -0,0 +1,317 @@
#!/bin/bash
# This shell script demonstrates how to use a host process container to collect
# ETW events for troubleshooting reliability and performance issues in Windows containers.
#
# This script is specifically written for Azure AKS environment, but it can be easily modified to run in other vendors' environments
#
# Key concepts and tools used:
# 1. `kubectl` to deploy pods and label nodes
# 2. Host process containers
# 3. ETW trace event collection with wpr.exe
# 4. `azcopy.exe` to upload and download collected trace files
# 5. Interactions between WSL and Windows desktop
# 6. WPA to exame the collected etl file.
# 7. NPM: Network Policy Manager
# By pass sudo command password
# sudo nano /etc/sudoers
# Insert the following line to sudoers
# <username> ALL=(ALL) NOPASSWD:ALL
# ========= Variables==========
# storage account for uploading collected trace files
storageAccountResourceGroupName=$1
storageAccountlocation=$2
storageAccountName=$3
storageAccountContainerName=$4
subscription=$5
sasExpiryDate=$(date -u -d '1 day' '+%Y-%m-%dT%H:%MZ')
# Define the global variable full_url as azcopy.exe target
declare -g full_url=""
declare -g sastoken=""
#node name defined in the create cluster.sh
nodename=wnode
hostprocesspod=hostsysprocess
#set up alias as shortcuts
k=kubectl
kex="$k exec -n x"
kax="$k apply -n x"
klpx="$k label pod -n x"
hostprocesspod=hostsysprocess
kexhost="$k exec $hostprocesspod --"
CreateHostProcessContainer()
{
#get all the pods on the current cluster before host process container
$k get pods -A
#Create host process container in the default name space
$k label nodes aks"$nodename"000000 vm=0
$k delete pod $hostprocesspod
$k apply -f ./yaml/$hostprocesspod.yaml --wait
$k wait --for=condition=Ready --all --timeout -1s pod
#get all the pods on the current cluster after host process container
$k get pods -A
}
StartPerfTrace()
{
#Start collecting traces with etw providers
$k exec $hostprocesspod -- wpr.exe -start "c:\\Program Files\\Containerd\\containerplatform.wprp" -start cpu -start diskio -start fileio -compress -skipPdbGen -recordtempto d:\\perf
}
DownloadNeededFiles()
{
echo "create d:\perf folder"
$kexhost cmd.exe /C md d:\\perf
echo "copy azcopy.exe to the target node d:\perf folder"
$k cp azcopy.exe $hostprocesspod:d:/perf/azcopy.exe
$k cp ./traceprofiles/ContainerPlatform.wprp $hostprocesspod:d:/perf/ContainerPlatform.wprp
$k cp ./traceprofiles/system.wprp $hostprocesspod:d:/perf/system.wprp
$k cp Switchport.ps1 $hostprocesspod:d:/perf/Switchport.ps1
}
testDeny()
{
MAX_ROUNDS=$((12 * 5)) # 3 minutes
round=1
while [[ $round -le $MAX_ROUNDS ]];
do
$kex b -c cont-80-tcp -- /agnhost connect s-a.x.svc.cluster.local:80 --timeout=5s --protocol=tcp
if [[ $? -ne 0 ]]; then
echo "Applied the policy connection return $? b->a. denied"
return 1
fi
$kex b -c cont-80-tcp -- /agnhost connect s-a.x.svc.cluster.local:80 --timeout=5s --protocol=tcp
echo "sleeping 3 seconds after round $round return $?"
sleep 3
round=$(($round + 1))
done
}
testAllow()
{
MAX_ROUNDS=$((12 * 5)) # 3 minutes
round=1
while [[ $round -le $MAX_ROUNDS ]];
do
$kex b -c cont-80-tcp -- /agnhost connect s-a.x.svc.cluster.local:80 --timeout=5s --protocol=tcp
if [[ $? == 0 ]]; then
echo "connection return $? b->a. allowed"
return 0
fi
$kex b -c cont-80-tcp -- /agnhost connect s-a.x.svc.cluster.local:80 --timeout=5s --protocol=tcp
echo "sleeping 3 seconds after round $round return $?"
sleep 3
round=$(($round + 1))
done
}
GetSwitchPortMappings()
{
filename=$1
portmapping=d:\\perf\\$filename
echo "delete the existing port mapping log files"
$kexhost cmd.exe /C del /Q d:\\perf\\*.log
echo "get current switch port settings"
$kexhost Powershell.exe d:\\perf\\Switchport.ps1
echo "compress the switch port settings"
$kexhost Powershell.exe compress-archive d:\\perf\\*.log $portmapping -force
echo "upload port mapping file"
UploadFile $filename
DownloadFile $filename
}
GetResults()
{
reslutfilename=$1
StopPerfTrace $reslutfilename.etl
GetSwitchPortMappings $reslutfilename.zip
UploadFile $reslutfilename.etl
DownloadFile $reslutfilename.etl
}
ScenarioRepro()
{
GetSwitchPortMappings DefaultPolicy.zip
echo "==================prepare policy pods======================"
StartPerfTrace
$k apply -n x -f ./yaml/test-3-minimal-agnhost-pods.yaml --wait
$k wait --for=condition=Ready --all --timeout -1s pod
echo "------------------------End prepare policy pods--------------------------"
echo "1 ========================Start Default network allow b->a ========================"
$kex b -- echo "Start Default network allow b->a"
$kex b -c cont-80-tcp -- /agnhost connect s-a.x.svc.cluster.local:80 --timeout=5s --protocol=tcp
testAllow
$kex b -- echo "End Default connection return $? b->a allowed"
echo "1 ------------------------End Default connection return $? b->a allowed"
echo "2 ====================== Strt Default network allow c->a =========================="
$kex c -- echo "Start Default network allow c->a"
$kex c -c cont-80-tcp -- /agnhost connect s-a.x.svc.cluster.local:80 --timeout=5s --protocol=tcp
testAllow
GetResults afterpoddeployment
$kex c -- echo "End Default connection return $? c->a allowed"
echo "2 ---------------------- End Default connection return $? c->a allowed"
echo "3 ===================Start Apply the nework policy b->a blocked ==================="
StartPerfTrace
$kex c -- echo "Start Apply the nework policy b->a blocked"
$kax -f ./yaml/policy-ingress-access-from-updated-pod.yaml
testDeny
$kex b -- echo "End Applied the policy connection return $? b->a. denied"
GetResults applypolicy
echo "3 -------------------End Applied the policy connection return $? b->a. denied"
echo "4 ==================Start Label the Pod to allow the traffic b->a allowed ========="
StartPerfTrace
$kex c -- echo "Start Label the Pod to allow the traffic b->a allowed"
$klpx b pod2=updated
testAllow
$kex b -- echo "End Labeled the policy connection return $? b->a. allowed"
GetResults labelPod
echo "4 ------------------End Labeled the policy connection return $? b->a. allowed"
echo "5 ===================Start Unlabled the Pod b->a denied====================================="
StartPerfTrace
$kex c -- echo "Start Unlabled the Pod b->a denied"
$klpx b pod2-
testDeny
$kex b -- echo "End Removed the label the policy connection return $? b->a. denied"
GetResults unlabelPod
echo "5 -------------------End Removed the label the policy connection return $? b->a. denied"
echo "6 =================== Start Delete Policy b->a allowed ======================================"
StartPerfTrace
$kex c -- echo "Start Delete Policy b->a allowed"
kubectl delete -n x -f ./yaml/policy-ingress-access-from-updated-pod.yaml
testAllow
$kex b -- echo "End Removed the policy connection return $? b->a. allowed"
GetResults removepolicy
echo "6 --------------------End Removed the policy connection return $? b->a. allowed"
}
StopPerfTrace()
{
tracefile=$1
#Stop collecting traces
$k exec $hostprocesspod -- wpr.exe -stop d:\\perf\\$tracefile
}
GetStorageSASToken()
{
accountkey=$(az storage account keys list \
--resource-group $storageAccountResourceGroupName \
--account-name $storageAccountName \
--query "[0].value" -o tsv)
# Generate a SAS token for the container
sastoken=$(az storage container generate-sas \
--account-name ${storageAccountName} \
--account-key ${accountkey} \
--name $storageAccountContainerName \
--permissions "rwdl" \
--expiry $sasExpiryDate \
--https-only \
--output tsv)
}
UploadFile()
{
fileToUpload=$1
# Combine the URL, share name, and file path to get the full URL path
echo "containerName: ${storageAccountContainerName}"
echo "fileToUpload: ${fileToUpload}"
echo "sas_token: ${sastoken}"
full_url="https://${storageAccountName}.blob.core.windows.net/${storageAccountContainerName}/${fileToUpload}?${sastoken}"
echo $full_url
#copy the trace to the storage share
$k exec $hostprocesspod -- d:\\perf\\azcopy.exe cp d:\\perf\\$fileToUpload "${full_url}"
#delete the uploaded file
$k exec $hostprocesspod -- cmd.exe del /Q d:\\perf\\$fileToUpload
}
DownloadFile()
{
fileToDownload=$1
#download trace to my local volume
echo "containerName: ${storageAccountContainerName}"
echo "fileToUpload: ${fileToUpload}"
echo "sas_token: ${sastoken}"
download_url="https://${storageAccountName}.blob.core.windows.net/${storageAccountContainerName}/${fileToDownload}?${sastoken}"
azcopy cp "${download_url}" ./results/$fileToDownload
}
Cleanup()
{
$k delete ns chaos-jr --wait
$k -n chaos-jr wait --for=condition=Delete --all --timeout -1s pod
$k delete ns x --wait
$k -n x wait --for=condition=Delete --all --timeout -1s pod
$k delete ns test --wait
$k -n test wait --for=condition=Delete --all --timeout -1s pod
$k create ns x
}
# Set the default account
az account set --subscription "${subscription}"
#step 1
Cleanup
#step 2
GetStorageSASToken
#step 3
CreateHostProcessContainer
#step 4
DownloadNeededFiles
#step 5
ScenarioRepro

Просмотреть файл

@ -0,0 +1,45 @@
function GetRuless {
param(
[Parameter(mandatory=$true)]
[string] $portName
)
$command = 'c:\windows\system32\vfpctrl.exe /list-rule /port "{0}"' -f $portName
Write-Output $command
Invoke-Expression $command | Out-File "d:\perf\$portName.Rule.log"
}
function GetLayers {
param(
[Parameter(mandatory=$true)]
[string] $portName
)
$command = 'c:\windows\system32\vfpctrl.exe /list-layer /port "{0}"' -f $portName
Write-Output $command
Invoke-Expression $command | Out-File "d:\perf\$portName.layer.log"
}
function GetGroups {
param(
[Parameter(mandatory=$true)]
[string] $portName
)
$command = 'c:\windows\system32\vfpctrl.exe /list-group /port "{0}"' -f $portName
Write-Output $command
Invoke-Expression $command | Out-File "d:\perf\$portName.group.log"
}
$switchPorts=vfpctrl /list-vmswitch-port
foreach($port in $switchPorts)
{
if ($port.StartsWith("Port name"))
{
$portparts = $port.split(":")
$portName = $portparts[1].trim()
Write-Output $portName
GetLayers $portName
GetGroups $portName
GetRuless $portName
}
}

Просмотреть файл

@ -0,0 +1,20 @@
apiVersion: v1
kind: Pod
metadata:
labels:
pod: hostsysprocess
name: hostsysprocess
spec:
securityContext:
windowsOptions:
hostProcess: true
runAsUserName: "NT AUTHORITY\\SYSTEM"
hostNetwork: true
containers:
- name: test
image: mcr.microsoft.com/oss/kubernetes/pause:3.9-windows-ltsc2022-amd64
imagePullPolicy: IfNotPresent
command:
- pause.exe
nodeSelector:
vm: "0"

Просмотреть файл

@ -0,0 +1,19 @@
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-client-a-via-pod-selector
spec:
ingress:
- from:
- podSelector:
matchLabels:
pod: b
pod2: updated
- podSelector:
matchLabels:
pod: c
podSelector:
matchLabels:
pod: a
policyTypes:
- Ingress

Просмотреть файл

@ -0,0 +1,118 @@
# pods
apiVersion: v1
kind: Pod
metadata:
labels:
pod: a
name: a
spec:
containers:
- command:
- /agnhost
- serve-hostname
- --tcp
- --http=false
- --port
- "80"
image: k8s.gcr.io/e2e-test-images/agnhost:2.33
imagePullPolicy: IfNotPresent
name: cont-80-tcp
ports:
- containerPort: 80
name: serve-80-tcp
protocol: TCP
nodeSelector:
vm: "0"
---
apiVersion: v1
kind: Pod
metadata:
labels:
pod: b
name: b
spec:
containers:
- command:
- /agnhost
- serve-hostname
- --tcp
- --http=false
- --port
- "80"
image: k8s.gcr.io/e2e-test-images/agnhost:2.33
imagePullPolicy: IfNotPresent
name: cont-80-tcp
ports:
- containerPort: 80
name: serve-80-tcp
protocol: TCP
nodeSelector:
vm: "0"
---
apiVersion: v1
kind: Pod
metadata:
labels:
pod: c
name: c
spec:
containers:
- command:
- /agnhost
- serve-hostname
- --tcp
- --http=false
- --port
- "80"
image: k8s.gcr.io/e2e-test-images/agnhost:2.33
imagePullPolicy: IfNotPresent
name: cont-80-tcp
ports:
- containerPort: 80
name: serve-80-tcp
protocol: TCP
nodeSelector:
vm: "0"
---
# services
apiVersion: v1
kind: Service
metadata:
name: s-a
spec:
ports:
- name: service-port-tcp-80
port: 80
protocol: TCP
targetPort: 80
selector:
pod: a
type: ClusterIP
---
apiVersion: v1
kind: Service
metadata:
name: s-b
spec:
ports:
- name: service-port-tcp-80
port: 80
protocol: TCP
targetPort: 80
selector:
pod: b
type: ClusterIP
---
apiVersion: v1
kind: Service
metadata:
name: s-c
spec:
ports:
- name: service-port-tcp-80
port: 80
protocol: TCP
targetPort: 80
selector:
pod: c
type: ClusterIP