Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AWS ALB 삭제 후 Nginx Ingress(Baremetal) 구축 (요금 문제) #42

Closed
3 tasks done
Tracked by #1
junha-ahn opened this issue Sep 3, 2023 · 3 comments · Fixed by #47
Closed
3 tasks done
Tracked by #1

AWS ALB 삭제 후 Nginx Ingress(Baremetal) 구축 (요금 문제) #42

junha-ahn opened this issue Sep 3, 2023 · 3 comments · Fixed by #47
Assignees
Labels
enhancement New feature or request Major Major topic

Comments

@junha-ahn
Copy link
Member

junha-ahn commented Sep 3, 2023

Description

#37중요한 이슈 발견

ALB는 사용당 (커넥션당) 요금이 발생한다.

부하테스트 중 심각한 요금 문제가 발생할 가능성이 높음으로, ALB를 제거한다.

기존구조 IG => ALB(Public-IP) => EKS Backend Pod => DB
향후구조 IG => EKS NginX Ingress Service (Public-IP) => EKS Backend Pod => DB

To do

  • 1. ALB 삭제
  • 2. Nginx 설치
  • 3. 다이어그램 그리기

Test Checklist

  • curl ...:80/bookmarks return []

Result

@junha-ahn junha-ahn added enhancement New feature or request Major Major topic labels Sep 3, 2023
@junha-ahn junha-ahn moved this to Todo in Kanban Infra Sep 3, 2023
@junha-ahn junha-ahn mentioned this issue Sep 3, 2023
@junha-ahn junha-ahn changed the title ALB 삭제 Nginx 구축 ALB 삭제 Nginx Ingress 구축 Sep 3, 2023
@junha-ahn junha-ahn changed the title ALB 삭제 Nginx Ingress 구축 ALB 삭제 Nginx Ingress 구축 (요금 문제) Sep 3, 2023
@junha-ahn junha-ahn assigned junha-ahn and unassigned jacepark12 Sep 11, 2023
@junha-ahn junha-ahn mentioned this issue Sep 12, 2023
8 tasks
@junha-ahn
Copy link
Member Author

junha-ahn commented Sep 12, 2023

기본 개념

Ingress에 대해서

Ingress는 외부에서 k8s cluster 내부로 들어오는 네트워크 요청 즉, <Ingress 트래픽>을 어떻게 처리할지 정의한다.

  • 외부 요청을 어떻게 처리할 것인지를 정의하는 집합인 Ingress를 정의한 뒤, 이를 Ingress Controller라고 부르는 특별한 웹 서버에 적용함으로써 추상화된 단계에서 서비스 처리 로직을 정의할 수 있다.
  • 또한, Ingress Controller 종류 및 사용 중인 Cloud Provider에 따라 다양한 기능을 부가적으로 사용할 수도 있으니, 서비스를 외부로 노출시켜 제공해야 한다면 Ingress를 사용하는 것이 바람직하다.

어떻게 실제 구현하는가

  • Ingress 요청을 처리하기 위한 Service는 일반적으로 Cloud Platform에서 제공되는 Load Balanser 타입의 Service를 사용한다.
  • Private Cloud에서 운영하고 있는 서버에 Ingress를 직접 구축하게 된다면, Service의 Type으로서 NodePort 또는 ExternalIP, MetalLB 등을 대신 사용할 수 있다.

Ingress (Object) 와 Ingress Controller 차이

k8s 에서 Ingress 를 사용하기 위해서는 두 가지가 필요하다.

  1. YAML 파일에서 [ kind: Ingress ]로 정의되는 Ingress 오브젝트이다. (kind: Ingress)
  2. Ingress 규칙이 적용될 Ingress Controller 이다. (우리가 설치할 ingress-nginx가 여기에 해당)

Ingress 는 단지 Ingress 규칙을 정의하는 선언적인 오브젝트일 뿐, 외부 요청을 받아들이는 실제 서버가 아니기 때문이다.

Ingress 는 Ingress Controller 라고 하는 특수한 서버 컨테이너에 적용되어야 Ingress 에 적용된 규칙이 활성화된다.

  • 즉, Ingress Controller 가 외부로부터 네트워크 요청을 수신했을 때, Ingress 규칙에 기반해 이 요청을 어떻게 처리할지를 결정한다.

Ingress-nginx

Ingress-nginx는 Nginx를 reverse proxy와 load balancer로 사용하는 k8s 용 Ingress Controller이다.

중간정리: 그렇다면 나는 어떻게 해야 하는가?

Ingress-controller를 설치하고 (HostNetwork : True) Ingress Object를 작성해야 한다. 그리고 앞으로 오는 트래픽은 Ingress Object에 정의된 규칙을 기반으로 처리되어야 한다.

Ingress-nginx에는 너무 다양한 Object를 Template화해서 설치한다. 이해가 필요하나 현재 어려움을 느끼고 있다. Nginx Ingress 설치 및 활용 과 같은 글을 천천히 읽으면서 친근해져가자...

MetalLB란?

출처

Nodeport

image

NodePort는 효율성이 떨어진다.

  1. 사용자가 해당 Nodeport로 접속
  2. 워커노드가 서비스로 이를 바인딩한다.
  3. 서비스가 Pod에 연결한다.

만약 노드가 죽는다면, IP가 달라지는 문제점이 생긴다.

  • 따라서 Production 에서는 사용하지 않고, 개인용과 테스트용에서 사용한다.

Load Balancer on Cloud

image

가장 간단하게 동작한다

  • 하지만 성능테스트 환경에서는 비용 문제 발생

MetalLB

만약 클라우드가 아닌 환경에서 LoadBalancer 타입을 배포하면 어떻게 될까?

  • 몇분이 지나도 External IP가 할당되지 않는다.
  • 이를 받아주기 위한 API나 구현체가 전혀 준비되지 않았기 때문이다.

어떻게 할 수 있을까? MetalLB를 통해

  • MetalLB 는 온프레미스 환경(IDC)에서 사용할 수 있는 서비스(로드밸런서 타입)입니다. (BareMetalLoadBalancer 약자)
  • 서비스(로드 밸런서)의 'External IP' 전파를 위해서 표준 프로토콜인 ARP(IPv4)/NDP(IPv6), BGP 를 사용합니다. (기본은 L2 모드)

한마디로 클라우드 환경에서 제공하는 LB가 아닌 베어메탈 환경에서 설치하는 LB

image
image

  1. metal lb deployment를 통해 pod 배포
  2. 필요한 서비스 어카운트, 서비스 등등을 배포 (demonset.apps/speaker, deployment.apps/controller가 가장 중요)
    • 각 노드별로 SPEAKER가 하나씩 설치
    • CONTROLLER는 하나만 설치 (종합적으로 관리)
  3. MetalLB가 실제로 L2 통신을 할 수 있도록 세팅한다. (l2config.yaml - kubernetes의 Configmap으로 짜여져있다)
  4. expose lb-deployment (port=80) --type=LoadBalancer

핵심 컴퍼넌트 Speaker는 모든 노드에 실행되도록 daemonset 사용 - 특히 **host network**를 이용한다. - L2 모드는 **리더 Speaker Pod**이 존재한다. (리더 Specker Pod의 Node의 Externel IP가 대표 IP)

소프트웨어로 구현한 L2 스위치가 존재하기 때문에 '효율성'은 떨어진다. 따라서 규모가 있는 경우에는 좀 다른 설정이 필요하다. (네트워크 엔지니어와의 상담 필요)

다양한 위치에 배포되는 MetalLB

image

내가 원하는 방식에 가까운듯 Nginx Ingress Controller Front에 배포!

image


image

image

https://www.youtube.com/watch?v=k8bxtsWe9qw

중간정리: MetalLB의 필요성

현재상황

  • Nginx Ingress + NodePort 조합으로 curl <ip>:30000/을 통해서 Ingress 컨트롤이 가능하다.
  • 즉 여러개의 Backend Pod 에 부하 분산 가능

필요성

  • 현재 "성능 테스트"환경에서 Node가 죽어 Endpoint 변경으로 문제가 발생할까? "아직 모른다"
  • 만약 Nginx 한대로로 감당할 수 없는 부하가 발생할까? (그때 MetalLB 설치 필요) "아직 모른다"

Todo: Ingresss-nginx + HostNetwork 조합은 불가능한가?

  • 각 노드의 IP:80으로 접속 가능한 상태
  • 다만 굳이 필요하지는 않다. 30000번 포트냐 80포트냐는 큰 영향을 주지 않는다.
  • 따라서 해당 확인이 끝나면 Helm-repository에 Ingress-nginx를 설치한다. (그 후 부하테스트 진행)
  • 추후 필요성이 발생하면 MeltaLB 설치

@junha-ahn
Copy link
Member Author

junha-ahn commented Sep 12, 2023

AWS Load Balancer 없이 EKS Node(EC2)의 Public IP로 Nginx Ingress에 집적 붙을 수 는 없나?

키워드

  • aws eks nginx ingress controller without load balancer

How do I make ingress-nginx work without built-in LoadBalancer support for Kubernetes?

I would need to expose services so that outside world can reach it - which can be done with NodePort

I can just expose ingress-nginx as NodePort and point DNS record (AAAA) to it?

"mysebsite.com" with AAAA record of "123.456.789", the nginx-ingress exposed to "123.456.789" will receive the request

I think the best in your case is to use "hostNetwork: true" for the ingress controller. For more details, check for instance https://kubernetes.github.io/ingress-nginx/deploy/baremetal/#via-the-host-network

EKS 각 Node의 외부접근(특정 포트)을 허용한다

각각의 http://<EXTERNAL-IP>:80 으로 접속할 경우 Nginx에 요청이 전달되어야 한다.

$ kubectl get node -o wide
NAME                                             STATUS   ROLES    AGE    VERSION               INTERNAL-IP   EXTERNAL-IP      OS-IMAGE         KERNEL-VERSION                  CONTAINER-RUNTIME
ip-10-0-71-165.ap-northeast-2.compute.internal   Ready    <none>   23h    v1.27.4-eks-8ccc7ba   10.0.71.165   13.125.122.142   Amazon Linux 2   5.10.186-179.751.amzn2.x86_64   containerd://1.6.19
ip-10-0-77-252.ap-northeast-2.compute.internal   Ready    <none>   2d6h   v1.27.4-eks-8ccc7ba   10.0.77.252   43.201.85.206    Amazon Linux 2   5.10.186-179.751.amzn2.x86_64   containerd://1.6.19
ip-10-0-93-81.ap-northeast-2.compute.internal    Ready    <none>   2d6h   v1.27.4-eks-8ccc7ba   10.0.93.81    43.201.150.44    Amazon Linux 2   5.10.186-179.751.amzn2.x86_64   containerd://1.6.19
ip-10-0-94-57.ap-northeast-2.compute.internal    Ready    <none>   2d6h   v1.27.4-eks-8ccc7ba   10.0.94.57    52.79.49.224     Amazon Linux 2   5.10.186-179.751.amzn2.x86_64   containerd://1.6.19

#46 향후 하나의 노드를 Public Subnet에 배치 (Ingress Controller 용) 그리고 나머지 노드를 Private Subnet에 배치

EKS Node Group SG 변경

module "eks" {
  source  = "terraform-aws-modules/eks/aws"

  cluster_name    = "ticketing-main-eks"

...

+  node_security_group_additional_rules = {
+    ingress_http = {
+      description = "open http"
+      protocol    = "-1"
+      from_port   = 80
+      to_port     = 80
+      type        = "ingress"
+      cidr_blocks      = ["0.0.0.0/0"]
+    }
+  }
}  

Terraform AWS VPC 설정 변경

Network Access Control Lists (ACL or NACL)에 관련 설명이 존재한다.

module "vpc" {
  source  = "terraform-aws-modules/vpc/aws"

  name = "main"
  cidr = "10.0.0.0/16"

  azs             = ["ap-northeast-2a", "ap-northeast-2b"]
  private_subnets = ["10.0.0.0/19", "10.0.32.0/19"]
  public_subnets  = ["10.0.64.0/19", "10.0.96.0/19"]

  map_public_ip_on_launch = true
+  manage_default_network_acl = true

+  public_dedicated_network_acl = true

+  public_inbound_acl_rules = [
+    {
+      rule_number = 1
+      rule_action = "allow"
+      from_port   = 80
+      to_port     = 80
+      protocol    = "tcp"
+      cidr_block  = "0.0.0.0/0"
+    },
+  ]
}

그 외, 고려해볼 VPC 옵션

기존

image
image
image

규칙 우선순위

  • * 는 가장 후순위
  • rule number는 낮은 것 우선. (모순되더라도 나머지 규칙은 무시)
  • 현재 최상위 규칙은 모든 트래픽을 허용중이다. 즉 변경할 필요가 없다

테스트 Nodeport:30000 으로 연결 가능 테스트

apiVersion: v1
kind: Service
metadata:
  name: test
spec:
  type: NodePort     # 서비스 타입
  ports:
  - port: 8080
    targetPort: 8080 
    nodePort: 30001
    protocol: TCP
    name: http
  externalIPs: # 만약 이 부분이 없어진다면 접속에 장애가 생긴다
    - 13.125.122.142
    - 43.201.85.206 
  selector:
    app.kubernetes.io/instance: prod
    app.kubernetes.io/name: ticketing-application
$ curl 13.125.122.142:30001
OK

hostNetwork: true를 이용한 80 포트 접속 테스트

$ helm upgrade --install ingress-nginx ingress-nginx   --repo https://kubernetes.github.io/ingress-nginx 
$ helm upgrade --install ingress-nginx ingress-nginx   --repo https://kubernetes.github.io/ingress-nginx  --set controller.hostNetwork=true,controller.service.type="",controller.kind=DaemonSet

$ helm list
NAME            NAMESPACE       REVISION        UPDATED                                 STATUS          CHART                   APP VERSION
ingress-nginx   default         2               2023-09-12 08:56:39.597860234 +0000 UTC deployed        ingress-nginx-4.7.2     1.8.2     

$ kubectl get pod -o wide
NAME                                          READY   STATUS    RESTARTS   AGE     IP            NODE                                             NOMINATED NODE   READINESS GATES
ingress-nginx-controller-69tvt                1/1     Running   0          5h25m   10.0.77.252   ip-10-0-77-252.ap-northeast-2.compute.internal   <none>           <none>
ingress-nginx-controller-6r4ms                1/1     Running   0          5h25m   10.0.71.165   ip-10-0-71-165.ap-northeast-2.compute.internal   <none>           <none>
ingress-nginx-controller-h8jh5                1/1     Running   0          5h25m   10.0.93.81    ip-10-0-93-81.ap-northeast-2.compute.internal    <none>           <none>
ingress-nginx-controller-jvn5k                1/1     Running   0          5h25m   10.0.94.57    ip-10-0-94-57.ap-northeast-2.compute.internal    <none>           <none>

 $ kubectl get svc
NAME                                 TYPE        CLUSTER-IP       EXTERNAL-IP                    PORT(S)          AGE
ingress-nginx-controller             ClusterIP   172.20.150.192   <none>                         80/TCP,443/TCP   5h26m
ingress-nginx-controller-admission   ClusterIP   172.20.95.37     <none>                         443/TCP          5h26m

$ curl 13.125.122.142
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx</center>
</body>
</html>

$ curl 43.201.150.44
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx</center>
</body>
</html>

@junha-ahn junha-ahn moved this from Todo to In Progress in Kanban Infra Sep 12, 2023
@junha-ahn junha-ahn linked a pull request Sep 12, 2023 that will close this issue
@junha-ahn
Copy link
Member Author

junha-ahn commented Sep 13, 2023

Nginx Ingress Baremetal 직접 따라해보기

참고

배경: Backend Service

apiVersion: v1
kind: Service
metadata:
  name: {{ include "ticketing-chart.fullname" . }}
spec:
  type: ClusterIP
  ports:
  - port: {{ .Values.backend.port }}
    targetPort: {{ .Values.backend.port }}
  selector:
    {{- include "ticketing-chart.selectorLabels" . | nindent 4 }}
$ kubectl get svc
NAME                         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
kubernetes                   ClusterIP   172.20.0.1      <none>        443/TCP    30d
prod-ticketing-application   ClusterIP   172.20.110.40   <none>        8080/TCP   15s


$ kubectl port-forward svc/prod-ticketing-application 3001:8080 
Forwarding from 127.0.0.1:3001 -> 8080
Forwarding from [::1]:3001 -> 8080

$ curl 127.0.0.1:3001
OK
$ curl 127.0.0.1:3001/bookamrks
{"message":"JWT Autorization failed."}

따라해보기

$ wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.2/deploy/static/provider/baremetal/deploy.yaml

$ kubectl apply -f deploy.yaml 
namespace/ingress-nginx created
serviceaccount/ingress-nginx created
serviceaccount/ingress-nginx-admission created
role.rbac.authorization.k8s.io/ingress-nginx created
role.rbac.authorization.k8s.io/ingress-nginx-admission created
clusterrole.rbac.authorization.k8s.io/ingress-nginx created
clusterrole.rbac.authorization.k8s.io/ingress-nginx-admission created
rolebinding.rbac.authorization.k8s.io/ingress-nginx created
rolebinding.rbac.authorization.k8s.io/ingress-nginx-admission created
clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx created
clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx-admission created
configmap/ingress-nginx-controller created
service/ingress-nginx-controller created
service/ingress-nginx-controller-admission created
deployment.apps/ingress-nginx-controller created
job.batch/ingress-nginx-admission-create created
job.batch/ingress-nginx-admission-patch created
ingressclass.networking.k8s.io/nginx created
validatingwebhookconfiguration.admissionregistration.k8s.io/ingress-nginx-admission created

 $ kubectl get all -n=ingress-nginx
NAME                                            READY   STATUS      RESTARTS   AGE
pod/ingress-nginx-admission-create-pxrtx        0/1     Completed   0          9s
pod/ingress-nginx-admission-patch-ff6xm         0/1     Completed   0          8s
pod/ingress-nginx-controller-79bc9f5df8-7g9tv   0/1     Running     0          9s

NAME                                         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                      AGE
service/ingress-nginx-controller             NodePort    172.20.109.252   <none>        80:31475/TCP,443:31396/TCP   9s
service/ingress-nginx-controller-admission   ClusterIP   172.20.144.89    <none>        443/TCP                      9s

NAME                                       READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/ingress-nginx-controller   0/1     1            0           10s

NAME                                                  DESIRED   CURRENT   READY   AGE
replicaset.apps/ingress-nginx-controller-79bc9f5df8   1         1         0       10s

NAME                                       COMPLETIONS   DURATION   AGE
job.batch/ingress-nginx-admission-create   1/1           4s         10s
job.batch/ingress-nginx-admission-patch    1/1           3s         9s
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-myservicea
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: prod-ticketing-application
            port:
              number: 8080
  ingressClassName: nginx
$ kubectl apply -f ingress.yaml
ingress.networking.k8s.io/ingress-myservicea created

$ kubectl describe ingress ingress-myservicea
Name:             ingress-myservicea
Labels:           <none>
Namespace:        default
Address:          
Ingress Class:    nginx
Default backend:  <default>
Rules:
  Host        Path  Backends
  ----        ----  --------
  *           
              /   prod-ticketing-application:8080 (10.0.87.162:8080)
Annotations:  nginx.ingress.kubernetes.io/rewrite-target: /
Events:
  Type    Reason  Age   From                      Message
  ----    ------  ----  ----                      -------
  Normal  Sync    5s    nginx-ingress-controller  Scheduled for sync

$ kubectl get svc -n=ingress-nginx
NAME                                 TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                      AGE
ingress-nginx-controller             NodePort    172.20.109.252   <none>        80:31475/TCP,443:31396/TCP   2m10s
ingress-nginx-controller-admission   ClusterIP   172.20.144.89    <none>        443/TCP                      2m10s

 $ kubectl get svc -n=ingress-nginx
NAME                                 TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                      AGE
ingress-nginx-controller             NodePort    172.20.109.252   <none>        80:31475/TCP,443:31396/TCP   2m10s
ingress-nginx-controller-admission   ClusterIP   172.20.144.89    <none>        443/TCP                      2m10s

$ kubectl get nodes -o wide
NAME                                             STATUS   ROLES    AGE    VERSION               INTERNAL-IP   EXTERNAL-IP      OS-IMAGE         KERNEL-VERSION                  CONTAINER-RUNTIME
ip-10-0-71-165.ap-northeast-2.compute.internal   Ready    <none>   45h    v1.27.4-eks-8ccc7ba   10.0.71.165   13.125.122.142   Amazon Linux 2   5.10.186-179.751.amzn2.x86_64   containerd://1.6.19
ip-10-0-77-252.ap-northeast-2.compute.internal   Ready    <none>   3d4h   v1.27.4-eks-8ccc7ba   10.0.77.252   43.201.85.206    Amazon Linux 2   5.10.186-179.751.amzn2.x86_64   containerd://1.6.19
ip-10-0-93-81.ap-northeast-2.compute.internal    Ready    <none>   3d4h   v1.27.4-eks-8ccc7ba   10.0.93.81    43.201.150.44    Amazon Linux 2   5.10.186-179.751.amzn2.x86_64   containerd://1.6.19
ip-10-0-94-57.ap-northeast-2.compute.internal    Ready    <none>   3d4h   v1.27.4-eks-8ccc7ba   10.0.94.57    52.79.49.224     Amazon Linux 2   5.10.186-179.751.amzn2.x86_64   containerd://1.6.19

$ curl 13.125.122.142:31475
OK
$ curl 43.201.85.206:31475
OK

기타

  • kubectl delete ns ingress-nginx --grace-period=0 --force 네임스페이스 삭제 오류시

HostNetwork True 구성 따라하기

Template 파일 생성

$ helm template ingress-nginx ingress-nginx   --repo https://kubernetes.github.io/ingress-nginx  --set controller.hostNetwork=true,controller.service.type="",controller.kind=DaemonSet > nginx.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-myservicea
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: development-ticketing-application
            port:
              number: 8080
  ingressClassName: nginx

Test

$  kubectl describe ingress                                                                                   05:15:21 PM
Name:             development-ticketing-application
Labels:           argocd.argoproj.io/instance=development
Namespace:        default
Address:          172.20.209.236
Ingress Class:    nginx
Default backend:  <default>
Rules:
  Host        Path  Backends
  ----        ----  --------
  *           
              /   development-ticketing-application:8080 (10.0.80.146:8080)
Annotations:  nginx.ingress.kubernetes.io/rewrite-target: /
Events:
  Type    Reason  Age                From                      Message
  ----    ------  ----               ----                      -------
  Normal  Sync    29m (x2 over 30m)  nginx-ingress-controller  Scheduled for sync
  Normal  Sync    29m (x2 over 30m)  nginx-ingress-controller  Scheduled for sync
  Normal  Sync    29m (x2 over 30m)  nginx-ingress-controller  Scheduled for sync
  Normal  Sync    29m (x2 over 30m)  nginx-ingress-controller  Scheduled for sync

❯ curl 43.201.85.206
OK

Todo

  • Nginx 프로메테우스 구성

@junha-ahn junha-ahn changed the title ALB 삭제 Nginx Ingress 구축 (요금 문제) AWS ALB 삭제 후 Nginx Ingress(Baremetal) 구축 (요금 문제) Sep 13, 2023
@github-project-automation github-project-automation bot moved this from In Progress to Done in Kanban Infra Sep 14, 2023
@junha-ahn junha-ahn reopened this Sep 14, 2023
@junha-ahn junha-ahn mentioned this issue Sep 17, 2023
6 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request Major Major topic
Projects
Status: Done
Development

Successfully merging a pull request may close this issue.

2 participants