I have a azure function app in powershell, dedicated to kubernetes functions.
There are multiple functions but on each of them, the first thing we do is something like this.
az login --service-principal -u $usr -p $pwd --tenant $tenant
$config = $HOME + "/.kube/$tenant";
az account set --subscription $subscription
az aks get-credentials --overwrite-existing --name $cluster --resource-group $rg --admin --file $config
kubectl config set-context --current --namespace=$tenant
This sets the contexts we will be working with on our next kubectl commands.
We do it, because we have multiple clusters on multiple regions, so everytime we get a call on the function app, we need to connect to the given cluster to work on it.
The problem with this is when we get 2 requests at exactly the same time for 2 different clusters and the earliest call will get its context overriden and be executing kubectl commands on the incorrect cluster.
Is there a way to isolate each call or a solution to this?
2
Answers
I think you are referring to concurrent powershell commands execution?
You can wrap those az login/k8s context setting/kubectl commands stuff into a script, and use powershell’s builtin concurrency mechanism to get your job done.
PowerShell concurrently runs commands and scripts through
jobs
.These docs or tutorial may be helpful:
You should be able to just use kubectl’s global
--context
parameter (and--kubeconfig
if needed), example:In case you have two different clusters that are named the same, you can use
az aks get-credentials
own--context
command param, and just pick a discriminator for your concurrent script executions:Note that adding
--admin
command param when fetching credentials will also append-admin
to the names in the kubeconfig; thus forcing you to add "-admin" to the$contextName
:There is a limitation to this, in that
az aks get-credentials
doesn’t allow us to override the parametername
for the generateduser
object (at least not to my knowledge, nor is it mentioned in the docs). Its format is "static" and will always beclusterUser_{resourceGroupName}_{clusterName}
orclusterAdmin_{resourceGroupName}_{clusterName}
if using--admin
.This is really only a concern if you have 2 different clusters that have the exact same name and resource group name (I’d question why this would ever be the case, but alas).
You’d most likely see 2 different outcomes here:
az aks get-credentials
will override the existing object with the new values if you use--overwrite-existing
command param, causing all API calls to the 1st invocation’s cluster to fail with either 401 or 403 related errors (is my guess at least)To counter this you can write to a specific kubeconfig file, again unique to the script’s current context/execution, and then use kubectl’s global
--kubeconfig
command param:Remember to add "-admin" to your
$contextName
, if you use--admin
(and separate the$contextName
and$kubeconfig
assignments, obviously).