-
Notifications
You must be signed in to change notification settings - Fork 145
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
194 additions
and
0 deletions.
There are no files selected for viewing
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,194 @@ | ||
# Example of static PV mount with workload identity | ||
|
||
## prerequisite | ||
|
||
### 1. Create a cluster with oidc-issuer enabled | ||
``` | ||
export RESOURCE_GROUP=<your resource group name> | ||
export CLUSTER_NAME=<your cluster name> | ||
export REGION=<your region> | ||
az group create --name $RESOURCE_GROUP --location $REGION | ||
az aks create -n $CLUSTER_NAME -g $RESOURCE_GROUP --enable-oidc-issuer | ||
az aks get-credentials -n $CLUSTER_NAME -g $RESOURCE_GROUP --overwrite-existing | ||
``` | ||
|
||
### 2. Create a storage account and fileshare (or use your own storage account and fileshare) | ||
``` | ||
export ACCOUNT=<your storage account name> | ||
az storage account create \ | ||
--resource-group $RESOURCE_GROUP \ | ||
--name $ACCOUNT \ | ||
--location $REGION \ | ||
--kind StorageV2 \ | ||
--sku Standard_LRS \ | ||
--enable-large-file-share \ | ||
--output none | ||
export SHARE=<your fileshare name> | ||
az storage share-rm create \ | ||
--resource-group $RESOURCE_GROUP \ | ||
--storage-account $ACCOUNT \ | ||
--name $SHARE \ | ||
--quota 1024 \ | ||
--enabled-protocols SMB \ | ||
--output none | ||
``` | ||
|
||
### 3. Create managed identity and role assignment | ||
``` | ||
export UAMI=<your managed identity name> | ||
az identity create --name $UAMI --resource-group $RESOURCE_GROUP | ||
export USER_ASSIGNED_CLIENT_ID="$(az identity show -g $RESOURCE_GROUP --name $UAMI --query 'clientId' -o tsv)" | ||
export IDENTITY_TENANT=$(az aks show --name $CLUSTER_NAME --resource-group $RESOURCE_GROUP --query identity.tenantId -o tsv) | ||
export ACCOUNT_SCOPE=$(az storage account show --name $ACCOUNT --query id -o tsv) | ||
az role assignment create --role "Storage Account Contributor" --assignee $USER_ASSIGNED_CLIENT_ID --scope $ACCOUNT_SCOPE | ||
``` | ||
|
||
### 4. Create service account | ||
``` | ||
export SERVICE_ACCOUNT_NAME=<your sa name> | ||
export SERVICE_ACCOUNT_NAMESPACE=<your sa namespace> | ||
cat <<EOF | kubectl apply -f - | ||
apiVersion: v1 | ||
kind: ServiceAccount | ||
metadata: | ||
name: ${SERVICE_ACCOUNT_NAME} | ||
namespace: ${SERVICE_ACCOUNT_NAMESPACE} | ||
EOF | ||
``` | ||
|
||
### 5. Create the federated identity credential between the managed identity, service account issuer, and subject using the az identity federated-credential create command. | ||
``` | ||
export FEDERATED_IDENTITY_NAME=<your federated identity name> | ||
export AKS_OIDC_ISSUER="$(az aks show --resource-group $RESOURCE_GROUP --name $CLUSTER_NAME --query "oidcIssuerProfile.issuerUrl" -o tsv)" | ||
az identity federated-credential create --name $FEDERATED_IDENTITY_NAME \ | ||
--identity-name $UAMI \ | ||
--resource-group $RESOURCE_GROUP \ | ||
--issuer $AKS_OIDC_ISSUER \ | ||
--subject system:serviceaccount:${SERVICE_ACCOUNT_NAMESPACE}:${SERVICE_ACCOUNT_NAME} | ||
``` | ||
|
||
## use case 1: Pod with ephemeral inline volume | ||
``` | ||
cat <<EOF | kubectl apply -f - | ||
kind: Pod | ||
apiVersion: v1 | ||
metadata: | ||
name: nginx-azurefile-inline-volume | ||
spec: | ||
serviceAccountName: $SERVICE_ACCOUNT_NAME #required, Pod does not use this service account has no permission to mount the volume | ||
nodeSelector: | ||
"kubernetes.io/os": linux | ||
containers: | ||
- image: mcr.microsoft.com/oss/nginx/nginx:1.19.5 | ||
name: nginx-azurefile | ||
command: | ||
- "/bin/bash" | ||
- "-c" | ||
- set -euo pipefail; while true; do echo $(date) >> /mnt/azurefile/outfile; sleep 1; done | ||
volumeMounts: | ||
- name: persistent-storage | ||
mountPath: "/mnt/azurefile" | ||
volumes: | ||
- name: persistent-storage | ||
csi: | ||
driver: file.csi.azure.com | ||
volumeAttributes: | ||
storageaccount: $ACCOUNT # required | ||
shareName: $SHARE # required | ||
clientID: $USER_ASSIGNED_CLIENT_ID # required | ||
resourcegroup: $RESOURCE_GROUP # required, please make sure your account is NOT created under AKS node resource group(prefix with `MC_`) | ||
# tenantID: $IDENTITY_TENANT #optional, only specified when workload identity and AKS cluster are in different tenant | ||
# subscriptionid: $SUBSCRIPTION #optional, only specified when workload identity and AKS cluster are in different subscription | ||
EOF | ||
``` | ||
|
||
## use case 2: static provision with PV | ||
``` | ||
cat <<EOF | kubectl apply -f - | ||
apiVersion: v1 | ||
kind: PersistentVolume | ||
metadata: | ||
annotations: | ||
pv.kubernetes.io/provisioned-by: file.csi.azure.com | ||
name: pv-azurefile | ||
spec: | ||
capacity: | ||
storage: 10Gi | ||
accessModes: | ||
- ReadWriteMany | ||
persistentVolumeReclaimPolicy: Retain | ||
storageClassName: azurefile-csi | ||
mountOptions: | ||
- dir_mode=0777 | ||
- file_mode=0777 | ||
- uid=0 | ||
- gid=0 | ||
- mfsymlinks | ||
- cache=strict | ||
- nosharesock | ||
csi: | ||
driver: file.csi.azure.com | ||
readOnly: false | ||
# make sure volumeid is unique for every identical share in the cluster | ||
# the # character is reserved for internal use | ||
volumeHandle: unique_volume_id | ||
volumeAttributes: | ||
storageaccount: $ACCOUNT # required | ||
shareName: $SHARE # required | ||
clientID: $USER_ASSIGNED_CLIENT_ID # required | ||
resourcegroup: $RESOURCE_GROUP # required, please make sure your account is NOT created under AKS node resource group(prefix with `MC_`) | ||
# tenantID: $IDENTITY_TENANT #optional, only specified when workload identity and AKS cluster are in different tenant | ||
# subscriptionid: $SUBSCRIPTION #optional, only specified when workload identity and AKS cluster are in different subscription | ||
--- | ||
apiVersion: apps/v1 | ||
kind: StatefulSet | ||
metadata: | ||
name: statefulset-azurefile | ||
labels: | ||
app: nginx | ||
spec: | ||
podManagementPolicy: Parallel | ||
serviceName: statefulset-azurefile | ||
replicas: 1 | ||
template: | ||
metadata: | ||
labels: | ||
app: nginx | ||
spec: | ||
serviceAccountName: $SERVICE_ACCOUNT_NAME #required, Pod does not use this service account has no permission to mount the volume | ||
nodeSelector: | ||
"kubernetes.io/os": linux | ||
containers: | ||
- name: statefulset-azurefile | ||
image: mcr.microsoft.com/oss/nginx/nginx:1.19.5 | ||
command: | ||
- "/bin/bash" | ||
- "-c" | ||
- set -euo pipefail; while true; do echo $(date) >> /mnt/azurefile/outfile; sleep 1; done | ||
volumeMounts: | ||
- name: persistent-storage | ||
mountPath: /mnt/azurefile | ||
updateStrategy: | ||
type: RollingUpdate | ||
selector: | ||
matchLabels: | ||
app: nginx | ||
volumeClaimTemplates: | ||
- metadata: | ||
name: persistent-storage | ||
spec: | ||
storageClassName: azurefile-csi | ||
accessModes: ["ReadWriteMany"] | ||
resources: | ||
requests: | ||
storage: 10Gi | ||
EOF | ||
``` |