1. 기본 환경 배포
이번 실습은 IAM 사용자 계정을 통해 관리 콘솔에 접근하고 액세스 키를 활용해 awscli 도구를 사용합니다.
해당 작업을 수행하지 않았다면 아래 토글을 확장해 작업을 선행하고 본격적인 실습에 들어갑니다.
IAM 사용자 생성 및 액세스 키 생성
1.1. Terraform을 통한 기본 인프라 배포
Terraform을 통한 기본 인프라 배포에 앞서 SSH 키 페어, IAM User Access Key ID, IAM User Secret Access Key를 미리 확인하고 메모해 둡니다.
Terraform으로 기본 인프라 배포
cd cnaee_class_tf/ch2
Bash
복사
# 실습 디렉터리 경로 진입
export TF_VAR_KeyName=[각자 ssh keypair]
export TF_VAR_MyIamUserAccessKeyID=[각자 iam 사용자의 access key id]
export TF_VAR_MyIamUserSecretAccessKey=[각자 iam 사용자의 secret access key]
export TF_VAR_SgIngressSshCidr=$(curl -s ipinfo.io/ip)/32
Bash
복사
# Terraform 환경 변수 저장
terraform init
terraform plan
Bash
복사
# Terraform 배포
nohup sh -c "terraform apply -auto-approve" > create.log 2>&1 &
Bash
복사
Note:
nohup으로 백그라운드로 실행하도록 변경했습니다.
Terraform 배포가 완료되면 정상적으로 자원 생성이 되었는지 확인을 합니다.(cat create.log)
Terraform을 통한 기본 인프라 배포가 완료되면 관리 콘솔에서 생성된 인프라들을 확인합니다.
Note:
AWS 관리 콘솔에 로그인 할 땐 IAM 사용자 계정으로 진행합니다.
1.2. 기본 정보 확인 및 설정
Terraform 배포가 완료 후 출력되는 Output 정보에서 bastion_host_ip의 퍼블릭 IP를 확인합니다.
해당 IP로 EKS 관리용 인스턴스(myeks-bastion-EC2)에 SSH로 접속하고 아래 명령어를 통해 정보를 확인합니다.
Note:
myeks-bastion-EC2의 OS 변경으로 SSH 접근에 대한 계정을 ubuntu로 지정합니다.
(ssh -i ~/.ssh/XXXX.pem ubuntu@X.X.X.X)
기본 설정 및 확인
aws eks update-kubeconfig \
--region $AWS_DEFAULT_REGION \
--name $CLUSTER_NAME
Shell
복사
# EKS 클러스터 인증 정보 업데이트
kubens default
Bash
복사
# kubens default 설정
echo $AWS_DEFAULT_REGION
echo $CLUSTER_NAME
echo $VPCID
echo $PublicSubnet1,$PublicSubnet2,$PublicSubnet3
echo $PrivateSubnet1,$PrivateSubnet2,$PrivateSubnet3
Bash
복사
# 변수 호출 종합
eksctl get cluster
Bash
복사
# eksctl을 통한 eks cluster 정보 확인
eksctl get nodegroup \
--cluster $CLUSTER_NAME \
--name ${CLUSTER_NAME}-node-group
Bash
복사
# eksctl을 통한 노드 그룹 정보 확인
kubectl get node -owide
Bash
복사
# kubectl을 통한 노드 정보 확인
PublicN1=$(kubectl get node --label-columns=topology.kubernetes.io/zone --selector=topology.kubernetes.io/zone=ap-northeast-2a -o jsonpath={.items[0].status.addresses[0].address})
PublicN2=$(kubectl get node --label-columns=topology.kubernetes.io/zone --selector=topology.kubernetes.io/zone=ap-northeast-2b -o jsonpath={.items[0].status.addresses[0].address})
PublicN3=$(kubectl get node --label-columns=topology.kubernetes.io/zone --selector=topology.kubernetes.io/zone=ap-northeast-2c -o jsonpath={.items[0].status.addresses[0].address})
echo "export PublicN1=$PublicN1" >> /etc/profile
echo "export PublicN2=$PublicN2" >> /etc/profile
echo "export PublicN3=$PublicN3" >> /etc/profile
echo $PublicN1, $PublicN2, $PublicN3
Bash
복사
# 노드 IP 변수 선언
for node in $PublicN1 $PublicN2 $PublicN3; \
do \
ssh -i ~/.ssh/kp_node.pem -o StrictHostKeyChecking=no ec2-user@$node hostname; \
done
Bash
복사
# 노드에 ssh 접근 확인
aws ec2 describe-security-groups \
--filters Name=group-name,Values=myeks-node-group-sg \
--query "SecurityGroups[*].[GroupId]" \
--output text
Bash
복사
# 노드 보안 그룹 확인 및 변수 선언
NGSGID=$(aws ec2 describe-security-groups --filters Name=group-name,Values=myeks-node-group-sg --query "SecurityGroups[*].[GroupId]" --output text); echo $NGSGID
echo "export NGSGID=$NGSGID" >> /etc/profile
Bash
복사
aws ec2 authorize-security-group-ingress \
--group-id $NGSGID \
--protocol tcp \
--port 80 \
--cidr 192.168.0.0/16
Bash
복사
# 노드 보안 그룹 설정
2. VPC CNI - Network Policy 설정 및 확인
2.1. VPC CNI - Network Policy 활성화
버전 확인 (Network Policy 설치 - 적합성 확인)
aws eks describe-cluster \
--name $CLUSTER_NAME \
--query cluster.version \
--output text
Bash
복사
# EKS 클러스터 버전 확인
kubectl describe daemonset aws-node \
--namespace kube-system | grep amazon-k8s-cni: | cut -d : -f 3
Bash
복사
# VPC CNI 버전 확인
ssh -i ~/.ssh/kp_node.pem ec2-user@$PublicN1 uname -r
Bash
복사
# 워커 노드의 OS 커널 버전 확인
aws-node 데몬셋 정보 확인
kubectl get ds aws-node -n kube-system -o yaml
Bash
복사
# aws-node 데몬셋 상세 정보 확인
kubectl get ds aws-node -n kube-system -o yaml | grep enable-network-policy
Bash
복사
# aws-node 데몬셋 network-policy 정보 확인
Note:
기본적으로 VPC-CNI의 Kubernetes Network Policy는 비활성화 상태입니다.
Terraform eks.tf 파일 수정 및 적용
...
vpc-cni = {
most_recent = true
configuration_values = jsonencode({
enableNetworkPolicy = "true"
})
}
...
Bash
복사
# [eks.tf 수정] module.eks의 addon 영역에서 수정
terraform apply -auto-approve
Bash
복사
# [사용자 PC] terraform apply
kubectl get ds aws-node -n kube-system -o yaml | grep enable-network-policy
Bash
복사
# aws-node 데몬셋 network-policy 정보 확인
2.2. VPC CNI - Network Policy 정보 확인
노드에 BPF 파일 시스템 탑재 확인
ssh -i ~/.ssh/kp_node.pem ec2-user@$PublicN1 mount | grep -i bpf
ssh -i ~/.ssh/kp_node.pem ec2-user@$PublicN1 df -a | grep -i bpf
Bash
복사
# 노드에 BPF 파일 시스템을 탑재 확인
VPC CNI - Network Policy 정보 확인
kubectl get pod -n kube-system -l k8s-app=aws-node
Bash
복사
# aws-node 파드 정보 확인
kubectl get ds aws-node -n kube-system -o yaml | grep -i image:
Bash
복사
# aws-node에 컨테이너 이미지 확인
kubectl api-resources | grep -i policyendpoints
Bash
복사
# k8s api 확인
kubectl get crd
Bash
복사
# CRD 확인
eBPF 정보 확인
ssh -i ~/.ssh/kp_node.pem ec2-user@$PublicN1 \
sudo /opt/cni/bin/aws-eks-na-cli ebpf progs
Bash
복사
# eBPF 프로그램 확인
ssh -i ~/.ssh/kp_node.pem ec2-user@$PublicN1 \
sudo /opt/cni/bin/aws-eks-na-cli ebpf loaded-ebpfdata
Bash
복사
# eBPF 데이터 확인
3. VPC CNI - Network Policy 동작 확인
3.1. 실습 파일 다운로드 및 데모 애플리케이션 배포
데모 애플리케이션 배포 및 확인
wget https://github.com/cloudneta/cnaeelab/raw/master/_data/demo_ch2_1.zip
unzip demo_ch2_1.zip
Bash
복사
# VPC CNI - Network Policy 실습 파일 다운로드 및 압축 해제
cd demo_ch2_1
tree
Bash
복사
# 대상 경로 진입 및 확인
kubectl label nodes $(kubectl get nodes | awk '{print $1}' | grep -E '^ip-192-168-[12]-') node-group=general
Bash
복사
# 192-168-1-XXX, 192-168-2-XXX 노드에 'node-group=general' 라벨 추가
kubectl label nodes $(kubectl get nodes | awk '{print $1}' | grep -E '^ip-192-168-3-') node-group=web
Bash
복사
# 192-168-3-XXX 노드에 'node-group=web' 라벨 추가
Note:
Node #1, #2는 genernal 라벨을 추가하고 Node #3는 web 라벨을 추가합니다.
이로써 red/blue 파드는 general 영역에 배포하고, demo-web 파드는 web 영역에 배포합니다.
kubectl apply -f manifest/
Bash
복사
# 데모 애플리케이션 배포
kubectl get pod,svc -n red -owide; echo '---'
kubectl get pod,svc -n blue -owide; echo '---'
kubectl get networkpolicy -n red
Bash
복사
# 생성 자원 확인
kubectl exec -it red-1 -n red -- curl demo-web
Bash
복사
# demo-web으로 통신 확인
kubectl exec -it red-2 -n red -- curl demo-web
Bash
복사
kubectl exec -it blue-1 -n blue -- curl demo-web.red
Bash
복사
kubectl exec -it blue-2 -n blue -- curl demo-web.red
Bash
복사
파드별 모니터링(1)
while true; do \
kubectl exec -it red-1 -n red -- curl --connect-timeout 1 demo-web; date; \
kubectl exec -it red-1 -n red -- ip -4 addr | grep "192.168."; \
echo -e "\033[31mred-1\033[0m"; sleep 1; done
Bash
복사
# [신규 터미널1] red-1에서 demo-web으로 http 접근 및 IP 확인
while true; do \
kubectl exec -it red-2 -n red -- curl --connect-timeout 1 demo-web; date; \
kubectl exec -it red-2 -n red -- ip -4 addr | grep "192.168."; \
echo -e "\033[31mred-2\033[0m"; sleep 1; done
Bash
복사
# [신규 터미널2] red-2에서 demo-web으로 http 접근 및 IP 확인
while true; do \
kubectl exec -it blue-1 -n blue -- curl --connect-timeout 1 demo-web.red; date; \
kubectl exec -it blue-1 -n blue -- ip -4 addr | grep "192.168."; \
echo -e "\033[38;5;26mblue-1\033[0m"; sleep 1; done
Bash
복사
# [신규 터미널3] blue-1에서 demo-web.red로 http 접근 및 IP 확인
while true; do \
kubectl exec -it blue-2 -n blue -- curl --connect-timeout 1 demo-web.red; date; \
kubectl exec -it blue-2 -n blue -- ip -4 addr | grep "192.168."; \
echo -e "\033[38;5;26mblue-2\033[0m"; sleep 1; done
Bash
복사
# [신규 터미널4] blue-2에서 demo-web.red로 http 접근 및 IP 확인
3.2. Network Policy 적용 및 확인
[demo-web] 01_deny_all_ingress 적용
cat netpolicy/01_deny_all_ingress.yaml
Bash
복사
# 01_deny_all_ingress.yaml 확인
kubectl apply -f netpolicy/01_deny_all_ingress.yaml
Bash
복사
# 01_deny_all_ingress.yaml 적용
[demo-web] 01_deny_all_ingress 확인
kubectl get networkpolicy -n red
Bash
복사
# network policy 확인
kubectl exec -it deploy/demo-web -n red -- curl wttr.in/Seoul?m1
Bash
복사
# demo-web에서 Egress 통신 확인
ssh -i ~/.ssh/kp_node.pem ec2-user@$PublicN3 \
sudo /opt/cni/bin/aws-eks-na-cli ebpf progs | awk '!/maps count : 0/' | grep -v '=='
Bash
복사
# eBPF 프로그램 확인
Warning:
eBPF 프로그램 ID는 고정된 값이 아닙니다.
ssh -i ~/.ssh/kp_node.pem ec2-user@$PublicN3 sudo \
/opt/cni/bin/aws-eks-na-cli ebpf loaded-ebpfdata
Bash
복사
# eBPF 데이터 확인
read EGRESS_MAP_ID INGRESS_MAP_ID AWS_CONNTRACK_MAP_ID < <(
ssh -i ~/.ssh/kp_node.pem ec2-user@$PublicN3 sudo /opt/cni/bin/aws-eks-na-cli ebpf loaded-ebpfdata | \
awk '
/egress_map/ {getline; egress=$NF}
/ingress_map/ {getline; ingress=$NF}
/aws_conntrack_map/ {getline; conntrack=$NF}
END {print egress, ingress, conntrack}'
)
echo "EGRESS_MAP_ID: $EGRESS_MAP_ID"
echo "INGRESS_MAP_ID: $INGRESS_MAP_ID"
echo "AWS_CONNTRACK_MAP_ID: $AWS_CONNTRACK_MAP_ID"
Bash
복사
# eBPF dump map ID 변수 선언
ssh -i ~/.ssh/kp_node.pem ec2-user@$PublicN3 \
sudo /opt/cni/bin/aws-eks-na-cli ebpf dump-maps $INGRESS_MAP_ID
Bash
복사
# eBPF dump-map에서 ingress_map 확인
ssh -i ~/.ssh/kp_node.pem ec2-user@$PublicN3 \
sudo /opt/cni/bin/aws-eks-na-cli ebpf dump-maps $EGRESS_MAP_ID
Bash
복사
# eBPF dump-map에서 egress_map 확인
ssh -i ~/.ssh/kp_node.pem ec2-user@$PublicN3 \
sudo /opt/cni/bin/aws-eks-na-cli ebpf dump-maps $AWS_CONNTRACK_MAP_ID
Bash
복사
# eBPF dump-map에서 aws_conntrack_map 확인
[demo-web] 01_deny_all_ingress 삭제
kubectl delete -f netpolicy/01_deny_all_ingress.yaml
Bash
복사
# 01_deny_all_ingress.yaml 삭제
[demo-web] 02_allow_redns_red1_ingress 적용
cat netpolicy/02_allow_redns_red1_ingress.yaml
Bash
복사
# 02_allow_redns_red1_ingress.yaml 확인
kubectl apply -f netpolicy/02_allow_redns_red1_ingress.yaml
Bash
복사
# 02_allow_redns_red1_ingress.yaml 적용
[demo-web] 02_allow_redns_red1_ingress 확인
kubectl get networkpolicy -n red
Bash
복사
# network policy 확인
ssh -i ~/.ssh/kp_node.pem ec2-user@$PublicN3 \
sudo /opt/cni/bin/aws-eks-na-cli ebpf dump-maps $INGRESS_MAP_ID
Bash
복사
# eBPF dump-map에서 ingress_map 확인
ssh -i ~/.ssh/kp_node.pem ec2-user@$PublicN3 \
sudo /opt/cni/bin/aws-eks-na-cli ebpf dump-maps $AWS_CONNTRACK_MAP_ID
Bash
복사
# eBPF dump-map에서 aws_conntrack_map 확인
[demo-web] 02_allow_redns_red1_ingress 삭제
kubectl delete -f netpolicy/02_allow_redns_red1_ingress.yaml
Bash
복사
# 02.allow_redns_red1_ingress.yaml 삭제
[demo-web] 03_allow_redns_ingress 적용
cat netpolicy/03_allow_redns_ingress.yaml
Bash
복사
# 03_allow_redns_ingress.yaml 확인
kubectl apply -f netpolicy/03_allow_redns_ingress.yaml
Bash
복사
# 03_allow_redns_ingress.yaml 적용
[demo-web] 03_allow_redns_ingress 확인
kubectl get networkpolicy -n red
Bash
복사
# network policy 확인
ssh -i ~/.ssh/kp_node.pem ec2-user@$PublicN3 \
sudo /opt/cni/bin/aws-eks-na-cli ebpf dump-maps $INGRESS_MAP_ID
Bash
복사
# eBPF dump-map에서 ingress_map 확인
ssh -i ~/.ssh/kp_node.pem ec2-user@$PublicN3 \
sudo /opt/cni/bin/aws-eks-na-cli ebpf dump-maps $AWS_CONNTRACK_MAP_ID
Bash
복사
# eBPF dump-map에서 aws_conntrack_map 확인
[demo-web] 03_allow_redns_ingress 삭제
kubectl delete -f netpolicy/03_allow_redns_ingress.yaml
Bash
복사
# 03_allow_redns_ingress 삭제
[demo-web] 04_allow_bluens_blue2_ingress 적용
cat netpolicy/04_allow_bluens_blue2_ingress.yaml
Bash
복사
# 04_allow_bluens_blue2_ingress.yaml 확인
kubectl apply -f netpolicy/04_allow_bluens_blue2_ingress.yaml
Bash
복사
# 04_allow_bluens_blue2_ingress.yaml 적용
[demo-web] 04_allow_bluens_blue2_ingress 확인
kubectl get networkpolicy -n red
Bash
복사
# network policy 확인
ssh -i ~/.ssh/kp_node.pem ec2-user@$PublicN3 \
sudo /opt/cni/bin/aws-eks-na-cli ebpf dump-maps $INGRESS_MAP_ID
Bash
복사
# eBPF dump-map에서 ingress_map 확인
ssh -i ~/.ssh/kp_node.pem ec2-user@$PublicN3 \
sudo /opt/cni/bin/aws-eks-na-cli ebpf dump-maps $AWS_CONNTRACK_MAP_ID
Bash
복사
# eBPF dump-map에서 aws_conntrack_map 확인
[demo-web] 04_allow_bluens_blue2_ingress 삭제
kubectl delete -f netpolicy/04_allow_bluens_blue2_ingress.yaml
Bash
복사
# 04_allow_bluens_blue2_ingress.yaml 삭제
[demo-web] 05_deny_redns_red1_ingress 적용
cat netpolicy/05_deny_redns_red1_ingress.yaml
Bash
복사
# 05_deny_redns_red1_ingress.yaml 확인
kubectl apply -f netpolicy/05_deny_redns_red1_ingress.yaml
Bash
복사
# 05_deny_redns_red1_ingress.yaml 적용
[demo-web] 05_deny_redns_red1_ingress 확인
kubectl get networkpolicy -n red
Bash
복사
# network policy 확인
ssh -i ~/.ssh/kp_node.pem ec2-user@$PublicN3 \
sudo /opt/cni/bin/aws-eks-na-cli ebpf dump-maps $INGRESS_MAP_ID
Bash
복사
# eBPF dump-map에서 ingress_map 확인
ssh -i ~/.ssh/kp_node.pem ec2-user@$PublicN3 \
sudo /opt/cni/bin/aws-eks-na-cli ebpf dump-maps $AWS_CONNTRACK_MAP_ID
Bash
복사
# eBPF dump-map에서 aws_conntrack_map 확인
[demo-web] 05_deny_redns_red1_ingress 삭제
kubectl delete -f netpolicy/05_deny_redns_red1_ingress.yaml
Bash
복사
# 05_deny_redns_red1_ingress.yaml 삭제
파드별 모니터링(2)
while true; do \
kubectl exec -it red-1 -n red -- curl --connect-timeout 1 demo-web; date; \
kubectl exec -it red-1 -n red -- ip -4 addr | grep "192.168."; \
echo -e "\033[31mred-1\033[0m"; sleep 1; done
Bash
복사
# [신규 터미널1] red-1에서 demo-web으로 http 접근 및 IP 확인 (유지)
while true; do \
kubectl exec -it red-1 -n red -- nslookup google.com; date; \
kubectl exec -it red-1 -n red -- ip -4 addr | grep "192.168."; \
echo -e "\033[31mred-1\033[0m"; sleep 1; done
Bash
복사
# [신규 터미널2] red-2에서 red-1에서 google.com으로 nslookup
[red-1] 06_deny_all_egress_from_red1 적용
cat netpolicy/06_deny_all_egress_from_red1.yaml
Bash
복사
# 06_deny_all_egress_from_red1.yaml 확인
kubectl apply -f netpolicy/06_deny_all_egress_from_red1.yaml
Bash
복사
# 06_deny_all_egress_from_red1.yaml 적용
[red-1] 06_deny_all_egress_from_red1 확인
kubectl get networkpolicy -n red
Bash
복사
# network policy 확인
kubectl exec -it red-2 -n red -- curl ipinfo.io/ip ; echo
Bash
복사
# red-2에서 Egress 통신 확인
ssh -i ~/.ssh/kp_node.pem ec2-user@$PublicN1 sudo \
/opt/cni/bin/aws-eks-na-cli ebpf loaded-ebpfdata
Bash
복사
# eBPF 데이터 확인
N1_EG_MAP_ID=$(ssh -i ~/.ssh/kp_node.pem ec2-user@$PublicN1 sudo /opt/cni/bin/aws-eks-na-cli ebpf loaded-ebpfdata | \
awk '/Pod Identifier : red-red Direction : egress/ {p=1} p && /egress_map/ {getline; print $NF; exit}')
echo "Node1 - egress_map ID: $N1_EG_MAP_ID"
Bash
복사
# 노드1의 egress_map id 변수 선언
ssh -i ~/.ssh/kp_node.pem ec2-user@$PublicN1 \
sudo /opt/cni/bin/aws-eks-na-cli ebpf dump-maps $N1_EG_MAP_ID
Bash
복사
# eBPF dump-map에서 egress_map 확인
[red-1] 06_deny_all_egress_from_red1 삭제
kubectl delete -f netpolicy/06_deny_all_egress_from_red1.yaml
Bash
복사
# 06_deny_all_egress_from_red1.yaml 삭제
[red-1] 07_allow_dns_egress_from_red1 적용
cat netpolicy/07_allow_dns_egress_from_red1.yaml
Bash
복사
# 07_allow_dns_egress_from_red1.yaml 확인
kubectl apply -f netpolicy/07_allow_dns_egress_from_red1.yaml
Bash
복사
# 07_allow_dns_egress_from_red1.yaml 적용
[red-1] 07_allow_dns_egress_from_red1 확인
kubectl get networkpolicy -n red
Bash
복사
# network policy 확인
ssh -i ~/.ssh/kp_node.pem ec2-user@$PublicN1 \
sudo /opt/cni/bin/aws-eks-na-cli ebpf dump-maps $N1_EG_MAP_ID
Bash
복사
# eBPF dump-map에서 egress_map 확인
kubectl get pod -n kube-system -owide | grep core
Bash
복사
# coredns 파드의 IP 주소 확인
[red-1] 07_allow_dns_egress_from_red1 삭제
kubectl delete -f netpolicy/07_allow_dns_egress_from_red1.yaml
Bash
복사
# 07_allow_dns_egress_from_red1.yaml 삭제
4. 실습 환경 삭제
실습 환경 삭제와 Terraform 삭제 작업을 진행합니다.
4.1. 실습 자원 삭제
실습 애플리케이션 삭제
kubectl delete -f manifest/
Bash
복사
# 데모 애플리케이션 삭제
4.2. Terraform 삭제
Terraform 자원 삭제
nohup sh -c "terraform destroy -auto-approve" > delete.log 2>&1 &
Bash
복사
# terraform 자원 삭제
Warning:
nohup으로 백그라운드로 실행하도록 변경했습니다.
Terraform 삭제가 완료되면 정상적으로 자원 삭제 되었는지 확인을 합니다.(cat delete.log)
여기까지 2장의 첫 번째 실습인 “Amazon VPC CNI - Network Policy 구성하기” 실습을 마칩니다.
수고하셨습니다 :)