스마트 홈 환경에서 홈 어시스턴트(Home Assistant)는 단순한 자동화를 넘어, 주거 공간의 핵심 인프라로 기능하는 경우가 증가하고 있습니다. 조명, 온도 조절, 보안 시스템, 에너지 관리 등 민감하고 중요한 기능들이 홈 어시스턴트에 통합되면서, 시스템의 안정성은 선택이 아닌 필수가 되었습니다. 만약 핵심 제어 시스템이 예기치 않게 중단된다면, 이는 단순한 불편함을 넘어 심각한 보안 취약점이나 재산 피해로 이어질 수 있습니다. 본 글은 5년차 이상 시니어 개발자를 대상으로, 홈 어시스턴트 시스템의 고가용성(High Availability, HA) 확보 및 재해 복구(Disaster Recovery, DR) 전략 구현을 위한 실전 체크리스트와 심층적인 점검 가이드를 제공합니다. 시스템 안정성을 극대화하고, 예측 불가능한 상황에서도 서비스 연속성을 유지하는 방안에 대해 심도 있게 논의하고자 합니다.
📑 목차
- 프로젝트 상황 설정: 스마트 홈 인프라의 핵심, 홈 어시스턴트
- 문제 발생: 핵심 시스템의 예기치 않은 중단
- 원인 분석: 고가용성 및 재해 복구 전략의 부재
- 단일 장애점(SPOF)의 문제점
- 백업 및 복구 프로세스의 미흡성
- 해결 과정: 고가용성 아키텍처 설계 및 백업 전략 구현
- 고가용성(HA) 아키텍처 구축 방안
- 재해 복구(DR)를 위한 백업 및 복구 전략
- 점검 가이드: 실전 체크리스트 및 트레이드오프 분석
- 고가용성 설계 점검 체크리스트
- 백업 및 복구 전략 점검 체크리스트
- 트레이드오프 분석: 비용, 복잡성, 안정성
- 교훈 및 시사점: 안정적인 스마트 홈 인프라를 위한 지속적인 노력
Image by 12019 on Pixabay
프로젝트 상황 설정: 스마트 홈 인프라의 핵심, 홈 어시스턴트
가상의 프로젝트 상황을 설정합니다. 한 시니어 개발팀은 복잡하고 광범위한 스마트 홈 환경을 구축 및 운영하고 있습니다. 이 환경은 다음과 같은 핵심 기능을 홈 어시스턴트에 의존하고 있습니다.
- 보안 시스템 연동: 침입 감지 센서, CCTV 녹화 트리거, 비상 사이렌 제어
- 환경 제어: 실내외 온도 및 습도에 따른 HVAC(난방, 환기, 공조) 시스템 자동화, 공기 질 관리
- 에너지 관리: 태양광 발전 모니터링, 스마트 플러그를 통한 전력 소비 최적화, 피크 시간대 부하 분산
- 일상 자동화: 출퇴근 시간에 따른 조명 및 블라인드 제어, 음성 비서 연동
이러한 기능들은 홈 어시스턴트의 자동화(Automation), 스크립트(Script), 애드온(Add-ons), 그리고 통합(Integrations)에 깊이 의존하고 있으며, 시스템 중단은 곧 거주자의 안전, 편의, 그리고 에너지 효율성에 직접적인 영향을 미치는 상황입니다. 개발팀은 이러한 중요성을 인지하고, 홈 어시스턴트 인프라의 최고 수준의 안정성을 확보하는 것을 최우선 과제로 설정하였습니다.
문제 발생: 핵심 시스템의 예기치 않은 중단
어느 날 새벽, 예기치 않은 사건으로 인해 스마트 홈 시스템 전체가 마비되는 상황이 발생했습니다.
- 원인: 장기간 사용하던 SD 카드의 논리적 손상으로 인해 홈 어시스턴트 OS가 부팅되지 않음.
- 직접적인 영향:
- 보안 시스템의 작동 중단으로 인해 새벽 시간대 이상 감지 알림이 누락되었습니다.
- HVAC 시스템 제어가 불가능해져 실내 온도가 급격히 변동하였습니다.
- 에너지 모니터링 및 최적화 기능이 정지되어 불필요한 전력 소모가 발생하였습니다.
- 모든 자동화 기능이 멈춰 거주자의 일상에 심각한 불편을 초래했습니다.
- 간접적인 영향: 시스템 복구를 위해 약 4시간의 수동 작업이 필요했으며, 이 과정에서 최근 24시간 동안의 에너지 사용량 및 환경 센서 데이터가 유실되었습니다. 이는 거주자의 안전에 대한 우려와 시스템에 대한 신뢰도 하락으로 이어졌습니다. 특히, 중요한 보안 알림이 누락된 점은 팀에 큰 경각심을 주었습니다.
이러한 상황은 단일 장애점(Single Point of Failure, SPOF)에 대한 고려 부족과 재해 복구 계획(Disaster Recovery Plan, DRP)의 미흡성이 복합적으로 작용한 결과로 판단됩니다.
원인 분석: 고가용성 및 재해 복구 전략의 부재
발생한 문제의 근본적인 원인을 분석한 결과, 홈 어시스턴트 시스템 설계에 있어 고가용성 및 재해 복구 전략이 충분히 고려되지 않았음이 명확히 드러났습니다.
단일 장애점(SPOF)의 문제점
기존 시스템은 다음과 같은 명확한 단일 장애점을 가지고 있었습니다.
- 하드웨어 의존성:
- 부팅 미디어: 홈 어시스턴트 OS가 설치된 SD 카드는 임베디드 환경에서 흔히 사용되지만, 수명과 안정성 면에서 취약점을 가집니다. 특히 잦은 쓰기 작업(로그, 데이터베이스 업데이트)은 SD 카드의 수명을 단축시키고 데이터 손상 위험을 높입니다.
- 단일 컴퓨팅 유닛: Raspberry Pi와 같은 단일 SBC(Single Board Computer)에 모든 홈 어시스턴트 인스턴스가 운영되므로, 해당 장비의 고장은 시스템 전체의 마비로 직결됩니다.
- 전원 공급 장치: UPS(Uninterruptible Power Supply)의 부재로 인해 정전 시 시스템이 즉시 다운되는 문제점이 존재합니다.
- 소프트웨어 및 데이터베이스 의존성:
- 내부 SQLite 데이터베이스: 기본적으로 사용되는 SQLite 데이터베이스는 단일 파일 기반으로, 손상 시 복구가 어렵고 고가용성 구성에 적합하지 않습니다. 대량의 센서 데이터나 이벤트 로그가 쌓일 경우 성능 저하 및 데이터 손상 위험이 증가합니다.
- 설정 파일 및 애드온: YAML 기반의 설정 파일(.yaml)과 설치된 애드온들은 모두 단일 호스트에 존재하며, 이들의 손상 또한 전체 시스템에 영향을 미칩니다.
- 네트워크 의존성: 라우터 고장이나 인터넷 연결 단절 시, 클라우드 기반 서비스(예: 외부 날씨 정보, 음성 비서 연동) 및 외부 접근(원격 제어)이 불가능해집니다.
백업 및 복구 프로세스의 미흡성
기존의 백업 전략은 다음과 같은 문제점을 가지고 있었습니다.
- 백업의 비정기성 및 수동성: 백업이 정기적으로 자동화되어 있지 않았고, 대부분 수동으로 이루어져 최신 상태를 반영하지 못하는 경우가 많았습니다.
- 백업 데이터의 저장 위치: 백업 데이터가 주로 로컬 저장소(동일 SD 카드 또는 연결된 USB 드라이브)에만 저장되어, 물리적 재해 발생 시 백업 데이터까지 함께 손실될 위험이 높았습니다.
- 복구 절차의 미비: 재해 발생 시 시스템을 복구하는 명확한 절차(RTO, RPO 정의 포함)가 문서화되어 있지 않았고, 실제 복구 훈련이 전무하여 복구에 필요한 시간이 과도하게 소요되었습니다.
- 데이터 무결성 검증 부재: 백업된 데이터의 무결성이나 복구 가능성에 대한 주기적인 검증 작업이 이루어지지 않아, 막상 복구가 필요할 때 백업 파일이 손상되어 있거나 불완전한 상태일 가능성이 있었습니다.
이러한 문제점들을 종합적으로 고려할 때, 홈 어시스턴트 인프라의 안정성을 확보하기 위해서는 고가용성 아키텍처 도입과 체계적인 재해 복구 전략 수립이 필수적으로 판단되었습니다.
Image by antonbe on Pixabay
해결 과정: 고가용성 아키텍처 설계 및 백업 전략 구현
문제 발생 이후, 개발팀은 홈 어시스턴트 시스템의 안정성 강화를 위해 고가용성(HA) 아키텍처 설계와 재해 복구(DR) 전략 구현에 착수하였습니다.
고가용성(HA) 아키텍처 구축 방안
단일 장애점(SPOF)을 제거하고 서비스 연속성을 확보하기 위해 다음과 같은 HA 아키텍처를 설계하고 구현하였습니다.
하드웨어 이중화 및 클러스터링
단일 호스트의 의존성을 줄이기 위해 여러 대의 컴퓨팅 유닛을 활용하는 방안을 모색했습니다.
- Kubernetes 기반 컨테이너화: 홈 어시스턴트 코어 및 애드온들을 Docker 컨테이너로 분리하고, k3s 또는 MicroK8s와 같은 경량 Kubernetes 클러스터에 배포합니다. 최소 2대 이상의 Raspberry Pi 4 또는 동급 SBC로 클러스터를 구성하여 노드 장애 시에도 서비스가 다른 노드로 자동 이전되도록 설정합니다.
PV(Persistent Volume) 및 PVC(Persistent Volume Claim)를 사용하여 홈 어시스턴트 설정 및 데이터가 영속적으로 유지되도록 구성하며, 이를 위해 NFS(Network File System)나 Longhorn과 같은 분산 스토리지 솔루션을 활용합니다.# k3s 클러스터 초기화 (마스터 노드) curl -sfL https://get.k3s.io | sh -s - --cluster-init # 워커 노드 조인 (토큰과 마스터 IP 필요) curl -sfL https://get.k3s.io | sh -s - --server https://<MASTER_IP>:6443 --token <NODE_TOKEN> - 가상화 환경(Proxmox VE) 활용: 강력한 서버 하드웨어에 Proxmox VE와 같은 하이퍼바이저를 설치하고, 홈 어시스턴트를 포함한 여러 VM(Virtual Machine)을 생성합니다. 2대 이상의 Proxmox 노드를 클러스터로 구성하여 HA 기능을 활성화하고, 공유 스토리지(Ceph, NFS, iSCSI)를 사용하여 VM의 라이브 마이그레이션(Live Migration)을 가능하게 합니다. 이는 하드웨어 유지보수 시에도 서비스 중단 없이 VM을 이동시킬 수 있도록 합니다.
데이터베이스 이중화
내부 SQLite 데이터베이스의 취약점을 해결하기 위해 외부 PostgreSQL 또는 MariaDB(MySQL) 데이터베이스를 도입하고 이중화 구성을 적용합니다.
- 마스터-슬레이브(Master-Slave) 복제: 주 데이터베이스 서버와 보조 데이터베이스 서버를 구성하여, 주 서버에 장애 발생 시 보조 서버로 빠르게 전환할 수 있도록 합니다. PostgreSQL의 WAL(Write-Ahead Log) Shipping이나 MariaDB의 바이너리 로그 복제를 활용합니다.
# PostgreSQL streaming replication 설정 예시 (pg_hba.conf) host replication all <REPLICA_IP>/32 md5 # PostgreSQL replication 설정 예시 (postgresql.conf) wal_level = replica max_wal_senders = 10 wal_keep_size = 64 archive_mode = on archive_command = 'cp %p /mnt/server/archivedir/%f' - 고가용성 프록시: HAProxy 또는 ProxySQL을 데이터베이스 앞에 두어, 애플리케이션이 항상 활성 데이터베이스 인스턴스에 연결되도록 로드 밸런싱 및 페일오버 기능을 제공합니다.
네트워크 및 전원 이중화
- 네트워크 이중화: 메인 라우터 외에 백업 라우터를 준비하고, 이중 WAN(Wide Area Network) 구성을 통해 인터넷 연결 단절에 대비합니다. 또한, 내부 네트워크의 핵심 스위치에도 이중화를 고려합니다.
- 전원 이중화: 홈 어시스턴트 호스트 및 네트워크 장비, 공유 스토리지 등에 UPS(무정전 전원 공급 장치)를 연결하여 단기 정전에 대비하고, 장시간 정전 시 자동으로 시스템을 안전하게 종료하거나 저전력 모드로 전환하도록 설정합니다.
| HA 전략 | 장점 | 단점 | 주요 고려사항 |
|---|---|---|---|
| Kubernetes 클러스터 (k3s/MicroK8s) | 높은 확장성 및 유연성, 컨테이너 기반 HA 용이, 자원 효율적 | 초기 설정 및 운영 복잡성, 학습 곡선, 스토리지 HA 구성 필요 | 컨테이너 오케스트레이션 이해, 분산 스토리지 솔루션 선택 |
| Proxmox VE 클러스터 (HA VM) | VM 단위의 HA, 라이브 마이그레이션, GUI 기반 관리 용이 | 전용 서버 하드웨어 필요, 공유 스토리지 필수, 초기 비용 높음 | 서버 하드웨어 선정, 공유 스토리지(Ceph 등) 설계, VM 최적화 |
| DB 이중화 (PostgreSQL/MariaDB) | 데이터 유실 최소화, DB 성능 향상, 복원력 증대 | 추가 DB 서버 필요, 복제 설정 복잡성, 동기화 지연 가능성 | 적절한 복제 방식 선택, 모니터링, 페일오버 자동화 고려 |
재해 복구(DR)를 위한 백업 및 복구 전략
고가용성 아키텍처가 시스템 중단 시간을 최소화하는 데 중점을 둔다면, 재해 복구 전략은 대규모 재해(예: 데이터 센터 파괴, 광범위한 시스템 손상) 발생 시 데이터를 보호하고 서비스를 완전히 복원하는 데 중점을 둡니다.
정기적인 자동 백업
- 홈 어시스턴트 내장 백업: Full Snapshot 기능을 활용하여 OS, 설정, 애드온, 데이터베이스를 포함한 전체 시스템 스냅샷을 주기적으로 생성합니다. 이를 스케줄링하여 자동화합니다.
# Home Assistant REST API를 이용한 백업 생성 (예시) curl -X POST -H "Authorization: Bearer YOUR_LONG_LIVED_TOKEN" \ -H "Content-Type: application/json" \ -d '{"name": "full_snapshot_daily"}' \ http://<HOME_ASSISTANT_IP>:8123/api/hassio/snapshots/new/full - 애드온 활용: Google Drive Backup, Samba Backup과 같은 애드온을 설치하여 백업 파일을 클라우드 스토리지나 네트워크 스토리지(NAS)로 자동 전송합니다.
- 파일 시스템 스냅샷: Proxmox VE나 ZFS/Btrfs와 같은 고급 파일 시스템을 사용하는 경우, VM 또는 컨테이너의 파일 시스템 스냅샷을 주기적으로 생성하여 특정 시점으로의 빠른 롤백을 가능하게 합니다.
- 데이터베이스 백업: 외부 DB를 사용하는 경우,
pg_dump(PostgreSQL) 또는mysqldump(MariaDB/MySQL) 명령어를 사용하여 데이터베이스 자체의 논리적 백업을 별도로 수행하고, 이를 백업 저장소로 전송합니다.
백업 데이터의 외부 저장 및 버전 관리
- 오프사이트(Off-site) 스토리지: 모든 백업 데이터는 물리적으로 분리된 오프사이트 스토리지(예: Google Drive, Amazon S3, Azure Blob Storage, 원격 NAS)에 저장하여 로컬 재해로부터 보호합니다.
- 버전 관리 및 보존 정책: 백업 데이터에 대한 버전 관리를 적용하고, RPO(Recovery Point Objective)를 고려하여 적절한 보존 정책(예: 일별 백업 7일, 주별 백업 4주, 월별 백업 6개월)을 수립합니다.
- 불변(Immutable) 백업: 랜섬웨어 공격 등에 대비하여 백업 데이터를 한 번 기록되면 변경하거나 삭제할 수 없는 불변 스토리지에 저장하는 방안을 고려합니다.
복구 절차 정의 및 주기적 테스트
- RTO(Recovery Time Objective) 및 RPO(Recovery Point Objective) 설정: 시스템 복구에 허용되는 최대 시간(RTO)과 데이터 손실 허용 범위(RPO)를 명확히 정의합니다. 예를 들어, RTO는 1시간, RPO는 30분으로 설정할 수 있습니다.
- DRP(Disaster Recovery Plan) 문서화: 재해 발생 시 단계별 복구 절차, 담당자, 비상 연락망, 필요한 도구 및 자원 등을 상세히 문서화합니다.
# DRP 문서 주요 목차 1. 재해 유형 및 비상 연락망 2. RTO/RPO 정의 3. 비상 시 대응 절차 (Initial Response) 4. 시스템 복구 절차 (Recovery Steps) - 백업 데이터 위치 및 접근 방법 - 하드웨어 교체 및 OS 재설치 - Home Assistant 코어 및 DB 복원 - 연동 서비스 재설정 5. 복구 후 검증 및 모니터링 6. 정기적인 DRP 훈련 계획 - 주기적인 복구 훈련(DR Drill): 정의된 DRP에 따라 주기적으로 복구 훈련을 실시하여 절차의 유효성을 검증하고, 팀원들의 숙련도를 향상시킵니다. 이는 실제 재해 발생 시 혼란을 줄이고 신속한 대응을 가능하게 합니다.
Image by stevepb on Pixabay
점검 가이드: 실전 체크리스트 및 트레이드오프 분석
구현된 고가용성 및 재해 복구 전략이 실제 환경에서 효과적으로 작동하는지 확인하기 위한 실전 체크리스트와 함께, 각 전략의 도입 시 고려해야 할 트레이드오프를 분석합니다.
고가용성 설계 점검 체크리스트
- SPOF 식별 및 제거 여부:
- [ ] 모든 하드웨어 구성 요소(SBC, 스토리지, PSU)에 대한 이중화 또는 대체 경로가 확보되었는가?
- [ ] 네트워크 인프라(라우터, 스위치, 인터넷 회선)에 대한 이중화가 적용되었는가?
- [ ] 데이터베이스가 이중화되었으며, 페일오버 메커니즘이 정상 작동하는가?
- 페일오버(Failover) 메커니즘 동작 확인:
- [ ] 주 서버/노드 강제 종료 시 백업 서버/노드로의 자동 전환이 정상적으로 이루어지는가?
- [ ] 서비스 중단 시간(Downtime)이 정의된 RTO 내에 있는가? (예: 전환 시간 5분 이내)
- [ ] 페일오버 발생 시 데이터 일관성 문제가 없는가?
- 모니터링 및 알림 시스템 구축 여부:
- [ ] 시스템의 주요 구성 요소(CPU, 메모리, 스토리지, 네트워크) 상태를 실시간으로 모니터링하는가?
- [ ] 장애 발생 시 SMS, 이메일, 메신저 등 다양한 채널로 알림이 즉시 전송되는가?
- [ ] 모니터링 시스템 자체가 SPOF가 되지 않도록 이중화되었는가? (예: 외부 모니터링 서비스 활용)
- 성능 오버헤드 분석:
- [ ] HA 구성으로 인해 추가된 리소스(CPU, 메모리, 네트워크 대역폭)가 시스템 성능에 미치는 영향은 분석되었는가?
- [ ] 이중화된 데이터베이스의 복제 지연(Replication Lag)은 허용 가능한 범위 내에 있는가?
백업 및 복구 전략 점검 체크리스트
- 백업 주기 및 유효성:
- [ ] 백업이 정의된 RPO를 충족하기에 충분한 주기로 자동 실행되는가? (예: 매 시간, 매일)
- [ ] 백업 대상(OS, 설정, DB, 애드온)이 모두 포함되어 있는가?
- [ ] 백업 완료 여부 및 성공/실패에 대한 알림이 정상적으로 수신되는가?
- 복구 시간 목표(RTO) 및 복구 시점 목표(RPO) 달성 가능성:
- [ ] 백업 데이터의 저장 위치 및 접근 방식이 RTO 달성에 적합한가? (예: 클라우드 스토리지 다운로드 시간 고려)
- [ ] DRP에 명시된 복구 절차를 따라 실제 복구 훈련을 수행했을 때 RTO/RPO를 달성할 수 있었는가?
- 백업 데이터 무결성 및 보안:
- [ ] 백업 데이터의 무결성 검증 절차가 주기적으로 수행되는가? (예: 파일 해시 검증, 샘플 복구 테스트)
- [ ] 백업 데이터가 암호화되어 저장되며, 접근 권한이 적절히 관리되는가?
- [ ] 백업 데이터가 랜섬웨어 등으로부터 보호되는 불변 스토리지에 저장되는가?
- 복구 절차 문서화 및 훈련 여부:
- [ ] DRP가 최신 상태로 유지되며, 모든 팀원이 접근 가능한가?
- [ ] 주기적인 DR 훈련이 계획되어 있고, 실제 수행되는가?
- [ ] 훈련 결과를 바탕으로 DRP가 지속적으로 개선되는가?
트레이드오프 분석: 비용, 복잡성, 안정성
완벽한 고가용성과 재해 복구 시스템을 구축하는 것은 상당한 비용과 복잡성을 수반합니다. 따라서 프로젝트의 중요도와 예산을 고려하여 적절한 균형점을 찾는 것이 중요합니다. 아래 표는 다양한 수준의 HA/DR 전략에 따른 트레이드오프를 비교합니다.
| HA/DR 수준 | 특징 | 예상 비용 | 복잡성 | 안정성/복원력 | RTO/RPO 목표 |
|---|---|---|---|---|---|
| 기본 (Basic) | 단일 호스트, 자동 백업만 클라우드 저장 | 낮음 (클라우드 스토리지 비용) | 낮음 | 보통 (하드웨어 재해 시 수동 복구) | RTO: 수 시간, RPO: 1일 |
| 중급 (Intermediate) | HAProxy/DB 이중화, UPS, 정기적 DR 훈련 | 중간 (추가 하드웨어, SW 라이선스) | 중간 | 높음 (부분적 자동 페일오버) | RTO: 30분~1시간, RPO: 1시간 |
| 고급 (Advanced) | Kubernetes/Proxmox 클러스터, 분산 스토리지, 완벽한 DB 이중화, 다중 WAN, 불변 백업, 자동 DR 시스템 | 높음 (다수 서버, 전문 인력, 클라우드 비용) | 매우 높음 | 매우 높음 (완전 자동 페일오버, 데이터 유실 거의 없음) | RTO: 수 분, RPO: 수 분 |
시니어 개발자는 이러한 트레이드오프를 명확히 이해하고, 특정 환경의 요구사항과 제약을 바탕으로 최적의 HA/DR 전략을 선택해야 합니다. 무조건 최고 수준의 안정성을 추구하기보다는, 비즈니스 연속성 계획(BCP)의 일환으로 중요도를 분석하고 현실적인 목표를 설정하는 것이 중요합니다.
교훈 및 시사점: 안정적인 스마트 홈 인프라를 위한 지속적인 노력
이번 시스템 중단 사태를 통해 개발팀은 고가용성 및 재해 복구 전략이 시스템 구축 초기 단계부터 필수적으로 고려되어야 하는 핵심 요소임을 다시 한번 깨달았습니다. 단일 장애점을 식별하고 제거하며, 예측 불가능한 상황에 대비하는 체계적인 백업 및 복구 절차를 수립하는 것은 시스템 안정성을 보장하는 데 있어 아무리 강조해도 지나치지 않습니다.
안정적인 스마트 홈 인프라를 구축하는 것은 한 번의 설정으로 끝나는 작업이 아닙니다. 기술 스택의 변화, 새로운 위협의 등장, 그리고 시스템 규모의 확장 등에 따라 지속적인 점검, 개선, 그리고 훈련이 요구되는 과정입니다. 특히, 홈 어시스턴트와 같은 오픈소스 기반의 유연한 시스템은 사용자의 역량에 따라 무한한 가능성을 제공하지만, 동시에 안정성 확보에 대한 책임 또한 사용자에게 있음을 시사합니다.
본 가이드에서 제시된 체크리스트와 트레이드오프 분석은 시니어 개발자들이 자신의 홈 어시스턴트 환경을 더욱 견고하게 만들고, 미래의 잠재적 재해에 대비하는 데 실질적인 도움을 줄 수 있을 것으로 기대됩니다. 사전 예방적 접근 방식과 철저한 계획만이 안정적이고 신뢰할 수 있는 스마트 홈 환경을 유지하는 열쇠입니다.
여러분의 홈 어시스턴트 HA/DR 전략은 어떠한가요? 본 글에서 다루지 못한 혹은 여러분만의 특별한 노하우가 있다면 댓글로 공유해 주시기 바랍니다.