실습

Ingress-NGINX Controller

Introduction

  1. Helm 차트 리포지토리 추가

    {
        helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
        helm repo update
    }
  2. Ingress-NGINX Controller 설치

    helm install ingress-nginx ingress-nginx/ingress-nginx -n kube-system \
    --set controller.service.annotations.service\\.beta\\.kubernetes\\.io/aws-load-balancer-type=nlb
  3. 배포된 구성요소 확인

    kubectl -n kube-system get all -l app.kubernetes.io/name=ingress-nginx
  4. 생성된 Service 확인

    kubectl -n kube-system get svc ingress-nginx-controller
  5. 생성된 NLB 상세 내용 확인

    aws elbv2 describe-load-balancers --names \
    $(kubectl -n kube-system get svc ingress-nginx-controller \
    -o jsonpath='{.status.loadBalancer.ingress[0].hostname}' \
    | grep -o -E '^[a-z0-9]+' ) --no-cli-pager
  6. 웹 브라우저를 열고 Service의 External IP 주소로 접속 - 아래의 명령어로 주소 확인 가능

    kubectl -n kube-system get svc ingress-nginx-controller \
    -o jsonpath='{.status.loadBalancer.ingress[0].hostname}{"\n"}' 
  7. 생성된 NGINX Ingress Controller Pod에서 실행중인 프로세스 확인

    kubectl -n kube-system exec deploy/ingress-nginx-controller -- \
    ps aux
  8. NGINX 설정 파일 리뷰

    kubectl -n kube-system exec deploy/ingress-nginx-controller -- \
    cat /etc/nginx/nginx.conf
  9. 생성된 NLB 주소로 접속했을때 404 Not Found가 나오는 이유 확인

    kubectl -n kube-system exec deploy/ingress-nginx-controller -- \
    cat /etc/nginx/nginx.conf | grep 404 -B 9 -A 2

Virtual hosting

  1. Deployment 생성

    {
        kubectl create deployment nginx --image=nginx --port=80
        kubectl create deployment httpd --image=httpd --port=80
    }
  2. Service 생성

    {
        kubectl expose deploy nginx 
        kubectl expose deploy httpd
    }
  3. 생성된 Service 확인

    kubectl get svc -l app
  4. Ingress 생성

    cat <<EOF | kubectl apply -f -
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: nginx
    spec:
      rules:
      - host: nginx.example.com
        http:
          paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: nginx
                port:
                  number: 80
    ---
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: httpd
    spec:
      rules:
      - host: httpd.example.com
        http:
          paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: httpd
                port:
                  number: 80
    EOF
  5. 생성된 Ingress 확인

    kubectl get ing
  6. NGINX Ingress Controller 로그 확인

    kubectl logs -n kube-system deploy/ingress-nginx-controller
  7. 생성된 IngressClass 확인

    kubectl get ingressclass
  8. Ingress 수정 - IngressClass 명시

    cat <<EOF | kubectl apply -f -
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: nginx
    spec:
      ingressClassName: nginx
      rules:
      - host: nginx.example.com
        http:
          paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: nginx
                port:
                  number: 80
    ---
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: httpd
    spec:
      ingressClassName: nginx
      rules:
      - host: httpd.example.com
        http:
          paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: httpd
                port:
                  number: 80
    EOF
  9. Ingress 객체에 발생한 Event 확인

    kubectl describe ing
  10. NGINX Ingress Controller 엔드포인트 확인

    kubectl -n kube-system get svc ingress-nginx-controller
  11. NGINX Ingress Controller 로그 확인

    kubectl logs -n kube-system deploy/ingress-nginx-controller
  12. Ingress에 명시한 Host 주소를 HTTP 헤더값에 추가하고 NGINX Ingress Controller 엔드포인트 호출

    curl -H "Host: nginx.example.com" \
    $(kubectl -n kube-system get svc ingress-nginx-controller \
    -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')
    curl -H "Host: httpd.example.com" \
    $(kubectl -n kube-system get svc ingress-nginx-controller \
    -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')
  13. NGINX 설정 파일에 위에서 명시한 Host들에 대한 설정들이 추가 되었는지 확인

    kubectl -n kube-system exec deploy/ingress-nginx-controller -- \
    cat /etc/nginx/nginx.conf \
    | grep "server_name nginx.example.com" -B 1 -A 130
    kubectl -n kube-system exec deploy/ingress-nginx-controller -- \
    cat /etc/nginx/nginx.conf \
    | grep "server_name httpd.example.com" -B 1 -A 130
  14. Ingress 삭제

    kubectl delete ing nginx httpd
  15. NGINX 설정 파일에 위에서 삭제한 Ingress 명시한 Host들에 대한 설정들이 삭제 되었는지 확인

    kubectl -n kube-system exec deploy/ingress-nginx-controller -- \
    cat /etc/nginx/nginx.conf \
    | grep "server_name nginx.example.com" -B 1 -A 130
    kubectl -n kube-system exec deploy/ingress-nginx-controller -- \
    cat /etc/nginx/nginx.conf \
    | grep "server_name httpd.example.com" -B 1 -A 130
  16. 리소스 삭제

    {
        kubectl delete svc nginx httpd
        kubectl delete deploy nginx httpd
    }

Path based routing

  1. 리소스 생성

    {
        kubectl create deployment nginx --image=nginx --port=80
        kubectl create deployment httpd --image=httpd --port=80
        kubectl expose deploy nginx 
        kubectl expose deploy httpd
    }
  2. 생성된 리소스 확인

    kubectl get all -l app
  3. Ingress 생성

    cat <<EOF | kubectl apply -f -
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: my-app
    spec:
      ingressClassName: nginx
      rules:
      - host: myapp.example.com
        http:
          paths:
          - path: /nginx
            pathType: Prefix
            backend:
              service:
                name: nginx
                port:
                  number: 80
          - path: /httpd
            pathType: Prefix
            backend:
              service:
                name: httpd
                port:
                  number: 80
    EOF
  4. Ingress 객체에 발생한 Event 확인

    kubectl describe ing
  5. NGINX Ingress Controller 로그 확인

    kubectl logs -n kube-system deploy/ingress-nginx-controller
  6. Ingress에 명시한 Host 주소를 HTTP 헤더값에 추가하고 각각의 경로로 NGINX Ingress Controller 엔드포인트 호출

    curl -H "Host: myapp.example.com" \
    $(kubectl -n kube-system get svc ingress-nginx-controller \
    -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')/nginx
    curl -H "Host: myapp.example.com" \
    $(kubectl -n kube-system get svc ingress-nginx-controller \
    -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')/httpd
  7. NGINX Ingress Controller 로그 확인

    kubectl logs -n kube-system deploy/ingress-nginx-controller

    e.g.

    52.78.3.76 - - [24/Jul/2022:08:16:10 +0000] "GET /nginx HTTP/1.1" 404 153 "-" "curl/7.79.1" 86 0.003 [default-nginx-80] [] 192.168.44.219:80 153 0.004 404 b69bb70369b94d0208af4cf26d5f19a5
    52.78.3.76 - - [24/Jul/2022:08:16:21 +0000] "GET /httpd HTTP/1.1" 404 196 "-" "curl/7.79.1" 86 0.001 [default-httpd-80] [] 192.168.88.56:80 196 0.000 404 efdfacfbf5858ebc27a01dcb815da8d9
  8. Ingress 수정 - https://kubernetes.github.io/ingress-nginx/examples/rewrite/

    cat <<EOF | kubectl apply -f -
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: my-app
      annotations:
        nginx.ingress.kubernetes.io/rewrite-target: /
    spec:
      ingressClassName: nginx
      rules:
      - host: myapp.example.com
        http:
          paths:
          - path: /nginx
            pathType: Prefix
            backend:
              service:
                name: nginx
                port:
                  number: 80
          - path: /httpd
            pathType: Prefix
            backend:
              service:
                name: httpd
                port:
                  number: 80
    EOF
  9. NGINX Ingress Controller 로그 확인

    kubectl logs -n kube-system deploy/ingress-nginx-controller
  10. Ingress에 명시한 Host 주소를 HTTP 헤더값에 추가하고 각각의 경로로 NGINX Ingress Controller 엔드포인트 호출

    curl -H "Host: myapp.example.com" \
    $(kubectl -n kube-system get svc ingress-nginx-controller \
    -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')/nginx
    curl -H "Host: myapp.example.com" \
    $(kubectl -n kube-system get svc ingress-nginx-controller \
    -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')/httpd
  11. 새로운 리소스 생성

    {
        kubectl create deployment v1 --image=youngwjung/nginx:v1 --port=80
        kubectl create deployment v2 --image=youngwjung/nginx:v2 --port=80
        kubectl expose deploy v1 
        kubectl expose deploy v2
    }
  12. 새로 배포한 애플리케이션 호출

    kubectl exec deploy/v1 -- curl -s localhost
    kubectl exec deploy/v2 -- curl -s localhost
  13. Ingress 수정

    cat <<EOF | kubectl apply -f -
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: my-app
      annotations:
        nginx.ingress.kubernetes.io/rewrite-target: /
    spec:
      ingressClassName: nginx
      rules:
      - host: myapp.example.com
        http:
          paths:
          - path: /nginx
            pathType: Prefix
            backend:
              service:
                name: nginx
                port:
                  number: 80
          - path: /httpd
            pathType: Prefix
            backend:
              service:
                name: httpd
                port:
                  number: 80
          - path: /nginx/v1
            pathType: Exact
            backend:
              service:
                name: v1
                port:
                  number: 80
          - path: /httpd/v2
            pathType: Exact
            backend:
              service:
                name: v2
                port:
                  number: 80
    EOF
  14. NGINX Ingress Controller 로그 확인

    kubectl logs -n kube-system deploy/ingress-nginx-controller
  15. Ingress에 명시한 Host 주소를 HTTP 헤더값에 추가하고 새롭게 명시한 경로들로 NGINX Ingress Controller 엔드포인트 호출

    curl -H "Host: myapp.example.com" \
    $(kubectl -n kube-system get svc ingress-nginx-controller \
    -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')/nginx/v1
    curl -H "Host: myapp.example.com" \
    $(kubectl -n kube-system get svc ingress-nginx-controller \
    -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')/httpd/v2
  16. 리소스 삭제

    {
        kubectl delete svc nginx httpd v1 v2
        kubectl delete deploy nginx httpd v1 v2
        kubectl delete ing my-app
    }

TLS/SSL

  1. CFSSL 설치

    {
        VERSION=$(curl --silent "https://api.github.com/repos/cloudflare/cfssl/releases/latest" | grep '"tag_name"' | sed -E 's/.*"([^"]+)".*/\1/')
        VNUMBER=${VERSION#"v"}
        wget https://github.com/cloudflare/cfssl/releases/download/${VERSION}/cfssl_${VNUMBER}_linux_amd64 -O cfssl
        chmod +x cfssl
        sudo mv cfssl /usr/local/bin
    }
  2. CA 인증서 및 CA 사설키 생성

    cat > ca.json <<EOF
    {
      "CN": "mycompany",
      "key": {
        "algo": "rsa",
        "size": 2048
      },
      "names": [
        {
          "C": "KR",
          "O": "mycompany",
          "OU": "devops"
        }
      ]
    }
    EOF
    cfssl gencert -initca ca.json | cfssljson -bare ca
  3. CA 설정파일 생성

    cat > ca-config.json <<EOF
    {
      "signing": {
        "default": {
          "expiry": "8760h"
        },
        "profiles": {
          "mycompany": {
            "usages": ["signing", "key encipherment", "server auth"],
            "expiry": "8760h"
          }
        }
      }
    }
    EOF
  4. 인증서 생성요청 설정파일 생성

    cat > mycompany-csr.json <<EOF
    {
      "CN": "mycompany",
      "key": {
        "algo": "rsa",
        "size": 2048
      },
      "names": [
        {
          "C": "KR",
          "O": "mycompany",
          "OU": "devops"
        }
      ]
    }
    EOF
  5. 인증서 및 사설키 생성

    cfssl gencert \
    -ca=ca.pem \
    -ca-key=ca-key.pem \
    -config=ca-config.json \
    -hostname=mycompany.com \
    -profile=mycompany \
    mycompany-csr.json | cfssljson -bare mycompany
  6. Secret 생성

    kubectl create secret tls mycompany-com \
    --cert=mycompany.pem \
    --key=mycompany-key.pem
  7. 데모 웹사이트 배포

    {
        kubectl create deployment nginx --image=nginx --port=80
        kubectl expose deploy nginx 
    }
  8. 생성된 리소스 확인

    kubectl get all -l app=nginx
  9. Ingress 생성

    cat <<EOF | kubectl apply -f -
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: nginx
    spec:
      ingressClassName: nginx
      tls: 
      - hosts:
        - mycompany.com
        secretName: mycompany-com
      rules:
      - host: mycompany.com
        http:
          paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: nginx
                port:
                  number: 80
    EOF
  10. Ingress 생성 확인 - ADDRESS에 NGINX Ingress Controller 엔드포인트가 업데이트 되는지 확인

    kubectl get ing nginx -w
  11. Ingress에 명시한 Host 주소를 호출하면 NGINX Ingress Controller 엔드포인트로 연결되도록 하고 프로토콜로 데모 웹사이트 호출

    curl -v --cacert ca.pem https://mycompany.com \
    --connect-to mycompany.com:443:\
    $(kubectl -n kube-system get svc ingress-nginx-controller \
    -o jsonpath='{.status.loadBalancer.ingress[0].hostname}'):443
  12. 리소스 삭제

    {
        kubectl delete ing nginx
        kubectl delete deploy nginx
        kubectl delete svc nginx
        kubectl delete secret mycompany-com
        rm ca*
        rm mycompany*
    }

Clean up

  1. NGINX Ingress Controller 삭제

    kubectl delete -f \
    https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/aws/deploy.yaml

AWS Load Balancer Controller

Introduction

  1. EKS 클러스터가 생성되어 있는 AWS 계정번호 확인하고 환경변수로 저장

    {
        export ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
        echo $ACCOUNT_ID
    }
  2. Node에 부여된 Label을 통해서 EKS 클러스터 이름 확인하고 환경변수로 저장

    {
        export CLUSTER_NAME=$(kubectl get node \
        -o=jsonpath='{.items[0].metadata.labels.alpha\.eksctl\.io\/cluster-name}')
        echo $CLUSTER_NAME
    }
  3. IAM OIDC 제공자 생성

    eksctl utils associate-iam-oidc-provider \
    --region ap-northeast-2 \
    --cluster $CLUSTER_NAME \
    --approve
  4. AWS Load Balancer Controller에 부여할 IAM 권한이 명시된 JSON 파일 다운로드

    curl -o aws-loadbalancer-controller-policy.json \
    https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/main/docs/install/iam_policy.json
  5. 다운받은 IAM 정책 JSON 파일 리뷰

    cat aws-loadbalancer-controller-policy.json
  6. IAM 정책 생성

    aws iam create-policy \
    --policy-name AWSLoadBalancerControllerIAMPolicy \
    --policy-document file://aws-loadbalancer-controller-policy.json
  7. 이미 IAM 정책이 존재할 경우 정책 문서 업데이트

    {
      NON_DEFAULT_VERSIONS=$(aws iam list-policy-versions \
      --policy-arn arn:aws:iam::${ACCOUNT_ID}:policy/AWSLoadBalancerControllerIAMPolicy \
      --query 'Versions[?IsDefaultVersion==`false`].VersionId' \
      --output text)
      
      for version in $NON_DEFAULT_VERSIONS
      do
        aws iam delete-policy-version \
        --policy-arn arn:aws:iam::${ACCOUNT_ID}:policy/AWSLoadBalancerControllerIAMPolicy \
        --version-id $version
      done
      
      aws iam create-policy-version \
      --policy-arn arn:aws:iam::${ACCOUNT_ID}:policy/AWSLoadBalancerControllerIAMPolicy \
      --policy-document file://aws-loadbalancer-controller-policy.json \
      --set-as-default
    }
  8. ServiceAccount 생성

    eksctl create iamserviceaccount \
    --cluster $CLUSTER_NAME \
    --namespace=kube-system \
    --name=aws-load-balancer-controller \
    --attach-policy-arn=arn:aws:iam::${ACCOUNT_ID}:policy/AWSLoadBalancerControllerIAMPolicy \
    --override-existing-serviceaccounts \
    --approve
  9. Helm이 설치되어 있지 않을 경우에는 아래의 명령어로 Helm 설치

    curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
  10. EKS 리포지토리 추가

    helm repo add eks https://aws.github.io/eks-charts
  11. 위에서 추가한 리포지토리가 추가되었는지 확인

    helm repo list
  12. 위에서 추가한 리포지토리에 있는 Helm 차트 목록 확인

    helm search repo eks
  13. AWS Load Balancer Controller 설치

    helm install aws-load-balancer-controller eks/aws-load-balancer-controller \
    --namespace kube-system \
    --set clusterName=$CLUSTER_NAME \
    --set replicaCount=1 \
    --set serviceAccount.create=false \
    --set serviceAccount.name=aws-load-balancer-controller
  14. AWS Load Balancer Controller 로그 확인

    kubectl -n kube-system logs deploy/aws-load-balancer-controller
  15. 데모 웹사이트 배포

    {
        kubectl create deployment nginx --image=nginx --port=80
        kubectl expose deploy nginx 
    }
  16. 생성된 리소스 확인

    kubectl get all -l app=nginx
  17. Ingress 생성

    cat <<EOF | kubectl apply -f -
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: nginx
    spec:
      ingressClassName: alb
      rules:
      - http:
          paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: nginx
                port:
                  number: 80
    EOF
  18. 생성된 Ingress 확인

    kubectl get ing nginx
  19. 위에서 생성한 Ingress에 발생한 Event 확인

    kubectl describe ingress nginx
  20. AWS Load Balancer Controller 로그 확인

    kubectl -n kube-system logs deploy/aws-load-balancer-controller
  21. Ingress 수정

    cat <<EOF | kubectl apply -f -
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: nginx
      annotations:
        alb.ingress.kubernetes.io/target-type: ip
    spec:
      ingressClassName: alb
      rules:
      - http:
          paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: nginx
                port:
                  number: 80
    EOF
  22. Ingress 상태 확인

    kubectl get ing nginx
  23. Ingress에 발생한 Event 확인

    kubectl describe ingress nginx
  24. AWS Load Balancer Controller 로그 확인

    kubectl -n kube-system logs deploy/aws-load-balancer-controller
  25. 아래의 명령어를 실행해서 생성된 ALB 엔드포인트를 확인하고 웹브라우저를 통해서 접근이 되는지 확인

    echo $(kubectl get ing nginx -o=jsonpath='{.status.loadBalancer.ingress[0].hostname}')
  26. 생성된 ALB 이름을 확인하고 환경변수로 저장

    {
        export LoadBalancerName=$(aws elbv2 describe-load-balancers | \
        jq -r '.LoadBalancers[] | 
        select(.DNSName == "'"$(kubectl get ing nginx -o=jsonpath='{.status.loadBalancer.ingress[0].hostname}')"'") | 
        .LoadBalancerName')
    
        echo $LoadBalancerName
    }
  27. ALB의 상세 내용 확인

    aws elbv2 describe-load-balancers --names $LoadBalancerName --no-cli-pager
  28. ALB의 Scheme 확인

    aws elbv2 describe-load-balancers --names $LoadBalancerName \
    --query 'LoadBalancers[0].Scheme' --output text
  29. ALB가 생성된 서브넷 확인

    aws elbv2 describe-load-balancers --names $LoadBalancerName \
    --query 'LoadBalancers[0].AvailabilityZones[*]' --no-cli-pager
  30. ALB가 생성된 서브넷에 부여된 태그 확인

    aws ec2 describe-subnets --subnet-ids --query 'Subnets[*].Tags' \
    $(aws elbv2 describe-load-balancers --names $LoadBalancerName \
    --query 'LoadBalancers[0].AvailabilityZones[*].SubnetId' --output text) \
    --no-cli-pager
  31. AWS Load Balancer Controller가 ALB를 생성한 서브넷을 선택하는 방법 확인 - https://kubernetes-sigs.github.io/aws-load-balancer-controller/latest/deploy/subnet_discovery

  32. AWS Load Balancer Controller로 Ingress 생성할때 요구되는 파라미터 및 기본값 확인 - https://kubernetes-sigs.github.io/aws-load-balancer-controller/latest/guide/ingress/annotations

  33. Ingress 수정

    cat <<EOF | kubectl apply -f -
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: nginx
      annotations:
        alb.ingress.kubernetes.io/scheme: internet-facing
        alb.ingress.kubernetes.io/target-type: ip
    spec:
      ingressClassName: alb
      rules:
      - http:
          paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: nginx
                port:
                  number: 80
    EOF
  34. Ingress에 발생한 Event 확인

    kubectl describe ingress nginx
  35. AWS Load Balancer Controller 로그 확인

    kubectl -n kube-system logs deploy/aws-load-balancer-controller
  36. 아래의 명령어를 실행해서 생성된 ALB 엔드포인트를 확인하고 웹브라우저를 통해서 접근이 되는지 확인

    echo $(kubectl get ing nginx -o=jsonpath='{.status.loadBalancer.ingress[0].hostname}')
  37. 기존에 생성된 ALB가 존재하는지 확인

    aws elbv2 describe-load-balancers --names $LoadBalancerName
  38. 새롭게 생성된 ALB의 ARN를 확인하고 환경변수로 저장

    {
        export LoadBalancerArn=$(aws elbv2 describe-load-balancers | \
        jq -r '.LoadBalancers[] | 
        select(.DNSName == "'"$(kubectl get ing nginx -o=jsonpath='{.status.loadBalancer.ingress[0].hostname}')"'") | 
        .LoadBalancerArn')
    
        echo $LoadBalancerArn
    }
  39. 아파치 웹서버 배포

    {
        kubectl create deployment httpd --image=httpd
        kubectl expose deployment httpd --port=80
    }
  40. Ingress 수정

    cat <<EOF | kubectl apply -f -
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: nginx
      annotations:
        alb.ingress.kubernetes.io/scheme: internet-facing
        alb.ingress.kubernetes.io/target-type: ip
    spec:
      ingressClassName: alb
      rules:
      - host: nginx.example.com
        http:
          paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: nginx
                port:
                  number: 80
      - host: httpd.example.com
        http:
          paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: httpd
                port:
                  number: 80
    EOF
  41. 아래의 명령어를 실행해서 생성된 ALB 엔드포인트를 확인하고 웹브라우저를 통해서 접근이 되는지 확인

    echo $(kubectl get ing nginx -o=jsonpath='{.status.loadBalancer.ingress[0].hostname}')
  42. cURL 명령어로 Host 값을 nginx.example.com으로 명시하고 ALB 엔드포인트 호출

    curl -H "Host: nginx.example.com" \
    $(kubectl get ing nginx -o=jsonpath='{.status.loadBalancer.ingress[0].hostname}') 
  43. cURL 명령어로 Host 값을 httpd.example.com으로 명시하고 ALB 엔드포인트 호출

    curl -H "Host: httpd.example.com" \
    $(kubectl get ing nginx -o=jsonpath='{.status.loadBalancer.ingress[0].hostname}') 
  44. ALB의 리스너 ARN를 확인하고 환경변수로 저장

    {
        export ListnerArn=$(aws elbv2 describe-listeners \
        --load-balancer-arn $LoadBalancerArn \
        --query "Listeners[0].ListenerArn" --output text)
        
        echo $ListnerArn
    }
  45. ALB 리스너 확인

    aws elbv2 describe-listeners --listener-arns $ListnerArn
  46. ALB 리스너 규칙 확인

    aws elbv2 describe-rules --listener-arn $ListnerArn --no-cli-pager
  47. ALB에 연동된 대상그룹들의 ARN을 확인하고 환경변수로 저장

    {
        export TG=$(aws elbv2 describe-target-groups \
        --load-balancer-arn $LoadBalancerArn \
        --query "TargetGroups[*].TargetGroupArn" \
        --output text)
        
        echo $TG
    }
  48. 대상그룹 확인

    aws elbv2 describe-target-groups --target-group-arns $TG --no-cli-pager
  49. 대상그룹에 포함된 대상 목록 확인

    for target in $TG
    do 
      aws elbv2 describe-target-health --target-group-arn $target --no-cli-pager
    done
  50. Pod 목록 확인

    kubectl get pod -o wide -l 'app in (nginx,httpd)'
  51. 아파치 Deployment의 Replica 갯수를 3개로 조정

    kubectl scale deployment httpd --replicas=3
  52. Pod 목록 확인

    kubectl get pod -o wide -l 'app in (nginx,httpd)'
  53. 대상그룹에 포함된 대상 목록 확인

    for target in $TG
    do 
      aws elbv2 describe-target-health --target-group-arn $target --no-cli-pager
    done
  54. Ingress 삭제

    kubectl delete ing nginx
  55. AWS Load Balancer Controller 로그 확인

    kubectl -n kube-system logs deploy/aws-load-balancer-controller
  56. ALB가 삭제되었는지 확인

    aws elbv2 describe-load-balancers --load-balancer-arns $LoadBalancerArn
  57. 리소스 삭제

    {
        kubectl delete svc httpd nginx 
        kubectl delete deploy httpd nginx
    }

IngressGroup

  1. Ingress 생성

    cat <<EOF | kubectl apply -f -
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: my-service
      annotations:
        alb.ingress.kubernetes.io/scheme: internet-facing
        alb.ingress.kubernetes.io/target-type: ip
        alb.ingress.kubernetes.io/group.name: my-service
        alb.ingress.kubernetes.io/actions.response-404: >
          {"type":"fixed-response","fixedResponseConfig":{"contentType":"text/plain","statusCode":"404","messageBody":"Not Found"}}
    spec:
      ingressClassName: alb
      defaultBackend:
        service:
          name: response-404
          port:
            name: use-annotation
    EOF
  2. 생성된 Ingress 확인

    kubectl get ing my-service
  3. 위에서 생성한 Ingress에 발생한 Event 확인

    kubectl describe ingress my-service
  4. AWS Load Balancer Controller 로그 확인

    kubectl -n kube-system logs deploy/aws-load-balancer-controller --tail 15
  5. 아래의 명령어를 실행해서 생성된 ALB 엔드포인트를 확인하고 웹브라우저를 통해서 접근이 되는지 확인

    echo $(kubectl get ing my-service -o=jsonpath='{.status.loadBalancer.ingress[0].hostname}')
  6. Product 서비스 배포

    cat <<'EOF' | kubectl apply -f -
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: product
      labels:
        app: product
    spec:
      selector:
        matchLabels:
          app: product
      template:
        metadata:
          labels:
            app: product
        spec:
          containers:
          - name: product
            image: nginx
            ports:
            - containerPort: 80
            volumeMounts:
            - name: html
              mountPath: /usr/share/nginx/html
          initContainers:
          - name: index
            image: bash
            command:
              - 'bash'
              - '-c'
              - 'echo "<h1>${APP^^}</h1>" > /data/index.html'
            env:
            - name: APP
              valueFrom:
                fieldRef:
                  fieldPath: metadata.labels['app']
            volumeMounts:
            - name: html
              mountPath: /data
          volumes:
          - name: html
            emptyDir: {}
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: product
      labels:
        app: product
    spec:
      selector:
        app: product
      ports:
      - port: 80
    EOF
  7. 리소스가 정상적으로 생성되었는지 확인

    kubectl get all -l app=product
  8. /product 경로로 접속할 경우 위에 배포한 서비스로 연결되도록 Ingress 생성

    cat <<EOF | kubectl apply -f -
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: product
      annotations:
        alb.ingress.kubernetes.io/group.name: my-service
    spec:
      ingressClassName: alb
      rules:
      - http:
          paths:
          - path: /product
            pathType: Prefix
            backend:
              service:
                name: product
                port:
                  number: 80
    EOF
  9. 생성된 Ingress 확인

    kubectl get ing product
  10. 위에서 생성한 Ingress에 발생한 Event 확인

    kubectl describe ingress product
  11. AWS Load Balancer Controller 로그 확인

    kubectl -n kube-system logs deploy/aws-load-balancer-controller --tail 10
  12. Ingress 수정

    cat <<EOF | kubectl apply -f -
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: product
      annotations:
        alb.ingress.kubernetes.io/group.name: my-service
        alb.ingress.kubernetes.io/target-type: ip
    spec:
      ingressClassName: alb
      rules:
      - http:
          paths:
          - path: /product
            pathType: Prefix
            backend:
              service:
                name: product
                port:
                  number: 80
    EOF
  13. Ingress 확인

    kubectl get ing product
  14. Ingress에 발생한 Event 확인

    kubectl describe ingress product
  15. 처음에 생성한 Ingress의 ALB 엔드포인트에 방금 생성한 Ingress에 명시한 경로로 웹브라우저를 통해서 접근이 되는지 확인 - 아래의 명령어로 주소 확인 가능

    echo $(kubectl get ing my-service -o=jsonpath='{.status.loadBalancer.ingress[0].hostname}')/product
  16. Product 서비스의 로그 확인

    kubectl logs deploy/product
  17. Product 서비스의 루트 경로 호출

    kubectl exec deploy/product -- curl -s localhost
  18. Product 서비스의 /product 경로 호출

    kubectl exec deploy/product -- curl -s localhost/product
  19. Product 서비스 수정

    cat <<'EOF' | kubectl apply -f -
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: product
      labels:
        app: product
    spec:
      selector:
        matchLabels:
          app: product
      template:
        metadata:
          labels:
            app: product
        spec:
          containers:
          - name: product
            image: nginx
            ports:
            - containerPort: 80
            volumeMounts:
            - name: html
              mountPath: /usr/share/nginx/html
          initContainers:
          - name: index
            image: bash
            command:
              - 'bash'
              - '-c'
              - 'mkdir /data/$APP && echo "<h1>${APP^^}</h1>" > /data/$APP/index.html'
            env:
            - name: APP
              valueFrom:
                fieldRef:
                  fieldPath: metadata.labels['app']
            volumeMounts:
            - name: html
              mountPath: /data
          volumes:
          - name: html
            emptyDir: {}
    EOF
  20. Product 서비스의 루트 경로 호출

    kubectl exec deploy/product -- curl -s localhost
  21. Product 서비스의 /product 경로 호출

    kubectl exec deploy/product -- curl -sL localhost/product
  22. 처음에 생성한 Ingress의 ALB 엔드포인트에 /product 경로로 웹브라우저를 통해서 접근이 되는지 확인 - 아래의 명령어로 주소 확인 가능

    echo $(kubectl get ing my-service -o=jsonpath='{.status.loadBalancer.ingress[0].hostname}')/product
  23. Payment 서비스 배포

    cat <<'EOF' | kubectl apply -f -
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: payment
      labels:
        app: payment
    spec:
      selector:
        matchLabels:
          app: payment
      template:
        metadata:
          labels:
            app: payment
        spec:
          containers:
          - name: payment
            image: nginx
            ports:
            - containerPort: 80
            volumeMounts:
            - name: html
              mountPath: /usr/share/nginx/html
          initContainers:
          - name: index
            image: bash
            command:
              - 'bash'
              - '-c'
              - 'mkdir /data/$APP && echo "<h1>${APP^^}</h1>" > /data/$APP/index.html'
            env:
            - name: APP
              valueFrom:
                fieldRef:
                  fieldPath: metadata.labels['app']
            volumeMounts:
            - name: html
              mountPath: /data
          volumes:
          - name: html
            emptyDir: {}
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: payment
      labels:
        app: payment
    spec:
      selector:
        app: payment
      ports:
      - port: 80
    EOF
  24. 리소스가 정상적으로 생성되었는지 확인

    kubectl get all -l app=payment
  25. /payment 경로로 접속할 경우 위에 배포한 서비스로 연결되도록 Ingress 생성

    cat <<EOF | kubectl apply -f -
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: payment
      annotations:
        alb.ingress.kubernetes.io/group.name: my-service
        alb.ingress.kubernetes.io/target-type: ip
    spec:
      ingressClassName: alb
      rules:
      - http:
          paths:
          - path: /payment
            pathType: Prefix
            backend:
              service:
                name: payment
                port:
                  number: 80
    EOF
  26. 생성된 Ingress 확인

    kubectl get ing payment
  27. 위에서 생성한 Ingress에 발생한 Event 확인

    kubectl describe ingress payment
  28. AWS Load Balancer Controller 로그 확인

    kubectl -n kube-system logs deploy/aws-load-balancer-controller --tail 10
  29. 처음에 생성한 Ingress의 ALB 엔드포인트에 /payment 경로로 웹브라우저를 통해서 접근이 되는지 확인 - 아래의 명령어로 주소 확인 가능

    echo $(kubectl get ing my-service -o=jsonpath='{.status.loadBalancer.ingress[0].hostname}')/payment
  30. 위에서 개별로 생성한 3개의 Ingress들이 동일한 ALB를 사용하는지 확인

    kubectl get ing my-service product payment
  31. 리소스 삭제

    {
        kubectl delete ing payment product my-service
        kubectl delete deploy payment product
        kubectl delete svc payment product
    }

Last updated