Skip to content
JAEWON CHANGSystems Dossier
Language

Specification

Organisation
SKKU Systems Consultant Group (SCG)
Period
2022 – 2026
Environment
Self-operated on-premise servers
Scope
About 15 web services in real campus use
Migration
Dependency assessment, then service-by-service
Role
Dev lead → president · server and infrastructure ownership · technical decisions

Context

Every service deployed differently — some under PM2, some under Docker. The projects over ten years old were bound tightly to a local filesystem and to one particular host.

Much of the operating knowledge lived in people's memory rather than in a document: which server ran what was something you had to know.

Approach

  1. Nothing moved at once. For each service I first established whether it was stateless or stateful, how it depended on the local filesystem and the database, where it wrote files, what breaking it would affect, and whether it could be recovered.

  2. Services that could move went to Kubernetes in stages. Services that could not stayed where they were, with the reason written down.

  3. Desired state was declared in Git and reconciled into the cluster by ArgoCD. Helm held per-service differences as values; GitHub Actions built the images.

  4. A Sync status in ArgoCD did not count as a deployment check. After every deploy I confirmed that pods were actually replaced, that containers were healthy, and that the service responded. Declared state and running behaviour are not the same thing.

  5. Vault held the secrets, so credentials never sat in code or plain configuration. Alongside Grafana-based monitoring, I dealt with the gap between a passing health check and a working service.

System

GitOps deploy and verification pathCommitGitHub Actionsbuild imageGitdesired stateArgoCDreconcileKubernetesVerify in clusterpod · container · response
Fig. gitops loop

A Sync status is not a deployment check. The response is.

A commit is built into an image by GitHub Actions and the desired state is declared in Git. After ArgoCD reconciles the cluster, pod replacement, container health and service response are each checked directly.

Measured

Services operated

~15

Web services in real campus use.

Oldest codebase

10y+

Bound tightly to a local filesystem and a specific host.

Boundaries

  • etcd failure, single points of failure, node failure, high availability, stateful workloads and persistent storage, and whether the database belongs inside or outside the cluster — these were reviewed and discussed during operation. I did not build them.
  • No infrastructure-as-code tooling (Terraform, Ansible) was used.
  • The group's infrastructure was run as a team; I held overall ownership and technical decisions.