ISC DHCP 에서 Kea DHCP 로 마이그레이션 (Docker)

ISC DHCP EOL (End of Life)

ISC(Internet Systems Consortium) 는 2022년 말에 ISC DHCP (dhcpd) 의 유지보수 종료를 공식 발표하였습니다.
1995년부터 약 30년간 사용되어 온 ISC DHCP 는 더 이상 업데이트가 제공되지 않으며, 심각한 보안 취약점이 발견되더라도 패치가 제공되지 않습니다.

ISC 는 후속 DHCP 서버로 Kea DHCP 를 권장하고 있으며, 마이그레이션을 위한 도구인 KeaMA(Kea Migration Assistant) 와 공식 Docker 이미지도 제공하고 있습니다.

이번 포스팅에서는 기존 ISC DHCP 설정을 Docker 기반의 Kea DHCP 로 마이그레이션하는 방법에 대해 기록하도록 하겠습니다.

Kea DHCP 란?

Kea DHCP 는 ISC 에서 개발한 차세대 오픈소스 DHCP 서버입니다.
ISC DHCP 와 비교하여 아래와 같은 특징이 있습니다.

  • JSON 기반 설정 파일 형식
  • REST API 를 통한 원격 관리 지원 (kea-ctrl-agent)
  • 데이터베이스 백엔드 지원 (MySQL, PostgreSQL)
  • 멀티스레드 지원으로 높은 성능
  • DHCPv4, DHCPv6, Dynamic DNS 가 별도 프로세스로 분리
  • Hook 라이브러리를 통한 기능 확장
  • High Availability 지원

테스트 환경

  • 테스트 환경: Amazon Linux 2
  • 기존 DHCP 서버: ISC DHCP (dhcpd)
  • 마이그레이션 대상: Kea DHCP (Docker Container)
  • Kea DHCP 이미지: docker.cloudsmith.io/isc/docker/kea-dhcp4

Step 1) 기존 ISC DHCP 설정 확인 및 백업

마이그레이션 전 반드시 기존 설정 파일과 Lease 파일을 백업합니다.

$ sudo cp /etc/dhcp/dhcpd.conf /etc/dhcp/dhcpd.conf.backup
$ sudo cp /var/lib/dhcpd/dhcpd.leases /var/lib/dhcpd/dhcpd.leases.backup

기존 ISC DHCP 설정 파일을 확인합니다.

$ cat /etc/dhcp/dhcpd.conf
#
# DHCP Server Configuration file.
#   see /usr/share/doc/dhcp*/dhcpd.conf.example
#   see dhcpd.conf(5) man page
#

# Global configuration ####################################
option domain-name "chhanz.xyz";
default-lease-time 3600;
max-lease-time 7200;
authoritative;

# subnet configuration ####################################
subnet 10.100.200.0 netmask 255.255.255.0 {
option routers                  10.100.200.1;
option subnet-mask              255.255.255.0;
option domain-name-servers      1.1.1.1;
option time-offset              -18000;
range 10.100.200.100 10.100.200.200;
}

host pve1.chhanz.xyz {
hardware ethernet BC:24:11:F3:9F:00;
fixed-address 10.100.200.50;
}

host pve2.chhanz.xyz {
hardware ethernet BC:24:11:D7:AA:55;
fixed-address 10.100.200.51;
}

host pve3.chhanz.xyz {
hardware ethernet BC:24:11:C9:53:86;
fixed-address 10.100.200.52;
}

위와 같이 10.100.200.0/24 서브넷에 대한 DHCP 설정과 Proxmox 노드 3대에 대한 고정 IP 할당 설정이 되어 있습니다.

Step 2) Kea DHCP Docker 이미지 Pull

ISC 에서 제공하는 공식 Kea DHCP Docker 이미지를 가져옵니다.

[root@chhan-al2 ~]# docker pull docker.cloudsmith.io/isc/docker/kea-dhcp4
Using default tag: latest
latest: Pulling from isc/docker/kea-dhcp4
f637881d1138: Pull complete
d39b6622b069: Pull complete
307f453979a4: Pull complete
Digest: sha256:fdc40a60b0c392247d2411fb445b88b9d204d929ed4e8431a235edcefbe6a0bd
Status: Downloaded newer image for docker.cloudsmith.io/isc/docker/kea-dhcp4:latest
docker.cloudsmith.io/isc/docker/kea-dhcp4:latest

위와 같이 이미지가 정상적으로 다운로드 된 것을 확인 할 수 있습니다.

Step 3) KeaMA Docker 를 이용한 설정 변환

ISC 에서 제공하는 KeaMA(Kea Migration Assistant) Docker 이미지를 사용하여 기존 dhcpd.conf 를 Kea JSON 설정 파일로 자동 변환합니다.

먼저 KeaMA Docker 이미지를 가져옵니다.

[root@chhan-al2 ~]# docker pull docker.cloudsmith.io/isc/keama/keama:4.5.0
4.5.0: Pulling from isc/keama/keama
4693057ce236: Pull complete
9ad60c84bfbe: Pull complete
ce0f4c80e9b7: Pull complete
...생략
Digest: sha256:1ce87368b16d528a0f6c64b48e5316caaa21bccca99bfe7a3e9b368eaa6b1f1f
Status: Downloaded newer image for docker.cloudsmith.io/isc/keama/keama:4.5.0
docker.cloudsmith.io/isc/keama/keama:4.5.0

변환 결과를 저장할 디렉토리를 생성하고 권한을 설정합니다.

[root@chhan-al2 ~]# mkdir convert
[root@chhan-al2 ~]# chown 1000:1000 convert

아래와 같이 KeaMA 컨테이너를 실행하여 설정 파일을 변환합니다.

[root@chhan-al2 ~]# docker run -ti --rm \
	-v /etc/dhcp/dhcpd.conf:/home/keama/app/dhcpd.conf \
	-v /root/convert:/home/keama/app/convert \
	docker.cloudsmith.io/isc/keama/keama:4.5.0 \
	/home/keama/app/keama -4 -i /home/keama/app/dhcpd.conf -o /home/keama/app/convert/kea-dhcpd.conf
KEAMA 4.5.0
Reading isc-dhcp config (IPv4 mode) from /home/keama/app/dhcpd.conf, writing Kea JSON config to /home/keama/app/convert/kea-dhcpd.conf.
Started parsing new subnet declaration in line 15
Converted subnet 10.100.200.0/24 (lines 15 to 22)...
Parsing new host declaration at line 24
Converted host hw-address:bc:24:11:f3:9f:00 hostname:pve1.chhanz.xyz ip-address:10.100.200.50  (lines 24 to 27)
Parsing new host declaration at line 28
Converted host hw-address:bc:24:11:d7:aa:55 hostname:pve2.chhanz.xyz ip-address:10.100.200.51  (lines 28 to 31)
Parsing new host declaration at line 32
Converted host hw-address:bc:24:11:c9:53:86 hostname:pve3.chhanz.xyz ip-address:10.100.200.52  (lines 32 to 35)
Parsed 36 lines from the input (ISC DHCP config) /home/keama/app/dhcpd.conf file.
Wrote 1964 bytes to Kea JSON output /home/keama/app/convert/kea-dhcpd.conf file.

위와 같이 서브넷 1개와 호스트 예약 3개가 정상적으로 변환된 것을 확인 할 수 있습니다.

변환된 설정 파일 확인

[root@chhan-al2 ~]# cat convert/kea-dhcpd.conf
{
  #
  # DHCP Server Configuration file.
  #   see /usr/share/doc/dhcp*/dhcpd.conf.example
  #   see dhcpd.conf(5) man page
  #
  #
  # Global configuration ####################################
  #option domain-name "chhanz.xyz";
  #option domain-name-servers ns.chhanz.xyz;
  /// This configuration declares some subnets but has no interfaces-config
  /// Reference Kea #245
  "Dhcp4": {
    "valid-lifetime": 3600,
    "max-valid-lifetime": 7200,
    "authoritative": true,
    "subnet4": [
      # subnet configuration ####################################
      {
        "id": 1,
        "subnet": "10.100.200.0/24",
        "option-data": [
          {
            "space": "dhcp4",
            "name": "routers",
            "code": 3,
            "data": "10.100.200.1"
          },
          {
            "space": "dhcp4",
            "name": "subnet-mask",
            "code": 1,
            "data": "255.255.255.0"
          },
          {
            "space": "dhcp4",
            "name": "domain-name-servers",
            "code": 6,
            "data": "1.1.1.1"
          },
          {
            "space": "dhcp4",
            "name": "time-offset",
            "code": 2,
            "data": "-18000"
          }
        ],
        "pools": [
          {
            "pool": "10.100.200.100 - 10.100.200.200"
          }
        ]
      }
    ],
    "host-reservation-identifiers": [
      "hw-address"
    ],
    "reservation-mode": "global",
    "reservations": [
      {
        "hostname": "pve1.chhanz.xyz",
        "hw-address": "bc:24:11:f3:9f:00",
        "ip-address": "10.100.200.50"
      },
      {
        "hostname": "pve2.chhanz.xyz",
        "hw-address": "bc:24:11:d7:aa:55",
        "ip-address": "10.100.200.51"
      },
      {
        "hostname": "pve3.chhanz.xyz",
        "hw-address": "bc:24:11:c9:53:86",
        "ip-address": "10.100.200.52"
      }
    ]
  }
}

참고 : KeaMA 가 변환한 결과에는 주석(#, ///) 과 함께 interfaces-config, lease-database, loggers 등의 항목이 포함되어 있지 않습니다.
이 항목들은 수동으로 추가해야 하며, 주석도 제거해야 합니다. (Kea 는 표준 JSON 을 사용하므로 주석을 지원하지 않습니다)

Step 4) 변환된 설정 파일 수정

KeaMA 가 변환한 설정 파일은 그대로 사용할 수 없으며, 아래와 같은 수정이 필요합니다.

[root@chhan-al2 ~]# mkdir -p /etc/kea/config
[root@chhan-al2 ~]# mkdir -p /etc/kea/leases

변환된 파일을 복사하고 수정합니다.

[root@chhan-al2 ~]# cp convert/kea-dhcpd.conf /etc/kea/config/kea-dhcp4.conf
[root@chhan-al2 ~]# vi /etc/kea/config/kea-dhcp4.conf

아래와 같은 항목들을 수정합니다.

1) 주석 제거

Kea 는 표준 JSON 형식을 사용하므로 KeaMA 가 남긴 #, /// 주석을 모두 제거합니다.

2) interfaces-config, control-socket, lease-database 추가

KeaMA 변환 결과에는 포함되지 않는 항목들을 Dhcp4 블록 상단에 추가합니다.

    "interfaces-config": {
      "interfaces": [ "eth1" ],
      "dhcp-socket-type": "raw"
    },
    "control-socket": {
      "socket-type": "unix",
      "socket-name": "/var/run/kea/kea4-ctrl-socket"
    },
    "lease-database": {
      "type": "memfile",
      "persist": true,
      "name": "/var/lib/kea/kea-leases4.csv",
      "lfc-interval": 3600
    },

3) option-data 에서 불필요한 필드 제거

KeaMA 가 생성한 space, code 필드는 생략 가능하므로 간결하게 정리합니다.
또한 subnet-mask 옵션은 Kea 가 서브넷 정의에서 자동으로 처리하므로 제거합니다.

변경 전 (KeaMA 변환 결과):

          {
            "space": "dhcp4",
            "name": "routers",
            "code": 3,
            "data": "10.100.200.1"
          },

변경 후:

          {
            "name": "routers",
            "data": "10.100.200.1"
          },

4) reservation-mode 를 신규 키워드로 변경

Kea 2.6 이상에서 reservation-mode 는 deprecated 되었습니다.
아래와 같이 reservations-global, reservations-in-subnet 으로 변경합니다.

변경 전 (KeaMA 변환 결과):

    "reservation-mode": "global",

변경 후:

    "reservations-global": true,
    "reservations-in-subnet": false,

5) loggers 추가

Docker 환경에서 docker logs 로 로그를 확인할 수 있도록 stdout 출력 설정을 추가합니다.

    "loggers": [
      {
        "name": "kea-dhcp4",
        "output-options": [
          {
            "output": "stdout",
            "flush": true
          }
        ],
        "severity": "INFO",
        "debuglevel": 0
      }
    ]

최종 설정 파일

위 수정 사항을 모두 반영한 최종 설정 파일은 아래와 같습니다.

[root@chhan-al2 ~]# cat /etc/kea/config/kea-dhcp4.conf
{
  "Dhcp4": {
    "interfaces-config": {
      "interfaces": [ "eth1" ],
      "dhcp-socket-type": "raw"
    },
    "control-socket": {
      "socket-type": "unix",
      "socket-name": "/var/run/kea/kea4-ctrl-socket"
    },
    "lease-database": {
      "type": "memfile",
      "persist": true,
      "name": "/var/lib/kea/kea-leases4.csv",
      "lfc-interval": 3600
    },
    "authoritative": true,
    "valid-lifetime": 3600,
    "max-valid-lifetime": 7200,
    "subnet4": [
      {
        "id": 1,
        "subnet": "10.100.200.0/24",
        "option-data": [
          {
            "name": "routers",
            "data": "10.100.200.1"
          },
          {
            "name": "domain-name-servers",
            "data": "1.1.1.1"
          },
          {
            "name": "time-offset",
            "data": "-18000"
          }
        ],
        "pools": [
          {
            "pool": "10.100.200.100 - 10.100.200.200"
          }
        ]
      }
    ],
    "host-reservation-identifiers": [
      "hw-address"
    ],
    "reservations-global": true,
    "reservations-in-subnet": false,
    "reservations": [
      {
        "hostname": "pve1.chhanz.xyz",
        "hw-address": "bc:24:11:f3:9f:00",
        "ip-address": "10.100.200.50"
      },
      {
        "hostname": "pve2.chhanz.xyz",
        "hw-address": "bc:24:11:d7:aa:55",
        "ip-address": "10.100.200.51"
      },
      {
        "hostname": "pve3.chhanz.xyz",
        "hw-address": "bc:24:11:c9:53:86",
        "ip-address": "10.100.200.52"
      }
    ],
    "loggers": [
      {
        "name": "kea-dhcp4",
        "output-options": [
          {
            "output": "stdout",
            "flush": true
          }
        ],
        "severity": "INFO",
        "debuglevel": 0
      }
    ]
  }
}

ISC DHCP 와 Kea DHCP 설정 비교

항목 ISC DHCP (dhcpd.conf) Kea DHCP (kea-dhcp4.conf)
설정 형식 자체 문법 JSON
Subnet 선언 subnet 10.100.200.0 netmask 255.255.255.0 "subnet": "10.100.200.0/24"
IP 범위 range 10.100.200.100 10.100.200.200; "pool": "10.100.200.100 - 10.100.200.200"
고정 IP 할당 host pve1 { hardware ethernet ...; fixed-address ...; } "reservations": [{"hw-address": "...", "ip-address": "..."}]
옵션 설정 option routers 10.100.200.1; "option-data": [{"name": "routers", "data": "10.100.200.1"}]
Lease 저장 /var/lib/dhcpd/dhcpd.leases /var/lib/kea/kea-leases4.csv 또는 DB
서비스명 dhcpd kea-dhcp4

Step 5) 설정 파일 검증

컨테이너를 실행하기 전에 설정 파일의 문법을 검증합니다.

[root@chhan-al2 ~]# docker run --rm \
    -v /etc/kea/config:/etc/kea \
    docker.cloudsmith.io/isc/docker/kea-dhcp4 \
    kea-dhcp4 -t /etc/kea/kea-dhcp4.conf
2026-02-09 06:04:14.319 WARN  [kea-dhcp4.dhcpsrv/1.140164228530912]
DHCPSRV_MT_DISABLED_QUEUE_CONTROL disabling dhcp queue control when multi-threading is enabled.
2026-02-09 06:04:14.319 WARN  [kea-dhcp4.dhcp4/1.140164228530912]
DHCP4_RESERVATIONS_LOOKUP_FIRST_ENABLED Multi-threading is enabled and host reservations lookup is always performed first.
2026-02-09 06:04:14.319 INFO  [kea-dhcp4.dhcpsrv/1.140164228530912]
DHCPSRV_CFGMGR_NEW_SUBNET4 a new subnet has been added to configuration: 10.100.200.0/24 with params: valid-lifetime=3600
2026-02-09 06:04:14.319 INFO  [kea-dhcp4.dhcpsrv/1.140164228530912]
DHCPSRV_CFGMGR_SOCKET_TYPE_SELECT using socket type raw
...생략

위와 같이 DHCPSRV_CFGMGR_NEW_SUBNET4 로그에서 10.100.200.0/24 서브넷이 정상적으로 추가된 것을 확인 할 수 있습니다.
ERROR 없이 출력이 완료되면 설정 파일에 문제가 없는 것입니다.

Step 6) 기존 ISC DHCP 서비스 중지

Kea DHCP 컨테이너를 시작하기 전에 기존 ISC DHCP 서비스를 중지합니다.
동일한 포트(UDP 67/68) 를 사용하기 때문에 반드시 기존 서비스를 먼저 중지해야 합니다.

[root@chhan-al2 ~]# systemctl stop dhcpd
[root@chhan-al2 ~]# systemctl disable dhcpd
Removed symlink /etc/systemd/system/multi-user.target.wants/dhcpd.service.

Step 7) Kea DHCP 컨테이너 실행

아래와 같이 Kea DHCP 컨테이너를 실행합니다.
DHCP 서버는 브로드캐스트 패킷을 수신해야 하므로 --net host 옵션을 사용합니다.

[root@chhan-al2 ~]# docker run -d \
    --name kea-dhcp4 \
    --restart=always \
    --net host \
    -v /etc/kea/config:/etc/kea \
    -v /etc/kea/leases:/var/lib/kea \
    docker.cloudsmith.io/isc/docker/kea-dhcp4

컨테이너 실행 상태를 확인합니다.

[root@chhan-al2 ~]# docker ps
CONTAINER ID   IMAGE                                          COMMAND                  CREATED         STATUS         PORTS   NAMES
a1b2c3d4e5f6   docker.cloudsmith.io/isc/docker/kea-dhcp4      "/usr/sbin/kea-dhcp4…"   5 seconds ago   Up 3 seconds           kea-dhcp4

위와 같이 Kea DHCP 컨테이너가 정상적으로 실행 중인 것을 확인 할 수 있습니다.

Step 8) 동작 확인

로그 확인

아래와 같이 컨테이너 로그를 통해 Kea DHCP 서버의 동작 상태를 확인합니다.

[root@chhan-al2 ~]# docker logs -f kea-dhcp4
2026-02-09 06:13:00.211 INFO  [kea-dhcp4.dhcp4/1.140589193589472]
DHCP4_STARTING Kea DHCPv4 server version 3.0.2 (stable) starting
...생략
2026-02-09 06:13:00.213 INFO  [kea-dhcp4.dhcpsrv/1.140589193589472]
DHCPSRV_CFGMGR_ADD_IFACE listening on interface eth1
2026-02-09 06:13:00.213 INFO  [kea-dhcp4.dhcp4/1.140589193589472]
DHCP4_CONFIG_COMPLETE DHCPv4 server has completed configuration: added IPv4 subnets: 1; DDNS: disabled
...생략
2026-02-09 06:13:00.251 INFO  [kea-dhcp4.dhcp4/1.140589193589472]
DHCP4_MULTI_THREADING_INFO enabled: yes, number of threads: 2, queue size: 64
2026-02-09 06:13:00.251 INFO  [kea-dhcp4.dhcp4/1.140589193589472]
DHCP4_STARTED Kea DHCPv4 server version 3.0.2 started

위와 같이 Kea DHCP 서버 버전 3.0.2 가 정상적으로 시작된 것을 확인 할 수 있습니다.

DHCP 클라이언트가 IP 를 요청하면 아래와 같은 로그를 확인 할 수 있습니다.

2026-02-09 06:13:12.733 INFO  [kea-dhcp4.packets/1.140589172878136]
DHCP4_PACKET_RECEIVED [hwtype=1 bc:24:11:27:12:8c], cid=[no info], tid=0x9ae58e2a:
DHCPDISCOVER (type 1) received from 0.0.0.0 to 255.255.255.255 on interface eth1
2026-02-09 06:13:12.733 INFO  [kea-dhcp4.leases/1.140589172878136]
DHCP4_LEASE_OFFER [hwtype=1 bc:24:11:27:12:8c], cid=[no info], tid=0x9ae58e2a:
lease 10.100.200.100 will be offered
...생략
2026-02-09 06:13:12.734 INFO  [kea-dhcp4.leases/1.140589173021496]
DHCP4_LEASE_ALLOC [hwtype=1 bc:24:11:27:12:8c], cid=[no info], tid=0x9ae58e2a:
lease 10.100.200.100 has been allocated for 3600 seconds
2026-02-09 06:13:12.734 INFO  [kea-dhcp4.packets/1.140589173021496]
DHCP4_PACKET_SEND [hwtype=1 bc:24:11:27:12:8c], cid=[no info], tid=0x9ae58e2a:
trying to send packet DHCPACK (type 5) from 10.100.200.1:67 to 10.100.200.100:68 on interface eth1

위와 같이 DHCPDISCOVER → DHCPOFFER → DHCPREQUEST → DHCPACK 과정을 거쳐 10.100.200.100 IP 가 정상적으로 할당되는 것을 확인 할 수 있습니다.

Lease 파일 확인

[root@chhan-al2 ~]# cat /etc/kea/leases/kea-leases4.csv
address,hwaddr,client_id,valid_lifetime,expire,subnet_id,fqdn_fwd,fqdn_rev,hostname,state,user_context,pool_id
10.100.200.100,bc:24:11:27:12:8c,,3600,1770621192,1,0,0,rhel7,0,,0

위와 같이 DHCP IP 가 정상적으로 할당되는 것을 확인 할 수 있습니다.

설정 변경 시 컨테이너 재시작

설정 파일을 수정한 후에는 아래와 같이 컨테이너를 재시작합니다.

[root@chhan-al2 ~]# vi /etc/kea/config/kea-dhcp4.conf
[root@chhan-al2 ~]# docker restart kea-dhcp4
kea-dhcp4

참고

chhanz's profile image

chhanz

2026-02-09 12분 읽기

Read more posts by this author