Kubernetes a propojení s cloudovými službami pomocí Workload Identity

31. 8. 2023
Doba čtení: 7 minut

Sdílet

Autor: Depositphotos
Nedávno byla z Azure AD Workload Identity odstraněna nálepka Preview, nejen tím se pro nás stává zajímavé tuto službu prozkoumat. Jedná se o způsob, jak integrovat aplikace běžící v Kubernetes s externím identity providerem.

Popis problému: Máme k dispozici Kubernetes Cluster a v něm běžící aplikaci u které chceme, aby měla přístup k vybraným službám na cloudu (např. Azure Key Vault). Jak nejlépe zajistit autorizaci, propojení a vzájemnou konfiguraci?

Secrets a jejich správa byla vždy výzvou. Ve světě Azure se svatý grál nazývá Service Principal (SP) známý také jako „App Registration“ nebo „Application“, v poslední době také alternativa „Managed Identity“ (MI). SP i MI jsou obvykle spojována s přiřazením práv pro přístup ke službám v Azure.

V tomto případě je velkým omezením doba expirace secretu u SP, což znamená, že se musí pravidelně nahrazovat novým. Taková rotace přináší nezanedbatelnou složitost do infrastruktury a každodenní údržby. Při porovnání s AWS IAM, kde pro uživatele obdobně generujeme credentials jako je „AWS Secret Access Key“, zjistíme že jejich credentials jsou věčné a není je nutné rotovat. Hodnocení takového přístupu nechám na čtenáři.

Jak to vyřešit?

Managed Identity – je skvělá odpověď. Umožňuje přiřadit tuto identitu k určitým Azure službám a pomocí IAM rolí a přiřazení oprávnění řídit přístupová práva. To všechno bez využití tradičních generovaných hesel, automaticky a v principu passwordless.

Nevýhodou je, že Managed Identity nelze přiřadit k identitám mimo ekosystém Azure (např lokální vývoj). To stejné dlouho platilo i pro Kubernetes Cluster, nicméně právě funkcí Workload Identity, která využívá federovanou identitu, tento problém řešíme.

Konečně se dostáváme k původnímu tématu článku, využít Workload Identity, která nám nabízí vše, co potřebujeme: Na jedné straně máme Kubernetes Pod a jeho potřebu mít práva přistupovat do služeb Azure a na druhém Azure Service Principal nebo Managed Identity, jejíž práva chceme využívat.

V článku se zaměříme na používání Workload Identity společně s clusterem Azure AKS, který poskytuje nejběžnější případ použití. Jako Cloud identitu využijeme Managed Identity.

Jak to funguje?

V tomto scénáři přebírá Kubernetes Cluster roli vydavatele tokenů. Generuje tokeny speciálně pro potřeby Kubernetes Service Account. Tyto tokeny lze nakonfigurovat tak, aby jim Azure AD aplikace nebo manažované identity důvěřovaly, a díky tomu má možnost Kubernetes Service Account přistupovat ke službám, ke kterým má vzdálená Azure identita přístup.

Předpoklady:

Azure Portal:

  • vytvořená Resource Group: workload-identity
  • práva pro přiřazování Azure rolí

Celý postup se dá shrnout do 4 kroků:

  1. Vytvoření Azure AD identity
    • Service Principal nebo Managed Identity (na tento se zaměříme my)
  2. Nastavení AKS Clusteru
    • Povolení OIDC and Workload Identity
    • Vytvoření Kubernetes Service Account
  3. Vytvoření důvěry (vazby) mezi Kubernetes Service Accountem a Azure AD identitou
  4. Testování Workload Identity na zkušební aplikaci
    • Založení testovacího Azure Key Vault
    • Vytvoření aplikace – Kubernetes Deployment
    • Nastavení práv Aplikace pro přístup do Azure Key Vault
    • Ověření funkčnosti

Návod

1. Vytvoření identity Azure AD

V našem případě zvolíme metodu (b) Managed Identity, kterou si můžeme vytvořit použitím Azure CLI (příkazové řádky):

S využitím azure cli a příkazové řádky:

az identity create --name our_app_identity --resource-group workload-identity

a nebo přímo v Azure portálu:

Při vytvoření si poznamenejte hodnotu Client ID této identity. V případě příkazu je výstupem soubor ve formátu JSON obsahující hodnotu clientId. V portálu lze hodnotu nalézt v detailu spravované identity.

2. Nastavení AKS Clusteru

Druhým krokem je nastavení AKS clusteru, aby podporoval flagy oidc-issuer a Workload Identity. A následně uvnitř clusteru vytvoření Service Accountu, který bude reprezentovat Managed Identity, kterou jsme vytvořili v Azure.

a) Příprava AKS clusteru:

Vytvoření nového clusteru

​​az aks create --name WORKLOAD-IDENTITY --resource-group workload-identity --enable-oidc-issuer --enable-workload-identity

Upravení již existujícího clusteru

Pomocí Azure CLI:

az aks update --name WORKLOAD-IDENTITY   --resource-group workload-identity --enable-oidc-issuer --enable-workload-identity

Pomocí Terraform:

resource "azurerm_resource_group" "west_europe" {
    name = "workload-identity"
    location = "West Europe"
}

resource "azurerm_kubernetes_cluster" "example" {
    name = "WORKLOAD-IDENTITY"
    location = azurerm_resource_group.west_europe.location
    resource_group_name = azurerm_resource_group.west_europe.name

    # přídáme parametry pro workload-identity a oidc-issuer
    workload_identity_enabled = true
    oidc_issuer_enabled  = true

    # ostatní parametry byly vynechány pro stručnost
}

b) Vytvoření Service Account uvnitř Kubernetes Clusteru

Nejprve je nutné se přihlásit do clusteru

V Azure portále vyhledejte AKS → Otevřete detail našeho clusteru WORKLOAD-IDENTITY → Connect → Spusťte příkazy v bash Cloudshell:

Vytvoření Service Account

Pro vytvoření Kubernetes Recource Service Account upravte příkaz níže, obsahující dvě vstupní hodnoty: TenantID a ClientId naší identity v Azure

export TENANT_ID="<nahrad-vlastnim-tenant-id>" #také známé jako directoryID lze získat https://portal.azure.com/#settings/directory
export MANAGED_IDENTITY_CLIENT_ID="<nahrad-vlastnim-cliend-id>" # Výstup kroku 1

kubectl apply -f -  <<EOF
apiVersion: v1
kind: ServiceAccount
metadata:
 annotations:
   azure.workload.identity/client-id: ${MANAGED_IDENTITY_CLIENT_ID}
   azure.workload.identity/tenant-id: ${TENANT_ID}
 labels:
   azure.workload.identity/use: "true"
 name: root-cz
EOF

3. Vytvoření vazby mezi Azure Managed Identity a Kubernetes Service Account

export SERVICE_ACCOUNT_NAMESPACE="default"
export SERVICE_ACCOUNT_NAME="root-cz"
export AKS_CLUSTER_NAME="WORKLOAD-IDENTITY"
export RESOURCE_GROUP="workload-identity"
export USER_ASSIGNED_MANAGED_IDENTITY_NAME="our_app_identity"


# Output the OIDC issuer URL
SERVICE_ACCOUNT_ISSUER=`az aks show --resource-group "${RESOURCE_GROUP}" --name "${AKS_CLUSTER_NAME}" --query "oidcIssuerProfile.issuerUrl" -otsv`

# Vytvoření federovaných přístupových údajů
az identity federated-credential create \
--name "kubernetes-federated-identity-${SERVICE_ACCOUNT_NAMESPACE}-${SERVICE_ACCOUNT_NAME}" \
--identity-name „${USER_ASSIGNED_MANAGED_IDENTITY_NAME}" \
--resource-group "${RESOURCE_GROUP}" \
--issuer "${SERVICE_ACCOUNT_ISSUER}" \
--subject "system:serviceaccount:${SERVICE_ACCOUNT_NAMESPACE}:${SERVICE_ACCOUNT_NAME}"

4. Testování Workload Identity na zkušební aplikaci

a) Založení testovacího Azure Key Vault

export KEY_VAULT_NAME="workload-identity" #unique name

# Create KeyVault
az keyvault create --name "${KEY_VAULT_NAME}" --resource-group "workload-identity" --location "WestEurope"


# Create a secret
az keyvault secret set --vault-name "${KEY_VAULT_NAME}" --name "testPassword" --value "passw0rd"

b) Vytvoření aplikace – Kubernetes Deployment

kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: demo-app
spec:
replicas: 1
selector:
  matchLabels:
    app: demo-app
template:
  metadata:
    labels:
      app: demo-app
      azure.workload.identity/use: "true"
  spec:
    serviceAccountName: root-cz
    containers:
    - name: demo-app
      image: python:3.9
      command: ["sh", "-c"]
      args:
        - |
          pip install azure-identity azure-keyvault-secrets

          python -c '
          from azure.identity import DefaultAzureCredential
          from azure.keyvault.secrets import SecretClient

          # Set the Azure Key Vault details
          vault_url = "https://workload-identity.vault.azure.net/"
          secret_name = "testPassword"

          # Create an instance of the DefaultAzureCredential class to authenticate
          credential = DefaultAzureCredential()

          # Create an instance of the SecretClient class
          secret_client = SecretClient(vault_url=vault_url, credential=credential)

          # Retrieve the secret value from Azure Key Vault
          secret_value = secret_client.get_secret(secret_name).value

          # Print the secret value
          print(f"The secret value for '{secret_name}' is: {secret_value}")
          '
      workingDir: /
EOF

Ve skriptu výše si povšimněte především:

  • labelu azure.workload.identity/use: "true" ten právě označuje tento deployment jako využivající workload-identity.
  • dále pak associace deploymentu s dříve vytvořeným service-accountem root-czserviceAccountName: root-cz

Následně jsou pak automaticky k podu přidané 4 ENV Variables:

  • AZURE_CLIENT_ID
  • AZURE_TENANT_ID
  • AZURE_FEDERATED_TOKEN_FILE
  • AZURE_AUTHORITY_HOST

ty obsahují hodnoty sloužící k přístupu do Azure. A právě hodnotu AZURE_FEDERATED_TOKEN_FILE Workoad Identity pravidelně rotuje

c) Nastavení práv aplikace pro přístup do Azure Key Vault

Následuje poslední a nejdůležitější část tohoto tutoriálu. Důvod, proč toto cvičení děláme, a to samotné nastavení práv Managed Identity k přístupu do vytvořeného Azure Key Vault.
!Pro tento úkon jsou nezbytná práva přiřazování rolí v Azure AD

Pro přístup do Azure Key Vault jsou potřeba celkem dvě práva:

1. Azure Key Vault Reader role na vytvořený workload-identity Key Vault:

Tato role umožňuje Managed Identity přístup k objektům Azure Key Vault (ne k samotné hodnotě).

2. Access policies – Get and List permissions na Secrets:

Tato permission umožňuje Managed Identity přístup k hodnotě uloženého secretu.

d) Ověření funkčnosti

Vše máme nastavené, deployment vytvořený a potřebujeme se podívat na jeho logy:

kubectl logs deployment/demo-ap

Pokud vidíte v logu tento řádek, gratuluji vám. Znamená to, že Kubernetes pod přistupuje k Azure Key Vault bez manuálně spravovaných přístupů, ale za použití Workload Identity.

The secret value for testPassword is: passw0rd

Workload Identity je skvělý nástroj, jak federovat identitu Azure na jiné aplikace a služby. V našem případě to byla aplikace v rámci spravovaného Kubernetes clusteru, nicméně nic nebrání využít ji například při běhu CI/CD jobů (Github Actions,…).

docker + kubernetes školení s dotací tip

Alternativy

Kdo se problematikou federované identity v clusteru a Azure zabýval, jistě ví, že existuje zdánlivá alternativa Pod-identity. Ta skutečně umožňuje vytvoření obdobného nastavení. Je však nutno říct, že byla označena jako DEPRECATED, jejím následníkem je právě Workload Identity.

Odkazy

(Autorem obrázků je Ondřej Trojan.)

Autor článku

Vystudoval FEL ČVUT obor Kybernetika a Softwarové inženýrství. Pracuje jako DevOps a Solution Architect na volné noze.

Pracuje v technologické společnosti Cleverlance na pozicích DevOps Lead a Cloud Solution Architect. Aktuálně se věnuje především vývoji projektů pro automotive v rámci značek koncernu Volkswagen AG.