This repository contains everything that's needed to demo the working principles and building blocks of a Knative based serverless workload on AKS (Kubernetes)
Warning All commands and code used within this repository should be used for demo and learning pursposes only! It may have serious security shortcomings that should NOT be part of your production setup.
deployment.sh
: a complete Bash-script that deploys all steps of this demo automatically (after taking care of some prerequisites)functions
: the (Bash) functions used within thedeployment.sh
Bash-scriptcleanup.sh
: a Bash-script that cleans up everything that's been created by the deployment scriptREADME.md
: the file you're reading now- licence
.var
: file containing all variables that are used within the Bash-scripts.azCred
: contains your Azure credentials. Be very careful with this file and add it to.gitignore
https://github.com/knative/docs/tree/main/code-samples/serving/hello-world/helloworld-python
https://knative.dev https://github.com/knative
https://knative.dev/docs/client/install-kn/
https://learn.microsoft.com/en-us/cli/azure/install-azure-cli https://github.com/Azure/azure-cli
https://github.com/kubernetes/kubectl
- rgName = name of the Resource Group to be used in Azure
- adminName = name of the admin account for the Jumpbox VM
- location = Azure Region to deploy all resources to
- appName = name to be used for the Azure Service Principal
- clusterName = name of the AKS Cluster
- registryName = name of the Azure Container Registry (ACR)
- imageName = name of the container image to be used
- imageTag = version tag for the container
- pullSecretName = name of the Kubernetes secret to be used for pulling the container image from ACR
- k8sNamespace = name of the Kubernetes namespace to be used by Knative
- appMessage = message to be displayed with the Python app
- appName= name of the Knative app to be deployed
- azUsername = your Azure user name
- azPassword = your Azure password
- azSubscription = the Azure subscription you want to uze
variables used in .spCred for this demo (create this file if you already have a Service Principal, otherwise it will be created during Step 1 of the the DEMO)
- appID = Service Principal application ID
- certName = name (and/or path) of the certificate to authenticate the Service Principal
- tenantID = ID of the tenant used
- some Linux-distro running Bash
- one of the following Microsoft Azure accounts:
- User account with
Contributor
role on Subscription or on a Resource Group Service Principal
account withContributor
permissions on Subscription or on a Resource Group
- User account with
az
CLI toolkn
CLI toolkubectl
CLI toolpodman
(ordocker
)- option 1) a file called
.azCred
containing:- Azure username
- Azure password
- Azure subscription to be used
- option 2) a file called
.spCred
containing:- Service Principal App ID
- Path to Service Principal certificate
- tenant ID of the Azure environment
Log in to Azure to deploy a jumbox VM. This step is optional, you can also run all the commands on your local system
or in a VM you host on some platform of your own choice.
source the .azCred and .var files
source .azCred
source .var
Option 1) Log in to Azure and set the Subscription you want to use
az login \
--username $azUsername \
--password $azPassword \
--output none
az account set \
--subscription $azSubscription
Option 2) create a Service Principal (or log in with it if you have one)
#get the subscription ID
subscriptionID=$(az account show --query id --output tsv)
#creat the service principal with scope limited to Resource Group
az ad sp create-for-rbac \
--name $appName \
--role Contributor \
--scopes /subscriptions/$subscriptionID/resourceGroups/$rgName \
--output none
#get AppID for the Service Principal
appID=$(az ad sp list --display-name $appName --query [].appId --output tsv)
printf "\rappID=\"$appID\"\n" >> .spCred
#create a self-signed certificate for the Service Principal and move it to working directory
certPath=$(az ad sp credential reset --id $appID --create-cert --query fileWithCertAndPrivateKey --output tsv)
#move the certificate to the working directory
mv $certPath .
#write the certificate name into .spCred
certName=$(echo $(ls) | grep -o 'tmp.*.pem')
printf "\rcertName=\"$certName\"\n" >> .spCred
#get the Tenant ID
tenantID=$(az account show \
--query tenantId \
--output tsv)
#write tenantID to .spCred
printf "\rtenantID=\"$tenantID\"\n" >> .spCred
#log user out
az logout
#log in with Service Principal
az login --service-principal \
--username $appID \
--password $certName \
--tenant $tenantID \
--output none
az group create \
--name $rgName \
--location $location \
--output none
az vm create \
--name jumpbox \
--resource-group $rgName \
--admin-user $adminName \
--generate-ssh-key \
--image Canonical:0001-com-ubuntu-server-jammy:22_04-lts:22.04.202204200 \
--size Standard_B2ms \
--output none
get jumpbox VM IP address
jumpBoxIP=$(az vm list-ip-addresses \
--resource-group $rgName \
--name jumpbox \
--query [].virtualMachine.network.publicIpAddresses[0].ipAddress \
--output tsv)
copy your azure credentials and helloworld directory to the jumpbox VM:
scp -r .spCred .var helloworld $adminName@$jumpBoxIP:/home/knative
connect to the jumpbox via ssh (might prompt for confirmation because of connection to new remote server)
ssh $adminName@$jumpBoxIP
kn
curl https://storage.googleapis.com/knative-nightly/client/latest/kn-linux-amd64 --output kn
chmod +x kn
sudo mv kn /usr/local/bin
Azure CLI
curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash
kubectl
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
Podman
sudo apt-get -y install podman
source .spCred
source .var
az login --service-principal \
--username $appID \
--password $certName \
--tenant $tenantID \
--output none
make sure you're in the right subscription
az account set --subscription $Subscription
First, select the latest available AKS versions available in your location
aksVersion=$(az aks get-versions \
--location $location \
--output tsv \
--query 'max_by(orchestrators[], &orchestratorVersion).orchestratorVersion')
Deploy the cluster
az aks create \
--name $clusterName \
--resource-group $rgName \
--kubernetes-version $aksVersion \
--node-count 1 \
--node-vm-size Standard_D2_v3 \
--generate-ssh-keys
Get AKS credentials for use with kubectl
az aks get-credentials --resource-group $rgName --name $clusterName
install knative serving crds and core
kubectl apply -f https://github.com/knative/serving/releases/latest/download/serving-crds.yaml
kubectl apply -f https://github.com/knative/serving/releases/latest/download/serving-core.yaml
install Kourier for networking
kubectl apply -f https://github.com/knative/net-kourier/releases/latest/download/kourier.yaml
deploy Knative Serving to use Kourier by default
kubectl patch configmap/config-network --namespace knative-serving --type merge --patch '{"data":{"ingress-class":"kourier.ingress.networking.knative.dev"}}'
deploy Serving Default Domain for service with sslip.io
kubectl apply -f https://github.com/knative/serving/releases/latest/download/serving-default-domain.yaml
Check if name is available (name must be globally unique). This will return true
(available) or false
(unavailable)
az acr check-name --name $registryName --query nameAvailable --output tsv
create ACR
az acr create \
--name $registryName \
--resource-group $rgName \
--sku Standard \
--location $location \
--zone-redundancy Disabled \
--output none
enable admin account
Warning be carefull with providing admin access to the registry!
az acr update \
--name $registryName \
--admin-enabled true \
--anonymous-pull-enabled false \
--output none
get registry credentials for pushing containers and create shell variable
Warning be carefull you don't loose these credentials
acrCred=$(az acr credential show \
--name $registryName \
--query passwords[0].value \
--output tsv)
Change Directory to helloworld
cd helloworld
If you use Docker instead of Podman, you need to log in to the Azure Container Registry
this is needed to make use of the private container registry
echo $acrCred | sudo docker login \
--username $registryName \
--password-stdin \
$registryName.azurecr.io
build the container using the Dockerfile
podman build -t $imageName:$imageTag .
push container to ACR
podman push $registryName:$acrCred $imageName:$imageTag azurecr.io/$imageName:$imageTag
create a pull secret in Kubernetes
Note docker-server value needs to be FQDN including https://
kubectl create secret docker-registry $pullSecretName \
--docker-server=https://$registryName.azurecr.io \
--docker-username=$registryName \
--docker-password=$acrCred
create a namespace for Knative
kubectl create ns $k8sNamespace
make namespace default for all other commands
kubectl config set-context --current --namespace=$k8sNameSpace
edit service.yaml to set values
Make sure that, in the service.yaml
file, the following things are correct and alligned with the values you've chosen during this tutorial:
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: **<service name>**
namespace: **<name for namespace>**
spec:
template:
spec:
containers:
- image: **<registry name>.azurecr.io/<image name>:<tag>**
env:
- name: TARGET
value: **"<your text here>"**
imagePullSecrets:
- name: **<secret name>**
kubectl apply --filename service.yaml
get information about the service and show the URL
kn service describe <service name>
Note If you want to overwrite the previous deployment of the
helloworld
service, add the--force
flag. the--env TARGET=""
flag is optional. When left out, the Python app will use the default as defined in the source code.
kn service create $appName \
--image $registryName.azurecr.io/$imageName:$imageTag \
--pull-secret $pullSecretName \
--env TARGET="$appMessage"