[디버깅기] eks 로 띄운 서비스 curl: (52) Empty reply from server/* OpenSSL SSL_connect: SSL_ERROR_SYSCALL in connection [L4/L7, LoadBalancer, ingress, service, kubectl, aws eks]
요약: 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 에서 진행한 워크샵 자료이다.
"쿠버네티스에서 서비스 타입 중, NodePort 혹은 LoadBalancer로도 외부로 노출할 수 있지만 인그레스 없이 서비스를 사용할 경우, 모든 서비스에게 라우팅 규칙 및 TLS/SSL 등의 상세한 옵션들을 적용해야 되죠. 그래서 인그레스가 필요합니다."
그래서 인그레스를 만들어보기로 했다. 근데 loadBalancer로도 되어야 하는데 왜 안되는 걸까? ㅠㅠ 이럴땐 ㅠㅠ 말고 공식문서를 보면 편하다 이렇게 나와있다.
"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 를 가져오고 통신이 일단 되는 것으로 파악하고 이는 다른 글에서 다루도록 하겠다!
참고자료