yeonghoon.kim

  • 게시판
  • 갤러리

Docker Compose 서비스를 Kubernetes로 이전(깃랩 도커 저장소 필요)

김영훈 2026.06.10 12:04 조회 수 : 20

기존 Docker Compose로 실행하던 yeonghoon.kim과 money.yeonghoon.kim 서비스를 Kubernetes로 이전함.

애플리케이션 이미지는 기존 DGX GitLab Registry에 push하고 Kubernetes Deployment에서 pull하도록 구성함.

Namespace, PV/PVC, ConfigMap, Secret 예제, Deployment 또는 StatefulSet, Service, Ingress manifest를 작성하고 kubectl apply로 배포함.

실제 Secret 파일은 제외하고 secret.example.yaml만 기록함.

이미지 빌드와 push

# Rhymix PHP 이미지를 빌드하고 Registry에 올린다.
docker build -t registry-dgx.kyh:5050/ioniere/3009-yeonghoon.kim/rhymix-php:8.2-001 docker/php
docker push registry-dgx.kyh:5050/ioniere/3009-yeonghoon.kim/rhymix-php:8.2-001

# Money Web 이미지를 빌드하고 Registry에 올린다.
docker build \
  -f ~/gitlab-project-clones/ioniere/3006-money.yeonghoon.kim/app-image/Dockerfile \
  -t registry-dgx.kyh:5050/ioniere/3006-money.yeonghoon.kim/money-web:0.1.0 \
  ~/gitlab-project-clones/ioniere/3006-money.yeonghoon.kim
docker push registry-dgx.kyh:5050/ioniere/3006-money.yeonghoon.kim/money-web:0.1.0

Kubernetes manifest 원문

===== 3009-yeonghoon.kim =====

----- k8s/configmap-nginx.yaml -----
apiVersion: v1
kind: ConfigMap
metadata:
  name: rhymix-nginx-config
  namespace: 3009-yeonghoon-kim
data:
  default.conf: |
    server {
        listen 80;
        server_name localhost;

        server_tokens off;

        root /var/www/html;
        index index.php index.html;

        client_max_body_size 64M;

        access_log /var/log/nginx/access.log;
        error_log /var/log/nginx/error.log;

        include /etc/nginx/conf.d/rhymix.inc;

        location ~ \.php$ {
            fastcgi_pass 127.0.0.1:9000;
            fastcgi_index index.php;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            include fastcgi_params;

            fastcgi_read_timeout 300;
            fastcgi_send_timeout 300;
        }

        location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff|woff2|ttf|svg|eot)$ {
            expires 30d;
            add_header Cache-Control "public, immutable";
        }
    }

  rhymix.inc: |
    location ~ ^/modules/editor/(skins|styles)/.+\.html$ {
        # pass
    }
    location ~ ^/(addons|common/tpl|files/(faceOff|ruleset)|(m\.)?layouts|modules|plugins|themes|widgets|widgetstyles)/.+\.(html|xml|blade\.php)$ {
        return 403;
    }
    location ~ ^/files/(attach|config|cache)/.+\.(ph(p|t|ar)?[0-9]?|p?html?|cgi|pl|exe|[aj]spx?|inc|bak)$ {
        return 403;
    }
    location ~ ^/files/(env|member_extra_info/(new_message_flags|point))/ {
        return 403;
    }
    location ~ ^/(\.git|\.ht|\.travis|codeception\.|composer\.|Gruntfile\.js|package\.json|CONTRIBUTING|COPYRIGHT|LICENSE|README) {
        return 403;
    }

    location ~ ^/(.+)/(addons|files|layouts|m\.layouts|modules|widgets|widgetstyles)/(.+) {
        try_files $uri $uri/ /$2/$3;
    }

    location ~ ^/(.+)\.min\.(css|js)$ {
        try_files $uri $uri/ /$1.$2;
    }

    location ~ ^/files/download/ {
        try_files $uri $uri/ /index.php$is_args$args;
    }

    location / {
        try_files $uri $uri/ /index.php$is_args$args;
    }

----- k8s/deployment-web.yaml -----
apiVersion: apps/v1
kind: Deployment
metadata:
  name: rhymix-web
  namespace: 3009-yeonghoon-kim
spec:
  replicas: 1
  selector:
    matchLabels:
      app: rhymix-web
  template:
    metadata:
      labels:
        app: rhymix-web
    spec:
      imagePullSecrets:
        - name: gitlab-registry-secret
      containers:
        - name: nginx
          image: nginx:alpine
          imagePullPolicy: IfNotPresent
          ports:
            - name: http
              containerPort: 80
          volumeMounts:
            - name: html
              mountPath: /var/www/html
            - name: nginx-config
              mountPath: /etc/nginx/conf.d/default.conf
              subPath: default.conf
              readOnly: true
            - name: nginx-config
              mountPath: /etc/nginx/conf.d/rhymix.inc
              subPath: rhymix.inc
              readOnly: true

        - name: php
          image: registry-dgx.kyh:5050/ioniere/3009-yeonghoon.kim/rhymix-php:8.2-001
          imagePullPolicy: IfNotPresent
          envFrom:
            - secretRef:
                name: rhymix-db-secret
          env:
            - name: DB_HOST
              value: db
            - name: DB_PORT
              value: "3306"
            - name: TZ
              value: Asia/Seoul
          ports:
            - name: php-fpm
              containerPort: 9000
          volumeMounts:
            - name: html
              mountPath: /var/www/html

      volumes:
        - name: html
          persistentVolumeClaim:
            claimName: rhymix-html
        - name: nginx-config
          configMap:
            name: rhymix-nginx-config

----- k8s/ingress.yaml -----
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: rhymix-web
  namespace: 3009-yeonghoon-kim
spec:
  ingressClassName: nginx
  rules:
    - host: yeonghoon.kim
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: rhymix-web
                port:
                  number: 80
    - host: www.yeonghoon.kim
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: rhymix-web
                port:
                  number: 80

----- k8s/namespace.yaml -----
apiVersion: v1
kind: Namespace
metadata:
  name: 3009-yeonghoon-kim

----- k8s/pv-pvc.yaml -----
apiVersion: v1
kind: PersistentVolume
metadata:
  name: 3009-rhymix-html-pv
spec:
  capacity:
    storage: 20Gi
  accessModes:
    - ReadWriteMany
  persistentVolumeReclaimPolicy: Retain
  storageClassName: 3009-rhymix-nfs
  nfs:
    server: 192.168.200.100
    path: /mnt/k8s-nfs/3009-yeonghoon.kim/html
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: rhymix-html
  namespace: 3009-yeonghoon-kim
spec:
  accessModes:
    - ReadWriteMany
  storageClassName: 3009-rhymix-nfs
  resources:
    requests:
      storage: 20Gi
  volumeName: 3009-rhymix-html-pv
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: 3009-rhymix-mariadb-pv
spec:
  capacity:
    storage: 5Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  storageClassName: 3009-rhymix-nfs
  nfs:
    server: 192.168.200.100
    path: /mnt/k8s-nfs/3009-yeonghoon.kim/mariadb
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: rhymix-mariadb
  namespace: 3009-yeonghoon-kim
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: 3009-rhymix-nfs
  resources:
    requests:
      storage: 5Gi
  volumeName: 3009-rhymix-mariadb-pv

----- k8s/secret.example.yaml -----
apiVersion: v1
kind: Secret
metadata:
  name: rhymix-db-secret
  namespace: 3009-yeonghoon-kim
type: Opaque
stringData:
  MYSQL_ROOT_PASSWORD: "CHANGE_ME_ROOT_PASSWORD"
  MYSQL_DATABASE: "rhymix"
  MYSQL_USER: "rhymix"
  MYSQL_PASSWORD: "CHANGE_ME_USER_PASSWORD"


----- k8s/service-web.yaml -----
apiVersion: v1
kind: Service
metadata:
  name: rhymix-web
  namespace: 3009-yeonghoon-kim
spec:
  selector:
    app: rhymix-web
  ports:
    - name: http
      port: 80
      targetPort: 80

----- k8s/statefulset-db.yaml -----
apiVersion: v1
kind: Service
metadata:
  name: db
  namespace: 3009-yeonghoon-kim
spec:
  selector:
    app: rhymix-db
  ports:
    - name: mysql
      port: 3306
      targetPort: 3306
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: rhymix-db
  namespace: 3009-yeonghoon-kim
spec:
  serviceName: db
  replicas: 1
  selector:
    matchLabels:
      app: rhymix-db
  template:
    metadata:
      labels:
        app: rhymix-db
    spec:
      containers:
        - name: mariadb
          image: mariadb:10.6
          imagePullPolicy: IfNotPresent
          args:
            - "--character-set-server=utf8mb4"
            - "--collation-server=utf8mb4_unicode_ci"
          envFrom:
            - secretRef:
                name: rhymix-db-secret
          env:
            - name: TZ
              value: Asia/Seoul
          ports:
            - name: mysql
              containerPort: 3306
          volumeMounts:
            - name: mariadb-data
              mountPath: /var/lib/mysql
      volumes:
        - name: mariadb-data
          persistentVolumeClaim:
            claimName: rhymix-mariadb

===== 3006-money.yeonghoon.kim =====

----- k8s/00-namespace.yaml -----
apiVersion: v1
kind: Namespace
metadata:
  name: money
  labels:
    app.kubernetes.io/name: money
    app.kubernetes.io/part-of: money

----- k8s/10-mysql-pv-pvc.yaml -----
apiVersion: v1
kind: PersistentVolume
metadata:
  name: money-mysql-data-pv
  labels:
    app.kubernetes.io/name: money-mysql
    app.kubernetes.io/part-of: money
spec:
  capacity:
    storage: 5Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  storageClassName: ""
  nfs:
    server: 192.168.200.100
    path: /mnt/k8s-nfs/3006-money.yeonghoon.kim/mysql
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: money-mysql-data
  namespace: money
  labels:
    app.kubernetes.io/name: money-mysql
    app.kubernetes.io/part-of: money
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: ""
  volumeName: money-mysql-data-pv
  resources:
    requests:
      storage: 5Gi

----- k8s/20-web-configmap.yaml -----
apiVersion: v1
kind: ConfigMap
metadata:
  name: money-web-config
  namespace: money
  labels:
    app.kubernetes.io/name: money-web
    app.kubernetes.io/part-of: money
data:
  APP_ENV: "production"
  PHP_TIMEZONE: "Asia/Seoul"
  API_BASE_PATH: "/api"
  CORS_ALLOWED_ORIGINS: "https://money.yeonghoon.kim"
  USE_DOCKER_MYSQL: "true"
  DB_HOST: "money-mysql"
  DB_PORT: "3306"
  DB_NAME: "money_management"
  DB_USER: "root"
  MAX_LOGIN_ATTEMPTS: "5"
  LOGIN_LOCKOUT_TIME: "900"

----- k8s/21-mysql-configmap.yaml -----
apiVersion: v1
kind: ConfigMap
metadata:
  name: money-mysql-config
  namespace: money
  labels:
    app.kubernetes.io/name: money-mysql
    app.kubernetes.io/part-of: money
data:
  TZ: "Asia/Seoul"
  MYSQL_DATABASE: "money_management"
  MYSQL_CHARACTER_SET_SERVER: "utf8mb4"
  MYSQL_COLLATION_SERVER: "utf8mb4_unicode_ci"

----- k8s/22-mysql-files-configmap.yaml -----
apiVersion: v1
data:
  my.cnf: |-
    [mysqld]
    character-set-server=utf8mb4
    collation-server=utf8mb4_unicode_ci
    init-connect='SET NAMES utf8mb4'

    [mysql]
    default-character-set=utf8mb4

    [client]
    default-character-set=utf8mb4
  schema.sql: "-- =====================================\n-- 머니매니저 데이터베이스 스키마\n-- =====================================\n--\n--
    개인 자산관리 웹 애플리케이션의 전체 데이터베이스 구조를 정의합니다.\n-- 현금, 투자, 연금 자산 관리와 지출 추적, 아카이브 시스템을
    지원합니다.\n--\n-- 주요 테이블 그룹:\n-- 1. 자산 관리 테이블\n--    - cash_assets: 현금성 자산 (은행 계좌,
    현금 등)\n--    - investment_assets: 투자 자산 (주식, 펀드, ISA 등)\n--    - pension_assets:
    연금 자산 (연금저축, 퇴직연금 등)\n--\n-- 2. 지출 관리 테이블\n--    - daily_expenses: 일간 지출 내역\n--
    \   - fixed_expenses: 고정 지출 (월세, 공과금 등)\n--    - prepaid_expenses: 선납 지출 (보험료
    등)\n--\n-- 3. 아카이브 시스템\n--    - monthly_archives: 월별 아카이브 기본 정보\n--    - *_archive:
    각 자산/지출의 아카이브 데이터\n--    - archive_summary_cache: 아카이브 요약 정보 캐시\n--\n-- 4. 시스템
    관리 테이블\n--    - user_sessions: 세션 기반 인증\n--    - assets_monthly_snapshot: 월별 자산
    스냅샷\n--    - expenses_monthly_summary: 월별 지출 요약\n--\n-- 데이터베이스 특징:\n-- - UTF-8
    완전 지원 (utf8mb4, 이모지 포함)\n-- - 소프트 삭제 지원 (deleted_at 컬럼)\n-- - 자동 타임스탬프 (created_at,
    updated_at)\n-- - 외래키 제약조건으로 데이터 무결성 보장\n-- - 성능 최적화 인덱스\n-- - 계산된 컬럼으로 실시간 집계\n--\n--
    @database money_management\n-- @charset utf8mb4\n-- @collation utf8mb4_unicode_ci\n--
    @engine InnoDB\n-- @version 1.0\n-- @author YeongHoon Kim\n--\n-- MySQL dump 10.13
    \ Distrib 8.0.43, for Linux (x86_64)\n--\n-- Host: localhost    Database: money_management\n--
    ------------------------------------------------------\n-- Server version\t8.0.43\n\n/*!40101
    SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;\n/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS
    */;\n/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;\n/*!50503
    SET NAMES utf8mb4 */;\n/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;\n/*!40103 SET
    TIME_ZONE='+00:00' */;\n/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0
    */;\n/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0
    */;\n/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;\n/*!40111
    SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;\n\n--\n-- Table structure for
    table `archive_summary_cache`\n--\n\nDROP TABLE IF EXISTS `archive_summary_cache`;\n/*!40101
    SET @saved_cs_client     = @@character_set_client */;\n/*!50503 SET character_set_client
    = utf8mb4 */;\nCREATE TABLE `archive_summary_cache` (\n  `archive_id` int NOT
    NULL,\n  `cash_total` bigint DEFAULT '0',\n  `cash_count` int DEFAULT '0',\n  `investment_total`
    bigint DEFAULT '0',\n  `investment_count` int DEFAULT '0',\n  `pension_total`
    bigint DEFAULT '0',\n  `pension_count` int DEFAULT '0',\n  `total_assets` bigint
    GENERATED ALWAYS AS (((`cash_total` + `investment_total`) + `pension_total`))
    STORED,\n  `updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,\n
    \ PRIMARY KEY (`archive_id`),\n  CONSTRAINT `archive_summary_cache_ibfk_1` FOREIGN
    KEY (`archive_id`) REFERENCES `monthly_archives` (`id`) ON DELETE CASCADE\n) ENGINE=InnoDB
    DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;\n/*!40101 SET character_set_client
    = @saved_cs_client */;\n\n--\n-- Table structure for table `assets_archive_data`\n--\n\nDROP
    TABLE IF EXISTS `assets_archive_data`;\n/*!40101 SET @saved_cs_client     = @@character_set_client
    */;\n/*!50503 SET character_set_client = utf8mb4 */;\nCREATE TABLE `assets_archive_data`
    (\n  `id` int NOT NULL AUTO_INCREMENT,\n  `archive_id` int NOT NULL,\n  `asset_table`
    enum('cash_assets','investment_assets','pension_assets') COLLATE utf8mb4_unicode_ci
    NOT NULL,\n  `asset_data` json NOT NULL COMMENT '원본 테이블 데이터 완전 보존',\n  `created_at`
    timestamp NULL DEFAULT CURRENT_TIMESTAMP,\n  PRIMARY KEY (`id`),\n  KEY `idx_archive_table`
    (`archive_id`,`asset_table`),\n  KEY `idx_archive_id` (`archive_id`),\n  CONSTRAINT
    `assets_archive_data_ibfk_1` FOREIGN KEY (`archive_id`) REFERENCES `monthly_archives`
    (`id`) ON DELETE CASCADE\n) ENGINE=InnoDB AUTO_INCREMENT=859 DEFAULT CHARSET=utf8mb4
    COLLATE=utf8mb4_unicode_ci;\n/*!40101 SET character_set_client = @saved_cs_client
    */;\n\n--\n-- =====================================\n-- 현금성 자산 테이블 (cash_assets)\n--
    =====================================\n--\n-- 사용자의 현금성 자산을 관리하는 핵심 테이블입니다.\n--
    은행 계좌, 현금, 외화 등 유동성이 높은 자산을 추적합니다.\n--\n-- 주요 기능:\n-- - 자산 유형별 분류 (현금/통장)\n--
    - 계좌별 잔액 관리\n-- - 드래그 앤 드롭 순서 변경 (display_order)\n-- - 소프트 삭제 지원 (deleted_at)\n--
    - 자동 타임스탬프 (created_at, updated_at)\n--\n-- 인덱스 최적화:\n-- - 활성 자산 조회 (deleted_at
    IS NULL)\n-- - 순서 정렬 (display_order)\n--\n-- 관련 테이블:\n-- - cash_assets_archive:
    월별 아카이브 데이터\n--\n\nDROP TABLE IF EXISTS `cash_assets`;\n/*!40101 SET @saved_cs_client
    \    = @@character_set_client */;\n/*!50503 SET character_set_client = utf8mb4
    */;\nCREATE TABLE `cash_assets` (\n  `id` int NOT NULL AUTO_INCREMENT,\n  `type`
    enum('현금','통장') COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '자산 유형',\n  `account_name`
    varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '계좌명',\n  `item_name`
    varchar(200) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '항목명',\n  `balance` int
    NOT NULL DEFAULT '0' COMMENT '잔액(원)',\n  `display_order` int NOT NULL DEFAULT
    '0' COMMENT '표시 순서',\n  `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,\n
    \ `updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,\n
    \ `deleted_at` timestamp NULL DEFAULT NULL COMMENT '삭제일시 (NULL이면 활성)',\n  PRIMARY
    KEY (`id`),\n  KEY `idx_display_order` (`display_order`),\n  KEY `idx_cash_assets_deleted`
    (`deleted_at`)\n) ENGINE=InnoDB AUTO_INCREMENT=23 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;\n/*!40101
    SET character_set_client = @saved_cs_client */;\n\n--\n-- Table structure for
    table `cash_assets_archive`\n--\n\nDROP TABLE IF EXISTS `cash_assets_archive`;\n/*!40101
    SET @saved_cs_client     = @@character_set_client */;\n/*!50503 SET character_set_client
    = utf8mb4 */;\nCREATE TABLE `cash_assets_archive` (\n  `id` int NOT NULL AUTO_INCREMENT,\n
    \ `archive_id` int NOT NULL COMMENT '월별 아카이브 ID',\n  `type` enum('현금','통장') COLLATE
    utf8mb4_unicode_ci NOT NULL COMMENT '자산 유형',\n  `account_name` varchar(100) COLLATE
    utf8mb4_unicode_ci DEFAULT NULL COMMENT '계좌명',\n  `item_name` varchar(200) COLLATE
    utf8mb4_unicode_ci NOT NULL COMMENT '항목명',\n  `balance` int NOT NULL DEFAULT '0'
    COMMENT '잔액(원)',\n  `display_order` int NOT NULL DEFAULT '0' COMMENT '표시 순서',\n
    \ `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,\n  PRIMARY KEY (`id`),\n
    \ KEY `idx_archive_id` (`archive_id`),\n  CONSTRAINT `cash_assets_archive_ibfk_1`
    FOREIGN KEY (`archive_id`) REFERENCES `monthly_archives` (`id`) ON DELETE CASCADE\n)
    ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;\n/*!40101 SET
    character_set_client = @saved_cs_client */;\n\n--\n-- Table structure for table
    `daily_expenses`\n--\n\nDROP TABLE IF EXISTS `daily_expenses`;\n/*!40101 SET @saved_cs_client
    \    = @@character_set_client */;\n/*!50503 SET character_set_client = utf8mb4
    */;\nCREATE TABLE `daily_expenses` (\n  `id` int NOT NULL AUTO_INCREMENT,\n  `expense_date`
    date NOT NULL COMMENT '지출일자',\n  `total_amount` int NOT NULL DEFAULT '0' COMMENT
    '총 금액(원)',\n  `food_cost` int DEFAULT '0' COMMENT '식비(원)',\n  `necessities_cost`
    int DEFAULT '0' COMMENT '생필품비(원)',\n  `transportation_cost` int DEFAULT '0' COMMENT
    '교통비(원)',\n  `other_cost` int DEFAULT '0' COMMENT '기타(원)',\n  `created_at` timestamp
    NULL DEFAULT CURRENT_TIMESTAMP,\n  `updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP
    ON UPDATE CURRENT_TIMESTAMP,\n  `deleted_at` timestamp NULL DEFAULT NULL,\n  PRIMARY
    KEY (`id`),\n  UNIQUE KEY `unique_expense_date` (`expense_date`,`deleted_at`),\n
    \ KEY `idx_daily_expenses_deleted` (`deleted_at`),\n  KEY `idx_daily_expenses_date`
    (`expense_date`)\n) ENGINE=InnoDB AUTO_INCREMENT=1119 DEFAULT CHARSET=utf8mb4
    COLLATE=utf8mb4_unicode_ci;\n/*!40101 SET character_set_client = @saved_cs_client
    */;\n\n--\n-- Table structure for table `fixed_expenses`\n--\n\nDROP TABLE IF
    EXISTS `fixed_expenses`;\n/*!40101 SET @saved_cs_client     = @@character_set_client
    */;\n/*!50503 SET character_set_client = utf8mb4 */;\nCREATE TABLE `fixed_expenses`
    (\n  `id` int NOT NULL AUTO_INCREMENT,\n  `category` varchar(50) COLLATE utf8mb4_unicode_ci
    DEFAULT NULL COMMENT '분류 (보험, 통신, 주거 등)',\n  `item_name` varchar(200) COLLATE
    utf8mb4_unicode_ci NOT NULL COMMENT '항목명',\n  `amount` int NOT NULL COMMENT '금액(원)',\n
    \ `payment_date` int DEFAULT NULL COMMENT '매월 결제일 (1-31)',\n  `payment_method`
    enum('신용','체크','현금') COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '결제수단',\n  `is_active`
    tinyint(1) DEFAULT '1' COMMENT '활성 여부',\n  `created_at` timestamp NULL DEFAULT
    CURRENT_TIMESTAMP,\n  `updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON
    UPDATE CURRENT_TIMESTAMP,\n  `deleted_at` timestamp NULL DEFAULT NULL,\n  PRIMARY
    KEY (`id`),\n  KEY `idx_fixed_expenses_deleted` (`deleted_at`)\n) ENGINE=InnoDB
    AUTO_INCREMENT=75 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;\n/*!40101
    SET character_set_client = @saved_cs_client */;\n\n--\n-- Table structure for
    table `fixed_expenses_archive`\n--\n\nDROP TABLE IF EXISTS `fixed_expenses_archive`;\n/*!40101
    SET @saved_cs_client     = @@character_set_client */;\n/*!50503 SET character_set_client
    = utf8mb4 */;\nCREATE TABLE `fixed_expenses_archive` (\n  `id` int NOT NULL AUTO_INCREMENT,\n
    \ `archive_id` int NOT NULL COMMENT '월별 아카이브 ID',\n  `category` varchar(50) COLLATE
    utf8mb4_unicode_ci DEFAULT NULL COMMENT '카테고리',\n  `item_name` varchar(200) COLLATE
    utf8mb4_unicode_ci NOT NULL COMMENT '항목명',\n  `amount` int NOT NULL DEFAULT '0'
    COMMENT '금액(원)',\n  `payment_date` int DEFAULT NULL COMMENT '결제일(1-31)',\n  `payment_method`
    enum('신용','체크','현금') COLLATE utf8mb4_unicode_ci DEFAULT '신용' COMMENT '결제수단',\n
    \ `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,\n  PRIMARY KEY (`id`),\n
    \ KEY `idx_archive_id` (`archive_id`),\n  CONSTRAINT `fixed_expenses_archive_ibfk_1`
    FOREIGN KEY (`archive_id`) REFERENCES `monthly_archives` (`id`) ON DELETE CASCADE\n)
    ENGINE=InnoDB AUTO_INCREMENT=4381 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;\n/*!40101
    SET character_set_client = @saved_cs_client */;\n\n--\n-- Table structure for
    table `investment_assets`\n--\n\nDROP TABLE IF EXISTS `investment_assets`;\n/*!40101
    SET @saved_cs_client     = @@character_set_client */;\n/*!50503 SET character_set_client
    = utf8mb4 */;\nCREATE TABLE `investment_assets` (\n  `id` int NOT NULL AUTO_INCREMENT,\n
    \ `category` enum('저축','혼합','주식') COLLATE utf8mb4_unicode_ci NOT NULL COMMENT
    '자산 분류',\n  `account_name` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL
    COMMENT '계좌명',\n  `item_name` varchar(200) COLLATE utf8mb4_unicode_ci NOT NULL
    COMMENT '종목명',\n  `current_value` int NOT NULL DEFAULT '0' COMMENT '현재 평가금액(원)',\n
    \ `deposit_amount` int NOT NULL DEFAULT '0' COMMENT '납입 원금(원)',\n  `display_order`
    int NOT NULL DEFAULT '0',\n  `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,\n
    \ `updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,\n
    \ `deleted_at` timestamp NULL DEFAULT NULL,\n  PRIMARY KEY (`id`),\n  KEY `idx_investment_assets_deleted`
    (`deleted_at`)\n) ENGINE=InnoDB AUTO_INCREMENT=22 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;\n/*!40101
    SET character_set_client = @saved_cs_client */;\n\n--\n-- Table structure for
    table `investment_assets_archive`\n--\n\nDROP TABLE IF EXISTS `investment_assets_archive`;\n/*!40101
    SET @saved_cs_client     = @@character_set_client */;\n/*!50503 SET character_set_client
    = utf8mb4 */;\nCREATE TABLE `investment_assets_archive` (\n  `id` int NOT NULL
    AUTO_INCREMENT,\n  `archive_id` int NOT NULL COMMENT '월별 아카이브 ID',\n  `category`
    enum('저축','혼합','주식') COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '자산 분류',\n  `account_name`
    varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '계좌명',\n  `item_name`
    varchar(200) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '종목명',\n  `current_value`
    int NOT NULL DEFAULT '0' COMMENT '현재 평가금액(원)',\n  `deposit_amount` int NOT NULL
    DEFAULT '0' COMMENT '납입 원금(원)',\n  `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,\n
    \ PRIMARY KEY (`id`),\n  KEY `idx_archive_id` (`archive_id`),\n  CONSTRAINT `investment_assets_archive_ibfk_1`
    FOREIGN KEY (`archive_id`) REFERENCES `monthly_archives` (`id`) ON DELETE CASCADE\n)
    ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;\n/*!40101 SET
    character_set_client = @saved_cs_client */;\n\n--\n-- Table structure for table
    `monthly_archives`\n--\n\nDROP TABLE IF EXISTS `monthly_archives`;\n/*!40101 SET
    @saved_cs_client     = @@character_set_client */;\n/*!50503 SET character_set_client
    = utf8mb4 */;\nCREATE TABLE `monthly_archives` (\n  `id` int NOT NULL AUTO_INCREMENT,\n
    \ `archive_month` date NOT NULL COMMENT '아카이브 월 (YYYY-MM-01 형식)',\n  `modification_notes`
    text COLLATE utf8mb4_unicode_ci COMMENT '수정 내역',\n  `created_at` timestamp NULL
    DEFAULT CURRENT_TIMESTAMP,\n  `updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP
    ON UPDATE CURRENT_TIMESTAMP,\n  `last_modified` timestamp NULL DEFAULT CURRENT_TIMESTAMP
    ON UPDATE CURRENT_TIMESTAMP,\n  PRIMARY KEY (`id`),\n  UNIQUE KEY `unique_archive_month`
    (`archive_month`)\n) ENGINE=InnoDB AUTO_INCREMENT=170 DEFAULT CHARSET=utf8mb4
    COLLATE=utf8mb4_unicode_ci;\n/*!40101 SET character_set_client = @saved_cs_client
    */;\n\n--\n-- Table structure for table `pension_assets`\n--\n\nDROP TABLE IF
    EXISTS `pension_assets`;\n/*!40101 SET @saved_cs_client     = @@character_set_client
    */;\n/*!50503 SET character_set_client = utf8mb4 */;\nCREATE TABLE `pension_assets`
    (\n  `id` int NOT NULL AUTO_INCREMENT,\n  `type` enum('연금저축','퇴직연금') COLLATE utf8mb4_unicode_ci
    NOT NULL COMMENT '연금 유형',\n  `item_name` varchar(200) COLLATE utf8mb4_unicode_ci
    NOT NULL COMMENT '상품명',\n  `current_value` int NOT NULL DEFAULT '0' COMMENT '평가금액(원)',\n
    \ `deposit_amount` int NOT NULL DEFAULT '0' COMMENT '납입잔액(원)',\n  `display_order`
    int NOT NULL DEFAULT '0',\n  `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,\n
    \ `updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,\n
    \ `deleted_at` timestamp NULL DEFAULT NULL,\n  PRIMARY KEY (`id`),\n  KEY `idx_pension_assets_deleted`
    (`deleted_at`)\n) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;\n/*!40101
    SET character_set_client = @saved_cs_client */;\n\n--\n-- Table structure for
    table `pension_assets_archive`\n--\n\nDROP TABLE IF EXISTS `pension_assets_archive`;\n/*!40101
    SET @saved_cs_client     = @@character_set_client */;\n/*!50503 SET character_set_client
    = utf8mb4 */;\nCREATE TABLE `pension_assets_archive` (\n  `id` int NOT NULL AUTO_INCREMENT,\n
    \ `archive_id` int NOT NULL COMMENT '월별 아카이브 ID',\n  `type` enum('연금저축','퇴직연금')
    COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '연금 유형',\n  `item_name` varchar(200)
    COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '상품명',\n  `current_value` int NOT
    NULL DEFAULT '0' COMMENT '평가금액(원)',\n  `deposit_amount` int NOT NULL DEFAULT '0'
    COMMENT '납입잔액(원)',\n  `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,\n
    \ PRIMARY KEY (`id`),\n  KEY `idx_archive_id` (`archive_id`),\n  CONSTRAINT `pension_assets_archive_ibfk_1`
    FOREIGN KEY (`archive_id`) REFERENCES `monthly_archives` (`id`) ON DELETE CASCADE\n)
    ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;\n/*!40101 SET
    character_set_client = @saved_cs_client */;\n\n--\n-- Table structure for table
    `prepaid_expenses`\n--\n\nDROP TABLE IF EXISTS `prepaid_expenses`;\n/*!40101 SET
    @saved_cs_client     = @@character_set_client */;\n/*!50503 SET character_set_client
    = utf8mb4 */;\nCREATE TABLE `prepaid_expenses` (\n  `id` int NOT NULL AUTO_INCREMENT,\n
    \ `item_name` varchar(200) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '항목명',\n
    \ `amount` int NOT NULL COMMENT '금액(원)',\n  `payment_date` int DEFAULT NULL COMMENT
    '결제일',\n  `payment_method` enum('신용','체크','현금') COLLATE utf8mb4_unicode_ci NOT
    NULL COMMENT '결제수단',\n  `expiry_date` date DEFAULT NULL COMMENT '만료일',\n  `is_active`
    tinyint(1) DEFAULT '1' COMMENT '활성 여부',\n  `created_at` timestamp NULL DEFAULT
    CURRENT_TIMESTAMP,\n  `updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON
    UPDATE CURRENT_TIMESTAMP,\n  `deleted_at` timestamp NULL DEFAULT NULL,\n  PRIMARY
    KEY (`id`),\n  KEY `idx_prepaid_expenses_deleted` (`deleted_at`)\n) ENGINE=InnoDB
    AUTO_INCREMENT=45 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;\n/*!40101
    SET character_set_client = @saved_cs_client */;\n\n--\n-- Table structure for
    table `prepaid_expenses_archive`\n--\n\nDROP TABLE IF EXISTS `prepaid_expenses_archive`;\n/*!40101
    SET @saved_cs_client     = @@character_set_client */;\n/*!50503 SET character_set_client
    = utf8mb4 */;\nCREATE TABLE `prepaid_expenses_archive` (\n  `id` int NOT NULL
    AUTO_INCREMENT,\n  `archive_id` int NOT NULL COMMENT '월별 아카이브 ID',\n  `item_name`
    varchar(200) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '항목명',\n  `amount` int
    NOT NULL DEFAULT '0' COMMENT '금액(원)',\n  `payment_date` int DEFAULT NULL COMMENT
    '결제일(1-31)',\n  `payment_method` enum('신용','체크','현금') COLLATE utf8mb4_unicode_ci
    DEFAULT '신용' COMMENT '결제수단',\n  `expiry_date` date DEFAULT NULL COMMENT '만료일',\n
    \ `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,\n  PRIMARY KEY (`id`),\n
    \ KEY `idx_archive_id` (`archive_id`),\n  CONSTRAINT `prepaid_expenses_archive_ibfk_1`
    FOREIGN KEY (`archive_id`) REFERENCES `monthly_archives` (`id`) ON DELETE CASCADE\n)
    ENGINE=InnoDB AUTO_INCREMENT=1054 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;\n/*!40101
    SET character_set_client = @saved_cs_client */;\n\n--\n-- Table structure for
    table `user_sessions`\n--\n\nDROP TABLE IF EXISTS `user_sessions`;\n/*!40101 SET
    @saved_cs_client     = @@character_set_client */;\n/*!50503 SET character_set_client
    = utf8mb4 */;\nCREATE TABLE `user_sessions` (\n  `session_id` varchar(128) COLLATE
    utf8mb4_unicode_ci NOT NULL,\n  `user_email` varchar(255) COLLATE utf8mb4_unicode_ci
    NOT NULL,\n  `session_data` text COLLATE utf8mb4_unicode_ci,\n  `created_at` timestamp
    NULL DEFAULT CURRENT_TIMESTAMP,\n  `expires_at` timestamp NOT NULL,\n  `last_activity`
    timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,\n  `ip_address`
    varchar(45) COLLATE utf8mb4_unicode_ci DEFAULT NULL,\n  `user_agent` text COLLATE
    utf8mb4_unicode_ci,\n  `csrf_token` varchar(128) COLLATE utf8mb4_unicode_ci DEFAULT
    NULL COMMENT 'CSRF 방지 토큰',\n  `is_active` tinyint(1) DEFAULT '1',\n  PRIMARY KEY
    (`session_id`),\n  KEY `idx_user_email` (`user_email`),\n  KEY `idx_expires_at`
    (`expires_at`),\n  KEY `idx_active` (`is_active`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
    COLLATE=utf8mb4_unicode_ci;\n/*!40101 SET character_set_client = @saved_cs_client
    */;\n\n--\n-- Dumping routines for database 'money_management'\n--\n/*!40103 SET
    TIME_ZONE=@OLD_TIME_ZONE */;\n\n/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;\n/*!40014
    SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;\n/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS
    */;\n/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;\n/*!40101
    SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;\n/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION
    */;\n/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;\n\n-- Dump completed on 2025-09-29
    10:02:48\n-- 로그인 시도 기록 테이블 (Rate Limiting용)\n-- IP + email 기준으로 실패 횟수 추적, 일정 횟수
    초과 시 잠금\nCREATE TABLE IF NOT EXISTS login_attempts (\n    id INT AUTO_INCREMENT
    PRIMARY KEY,\n    email VARCHAR(255) NOT NULL,\n    ip_address VARCHAR(45) NOT
    NULL,\n    attempted_at DATETIME DEFAULT CURRENT_TIMESTAMP,\n    INDEX idx_email_ip
    (email, ip_address),\n    INDEX idx_attempted_at (attempted_at)\n);\n"
kind: ConfigMap
metadata:
  name: money-mysql-files
  namespace: money

----- k8s/30-secret.example.yaml -----
apiVersion: v1
kind: Secret
metadata:
  name: money-secret
  namespace: money
  labels:
    app.kubernetes.io/name: money
    app.kubernetes.io/part-of: money
type: Opaque
stringData:
  DB_PASSWORD: "REPLACE_ME_DO_NOT_COMMIT"
  LOGIN_USERNAME: "REPLACE_ME_DO_NOT_COMMIT"
  LOGIN_PASSWORD_HASH: "REPLACE_ME_DO_NOT_COMMIT"
  TELEGRAM_BOT_TOKEN: "REPLACE_ME_DO_NOT_COMMIT"
  TELEGRAM_CHAT_ID: "REPLACE_ME_DO_NOT_COMMIT"

----- k8s/40-mysql-deployment.yaml -----
apiVersion: apps/v1
kind: Deployment
metadata:
  name: money-mysql
  namespace: money
  labels:
    app.kubernetes.io/name: money-mysql
    app.kubernetes.io/part-of: money
spec:
  replicas: 1
  strategy:
    type: Recreate
  selector:
    matchLabels:
      app.kubernetes.io/name: money-mysql
  template:
    metadata:
      labels:
        app.kubernetes.io/name: money-mysql
        app.kubernetes.io/part-of: money
    spec:
      containers:
        - name: mysql
          image: mysql:8.4
          imagePullPolicy: IfNotPresent
          ports:
            - name: mysql
              containerPort: 3306
          envFrom:
            - configMapRef:
                name: money-mysql-config
          env:
            - name: MYSQL_ROOT_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: money-secret
                  key: DB_PASSWORD
          args:
            - "--character-set-server=utf8mb4"
            - "--collation-server=utf8mb4_unicode_ci"
          volumeMounts:
            - name: mysql-data
              mountPath: /var/lib/mysql
            - name: mysql-config
              mountPath: /etc/mysql/conf.d/my.cnf
              subPath: my.cnf
            - name: mysql-schema
              mountPath: /docker-entrypoint-initdb.d/01-schema.sql
              subPath: schema.sql
          readinessProbe:
            exec:
              command:
                - sh
                - -c
                - mysqladmin ping -h 127.0.0.1 -uroot -p"$MYSQL_ROOT_PASSWORD"
            initialDelaySeconds: 20
            periodSeconds: 10
            timeoutSeconds: 5
          livenessProbe:
            exec:
              command:
                - sh
                - -c
                - mysqladmin ping -h 127.0.0.1 -uroot -p"$MYSQL_ROOT_PASSWORD"
            initialDelaySeconds: 60
            periodSeconds: 30
            timeoutSeconds: 5
          resources:
            requests:
              cpu: 100m
              memory: 512Mi
            limits:
              cpu: 1000m
              memory: 1Gi
      volumes:
        - name: mysql-data
          persistentVolumeClaim:
            claimName: money-mysql-data
        - name: mysql-config
          configMap:
            name: money-mysql-files
            items:
              - key: my.cnf
                path: my.cnf
        - name: mysql-schema
          configMap:
            name: money-mysql-files
            items:
              - key: schema.sql
                path: schema.sql

----- k8s/50-mysql-service.yaml -----
apiVersion: v1
kind: Service
metadata:
  name: money-mysql
  namespace: money
  labels:
    app.kubernetes.io/name: money-mysql
    app.kubernetes.io/part-of: money
spec:
  type: ClusterIP
  selector:
    app.kubernetes.io/name: money-mysql
  ports:
    - name: mysql
      port: 3306
      targetPort: mysql

----- k8s/60-web-deployment.yaml -----
apiVersion: apps/v1
kind: Deployment
metadata:
  name: money-web
  namespace: money
  labels:
    app.kubernetes.io/name: money-web
    app.kubernetes.io/part-of: money
spec:
  replicas: 1
  strategy:
    type: Recreate
  selector:
    matchLabels:
      app.kubernetes.io/name: money-web
  template:
    metadata:
      labels:
        app.kubernetes.io/name: money-web
        app.kubernetes.io/part-of: money
    spec:
      imagePullSecrets:
        - name: gitlab-registry-secret
      containers:
        - name: web
          image: registry-dgx.kyh:5050/ioniere/3006-money.yeonghoon.kim/money-web:0.1.0
          imagePullPolicy: IfNotPresent
          ports:
            - name: http
              containerPort: 80
          envFrom:
            - configMapRef:
                name: money-web-config
            - secretRef:
                name: money-secret
          volumeMounts:
            - name: app-logs
              mountPath: /var/log/app
          readinessProbe:
            httpGet:
              path: /
              port: http
            initialDelaySeconds: 10
            periodSeconds: 10
            timeoutSeconds: 5
          livenessProbe:
            httpGet:
              path: /
              port: http
            initialDelaySeconds: 30
            periodSeconds: 30
            timeoutSeconds: 5
          resources:
            requests:
              cpu: 50m
              memory: 128Mi
            limits:
              cpu: 500m
              memory: 512Mi
      volumes:
        - name: app-logs
          emptyDir: {}

----- k8s/70-web-service.yaml -----
apiVersion: v1
kind: Service
metadata:
  name: money-web
  namespace: money
  labels:
    app.kubernetes.io/name: money-web
    app.kubernetes.io/part-of: money
spec:
  type: ClusterIP
  selector:
    app.kubernetes.io/name: money-web
  ports:
    - name: http
      port: 80
      targetPort: http

----- k8s/80-ingress.yaml -----
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: money-web
  namespace: money
  labels:
    app.kubernetes.io/name: money-web
    app.kubernetes.io/part-of: money
  annotations:
    nginx.ingress.kubernetes.io/proxy-body-size: "20m"
spec:
  ingressClassName: nginx
  rules:
    - host: money.yeonghoon.kim
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: money-web
                port:
                  name: http

적용 명령

# 각 프로젝트 저장소에서 manifest를 적용한다.
kubectl apply -f k8s/

# 배포 상태를 확인한다.
kubectl get pods,svc,ingress -A -o wide
 


  • 추천 0

  • 비추천 0
이 게시물을
목록

댓글 2

번호 제목 글쓴이 날짜 조회 수
339 yeonghoon.kim php 업그레이드 new 김영훈 2026.07.09 0
338 GitLab Registry PAT 만료로 이미지 Pull 실패 김영훈 2026.07.08 14
337 Stateful과 Stateless 구분해보기 김영훈 2026.07.02 23
336 Git revert는 기록을 지우는 게 아니라 되돌리는 기록을 남기는 것 김영훈 2026.06.29 19
335 OutOfSync와 Degraded 구분하기 김영훈 2026.06.28 25
334 control-plane 장애 시나리오 관찰 김영훈 2026.06.27 12
333 worker 재부팅 전 drain 절차 정리 김영훈 2026.06.26 20
332 ImagePullBackOff와 registry pull secret 누락 김영훈 2026.06.22 17
331 ArgoCD 복구 중 GitLab 접근 문제 정리 김영훈 2026.06.22 26
330 관측 스택과 앱 배포 저장소 구조 정리 김영훈 2026.06.19 23
329 SOPS Secret 복구와 ArgoCD root Application 적용 김영훈 2026.06.18 28
328 복구 런북 초반 누락 사항 정리 김영훈 2026.06.17 15
327 CoreDNS로 GitLab Registry 내부 주소 고정 김영훈 2026.06.17 19
326 ArgoCD와 GitOps 구조 준비 김영훈 2026.06.16 16
325 SOPS age로 Kubernetes Secret 암복호화 김영훈 2026.06.15 23
324 yeonghoon.kim 배포 파일을 Helm Chart로 전환 [1] 김영훈 2026.06.12 18
» Docker Compose 서비스를 Kubernetes로 이전(깃랩 도커 저장소 필요) [2] 김영훈 2026.06.10 20
322 Kubernetes 기본 클러스터, ingress-nginx 설치 김영훈 2026.06.09 15
321 DGX Kubernetes 구성 계획 김영훈 2026.06.08 25
320 2026년 일본 여행(21일) 요약 김영훈 2026.06.02 17
쓰기 태그
 첫 페이지 1 2 3 4 5 6 7 8 9 10 끝 페이지