2023년 3월 6일부터 @cloudnet study를 시작 하였다.
[24단계 실습으로 정복하는 쿠버네티스][이정훈 지음]의 책을 기본으로 학습을 한다.
운영을 하면서도 부족한 부분을 배울 수 있을 것이란 기대감과 함께 시작한 수업이나 숙제를 하지 못해서 발생하는 불상사를 경험하지 않고 5주간의 스터디를 잘 마무리 했으면 좋겠다.
1주차 스터디 내용을 정리해 본다.
시작하기에 앞서 사용하게 될 솔루션에 대해서 정리해본다
kops-new-ec2.yaml(cloudformation 설정 파일)
Parameters:
KeyName:
Description: Name of an existing EC2 KeyPair to enable SSH access to the instances. Linked to AWS Parameter
Type: AWS::EC2::KeyPair::KeyName
ConstraintDescription: must be the name of an existing EC2 KeyPair.
SgIngressSshCidr:
Description: The IP address range that can be used to communicate to the EC2 instances
Type: String
MinLength: '9'
MaxLength: '18'
Default: 0.0.0.0/0
AllowedPattern: (\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/(\d{1,2})
ConstraintDescription: must be a valid IP CIDR range of the form x.x.x.x/x.
LatestAmiId:
Description: (DO NOT CHANGE)
Type: 'AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>'
Default: '/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2'
AllowedValues:
- /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2
Resources:
MyVPC:
Type: AWS::EC2::VPC
Properties:
EnableDnsSupport: true
EnableDnsHostnames: true
CidrBlock: 10.0.0.0/16
Tags:
- Key: Name
Value: My-VPC
MyIGW:
Type: AWS::EC2::InternetGateway
Properties:
Tags:
- Key: Name
Value: My-IGW
MyIGWAttachment:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
InternetGatewayId: !Ref MyIGW
VpcId: !Ref MyVPC
MyPublicRT:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref MyVPC
Tags:
- Key: Name
Value: My-Public-RT
DefaultPublicRoute:
Type: AWS::EC2::Route
DependsOn: MyIGWAttachment
Properties:
RouteTableId: !Ref MyPublicRT
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !Ref MyIGW
MyPublicSN:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref MyVPC
AvailabilityZone: !Select [ 0, !GetAZs '' ]
CidrBlock: 10.0.0.0/24
Tags:
- Key: Name
Value: My-Public-SN
MyPublicSNRouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId: !Ref MyPublicRT
SubnetId: !Ref MyPublicSN
KOPSEC2SG:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: kops ec2 Security Group
VpcId: !Ref MyVPC
Tags:
- Key: Name
Value: KOPS-EC2-SG
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: '22'
ToPort: '22'
CidrIp: !Ref SgIngressSshCidr
KOPSEC2:
Type: AWS::EC2::Instance
Properties:
InstanceType: t2.micro
ImageId: !Ref LatestAmiId
KeyName: !Ref KeyName
Tags:
- Key: Name
Value: kops-ec2
NetworkInterfaces:
- DeviceIndex: 0
SubnetId: !Ref MyPublicSN
GroupSet:
- !Ref KOPSEC2SG
AssociatePublicIpAddress: true
PrivateIpAddress: 10.0.0.10
UserData:
Fn::Base64:
!Sub |
#!/bin/bash
hostnamectl --static set-hostname kops-ec2
# Change Timezone
ln -sf /usr/share/zoneinfo/Asia/Seoul /etc/localtime
# Install Packages
cd /root
yum -y install tree jq git htop
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
curl -Lo kops https://github.com/kubernetes/kops/releases/download/$(curl -s https://api.github.com/repos/kubernetes/kops/releases/latest | grep tag_name | cut -d '"' -f 4)/kops-linux-amd64
chmod +x kops
mv kops /usr/local/bin/kops
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install
export PATH=/usr/local/bin:$PATH
source ~/.bash_profile
complete -C '/usr/local/bin/aws_completer' aws
ssh-keygen -t rsa -N "" -f /root/.ssh/id_rsa
echo 'alias vi=vim' >> /etc/profile
echo 'sudo su -' >> /home/ec2-user/.bashrc
curl -s https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash
wget https://github.com/andreazorzetto/yh/releases/download/v0.4.0/yh-linux-amd64.zip
unzip yh-linux-amd64.zip
mv yh /usr/local/bin/
Outputs:
KopsEC2IP:
Value: !GetAtt KOPSEC2.PublicIp
Cli를 통한 배포
# yaml 파일 다운로드
curl -O https://s3.ap-northeast-2.amazonaws.com/cloudformation.cloudneta.net/K8S/kops-new-ec2.yaml
# 배포
# aws cloudformation deploy --template-file ~/Downloads/kops-new-ec2.yaml --stack-name mykops --parameter-overrides KeyName=<My SSH Keyname> SgIngressSshCidr=<My Home Public IP Address>/32 --region <리전>
예시) aws cloudformation deploy --template-file ~/Downloads/**kops-new-ec2.yaml** --stack-name **mykops** --parameter-overrides KeyName=**kp-gasida** SgIngressSshCidr=$(curl -s ipinfo.io/ip)/32 --region ap-northeast-2
# CloudFormation 스택 배포 완료 후 EC2 IP 출력
aws cloudformation describe-stacks --stack-name **mykops** --query 'Stacks[*].Outputs[*].OutputValue' --output text
예시) 3.35.137.31
# kOps-ec2 에 SSH 접속
예시) ssh -i <My SSH Keyfile> ec2-user@3.35.137.31
ssh -i ~/.ssh/kp-gasida.pem ec2-user@$(aws cloudformation describe-stacks --stack-name mykops --query 'Stacks[*].Outputs[0].OutputValue' --output text)
AWS Console를 활용한 배포
- 스택 이름, KeyName등을 설정 한 후 진행
- 기타 페이지에서 다음을 누른 후 “전송” 버튼을 클릭 하면 스택 생성 및 작업 진행
- 기본 인스턴 스 생성 및 ssh 접속 테스트 진행
- 기본 인프라가 정상적으로 배포 된 것을 확인 할 수 있다.
aws cli 페이지 출력 옵셔
export AWS_PAGER=""
리소스를 배치할 리전 설정
REGION=ap-northeast-2 #서울
k8s 설정 파일 저장 할 s3 버킷 생성
#k8s 설정 파일이 저장 될 버킷 생성
aws s3 mb s3://버킷<유일한 이름> -- region $REGION
ex) aws s3 mb s3://louis-s3-kops --region ap-northeast-2
#s3 버킷 생성 확인
aws s3 ls
2023-03-05 20:17:34 louis-s3-kops
배포시 필요한 정보들을 환경 변수로 저장해서 배포의 용의성을 확보
export AWS_PAGER=""
export REGION=ap-northeast-2
export KOPS_CLUSTER_NAME=hj-devstory.kr
export KOPS_STATE_STORE=s3://louis-s3-kops
echo 'export AWS_PAGER=""' >>~/.bashrc
echo 'export REGION=ap-northeast-2' >>~/.bashrc
echo 'export KOPS_CLUSTER_NAME=hj-devstory.kr' >>~/.bashrc
echo 'export KOPS_STATE_STORE=s3://louis-s3-kops' >>~/.bashrc
kops 설정 파일 생성(s3) 및 k8s 클러스터 배포 : 6분 정도 소요
kops create cluster --zones="$REGION"a,"$REGION"c --networking amazonvpc --cloud aws \
--master-size t3.medium --node-size t3.medium --node-count=2 --network-cidr 172.30.0.0/16 \
--ssh-public-key ~/.ssh/id_rsa.pub --name=$KOPS_CLUSTER_NAME --kubernetes-version "1.24.10" -y
[root@kops-ec2 ~]# kops create cluster --zones="$REGION"a,"$REGION"c --networking amazonvpc --cloud aws \
> --master-size t3.medium --node-size t3.medium --node-count=2 --network-cidr 172.30.0.0/16 \
> --ssh-public-key ~/.ssh/id_rsa.pub --name=$KOPS_CLUSTER_NAME --kubernetes-version "1.24.10" -y
I0311 16:27:48.291376 25662 create_cluster.go:831] Using SSH public key: /root/.ssh/id_rsa.pub
I0311 16:27:48.703940 25662 new_cluster.go:1279] Cloud Provider ID = aws
I0311 16:27:48.795056 25662 subnets.go:185] Assigned CIDR 172.30.32.0/19 to subnet ap-northeast-2a
I0311 16:27:48.795193 25662 subnets.go:185] Assigned CIDR 172.30.64.0/19 to subnet ap-northeast-2c
-------
I0311 16:28:03.411631 25662 keypair.go:225] Issuing new certificate: "service-account"
I0311 16:28:06.446286 25662 executor.go:111] Tasks: 48 done / 103 total; 21 can run
I0311 16:28:07.282448 25662 executor.go:111] Tasks: 69 done / 103 total; 28 can run
W0311 16:28:08.822981 25662 retry_handler.go:99] Got RequestLimitExceeded error on AWS request (ec2::AuthorizeSecurityGroupIngress)
I0311 16:28:10.051442 25662 executor.go:111] Tasks: 97 done / 103 total; 3 can run
I0311 16:28:10.973689 25662 executor.go:155] No progress made, sleeping before retrying 3 task(s)
I0311 16:28:20.974088 25662 executor.go:111] Tasks: 97 done / 103 total; 3 can run
I0311 16:28:22.180002 25662 executor.go:111] Tasks: 100 done / 103 total; 3 can run
I0311 16:28:22.276402 25662 executor.go:111] Tasks: 103 done / 103 total; 0 can run
I0311 16:28:23.438692 25662 dns.go:238] Pre-creating DNS records
I0311 16:28:23.933149 25662 update_cluster.go:326] Exporting kubeconfig for cluster
kOps has set your kubectl context to hj-devstory.kr
Cluster is starting. It should be ready in a few minutes.
Suggestions:
생성 모니터링 및 검증
# 옵션 [터미널1] EC2 생성 모니터링
while true; do aws ec2 describe-instances --query "Reservations[*].Instances[*].{PublicIPAdd:PublicIpAddress,InstanceName:Tags[?Key=='Name']|[0].Value,Status:State.Name}" --filters Name=instance-state-name,Values=running --output text ; echo "------------------------------" ; sleep 1; done
------------------------------
------------------------------
kops-ec2 43.200.244.125 running
------------------------------
kops-ec2 43.200.244.125 running
------------------------------
kops-ec2 43.200.244.125 running
master-ap-northeast-2a.masters.hj-devstory.kr 52.78.137.235 running
------------------------------
nodes-ap-northeast-2c.hj-devstory.kr 52.79.228.17 running
kops-ec2 43.200.244.125 running
master-ap-northeast-2a.masters.hj-devstory.kr 52.78.137.235 running
------------------------------
nodes-ap-northeast-2c.hj-devstory.kr 52.79.228.17 running
kops-ec2 43.200.244.125 running
master-ap-northeast-2a.masters.hj-devstory.kr 52.78.137.235 running
nodes-ap-northeast-2a.hj-devstory.kr 43.201.50.188 running
------------------------------
nodes-ap-northeast-2c.hj-devstory.kr 52.79.228.17 running
kops-ec2 43.200.244.125 running
master-ap-northeast-2a.masters.hj-devstory.kr 52.78.137.235 running
[root@kops-ec2 ~]# kops validate cluster --wait 10m
Validating cluster hj-devstory.kr
INSTANCE GROUPS
NAME ROLE MACHINETYPE MIN MAX SUBNETS
master-ap-northeast-2a Master t3.medium 1 1 ap-northeast-2a
nodes-ap-northeast-2a Node t3.medium 1 1 ap-northeast-2a
nodes-ap-northeast-2c Node t3.medium 1 1 ap-northeast-2c
NODE STATUS
NAME ROLE READY
i-04c1624caf52f928c node True
i-05371281803cc5f32 master True
i-0a3e378593bff3ee8 node True
Your cluster hj-devstory.kr is ready
[root@kops-ec2 ~]# kops delete cluster --yes
TYPE NAME ID
autoscaling-config master-ap-northeast-2a.masters.hj-devstory.kr lt-0575a0f256134006f
autoscaling-config nodes-ap-northeast-2a.hj-devstory.kr lt-0ce46b48671d27f63
autoscaling-config nodes-ap-northeast-2c.hj-devstory.kr lt-0f4629f3a240eccec
autoscaling-group master-ap-northeast-2a.masters.hj-devstory.kr master-ap-northeast-2a.masters.hj-devstory.kr
autoscaling-group nodes-ap-northeast-2a.hj-devstory.kr nodes-ap-northeast-2a.hj-devstory.kr
autoscaling-group nodes-ap-northeast-2c.hj-devstory.kr nodes-ap-northeast-2c.hj-devstory.kr
dhcp-options hj-devstory.kr dopt-0d984747f7a3af95f
iam-instance-profile masters.hj-devstory.kr masters.hj-devstory.kr
iam-instance-profile nodes.hj-devstory.kr nodes.hj-devstory.kr
iam-role masters.hj-devstory.kr masters.hj-devstory.kr
iam-role nodes.hj-devstory.kr nodes.hj-devstory.kr
instance master-ap-northeast-2a.masters.hj-devstory.kr i-05371281803cc5f32
instance nodes-ap-northeast-2a.hj-devstory.kr i-04c1624caf52f928c
instance nodes-ap-northeast-2c.hj-devstory.kr i-0a3e378593bff3ee8
internet-gateway hj-devstory.kr igw-0b613d8bff9a144aa
keypair kubernetes.hj-devstory.kr-de:37:cb:d8:03:19:9b:12:a4:90:48:53:63:52:de:aa key-072f62ea59b959b3f
route-table hj-devstory.kr rtb-093416a4c2516763a
route53-record api.hj-devstory.kr. Z0154501DIXOV5IILPU3/A/api.hj-devstory.kr.
route53-record api.internal.hj-devstory.kr. Z0154501DIXOV5IILPU3/A/api.internal.hj-devstory.kr.
route53-record kops-controller.internal.hj-devstory.kr. Z0154501DIXOV5IILPU3/A/kops-controller.internal.hj-devstory.kr.
security-group masters.hj-devstory.kr sg-06e542890522a2bf2
security-group nodes.hj-devstory.kr sg-0f5bf8f66a7c8280c
subnet ap-northeast-2a.hj-devstory.kr subnet-0b832911152f68e87
subnet ap-northeast-2c.hj-devstory.kr subnet-02b5596fdde2b33e8
volume a.etcd-events.hj-devstory.kr vol-0f97b4545f58600d1
volume a.etcd-main.hj-devstory.kr vol-018d77631ac24c82d
volume master-ap-northeast-2a.masters.hj-devstory.kr vol-06c727983170f3fad
volume nodes-ap-northeast-2a.hj-devstory.kr vol-0a92c098bb5c7b41d
volume nodes-ap-northeast-2c.hj-devstory.kr vol-0c0b7ac40419e0ae0
vpc hj-devstory.kr vpc-0ccd6f92450d69a3b
autoscaling-config:lt-0575a0f256134006f ok
autoscaling-config:lt-0ce46b48671d27f63 ok
autoscaling-config:lt-0f4629f3a240eccec ok
---------
volume:vol-0c0b7ac40419e0ae0 ok
volume:vol-0a92c098bb5c7b41d ok
volume:vol-06c727983170f3fad ok
volume:vol-018d77631ac24c82d ok
volume:vol-0f97b4545f58600d1 ok
internet-gateway:igw-0b613d8bff9a144aa ok
subnet:subnet-0b832911152f68e87 ok
subnet:subnet-02b5596fdde2b33e8 ok
security-group:sg-06e542890522a2bf2 ok
security-group:sg-0f5bf8f66a7c8280c ok
route-table:rtb-093416a4c2516763a ok
vpc:vpc-0ccd6f92450d69a3b ok
dhcp-options:dopt-0d984747f7a3af95f ok
Deleted kubectl config for hj-devstory.kr
Deleted cluster: "hj-devstory.kr"
kubeadm 만으로 클러스터를 구성해 오던 내게 kOps 는 신세계와 같았다.
dns 구성 및 기타의 설정을 준비하는게 조금은 귀찮은 작업 이지만 클러스터 구성 및 관리가 훨씬 간편해지는 부분에 대해서 굉장히 매력적으로 다가 왔다.
앞으로 스터디를 통해서 kOps와 기타 서비스 및 툴들 잘 활용해서 효과적인 운영 환경을 관리 하는 엔지니어로 한단계 오르게 되길 상상해 본다.