• Microsoft CSP
    Microsoft CSP

    S Microsoft CSP transformujeme  business pro dosažení obchodních a technologických cílů.

  • Managed Microsoft 365
    Managed Microsoft 365

    Zajistíme bezpečnost, produktivitu a optimalizaci. Vy se soustředíte na podnikání, my na IT.

  • Dozvědet se víc

    Získejte více informací o produktech Microsoft solution partner

  • Chci vědět víc

    Získejte více informací o produktech Kybernetická bezpečnost

  • Copilot M365
    Copilot M365

    Copilot pro Microsoft 365 nabízí pokročilé AI funkce integrované do byznysových nástrojů.

  • Copilot Osobní trenér
    Copilot Osobní trenér

    Žádné teorie, jen praktické rady a tipy, které vám ušetří čas a energii při vaši každodenní práci.

  • Dozvědet se víc

    Získejte více informací o produktech Umělá inteligence

  • Chci vědět víc

    Získejte více informací o produktech Cloudová infrastruktura

    • KPCS řeší technologické výzvy efektivně a v čas. Tím podporujeme růst vašeho podnikání.

      • Dozvědet se víc

        Získejte více informací o produktech Microsoft solution partner

      • Microsoft CSP
        Microsoft CSP

        S Microsoft CSP transformujeme  business pro dosažení obchodních a technologických cílů.

      • Managed Microsoft 365
        Managed Microsoft 365

        Zajistíme bezpečnost, produktivitu a optimalizaci. Vy se soustředíte na podnikání, my na IT.

    • Kybernetická bezpečnost je klíčová. S našimi službami jsou vaše data a systémy chráněny.

      • Chci vědět víc

        Získejte více informací o produktech Kybernetická bezpečnost

    • Zmapujte svůj potenciál AI a najděte nejlepší řešení. AI bude vaším důvěryhodným kolegou.

      • Dozvědet se víc

        Získejte více informací o produktech Umělá inteligence

      • Copilot M365
        Copilot M365

        Copilot pro Microsoft 365 nabízí pokročilé AI funkce integrované do byznysových nástrojů.

      • Copilot Osobní trenér
        Copilot Osobní trenér

        Žádné teorie, jen praktické rady a tipy, které vám ušetří čas a energii při vaši každodenní práci.

    • Azure je flexibilní a škálovatelná platforma, která poskytuje moderní produkty, služby a provoz.

      • Chci vědět víc

        Získejte více informací o produktech Cloudová infrastruktura

  • Reference
  • Proč KPCS
  • Kariéra
  • Novinky
  • Kontakt
Zpět na novinky

Implementace akv2k8s v Azure Kubernetes Services (AKS)

Blog
19. ledna 2022 KPCS
Implementace akv2k8s v Azure Kubernetes Services (AKS)

Tento LAB popisuje implementaci projektu akv2k8s v Azure Kuberenetes Services / AKS. LAB používá imperativní způsob deploymentu (Azure CLI příkazy v našem případě). Ve svých prostředích pravděpodobně použijete declarativní způsob deploymentu instancí služeb, tzn. definování infrastruktury jako kód (Infrastructure As A Code) prostřednictvím Azure Resource Manager (ARM), Bicep, nebo Terraform.

Dále budete nejspíše orchestrovat takové declarativní definice ve svých Continuous Integration/Continuous Deployment pipelines (S použitím Azure DevOps, nebo Githubu, či jiného CI/CD nástroje). Infrastruktura popsaná níže neobsahuje jiné bezpečnostně orientovaná témata, která by měla být brána v úvahu a implementována s ohledem na základní bezpečnostní úroveň cloud poskytovatele a bezpečnostní úrovně dle požadavků ve vašem projektu (to může být např.: private endpoints, private cluster deployment, encryption at rest, pokročilejší integrace na AAD atp.). Taktéž byste vždy při používání open source projektů jako je akv2k8s měli navštívit github stránky projektu a popřemýšlet o všech aspektech použití vámi vybraného OpenSource projektu před tím, než ho využijete.

Cíl projektu

Cílem tohoto projektu je:

  • test akv2k8s projektu implementací do Azure Kubernetes Services
  • test funkcionality replikace tzv „secrets“ mezi instancemi služeb Azure KeyVault and Azure Kubernetes Services (synchronizace secrets do kubernetes secrets, které jsou trvale uložené v etcd databázi)
  • test funkcionality ve smyslu mapování synchronizovaných secrets jako proměnných do podu, ve kterém běží aplikační kontejner
  • deployment infastruktury dle tohoto designu:

Co není součástí projektu

  • deklarativní způsob deploymentu (který by měl být použit společně s DevOps principy, jako součást Cloud Native architektury), v tomto projektu provádíme deployment deklarativním způsobem pouze u částí deploymentu do kubernetes
  • využítí Using Continuous Integration/ Continuous Deployment (CI/CD) pipelines (taktéž jako best practice pro Cloud Native architekturu)
  • mapování secrets projektem akv2k8s do aplikačního kontejneru napřímo (s použitím sidecar kontejneru) bez synchronizace do kubernetes secrets (jedná se o další způsob implementace projektu akv2k8s, pro více informací využijte dokumentaci projektu)

Předpoklady

Pro realizaci projektu je nezbytné:

  • mít přístup k Azure subscribci (potřebujete mít oprávnění owner, k resource group kterou budeme vytvářet, tj v ideálním případě je mít oprávnění owner už na subscribci ve které budeme resource group vytvářet)
  • Laptop s příkazovou řádkou (Windows with Powershell, Linux, Mac, či cokoliv jiného) nebo využít Azure Cloud shell, jestli potřebujete do svého CLI instalovat Azure CLI, využijte odkaz https://docs.microsoft.com/en-us/cli/azure/install-azure-cli
  • Azure CLI musí být ve verzi minimálně „2.31.0“, použijte „az upgrade“ příkaz pro povýšení Azure CLI na nejnovější verzi, zároveň je nutné mít nainstalované rozšíření Azure CLI „aks-preview“ v minimální verzi „0.5.49“

Níže v LABu použijeme variantu Azure CLI.

Celý LAB si můžete zároveň projít v repository GitHubu

Přípravné práce – deployment Azure infrastruktury do Azure Resource Group

Vytvořte resource group do které budete následně provádět deployment dalších instancí služeb, změňte název resource group v proměnné GROUP_NAME a vámi požadovaný azure region v proměnné LOCATION (pro seznam všech azure regionů využijte dokumentaci: https://azure.microsoft.com/en-us/global-infrastructure/geographies/#overview):

GROUP_NAME=rg-aks-test
LOCATION=northeurope
az group create \
    --location $LOCATION \
    --resource-group $GROUP_NAME
Deployment Azure Container Registry (ACR)

Vytvořte Azure Container Registry (ACR). Název ACR musí být globálně unikátní, proto zaměňte název ACR v proměnné ACR_NAME za vámi vybraný název:

# change the name acraktestaks with your value, it must be globally unique!
ACR_NAME=acraktestaks
az acr create \
    --resource-group $GROUP_NAME \
    --name $ACR_NAME \
    --sku Basic
Deployment User Assigned Managed Identities pro AKS

Vytvořte Azure User Assigned Managed Identity pro AKS cluster, zaměňte hodnotu proměnné UAMI_NAME za vlasntí název:

UAMI_NAME=uami-aks
az identity create \
    --resource-group $GROUP_NAME \
    --name $UAMI_NAME

Vyexportujte ID managed identity do nové proměnné UAMI_ID (bude použita později):

UAMI_ID=$(az identity show \
    --resource-group $GROUP_NAME \
    --query "id" \
    --name $UAMI_NAME \
    -o tsv)

Vytvořte Azure User Assigned Managed Identity pro AKS cluster resp. Kubelet, změňte hodnotu proměnné UAMI_KUBELET_NAME za vlastní název:

UAMI_KUBELET_NAME=uami-aks-kubelet
az identity create \
    --resource-group $GROUP_NAME \
    --name $UAMI_KUBELET_NAME

Vyexportujte ID managed identity Kubeletu do nové proměnné UAMI_KUBELET_ID (bude použita později):

UAMI_KUBELET_ID=$(az identity show \
    --resource-group $GROUP_NAME \
    --query "id" \
    --name $UAMI_KUBELET_NAME \
    -o tsv)
Deployment Azure KeyVault (AKV) s integrací na Azure RBAC

Vytvořte Azure KeyVault instanci, změňte hodnotu proměnné KV_NAME za vlastní název, musí být globálně unikátní:

# change the name kv-testaks with your value, it must be globally unique!
KV_NAME=kv-tstaks
az keyvault create \
    --location $LOCATION \
    --resource-group $GROUP_NAME \
    --enable-rbac-authorization true \
    --name $KV_NAME

Vyexportujte ID KeyVaultu do nové proměnné KV_ID:

KV_ID=$(az keyvault show \
    --resource-group $GROUP_NAME \
    --query "id" \
    --name $KV_NAME \
    -o tsv)

Vyexportujte principalId User Assigned Managed Identity Kubeletu do nové proměnné UAMI_KUBELET_PRINCIPALID (bude použita Kubeletem pro přístup k Azure KeyVaultu, resp. k secrets v něm uloženým):

UAMI_KUBELET_PRINCIPALID=$(az identity show \
    --resource-group $GROUP_NAME \
    --query "principalId" \
    --name $UAMI_KUBELET_NAME \
    -o tsv)

A zároveň přidejte takové identitě přístupové oprávnění právě pro secrets daného Azure KeyVaultu. To provedete tak, že vytvoříte role assignment pro Managed Identitu, kterou AKS cluster používá. K tomu použijte built in roli, která je popsána v dokumentaci „https://docs.microsoft.com/en-us/azure/role-based-access-control/built-in-roles#key-vault-secrets-user“:

az role assignment create \
    --assignee $UAMI_KUBELET_PRINCIPALID \
    --role "Key Vault Secrets User" \
    --scope $KV_ID

V tuto chvíli bychom také měli přidat AAD RBAC roli Azure Key Vault Secret Officer nějakému člověku/týmu/identitě, kdo bude zodpovědný za životní cyklus secretů v Azure KeyVault. Vytvořme tedy proměnnou, která vyexportuje objectId aktuálně přihlášeného uživatele do nové proměnné USER_NAME_OBJECTID:

USER_NAME_OBJECTID=$(az ad signed-in-user show \
    --query "objectId" \
    -o tsv)

A následně přidáme této proměnné built-in roli Azure Key Vault Secret Officer https://docs.microsoft.com/en-us/azure/role-based-access-control/built-in-roles#key-vault-secrets-officer:

az role assignment create \
    --assignee $USER_NAME_OBJECTID \
    --role "Key Vault Secrets Officer" \
    --scope $KV_ID
Deployment další nutné RBAC role

Přidejte další nezbytné oprávnění pro managed identities. Tj přidejte oprávnění pro User Assigned Managed Identity AKS clusteru, tak aby měla roli owner nad User Assigned Managed Identity Kubelet serveru (krok nutný pro úspěšnost následného deploymentu AKS clusteru)

Vyexportujte principalId User Assigned Managed Identity AKS clusteru jako novou proměnnou UAMI_ID_PRINCIPALID:

UAMI_ID_PRINCIPALID=$(az identity show \
    --resource-group $GROUP_NAME \
    --query "principalId" \
    --name $UAMI_NAME \
    -o tsv)

Vytvořte nový role assignment:

az role assignment create \
    --assignee $UAMI_ID_PRINCIPALID \
    --role "Owner" \
    --scope $UAMI_KUBELET_ID
Deployment Azure Kubernetes Services (AKS)

Vytvořte Azure Kubernetes Services (AKS) s použitím níže uvedených parametrů (využíváme dříve exportované proměnné), změňte hodnotu proměnné AKS_NAME za vlastní název, musí být globálně unikátní:

# change the name aks-aktest with your value, it must be globally unique!
AKS_NAME=aks-aktest
az aks create \
    --resource-group $GROUP_NAME \
    --attach-acr $ACR_NAME \
    --enable-managed-identity \
    --assign-identity $UAMI_ID \
    --assign-kubelet-identity $UAMI_KUBELET_ID \
    --node-count 2 \
    --generate-ssh-keys \
    --name $AKS_NAME

V případě, že dostanete chybové hlášky s upozorněním na neznámé argumenty, tak aktualizujte „az cli“ s použitím „az update“ příkazu, viz minimální požadavky v úvodní sekci labu.

Vygenerujte si .kubeconfig soubor abyste měli přístup do AKS clusteru:

# Get cluster credentials
az aks get-credentials \
    --resource-group $GROUP_NAME \
    --name $AKS_NAME

Vyzkoušejte přístup do AKS clusteru s použitím „kubectl“ utility:

kubectl get nodes

Měli byste obdržet výstup podobný tomuto:

kolarik@Azure:~$ kubectl get nodes
NAMESTATUSROLESAGEVERSION
aks-nodepool1-41796624-vmss000000Readyagent15mv1.21.7
aks-nodepool1-41796624-vmss000001Readyagent15mv1.21.7

Deployment akv2k8s controlleru

Deploy kubernetes namespace

Vytvořte kubernetes namespace:

NAMESPACE_NAME=akv2k8s
kubectl create namespace $NAMESPACE_NAME --dry-run=client -o yaml | kubectl apply -f -

Měli byste obdržet výstup podobný tomuto:

namespace/akv2k8s created
Deploy akv2k8s controlleru s použitím helm chartu

Nyní, vytvořte akv2k8s controller s použitím helm chartu do kubernetes namespace. Přidejte „spv-charts“ do lokálního repository:

helm repo add spv-charts https://charts.spvapi.no

Měli byste obdržet výstup podobný tomuto:

"spv-charts" has been added to your repositories

Nyní aktualizujte cache lokálního helm repository:

helm repo update

Měli byste obdržet výstup podobný tomuto:

Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "spv-charts" chart repository
Update Complete. ⎈Happy Helming!⎈

Nyní nainstalujte controller s využitím „helm upgrade“ a parametrů:

helm upgrade -i \
    akv2k8s \
    spv-charts/akv2k8s \
    --namespace $NAMESPACE_NAME

Měli byste obdržet výstup podobný tomuto:

Release "akv2k8s" does not exist. Installing it now.
W0103 11:43:23.082623     167 warnings.go:67] policy/v1beta1 PodDisruptionBudget is deprecated in v1.21+, unavailable in v1.25+; use policy/v1 PodDisruptionBudget
W0103 11:43:23.563168     167 warnings.go:67] policy/v1beta1 PodDisruptionBudget is deprecated in v1.21+, unavailable in v1.25+; use policy/v1 PodDisruptionBudget
NAME: akv2k8s
LAST DEPLOYED: Mon Jan  3 11:43:20 2022
NAMESPACE: akv2k8s
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
Congratulations! You've successfully installed Azure Key Vault to Kubernetes.
For more information see the documentation at https://akv2k8s.io.

Jestli jste došli až sem, tak jste úspěšně nainstalovali potřebnou infrastrukturu, včetně AKS clusteru a controlleru akv2k8s dovnitř kubernetes clusteru.

Nyní můžete vidět, že se nám API schéma aktualizovalo o nové API, zkuste pustit následující příkaz:

kubectl -n akv2k8s api-resources

a uvidíte, že je zde nový typ objektu „akvs“:

Zdroj: https://github.com/akczcz/akv2k8s/blob/main/img/akv-API.PNG

Podívejme se co vše nám helm chart vytvořil:

kubectl -n akv2k8s get all

Měli byste obdržet výstup podobný tomuto:

NAMEREADYSTATUSRESTARTSAGE
pod/akv2k8s-controller-d4ff9564c-qc5vk1/1Running0109m
pod/akv2k8s-envinjector-69f4d6bcb9-2ltcj1/1Running0109m
pod/akv2k8s-envinjector-69f4d6bcb9-mpp4f1/1Running0109m
NAMETYPECLUSTER-IPEXTERNAL-IPEXTERNAL-IPAGE
service/akv2k8s-controllerClusterIP10.0.92.1739000/TCP109m
service/akv2k8s-envinjectorClusterIP10.0.80.235443/TCP,80/TCP,9443/TCP109m
NAMEREADYUP-TO-DATERESTARTSAGE
deployment.apps/akv2k8s-controller1/111109m
deployment.apps/akv2k8s-envinjector2/222109m
NAMEDESIREDCURRENTREADYAGE
replicaset.apps/akv2k8s-controller-d4ff9564c111109m
replicaset.apps/akv2k8s-envinjector-69f4d6bcb9222109m

Můžete se podívat na logy controlleru nově vytvořeného controlleru akv2k8s, zaměňte ale název podu akv2k8s-controller-d4ff9564c-qc5vk za tu vaši, kterou jste získali ve výstupu z předchozího příkazu:

kubectl -n akv2k8s logs akv2k8s-controller-d4ff9564c-qc5vk

Měli byste obdržet výstup podobný tomuto:

I0104 09:44:44.261444       1 main.go:96] "log settings" format="text" level="2"
I0104 09:44:44.261502       1 version.go:31] "version info" version="1.3.0" commit="a375982" buildDate="2021-08-06T06:52:07Z" component="controller"
W0104 09:44:44.261605       1 client_config.go:615] Neither --kubeconfig nor --master was specified.  Using the inClusterConfig.  This might not work.
I0104 09:44:44.263070       1 main.go:161] "Creating event broadcaster"
I0104 09:44:44.836258       1 controller.go:167] "setting up event handlers"
I0104 09:44:44.836291       1 controller.go:178] "starting azurekeyvaultsecret controller"
I0104 09:44:45.336466       1 controller.go:196] "starting azure key vault secret queue"
I0104 09:44:45.336506       1 controller.go:199] "starting azure key vault deleted secret queue"
I0104 09:44:45.336516       1 controller.go:202] "starting azure key vault queue"
I0104 09:44:45.336525       1 controller.go:205] "started workers"

Pamatujte si, jak se podíváte na logy controlleru, velmi pravděpodobně budete takové logy využívat v případě řešení jakýchkoliv obtíží, uvidíte zde informace ohledně synchronizace secrets, včetně případných potíží !!!

Vytvoření testovacích secrets v Azure KeyVault

Vytvoříte testovací secrets v Azure KeyVaultu, můžete jakkoliv změnit hodnoty proměnných, jen si pak nezapomeňte aktualizovat konfigurační scripty v následujících sekcích, jelikož ty konfigurační scripty nejsou parametrizované a mapují se přímo na tyto hodnoty:

SECRET_NAME1="secretname1"
SECRET_VALUE1="TopSecretPassword"
az keyvault secret set \
    --vault-name $KV_NAME \
    --name $SECRET_NAME1 \
    --value $SECRET_VALUE1

SECRET_SQL="sqlconnectionstring"
SECRET_SQL_VALUE="TopSecretConnectionString"
az keyvault secret set \
    --vault-name $KV_NAME \
    --name $SECRET_SQL \
    --value $SECRET_SQL_VALUE

Měli byste pro každý secret obdržet výstup podobný tomuto:

{
  "attributes": {
    "created": "2022-01-04T09:58:02+00:00",
    "enabled": true,
    "expires": null,
    "notBefore": null,
    "recoveryLevel": "Recoverable+Purgeable",
    "updated": "2022-01-04T09:58:02+00:00"
  },
  "contentType": null,
  "id": "https://kv-tstaks.vault.azure.net/secrets/sqlconnectionstring/80a419159fb94611a91f616295bd33bf",
  "kid": null,
  "managed": null,
  "name": "sqlconnectionstring",
  "tags": {
    "file-encoding": "utf-8"
  },
  "value": "TopSecretConnectionString"
}

Záměrně jsem zde nechal celý výstup, tak abyste viděli celé id secretu, včetně jeho názvu (/sqlconnectionstring/) a jeho verze (/80a419159fb94611a91f616295bd33bf), verze se s každou další změnou mění a akv2k8s controller v kubernetes synchronizuje právě nové verze do kubernetes secrets.

Můžete si zobrazit všechny secrety z keyvaultu:

az keyvault secret list --vault-name $KV_NAME -o table

Měli byste obdržet výstup podobný tomuto:

NameIdContentTypeEnabledExpires
secretname1https://kv-tstaks.vault.azure.net/secrets/secretname1True
sqlconnectionstringhttps://kv-tstaks.vault.azure.net/secrets/sqlconnectionstringTrue

nebo si můžete zobrazit seznam secrets v GUI Azure KeyVault instance.

Vytvoření akvs mapovacích objektů uvnitř kubernetes (akvs)

Nejprve vytvořte namespace pro aplikaci, později v tomto namespace vytvoříte secrets, je nutné mít secrets ve stejném namespace jako aplikaci z důvodu budoucích referencí:

NAMESPACE_NAME_APP=app
kubectl create namespace $NAMESPACE_NAME_APP --dry-run=client -o yaml | kubectl apply -f -

Měli byste obdržet výstup podobný tomuto:

namespace/app created

Nyní se podívejte na soubor /manifests/akv.yaml, připravil jsem zde 2 objekty deklarativním způsobem, taktéž si můžete celé repository naklonovat do vašeho lokálního gitu:

DIR_NAME=manifests
mkdir $DIR_NAME
cd $DIR_NAME
vi akv.yaml #and put content of file bellow

Změnte ale hodnoty v yaml souboru, tak aby se popis správně odkazoval na existující odkazy, všímejte si těch položek, za kterými je „#“ a zkontrolujte validnost dané hodnoty:

# secrets for Persistent storage
apiVersion: spv.no/v2beta1
kind: AzureKeyVaultSecret
metadata:
  name: akvs-secret-name1 # 1. name of akvs object
  namespace: app
spec:
  vault:
    name: kv-tstaks # 2. name of key vault, change IT with your value!
    object:
      name: secretname1 # 3. name of the akv object
      type: secret # 4. akv object type
  output: 
    secret: 
      name: akv-secret-name1 # 5. kubernetes secret name
      dataKey: secretname1 # 6. key to store object value in kubernetes apiVersion: v1
---
apiVersion: spv.no/v2beta1
kind: AzureKeyVaultSecret # 1. name of akvs object
metadata:
  name: akvs-secret-sql
  namespace: app
spec:
  vault:
    name: kv-tstaks # 2. name of key vault, change IT with your value!
    object:
      name: sqlconnectionstring # 3. name of the akv object
      type: secret # 4. akv object type
  output: 
    secret: 
      name: akv-sql # 5. kubernetes secret name
      dataKey: sqlconnectionstring # 6. key to store object value in kubernetes apiVersion: v1

Následně tento manifest soubor uložte:

Zdroj: https://github.com/akczcz/akv2k8s/blob/main/img/akv-yaml.PNG

A následně proveďte deployment manifest souboru do kubernetes clusteru:

kubectl apply -f ~/manifests/akv.yaml

Měli byste obdržet výstup podobný tomuto:

azurekeyvaultsecret.spv.no/akvs-secret-name1 created
azurekeyvaultsecret.spv.no/akvs-secret-sql created

Vypište se seznam objektů akvs (mapovací objekty na kuberentes secrets dle předchozího yaml souboru):

kubectl -n app get akvs

Jestli jste udělali někde chybu, tak pravděpodobně nevidíte objekty v synchronizovaném stavu:

NAMEVAULTVAULT OBJECTSECRET NAMESYNCHEDAGE
akvs-secret-name1kv-testaksSECRET-NAME120m
akvs-secret-sqlkv-testaksSECRET-SQL20m

Jestli objekty nejsou v synchronizovaném stavu, tak se běžte podívat na logy akv2k8s controlleru, tak jak jsme si již zkoušeli v předchozích krocích a podívejte se v logu co je chybně (mohou to být přístupové práva, sítě, reference atp.). Jestli jste vše udělali bez chyby, tak byste měli obdržet výstup podobný tomuto:

NAMEVAULTVAULT OBJECTSECRET NAMESYNCHEDAGE
akvs-secret-name1kv-testakssecretname1akv-secret-name15s5m44s
akvs-secret-sqlkv-testakssqlconnectionstringakv-sql5s5m44s

Zároveň byste měli zkontrolovat, zda-li bytvořeny nějaké objekty typu kubernetes secrets:

kubectl -n app get secrets

V případě potíží uvidíte pouze default servisní token secret:

NAMETYPEDATAAGE
default-token-4fjp5kubernetes.io/service-account-token338m

Jestli jsou vaše akvs objekty správně synchronizované, dostanete výstup podobný tomuto:

NAMETYPEDATAAGE
akv-secret-name1Opaque196s
akv-sqlOpaque196s
default-token-4fjp5kubernetes.io/service-account-token372m

Zkuste si následně popsat nějaký secret a podívat se do něj, zdali něco obsahuje:

kubectl -n app describe secret akv-secret-name1

Měli byste obdržet výstup podobný tomuto:

kolarik@Azure:~$ kubectl -n app describe secret akv-secret-name1
Name:akv-secret-name1
Namespace:app
Labels:<"none">
Annotations:<"none">
Type:Opaque
Data
====
secretname1:  17 bytes

Jak asi nejspíše víte, tak kubernetes secrets jsou ukládány do perzistentní vrstvy kubernetes, tj do databáze etcd. Ta není šifrovaná, položky v ní jsou encodované base64 algoritmem, to znamená, že v případě, že v daném namespace máme příslušené oprávnění, můžeme zkusit si daný obsah zobrazit a přes base64 utilitu dekódovat:

kubectl -n app get secrets/akv-secret-name1 --template={ {.data.secretname1} } | base64 -d

Z výstupu bychom měli dostat dekódovaný obsah 🙂

Že je toho na vás příliš? Dobře dáme si přestávku. Příště začneme vytvořením testovací aplikace a mapováním objektů/secrets

Vítejte zpět. A bez dlouhého zdržování se pustíme rovnou do práce.

Vytvoření testovací aplikace a mapování objektů/secrets

Nyní si zkuste vytvořit jednoduchou testovací aplikaci a namapovat pro ni secrets ve formě proměnných, abychom otestovali celý koncept:

# Go to the manigests folder if you did not so far
cd ~/manifests
kubectl create deployment nginx --image=nginx --dry-run=client --namespace=app -o yaml > nginx.yaml

Přízak použije tzv. dry-run, tj s pomocí výstupu do yaml formátu a přesměrováním do souboru provede vytvoření základního yaml konfiguračního souboru, který definuje deployment typu deployment a použije k tomu image kontejneru nginx z veřejně přístupného registru https://hub.docker.com, který je označen tagem latest, pojmenuje takový deployment „nginx“ and vytvoří ho do namespace který se jmenuje „app“, kde jsou již synchronizované secrets, které později použijeme.

V případě že se na obsah souboru podáváte:

# Go to the manigests folder if you did not so far
cd ~/manifests
cat nginx.yaml

měli byste vidět obsah podobný tomuto výstupu:

apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: nginx
  name: nginx
  namespace: app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: nginx
    spec:
      containers:
      - image: nginx
        name: nginx
        resources: {}
status: {}

Nyní aplikujte manifest soubor do kubernetes clusteru, vytvoříte tím deployment, replicaset a pod:

cd ~/manifests
kubectl apply -f  nginx.yaml

Zkontrolujte co jste vytvořili:

kubectl -n app get deploy,pod,rs,service

měli byste vidět obsah podobný tomuto výstupu:

NAMEREADYUP-TO-DATEAVAILABLEAGE
deployment.apps/nginx1/11133s
NAMEREADYSTATUSRESTARTSAGE
pod/nginx-6799fc88d8-cgc6z1/1Running033s
NAMEDESIREDCURRENTREADYAGE
replicaset.apps/nginx-6799fc88d811133s

Jak vidíte, vytvořili jsme 1 x deployment, 1 x replicaset a 1x deployment.

Nyní zkuste pustit příkaz uvnitř kontejneru, v podu, kde zkusíme vypsat pomocí příkazu printenv všechny proměnné, nezapomeňte zaměnit název podu za ten váš:

# change pod name nginx-6799fc88d8-cgc6z with your real one
kubectl -n app exec nginx-6799fc88d8-cgc6z it -- printenv

měli byste vidět obsah podobný tomuto výstupu:

PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=nginx-6799fc88d8-cgc6z
NGINX_VERSION=1.21.5
NJS_VERSION=0.7.1
PKG_RELEASE=1~bullseye
KUBERNETES_PORT=tcp://10.0.0.1:443
KUBERNETES_PORT_443_TCP=tcp://10.0.0.1:443
KUBERNETES_PORT_443_TCP_PROTO=tcp
KUBERNETES_PORT_443_TCP_PORT=443
KUBERNETES_PORT_443_TCP_ADDR=10.0.0.1
KUBERNETES_SERVICE_HOST=10.0.0.1
KUBERNETES_SERVICE_PORT=443
KUBERNETES_SERVICE_PORT_HTTPS=443
HOME=/root

Pamatujte si tento výstup (zkopírujte si ten obsah někam pro budoucí porovnání) … zkusíme nyní do proměnných přidat hodnoty z kubernetes secrets což je cíl našeho labu.

Jestli zeditujeme opět yaml manifest soubor a znovu jej zaplikujeme, tak nám vytvoří nový replicaset a nové pody. (v reálném projektu to však za vás dělají agenti které spouští vaše DevOps pipelines)

Zeditujte nyní manifest soubor a přidejte reference na secrets. Pro snazší orientaci jsem položky označil poznámkou s textem „added new line“. Zároveň můžete smazat nepotřebné řádky jako jsou timespamps a status:

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx
  name: nginx
  namespace: app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  strategy: {}
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - env: # added new line
        - name: SECRET_NAME1 # added new line
          valueFrom: # added new line
            secretKeyRef: # added new line
              name: akv-secret-name1 # added new line
              key: secretname1 # added new line
        - name: SQL_CONNECTION_STRING # added new line
          valueFrom: # added new line
            secretKeyRef: # added new line
              name: akv-sql # added new line
              key: sqlconnectionstring # added new line
        image: nginx
        name: nginx
        resources: {}

Uložte změny „:wq“ ve vimu.

A nyní proveďte znovu aplikaci změn:

cd ~/manifests
kubectl apply -f  nginx.yaml

Jestli neuvidíte nějakou chybovou hlášku, tak byste měli obdržet výstup podobný tomuto:

deployment.apps/nginx configured

Podívejte se, co jste vytvořili:

kubectl -n app get deploy,pod,rs,service

Měli byste obdržet výstup, který ukazuje, že došlo k vytvoření nového replicasetu a podu:

NAMEREADYUP-TO-DATEAVAILABLEAGE
deployment.apps/nginx1/11141m
NAMEREADYSTATUSRESTARTSAGE
pod/nginx-67cfb48f7c-lwwnj1/1Running099s
NAMEDESIREDCURRENTREADYAGE
replicaset.apps/nginx-55ddf89fb700018m
replicaset.apps/nginx-6799fc88d800041m
replicaset.apps/nginx-67cfb48f7c11199s

Nyní konečně zkuste znovu vypsat proměnné zevnitř kontejneru, opět nezapomeňte nahradit název podu v příkazu níže za ten váš:

# change pod name nginx-67cfb48f7c-lwwnj with your real one
kubectl -n app exec nginx-67cfb48f7c-lwwnj it -- printenv

Měli byste obdržet výstup zobrazující taktéž proměnné, které mají stejné hodnoty jak ty v Azure Key Vaults:

PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=nginx-67cfb48f7c-lwwnj
NGINX_VERSION=1.21.5
NJS_VERSION=0.7.1
PKG_RELEASE=1~bullseye
SQL_CONNECTION_STRING=TopSecretConnectionString
SECRET_NAME1=TopSecretPassword
KUBERNETES_SERVICE_PORT=443
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_PORT=tcp://10.0.0.1:443
KUBERNETES_PORT_443_TCP=tcp://10.0.0.1:443
KUBERNETES_PORT_443_TCP_PROTO=tcp
KUBERNETES_PORT_443_TCP_PORT=443
KUBERNETES_PORT_443_TCP_ADDR=10.0.0.1
KUBERNETES_SERVICE_HOST=10.0.0.1
HOME=/root

Zdroj: https://github.com/akczcz/akv2k8s/blob/main/img/printenv.PNG

Jestli jste došli až sem, tak jste vyzkoušeli cíl tohoto projektu, synchronizovali jste Azure KeyVault secrets do kubernetes secrets a namapovali je přes proměnné do aplikace.

Gratuluji Vám !!!

Na konec nezapomeňte smazat všechny vytvořené objekty v LABu, tj smazat celou resource group:

az group delete --resource-group $GROUP_NAME

Tuto implementaci Adam provedl na živé ukázce během webináře „Jak na Hardcoded credentials?“, jeho záznam můžete shlédnou po registraci

Novinky v KPCS

KPCS CZ získala specializaci Build AI Apps on Microsoft Azure
KPCS CZ získala specializaci Build AI Apps on Microsoft Azure

V době, kdy umělá inteligence mění způsob, jakým firmy inovují a komunikují se zákazníky, je důležité být připraven a mít potřebné znalosti i zkušenosti. Získání této specializace od společnosti Microsoft potvrzuje naši odbornost v oblasti návrhu, vývoje a nasazení moderních AI aplikací na platformě Azure.

24. dubna 2025
„AI – Kdy zapnout, kdy vypnout a kdy se usmívat!“
„AI – Kdy zapnout, kdy vypnout a kdy se usmívat!“

Chcete si usnadnit práci? Může být AI vaším nepostradatelným pomocníkem? Převezme AI monotónní úkoly a uvolní čas na strategické myšlení místo administrativy? Zvýšíte efektivitu s AI asistenty a agenty? Tyto a další otázky budou zodpovězeny na našem workshopu, kde se dozvíte, proč je pro vás důležité porozumět AI a jak vám může pomoci v každodenním fungování.

26. února 2025 KPCS
CES 2025 – Technologická inspirace a budoucnost pod taktovkou inovací
CES 2025 – Technologická inspirace a budoucnost pod taktovkou inovací

Každoroční technologický veletrh CES 2025 v Las Vegas znovu překonal očekávání a představil řadu revolučních, ale někdy i velmi podivných produktů a trendů, které formují budoucnost technologického průmyslu.

15. ledna 2025
Kontakt