5 분 소요

image

AWS EKS에서 kubectl 접속부터 Pod, Service, Deployment, Ingress 등 쿠버네티스 오브젝트와 helm을 사용하며 발생한 문제를 해결한 내용을 정리했습니다.
(계속 업데이트할 예정입니다.)

로컬 PC는 macOS Catalina를 사용중이며 AWS EKS는 1.14버전입니다.

$ k version
Client Version: version.Info{Major:"1", Minor:"14", GitVersion:"v1.14.8", GitCommit:"211047e9a1922595eaa3a1127ed365e9299a6c23", GitTreeState:"clean", BuildDate:"2019-10-15T12:11:03Z", GoVersion:"go1.12.10", Compiler:"gc", Platform:"darwin/amd64"}
Server Version: version.Info{Major:"1", Minor:"14+", GitVersion:"v1.14.9-eks-c0eccc", GitCommit:"c0eccca51d7500bb03b2f163dd8d534ffeb2f7a2", GitTreeState:"clean", BuildDate:"2019-12-22T23:14:11Z", GoVersion:"go1.12.12", Compiler:"gc", Platform:"linux/amd64"}

쿠버네티스 개념에 대한 설명은 없습니다.

kubectl↔EKS cluster 연결

  1. aws-iam-authenticator 설치
    (가이드에서는 설치하라고 하는데 필요한지 모르겠습니다. 이후 과정에서 관련 문제가 발생하면 설치해주세요.)
    • brew install aws-iam-authenticator
  2. awscli 설치
    • pip3 install awscli
    • aws configure
  3. IAM 사용자/역할 확인
    • aws sts get-caller-identity
  4. eks kubeconfig 추가
    • aws eks update-kubeconfig --name <cluster-name>

클러스터를 생성하고 다른 사용자에게 권한 주기

클러스터를 만든 사용자 계정이 아닌 다른 계정으로 kubectl을 이용해 접근하니 권한 에러가 발생했습니다.

다른 사용자에게 권한 주기를 참고해 권한을 지급하는 등의 설정을 할 수 있습니다.

# aws-auth.yaml 예

apiVersion: v1
kind: ConfigMap
metadata:
  name: aws-auth
  namespace: kube-system
data:
  mapRoles: |
    - rolearn: arn:aws:iam::832626921517:role/AWSEC2AmazonEKSGroup # 노드 IAM 역할
      username: system:node:
      groups:
        - system:bootstrappers
        - system:nodes
  mapUsers: |
    - userarn: arn:aws:iam::832626921517:user/Kubernetes # 사용자
      username: Kubernetes # 사용자 이름
      groups: # 그룹 (https://kubernetes.io/docs/reference/access-authn-authz/rbac/#default-roles-and-role-bindings 참고)
        - system:masters
  • aws-auth 확인: kubectl describe configmap -n kube-system aws-auth
  • EKS 반영: kubectl apply -f aws-auth.yaml

Dashboard

쿠버네티스를 관리할 수 있는 대시보드를 띄울 수 있습니다.

참고자료

Ingress

인그레스는 클라이언트의 요청을 서비스로 전달합니다.

아래의 helm을 참고하면 간편하게 구성할 수 있습니다.

Ingress만 생성하면 사용할 수 없고, Ingress Controller를 생성해줘야 합니다.

https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/mandatory.yaml 설정을 이용해서 인그레스 컨트롤러를 생성했는데, 추가적인 설정이 필요했습니다.

kind: ConfigMap
apiVersion: v1
metadata:
name: nginx-configuration
namespace: ingress-nginx
labels:
  app.kubernetes.io/name: ingress-nginx
  app.kubernetes.io/part-of: ingress-nginx
data:
# 옵션에 대한 설명은
# [https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/configmap](https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/configmap/#use-forwarded-headers)
# 에서 확인할 수 있습니다.
use-forwarded-headers: "true"
compute-full-forwarded-for: "true"
use-proxy-protocol: "true"
# TCP4 프록시하는 로그
172.31.40.219 - - [23/Dec/2019:03:19:26 +0000] "PROXY TCP4 27.115.124.6 172.31.40.219 64396 443" 400 163 "-" "-" 0 0.091 [] [] - - - - 936532129462698291cc150891df4eb9
172.31.40.219 - - [23/Dec/2019:03:19:27 +0000] "PROXY TCP4 27.115.124.70 172.31.40.219 49929 443" 400 163 "-" "-" 0 0.098 [] [] - - - - 3a28d01a364cd0d78eaeeaad879f26fb

# 설정 적용 후 정상 동작하는 로그
106.240.29.163 - - [23/Dec/2019:03:24:15 +0000] "GET / HTTP/2.0" 200 27 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36" 13 0.003 [default-sample-service-18080] [] 172.31.13.213:8080 27 0.004 200 9bef6f2255aa43db65e1204cb4321e41
106.240.29.163 - - [23/Dec/2019:03:24:15 +0000] "GET / HTTP/2.0" 200 27 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36" 13 0.004 [default-sample-service-18080] [] 172.31.10.7:8080 27 0.004 200 6f811489dd313133b69f6cede18bb6a5

external-dns를 이용해 route 53의 레코드를 자동으로 설정 할 수 있습니다.

이때, EKS 역할이 사용할 route 53의 권한 정책이 필요합니다.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "VisualEditor0",
      "Effect": "Allow",
      "Action": [
        "route53:ChangeResourceRecordSets",
        "route53:ListResourceRecordSets"
      ],
      "Resource": "arn:aws:route53:::hostedzone/*"
    },
    {
      "Sid": "VisualEditor1",
      "Effect": "Allow",
      "Action": "route53:ListHostedZones",
      "Resource": "*"
    }
  ]
}

ingress 메니페스트 파일입니다.

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: sample-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
    - host: "sample.jubeom.dev"
      http:
        paths:
          - path: /
            backend:
              serviceName: sample-service
              servicePort: 18080

인그레스를 적용하면 ruleshost를 이용해 레코드를 자동으로 생성합니다.

image

image

참고자료

HPA (Horizontal Pod Autoscaler)

파드의 수를 수평적으로 확장할 수 있는 기능입니다.

문제 1. no matches for kind "HorizontalPodAutoScaler" in version "autoscaling/v2beta1"

error: unable to recognize "?.yml": no matches for kind "HorizontalPodAutoScaler" in version "autoscaling/v2beta1"

버전에 맞지 않은 yml 세팅을 사용해 발생한 문제입니다.

AWS EKS 클러스터는 1.14 버전을 사용 중입니다.
공식 문서의 룰에 따라 HPA를 설정해서 해결할 수 있었습니다.

apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
    name: sample-hpa
spec: # https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.14/#horizontalpodautoscalerspec-v2beta2-autoscaling
    scaleTargetRef:
    apiVersion: extensions/v1beta1
    kind: Deployment
    name: sample-app
    minReplicas: 1
    maxReplicas: 5
    metrics: # https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.14/#metricspec-v2beta2-autoscaling
    - type: Resource
        resource: # https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.14/#resourcemetricsource-v2beta2-autoscaling
        name: cpu
        target: # https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.14/#metrictarget-v2beta2-autoscaling
                    type: Utilization
            averageUtilization: 80
            # type: AverageValue
            # averageValue: 80

참고자료

문제 2. target pod cpu unknown

$ kubectl get hpa
NAME         REFERENCE               TARGETS        MINPODS   MAXPODS   REPLICAS   AGE
sample-hpa   Deployment/sample-app   <unknown>/80   1         5         1          18m

$ kubectl describe hpa
Name:                    sample-hpa
Namespace:               default
Labels:                  <none>
Annotations:             kubectl.kubernetes.io/last-applied-configuration:
                            {"apiVersion":"autoscaling/v2beta2","kind":"HorizontalPodAutoscaler","metadata":{"annotations":{},"name":"sample-hpa","namespace":"default...
CreationTimestamp:       Tue, 24 Dec 2019 10:07:08 +0900
Reference:               Deployment/sample-app
Metrics:                 ( current / target )
    resource cpu on pods:  <unknown> / 80
Min replicas:            1
Max replicas:            5
Deployment pods:         1 current / 0 desired
Conditions:
    Type           Status  Reason                   Message
    ----           ------  ------                   -------
    AbleToScale    True    SucceededGetScale        the HPA controller was able to get the target's current scale
    ScalingActive  False   FailedGetResourceMetric  the HPA was unable to compute the replica count: unable to get metrics for resource cpu: unable to fetch metrics from resource metrics API: the server could not find the requested resource (get pods.metrics.k8s.io)
Events:
    Type     Reason                        Age                   From                       Message
    ----     ------                        ----                  ----                       -------
    Warning  FailedComputeMetricsReplicas  19m (x12 over 22m)    horizontal-pod-autoscaler  failed to get cpu utilization: unable to get metrics for resource cpu: unable to fetch metrics from resource metrics API: the server could not find the requested resource (get pods.metrics.k8s.io)
    Warning  FailedGetScale                17m (x5 over 18m)     horizontal-pod-autoscaler  deployments/scale.apps "sample-service" not found
    Warning  FailedGetResourceMetric       2m16s (x68 over 22m)  horizontal-pod-autoscaler  unable to get metrics for resource cpu: unable to fetch metrics from resource metrics API: the server could not find the requested resource (get pods.metrics.k8s.io)

아래 참고 자료를 이용해 메트릭 서버를 실행시켜 CPU 정보를 얻어올 수 있습니다.

$ k get hpa -w
sample-hpa   Deployment/sample-app   4%/80%          1         5         1          68m
sample-hpa   Deployment/sample-app   4%/80%          1         5         1          69m
sample-hpa   Deployment/sample-app   0%/80%          1         5         1          70m

부하를 줘서 실제로 파드의 수가 늘어나는지 확인하기 위해 스케일링 기준 CPU를 낮추고 loader.io를 이용해 테스트한 결과입니다.

image

참고자료

Helm

helm은 쿠버네티스 패키지 관리자입니다.

helm v3.x을 사용했습니다.
(version.BuildInfo{Version:”v3.0.2”, GitCommit:”19e47ee3283ae98139d98460de796c1be1e3975f”, GitTreeState:”clean”, GoVersion:”go1.13.5”})

helm 설치

$ brew install helm

레포지토리 추가

$ helm repo add stable https://kubernetes-charts.storage.googleapis.com/

헬름 차트 만들 때

  1. helm 템플릿 파일은 templates 디렉토리 하위에 있어야 합니다. (vscode에서 문법 오류)
  2. 확장자를 .yml을 사용하면 인식이 안됩니다. .yaml을 사용해야 합니다.

헬름 차트 릴리즈

$ helm install <name> <dir>

헬름 차트 업그레이드

helm upgrade <name> <dir>

다른 배포 환경을 사용할 경우 helm install sample-staging . --values ./values-staging.yml 와 같이 --values 옵션을 이용해 지정할 수 있습니다.

위(ingress)에서 설치한 nginx-ingress, external-dns는 helm을 이용해 손쉽게 구성할 수 있습니다.

# nginx-ingress
$ helm install nginx-ingress stable/nginx-ingress \
    --set controller.publishService.enabled=true

# external-dns
$ helm install external-dns stable/external-dns \
    --set aws.region=ap-northeast-2 \
    --set aws.zoneType=public

참고자료

무중단 배포

참고자료

모니터링

  • prometheus
$ helm install prometheus-operator stable/prometheus-operator # prometheus 설치
  • grafana
$ helm install grafana stable/grafana # grafana 설치
$ kubectl get secret grafana -o jsonpath="{.data.admin-password}" | base64 --decode ; echo # grafana 비밀번호 확인

grafana의 유저네임은 admin입니다.

image image image image

Import → 1860 (dashboard id) → Import

image

참고자료

댓글남기기