Giter VIP home page Giter VIP logo

kubernetes-keyvault-flexvol's Introduction

Key Vault FlexVolume [DEPRECATED]

WARNING ⚠️ This solution has been deprecated. Continue to use this for kubernetes version 1.15. For 1.16+, please use Azure Key Vault Provider for Secret Store CSI Driver

This solution is no longer supported as 1.15 is out of support in AKS

Seamlessly integrate your key management systems with Kubernetes.

Secrets, keys, and certificates in a key management system become a volume accessible to pods. Once the volume is mounted, its data is available directly in the container filesystem for your application.

CircleCI

Contents

Getting started

Supported Providers

  • Azure Key Vault

    💡 NOTE: To enable encryption at rest of Kubernetes data in etcd, use the Kubernetes KMS plugin for Azure Key Vault.

Installing Key Vault FlexVolume

OPTION 1: New AKS Engine cluster

AKS Engine creates customized Kubernetes clusters on Azure.

Follow the AKS Engine add-on documentation to create a new Kubernetes cluster with Key Vault FlexVolume already deployed.

OPTION 2: Existing AKS cluster

Azure Kubernetes Service (AKS) creates managed, supported Kubernetes clusters on Azure.

Deploy Key Vault FlexVolume to your AKS cluster with this command:

kubectl create -f https://raw.githubusercontent.com/Azure/kubernetes-keyvault-flexvol/master/deployment/kv-flexvol-installer.yaml

To validate Key Vault FlexVolume is running as expected, run the following command:

kubectl get pods -n kv

The output should show keyvault-flexvolume pods running on each agent node:

NAME                        READY     STATUS    RESTARTS   AGE
keyvault-flexvolume-f7bx8   1/1       Running   0          3m
keyvault-flexvolume-rcxbl   1/1       Running   0          3m
keyvault-flexvolume-z6jm6   1/1       Running   0          3m

If using keyvault-flexvolume in a cluster with pod security policy enabled, create the following policy that enables the spec required for keyvault-flexvolume to work -

kubectl apply -f https://raw.githubusercontent.com/Azure/kubernetes-keyvault-flexvol/master/deployment/kv-flexvol-psp.yaml

Using Key Vault FlexVolume

Key Vault FlexVolume offers four modes for accessing a Key Vault instance: Service Principal, Pod Identity, [VMSS User Assigned Managed Identity], [VMSS System Assigned Managed Identity].

OPTION 1: Service Principal

Add your service principal credentials as Kubernetes secrets accessible by the Key Vault FlexVolume driver.

kubectl create secret generic kvcreds --from-literal clientid=<CLIENTID> --from-literal clientsecret=<CLIENTSECRET> --type=azure/kv

Ensure this service principal has all the required permissions to access content in your Key Vault instance. If not, run the following Azure CLI commands:

# [Required for version < v0.0.13] Assign Reader Role to the service principal for your keyvault
az role assignment create --role Reader --assignee <principalid> --scope /subscriptions/<subscriptionid>/resourcegroups/<resourcegroup>/providers/Microsoft.KeyVault/vaults/<keyvaultname>

# Assign key vault permissions to your service principal
az keyvault set-policy -n $KV_NAME --key-permissions get --spn <YOUR SPN CLIENT ID>
az keyvault set-policy -n $KV_NAME --secret-permissions get --spn <YOUR SPN CLIENT ID>
az keyvault set-policy -n $KV_NAME --certificate-permissions get --spn <YOUR SPN CLIENT ID>

Fill in the missing pieces in this deployment for your own deployment. Make sure to:

  1. Reference the service principal Kubernetes secret created in the previous step

    secretRef:
      name: kvcreds
  2. Pass in properties for the Key Vault instance to the FlexVolume driver.

    Name Required Description Default Value
    usepodidentity no specify access mode: use a service principal or pod identity or vm managed identity "false"
    usevmmanagedidentity not required, available for version >= v0.0.15 specify access mode: use a service principal or pod identity or vm managed identity "false"
    vmmanagedidentityclientid not required, available for version >= v0.0.15 If using a user assigned identity as the VM's managed identity, then specify the identity's client id. If empty, then defaults to use the system assigned identity on the VM ""
    keyvaultname yes name of Key Vault instance ""
    keyvaultobjectnames yes names of Key Vault objects to access ""
    keyvaultobjectaliases no filenames to use when writing the objects keyvaultobjectnames
    keyvaultobjecttypes yes types of Key Vault objects: secret, key or cert ""
    keyvaultobjectversions no versions of Key Vault objects, if not provided, will use latest ""
    resourcegroup required for version < v0.0.14 name of resource group containing Key Vault instance ""
    subscriptionid required for version < v0.0.14 name of subscription containing Key Vault instance ""
    tenantid yes name of tenant containing Key Vault instance ""
    cloudname no Name of the cloud environment, e.g. something like AzureChinaCloud, AzureGermanCloud. If not provided, the default public Azure cloud will be used ""
    nmiport not required, available for version >= v0.0.17 Port number of the NMI daemonset. If not provided, the default NMI port is used "2579"

    Multiple values in the keyvaultobjectnames, keyvaultobjecttypes and keyvaultobjectversions properties should be separated with semicolons (;).

  3. Specify mount path of flexvolume to mount key vault objects

    volumeMounts:
       - name: test
          mountPath: /kvmnt
          readOnly: true

    Example of an nginx pod accessing a secret from a Key Vault instance:

    apiVersion: v1
    kind: Pod
    metadata:
      name: nginx-flex-kv
    spec:
      containers:
      - name: nginx-flex-kv
        image: nginx
        volumeMounts:
        - name: test
          mountPath: /kvmnt
          readOnly: true
      volumes:
      - name: test
        flexVolume:
          driver: "azure/kv"
          secretRef:
            name: kvcreds                             # [OPTIONAL] not required if using Pod Identity
          options:
            usepodidentity: "false"                   # [OPTIONAL] if not provided, will default to "false"
            usevmmanagedidentity: "false"             # [OPTIONAL new in version >= v0.0.15] if not provided, will default to "false"
            vmmanagedidentityclientid: "clientid"     # [OPTIONAL new in version >= v0.0.15] use the client id to specify which user assigned managed identity to use, leave empty to use system assigned managed identity
            keyvaultname: "testkeyvault"              # [REQUIRED] the name of the KeyVault
            keyvaultobjectnames: "testsecret"         # [REQUIRED] list of KeyVault object names (semi-colon separated)
            keyvaultobjectaliases: "secret.json"      # [OPTIONAL] list of KeyVault object aliases
            keyvaultobjecttypes: secret               # [REQUIRED] list of KeyVault object types: secret, key, cert (semi-colon separated)
            keyvaultobjectversions: "testversion"     # [OPTIONAL] list of KeyVault object versions (semi-colon separated), will get latest if empty
            resourcegroup: "testresourcegroup"        # [REQUIRED for version < v0.0.14] the resource group of the KeyVault
            subscriptionid: "testsub"                 # [REQUIRED for version < v0.0.14] the subscription ID of the KeyVault
            tenantid: "testtenant"                    # [REQUIRED] the tenant ID of the KeyVault
            nmiport: "nmiportnumber"                  # [OPTIONAL new in version >= v0.0.17] port number of the NMI daemonset, will default to "2579"

    Deploy your app

    kubectl create -f deployment/nginx-flex-kv.yaml

    Validate the pod has access to the secret from key vault:

    kubectl exec -it nginx-flex-kv cat /kvmnt/testsecret
    testvalue

OPTION 2: Pod identity

💡 The basic steps to configure AAD Pod Identity are reproduced here, but please refer to that project's README for more detail.

  1. Install AAD Pod Identity

    Run this command to create the aad-pod-identity deployment on an RBAC-enabled cluster:

    kubectl apply -f https://raw.githubusercontent.com/Azure/aad-pod-identity/master/deploy/infra/deployment-rbac.yaml
    
  2. Create an Azure Identity

    Run this Azure CLI command, and take note of the clientId and id values it returns:

    az identity create -g <resourcegroup> -n <name> -o json
  3. Assign Cluster SPN Role

    If the Service Principal used for the cluster was created separately (not automatically, as part of an AKS cluster's MC_ resource group), assign it the "Managed Identity Operator" role:

    az role assignment create --role "Managed Identity Operator" --assignee <sp id> --scope <full id of the managed identity>
  4. Assign Azure Identity Roles

    Ensure that your Azure Identity has the role assignments required to see your Key Vault instance and to access its content. Run the following Azure CLI commands to assign these roles if needed:

    # Assign Reader Role to new Identity for your Key Vault
    az role assignment create --role Reader --assignee <principalid> --scope /subscriptions/<subscriptionid>/resourcegroups/<resourcegroup>/providers/Microsoft.KeyVault/vaults/<keyvaultname>
    
    # set policy to access keys in your Key Vault
    az keyvault set-policy -n $KV_NAME --key-permissions get --spn <YOUR AZURE USER IDENTITY CLIENT ID>
    # set policy to access secrets in your Key Vault
    az keyvault set-policy -n $KV_NAME --secret-permissions get --spn <YOUR AZURE USER IDENTITY CLIENT ID>
    # set policy to access certs in your Key Vault
    az keyvault set-policy -n $KV_NAME --certificate-permissions get --spn <YOUR AZURE USER IDENTITY CLIENT ID>
  5. Install the Azure Identity

    Save this Kubernetes manifest to a file named aadpodidentity.yaml:

    apiVersion: "aadpodidentity.k8s.io/v1"
    kind: AzureIdentity
    metadata:
      name: <a-idname>
    spec:
      type: 0
      resourceID: /subscriptions/<subid>/resourcegroups/<resourcegroup>/providers/Microsoft.ManagedIdentity/userAssignedIdentities/<name>
      clientID: <clientId>

    Replace the placeholders with your user identity values. Set type: 0 for user-assigned MSI.

    Finally, save your changes to the file, then create the AzureIdentity resource in your cluster:

    kubectl apply -f aadpodidentity.yaml
  6. Install the Azure Identity Binding

    Save this Kubernetes manifest to a file named aadpodidentitybinding.yaml:

    apiVersion: "aadpodidentity.k8s.io/v1"
    kind: AzureIdentityBinding
    metadata:
      name: demo1-azure-identity-binding
    spec:
      azureIdentity: <a-idname>
      selector: <label value to match>

    Replace the placeholders with your values. Ensure that the AzureIdentity name matches the one in aadpodidentity.yaml.

    Finally, save your changes to the file, then create the AzureIdentityBinding resource in your cluster:

    kubectl apply -f aadpodidentitybinding.yaml
  7. Update the Application Deployment

    Your application manifest needs a couple of changes. Refer to the nginx-flex-kv-podid deployment as an example.

    a. Include the aadpodidbinding label to match the selector value from the previous step:

    metadata:
    labels:
        aadpodidbinding: "NAME OF the AzureIdentityBinding SELECTOR"

    b. Set usepodidentity to true:

    usepodidentity: "true"
  8. Deploy your app

    kubectl create -f deployment/nginx-flex-kv-podidentity.yaml
  9. Validate the pod can access the secret from Key Vault:

    kubectl exec -it nginx-flex-kv-podid cat /kvmnt/testsecret
    testvalue

NOTE: When using the Pod Identity option mode, there may be some delay in obtaining the objects from Key Vault. During pod creation time, AAD Pod Identity needs to create the AzureAssignedIdentity for the pod based on the AzureIdentity and AzureIdentityBinding and retrieve the token for Key Vault. It is possible for the pod volume mount to fail during this time. If it does, the kubelet will keep retrying until after the token retrieval is complete and the mount succeeds.

OPTION 3: VMSS User Assigned Managed Identity [New in version >= v0.0.15]

This option allows flexvol to use the user assigned managed identity on the k8s cluster VMSS directly.

Warning: As of today (2019/09), AKS does not preserve the user assigned identity on VMSS during upgrade. You will need to re-assign the managed identities to VMSS after an upgrade. The improved experience is planned.

  1. Create Azure Managed Identity
az identity create -g <RESOURCE GROUP> -n <IDENTITY NAME>
  1. Grant Azure Managed Identity KeyVault permissions

    Ensure that your Azure Identity has the role assignments required to see your Key Vault instance and to access its content. Run the following Azure CLI commands to assign these roles if needed:

    # set policy to access keys in your Key Vault
    az keyvault set-policy -n $KV_NAME --key-permissions get --spn <YOUR AZURE MANAGED IDENTITY CLIENT ID>
    # set policy to access secrets in your Key Vault
    az keyvault set-policy -n $KV_NAME --secret-permissions get --spn <YOUR AZURE MANAGED IDENTITY CLIENT ID>
    # set policy to access certs in your Key Vault
    az keyvault set-policy -n $KV_NAME --certificate-permissions get --spn <YOUR AZURE MANAGED IDENTITY CLIENT ID>
  2. Assign Azure Managed Identity to VMSS

az vmss identity assign -g <RESOURCE GROUP> -n <K8S-AGENT-POOL-VMSS> --identities <USER ASSIGNED IDENTITY RESOURCE ID>
  1. Deploy your application. Specify usevmmanagedidentity to true and provide vmmanagedidentityclientid.
usevmmanagedidentity: "true"               # [OPTIONAL] if not provided, will default to "false"
vmmanagedidentityclientid: "clientid"      # [OPTIONAL] use the client id to specify which user assigned managed identity to use, leave empty to use system assigned managed identity

OPTION 4: VMSS System Assigned Managed Identity [New in version >= v0.0.15]

This option allows flexvol to use the system assigned managed identity on the k8s cluster VMSS directly.

  1. Verify that the nodes have its own system assigned managed identity
az vmss identity show -g <resource group>  -n <vmss scalset name> -o yaml

The output should contain type: SystemAssigned.

  1. Grant Azure Managed Identity KeyVault permissions

    Ensure that the Azure system assigned Identity has the role assignments required to see your Key Vault instance and to access its content. Run the following Azure CLI commands to assign these roles if needed:

    # set policy to access keys in your Key Vault
    az keyvault set-policy -n $KV_NAME --key-permissions get --object-id <YOUR AZURE MANAGED IDENTITY OBJECT ID>
    # set policy to access secrets in your Key Vault
    az keyvault set-policy -n $KV_NAME --secret-permissions get --object-id <YOUR AZURE MANAGED IDENTITY OBJECT ID>
    # set policy to access certs in your Key Vault
    az keyvault set-policy -n $KV_NAME --certificate-permissions get --object-id <YOUR AZURE MANAGED IDENTITY OBJECT ID>
  2. Deploy your application. Specify usevmmanagedidentity to true.

usevmmanagedidentity: "true"               # [OPTIONAL] if not provided, will default to "false"

Detailed use cases

Design

To learn more about the design of Key Vault FlexVolume, see Concept.

About Key Vault

Key Vault FlexVolume interacts with Key Vault objects by using the Key Vault API.

Azure Key Vault has thorough documentation available to help clarify the difference between keys, secrets, and certificates.

About Certificates

It is important to understand how a certificate is structured in Key Vault.

As mentioned in Certificates are complex objects and Composition of a Certificate, Azure Key Vault (AKV) represents an X.509 certificate as three related resources:

  • an AKV-certificate
  • an AKV-key
  • an AKV-secret

All three will share the same name and the same version and can be fetched independently.

  • The AKV-certificate provides the public key and certificate metadata. Specifying cert in keyvaultobjecttypes will fetch the public key and certificate metadata.
  • The AKV-key provides the private key of the X.509 certificate. It can be useful for performing cryptographic operations such as signing if the corresponding certificate was marked as non-exportable. Specifying key in keyvaultobjecttypes will fetch the private key of the certificate if its policy allows for private key exporting.
  • The AKV-secret provides a way to export the full X.509 certificate, including its private key (if its policy allows for private key exporting). Specifying secret in keyvaultobjecttypes will fetch the base64-encoded certificate bundle.

Contributing

The Key Vault FlexVolume project welcomes contributions and suggestions. Please see CONTRIBUTING for details.

Code of conduct

This project has adopted the Microsoft Open Source Code of Conduct. For more information, see the Code of Conduct FAQ or contact [email protected] with any additional questions or comments.

kubernetes-keyvault-flexvol's People

Contributors

antoinega avatar aramase avatar billpratt avatar bnookala avatar chambras avatar hmm01i avatar horvatic avatar idanlevin avatar jeffloyd avatar jon-walton avatar jwendl avatar khenidak avatar larryclaman avatar lee0c avatar mboersma avatar microsoftopensource avatar mikkeljoergensen avatar msftgits avatar noelbundick avatar ohthehugemanatee avatar phillipsj avatar pjbgf avatar ritazh avatar serbrech avatar slack avatar spbreed avatar tariq1890 avatar timja avatar twem avatar yangl900 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

kubernetes-keyvault-flexvol's Issues

does azure key vault flex vol mount reflect latest version of secret in Key vault without redeploying pod?

I have a question I ran into while testing this . If I generate a new secret in Key vault, does the volume mount inside a pod reflect the latest value . If it does, how long is the wait time ?

Inside the pod spec for the volume, I am not using the version number so I always refer to the latest version. During my testing, new version of the secret in Key vault is not shown unless I delete and recreate the pod.

POD spec as below

apiVersion: v1
kind: Pod
metadata:
name: demopod
spec:
containers:
 — name: demopod
image: nginx
volumeMounts:
 — name: secretvolume
mountPath: /opt
readOnly: true
volumes:
 — name: secretvolume
flexVolume:
driver: “azure/kv”
secretRef:
name: kvcreds
options:
usepodidentity: “false”
resourcegroup: “xxxxx”
keyvaultname: “yyyyy”
keyvaultobjectname: “configfile”
keyvaultobjecttype: secret
subscriptionid: “xxxxx-yyyy-zzzzz”
tenantid: “aaaaa-bbbbbb-cccccccc”

"/var/lib/kubelet/volumeplugins/azure~kv/kv: line 27: sudo: command not found

Deployed the daemonset as documented and then tried to deploy the example nginx container from your example. The pod failed to create and I see this in the kubelet log:

I0808 23:20:18.050187    2077 reconciler.go:252] operationExecutor.MountVolume started for volume "test" (UniqueName: "flexvolume-azure/kv/d02f5840-9b42-11e8-9d86-000d3a3bcf16-test") pod "nginx-flex-kv-9f6c8c694-8b8v7" (UID: "d02f5840-9b42-11e8-9d86-000d3a3bcf16")
I0808 23:20:18.056681    2077 util.go:52] found flex volume secret info: clientid
I0808 23:20:18.056693    2077 util.go:52] found flex volume secret info: clientsecret
E0808 23:20:19.500751    2077 driver-call.go:251] Failed to unmarshal output for command: mount, output: "/var/lib/kubelet/volumeplugins/azure~kv/kv: line 27: sudo: command not found\n{\"status\": \"Success\"}\n", error: invalid character '/' looking for beginning of value
E0808 23:20:19.501033    2077 nestedpendingoperations.go:267] Operation for "\"flexvolume-azure/kv/d02f5840-9b42-11e8-9d86-000d3a3bcf16-test\" (\"d02f5840-9b42-11e8-9d86-000d3a3bcf16\")" failed. No retries permitted until 2018-08-08 23:22:21.5008958 +0000 UTC m=+70100.303765901 (durationBeforeRetry 2m2s). Error: "MountVolume.SetUp failed for volume \"test\" (UniqueName: \"flexvolume-azure/kv/d02f5840-9b42-11e8-9d86-000d3a3bcf16-test\") pod \"nginx-flex-kv-9f6c8c694-8b8v7\" (UID: \"d02f5840-9b42-11e8-9d86-000d3a3bcf16\") : invalid character '/' looking for beginning of value"

I checked and sudo is not available on that nginx image.
I made a change to the ismounted() function in kv to bypass the sudo line and it worked.

Perhaps it would be sufficient to check for the presence of ${MNTPATH}.

I'll work on an alternative approach and submit a PR for you to review.

Use kubernetes-keyvault-flexvol in a deployment

I could get this working on a pod. But how can I use it in a deployment, where I will have multiple pods spread across nodes. Each pod has to access the volume that contains the key.

Is there any alternate solution for such a scenario?

Thanks

Remove "list" permissions

Hi,

Does the FlexVol really needs a "list" permissions on KV?

Since KV doesn't have per-key-permissions, it's considered a best to only have a "get" permission without a "list" one, to avoid key traversing.

Assuming the user always provide a key name in the volume mount, I assume the "list" part is unnecessary.

Idan

Support env variables

It looks like this doesn't use actual Kubernetes secrets object correct? And the only way for an application to access a secret inside a container is to read from the filesystem (that is, the volume mount)?

Just looking for clarity - thanks.

Bug when using k8s namespaces other than default

I recognized a bug when using namespaces for deployments with keyvault-flexvol

I've a dedicated namespace development

After deploying theAzureIdentity, AzureIdentityBinding and a Pod to the development namespace. KeyVault driver isn't able to mount the key vault flex volume.

As a workaround the isse can be fixed by deploying both AzureIdentity and AzureIdentityBinding to the default namespace.

Once that's done, the Pod from namespace development can grab data from Keyvault.

I think this is a critical bug which prevents me - and I can imagine others may agree on that one - from using keyvault-flexvol for real deployments

vaultObjectVersion is not set

Here is the yaml file:

apiVersion: v1
kind: Pod
metadata:
  name: keyvault-demo
spec:
  containers:
  - name: keyvault-demo
    image: nginx
    volumeMounts:
    - name: secret-1
      mountPath: /secret1
      readOnly: true
  volumes:
  - name: secret-1
    flexVolume:
      driver: "azure/kv"
      secretRef:
        name: kvcreds 
      options:
        usepodidentity: "false"
        resourcegroup: "rrdprem-rg"
        keyvaultname: "rrdprem-kv"
        keyvaultobjectname: "appsecret1"
        keyvaultobjecttype: secret
        keyvaultobjectversion: "29b378fc9e89487c961d3b178667beb7"
        subscriptionid: "6abf90e5-4af2-4c86-83aa-5352df938db5"
        tenantid: "f7215caf-efd9-4bac-89c5-a3cf109a9f18"

And it failed with the following error:
Type Reason Age From Message


Normal Scheduled 4s default-scheduler Successfully assigned keyvault-demo to aks-nodepool1-33901137-2
Normal SuccessfulMountVolume 3s kubelet, aks-nodepool1-33901137-2 MountVolume.SetUp succeeded for volume "default-token-d52qb"
Warning FailedMount 2s (x3 over 3s) kubelet, aks-nodepool1-33901137-2 MountVolume.SetUp failed for volume "secret-1" : mount command failed, status: Failure, reason: /etc/kubernetes/volumeplugins/azure~kv/azurekeyvault-flexvolume failed, -vaultObjectVersion is not set

Brand new install - getting error "invalid character"

Hello, I'm trying this out for the first time. I've followed the instructions, I have a new cluster just setup today, and I've put together these steps for the whole process on a brand new cluster.

    # Install these
    
    kubectl create -f https://raw.githubusercontent.com/Azure/kubernetes-keyvault-flexvol/master/deployment/kv-flexvol-installer.yaml
    kubectl create -f https://raw.githubusercontent.com/Azure/aad-pod-identity/master/deploy/infra/deployment-rbac.yaml
    
    # Add the existing identity with access to the keyvaults
    apiVersion: "aadpodidentity.k8s.io/v1"
    kind: AzureIdentity
    metadata:
     name: 0afbc123-3-eus2-uai
    spec:
     type: 0
     ResourceID: /subscriptions/11111111-1111-1111-1111-111111111111/resourcegroups/ManagedServiceIdentity-Stage-Eus2-Rg/providers/Microsoft.ManagedIdentity/userAssignedIdentities/0afbc123-3-eus2-uai
     ClientID: 22222222-2222-2222-2222-222222222222
    
    # adding 0afbc123 as a binding
    apiVersion: "aadpodidentity.k8s.io/v1"
    kind: AzureIdentityBinding
    metadata:
     name: 0afbc123-3-eus2-uai-binding
    spec:
     AzureIdentity: 0afbc123-3-eus2-uai
     Selector: 0afbc123-3-eus2-uai-selector
    
    # add a deployment that uses this stuff
    apiVersion: v1
    kind: Pod
    metadata:
      labels:
        app: nginx-flex-kv-podid
        aadpodidbinding: "0afbc123-3-eus2-uai-selector"
      name: nginx-flex-kv-podid
    spec:
      containers:
      - name: nginx-flex-kv-podid
        image: nginx
        volumeMounts:
        - name: test
          mountPath: /kvmnt
          readOnly: true
      volumes:
      - name: test
        flexVolume:
          driver: "azure/kv"
          options:
            usepodidentity: "true"
            keyvaultname: "thetestkeyvault"
            keyvaultobjectnames: "TEST"
            keyvaultobjecttypes: secret
            resourcegroup: "TestKeyVault-Rg"
            subscriptionid: "11111111-1111-1111-1111-111111111111"
            tenantid: "33333333-3333-3333-3333-333333333333"

After I run this, the nginx pod won't start up, doing a describe shows this error:

    MountVolume.SetUp failed for volume "test" : invalid character 'I' looking for beginning of value

My identity 0afbc123-3-eus2-uai does have Reader on the thetestkeyvault, as well as the secrets/certs/keys - get/list permissions

Here's my describe on the pod:

    root@facfdb90317b:/data# kubectl describe pods/nginx-flex-kv-podid
    Name:         nginx-flex-kv-podid
    Namespace:    default
    Node:         aks-default-15419034-0/10.197.54.6
    Start Time:   Fri, 15 Feb 2019 02:35:09 +0000
    Labels:       aadpodidbinding=0afbc123-3-eus2-uai-selector
                  app=nginx-flex-kv-podid
    Annotations:  <none>
    Status:       Pending
    IP:           
    Containers:
      nginx-flex-kv-podid:
        Container ID:   
        Image:          nginx
        Image ID:       
        Port:           <none>
        Host Port:      <none>
        State:          Waiting
          Reason:       ContainerCreating
        Ready:          False
        Restart Count:  0
        Environment:
          KUBERNETES_PORT_443_TCP_ADDR:  mycontainer.hcp.eastus2.azmk8s.io
          KUBERNETES_PORT:               tcp://mycontainer.hcp.eastus2.azmk8s.io:443
          KUBERNETES_PORT_443_TCP:       tcp://mycontainer.hcp.eastus2.azmk8s.io:443
          KUBERNETES_SERVICE_HOST:       mycontainer.hcp.eastus2.azmk8s.io
        Mounts:
          /kvmnt from test (ro)
          /var/run/secrets/kubernetes.io/serviceaccount from default-token-sxp96 (ro)
    Conditions:
      Type           Status
      Initialized    True 
      Ready          False 
      PodScheduled   True 
    Volumes:
      test:
        Type:       FlexVolume (a generic volume resource that is provisioned/attached using an exec based plugin)
        Driver:     azure/kv
        FSType:     
        SecretRef:  nil
        ReadOnly:   false
        Options:    map[keyvaultobjecttypes:secret resourcegroup:TestKeyVault-Rg subscriptionid:11111111-1111-1111-1111-111111111111 tenantid:22222222-2222-2222-2222-222222222222 usepodidentity:true keyvaultname:thetestkeyvault keyvaultobjectnames:TEST]
      default-token-sxp96:
        Type:        Secret (a volume populated by a Secret)
        SecretName:  default-token-sxp96
        Optional:    false
    QoS Class:       BestEffort
    Node-Selectors:  <none>
    Tolerations:     node.kubernetes.io/not-ready:NoExecute for 300s
                     node.kubernetes.io/unreachable:NoExecute for 300s
    Events:
      Type     Reason                 Age                From                             Message
      ----     ------                 ----               ----                             -------
      Normal   Scheduled              53s                default-scheduler                Successfully assigned nginx-flex-kv-podid to aks-default-15419034-0
      Normal   SuccessfulMountVolume  52s                kubelet, aks-default-15419034-0  MountVolume.SetUp succeeded for volume "default-token-sxp96"
      Warning  FailedMount            20s (x7 over 52s)  kubelet, aks-default-15419034-0  MountVolume.SetUp failed for volume "test" : invalid character 'I' looking for beginning of value

Thanks!

Allow for different certificate format (public/private key)

When pulling an object of type cert from keyvault, we do not have a choice in the format of the resulting file. Additionally, the current implementation only gets the public portion of the certificate.

Being able to pull both the public and secret part of the certificate in a mycert.crt and mycert.key would be useful to setup SSL endpoint for ingress controllers for example.

kv flex-volume mounting after multiple failures

Hi,

I am having an issue that I am not able to explain/isolate. When the pod starts it fails to mount and then after few minute it successfully mount the kv-flexvolume, this is not consistent sometimes it never mounts.

Events:
  Type     Reason       Age                   From                             Message
  ----     ------       ----                  ----                             -------
  Normal   Scheduled    12m                   default-scheduler                Successfully assigned externaldns/external-dns-64c4488cd9-7bzkl to aks-default-38594516-0
  Warning  FailedMount  8m45s (x10 over 12m)  kubelet, aks-default-38594516-0  MountVolume.SetUp failed for volume "azurekv" : mount command failed, status: Failure, reason: /etc/kubernetes/volumeplugins/azure~kv/azurekeyvault-flexvolume failed, failed to get key vault
  Warning  FailedMount  8m38s (x2 over 10m)   kubelet, aks-default-38594516-0  Unable to mount volumes for pod "external-dns-64c4488cd9-7bzkl_externaldns(e6f19211-2a35-11e9-8203-32eed183208c)": timeout expired waiting for volumes to attach or mount for pod "externaldns"/"external-dns-64c4488cd9-7bzkl". list of unmounted volumes=[azurekv]. list of unattached volumes=[azurekv external-dns-token-6bbqw]
  Normal   Pulling      6m33s                 kubelet, aks-default-38594516-0  pulling image "registry.opensource.zalan.do/teapot/external-dns:v0.5.9"
  Normal   Pulled       6m32s                 kubelet, aks-default-38594516-0  Successfully pulled image "registry.opensource.zalan.do/teapot/external-dns:v0.5.9"
  Normal   Created      6m29s                 kubelet, aks-default-38594516-0  Created container
  Normal   Started      6m29s                 kubelet, aks-default-38594516-0  Started container

Here is the logs from the aks-default-38594516-0

`XXXX-XXXX-XXXX-XXXX-XXXX
I0206 18:12:01.865336    5671 main.go:98] starting the azurekeyvault-flexvolume, 0.0.6
I0206 18:12:01.865388    5671 main.go:275] subscriptionID: XXXX-XXXX-XXXX-XXXX-XXXX
I0206 18:12:01.865392    5671 main.go:276] vaultName: dev-aurora-vault
I0206 18:12:01.865395    5671 main.go:277] resourceGroup: aurora
I0206 18:12:01.865419    5671 oauth.go:135] azure: using pod identity to retrieve token

[error] failed to get key vault, error: failed to get vault, error: keyvault.VaultsClient#Get: Failure responding to request: StatusCode=401 -- Original Error: autorest/azure: Service returned an error. Status=401 Code="AuthenticationFailed" Message="Authentication failed. The 'Authorization' header is missing."

 failed to get key vault
Wed Feb 6 18:12:01 UTC 2019 ERROR: {"status": "Failure", "message": "/etc/kubernetes/volumeplugins/azure~kv/azurekeyvault-flexvolume failed, failed to get key vault "}
Wed Feb  6 18:12:18 UTC 2019 ismounted | /var/lib/kubelet/pods/a95407df-2a3a-11e9-8203-32eed183208c/volumes/azure~kv/azurekv does not exist
Wed Feb  6 18:12:18 UTC 2019 PODNAME: external-dns-64c4488cd9-jllvm
Wed Feb  6 18:12:18 UTC 2019 EXEC: /etc/kubernetes/volumeplugins/azure~kv/azurekeyvault-flexvolume -logtostderr=1 -vaultName=dev-aurora-vault -vaultObjectNames=azure-config -resourceGroup=aurora -dir=/var/lib/kubelet/pods/a95407df-2a3a-11e9-8203-32eed183208c/volumes/azure~kv/azurekv -subscriptionId=XXXX-XXXX-XXXX-XXXX-XXXX -cloudName= -tenantId=XXXXXX-XXXX-XXXX-XXXX-XXXXXXX -aADClientSecret= -aADClientID= -usePodIdentity=true -podNamespace=ambassador -podName=external-dns-64c4488cd9-jllvm -vaultObjectVersions= -vaultObjectTypes=secret
dev-aurora-vault
azurekeyvault-flexvolume 0.0.6
XXXX-XXXX-XXXX-XXXX-XXXX
I0206 18:12:18.017379    6140 main.go:98] starting the azurekeyvault-flexvolume, 0.0.6
I0206 18:12:18.017441    6140 main.go:275] subscriptionID: XXXX-XXXX-XXXX-XXXX-XXXX
I0206 18:12:18.017446    6140 main.go:276] vaultName: dev-aurora-vault
I0206 18:12:18.017450    6140 main.go:277] resourceGroup: aurora
I0206 18:12:18.017486    6140 oauth.go:135] azure: using pod identity to retrieve token

[error] failed to get key vault, error: failed to get vault, error: keyvault.VaultsClient#Get: Failure responding to request: StatusCode=401 -- Original Error: autorest/azure: Service returned an error. Status=401 Code="AuthenticationFailed" Message="Authentication failed. The 'Authorization' header is missing."

 failed to get key vault
Wed Feb 6 18:12:18 UTC 2019 ERROR: {"status": "Failure", "message": "/etc/kubernetes/volumeplugins/azure~kv/azurekeyvault-flexvolume failed, failed to get key vault "}
Wed Feb  6 18:12:50 UTC 2019 ismounted | /var/lib/kubelet/pods/a95407df-2a3a-11e9-8203-32eed183208c/volumes/azure~kv/azurekv does not exist
Wed Feb  6 18:12:50 UTC 2019 PODNAME: external-dns-64c4488cd9-jllvm
Wed Feb  6 18:12:50 UTC 2019 EXEC: /etc/kubernetes/volumeplugins/azure~kv/azurekeyvault-flexvolume -logtostderr=1 -vaultName=dev-aurora-vault -vaultObjectNames=azure-config -resourceGroup=aurora -dir=/var/lib/kubelet/pods/a95407df-2a3a-11e9-8203-32eed183208c/volumes/azure~kv/azurekv -subscriptionId=XXXX-XXXX-XXXX-XXXX-XXXX -cloudName= -tenantId=XXXXXX-XXXX-XXXX-XXXX-XXXXXXX -aADClientSecret= -aADClientID= -usePodIdentity=true -podNamespace=ambassador -podName=external-dns-64c4488cd9-jllvm -vaultObjectVersions= -vaultObjectTypes=secret
dev-aurora-vault
azurekeyvault-flexvolume 0.0.6
XXXX-XXXX-XXXX-XXXX-XXXX
I0206 18:12:50.208958    6881 main.go:98] starting the azurekeyvault-flexvolume, 0.0.6
I0206 18:12:50.209012    6881 main.go:275] subscriptionID: XXXX-XXXX-XXXX-XXXX-XXXX
I0206 18:12:50.209016    6881 main.go:276] vaultName: dev-aurora-vault
I0206 18:12:50.209019    6881 main.go:277] resourceGroup: aurora
I0206 18:12:50.209043    6881 oauth.go:135] azure: using pod identity to retrieve token

[error] failed to get key vault, error: failed to get vault, error: keyvault.VaultsClient#Get: Failure responding to request: StatusCode=401 -- Original Error: autorest/azure: Service returned an error. Status=401 Code="AuthenticationFailed" Message="Authentication failed. The 'Authorization' header is missing."

 failed to get key vault
Wed Feb 6 18:12:50 UTC 2019 ERROR: {"status": "Failure", "message": "/etc/kubernetes/volumeplugins/azure~kv/azurekeyvault-flexvolume failed, failed to get key vault "}
Wed Feb  6 18:13:54 UTC 2019 ismounted | /var/lib/kubelet/pods/a95407df-2a3a-11e9-8203-32eed183208c/volumes/azure~kv/azurekv does not exist
Wed Feb  6 18:13:54 UTC 2019 PODNAME: external-dns-64c4488cd9-jllvm
Wed Feb  6 18:13:54 UTC 2019 EXEC: /etc/kubernetes/volumeplugins/azure~kv/azurekeyvault-flexvolume -logtostderr=1 -vaultName=dev-aurora-vault -vaultObjectNames=azure-config -resourceGroup=aurora -dir=/var/lib/kubelet/pods/a95407df-2a3a-11e9-8203-32eed183208c/volumes/azure~kv/azurekv -subscriptionId=XXXX-XXXX-XXXX-XXXX-XXXX -cloudName= -tenantId=XXXXXX-XXXX-XXXX-XXXX-XXXXXXX -aADClientSecret= -aADClientID= -usePodIdentity=true -podNamespace=ambassador -podName=external-dns-64c4488cd9-jllvm -vaultObjectVersions= -vaultObjectTypes=secret
dev-aurora-vault
azurekeyvault-flexvolume 0.0.6
XXXX-XXXX-XXXX-XXXX-XXXX
I0206 18:13:54.398159    8254 main.go:98] starting the azurekeyvault-flexvolume, 0.0.6
I0206 18:13:54.398225    8254 main.go:275] subscriptionID: XXXX-XXXX-XXXX-XXXX-XXXX
I0206 18:13:54.398229    8254 main.go:276] vaultName: dev-aurora-vault
I0206 18:13:54.398233    8254 main.go:277] resourceGroup: aurora
I0206 18:13:54.398261    8254 oauth.go:135] azure: using pod identity to retrieve token

[error] failed to get key vault, error: failed to get vault, error: keyvault.VaultsClient#Get: Failure responding to request: StatusCode=401 -- Original Error: autorest/azure: Service returned an error. Status=401 Code="AuthenticationFailed" Message="Authentication failed. The 'Authorization' header is missing."

 failed to get key vault
Wed Feb 6 18:13:54 UTC 2019 ERROR: {"status": "Failure", "message": "/etc/kubernetes/volumeplugins/azure~kv/azurekeyvault-flexvolume failed, failed to get key vault "}
Wed Feb  6 18:15:56 UTC 2019 ismounted | /var/lib/kubelet/pods/a95407df-2a3a-11e9-8203-32eed183208c/volumes/azure~kv/azurekv does not exist
Wed Feb  6 18:15:56 UTC 2019 PODNAME: external-dns-64c4488cd9-jllvm
Wed Feb  6 18:15:56 UTC 2019 EXEC: /etc/kubernetes/volumeplugins/azure~kv/azurekeyvault-flexvolume -logtostderr=1 -vaultName=dev-aurora-vault -vaultObjectNames=azure-config -resourceGroup=aurora -dir=/var/lib/kubelet/pods/a95407df-2a3a-11e9-8203-32eed183208c/volumes/azure~kv/azurekv -subscriptionId=XXXX-XXXX-XXXX-XXXX-XXXX -cloudName= -tenantId=XXXXXX-XXXX-XXXX-XXXX-XXXXXXX -aADClientSecret= -aADClientID= -usePodIdentity=true -podNamespace=ambassador -podName=external-dns-64c4488cd9-jllvm -vaultObjectVersions= -vaultObjectTypes=secret
dev-aurora-vault
azurekeyvault-flexvolume 0.0.6
XXXX-XXXX-XXXX-XXXX-XXXX
I0206 18:15:56.656382   11666 main.go:98] starting the azurekeyvault-flexvolume, 0.0.6
I0206 18:15:56.656482   11666 main.go:275] subscriptionID: XXXX-XXXX-XXXX-XXXX-XXXX
I0206 18:15:56.656486   11666 main.go:276] vaultName: dev-aurora-vault
I0206 18:15:56.656489   11666 main.go:277] resourceGroup: aurora
I0206 18:15:56.656515   11666 oauth.go:135] azure: using pod identity to retrieve token

 accesstoken: eyJ0##### REDACTED #####i3IQ

 clientid: 59f7##### REDACTED #####73e5
I0206 18:15:57.232027   11666 oauth.go:135] azure: using pod identity to retrieve token

 accesstoken: eyJ0##### REDACTED #####QreQ

 clientid: 59f7##### REDACTED #####73e5
I0206 18:15:57.339939   11666 main.go:132] retrieving secret azure-config (version: )
I0206 18:15:57.512055   11666 main.go:176] azure KeyVault wrote secret azure-config at /var/lib/kubelet/pods/a95407df-2a3a-11e9-8203-32eed183208c/volumes/azure~kv/azurekv
Wed Feb  6 18:15:57 UTC 2019 EXEC: ls /var/lib/kubelet/pods/a95407df-2a3a-11e9-8203-32eed183208c/volumes/azure~kv/azurekv
azure-config
Wed Feb 6 18:15:57 UTC 2019 INFO: {"status": "Success"}

Add useragent

(edited on behalf of @ritazh )

Add http userAgent header to all requests with value keyvault-volume-driver whenever possible.

Multiple secrets in one flexvolume

Hi

Would it be possible to have multiple secrets in one flexvolume?
I'm trying to integrate this with jenkins configuration as code plugin:
https://github.com/jenkinsci/configuration-as-code-plugin/tree/master/demos/kubernetes-secrets

Which expects each secret to be under the same directory
i.e

/kvmnt/secret-1
/kvmnt/secret-2

To get more than one secret working with this tool it seems like you need different mount point per secret,
i.e.

/secret-1-mount/secret-1
/secret-2-mount/secret-2

Is it possible to do what I'm trying to achieve?

Thanks

Can we mount the whole keyvault instead of specific secrets

Hi, we have a use case where we want to access the long list of secrets, I was wondering if it's possible to mount the whole keyvault or do you support regex in secret name so I can mount a list of secrets in one call instead of providing the individual secret name in the template

Get updated value after keyvault is mounted

Right now, the value of the key is only set at the time when the keyvault is mounted which is the time when the pod starts. To get subsequent updates, pod needs to be restarted. Can we add a sidecar to watch the value and update the value in the mounted volume?

Docs

  • Get started
  • How to debug, logs
  • Operating modes (integrated, not-integrated)
  • Warnings

[docs]: Improve docs regarding AzureIdentity and AzureIdentityBinding

tl;dr: Don't put AzureIdentity and AzureIdentityBinding in a single yaml file

The AzureIdentityBinding depends on AzureIdentity obviously. Unfortunately will the drive not do any consistency check here.

While trying to adopt the KeyVault integration using a PodIdentity, I added both AzureIdentity and AzureIdentityBinding to a single yaml file.

The only error I received was that the pod didn't start because the KeyVault volume couldn't be mounted. After some investigation, I recognized that calls to Azure KeyVault were sent without Authorization header.

The KeyVault driver didn't report any real insights... But after a couple of seconds, k8s tried to spin up the Pod again and everything worked as expected.
I think the behavior is correct, but documentation should point users in the right direction and explicitly mention that AzureIdentity and AzureIdentityBinding should not belong to a single yaml file.

Volume mount failing but secret being retrieved

Currently implementing a test of Azure KV FlexVolumes with AAD PodId in an AKS cluster but experiencing some strange behaviour.

AAD PodId K8's components deployed using helm https://github.com/Azure/aad-pod-identity/tree/master/charts/aad-pod-identity & https://raw.githubusercontent.com/Azure/kubernetes-keyvault-flexvol/master/deployment/kv-flexvol-installer.yaml . Azure components (User Managed ID & access controls) deployed with Terraform. All of the Azure components seem to be fine.

A test pod with a volume mount and a test secret have been deployed using:

apiVersion: v1
kind: Pod
metadata:
  labels:
    app: nginx-flex-kv-podid
    aadpodidbinding: aadpodid
  name: nginx-flex-kv-podid
spec:
  containers:
  - name: nginx-flex-kv-podid
    image: nginx
    volumeMounts:
    - name: test
      mountPath: /kv
      readOnly: true
  volumes:
  - name: test
    flexVolume:
      driver: "azure/kv"
      options:
        usepodidentity: "true"
        keyvaultname: "sandbox-kv"
        keyvaultobjectnames: "password"
        keyvaultobjecttypes: "secret"
        keyvaultobjectversions: "bda5b53cd0184fa59cbe683bf6e9e2e9"
        resourcegroup: "sandbox"
        subscriptionid: "XXXXXX-XXXX-XXXX-XXXX-XXXXXXXX"
        tenantid: "XXXXXX-XXXX-XXXX-XXXX-XXXXXXXX"

Things get interesting now.

mic log records the following:

I0206 16:40:00.119882 1 event.go:218] Event(v1.ObjectReference{Kind:"AzureIdentityBinding", Namespace:"default", Name:"azure-identity-binding", UID:"9327f0b1-2a2c-11e9-a16b-e619d6e0ff11", APIVersion:"aadpodidentity.k8s.io/v1", ResourceVersion:"12473313", FieldPath:""}): type: 'Normal' reason: 'binding applied' Binding azure-identity-binding applied on node aks-agentpool-11854310-0 for pod nginx-flex-kv-podid-default-azure-identity

nmi pod logging a 400, Identity not found:

time="2019-02-06T16:37:45Z" level=error msg="failed to get service principal token for pod:default/nginx-flex-kv-podid, adal: Refresh request failed. Status Code = '400'. Response body: {"error":"invalid_request","error_description":"Identity not found"}" req.method=GET req.path=/host/token/ req.remote=127.0.0.1

Expecting to see logs to the effect of 10 & 12 detailed here regarding PodId https://github.com/Azure/aad-pod-identity/tree/master/charts/aad-pod-identity . Save this one for a bit later because it would appear from these logs that any lookup using PodId will fail. It doesn't.

The log related to the failed volume mount is:

Warning FailedMount 59s (x4 over 1m) kubelet, aks-agentpool-11854310-3 MountVolume.SetUp failed for volume "test" : mount command failed, status: Failure, reason: /etc/kubernetes/volumeplugins/azure~kv/azurekeyvault-flexvolume failed, failed to get key vault

Yet kubectl exec -it nginx-flex-kv-podid cat /kv/password successfully returns the correct value of the secret referenced. This suggests the AAD PodId is working fine and that all the permissions set to allow the AKS Service Principle to use the User Managed ID to authenticate to and read from KeyVault are also ok.

Interesting conundrum. Grateful for any input that may help explain this behaviour.

The docu lacks some details which may result in errors

The docu should be extended, as it lakes some important Details which may result in erros like the following :

  Warning  FailedMount            8s (x5 over 17s)  kubelet, aks-agentpool-37252822-0  MountVolume.SetUp failed for volume "test" : mount command failed, status: Failure, reason: /etc/kubernetes/volumeplugins/azure~kv/azurekeyvault-flexvolume failed, failed to get key vault

Or

Warning  FailedMount  6s (x5 over 16s)  kubelet, aks-agentpool-16481727-0  MountVolume.SetUp failed for volume "test" : mount command failed, status: Failure, reason: /etc/kubernetes/volumeplugins/azure~kv/azurekeyvault-flexvolume failed, failed to get secret passwd

 
1: Verify the SP values are correct

Connec to one of your agent-nodes and cat the file “cat /etc/kubernetes/azure.json”
Look for the properties "aadClientId" and "aadClientSecret", they contain the values for the clientid and the clientsecret.
With those details you are able to create the secret “kvcreds” correct:    kubectl create secret generic kvcreds --from-literal clientid= --from-literal clientsecret= --type=azure/kv
 
 
2: Set the POD properties correct
 
In the sample this POD manifest is used
-->
apiVersion: v1
kind: Pod
metadata:
  name: nginx-flex-kv
spec:
  containers:
  - name: nginx-flex-kv
    image: nginx
    volumeMounts:
    - name: test
      mountPath: /kvmnt
      readOnly: true
  volumes:
  - name: test
    flexVolume:
      driver: "azure/kv"
      secretRef:
        name: kvcreds # mounting point to the pod
      options:
        usepodidentity: "false"
        keyvaultname: "testkeyvault"
        keyvaultobjectname: "testsecret"
        keyvaultobjecttype: secret # OPTIONS: secret, key, cert
        keyvaultobjectversion: "testversion"
        resourcegroup: "testresourcegroup"
        subscriptionid: "testsub"
        tenantid: "testtenant"
<--
 
Please get sure you use the correct value for keyvaultobjectversion. In the sample a string is used, but this one has actually to be a hex value like “9aff2d69ae274d69bbd23b2465bc700c”
In order to list the version for a secret you can run a command like “az keyvault secret list-versions -n passwd --vault-name malachma2”
It will print out a line with the property id and value https://malachma.vault.azure.net/secrets/passwd/9aff2d69ae274d69bbd23b2465bc700c
The last path detail is the version of the secret.
 
In order to get the subscription-id and the tenant-id this command has to be used: az accound show
You will receive an output like the following one
{
  "environmentName": "AzureCloud",
  "id": "c98141ca-e173-46dd-9395-59a0c4xxxxxx",
  "isDefault": true,
  "name": "Microsoft Azure Internal Consumption",
  "state": "Enabled",
  "tenantId": "72f988bf-86f1-41af-91ab-2d7cd0xxxxxx",
  "user": {
    "name": "[email protected]",
    "type": "user"
  }
}
 
3: Extend the ServicePrincipal with additional access Rights (Even if the keyvault is part of the same resource-group as the cluster is)

   a: az role assignment create --role Reader --assignee --scope /subscriptions//resourcegroups//providers/Microsoft.KeyVault/vaults/
   b: az keyvault set-policy -n $KV_NAME --secret-permissions get list --spn

Consider using a CRD for holding Key Vault configuration

This really is a UX improvement as it wouldn't enable new scenarios per se.

The configuration we need to put under "flexVolume" is quite verbose. Most of it gets repeated in each pod using the same key vault:

  • driver
  • secretRef
  • usepodidentity
  • keyvaultname
  • resourcegroup
  • subscriptionid
  • tenantid

From the DRY principle, it would be nice to have that configuration in a separate object (CRD) and have pod simply referring to that CRD.

unable to mount volume-- (Duplicate issue but other resolutions are not working)

I am facing a similar issue related to volume mount.
my pod definition --

apiVersion: v1
kind: Pod 
metadata:
  name: sample-pod
  labels:
     aadpodidbinding: "dev_app"
spec:
 restartPolicy: Never
 containers:
 - name: nginx 
   image: nginx:latest
   volumeMounts:
    - name: kv-dev
      mountPath: /kvmount
      readOnly: true
 volumes:
 - name: kv-dev
   flexVolume:
      driver: "azure/kv"
      options:
        usepodidentity: "true"                 
        keyvaultname: "kv-name"        
        keyvaultobjectnames: "key1"                                
        keyvaultobjecttypes: "secret"                                
        keyvaultobjectversions: "version" 
        resourcegroup: "mydevrg"                      
        subscriptionid: "subscription id"     
        tenantid: "tenand id"

Logs from /var/log/kv-driver.log



Wed Apr 10 06:51:10 UTC 2019 ismounted | not mounted
Wed Apr 10 06:51:10 UTC 2019 PODNAME: sample-pod
Wed Apr 10 06:51:10 UTC 2019 mount
Wed Apr 10 06:51:10 UTC 2019 /etc/kubernetes/volumeplugins/azure~kv/azurekeyvault-flexvolume -logtostderr=1 -vaultName=env-dev-secrets -vaultObjectNames=key1 -vaultObjectAliases= -resourceGroup=env-development-keys -dir=/var/lib/kubelet/pods/04759d6f-5b5b-11e9-a910-ea94745bd5eb/volumes/azure~kv/kv-dev -subscriptionId=2aefe---de-a2f7-700b4dd06ad1 -cloudName= -tenantId=fbfbfbnf---03-a8a1e287fa9d -aADClientSecret= -aADClientID= -usePodIdentity=true -podNamespace=default -podName=sample-pod -vaultObjectVersions=96efefefefw20411d8b2712cc8 -vaultObjectTypes=secret
I0410 06:51:10.800266   19396 keyvaultFlexvolumeAdapter.go:32] azurekeyvault-flexvolume 0.0.10
I0410 06:51:10.800365   19396 keyvaultFlexvolumeAdapter.go:41] starting the azurekeyvault-flexvolume, 0.0.10
I0410 06:51:10.800426   19396 oauth.go:135] azure: using pod identity to retrieve token
I0410 06:51:10.810047   19396 oauth.go:135] azure: using pod identity to retrieve token
F0410 06:51:10.812298   19396 main.go:82] [error] : failed to get keyvaultClient: failed to get key vault token: failed to get service principal token: nmi response failed with status code: 403
Wed Apr 10 06:51:10 UTC 2019 umount
Wed Apr 10 06:51:10 UTC 2019 ERROR: {"status": "Failure", "message": "/etc/kubernetes/volumeplugins/azure~kv/azurekeyvault-flexvolume failed, F0410 06:51:10.812298 19396 main.go:82] [error] : failed to get keyvaultClient: failed to get key vault token: failed to get service principal token: nmi response failed with status code: 403 "}
Wed Apr 10 06:53:12 UTC 2019 ismounted | not mounted
Wed Apr 10 06:53:12 UTC 2019 PODNAME: sample-pod
Wed Apr 10 06:53:12 UTC 2019 mount
Wed Apr 10 06:53:12 UTC 2019 /etc/kubernetes/volumeplugins/azure~kv/azurekeyvault-flexvolume -logtostderr=1 -vaultName=env-dev-secrets -vaultObjectNames=key1 -vaultObjectAliases= -resourceGroup=env-development-keys -dir=/var/lib/kubelet/pods/04759d6f-5b5b-11e9-a910-ea94745bd5eb/volumes/azure~kv/kv-dev -subscriptionId=25a1ewrewewr8de-a2f7-700b4dd06ad1 -cloudName= -tenantId=c98d2fc9-defewrer43ca-a603-a8a1e287fa9d -aADClientSecret= -aADClientID= -usePodIdentity=true -podNamespace=default -podName=sample-pod -vaultObjectVersions=96e4c4rewrererer11d8b2712cc8 -vaultObjectTypes=secret
I0410 06:53:12.970569   22037 keyvaultFlexvolumeAdapter.go:32] azurekeyvault-flexvolume 0.0.10
I0410 06:53:12.970663   22037 keyvaultFlexvolumeAdapter.go:41] starting the azurekeyvault-flexvolume, 0.0.10
I0410 06:53:12.970703   22037 oauth.go:135] azure: using pod identity to retrieve token
I0410 06:53:12.981358   22037 oauth.go:135] azure: using pod identity to retrieve token
F0410 06:53:12.984216   22037 main.go:82] [error] : failed to get keyvaultClient: failed to get key vault token: failed to get service principal token: nmi response failed with status code: 403
Wed Apr 10 06:53:12 UTC 2019 umount
Wed Apr 10 06:53:13 UTC 2019 ERROR: {"status": "Failure", "message": "/etc/kubernetes/volumeplugins/azure~kv/azurekeyvault-flexvolume failed, F0410 06:53:12.984216 22037 main.go:82] [error] : failed to get keyvaultClient: failed to get key vault token: failed to get service principal token: nmi response failed with status code: 403 "}

As per the suggestions in other issues, I waited for more that one hour but the volume is not mounting.

Azuredentity definition--

apiVersion: "aadpodidentity.k8s.io/v1"
kind: AzureIdentity
metadata:
  name: dev-pod-identity
spec:
  type: 0
  ResourceID: /subscriptions/25a1anc-----d06ad1/resourcegroups/env-dev/providers/Microsoft.ManagedIdentity/userAssignedIdentities/dev_pod_identity
  ClientID: cd8b-------abcd ----e8231e1

Azure binding definition--

apiVersion: "aadpodidentity.k8s.io/v1"
kind: AzureIdentityBinding
metadata:
 name: dev-pod-identity-binding
spec:
 AzureIdentity: dev-pod-identity
 Selector: dev_app

Looking for urgent help.

Support .NET configuration conventions for structured data

The .NET convention for structured keys is using underscores where json or other structured format is not available, like environment variable names and, in this case, file names.

For some reason, Azure Key Vault doesn't allow underscores in key names, so dashes are used instead. And the logical thing is to use the KeyPerFileConfigurationProvider and call config.AddKeyPerFile("/kv") to load all values. But this provides doesn't handle double dashes.

It would be stupid to write yet another configuration provider to handle this, and when the convention is established, the FlexVolume provider should replace double dashes with double underscores. Or provide a variable to specify the delimiter.

Flex-volume with pod-identity fails to mount multiple times with 403 error then succeeds

When deploying/restarting a pod with keyvault flex-volume, volume mounting fails multiple times with 403, but it eventually succeeds after a few retries. Is that an expected behavior? Is there way to mitigate it and avoid this error?

Error details:

MountVolume.SetUp failed for volume "keyvault-secrets" : mount command failed, status: Failure, reason: /etc/kubernetes/volumeplugins/azure~kv/azurekeyvault-flexvolume failed, F0213 07:28:59.049161 19766 main.go:80] [error] : failed to get keyvaultClient: failed to get key vault token: nmi response failed with status code: 403

NMI logs:

time="2019-02-13T07:28:35Z" level=info msg="Rules for table(nat) chain(aad-metadata) rules(-N aad-metadata, -A aad-metadata ! -s 127.0.0.1/32 -d 169.254.169.254/32 -p tcp -m tcp --dport 80 -j DNAT --to-destination 10.0.240.166:2579, -A aad-metadata -j RETURN)"
time="2019-02-13T07:28:59Z" level=error msg="no AzureAssignedIdentity found for pod:ecm-prod/ecm-datl-sec-manual-01-rzlkd, <nil>" req.method=GET req.path=/host/token/ req.remote=127.0.0.1
time="2019-02-13T07:28:59Z" level=info msg="Status (403) took 52610486 ns" req.method=GET req.path=/host/token/ req.remote=127.0.0.1
time="2019-02-13T07:28:59Z" level=error msg="no AzureAssignedIdentity found for pod:ecm-prod/ecm-datl-sec-manual-01-rzlkd, <nil>" req.method=GET req.path=/host/token/ req.remote=127.0.0.1
time="2019-02-13T07:28:59Z" level=info msg="Status (403) took 7896683 ns" req.method=GET req.path=/host/token/ req.remote=127.0.0.1
time="2019-02-13T07:28:59Z" level=error msg="no AzureAssignedIdentity found for pod:ecm-prod/ecm-datl-sec-manual-01-rzlkd, <nil>" req.method=GET req.path=/host/token/ req.remote=127.0.0.1
time="2019-02-13T07:28:59Z" level=info msg="Status (403) took 7797379 ns" req.method=GET req.path=/host/token/ req.remote=127.0.0.1
time="2019-02-13T07:28:59Z" level=error msg="no AzureAssignedIdentity found for pod:ecm-prod/ecm-datl-sec-manual-01-rzlkd, <nil>" req.method=GET req.path=/host/token/ req.remote=127.0.0.1
time="2019-02-13T07:28:59Z" level=info msg="Status (403) took 7302061 ns" req.method=GET req.path=/host/token/ req.remote=127.0.0.1
time="2019-02-13T07:29:00Z" level=info msg="matched identityType:0 clientid:545386ea-2886-4714-8960-ce274cc8563b resource:https://management.azure.com/" req.method=GET req.path=/host/token/ req.remote=127.0.0.1
time="2019-02-13T07:29:00Z" level=info msg="Status (200) took 16266383 ns" req.method=GET req.path=/host/token/ req.remote=127.0.0.1
time="2019-02-13T07:29:01Z" level=info msg="matched identityType:0 clientid:545386ea-2886-4714-8960-ce274cc8563b resource:https://vault.azure.net" req.method=GET req.path=/host/token/ req.remote=127.0.0.1

Support for Security context FSGroup

We have successfully mounted our keyvault and exposed some secrets from multiple vaults. This seems to work well and are happy with this.
There is a problem using this driver in our products because we are trying to read these using a module in a node/java app that is not running at root user.

Currently all the mounts are as using root group and user consequently we can not read the secrets in the flexvolume.

Please can we support the security context features:

spec:
  securityContext:
    runAsUser: xxx
    fsGroup: xxx

Can you use a wildcard for keyvaultobjectnames?

The pattern that our services follow is that every service has its own Azure Key Vault instance, so the service should have access to all the secrets in the Key Vault. This allows for new secrets to be added to the Key Vault and get picked up by the service only a redeploy (and not needing to modify any config files).

Is there some way to use a wildcard for keyvaultobjectnames?

Thanks,
Erick

KeyVault Object Version latest

Within the concept document is stats that the version can be omitted and it will return the latest version. this doesn't appear to have been implemented. If i exclude the version the container doesn't start correctly.

Concept

KeyVault Object Version: optional (empty == latest version)

README.md

Name Required Description Default Value
keyvaultobjectversion yes key vault object version ""

Leaking access tokens in log files

Currently the generated access tokens used to access KeyVault are being logged in plain-text.

This allows a "reader" of the log files to privilege escalate, spoofing the Managed Identity in question and also gain access to sensitive information. Other identities could also be spoofed, depending on the credentials stored in the keyVault instance.

Please consider the PR #41 I have just submitted in order to redact most of that information from the logs.

working with OSBA

Does keyvault flextool work with AKS OSBA? how do i create my secrets in key-vault and refer it in OSBA service manifests using keyvault flex tool? Any guidance?

Unable to mount volumes for pod "nginx-flex-kv-podid_default"

Events:
  Type     Reason                 Age                From                               Message
  ----     ------                 ----               ----                               -------
  Normal   Scheduled              10m                default-scheduler                  Successfully assigned nginx-flex-kv-podid to aks-agentpool-23065106-0
  Normal   SuccessfulMountVolume  10m                kubelet, aks-agentpool-23065106-0  MountVolume.SetUp succeeded for volume "default-token-cqd6w"
  Warning  FailedMount            2m (x10 over 10m)  kubelet, aks-agentpool-23065106-0  MountVolume.SetUp failed for volume "test" : invalid character 's' looking for beginning of value
  Warning  FailedMount            1m (x4 over 8m)    kubelet, aks-agentpool-23065106-0  Unable to mount volumes for pod "nginx-flex-kv-podid_default(be10160c-93bb-11e8-b1ce-aa6af2addf8c)": timeout expired waiting for volumes to attach or mount for pod "default"/"nginx-flex-kv-podid". list of unmounted volumes=[test]. list of unattached volumes=[test default-token-cqd6w]
uday@DESKTOP-RGMO1N7:/mnt/c/git/kubernetes-keyvault-flexvol/deployment$ kubectl get azureassignedidentities
NAME                                         CREATED AT
nginx-flex-kv-podid-default-pod-identity     6m
apiVersion: v1
kind: Pod
metadata:
  labels:
    app: nginx-flex-kv-podid
    aadpodidbinding: "demo"
  name: nginx-flex-kv-podid
spec:
  containers:
  - name: nginx-flex-kv-podid
    image: nginx
    volumeMounts:
    - name: test
      mountPath: /kvmnt
      readOnly: true
  volumes:
  - name: test
    flexVolume:
      driver: "azure/kv"
      options:
        usePodIdentity: "true"
        keyvaultname: "aks-vdc-kv"
        keyvaultobjectname: "tenantID"
        keyvaultobjecttype: "secret"
        keyvaultobjectversion: "33b73696bb9d4b839e0c1a5412089e31"
        resourcegroup: "aks-kv"

Failed to Mount: 'Invalid character 'I' looking for beginning of value'

We are getting the following error when trying to use the Azure KeyVault Flexvol:

kubectl output using at test job:

  Normal   Scheduled               15s   default-scheduler           Successfully assigned newspace/test-azflexjob-njmcs to test-worker5
  Warning  FailedMount             12s   kubelet, test-worker5  MountVolume.SetUp failed for volume "az-secret" : invalid character 'I' looking for beginning of value
  Normal   Pulling                 11s   kubelet, test-worker5  pulling image "busybox"
  Normal   Pulled                  9s    kubelet, test-worker5  Successfully pulled image "busybox"
  Normal   Created                 9s    kubelet, test-worker5  Created container
  Normal   Started                 8s    kubelet, test-worker5  Started container

Logging output:

E0222 20:31:04.965438    3260 driver-call.go:251] Failed to unmarshal output for command: mount, output: "I0222 20:31:02.904722   14032 keyvaultFlexvolumeAdapter.go:32] azurekeyvault-flexvolume 0.0.8
I0222 20:31:02.904814   14032 keyvaultFlexvolumeAdapter.go:41] starting the azurekeyvault-flexvolume, 0.0.8
I0222 20:31:04.501628   14032 keyvaultFlexvolumeAdapter.go:65] retrieving secret testsecret (version: 7b448f7d55234a76b0068ffwf8hf322)
I0222 20:31:04.962156   14032 keyvaultFlexvolumeAdapter.go:124] azure KeyVault wrote secret testsecret at /opt/rke/var/lib/kubelet/pods/c57e768e-36e0-11e9-b4d6-000d3a36e51b/volumes/azure~kv/az-secret
{\"status\": \"Success\"}
", error: invalid character 'I' looking for beginning of value

The volume is successfully mounted after a 500ms retry attempt.

It appears that the output from the stderr includes more than the status and that data can't be consumed. I have tested removing the -logtostderr=1 from line 158 in the kv file and that fixes the issue.

Env:
Kubernetes: v1.11.6
OS: CoreOS-1967.6.0
RKE: v0.1.16

invalid character '/' looking for beginning of value

When I try and deploy a pod with a secret mounted I am getting this error:

invalid character '/' looking for beginning of value

It seems to be related to the "driver" section of the flex volume, but I can;t see anything obvious I am doing wrong.

Type     Reason                 Age               From                               Message
  ----     ------                 ----              ----                               -------
  Normal   Scheduled              14s               default-scheduler                  Successfully assigned keyvault-flex-demo to aks-nodepool1-30108646-0
  Normal   SuccessfulMountVolume  14s               kubelet, aks-nodepool1-30108646-0  MountVolume.SetUp succeeded for volume "default-token-v8hjk"
  Warning  FailedMount            6s (x5 over 14s)  kubelet, aks-nodepool1-30108646-0  MountVolume.SetUp failed for volume "secret1" : invalid character '/' looking for beginning of value

Pod Yaml File:

apiVersion: v1
kind: Pod
metadata:
  name: keyvault-flex-demo
spec:
  containers:
  - name: keyvault-flex-demo
    image: nginx
    volumeMounts:
    - name: secret1
      mountPath: /kvmnt
      readOnly: true
  volumes:
  - name: secret1
    flexVolume:
      driver: "azure/kv"
      secretRef:
        name: kvcreds # mounting point to the pod
      options:
        usepodidentity: "false"
        keyvaultname: "kvFlexVolume"
        keyvaultobjectname: "appsecret1"
        keyvaultobjecttype: secret # OPTIONS: secret, key, cert
        keyvaultobjectversion: "b5b8ecffa0344756be898a7170148e7d"
        resourcegroup: "keyvaultFlexVolume"
        subscriptionid: "xxx"
        tenantid: "xxx"

MountVolume.SetUp failed for volume "test" : invalid character 'F' after object key:value pair

I’m deploying FlexVol on AKS according to the procedure:
https://github.com/Azure/kubernetes-keyvault-flexvol

I’m trying option 1 as mentioned “OPTION 1 - Service Principal” and using the sample POD configuration file provided in the same doc.

however the POD doesn’t seem to recognize the flexVolume configuration section and I get the following error:
“MountVolume.SetUp failed for volume "test" : invalid character 'F' after object key:value pair”

My AKS version is 1.12 and I have installed the plugin as mentioned in the doc. I can see the installation POD running on my agents and nothing special in its logs:

NAME READY STATUS RESTARTS AGE
keyvault-flexvolume-n44sl 1/1 Running 0 10m

can anyone please advise?
Thanks,

Can KV Flex Volume be used to access multiple Key Vaults

scenario like this:
Multiple teams (business units) using a shared AKS cluster.
Each team want their own key vault and be able to access them using their own Service Principal using KV Flex volume mount.
Can I create something like below to be able to do this.
The idea being without stepping on each other's Key Vault

  1. kvcredsteam1 will be used by Team1 to access Key Vault1
  2. kvcredsteam2 will be used by Team2 to access Key Vault2
    kubectl create secret generic kvcredsteam1
    kubectl create secret generic kvcredsteam2

Is there anything in KV Flex Vol implementation which might prevent the above configuration ?
If such a configuration is permitted, is there a limit in number of KVs within reasonable limit of course

Error often comes up when reading secret

I've configured the Keyvault flex using MSI.
Deployment:

 ``` options:
    usepodidentity: "true"         # [OPTIONAL] if not provided, will default to "false"
    keyvaultname: "my-secrets-dev"               # the name of the KeyVault
    keyvaultobjectnames: "Secret1;Secret2"        # list of KeyVault object names (semi-colon separated)
    keyvaultobjecttypes: "secret;secret"    # list of KeyVault object types: secret, key or cert (semi-colon separated)
    keyvaultobjectversions: ""     # [OPTIONAL] list of KeyVault object versions (semi-colon separated), will get latest if empty
    resourcegroup: "my-dev-keyvault"              # the resource group of the KeyVault
    subscriptionid: "000000000000000"             # the subscription ID of the KeyVault
    tenantid: "000000000"                   # the tenant ID of the KeyVault

I've configured 2 secrets.
Reading one of the secrets I get an exception now and then together with the value.
Once I had the 'use of closed connection' message.

It happens especially when executing the commands fast after each other. But not always.

The commands below are executed right after each other.

  • kubectl exec -it nginx-flex-kv-podid cat /kvmnt/Secret1
    TopSecret
  • kubectl exec -it nginx-flex-kv-podid cat /kvmnt/Secret1
    TopSecretE0104 15:22:49.282352 422 v3.go:79] EOF
  • kubectl exec -it nginx-flex-kv-podid cat /kvmnt/Secret1
    TopSecret
  • kubectl exec -it nginx-flex-kv-podid cat /kvmnt/Secret1
    TopSecretE0104 15:22:56.725635 446 v3.go:79] EOF
  • kubectl exec -it nginx-flex-kv-podid cat /kvmnt/Secret1
    TopSecret
  • kubectl exec -it nginx-flex-kv-podid cat /kvmnt/Secret1
    TopSecretE0104 15:32:40.761018 531 v3.go:79] EOF
  • kubectl exec -it nginx-flex-kv-podid cat /kvmnt/Secret1
    TopSecretE0104 15:20:44.649605 331 v3.go:79] tls: use of closed connection
  • kubectl exec -it nginx-flex-kv-podid cat /kvmnt/Secret1
    TopSecret
  • kubectl exec -it nginx-flex-kv-podid cat /kvmnt/Secret1
    TopSecret
  • kubectl exec -it nginx-flex-kv-podid cat /kvmnt/Secret1
    TopSecretE0104 15:32:52.378853 567 v3.go:79] EOF

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.