๐Ÿ›ด์ฟ ๋ฒ„๋„คํ‹ฐ์Šค ์Šคํ„ฐ๋”” PKOS 1์ฃผ์ฐจ AWS kOps ์„ค์น˜ ๋ฐ ๊ธฐ๋ณธ ์‚ฌ์šฉ

Burstยท2023๋…„ 2์›” 27์ผ
0

๐Ÿ˜ŽPKOS์Šคํ„ฐ๋””

๋ชฉ๋ก ๋ณด๊ธฐ
1/7

๋ชฉํ‘œ

์ด๋ฒˆ 1์ฃผ์ฐจ ์Šคํ„ฐ๋””์—์„œ๋Š” KOPS ์„ค์น˜ ๋ฐ ์‚ฌ์šฉ๋ฒ•์„ ํ•™์Šต ํ•  ์˜ˆ์ •์ด๋‹ค.

KOPS

  • Kubernetes Operations(kOps) - Production Grade k8s Installation, Upgrades and Management
    - kOps ๋Š” ํด๋ผ์šฐ๋“œ ํ”Œ๋žซํผ(aws, gcp, azure ๋“ฑ)์—์„œ ์‰ฝ๊ฒŒ k8s ๋ฅผ ์„ค์น˜ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ฃผ๋Š” ๋„๊ตฌ
    - kOps ๋Š” ์„œ๋ฒ„ ์ธ์Šคํ„ด์Šค์™€ ๋„คํŠธ์›Œํฌ ๋ฆฌ์†Œ์Šค ๋“ฑ์„ ํด๋ผ์šฐ๋“œ์—์„œ ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•ด k8s ๋ฅผ ์„ค์น˜
    - kOps ๋Š” AWS ์˜ ๋‹ค์–‘ํ•œ ์„œ๋น„์Šค์™€ ์œ ์—ฐํ•˜๊ฒŒ ์—ฐ๋™๋˜์–ด ์‚ฌ์šฉ ๊ฐ€๋Šฅ

kops instance ๋ฐฐํฌ

# 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 <๋ฆฌ์ „>

# 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

kops-new-ec2.yaml

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
            yum -y install tree tmux jq git
            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

Kops ํด๋Ÿฌ์Šคํ„ฐ ๋ฐฐํฌ ๋ฐ ํ™•์ธ


# IAM User ์ž๊ฒฉ ๊ตฌ์„ฑ : ์‹ค์Šต ํŽธ๋ฆฌ๋ฅผ ์œ„ํ•ด administrator ๊ถŒํ•œ์„ ๊ฐ€์ง„ IAM User ์˜ ์ž๊ฒฉ ์ฆ๋ช… ์ž…๋ ฅ
aws configure
AWS Access Key ID [None]: Aceess Key
AWS Secret Access Key [None]: Secret Access Key
Default region name [None]: ap-northeast-2
Default output format [None]: json

# ์ž๊ฒฉ ๊ตฌ์„ฑ ์ ์šฉ ํ™•์ธ : ๋…ธ๋“œ IP ํ™•์ธ
aws ec2 describe-instances

# aws cli ํŽ˜์ด์ง€ ์ถœ๋ ฅ ์˜ต์…˜
export AWS_PAGER=""

# ๋ฆฌ์†Œ์Šค๋ฅผ ๋ฐฐ์น˜ํ•  ๋ฆฌ์ „์ด๋ฆ„์„ ๋ณ€์ˆ˜ ์ง€์ •
REGION=ap-northeast-2  # ์„œ์šธ ๋ฆฌ์ „ ์‚ฌ์šฉ

# ๋ฐฐํฌ ์‹œ ์ฐธ๊ณ ํ•  ์ •๋ณด๋ฅผ ํ™˜๊ฒฝ ๋ณ€์ˆ˜์— ์ €์žฅ
export KOPS_CLUSTER_NAME=<์ž์‹ ์˜ ํผ๋ธ”๋ฆญ ํ˜ธ์ŠคํŒ… ๋ฉ”์ธ ์ฃผ์†Œ>
export KOPS_STATE_STORE=<s3://(์œ„์—์„œ ์ƒ์„ฑํ•œ ์ž์‹ ์˜ ๋ฒ„ํ‚ท ์ด๋ฆ„)>
export AWS_PAGER=""
export REGION=ap-northeast-2

# kops ์„ค์ • ํŒŒ์ผ ์ƒ์„ฑ(s3) ๋ฐ k8s ํด๋Ÿฌ์Šคํ„ฐ ๋ฐฐํฌ : 6๋ถ„ ์ •๋„ ์†Œ์š”
## CNI๋Š” aws vpc cni ์‚ฌ์šฉ, ๋งˆ์Šคํ„ฐ ๋…ธ๋“œ 1๋Œ€(t3.medium), ์›Œ์ปค ๋…ธ๋“œ 2๋Œ€(t3.medium), ํŒŒ๋“œ ์‚ฌ์šฉ ๋„คํŠธ์›Œํฌ ๋Œ€์—ญ ์ง€์ •(172.30.0.0/16)
## --container-runtime containerd --kubernetes-version 1.24.0

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.9" -y

# validate
kops validate cluster --wait 10m


kops ์„ค์น˜ ํ™•์ธ

# kops ํด๋Ÿฌ์Šคํ„ฐ ์ •๋ณด ํ™•์ธ
kops get cluster

# ์ธ์Šคํ„ด์Šค๊ทธ๋ฃน ์ •๋ณด ํ™•์ธ
kops get ig

# ์ธ์Šคํ„ด์Šค ์ •๋ณด ํ™•์ธ
kops get instances

# ์ž๋™ ์™„์„ฑ ๋ฐ alias ์ถ•์•ฝ ์„ค์ •
source <(kubectl completion bash)
echo 'source <(kubectl completion bash)' >> ~/.bashrc
echo 'alias k=kubectl' >> ~/.bashrc
echo 'complete -F __start_kubectl k' >> ~/.bashrc

๊ด€๋ฆฌ ํŽธ๋ฆฌ์„ฑ ๋„๊ตฌ

kubectl cli ํ”Œ๋Ÿฌ๊ทธ์ธ ๋งค๋‹ˆ์ €(krew)

kubectl ๋ช…๋ น์–ด๋ฅผ ํŽธํ•˜๊ณ  ๊ฐ„๋‹จํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ํ”Œ๋Ÿฌ๊ทธ์ธ

์„ค์น˜
# ์„ค์น˜
curl -fsSLO https://github.com/kubernetes-sigs/krew/releases/download/v0.4.3/krew-linux_amd64.tar.gz
tar zxvf krew-linux_amd64.tar.gz
./krew-linux_amd64 install krew
tree -L 3 /root/.krew/bin

# PATH ์ถ”๊ฐ€
export PATH="${PATH}:/root/.krew/bin"
echo 'export PATH="${PATH}:/root/.krew/bin"' >>~/.bashrc

# krew ํ™•์ธ
kubectl krew
kubectl krew update
kubectl krew search
kubectl krew list
kubectl krew
์œ ์šฉํ•œ krew ๋ชฉ๋ก
  • kube-ctx : ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค ์ปจํ…์ŠคํŠธ ์‚ฌ์šฉ
  • kube-ns : ๋„ค์ž„์ŠคํŽ˜์ด์Šค(๋‹จ์ผ ํด๋Ÿฌ์Šคํ„ฐ ๋‚ด์—์„œ ๊ฐ€์ƒ ํด๋Ÿฌ์Šคํ„ฐ) ์‚ฌ์šฉ
  • kube-df-pv : Pod ๋ณผ๋ฅจ ์ •๋ณด ํ™•์ธ
  • kube-ktop : ๋ฆฌ๋ˆ…์Šค top ๋ช…๋ น์–ด์™€ ๋น„์Šทํ•˜๊ฒŒ pod์˜ ๋ฆฌ์†Œ์Šค ์‚ฌ์šฉ๋Ÿ‰์„ ํ™•์ธ

Helm(ํ—ฌ๋ฆ„)

์ฐธ๊ณ 1, ์ฐธ๊ณ 2
๋‹ค์–‘ํ•œ ํ™˜๊ฒฝ/์„ค์ •์—์„œ ํ•˜๋‚˜์˜ ํ…œํ”Œ๋ฆฟ์œผ๋กœ ์žฌ์‚ฌ์šฉ, ํ•„์š”ํ•œ ๋ชจ๋“ˆ๋งŒ ๋ฐฐํฌ ๊ฐ€๋Šฅ, ์•ˆ์ •์ ์ธ ํ—ฌ๋ฆ„ ์ฐจํŠธ ์ƒํƒœ๊ณ„์—์„œ ํ•„์š”ํ•œ ์˜คํ”ˆ์†Œ์Šค ์„ค์น˜

๋งค๋‹ˆํŽ˜์ŠคํŠธ ๋ฒ”์šฉํ™”
์ฟ ๋ฒ„๋„คํ‹ฐ์Šค๋Š” YAML ํ˜•์‹์œผ๋กœ ๋งค๋‹ˆํŽ˜์ŠคํŠธ๋ฅผ ์ž‘์„ฑํ•˜๊ณ  kubectl์„ ์‚ฌ์šฉํ•˜์—ฌ ์˜ค๋ธŒ์ ํŠธ๋ฅผ ์ œ์–ดํ•œ๋‹ค.
๊ทธ๋Ÿฌ๋‚˜ ์‹œ์Šคํ…œ์ด ๋Œ€๊ทœ๋ชจ๋กœ ๋ฐ”๋€Œ๋ฉด์„œ ๋น„์Šทํ•œ ๋งค๋‹ˆํŽ˜์ŠคํŠธ๋ฅผ ๋Œ€๋Ÿ‰์œผ๋กœ ๋งŒ๋“ค์–ด์•ผ ํ•˜๋ฏ€๋กœ ์žฌ์‚ฌ์šฉ์ด๋‚˜ ์ผ๊ด„ ๋ณ€๊ฒฝ ์ž‘์—…์ด ์–ด๋ ค์›Œ ์ง€๊ฒŒ ๋œ๋‹ค. ๊ทธ๋ž˜์„œ ํ•„์š”ํ•œ ๊ฒƒ์ด ๋งค๋‹ˆํŽ˜์ŠคํŠธ ๋ฒ”์šฉํ™”๋ผ๋Š” ๊ฐœ๋…์ด๋‹ค.

ํ—ฌ๋ฆ„ ์ฐจํŠธ(Helm Chart)

  • ์ฐจํŠธ(Chart) : ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค์—์„œ ์‹คํ–‰ํ•  ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋งŒ๋“œ๋Š” ๋ฐ ํ•„์š”ํ•œ ์ •๋ณด ๋ฌถ์Œ(=์••์ถ• ํŒŒ์ผ)

  • ๋กค๋ง ์—…๋ฐ์ดํŠธ ๋“ฑ์—๋„ ์ง€์›ํ•˜๋Š” ๊ฒƒ๋“ค์ด ๋งŽ์•„ ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค์—์„œ ์ตœ์ ํ™”๋œ ์„ค์ •์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์žฅ์ ๋„ ์žˆ๋‹ค.

  • ํ—ฌ๋ฆ„์ด ๊ด€๋ฆฌํ•˜๋Š” ๊ณต์‹ ์ฐจํŠธ๋Š” Artifact Hub์—์„œ ์ œ๊ณต

    • ๋Œ€ํ‘œ: Bitnami

[๊ณผ์ œ1] ๊ฐ์ž ์„ค์น˜ํ•œ AWS kOps ํด๋Ÿฌ์Šคํ„ฐ์˜ ์ •๋ณด๋ฅผ ์˜ฌ๋ ค์ฃผ์„ธ์š”.
#kops get cluster #ํด๋Ÿฌ์Šคํ„ฐ ์ •๋ณด ์ถœ๋ ฅ

#kops get instances #๊ฐ EC2 ์ธ์Šคํ„ด์Šค์˜ ์ •๋ณด ์ถœ๋ ฅ

[๊ณผ์ œ2] Helm ์œผ๋กœ ์›Œ๋“œํ”„๋ ˆ์Šค๋ฅผ ๋ฐฐํฌํ•˜๊ณ  ๊ด€๋ฆฌํŽ˜์ด์ง€์— ์ ‘์†ํ•ด์„œ ๊ธ€ 1๊ฐœ ์ž‘์„ฑํ•ด์ฃผ์‹œ๊ณ  ์Šคํฌ๋ฆฐ์ƒท์„ ์˜ฌ๋ ค์ฃผ์„ธ์š”.
#๊ฒŒ์‹œ๊ธ€์— ์ด๋ฏธ์ง€๋ฅผ ์˜ฌ๋ฆฌ๊ณ  ์ €์žฅ

[๊ณผ์ œ3] AWS kOps ํ™œ์šฉ - ์›Œ์ปค ๋…ธ๋“œ ์ฆ๊ฐ€(ASG = Auto Scaling Group ํ™œ์šฉ)
1. Ig ํŽธ์ง‘ ์ „(maxSize:1, minSize:1)

2. lg ํŽธ์ง‘ ํ›„(maxSize:3, minSize:3)

3. ์—…๋ฐ์ดํŠธ ์ „ node ์ˆ˜

4. ์—…๋ฐ์ดํŠธ ๋ฐ ๋กค๋ง ์—…๋ฐ์ดํŠธ

5. ์ถ”๊ฐ€ Node ํ™•์ธ

6. AWS ์˜คํ† ์Šค์ผ€์ผ๋ง ๋ฐ ์ธ์Šคํ„ด์Šค ํ™•์ธ

๋งˆ๋ฌด๋ฆฌ

์ฒ˜์Œ ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค๋ฅผ ๊ณต๋ถ€ํ•˜๋ฉด์„œ ํด๋Ÿฌ์Šคํ„ฐ๋ฅผ kubeadm์œผ๋กœ ๊ตฌ์„ฑํ•˜์—ฌ ์‚ฌ์šฉํ–ˆ์—ˆ๋‹ค. ์ง์ ‘ ๊ตฌ์„ฑํ•˜๋ฉด์„œ ๋งŽ์€ ์‹œ๊ฐ„์ด ๊ฑธ๋ ธ๊ณ , ๋งค๋ฒˆ ๊ตฌ์„ฑํ• ๋•Œ๋งˆ๋‹ค ์—๋Ÿฌ๋กœ ๊ณ ์ƒ์„ ํ•˜์˜€๋‹ค. KOPS๋ฅผ ์ ‘ํ•˜๊ณ  ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค ํด๋Ÿฌ์Šคํ„ฐ๋ฅผ ๋„ˆ๋ฌด ์‰ฝ๊ฒŒ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ์–ด์„œ ๋†€๋ผ์› ๋‹ค. Helm๋„ ๋งŽ์ด ๋“ค์–ด๋Š” ๋ดค์ง€๋งŒ ์ฒ˜์Œ ์‚ฌ์šฉํ•ด ๋ดค๋‹ค.
Helm Chart๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์‰ฝ๊ณ  ํ•œ๋ฒˆ์— ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋ฐฐํฌํ•  ์ˆ˜ ์žˆ๊ณ , ๊ตฌ์„ฑ ๋ณ€๊ฒฝ ๋ฐ ์ ์šฉ ์‹œ yaml์„ ํ†ตํ•ด ์‰ฝ๊ฒŒ ์—…๋ฐ์ดํŠธ ํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค. ๊ธฐ๋ณธ์ ์ธ ํด๋Ÿฌ์Šคํ„ฐ๋งŒ ๊ตฌ์„ฑํ•ด์„œ ์‚ฌ์šฉํ•ด๋ณธ ๋‚˜๋กœ์จ๋Š” ๋‹ค์–‘ํ•œ ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค ํ™˜๊ฒฝ์„ ์‚ฌ์šฉํ•ด ๋ณผ ์ˆ˜ ์žˆ์–ด์„œ ์ข‹์•˜๋‹ค!!๐Ÿ˜„

profile
Cloud Developer

0๊ฐœ์˜ ๋Œ“๊ธ€