Skip to main content

Reducing AWS EKS get-token Calls Made by Kubectl

Introduction

This should be applied when there is a need to optimize the latency of kubectl calls to AWS EKS.

Prerequisites

AWS EKS deployment targetKubeconfig file configured to run aws eks get-token

Instructions

Create script

Create a script named aws-get-token.sh with the following content

#!/bin/bash -e
awsCluster=$1
region=$2
# 840 sec = 14 min
maxFileAge=840

if [[ -f /tmp/$awsCluster.token ]]; then
# file age in seconds = current_time - file_modification_time.
fileage=$(($(date +%s) - $(stat -c '%Y' "/tmp/$awsCluster.token")))
if [[ $fileage > $maxFileAge ]]; then
#echo "Getting token again ..."
TOKEN=$(aws eks get-token --cluster-name $awsCluster --region $region)
echo $TOKEN > /tmp/$awsCluster.token
else
TOKEN=$( /tmp/$awsCluster.token
fi
echo -n $TOKEN

Create configMap in Spinnaker Namespace for Script aws-get-token.sh

Run the following command: kubectl -n $SPINNAKER_NAMESPACE create configmap aws-get-token --from-file aws-get-token.sh

Alter kubeconfig File

Alter kubeconfig file to make use of the aws-get-token.sh script created above. The kubeconfig file should look something like the following. Take note of the args and the command portion of this file.

apiVersion: v1
clusters:
- cluster:
certificate-authority-data: LS0txxxx=
server: https://B39xxxxx.yl4.${region}.eks.amazonaws.com
name: arn:aws:eks:${region}:xxxxx:cluster/${awsCluster}
contexts:
- context:
cluster: arn:aws:eks:${region}:xxxxx:cluster/${awsCluster}
user: arn:aws:eks:${region}:xxxxx:cluster/${awsCluster}
name: arn:aws:eks:${region}:xxxxx:cluster/${awsCluster}
current-context: arn:aws:eks:${region}:xxxxx:cluster/${awsCluster}
kind: Config
preferences: {}
users:
- name: arn:aws:eks:${region}:xxxxx:cluster/${awsCluster}
user:
exec:
apiVersion: client.authentication.k8s.io/v1alpha1
args:
- ${awsCluster}
- ${region}
command: /home/spinnaker/bin/aws-get-token.sh

Configure Spinnaker to Mount the Script

Configure Spinnaker to mount the script aws-get-token.sh as a configMap.

Using Halyard

In the service-settings/clouddriver.yml file add the following content:

kubernetes:
securityContext:
runAsUser: 1000
runAsGroup: 1000
fsGroup: 1000
volumes:
- id: aws-bin-dir
type: emptyDir
mountPath: /home/spinnaker/bin
- id: aws-get-token
type: configMap
mountPath: /aws-scripts-ro

Using Operator

Create a YAML file with the following content. Make sure to change `````` to match your CRD version

apiVersion: 
kind: SpinnakerService
metadata:
name: spinnaker
spec:
spinnakerConfig:
service-settings:
clouddriver:
kubernetes:
securityContext:
runAsUser: 1000
runAsGroup: 1000
fsGroup: 1000
volumes:
- id: aws-bin-dir
type: emptyDir
mountPath: /home/spinnaker/bin
- id: aws-get-token
type: configMap
mountPath: /aws-scripts-ro

Configure initContainer for Clouddriver

Configure an initContainer for Clouddriver which will copy the script aws-get-token.sh from the read-only location to /home/spinnaker/bin and make it executable.

Halyard

In the ~/.hal/config file find the initContainers section and add the following:

    initContainers:
spin-clouddriver:
- name: init-clouddriver
image: busybox:latest
command:
- sh
- -c
- cp /aws-scripts-ro/aws-get-token.sh /home/spinnaker/bin && chown -R 1000:1000 /home/spinnaker/bin/* && chmod 755 /home/spinnaker/bin/aws-get-token.sh
volumeMounts:
- mountPath: /home/spinnaker/bin
name: aws-bin-dir
- mountPath: /aws-scripts-ro
name: aws-get-token

Operator

Create a YAML file with the following content. Make sure to change `````` to match your CRD version

apiVersion: 
kind: SpinnakerService
metadata:
name: spinnaker
spec:
spinnakerConfig:
config:
deploymentEnvironment:
initContainers:
spin-clouddriver:
- name: init-clouddriver
image: busybox:latest
command:
- sh
- -c
- cp /aws-scripts-ro/aws-get-token.sh /home/spinnaker/bin && chown -R 1000:1000 /home/spinnaker/bin/* && chmod 755 /home/spinnaker/bin/aws-get-token.sh
volumeMounts:
- mountPath: /home/spinnaker/bin
name: aws-bin-dir
- mountPath: /aws-scripts-ro
name: aws-get-token

Redeploy Spinnaker

Redeploy Spinnaker with the changed configuration and new kubeconfig file