카이도스의 Tech Blog
PKOS(쿠버네티스) 1주차 - AWS kOps 설치 및 기본 사용 본문
쿠버네티스 기초
*발음
- master(control-plane, leader) : 마스터, 컨트롤 플레인, 리더
- node(worker node) : 노드, 워커노드 (구 minion 미니언)
- k8s(kubernetes, k~s 사이에 8글자 == k8s) : 쿠버네티스, 케이에잇츠, 케이팔에스
- De facto(라틴어) : 데 팍토, 사실상의 의미 - Kubernetes has become a de facto standard.
- kubectl : 큐브 컨트롤(control), 큐버 컨트롤, 큐브 시티엘, 큐버 시티엘
- etcd : 엣시디, 이티시디
- flannel : 플라넬
- calico : 칼리코, 캘리코
- istio : 이스티오
- helm : 헬름, 핾, 햄
- pod : 파드, 포드
- label : 레이블, 라벨
* 쿠버네티스 아키텍처
- Kubernetes Components : K8S 클러스터는 Controle Plane(마스터)와 Node(노드)로 구성
- Control Plane(마스터 노드) 핵심 컴포넌트 : 마스터는 단일 서버 혹은 고가용성을 위한 클러스터 마스터로 구축
kube-apiserver : 마스터로 전달되는 모든 요청을 받아 드리는 API 서버
etcd : 클러스터내 모든 메타 정보를 저장하는 서비스
kube-scheduler : 사용자의 요청에 따라 적절하게 컨테이너를 워커 노드에 배치하는 스케줄러
kube-controller-manager : 현재 상태와 바라는 상태를 지속적으로 확인하며 특정 이벤트에 따라 특정 동작을 수행하는 컨트롤러 cloud-controller-manager : 클라우드 플랫폼(AWS, GCP, Azure 등)에 특화된 리소스를 제어하는 클라우드 컨트롤러
- 워커 노드
kubelet : 마스터의 명령에 따라 컨테이너의 라이프 사이클을 관리하는 노드 관리자
kube-proxy : 컨테이너의 네트워킹을 책임지는 프록시, 네트워크 규칙을 유지 관리
Container Runtime : 실제 컨테이너를 실행하는 컨테이너 실행 환경, (Docker & containerD & CRI-O)
- Add on
CNI : Container Network Interface 는 k8s 네트워크 환경을 구성해준다, 다양한 플러그인이 존재
DNS : 쿠버네티스 서비스를 위해 DNS 레코드를 제공해주며, Service Discovery 기능을 제공을 한다. 대표적으로 CoreDNS 가 있다
CSI : Container Storage Interface
그외 대시보드, 모니터링, 로깅 등등이 있다.
* 쿠버네티스는 멱등성의 특징을 가진다.
-멱등성 : 연산을 여러 번 적용하더라도 결과가 달라지지 않는 성질
AWS Kops 소개
* Kubernetes Operations(kOps) - Production Grade k8s Installation, Upgrades and Management
kOps 는 클라우드 플랫폼(aws, gcp, azure 등)에서 쉽게 k8s 를 설치할 수 있도록 도와주는 도구
kOps 는 서버 인스턴스와 네트워크 리소스 등을 클라우드에서 자동으로 생성해 k8s 를 설치
kOps 는 AWS 의 다양한 서비스와 유연하게 연동되어 사용 가능
지원 버전 : Github 에 보면 현재 kOps v1.25 이 최신버전
실습구성도
- k8s 를 배포할 수 있는 kops 가 설치된 ec2 를 cloudformation 에 의해서 생성됨
- kops 로 k8s 클러스터를 생성 : k8s 설정 파일을 s3 에 저장
- 버전 : k8s v1.24.9, OS Ubuntu 20.04 LTS
- kops-ec2 역할 : kOps 배포 수행, kubectl 명령 실행 등
- 마스터 노드와 워커 노드는 EC2 Auto Scaling Group(=ASG) 설정으로 구성됨
- 도메인은 퍼블릭 도메인 혹은 프라이빗 도메인을 사용, Gossip 도 가능 → 현재 실습 내용은 퍼블릭 도메인을 사용함
실습 시작
제공된 yaml 파일 다운로드하여 진행했다.(나중에 yaml 파일을 직접 생성하여 하는날이 오길...)
-기본 인프라 배포
*shell에서 진행
# yaml 파일 다운로드
curl -O yaml파일경로
(https://s3.ap-northeast-2.amazonaws.com/cloudformation.cloudneta.net/K8S/kops-new-ec2.yaml)
# yaml파일 내용(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
unzip yh-linux-amd64.zip
mv yh /usr/local/bin/
Outputs:
KopsEC2IP:
Value: !GetAtt KOPSEC2.PublicIp
|
# 배포
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 PJH-aws-test.pem= SgIngressSshCidr=/32 --region ap-northeast-2
# CloudFormation 스택 배포 완료 후 EC2 IP 출력
aws cloudformation describe-stacks --stack-name mykops --query 'Stacks[*].Outputs[*].OutputValue' --output text
예시) 43.201.48.178
# kOps-ec2 에 SSH 접속
ssh -i <My SSH Keyfile> ec2-user@IP
예시)ssh -i PJH-aws-test.pem ec2-user@43.201.48.178
-kOps 클러스터 배포 및 확인 : KOps-ec2 에 SSH 로그인 후 아래 실행
# 기본 툴 및 SSH 키 설치 등 확인
kubectl version --client=true -o yaml
kops version
aws --version
ls /root/.ssh/id_rsa*
# AWS 웹에서 IAM 사용자 추가하기
사용자권한은 AdministratorAccess 권한으로 생성했음.(기존 정책 직접 연결)
# IAM User 자격 구성 : 실습 편리를 위해 administrator 권한을 가진 IAM User 의 자격 증명 입력
aws configure
# aws cli 페이지 출력 옵션
export AWS_PAGER=""
# 자격 구성 적용 확인 : 노드 IP
aws ec2 describe-instances
# k8s 설정 파일이 저장될 버킷 생성
aws s3 mb s3://버킷<유일한 이름> --region <S3 배포될 AWS 리전>
예시) aws s3 mb s3://pjh-k8s-s3 --region ap-northeast-2
aws s3 ls
# 배포 시 참고할 정보를 환경 변수에 저장(재로그인시에도 환경변수 실행될수있게 셋팅포함)
export AWS_PAGER=""
export REGION=ap-northeast-2
export NAME=<자신의 퍼블릭 호스팅 메인 주소>
export KOPS_STATE_STORE=s3://(위에서 생성한 자신의 버킷 이름)
echo 'export AWS_PAGER=""' >>~/.bashrc
echo 'export REGION=ap-northeast-2' >>~/.bashrc
echo 'export KOPS_CLUSTER_NAME=<자신의 퍼블릭 호스팅 메인 주소>' >>~/.bashrc
echo 'export KOPS_STATE_STORE=s3://(위에서 생성한 자신의 버킷 이름)' >>~/.bashrc
예시)
export AWS_PAGER=""
export REGION=ap-northeast-2
export KOPS_CLUSTER_NAME=pjhtest.click
export KOPS_STATE_STORE=s3://pjh-k8s-s3
echo 'export AWS_PAGER=""' >>~/.bashrc
echo 'export REGION=ap-northeast-2' >>~/.bashrc
echo 'export KOPS_CLUSTER_NAME=pjhtest.click' >>~/.bashrc
echo 'export KOPS_STATE_STORE=s3://pjh-k8s-s3' >>~/.bashrc
# 옵션 [터미널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 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
kOps 설치 확인 : 설치 완료 후 진행
# 노드 IP 확인
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
# 파드 IP 확인
kubectl get pod -n kube-system -o=custom-columns=NAME:.metadata.name,IP:.status.podIP,STATUS:.status.phase
# kops 클러스터 정보 확인
kops get cluster
kops get cluster -o yaml
# 인스턴스그룹 정보 확인
kops get ig
kops get ig -o yaml
kops get ig -o yaml | yh (yh 설치해서 시인성 좋게보기)
# 인스턴스 정보 확인
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 cluster-info
# 노드 정보 확인 : 아래 출력 정보 의미는?
kubectl get nodes -v6
# CRI 컨테이너 런타임이 무엇인가요?
kubectl get nodes -o wide
# 배포 완료 후 정보 확인
tree -L 1 ~/.kube
cat .kube/config | yh
# volume(sc)
k get sc
kubectl get sc kops-csi-1-21 -o jsonpath={.parameters} ;echo
kubectl get sc kops-csi-1-17 -o jsonpath={.parameters} ;echo
# [master node] aws vpc cni log
ssh -i ~/.ssh/id_rsa ubuntu@api.$KOPS_CLUSTER_NAME ls /var/log/aws-routed-eni
ssh -i ~/.ssh/id_rsa ubuntu@api.$KOPS_CLUSTER_NAME cat /var/log/aws-routed-eni/plugin.log | jq
ssh -i ~/.ssh/id_rsa ubuntu@api.$KOPS_CLUSTER_NAME cat /var/log/aws-routed-eni/ipamd.log | jq
# pod ip 확인
k get pod -n kube-system
k get pod -n kube-system -owide
# [master node] iptables rules
ssh -i ~/.ssh/id_rsa ubuntu@api.$KOPS_CLUSTER_NAME sudo iptables -t nat -S
# [master node] 컨테이너 정보 확인
ssh -i ~/.ssh/id_rsa ubuntu@api.$KOPS_CLUSTER_NAME ps axf |grep /usr/bin/containerd
ssh -i ~/.ssh/id_rsa ubuntu@api.$KOPS_CLUSTER_NAME ps afxuwww
# [master node] tree 툴 설치
ssh -i ~/.ssh/id_rsa ubuntu@api.$KOPS_CLUSTER_NAME sudo apt install -y tree jq
# [master node] Static 파드 정보 확인 : Static 파드는 무엇일까요?
ssh -i ~/.ssh/id_rsa ubuntu@api.$KOPS_CLUSTER_NAME tree /etc/kubernetes/manifests/
ssh -i ~/.ssh/id_rsa ubuntu@api.$KOPS_CLUSTER_NAME cat /etc/kubernetes/manifests/kube-apiserver.manifest
ssh -i ~/.ssh/id_rsa ubuntu@api.$KOPS_CLUSTER_NAME cat /etc/kubernetes/manifests/kube-controller-manager.manifest
# [master node] 볼륨/마운트 확인 : nvme1n1 과 nvme2n1 은 etcd-events, etcd-main 으로 사용
ssh -i ~/.ssh/id_rsa ubuntu@api.$KOPS_CLUSTER_NAME lsblk
ssh -i ~/.ssh/id_rsa ubuntu@api.$KOPS_CLUSTER_NAME df -hT --type=ext4
# [master node] nvme1n1,nvme1n2 디렉터리 확인
ssh -i ~/.ssh/id_rsa ubuntu@api.$KOPS_CLUSTER_NAME tree /mnt/master-vol-008055c4e6ab61455
ssh -i ~/.ssh/id_rsa ubuntu@api.$KOPS_CLUSTER_NAME tree /mnt/master-vol-000def8aecbddb231
# [master node] kubelet 상태 확인
ssh -i ~/.ssh/id_rsa ubuntu@api.$KOPS_CLUSTER_NAME systemctl status kubelet | yh
master node에 SSH 접속 후 확인
# [master node] SSH 접속
ssh -i ~/.ssh/id_rsa ubuntu@api.$KOPS_CLUSTER_NAME
# [master node] EC2 메타데이터 확인 : IAM Role
TOKEN=`curl -s -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"`
echo $TOKEN
curl -s -H "X-aws-ec2-metadata-token: $TOKEN" –v http://169.254.169.254/
curl -s -H "X-aws-ec2-metadata-token: $TOKEN" –v http://169.254.169.254/latest/
curl -s -H "X-aws-ec2-metadata-token: $TOKEN" –v http://169.254.169.254/latest/meta-data/iam/security-credentials/
curl -s -H "X-aws-ec2-metadata-token: $TOKEN" –v http://169.254.169.254/latest/meta-data/iam/security-credentials/masters.pjhtest.click | jq
워커 노드에 SSH 접속 후 확인 : 워커 노드의 public ip 로 SSH 접속
# 워커 노드 Public IP 확인
aws ec2 describe-instances --query "Reservations[*].Instances[*].{PublicIPAdd:PublicIpAddress,InstanceName:Tags[?Key=='Name']|[0].Value}" --filters Name=instance-state-name,Values=running --output table
# 워커 노드 Public IP 변수 지정
W1PIP=<워커 노드 1 Public IP>
W2PIP=<워커 노드 2 Public IP>
예시)
W1PIP=3.34.40.17
W2PIP=3.34.46.70
# 워커 노드 SSH 접속
ssh -i ~/.ssh/id_rsa ubuntu@$W1PIP
exit
ssh -i ~/.ssh/id_rsa ubuntu@$W2PIP
exit
# 워커 노드 스토리지 확인
ssh -i ~/.ssh/id_rsa ubuntu@$W1PIP lsblk
ssh -i ~/.ssh/id_rsa ubuntu@$W2PIP lsblk
ssh -i ~/.ssh/id_rsa ubuntu@$W1PIP df -hT -t ext4
ssh -i ~/.ssh/id_rsa ubuntu@$W2PIP df -hT -t ext4
AWS Route53 도메인 정보 확인
# 자신의 도메인 변수 지정
MyDomain=<자신의 도메인>
MyDomain=pjhtest.click
# 자신의 Route 53 도메인 ID 조회 및 변수 지정
aws route53 list-hosted-zones-by-name --dns-name "${MyDomain}." | jq
aws route53 list-hosted-zones-by-name --dns-name "${MyDomain}." --query "HostedZones[0].Name"
aws route53 list-hosted-zones-by-name --dns-name "${MyDomain}." --query "HostedZones[0].Id" --output text MyDnzHostedZoneId=`aws route53 list-hosted-zones-by-name --dns-name "${MyDomain}." --query "HostedZones[0].Id" --output text`
echo $MyDnzHostedZoneId
# A 레코드 타입 조회
aws route53 list-resource-record-sets --hosted-zone-id "${MyDnzHostedZoneId}" --query "ResourceRecordSets[?Type == 'A']" | jq
aws route53 list-resource-record-sets --hosted-zone-id "${MyDnzHostedZoneId}" --query "ResourceRecordSets[?Type == 'A'].Name" | jq
aws route53 list-resource-record-sets --hosted-zone-id "${MyDnzHostedZoneId}" --query "ResourceRecordSets[?Type == 'A'].Name" --output text
# A 레코드 값 반복 조회
while true; do aws route53 list-resource-record-sets --hosted-zone-id "${MyDnzHostedZoneId}" --query "ResourceRecordSets[?Type == 'A']" | jq ; date ; echo ; sleep 1; done
헬름(HELM)
레포지토리 등록
[등록] helm repo add bitnami https://charts.bitnami.com/bitnami
[조회] helm repo list
[Chart 찾기] helm search repo bitnami | grep tomcat
[업데이트] helm repo update
[삭제] # helm repo remove bitnami
워드프레스 배포
# 아티팩트 허브에서 검색
helm search hub wordpress
# repo 추가 및 확인
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo list
# wordpress 검색
helm search repo wordpress
# 네임스페이스 생성
kubectl create ns wordpress
# 터미널2
watch kubectl get pod,svc
# 기본 파라미터를 덮어쓸수 있게 --set 으로 지정
helm install myblog \ --set wordpressUsername=admin \ --set wordpressPassword=password \ --set wordpressBlogName="PKOS BLOG" \ --namespace wordpress bitnami/wordpress --version 15.2.22
과제2 (Helm 으로 워드프레스를 배포하고 관리페이지에 접속해서 글 1개 작성해주시고 스크린샷을 올려주세요)
과제3 워커 노드 증가(ASG = Auto Scaling Group 활용)
# 인스턴스그룹 정보 확인
kops get ig
# 편집
kops edit ig nodes-ap-northeast-2a
# 적용
kops update cluster --yes
kops rolling-update cluster
실습완료 후 삭제 완료(1단계 과제까지는 최대한 작성했지만 2, 3 과제부터는 스킵.......ㅠㅠ)
모든 실습 완료 후 삭제 작업은 꼭 진행하자!!
kOps 클러스터 삭제: kops delete cluster --yes
(클러스터 삭제 완료 확인 후) AWS CloudFormation 스택 삭제 : aws cloudformation delete-stack --stack-name mykops
'KOPS' 카테고리의 다른 글
PKOS 6주차 - Alerting 얼럿매니저 로깅시스템 (0) | 2023.02.23 |
---|---|
PKOS 5주차 - 프로메테우스 그라파나 (0) | 2023.02.14 |
PKOS 4주차 - Harbor Gitlab ArgoCD (0) | 2023.02.07 |
PKOS(쿠버네티스)3주차 - Ingress & Storage (0) | 2023.02.01 |
PKOS(쿠버네티스)2주차 - 쿠버네티스 네트워크 (0) | 2023.01.26 |