Helm 차트 구성
SMCTF의 백엔드 및 Container Provisioner, Ingress와 SA/RBAC 리소스 등을 배포하기 위해 Kubernetes 내 모든 리소스는 Helm 차트를 통해 배포됩니다.
로깅/모니터링(FluentBit + ServiceMonitor)은 별도의 kubernetes-observability Helm 차트에서 관리합니다.
아래의 명령어로 Helm 차트를 배포할 수 있습니다.
helm upgrade --install smctf ./kubernetes -f kubernetes/values.yaml기본적으로 필요한 네임스페이스 등이 포함되어 있으며, values.yaml은 배포 전에 적절하게 수정하여 사용해야 합니다.
SMCTF Helm 차트 설치 후 AWS LB Controller를 설치하세요. (IRSA 및 VPC ID를 필요로 하기 때문에 반드시 SMCTF Helm 차트 설치 후에 설치해야 합니다.)
helm repo add eks https://aws.github.io/eks-chartshelm repo update eks
helm install aws-load-balancer-controller eks/aws-load-balancer-controller \ -n kube-system \ --set clusterName=smctf \ --set serviceAccount.create=false \ --set serviceAccount.name=aws-load-balancer-controller \ --set nodeSelector.role=backend \ --set vpcId="<VPC_ID>" \ --set region=ap-northeast-2Prometheus 스택 설치 후 observability 차트를 설치합니다. (ServiceMonitor CRD 포함)
helm repo add prometheus-community https://prometheus-community.github.io/helm-chartshelm repo update
helm upgrade --install kube-prometheus-stack prometheus-community/kube-prometheus-stack \ -n monitoring --create-namespace \ --set grafana.enabled=false \ --set alertmanager.enabled=false \ --set prometheus.prometheusSpec.nodeSelector.role=backend \ --set prometheusOperator.nodeSelector.role=backend \ --set kubeStateMetrics.nodeSelector.role=backend \ --set nodeExporter.nodeSelector.role=backend
helm upgrade --install smctf-observability ./kubernetes-observability -f kubernetes-observability/values.yamlvalues.yaml을 구성하기 위해 Terraform을 통해 프로비저닝된 리소스들의 출력 결과를 확인해야 합니다. 이는 terraform output 명령어를 통해 확인할 수 있으며, 이를 기반으로 Helm 차트의 values.yaml을 적절하게 수정하여 배포해야 합니다.
Terraform 출력에 맞게 수정해야하는 필드는 아래와 같습니다.
# - elbController.serviceAccount.annotations.eks.amazonaws.com/role-arn (AWS Account ID/IRSA Role ARN)# - backend.serviceAccount.annotations.eks.amazonaws.com/role-arn (AWS Account ID/IRSA Role ARN)# - provisioner.serviceAccount.annotations.eks.amazonaws.com/role-arn (AWS Account ID/IRSA Role ARN)# - backend.config.DB_HOST (PostgreSQL RDS Endpoint)# - backend.config.REDIS_ADDR (ElastiCache Redis Endpoint, usually in the format "<cache-cluster-name>.xxxxxx.0001.use1.cache.amazonaws.com:6379")# - backend.ingress.securityGroupId (ALB Security Group ID)# - backend.ingress.https.certificateArn (ALB Certificate ARN, if HTTPS is enabled)# - provisioner.config.DDB_STACK_TABLE (DynamoDB Configuration)backend.ingress.securityGroupId는 설정하지 않고 주석처리 할 수 있습니다. 이 경우 자동으로 HTTP 80 포트 또는 HTTPS 443 포트가 열리도록 ALB 보안 그룹이 구성됩니다.- HTTPS Ingress를 위한 ACM은 따로 발급받은 인증서 ARN이 필요합니다. 이는 Terraform에서 ACM 인증서를 생성하지 않습니다.
- CloudWatch Logs Group Name은
/aws/eks/<project>-<env>/logs형식으로 설정되어야 하며, IRSA 설정으로 인해 고정된 형식이여야 합니다. (observability 차트의values.yaml에서 설정)
values.yaml 업데이트 또는 특정 필드를 업데이트하려면 아래와 같은 Helm 명령어를 사용할 수 있습니다.
helm upgrade --install smctf ./kubernetes \ --set backend.deployment.image.tag=v1.2.0 \ --set backend.deployment.replicas=3
helm upgrade --install smctf ./kubernetes -f new-values.yaml아래부터 values.yaml의 주요 구성 요소에 대한 설명과 예시 설정을 제공합니다. 필요에 따라 적절히 수정해야하며, 여기에 애플리케이션의 환경 변수가 모두 포함됩니다.
외부에 노출되지 않도록 절대적으로 주의하세요.
네임스페이스 구성
Section titled “네임스페이스 구성”namespaces: create: true backend: backend stacks: stackslogging, monitoring 네임스페이스는 observability 차트에서 생성됩니다.
AWS ELB Controller 구성
Section titled “AWS ELB Controller 구성”elbController: enabled: true serviceAccount: name: aws-load-balancer-controller namespace: kube-system labels: app.kubernetes.io/name: aws-load-balancer-controller annotations: eks.amazonaws.com/role-arn: arn:aws:iam::<AWS_ACCOUNT_ID>:role/smctf-dev-irsa-albResourceQouta 및 LimitRange 구성
Section titled “ResourceQouta 및 LimitRange 구성”stacksQuota: enabled: true name: stacks-resource-quota namespace: stacks hard: requests.cpu: '6' requests.memory: '6Gi' limits.cpu: '6' limits.memory: '6Gi'
stacksLimitRange: enabled: true name: stacks-limit-range namespace: stacks containerDefaults: max: cpu: '500m' memory: '512Mi' default: cpu: '500m' memory: '512Mi' defaultRequest: cpu: '500m' memory: '512Mi'NetworkPolicy 구성
Section titled “NetworkPolicy 구성”stacksDenyNetworkPolicy: enabled: true namePrefix: deny-from-stacks denyFromNamespace: stacks namespaces: - monitoring - backendBackend 구성
Section titled “Backend 구성”backend: enabled: true serviceAccount: name: smctf-backend namespace: backend annotations: eks.amazonaws.com/role-arn: arn:aws:iam::<AWS_ACCOUNT_ID>:role/smctf-dev-irsa-backend configName: smctf-backend-config secretName: smctf-backend-secretBackend ConfigMap 구성
Section titled “Backend ConfigMap 구성”config: APP_ENV: 'production' HTTP_ADDR: ':8080' SHUTDOWN_TIMEOUT: '10s' AUTO_MIGRATE: 'true' BCRYPT_COST: '12' DB_HOST: 'smctf-dev-postgres.cp4cewyumxw7.ap-northeast-2.rds.amazonaws.com' DB_PORT: '5432' DB_USER: 'app_user' DB_NAME: 'app_db' DB_SSLMODE: 'require' DB_MAX_OPEN_CONNS: '25' DB_MAX_IDLE_CONNS: '10' DB_CONN_MAX_LIFETIME: '30m' REDIS_ADDR: 'smctf-dev-redis.q2pzrs.ng.0001.apn2.cache.amazonaws.com:6379' REDIS_DB: '0' REDIS_POOL_SIZE: '20' JWT_ISSUER: 'smctf' JWT_ACCESS_TTL: '24h' JWT_REFRESH_TTL: '168h' SUBMIT_WINDOW: '1m' SUBMIT_MAX: '10' TIMELINE_CACHE_TTL: '60s' LEADERBOARD_CACHE_TTL: '60s' APP_CONFIG_CACHE_TTL: '2m' CORS_ALLOWED_ORIGINS: 'http://localhost:3000,http://localhost:5173,https://smctf.example.com,https://ctf.swua.kr' STACKS_ENABLED: 'true' STACKS_MAX_PER_USER: '3' STACKS_PROVISIONER_BASE_URL: 'http://container-provisioner.backend.svc.cluster.local:8081' STACKS_PROVISIONER_TIMEOUT: '5s' STACKS_CREATE_WINDOW: '1m' STACKS_CREATE_MAX: '1' LOG_DIR: 'logs' LOG_FILE_PREFIX: 'app' LOG_MAX_BODY_BYTES: '1048576' S3_ENABLED: 'true' S3_REGION: 'ap-northeast-2' S3_BUCKET: 'smctf-challenges-bucket' # S3_ENDPOINT: "" S3_FORCE_PATH_STYLE: 'false' S3_PRESIGN_TTL: '15m' BOOTSTRAP_ADMIN_TEAM: 'true' BOOTSTRAP_ADMIN_USER: 'true' BOOTSTRAP_ADMIN_USERNAME: 'admin'Backend Secrets 구성
Section titled “Backend Secrets 구성”secret: DB_PASSWORD: 'app_password' REDIS_PASSWORD: '' JWT_SECRET: 'change-me-strong' FLAG_HMAC_SECRET: 'change-me-too-strong' STACKS_PROVISIONER_API_KEY: 'secret-strong' # S3_ACCESS_KEY_ID: "" # S3_SECRET_ACCESS_KEY: "" BOOTSTRAP_ADMIN_USERNAME: 'admin' BOOTSTRAP_ADMIN_EMAIL: 'admin@smctf.com' BOOTSTRAP_ADMIN_PASSWORD: 'admin123!'Backend Deployment 및 Service 구성
Section titled “Backend Deployment 및 Service 구성”deployment: name: smctf-backend replicas: 2 containerName: smctf-backend-app image: repository: <AWS_ACCOUNT_ID>.dkr.ecr.ap-northeast-2.amazonaws.com/backend tag: latest pullPolicy: IfNotPresent port: 8080 nodeSelector: role: backend automountServiceAccountToken: true
service: name: smctf-backend type: NodePort port: 80 targetPort: 8080 nodePort: 30080Backend Ingress 구성
Section titled “Backend Ingress 구성”ingress: enabled: true className: alb annotations: kubernetes.io/ingress.class: alb alb.ingress.kubernetes.io/scheme: internet-facing alb.ingress.kubernetes.io/target-type: instance alb.ingress.kubernetes.io/backend-protocol: HTTP alb.ingress.kubernetes.io/healthcheck-path: /healthz # securityGroupId: sg-0316b2f31ab20189d host: '' path: / pathType: Prefix http: enabled: false listenPorts: '[{"HTTP":80}]' https: enabled: true listenPorts: '[{"HTTP":80},{"HTTPS":443}]' certificateArn: arn:aws:acm:ap-northeast-2:<AWS_ACCOUNT_ID>:certificate/3cc6e4d6-c43f-411a-9b5a-3c07105fb2c6 sslRedirect: trueContainer Provisioner 구성
Section titled “Container Provisioner 구성”provisioner: enabled: true serviceAccount: name: container-provisioner namespace: backend annotations: eks.amazonaws.com/role-arn: arn:aws:iam::<AWS_ACCOUNT_ID>:role/smctf-dev-irsa-container-provisioner configName: container-provisioner-config secretName: container-provisioner-secret
rbac: clusterRoleName: container-provisioner-role clusterRoleBindingName: container-provisioner-bindingContainer Provisioner ConfigMap 구성
Section titled “Container Provisioner ConfigMap 구성”config: APP_ENV: 'local' HTTP_ADDR: ':8081' SHUTDOWN_TIMEOUT: '10s' API_KEY_ENABLED: 'true' LOG_DIR: 'logs' LOG_FILE_PREFIX: 'app' LOG_MAX_BODY_BYTES: '1048576' STACK_NAMESPACE: 'stacks' STACK_TTL: '2h' STACK_SCHEDULER_INTERVAL: '10s' STACK_NODEPORT_MIN: '31001' STACK_NODEPORT_MAX: '32767' STACK_PORT_LOCK_TTL: '30s' STACK_NODE_ROLE: 'stack' STACK_REQUIRE_INGRESS_NETWORK_POLICY: 'true' DDB_USE_MOCK: 'false' DDB_STACK_TABLE: 'smctf-container-provisioner-stacks' DDB_CONSISTENT_READ: 'true' AWS_REGION: 'ap-northeast-2' # AWS_ENDPOINT: "" K8S_USE_MOCK: 'false' # K8S_KUBECONFIG: "" # K8S_CONTEXT: "" K8S_CLIENT_QPS: '20' K8S_CLIENT_BURST: '40' STACK_SCHEDULING_TIMEOUT: '20s'Container Provisioner Secrets 구성
Section titled “Container Provisioner Secrets 구성”secret: API_KEY: 'secret-strong' LOG_DISCORD_WEBHOOK_URL: '' LOG_SLACK_WEBHOOK_URL: ''Container Provisioner Deployment 및 Service 구성
Section titled “Container Provisioner Deployment 및 Service 구성”deployment: name: container-provisioner replicas: 2 containerName: container-provisioner-app image: repository: <AWS_ACCOUNT_ID>.dkr.ecr.ap-northeast-2.amazonaws.com/container-provisioner tag: latest pullPolicy: IfNotPresent port: 8081 nodeSelector: role: backend automountServiceAccountToken: true
service: name: container-provisioner type: ClusterIP port: 8081 targetPort: 8081Observability 구성 (Logging/Monitoring)
Section titled “Observability 구성 (Logging/Monitoring)”로깅(FluentBit)과 모니터링(ServiceMonitor)은 kubernetes-observability/values.yaml에서 관리합니다.
자세한 구성은 Observability 문서에서 확인하세요.