'Server/AWS'에 해당하는 글 49건

AWS 로드 밸런서 컨트롤러는 k8s ingress 를 생성할 때 ALB(Application Load Balancer) / NLB(Network Load Balancer) 를 생성해 주고 관리한다. ALB / NLB 가 필요하다면 배포해야 하는데 EKS 와 k8s 간에 로드 밸런서 관리 권한을 연결해야 한다. eksctl + cloudFormation 으로 자동 생성할 수도 있지만, aws 관리콘솔 + awscli + kubectl 을 사용하여 수동 설정했다.

 

 

IAM / ServiceAccount 설정

 

AWS 로드 밸런서 컨트롤러의 IAM 정책(사용자 대신 AWS API를 호출) 다운로드

- 버전 확인 : https://docs.aws.amazon.com/eks/latest/userguide/aws-load-balancer-controller.html

 

Installing the AWS Load Balancer Controller add-on - Amazon EKS

If you view the policy in the AWS Management Console, the console shows warnings for the ELB service, but not for the ELB v2 service. This happens because some of the actions in the policy exist for ELB v2, but not for ELB. You can ignore the warnings for

docs.aws.amazon.com

 

$ curl -o iam_policy.json https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.3.0/docs/install/iam_policy.json

 

다운로드한 정책을 사용하여 IAM 정책 생성

 

$ aws iam create-policy \
--policy-name AWSLoadBalancerControllerIAMPolicy \
--policy-document file://iam_policy.json

 

IAM 자격증명 공급자 생성(AWS 관리콘솔)

 

  • 클러스터에서 OpenID Connect 공급자 URL 복사하여 지문/인증서 확인
  • 대상: sts.amazonaws.com

 

IAM 역할 생성(AWS 관리콘솔)

 

  • Web Identity > 생성한 자격증명 공급자 연결 > 정책 선택(AWSLoadBalancerControllerIAMPolicy) > 역할 이름 입력(AmazonEKSLoadBalancerControllerRole) 후 생성
  • 생성한 역할에서 [신뢰 관계] 편집

oidc.eks.ap-northeast-2.amazonaws.com/id/EXAMPLED123D4633E53DE1B716D3041E:aud /

sts.amazonaws.com.

   
oidc.eks.ap-northeast-2.amazonaws.com/id/EXAMPLED123D4633E53DE1B716D3041E:sub /

system:serviceaccount:kube-system:aws-load-balancer-controller

 

k8s ServiceAccount 추가

 

$ vi aws-load-balancer-controller-service-account.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  labels:
    app.kubernetes.io/component: controller
    app.kubernetes.io/name: aws-load-balancer-controller
  name: aws-load-balancer-controller
  namespace: kube-system
  annotations:
      eks.amazonaws.com/role-arn: arn:aws:iam::111122223333:role/AmazonEKSLoadBalancerControllerRole

$ kubectl apply -f aws-load-balancer-controller-service-account.yaml
serviceaccount/aws-load-balancer-controller created

 

여기까지의 작업으로 쿠버네티스의 ServiceAccount 는 AWS 의 AmazonEKSLoadBalancerControllerRole 역할을 얻게 되었고, ingress 와 loadbalancer 에 대하여 AWS 에 ALB 와 NLB 를 각각 생성/관리할 수 있게 되었다.

 

 

Load Balancer Controller 설치

 

Fargate 에 컨트롤러를 배포할 때는 cert-manager 에 의존하지 않기 때문에 Helm 차트를 사용하여 설치한다. Helm 은 Kubernetes 클러스터에서 사용하는 패키지 관리자로 yum, apt 와 흡사하며, 흔히 나오는 차트라는 단어는 helm 패키지라고 이해하면 된다.

 

Helm 설치 - https://docs.aws.amazon.com/ko_kr/eks/latest/userguide/helm.html

 

Amazon EKS에 Helm 사용 - Amazon EKS

Amazon EKS에 Helm 사용 Kubernetes용 Helm 패키지 관리자는 Kubernetes 클러스터에서 애플리케이션을 설치하고 관리하는 데 도움이 됩니다. 자세한 내용은 Helm 설명서를 참조하십시오. 이 주제에서는 Helm

docs.aws.amazon.com

 

eks 저장소 초기화 뒤 설치

 

$ helm repo add eks https://aws.github.io/eks-charts
"eks" has been added to your repositories

 

eks 저장소 차트 확인

 

$ helm repo update
$ helm search repo eks
...
eks/aws-load-balancer-controller
...

 

컨트롤러 설치

 

$ helm install aws-load-balancer-controller eks/aws-load-balancer-controller \
-n kube-system \
--set clusterName=cluster-name \
--set serviceAccount.create=false \
--set serviceAccount.name=aws-load-balancer-controller \
--set region=region-code \
--set vpcId=vpc-xxxxxxxx \
--set image.repository=account.dkr.ecr.region-code.amazonaws.com/amazon/aws-load-balancer-controller

LAST DEPLOYED: Thu Dec  9 13:27:38 2021
NAMESPACE: kube-system
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
AWS Load Balancer controller installed!

 

이미지 저장소 속성에서, 서울의 region-code 는 ap-northeast-2, account 는 602401143452 이다. 

image.repository=602401143452.dkr.ecr.ap-northeast-2.amazonaws.com/amazon/aws-load-balancer-controller

 

위 명령에서 install 후에 차트 업그레이드(upgrade)시 필요한 TargetGroupBinding 사용자 리소스를 설치한다. 

 

$ kubectl apply -k "github.com/aws/eks-charts/stable/aws-load-balancer-controller/crds?ref=master"

 

 

Fargate 프로파일 생성 : kube-system 에 선택기 매칭이 필요한 경우 추가.

  • app.kubernetes.io/instance = aws-load-balancer-controller
  • app.kubernetes.io/name = aws-load-balancer-controller

 

$ kubectl rollout restart -n kube-system deployment aws-load-balancer-controller

 

 

컨트롤러 설치 확인

 

$ kubectl get deployment -n kube-system aws-load-balancer-controller
NAME                           READY   UP-TO-DATE   AVAILABLE   AGE
aws-load-balancer-controller   2/2     2            2           84s

 

load-balancer-controller

 


 

삽질1. 리전별 ECR 주소 혼동

 

--set image.repository=account.dkr.ecr.region-code.amazonaws.com/amazon/aws-load-balancer-controller

 

컨트롤러 설치시 account 를 accountId 로 착각해 주소가 다르다는 오류를 발생시켰었다. AWS Load Balancer Controller, Amazon VPC CNI, kube-proxy, CoreDNS 등의 ECR 저장소를 이용할 때 주소가 리전마다 다르므로 주의한다.

 

리전별 ECR 주소 참고 : https://docs.aws.amazon.com/eks/latest/userguide/add-ons-images.html

 

Amazon EKS add-on container image addresses - Amazon EKS

Amazon EKS add-on container image addresses When you deploy Amazon EKS add-ons such as the AWS Load Balancer Controller, the Amazon VPC CNI, kube-proxy, CoreDNS, or storage drivers, you pull an image from an Amazon ECR repository. The image name and tag ar

docs.aws.amazon.com

 

 

삽질2. aws-load-balancer-controller 설치 에러

 

$ helm install aws-load-balancer-controller...
Error: INSTALLATION FAILED: rendered manifests contain a resource that already exists. Unable to continue with install: ClusterRole "aws-load-balancer-contro
ller-role" in namespace "" exists and cannot be imported into the current release: invalid ownership metadata; label validation error: missing key "app.kuber
netes.io/managed-by": must be set to "Helm"; annotation validation error: missing key "meta.helm.sh/release-name": must be set to "aws-load-balancer-controll
er"; annotation validation error: missing key "meta.helm.sh/release-namespace": must be set to "kube-system"

 

Kubernetes manifest 를 적용하여 설치했다가 이미 필요한 설정값들이 달라 발생한 오류. 재설치 하면서 발생하는 기존 리소스들 전부 찾아서 삭제하고 OK 떨어질때까지 반복하면서 해결.

 

$ kubectl delete clusterrole aws-load-balancer-controller-role
$ kubectl delete clusterrolebinding aws-load-balancer-controller-rolebinding
$ kubectl delete service aws-load-balancer-webhook-service -n kube-system
$ kubectl delete MutatingWebhookConfiguration aws-load-balancer-webhook
$ kubectl delete ValidatingWebhookConfiguration aws-load-balancer-webhook

 

 


WRITTEN BY
손가락귀신
정신 못차리면, 벌 받는다.

,

EKS Cluster

Server/AWS 2021. 12. 8. 22:24

EKS(Elastic Kubernetes Service) 는 Kubernetes 를 실행해주는 프로덕션 환경의 관리형 서비스로, 사용자를 대신해 제어 플레인 또는 노드 설치, 작동 및 유지 관리를 한다. 오픈 소스 Kubernetes 소프트웨어의 최신 버전을 실행하므로 Kubernetes 커뮤니티의 모든 기존 플러그인과 도구도 사용할 수 있다. AWS 서비스들과의 통합이 쉽지만 기본적으로 IAM, VPC, ECR, ALB 등이 함께 사용되기 때문에 사전 숙지가 필요하다. 가장 중요한 쿠버네티스 사용법 역시 공식 사이트를 보면 자세하게 설명이 잘 되어 있지만, 분량도 많고, 테스트 환경 기반이다보니 막상 프로덕션 환경에서 사용하려고 하면 머릿속이 하얘지는... 사실 ECS/EKS 의 큰 차이는 모르겠다. ECS 를 잘 써왔는데 굳이 EKS 를 쓰려는 이유는 그냥 한번 써볼라꼬. 난 그저 컨테이너 자동 복구, 무중단 배포, 오토 스케일링만 잘되면 된다. 쿠버네티스를 모르더라도 EKS 를 잘 쓸 수 있는지 EKS 가이드를 참고하여 Fargate 위주로 제가 한번 먹어보겠습니다.

 

주의해야 할 것은 AWS 문서는 한글판에만 의존해서는 안된다. 영문판보다 버전도 낮고 번역이 정반대인 경우도 있고, 예제의 경우 시나리오 중간중간 버전이 혼용되는가 하면... 등의 이유로 영문판과 함께 보기를 권장한다. 덕분에 예상치 못한 에러들이 발생해서 도움이 많이 됐다...;

 

 

클러스터

 

EKS 를 시작할 때, 가장 먼저 해야할 일이 클러스터를 생성하는 것이다. 이 안에 제어영역(Control Plane) 과 해당 노드가 포함된다.

 

 

클러스터 생성 방법1)

 

클러스터 관리가 가능한 eksctl 명령 도구를 사용하는 방법이다. 

 

- eksctl 설치 : https://docs.aws.amazon.com/ko_kr/eks/latest/userguide/install-kubectl.html

 

kubectl 설치 - Amazon EKS

Amazon EKS 클러스터 제어 영역과 마이너 버전이 하나 다른 kubectl 버전을 사용해야 합니다. 예를 들어, 1.20 kubectl 클라이언트는 Kubernetes 1.19, 1.20 및 1.21 클러스터로 작업해야 합니다.

docs.aws.amazon.com

 

$ eksctl create cluster \
--name my-cluster \
--region us-west-2

 

생략된 옵션이 매우 많다. eksctl 은 이런 식으로 줄줄줄 써 내려가거나 yaml 파일로 만들어서 관리할 때 유용한 툴이다. 위처럼 간단하게 명령해도 CloudFormation 을 이용한, 이미 준비된 완벽한 클러스터가 만들어진다.(약 20분 소요) 한번에 클러스터가 만들어진다는 장점은 있지만, 이 때 필요한 IAM 권한이나 VPC 등이 생성되고 연동되는 과정이 보이지 않으므로 잘 살펴보아야 한다. 오히려 초보자에게는 방법2) 가 더 유용할 수 있다. 

 

옵션을 나열하고 --dry-run 옵션까지 추가하면 지정한 옵션과 default 옵션으로 만들어질 항목들을 클러스터 생성없이 테스트 해볼 수 있고, yaml 파일로 만들어서 유지관리 할 수도 있다.

 

$ eksctl create cluster --dry-run > config.yaml

 

 

클러스터 생성 방법2)

 

AWS 관리콘솔로 클러스터를 생성하는 방법이다. 보기도 편하고 필수항목들이 준비되지 않으면 진행되지 않는다. IAM role(AmazonEKSClusterPolicy) / VPC / 보안그룹 등이 준비되어 있어야 한다. 보안그룹은 일단 공개, VPC 는 Fargate 의 경우 private 서브넷을 반드시 필요로 하므로 public/private 서브넷을 모두 구성한다.(약 10분 소요)

 

 

Fargate 프로파일

 

클러스터는 생성되었지만, 막상 클러스터를 선택해 세부정보를 보면 node 도 보이지 않고, DNS 서버인 CoreDNS 도 대기(pending) 상태임을 워크로드에서 확인할 수 있다. Fargate 에서 pod 를 실행시키려면 Fargate 프로파일을 생성해서 워크로드의 deployment 들과 매칭이 필요하다. CoreDNS 가 작동할 수 있도록 AWS 관리콘솔에서 Fargate 프로파일을 생성한다. 이 때도 AM 에서 pod 실행 역할(AmazonEKSFargatePodExecutionRolePolicy) 을 생성하고 연결해 주어야 한다. pod 를 생성할 서브넷도 선택하고, 워크로드의 coredns 에서 네임스페이스와 선택기(레이블) 을 확인하여 네임스페이스 또는 네임스페이스+선택기(레이블) 이 일치하도록 Fargate 프로파일을 생성한다.

 

이 단계에서는 Fargate 프로파일에 namespace: kube-system 만 생성해도 CoreDNS 와 매칭된다. 

 

그리고 eksctl 의 --fargate 옵션으로 클러스터를 설치하지 않으면 CoreDNS 의 기본값은 EC2 를 사용하도록 구성되기 때문에, CoreDNS deployment 의 해당 구성 부분을 삭제해 주어야 한다. 또한 그 전에 클러스터와의 통신을 위해 kubectl 툴을 사용할 수 있도록 kubeconfig(~/.kube/config) 를 구성한다.

 

- kubectl 설치 : https://docs.aws.amazon.com/ko_kr/eks/latest/userguide/install-kubectl.html

 

kubectl 설치 - Amazon EKS

Amazon EKS 클러스터 제어 영역과 마이너 버전이 하나 다른 kubectl 버전을 사용해야 합니다. 예를 들어, 1.20 kubectl 클라이언트는 Kubernetes 1.19, 1.20 및 1.21 클러스터로 작업해야 합니다.

docs.aws.amazon.com

 

앞으로의 kubectl 명령이 클러스터와 통신하도록 kubeconfig 구성

$ aws eks update-kubeconfig --region <region> --name <cluster>

 

coredns 설정에서 ec2 구문 제거

$ kubectl patch deployment coredns \
-n kube-system \
--type json \
-p='[{"op": "remove", "path": "/spec/template/metadata/annotations/eks.amazonaws.com~1compute-type"}]'

 

기존 파드를 삭제하고 다시 생성

$ kubectl rollout restart -n kube-system deployment coredns
deployment.apps/coredns restarted

 

coredns 배포 확인

$ kubectl get -n kube-system deployment coredns 
NAME      READY   UP-TO-DATE   AVAILABLE   AGE
coredns   2/2     2            2           6d23h

 

2개의 pod가 준비 완료되면 클러스터 생성부터 CoreDNS pods 띄우는 것까지 성공한 것이다. 만약 CoreDNS 가 정상적으로 생성되지 않았다면 IAM / VPC / Fargate 프로파일을 다시 살펴보아야 한다. Fargate 프로파일은 한번 생성하면 수정할 수 없으므로, 수정이 필요하다면 새로 생성하여 업데이트한 후에 원본을 삭제해야 한다.

 

workload-coredns

 

리소스 생성/삭제 시간이 생각보다 길어 테스트 과정이 상당히 지루했다. 앞으로 할일은 EKS 에서 nginx 화면을 브라우저에서 확인하기?

 


WRITTEN BY
손가락귀신
정신 못차리면, 벌 받는다.

,

계정 분리 때문에 AWS 계정간 도메인을 이전해 보았다. (호스팅 영역은 이전되지 않음)

 

도메인을 다른 AWS 계정으로 이전하기 참고.

 

 

 

도메인을 다른 AWS 계정으로 이전하기 - Amazon Route 53

도메인을 다른 AWS 계정으로 이전하기 하나의 AWS 계정을 사용해 도메인을 등록했는데, 그 도메인을 다른 AWS 계정으로 이전하고 싶다면, AWS 지원 센터에 연락해 이전을 요청할 수 있습니다. 도메

docs.aws.amazon.com

 

accept-domain-transfer-from-another-aws-account — AWS CLI 2.4.1 Command Reference

accept-domain-transfer-from-another-aws-account Synopsis accept-domain-transfer-from-another-aws-account --domain-name --password [--cli-input-json | --cli-input-yaml] [--generate-cli-skeleton ] Options --domain-name (string) --password (string) --cli-inpu

awscli.amazonaws.com

 

transfer-domain-to-another-aws-account — AWS CLI 2.4.1 Command Reference

transfer-domain-to-another-aws-account Description Transfers a domain from the current AWS account to another AWS account. Note the following: Warning When you transfer a domain from one AWS account to another, Route 53 doesn’t transfer the hosted zone t

awscli.amazonaws.com

 

 

AWS Support 는 언제 응답이 올지 몰라 AWS Cli 를 사용했다.

 

> aws route53domains transfer-domain-to-another-aws-account --domain-name example.com --account-id 123456789012
Could not connect to the endpoint URL: "https://route53domains.ap-northeast-2.amazonaws.com/"

 

대부분 이러한 endpoint 관련 에러가 발생할 때는, 해당 리전에 실제로 리소스가 존재하는지 확인해야 하며, 리전을 구분하지 않는 IAM 이나 Route53 같은 리소스의 엔드포인트로 API 호출이 필요할 때는 기본 리전인 미국 동부(버지니아 북부) : us-east-1 을 사용하면 된다.

 

 

1. 보내는 계정에서 도메인 목록 확인

 

> aws --region us-east-1 route53domains list-domains
{
    "Domains": [
        {
            "DomainName": "example.com",
            "AutoRenew": true,
            "TransferLock": false,
            "Expiry": "2031-07-20T15:39:53+09:00"
        },
        ...
    ]
}

 

 

2. 보내는 계정에서 도메인 이전 신청

 

--domain-name 과 --account-id 를 정확하게 입력하고, 응답 파라미터 중 Password 값을 받는 계정에 전달한다.

 

> aws --region us-east-1 route53domains transfer-domain-to-another-aws-account --domain-name example.com --account-id 123456789012 --profile sender
{
    "OperationId": "432483b1-432e-5211-a7af-12cb5815b8fc",
    "Password": "JfNLAZ&)Gg>~`3"
}

 

domain-sender
콘솔 확인

 

3. 받는 계정에서 도메인 승인

 

--domain-name 과 --password 를 정확하게 입력한다.

 

> aws --region us-east-1 route53domains accept-domain-transfer-from-another-aws-account --domain-name example.com --password "JfNLKZ&)Gg>~`3" --profile receiver
{
    "OperationId": "43218608-1a9f-4a23-aa43-432166649b7b"
}

 

domain-receiver
콘솔 확인

 

 


WRITTEN BY
손가락귀신
정신 못차리면, 벌 받는다.

,

AWS https 세팅

Server/AWS 2021. 11. 22. 21:43

ssl-check

 

매번 인프라가 다 해주다보니 ACM 인증서 발급도 한번 못해봤는데, 공짜인줄은 몰랐네;

 

https 통신은 ssl 보안 서버 인증서가 필요하다. ssl 인증서는 한국정보인증을 비롯한 많은 곳에서 구매가 가능한데 AWS Certificate Manager(ACM) 에서는 이 비싼(?) ssl 인증서를 무료로 제공한다. ALB, Cloud Front, API Gateway, ... 등에서 이 인증서를 사용할 수 있으며 따로 설치가 필요없다.

 

예를 들면, Cloud Front 에 S3 와 ssl 인증서를 연결하고 특정 도메인을 Cloud Front 에 연결하는 단계는 다음과 같다.

 

S3 - 특정 버킷의 특정 디렉토리에 리소스 업로드
ACM - 특정 도메인의 인증서 생성
Cloud Front - 배포 생성하여 S3 와 ACM 연결
Route 53 - 레코드 생성하여 Cloud Front 연결

 

 

1. Route 53 DNS 설정

 

AWS 에서 도메인을 관리하기 위해서는 Rourte 53 에 호스팅 영역을 추가하고, 레코드를 생성한다. 외부 도메인일 경우 도메인 구매한 곳(가비아나 카페24 같은?) 에서 네임서버를 해당 NS 값으로 변경해 준다. 아래와 유사한...

 

  • ns-94.awsdns-12.com.
  • ns-1975.awsdns-56.co.uk.
  • ns-1181.awsdns-18.org.
  • ns-743.awsdns-28.net.

 

 

2. ACM 인증서 요청

 

인증서는 반드시 미국 동부(버지니아 북부) 리전(us-east-1)에서 요청해야 하며, 그렇지 않으면 Cloud Front 에서 해당 인증서를 선택할 수 없다. 인증서 요청시, 사용하려는 여러 도메인을 등록해도 되고 아래처럼 모든 2차 도메인 처리(*)와 2차 도메인이 없는 두가지 경우를 등록해도 된다.

 

  • example.com
  • *.example.com

 

해당 도메인에 대해 DNS 검증을 하며, Route 53 에 해당 레코드가 작성되어 있지 않다면 인증서 요청시 생성된 CNAME 으로 레코드 생성이 가능하다.

 

약 1분 내로 인증서 상태가 [검증 대기 중] 에서 [발급됨] 으로 변경되며, 이제 *.example.com 도메인에 대해 https 통신을 할 수 있다. 검증이 30분에서 이틀까지 걸렸다는 글들도 있던데 난 모르겠고...

 

 

3. Cloud Front 배포 생성

 

  • 원본 도메인(S3) 및 경로 설정
  • 대체 도메인 이름(CNAME) 추가: example.com, www.example.com, ...
  • SSL 인증서 선택
  • 프로토콜 정책: Redirect HTTP to HTTPS (HTTP 시도시 HTTPS 로 연결)
  • 기본값 루트 객체: index.html (default 파일)

 

 

4. Route 53 도메인 연결 (별칭-alias)

 

  • example.com (A) www.example.com.
  • www.example.com (A) d1asdfqwerasdf.cloudfront.net.

 

여기까지 설정했다면 example.com 도메인으로 접속했을 때 https://example.com 으로 연결되며 cloudfront 를 통해 s3 리소스를 확인할 수 있어야 한다. (Response Header 에서 cloudfront 확인) 

 

403 forbidden error 등이 발생한다면, S3 버킷 정책을 public access 가 가능하도록 설정한다.

 

 


WRITTEN BY
손가락귀신
정신 못차리면, 벌 받는다.

,

Tomcat Log - Slack Alarm

Server/AWS 2020. 10. 28. 19:00

톰캣에 특정 키워드가 포함된 에러로그가 발생됐을 때 슬랙으로 알림을 받기 위해 필요한 서비스들은 AWS 의 cloudwatch, sns, lambda 등 이다. 이 서비스들로 과정을 대충 설명하자면...


  • cloudwatch 에 톰캣 로그를 남길 수 있다. 그리고 특정 키워드들의 필터링이 가능하다. 필터링 됐을때 경보(알림)이 가능하다.
  • 경보 설정에서 SNS 로 알림을 전송할 수 있다.
  • SNS 에 알림이 오면 슬랙에 메시지를 전달하는 Lambda 함수를 실행하게 하면 끝.



EC2 로그를 cloudwatch 로...

지표 필터(Metric Filter) 생성

경보를 처리할 SNS(Simple Notification Service) 생성

경보(Alarms) 생성

슬랙 웹훅(WebHooks URL) 생성

람다(Lambda) 생성



1. EC2 로그를 cloudwatch 로...


EC2 의 특정 로그를 cloudwatch 로 전달하기 위해서는 awslogs 가 설치되어 있어야 한다.

아래는 centos7 에서의 설치 및 설정 예이다. (OS 별로 설치 방법은 다름.)


# yum install awslogs
No matches found
 
# curl https://s3.amazonaws.com/aws-cloudwatch/downloads/latest/awslogs-agent-setup.py -O
 
# python ./awslogs-agent-setup.py --region ap-northeast-1
AWS Access Key ID [None]: ********************
AWS Secret Access Key [None]: ****************************************
 
Path of log file to upload: /var/log/tomcat8/api.log
Destination Log Group name: /project1/var/log/tomcat8/api.log
 
Timestamp format: 3. %Y-%m-%d %H:%M:%S (2008-09-08 11:52:54)
cs


curl 로 다운받아 setup 파일을 리전과 함께 실행하면 IAM 및 로그 관련 설정을 하게 된다.

AWS Key 는 CloudWatch Logs 에 대한 권한이 있는 IAM 정보를 적으면 되고, 

EC2 의 어떤 로그 파일을 cloudwatch 로그 그룹으로 생성할 것인지 를 적으면 되고,

로그 파일의 datetime_format 을 선택하면 된다.


위에 설정한 항목들은 /var/awslogs/etc/awslogs.conf 파일에서 수정 및 추가가 가능하다.


...
[/var/log/tomcat8/catalina.log]
datetime_format = %d-%b-%Y %H:%M:%S
file = /var/log/tomcat8/catalina.*.log
buffer_duration = 5000
log_stream_name = {instance_id}
initial_position = start_of_file
log_group_name = /project1/var/log/tomcat8/catalina.log
 
[/var/log/tomcat8/web.log]
datetime_format = %Y-%m-%d %H:%M:%S
file = /var/log/tomcat8/web.log
buffer_duration = 5000
log_stream_name = {instance_id}
initial_position = start_of_file
log_group_name = /project1/var/log/tomcat8/web.log
...
cs


설정을 마쳤으면 awslogs 데몬을 올리고 부팅시 시작되도록 설정한다.


# systemctl start awslogs
# chkconfig awslogs on
cs


여기까지 마쳤다면 cloudwatch log-group 에서 catalina.log 등의 로그를 확인할 수 있다.


설정 중 datetime_format 의 형식대로 로그의 라인을 구분하므로 이 부분을 정확하게 선택하지 않으면 cloudwatch 에서 로그를 볼 수 없을 것이다. 만약 awslogs 데몬이 시작된 후에도 cloudwatch 에 로그가 생성되지 않았다면 /var/log/awslogs.log 파일에서 에러 로그를 확인한다.



2. 지표 필터(Metric Filter) 생성


cloudwatch 특정 로그의 [지표 필터] 탭에서 지표 필터를 생성한다.


우리의 목적은 로그에서 에러 문구를 추출하는 것이므로 [패턴 필터링] 항목에는 필터링할 키워드를 나열한다. error 나 exception 등 원하는 것들을 나열하고 [패턴 테스트] 항목에서 테스트를 할 수 있다. (아래 예에서는 ERROR, Error, error 라는 키워드를 필터링 하였다.) 지표의 세부 정보까지 입력하면 지표 필터가 생성고, 이것은 cloudwatch 의 경보(Alarms) 에서 사용될 것이다.



3. 경보를 처리할 SNS(Simple Notification Service) 생성


SNS 메뉴의 토픽을 표준(standard) 및 default 설정으로 하나 생성한다.

이 토픽은 경보를 받아 람다로 전달될 것이다.



4. 경보(Alarms) 생성


다시 cloudwatch 의 경보(Alarms) 로 돌아와 경보를 생성한다. 이미 생성한 지표를 선택하고 1분안에 에러가 발생한다면, 이미 생성한 SNS 토픽으로 전달하도록 설정한다.



5. 슬랙 웹훅(WebHooks URL) 생성


특정 채널로 메시지를 전달 받기 위해서는 슬랙에서 별도의 WebHooks 를 생성하고 람다에 입력해 주어야 한다.

슬랙앱에서 [Administration]-[Manage Apps] 를 클릭하면 브라우저로 Manage 페이지가 열린다.

webhooks 이 없다면 상단 App 검색창에서 검색하여 [Incoming WebHooks] 를 install 하고 [Add to Slack] 을 클릭하여 WebHooks 를 생성한다.



Post to Cannel 항목에는 메시지를 전달받을 채널을 선택하면 되고 Webhook URL 은 람다에 입력해야 하므로 기록해 놓는다.




6. 람다(Lambda) 생성


SNS 에 알림이 발생하면 실행될 람다를 생성한다.

함수 생성 - Blueprints :  cloudwatch-alarm-to-slack-python  를 선택.

구독할(위에 생성한) SNS 를 선택하고 약간의 코드 수정, 환경 변수 추가만 하면 슬랙으로 알림을 보낼 수 있다.


import boto3
import json
import logging
import os
 
from base64 import b64decode
from urllib.request import Request, urlopen
from urllib.error import URLError, HTTPError
 
 
# The base-64 encoded, encrypted key (CiphertextBlob) stored in the kmsEncryptedHookUrl environment variable
#ENCRYPTED_HOOK_URL = os.environ['kmsEncryptedHookUrl']
# The Slack channel to send a message to stored in the slackChannel environment variable
#SLACK_CHANNEL = os.environ['slackChannel']
 
#HOOK_URL = "https://" + boto3.client('kms').decrypt(
#    CiphertextBlob=b64decode(ENCRYPTED_HOOK_URL),
#    EncryptionContext={'LambdaFunctionName': os.environ['AWS_LAMBDA_FUNCTION_NAME']}
#)['Plaintext'].decode('utf-8')
 
HOOK_URL = os.environ['HOOK_URL']
 
logger = logging.getLogger()
logger.setLevel(logging.INFO)
 
 
def lambda_handler(event, context):
    logger.info("Event: " + str(event))
    message = json.loads(event['Records'][0]['Sns']['Message'])
    logger.info("Message: " + str(message))
 
    alarm_name = message['AlarmName']
    #old_state = message['OldStateValue']
    new_state = message['NewStateValue']
    reason = message['NewStateReason']
 
    slack_message = {
        'text'"%s state is now %s: %s" % (alarm_name, new_state, reason)
    }
 
    req = Request(HOOK_URL, json.dumps(slack_message).encode('utf-8'))
    try:
        response = urlopen(req)
        response.read()
        logger.info("Message posted")
        #logger.info("Message posted to %s", slack_message['channel'])
    except HTTPError as e:
        logger.error("Request failed: %d %s", e.code, e.reason)
    except URLError as e:
        logger.error("Server connection failed: %s", e.reason)
cs


생성된 코드에서 기존 환경 변수인 kmsEncryptedHookUrl 과 slackChannel 을 사용하지 않고 HOOK_URL 을 직접 사용하는 코드로 변경한 것이다. 코드 수정 후 환경 변수 항목에 HOOK_URL 이름으로 WebHooks URL 을 입력하면 완성이다.


이제 톰캣 로그에 ERROR, Error, error 등의 키워드가 표시되면 슬랙으로 아래처럼 알림이 발송될 것이다.




로그 상세를 알람 메시지에 표시하고 싶었지만... 불가...




WRITTEN BY
손가락귀신
정신 못차리면, 벌 받는다.

,