# 5. EFK 스택구축 - 구축간에 막힌부분

empty·2021년 1월 5일

EFK-STACK

목록 보기
6/6
post-thumbnail

Kibana배포 후 웹페이지에 접속 시 "Kibana Server Is Not Ready Yet" 출력되는 현상

1. Pod의 로그 확인

단순히 Kibana 서비스에 문제가 발생한 줄 알고 kubectl logs 로 Kibana의 파드의 로그 확인하였음. 확인결과 엘라스틱 서치의 엔드포인트로 연결이 안됨 [http://elasticsearch:9200](http://elasticsearch:9200)

그래서 구글링 결과 6.60 버전 이후로부터는 엘라스틱서치를 연결하는 환경변수의 인자값이 기존 환경변수 ELASTICSEARCH_URLELASTICSEARCH_HOST 로 변경되었다는 것을 알아냄 그래서 Kibana의 매니페스트 파일에 정의되어 있는 환경변수(env) 인자값의 문제가 있는줄 알고 수정하였는데도 안됨..

2. Pod에 직접 접속 후 Curl

kubectl exec -n efk-stack -it kibana-xxxxx /bin/bash 해당 명령어를 사용하여 파드로 접속 후 엘라스틱 서치의 엔드포인트에 curl을 찍어봄.. 예상한대로 안되고 "Could not Resolv Host" 출력됨.

반면 엘라스틱 서치의 IP를 curl한 결과 제대로 찍힌다! 그러면 원인은 엘라스틱 서치 파드와 연결되어 있는 서비스의 도메인 네임에 연결이 안된다는 것인데 그래서 DNS의 문제인가 하고 쿠버네티스의 DNS를 테스트 해봄

3. DNS 확인 (원인파악 완료)

쿠버네티스에서 DNS가 정상적으로 동작중인지는 kubectl get pod -n kube-system 명렁어로 coredns 파드가 RUNNING중인지 확인하거나 컨테이너에 접속 후 nslookup kubernetes를 날리는 방법이 있다.

전자의 경우는 정상적으로 RUNNING 상태였었고 후자의 경우 "Could not Resolv Host"이 출력되었다. ⇒ 원인파악 완료

그렇다면 왜 쿠버네티스의 로컬 dns로 연결이 안되는 것인가?

다양한 이유가 있겠지만 EKS는 기본적으로 AWS의 환경에서 동작하게 된다. AWS에서 동작하기 때문에 여러가지 보안정책을 만족을 해야 EKS 클러스터를 생성하고 관리를 할 수 있다. 보안정책으로는 ACL, 보안그룹, IAM Role 등 여러가지 정책이 있지만 내 문제의 경우는 보안그룹이었다.

EKS클러스터를 생성 하는 순서를 간략하게 살펴보자.

  1. VPC생성 (서브넷, 라우팅 테이블 등 설정함)
  2. EKS클러스터를 관장하는 Role 생성
  3. Role기반으로 EKS클러스터 생성
    • 클러스터의 보안그룹도 같이 생성됨
  4. Node_Group으로 워커노드 구성
    • EKS클러스터는 Node_Group 혹은 Worker_Group으로 워커노드를 구성할 것인지 사용자가 선택할 수 있다.
  5. Fargate프로파일 추가하여 클러스터를 컨트롤 할 수 있는 kubeconfig 파일생성
  6. 해당 kubeconfig파일로 클러스터 관리

여기서 주의깊게 살펴봐야 하는 부분은 바로 보안그룹이 생성되는 2번이다.

EKS클러스터 생성 시 보안그룹은 클러스터의 보안그룹과 워커노드의 보안그룹 두 가지로 크게 나뉜다. 클러스터 보안그룹은 기본 보안그룹과 추가 보안그룹이 생성된다.

*나는 Terraform으로 EKS모듈을 사용하였다.

클러스터 보안 그룹(sg-0ffae9fed16c34fa3)은 단순하게 자기자신의 보안그룹끼리 모든 프로토콜 통신이 가능하도록 설정이 되어있다. (아래사진)

추가 보안 그룹(sg-005c5bdee2f3a9087)은 sg-09c37a27e86ad83b4보안그룹만 HTTPS를 허용하게 설정되어있다.

sg-09c37a27e86ad83b4 보안그룹의 인바운드이다.

즉, 워커노드로 동작하는 EC2들은 '클러스터 보안 그룹'에 속해야 클러스터로 통신할 수 있는데 On-Deman로 사용하는 워커노드는 속해있었지만 Spot-Instance로 사용중인 워커노드는 속해있지 않았다.

여기서 해결방법은

  1. 클러스터 보안그룹의 인바운드에 Spot-Instance의 보안그룹을 추가
  2. Spot-Instance가 생성될 때 클러스터 보안그룹을 포함하게 설정

Terraform으로 EKS를 관리한다면 1번방법은 임시방편이고 2번방법으로 Terraform코드를 수정해야한다. 이왕 코드를 수정하는 겸 해당 테라폼 코드는 테스트용도로만 사용하니 비용절감을 위해 Spot-Instance로만 EKS클러스터를 구성하도록 수정하였다.

###################  Create EKS   ###################
# EKS 클러스터를 프로비저닝합니다.
# 비용절감을 위해 On-Demand 노드 하나, Spot-Instance 노드 하나로 구성합니다.
module "eks" {
  source          = "git::<https://github.com/terraform-aws-modules/terraform-aws-eks.git?ref=v13.2.1>"
  cluster_name    = local.cluster_name
  vpc_id          = module.vpc.aws_vpc_id
  subnets         = module.vpc.private_subnets
  cluster_version = "1.18"
  manage_aws_auth = false

  # EKS Cluster의 보안그룹을 추가시킴
  worker_security_group_id = module.eks.cluster_security_group_id

# This is Important to Use K8S Objects Module's config_path
  write_kubeconfig = true
  config_output_path = pathexpand("~/.kube/kubeconfig_${local.cluster_name}")

  node_groups = [
    {
      name                = "on-demand-1"
      instance_type       = "t3.medium"
      asg_max_size        = 3
      key_name            = aws_key_pair.shin-eks.key_name
      kubelet_extra_args  = "--node-labels=spot=false"
      suspended_processes = ["AZRebalance"]
      additional_tags     = {
        "k8s.io/cluster-autoscaler/enabled" = "true"
      }

      source_security_group_ids = [
        aws_security_group.seunghyeon-bastion-sg.id
      ]
    }
  ]

  worker_groups_launch_template = [
    {
      name                    = "spot-1"
      override_instance_types = ["t3.medium", "t3a.medium"]
      spot_instance_pools     = 5
      asg_max_size            = 5
      asg_desired_capacity    = 1
      key_name                = aws_key_pair.shin-eks.key_name
      kubelet_extra_args      = "--node-labels=node.kubernetes.io/lifecycle=spot"

      # EKS Cluster의 보안그룹을 추가시킴
      additional_security_group_ids = [module.eks.cluster_primary_security_group_id]
      additional_tags = {
        "k8s.io/cluster-autoscaler/enabled" = "true"
      }

      source_security_group_ids = [
        aws_security_group.seunghyeon-bastion-sg.id
      ]
    }
  ]
}

결론

별것도 아닌 문제에 며칠을 해맸다. 아직 트러블 슈팅에 익숙하지 않고 문제가 발생하면 무조건 구글링만 하다보니까 차근차근 생각을 못했던게 문제해결에 시간을 많이 잡아먹은것 같다.

앞으로 클라우드 벤더사에 인프라를 올리게 되면 해당 벤더사에서 제공하는 보안정책을 명확하게 확인하자.

0개의 댓글