Application Load Balancer(ALB) 만들기

이 주제에서는 GKE on AWS를 통해 AWS 애플리케이션 부하 분산기(ALB)를 설정하는 방법을 보여줍니다.

시작하기 전에

GKE on AWS를 사용하기 전에 다음 작업을 수행했는지 확인합니다.

서브넷 태그하기

GKE on AWS에는 ALB 엔드포인트를 포함하는 서브넷에 태그가 필요합니다. GKE on AWS는 AWSCluster 리소스의 spec.Networking.ServiceLoadBalancerSubnetIDs 필드에 지정된 모든 서브넷에 자동으로 태그를 지정합니다.

GKE on AWS를 기존 VPC에 설치했거나 추가 서브넷을 사용하려면 2개 이상의 AWS 가용성 영역의 서브넷에 태그를 적용합니다.

GKE on AWS에 ALB 설정

ALB를 만들려면 먼저 AWS IAM 권한을 설정하고 액세스 키를 제공하여 GKE on AWS를 구성해야 합니다.

AWS IAM 권한 만들기

사용자 클러스터용 ALB를 만들려면 ALB를 만들고 작동할 권한이 있는 AWS IAM 사용자를 설정해야 합니다.

  1. ALB 인그레스 컨트롤러의 IAM 정책을 다운로드합니다. GitHub에서 정책을 검토할 수 있습니다.

    curl -o iam-policy.json https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.4.0/docs/install/iam_policy.json
    
  2. aws 명령줄 도구를 사용하여 ALBIngressControllerIAMPolicy라는 이름의 IAM 정책을 만듭니다.

    aws iam create-policy \
      --policy-name ALBIngressControllerIAMPolicy \
      --policy-document file://iam-policy.json
    

    응답에는 IAM 정책의 Amazon 리소스 이름(ARN)이 포함됩니다. 나중에 사용하기 위해 ARN을 저장합니다.

부하 분산기에 대한 액세스 권한 부여

이 섹션에서는 사용자 정책을 AWS IAM 사용자 또는 구성된 워크로드 아이덴티티가 있는 IAM 역할과 연결합니다.

IAM 사용자

  1. aws 도구를 사용하여 ALB 인그레스 컨트롤러의 IAM 사용자를 만듭니다.

    aws iam create-user \
    --user-name ALB_CONTROLLER_USER_NAME
    

    ALB_CONTROLLER_USER_NAME을 ALB 인그레스 컨트롤러용으로 만들 사용자 이름으로 바꿉니다.

  2. ALBIngressControllerIAMPolicy를 사용자 이름에 연결합니다.

    aws iam attach-user-policy \
     --user-name ALB_CONTROLLER_USER_NAME \
     --policy-arn ALB_IAM_POLICY_ARN
    

    다음을 바꿉니다.

    • ALB_CONTROLLER_USER_NAME을 ALB 인그레스 컨트롤러용으로 만들 사용자 이름으로 바꿉니다.
    • ALB_IAM_POLICY_ARN를 이전에 만든 IAM 정책의 ARN으로 바꿉니다.
  3. ALB 인그레스 컨트롤러 사용자의 AWS IAM 액세스 키를 만듭니다.

    aws iam create-access-key --user-name ALB_CONTROLLER_USER_NAME
    

    ALB_CONTROLLER_USER_NAME을 ALB 인그레스 컨트롤러용으로 만들 사용자 이름으로 바꿉니다.

    aws 명령줄 도구는 액세스 키의 세부정보를 출력합니다.

    {
      "AccessKey": {
        "UserName": ALB_CONTROLLER_USER_NAME
        "AccessKeyId": "AKIAIOSFODNN7EXAMPLE",
        "Status": "Active",
        "SecretAccessKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
        "CreateDate": "2020-07-23T17:53:58Z"
      }
    }
    
  4. 액세스 키와 보안 비밀 액세스 키를 환경 변수에 저장합니다. 이를 사용하여 사용자 클러스터를 구성합니다.

    ALB_ACCESS_KEY_ID=ACCESS_KEY_ID
    ALB_SECRET_ACCESS_KEY=SECRET_ACCESS_KEY
    
  5. 액세스 키와 보안 비밀 액세스 키를 사용하여 클러스터에서 보안 비밀을 만듭니다. ALB 인그레스 컨트롤러는 이 보안 비밀을 사용하여 AWS에 인증하고 ALB를 관리합니다.

    env HTTPS_PROXY=http://localhost:8118 \
      kubectl create secret generic alb-ingress-controller-creds \
      -n kube-system \
      --from-literal=access_key_id=$ALB_ACCESS_KEY_ID \
      --from-literal=secret_access_key=$ALB_SECRET_ACCESS_KEY
    

워크로드 아이덴티티가 있는 역할

워크로드 아이덴티티로 사용자 클러스터 만들기의 단계를 완료합니다. 정책을 만들 때 EXISTING_AWS_POLICY 값에 ALBIngressControllerIAMPolicy의 ARN을 사용합니다.

클러스터 구성

ALB를 구성하려면 사용자 클러스터에 다음 구성요소를 설치해야 합니다.

  1. GitHub에서 매니페스트를 설치하여 Jetstack cert-manager를 배포합니다.

    env HTTPS_PROXY=http://localhost:8118 \
      kubectl apply \
      --validate=false \
      -f https://github.com/jetstack/cert-manager/releases/download/v1.5.4/cert-manager.yaml
    
  2. GitHub에서 AWS 부하 분산기 컨트롤러 매니페스트를 다운로드합니다.

    curl -Lo v2_4_0_full.yaml https://github.com/kubernetes-sigs/aws-load-balancer-controller/releases/download/v2.4.0/v2_4_0_full.yaml
    
  3. 워크로드 아이덴티티가 있는 IAM 사용자 또는 역할을 사용하는 경우 선택합니다.

    IAM 사용자

    v2_4_0_full.yaml 파일을 수정하고 kind: Deployment를 검색합니다. 배포 객체를 수정된 버전으로 바꿉니다.

    kind: Deployment
    metadata:
      labels:
        app.kubernetes.io/component: controller
        app.kubernetes.io/name: aws-load-balancer-controller
      name: aws-load-balancer-controller
      namespace: kube-system
    spec:
      replicas: 1
      selector:
      matchLabels:
        app.kubernetes.io/component: controller
        app.kubernetes.io/name: aws-load-balancer-controller
      template:
        metadata:
          labels:
            app.kubernetes.io/component: controller
            app.kubernetes.io/name: aws-load-balancer-controller
        spec:
          containers:
            - args:
              - --cluster-name=CLUSTER_UID
              - --aws-region=AWS_REGION
              - --aws-vpc-id=AWS_VPC_ID
              - --ingress-class=alb
              - --disable-restricted-sg-rules=true
            image: amazon/aws-alb-ingress-controller:v2.4.0
            env:
            - name: AWS_ACCESS_KEY_ID
              valueFrom:
                secretKeyRef:
                  name: alb-ingress-controller-creds
                  key: access_key_id
            - name: AWS_SECRET_ACCESS_KEY
              valueFrom:
                secretKeyRef:
                  name: alb-ingress-controller-creds
                  key: secret_access_key
            livenessProbe:
              failureThreshold: 2
              httpGet:
                path: /healthz
                port: 61779
                scheme: HTTP
              initialDelaySeconds: 30
              timeoutSeconds: 10
            name: controller
            ports:
            - containerPort: 9443
              name: webhook-server
              protocol: TCP
            resources:
              limits:
                cpu: 200m
                memory: 500Mi
              requests:
                cpu: 100m
                memory: 200Mi
            securityContext:
              allowPrivilegeEscalation: false
              readOnlyRootFilesystem: true
              runAsNonRoot: true
            volumeMounts:
            - mountPath: /tmp/k8s-webhook-server/serving-certs
              name: cert
              readOnly: true
          priorityClassName: system-cluster-critical
          securityContext:
            fsGroup: 1337
          serviceAccountName: aws-load-balancer-controller
          terminationGracePeriodSeconds: 10
          volumes:
          - name: cert
            secret:
              defaultMode: 420
              secretName: aws-load-balancer-webhook-tls
        ---
    

    다음을 바꿉니다.

    • AWS_ACCESS_KEY_ID: AWS IAM 사용자를 만들 때 생성된 AWS 액세스 키
    • AWS_SECRET_ACCESS_KEY: AWS IAM 사용자를 만들 때 생성된 AWS 보안 비밀 액세스 키

    워크로드 아이덴티티가 있는 역할

    v2_4_0_full.yaml 파일을 수정하고 kind: Deployment를 검색합니다. Deployment 객체를 수정된 버전으로 바꿉니다.

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      labels:
        app.kubernetes.io/component: controller
        app.kubernetes.io/name: aws-load-balancer-controller
      name: aws-load-balancer-controller
      namespace: kube-system
    spec:
      replicas: 1
      selector:
        matchLabels:
          app.kubernetes.io/component: controller
          app.kubernetes.io/name: aws-load-balancer-controller
      template:
        metadata:
          labels:
            app.kubernetes.io/component: controller
            app.kubernetes.io/name: aws-load-balancer-controller
        spec:
          containers:
          - args:
            - --cluster-name=CLUSTER_UID
            - --aws-region=AWS_REGION
            - --aws-vpc-id=AWS_VPC_ID
            - --ingress-class=alb
            - --disable-restricted-sg-rules=true
            image: amazon/aws-alb-ingress-controller:v2.4.0
            env:
            - name: AWS_ROLE_ARN
              value: LB_CONTROLLER_ROLE_ARN
            - name: AWS_WEB_IDENTITY_TOKEN_FILE
              value: /var/run/secrets/aws-load-balancer-controller/serviceaccount/token
            livenessProbe:
              failureThreshold: 2
              httpGet:
                path: /healthz
                port: 61779
                scheme: HTTP
              initialDelaySeconds: 30
              timeoutSeconds: 10
            name: controller
            ports:
            - containerPort: 9443
              name: webhook-server
              protocol: TCP
            resources:
              limits:
                cpu: 200m
                memory: 500Mi
              requests:
                cpu: 100m
                memory: 200Mi
            securityContext:
              allowPrivilegeEscalation: false
              readOnlyRootFilesystem: true
              runAsNonRoot: true
            volumeMounts:
            - mountPath: /tmp/k8s-webhook-server/serving-certs
              name: cert
              readOnly: true
            - mountPath: /var/run/secrets/aws-load-balancer-controller/serviceaccount
              name: aws-iam-token
              readOnly: true
          priorityClassName: system-cluster-critical
          securityContext:
            fsGroup: 1337
          serviceAccountName: aws-load-balancer-controller
          terminationGracePeriodSeconds: 10
          volumes:
          - name: cert
            secret:
              defaultMode: 420
              secretName: aws-load-balancer-webhook-tls
          - name: aws-iam-token
            projected:
              defaultMode: 420
              sources:
              - serviceAccountToken:
                  audience: sts.amazonaws.com
                  expirationSeconds: 86400
                  path: token
    ---
    

    다음을 바꿉니다.

    • CLUSTER_UID: 클러스터의 UID입니다. 예를 들면 bbc7d232-21f6-4bb1-90dd-4b064cf8ccf8입니다.
    • AWS_VPC_ID: AWS VPC의 ID입니다. 예를 들면 vpc-1234567890abc입니다.
    • LB_CONTROLLER_ROLE_ARN: AWSLBControllerRole 역할의 ARN
    • AWS_REGION: 클러스터의 AWS 리전입니다. 예를 들면 us-east-1입니다.
  4. 클러스터에 컨트롤러를 적용합니다.

    env HTTPS_PROXY=http://localhost:8118 \
      kubectl apply -f v2_4_0_full.yaml
    

    GKE on AWS는 ALB 인그레스 컨트롤러를 설치합니다.

ALB 만들기

이 섹션에서는 게임 2048에 대한 2차 저작물을 처리하는 ALB 예시를 만듭니다.

  1. 다음 YAML 구성을 2048.yaml이라는 파일에 복사합니다. 구성은 Kubernetes 네임스페이스, 서비스, 배포를 만듭니다. 인그레스를 통해 배포를 노출시킵니다.

    apiVersion: v1
    kind: Namespace
    metadata:
      name: "2048-game"
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: "service-2048"
      namespace: "2048-game"
    spec:
      ports:
        - port: 80
          targetPort: 80
          protocol: TCP
      type: NodePort
      selector:
        app: "2048"
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: "2048-deployment"
      namespace: "2048-game"
    spec:
      selector:
        matchLabels:
          app: "2048"
      replicas: 5
      template:
        metadata:
          labels:
            app: "2048"
        spec:
          containers:
          - image: alexwhen/docker-2048
            imagePullPolicy: Always
            name: "2048"
            ports:
            - containerPort: 80
    ---
    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
      name: "2048-ingress"
      namespace: "2048-game"
      annotations:
        kubernetes.io/ingress.class: alb
        alb.ingress.kubernetes.io/scheme: internet-facing
      labels:
        app: 2048-ingress
    spec:
      rules:
        - http:
            paths:
              - path: /*
                backend:
                  serviceName: "service-2048"
                  servicePort: 80
    
  2. kubectl를 사용하여 클러스터에 구성을 적용합니다.

    env HTTPS_PROXY=http://localhost:8118 \
      kubectl apply -f 2048.yaml
    
  3. kubectl를 사용하여 인그레스 리소스의 상태를 확인합니다.

    env HTTPS_PROXY=http://localhost:8118 \
      kubectl get ingress -n 2048-game 2048-ingress
    

    인그레스 상태가 표시됩니다. ADDRESS 열에는 인그레스의 엔드포인트가 포함됩니다.

    NAME           HOSTS   ADDRESS                                                             PORTS   AGE
    2048-ingress   *       123456-2048game-2048ingr-6fa0-abcdefg.us-east-1.elb.amazonaws.com   80      2m19s
    
  4. 브라우저에서 ALB 엔드포인트로 이동합니다. 예를 들면 http://123456-2048game-2048ingr-6fa0-abcdefg.us-east-1.elb.amazonaws.com입니다. 2048 게임이 표시됩니다.

다음 단계