EKS (AWS) - Amazon Elastic Kubernetes Service
Tổng quan
Amazon EKS là managed Kubernetes service trên AWS. EKS quản lý control plane và integrates với AWS services.
EKS Architecture
Components
- Control Plane: Managed by AWS
- Data Plane: Worker nodes trên EC2
- Networking: VPC, subnets, security groups
- Storage: EBS, EFS, FSx integration
- Load Balancing: ALB, NLB integration
Service Integration
# AWS Load Balancer Controller
apiVersion: v1
kind: Service
metadata:
name: nginx-service
annotations:
service.beta.kubernetes.io/aws-load-balancer-type: nlb
service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing
spec:
type: LoadBalancer
ports:
- port: 80
targetPort: 80
selector:
app: nginx
Cluster Creation
eksctl Installation
# Download and install eksctl
curl --silent --location "https://github.com/weaveworks/eksctl/releases/latest/download/eksctl_$(uname -s)_amd64.tar.gz" | tar xz -C /tmp
sudo mv /tmp/eksctl /usr/local/bin
# Create cluster
eksctl create cluster \
--name my-cluster \
--version 1.24 \
--region us-west-2 \
--nodegroup-name standard-workers \
--node-type t3.medium \
--nodes 3 \
--nodes-min 1 \
--nodes-max 4 \
--ssh-access \
--ssh-public-key my-key \
--managed
Cluster Configuration
# cluster.yaml
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
name: production-cluster
region: us-west-2
version: "1.24"
vpc:
cidr: "10.0.0.0/16"
enableDnsHostnames: true
enableDnsSupport: true
managedNodeGroups:
- name: general-workers
instanceType: t3.medium
minSize: 3
maxSize: 10
desiredCapacity: 3
ssh:
publicKeyName: my-key
iam:
withAddonPolicies:
autoScaler: true
cloudWatch: true
ebs: true
efs: true
fsx: true
imageBuilder: true
addons:
- name: vpc-cni
- name: coredns
- name: kube-proxy
- name: aws-ebs-csi-driver
Node Groups
Managed Node Groups
# Create managed node group
eksctl create nodegroup \
--cluster my-cluster \
--name spot-workers \
--node-type m5.large \
--nodes-min 2 \
--nodes-max 8 \
--spot \
--ssh-access \
--ssh-public-key my-key \
--managed
Self-Managed Node Groups
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: aws-node
namespace: kube-system
spec:
selector:
matchLabels:
k8s-app: aws-node
template:
metadata:
labels:
k8s-app: aws-node
spec:
containers:
- name: aws-node
image: 602401143452.dkr.ecr.us-west-2.amazonaws.com/amazon-k8s-cni:v1.11.4
env:
- name: CLUSTER_NAME
value: my-cluster
- name: AWS_REGION
value: us-west-2
Networking
VPC CNI
apiVersion: v1
kind: ConfigMap
metadata:
name: amazon-vpc-cni
namespace: kube-system
data:
enable-pod-eni: "false"
enable-windows-ipam: "false"
warm-pool-size: "1"
minimum-ip-target: "3"
warm-ip-target: "1"
ALB Ingress Controller
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-ingress
annotations:
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:us-west-2:123456789012:certificate/abc123
spec:
rules:
- host: example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-service
port:
number: 80
Storage
EBS CSI Driver
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: ebs-gp3
provisioner: ebs.csi.aws.com
parameters:
type: gp3
iops: "3000"
throughput: "125"
encrypted: "true"
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true
EFS Integration
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: efs-sc
provisioner: efs.csi.aws.com
parameters:
provisioningMode: efs-ap
fileSystemId: fs-abc123
directoryPerms: "700"
gidRangeStart: "1000"
gidRangeEnd: "2000"
IAM Integration
Service Accounts
apiVersion: v1
kind: ServiceAccount
metadata:
name: aws-load-balancer-controller
namespace: kube-system
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/AmazonEKSLoadBalancerControllerRole
IRSA (IAM Roles for Service Accounts)
# Create OIDC provider
eksctl utils associate-iam-oidc-provider \
--cluster my-cluster \
--approve
# Create service account with IAM role
eksctl create iamserviceaccount \
--cluster my-cluster \
--namespace kube-system \
--name aws-load-balancer-controller \
--attach-policy-arn arn:aws:iam::aws:policy/ElasticLoadBalancingFullAccess \
--approve
Security
Pod Security Groups
apiVersion: vpcresources.k8s.aws/v1alpha1
kind: SecurityGroupPolicy
metadata:
name: allow-rds-access
spec:
podSelector:
matchLabels:
app: database-client
securityGroups:
groupIds:
- sg-12345678
Network Policies
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all-ingress
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
egress:
- to:
- namespaceSelector:
matchLabels:
name: kube-system
- to: []
ports:
- protocol: UDP
port: 53
Monitoring
CloudWatch Integration
apiVersion: v1
kind: ConfigMap
metadata:
name: cwagentconfig
namespace: amazon-cloudwatch
data:
cwagentconfig.json: |
{
"logs": {
"metrics_collected": {
"kubernetes": {
"cluster_name": "my-cluster",
"metrics_collection_interval": 60
}
}
}
}
Container Insights
# Deploy CloudWatch agent
kubectl apply -f https://raw.githubusercontent.com/aws-samples/amazon-cloudwatch-container-insights/latest/k8s-deployment-manifest-templates/deployment-mode/daemonset/container-insights-monitoring/cloudwatch-namespace.yaml
# Deploy Fluent Bit
kubectl apply -f https://raw.githubusercontent.com/aws-samples/amazon-cloudwatch-container-insights/latest/k8s-deployment-manifest-templates/deployment-mode/daemonset/container-insights-monitoring/fluent-bit/fluent-bit.yaml
Autoscaling
Cluster Autoscaler
apiVersion: apps/v1
kind: Deployment
metadata:
name: cluster-autoscaler
namespace: kube-system
spec:
replicas: 1
selector:
matchLabels:
app: cluster-autoscaler
template:
metadata:
labels:
app: cluster-autoscaler
spec:
serviceAccountName: cluster-autoscaler
containers:
- image: k8s.gcr.io/autoscaling/cluster-autoscaler:v1.21.0
name: cluster-autoscaler
command:
- ./cluster-autoscaler
- --v=4
- --stderrthreshold=info
- --cloud-provider=aws
- --skip-nodes-with-local-storage=false
- --expander=least-waste
- --node-group-auto-discovery=asg:tag=k8s.io/cluster-autoscaler/enabled,k8s.io/cluster-autoscaler/my-cluster
- --balance-similar-node-groups
- --skip-nodes-with-system-pods=false
Fargate
Fargate Profiles
# Create Fargate profile
eksctl create fargateprofile \
--cluster my-cluster \
--name fargate-profile \
--namespace production \
--labels app=web
Fargate Configuration
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
name: fargate-cluster
region: us-west-2
fargateProfiles:
- name: default
selectors:
- namespace: default
labels:
workload-type: fargate
- name: kube-system
selectors:
- namespace: kube-system
Best Practices
Cluster Management
- Use latest Kubernetes versions
- Regular node group updates
- Implement proper tagging
- Monitor costs với AWS Cost Explorer
- Use spot instances cho cost optimization
Security
- Enable logging cho audit trails
- Use IAM roles cho service accounts
- Implement network policies
- Regular security scanning
- Use private subnets cho worker nodes
Performance
- Right-size node instances
- Use dedicated instances cho production
- Implement proper resource requests/limits
- Monitor performance metrics
- Use container insights
Cost Optimization
Spot Instances
# Spot instance node group
managedNodeGroups:
- name: spot-workers
instanceTypes:
- t3.medium
- t3.large
- m5.large
spot: true
minSize: 2
maxSize: 10
desiredCapacity: 4
Savings Plans
# Check compute savings plans
aws savingsplans describe-savings-plans
# Analyze cost với Cost Explorer
aws ce get-cost-and-usage \
--time-period Start=2023-01-01,End=2023-12-31 \
--granularity MONTHLY \
--metrics BlendedCost
Next Steps
- 📚 Học về GKE (GCP)
- 🎯 Practice EKS deployment
- 🏗️ Explore Fargate workloads
- 💻 Setup cost monitoring
Content sẽ được expand với advanced EKS configurations và real-world deployment scenarios.