DevOps

Kubernetes Docker Swarm Instalasi Aman: Migrasi Zero Downtime

Asep Alazhari

Pelajari cara install Kubernetes bersamaan dengan Docker Swarm yang masih running. Panduan ini memastikan zero downtime untuk service production lo selama migrasi.

Kubernetes Docker Swarm Instalasi Aman: Migrasi Zero Downtime

Notifikasi tengah malam dan pesan “service is down” yang familiar banget adalah mimpi buruk setiap DevOps engineer. Gue udah berkali-kali ngalamin, natap dashboard monitoring jam 3 pagi sambil troubleshooting lingkungan production di mana setiap detik downtime itu artinya kehilangan pendapatan dan user yang kesel. Tapi kadang, momen-momen menantang kayak gini justru jadi katalis buat pertumbuhan dan inovasi.

Cerita migrasi ini dimulai dari tantangan pribadi dan kesempatan strategis yang ketemu di timing yang pas banget. Gue udah pake Docker Swarm bertahun-tahun, dan meskipun dia ngerjain tugasnya dengan baik, gue nggak bisa abaikan kenyataan: Kubernetes udah jadi standar industri. Docker Swarm, meskipun sederhana, makin berasa jadul di landscape di mana Kubernetes mendominasi orkestrasi container enterprise. Ekosistem, tooling, pasar kerja, dan momentum komunitas semuanya nunjuk ke satu arah.

Motivasinya bukan cuma keingintahuan teknis aja, ini tentang mempersiapkan skill masa depan dan infrastruktur gue. Gue butuh tantang diri gue sendiri buat menguasai Kubernetes, bukan cuma sebagai latihan akademis aja, tapi lewat implementasi nyata dengan beban kerja production beneran. Ketika kesempatan buat migrasi beberapa aplikasi ke infrastruktur server yang baru muncul, timingnya nggak bisa lebih sempurna lagi. Ini kesempatan gue buat menjembatani teori dengan praktik.

Tapi kenyataan bisnisnya ga kenal ampun banget: toleransi zero downtime. Beban kerja production, sebut aja prod-app, melayani ribuan user setiap hari, sementara dua service staging (staging-app-1 dan staging-app-2) krusial banget buat siklus development yang sedang berjalan. Ini bukan cuma perjalanan belajar pribadi, ini tindakan keseimbangan berisiko tinggi antara merangkul masa depan orkestrasi container sambil menjaga stabilitas kuat untuk operasi yang ada.

Terobosannya dateng dengan apa yang gue sebut “strategi koeksistensi paralel”, menjalankan cluster Kubernetes lengkap berdampingan dengan infrastruktur Docker Swarm yang ada tanpa mengganggu satu pun container production. Pendekatan ini membuktikan bahwa lo bisa mengejar adopsi teknologi terdepan sambil mempertahankan keunggulan operasional. Kadang cara terbaik buat belajar bukan mengganti, tapi membangun berdampingan dan transisi secara bertahap.


Keputusan Strategis: Kenapa Gue Pilih Parallel Installation

Migrasi sistem production itu secara inheren berisiko. Satu langkah salah bisa menyebabkan downtime yang bencana, berdampak pada user dan pendapatan. Strategi gue adalah mengurangi risiko ini sepenuhnya dengan menghindari upgrade in-place langsung. Alih-alih mengonversi atau mengganti Docker Swarm yang ada, gue pilih membangun cluster Kubernetes baru di server fisik yang sama. Pendekatan ultra-aman ini memungkinkan gue untuk:

  • Pertahankan 100% Uptime untuk Production: prod-app tetap di Docker Swarm, sepenuhnya terisolasi dari proses instalasi Kubernetes melalui partisi sumber daya yang hati-hati.
  • Lingkungan Staging yang Aman: Gue tunjuk service staging, staging-app-1 dan staging-app-2, sebagai kandidat pertama untuk testing migrasi Kubernetes. Ini menyediakan sandbox terkontrol untuk memvalidasi platform orkestrasi baru tanpa risiko production sama sekali.
  • Perubahan Tanpa Dampak: Metodologi instalasi dirancang dengan teliti untuk menghindari reboot sistem, modifikasi hostname, atau rekonfigurasi firewall, memastikan bahwa service yang ada terus beroperasi normal.
  • Koeksistensi Resource: Kedua container runtime (Docker dan containerd) beroperasi bersamaan menggunakan interface socket yang berbeda, mencegah konflik resource atau degradasi performa.

Metode ini memberikan gue yang terbaik dari kedua dunia: stabilitas dari lingkungan production saat ini dan jalur aman menuju platform orkestrasi container yang lebih modern.

Phase 1: Pre-Installation & System Preparation

Sebelum terjun ke instalasi Kubernetes, gue implementasi audit pra-instalasi komprehensif di semua enam server (k8s-node01 sampai k8s-node06). Fase penilaian “read-only” ini dirancang untuk membangun pemahaman dasar dari infrastruktur saat ini tanpa membuat modifikasi apa pun yang bisa berdampak pada service yang berjalan.

Audit-nya mencakup beberapa area kritis: kompatibilitas versi OS (memastikan baseline CentOS 7.x/RHEL 7.x), verifikasi hostname untuk menghindari konflik DNS, validasi kesehatan cluster Docker Swarm, dan resource sistem yang tersedia. Yang paling penting, gue verifikasi bahwa semua service production berjalan optimal sebelum melanjutkan.

Salah satu langkah yang paling kritis tapi mengejutkan rendah risiko adalah memperbarui file /etc/hosts di semua node dengan topologi cluster Kubernetes. Setup resolusi host ini fundamental untuk komunikasi antar-node Kubernetes, tapi sepenuhnya transparan terhadap service Docker Swarm yang ada karena mereka tetap menggunakan mekanisme service discovery yang sudah mapan.

Code Block: System Status Verification & Host Resolution

# Execute on ALL servers (k8s-node01 through k8s-node06)
# Validate Docker Swarm cluster health
docker ps --format "table {{.Names}}\t{{.Image}}\t{{.Status}}"
docker service ls  # Verify all services are running
echo "✅ Docker Swarm cluster is healthy - safe to proceed"

# Add Kubernetes cluster nodes to /etc/hosts for proper name resolution
sudo tee -a /etc/hosts <<EOF
192.168.1.10 k8s-node01
192.168.1.11 k8s-node02
192.168.1.12 k8s-node03
192.168.1.13 k8s-node04
192.168.1.14 k8s-node05
192.168.1.15 k8s-node06
EOF
echo "✅ Kubernetes cluster host resolution configured"

Baca Juga: GitLab CI/CD: Variabel Dinamis Lintas Environment


Phase 2: Container Runtime Coexistence

Salah satu tantangan terbesar adalah menjalankan Kubernetes bersamaan dengan Docker Swarm. Kubernetes memerlukan Container Runtime Interface (CRI), dan meskipun Docker secara teoritis bisa dipakai, gue pilih containerd untuk setup yang lebih bersih dan terisolasi.

Gue install containerd di setiap server. Ini proses non-disruptive karena containerd itu runtime ringan yang bisa hidup berdampingan dengan Docker daemon tanpa konflik. Perubahan konfigurasi utama adalah mengaktifkan driver SystemdCgroup, persyaratan untuk Kubernetes, di dalam file konfigurasi containerd.

Code Block: Installing and Configuring containerd

# Execute on ALL servers
sudo dnf install -y containerd
sudo systemctl enable containerd
sudo systemctl start containerd

# Change SystemdCgroup = false to true in /etc/containerd/config.toml
sudo vim /etc/containerd/config.toml

# Verify both are running
sudo systemctl status docker --no-pager
sudo systemctl status containerd --no-pager
echo "✅ Both Docker and containerd are running in parallel"

Baca Juga: Menguasai Automated Docker Tagging di GitLab CI/CD: Panduan Praktis


Phase 3 & 4: Cluster Initialization & Control Plane Setup

Dengan fondasi infrastruktur yang sudah ditetapkan, gue lanjutkan untuk menginstal komponen inti Kubernetes (kubelet, kubeadm, kubectl) di semua node. Strategi instalasi melibatkan deploy komponen ini secara system-wide sambil menjaga mereka tidak aktif sampai fase inisialisasi cluster. Perintah kubeadm init dieksekusi secara eksklusif di node control plane utama yang ditunjuk, k8s-node01.

Perintah inisialisasi mencakup flag kunci yang kritis untuk pendekatan ultra-aman:

  • --ignore-preflight-errors=Swap: Flag ini memungkinkan gue melewati persyaratan swap-off default Kubernetes, yang akan memerlukan perubahan tingkat sistem.
  • --cri-socket=unix:///var/run/containerd/containerd.sock: Ini secara eksplisit memberitahu kubeadm untuk menggunakan containerd runtime yang baru diinstal, memastikan dia tidak mengganggu Docker.

Setelah node utama diinisialisasi, gue simpan perintah join yang dihasilkan untuk node lain dan konfigurasi kubectl untuk mengelola cluster baru. Ini memberikan gue pandangan pertama ke kesehatan cluster dan mengonfirmasi control plane baru sudah aktif dan berjalan.


Final Phase: CNI, Node Join, dan Cluster Validation

Langkah-langkah yang tersisa melibatkan membawa sisa cluster online dan persiapan untuk beban kerja.

  • Instalasi CNI: Gue install Calico, plugin CNI (Container Network Interface) yang populer, untuk mengaktifkan komunikasi jaringan antar pod. Langkah ini dilakukan di k8s-node01 dan langsung membawa node ke status “Ready”.
  • Penggabungan Node: Gue pakai perintah kubeadm join yang tersimpan untuk menambahkan k8s-node02 sebagai node control plane kedua (memastikan high availability) dan konfigurasi empat server yang tersisa (k8s-node03 sampai k8s-node06) sebagai worker node.
  • Tools & Ingress: Gue install Helm untuk manajemen paket, local storage provisioner untuk persistent volume, dan HAProxy Ingress Controller untuk mengelola traffic eksternal. Karena gue di belakang corporate firewall, gue pakai instalasi manual berbasis YAML untuk HAProxy, yang terbukti jadi solusi yang dapat diandalkan.

Akhirnya, validasi komprehensif mengonfirmasi kesuksesan gue: semua node Kubernetes siap, system pod berjalan, dan yang paling penting, prod-app production masih berjalan lancar di Docker Swarm.

Pendekatan bertahap dan ultra-aman ini membuktikan bahwa mungkin untuk mengadopsi teknologi baru tanpa mengorbankan stabilitas dari lingkungan production lo saat ini. Service staging sekarang berjalan di Kubernetes, dan gue bisa memvalidasi fungsionalitas dan performa sebelum membuat lompatan penuh, sementara service bisnis-kritis terus beroperasi tanpa gangguan.

Architecture Overview: NodePort vs Ingress Strategy

Salah satu keputusan arsitektur kunci yang muncul dari migrasi ini adalah mengimplementasi strategi routing berbasis NodePort untuk aplikasi. Tidak seperti pendekatan berbasis Ingress tradisional, gue pilih akses NodePort langsung karena beberapa alasan yang menarik:

Kenapa Arsitektur NodePort?

  • Jalur Jaringan yang Disederhanakan: Akses eksternal langsung via NodeIP:30080 menghilangkan kompleksitas dari konfigurasi Ingress controller dan load balancer
  • Mengurangi Titik Kegagalan: Lompatan jaringan yang lebih sedikit berarti titik kegagalan potensial yang lebih sedikit di jalur request
  • Kompatibilitas Corporate Firewall: Banyak lingkungan enterprise punya kebijakan firewall ketat yang membuat akses NodePort lebih mudah daripada setup Ingress yang kompleks
  • Manfaat Performa: Akses langsung mengurangi latensi dibanding multiple proxy layer

Implementation Pattern

# NodePort Service Configuration
apiVersion: v1
kind: Service
metadata:
    name: staging-app-1
    namespace: staging
spec:
    type: NodePort
    ports:
        - port: 3000
          targetPort: 3000
          nodePort: 30080
    selector:
        app: staging-app-1

Arsitektur ini memungkinkan gue mengekspos staging-app-1 langsung di port 30080 di semua node, dengan HAProxy eksternal yang merutekan request /app1 ke NodeIP:30080 untuk akses user yang mulus.

Configuration Management Strategy

Salah satu pelajaran terpenting yang dipelajari selama migrasi ini adalah pentingnya kritis dari manajemen konfigurasi yang tepat. Kubernetes menyediakan dua mekanisme utama untuk data konfigurasi: ConfigMap untuk data non-sensitif dan Secret untuk informasi sensitif.

ConfigMap vs Secret Separation

ConfigMap Usage (Public Configuration):

apiVersion: v1
kind: ConfigMap
metadata:
    name: app-config
data:
    NODE_ENV: "production"
    APP_PORT: "3000"
    BASE_PATH: "/app"
    PUBLIC_API_URL: "https://api.example.com"

Secret Usage (Sensitive Data):

apiVersion: v1
kind: Secret
metadata:
    name: app-secrets
type: Opaque
data:
    API_KEY: <base64-encoded-value>
    DATABASE_URL: <base64-encoded-value>
    JWT_SECRET: <base64-encoded-value>

Pemisahan ini memastikan bahwa informasi sensitif dienkripsi saat diam dan dikelola dengan benar melalui Kubernetes RBAC, sementara konfigurasi publik tetap mudah dibaca dan dapat dipelihara.

Production-Ready Feature

Migrasi ini bukan hanya tentang memindahkan container dari Docker Swarm ke Kubernetes, tapi tentang mengimplementasi fitur tingkat enterprise yang akan meningkatkan postur operasional.

Horizontal Pod Autoscaler (HPA) Setup

Salah satu fitur paling powerful dari Kubernetes adalah scaling otomatis berdasarkan penggunaan resource:

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
    name: staging-app-hpa
spec:
    scaleTargetRef:
        apiVersion: apps/v1
        kind: Deployment
        name: staging-app-1
    minReplicas: 15
    maxReplicas: 60
    metrics:
        - type: Resource
          resource:
              name: cpu
              target:
                  type: Utilization
                  averageUtilization: 65
        - type: Resource
          resource:
              name: memory
              target:
                  type: Utilization
                  averageUtilization: 75

Konfigurasi ini secara otomatis menskalakan aplikasi staging antara 15 dan 60 replika berdasarkan penggunaan CPU (threshold 65%) dan memory (threshold 75%), memastikan penggunaan resource yang optimal dan performa.

Pod Disruption Budget (PDB) Configuration

Untuk mempertahankan high availability selama pemeliharaan cluster atau update, gue implementasi Pod Disruption Budget:

apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
    name: staging-app-pdb
spec:
    minAvailable: 75%
    selector:
        matchLabels:
            app: staging-app-1

Ini memastikan bahwa setidaknya 75% dari pod aplikasi tetap tersedia selama gangguan sukarela seperti pemeliharaan node atau upgrade cluster.

Security Context Implementation

Keamanan sangat penting dalam setup production-ready. Gue implementasi security context yang komprehensif:

spec:
    template:
        spec:
            securityContext:
                runAsNonRoot: true
                runAsUser: 1001
                fsGroup: 1001
            containers:
                - name: app
                  securityContext:
                      allowPrivilegeEscalation: false
                      readOnlyRootFilesystem: true
                      capabilities:
                          drop:
                              - ALL
                  volumeMounts:
                      - name: tmp-volume
                        mountPath: /tmp
                      - name: cache-volume
                        mountPath: /app/.next/cache

Konfigurasi ini memastikan aplikasi berjalan sebagai non-root user dengan privilege minimal dan read-only root filesystem, secara signifikan mengurangi attack surface.

Lesson Learned dan Best Practice

1. Monitoring Resource itu Kritis

Selama instalasi paralel, gue menemukan bahwa monitoring konsumsi resource Docker Swarm dan Kubernetes sangat penting. Gue implementasi monitoring komprehensif pakai Prometheus dan Grafana untuk melacak:

  • Penggunaan memory di kedua platform
  • Pola penggunaan CPU
  • Segregasi traffic jaringan
  • Disk I/O untuk runtime container yang berbeda

2. Integrasi GitLab CI/CD

Migrasi juga melibatkan update pipeline CI/CD untuk mendukung kedua platform selama periode transisi. Gue implementasi strategi deployment yang canggih:

stages:
    - build
    - deploy-swarm
    - deploy-k8s
    - validate

deploy-staging-k8s:
    stage: deploy-k8s
    script:
        - kubectl apply -k k8s/
        - kubectl rollout status deployment/staging-app-1 -n staging
    only:
        - main
    when: manual # Safety measure for controlled deployments

3. Evolusi Health Check

Salah satu manfaat tak terduga adalah evolusi dari strategi health check. Kemampuan health check native Kubernetes (liveness, readiness, dan startup probe) memberikan kontrol yang jauh lebih granular daripada health check dasar Docker Swarm:

livenessProbe:
    httpGet:
        path: /api/health
        port: 3000
    initialDelaySeconds: 30
    periodSeconds: 10
readinessProbe:
    httpGet:
        path: /api/ready
        port: 3000
    initialDelaySeconds: 5
    periodSeconds: 5
startupProbe:
    httpGet:
        path: /api/startup
        port: 3000
    initialDelaySeconds: 10
    periodSeconds: 5
    failureThreshold: 30

Pendekatan tri-probe ini secara signifikan meningkatkan reliabilitas aplikasi dan tingkat keberhasilan deployment.

Perjalanan dari Docker Swarm ke Kubernetes nggak harus jadi lompatan iman. Dengan perencanaan yang hati-hati, strategi instalasi paralel, dan testing komprehensif, lo bisa mencapai migrasi zero-downtime sambil membangun platform orkestrasi container yang lebih scalable dan maintainable. Kuncinya adalah kesabaran, persiapan menyeluruh, dan selalu punya rencana rollback yang siap.

Back to Blog

Related Posts

View All Posts »
GitLab CI/CD: Variabel Dinamis Lintas Environment
Development

GitLab CI/CD: Variabel Dinamis Lintas Environment

Pelajari cara cerdas mengelola variabel di GitLab CI/CD agar pipeline lo fleksibel dan otomatis menyesuaikan diri dengan berbagai environtment seperti development, staging, dan production.