EKS Hybrid Nodes Complete Guide
Table of Contentsโ
- Overview
- Prerequisites
- Networking and DNS Configuration
- Harbor Private Registry Installation
- EKS Hybrid Nodes Configuration
- Harbor and EKS Integration
- GPU Server Integration
- Cost Analysis and Optimization
- Dynamic Resource Allocation (DRA)
- Operations and Maintenance
Overviewโ
This guide provides a complete adoption methodology for Amazon EKS Hybrid Nodes. Officially launched in December 2024, EKS Hybrid Nodes enables unified management of on-premises infrastructure and AWS EKS, allowing you to manage high-performance GPU servers and cloud resources within a single Kubernetes cluster.
Key Features:
- Unified management of on-premises and cloud resources
- Harbor 2.13 private registry integration
- H100 GPU server support
- Dynamic Resource Allocation (DRA)
- Flexible workload placement
Prerequisitesโ
System Requirementsโ
On-premises Nodes:
- Operating System: Ubuntu 20.04/22.04/24.04 LTS or RHEL 8/9
- Docker Engine 20.10.10+ (for Harbor)
- Container Runtime: containerd 1.6.x or higher
- Minimum Hardware: 2 CPU cores, 4GB RAM
GPU Servers (Optional):
- NVIDIA Driver 550.x or higher
- NVIDIA Container Toolkit
- H100/H200 GPU support
Network Requirementsโ
| Item | Requirement |
|---|---|
| Bandwidth | Minimum 10Gbps (Direct Connect or VPN) |
| Latency | Recommended under 5ms |
| MTU | Jumbo Frame (9000) recommended |
Networking and DNS Configurationโ
Required Firewall Settingsโ
Firewall port configuration required between on-premises and AWS:
| Protocol | Port | Direction | Purpose |
|---|---|---|---|
| TCP | 443 | Bidirectional | Kubernetes API server communication |
| TCP | 10250 | On-premises โ AWS | Kubelet API |
| TCP/UDP | 53 | Bidirectional | DNS lookups |
| TCP | 6443 | On-premises โ AWS | Kubernetes API (alternative) |
Pod CIDR Firewall Configurationโ
It is recommended to register the entire Pod CIDR range in the firewall.
Configuration Methods:
-
Register entire CIDR (recommended): e.g.,
10.244.0.0/16- Flexible handling of dynamic Pod IP allocation
- No additional firewall configuration needed during Pod scaling
- Reduced management complexity
-
Register only static worker node IPs (not recommended):
- Firewall rules must be updated whenever Pod IPs change
- Increased operational complexity
- Increased risk of service disruption
Istio + Calico CNI Mixed Modeโ
Additional port configuration when using Istio service mesh with Calico CNI:
| Component | Port | Purpose |
|---|---|---|
| Envoy Proxy | 15001 | Outbound traffic |
| Envoy Proxy | 15006 | Inbound traffic |
| Pilot | 15010 | xDS server |
| Istio Telemetry | 15004 | Mixer policy |
| Calico BGP | 179 | BGP peering |
| Calico Felix | 9099 | Metrics |
# Firewall rule examples (AWS Security Group)
aws ec2 authorize-security-group-ingress \
--group-id sg-hybrid-nodes \
--protocol tcp \
--port 15001 \
--source-group sg-eks-cluster
aws ec2 authorize-security-group-ingress \
--group-id sg-hybrid-nodes \
--protocol tcp \
--port 179 \
--source-group sg-hybrid-nodes
DNS Configurationโ
Route 53 Resolver Inbound Endpoint (On-premises โ AWS)โ
Purpose: Allow on-premises servers to resolve AWS internal domains
# Create Route 53 Resolver Inbound Endpoint
aws route53resolver create-resolver-endpoint \
--creator-request-id unique-id-123 \
--name hybrid-inbound-endpoint \
--security-group-ids sg-resolver-xxxxx \
--direction INBOUND \
--ip-addresses SubnetId=subnet-xxxxx,Ip=10.0.1.100 \
SubnetId=subnet-yyyyy,Ip=10.0.2.100
On-premises DNS configuration (e.g., BIND):
# /etc/named.conf
zone "eks.amazonaws.com" {
type forward;
forward only;
forwarders { 10.0.1.100; 10.0.2.100; };
};
Route 53 Resolver Outbound Endpoint (AWS โ On-premises)โ
Purpose: Allow AWS worker nodes to resolve on-premises internal domains
# Create Outbound Endpoint
aws route53resolver create-resolver-endpoint \
--creator-request-id unique-id-456 \
--name hybrid-outbound-endpoint \
--security-group-ids sg-resolver-xxxxx \
--direction OUTBOUND \
--ip-addresses SubnetId=subnet-xxxxx \
SubnetId=subnet-yyyyy
# Create Resolver Rule
aws route53resolver create-resolver-rule \
--creator-request-id unique-id-789 \
--name on-prem-dns-rule \
--rule-type FORWARD \
--domain-name company.local \
--target-ips Ip=192.168.1.53,Port=53 Ip=192.168.1.54,Port=53 \
--resolver-endpoint-id rslvr-out-xxxxx
Bidirectional DNS Resolution Verificationโ
# Resolve AWS domain from on-premises
dig @10.0.1.100 my-service.eks.amazonaws.com
# Resolve on-premises domain from AWS
dig harbor.company.local
CIDR Designโ
CIDR Design Principlesโ
AWS VPC CIDR:
- Primary:
10.0.0.0/16(65,536 IPs) - Secondary (if needed):
10.1.0.0/16
On-premises CIDR:
- Existing network:
192.168.0.0/16 - Pod CIDR:
10.244.0.0/16 - Service CIDR:
10.96.0.0/16
Overlap Prevention:
# Check for CIDR overlap
aws ec2 describe-vpcs --query 'Vpcs[*].CidrBlock'
# Check on-premises routing table
ip route show
Routing Configurationโ
# Create AWS Transit Gateway
aws ec2 create-transit-gateway \
--description "Hybrid connectivity" \
--options AmazonSideAsn=64512,AutoAcceptSharedAttachments=enable
# Create VPN connection
aws ec2 create-vpn-connection \
--type ipsec.1 \
--customer-gateway-id cgw-xxxxx \
--transit-gateway-id tgw-xxxxx \
--options TunnelInsideIpVersion=ipv4,TunnelOptions=[{TunnelInsideCidr=169.254.10.0/30}]
Harbor Private Registry Installationโ
Download Harbor 2.13.2โ
# Download Harbor 2.13.2 (latest stable version)
wget https://github.com/goharbor/harbor/releases/download/v2.13.2/harbor-offline-installer-v2.13.2.tgz
# Extract
tar xvf harbor-offline-installer-v2.13.2.tgz
cd harbor
SSL/TLS Certificate Configurationโ
Generate Self-Signed Certificatesโ
# 1. Generate CA certificate
openssl genrsa -out ca.key 4096
openssl req -x509 -new -nodes -sha512 -days 3650 \
-key ca.key \
-out ca.crt \
-subj "/C=KR/ST=Seoul/L=Seoul/O=MyOrganization/CN=Harbor-CA"
# 2. Generate server certificate
openssl genrsa -out harbor.key 4096
openssl req -new -sha512 \
-key harbor.key \
-out harbor.csr \
-subj "/C=KR/ST=Seoul/L=Seoul/O=MyOrganization/CN=harbor.yourdomain.com"
# 3. Create v3.ext file (SAN configuration)
cat > v3.ext <<EOF
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1=harbor.yourdomain.com
DNS.2=yourdomain.com
IP.1=192.168.1.100
EOF
# 4. Sign the certificate
openssl x509 -req -sha512 -days 3650 \
-extfile v3.ext \
-CA ca.crt -CAkey ca.key -CAcreateserial \
-in harbor.csr \
-out harbor.crt
# 5. Create certificate directory and copy files
mkdir -p /data/cert
cp harbor.crt /data/cert/
cp harbor.key /data/cert/
Harbor Configuration File Setupโ
# Copy and edit harbor.yml
cp harbor.yml.tmpl harbor.yml
vi harbor.yml
Key configuration settings:
# Hostname setting
hostname: harbor.yourdomain.com
# HTTPS configuration
https:
port: 443
certificate: /data/cert/harbor.crt
private_key: /data/cert/harbor.key
# Harbor admin password
harbor_admin_password: Harbor12345!
# Database settings
database:
password: root123
max_idle_conns: 100
max_open_conns: 900
conn_max_lifetime: 5m
conn_max_idle_time: 0
# Data storage path
data_volume: /data
# Log settings
log:
level: info
local:
rotate_count: 50
rotate_size: 200M
location: /var/log/harbor
# Trivy vulnerability scanner settings
trivy:
ignore_unfixed: false
skip_update: false
offline_scan: false
insecure: false
# Metrics settings
metric:
enabled: true
port: 9090
path: /metrics
Run Harbor Installationโ
# Run preparation script
sudo ./prepare
# Install Harbor (with Trivy)
sudo ./install.sh --with-trivy
# Verify installation
docker-compose ps
Create Robot Accountโ
# Create via Harbor UI or API
curl -X POST "https://harbor.yourdomain.com/api/v2.0/robots" \
-H "Content-Type: application/json" \
-u "admin:Harbor12345!" \
-d '{
"name": "k8s-robot",
"duration": 365,
"description": "Robot account for Kubernetes",
"disable": false,
"level": "system",
"permissions": [
{
"namespace": "*",
"kind": "project",
"access": [
{
"resource": "repository",
"action": "pull"
}
]
}
]
}'
EKS Hybrid Nodes Configurationโ
Install nodeadmโ
# For x86_64 architecture
curl -OL 'https://hybrid-assets.eks.amazonaws.com/releases/latest/bin/linux/amd64/nodeadm'
# For ARM architecture (if needed)
# curl -OL 'https://hybrid-assets.eks.amazonaws.com/releases/latest/bin/linux/arm64/nodeadm'
# Grant execute permission
chmod +x nodeadm
sudo mv nodeadm /usr/local/bin/
# Verify version
nodeadm version
Install Required Componentsโ
# Install Kubernetes 1.33 support components
sudo nodeadm install 1.33 --credential-provider ssm
# Or when using IAM Roles Anywhere
# sudo nodeadm install 1.33 --credential-provider iam-ra
Create NodeConfig Fileโ
# nodeconfig.yaml
apiVersion: node.eks.aws/v1alpha1
kind: NodeConfig
spec:
cluster:
name: my-hybrid-cluster
region: ap-northeast-2 # Seoul Region
# Hybrid node configuration using SSM
hybrid:
ssm:
activationCode: "YOUR-ACTIVATION-CODE"
activationId: "YOUR-ACTIVATION-ID"
# Containerd configuration (Harbor registry settings)
containerd:
config: |
version = 2
[plugins."io.containerd.grpc.v1.cri"]
[plugins."io.containerd.grpc.v1.cri".registry]
config_path = "/etc/containerd/certs.d:/etc/docker/certs.d"
[plugins."io.containerd.grpc.v1.cri".registry.mirrors]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."harbor.yourdomain.com"]
endpoint = ["https://harbor.yourdomain.com"]
[plugins."io.containerd.grpc.v1.cri".registry.configs]
[plugins."io.containerd.grpc.v1.cri".registry.configs."harbor.yourdomain.com"]
[plugins."io.containerd.grpc.v1.cri".registry.configs."harbor.yourdomain.com".auth]
username = "robot$k8s-robot"
password = "YOUR-ROBOT-TOKEN"
[plugins."io.containerd.grpc.v1.cri".registry.configs."harbor.yourdomain.com".tls]
ca_file = "/etc/ssl/certs/harbor-ca.crt"
insecure_skip_verify = false
# Kubelet settings
kubelet:
config:
shutdownGracePeriod: 30s
maxPods: 110
flags:
- --node-labels=node-type=hybrid,registry=harbor
Install Certificatesโ
# Add CA certificate to system trust store
sudo cp ca.crt /usr/local/share/ca-certificates/harbor-ca.crt
sudo update-ca-certificates
# Create certificate directory for Containerd
sudo mkdir -p /etc/containerd/certs.d/harbor.yourdomain.com
# Copy certificate
sudo cp ca.crt /etc/containerd/certs.d/harbor.yourdomain.com/ca.crt
# Restart Containerd
sudo systemctl restart containerd