EKS Hybrid Nodes 완전 가이드
📅 작성일: 2025-08-20 | 수정일: 2026-02-14 | ⏱️ 읽는 시간: 약 8분
목차
- 개요
- 사전 준비
- 네트워킹 및 DNS 구성
- Harbor Private Registry 설치
- EKS Hybrid Nodes 구성
- Harbor와 EKS 통합
- GPU 서버 통합
- 비용 분석 및 최적화
- 동적 리소스 할당 (DRA)
- 운영 및 유지보수
개요
이 가이드는 Amazon EKS Hybrid Nodes의 완전한 도입 방법을 제공합니다. 2024년 12월 정식 출시된 EKS Hybrid Nodes는 온프레미스 인프라와 AWS EKS를 통합 관리할 수 있게 해주며, 특히 고성능 GPU 서버와 클라우드 리소스를 하나의 Kubernetes 클러스터로 관리할 수 있습니다.
주요 기능:
- 온프레미스와 클라우드의 통합 관리
- Harbor 2.13 프라이빗 레지스트리 통합
- H100 GPU 서버 지원
- 동적 리소스 할당 (DRA)
- 유연한 워크로드 배치
사전 준비
시스템 요구사항
온프레미스 노드:
- 운영체제: Ubuntu 20.04/22.04/24.04 LTS 또는 RHEL 8/9
- Docker Engine 20.10.10+ (Harbor용)
- Container Runtime: containerd 1.6.x 이상
- 최소 하드웨어: 2 CPU cores, 4GB RAM
GPU 서버 (선택사항):
- NVIDIA Driver 550.x 이상
- NVIDIA Container Toolkit
- H100/H200 GPU 지원
네트워크 요구사항
| 항목 | 요구사항 |
|---|---|
| 대역폭 | 최소 10Gbps (Direct Connect 또는 VPN) |
| 지연시간 | 5ms 이하 권장 |
| MTU | Jumbo Frame (9000) 권장 |
네트워킹 및 DNS 구성
필수 방화벽 설정
온프레미스와 AWS 간 필요한 방화벽 포트 구성:
| 프로토콜 | 포트 | 방향 | 목적 |
|---|---|---|---|
| TCP | 443 | 양방향 | Kubernetes API 서버 통신 |
| TCP | 10250 | 온프레미스 → AWS | Kubelet API |
| TCP/UDP | 53 | 양방향 | DNS 조회 |
| TCP | 6443 | 온프레미스 → AWS | Kubernetes API (대체) |
Pod CIDR 방화벽 구성
권장사항
전체 Pod CIDR 대역을 방화벽에 등록하는 것을 권장합니다.
구성 방법:
-
전체 CIDR 등록 (권장): 예)
10.244.0.0/16- 동적 Pod IP 할당에 유연하게 대응
- Pod 스케일링 시 추가 방화벽 설정 불필요
- 관리 복잡도 감소
-
고정 IP 워커노드만 등록 (비권장):
- Pod IP가 변경될 때마다 방화벽 규칙 업데이트 필요
- 운영 복잡도 증가
- 서비스 중단 위험 증가
Istio + Calico CNI 혼합 모드
Istio 서비스 메시와 Calico CNI를 함께 사용하는 경우 추가 포트 구성:
| 컴포넌트 | 포트 | 용도 |
|---|---|---|
| Envoy Proxy | 15001 | 아웃바운드 트래픽 |
| Envoy Proxy | 15006 | 인바운드 트래픽 |
| Pilot | 15010 | xDS 서버 |
| Istio Telemetry | 15004 | Mixer 정책 |
| Calico BGP | 179 | BGP 피어링 |
| Calico Felix | 9099 | 메트릭 |
# 방화벽 규칙 예시 (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 구성
Route 53 Resolver Inbound Endpoint (온프레미스 → AWS)
목적: 온프레미스 서버가 AWS 내부 도메인을 조회할 수 있도록 설정
# 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
온프레미스 DNS 설정 (예: 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 → 온프레미스)
목적: AWS 워커노드가 온프레미스 내부 도메인을 조회할 수 있도록 설정
# 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
# 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
양방향 DNS 조회 검증
# 온프레미스에서 AWS 도메인 조회
dig @10.0.1.100 my-service.eks.amazonaws.com
# AWS에서 온프레미스 도메인 조회
dig harbor.company.local
CIDR 설계
CIDR 설계 원칙
AWS VPC CIDR:
- Primary:
10.0.0.0/16(65,536 IP) - Secondary (필요시):
10.1.0.0/16
온프레미스 CIDR:
- 기존 네트워크:
192.168.0.0/16 - Pod CIDR:
10.244.0.0/16 - Service CIDR:
10.96.0.0/16
중복 방지:
# CIDR 중복 검사
aws ec2 describe-vpcs --query 'Vpcs[*].CidrBlock'
# 온프레미스 라우팅 테이블 확인
ip route show
라우팅 구성
# AWS Transit Gateway 생성
aws ec2 create-transit-gateway \
--description "Hybrid connectivity" \
--options AmazonSideAsn=64512,AutoAcceptSharedAttachments=enable
# VPN 연결 생성
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 설치
Harbor 2.15.x 다운로드
# Harbor 2.15.1 다운로드 (최신 안정 버전, 2026-06 기준)
wget https://github.com/goharbor/harbor/releases/download/v2.15.1/harbor-offline-installer-v2.15.1.tgz
# 압축 해제
tar xvf harbor-offline-installer-v2.15.1.tgz
cd harbor
SSL/TLS 인증서 구성
자체 서명 인증서 생성
# 1. CA 인증서 생성
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. 서버 인증서 생성
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. v3.ext 파일 생성 (SAN 설정)
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. 인증서 서명
openssl x509 -req -sha512 -days 3650 \
-extfile v3.ext \
-CA ca.crt -CAkey ca.key -CAcreateserial \
-in harbor.csr \
-out harbor.crt
# 5. 인증서 디렉토리 생성 및 복사
mkdir -p /data/cert
cp harbor.crt /data/cert/
cp harbor.key /data/cert/
Harbor 구성 파일 설정
# harbor.yml 파일 복사 및 편집
cp harbor.yml.tmpl harbor.yml
vi harbor.yml
주요 설정 내용:
# 호스트명 설정
hostname: harbor.yourdomain.com
# HTTPS 구성
https:
port: 443
certificate: /data/cert/harbor.crt
private_key: /data/cert/harbor.key
# Harbor 관리자 비밀번호
harbor_admin_password: Harbor12345!
# 데이터베이스 설정
database:
password: root123
max_idle_conns: 100
max_open_conns: 900
conn_max_lifetime: 5m
conn_max_idle_time: 0
# 데이터 저장 경로
data_volume: /data
# 로그 설정
log:
level: info
local:
rotate_count: 50
rotate_size: 200M
location: /var/log/harbor
# Trivy 취약점 스캐너 설정
trivy:
ignore_unfixed: false
skip_update: false
offline_scan: false
insecure: false
# 메트릭 설정
metric:
enabled: true
port: 9090
path: /metrics
Harbor 설치 실행
# 설치 준비 스크립트 실행
sudo ./prepare
# Harbor 설치 (Trivy 포함)
sudo ./install.sh --with-trivy
# 설치 확인
docker-compose ps
Robot Account 생성
# Harbor UI에서 생성하거나 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 구성
nodeadm 설치
# x86_64 아키텍처용
curl -OL 'https://hybrid-assets.eks.amazonaws.com/releases/latest/bin/linux/amd64/nodeadm'
# ARM 아키텍처용 (필요시)
# curl -OL 'https://hybrid-assets.eks.amazonaws.com/releases/latest/bin/linux/arm64/nodeadm'
# 실행 권한 부여
chmod +x nodeadm
sudo mv nodeadm /usr/local/bin/
# 버전 확인
nodeadm version
필수 구성 요소 설치
# Kubernetes 1.33 지원 컴포넌트 설치
sudo nodeadm install 1.33 --credential-provider ssm
# 또는 IAM Roles Anywhere 사용시
# sudo nodeadm install 1.33 --credential-provider iam-ra
NodeConfig 파일 생성
# nodeconfig.yaml
apiVersion: node.eks.aws/v1alpha1
kind: NodeConfig
spec:
cluster:
name: my-hybrid-cluster
region: ap-northeast-2 # 서울 리전
# SSM을 사용한 하이브리드 노드 구성
hybrid:
ssm:
activationCode: "YOUR-ACTIVATION-CODE"
activationId: "YOUR-ACTIVATION-ID"
# Containerd 구성 (Harbor 레지스트리 설정)
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 설정
kubelet:
config:
shutdownGracePeriod: 30s
maxPods: 110
flags:
- --node-labels=node-type=hybrid,registry=harbor
인증서 설치
# CA 인증서를 시스템 신뢰 저장소에 추가
sudo cp ca.crt /usr/local/share/ca-certificates/harbor-ca.crt
sudo update-ca-certificates
# Containerd용 인증서 디렉토리 생성
sudo mkdir -p /etc/containerd/certs.d/harbor.yourdomain.com
# 인증서 복사
sudo cp ca.crt /etc/containerd/certs.d/harbor.yourdomain.com/ca.crt
# Containerd 재시작
sudo systemctl restart containerd
노드 초기화
# NodeConfig를 사용하여 노드 초기화
sudo nodeadm init --config-source file://nodeconfig.yaml
# 노드 상태 확인
kubectl get nodes
Harbor와 EKS 통합
네트워크 구성
# Harbor 보안 그룹에 EKS 노드 액세스 허용
aws ec2 authorize-security-group-ingress \
--group-id sg-harbor-xxxxx \
--protocol tcp \
--port 443 \
--source-group sg-eks-nodes-xxxxx \
--region ap-northeast-2
CoreDNS 구성
# CoreDNS ConfigMap 수정
kubectl edit configmap coredns -n kube-system
# 다음 내용 추가
data:
Corefile: |
.:53 {
errors
health
kubernetes cluster.local in-addr.arpa ip6.arpa {
pods insecure
fallthrough in-addr.arpa ip6.arpa
}
# Harbor DNS 추가
hosts {
192.168.1.100 harbor.yourdomain.com
fallthrough
}
prometheus :9153
forward . /etc/resolv.conf
cache 30
loop
reload
loadbalance
}
Kubernetes Secret 생성
# Docker 로그인 테스트
docker login harbor.yourdomain.com
Username: robot$k8s-robot
Password: YOUR-ROBOT-TOKEN
# Kubernetes Secret 생성
kubectl create secret docker-registry harbor-registry \
--docker-server=harbor.yourdomain.com \
--docker-username='robot$k8s-robot' \
--docker-password='YOUR-ROBOT-TOKEN' \
--docker-email=admin@yourdomain.com
# 모든 네임스페이스에 Secret 복사 (선택사항)
for ns in $(kubectl get ns -o jsonpath='{.items[*].metadata.name}'); do
kubectl get secret harbor-registry -o yaml | \
sed "s/namespace: default/namespace: $ns/" | \
kubectl apply -f -
done
테스트 및 검증
# 1. 네트워크 연결 확인
curl -k https://harbor.yourdomain.com/api/v2.0/health
# 2. 노드에서 직접 이미지 풀 테스트
sudo crictl pull harbor.yourdomain.com/library/nginx:latest
# 3. Kubernetes Pod 배포 테스트
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: harbor-test
spec:
containers:
- name: nginx
image: harbor.yourdomain.com/library/nginx:latest
imagePullSecrets:
- name: harbor-registry
EOF
# 4. Pod 상태 확인
kubectl get pod harbor-test
kubectl describe pod harbor-test