---
title: "OpenStack에서 Neutron 에이전트 자동 재시작을 위한 Kolla Ansible 스크립트"
description: "<summary>Neutron 에이전트가 주기적으로 다운되는 문제를 해결하기 위해 Kolla Ansible을 이용해 5분마다 에이전트 상태를 CSV로 확인하고, Alive가 False이면서 State가 True인 경우 SSH를 통해 해당 Docker 컨테이너를 자동 재시작하는 스크립트를 작성하였다. 스크립트는 CSV 파싱, 컨테이너 이름 변환, 안정적인 SSH 연결, 트랩을 통한 정상 종료 등을 포함하며, 백그라운드 실행 및 로그 확인 방법도 제공한다. 이를 통해 에이전트 관리가 간편해지지만, 근본 원인 분석도 필요함을 강조한다.</summary>"
date: "2025-10-22"
last_modified: "2026-08-06T00:36:00.000Z"
type: "Post"
tags:
  - "openstack"
  - "network"
  - "docker"
  - "ssh"
  - "kolla ansible"
  - "Ansible"
categories:
  - "🤖 Computer Science"
series:
  - "오픈스택 운영"
canonical_url: "https://blog.pieroot.xyz/neutron-restart"
markdown_url: "https://blog.pieroot.xyz/neutron-restart.md"
---

# OpenStack에서 Neutron 에이전트 자동 재시작을 위한 Kolla Ansible 스크립트

\<summary\>Neutron 에이전트가 주기적으로 다운되는 문제를 해결하기 위해 Kolla Ansible을 이용해 5분마다 에이전트 상태를 CSV로 확인하고, Alive가 False이면서 State가 True인 경우 SSH를 통해 해당 Docker 컨테이너를 자동 재시작하는 스크립트를 작성하였다. 스크립트는 CSV 파싱, 컨테이너 이름 변환, 안정적인 SSH 연결, 트랩을 통한 정상 종료 등을 포함하며, 백그라운드 실행 및 로그 확인 방법도 제공한다. 이를 통해 에이전트 관리가 간편해지지만, 근본 원인 분석도 필요함을 강조한다.\</summary\>

### 개요

연구실에서 운영 중인 OpenStack 환경에서 Neutron 에이전트가 주기적으로 다운되는 문제가 발생했습니다. 이를 해결하기 위해 Kolla Ansible을 활용한 자동 재시작 스크립트를 작성했습니다.

이 스크립트는 5분마다 에이전트 상태를 체크하고, 문제가 발생한 에이전트를 자동으로 재시작합니다.

![image](https://blog.pieroot.xyz/api/image-proxy?id=ff61142f-d340-4f4e-a779-a33b4d2df958&kind=s3&pageId=2e0067c0-15d0-80aa-a426-d244be8db44b&source=block&blockId=2e4067c0-15d0-80bb-bf6e-cab57b18f8a9)

### 문제 상황

Neutron 네트워크 에이전트는 OpenStack에서 네트워크 기능을 담당하는 핵심 구성요소입니다.

![image](https://blog.pieroot.xyz/api/image-proxy?id=1fb5a384-17d5-41d4-93b5-6c827b2420c5&kind=s3&pageId=2e0067c0-15d0-80aa-a426-d244be8db44b&source=block&blockId=2e0067c0-15d0-8088-bd8a-ff1a1a2795b3)

그런데 가끔씩 `openstack network agent list` 명령어로 에이전트 상태를 확인해보면 Alive가 `False`로 표시되는 경우가 발생합니다. 이런 상태가 되면 네트워크가 정상적으로 동작하지 않게 됩니다.

![오류 감지를 위해 discord에 alert 설정](https://blog.pieroot.xyz/api/image-proxy?id=e2c01a70-432e-4d38-a952-3c2829c03f5d&kind=s3&pageId=2e0067c0-15d0-80aa-a426-d244be8db44b&source=block&blockId=2e0067c0-15d0-8088-aed9-ff19a3bf8189)

### 스크립트 동작 방식

스크립트는 다음과 같은 방식으로 동작합니다:

1. **5분 주기로 자동 실행:** 무한 루프로 계속 돌면서 주기적으로 체크합니다.

1. **Agent 상태 조회:** `openstack network agent list`로 모든 네트워크 에이전트의 상태를 CSV 형식으로 가져옵니다.

1. **문제 있는 에이전트 찾기:** Alive가 `False`이면서 State는 `True`인 에이전트를 탐지합니다.

1. **SSH로 재시작:** 문제가 있는 호스트에 SSH로 접속해서 해당 Docker 컨테이너를 재시작합니다.

1. **결과 요약:** 몇 개의 에이전트를 재시작했는지 출력합니다.

### 핵심 기능

#### 1. CSV 파싱

OpenStack CLI가 출력하는 CSV 형식을 파싱해서 각 필드를 추출합니다. 따옴표 제거 처리도 포함되어 정확한 값을 얻을 수 있습니다.

```bash
AGENT_LIST=$(openstack network agent list --sort-column Alive -f csv -c "Agent Type" -c "Host" -c "Availability Zone" -c "Alive" -c "State" -c "Binary")
```

#### Agent List 변수 예시

CSV 형식으로 다음과 같은 데이터가 들어옵니다:

```javascript
"Agent Type","Host","Availability Zone","Alive","State","Binary"
"Open vSwitch agent","dms-compute2","","True","True","neutron-openvswitch-agent"
"Metadata agent","dms-controller1","","True","True","neutron-metadata-agent"
"Metadata agent","dms-compute2","","True","True","neutron-metadata-agent"
"Open vSwitch agent","dms-controller1","","True","True","neutron-openvswitch-agent"
...
```

#### 2. Docker 컨테이너 이름 변환

Neutron 바이너리 이름(예: `neutron-dhcp-agent`)을 Docker 컨테이너 이름(예: `neutron_dhcp_agent`)으로 변환합니다. 하이픈을 언더바로 바꿔주는 간단한 로직입니다.

```bash
binary="${binary//\"/}"
CONTAINER_NAME="${binary//-/_}" # '-' 를 '_' 로 변경
```

#### 3. 안정적인 SSH 연결

타임아웃 설정으로 네트워크 문제로 인한 무한 대기를 방지했습니다. 재시작이 실패해도 다른 에이전트 처리를 계속하도록 구성했습니다.

```bash
if timeout 60 ssh -n -o ConnectTimeout=10 -o StrictHostKeyChecking=no "$host" "sudo docker restart $CONTAINER_NAME" 2&gt;&1; then
    echo "✓ $host의 $CONTAINER_NAME 재시작 성공"
    ((RESTART_COUNT++))
else
    echo "✗ $host의 $CONTAINER_NAME 재시작 실패 (계속 진행)"
    # 실패해도 계속 진행
fi
```

#### 4. 정상 종료 처리

`Ctrl+C`로 깔끔하게 중지할 수 있도록 trap을 설정했습니다.

```bash
trap 'echo ""; echo "========================================="; echo "스크립트가 중지되었습니다."; echo "========================================="; exit 0' INT TERM
```

### 사용 방법

```bash
# 스크립트 실행 권한 부여
chmod +x neutron_agent_restart.sh

# 백그라운드로 실행
nohup ./neutron_agent_restart.sh &gt; neutron_monitor.log 2&gt;&1 &

# 실시간 로그 확인
tail -f neutron_monitor.log
```

### 전체 스크립트

```shell
#!/bin/bash
#
# Neutron Network Agent 재시작 스크립트 (무한 루프 버전)
# 5분마다 openstack network agent list를 실행하여 Alive가 XXX인 agent들을 자동으로 재시작합니다.
#

# Ctrl+C 시 정상 종료 처리
trap 'echo ""; echo "========================================="; echo "스크립트가 중지되었습니다."; echo "========================================="; exit 0' INT TERM

echo "========================================="
echo "Neutron Agent 모니터링 시작"
echo "5분마다 자동 실행 및 재시작"
echo "중지하려면 Ctrl+C를 누르세요."
echo "========================================="
echo ""

# 무한 루프
while true; do
    echo "========================================="
    echo "실행 시간: $(date '+%Y-%m-%d %H:%M:%S')"
    echo "========================================="
    echo ""
    
    # openstack network agent list 실행 (CSV 포맷 사용)
    echo "Network Agent 상태 조회 중..."
    AGENT_LIST=$(openstack network agent list --sort-column Alive -f csv -c "Agent Type" -c "Host" -c "Availability Zone" -c "Alive" -c "State" -c "Binary")
    
    # XXX 상태의 agent들 추출
    echo "문제가 있는 Agent 확인 중..."
    echo ""
    
    # 진행 상황 추적 변수
    RESTART_COUNT=0
    
    # 각 라인 처리 (CSV 파싱)
    # 헤더 건너뛰기
    # 임시 파일을 사용하여 루프 안정성 확보
    TEMP_FILE=$(mktemp)
    echo "$AGENT_LIST" | tail -n +2 &gt; "$TEMP_FILE"
    
    while IFS=',' read -r agent_type host availability_zone alive state binary; do
        # 따옴표 제거
        agent_type="${agent_type//\"/}"
        host="${host//\"/}"
        availability_zone="${availability_zone//\"/}"
        alive="${alive//\"/}"
        state="${state//\"/}"
        binary="${binary//\"/}"
        # Docker 컨테이너 이름으로 변환 (하이픈 → 언더바)
        CONTAINER_NAME="${binary//-/_}"
        
        # Alive가 False이고 State가 True인 경우만 처리
        # echo "검사 중: Host=$host, Binary=$binary, Alive=$alive, State=$state"
        if [[ "$alive" == "False" && "$state" == "True" ]]; then
            echo "발견된 문제 Agent:"
            echo "  Host: $host"
            echo "  Binary: $binary"
            echo "  Agent Type: $agent_type"
            echo ""
            
            # SSH 접속하여 Docker 컨테이너 재시작
            echo "SSH 접속 중: $host"
            echo "Docker 컨테이너 재시작: $CONTAINER_NAME"
            
            # SSH 명령 실행 (에러가 발생해도 계속 진행)
            if timeout 60 ssh -n -o ConnectTimeout=10 -o StrictHostKeyChecking=no "$host" "sudo docker restart $CONTAINER_NAME" 2&gt;&1; then
                echo "✓ $host의 $CONTAINER_NAME 재시작 성공"
                ((RESTART_COUNT++))
            else
                echo "✗ $host의 $CONTAINER_NAME 재시작 실패 (계속 진행)"
                # 실패해도 계속 진행
            fi
            
            echo ""
        fi
    done &lt; "$TEMP_FILE"
    
    # 임시 파일 삭제
    rm -f "$TEMP_FILE"
    
    # 결과 요약
    echo "========================================="
    if [ $RESTART_COUNT -eq 0 ]; then
        echo "문제가 있는 Agent가 없습니다."
    else
        echo "총 재시작한 Agent 수: $RESTART_COUNT"
    fi
    echo "========================================="
    echo ""
    
    # 5분 대기 (300초)
    echo "다음 실행까지 5분 대기..."
    echo ""
    sleep 300
done
```

### 주의사항

- **SSH 키 설정 필수:** 스크립트 실행 서버에서 모든 컴퓨트 노드로 비밀번호 없이 SSH 접속이 가능해야 합니다. 

- **sudo 권한:** 각 노드에서 Docker 컨테이너 재시작을 위해 sudo 권한이 필요합니다.

- **재시작 주기 조정:** 현재는 5분(300초)으로 설정되어 있으며, 환경에 맞게 조정 가능합니다.

### 마무리

이 스크립트 덕분에 Neutron 에이전트 관리가 훨씬 편해졌습니다. 하지만 이는 임시방편이며, 근본적으로 에이전트가 자주 다운되는 원인을 찾아야 합니다.

주로 메모리 부족, 네트워크 불안정, RabbitMQ 연결 문제 등이 원인인 경우가 많습니다. 로그를 잘 살펴보면서 근본 원인을 해결하는 것이 중요합니다.
