Home
home

2장 실습 - Amazon VPC CNI - Network Policy 구성하기

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 구성하기” 실습을 마칩니다.
수고하셨습니다 :)