Deploy an Ubuntu Pro EKS cluster - using Pro tokens¶
This guide shows how to deploy an EKS cluster with Ubuntu Pro nodes using Ubuntu Pro tokens and EC2 launch templates.
Prerequisites¶
You need:
eksctl
: Check the instructions to install eksctlpacker
: only needed if you want to enable FIPS for the cluster nodes. Install it withsudo snap install packer
your AWS access key ID and secret access key
an Ubuntu Pro token
Prepare the cluster for deployment¶
Although Ubuntu Pro for EKS is available as an AMI for Ubuntu 22.04 LTS (see Deploy an Ubuntu Pro EKS cluster - using a Pro AMI), there is no such EKS related offer available for Ubuntu 20.04 LTS. So to use Pro in 20.04 LTS, you need to provision the EKS cluster with customised Ubuntu nodes.
The steps needed for deploying the cluster depend on whether you need to enable FIPS or not.
When FIPS is not enabled, you can use one of the existing Ubuntu EKS AMIs and customise it using cloud-init’s ubuntu-advantage module during deployment.
For this deployment, you’ll also need to have an existing launch template on AWS.
Update user-data in launch template
On the advanced section of your launch template (user-data section), copy the following code (replacing the “token” field with your Pro token):
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="==MYBOUNDARY=="
--==MYBOUNDARY==
Content-Type: text/cloud-config; charset="us-ascii"
ubuntu_advantage:
token: <pro_token>
enable:
- esm
--==MYBOUNDARY==
Content-Type: text/x-shellscript; charset="us-ascii"
#!/bin/bash
sudo /etc/eks/bootstrap.sh procluster
--==MYBOUNDARY==--
Cloud-init will use this user-data to enable ESM on the cluster nodes and bootstrap the AWS EKS cluster.
When enabling FIPS, the most reliable way to deploy an Ubuntu Pro EKS cluster is to build a custom Ubuntu Pro AMI (with Packer) and use it during cluster creation.
Caveats:
To get the latest updates and security fixes from upstream, you’ll have to regularly rebuild your custom Ubuntu Pro image. Also, storing an AMI on AWS has a cost associated with it, and if required you might have to replicate it in multiple regions too.
Get and modify the Packer file:
Create an eks-ubuntu-fips.json
file with the following content (replacing the
placeholder credentials with your own in the “variables” section):
{
"variables": {
"aws_access_key": "YOUR_IAM_ACCESS_KEY",
"aws_secret_key": "YOUR_IAM_SECRET_KEY",
"pro_token": "YOUR_PRO_TOKEN",
"eks_ver": "YOUR_EKS_VERSION"
},
"builders": [
{
"type": "amazon-ebs",
"access_key": "{{user `aws_access_key`}}",
"secret_key": "{{user `aws_secret_key`}}",
"region": "us-east-1",
"instance_type": "t2.micro",
"ami_name": "eks{{user `eks_ver`}}-fips-ubuntu20.04-{{timestamp}}",
"source_ami_filter": {
"filters": {
"virtualization-type": "hvm",
"name": "ubuntu-eks/k8s_{{user `eks_ver`}}/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*",
"root-device-type": "ebs"
},
"owners": ["099720109477"],
"most_recent": true
},
"ssh_username": "ubuntu"
}
],
"provisioners": [
{
"type": "shell",
"inline": [
"cloud-init status --wait",
"sudo apt-get update && sudo apt-get upgrade -y --with-new-pkgs"
]
},
{
"type": "shell",
"inline": [
"sudo pro attach {{user `pro_token`}}",
"sudo pro status --wait",
"sudo pro enable fips --assume-yes"
]
},
{
"type": "shell",
"inline": [
"sudo truncate -s 0 /etc/machine-id",
"sudo truncate -s 0 /var/lib/dbus/machine-id"
]
}
]
}
This is the file that will be used by Packer to build the custom Ubuntu Pro AMI.
Remember that the final AMI needs to be in the same region as the EKS cluster, so make sure to adjust the “region” above accordingly.
This Packer file takes as a source an existing AMI of an EKS-based Ubuntu Focal Server for amd64. It will then launch shell commands to wait for cloud-init to finish and upgrade the system. Afterwards, it attaches the machine to a Pro subscription using your Pro token and enables FIPS. To conclude, it removes the machine-id from the custom image, to have a unique machine-id on every node instantiation.
Build the custom Ubuntu Pro AMI:
To build the image, run packer build eks-ubuntu-fips.json
.
The resulting logs should look something like:
Build 'amazon-ebs' finished after 9 minutes 35 seconds.
==> Wait completed after 9 minutes 35 seconds
==> Builds finished. The artifacts of successful builds are:
--> amazon-ebs: amis were created:
us-east-1: ami-xxxxxxxx
Note
Save a copy of the provided AMI ID for the next step.
Create the eksctl
config file¶
You’re now ready to deploy the EKS cluster with Ubuntu Pro nodes.
To do so, start by creating a cluster.yaml
with the following content
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
name: procluster
region: us-east-1
version: 'YOUR_EKS_VERSION'
Add the following content to your file
managedNodeGroups:
- name: ng-procluster
desiredCapacity: 2
launchTemplate:
id: lt-12345
version: "1"
This config file will allow you to create an EKS cluster using the launch template from above, with two nodes.
managedNodeGroups:
- name: ng-procluster
instanceType: t3.small
desiredCapacity: 2
labels: {role: worker}
ami: ami-xxxxx
amiFamily: AmazonLinux2
ssh:
publicKeyName: yoursshkeyname
overrideBootstrapCommand: |
#!/bin/bash
sudo /etc/eks/bootstrap.sh procluster
This config file allows you to create a cluster using the AMI from the previous step, with two nodes and SSH access.
The overrideBootstrapCommand
lets you launch the bootstrap script from AWS EKS
to initialise the nodes.
For further cluster customisation check out eksctl details.
Create the EKS cluster¶
To create the EKS cluster, run eksctl create cluster -f cluster.yaml
(you might need to specify the --profile
option if you have multiple
profiles). When this command finishes, see the nodes with
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
ip-xxx-xxx-xx-xxx.us-east-1.compute.internal Ready <none> 2m45s v1.23.x
ip-xxx-xxx-x-xx.us-east-1.compute.internal Ready <none> 2m45s v1.23.x
(Optional) Verify Pro subscription¶
To check that the deployed nodes have Ubuntu Pro, run:
$ aws --region <region_name> ec2 describe-instances \
--filters Name=instance-state-name,Values=running \
--query 'Reservations[*].Instances[*].[InstanceType, LaunchTime, PlatformDetails]'
--output table
----------------------------------------------------------------
| DescribeInstances |
+-----------+-----------------------------+--------------------+
| t3.medium| 2024-05-07T19:57:33+00:00 | Ubuntu Pro Linux |
| t3.medium| 2024-05-07T19:57:33+00:00 | Ubuntu Pro Linux |
+-----------+-----------------------------+--------------------+