기술스택을 쌓아보자/AWS

[디버깅기] eks 로 띄운 서비스 curl: (52) Empty reply from server/* OpenSSL SSL_connect: SSL_ERROR_SYSCALL in connection [L4/L7, LoadBalancer, ingress, service, kubectl, aws eks]

소리331 2023. 6. 25. 18:24
반응형

요약: eks 에서 ingress를 생성해주어야 한다!

인트로 - 해결법을 찾아가기 

azure 에서 k8s를 통해 서비스를 띄운뒤, 같은 내용의 manifest file을 eks 에도 띄우려고 하였다. 애저에서 잘 되던거니 어련히 알아서 잘 되겠거니 했는데, 서비스를 띄우는 것까진 성공했지만 막상 웹앱에 접근하려고 하니 serivce에서 제공하는 external ip 로 접근할 수 없었다. 

그렇다면 내가 만든게 뭔가 잘못된 것! 

아래는 내가 처음에 azure에서 띄운 서비스의 manifest 파일이다.

kind: Namespace
metadata:
  creationTimestamp: null
  name: my-name
spec: {}
status: {}
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-name
  namespace: my-name
  labels:
    finter-snu: c2
spec:
  strategy:
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
    type: RollingUpdate
  replicas: 1
  selector:
    matchLabels:
      my-label: value
  template:
    metadata:
      labels:
        my-label: value
    spec:
      containers:
        - name: my-name
          image: my-image
          ports:
            - containerPort: my-port
          command: []
          env:
            - name: my-name
              value: "my-name"

---

apiVersion: v1
kind: Service
metadata:
  name: my-name
  namespace: my-name
spec:
  selector:
    my-name:b
  ports:
    - protocol: TCP
      name: my-name
      port: my-port
      targetPort: my-target-name
  type: LoadBalancer

 

 

pod 안에서 앱은 잘 띄워졌는데, services 에서 나온 externalip 로 접근 할 수 없는 것이었다. 그러던 중 아래 문서를 보고 조금 가늠을 잡아보았다. aws 에서 진행한 워크샵 자료이다. 

 

Workshop Studio

 

catalog.us-east-1.prod.workshops.aws

"쿠버네티스에서 서비스 타입 중, NodePort 혹은 LoadBalancer로도 외부로 노출할 수 있지만 인그레스 없이 서비스를 사용할 경우, 모든 서비스에게 라우팅 규칙 및 TLS/SSL 등의 상세한 옵션들을 적용해야 되죠. 그래서 인그레스가 필요합니다."

그래서 인그레스를 만들어보기로 했다. 근데 loadBalancer로도 되어야 하는데 왜 안되는 걸까? ㅠㅠ 이럴땐 ㅠㅠ 말고 공식문서를 보면 편하다 이렇게 나와있다. 

 

Amazon EKS의 네트워크 로드 밸런싱 - Amazon EKS

이전 버전과의 호환성을 위해 service.beta.kubernetes.io/aws-load-balancer-type: "nlb-ip" 주석이 여전히 지원됩니다. 그러나 service.beta.kubernetes.io/aws-load-balancer-type: "nlb-ip" 대신 새 로드 밸런서에 이전 주석을

docs.aws.amazon.com

"Kubernetes 유형의 Service LoadBalancer를 생성하면 AWS 클라우드 공급자 로드 밸런서 컨트롤러가 기본적으로 AWS Classic 로드 밸런서를 생성하지만 AWS 네트워크 로드 밸런서도 생성할 수 있습니다. 이 컨트롤러는 향후 중요한 버그 수정만 수신하고 있습니다. AWS 클라우드 공급자 로드 밸런서 사용에 대한 자세한 내용은 Kubernetes 설명서의 AWS 클라우드 공급자 로드 밸런서 컨트롤러를 참조하세요. 이 주제에서는 이에 대해 다루지 않습니다."

=> 그러니까 내가 만든 LoadBalancer 는 NLB를 만들었기 때문에 , Ingresss를 통해 생성해주어야 l7 레이어를 사용할 수 있는 것이다. 그러니까 l4 레이어는 포트기준으로 배포되고,  나는 서비스를 포트 번호에 할당했기 때문에 이 부분에서 충돌이 발생했을 것 것 같다. 그래서 하나의 서비스만 진행하는 거 포트번호를 할당하지 않고 서비스를 돌려보았다. 내가 이해한 게 맞다면 다시 돌아야 할 것이다. => 안돈다 ㅠㅠ 이것 역시 Service를 사용하고 있기 때문이다. ingress 는 자동으로 만들어지지 않는다. 직접 구현해야한다. 우리는 ALB를 사용하고, https를 listen 할 수 있는 Ingress를 생성해야한다

"인그레스는 외부 요청 처리에 대한 규칙들을 설정해놓은 것을 의미하며, 이런 설정이 동작하기 위해서 필요한 것이 인그레스 컨트롤러입니다. kube-controller-manager의 일부로 실행되는 다른 컨트롤러와 달리 인그레스 컨트롤러는 클러스터와 함께 생성되진 않습니다. 따라서 직접 구현해야 합니다"

- 쿠버네티스의 Ingress의 경우, Application Load Balancers으로 프로비저닝됩니다.
- 쿠버네티스의 Service의 경우, Network Load Balancers으로 프로비저닝됩니다.

 

디버깅 시도 1 - ingress 생성하기.

필요 권한 부여하기

eksctl utils associate-iam-oidc-provider \
    --region ${AWS_REGION} \
    --cluster eks-demo \
    --approve
    
    
2023-06-25 17:26:02 [ℹ]  will create IAM Open ID Connect provider for cluster "" in "ap-northeast-2"
2023-06-25 17:26:02 [✔]  created IAM Open ID Connect provider for cluster "" in "ap-northeast-2"

# 이후에 OIDC 권한이 잘 생성되어 있는지 확인한다.
# 생성 확인 => URI 가 반환된다.
aws eks describe-cluster --name MY-CLUSTER --query "cluster.identity.oidc.issuer" --output text
# 권한을 부여한다.
eksctl utils associate-iam-oidc-provider --region ap-northeast-2 --cluster MY-CLUSTER --approve

클러스터에 컨트롤러 추가하기

# cert-manager 오픈소스 설치
kubectl apply --validate=false -f https://github.com/jetstack/cert-manager/releases/download/v1.5.4/cert-manager.yaml

yaml 파일을 다운로드 받고, 내 group node name을 수정해준다(731번째줄)
https://catalog.us-east-1.prod.workshops.aws/workshops/9c0aa9ab-90a9-44a6-abe1-8dff360ae428/ko-KR/60-ingress-controller/100-launch-alb

 

기존 yaml의 service와 ingress 수정하기 

apiVersion: v1
kind: Service
metadata:
  name: my-name
  namespace: my-name
spec:
  selector:
    my-label: value
  type: NodePort
  ports:
    - protocol: TCP
      name: alpha
      port: 15000
      targetPort: 15000
    - protocol: TCP
      name: cmsearch
      port: 19004
      targetPort: 19004

---

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
    name: my-name
    namespace: my-namespace
    annotations:
      kubernetes.io/ingress.class: alb
      alb.ingress.kubernetes.io/scheme: internet-facing
      alb.ingress.kubernetes.io/target-type: ip
      alb.ingress.kubernetes.io/group.name: my-name
      alb.ingress.kubernetes.io/group.order: '1'
spec:
    rules:
    - http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: my-name
                port:
                  number: my-ports

다른 에러 발견!1

=> iam에서 해당 역할에 정책을 부여합니다 참고 링크는 아래 사용 

https://devstarsj.github.io/development/2022/01/08/EKS.AWSLoadBalancer.ALB/

FailedBuildModel  29m  ingress  
Failed build model due to AccessDenied: User: arn:aws:sts::계정명:assumed-role/그룹명/i-0927e0ad3f332e272 is not authorized to perform: elasticloadbalancing:DescribeTags because no identity-based policy allows the elasticloadbalancing:DescribeTags action

다른 에러 발견!

이제 ingress에서 address 까지 잘 보이나, 404 에러가 떴다. 여기까지 일단 ingress 에서 address 를 가져오고 통신이 일단 되는 것으로 파악하고 이는 다른 글에서 다루도록 하겠다!

ㅜㅜ

참고자료

 

Workshop Studio

 

catalog.us-east-1.prod.workshops.aws

 

Amazon EKS의 네트워크 로드 밸런싱 - Amazon EKS

이전 버전과의 호환성을 위해 service.beta.kubernetes.io/aws-load-balancer-type: "nlb-ip" 주석이 여전히 지원됩니다. 그러나 service.beta.kubernetes.io/aws-load-balancer-type: "nlb-ip" 대신 새 로드 밸런서에 이전 주석을

docs.aws.amazon.com

 

L4 / L7 로드밸런서 차이 (Load balancer)

로드밸런서는 트래픽을 받아서 여러 대의 서버에 분산시키는 하드웨어 또는 소프트웨어 입니다. 부하 분산에는 L4 Load Balancer와 L7 Load Balancer가 많이 사용됩니다. L4부터 Port를 다룰 수 있기 때문

jaehoney.tistory.com

 

반응형