이번 게시글은 가시다님의 AEWS [2기] 스터디 내용을 정리한 포스트 입니다.
이번 게시글은 첫 주차의 스터디 내용인 Amazon EKS 설치 및 기본 사용에 대해 정리합니다.
EKS의 구성 요소를 간단히 파악하고, 실제로 배포해 봅니다.
Amzaon EKS 개요
- Amazon EKS는 Kubernetes를 쉽게 실행할 수 있는 관리형 서비스입니다.[1]
- Kubernetes 클러스터는 컨트롤 플레인과 워커 노드로 구성되어 있습니다. EKS는 컨트롤 플레인을 여러 가용 영역에 인스턴스를 실행하여 고가용성을 보장하고, 지속적인 관리를 통해 비정상 적인 컨트롤 플레인 노드를 감지, 교체하며 자동화된 버전 업그레이드를 제공합니다.
- 오픈소스 Kubernetes 소프트웨어의 최신 버전을 사용하기에 Kubernetes에 사용되는 플러그인과 툴을 모두 사용할 수 있습니다.
- Kuberenetes의 버전은 x.y.z로 표기 됩니다. 여기서 x 는 메이저 버전, y 는 마이너 버전, z 는 패치 버전을 의미합니다. [2]
- Amazon EKS의 지원 버전은 AWS의 홈페이지에서 확인할 수 있습니다. [3]
- 다양한 Amazon 리소스와 병합하여 서비스를 운영할 수 있습니다.
- 컨테이너 이미지 저장소인 Amazon ECR(Elastic Container Registry)
- 로드 분산을 위한 AWS ELB(Elastic Load Balancing)
- 인증을 위한 AWS IAM
- 격리된 Amazon VPC
컨트롤 플레인 액세스 옵션
- Amazon EKS의 컨트롤 플레인 노드는 AWS가 관리 해줍니다(위 사진의 AWS VPC). 사용자는 워커 노드의 구성(위 사진의 Your VPC)을 진행합니다.
- Amazon EKS의 컨트롤 플레인은 사용자의 `kubectl` 도구를 통한 리소스 생성, 워커 노드와의 통신을 위해 원활한 네트워크 통신이 필요합니다.
- 사용자는 EKS의 엔드포인트(컨트롤 플레인의 API 주소)를 Public 혹은 Private으로 노출시킬 수 있습니다.(위 사진은 Public 노출)
- 사용자는 EKS의 엔드포인트 노출 구성을 Public, Public & Private, Private로 구성할 수 있습니다. [4]
- [엔드포인트의 Public 노출]
- 새 Amazon EKS 클러스터의 기본 동작입니다.
- 클러스터의 VPC 내에서 비롯된 Kubernetes API 요청(예: 컨트롤 플레인 통신에 대한 노드)은 VPC에서 벗어나지만 Amazon의 네트워크에서는 벗어나지 않습니다.
- 인터넷에서 클러스터 API 서버에 액세스할 수 있습니다. 선택적으로 퍼블릭 엔드포인트에 액세스할 수 있는 CIDR 블록을 제한할 수 있습니다. 특정 CIDR 블록에 대한 액세스를 제한하는 경우, 프라이빗 엔드포인트를 활성화하거나 지정된 CIDR 블록에 노드와 Fargate Pods(사용하는 경우)가 퍼블릭 엔드포인트에 액세스하는 주소를 포함합니다
- [엔드포인트의 Public & Private 노출]
- 클러스터의 VPC 내 Kubernetes API 요청(예: 컨트롤 플레인 통신에 대한 노드)은 프라이빗 VPC 엔드포인트를 사용합니다.
- 인터넷에서 클러스터 API 서버에 액세스할 수 있습니다. 선택적으로 퍼블릭 엔드포인트에 액세스할 수 있는 CIDR 블록을 제한할 수 있습니다.
- [엔드포인트의 Private 노출]
- 클러스터 API 서버에 대한 모든 트래픽은 클러스터의 VPC 또는 연결된 네트워크 내에서 비롯되어야 합니다.
- 인터넷에서 API 서버로 퍼블릭 액세스할 수 없습니다. 모든 kubectl 명령은 VPC 또는 연결된 네트워크 내에서 가져와야 합니다.
- 클러스터의 API 서버 엔드포인트는 퍼블릭 DNS 서버에 의해 VPC의 프라이빗 IP 주소로 확인됩니다. 이전에는 VPC 내에서만 엔드포인트를 확인할 수 있었습니다.
- 퍼블릭 액세스를 활성화한 다음 다시 비활성화합니다. 클러스터에 대해 한 번만 수행하면 엔드포인트가 해당 시점부터 프라이빗 IP 주소로 확인됩니다.
- 엔드포인트가 VPC 내부에서 기존 클러스터에 대한 프라이빗 IP 주소로 확인되지 않는 경우 다음을 수행할 수 있습니다.
Amazon EKS 배포
Step 1. 기본 인프라 배포하기
Amazon EKS는 콘솔 또는 eksctl 이라는 cmd 유틸리티 도구로 배포할 수 있습니다. 이번 실습에서는 eksctl 도구를 사용하여 배포합니다. 그 전에 eksctl을 사용할 수 있는 EC2 instance를 배포합니다. 링크를 클릭하면 AWS CloudFormation을 통해 EC2 Instance 및 VPC 기본 환경을 자동 구성 해줍니다.
- 링크를 클릭하여 CloudFormation으로 기본 인프라를 배포합니다.
- 스택 생성 단계에서 [다음]을 클릭합니다.
- ClusterBase Name은 EKS 클러스터의 이름입니다. KeyName은 EC2 Instance의 접속을 위한 SSH Key 이고, SgIngressSshCidr은 EC2 Instance의 SSH 접속 허용 IP주소 입니다. 본인의 공인 IP를 조회하여 알맞게 설정 합니다.
- SSH Key 생성은 AWS의 공식 문서를 참고합니다. [5]
- 나머지 옵션은 Default로 두고 [전송]을 클릭하여 CloudFormation을 통해 기본 인프라를 생성합니다. 생성이 완료되면 CloudFormation의 스택 메뉴의 출력 탭에서 EC2 Instance의 공인 IP 주소를 확인할 수 있습니다.
Step 2. EKS 클러스터 배포하기
- 아래 명령어를 통해 Local PC에서 EC2 Instance로 SSH 접속을 진행합니다.
#ssh -i "KeyName" ec2-user@"Public-IP"
ssh -i hj42700eks.pem ec2-user@15.165.74.55
- `aws configure` 명령을 통해 aws cmd를 사용 하기위한 인증 구성을 진행합니다. 실습 편의를 위해 `AdministratorAccess` 권한을 보유한 IAM User 및 Access Key를 발급하여 사용합니다. [6]
- IAM User의 Access Key의 노출은 항상 유의하시기 바랍니다.
- EC2 Instance의 기본 정보를 확인합니다.
# (옵션) cloud-init 실행 과정 로그 확인
tail -f /var/log/cloud-init-output.log
# 사용자 확인
whoami
# 기본 툴 및 SSH 키 설치 등 확인
kubectl version --client=true -o yaml | yh
eksctl version
aws --version
ls /root/.ssh/id_rsa*
# 도커 엔진 설치 확인
docker info
- eksctl 명령을 사용하기 위해 VPC 정보를 조회하여 서브넷 등의 항목을 환경 변수로 저장합니다.
# EKS 배포할 VPC 정보 확인
aws ec2 describe-vpcs --filters "Name=tag:Name,Values=$CLUSTER_NAME-VPC" | jq
aws ec2 describe-vpcs --filters "Name=tag:Name,Values=$CLUSTER_NAME-VPC" | jq Vpcs[]
aws ec2 describe-vpcs --filters "Name=tag:Name,Values=$CLUSTER_NAME-VPC" | jq Vpcs[].VpcId
aws ec2 describe-vpcs --filters "Name=tag:Name,Values=$CLUSTER_NAME-VPC" | jq -r .Vpcs[].VpcId
export VPCID=$(aws ec2 describe-vpcs --filters "Name=tag:Name,Values=$CLUSTER_NAME-VPC" | jq -r .Vpcs[].VpcId)
echo "export VPCID=$VPCID" >> /etc/profile
echo $VPCID
# EKS 배포할 VPC에 속한 Subnet 정보 확인
aws ec2 describe-subnets --filters "Name=vpc-id,Values=$VPCID" --output json | jq
aws ec2 describe-subnets --filters "Name=vpc-id,Values=$VPCID" --output yaml
## 퍼블릭 서브넷 ID 확인
aws ec2 describe-subnets --filters Name=tag:Name,Values="$CLUSTER_NAME-PublicSubnet1" | jq
aws ec2 describe-subnets --filters Name=tag:Name,Values="$CLUSTER_NAME-PublicSubnet1" --query "Subnets[0].[SubnetId]" --output text
export PubSubnet1=$(aws ec2 describe-subnets --filters Name=tag:Name,Values="$CLUSTER_NAME-PublicSubnet1" --query "Subnets[0].[SubnetId]" --output text)
export PubSubnet2=$(aws ec2 describe-subnets --filters Name=tag:Name,Values="$CLUSTER_NAME-PublicSubnet2" --query "Subnets[0].[SubnetId]" --output text)
echo "export PubSubnet1=$PubSubnet1" >> /etc/profile
echo "export PubSubnet2=$PubSubnet2" >> /etc/profile
echo $PubSubnet1
echo $PubSubnet2
- 아래 명령을 통해 EKS 클러스터를 생성합니다.
# 변수 확인
echo $AWS_DEFAULT_REGION
echo $CLUSTER_NAME
echo $VPCID
echo $PubSubnet1,$PubSubnet2
# eks 클러스터 & 관리형노드그룹 배포: 총 15분 소요
eksctl create cluster --name $CLUSTER_NAME --region=$AWS_DEFAULT_REGION --nodegroup-name=$CLUSTER_NAME-nodegroup --node-type=t3.medium \
--node-volume-size=30 --vpc-public-subnets "$PubSubnet1,$PubSubnet2" --version 1.28 --ssh-access --external-dns-access --verbose 4
- AWS 콘솔의 Elastic Kubernetes Service 메뉴에 클러스터가 생성되고, 엔드포인트 노출은 기본 설정값인 Public인 것을 확인 할 수 있습니다.
- 아래의 명령어로 EKS 정보를 확인 해봅니다.
# eks 클러스터 정보 확인
(hakjunadmin@myeks:N/A) [root@myeks-host ~]# kubectl cluster-info
Kubernetes control plane is running at https://{###}.gr7.ap-northeast-2.eks.amazonaws.com
CoreDNS is running at https://{###}.gr7.ap-northeast-2.eks.amazonaws.com/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
# eks 노드 그룹 정보 확인
(hakjunadmin@myeks:N/A) [root@myeks-host ~]# eksctl get nodegroup --cluster $CLUSTER_NAME --name $CLUSTER_NAME-nodegroup
CLUSTER NODEGROUP STATUS CREATED MIN SIZE MAX SIZE DESIRED CAPACITY INSTANCE TYPE IMAGE ID ASG NAME TYPE
myeks myeks-nodegroup ACTIVE 2024-03-09T12:00:43Z 2 2 2 t3.medium AL2_x86_64 eks-myeks-nodegroup-fac7118b-1492-ea7c-8aa8-e964b52035cb managed
(hakjunadmin@myeks:N/A) [root@myeks-host ~]# aws eks describe-nodegroup --cluster-name $CLUSTER_NAME --nodegroup-name $CLUSTER_NAME-nodegroup | jq
# 노드의 capacityType 확인
(hakjunadmin@myeks:N/A) [root@myeks-host ~]# kubectl get node --label-columns=eks.amazonaws.com/capacityType
NAME STATUS ROLES AGE VERSION CAPACITYTYPE
ip-192-168-1-162.ap-northeast-2.compute.internal Ready <none> 9m22s v1.28.5-eks-5e0fdde ON_DEMAND
ip-192-168-2-116.ap-northeast-2.compute.internal Ready <none> 9m23s v1.28.5-eks-5e0fdde ON_DEMAND
# 파드 정보 확인 : 온프레미스 쿠버네티스의 파드 배치와 다른점은? , 파드의 IP의 특징이 어떤가요? 자세한 네트워크는 2주차에서 다룸
(hakjunadmin@myeks:N/A) [root@myeks-host ~]# kubectl get pod -n kube-system
NAME READY STATUS RESTARTS AGE
aws-node-d5k2n 2/2 Running 0 10m
aws-node-dxsm6 2/2 Running 0 10m
coredns-56dfff779f-jgnq6 1/1 Running 0 15m
coredns-56dfff779f-rk6rt 1/1 Running 0 15m
kube-proxy-dt88k 1/1 Running 0 10m
kube-proxy-ndb66 1/1 Running 0 10m
# 모든 파드의 컨테이너 이미지 정보 확인
(hakjunadmin@myeks:N/A) [root@myeks-host ~]# kubectl get pods --all-namespaces -o jsonpath="{.items[*].spec.containers[*].image}" | tr -s '[[:space:]]' '\n' | sort | uniq -c
2 602401143452.dkr.ecr.ap-northeast-2.amazonaws.com/amazon/aws-network-policy-agent:v1.0.4-eksbuild.1
2 602401143452.dkr.ecr.ap-northeast-2.amazonaws.com/amazon-k8s-cni:v1.15.1-eksbuild.1
2 602401143452.dkr.ecr.ap-northeast-2.amazonaws.com/eks/coredns:v1.10.1-eksbuild.4
2 602401143452.dkr.ecr.ap-northeast-2.amazonaws.com/eks/kube-proxy:v1.28.2-minimal-eksbuild.2
- 아래의 명령어로 워커 노드의 정보를 확인해 봅니다.
- 워커 노드 SSH 접속
```bash
# 노드 IP 확인 및 PrivateIP 변수 지정
aws ec2 describe-instances --query "Reservations[*].Instances[*].{PublicIPAdd:PublicIpAddress,PrivateIPAdd:PrivateIpAddress,InstanceName:Tags[?Key=='Name']|[0].Value,Status:State.Name}" --filters Name=instance-state-name,Values=running --output table
kubectl get node --label-columns=topology.kubernetes.io/zone
kubectl get node --label-columns=topology.kubernetes.io/zone --selector=topology.kubernetes.io/zone=ap-northeast-2a
kubectl get node --label-columns=topology.kubernetes.io/zone --selector=topology.kubernetes.io/zone=ap-northeast-2c
**N1=$(**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})
**N2=$**(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 $N1, $N2
echo "export N1=$N1" >> /etc/profile
echo "export N2=$N2" >> /etc/profile
# eksctl-host 에서 노드의IP나 coredns 파드IP로 ping 테스트
ping <IP>
ping -c 1 $N1
ping -c 1 $N2
# 노드 보안그룹 ID 확인
aws ec2 describe-security-groups --filters Name=group-name,Values=*nodegroup* --query "SecurityGroups[*].[GroupId]" --output text
NGSGID=$(aws ec2 describe-security-groups --filters Name=group-name,Values=*nodegroup* --query "SecurityGroups[*].[GroupId]" --output text)
echo $NGSGID
echo "export NGSGID=$NGSGID" >> /etc/profile
# 노드 보안그룹에 eksctl-host 에서 노드(파드)에 접속 가능하게 룰(Rule) 추가 설정
aws ec2 authorize-security-group-ingress --group-id $NGSGID --protocol '-1' --cidr **192.168.1.100/32**
# eksctl-host 에서 노드의IP나 coredns 파드IP로 ping 테스트
ping -c 2 $N1
ping -c 2 $N2
# 워커 노드 SSH 접속
**ssh -i ~/.ssh/id_rsa ec2-user@$N1 hostname
ssh -i ~/.ssh/id_rsa ec2-user@$N2 hostname**
**ssh ec2-user@$N1
exit**
**ssh ec2-user@$N2
exit**
```
- 노드의 네트워크 정보 확인
# AWS VPC CNI 사용 확인
(hakjunadmin@myeks:N/A) [root@myeks-host ~]# kubectl -n kube-system get ds aws-node
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
aws-node 2 2 2 2 2 <none> 24m
(hakjunadmin@myeks:N/A) [root@myeks-host ~]# kubectl describe daemonset aws-node --namespace kube-system | grep Image | cut -d "/" -f 2
amazon-k8s-cni-init:v1.15.1-eksbuild.1
amazon-k8s-cni:v1.15.1-eksbuild.1
amazon
# 파드 IP 확인
(hakjunadmin@myeks:N/A) [root@myeks-host ~]# kubectl get pod -n kube-system -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
aws-node-d5k2n 2/2 Running 0 18m 192.168.2.116 ip-192-168-2-116.ap-northeast-2.compute.internal <none> <none>
aws-node-dxsm6 2/2 Running 0 18m 192.168.1.162 ip-192-168-1-162.ap-northeast-2.compute.internal <none> <none>
coredns-56dfff779f-jgnq6 1/1 Running 0 24m 192.168.2.10 ip-192-168-2-116.ap-northeast-2.compute.internal <none> <none>
coredns-56dfff779f-rk6rt 1/1 Running 0 24m 192.168.2.90 ip-192-168-2-116.ap-northeast-2.compute.internal <none> <none>
kube-proxy-dt88k 1/1 Running 0 18m 192.168.1.162 ip-192-168-1-162.ap-northeast-2.compute.internal <none> <none>
kube-proxy-ndb66 1/1 Running 0 18m 192.168.2.116 ip-192-168-2-116.ap-northeast-2.compute.internal <none> <none>
(hakjunadmin@myeks:N/A) [root@myeks-host ~]# kubectl get pod -n kube-system -l k8s-app=kube-dns -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
coredns-56dfff779f-jgnq6 1/1 Running 0 24m 192.168.2.10 ip-192-168-2-116.ap-northeast-2.compute.internal <none> <none>
coredns-56dfff779f-rk6rt 1/1 Running 0 24m 192.168.2.90 ip-192-168-2-116.ap-northeast-2.compute.internal <none> <none>
# 노드 정보 확인
(hakjunadmin@myeks:N/A) [root@myeks-host ~]# for i in $N1 $N2; do echo ">> node $i <<"; ssh ec2-user@$i hostname; echo; done
>> node 192.168.1.162 <<
ip-192-168-1-162.ap-northeast-2.compute.internal
>> node 192.168.2.116 <<
ip-192-168-2-116.ap-northeast-2.compute.internal
- 노드의 cgroup version 확인
(hakjunadmin@myeks:N/A) [root@myeks-host ~]# for i in $N1 $N2; do echo ">> node $i <<"; ssh ec2-user@$i stat -fc %T /sys/fs/cgroup/; echo; done
>> node 192.168.1.162 <<
tmpfs
>> node 192.168.2.116 <<
tmpfs
- 노드의 process 정보 확인
for i in $N1 $N2; do echo ">> node $i <<"; ssh ec2-user@$i sudo systemctl status kubelet; echo; done
for i in $N1 $N2; do echo ">> node $i <<"; ssh ec2-user@$i sudo pstree; echo; done
for i in $N1 $N2; do echo ">> node $i <<"; ssh ec2-user@$i ps afxuwww; echo; done
for i in $N1 $N2; do echo ">> node $i <<"; ssh ec2-user@$i ps axf |grep /usr/bin/containerd; echo; done
for i in $N1 $N2; do echo ">> node $i <<"; ssh ec2-user@$i ls /etc/kubernetes/manifests/; echo; done
for i in $N1 $N2; do echo ">> node $i <<"; ssh ec2-user@$i ls /etc/kubernetes/kubelet/; echo; done
for i in $N1 $N2; do echo ">> node $i <<"; ssh ec2-user@$i cat /etc/kubernetes/kubelet/kubelet-config.json; echo; done
- 노드의 스토리지 정보 확인
(hakjunadmin@myeks:N/A) [root@myeks-host ~]# for i in $N1 $N2; do echo ">> node $i <<"; ssh ec2-user@$i lsblk; echo; done
>> node 192.168.1.162 <<
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
nvme0n1 259:0 0 30G 0 disk
├─nvme0n1p1 259:1 0 30G 0 part /
└─nvme0n1p128 259:2 0 1M 0 part
>> node 192.168.2.116 <<
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
nvme0n1 259:0 0 30G 0 disk
├─nvme0n1p1 259:1 0 30G 0 part /
└─nvme0n1p128 259:2 0 1M 0 part
- [중요] AWS 콘솔의 EC2 좌측 메뉴의 네트워크 인터페이스 메뉴에 접근 해 보면 설명 란에 ControlPlaneSecurityGroup을 사용하는 ENI를 확인할 수 있습니다. 특이한 부분은 ENI의 소유자와 요청자, 인스턴스 소유자가 다르다는 점 입니다. 이는 AWS에서 관리하는 영역인 ControlPlane과, 사용자의 워커 노드(Data Plane)와의 VPC 영역이 다르기에 이 둘을 연결하는 역할을 담당하는 네트워크 인터페이스 이기 때문에 네트워크 인터페이스의 소유는 본인으로 조회되지만, 요청자와 인스턴스 소유자는 다른 계정ID로 조회 됩니다.
Step 3. 간단한 Application 배포하기
- 아래 코드를 통해 마리오 게임을 Deployment 방식의 Pod로 배포하고, Loadbalancer Type의 서비스를 배포하여 외부에서 접근 가능하게 구성합니다.
# 수퍼마리오 디플로이먼트 배포
(hakjunadmin@myeks:N/A) [root@myeks-host ~]# curl -s -O https://raw.githubusercontent.com/gasida/PKOS/main/1/mario.yaml
(hakjunadmin@myeks:N/A) [root@myeks-host ~]# kubectl apply -f mario.yaml
deployment.apps/mario created
service/mario created
(hakjunadmin@myeks:N/A) [root@myeks-host ~]# cat mario.yaml | yh
apiVersion: apps/v1
kind: Deployment
metadata:
name: mario
labels:
app: mario
spec:
replicas: 1
selector:
matchLabels:
app: mario
template:
metadata:
labels:
app: mario
spec:
containers:
- name: mario
image: pengbai/docker-supermario
---
apiVersion: v1
kind: Service
metadata:
name: mario
spec:
selector:
app: mario
ports:
- port: 80
protocol: TCP
targetPort: 8080
type: LoadBalancer
(hakjunadmin@myeks:N/A) [root@myeks-host ~]# # 배포 확인 : CLB 배포 확인
(hakjunadmin@myeks:N/A) [root@myeks-host ~]# kubectl get deploy,svc,ep mario
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/mario 1/1 1 1 2m12s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/mario LoadBalancer 10.100.34.134 a10e0eaddcca9410db58510915b39df7-1509411198.ap-northeast-2.elb.amazonaws.com 80:32242/TCP 2m12s
NAME ENDPOINTS AGE
endpoints/mario 192.168.1.228:8080 2m12s
# 마리오 게임 접속 : CLB 주소로 웹 접속
(hakjunadmin@myeks:N/A) [root@myeks-host ~]# kubectl get svc mario -o jsonpath={.status.loadBalancer.ingress[0].hostname} | awk '{ print "Mario URL = http://"$1 }'
Mario URL = http://a10e0eaddcca9410db58510915b39df7-1509411198.ap-northeast-2.elb.amazonaws.com
- CLB 주소를 웹 브라우저에 입력하여 접근이 잘 되는지 확인합니다.
Step 4. 삭제하기
- 아래 명령을 통해 EKS 클러스터를 삭제합니다.
eksctl delete cluster --name $CLUSTER_NAME
- 아래 명령을 통해 CloudFormation 스택을 삭제합니다.
aws cloudformation delete-stack --stack-name myeks
[2] : https://kubernetes.io/ko/releases/version-skew-policy/
[3] : https://docs.aws.amazon.com/ko_kr/eks/latest/userguide/kubernetes-versions.html
[4] : https://docs.aws.amazon.com/ko_kr/eks/latest/userguide/cluster-endpoint.html
[5] : https://docs.aws.amazon.com/ko_kr/AWSEC2/latest/UserGuide/create-key-pairs.html
'클라우드' 카테고리의 다른 글
[EKS] Storage & NodeGroup (0) | 2024.03.23 |
---|---|
[EKS] Networking (0) | 2024.03.14 |
[k8s] Pod의 안정적인 유지 - liveness probe (0) | 2023.10.22 |
[devops] Argo project로 CI/CD Pipeline 구현하기 (0) | 2023.07.26 |
[Docker] Docker-Compose (0) | 2023.07.14 |