Kubernetes 기반 IoT 장치 관리 플랫폼의 오프라인 배포 가이드

IoT 환경에서 안정적인 장치 관리를 위한 Kubespray 활용법

스마트 팩토리, 스마트 빌딩 등 IoT 장치가 급격히 증가하면서 데이터 수집 지연, 복잡한 배포 절차, 불안정한 네트워크 등의 문제에 직면하는 경우가 많습니다. 이 글에서는 Ansible 기반의 Kubernetes 배포 도구인 Kubespray를 사용해 오프라인 환경에서도 신속하게 IoT 장치 관리 플랫폼을 구축하는 방법을 다룹니다. 오프라인 클러스터 배포부터 네트워크 및 스토리지 구성, 애플리케이션 배포까지 실전 중심으로 설명합니다.

Kubespray 선택 이유: 자동화와 오프라인 지원

IoT 환경은 대개 외부 인터넷 접근이 제한적이며, 장비 성능도 제약이 많습니다. 이러한 조건에서 Kubespray는 다음과 같은 장점으로 적합한 솔루션입니다.

  • Ansible 기반 자동화: 반복적인 수작업 배포 오류를 줄이고 일관성 있는 운영이 가능합니다.
  • 다양한 Kubernetes 버전 지원: 하드웨어 사양에 맞춰 최적의 버전을 선택할 수 있습니다.
  • 완벽한 오프라인 배포 지원: 내부 저장소를 통해 모든 의존성을 로컬에서 제공할 수 있습니다.
  • 확장성과 유연성: 노드 추가/제거가 쉬우며, 다양한 CNI 및 스토리지 옵션을 제공합니다.

오프라인 환경 준비하기

인터넷 연결이 없는 환경에서 Kubespray를 실행하려면 다음 아티팩트들을 사전에 확보하고 내부 저장소를 구성해야 합니다.

필수 아티팩트 목록

  • Kubernetes 바이너리 및 관련 CLI 툴 (kubectl, kubeadm 등)
  • Docker 또는 containerd 이미지
  • OS용 패키지 (RPM 또는 DEB)
  • Kubespray에서 사용하는 컨테이너 이미지 (etcd, coredns, calico 등)
  • [선택] Python 패키지 (pip로 설치되는 모듈)
  • [선택] Helm 차트 파일

내부 저장소 설정

다음과 같은 내부 서비스를 미리 구성합니다.

  • HTTP 서버: 정적 파일 (예: 바이너리) 제공
  • Yum/Deb 저장소: OS 패키지 배포용
  • 프라이빗 컨테이너 레지스트리: Docker 이미지 저장 및 배포
  • PyPI 미러: 파이썬 종속성 해결용 (선택)
  • Helm 리포지터리: Helm 차트 호스팅 (선택)

Inventory 설정 예시

# registry 설정
registry_host: "registry.internal.example.com"
kube_image_repo: "{{ registry_host }}"
gcr_image_repo: "{{ registry_host }}"
docker_image_repo: "{{ registry_host }}"

# 파일 저장소 URL
files_repo: "https://files:secret@files.internal.example.com/k8s-artifacts"

# Yum 저장소 예시 (CentOS)
docker_rh_repo_base_url: "http://yum.internal.example.com/docker-ce/$releasever/$basearch"
docker_rh_repo_gpgkey: "http://yum.internal.example.com/docker-ce/gpg"

Kubernetes 클러스터 배포 절차

모든 준비가 완료되면 다음 단계로 클러스터를 생성합니다.

1. Ansible 설치

배포용 호스트에 Ansible을 설치합니다.

pip install ansible==7.0.0

2. Inventory 구성

클러스터 노드 정보를 YAML 형식으로 정의합니다. 예:

[all]
master-1 ansible_host=192.168.1.10
worker-1 ansible_host=192.168.1.11
worker-2 ansible_host=192.168.1.12

[kube_control_plane]
master-1

[etcd]
master-1

[kube_node]
worker-1
worker-2

[k8s_cluster:children]
kube_control_plane
kube_node

3. 클러스터 배포 실행

다음 명령어로 클러스터를 생성합니다.

ansible-playbook -i inventory/mycluster/hosts.ini \
  -b cluster.yml --extra-vars "@inventory/mycluster/group_vars/all/offline.yml"

컨테이너 기반 실행도 가능합니다.

docker run --rm -v ./inventory:/inventory \
  private-registry/kubespray:v2.25.0 \
  ansible-playbook -i /inventory/mycluster/hosts.ini -b cluster.yml

네트워크 구성: Calico 기반 안정성 확보

IoT 장치는 다양한 네트워크 영역에 분산되어 있으므로, Calico를 이용한 유연한 네트워킹이 중요합니다.

BGP 기반 통신 활성화

여러 서브넷에 걸쳐 장치가 존재할 경우, BGP 피어링을 통해 라우팅을 공유합니다.

peer_with_router: true
calico_bgp_peers:
  - peer_ip: 192.168.0.1
    peer_as: 65001
    node_selector: all()

VXLAN 백엔드 사용

BGP가 사용 불가능한 환경에서는 VXLAN을 사용하여 오버레이 네트워크를 구성합니다.

calico_network_backend: vxlan
calico_vxlan_mode: Always

통신 암호화 설정

민감한 장치 데이터 전송 시 보안 강화를 위해 IPsec 암호화를 활성화합니다.

calico_encryption_enabled: true
epel_enabled: true  # CentOS 계열 필요

스토리지 구성: 로컬 디스크 기반 PV 제공

엣지 환경에서는 데이터 지연 최소화를 위해 로컬 스토리지를 활용하는 것이 효과적입니다. Local Static Provisioner를 사용하면 간단히 PersistentVolume을 생성할 수 있습니다.

로컬 스토리지 클래스 정의

local_volume_provisioner_storage_classes:
  local-hdd:
    host_dir: /mnt/disks
    mount_dir: /mnt/disks
    volume_mode: Filesystem
    fs_type: ext4
  fast-ssd:
    host_dir: /mnt/ssd
    mount_dir: /mnt/ssd
    block_cleaner_command:
      - "/scripts/shred.sh"
      - "1"

로컬 볼륨 생성 방법

물리 디스크를 마운트하는 방식이 가장 일반적입니다.

# SSD 디스크 마운트
mkdir -p /mnt/ssd/data01
mount /dev/nvme0n1p1 /mnt/ssd/data01

# fstab에 등록하여 재부팅 후에도 유지
echo "/dev/nvme0n1p1 /mnt/ssd/data01 ext4 defaults 0 0" >> /etc/fstab

IoT 관리 애플리케이션 배포 예시

클러스터 준비 후, 실제 장치 관리 애플리케이션을 배포해 봅니다.

Deployment 및 Service 정의

apiVersion: apps/v1
kind: Deployment
metadata:
  name: device-controller
spec:
  replicas: 2
  selector:
    matchLabels:
      app: device-controller
  template:
    metadata:
      labels:
        app: device-controller
    spec:
      containers:
      - name: controller
        image: registry.internal/device-controller:v1.2
        ports:
        - containerPort: 8080
        volumeMounts:
        - name: storage
          mountPath: /data
      volumes:
      - name: storage
        persistentVolumeClaim:
          claimName: device-pvc
---
apiVersion: v1
kind: Service
metadata:
  name: device-service
spec:
  selector:
    app: device-controller
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080
  type: NodePort

PersistentVolumeClaim 생성

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: device-pvc
spec:
  storageClassName: local-hdd
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 20Gi

클러스터 확장 및 관리

장치 수가 늘어날 경우, 기존 클러스터에 노드를 추가할 수 있습니다.

ansible-playbook -i inventory/mycluster/hosts.ini \
  -b scale.yml --extra-vars "node=worker-3"

노드 제거도 동일한 방식으로 수행합니다.

ansible-playbook -i inventory/mycluster/hosts.ini \
  -b remove-node.yml --extra-vars "node=worker-1"

결론

Kubespray를 사용하면 네트워크가 제한된 IoT 환경에서도 안정적인 쿠버네티스 클러스터를 신속하게 구축할 수 있습니다. 오프라인 아티팩트 준비, 내부 저장소 구성, Calico 기반 네트워크 설정, 로컬 스토리지 연동을 통해 엣지 환경에 최적화된 장치 관리 플랫폼을 구현할 수 있습니다. 향후 Prometheus, Grafana 등을 통합하여 모니터링 및 시각화 기능을 확장하면 더욱 강력한 운영 체계를 마련할 수 있습니다.

태그: kubespray kubernetes IoT Ansible offline-deployment

6월 20일 21:52에 게시됨