어제자에 실행이 잘되었다면 위와같이 인스턴스 두개가 생긴것을 확인할 수 있다.
그리고 클러스터도 보인다. 이렇게 되면 cloudformation 용 맞춤 yaml 파일이 만들어진다.
실재로 템플릿을 확인해보면 ScalingConfig 부분이 위와같이 작성된 것을 확인해볼 수 있다.
eksctl(쿠버네티스 관리자) -> 옵션 -> cloudformation(yaml)(클러스터-eks 클러스터 자체, 노드그룹-worker 에 대한 scale 조정을 위한 템플릿) -> 인프라 구현
deployment -> replicas 2 + autoscaler 를 이용하게 되면 최소 개수, 최대 개수(2-5) 지정가능. 이렇게 설정하면 동작중인 두 노드를 중지 시키면? 다시 작동한다.
---
aws에서 EKS중 하나의 노드그룹을 클릭해보면 위와같이 노드갯수가 지정되어 있는것도 볼 수 있다.
AWS CloudFormation이란 무엇인가요? - AWS CloudFormation (amazon.com)
AWS CloudFormation이란 무엇인가요? - AWS CloudFormation
AWS CloudFormation이란 무엇인가요? AWS CloudFormation은 AWS 리소스를 모델링하고 설정하여 리소스 관리 시간을 줄이고 AWS에서 실행되는 애플리케이션에 더 많은 시간을 사용하도록 해 주는 서비스입니
docs.aws.amazon.com
템플릿 기본 사항 알아보기 - AWS CloudFormation (amazon.com)
템플릿 기본 사항 알아보기 - AWS CloudFormation
템플릿 기본 사항 알아보기 시작하기에서는 템플릿을 사용하여 스택을 생성하는 방법을 배웠습니다. 템플릿에 선언된 리소스와 이들 리소스를 스택의 리소스로 매핑하는 방법에 대해 살펴보았
docs.aws.amazon.com
aws cloudformation template example yaml 을 검색하면 위와같이 나온다.
이게 뭐냐면 우리가 AWS로 환경을 구성한다고 할때. 어떤 파일을 쓰고 어떤 페이지를 사용할지 등의 정보등을 yaml 파일로 작성하고 배포할 수 있다. 이렇게 하면 한꺼번에 배포, 삭제가 가능해진다.
이와 똑같이 openstack에도 heat template이 존재한다. HOT(Heat Orchestration Template)이라고 부른다.
그리고 이런것도 가능하다.
aws의 key(계정정보)를 openstack에 담아놓는것이다. 그런다음에 openstack에 템플릿을 담아놓으면 aws에 생기게 된다.
그래서 템플릿 버전을 보면
AWSTemplateFormat이 존재한다. 이걸 써서 만들고 배포하면 인증을 통해서 AWS에 환경을 뿌리는 것도 가능해진다.
클러스터가 완성되면 이미지 저장소(사설)를 준비한다. (퍼블릭으로 저장소를 생성하는 것도 가능하지만 보안상 사설을 이용하기로 한다.)
보면 왼쪽에 ECR이라는 게 존재한다.
가서 위와같이 프라이빗 리포지토리를 만들어보자
이름은 {내 닉네임}/{저장소 이름}
하고나면 나만의 공간이 만들어진 것을 확인할 수 있다. 이제 이 공간에 로그인해서 접근할 수 있다.
실재로 저장소에 로그인 해보자
```
aws ecr get-login-password --region=ap-northeast-1 | docker login --username AWS --password-stdin <url 주소>
```
하고 나면 인증정보가
```
cat /root/.docker/config.json
```
에 저장되어 있는 것을 확인할 수 있다.
```
aws ecr
```
로 명령어 처리해주면 된다.
```
docker image pull nginx
```
로 nginx 최신 버전을 긁어와서 ECS 에 올려보자
하면 ECR에 올릴 수 있는 이미지가 만들어진다.
httpd로 하나더 만들어서 업로드해보자
두개다 업로드 된것을 확인해볼 수 있다.
이게 이름은 길긴한데 이미 정해진거라 어쩔 수 없다.
암튼 이 상태로 배포를 해보자
nginx_pod.yaml과 httpd_pod.yaml 파일을 만들어서 배포까지 해보자
nginx_pod.yaml 파일을 확인해보면 위와같다.
그리고 httpd_pod는 green 이미지를 사용했다. 두개를 배포하고 다음의 명령어를 사용하자
```
k port-forward nginx-green 8001:80 & k port-forward nginx-blue 8002:80
```
그러면 위와같이 8001과 8002가 다른 이미지로 보이는 것을 확인할 수 있다.
만약 원격지 이미지를 지우고 싶다면
```
aws ecr batch-delete-image --repository-name tonyhan/testweb --image-ids imageTag=blue --region ap-northeast-1
```
이미지가 삭제된 모습을 확인할 수 있다.
green까지 삭제해주자
저장소 자체를 삭제해줄 수도 있다.
```
aws ecr delete-repository --repository-name tonyhan/testweb --force --region ap-northeast-1
```
---
포드를 배포하고 외부로의 "서비스"를 위하여 LB를 사용해보자
load balancer를 사용하면 위와같이 엄청 긴 도메인이 생기는데 이걸 CNAME으로 바꾸어서 배포해주어야 한다.
pod는 이렇게 작성해주었다.
nginx_lb.yaml 파일을 이렇게 작성해주었다.
ec2 로드밸런서에 가보면 DNS 이름이 보인다. 이 이름을 복사해서 뒤에 :8001을 붙여보자
그러면 이렇게 우리가 만든 이미지가 배포된 것을 확인해볼 수 있다.
문제는 저 도메인으로 접속하는게 매우 어렵기 때문에 간단한 주소로 접속이 되도록 가비아와 같은 곳에 도메인을 등록해주자
---
EBS를 PV로 사용하기
aws의 EBS 볼륨에서 PV를 만들고 이걸 Pod에 붙여보자
동적으로 이걸 연결해서 사용해보자
이걸 위해 StorageClass를 이용해보자
이때의 gp2는 SSD이다.
만들어진 공간에서 적은 분량 사용이 가능해진다.
EC2로 가보면 EBS부분에 볼륨이라는 것이보인다. 이건 각 인스턴스에게 부여된 볼륨이라고 생각할 수 있다.
IOPS라는 게 있는데 IOPS가 높을 수록 처리가 빨라진다. 대신 오래 저장하면 가격이 비싸진다.
낮은것은 느리지만 오래 저장해도 가격이 싸다.
요 상태로 생성해보자
이제 볼륨을 가지고 포드에 연결해보자
- 정적
pv/pvc
개발자가 필요한 볼륨을 자신의 포드에 명시한다. 이때 nfs, iscsi, glusterfs, ... target 주소 등을 명시해야한다.
- 동적
PV pool 에 볼륨을 집어넣고 사용자는 PVC를 요청하면 StorageClass 를 통해서 Pod Provisioner에게 연결되어서 자신의 요청에 맞는 PV를 연결해준다. 그래서 우리는 pod를 휘발성이기에 영구적으로 보관가능한 스토리지가 필요하다.
동적인 방법에서는 pv, pvc, storageclass, provisioner가 필요하다.
storageclass.yaml 파일을 확인해보자
공식문서를 참고해보면 이런식으로 작성되어 있는 것을 확인해볼 수 있다.
openstack으로도 이게 가능하다.
volumeBindingMode가 Immediate -> StorageClass를 배포즉시 pv-pvc를 매핑한다.
WaitForFirstConsumer -> 딜레이를 두고 포드가 생성되면서 요청을 하게되면 그때 생성된다.
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-fst-sc
spec:
storageClassName: faststorage
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
pvc.yaml 인데 이걸 pod에 집어넣어주면 되는 것이다.
위와같이 PV를 제공해줄 수도 있다.
마지막으로 pod에 볼륨을 넣어놓았다. 여기에 적힌 볼륨은 링크일 뿐이고 실재 데이터는 EBS 상에 저장이 되는 형태이다.
이런식으로 배포를 해보니
nginx-pod가 동작중이고
pod의 저장소 중 aws 관련된것을 찾아보니 저장소가 잡혀있는 것을 볼 수 있다.
실재로 aws가서 확인해보니 볼륨이 생성된거까지도 확인이 가능했다.
---
모니터링과 오토스케일링
CloudWatch의 Container Insights로 포드상태 확인
인스턴스의 IAM 역활 부분을 확인해보자
그럼 위와같이 권한 정책 항목들이 떠있는 것을 볼 수 있다. 즉 노드자체에서 할 수 있는것들이 권한 부분이 작성되어 있는데 여기에서 할 수 있는것의 대부분이 EKS인것을 알 수 있다.
그런데 우리가 모니터링이 하고 싶다면?
지금 현재 작업하고 있는 계정은 웹이나 CLI에서 모두 루트계정을 사용하고 있다.
root 로그인 -> aws 전체 프로젝트를 관리할 수 있는 계정
IAM 로그인 -> root 계정이 만들어준 계정 (개발자, DB 관리자, 인프라 담당자)
두가지가 존재한다.
s3fullaccess 권한이 검색되는데 이건 s3에 대한 권한을 모두 부여하는 것이다.
CloudWatchAgentAdminPolicy의 경우 인스턴스 내부에 모니터링을 위한 에이전트 서버를 설치하는 것이다. 이 서버가 인스턴스 내부의 데이터를 읽어와서 모니터링을 할 수 있게 해준다.
우리는 이중에 ServerPolicy를 선택하자
놀랍게도 이렇게 해주면 우리가 만든 인스턴스 모두에 권한이 부여되어 있을 것이다. 왜냐하면 같은 노드그룹이다보니까 가능한 부분인것이다.
□ EKS 클러스터에 CloudWatch 용 네임스페이스 생성
root@awscli:~/k8s# kubectl apply -f \
https://raw.githubusercontent.com/aws-samples/amazon-cloudwatch-container-insights/latest/k8s-deployment-manifest-templates/deployment-mode/daemonset/container-insights-monitoring/cloudwatch-namespace.yaml
namespace/amazon-cloudwatch created
root@awscli:~/k8s#
□ cloudWatch 에이전트의 서비스 계정 생성
root@awscli:~/k8s# kubectl apply -f \
https://raw.githubusercontent.com/aws-samples/amazon-cloudwatch-container-insights/latest/k8s-deployment-manifest-templates/deployment-mode/daemonset/container-insights-monitoring/cwagent/cwagent-serviceaccount.yaml
serviceaccount/cloudwatch-agent created
clusterrole.rbac.authorization.k8s.io/cloudwatch-agent-role created
clusterrolebinding.rbac.authorization.k8s.io/cloudwatch-agent-role-binding created
root@awscli:~/k8s#
□ CloudWatch 에이전트에 대한 ConfigMap 생성
root@awscli:~/k8s# curl -O \
https://raw.githubusercontent.com/aws-samples/amazon-cloudwatch-container-insights/latest/k8s-deployment-manifest-templates/deployment-mode/daemonset/container-insights-monitoring/cwagent/cwagent-configmap.yaml
#불러오기는 하는데 들여와서 내용을 수정해야 한다.
#cluster_name을 수정해주자
# eks-work-cluster
# 그 다음에 배포해주자
kubectl apply -f cwagent-configmap.yaml
□ DaemonSet 로 CloudWatch 에이전트 배포
root@awscli:~/k8s# kubectl apply -f \
https://raw.githubusercontent.com/aws-samples/amazon-cloudwatch-container-insights/latest/k8s-deployment-manifest-templates/deployment-mode/daemonset/container-insights-monitoring/cwagent/cwagent-daemonset.yaml
DaemonSet은 특정 포드에 연결되어서 모니터링과 백업등을 전담하는 친구이다.
실재로 위의 과정을 수행해보자
이렇게하면 CloudWatch라는 것으로 상태 확인이 가능한다.
근데 실재로는 이걸 그냥 aws 콘솔에서도 가능한데 왜 하는 것일까?
각 (EKS에 참여하는)노드의 CPU, RAM 상태만을 확인하기 위한 목적이 아니라 해당 정보를 별도로 수집하고 이를 토대로 auto scale 하기 위한 목적
이게 auto scaler에서 metric-server : 노드의 리소스 정보 수집 = CloudWatchAgentServer를 통해 모인 정보는 agent를 통해 통합관리된다.
---
Ansible
이렇게 만들어줄것이다. VM1을 master로 사용할 계획이다. 이때 kvm이 가급적 리소스를 적게 써야 한다.
그리고 김치도 옆에 웹브라저로 떠 있어야 한다.
현재 중요한것은 하이퍼바이저 하나는 있어야 한다. 메모리 12GB, CPU 코어 4개정도로 만들어놓자.
cat cluster_autoscaler.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
labels:
k8s-addon: cluster-autoscaler.addons.k8s.io
k8s-app: cluster-autoscaler
name: cluster-autoscaler
namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: cluster-autoscaler
labels:
k8s-addon: cluster-autoscaler.addons.k8s.io
k8s-app: cluster-autoscaler
rules:
- apiGroups: [""]
resources: ["events","endpoints"]
verbs: ["create", "patch"]
- apiGroups: [""]
resources: ["pods/eviction"]
verbs: ["create"]
- apiGroups: [""]
resources: ["pods/status"]
verbs: ["update"]
- apiGroups: [""]
resources: ["endpoints"]
resourceNames: ["cluster-autoscaler"]
verbs: ["get","update"]
- apiGroups: [""]
resources: ["nodes"]
verbs: ["watch","list","get","update"]
- apiGroups: [""]
resources: ["pods","services","replicationcontrollers","persistentvolumeclaims","persistentvolumes"]
verbs: ["watch","list","get"]
- apiGroups: ["extensions"]
resources: ["replicasets","daemonsets"]
verbs: ["watch","list","get"]
- apiGroups: ["policy"]
resources: ["poddisruptionbudgets"]
verbs: ["watch","list"]
- apiGroups: ["apps"]
resources: ["statefulsets"]
verbs: ["watch","list","get"]
- apiGroups: ["storage.k8s.io"]
resources: ["storageclasses"]
verbs: ["watch","list","get"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: cluster-autoscaler
namespace: kube-system
labels:
k8s-addon: cluster-autoscaler.addons.k8s.io
k8s-app: cluster-autoscaler
rules:
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["create"]
- apiGroups: [""]
resources: ["configmaps"]
resourceNames: ["cluster-autoscaler-status"]
verbs: ["delete","get","update"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: cluster-autoscaler
labels:
k8s-addon: cluster-autoscaler.addons.k8s.io
k8s-app: cluster-autoscaler
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-autoscaler
subjects:
- kind: ServiceAccount
name: cluster-autoscaler
namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: cluster-autoscaler
namespace: kube-system
labels:
k8s-addon: cluster-autoscaler.addons.k8s.io
k8s-app: cluster-autoscaler
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: cluster-autoscaler
subjects:
- kind: ServiceAccount
name: cluster-autoscaler
namespace: kube-system
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: cluster-autoscaler
namespace: kube-system
labels:
app: cluster-autoscaler
spec:
replicas: 1
selector:
matchLabels:
app: cluster-autoscaler
template:
metadata:
labels:
app: cluster-autoscaler
spec:
serviceAccountName: cluster-autoscaler
containers:
- image: k8s.gcr.io/cluster-autoscaler:v1.2.2
name: cluster-autoscaler
resources:
limits:
cpu: 100m
memory: 300Mi
requests:
cpu: 100m
memory: 300Mi
command:
- ./cluster-autoscaler
- --v=4
- --stderrthreshold=info
- --cloud-provider=aws
- --skip-nodes-with-local-storage=false
# 오토스케일링 그룹 이름 설정
- --nodes=2:5:eks-debff172-47d2-3cdd-4029-e0d9360b29b
env:
- name: AWS_REGION
# 리전을 지정
value: ap-northeast-1
volumeMounts:
- name: ssl-certs
mountPath: /etc/ssl/certs/ca-certificates.crt
readOnly: true
imagePullPolicy: "Always"
volumes:
- name: ssl-certs
hostPath:
path: "/etc/ssl/certs/ca-bundle.crt"
'Development(Web, Server, Cloud) > 22) LINUX - Cloud' 카테고리의 다른 글
클라우드 71일차 (0) | 2022.05.09 |
---|---|
클라우드 70일차(kvm,vagrant, ansible) (1) | 2022.05.03 |
클라우드 68일차 (0) | 2022.04.29 |
클라우드 67일차(PV,PVC,jenkins,gcp-정리중) (0) | 2022.04.28 |
클라우드 66일차(k8s-labeling, ansible, jenkins) (0) | 2022.04.27 |