Notice
Recent Posts
Recent Comments
Link
«   2024/09   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
Tags
more
Archives
Today
Total
관리 메뉴

클라우드 엔지니어 꿈나무

Load Balancer를 사용하여 도메인 연결 본문

AWS

Load Balancer를 사용하여 도메인 연결

새싹싹이 2023. 12. 27. 15:33

awscli 설치 

apt update -y
apt install -y awscli

인스턴스 이미지 : ami-0454bb2fefc7de534

 

 

aws configure 로 aws와 연결

aws configure

 

 

 

kubernetes 설치

* bastion cli 및 aws console 쿠버네티스 1.27로 버전 맞추었으나 오류 발생

* aws console 1.27으로 유지, bastion 은 1.23.6 으로 설치 후, 정상 가동

aws 측에서는 버전은 위 아래 1까지 적용 가능하다고 했으나 1.27에서 1.27 가동 불가, 1.26 가동 불가

1.23.6으로 설치 후, 가동

 

쿠버네티스 다운로드

curl -LO "https://storage.googleapis.com/kubernetes-release/release/v1.23.6/bin/linux/amd64/kubectl"

 

kubectl 권한 부여 및 실행 경로 이동

chmod +x ./kubectl && mv ./kubectl /usr/local/bin  # ( = install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl)

 

 

 

eks 생성 tf

더보기

locals {
  cluster_name    = var.cluster_name
  cluster_version = var.cluster_version
  region          = "ap-northeast-2"
  vpc_id          = var.vpc_id
  public_subnets  = var.public_subnets
  private_subnets = var.private_subnets

  tag = {
    Environment = "test"
    Terraform   = "true"
  }
}

module "eks" {
  # https://registry.terraform.io/modules/terraform-aws-modules/eks/aws/latest
  source  = "terraform-aws-modules/eks/aws"
  version = "18.31.0"

  # Cluster Name Setting
  cluster_name    = local.cluster_name
  cluster_version = local.cluster_version

  # Cluster Endpoint Setting
  cluster_endpoint_private_access = true
  cluster_endpoint_public_access  = true


  # Network Setting
  vpc_id     = local.vpc_id
  subnet_ids = local.private_subnets

  # IRSA Enable / OIDC 구성
  enable_irsa = true

  node_security_group_additional_rules = {
    ingress_nodes_karpenter_port = {
      description                   = "Cluster API to Node group for Karpenter webhook"
      protocol                      = "tcp"
      from_port                     = 8443
      to_port                       = 8443
      type                          = "ingress"
      source_cluster_security_group = true
    }
  }

  # Tag Node Security Group
  node_security_group_tags = {
    "karpenter.sh/discovery" = local.cluster_name
  }

  eks_managed_node_groups = {
    initial = {
      instance_types = ["t3a.medium"]
      create_security_group = false
      create_launch_template = false     # do not remove
      launch_template_name = ""          # do not remove

      min_size     = 2
      max_size     = 3
      desired_size = 2

      iam_role_additional_policies = [
        # Required by Karpenter
        "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore"
      ]

      tags = {
      Name = "example-node-group"
      }


    }
  }

  # console identity mapping (AWS user)
  # eks configmap aws-auth에 콘솔 사용자 혹은 역할을 등록
  manage_aws_auth_configmap = true

  aws_auth_users = [
    {
      userarn  = "arn:aws:iam::<계정번호>:user/ <user ID> "
      username = "<user ID>"
      groups   = ["system:masters"]
    },
  ]

  aws_auth_accounts = [
    "<계정 번호>"
  ]
}

// 프라이빗 서브넷 태그
resource "aws_ec2_tag" "private_subnet_tag" {
  for_each    = toset(local.private_subnets)
  resource_id = each.value
  key         = "kubernetes.io/role/internal-elb"
  value       = "1"
}

resource "aws_ec2_tag" "private_subnet_cluster_tag" {
  for_each    = toset(local.private_subnets)
  resource_id = each.value
  key         = "kubernetes.io/cluster/${local.cluster_name}"
  value       = "owned"
}

resource "aws_ec2_tag" "private_subnet_karpenter_tag" {
  for_each    = toset(local.private_subnets)
  resource_id = each.value
  key         = "karpenter.sh/discovery/${local.cluster_name}"
  value       = local.cluster_name
}

// 퍼블릭 서브넷 태그
resource "aws_ec2_tag" "public_subnet_tag" {
  for_each    = toset(local.public_subnets)
  resource_id = each.value
  key         = "kubernetes.io/role/elb"
  value       = "1"
}

*나의 경우 bastion 인스턴스 생성 후, xshell 에서 작업을 했기 때문에 eks 보안 그룹에 443 bastion을 인바운드 규칙으로 추가했다.

 

aws eks 와 연결

aws eks update-kubeconfig --region <Region명> --name<EKS Cluster명>

 

연결 확인

 

 

eksctl 설치하여 진행할 경우, 하기 접은 글 참고

더보기

eksctl 설치

<<참고>>

https://docs.aws.amazon.com/ko_kr/eks/latest/userguide/aws-load-balancer-controller.html

 

AWS Load Balancer Controller 추가 기능 설치 - Amazon EKS

배포된 차트는 보안 업데이트를 자동으로 수신하지 않습니다. 새 차트가 사용 가능해지면 수동으로 업그레이드해야 합니다. 업그레이드 시 이전 명령에서 install을 upgrade로 변경하되, 이전 명령

docs.aws.amazon.com

curl --silent --location "https://github.com/weaveworks/eksctl/releases/latest/download/eksctl_$(uname -s)_amd64.tar.gz" | tar xz -C /tmp

mv /tmp/eksctl /usr/local/bin

eksctl version

 

tf 파일로 역할 생성하였으니 정책  부분 생략

IAM 정책 생성

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

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

 

클러스터에서 IAM OIDC(OpenID Connect) 공급자 연결

eksctl utils associate-iam-oidc-provider --region=ap-northeast-2 --cluster=test-eks-cluster --approve => Amazon EKS (Elastic Kubernetes Service) 

 

IAM 역할 생성

eksctl create iamserviceaccount \
  --cluster=my-cluster \
  --namespace=kube-system \
  --name=aws-load-balancer-controller \
  --role-name AmazonEKSLoadBalancerControllerRole \
  --attach-policy-arn=arn:aws:iam::111122223333:policy/AWSLoadBalancerControllerIAMPolicy \
  --approve

 

오토스케일용 karpenter.tf

더보기

module "karpenter" {
  source  = "terraform-aws-modules/eks/aws//modules/karpenter"
  version = "18.31.0"
  cluster_name = module.eks.cluster_name
  irsa_oidc_provider_arn          = module.eks.oidc_provider_arn
  irsa_namespace_service_accounts = ["karpenter:karpenter"]
  create_iam_role = false
  iam_role_arn    = module.eks.eks_managed_node_groups["initial"].iam_role_arn
}

resource "helm_release" "karpenter" {
  namespace        = "karpenter"
  create_namespace = true

  name                = "karpenter"
  repository          = "oci://public.ecr.aws/karpenter"
  repository_username = data.aws_ecrpublic_authorization_token.token.user_name
  repository_password = data.aws_ecrpublic_authorization_token.token.password
  chart               = "karpenter"
  version             = "v0.20.0"

  set {
    name  = "settings.aws.clusterName"
    value = module.eks.cluster_name
  }

  set {
    name  = "settings.aws.clusterEndpoint"
    value = module.eks.cluster_endpoint
  }

  set {
    name  = "serviceAccount.annotations.eks\\.amazonaws\\.com/role-arn"
    value = module.karpenter.irsa_arn
  }

  set {
    name  = "settings.aws.defaultInstanceProfile"
    value = module.karpenter.instance_profile_name
  }

  set {
    name  = "settings.aws.interruptionQueueName"
    value = module.karpenter.queue_name
  }
}

 

alb 역할 생성 (접은 글)

더보기

module "iam_assumable_role_alb_controller" {
  source                        = "terraform-aws-modules/iam/aws//modules/iam-assumable-role-with-oidc"
  version                       = "5.0.0"
  create_role                   = true
  role_name                     = "${local.cluster_name}-alb-controller"
  role_description              = "Used by AWS Load Balancer Controller for EKS"
  provider_url                  = module.eks.cluster_oidc_issuer_url
  oidc_fully_qualified_subjects = ["system:serviceaccount:kube-system:aws-load-balancer-controller"]
}

data "http" "iam_policy" {
  url = "https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.4.1/docs/install/iam_policy.json"
}

resource "aws_iam_role_policy" "controller" {
  name_prefix = "AWSLoadBalancerControllerIAMPolicy"
  policy      = data.http.iam_policy.response_body
  role        = module.iam_assumable_role_alb_controller.iam_role_name
}

data "aws_iam_policy_document" "additional_permissions" {
  statement {
    effect = "Allow"
    actions = [
      "elasticloadbalancing:AddTags",
    ]
    resources = ["*"]
  }
}

resource "aws_iam_policy" "additional_permissions" {
  name        = "AdditionalPermissions"
  description = "Additional permissions for AWS Load Balancer Controller"
  policy      = data.aws_iam_policy_document.additional_permissions.json
}

resource "aws_iam_role_policy_attachment" "additional_permissions" {
  role       = module.iam_assumable_role_alb_controller.iam_role_name
  policy_arn = aws_iam_policy.additional_permissions.arn
}

 

Cert manager 구성

Cert manager 가 없다면 AWS Load Balancer Controller에서 Certificate를 배포하지 못함

curl -Lo cert-manager.yaml https://github.com/jetstack/cert-manager/releases/download/v1.12.3/cert-manager.yaml 
# cert-manager를 설치한 다음 인증서 구성을 Webhook

#선택 사항
sed -i.bak -e 's|quay.io|<계정 번호>.dkr.ecr.region-code.amazonaws.com|' ./cert-manager.yaml 
#자체 레지스트리 이름으로 세 개의 이미지에 대한 매니페스트 quay.io 로 변경 (개인 리포지토리의 이름이 원본 리포지토리와 동일할 떄

kubectl apply -f cert-manager.yaml

 

ALB Controller 설치

해당 부분에 ServiceAccount 까지 표시되어 있음

curl -Lo v2_5_4_full.yaml https://github.com/kubernetes-sigs/aws-load-balancer-controller/releases/download/v2.5.4/v2_5_4_full.yaml     

#선택 사항 이 부분을 제거하지 않으면 이전 단계에서 서비스 계정에 작성한 필수 주석이 덮어씌어지고, 제거하면 컨트롤러를 삭제할 경우 이전 단계에서 생성한 서비스 계정 유지
sed -i.bak -e 's|your-cluster-name|<클러스터명>|' ./v2_5_4_full.yaml

 

 

해당 yaml 파일에 클러스터 명 수정

(서비스 어카운트까지 생성되는 yaml 코드)

 

만약 service account 를 먼저 생성해준 상태라면 ServiceAccount 부분 삭제

 

kubectl apply -f v2_5_4_full.yaml

 

 

provisioner.yaml

vi provisioner.yaml

apiVersion: karpenter.sh/v1alpha5
kind: Provisioner
metadata:
  name: service
spec:
  taints:
    - key: service
      value: "true"
      effect: NoSchedule
  labels:
    nodeType: service-2023
  requirements:
    - key: "node.kubernetes.io/instance-type"
      operator: In
      values: ["t3.medium","t3a.medium"]
    - key: "topology.kubernetes.io/zone"
      operator: In
      values: [ "ap-northeast-2a", "ap-northeast-2c" ]
    - key: "karpenter.sh/capacity-type"
      operator: In
      values: ["on-demand"]
  providerRef:
    name: service-lt
  ttlSecondsAfterEmpty: 30
  ttlSecondsUntilExpired: 1209600
---
apiVersion: karpenter.k8s.aws/v1alpha1
kind: AWSNodeTemplate
metadata:
  name: service-lt
spec:
  subnetSelector:
    karpenter.sh/discovery/kang-cluster: '*'
  securityGroupSelector:
    aws:eks:cluster-name: kang-cluster   # do not change
  tags:
    karpenter.sh/discovery: kang-cluster

kubectl apply -f provisioner.tf

 

 

namespace.yaml 생성 (=kubectl create ns test-ingress-alb)

vi namespace.yaml

apiVersion: v1
kind: Namespace
metadata:
  name: flask
  
kubectl apply -f namespace.yaml

 

 

deployment.yaml 생성

vi deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: flask
  name: flask
spec:
  revisionHistoryLimit: 5
  replicas: 3
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 0%
  selector:
    matchLabels:
      app.kubernetes.io/name: flask
  template:
    metadata:
      labels:
        app.kubernetes.io/name: flask
    spec:
      containers:
        - name: flask
          image: "끌고 올 이미지 주소"
          imagePullPolicy: IfNotPresent
          ports:
            - name: http
              containerPort: 8080
              protocol: TCP
      nodeSelector:
        nodeType: service-2023
      tolerations:
        - key: service
          operator: "Equal"
          value: "true"
          effect: "NoSchedule"
          
kubectl apply -f deployment.yaml

 

service.yaml

vi service.yaml

apiVersion: v1
kind: Service
metadata:
  namespace: flask
  name: flask
spec:
  type: ClusterIP
  ports:
    - port: 8080
      targetPort: 8080
      protocol: TCP
      name: http
  selector:
    app.kubernetes.io/name: flask

kubectl apply -f service.yaml

 

test-ingress-alb.yaml 생성

vi test-ingress-alb.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  namespace: flask
  name: flask
  annotations:
    kubernetes.io/ingress.class: alb
    alb.ingress.kubernetes.io/load-balancer-name: kang-alb
    alb.ingress.kubernetes.io/target-type: ip
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS": 443}]'
    alb.ingress.kubernetes.io/healthcheck-path: /
    alb.ingress.kubernetes.io/subnets: subnet-####,subnet-####  #퍼블릭 서브넷 
    alb.ingress.kubernetes.io/certificate-arn: <acm 주소> 
spec:
  rules:
    - http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: flask
                port:
                  number: 8080
  tls:
    - hosts:
        - # 실제 도메인으로 교체
      secretName:  # 임의의 시크릿 이름으로 지정

 

 

로드밸런서 생성 확인

 

 

호스팅 영역 생성

 

 

 

 

Route53 연결

레코드 이름 앞에 www 입력 필수

 

 

도메인 이름 입력

연결 확인

 

 

트러블 슈팅

alb-controller 생성 후, pod 조회하면 하기와 같이 CrashLoopBackOff 에러 출력

 

최신 버전인 v2_5_4_full.yaml 다운받아 실행하니 정상 작동



'AWS' 카테고리의 다른 글

AWS Cloudfront 사용하여 route53과 연결하기  (0) 2024.01.03
EKS autoscaling 생성 w/helm  (0) 2024.01.03
AWS OPENVPN 설치  (0) 2023.12.25
AWS ECR 생성 및 레포지토리에 이미지 업로드  (0) 2023.12.10
AWS OpenVPN 으로 로그인  (0) 2023.12.10