The Ultimate Comprehensive Guide to Setting Up Self-Hosted Airbyte on EKS Using Karpenter
Luqman Bello
Posted on September 17, 2024
Table of Contents
- Introduction
- Prerequisites
- Setting Up EKS with Karpenter
- Deploying Airbyte on EKS
- Upgrading Airbyte OSS Version
- Monitoring and Maintenance
- Troubleshooting Common Errors
Introduction
Airbyte is an open-source data integration platform that enables you to consolidate your data from various sources to data warehouses, lakes, and databases. This 2024 guide walks you through setting up a production-ready, self-hosted Airbyte instance on Amazon EKS (Elastic Kubernetes Service) using Karpenter for dynamic node provisioning. The setup includes best practices for security, scalability, and maintenance.
Prerequisites
- AWS Account: An active AWS account with appropriate permissions
- AWS CLI: Version 2.13.0 or later
- kubectl: Version 1.28 or later
- Helm: Version 3.12 or later
- eksctl: Version 0.163.0 or later
- Basic knowledge: Kubernetes, AWS, and command-line operations
Setting Up EKS with Karpenter
Creating an EKS Cluster
Create a modern EKS cluster using eksctl
with the latest supported version:
eksctl create cluster \
--name airbyte-cluster \
--region us-west-2 \
--version 1.28 \
--with-oidc \
--zones us-west-2a,us-west-2b \
--nodegroup-name standard-workers \
--node-type t3.large \
--nodes 2 \
--nodes-min 1 \
--nodes-max 4 \
--managed \
--addons aws-ebs-csi-driver,vpc-cni,coredns,kube-proxy \
--node-volume-size 100 \
--external-dns-access
Key changes from previous versions:
- Updated to EKS 1.28 (latest stable)
- Added essential EKS add-ons
- Increased default node size to t3.large for better performance
- Added larger root volume for containers
- Enabled external DNS access for better integration
Installing Karpenter
- Create AWS IAM Resources for Karpenter
Using the latest Karpenter IAM setup:
export CLUSTER_NAME="airbyte-cluster"
export AWS_ACCOUNT_ID="$(aws sts get-caller-identity --query Account --output text)"
export AWS_REGION="us-west-2"
curl -fsSL https://karpenter.sh/v0.32.0/getting-started/getting-started-with-eksctl/cloudformation.yaml > cloudformation.yaml
aws cloudformation deploy \
--stack-name "karpenter-${CLUSTER_NAME}" \
--template-file cloudformation.yaml \
--capabilities CAPABILITY_NAMED_IAM \
--parameter-overrides "ClusterName=${CLUSTER_NAME}"
- Install Karpenter Controller
helm repo add karpenter https://charts.karpenter.sh
helm repo update
helm install karpenter karpenter/karpenter \
--namespace karpenter --create-namespace \
--version v0.32.0 \
--set serviceAccount.annotations."eks\.amazonaws\.com/role-arn"=arn:aws:iam::${AWS_ACCOUNT_ID}:role/karpenter-controller-${CLUSTER_NAME} \
--set settings.aws.clusterName=${CLUSTER_NAME} \
--set settings.aws.defaultInstanceProfile=KarpenterNodeInstanceProfile-${CLUSTER_NAME} \
--set settings.aws.interruptionQueueName=karpenter-${CLUSTER_NAME} \
--set controller.resources.requests.cpu=1 \
--set controller.resources.requests.memory=1Gi \
--set controller.resources.limits.cpu=1 \
--set controller.resources.limits.memory=1Gi
- Create a Modern Provisioner
Create provisioner.yaml
:
apiVersion: karpenter.sh/v1beta1
kind: NodePool
metadata:
name: default
spec:
template:
spec:
requirements:
- key: "kubernetes.io/arch"
operator: In
values: ["amd64"]
- key: "kubernetes.io/os"
operator: In
values: ["linux"]
- key: "karpenter.sh/capacity-type"
operator: In
values: ["on-demand"]
- key: "node.kubernetes.io/instance-type"
operator: In
values: ["t3.large", "t3.xlarge", "m5.large", "m5.xlarge"]
nodeClassRef:
name: default
limits:
resources:
cpu: 100
memory: 100Gi
disruption:
consolidationPolicy: WhenUnderutilized
consolidateAfter: 30s
weight: 10
---
apiVersion: karpenter.sh/v1beta1
kind: EC2NodeClass
metadata:
name: default
spec:
amiFamily: AL2
roleClassName: default
subnetSelectorTerms:
- tags:
karpenter.sh/discovery: ${CLUSTER_NAME}
securityGroupSelectorTerms:
- tags:
karpenter.sh/discovery: ${CLUSTER_NAME}
tags:
karpenter.sh/discovery: ${CLUSTER_NAME}
Apply the configuration:
kubectl apply -f provisioner.yaml
Deploying Airbyte on EKS
Configuring Airbyte Resources
- Create Namespace and Storage Class
kubectl create namespace airbyte
cat <<EOF | kubectl apply -f -
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: airbyte-storage
provisioner: ebs.csi.aws.com
parameters:
type: gp3
encrypted: "true"
reclaimPolicy: Retain
allowVolumeExpansion: true
volumeBindingMode: WaitForFirstConsumer
EOF
- Set Up Persistent Storage
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: airbyte-pvc
namespace: airbyte
spec:
storageClassName: airbyte-storage
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 50Gi
Deploying Airbyte
- Add Airbyte Helm Repository
helm repo add airbyte https://airbytehq.github.io/helm-charts
helm repo update
- Create Custom Values File
Create airbyte-values.yaml
:
global:
serviceAccountName: airbyte-admin
database:
secretName: airbyte-db-secrets
logs:
storage:
enabled: true
webapp:
resources:
limits:
cpu: "1"
memory: 2Gi
requests:
cpu: "0.5"
memory: 1Gi
server:
resources:
limits:
cpu: "2"
memory: 4Gi
requests:
cpu: "1"
memory: 2Gi
worker:
resources:
limits:
cpu: "2"
memory: 4Gi
requests:
cpu: "1"
memory: 2Gi
persistence:
enabled: true
storageClass: airbyte-storage
size: 50Gi
metrics:
enabled: true
serviceMonitor:
enabled: true
- Install Airbyte
helm install airbyte airbyte/airbyte \
--namespace airbyte \
--values airbyte-values.yaml \
--version 0.50.0
- Verify Deployment
kubectl get pods -n airbyte
kubectl get svc -n airbyte
Upgrading Airbyte OSS Version
- Backup Before Upgrade
# Backup using Velero or similar tool
velero backup create airbyte-backup \
--include-namespaces airbyte
- Update Helm Repository
helm repo update
helm search repo airbyte/airbyte --versions
- Upgrade Airbyte
helm upgrade airbyte airbyte/airbyte \
--namespace airbyte \
--values airbyte-values.yaml \
--version <NEW_VERSION> \
--timeout 15m
Monitoring and Maintenance
- Set Up Monitoring
# Install Prometheus and Grafana
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
helm install prometheus prometheus-community/kube-prometheus-stack \
--namespace monitoring \
--create-namespace
- Configure Log Aggregation
Use AWS CloudWatch Logs:
kubectl apply -f https://raw.githubusercontent.com/aws/containers-roadmap/master/preview-programs/cloudwatch-logs/cloudwatch-logs-configmap.yaml
Troubleshooting Common Errors
Pod Scheduling Issues
-
Symptom: Pods stuck in
Pending
state - Solution: Check Karpenter logs and node pool configuration:
kubectl logs -n karpenter -l app.kubernetes.io/name=karpenter -f
Database Connection Issues
- Symptom: Database connection errors in Airbyte logs
- Solution: Verify secrets and connection strings:
kubectl get secrets -n airbyte
kubectl logs -n airbyte deployment/airbyte-server
Resource Constraints
- Symptom: OOMKilled or CPU throttling
- Solution: Adjust resource limits in values.yaml:
resources:
limits:
memory: "4Gi"
cpu: "2"
requests:
memory: "2Gi"
cpu: "1"
Karpenter Node Provisioning Issues
- Symptom: Nodes not being provisioned
- Solution: Check NodePool and EC2NodeClass configurations:
kubectl describe nodepool default
kubectl describe ec2nodeclass default
This guide provides a robust foundation for running Airbyte on EKS with Karpenter. Remember to regularly check for updates and security patches for all components. For production environments, consider implementing additional security measures and backup strategies.
For questions, issues, or suggestions, please leave a comment below!
Posted on September 17, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
September 17, 2024