home..

프로비저닝

kubernetes msa mont-kim aws eks kops PKOS gasida CloudNet

1주차 KOPS로 노드 프로비저닝

이번 스터디에서는 KOPS를 이용한 프로비저닝을 진행한다.

시작에 앞서

작업환경에따라 KOPS 프로비저닝 환경이 다를 수 있기때문에

KOPS EC2를 별도로 생성하여 이 작업환경에서 작업을 시작한다.

  • KOPS로 프로비저닝 하는 이유
    1. 온프레미스 제외 각 PC에서 가상화를 통한 프로비저닝 (Kubespray 등)의 경우 각 PC의 사양 또는 호환성 (윈도우, 유닉스 등)에 따라 다르기때문에 동일한 환경을 제공 할 수 없다.
    2. EKS 프로비저닝 테라폼을 이용한 EKS 프로비저닝이 훨씬 보편적이지만, 클러스터 프로비저닝에 시간이 KOPS보다 오래걸리기때문에 제외

KOPS EC2는 클라우드 포메이션을 이용해 생성을 하는데

클라우드 포메이션은 작성된 파일이 있다면 링크를 통해 AWS 콘솔에서도 생성이 가능하고

작업환경에서 명령어를 통해서도 생성이 가능하다.

윈도우 환경에서는 CMD 명령어가 익숙하지않아 직접 테스트해보지 못했지만

맥의경우 shell 명령어가 어렵지 않기때문에 훨씬 쉽게 사용 할 수 있다

KOPS 프로비저닝 클러스터 아키텍쳐

KOPS Cluster Demo.png

draw.io에서 구조를 그리는것이 보편적이지만

https://www.cloudcraft.co/ 라는 플랫폼에서도 조금 입체적인 그림을 그릴 수 있다고해서 그려봤다.

Untitled

정확한 스펙을 기입하면 예상비용도 산정이 가능하다.

클라우드 포메이션을 이용한 KOPS EC2 생성

해당 yaml파일이 첨부되어있는 링크를클릭하면

Template 파일이 첨부되어있는 상태로 바로 진행이 가능하다.

링크로 바로 접속하지않아도, AWS 콘솔창의 CloudFormation 생성에 해당 템플릿을 넣고 진행해도 무방하다

  • 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
    
    

다음과 같은 화면을 볼 수 있다.

https://t37022643.p.clickup-attachments.com/t37022643/d3788c20-4ad2-4384-bbcb-659ade56bcfb/CloudFormation.png

보안을 위해 본인의 작업환경에서만 접근을 허용해주기 위해

SgIngressCidr 를 본인의 IP / 32 로 선언을 한다

만약 본인의 IP를 모른다면


curl -s ipinfo.io/ip

명령어로 본인의 IP를 확인 할 수 있다.

AWS 콘솔창에서 CloudFormation Apply를 하면 다음과 같은 진행 프로세스를 볼 수 있다.

https://t37022643.p.clickup-attachments.com/t37022643/7ef55a91-5a5d-4627-985e-09d7a215b8e8/image.png

생성이 종료되었으면 인스턴스 콘솔창에 들어가 생성된 KOPS-EC2 정보를 확인한다.

https://t37022643.p.clickup-attachments.com/t37022643/fd8357c8-d82c-4c9b-af34-f04a01070ab2/image.png

해당인스턴스에 개방주소(public IP)와 pem(ppk) 키로 로그인을 해 KOPS-EC2에 접속을 한다

프로비저닝 된 이미지에서 기본적인 명령어들을 이용해 이미지 확인을 진행한다


# 기본 툴 및 SSH 키 설치 등 확인
kubectl version --client=true -o yaml

kops version
Client version: 1.25.3 (git-v1.25.3)

aws --version

KOPS EC2는 Amazon Linux로 프로비저닝되어 AWS 통합에 필요한 간단한 서비스, 유틸리티 및 도구들이 설치되어있어 KOPS 프로비저닝을 바로 진행 할 수 있습니다.

KOPS 프로비저닝

위의 이미지 확인이 모두 완료된후

이후 기본적인 명령어를 위한 configure를 진행한다.


aws configure

이때 IAM User 생성에서 진행했던 “엑세스 키”를 입력한다.

https://t37022643.p.clickup-attachments.com/t37022643/1524353c-c9f3-4023-b20e-ce2ccad4049c/image.png

생성한 KOPS-EC2에서 AWS 명령어를 쓰기위한 기본적인 조건은 충족했지만

프로비저닝 할 클러스터의 정보를 입력해야하기때문에, 다른 변수들을 입력해준다.


export AWS_PAGER=""
export REGION=ap-northeast-2
export KOPS_CLUSTER_NAME=@@@@@@.com
export KOPS_STATE_STORE=s3://@@@@@@@@

변수를 입력하는 제일 확실한 방법은 bashrc에 입력해 bash 접속을 할때마다

변수를 지정해주는것이 제일 명확하다.


echo 'export AWS_PAGER=""' >>~/.bashrc
echo 'export REGION=ap-northeast-2' >>~/.bashrc
echo 'export KOPS_CLUSTER_NAME=@@@@@@.com' >>~/.bashrc
echo 'export KOPS_STATE_STORE=s3://@@@@@@@@@' >>~/.bashrc


기본 config 설정을 진행후 AWS 커맨드로 프로비저닝을 진행한다.

KOPS_CLUSTER_NAME 은 route53에서 구매, 등록되어있는 도메인을 입력할경우

자동으로 api 서버등이 등록이된다.

KOPS_STATE_STORE 는 쿠버네티스 기본자원들이 S3 버킷에 저장되는데, 이 버킷명을 지정해주면 된다.

KOPS 클러스터 생성

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

이때 위에 첨부했던 구조도와 같이 쿠버네티스 클러스터가 배포된다.

생성에는 약 6분정도 소요된다고 하는데, 10분정도 뒤에 AWS콘솔창에서도 정상적으로 생성된 모습들을 볼 수 있다.

https://t37022643.p.clickup-attachments.com/t37022643/611647a3-71d4-4df1-a7cd-a3d55a4f48be/image.png

시간이 조금 지난후, AWS 콘솔의 인스턴스 정보를 보면 t3.medium으로 프로비저닝 된것을 확인할 수 있다.

KOPS-EC2에서


kops validate cluster --wait 10m

kubectl get nodes

명령어등으로 프로비저닝 된 쿠버네티스 클러스터의 상태를 확인 할 수 있다.

발생했던 오류

  • DNS 오류

    인스턴스의 상태는 모두 정상인데, kubectl 명령어 또는 kops validate cluster가 정상적으로 되지 않을경우

    Route 53의 DNS 등록정보가 잘못 등록되어있는 경우가 있다.

해당 파일에서 route53에서 구매했던 도메인을입력하면

자동으로 route 53 서브도메인이 등록된다.

(다른 호스팅 사이트에서 구매한 도메인도 route 53에 등록하고, 권한을 부여하면 정상적으로 사용이 가능할것 같다)

알수 없는 이유로 route53의 api 서브도메인이 다른 IP로 등록되어있었다…

과정을 따라하다 몇번 삭제, 재생성하다 생긴 오류인거같다

프로비저닝 클러스터 확인하기


kops get cluster
kops get instances

https://t37022643.p.clickup-attachments.com/t37022643/dc37288d-c803-4cf0-b433-c6228cf2b7f1/image.png

정상적인 kops 클러스터임을 확인 할 수 있다.

WordPress 배포하기

이제 클러스터에 Wordpress 를 배포하여 정상적으로 동작하는것을 확인한다.

배포는 HELM을 이용해 진행되는데, HELM에 대해서는 따로 정리해서 올려두겠습니다.

간단하게 요약하면 하나의 템플릿을 이용해 소스를 설치하기 쉽게 만들어져있는 도구입니다.

이번 helm 배포에서는 별도로 repo를 pull하고, values.yaml파일에 필요한 변수들을 명세하여 실행하지않지만 모듈에 필요한 변수들만 정의하여 배포하는 방법도 가능합니다.

helm prerequsite

helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo list

사용하고자 하는 helm repo를 로컬에 등록하고 확인하는 과정입니다.

kubectl create ns wordpress

HELM으로 배포할 wordpress는 별도의 namespace : wordpress에서 시작한다.

helm 배포하기

helm install myblog \
  --set wordpressUsername=admin \
  --set wordpressPassword=password \
  --set wordpressBlogName="PKOS BLOG" \
  --namespace wordpress bitnami/wordpress --version 15.2.22

마주했던 또다른 문제

hlelm을 통해 wordpress 자원을 생성을 했는데 IAM에서 권한 오류가 발생해 loadbalancer type의 service를 생성하는데 pending이 되고있다.

해당 Service를 Describe 했을때 나오는 에러멘트인데, IAM 권한문제라고 알려주고있어 IAM 설정을 다시 보기로 한다.

https://t37022643.p.clickup-attachments.com/t37022643/a67e1bb3-851b-48ac-b7f0-091130c5e3e1/image.png

IAM 수정

https://us-east-1.console.aws.amazon.com/iamv2/home#/roles

https://t37022643.p.clickup-attachments.com/t37022643/a0db9701-788f-4667-a8fa-4d979018f505/image.png

Elastic Load Balancing 관련 IAM Role을 추가한다.

역할생성이 완료되면 권한을 받아 LoadBalancer를 사용 할 수 있다.

Untitled

이제 정상적으로 service에서 loadbalancer가 생성된것을 확인 할 수 있다.

Untitled

이제 생성된 loadbalancer의 external-ip로 접속을 하면 wordpress 사이트에 접속 할 수있다.

Untitled

/admin 페이지에 접속해서 publish를 하면 main페이지의 내용을 publish 가능하다.

Untitled

AutoScaling 값 조절

쿠버네티스의 핵심은 컨테이너 단위의 자원을 가변적으로 관리한다는 장점이 있다.

이에따라 사용량 또는 다른 전략들에 의해 (쿠버네티스) 시스템 자체의 최대 자원량이 늘어야하는 경우가있는데, AutoScaling 설정에 따라 최대 자원량을 정해둘 수 있다.

온프레미스 쿠버네티스 클러스터에서는 오토스케일링이 꽤나 제한적이지만, 클라우드에서는 오토스케일링이 어렵지않게 가능하다.

오토스케일링 옵션 조절은 KOPS를 이용해 node 오토스케일링 정보를 변경 할 수 있다.

kops edit ig nodes-ap-northeast-2a

# Please edit the object below. Lines beginning with a '#' will be ignored,
# and an empty file will abort the edit. If an error occurs while saving this file will be
# reopened with the relevant failures.
#
apiVersion: kops.k8s.io/v1alpha2
kind: InstanceGroup
metadata:
  creationTimestamp: "2023-01-10T03:24:39Z"
  labels:
    kops.k8s.io/cluster: mont-kim.com
  name: nodes-ap-northeast-2a
spec:
  image: 099720109477/ubuntu/images/PKOS/hvm-ssd/ubuntu-focal-20.04-amd64-server-20221206
  instanceMetadata:
    httpPutResponseHopLimit: 1
    httpTokens: required
  machineType: t3.medium
  maxSize: 1
  minSize: 1
  role: Node
  subnets:
  - ap-northeast-2a

KOPS 명령어는 각 AZ 노드별로 (2a, 2c) 설정을 진행하기때문에 각각 값을 수정하면 된다.

(max 1→3, min 1→2로 조절을 진행했다)

maxSize, minSize를 수정후 적용을 진행한다.

kops update cluster --yes
kops rolling-update cluster

해당 명령어들을 입력하면

AWS 콘솔창에서 EC2의 AutoScaling Group 값이 변경된것을 확인 할 수 있다.

https://t37022643.p.clickup-attachments.com/t37022643/9bc20bda-98c5-4269-bbaa-9e5b01b83ad7/image.png

https://t37022643.p.clickup-attachments.com/t37022643/a0287156-634d-4400-b6dd-9ae4e7202170/image.png

kops 명령어로 클러스터 정보를 확인해도 오토스케일링 된 노드의 정보를 확인 할 수 있다.

https://t37022643.p.clickup-attachments.com/t37022643/cbdcab77-7d42-4621-becc-9d3fe0f4fb3e/image.png

kubectl get nodes 의 정보로도 증가된 노드를 확인 할 수 있다.

https://t37022643.p.clickup-attachments.com/t37022643/deab12e4-07f8-44a6-8614-d5254507e7ee/image.png

kops 명령어로 클러스터 정보를 확인해도 오토스케일링 된 노드의 정보를 확인 할 수 있다.

kubectl get nodes 의 정보로도 증가된 노드를 확인 할 수 있다.

© 2024 mont kim   •  Powered by Soopr   •  Theme  Moonwalk