Terraform을 사용하여 네트워크 로드 밸런서 구성

응용 프로그램에서 어떤 형식의 부하 균형을 사용합니까?대답하지 마.이것은 반문구다.네가 감히 내가 옳다고 내기를 걸다니, 네가 도발적으로 비명을 질렀다.그렇지 않으면, 나는 어떻게 유량의 고른 분포를 확보할 것인가?
부하 평형기는 각종 형상과 사이즈가 있다.과거에는 운영진의 관심사였다.응용 프로그램 개발자로서, 너는 그것들을 고려할 필요 없이 수년의 시간을 들일 수 있다.구름 위에서 상황이 항상 그렇지는 않다.다행히도 AWS는 easy과 같은 자원을 만들어 주었습니다.만약 네가 Infrastructure as Code을 사용한다면 상황은 더욱 나빠질 것이다.본고에서, 나는 Terraform을 사용하여 네트워크 부하 평형기의 실례를 설정할 것이다.

AWS입니다.물론 서로 경쟁할 수 있는 선택은 다양하다


AWS에는 세 가지 유형의 로드 밸런서가 있습니다.
  • Classic
  • Network Load Balancer (NLB)
  • Application Load Balancer (ALB)
  • 고전적인 부하 평형기는 과거의 유적이 되고 있다.일반적으로 NLB(4층)와 ALB(7층) 사이에서 선택할 수 있습니다.만약 네가 the number of features을 걱정한다면 그들은 너를 도와 해결할 것이다.이 세 가지는 모두 관리를 받는 인프라 시설이다.AWS는 가용성과 확장성을 투명하게 처리합니다.
    우리 NLB에 대해 이야기합시다.4층으로서 사용하는 응용 프로토콜을 모른다는 뜻이다.그럼에도 불구하고 NLB는 당신의 생활 속의 대부분의 부하 균형 수요를 만족시킬 수 있다.HTTP 경로를 기반으로 하는 경로를 원하지 않으면그럼 ALB가 필요해요. 나중에 댓글로 소개해 드릴게요.

    기본 로드 밸런서 설정


    부하 균형기를 설정하려면 세 가지 종류의 자원을 설정해야 한다.
  • 로드 밸런서 자체
  • 트래픽 전달 탐지기
  • 트래픽이 목적지에 도달하도록 보장하는 타겟 그룹
  • 가장 전형적인 설정은 가상 개인 클라우드(VPC)로 공공 서브넷과 개인 서브넷이 있다.부하 평형기가 공공 서브넷에 들어가다.이러한 인스턴스는 개인 서브넷에 있습니다.다운타임을 방지하기 위해 모든 컨텐츠를 다중 가용성 영역(AZ)에 구축합니다.

    만약에 우리가 기존의 VPC(vpc_id으로 표시됨)를 가지고 있다면 이 코드 세그먼트는 부하 균형기를 만들 것이다.
    data "aws_subnet_ids" "this" {
      vpc_id = var.vpc_id
    
      tags = {
        Tier = "Public"
      }
    }
    
    resource "aws_lb" "this" {
      name = "basic-load-balancer"
      load_balancer_type = "network"
      subnets = data.aws_subnet_ids.this.ids
    
      enable_cross_zone_load_balancing = true
    }
    
    aws_lb 리소스는 NLB와 ALB를 모두 나타내므로 load_balancer_type 매개 변수에 따라 다릅니다.일부 매개 변수는 한 종류에만 적용되기 때문에 문서를 자세히 읽어야 합니다.enable_cross_zone_load_balancinginteresting parameter입니다.문제가 발생하면 다른 AZ에 트래픽을 전송하여 가동 중지를 방지합니다.애리조나를 가로지르는 교통은 공짜가 아니니 이례적이지!

    청중.


    우리의 부하 균형기는 현재 좋은 경청자가 아니다.우리는 반드시 이 문제를 해결해야 한다.aws_lb_listener 리소스를 통해 처리할 포트와 처리 방법을 지정합니다.우리는 포트 80과 443을 감청하려고 하기 때문에 for_each을 사용하여 두 개의 다른 자원을 설정할 것이다.코드 좀 봅시다.
    variable "ports" {
      type = map(number)
      default = {
        http = 80
        https = 443
      }
    }
    
    resource "aws_lb_listener" "this" {
      for_each = var.ports
    
      load_balancer_arn = aws_lb.this.arn
    
      protocol = "TCP"
      port = each.value
    
      default_action {
        type = "forward"
        target_group_arn = aws_lb_target_group.this[each.key].arn
      }
    }
    
    ports 변수에 정의된 포트를 볼 수 있습니다.다음은 protocol.요청만 전달하려면 TCP 또는 UDP를 사용합니다.TLS를 프로토콜로 사용하여 terminate the TLS connection을 선택할 수도 있습니다.하지만 인증서를 만들어야 합니다.
    포트와 프로토콜이 존재하는 후에 우리는 조작을 실행해야 한다.가장 흔히 볼 수 있는 조작은 그것을 우리의 수신자 목표 그룹에 전달하는 것이다.그 밖에 우리는 방향을 바꾸고 결과를 복원하며 심지어 신분 검증까지 할 수 있다.참고로 저는 this article에서 신분 검증을 어떻게 하는지 보여 드렸습니다.

    목표 집단


    마지막 단계는 부하 밸런스가 누가 요청을 받아들일지 알 수 있도록 목표 그룹을 정의하는 것입니다.우리는 aws_lb_target_group 자원을 사용하여 이 점을 실현한다.여기에서 우리는 다시 갈라진다. 왜냐하면 다른 가능성이 있기 때문이다.

    실례에 기초하다


    목표 그룹은 특정한 실례를 가리킬 수 있다.기본 target_type입니다.실례를 명확하게 지정하고 싶지 않습니다. (만약 그것들이 실패하면 어떻게 합니까?)Autoscaling Group (ASG)을 만듭니다.코드에 ASG가 있다고 가정합니다.
    resource "aws_lb_target_group" "this" {
      for_each = var.ports
    
      port = each.value
      protocol = "TCP"
      vpc_id = var.vpc_id
    
      stickiness = []
    
      depends_on = [
        aws_lb.this
      ]
    
      lifecycle {
        create_before_destroy = true
      }
    }
    
    resource "aws_autoscaling_attachment" "target" {
      for_each = var.ports
    
      autoscaling_group_name = var.autoscaling_group_name
      alb_target_group_arn = aws_lb_target_group.this[each.value].arn
    }
    
    의존항에 대한 정확한 모델링을 위해lb자원을 포함하는 depends_on 블록을 추가했습니다.그렇지 않으면 자원을 없애는 것이 정상적으로 작동하지 못할 수도 있습니다.

    IP 기반


    인스턴스 ID가 아닌 IP를 사용하는 경우 target_type ip을 사용합니다.이러한 IP는 data 리소스를 통해 사용 가능하고 읽을 수 있다고 가정합니다.이들은 aws_lb_target_group_attachment을 통해 타깃 그룹과 연결했다.
    resource "aws_lb_target_group" "this" {
      for_each = var.ports
    
      port = each.value
      protocol = "TCP"
      vpc_id = var.vpc_id
      target_type = "ip"
    
      depends_on = [
        aws_lb.this
      ]
    
      lifecycle {
        create_before_destroy = true
      }
    }
    
    resource "aws_lb_target_group_attachment" "this" {
      for_each = local.ports_ips_product
    
      target_group_arn = aws_lb_target_group.this[each.value.port].arn
      target_id = each.value.ip
      availability_zone = "all"
      port = each.value
    }
    
    locals {
      ports_ips_product = flatten(
        [
          for port in values(var.ports): [
            for eni in keys(data.aws_network_interface.this): {
              port = port
              ip = data.aws_network_interface.this[eni].private_ip
            }
          ]
        ]
      )
    }
    
    data "aws_network_interfaces" "this" {
      filter {
        name = "description"
        values = ["ENI for target"]
      }
    }
    
    data "aws_network_interface" "this" {
      for_each = toset(data.aws_network_interfaces.this.ids)
      id = each.key
    }
    
    ENIs과의 연결은 [port, ip] 대 목록을 나타낸다.이것은 모든 것을 정확하게 정의하기 위해 서투른 지형 고리가 필요하다.
    이것은 두 가지 전형적인 예이지만, 이것은 유일한 방법이 아니다.ECS은 직접 액세스를 위해 타겟 그룹을 추가할 수 있습니다.Lambda을 사용하는 경우 ALB가 필요합니다.
    나는 만 자짜리 글을 쓰는 것을 피하기 위해 많은 세부 사항을 빠뜨렸다.각 대상 그룹과 연관된 상태 점검(health_check), 사용된 알고리즘(load_balancing_algorithm_type) 및 기타 여러 항목을 사용자 정의할 수 있습니다.융통성이 압도적일 수도 있다.나는 어릴 때부터 착수할 것을 건의한다.

    안전 조직


    네, 안전팀입니다.일정 시간마다 반짝이는 새로운 인프라에서 curl을 운행하면 시간 초과가 발생한다.피할 수 없이 너는 security groups을 잊어버렸다.
    네트워크 부하 균형기 자체는 관련 보안 그룹이 없습니다.인스턴스와 IP 기반 대상 그룹에 대해 로드 밸런서에서 대상 IP로의 트래픽을 허용하는 규칙을 추가할 수 있습니다.
    resource "aws_security_group" "this" {
      description = "Allow connection between NLB and target"
      vpc_id = var.vpc_id
    }
    
    resource "aws_security_group_rule" "ingress" {
      for_each = var.ports
    
      security_group_id = aws_security_group.this.id
      from_port = each.value
      to_port = each.value
      protocol = "tcp"
      type = "ingress"
      cidr_blocks = ["0.0.0.0/0"]
    }
    

    로드 밸런서에 액세스


    이렇게이런 자원이 있으면, 우리는 작업 부하 균형기를 하나 가지게 될 것이다!
    모든 로드 밸런서는 자동으로 할당된 DNS 엔트리를 통해 액세스할 수 있습니다.AWS CLI 덕분에 프로그래밍 방식으로 찾을 수 있습니다.
    export LB_NAME="basic-load-balancer"
    dns=$(aws elb describe-load-balancers --load-balancer-name $LB_NAME | jq -r '.LoadBalancerDescriptions[0].DNSName')
    nslookup $dns
    
    만약 등록 목표가 있다면, 우리는 dns의 내용을 사용하여 그것을 조회하고, 우리의 설정이 유효한지 확인할 수 있습니다.

    내부 로드 밸런서


    부하 균형기가 항상 공개적으로 사용할 수 있는 것은 아니다.VPC endpoints을 사용하여 트래픽을 AWS 네트워크에 유지한다고 가정합니다.VPC 엔드포인트 서비스 이후에 로드 밸런서가 있을 경우 이를 공개하고 싶지 않습니다.대신 internal 매개 변수를 true으로 설정합니다.LB는 개인 서브넷에 있을 수 있습니다.

    조작하다


    '운영'이라는 단어는 좀 강하다.이곳에는 조작할 만한 물건이 그리 많지 않다.적어도 우리한테는 아니야.그럼에도 불구하고 우리는 그래도 한번 생각해 보자.
    즉시 사용할 수 있는 CloudWatch 지표를 대량으로 내보냅니다.AWS 콘솔에는 보기 좋은 그래프가 있습니다.만약 네가 원한다면, 너는 다른 모니터링 도구를 사용할 수 있다.

    예쁜 라인이 모든 걸 더 좋아지게 해요.
    원가는요?pricing page에서 보듯이 NLB는 고정 가격에 로드 밸런서 용량 단위(LCU)를 기반으로 하는 상당히 신비로운 운영 비용을 제공합니다.솔직히 지출을 감시하는 가장 간단한 방법은 원가 관리자에서 몇 달 전의 상황을 살펴보는 것이다.
    마지막은 표현이야.NLB의 규모는 내일이 없는 것과 같다.모든 유일한 목표 IP는 55000개의 동시 연결을 지원할 수 있으며 프로그램이 잿더미로 붕괴된 후에 전체 과정은 즐겁게 요청을 전달할 것이다.'관리' 라는 단어는 정말 적합하다. 왜냐하면 자원 공급을 초과하는 어떤 일도 할 필요가 거의 없기 때문이다.

    결론


    부하 평형기는 모든 클라우드 컴퓨팅 설정의 불가결한 일부분이다.이것도 하나의 거대한 화제이기 때문에 나는 표면에 닿을 수밖에 없다.그러나 이것은 우리로 하여금 견고한 기초에서 시작하게 하기에 충분하다.

    좋은 웹페이지 즐겨찾기