How to deploy the AWS EBS CSI driver on K3s

This document (000020083) is provided subject to the disclaimer at the end of this document.

Situation

Task

This knowledge base article will provide the directions for deploying and testing the AWS EBS CSI driver and storage class on K3s.

Requirements

  • K3s 1.18+ (may apply to other versions)
  • Amazon Web Services (AWS) account with privileges to launch EC2 instances and create IAM policies.

Background

K3s has all in-tree storage providers removed since Kubernetes is shifting to out of tree providers for Container Storage Interface (CSI) and Cloud Provider Interface (CPI). While in-tree providers are convenient, they add a lot of bloat to Kubernetes and will eventually be removed from upstream Kubernetes, possibly in 2021.

This how-to guide will instruct you on installing and configuring the AWS EBS CSI driver and storage class. This will allow you to dynamically provision and attach an EBS volume to your pod without having to manually create a persistent volume (PV) and EBS volume in advance. In the event that your node crashes and your pod is re-launched on another node, your pod will be reattached to the volume assuming that node is running in the same availability zone used by the defunct node.

Solution

Assuming you want the CSI and storage class automatically deployed by K3s, copy the following YAML to a file in your manifests folder on one or all of your K3s servers. For example, /var/lib/rancher/k3s/server/manifests/aws-ebs-csi.yaml:

apiVersion: helm.cattle.io/v1
kind: HelmChart
metadata:
  name: aws-ebs-csi-driver
  namespace: kube-system
spec:
  chart: https://github.com/kubernetes-sigs/aws-ebs-csi-driver/releases/download/v0.5.0/helm-chart.tgz
  version: v0.5.0
  targetNamespace: kube-system
  valuesContent: |-
    enableVolumeScheduling: true
    enableVolumeResizing: true
    enableVolumeSnapshot: true
    extraVolumeTags:
      Name: k3s-ebs
      anothertag: anothervalue
---
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: ebs-storageclass
provisioner: ebs.csi.aws.com
volumeBindingMode: WaitForFirstConsumer
First, note at the time of this writing, v0.5.0 is the latest version of the driver. If there is a newer version available, you can replace this in the chart and version tags. See the AWS EBS CSI readme for documentation on the versions currently available. Second, you can customize the enableVolumeScheduling, enableVolumeResizing, enableVolumeSnaphost, and extraVolumeTags based on your needs. These parameters and others are documented in the Helm chart.

Next, you need to give the driver IAM permissions to manage EBS volumes. This can be done one of two ways. You can either feed your AWS access key and secret key as a Kubernetes secret, or use an AWS instance profile. Since the first option involves passing sensitive keys in clear text and storing them directly in Kubernetes, the second option is usually preferred. I will go over both options. For either option, make sure your access keys or instance profile has the following permissions set in IAM:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "ec2:AttachVolume",
        "ec2:CreateSnapshot",
        "ec2:CreateTags",
        "ec2:CreateVolume",
        "ec2:DeleteSnapshot",
        "ec2:DeleteTags",
        "ec2:DeleteVolume",
        "ec2:DescribeAvailabilityZones",
        "ec2:DescribeInstances",
        "ec2:DescribeSnapshots",
        "ec2:DescribeTags",
        "ec2:DescribeVolumes",
        "ec2:DescribeVolumesModifications",
        "ec2:DetachVolume",
        "ec2:ModifyVolume"
      ],
      "Resource": "*"
    }
  ]
}
Reference: https://github.com/kubernetes-sigs/aws-ebs-csi-driver/blob/master/docs/example-iam-policy.json
Option 1: Kubernetes Secret

You can place your AWS access key and secret key into a Kubernetes secret. Create a YAML file with the following contents and run a kubectl apply. You can also place this inside your /var/lib/rancher/k3s/server/manifests/aws-ebs-csi.yaml file. Keep in mind this is not a terribly secure option and anyone with access to these files or secrets in the kube-system namespace will be able to obtain your AWS access keys.

apiVersion: v1
kind: Secret
metadata:
  name: aws-secret
  namespace: kube-system
stringData:
  key_id: "AKI**********"
  access_key: "**********"
Option 2: Instance Profile

This option to more secure and should not expose your keys in clear text or in a Kubernetes secret object. You'll need to make sure when your EC2 instances are launched, you've attached an instance profile that has the permissions defined above in the JSON block.

Verifying and Testing

You can now check your pods to see if the CSI pods are running. You should see something like this:

# kubectl get pods -n kube-system | grep ebs
ebs-snapshot-controller-0                1/1     Running   0          15m
ebs-csi-node-k2gh5                       3/3     Running   0          15m
ebs-csi-node-xdcvn                       3/3     Running   0          15m
ebs-csi-controller-6f799b5548-46jqr      6/6     Running   0          15m
ebs-csi-controller-6f799b5548-h4nbb      6/6     Running   0          15m

Time to test things out. The following command can be run that should provision a 1GB EBS and attach it to your pod:

cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: myclaim
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: ebs-storageclass
  resources:
    requests:
      storage: 1Gi
---
apiVersion: v1
kind: Pod
metadata:
  name: storage-test
spec:
  containers:
  - name: "storage-test"
    image: "ubuntu:latest"
    command: ["/bin/sleep"]
    args: ["infinity"]
    volumeMounts:
      - name: myebs
        mountPath: /mnt/test
  volumes:
  - name: myebs
    persistentVolumeClaim:
      claimName: myclaim
EOF

In your AWS console, you should see a new EBS volume has been created. After about a minute, you should be able to exec into your pod and see the volume mounted in your pod:

# kubectl exec storage-test -- df -h
Filesystem      Size  Used Avail Use% Mounted on
overlay          31G  6.2G   25G  20% /
tmpfs            64M     0   64M   0% /dev
tmpfs           3.8G     0  3.8G   0% /sys/fs/cgroup
/dev/nvme2n1    976M  2.6M  958M   1% /mnt/test
/dev/root        31G  6.2G   25G  20% /etc/hosts
shm              64M     0   64M   0% /dev/shm
tmpfs           3.8G   12K  3.8G   1% /run/secrets/kubernetes.io/serviceaccount
tmpfs           3.8G     0  3.8G   0% /proc/acpi
tmpfs           3.8G     0  3.8G   0% /proc/scsi
tmpfs           3.8G     0  3.8G   0% /sys/firmware
Cleaning Up

Remove the test pod by running the following:

kubectl delete pod storage-test
Remove the PVC by running:
kubectl delete pvc myclaim
Check the AWS console and you should see your EBS volume has been removed automatically by the AWS EBS CSI driver.

Reference

Disclaimer

This Support Knowledgebase provides a valuable tool for SUSE customers and parties interested in our products and solutions to acquire information, ideas and learn from one another. Materials are provided for informational, personal or non-commercial use within your organization and are presented "AS IS" WITHOUT WARRANTY OF ANY KIND.

  • Document ID:000020083
  • Creation Date: 06-May-2021
  • Modified Date:06-May-2021
    • SUSE Rancher

< Back to Support Search

For questions or concerns with the SUSE Knowledgebase please contact: tidfeedback@suse.com

SUSE Support Forums

Get your questions answered by experienced Sys Ops or interact with other SUSE community experts.

Join Our Community

Support Resources

Learn how to get the most from the technical support you receive with your SUSE Subscription, Premium Support, Academic Program, or Partner Program.


SUSE Customer Support Quick Reference Guide SUSE Technical Support Handbook Update Advisories
Support FAQ

Open an Incident

Open an incident with SUSE Technical Support, manage your subscriptions, download patches, or manage user access.

Go to Customer Center