Multus CNI를 사용하면 Kubernetes의 파드에 여러 네트워크 인터페이스를 연결할 수 있다.
node.k8s.amazonaws.com/no_manage
으로 네트워크 인터페이스에 태그를 지정해야 한다.git clone https://github.com/aws-samples/eks-install-guide-for-multus
관리자 권한으로 AWS 콘솔에 로그인하고 Cloudformation 메뉴로 이동
스택 생성, 새 리소스 사용(표준) 선택
템플릿 파일 업로드: eks-install-guide-for-multus/cfn/templates/infra/eks-infra.yaml
스택 이름 입력: eks-multus-cluster
기본 VPC CIDR(10.0.0.0/16) 블록 및 서브넷 범위 사용
2개의 availability zone 선택
베스천 인스턴스 유형 선택
EC2 키 페어 이름 선택
나머지는 기본 값으로 유지한 채 [다음] 클릭, 아래 부분 승인 체크 후 [스택생성]
CloudFormation 스택이 완료될 때까지 기다린다. (다소 시간이 소요될 수 있음)
총 2개의 퍼블릭 및 프라이빗 EKS 서브넷, 4개의 Multus 서브넷(AZ당 2개), EKS 클러스터, IGW 및 NAT-GW가 있는 Amazon VPC가 생성된다. 또한 Multus 서브넷 및 컨트롤 플레인 보안 그룹에 대한 보안 그룹도 생성된다.
'eks-multus-cluster'라는 스택에 대한 CloudFormation 콘솔 출력 값을 확인한다. 특히 BastionPublicIp는 다음 섹션에서 필요한 IP이므로 기록해두자.
curl -o kubectl https://amazon-eks.s3-us-west-2.amazonaws.com/1.21.2/2021-07-05/bin/linux/amd64/kubectl curl -o kubectl.sha256 https://amazon-eks.s3.us-west-2.amazonaws.com/1.21.2/2021-07-05/bin/linux/amd64/kubectl.sha256 openssl sha1 -sha256 kubectl chmod +x ./kubectl mkdir -p $HOME/bin && cp ./kubectl $HOME/bin/kubectl && export PATH=$PATH:$HOME/bin echo 'export PATH=$PATH:$HOME/bin' >> ~/.bashrc kubectl version —short —client
aws eks update-kubeconfig --name eks-multus-cluster
kubectl get svc
관리자 권한으로 AWS 콘솔에 로그인하고 Cloudformation 메뉴로 이동
스택 생성, 새 리소스 사용(표준) 선택
템플릿 파일 업로드: eks-install-guide-for-multus/cfn/templates/node-group/eks-nodegroup-multus.yaml
스택 이름 지정: multus-cluster-ng01
1단계에서 생성했던 EKS ClusterName(eks-multus-cluster
) 입력 및 ClusterControlPlaneSecurityGroup(eks-multus-cluster-EksControlSecurityGroup-xxxx
형태) 선택
NodeGroupName 입력: multus-cluster-ng01
노드 Autoscaling 그룹 원하는 용량, 최대 및 최소 크기에 대해 1
지정
인스턴스 유형으로 c5.large
를 선택하고 볼륨 크기로 20
선택
1단계에서 사용한 키 페어 네임 선택
VPC ID(vpc-eks-multus-cluster
) 및 Subnet(privateAz1-eks-multus-cluster
) 선택
MultusSubnets(multus1Az1-eks-multus-cluster
, multus2Az1-eks-multus-cluster
) 선택
MultusSecurityGroups(eks-multus-cluster-MultusSecurityGroup*
) 선택
LambdaS3Bucket(이전에 생성한 S3 버킷명) 및 LambdaS3Key(lambda_function.zip
) 입력
다음 → I Acknowledge → 스택 생성 클릭
CloudFormation 스택이 완료될 때까지 기다린다.
정의된 Multus 서브넷에서 ENI를 연결하기 위해 노드 그룹 스택은 AWS Lambda 함수와 Amazon CloudWatch 이벤트 규칙을 배포한다. 스택은 no_manage: true
태그와 함께 Multus 서브넷에서 연결된 ENI로 EC2 인스턴스를 시작한다.
AWS VPC CNI는 ENI의 태그가 지정된 no_manage: true
를 관리하지 않는다. 이것은 Multus가 파드에 대한 추가 네트워크를 관리하기 위한 필수 단계이다.
스택이 완료되면 출력에서 NodeInstanceRole 값을 기록해둔다.
curl -o aws-auth-cm.yaml https://s3.us-west-2.amazonaws.com/amazon-eks/cloudformation/2020-10-29/aws-auth-cm.yaml
kubectl apply -f aws-auth-cm.yaml
kubectl get nodes --watch
다음 명령을 실행하여 Multus 데몬셋 다운로드 및 설치
kubectl apply -f https://raw.githubusercontent.com/aws/amazon-vpc-cni-k8s/master/config/multus/v3.7.2-eksbuild.1/aws-k8s-multus.yaml
다음 명령을 실행하여 배포된 내용 확인
kubectl get pods -n kube-system
각 노드에는 kube-multus-ds라는 하나의 파드가 있어야 한다.
cat <<EOF | kubectl apply -f -
apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
name: ipvlan-conf-1
spec:
config: '{
"cniVersion": "0.3.0",
"type": "ipvlan",
"master": "eth1",
"mode": "l3",
"ipam": {
"type": "host-local",
"subnet": "10.0.4.0/24",
"rangeStart": "10.0.4.70",
"rangeEnd": "10.0.4.80",
"gateway": "10.0.4.1"
}
}'
EOF
cat <<EOF | kubectl apply -f -
apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
name: ipvlan-conf-2
spec:
config: '{
"cniVersion": "0.3.0",
"type": "ipvlan",
"master": "eth2",
"mode": "l3",
"ipam": {
"type": "host-local",
"subnet": "10.0.6.0/24",
"rangeStart": "10.0.6.70",
"rangeEnd": "10.0.6.80",
"gateway": "10.0.6.1"
}
}'
EOF
kubectl describe network-attachment-definitions
[ec2-user@ip-10-0-0-188 ~]$ kubectl describe network-attachment-definitions
Name: ipvlan-conf-1
Namespace: default
Labels: <none>
Annotations: <none>
API Version: k8s.cni.cncf.io/v1
Kind: NetworkAttachmentDefinition
Metadata:
Creation Timestamp: 2022-03-01T08:30:03Z
Generation: 1
Managed Fields:
API Version: k8s.cni.cncf.io/v1
Fields Type: FieldsV1
fieldsV1:
f:metadata:
f:annotations:
.:
f:kubectl.kubernetes.io/last-applied-configuration:
f:spec:
.:
f:config:
Manager: kubectl-client-side-apply
Operation: Update
Time: 2022-03-01T08:30:03Z
Resource Version: 7916
UID: 0a07351d-1e49-4e25-a70c-88f089dc5a7f
Spec:
Config: { "cniVersion": "0.3.0", "type": "ipvlan", "master": "eth1", "mode": "l3", "ipam": { "type": "host-local", "subnet": "10.0.4.0/24", "rangeStart": "10.0.4.70", "rangeEnd": "10.0.4.80", "gateway": "10.0.4.1" } }
Events: <none>
Name: ipvlan-conf-2
Namespace: default
Labels: <none>
Annotations: <none>
API Version: k8s.cni.cncf.io/v1
Kind: NetworkAttachmentDefinition
Metadata:
Creation Timestamp: 2022-03-01T08:31:09Z
Generation: 1
Managed Fields:
API Version: k8s.cni.cncf.io/v1
Fields Type: FieldsV1
fieldsV1:
f:metadata:
f:annotations:
.:
f:kubectl.kubernetes.io/last-applied-configuration:
f:spec:
.:
f:config:
Manager: kubectl-client-side-apply
Operation: Update
Time: 2022-03-01T08:31:09Z
Resource Version: 8061
UID: f5673daf-0c0b-4c8b-9c5c-ea923c17b896
Spec:
Config: { "cniVersion": "0.3.0", "type": "ipvlan", "master": "eth2", "mode": "l3", "ipam": { "type": "host-local", "subnet": "10.0.6.0/24", "rangeStart": "10.0.6.70", "rangeEnd": "10.0.6.80", "gateway": "10.0.6.1" } }
Events: <none>
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: sampleapp-1
annotations:
k8s.v1.cni.cncf.io/networks: ipvlan-conf-1
spec:
containers:
- name: multitool
command: ["sh", "-c", "trap : TERM INT; sleep infinity & wait"]
image: praqma/network-multitool
EOF
kubectl exec -it sampleapp-1 -- ip -d address
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: sampleapp-dual
annotations:
k8s.v1.cni.cncf.io/networks: ipvlan-conf-1, ipvlan-conf-2
spec:
containers:
- name: multitool
command: ["sh", "-c", "trap : TERM INT; sleep infinity & wait"]
image: praqma/network-multitool
EOF
파드 네트워크 확인: kubectl exec -it sampleapp-dual -- ip -d address
Multus 인터페이스에 대한 파드 간의 연결 테스트: kubectl exec -it sampleapp-dual -- ping -I net1 <sampleapp-net1-ipaddress>
향후 요금이 발생하지 않도록 CloudFormation 서비스를 사용하여 생성된 모든 리소스를 삭제한다. CloudFormation으로 이동하여 생성한 두 개의 스택을 하나씩 삭제한다.
추가로 앞서 생성한 S3 버킷도 함께 삭제한다.