<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[vulcan Blog]]></title><description><![CDATA[중앙대학교에서 소프트웨어를 전공했습니다. 홈서버를 운영하는데 많은 관심이 있습니다. 보통 '불칸'이라는 아이디로 활동하고 있습니다.]]></description><link>https://vulcan.site</link><generator>GatsbyJS</generator><lastBuildDate>Sun, 13 Apr 2025 12:39:41 GMT</lastBuildDate><item><title><![CDATA[Proxmox에서 linux bridge 속도 테스트하기 01]]></title><description><![CDATA[시작 Proxmox에서 보통 VM이나 CT에 네트워크를 할당할 때는 linux bridge를 사용한다. nic의 포트를 linux brige에 할당해서 사용하거나 같은 linux bridge에서 여러 VM이 통신을 할 수 있다. 여기서 nic…]]></description><link>https://vulcan.site/proxmox-vmbr-01/</link><guid isPermaLink="false">https://vulcan.site/proxmox-vmbr-01/</guid><pubDate>Sat, 12 Apr 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h1 id=&quot;시작&quot; style=&quot;position:relative;&quot;&gt;시작&lt;a href=&quot;#%EC%8B%9C%EC%9E%91&quot; aria-label=&quot;시작 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Proxmox에서 보통 VM이나 CT에 네트워크를 할당할 때는 linux bridge를 사용한다. nic의 포트를 linux brige에 할당해서 사용하거나 같은 linux bridge에서 여러 VM이 통신을 할 수 있다. 여기서 nic의 포트 밖으로 나가지 않는 트래픽은 linux bridge에서 처리하는데 이 경우 host의 cpu가 처리하게 된다. 이 cpu는 네트워크 브릿징에 최적화된 칩이 아니기 때문에 속도에 제약이 발생할 수밖에 없다. 이 글에서는 proxmox의 linux bridge에서 내부적으로 낼 수 있는 최대 대역폭이 얼마인지를 테스트해 보려고 한다. (이 속도는 사용하는 cpu의 종류, 클럭에 따라 다를 수 있다.)&lt;/p&gt;
&lt;h1 id=&quot;환경&quot; style=&quot;position:relative;&quot;&gt;환경&lt;a href=&quot;#%ED%99%98%EA%B2%BD&quot; aria-label=&quot;환경 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;하드웨어 : AMD EPYC Milan 7T83, 2933Mhz 채널당 2 dimm&lt;/li&gt;
&lt;li&gt;proxmox version : proxmox-ve: 8.4.0 (running kernel: 6.8.12-9-pve)&lt;/li&gt;
&lt;li&gt;Test VM : 42 core, 128GB&lt;/li&gt;
&lt;li&gt;MTU : 9000&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;아래와 같이 MTU가 바르게 설정됐는지 확인할 수 있다.
&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 630px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/910a6145b857029866a0f56a51e88626/d6a46/ping.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 41.77215189873418%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAABYlAAAWJQFJUiTwAAABQElEQVQozz2SWY7CQAxE+zL8sAiRhJ1A9nTYQ0Yw3P8gNXqWej6sjqvtcpU7rmpOqpuTqiZV43NleaaqqlSWpUWe5yqKQm3bqmka3e933W43q9lut5rP59psNppOpxqNRnLf71fD8CPvO/nW63w+y3tvTY/Hwwjqujas6zrLGXS5XAyj5vl82h0D3Gvodb1eTcHhcDA1BAUEqtI0tXtySFBEfjwebXBQT537fN7q+96UQUQDilDAIHBshwFgEIGjNPTSB+4+v2+TDEGWZTaNwBoRCCEiwHBCPQKGYTAcQvpdUeZar9daLpdaLBaK4/j/TJLEThbPGYIHiKLI8NDHN7iLk8i8swOUMAkr5CjhmxWwN0hms5k1TyYTi/F4bHkQ4fIiswZsYgErBOS73c6Iw+74VYK9YBGi1WplL7zf7/UHm2oa6wQMeJ0AAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;ping&quot;
        title=&quot;ping&quot;
        src=&quot;/static/910a6145b857029866a0f56a51e88626/f058b/ping.png&quot;
        srcset=&quot;/static/910a6145b857029866a0f56a51e88626/c26ae/ping.png 158w,
/static/910a6145b857029866a0f56a51e88626/6bdcf/ping.png 315w,
/static/910a6145b857029866a0f56a51e88626/f058b/ping.png 630w,
/static/910a6145b857029866a0f56a51e88626/40601/ping.png 945w,
/static/910a6145b857029866a0f56a51e88626/d6a46/ping.png 1008w&quot;
        sizes=&quot;(max-width: 630px) 100vw, 630px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;h1 id=&quot;1-테스트-개요&quot; style=&quot;position:relative;&quot;&gt;1. 테스트 개요&lt;a href=&quot;#1-%ED%85%8C%EC%8A%A4%ED%8A%B8-%EA%B0%9C%EC%9A%94&quot; aria-label=&quot;1 테스트 개요 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;테스트의 주요 목표는 다음과 같다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;vmdr Multiqueue 값 조정: Proxmox VM 내 네트워크 인터페이스의 multiqueue 수를 1, 2, 4, 8, 16, 32, 40으로 순차적으로 변경하여 테스트 진행&lt;/li&gt;
&lt;li&gt;iperf3 병렬 채널 구성: 각 multiqueue 값에 대해 iperf3 테스트 채널 수를
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;기본 (1배): 현재 queue 수와 동일&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;2배: 현재 queue 수의 두 배&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;4배: 현재 queue 수의 네 배&lt;/p&gt;
&lt;p&gt;로 설정하여 성능 비교&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;성능 분석: 각 테스트 단계별로 네트워크 throughput, 지연 시간, 패킷 손실 및 CPU 부하 등을 측정하여 최적의 설정을 도출&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;2-테스트-스크립트&quot; style=&quot;position:relative;&quot;&gt;2. 테스트 스크립트&lt;a href=&quot;#2-%ED%85%8C%EC%8A%A4%ED%8A%B8-%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8&quot; aria-label=&quot;2 테스트 스크립트 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;#!/bin/bash
if [ &amp;quot;$#&amp;quot; -ne 1 ]; then
    echo &amp;quot;Usage: $0 &amp;lt;queue_number&amp;gt;&amp;quot;
    exit 1
fi

QUEUE=&amp;quot;$1&amp;quot;
SERVER_IP=&amp;quot;192.168.0.84&amp;quot;
TEST_TIME=30
OUTPUT_FILE=&amp;quot;queue_${QUEUE}.txt&amp;quot;

if [ -f &amp;quot;$OUTPUT_FILE&amp;quot; ]; then
    rm -f &amp;quot;$OUTPUT_FILE&amp;quot;
fi

for MULT in 1 2 4; do
    CHANNELS=$(( QUEUE * MULT ))
    echo &amp;quot;==========================&amp;quot; | tee -a &amp;quot;$OUTPUT_FILE&amp;quot;
    echo &amp;quot;채널 수: ${CHANNELS} (입력 queue: ${QUEUE}, multiplier: ${MULT})&amp;quot; | tee -a &amp;quot;$OUTPUT_FILE&amp;quot;
    echo &amp;quot;테스트 시작: $(date)&amp;quot; | tee -a &amp;quot;$OUTPUT_FILE&amp;quot;
    echo &amp;quot;--------------------------&amp;quot; | tee -a &amp;quot;$OUTPUT_FILE&amp;quot;

    iperf3 -c &amp;quot;$SERVER_IP&amp;quot; -P &amp;quot;$CHANNELS&amp;quot; -t &amp;quot;$TEST_TIME&amp;quot; &amp;gt;&amp;gt; &amp;quot;$OUTPUT_FILE&amp;quot; 2&amp;gt;&amp;amp;1

    echo &amp;quot;테스트 종료: $(date)&amp;quot; | tee -a &amp;quot;$OUTPUT_FILE&amp;quot;
    echo &amp;quot;&amp;quot; | tee -a &amp;quot;$OUTPUT_FILE&amp;quot;
    echo &amp;quot;&amp;quot; | tee -a &amp;quot;$OUTPUT_FILE&amp;quot;

    sleep 5
done

echo &amp;quot;테스트 완료. 결과는 ${OUTPUT_FILE} 파일을 확인하세요.&amp;quot;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&quot;3-테스트-결과&quot; style=&quot;position:relative;&quot;&gt;3. 테스트 결과&lt;a href=&quot;#3-%ED%85%8C%EC%8A%A4%ED%8A%B8-%EA%B2%B0%EA%B3%BC&quot; aria-label=&quot;3 테스트 결과 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;자세한 결과는 &lt;a href=&quot;https://github.com/firekann/vulcan.site/tree/master/content/blog/proxmox-vmbr-01&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;여기&lt;/a&gt;의 파일을 확인하자.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Queue&lt;/th&gt;
&lt;th&gt;채널 수&lt;/th&gt;
&lt;th&gt;대역폭 (Gbit/sec)&lt;/th&gt;
&lt;th&gt;Server VM CPU (%)&lt;/th&gt;
&lt;th&gt;Proxmox CPU (%)&lt;/th&gt;
&lt;th&gt;Client VM CPU (%)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;12.7&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;25.8&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;28.5&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;27.8&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;27.7&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;28.7&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;27.1&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;29.1&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;16&lt;/td&gt;
&lt;td&gt;56.2&lt;/td&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;52.6&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;16&lt;/td&gt;
&lt;td&gt;64.1&lt;/td&gt;
&lt;td&gt;12&lt;/td&gt;
&lt;td&gt;15&lt;/td&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;32&lt;/td&gt;
&lt;td&gt;66.6&lt;/td&gt;
&lt;td&gt;23&lt;/td&gt;
&lt;td&gt;29&lt;/td&gt;
&lt;td&gt;16&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;16&lt;/td&gt;
&lt;td&gt;16&lt;/td&gt;
&lt;td&gt;71.4&lt;/td&gt;
&lt;td&gt;12&lt;/td&gt;
&lt;td&gt;19&lt;/td&gt;
&lt;td&gt;13&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;16&lt;/td&gt;
&lt;td&gt;32&lt;/td&gt;
&lt;td&gt;74.4&lt;/td&gt;
&lt;td&gt;41&lt;/td&gt;
&lt;td&gt;48&lt;/td&gt;
&lt;td&gt;30&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;16&lt;/td&gt;
&lt;td&gt;64&lt;/td&gt;
&lt;td&gt;71.0&lt;/td&gt;
&lt;td&gt;39&lt;/td&gt;
&lt;td&gt;44&lt;/td&gt;
&lt;td&gt;26&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;32&lt;/td&gt;
&lt;td&gt;32&lt;/td&gt;
&lt;td&gt;76.4&lt;/td&gt;
&lt;td&gt;65&lt;/td&gt;
&lt;td&gt;50&lt;/td&gt;
&lt;td&gt;30&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;32&lt;/td&gt;
&lt;td&gt;64&lt;/td&gt;
&lt;td&gt;72.7&lt;/td&gt;
&lt;td&gt;78&lt;/td&gt;
&lt;td&gt;65&lt;/td&gt;
&lt;td&gt;30&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;32&lt;/td&gt;
&lt;td&gt;128&lt;/td&gt;
&lt;td&gt;75.8&lt;/td&gt;
&lt;td&gt;55&lt;/td&gt;
&lt;td&gt;53&lt;/td&gt;
&lt;td&gt;30&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;40&lt;/td&gt;
&lt;td&gt;40&lt;/td&gt;
&lt;td&gt;77.2&lt;/td&gt;
&lt;td&gt;40&lt;/td&gt;
&lt;td&gt;40&lt;/td&gt;
&lt;td&gt;26&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;40&lt;/td&gt;
&lt;td&gt;80&lt;/td&gt;
&lt;td&gt;69.2&lt;/td&gt;
&lt;td&gt;96&lt;/td&gt;
&lt;td&gt;30&lt;/td&gt;
&lt;td&gt;13&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;40&lt;/td&gt;
&lt;td&gt;128&lt;/td&gt;
&lt;td&gt;70.7&lt;/td&gt;
&lt;td&gt;96&lt;/td&gt;
&lt;td&gt;44&lt;/td&gt;
&lt;td&gt;18&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;40 * 4의 경우 160으로 iperf3의 최대 채널 수 128을 초과하기에 128로 낮춰서 테스트했음.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 630px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/0100103488be5f982ac89fb12a7ffac1/8ecb0/bandwidth.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 59.49367088607595%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAAA9hAAAPYQGoP6dpAAABrElEQVQoz42T6Y7bMAyEHR+SddhSZMlHY7SNt2iC7fs/3xSjVIt0gwL9QZCmlI8jkqlE1yHNCeu6YpmX7K/XK7Ztw77v2Zi7XC5YliUbvzfalwtCTDDWwg4DRudQtW2L48eB91/vuN1uuN/vOI4DVVVBSonT6ZSt6zrUdQ2tFb6/fUOIE9KS8PbzwHmaMKWItMwPoNEGfd+jaRoopSCEAPOM6YWQ2LYV3juEFBFizAVovZQQXQtrNWKcUDFpjMlqqKBACLfWQikNozWWZYKyFp0Q+S7PS9G6blA3DYZhQOW9z0kqfAbSzucpe617hGXOsPKKZ2CJx3FEFWPMsM9AKlNaQ4gOLniYYcjnnyEvwHmeM6w8mV7KPveNvfTBQZlHj4vyAmG7XoC8yB4Ow5gvhBAwxQlSdli3lNXVp/qfql6A/HBuxDxPcGeH/euO0Y8Y/Ih13z4G9N9AqtJaQ1sLodTj6ac67574MwRa6fFzTMhzPk+5bVo47xFSAv81rMICvMi4DIzbUGLnXC5MdSXmb9iuinSqJIwVeViWlnFefGPA4dH/vfDiY1i8y/g3HJgMglzMc6MAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;bandwidth&quot;
        title=&quot;bandwidth&quot;
        src=&quot;/static/0100103488be5f982ac89fb12a7ffac1/f058b/bandwidth.png&quot;
        srcset=&quot;/static/0100103488be5f982ac89fb12a7ffac1/c26ae/bandwidth.png 158w,
/static/0100103488be5f982ac89fb12a7ffac1/6bdcf/bandwidth.png 315w,
/static/0100103488be5f982ac89fb12a7ffac1/f058b/bandwidth.png 630w,
/static/0100103488be5f982ac89fb12a7ffac1/40601/bandwidth.png 945w,
/static/0100103488be5f982ac89fb12a7ffac1/8ecb0/bandwidth.png 989w&quot;
        sizes=&quot;(max-width: 630px) 100vw, 630px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 630px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/a4497b739e70f5e2011898ef9659dd81/1790f/cpu.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 66.45569620253164%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAYAAACpUE5eAAAACXBIWXMAAA9hAAAPYQGoP6dpAAAB/0lEQVQ4y3VS2Y7bMAy0ZeuWfF9x4jqHN9ugBfrW//+zKchNFu6ifRA4OjicoZgoqTAcRhyPR0zThMPhwMtai6qqMAwD+r7HOI4caV/XNYwx/MZ7D601YgwIISBJ0xTrcsL9fsflcsH5fMb1eoVSClmWIUkSXnuc5zlHypUyRyoyVEWAswYJXS7zhPvbG263G9Z1xbZtiDFyZSklE5AairQnTAUIh1jCWoPgLYyxSIQQGIYOy7Jgnme2ezqd+PG/VO2xyCWUsZDiwwG5YkKqSBuyQKroks4JU9zjV6LIMu7b3BQQgqwr7mtCZAT40TNxT0iY1v7cGA0fA4a6wLZMCEazaiakXr2S/mft60dM84TCO7RVgVDX6NoabVV+WCZW59ynAlK8/4gXNtZCa4Nx7DCNPUrv4ENgklxKzOOAMkYqmvw1IntVRMY4TRF9QF3SrHlURYWublCUAcPYQukcPmg49xybrwrpTIgMUmkuFpzF8dCh7ToUZYV1PaKqPbRR8M6jKAp0fcNDzoNNkomAVRFZmkLJHH1Tou8qTIcej8d3NE2FGC36JuwGXnDUUkMrTThF3zX4+diwXRY8thXvtxXb5Rt+//qBbVsxDC36voY1EkrJTzf7IaczcppQf5y1iMFDacWNpkuyaq1j5VS5aVr+FG7B8zPoHdkkYiIj8j+8gSKggGepfwAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;cpu&quot;
        title=&quot;cpu&quot;
        src=&quot;/static/a4497b739e70f5e2011898ef9659dd81/f058b/cpu.png&quot;
        srcset=&quot;/static/a4497b739e70f5e2011898ef9659dd81/c26ae/cpu.png 158w,
/static/a4497b739e70f5e2011898ef9659dd81/6bdcf/cpu.png 315w,
/static/a4497b739e70f5e2011898ef9659dd81/f058b/cpu.png 630w,
/static/a4497b739e70f5e2011898ef9659dd81/40601/cpu.png 945w,
/static/a4497b739e70f5e2011898ef9659dd81/1790f/cpu.png 1189w&quot;
        sizes=&quot;(max-width: 630px) 100vw, 630px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;h1 id=&quot;4-테스트-분석&quot; style=&quot;position:relative;&quot;&gt;4. 테스트 분석&lt;a href=&quot;#4-%ED%85%8C%EC%8A%A4%ED%8A%B8-%EB%B6%84%EC%84%9D&quot; aria-label=&quot;4 테스트 분석 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;그래프 분석
그래프는 각 Queue 및 iperf3 채널 수에 따른 대역폭과 CPU 사용량 변화를 보여준다.&lt;/p&gt;
&lt;p&gt;대역폭&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Queue 값이 증가할수록 대역폭이 증가하였으나, Queue가 16을 넘어서면 약 70~77Gbps 수준에서 포화 상태를 보인다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;특히 Queue 8에서 16채널(64.1Gbps)을 사용할 때 가장 효율적으로 대역폭이 증가하는 구간을 확인할 수 있다.&lt;/p&gt;
&lt;p&gt;CPU 사용량&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Proxmox와 VM의 CPU 사용률은 Queue 및 채널 수 증가와 함께 급격히 증가한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;특히 Queue 32 이상, 채널 수가 Queue의 2~4배인 경우 VM 및 Proxmox CPU 부하가 상당히 높아졌다.&lt;/p&gt;
&lt;p&gt;결과적으로 multiqueue를 너무 높이 설정하면 얻는 성능 증가 대비 CPU 자원 소모가 너무 높아진다.
특히 multiqueue가 8인 설정에서 좋은 성능과 적절한 CPU 자원 활용률을 보였다.&lt;/p&gt;
&lt;p&gt;나는 multiqueue를 조정해서 VM에 올린 TrueNAS와 proxmox간의 NFS연결에서 충분한 대역폭을 확보하고 싶었다. NFS의 마운팅 옵션에서 최대 16개의 커넥션을 설정할 수 있으므로 multiqueue를 8 ~ 16 정도로 설정하면 적당할 것 같다. 다음 글에서는 VM간의 실질적인 NFS 속도를 테스트해 보려고 한다.&lt;/p&gt;
&lt;p&gt;이 글이 Proxmox를 운영하거나 네트워크 성능을 최적화하려는 사용자들에게 좋은 참고 자료가 되길 바란다.&lt;/p&gt;
&lt;p&gt;잘못된 설명이나 추가로 설명했으면 좋겠는 부분, 오타, 맞춤법에 대한 지적은 언제나 환영합니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;이 글을 홈서버 사용자를 위한 것입니다. 틀린 내용이 있을 수 있고, 각자의 상황에 따라 데이터가 달라질 수 있습니다.&lt;/li&gt;
&lt;li&gt;이 글을 포함해 인터넷에 존재하는 코드, 스크립트를 복사해 사용할 때는 코드, 스크립트를 충분히 읽고, 분석하여 문제가 없는지 확인하시기를 바랍니다. 최소한 ChatGPT 같은 AI에 해당 코드, 스크립트가 정말 안전하고 사용해도 되는지 확인받으시길 권장합니다.&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[홈서버 2년간의 회고]]></title><description><![CDATA[시작 2022년 11월경부터 본격적으로 홈서버를 운영한 지 벌써…]]></description><link>https://vulcan.site/new-homeserver-01/</link><guid isPermaLink="false">https://vulcan.site/new-homeserver-01/</guid><pubDate>Sat, 15 Mar 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h1 id=&quot;시작&quot; style=&quot;position:relative;&quot;&gt;시작&lt;a href=&quot;#%EC%8B%9C%EC%9E%91&quot; aria-label=&quot;시작 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;2022년 11월경부터 본격적으로 홈서버를 운영한 지 벌써 2년하고도 반 정도가 지났다. 현재 홈서버의 구성에 대해서 살펴 보며 분석한 내용과 겪었던 실질적인 문제들을 바탕으로 새로운 서버 구성에 대한 큰 그림을 그려보고 지금까지의 경험을 정리해 보고자 한다.&lt;/p&gt;
&lt;h1 id=&quot;1-현재-구성과-문제점&quot; style=&quot;position:relative;&quot;&gt;1. 현재 구성과 문제점&lt;a href=&quot;#1-%ED%98%84%EC%9E%AC-%EA%B5%AC%EC%84%B1%EA%B3%BC-%EB%AC%B8%EC%A0%9C%EC%A0%90&quot; aria-label=&quot;1 현재 구성과 문제점 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;서버의 보다 자세한 구성에 대한 설명은 &lt;a href=&quot;https://bbconf.kr/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;bbconf&lt;/a&gt;에서 발표했던 &lt;a href=&quot;https://bbconfwebdav.vulcan.site/bbconf/2024-summer/%eb%b6%88%ec%b9%b8_%ed%99%88%ec%84%9c%eb%b2%84%201%eb%85%84%20%ec%82%ac%ec%9a%a9%ea%b8%b0%ec%99%80%20%ec%85%8b%ed%8c%85%ec%97%90%20%eb%8c%80%ed%95%b4%ec%84%9c.pdf&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;내용&lt;/a&gt;에 보다 자세히 적혀있다. 지금은 추가된 부분이 있지만 대략적인 부분은 큰 차이가 없다.&lt;/p&gt;
&lt;p&gt;현재의 구성은 아래와 같다.
&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 630px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/fdaeb382e683323cc3ad9d54055469c3/a86ac/server.webp&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 80.37974683544303%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/webp;base64,UklGRoIAAABXRUJQVlA4IHYAAADwAwCdASoUABAAPtFUo0uoJKMhsAgBABoJZQCsAB5wXMozuhE/5WzYAP7lqYu6CQ0LF1BaPTkgkN7FMkbzDtdcDCW2JY0YooyS9qG0avG5P840kAojNzzndwV69Y9DxVoTVYzXMQ1hL+5qdlmb7gYVZg0sEAAA&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;server&quot;
        title=&quot;server&quot;
        src=&quot;/static/fdaeb382e683323cc3ad9d54055469c3/8aab1/server.webp&quot;
        srcset=&quot;/static/fdaeb382e683323cc3ad9d54055469c3/81b7c/server.webp 158w,
/static/fdaeb382e683323cc3ad9d54055469c3/6ea66/server.webp 315w,
/static/fdaeb382e683323cc3ad9d54055469c3/8aab1/server.webp 630w,
/static/fdaeb382e683323cc3ad9d54055469c3/a70f5/server.webp 945w,
/static/fdaeb382e683323cc3ad9d54055469c3/4ef06/server.webp 1260w,
/static/fdaeb382e683323cc3ad9d54055469c3/a86ac/server.webp 3511w&quot;
        sizes=&quot;(max-width: 630px) 100vw, 630px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;
많은 VM, CT들을 운영하고 있는 메인 노드와 네트워킹, 모니터링, 관리 도구 등 운영에 꼭 필요하거나 서비스가 죽었을 때 치명적인 부분들을 담당하는 서브 노드 총 2개의 노드로 구성돼 있다. 이제부터 문제점을 하나씩 파악해 보자.&lt;/p&gt;
&lt;h2 id=&quot;11-단일-게이트웨이&quot; style=&quot;position:relative;&quot;&gt;1.1. 단일 게이트웨이&lt;a href=&quot;#11-%EB%8B%A8%EC%9D%BC-%EA%B2%8C%EC%9D%B4%ED%8A%B8%EC%9B%A8%EC%9D%B4&quot; aria-label=&quot;11 단일 게이트웨이 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;지금까지 가장 많은 문제를 일으킨 SPOF이다. 서버 전체의 게이트웨이, 방화벽, DNS, DHCP, reverse proxy, VLAN등 대부분의 네트워크를 pfsense가 담당하고 있다. 때문에 pfsense VM이나 해당 VM이 구동되는 서브 노드가 다운되면 외부에서 서버 전체에 대한 접근 방법이 없어지고, 내부에서도 인터넷에 접속이 불가능해진다. pfsense자체를 업데이트할 때도 다운타임이 발생하지만, 이는 비교적 짧다. 문제는 pfsense는 호스팅하고있는 하이퍼바이저인 proxmox를 업데이트할 때다. proxmox의 업데이트 이후 재부팅은 비교적 오래 걸리고, 매끄럽게 진행되지 않을 경우 다운타임은 무제한으로 길어진다. 때문에 이 문제를 해결해야 하는데, 방법은 두 가지가 있다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;pfsense의 HA 기능을 이용하는 것&lt;/li&gt;
&lt;li&gt;proxmox의 HA 기능을 이용하는 것&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;여기서 중요한 것은 두 방법 모두 2개 이상의 proxmox node가 필요하다는 것이다. pfsense의 HA 기능을 적절하게 활용하기 위해선 결국 서로 다른 proxmox node가 필요하고, 본격적인 proxmox HA 기능을 위해선 3개 이상의 node가 권장된다. 그럼 각각의 장단점에 대해서 살펴보자.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;pfsense의 HA 기능을 이용하는 것
&lt;ul&gt;
&lt;li&gt;장점
&lt;ul&gt;
&lt;li&gt;두 pfsense가 vrrp 패킷으로 서로의 생존을 확인하고 만약 active pfsense가 죽었을 때 standby pfsense가 바로 역할을 대신해서 다운타임을 최소화할 수 있다.&lt;/li&gt;
&lt;li&gt;대부분의 방화벽이나 게이트웨이가 이 방법을 사용한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;단점
&lt;ul&gt;
&lt;li&gt;2개의 공인 IP가 필요하다. 보통의 통신사의 정책에선 추가 비용을 내지 않으면 공인 IP는 1개가 원칙이다. 그리고 내가 아직은 알지 못하는 DDNS에 대한 지식이 필요할 수 있다.&lt;/li&gt;
&lt;li&gt;더블 NAT이 될 수 있다. 이는 구성의 불편함을 초래할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;proxmox의 HA 기능을 이용하는 것
&lt;ul&gt;
&lt;li&gt;장점
&lt;ul&gt;
&lt;li&gt;pfsense의 HA 기능을 이용할 때의 단점을 생각하지 않아도 된다.&lt;/li&gt;
&lt;li&gt;다른 VM에도 proxmox HA 기능을 적용할 예정이기에 추가로 pfsense HA에 대해서 신경 쓰지 않아도 된다.&lt;/li&gt;
&lt;li&gt;조사에 따르면 ceph 스토리지를 바탕으로 적절한 HA구성을 한다면 live migration을 proxmox에서 지원하기 때문에 이 방법도 다운타임이 거의 없다.(ping 기준 1~5 ping 정도가 드랍된다는 영상을 발견했다.)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;단점
&lt;ul&gt;
&lt;li&gt;pfsense를 업데이트할 경우에 발생하는 다운타임은 해결할 수 없다.&lt;/li&gt;
&lt;li&gt;proxmox HA 구성이 복잡하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;이미 proxmox에 ceph를 이용해 HA가 제대로 작동하는 3 node cluster를 구축할 계획을 세웠기 때문에 사실상 가장 큰 단점이 없는 셈이나 마찬가지다. 그리고 pfsense의 업데이트로 인한 다운타임은 경험상 1분 이내이다. 때문에 들어오는 WAN을 단순한 스위치에 연결하고 이걸 다시 3개의 노드에 연결해 준다. pfsense VM이 migration되면서 같은 MAC 주소를 유지하기 때문에 같은 공인 IP로 연결되게 된다. 때문에 proxmox의 HA 기능을 이용해 게이트웨이의 다운타임을 최소화하기로 결정했다. 1년에 2~4회 정도 업데이트를 진행한다고 생각하면 연간 다운타임을 5분 이하로 유지할 수 있을 것으로 기대한다.&lt;/p&gt;
&lt;p&gt;추가로 pfsense를 사용하면서 최신 드라이버에 대한 지원이 굉장히 느리다는걸 알았다. 최신 데비안 버전에도 올라간 드라이버가 이후에 진행된 pfsense의 업데이트에 포함되지 않는 경우도 있다. 때문에 비교적 업데이트가 빠른 opnsense로 migration하기로 결정했다.&lt;/p&gt;
&lt;h2 id=&quot;12-단일-스위치&quot; style=&quot;position:relative;&quot;&gt;1.2. 단일 스위치&lt;a href=&quot;#12-%EB%8B%A8%EC%9D%BC-%EC%8A%A4%EC%9C%84%EC%B9%98&quot; aria-label=&quot;12 단일 스위치 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;현재는 10Gbps 8port switch를 사용하고 있다. 네트워크 케이블을 재배치하거나, 스위치를 업데이트할 때 필연적으로 다운타임이 발생할 수밖에 없다. 이것을 해결하고자 mikrotik switch를 이용해 multi chassis link aggregation을 구성하고, 각 노드에서 backup bond를 하나 더 구성해 각 switch의 실패뿐만 아니라 특정 nic의 다운에도 대응할 수 있게 구성하려고 한다.&lt;/p&gt;
&lt;h2 id=&quot;13-모니터링-부족&quot; style=&quot;position:relative;&quot;&gt;1.3. 모니터링 부족&lt;a href=&quot;#13-%EB%AA%A8%EB%8B%88%ED%84%B0%EB%A7%81-%EB%B6%80%EC%A1%B1&quot; aria-label=&quot;13 모니터링 부족 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;기존의 grafana를 구성할 때 InfluxDB를 이용해 모든 메트릭 데이터를 여기로 통합하려했는데 잘 되지 않았다. 때문에 InfluxDB와 Prometheus와 병용하고, 서버 전체로 흩어져있는 로그 또한 수집해서 모니터링 할 수 있도록 loki를 이용해서 로그도 수집할 예정이다.&lt;/p&gt;
&lt;h2 id=&quot;14-서비스의-파편화&quot; style=&quot;position:relative;&quot;&gt;1.4. 서비스의 파편화&lt;a href=&quot;#14-%EC%84%9C%EB%B9%84%EC%8A%A4%EC%9D%98-%ED%8C%8C%ED%8E%B8%ED%99%94&quot; aria-label=&quot;14 서비스의 파편화 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://ansible.vulcan.site/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;ansible semaphore&lt;/a&gt;, &lt;a href=&quot;https://zitadel.vulcan.site/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;zitadel&lt;/a&gt;, &lt;a href=&quot;https://nextcloud.vulcan.site/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;nextcloud&lt;/a&gt;, &lt;a href=&quot;https://nextcloud.vulcan.site/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;netbird&lt;/a&gt;, &lt;a href=&quot;https://vulcan.site/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;blog&lt;/a&gt;, &lt;a href=&quot;https://immich.vulcan.site/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;immich&lt;/a&gt;, &lt;a href=&quot;https://grafana.vulcan.site/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;grafana&lt;/a&gt;, &lt;a href=&quot;https://plex.vulcan.site/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;plex&lt;/a&gt;, &lt;a href=&quot;https://ollama.vulcan.site/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;open web ui&lt;/a&gt;, pihole 등 많은 서비스들을 운영하고 있다. 하지만 일부는 stand alone, 일부는 docker compose로 여러 VM에 걸쳐 분리돼서 관리되고 있다. 이를 최대한 하나의 노드에서 docker compose를 이용해 관리하는 방식으로 migration하고, 가능하다면 RKE2로 쿠버네티스를 구성해서 쿠버 클러스토로 이전하는 게 목표이다.&lt;/p&gt;
&lt;h2 id=&quot;15-단일-전원&quot; style=&quot;position:relative;&quot;&gt;1.5. 단일 전원&lt;a href=&quot;#15-%EB%8B%A8%EC%9D%BC-%EC%A0%84%EC%9B%90&quot; aria-label=&quot;15 단일 전원 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;기존의 구성에서는 1개의 UPS에 모든 기기들이 연결돼 있었다. 이는 UPS가 실패하거나, PDU가 실패하거나, 각 케이블에 문제가 생겼을 때 전체 시스템을 죽일 수 있다. 그리고 기존의 납축전지를 이용한 UPS의 경우 2~3년마다 배터리를 교체해야 하고 매우 무겁고 비싸다. 하지만 최근에 ecoflow에서 river 3, delta 3 시리즈부터 10ms 이내의 전환 시간을 가진 UPS기준에 부합하는 파워뱅크를 출시했고, NUT최신버전에서 해당 기기에 대한 지원을 시작했다. 그래서 이 기기를 이용해 2개의 UPS를 구성하고, 포트별 on/off 조절이 가능한 PDU를 사용해서 강제 전원 on/off 기능도 추가할 예정이다.&lt;/p&gt;
&lt;h2 id=&quot;16-단일-wan&quot; style=&quot;position:relative;&quot;&gt;1.6. 단일 WAN&lt;a href=&quot;#16-%EB%8B%A8%EC%9D%BC-wan&quot; aria-label=&quot;16 단일 wan permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;단일 게이트웨이도 문제지만 WAN이 하나라는 건 치명적이다. 내가 외부에 있을 때 문제가 생기면 접근할 수 있는 수단이 전혀 없기 때문이다. 그리고 새로운 메인 노드는 mz32-ar0보드를 사용해 내장 BMC가 있고, 서브 노드로 구매 예정인 기기들도 Intel vpro 기능을 지원해서 BIOS레벨에 원격으로 접근이 가능하다. 하지만 여전히 네트워크는 필요하고, vpro나 BMC에 문제가 생겼을 경우 원격 접속이 불가능해진다. 때문에 pikvm을 이용해 모든 노드에 2가지 수단으로 BIOS레벨에 원격 접속이 가능하게 설정하고, 4G 모뎀을 이용해서 완전히 분리된 관리망을 구성할 예정이다.&lt;/p&gt;
&lt;h1 id=&quot;2-새로운-구성&quot; style=&quot;position:relative;&quot;&gt;2. 새로운 구성&lt;a href=&quot;#2-%EC%83%88%EB%A1%9C%EC%9A%B4-%EA%B5%AC%EC%84%B1&quot; aria-label=&quot;2 새로운 구성 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;아래와 같이 새로운 구성을 할 예정이다.
&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 630px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/a250cfaf0fb3612c77e6675a66827ef9/a7e3a/new_server.webp&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 33.54430379746836%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/webp;base64,UklGRnYAAABXRUJQVlA4IGoAAACQAwCdASoUAAcAPtFUo0uoJKMhsAgBABoJZwAAUiEmW0RLKmoAAP7veTa75i2GFaG15Gbkz+4IeAw7cVvi1eWiAkRkdz4T/bLHTlEctkcukvp4htMYWsl8DxilWe4fGCujyAJOQA41gAAA&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;new_server&quot;
        title=&quot;new_server&quot;
        src=&quot;/static/a250cfaf0fb3612c77e6675a66827ef9/8aab1/new_server.webp&quot;
        srcset=&quot;/static/a250cfaf0fb3612c77e6675a66827ef9/81b7c/new_server.webp 158w,
/static/a250cfaf0fb3612c77e6675a66827ef9/6ea66/new_server.webp 315w,
/static/a250cfaf0fb3612c77e6675a66827ef9/8aab1/new_server.webp 630w,
/static/a250cfaf0fb3612c77e6675a66827ef9/a70f5/new_server.webp 945w,
/static/a250cfaf0fb3612c77e6675a66827ef9/4ef06/new_server.webp 1260w,
/static/a250cfaf0fb3612c77e6675a66827ef9/a7e3a/new_server.webp 2305w&quot;
        sizes=&quot;(max-width: 630px) 100vw, 630px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;h2 id=&quot;21-네트워크&quot; style=&quot;position:relative;&quot;&gt;2.1. 네트워크&lt;a href=&quot;#21-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC&quot; aria-label=&quot;21 네트워크 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;맨 오른쪽은 메인 스토리지 서버이고 공유스토리지를 위한 NFS전용으로 40Gbps 2포트를 LAG해서 사용하고 10Gbps를 각각 2포트씩 LAG해서 한개는 대용량 스토리지 전용으로, 나머지는 LAN으로 사용한다. 3개의 서브 노드는 10Gbps 2포트를 LAG해서 사용하고 1개의 2.5Gbps는 백업 bond로 나머지 1개는 WAN으로 연결된다. 흰색으로 표시된 USB4 연결은 ceph 데이터 이동을 위한 ring network를 구성해 사용할 예정이다.&lt;/p&gt;
&lt;h2 id=&quot;22-스토리지&quot; style=&quot;position:relative;&quot;&gt;2.2. 스토리지&lt;a href=&quot;#22-%EC%8A%A4%ED%86%A0%EB%A6%AC%EC%A7%80&quot; aria-label=&quot;22 스토리지 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;모든 노드는 일반적인 nvme ssd 2장을 mirror구성으로 부트드라이브로 사용한다. 서브 노드의 경우 ceph와 VM을 위해 높은 iops를 확보하고 내구성을 위해 intel optane을 달아줄 예정이다. 메인 노드는 대용량 스토리지로 18TB 14장을 6장씩 RAIDZ2로 묶고 묶인 풀 2개를 stripe해서 사용하고 남는 2개는 hot spare로 사용할 예정이다. 이렇게 구성하면 14개 중 8개가 가용량이고 252TB중 144TB를 사용할 수 있다. 이 하드디스크 풀의 메타데이터용으로 역시 intel optane 2장을 mirror로 구성하고 이 optane 풀의 일부를 하드디스크 풀의 SLOG로 사용해 풀 내부의 ZIL을 둬서 속도가 저하되는 걸 방지한다. 그리고 공유스토리지용으로 micron 7450 MAX 4장을 stripe mirror로 구성해 속도와 안정성 모두 확보할 예정이다. 이 SSD 풀은 HDD 풀에 백업하고 HDD풀은 현재 사용 중인 메인 서버에 하이퍼백업을 해서 중요한 데이터의 경우 321백업 원칙을 지킬 수 있도록 했다.&lt;/p&gt;
&lt;h2 id=&quot;23-소프트웨어&quot; style=&quot;position:relative;&quot;&gt;2.3. 소프트웨어&lt;a href=&quot;#23-%EC%86%8C%ED%94%84%ED%8A%B8%EC%9B%A8%EC%96%B4&quot; aria-label=&quot;23 소프트웨어 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;하이퍼바이저로는 proxmox를 그대로 사용하고, grafana를 비롯해 기존에 사용하던 것들을 migration해줄 예정이다. pfsense의 경우 상기한 이유로 opnsense로 변경할 예정이고, 추가로 uptimekuma, speed tester등을 도입해서 업타임이나 인터넷 속도 등도 모니터링 할 예정이다.&lt;/p&gt;
&lt;h1 id=&quot;결론&quot; style=&quot;position:relative;&quot;&gt;결론&lt;a href=&quot;#%EA%B2%B0%EB%A1%A0&quot; aria-label=&quot;결론 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;2년 반 동안 현재의 서버에서 많은 서비스들을 운영해 보고 정말정말 많은 트러블슈팅을 하면서 많은 것을 배웠다. 이 지식을 바탕으로 더욱 발전된 홈서버를 설계하고 운영하면서 지금까지보다 더 많은 것을 배우고 성장할 수 있었으면 좋겠다. 그리고 새로운 서버를 구성하면서 지금까지 한번 했던 과정들을 반복하는 것들이 많다. 이것들을 튜토리얼로 정리해서 더 많은 사람이 홈서버에 쉽게 입문해서 같이 성장하고 재미를 느꼈으면 한다.&lt;/p&gt;
&lt;h1 id=&quot;운영중인-외부-서비스&quot; style=&quot;position:relative;&quot;&gt;운영중인 외부 서비스&lt;a href=&quot;#%EC%9A%B4%EC%98%81%EC%A4%91%EC%9D%B8-%EC%99%B8%EB%B6%80-%EC%84%9C%EB%B9%84%EC%8A%A4&quot; aria-label=&quot;운영중인 외부 서비스 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;지인이나 bbonf를 위해 구동되고 있는 서비스들의 목록&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://panty.run/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;https://panty.run/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://poptile.firekann.dev/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;https://poptile.firekann.dev/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://bbconfwebdav.vulcan.site/bbconf/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;https://bbconfwebdav.vulcan.site/bbconf/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://ramzida.com/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;http://ramzida.com/&lt;/a&gt;&lt;/p&gt;
&lt;h1 id=&quot;이사&quot; style=&quot;position:relative;&quot;&gt;이사&lt;a href=&quot;#%EC%9D%B4%EC%82%AC&quot; aria-label=&quot;이사 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;2월 초에 본가로 이사하면서 서버도 이사했다. 아래와 같은 배선을 모두 제거하고 이사해서 24시간 이내에 복구했다.&lt;/p&gt;
&lt;p&gt;이사 전
&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 630px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/32c2d6d6da74e479f3401e944d286b5c/aa596/before.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 139.24050632911394%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAcABQDASIAAhEBAxEB/8QAGAAAAwEBAAAAAAAAAAAAAAAAAAQFAgP/xAAWAQEBAQAAAAAAAAAAAAAAAAABAAL/2gAMAwEAAhADEAAAAes1hYtGTR3VaoZZhaG//8QAHRAAAgIDAAMAAAAAAAAAAAAAAQIDEQASEwQxMv/aAAgBAQABBQKR6U+S7YJDk3rpQ22MgtdLwQvQ+OMboI1A/8QAFBEBAAAAAAAAAAAAAAAAAAAAIP/aAAgBAwEBPwEf/8QAFREBAQAAAAAAAAAAAAAAAAAAASD/2gAIAQIBAT8BI//EAB8QAAIBBAIDAAAAAAAAAAAAAAABEQISIZExUXGBof/aAAgBAQAGPwIzGjhHsh0jfY3dGSbqNnH0XlkOnRHR/8QAHxAAAwEAAgEFAAAAAAAAAAAAAAERITFBUWFxocHw/9oACAEBAAE/IWPeW9r0IMsG19BblfkEqmOJ8QeFlWGHJ7+yLijxxIEVrppTTLGCglZbgU0WYVP/2gAMAwEAAgADAAAAECc4Qf/EABgRAAIDAAAAAAAAAAAAAAAAAAARARAh/9oACAEDAQE/EJpMw//EABcRAAMBAAAAAAAAAAAAAAAAAAABERD/2gAIAQIBAT8QxYVn/8QAHxABAAICAgIDAAAAAAAAAAAAAQARITFBYVGRgbHR/9oACAEBAAE/EDOs6WYswAFmCxiWg+AxJ2KDvGvucaFZM4fr3Bxeo8DiEQpwS76B7lBiJSNF9hHs5LQCe4E9uCgZuvJKhMGwuquIMQyLaJ//2Q==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;before&quot;
        title=&quot;before&quot;
        src=&quot;/static/32c2d6d6da74e479f3401e944d286b5c/828fb/before.jpg&quot;
        srcset=&quot;/static/32c2d6d6da74e479f3401e944d286b5c/ff44c/before.jpg 158w,
/static/32c2d6d6da74e479f3401e944d286b5c/a6688/before.jpg 315w,
/static/32c2d6d6da74e479f3401e944d286b5c/828fb/before.jpg 630w,
/static/32c2d6d6da74e479f3401e944d286b5c/0ede0/before.jpg 945w,
/static/32c2d6d6da74e479f3401e944d286b5c/3ac88/before.jpg 1260w,
/static/32c2d6d6da74e479f3401e944d286b5c/aa596/before.jpg 2589w&quot;
        sizes=&quot;(max-width: 630px) 100vw, 630px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;이사 후
&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 630px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/d19f68284393ff29a9f38297ed4ec4cc/158b9/after.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 263.9240506329114%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAA1ABQDASIAAhEBAxEB/8QAGQABAAMBAQAAAAAAAAAAAAAAAAIEBQMB/8QAFgEBAQEAAAAAAAAAAAAAAAAAAQAC/9oADAMBAAIQAxAAAAHhHh0rWGXF9jbS6mHDvUrSXHEOboCRA//EACAQAAICAgEFAQAAAAAAAAAAAAECAAMRITEEEhMiMkH/2gAIAQEAAQUCezJVyCBp+V9WU9w+iNMnCndXT5X9SVqcVjVagtl4GCwalZ8kbBb/xAAUEQEAAAAAAAAAAAAAAAAAAAAw/9oACAEDAQE/AQ//xAAUEQEAAAAAAAAAAAAAAAAAAAAw/9oACAECAQE/AQ//xAAfEAACAgEEAwAAAAAAAAAAAAAAARARIQISMUFRcYH/2gAIAQEABj8CfQsuoxFmIY/pp1WMfpi6HfkXIx7nUbXY7R//xAAdEAEAAgMBAQEBAAAAAAAAAAABABEhMUFhgVFx/9oACAEBAAE/IWGKL5G4TSli+ojP7nbozHyAzOJvMeBO0y5o3KvAj9J5qCcN8/kQOPg9ifBdBqXUqeJcRRcw+Cy+lRAIruvkbal09iAXS7HcOSGf/9oADAMBAAIAAwAAABBAHMD3B8P/xAAWEQADAAAAAAAAAAAAAAAAAAAAASD/2gAIAQMBAT8QtH//xAAZEQEBAQADAAAAAAAAAAAAAAAAAREQITH/2gAIAQIBAT8Q6xrzirKqv//EACMQAQEAAwABBAEFAAAAAAAAAAERACExQVFxocFhgZGx0fD/2gAIAQEAAT8QOMWHOhzRQaoW9cMCv5YoJaN+qt17WYIyMEm/Fx6KFSf7xMm+wgD0efx84IuhB9ZIU9w5wx1l+ETv9YlHIsb765tDYCLmmvfKmFp+4+sAEFqZ14tmWjmxTzRkUCBD0dX5wGg2JERQn6Y/z9niMNmO98oD9TNDtaVh8z27igRMHkJzP//Z&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;after&quot;
        title=&quot;after&quot;
        src=&quot;/static/d19f68284393ff29a9f38297ed4ec4cc/828fb/after.jpg&quot;
        srcset=&quot;/static/d19f68284393ff29a9f38297ed4ec4cc/ff44c/after.jpg 158w,
/static/d19f68284393ff29a9f38297ed4ec4cc/a6688/after.jpg 315w,
/static/d19f68284393ff29a9f38297ed4ec4cc/828fb/after.jpg 630w,
/static/d19f68284393ff29a9f38297ed4ec4cc/0ede0/after.jpg 945w,
/static/d19f68284393ff29a9f38297ed4ec4cc/3ac88/after.jpg 1260w,
/static/d19f68284393ff29a9f38297ed4ec4cc/158b9/after.jpg 1929w&quot;
        sizes=&quot;(max-width: 630px) 100vw, 630px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Terraform으로 proxmox에 VM 생성하기]]></title><description><![CDATA[시작 이전 글에서 Packer를 이용해서 proxmox에 ubuntu server Template를 만들어봤다. Template를 clone 해서 VM을 생성함으로서 편하게 설정이 완료된 VM…]]></description><link>https://vulcan.site/deploy-ubuntu-on-proxmox-with-terraform/</link><guid isPermaLink="false">https://vulcan.site/deploy-ubuntu-on-proxmox-with-terraform/</guid><pubDate>Tue, 11 Mar 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h1 id=&quot;시작&quot; style=&quot;position:relative;&quot;&gt;시작&lt;a href=&quot;#%EC%8B%9C%EC%9E%91&quot; aria-label=&quot;시작 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;&lt;a href=&quot;https://vulcan.site/build-ubuntu-image-for-proxmox-with-packer/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;이전 글&lt;/a&gt;에서 &lt;a href=&quot;https://www.hashicorp.com/products/packer&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Packer&lt;/a&gt;를 이용해서 &lt;a href=&quot;https://www.proxmox.com&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;proxmox&lt;/a&gt;에 ubuntu server &lt;a href=&quot;https://pve.proxmox.com/wiki/VM_Templates_and_Clones&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Template&lt;/a&gt;를 만들어봤다. Template를 clone 해서 VM을 생성함으로서 편하게 설정이 완료된 VM을 만들 수 있었다. 하지만 쿠버클러스터같이 같은 패키지를 설치한 비슷한 설정의 VM을 동시에 수십 혹은 수백 개를 생성해야 한다면, 이것을 모두 수동으로 clone하는 것은 쉽지 않을뿐더러 어리석은 짓이다. 그 때문에 이 글에서는 &lt;a href=&quot;https://www.hashicorp.com/products/terraform&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Terraform&lt;/a&gt;을 이용해서 k8s클러스터를 위한 VM 여러 개를 띄우는 과정을 자동화해 보겠다.&lt;/p&gt;
&lt;h1 id=&quot;1-terraform이란&quot; style=&quot;position:relative;&quot;&gt;1. Terraform이란?&lt;a href=&quot;#1-terraform%EC%9D%B4%EB%9E%80&quot; aria-label=&quot;1 terraform이란 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Terraform은 HashiCorp에서 개발한 인프라스트럭처를 코드로 관리(IaC, Infrastructure as Code)하는 도구다. 즉, 서버, 네트워크, 데이터베이스, 클라우드 리소스 등 다양한 인프라스트럭처를 선언적(configuration) 파일로 정의하고, 이를 기반으로 일관되고 자동화된 방식으로 배포, 수정, 삭제할 수 있다. Terraform은 이러한 특징들 덕분에 클라우드 인프라 운영 자동화와 관리의 복잡성을 크게 줄여준다.&lt;/p&gt;
&lt;h1 id=&quot;2-install-terraform&quot; style=&quot;position:relative;&quot;&gt;2. install Terraform&lt;a href=&quot;#2-install-terraform&quot; aria-label=&quot;2 install terraform permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;기본적으로 Terraform의 설정에 관한 문서는 &lt;a href=&quot;https://developer.hashicorp.com/terraform&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;여기&lt;/a&gt;에 아주 잘 정리돼 있다. ubuntu server noble에 설치할 거기 때문에 이 &lt;a href=&quot;https://developer.hashicorp.com/terraform/install#linux&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;튜토리얼&lt;/a&gt;을 따라 하자.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;wget -O - https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
echo &amp;quot;deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main&amp;quot; | sudo tee /etc/apt/sources.list.d/hashicorp.list
sudo apt update &amp;amp;&amp;amp; sudo apt install terraform&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;설치가 완료되고 &lt;code class=&quot;language-text&quot;&gt;terraform --version&lt;/code&gt;을 입력했을 때&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;~$ terraform --version
Terraform v1.10.5
on linux_amd64&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;이런 식으로 나온다면 설치가 완료된 것이다.&lt;/p&gt;
&lt;h1 id=&quot;3-directory-configuration&quot; style=&quot;position:relative;&quot;&gt;3. directory configuration&lt;a href=&quot;#3-directory-configuration&quot; aria-label=&quot;3 directory configuration permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Terraform을 이용해서 proxmox에 VM을 생성하기 위해서는 Terraform코드(&lt;code class=&quot;language-text&quot;&gt;vm-qemu-kube.tf&lt;/code&gt;)와 proxmox에 접속하기 위한 credentials를 저장할 파일(&lt;code class=&quot;language-text&quot;&gt;credentials.auto.tfvars&lt;/code&gt;)과 proxmox provider정보 파일(&lt;code class=&quot;language-text&quot;&gt;provider.tf&lt;/code&gt;)이 필요하다. 그리고 각 VM마다 다른 정보를 변수화해 저장하기 위한 파일(&lt;code class=&quot;language-text&quot;&gt;kube-cluster-config.auto.tfvars&lt;/code&gt;)이 필요하다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;css&quot;&gt;&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;terraform/
└── kube-cluster
    ├── credentials.auto.tfvars
    ├── kube-cluster-config.auto.tfvars
    ├── provider.tf
    └── vm-qemu-kube.tf&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&quot;4-file-configuration&quot; style=&quot;position:relative;&quot;&gt;4. file configuration&lt;a href=&quot;#4-file-configuration&quot; aria-label=&quot;4 file configuration permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;ubuntu server noble(24.04.x)를 기준으로 진행하겠다.&lt;/p&gt;
&lt;h2 id=&quot;41-providertf&quot; style=&quot;position:relative;&quot;&gt;4.1. provider.tf&lt;a href=&quot;#41-providertf&quot; aria-label=&quot;41 providertf permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Terraform이 proxmox와 상호작용 할 수 있도록 proxmox provider를 설정하는 파일이다. Terraform이 어떤 클라우드 서비스와 상호작용 해서 코드를 실행하기 위해선 클라우드 서비스 제공자(provider)에 대한 정보가 필요하다. 이 경우엔 proxmox가 클라우드 서비스 제공자이고, AWS, GCP 등 사용하는 클라우드 서비스에 따라 다를 수 있다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;terraform {
  required_version = &amp;quot;&amp;gt;= 0.13.0&amp;quot;

  required_providers {
    proxmox = {
      source = &amp;quot;telmate/proxmox&amp;quot;
      version = &amp;quot;3.0.1-rc6&amp;quot;
    }
  }
 }

variable &amp;quot;proxmox_api_url&amp;quot; {
  type = string
}

variable &amp;quot;proxmox_api_token_id&amp;quot; {
  type = string
  sensitive = true
}

variable &amp;quot;proxmox_api_token_secret&amp;quot; {
  type = string
  sensitive = true
}

variable &amp;quot;PUBLIC_SSH_KEY&amp;quot; {
  type = string
  sensitive = true
}

variable &amp;quot;USER&amp;quot; {
  type = string
}

variable &amp;quot;PASSWORD&amp;quot; {
  type = string
  sensitive = true
}

variable &amp;quot;vm_configs&amp;quot; {
  type = map(object({
    vmid = number
    ip   = string
    mac  = string
  }))
}

provider &amp;quot;proxmox&amp;quot; {
  pm_api_url          = var.proxmox_api_url
  pm_api_token_id     = var.proxmox_api_token_id
  pm_api_token_secret = var.proxmox_api_token_secret
  pm_tls_insecure     = true  #proxmox가 적절한 tls 인증서를 보유하고 있지 않을 경우 true로 해줘야한다.
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;proxmox_api_*&lt;/code&gt;변수들은 모두 proxmox에 접속하기 위한 값들이다. 이전에 &lt;a href=&quot;https://vulcan.site/build-ubuntu-image-for-proxmox-with-packer/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Packer글&lt;/a&gt;에서 사용했던 credentials과 유사하다.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;PUBLIC_SSH_KEY&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;USER&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;PASSWORD&lt;/code&gt;는 cloud-init을 통해 생성될 계정의 ssh key, username, password이다.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;vm_configs&lt;/code&gt;는 VM들을 생성할 때 각 VM마다 달라야 할 정보들을 변수로 지정하기 위함이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;42-credentialsautotfvars&quot; style=&quot;position:relative;&quot;&gt;4.2. credentials.auto.tfvars&lt;a href=&quot;#42-credentialsautotfvars&quot; aria-label=&quot;42 credentialsautotfvars permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;앞서 설명한 &lt;code class=&quot;language-text&quot;&gt;provider.tf&lt;/code&gt;에서 &lt;code class=&quot;language-text&quot;&gt;vm_configs&lt;/code&gt;을 제외한 변수의 값들을 저장하는 파일이다, 민감한 정보가 포함돼 있으니, 관리에 유의하도록 하자.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;proxmox_api_url             = &amp;quot;https://YOUR_PROXMOX_IP:8006/api2/json&amp;quot;
proxmox_api_token_id        = &amp;quot;YOUR_USERNAME@REALM_NAME!tokenid&amp;quot;
proxmox_api_token_secret    = &amp;quot;TOKEN_SECRET&amp;quot;
USER     = &amp;quot;YOUR_USERNAME&amp;quot;
PASSWORD = &amp;quot;YOUR_PASSWORD&amp;quot;
PUBLIC_SSH_KEY = &amp;quot;YOUR_SSH_KEY&amp;quot;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;43-kube-cluster-configautotfvars&quot; style=&quot;position:relative;&quot;&gt;4.3. kube-cluster-config.auto.tfvars&lt;a href=&quot;#43-kube-cluster-configautotfvars&quot; aria-label=&quot;43 kube cluster configautotfvars permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;여러 VM을 생성하면 vmid, VM이름, vmbr의 MAC주소, IP주소 등 달라야 하는 값들이 있다. 그리고 여러 개의 VM을 한 번에 생성하려면 &lt;code class=&quot;language-text&quot;&gt;vm-qemu-kube.tf&lt;/code&gt;을 이 값들을 바꿔가며 여러 번 실행해야 한다. 이런 방식은 매우 번거롭고 Packer나 Terraform과 같은 IaC툴의 장점인 일관성 유지에 좋지 않은 방법이다. 때문에 이것들도 변수로 만들어 관리하는게 좋다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;vm_configs = {
  control01 = {
    vmid = 811
    ip   = &amp;quot;ip=192.168.80.11/24,gw=192.168.80.1&amp;quot;
    mac  = &amp;quot;bc:24:11:00:08:11&amp;quot;
  },
  control02 = {
    vmid = 812
    ip   = &amp;quot;ip=192.168.80.12/24,gw=192.168.80.1&amp;quot;
    mac  = &amp;quot;bc:24:11:00:08:12&amp;quot;
  },
  control03 = {
    vmid = 813
    ip   = &amp;quot;ip=192.168.80.13/24,gw=192.168.80.1&amp;quot;
    mac  = &amp;quot;bc:24:11:00:08:13&amp;quot;
  },
  worker01 = {
    vmid = 831
    ip   = &amp;quot;ip=192.168.80.31/24,gw=192.168.80.1&amp;quot;
    mac  = &amp;quot;bc:24:11:00:08:31&amp;quot;
  },
  worker02 = {
    vmid = 832
    ip   = &amp;quot;ip=192.168.80.32/24,gw=192.168.80.1&amp;quot;
    mac  = &amp;quot;bc:24:11:00:08:32&amp;quot;
  },
  worker03 = {
    vmid = 833
    ip   = &amp;quot;ip=192.168.80.33/24,gw=192.168.80.1&amp;quot;
    mac  = &amp;quot;bc:24:11:00:08:33&amp;quot;
  },
  worker04 = {
    vmid = 834
    ip   = &amp;quot;ip=192.168.80.34/24,gw=192.168.80.1&amp;quot;
    mac  = &amp;quot;bc:24:11:00:08:34&amp;quot;
  },
  worker05 = {
    vmid = 835
    ip   = &amp;quot;ip=192.168.80.35/24,gw=192.168.80.1&amp;quot;
    mac  = &amp;quot;bc:24:11:00:08:35&amp;quot;
  },
  worker06 = {
    vmid = 836
    ip   = &amp;quot;ip=192.168.80.36/24,gw=192.168.80.1&amp;quot;
    mac  = &amp;quot;bc:24:11:00:08:36&amp;quot;
  }
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;나의 경우에는 kubernetes control plane 3개, worker node 6개 총 9개의 VM을 생성했다. 각각의 control01, control02, …, worker06은 VM의 이름이 되고, vmid, ip, mac주소를 지정해 줬다. 나는 pfsense 를 쓰고 있기 때문에 VLAN tag 80번에 192.168.80.0/24인 VLAN을 만들고, 192.168.80.1 ~ 192.168.80.100까지를 static IP대역으로 지정하고, 미리 static IP table에 IP와 MAC 주소를 맵핑해줬다. 사용하고 있는 라우터의 종류에 따라 미리 설정해줘야한다.&lt;/p&gt;
&lt;h2 id=&quot;44-vm-qemu-kubetf&quot; style=&quot;position:relative;&quot;&gt;4.4. vm-qemu-kube.tf&lt;a href=&quot;#44-vm-qemu-kubetf&quot; aria-label=&quot;44 vm qemu kubetf permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;여기서 사용되는 값들에 대한 상세는 &lt;a href=&quot;https://registry.terraform.io/providers/Terraform-for-Proxmox/proxmox/latest/docs/resources/vm_qemu&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;여기&lt;/a&gt;를 참고하자. 그리고 여기서 사용하는 대부분의 값들은 proxmox VM의 Hardware나 Option의 특정 값과 매칭되는 부분이 많으니 어떤 값으로 설정해야 할지 모르겠다면 기존에 사용하고 있던 VM의 값들을 참고하면 좋다.
&lt;code class=&quot;language-text&quot;&gt;vm-qemu-kube.tf&lt;/code&gt;는 qemu VM을 띄우기 위한 설정 파일이다. &lt;code class=&quot;language-text&quot;&gt;kube-cluster-config.auto.tfvars&lt;/code&gt;에 있는 &lt;code class=&quot;language-text&quot;&gt;vm_configs&lt;/code&gt;를 하나씩 순회하면서 반복 실행하기 위해 &lt;code class=&quot;language-text&quot;&gt;for_each&lt;/code&gt;를 이용했다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;resource &amp;quot;proxmox_vm_qemu&amp;quot; &amp;quot;kube&amp;quot; {

  for_each = var.vm_configs
  
  # -- General settings

  name        = each.key
  desc        = &amp;quot;kubernetes cluster&amp;quot;
  agent       = 1  # &amp;lt;-- (Optional) Enable QEMU Guest Agent
  target_node = &amp;quot;pve&amp;quot;  # &amp;lt;-- Change to the name of your Proxmox node (if you have multiple nodes)
  tags        = &amp;quot;ubuntu_noble,kubernetes&amp;quot;
  vmid        = each.value.vmid
  #pool        = &amp;quot;&amp;quot;

  # -- Template settings

  clone_id   = 800  # &amp;lt;-- Change to the name of the template or VM you want to clone
  full_clone = true  # &amp;lt;-- (Optional) Set to &amp;quot;false&amp;quot; to create a linked clone

  # -- Boot Process

  onboot           = true
  startup          = &amp;quot;&amp;quot;  # &amp;lt;-- (Optional) Change startup and shutdown behavior
  automatic_reboot = false  # &amp;lt;-- Automatically reboot the VM after config change

  # -- Hardware Settings

  #qemu_os  = &amp;quot;l26&amp;quot;
  #bios     = &amp;quot;ovmf&amp;quot;
  #machine  = &amp;quot;q35&amp;quot;
  cores    = 2
  sockets  = 1
  #cpu_type = &amp;quot;host&amp;quot;
  memory   = 4096
  balloon  = 0  # &amp;lt;-- (Optional) Minimum memory of the balloon device, set to 0 to disable ballooning
  numa     = false

  # -- Network Settings

  network {
    id       = 0  # &amp;lt;-- ! required since 3.x.x
    bridge   = &amp;quot;vmbr0&amp;quot;
    model    = &amp;quot;virtio&amp;quot;
    firewall = false
    tag      = 80
    macaddr  = each.value.mac
  }

  # -- Disk Settings
  
  scsihw = &amp;quot;virtio-scsi-single&amp;quot;  # &amp;lt;-- (Optional) Change the SCSI controller type, since Proxmox 7.3, virtio-scsi-single is the default one         
  
  disks {  # &amp;lt;-- ! changed in 3.x.x
    ide {
      ide0 {
        cloudinit {
          storage = &amp;quot;local-zfs&amp;quot;
        }
      }
    }
    virtio {
      virtio0 {
        disk {
          storage   = &amp;quot;local-zfs&amp;quot;
          size      = &amp;quot;20G&amp;quot;  # &amp;lt;-- Change the desired disk size, ! since 3.x.x size change will trigger a disk resize
          iothread  = true  # &amp;lt;-- (Optional) Enable IOThread for better disk performance in virtio-scsi-single
          replicate = false  # &amp;lt;-- (Optional) Enable for disk replication
        }
      }
    }
  }

  # -- Cloud Init Settings

  ipconfig0  = each.value.ip  # &amp;lt;-- Change to your desired IP configuration
  nameserver = &amp;quot;192.168.80.1&amp;quot;  # &amp;lt;-- Change to your desired DNS server
  ciuser     = var.USER
  cipassword = var.PASSWORD
  ciupgrade  = false
  sshkeys    = var.PUBLIC_SSH_KEY  # &amp;lt;-- (Optional) Change to your public SSH key
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;General settings
&lt;ul&gt;
&lt;li&gt;name        : VM의 이름이다. 여기서는 &lt;code class=&quot;language-text&quot;&gt;vm_configs&lt;/code&gt;의 key값을 사용한다.&lt;/li&gt;
&lt;li&gt;desc        : VM의 디스크립션이다.&lt;/li&gt;
&lt;li&gt;agent       : proxmox option의 QEMU Guest agent를 true로 할지 여부이다.&lt;/li&gt;
&lt;li&gt;target_node : 만약 proxmox cluster를 구성해서 proxmox node가 여러 개이면 target_node로 원하는 proxmox node의 이름을 적어준다&lt;/li&gt;
&lt;li&gt;tags        : proxmox의 tag를 지정해 준다. 여러 개 tag를 지정하려면 &lt;code class=&quot;language-text&quot;&gt;,&lt;/code&gt;로 구분해 준다.&lt;/li&gt;
&lt;li&gt;vmid        : 생성될 VM의 vmid이다. vmid는 유니크해야 한다. 여기서는 &lt;code class=&quot;language-text&quot;&gt;vm_configs&lt;/code&gt;의 value.vmid값을 사용한다.&lt;/li&gt;
&lt;li&gt;pool        : 해당 VM이 생성되길 원하는 pool이 있다면 그 이름을 적어준다. pool 구성을 한 기억이 없다면 생략해도 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Template settings
&lt;ul&gt;
&lt;li&gt;clone_id   : clone할 VM의 vmid이다. &lt;a href=&quot;https://vulcan.site/build-ubuntu-image-for-proxmox-with-packer/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;이전 글&lt;/a&gt;을 참고해 만든 Packer로 생성한 VM의 vmid를 적어준다.&lt;/li&gt;
&lt;li&gt;full_clone : proxmox에는 &lt;a href=&quot;https://pve.proxmox.com/wiki/VM_Templates_and_Clones&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;clone옵션&lt;/a&gt;이 full clone과 linked clone이 있다. 이 부분은 주의할 필요가 있다. proxmox cluster를 운영 중이라면 분명 migration기능을 이용했을 것이다. migration기능을 이용하려면 linked clone을 해서는 안 된다. linked clone을 하게되면 clone된 VM의 디스크가 원본 VM의 디스크 위치에 종속되기 때문에 별개로 다른 node로 이동이 불가능하다. 또한 원본 VM의 수정 또한 불가하다. 다만 linked clone은 full clone에 비해서 clone 속도가 굉장히 빠르고 디스크 소모 또한 적다. 때문에 테스트 용으로는 &lt;code class=&quot;language-text&quot;&gt;false&lt;/code&gt;로 해서 linked clone을 사용하고 실질적으로 배포해야 할 땐 full clone을 이용하기를 개인적으로 권장한다.(이 부분은 개인적인 경험을 바탕으로 작성됐다. 옳지 않은 부분이 있을 수 있다.)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Boot Process
&lt;ul&gt;
&lt;li&gt;onboot           : 생성하고 부팅할 건지 여부이다.&lt;/li&gt;
&lt;li&gt;startup          : &lt;a href=&quot;https://pve.proxmox.com/pve-docs/pve-admin-guide.html#pct_startup_and_shutdown&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;여길&lt;/a&gt; 참고하자.&lt;/li&gt;
&lt;li&gt;automatic_reboot : VM 설정에 변경이 생겼을 때 자동으로 reboot 해주는 기능. (e.g. cpu core 수 변경, 메모리 용량 변경 등)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Hardware Settings
&lt;ul&gt;
&lt;li&gt;qemu_os  : QEMU os type&lt;/li&gt;
&lt;li&gt;bios     : bios type&lt;/li&gt;
&lt;li&gt;machine  : machine type&lt;/li&gt;
&lt;li&gt;cores    : CPU 코어 수&lt;/li&gt;
&lt;li&gt;sockets  : CPU 소켓 수&lt;/li&gt;
&lt;li&gt;cpu_type : CPU type&lt;/li&gt;
&lt;li&gt;memory   : 메모리 용량(MiB)&lt;/li&gt;
&lt;li&gt;balloon  : 메모리 balloon 최소 용량. 0으로 하면 ballooning이 비활성화됨&lt;/li&gt;
&lt;li&gt;numa     : numa 활성화&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Network Settings
&lt;ul&gt;
&lt;li&gt;id       : &lt;a href=&quot;https://registry.terraform.io/providers/Terraform-for-Proxmox/proxmox/latest/docs/resources/vm_qemu#network-block&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;문서&lt;/a&gt;에는 불분명하게 적혀있으나 Network Device의 id(e.g. net0, net1, …)을 지정하는 것으로 보인다. 문서에는 순서에 따라 id가 정해진다고 돼 있으나 3.x.x버전 이후로 명시하도록 변경된 것 같다.&lt;/li&gt;
&lt;li&gt;bridge   : proxmox의 network bridge의 이름을 적어주면 된다. network bridge를 생성한 적이 없다면 기본으로 vmbr0가 있을 것이다.&lt;/li&gt;
&lt;li&gt;model    : 생성될 Network Device의 model을 입력한다. &lt;a href=&quot;https://registry.terraform.io/providers/Terraform-for-Proxmox/proxmox/latest/docs/resources/vm_qemu#network-block&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;문서&lt;/a&gt;를 참고하자.&lt;/li&gt;
&lt;li&gt;firewall : 방화벽 적용 여부이다. proxmox에서 방화벽을 설정하지 않고 pfsense나 opnsense같은 소프트웨어로 관리하고 있다면 false로 해도 문제없다.&lt;/li&gt;
&lt;li&gt;tag      : VLAN tag의 번호이다. VLAN을 사용하고 있지 않다면 &lt;code class=&quot;language-text&quot;&gt;-1&lt;/code&gt;로 하거나 주석 처리해 준다.&lt;/li&gt;
&lt;li&gt;macaddr  : Network Device의 MAC주소이다. 지정하지 않으면 랜덤으로 설정되기 때문에 static IP를 설정하기에 적절하지 않다. 사용하고 있는 DHCP서버에서 미리 static IP설정을 완료해 주고 설정한 MAC주소를 &lt;code class=&quot;language-text&quot;&gt;vm_configs&lt;/code&gt;의 mac에 적어준 다음 여기서 &lt;code class=&quot;language-text&quot;&gt;each.value.mac&lt;/code&gt;으로 불러와 준다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Disk Settings
&lt;ul&gt;
&lt;li&gt;scsihw : SCSI 컨트롤러 type을 지정해 준다.&lt;/li&gt;
&lt;li&gt;disks : 어떤 디스크 Bus/Device로 디스크를 생성해 줄 건지 정한다.(ide, sata, virtio, scsi)
&lt;ul&gt;
&lt;li&gt;ide0 : ide0으로 cloudinit을 위한 디스크를 생성해 준다.
&lt;ul&gt;
&lt;li&gt;storage : proxmox의 어떤 스토리지에 생성할지를 정한다. 생성할 스토리지는 proxmox storage content에서 Disk image를 포함해야 한다. 기본적으로는 local-zfs나 local-lvm이 있을 것이다. 처음에 zfs로 생성했다면 local-zfs를 ext4로 생성했다면 local-lvm을 사용하면 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;virtio0 : virtio0로 부팅할 디스크를 생성해 준다.
&lt;ul&gt;
&lt;li&gt;storage : 위의 ide0의 설명과 같다. 디스크가 생성되길 원하는 다른 storage가 있다면 해당 storage의 content를 확인하고, 해당 storage의 이름을 적어주면 된다.&lt;/li&gt;
&lt;li&gt;size : 생성될 디스크의 크기를 지정한다. &lt;code class=&quot;language-text&quot;&gt;regex \d+[GMK]&lt;/code&gt;를 따라서 원하는 용량으로 생성해 준다.&lt;/li&gt;
&lt;li&gt;iothread : IOThread 사용 여부이다. &lt;code class=&quot;language-text&quot;&gt;scsihw&lt;/code&gt;가 &lt;code class=&quot;language-text&quot;&gt;virtio-scsi-single&lt;/code&gt;이고, &lt;code class=&quot;language-text&quot;&gt;disks&lt;/code&gt;의 type이 &lt;code class=&quot;language-text&quot;&gt;virtio&lt;/code&gt;나 &lt;code class=&quot;language-text&quot;&gt;scsi&lt;/code&gt;일 때만 유효하다.&lt;/li&gt;
&lt;li&gt;replicate : replication 사용 여부이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Cloud Init Settings
&lt;ul&gt;
&lt;li&gt;ipconfig0  : 설정할 IP 주소이다. 위의 Network에서의 MAC주소와 같이 &lt;code class=&quot;language-text&quot;&gt;vm_configs&lt;/code&gt;의 &lt;code class=&quot;language-text&quot;&gt;each.value.ip&lt;/code&gt;로 불러와 준다.&lt;/li&gt;
&lt;li&gt;nameserver : 사용할 DNS 서버의 주소를 적으면 된다.&lt;/li&gt;
&lt;li&gt;ciuser     : 생성할 USER의 이름이다. var.USER로 &lt;code class=&quot;language-text&quot;&gt;credentials.auto.tfvars&lt;/code&gt;에서 설정한 USER를 불러와 준다.&lt;/li&gt;
&lt;li&gt;cipassword : 생성할 PASSWORD이다. var.USER로 &lt;code class=&quot;language-text&quot;&gt;credentials.auto.tfvars&lt;/code&gt;에서 설정한 PASSWORD를 불러와 준다.&lt;/li&gt;
&lt;li&gt;ciupgrade  : 부팅할 때 패키지 업그레이드를 할지 여부이다.(apt upgrade)&lt;/li&gt;
&lt;li&gt;sshkeys    : 생성할 PUBLIC_SSH_KEY이다. var.USER로 &lt;code class=&quot;language-text&quot;&gt;credentials.auto.tfvars&lt;/code&gt;에서 설정한 PUBLIC_SSH_KEY를 불러와 준다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;5-plan-and-apply&quot; style=&quot;position:relative;&quot;&gt;5. plan and apply&lt;a href=&quot;#5-plan-and-apply&quot; aria-label=&quot;5 plan and apply permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Terraform에선 Packer와 다르게 plan과 apply가 있다. plan은 현재 구성돼있는 인프라 구성과 적용할 구성을 비교해서 차이를 출력해 준다. apply는 현재 구성을 적용해 준다. 기본적으로 apply를 하기 전에 plan으로 변경되는 부분을 확인하는 편이 바람직하다. 먼저 &lt;code class=&quot;language-text&quot;&gt;terraform plan&lt;/code&gt;을 해준다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;~$ terraform plan
proxmox_vm_qemu.kube[&amp;quot;worker05&amp;quot;]: Refreshing state... [id=pve/qemu/835]
proxmox_vm_qemu.kube[&amp;quot;worker06&amp;quot;]: Refreshing state... [id=pve/qemu/836]
proxmox_vm_qemu.kube[&amp;quot;worker02&amp;quot;]: Refreshing state... [id=pve/qemu/832]
proxmox_vm_qemu.kube[&amp;quot;worker01&amp;quot;]: Refreshing state... [id=pve/qemu/831]
proxmox_vm_qemu.kube[&amp;quot;control02&amp;quot;]: Refreshing state... [id=pve/qemu/812]
proxmox_vm_qemu.kube[&amp;quot;worker03&amp;quot;]: Refreshing state... [id=pve/qemu/833]
proxmox_vm_qemu.kube[&amp;quot;worker04&amp;quot;]: Refreshing state... [id=pve/qemu/834]
proxmox_vm_qemu.kube[&amp;quot;control01&amp;quot;]: Refreshing state... [id=pve/qemu/811]
proxmox_vm_qemu.kube[&amp;quot;control03&amp;quot;]: Refreshing state... [id=pve/qemu/813]

No changes. Your infrastructure matches the configuration.

Terraform has compared your real infrastructure against your configuration and found no differences, so no changes are needed.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;한번 적용하고 다시 plan을 했다면 위와 같이 표시될 것이다. 처음이라면 변경되는 부분이 표시된다.&lt;/p&gt;
&lt;p&gt;이제 &lt;code class=&quot;language-text&quot;&gt;apply&lt;/code&gt;를 해보자.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;~$ terraform apply -auto-approve
proxmox_vm_qemu.kube[&amp;quot;worker03&amp;quot;]: Refreshing state... [id=pve/qemu/833]
proxmox_vm_qemu.kube[&amp;quot;worker01&amp;quot;]: Refreshing state... [id=pve/qemu/831]
proxmox_vm_qemu.kube[&amp;quot;worker04&amp;quot;]: Refreshing state... [id=pve/qemu/834]
proxmox_vm_qemu.kube[&amp;quot;control01&amp;quot;]: Refreshing state... [id=pve/qemu/811]
proxmox_vm_qemu.kube[&amp;quot;control03&amp;quot;]: Refreshing state... [id=pve/qemu/813]
proxmox_vm_qemu.kube[&amp;quot;worker06&amp;quot;]: Refreshing state... [id=pve/qemu/836]
proxmox_vm_qemu.kube[&amp;quot;control02&amp;quot;]: Refreshing state... [id=pve/qemu/812]
proxmox_vm_qemu.kube[&amp;quot;worker05&amp;quot;]: Refreshing state... [id=pve/qemu/835]
proxmox_vm_qemu.kube[&amp;quot;worker02&amp;quot;]: Refreshing state... [id=pve/qemu/832]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # proxmox_vm_qemu.kube[&amp;quot;control01&amp;quot;] will be created
  + resource &amp;quot;proxmox_vm_qemu&amp;quot; &amp;quot;kube&amp;quot; {
      + additional_wait        = 5
      + agent                  = 1
      + automatic_reboot       = false
      + balloon                = 0
      + bios                   = &amp;quot;seabios&amp;quot;
      + boot                   = (known after apply)
      + bootdisk               = (known after apply)
      + cipassword             = (sensitive value)
      + ciupgrade              = false
      + ciuser                 = &amp;quot;kube&amp;quot;
      + clone_id               = 800
      + clone_wait             = 10
      + cores                  = 2
      + cpu_type               = &amp;quot;host&amp;quot;
      + default_ipv4_address   = (known after apply)
      + default_ipv6_address   = (known after apply)
      + define_connection_info = true
      + desc                   = &amp;quot;kubernetes cluster&amp;quot;
      + force_create           = false
      + full_clone             = false
      + hotplug                = &amp;quot;network,disk,usb&amp;quot;
      + id                     = (known after apply)
      + ipconfig0              = &amp;quot;ip=192.168.80.11/24,gw=192.168.80.1&amp;quot;
...
proxmox_vm_qemu.kube[&amp;quot;worker01&amp;quot;]: Still creating... [2m20s elapsed]
proxmox_vm_qemu.kube[&amp;quot;worker01&amp;quot;]: Creation complete after 2m21s [id=pve/qemu/831]
proxmox_vm_qemu.kube[&amp;quot;worker05&amp;quot;]: Still creating... [2m30s elapsed]
proxmox_vm_qemu.kube[&amp;quot;worker03&amp;quot;]: Still creating... [2m30s elapsed]
proxmox_vm_qemu.kube[&amp;quot;worker05&amp;quot;]: Still creating... [2m40s elapsed]
proxmox_vm_qemu.kube[&amp;quot;worker03&amp;quot;]: Still creating... [2m40s elapsed]
proxmox_vm_qemu.kube[&amp;quot;worker03&amp;quot;]: Creation complete after 2m41s [id=pve/qemu/833]
proxmox_vm_qemu.kube[&amp;quot;worker05&amp;quot;]: Still creating... [2m50s elapsed]
proxmox_vm_qemu.kube[&amp;quot;worker05&amp;quot;]: Still creating... [3m0s elapsed]
proxmox_vm_qemu.kube[&amp;quot;worker05&amp;quot;]: Creation complete after 3m0s [id=pve/qemu/835]

Apply complete! Resources: 9 added, 0 changed, 0 destroyed.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;-auto-approve&lt;/code&gt;를 하면 자동으로 과정이 진행돼 위와 같이 끝날 것이다. 그냥 &lt;code class=&quot;language-text&quot;&gt;terraform apply&lt;/code&gt;를 하면 변경되는 부분을 보여주고, approve 할건지를 알려준다. approve 하게 되면 과정이 진행돼 똑같이 VM이 생성되면 종료된다. 나의 경우 linked clone으로 하면 3분 정도, full clone으로 하면 8분 30초 정도가 소요됐다. 사용하는 디스크의 속도에 따라 다를 수 있다.&lt;/p&gt;
&lt;h1 id=&quot;결론&quot; style=&quot;position:relative;&quot;&gt;결론&lt;a href=&quot;#%EA%B2%B0%EB%A1%A0&quot; aria-label=&quot;결론 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;&lt;a href=&quot;https://vulcan.site/build-ubuntu-image-for-proxmox-with-packer/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;이전 글&lt;/a&gt;에서 &lt;a href=&quot;https://www.hashicorp.com/products/packer&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Packer&lt;/a&gt;를 이용해 proxmox에 VM Template를 생성하는 방법에 대해서 다뤘다. 그리고 이번 글에서 Terraform으로 생성된 VM Template를 이용해 여러 개의 VM을 일관적으로 손쉽게 생성하고 관리하는 방법에 대해서 소개했다. 이 두 가지 IaC 도구를 사용해 proxmox에서 VM을 쉽게 생성하고 관리할 수 있고, 일관적이고 빠른 배포를 할 수 있게 됐다. proxmox를 사용하는 많은 사람들에게 도움이 됐으면 한다.&lt;/p&gt;
&lt;p&gt;다음 글에서는 생성된 VM에 ansible을 이용해 kubernetes cluster를 구성하고, kubernetes 대시보드를 생성하고, worker node를 추가, 제거할 수 있는 방법을 소개하려고 한다.&lt;/p&gt;
&lt;p&gt;잘못된 설명이나 추가로 설명했으면 좋겠는 부분, 오타, 맞춤법에 대한 지적은 언제나 환영합니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;이 글을 홈서버 사용자를 위한 것입니다. 실제 환경에서 사용할 때는 credential을 Vault나 환경 변수 등으로 좀 더 엄격하게 관리하시기를 바랍니다.&lt;/li&gt;
&lt;li&gt;이 글을 포함해 인터넷에 존재하는 코드, 스크립트를 복사해 사용할 때는 코드, 스크립트를 충분히 읽고, 분석하여 문제가 없는지 확인하시기를 바랍니다. 최소한 ChatGPT 같은 AI에 해당 코드, 스크립트가 정말 안전하고 사용해도 되는지 확인받으시길 권장합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;참고&quot; style=&quot;position:relative;&quot;&gt;참고&lt;a href=&quot;#%EC%B0%B8%EA%B3%A0&quot; aria-label=&quot;참고 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/ChristianLempa&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;ChristianLempa&lt;/a&gt; github/boilerplates&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/ChristianLempa/boilerplates/tree/main/terraform/proxmox&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;https://github.com/ChristianLempa/boilerplates/tree/main/terraform/proxmox&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://developer.hashicorp.com/terraform&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;HashiCorp Terraform&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://registry.terraform.io/providers/Terraform-for-Proxmox/proxmox/latest/docs&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;https://registry.terraform.io/providers/Terraform-for-Proxmox/proxmox/latest/docs&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Packer로 proxmox에 VM 이미지 생성하기]]></title><description><![CDATA[시작 proxmox를 벌써 3년 정도 사용하면서 많은 vm을 생성하고 삭제했다. 하지만 매번 vm을 생성할 때마다 같은 설정들을 반복했다는 걸 느꼈다. ssh key를 넣어주고, apt 저장소를 kakao mirror로 바꾸고, 필요할 경우 고정 ip…]]></description><link>https://vulcan.site/build-ubuntu-image-for-proxmox-with-packer/</link><guid isPermaLink="false">https://vulcan.site/build-ubuntu-image-for-proxmox-with-packer/</guid><pubDate>Tue, 18 Feb 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h1 id=&quot;시작&quot; style=&quot;position:relative;&quot;&gt;시작&lt;a href=&quot;#%EC%8B%9C%EC%9E%91&quot; aria-label=&quot;시작 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;proxmox를 벌써 3년 정도 사용하면서 많은 vm을 생성하고 삭제했다. 하지만 매번 vm을 생성할 때마다 같은 설정들을 반복했다는 걸 느꼈다. ssh key를 넣어주고, apt 저장소를 kakao mirror로 바꾸고, 필요할 경우 고정 ip를 할당하는 등의 것들이다. 하지만, 이 세팅들을 매번 하는 것도 질렸고, 무엇보다 이번에 k8s 클러스터를 구축하면서 동일한 설정과 동일한 패키지를 가지는 여러 vm을 생성해야 했다. 1n 개 이상의 vm을 이런 식으로, 수동으로 설정하는 것은 바보 같은 짓이라는 생각이 들었다.&lt;/p&gt;
&lt;p&gt;물론 &lt;a href=&quot;https://www.proxmox.com&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;proxmox&lt;/a&gt;에도 &lt;a href=&quot;https://pve.proxmox.com/wiki/VM_Templates_and_Clones&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Template&lt;/a&gt;라는 기능이 존재한다. Packer도 결과적으로 Template를 만드는 것이지만, proxmox만으로 이것을 하려면 직접 VM을 설치하고 세팅하여 이후에 이것을 Template으로 전환해야 하고, 만약 실수한다면 이 고정을 다시 해야 한다. 그 때문에 IaC도구의 힘을 빌리기로 했다. &lt;a href=&quot;https://www.hashicorp.com&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;HashiCorp&lt;/a&gt;의 &lt;a href=&quot;https://www.hashicorp.com/products/packer&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Packer&lt;/a&gt;와 &lt;a href=&quot;https://www.hashicorp.com/products/terraform&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Terraform&lt;/a&gt;, 그리고 &lt;a href=&quot;https://github.com/ansible/ansible&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Ansible&lt;/a&gt;을 사용하여 이 과정을 자동화하고자 한다. 이 글을 그 과정 중 첫 번째인 Packer에 대해서 간단하게 설명하고, proxmox에서 Packer로 기본적인 설정이 완료된 ubuntu 24.04, 22.04이미지를 만들어보고자 한다.&lt;/p&gt;
&lt;h1 id=&quot;1-packer란&quot; style=&quot;position:relative;&quot;&gt;1. Packer란?&lt;a href=&quot;#1-packer%EB%9E%80&quot; aria-label=&quot;1 packer란 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Packer는 이미지 빌드를 자동화해 주는 오픈소스 소프트웨어이다. 서버나 가상머신, 클라우드 인스턴스와 같은 환경에서 일관되고, 반복적인 배포를 할 때 유용하다. Template를 이용해서 항상 같은 이미지를 빌드하기 때문에 개발, 테스트, 프로덕션 환경을 일관적으로 유지할 수 있다. 또한 반복적인 작업을 줄일 수 있다. 만약 각 vm에 k8s 관련 패키지를 Ansible로 설치한다고 생각하면, 각 VM에 SSH로 접속해서 설치 스크립트를 실행할 것이고, 더 높은 네트워크 사용과 미리 설치해 둔 패키지를 설치하는 것보다는 당연히 클러스터의 배포가 느려질 것이다.&lt;/p&gt;
&lt;p&gt;이처럼 Packer는 DevOps 파이프라인의 가장 앞에서 가장 필수적이고 공통적인 패키지를 포함한 이미지를 미리 만들어둠으로써 배포 시간을 줄이고, 일관성을 유지할 수 있게 해준다. 이는 홈서버를 운영하는 입장에서도 매우 편리하다. 앞서 말한 ssh key, kakao mirror etc…들을 매번 세팅하는 건 매우 귀찮은 일이다. 특히 지인들과 서버를 공유하고 있다면 더욱 귀찮은 일이다. 이제 이 귀찮음을 해결해 보자.&lt;/p&gt;
&lt;h1 id=&quot;2-install-packer&quot; style=&quot;position:relative;&quot;&gt;2. install Packer&lt;a href=&quot;#2-install-packer&quot; aria-label=&quot;2 install packer permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;기본적으로 Packer의 설정에 관한 문서는 &lt;a href=&quot;https://developer.hashicorp.com/packer&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;여기&lt;/a&gt;에 아주 잘 정리돼 있다. ubuntu server noble에 설치할 거기 때문에 이 &lt;a href=&quot;https://developer.hashicorp.com/packer/install#linux&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;튜토리얼&lt;/a&gt;을 따라 하자.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;wget -O - https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
echo &amp;quot;deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main&amp;quot; | sudo tee /etc/apt/sources.list.d/hashicorp.list
sudo apt update &amp;amp;&amp;amp; sudo apt install packer&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;설치가 완료되고 &lt;code class=&quot;language-text&quot;&gt;packer --version&lt;/code&gt;을 입력했을 때&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;~$ packer --version
Packer v1.12.0&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;이런 식으로 나온다면 설치가 완료된 것이다.&lt;/p&gt;
&lt;h1 id=&quot;3-directory-configuration&quot; style=&quot;position:relative;&quot;&gt;3. directory configuration&lt;a href=&quot;#3-directory-configuration&quot; aria-label=&quot;3 directory configuration permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Packer를 이용해서 proxmox를 빌드하기 위해서는 packer Template에 사용될 폴더와 proxmox에 접속하기 위한 credentials를 저장할 파일이 필요하다. 그리고 이미지를 생성할 템플릿, ssh user의 credentials 파일, 설치 시 전달한 user data가 필요하다. 때문에 아래와 같이 폴더를 구성해서 jammy와 noble을 위한 Template를 작성할 것이다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;css&quot;&gt;&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;packer/
├── credentials.pkr.hcl
├── ubuntu-server-jammy
│   ├── files
│   │   └── 99-pve.cfg
│   ├── http
│   │   ├── meta-data
│   │   └── user-data
│   ├── run-packer.sh
│   ├── ssh-user-credentials.pkr.hcl
│   └── ubuntu-server-jammy.pkr.hcl
└── ubuntu-server-noble
    ├── files
    │   └── 99-pve.cfg
    ├── http
    │   ├── meta-data
    │   └── user-data
    ├── run-packer.sh
    ├── ssh-user-credentials.pkr.hcl
    └── ubuntu-server-noble.pkr.hcl&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;run-packer.sh&lt;/code&gt;는 validate와 build를 편하게 하기 위해서 작성했다.&lt;/p&gt;
&lt;h1 id=&quot;4-file-configuration&quot; style=&quot;position:relative;&quot;&gt;4. file configuration&lt;a href=&quot;#4-file-configuration&quot; aria-label=&quot;4 file configuration permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;ubuntu server noble(24.04.x)를 기준으로 진행하겠다.&lt;/p&gt;
&lt;h2 id=&quot;41-credentialspkrhcl&quot; style=&quot;position:relative;&quot;&gt;4.1. credentials.pkr.hcl&lt;a href=&quot;#41-credentialspkrhcl&quot; aria-label=&quot;41 credentialspkrhcl permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Packer가 proxmox에서 VM을 생성하고, 설정값을 입력하고, 이것을 template로 바꾸기 위해서는 어떤 방법으로든 proxmox의 쉘에 접속할 수밖에 없다. 이를 위해서 proxmox의 api_url, username과 password 혹은 token이 필요하다.(passward나 token 중 하나만 있어도 된다.) 이는 모든 template 파일에 포함돼야 하는데, 편의를 위해서 root 권한을 그대로 사용한다. 그 때문에 credentials 파일에서 username, password, token, api_url을 변수로 저장하고, 일관적으로 관리하려고 한다.(Packer를 위한 proxmox의 권한에 관련된 문서는 찾지 못했지만, 권한과 관련된 보안 이슈를 해결할 만한 솔루션을 발견했다. 해당 &lt;a href=&quot;https://github.com/hashicorp/packer-plugin-proxmox/issues/184&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;이슈&lt;/a&gt;에 따라 pool, group, user를 생성하고 적절히 권한을 주고 Packer가 proxmox Template를 완전히 생성한 뒤 root 권한으로 원하는 pool로 생성된 Template를 이동시키면 될 듯하다.) 아래와같이 &lt;code class=&quot;language-text&quot;&gt;credentials&lt;/code&gt; 파일을 작성해 준다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;# proxmox API credentials
proxmox_api_url             = &amp;quot;https://YOUR_PROXMOX_IP:8006/api2/json&amp;quot;
proxmox_api_token_id        = &amp;quot;YOUR_USERNAME@REALM_NAME!tokenid&amp;quot;
#token을 사용할거면 !tokenid를 뒤에 붙여줘야함 e.g. root@pam!packer
proxmox_api_password        = &amp;quot;YOUR_PASSWORD&amp;quot;   #token을 사용할거면 비워도도 됨
proxmox_api_token_secret    = &amp;quot;TOKEN_SECRET&amp;quot;    #password를 사용할거면 비워도도 됨&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;되도록 &lt;code class=&quot;language-text&quot;&gt;token&lt;/code&gt;을 사용하도록 하자.&lt;/p&gt;
&lt;h2 id=&quot;42-ssh-user-credentialspkrhcl&quot; style=&quot;position:relative;&quot;&gt;4.2. ssh-user-credentials.pkr.hcl&lt;a href=&quot;#42-ssh-user-credentialspkrhcl&quot; aria-label=&quot;42 ssh user credentialspkrhcl permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Packer가 VM을 생성하고, 이후에 VM에 접속해서 provisioner로 필요한 패키지를 설치하기 위해서는 해당 VM에 ssh로 접속해야 한다. 이를 위해서 &lt;code class=&quot;language-text&quot;&gt;user-data&lt;/code&gt;에 입력한 user와 동일한 데이터가 필요하다. 이 값도 예제 아래에 작성한 이유로 Template에서 유일하게 자주 변경해야 할 수도 있기 때문에 변수로 분리했다. 아래와같이 &lt;code class=&quot;language-text&quot;&gt;ssh-user-credentials&lt;/code&gt; 파일을 작성해 준다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;# ssh credentials
ssh_username                = &amp;quot;YOUR_USERNAME&amp;quot;   #e.g. packer
ssh_password                = &amp;quot;YOUR_PASSWORD&amp;quot;   #ssh key를 사용한다면 비워도도 됨
ssh_private_key_file_path   = &amp;quot;YOUR_PRIVATE_SSH_KEY_PATH&amp;quot;   #Packer가 설치돼있는 host의 path임 e.g. ~/.ssh/packer&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;이때 빌드를 위한 packer user와 ssh key를 입력해 두고, 나중에 Terraform 등을 이용해서 지워도 된다. 하지만 많은 VM을 생성하지 않을 때는 수동으로 clone 하므로, 이 user가 거슬릴 수 있다. 예제에서는 packer라는 user로 진행했지만, 이를 자주 사용하는 user와 ssh key로 변경해도 된다.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://developer.hashicorp.com/packer/integrations/hashicorp/proxmox/latest/components/builder/iso&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;문서&lt;/a&gt;대로라면 &lt;code class=&quot;language-text&quot;&gt;ssh_password&lt;/code&gt;를 이용해서도 접속할 수 있어야 하지만 나의 경우 오직 ssh key로만 접속할 수 있었다.&lt;/p&gt;
&lt;h2 id=&quot;43-user-data&quot; style=&quot;position:relative;&quot;&gt;4.3. user-data&lt;a href=&quot;#43-user-data&quot; aria-label=&quot;43 user data permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;이 &lt;code class=&quot;language-text&quot;&gt;user-data&lt;/code&gt;에 관해서 설명하려면 먼저 cloud-init에 대해서 알아야 한다. cloud-init은 VM 혹은 클라우드 인스턴스의 초부팅 시 사용자 지정 스크립트/환경 설정을 자동 적용해 주는 툴이다. proxmox에도 cloud-init을 설정해서 부팅 시 적용할 수 있는 옵션이 있다. 하지만 Packer는 이 방식을 사용하지 않고, 직접 임시로 HTTP 서버를 구동한다. 그리고 아래에서 작성할 template 코드에서 부팅시 옵션을 입력하는데, 이것이 Packer가 임시로 구동한 HTTP 서버에 접속해 &lt;code class=&quot;language-text&quot;&gt;user-data&lt;/code&gt;와 &lt;code class=&quot;language-text&quot;&gt;meta-data&lt;/code&gt;를 가져온다. 여기서는 http 폴더 아래에 있는 두 파일이 된다. 이 과정을 거치면서 VM은 설치 시에 &lt;code class=&quot;language-text&quot;&gt;user-data&lt;/code&gt;에 기술된 user를 생성하게 되고, 이후에 부팅했을 때 ssh로 접속하는 것이다. 위에서 작성한 &lt;code class=&quot;language-text&quot;&gt;ssh-user-credentials&lt;/code&gt;로 ssh 접속을 시도하기 때문에 대응하는 값으로 &lt;code class=&quot;language-text&quot;&gt;user-data&lt;/code&gt;파일을 작성해 준다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;json&quot;&gt;&lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;#cloud-config
autoinstall&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;
  version&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
  locale&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; en_US
  keyboard&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;
    layout&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; us
  ssh&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;
    install-server&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
    allow-pw&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
    disable_root&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
    ssh_quiet_keygen&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
    allow_public_ssh_keys&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
  packages&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;
    - qemu-guest-agent
    - sudo
  storage&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;
    layout&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;
      name&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; direct
    swap&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;
      size&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
  user-data&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;
    package_upgrade&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;
    timezone&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Asia/Seoul
    users&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;
      - name&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; YOUR_USERNAME
        groups&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;adm&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; sudo&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
        lock-passwd&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;
        sudo&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ALL=(ALL) NOPASSWD&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;ALL
        shell&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; /bin/bash
        #passwd&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; YOUR_PASSWORD
        # - or -
        ssh_authorized_keys&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;
          - YOUR_SSH_PUBLIC_KEY&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;위에서 작성한 &lt;code class=&quot;language-text&quot;&gt;ssh-user-credentials&lt;/code&gt;의 &lt;code class=&quot;language-text&quot;&gt;YOUR_USERNAME&lt;/code&gt;과 같은 username을 적어주고, &lt;code class=&quot;language-text&quot;&gt;YOUR_PRIVATE_SSH_KEY_PATH&lt;/code&gt;에 대응하는 public key를 적어주면 된다. 부팅하면서 최신 패키지를 적용하고 싶다면 &lt;code class=&quot;language-text&quot;&gt;package_upgrade&lt;/code&gt;를 true로 바꿔주면 된다.&lt;/p&gt;
&lt;h2 id=&quot;44-ubuntu-server-noblepkrhcl&quot; style=&quot;position:relative;&quot;&gt;4.4. ubuntu-server-noble.pkr.hcl&lt;a href=&quot;#44-ubuntu-server-noblepkrhcl&quot; aria-label=&quot;44 ubuntu server noblepkrhcl permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;가장 핵심이 되는 template 파일이다. proxmox에서 VM을 실행하고 빌드하고 템플릿으로 바꿔주는 파일이다. 파일에서 사용한 값에 대한 상세나, 추가 값들은 &lt;a href=&quot;https://developer.hashicorp.com/packer/integrations/hashicorp/proxmox/latest/components/builder/iso&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;여기&lt;/a&gt;에서 확인하면된다. 이 파일은 상당히 길기 때문에 나눠서 진행하겠다.&lt;/p&gt;
&lt;h3 id=&quot;441-variable-정의&quot; style=&quot;position:relative;&quot;&gt;4.4.1. Variable 정의&lt;a href=&quot;#441-variable-%EC%A0%95%EC%9D%98&quot; aria-label=&quot;441 variable 정의 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;앞서 작성한 &lt;code class=&quot;language-text&quot;&gt;credentials&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;ssh-user-credentials&lt;/code&gt; 두 파일에서 작성한 variable들에 대한 정의를 해줘야 한다. 각 type은 &lt;a href=&quot;https://developer.hashicorp.com/packer/integrations/hashicorp/proxmox/latest/components/builder/iso&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;여기&lt;/a&gt;에 적혀있는 type에 따라서 작성하면 된다. password는 사용하지 않는다면 이 부분과 아래에서 이 변수를 사용하는 부분 모두를 지워줘도 된다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;json&quot;&gt;&lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;# Variable Definitions
variable &lt;span class=&quot;token string&quot;&gt;&quot;proxmox_api_url&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    type = string
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
variable &lt;span class=&quot;token string&quot;&gt;&quot;proxmox_api_token_id&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    type = string
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
variable &lt;span class=&quot;token string&quot;&gt;&quot;proxmox_api_password&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    type = string
    sensitive = &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
variable &lt;span class=&quot;token string&quot;&gt;&quot;proxmox_api_token_secret&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    type = string
    sensitive = &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
variable &lt;span class=&quot;token string&quot;&gt;&quot;ssh_username&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    type = string
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
variable &lt;span class=&quot;token string&quot;&gt;&quot;ssh_password&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    type = string
    sensitive = &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
variable &lt;span class=&quot;token string&quot;&gt;&quot;ssh_private_key_file_path&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    type = string
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;442-resource-정의&quot; style=&quot;position:relative;&quot;&gt;4.4.2. Resource 정의&lt;a href=&quot;#442-resource-%EC%A0%95%EC%9D%98&quot; aria-label=&quot;442 resource 정의 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;여기서 사용되는 값들에 대한 상세는 다시 말하지만 &lt;a href=&quot;https://developer.hashicorp.com/packer/integrations/hashicorp/proxmox/latest/components/builder/iso&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;여기&lt;/a&gt;를 참고하자.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;source&lt;/code&gt;의 &lt;code class=&quot;language-text&quot;&gt;proxmox-iso&lt;/code&gt;는 type이기 때문에 그대로 작성해야 한다.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;Proxmox Connection Settings&lt;/code&gt;는 앞에 서술했듯이 proxmox에 접속해서 VM을 생성하고 설치 과정을 진행하기 위해서 선언해야 하는 값이다.
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;insecure_skip_tls_verify&lt;/code&gt;의 경우 valid한 TLS인증서가 달려있는 &lt;code class=&quot;language-text&quot;&gt;proxmox_url&lt;/code&gt;를 사용한다면 생략해도 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;ssh Settings&lt;/code&gt;는 생성된 VM에 접속해서 빌드 과정을 진행하기 위해서 ssh 접속을 위해서 선언해야 하는 값이다.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;VM General Settings&lt;/code&gt;는 VM을 생성할 때 사용되는 기본적인 값이다.
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;node&lt;/code&gt;의 경우 클러스터 구성이 아니라면 지정해 줄 필요는 없다.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;bios&lt;/code&gt;값의 경우 default는 seabios이다. 그런데 이 값을 ovmf로 할 경우 efi_config로 efi disk를 지정해 줘야 하는데, 이 경우 &lt;a href=&quot;https://bugzilla.proxmox.com/show_bug.cgi?id=3227&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;proxmox에서 live migration을 진행할 수 없게 되니&lt;/a&gt; 주의해야한다.(이 &lt;a href=&quot;https://forum.proxmox.com/threads/why-cant-proxmox-live-migrate-an-efi-disk.152941/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;스레드&lt;/a&gt;를 보면 해당 이슈가 아직도 존재하는것으로 보이고, 실제로 나도 실패했다.)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;VM OS Settings&lt;/code&gt;는 proxmox에서 OS가 저장된 저장소의 위치를 정의한다. 추가적인 디스크를 추가하지 않았다면 아마도 &lt;code class=&quot;language-text&quot;&gt;local&lt;/code&gt;일 것이다. 이 경우라면 &lt;code class=&quot;language-text&quot;&gt;YOUR_ISO_STORAGE_POOL&lt;/code&gt;를 local로 하면 된다. 그리고 &lt;a href=&quot;https://releases.ubuntu.com/24.04.1/ubuntu-24.04.1-live-server-amd64.iso?_ga=2.174163618.1627445440.1739895538-2098516798.1731756258&amp;#x26;_gl=1*1ijd3p4*_gcl_au*NDYzMTY4OTQ3LjE3Mzk4OTU1Mzg.&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;ubuntu-24.04.1-live-server-amd64.iso&lt;/a&gt;를 해당 저장소에 받아둬야 한다.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;VM Hard Disk Settings&lt;/code&gt;는 VM의 디스크 설정이다.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;VM Network Settings&lt;/code&gt;는 네트워크 설정이다. &lt;code class=&quot;language-text&quot;&gt;vlan_tag&lt;/code&gt;의 경우 해당 VLAN과 Packer host 사이에 방화벽이 있어서 ssh 접속이 불가능하진 않은지 확인해야한다.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;VM Cloud-Init Settings&lt;/code&gt;는 다음에 Terraform이나 직접 cloud-init 값을 입력하기 위해서 필요한 proxmox용 cloud-init disk를 생성하는 과정이다.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;PACKER Boot Commands&lt;/code&gt;는 앞서 설명했듯이 부팅 시에 Packer host의 임시 http 서버에 접속해서 cloud-init 정보를 가져오기 위한 커맨드이다.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;PACKER Autoinstall Settings&lt;/code&gt;는 방금 설명한 임시 http 서버에 대한 설정이다. 여기서 만약 &lt;code class=&quot;language-text&quot;&gt;http_port_min&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;http_port_max&lt;/code&gt;가 똑같이 설정된 여러 Packer template를 동시에 build 한다면 문제가 발생할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;# Resource Definiation for the VM Template
source &amp;quot;proxmox-iso&amp;quot; &amp;quot;ubuntu-server-noble&amp;quot; {

    # Proxmox Connection Settings
    proxmox_url = &amp;quot;${var.proxmox_api_url}&amp;quot;
    username    = &amp;quot;${var.proxmox_api_token_id}&amp;quot;
    password    = &amp;quot;${var.proxmox_api_password}&amp;quot;
    token       = &amp;quot;${var.proxmox_api_token_secret}&amp;quot;
    insecure_skip_tls_verify = true # (Optional) Skip TLS Verification

    # ssh Settings
    ssh_username                = &amp;quot;${var.ssh_username}&amp;quot;
    # (Option 1) Add your Password here
    #ssh_password                = &amp;quot;${var.ssh_password}&amp;quot;
    # - or -
    # (Option 2) Add your Private SSH KEY file here
    ssh_private_key_file        = &amp;quot;${var.ssh_private_key_file_path}&amp;quot;
    ssh_clear_authorized_keys   = true
    ssh_timeout                 = &amp;quot;30m&amp;quot;
    ssh_handshake_attempts      = 50
    ssh_pty                     = true

    # VM General Settings
    template_description = &amp;quot;Ubuntu Server Noble Image&amp;quot;
    node        = &amp;quot;pve&amp;quot;
    vm_id       = &amp;quot;9000&amp;quot;
    vm_name     = &amp;quot;ubuntu-server-noble&amp;quot;
    #pool        = &amp;quot;&amp;quot;
    tags        = &amp;quot;ubuntu_noble&amp;quot;
    os          = &amp;quot;l26&amp;quot;
    machine     = &amp;quot;q35&amp;quot;
    qemu_agent  = true
    cores       = &amp;quot;2&amp;quot;
    memory      = &amp;quot;4096&amp;quot;
    #bios        = &amp;quot;ovmf&amp;quot;
    #efi_config {
    #    efi_storage_pool    = &amp;quot;YOUR_STORAGE_POOL&amp;quot; #e.g. local-lvm
    #    efi_type            = &amp;quot;4m&amp;quot;
    #    pre_enrolled_keys   = true
    #}

    # VM OS Settings
    boot_iso {
      type              = &amp;quot;scsi&amp;quot;
      iso_file          = &amp;quot;YOUR_ISO_STORAGE_POOL:iso/ubuntu-24.04.1-live-server-amd64.iso&amp;quot;  #iso file name
      iso_storage_pool  = &amp;quot;YOUR_ISO_STORAGE_POOL&amp;quot; #local
      unmount           = true
    }

    # VM Hard Disk Settings
    scsi_controller     = &amp;quot;virtio-scsi-pci&amp;quot;
    disks {
        disk_size       = &amp;quot;20G&amp;quot;
        format          = &amp;quot;raw&amp;quot;
        storage_pool    = &amp;quot;YOUR_STORAG_POOL&amp;quot;  #e.g. local-lvm
        type            = &amp;quot;virtio&amp;quot;
    }

    # VM Network Settings
    network_adapters {
        model       = &amp;quot;virtio&amp;quot;
        bridge      = &amp;quot;vmbr1&amp;quot;
        #vlan_tag    = &amp;quot;100&amp;quot;
        firewall    = &amp;quot;false&amp;quot;
    }

    # VM Cloud-Init Settings
    cloud_init              = true
    cloud_init_storage_pool = &amp;quot;YOUR_STORAG_POOL&amp;quot;  #e.g. local-lvm

    # PACKER Boot Commands
    boot_command = [
        &amp;quot;&amp;lt;esc&amp;gt;&amp;lt;wait&amp;gt;&amp;quot;,
        &amp;quot;e&amp;lt;wait&amp;gt;&amp;quot;,
        &amp;quot;&amp;lt;down&amp;gt;&amp;lt;down&amp;gt;&amp;lt;down&amp;gt;&amp;lt;end&amp;gt;&amp;quot;,
        &amp;quot;&amp;lt;bs&amp;gt;&amp;lt;bs&amp;gt;&amp;lt;bs&amp;gt;&amp;lt;bs&amp;gt;&amp;lt;wait&amp;gt;&amp;quot;,
        &amp;quot;autoinstall ds=nocloud-net\\;s=http://{{ .HTTPIP }}:{{ .HTTPPort }}/ ---&amp;lt;wait&amp;gt;&amp;quot;,
        &amp;quot;&amp;lt;f10&amp;gt;&amp;lt;wait&amp;gt;&amp;quot;
    ]
    boot                    = &amp;quot;c&amp;quot;
    boot_wait               = &amp;quot;10s&amp;quot;
    communicator            = &amp;quot;ssh&amp;quot;

    # PACKER Autoinstall Settings
    http_directory          = &amp;quot;http&amp;quot;
    # (Optional) Bind IP Address and Port
    http_bind_address       = &amp;quot;YOUR_PACKER_HOST_IP&amp;quot; #packer host IP
    http_port_min           = 8802
    http_port_max           = 8902
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;443-build-정의&quot; style=&quot;position:relative;&quot;&gt;4.4.3. Build 정의&lt;a href=&quot;#443-build-%EC%A0%95%EC%9D%98&quot; aria-label=&quot;443 build 정의 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;VM생성 이후 ssh로 접속해서 실행할 커맨드이다. 여기서 &lt;code class=&quot;language-text&quot;&gt;sources&lt;/code&gt;는 위의 template에서 &lt;code class=&quot;language-text&quot;&gt;source&lt;/code&gt;와 대응하게 작성해야 한다. 여기서는 이후에 proxmox의 cloud-init 저장소를 활용하기 위한 준비와, 나의 경우 apt 저장소를 kakao로 변경하는 작업을 추가했다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;# Build Definition to create the VM Template
build {

    name    = &amp;quot;ubuntu-server-noble&amp;quot;
    sources = [&amp;quot;source.proxmox-iso.ubuntu-server-noble&amp;quot;]

    # Provisioning the VM Template for Cloud-Init Integration in Proxmox #1
    provisioner &amp;quot;shell&amp;quot; {
        inline = [
            &amp;quot;while [ ! -f /var/lib/cloud/instance/boot-finished ]; do echo &amp;#39;Waiting for cloud-init...&amp;#39;; sleep 1; done&amp;quot;,
            &amp;quot;sudo rm /etc/ssh/ssh_host_*&amp;quot;,
            &amp;quot;sudo truncate -s 0 /etc/machine-id&amp;quot;,
            &amp;quot;sudo apt -y autoremove --purge&amp;quot;,
            &amp;quot;sudo apt -y clean&amp;quot;,
            &amp;quot;sudo apt -y autoclean&amp;quot;,
            &amp;quot;sudo cloud-init clean&amp;quot;,
            &amp;quot;sudo rm -f /etc/cloud/cloud.cfg.d/subiquity-disable-cloudinit-networking.cfg&amp;quot;,
            &amp;quot;sudo rm -f /etc/netplan/00-installer-config.yaml&amp;quot;,
            &amp;quot;sudo sync&amp;quot;
        ]
    }

    # Provisioning the VM Template for Cloud-Init Integration in Proxmox #2
    provisioner &amp;quot;file&amp;quot; {
        source      = &amp;quot;files/99-pve.cfg&amp;quot;
        destination = &amp;quot;/tmp/99-pve.cfg&amp;quot;
    }

    # Provisioning the VM Template for Cloud-Init Integration in Proxmox #3
    provisioner &amp;quot;shell&amp;quot; {
        inline = [ &amp;quot;sudo cp /tmp/99-pve.cfg /etc/cloud/cloud.cfg.d/99-pve.cfg&amp;quot; ]
    }

    # Change apt repo to kakao mirror
    provisioner &amp;quot;shell&amp;quot; {
        inline = [
            &amp;quot;sudo sed -i &amp;#39;s|http://kr.archive.ubuntu.com/ubuntu/|http://mirror.kakao.com/ubuntu/|g&amp;#39; /etc/apt/sources.list.d/ubuntu.sources&amp;quot;
        ]
    }

    # Add additional provisioning scripts here
    # ...
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;ubuntu server noble과 jammy 모두 지금까지의 값들은 당연한 이름 같은 것을 제외하면 모두 동일하다. 하지만 ubuntu 24.04버전으로 오면서 apt 저장소 리스트를 저장하는 위치가 약간 바뀌었다. &lt;code class=&quot;language-text&quot;&gt;/etc/apt/sources.list -&gt; /etc/apt/sources.list.d/ubuntu.sources&lt;/code&gt; 때문에 jammy의 경우 아래와같이 apt 저장소를 바꾸는 코드만 수정해 주면 된다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;    # for ubuntu server jammy
    # Change apt repo to kakao mirror
    provisioner &amp;quot;shell&amp;quot; {
        inline = [
            &amp;quot;sudo sed -i &amp;#39;s|http://kr.archive.ubuntu.com/ubuntu/|http://mirror.kakao.com/ubuntu/|g&amp;#39; /etc/apt/sources.list&amp;quot;
        ]
    }&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;45-나머지&quot; style=&quot;position:relative;&quot;&gt;4.5. 나머지&lt;a href=&quot;#45-%EB%82%98%EB%A8%B8%EC%A7%80&quot; aria-label=&quot;45 나머지 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;meta-data&lt;/code&gt;의 경우 필요하다면 사용하면 된다. 여기서는 아무것도 작성하지 않아도 된다.
&lt;code class=&quot;language-text&quot;&gt;99-pve.cfg&lt;/code&gt;에는 &lt;code class=&quot;language-text&quot;&gt;datasource_list: [ConfigDrive, NoCloud]&lt;/code&gt; 한 줄만 있으면 되는데, 이것은 부팅 시에 cloud-init이 ConfigDrive를 먼저 진행할지, NoCloud로 먼저 진행할지를 정의하는 부분이다. proxmox의 경우 NoCloud방식을 사용한다. ConfigDrive를 먼저 확인하고 없다면 proxmox의 설정을 따르게 된다.&lt;/p&gt;
&lt;h2 id=&quot;46-run-packersh&quot; style=&quot;position:relative;&quot;&gt;4.6. run-packer.sh&lt;a href=&quot;#46-run-packersh&quot; aria-label=&quot;46 run packersh permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;#!/bin/bash

ACTION=$1
TEMPLATE_FILE=$2

if [ -z &amp;quot;$TEMPLATE_FILE&amp;quot; ]; then
    echo &amp;quot;Usage: $0 {validate|build|-v|-b} &amp;lt;template-file&amp;gt;&amp;quot;
    exit 1
fi

if [ &amp;quot;$ACTION&amp;quot; == &amp;quot;validate&amp;quot; ] || [ &amp;quot;$ACTION&amp;quot; == &amp;quot;-v&amp;quot; ]; then
    packer validate -var-file ../credentials.pkr.hcl -var-file ./ssh-user-credentials.pkr.hcl &amp;quot;$TEMPLATE_FILE&amp;quot;
elif [ &amp;quot;$ACTION&amp;quot; == &amp;quot;build&amp;quot; ] || [ &amp;quot;$ACTION&amp;quot; == &amp;quot;-b&amp;quot; ]; then
    packer build -var-file ../credentials.pkr.hcl -var-file ./ssh-user-credentials.pkr.hcl &amp;quot;$TEMPLATE_FILE&amp;quot;
else
    echo &amp;quot;Usage: $0 {validate|build|-v|-b} &amp;lt;template-file&amp;gt;&amp;quot;
    exit 1
fi&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;빌드의 편의를 위해 작성한 파일이다. 앞서 작성된 Packer 파일들을 빌드하기 위해서는&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;packer build -var-file ../credentials.pkr.hcl -var-file ./ssh-user-credentials.pkr.hcl ubuntu-server-noble.pkr.hcl&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;를 입력해야 한다고 했다. 이 스크립트는 반복되는 variable 파일을 이미 넣어둬서&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;./run-packer.sh -b ubuntu-server-noble.pkr.hcl&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;로 진행할 수 있다. validate의 경우&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;./run-packer.sh -v ubuntu-server-noble.pkr.hcl&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&quot;5-validate-and-build&quot; style=&quot;position:relative;&quot;&gt;5. validate and build&lt;a href=&quot;#5-validate-and-build&quot; aria-label=&quot;5 validate and build permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;위의 &lt;code class=&quot;language-text&quot;&gt;run-packer&lt;/code&gt; 스크립트를 이용해서 빌드해도 되지만, 일단은 정석적인 방법으로 빌드하려고 한다. 일단 Packer의 proxmox plugin을 설치해 준다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;~$ packer plugins install github.com/hashicorp/proxmox
Installed plugin github.com/hashicorp/proxmox v1.2.2 in &amp;quot;/home/user/.config/packer/plugins/github.com/hashicorp/proxmox/packer-plugin-proxmox_v1.2.2_x5.0_linux_amd64&amp;quot;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;위와 같이 뜬다면 성공적으로 설치된 것이다.&lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;packer build&lt;/code&gt;를 하기 이전에 validate 과정을 거쳐서 template 코드가 정상적으로 작성됐는지 확인해야 한다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;~$ packer validate -var-file ../credentials.pkr.hcl -var-file ./ssh-user-credentials.pkr.hcl ubuntu-server-noble.pkr.hcl
The configuration is valid.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;위와 같이 뜬다면 성공적으로 validate 된 것이다.&lt;/p&gt;
&lt;p&gt;validate가 성공했다면 비슷한 명령으로 build를 해준다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;~$ packer build -var-file ../credentials.pkr.hcl -var-file ./ssh-user-credentials.pkr.hcl ubuntu-server-noble.pkr.hcl&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;빌드를 하면 proxmox웹에서 지정한 vmid로 VM이 생성되고 부팅되는 걸 확인할 수 있다. 이때 아래와 같은 화면에서 절대 다른 조작을 해서는 안 된다. 이 화면에서 Packer가 proxmox에 키보드 입력을 통해 Packer가 띄운 http서버에서 cloud-init 정보를 가져오기 위한 커맨드를 입력하는데, 오조작으로 바로 설치 환경으로 들어가게 되면 Packer가 이후 프로세스를 진행할 수 없게 된다.
&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 630px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/b18ed4d83b8ddc3211b9aeaeffbed5ae/34abc/before_boot.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 55.06329113924051%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAABYlAAAWJQFJUiTwAAABGElEQVQoz62Ta6uCQBCGN81LGZYmZiEkXiAvCFFaX/z/P+s9vMPZIM4tDn14nNmd4d2dcVYppfATtm3DcRzMZjOYpgnDMPBbvpBlGS6Xi9D3Pdq2Fbquw/l8xv1+x+12e9hxHDEMA67Xq1jtM5bnOVTTNCI2TZOI8AAGSFEUOJ1OX6jr+gm9V5Yl1GKx+LuMF1kul1BRFMmC/WGv/gs11us1VBAEb7uh7/tQ8nmnIK/JkZjP5y/DfI1lWTJetJ+XU/A8Txa0q9VKekHobzYb8RnXOdvtVmC7KMQe6n+g6Oz3exkTjszxeESaptjtdjgcDrJXVZXkJEmCMAwfgnEcw3Xd59IpyNfA8SH0CUvj6TqmLfd06d/18gNVv/uqnvtc9AAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;before_boot&quot;
        title=&quot;before_boot&quot;
        src=&quot;/static/b18ed4d83b8ddc3211b9aeaeffbed5ae/f058b/before_boot.png&quot;
        srcset=&quot;/static/b18ed4d83b8ddc3211b9aeaeffbed5ae/c26ae/before_boot.png 158w,
/static/b18ed4d83b8ddc3211b9aeaeffbed5ae/6bdcf/before_boot.png 315w,
/static/b18ed4d83b8ddc3211b9aeaeffbed5ae/f058b/before_boot.png 630w,
/static/b18ed4d83b8ddc3211b9aeaeffbed5ae/40601/before_boot.png 945w,
/static/b18ed4d83b8ddc3211b9aeaeffbed5ae/78612/before_boot.png 1260w,
/static/b18ed4d83b8ddc3211b9aeaeffbed5ae/34abc/before_boot.png 3164w&quot;
        sizes=&quot;(max-width: 630px) 100vw, 630px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;
성공적으로 빌드가 완료되면 아래와 같이 proxmox Template가 생성된 것을 확인할 수 있다.
&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 418px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/5a57189967a04d3a9eebddbac2426e2c/d7398/build_complete.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 21.51898734177215%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAYAAACOXx+WAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAw0lEQVQY0zVPuw6DMBDja7pUAvFIgARIQAUqFkDqwECn9gO69Pvd+lqGyLHvzr4L6rrGuq4gTtMkr21bFEWBrutQVRWcc1BKiU7O3rIs4b1H3/dw1qJ+vXE2BkGe59i2DcuyQGsNY4wMU7fWisZ/lmVSO3gcx79+a1FqDXV/4BRlCJg2z7OYMJFDaZoiSRLRiDQLw1AMDs5HToyjBM2oMD7/G+77LlvyRJ7HRuIwDBLCUxl0cNaokTvv4JsW19sFw9fwA62UiZRBVcX+AAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;build_complete&quot;
        title=&quot;build_complete&quot;
        src=&quot;/static/5a57189967a04d3a9eebddbac2426e2c/d7398/build_complete.png&quot;
        srcset=&quot;/static/5a57189967a04d3a9eebddbac2426e2c/c26ae/build_complete.png 158w,
/static/5a57189967a04d3a9eebddbac2426e2c/6bdcf/build_complete.png 315w,
/static/5a57189967a04d3a9eebddbac2426e2c/d7398/build_complete.png 418w&quot;
        sizes=&quot;(max-width: 418px) 100vw, 418px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;h1 id=&quot;6-clone&quot; style=&quot;position:relative;&quot;&gt;6. clone&lt;a href=&quot;#6-clone&quot; aria-label=&quot;6 clone permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;이제 proxmox에 생성된 이미지를 clone 해보자. clone 하기에 앞서 proxmox에서 cloud-init 설정을 해줘야 한다.
&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 630px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/0b8318f1c09f53862bd41a04669ad26e/d9199/proxmox_cloud-init.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 62.65822784810127%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAYAAACpUE5eAAAACXBIWXMAABYlAAAWJQFJUiTwAAACCklEQVQ4y11TXYvTQBSdd/FVkDZJ2yRtkzZfM20ySbPrShG7VVZWEBcEX/YX+BMEQYUVfNDfe+RcnRB8ONzmzr3nnDt3qvb7Peq6hjFGovuttcZut5PIGsaqqqCNwTZNsSpLXH7/iauHX3j24zeef/4KozWU1kYKi6JElmXI8xxlWQ4ERVHIb+Yp1jQNdsbA1A3suzuUN7co39yiOr/GdrOB6g8HaSCiKEYURULcNH+dkpxOmTudTjifz3jJeH2Ny9Yi9D1EgY8oCBDHMZTRFYwuocsCq2iBZbTAxUWPtm2xWq0E6/V6gPve17WMv04SJGmKJEkkr5L7B3gfvgkevf2Cx6dPaNoOTV3LuFSdTqfwfV/geZ5EEhD8nkwmQ16lr+4RvvgI/+oOT/r3eGpvYNsOrbUyMkHSMAwH8Fp4pxR0d+5q1KHWaE0BvV0jDX0s5x6stTJynmWyGBYGQYDZbCZxPp8LiVse6ynCM9V2B1TaoG4ssqJEGMWyBG6UDSTk3TgikjJy3DRNsdlsxCVFeabcG2MTVWi973tRdU+HY7N5sVgMYB1FCN4dyZhXXddJM0FVJo/HI5h3D5tuGcfNFFoul4MJOpSl0CFH4ztzT4OOSDb+97DZPSMK84yPnLD/FsgzxYQsIM9lLIKqY1CdhA505PLjzfNMHNI+XdAli6k0JnAkY/x/7mr+AK1CkOR8PRTGAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;proxmox_cloud-init&quot;
        title=&quot;proxmox_cloud-init&quot;
        src=&quot;/static/0b8318f1c09f53862bd41a04669ad26e/f058b/proxmox_cloud-init.png&quot;
        srcset=&quot;/static/0b8318f1c09f53862bd41a04669ad26e/c26ae/proxmox_cloud-init.png 158w,
/static/0b8318f1c09f53862bd41a04669ad26e/6bdcf/proxmox_cloud-init.png 315w,
/static/0b8318f1c09f53862bd41a04669ad26e/f058b/proxmox_cloud-init.png 630w,
/static/0b8318f1c09f53862bd41a04669ad26e/40601/proxmox_cloud-init.png 945w,
/static/0b8318f1c09f53862bd41a04669ad26e/d9199/proxmox_cloud-init.png 960w&quot;
        sizes=&quot;(max-width: 630px) 100vw, 630px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;
위와 같이 User, Password, SSH public key를 넣어주고, IP Config는 기본으로 dhcp로 설정해 주면 된다. 이후에 다룰 Terraform으로 VM 여러 개 배포하기에서 고정 IP로 생성하는 방법에 대해서 자세히 다루겠다. 값을 다 넣었다면 VM을 우클릭하거나 우측 상단의 more에서 clone을 찾아서 clone을 진행한다.
&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 630px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/f20e55b68b3f9d633646237b8a822fea/e72de/proxmox_clone.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 41.77215189873418%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAABYlAAAWJQFJUiTwAAABB0lEQVQoz3WRPU7FMBCEfQUK6JPYzp8dO78dT6LkCHQ06blAem49aDZshPR4xWg2491vrdj4PsEPi6jOG3xaxa11sNZeqqpK3LkzL8tSdOaV9Ls+w4QQkXJGCAFN02KcZsQ4IMZ4qes68b7vBVbXNZZlwbZtmKZJzoZhQB8CDIN1XdG1LZqmwe32inmekXPGOI4ywGYdYg+BzAllDxfxQlxsGPCjKAppJIwZgQoljCAOKJAQFefpPDO6KaUkA3RCVHpD772A+A9Zt217iSCKuWHwd8N/UpDCtL6Xh+Er6Ws9bjxBCtP6krPwthI3+77jOA7Q+YJ3zQ9A7lcEPb994uXjG0/vX/gBLjvwzghKEYMAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;proxmox_clone&quot;
        title=&quot;proxmox_clone&quot;
        src=&quot;/static/f20e55b68b3f9d633646237b8a822fea/f058b/proxmox_clone.png&quot;
        srcset=&quot;/static/f20e55b68b3f9d633646237b8a822fea/c26ae/proxmox_clone.png 158w,
/static/f20e55b68b3f9d633646237b8a822fea/6bdcf/proxmox_clone.png 315w,
/static/f20e55b68b3f9d633646237b8a822fea/f058b/proxmox_clone.png 630w,
/static/f20e55b68b3f9d633646237b8a822fea/40601/proxmox_clone.png 945w,
/static/f20e55b68b3f9d633646237b8a822fea/e72de/proxmox_clone.png 1198w&quot;
        sizes=&quot;(max-width: 630px) 100vw, 630px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;
위와 같은 창이 뜰 것이다. 여기서 VM ID, Name 등을 넣어주고, Mode를 지정해 줘야 한다. 여기서 Linked Clone과 Full Clone이 있는데, Linked Clone은 원본 이미지에 의존해서 VM을 생성하기 때문에 디스크 공간을 절약하고 더 빠른 Clone을 할 수 있지만, 원본 이미지의 안정성이 보장돼야 한다. 또한 Linked Clone을 하면 link 돼 있는 이미지(예제에선 VM ID 9000)와 같은 디스크에 clone 된 VM이 존재해야 한다. replication을 적용한 상태의 서로다른 proxmox 노드로의 migration은 시도해 보진 않았지만, replication 없이 migration을 진행했을 때는 실패했으니 다른 노드로 migration 할 계획이 있다면 Full Clone을 권장한다. 보통의 경우라면 테스트할 때는 linked로 장기간 사용할 계획이라면 full을 추천한다.&lt;/p&gt;
&lt;h1 id=&quot;결론&quot; style=&quot;position:relative;&quot;&gt;결론&lt;a href=&quot;#%EA%B2%B0%EB%A1%A0&quot; aria-label=&quot;결론 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;앞으로는 생성된 이미지를 가지고 편하게 초기 세팅이 완료된 VM을 clone으로 생성해서 바로 사용할 수 있을 것이다. Packer를 이용해서 이미지를 만들고 이 이미지로 VM을 생성하는 방식은 그냥 OS 이미지로 부팅하고 생성하는 것보다 훨씬 편하고 일관적이다. proxmox를 사용을 굉장히 편리하게 해줘서 이 경험을 최대한 자세히 공유하고자 노력했고, 많은 사람들에게 도움이 됐으면 한다.&lt;/p&gt;
&lt;p&gt;다음 글에서 Terraform으로 같은 이미지를 사용해서 k8s cluster를 위한 VM 여러 개를 배포하는 과정을 설명하려고 한다.&lt;/p&gt;
&lt;p&gt;잘못된 설명이나 추가로 설명했으면 좋겠는 부분, 오타, 맞춤법에 대한 지적은 언제나 환영합니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;이 글을 홈서버 사용자를 위한 것입니다. 실제 환경에서 사용할 때는 credential을 Vault나 환경 변수 등으로 좀 더 엄격하게 관리하고, dedicate 한 proxmox user, pool, token 사용을 고려하기를 바랍니다. Packer가 설치된 host의 보안에 충분한 주의를 기울이기를 바랍니다.&lt;/li&gt;
&lt;li&gt;이 글을 포함해 인터넷에 존재하는 코드, 스크립트를 복사해 사용할 때는 코드, 스크립트를 충분히 읽고, 분석하여 문제가 없는지 확인하시기를 바랍니다. 최소한 ChatGPT 같은 AI에 해당 코드, 스크립트가 정말 안전하고 사용해도 되는지 확인받으시길 권장합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;참고&quot; style=&quot;position:relative;&quot;&gt;참고&lt;a href=&quot;#%EC%B0%B8%EA%B3%A0&quot; aria-label=&quot;참고 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/ChristianLempa&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;ChristianLempa&lt;/a&gt; github/boilerplates&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/ChristianLempa/boilerplates/tree/main/packer/proxmox&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;https://github.com/ChristianLempa/boilerplates/tree/main/packer/proxmox&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.hashicorp.com/ko/products/packer&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;HashiCorp Packer&lt;/a&gt; developer docs&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://developer.hashicorp.com/packer/integrations/hashicorp/proxmox&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;https://developer.hashicorp.com/packer/integrations/hashicorp/proxmox&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Proxmox Admin Guide 살펴보기]]></title><description><![CDATA[version 8.2.2, Thu Apr 25 09:24:16 CEST 2024 목적 지난 2년 동안 Proxmox…]]></description><link>https://vulcan.site/proxmox/admin-guide/01/</link><guid isPermaLink="false">https://vulcan.site/proxmox/admin-guide/01/</guid><pubDate>Mon, 29 Jul 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;version 8.2.2, Thu Apr 25 09:24:16 CEST 2024&lt;/p&gt;
&lt;h1 id=&quot;목적&quot; style=&quot;position:relative;&quot;&gt;목적&lt;a href=&quot;#%EB%AA%A9%EC%A0%81&quot; aria-label=&quot;목적 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;지난 2년 동안 Proxmox를 홈서버에서 정말 잘 사용해 왔다. 하지만 한 번도 제대로 &lt;a href=&quot;https://pve.proxmox.com/pve-docs/pve-admin-guide.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;공식 가이드&lt;/a&gt;를 읽어본 적이 없고, 전부 영어로 돼 있어 번역도 함께 진행해 보고자 한다.&lt;/p&gt;
&lt;h1 id=&quot;1-소개&quot; style=&quot;position:relative;&quot;&gt;1. 소개&lt;a href=&quot;#1-%EC%86%8C%EA%B0%9C&quot; aria-label=&quot;1 소개 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Proxmox VE는 가상 머신과 컨테이너를 실행하기 위한 플랫폼입니다. Debian Linux를 기반으로 하며, 완전한 오픈 소스입니다. 최대의 유연성을 위해 두 가지 가상화 기술을 구현했습니다 - 커널 기반 가상 머신(KVM)과 컨테이너 기반 가상화(LXC)입니다.&lt;/p&gt;
&lt;p&gt;주요 설계 목표 중 하나는 관리를 최대한 쉽게 만드는 것이었습니다. Proxmox VE는 단일 노드에서 사용할 수 있으며, 여러 노드로 클러스터를 구성할 수도 있습니다. 모든 관리 작업은 웹 기반 관리 인터페이스를 통해 수행할 수 있으며, 초보자도 몇 분 안에 Proxmox VE를 설치하고 설정할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./1%20introduction-01.png&quot; alt=&quot;img01&quot;&gt;&lt;/p&gt;
&lt;h2 id=&quot;11-중앙-관리&quot; style=&quot;position:relative;&quot;&gt;1.1. 중앙 관리&lt;a href=&quot;#11-%EC%A4%91%EC%95%99-%EA%B4%80%EB%A6%AC&quot; aria-label=&quot;11 중앙 관리 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;많은 사람들이 단일 노드로 시작하지만, Proxmox VE는 대규모 클러스터 노드 집합으로 확장할 수 있습니다. 클러스터 스택은 완전히 통합되어 있으며 기본 설치와 함께 제공됩니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;독특한 멀티 마스터 설계&lt;/p&gt;
&lt;p&gt;통합된 웹 기반 관리 인터페이스는 모든 KVM 게스트와 Linux 컨테이너는 물론 전체 클러스터에 대한 명확한 개요를 제공합니다. GUI를 통해 VM과 컨테이너, 스토리지 또는 클러스터를 쉽게 관리할 수 있습니다. 별도의 복잡하고 비용이 많이 드는 관리 서버를 설치할 필요가 없습니다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Proxmox 클러스터 파일 시스템 (pmxcfs)&lt;/p&gt;
&lt;p&gt;Proxmox VE는 구성 파일을 저장하기 위한 데이터베이스 기반 파일 시스템인 Proxmox 클러스터 파일 시스템 (pmxcfs)을 사용합니다. 이를 통해 수천 대의 가상 머신 구성을 저장할 수 있습니다. corosync를 사용하면 이러한 파일은 모든 클러스터 노드에서 실시간으로 복제됩니다. 파일 시스템은 디스크의 영구 데이터베이스 내부에 모든 데이터를 저장하지만, 데이터 복사본은 최대 30MB의 저장 용량을 제공하는 RAM에 저장됩니다. 이는 수천 개의 VM을 저장하기에 충분합니다.&lt;/p&gt;
&lt;p&gt;Proxmox VE는 이 독특한 클러스터 파일 시스템을 사용하는 유일한 가상화 플렛폼입니다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;웹 기반 관리 인터페이스&lt;/p&gt;
&lt;p&gt;Proxmox VE는 사용하기 쉽습니다. 관리 작업은 포함된 웹 기반 관리 인터페이스를 통해 수행할 수 있습니다. 별도의 관리 도구나 대용향 데이터베이스가 있는 추가 관리 노드를 설치할 필요가 없습니다. 멀티 마스터 도구를 사용하면 클러스터의 모든 노드에서 전체 클러스터를 관리할 수 있습니다. JavaScript 프레임워크(ExtJS)를 기반으로 하는 중앙 웹 기반 관리를 통해 모든 기능을 GUI에서 제어하고 각 노드의 기록 및 시스템 로그를 관리할 수 있습니다. 여기에는 백업 또는 복원 작업 실행, 실시간 마이그레이션 또는 고가용성(HA) 트리거 활동이 포함됩니다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;커맨드라인&lt;/p&gt;
&lt;p&gt;Unix 셸이나 Windows Powershell에 익숙한 고급 사용자를 위해 Proxmox VE는 가상 환경의 모든 구성 요소를 관리할 수 있는 커맨드라인 인터페이스를 제공합니다. 이 커맨드라인 인터페이스에는 지능형 탭 완성 기능과 UNIX 메뉴얼 페이지 형식의 전체 문서를 제공합니다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;REST API&lt;/p&gt;
&lt;p&gt;Proxmox VE는 RESTful API를 사용합니다. 기본 데이터 형식으로 JSON을 선택했으며, 전체 API는 JSON Schema를 사용하여 정의됩니다. 이를 통해 맞춤형 호스팅 환경과 같은 타사 관리 도구를 빠르고 쉽게 통합할 수 있습니다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;역할 기반 관리&lt;/p&gt;
&lt;p&gt;역할 기반 사용자 및 관리를 사용하여 모든 객체(VM, 스토리지, 노드 등)에 대한 세부적인 접근 권한을 정의할 수 있습니다. 이를 통해 권한을 정의하고 객체에 대한 접근을 제어할 수 있습니다. 이 개념은 접근 제어 목록(ACL)으로도 알려져 있습니다. 각 권한은 특정 경로에 대한 사용자(또는 그룹)와 역할(권한 집합)을 지정합니다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;인증 영역&lt;/p&gt;
&lt;p&gt;Proxmox VE는 Microsoft Active Directory, LDAP, Linux PAM 표준 인증 또는 내장된 Proxmox VE 인증 서버와 같은 다양한 인증 소스를 지원합니다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;12-유연한-스토리지-옵션&quot; style=&quot;position:relative;&quot;&gt;1.2. 유연한 스토리지 옵션&lt;a href=&quot;#12-%EC%9C%A0%EC%97%B0%ED%95%9C-%EC%8A%A4%ED%86%A0%EB%A6%AC%EC%A7%80-%EC%98%B5%EC%85%98&quot; aria-label=&quot;12 유연한 스토리지 옵션 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Proxmox VE의 스토리지 모델은 매우 유연합니다. 가상 머신 이미지는 하나 이상의 로컬 스토리지나 NFS와 같은 공유 스토리지 또는 SAN에 저장할 수 있습니다. 제한이 없으며, 원하는 만큼 많은 스토리지 정의를 구성할 수 있습니다. Debian Linux에서 사용 가능한 모든 스토리지 기술을 사용할 수 있습니다.&lt;/p&gt;
&lt;p&gt;가상 머신을 공유 스토리지에 저장하는 주요 이점 중 하나는 클러스터의 모든 노드가 VM 디스크 이미지에 직접 접근할 수 있어, 실행 중인 머신을 다운타임 없이 라이브 마이그레이션 할 수 있다는 점입니다.&lt;/p&gt;
&lt;p&gt;현재 지원하는 네트워크 스토리지 유형은 다음과 같습니다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;LVM Group (iSCSI target을 통한 네트워크 백업)&lt;/li&gt;
&lt;li&gt;iSCSI target&lt;/li&gt;
&lt;li&gt;NFS Share&lt;/li&gt;
&lt;li&gt;CIFS Share&lt;/li&gt;
&lt;li&gt;Ceph RBD&lt;/li&gt;
&lt;li&gt;Directly use iSCSI LUNs&lt;/li&gt;
&lt;li&gt;GlusterFS&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;지원하는 로컬 스토리지 유형은 다음과 같습니다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;LVM Group (블록 디바이스, FC 디바이스, DRBD 등과 같은 로컬 백업 장치)&lt;/li&gt;
&lt;li&gt;Directory (기존 파일 시스템 저장소)&lt;/li&gt;
&lt;li&gt;ZFS&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;13-통합-백업-및-복원&quot; style=&quot;position:relative;&quot;&gt;1.3. 통합 백업 및 복원&lt;a href=&quot;#13-%ED%86%B5%ED%95%A9-%EB%B0%B1%EC%97%85-%EB%B0%8F-%EB%B3%B5%EC%9B%90&quot; aria-label=&quot;13 통합 백업 및 복원 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;통합 백업 도구 (vzdump)는 실행 중인 컨테이너와 KVM 게스트의 일관된 스냅샷을 생성합니다. 기본적으로 VM 또는 CT 데이터의 아카이브를 생성하며, 여기에는 VM/CT 구성 파일도 포함됩니다.&lt;/p&gt;
&lt;p&gt;KVM 라이브 백업은 NFS, CIFS, iSCSI LUN, Ceph RBD에 있는 VM 이미지 등 모든 스토리지 유형에서 작동합니다. 새로운 백업 형식은 VM 백업을 빠르고 효율적으로 저장할 수 있도록 최적화되어 있습니다.(희소 파일, 비순차 데이터, 최소화된 I/O)&lt;/p&gt;
&lt;h2 id=&quot;14-고가용성-클러스터&quot; style=&quot;position:relative;&quot;&gt;1.4. 고가용성 클러스터&lt;a href=&quot;#14-%EA%B3%A0%EA%B0%80%EC%9A%A9%EC%84%B1-%ED%81%B4%EB%9F%AC%EC%8A%A4%ED%84%B0&quot; aria-label=&quot;14 고가용성 클러스터 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;멀티 노드 Proxmox VE HA 클러스터는 고가용성 가상 서버를 정의할 수 있게 해줍니다. Proxmox VE HA 클러스터는 검증된 Linux HA 기술을 기반으로 하여 안정적이고 신뢰할 수 있는 고가용성 서비스를 제공합니다.&lt;/p&gt;
&lt;h2 id=&quot;15-유연한-네트워킹&quot; style=&quot;position:relative;&quot;&gt;1.5. 유연한 네트워킹&lt;a href=&quot;#15-%EC%9C%A0%EC%97%B0%ED%95%9C-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%82%B9&quot; aria-label=&quot;15 유연한 네트워킹 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Proxmox VE는 브릿지 네트워킹 모델을 사용합니다. 모든 VM은 각 게스트의 가상 네트워크 케이블이 모두 같은 스위치에 연결된 것처럼 하나의 브릿지를 공유할 수 있습니다. VM을 외부와 연결하기 위해 브릿지는 물리적 네트워크 카드에 연결되고 TCP/IP 구성이 할당됩니다.&lt;/p&gt;
&lt;p&gt;추가적인 유연성을 위해 VLAN(IEEE 802.1q) 및 네트워크 본딩/집계가 가능합니다. 이를 통해 Proxmox VE 호스트를 위한 복잡하고 유연한 가상 네트워크를 구축하여 Linux 네스워크 스택의 모든 기능을 활용할 수 있습니다.&lt;/p&gt;
&lt;h2 id=&quot;16-통합-방화벽&quot; style=&quot;position:relative;&quot;&gt;1.6. 통합 방화벽&lt;a href=&quot;#16-%ED%86%B5%ED%95%A9-%EB%B0%A9%ED%99%94%EB%B2%BD&quot; aria-label=&quot;16 통합 방화벽 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;통합 방화벽을 통해 VM 또는 컨테이너 인터페이스에서 네트워크 패킷을 필터링할 수 있습니다. 일반적인 방화벽 규칙 세트를 “보안 그룹”으로 그룹화할 수 있습니다.&lt;/p&gt;
&lt;h2 id=&quot;17-하이퍼-컨버지드-인프라hci&quot; style=&quot;position:relative;&quot;&gt;1.7. 하이퍼 컨버지드 인프라(HCI)&lt;a href=&quot;#17-%ED%95%98%EC%9D%B4%ED%8D%BC-%EC%BB%A8%EB%B2%84%EC%A7%80%EB%93%9C-%EC%9D%B8%ED%94%84%EB%9D%BChci&quot; aria-label=&quot;17 하이퍼 컨버지드 인프라hci permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Proxmox VE는 컴퓨팅, 스토리지 및 네크워킹 자원을 긴밀하게 통합하고, 고가용성 클러스터, 백업/복원 재해 복구를 관리하는 가상화 플랫폼입니다. 모든 구성 요소는 소프트웨어 정의이며 서로 호환됩니다.&lt;/p&gt;
&lt;p&gt;따라서 중앙 웹 관리 인터페이스를 통해 이들을 단일 시스템처럼 관리할 수 있습니다. 이러한 기능들은 Proxmox VE를 오픈 소스 &lt;a href=&quot;https://en.wikipedia.org/wiki/Hyper-converged_infrastructure&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;하이퍼 컨버지드 인프라&lt;/a&gt;를 배포하고 관리하기 위한 이상적인 선택으로 만듭니다.&lt;/p&gt;
&lt;h3 id=&quot;171-proxmox-ve를-통한-하이퍼-컨버지드-인프라hci의-이점&quot; style=&quot;position:relative;&quot;&gt;1.7.1. Proxmox VE를 통한 하이퍼 컨버지드 인프라(HCI)의 이점&lt;a href=&quot;#171-proxmox-ve%EB%A5%BC-%ED%86%B5%ED%95%9C-%ED%95%98%EC%9D%B4%ED%8D%BC-%EC%BB%A8%EB%B2%84%EC%A7%80%EB%93%9C-%EC%9D%B8%ED%94%84%EB%9D%BChci%EC%9D%98-%EC%9D%B4%EC%A0%90&quot; aria-label=&quot;171 proxmox ve를 통한 하이퍼 컨버지드 인프라hci의 이점 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;하이퍼 컨버지드 인프라(HCI)는 인프라 수요는 높지만 관리 예산이 적을 때의 배포 환경, 원격 및 지사 환경과 같은 분산 설정, 또는 가상 사설 및 공용 클라우드에 특히 유용합니다.&lt;/p&gt;
&lt;p&gt;HCI는 다음과 같은 장점을 제공합니다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;확장성: 컴퓨팅, 네트워킹 및 스토리지 장치를 원활하게 확장할 수 있습니다.(예: 서버와 스토리지를 서로 독립적으로 빠르고 쉽게 확장 가능)&lt;/li&gt;
&lt;li&gt;저비용: Proxmox VE는 오픈 소스이며, 컴퓨팅, 스토리지, 네트워킹, 백업 및 관리 센터와 같은 필요한 모든 구성 요소를 통합합니다. 이는 비용이 많이 드는 컴퓨팅/스토리지 인프라를 대체할 수 있습니다.&lt;/li&gt;
&lt;li&gt;데이터 보호 및 효율성: 백업 및 재해 복구와 같은 서비스가 통합되어 있습니다.&lt;/li&gt;
&lt;li&gt;단순성: 간편한 구성과 중앙 집중식 관리가 가능합니다.&lt;/li&gt;
&lt;li&gt;오픈 소스: 벤더에 종속되지 않습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;172-하이퍼-컨버지드-인프라-스토리지&quot; style=&quot;position:relative;&quot;&gt;1.7.2. 하이퍼 컨버지드 인프라: 스토리지&lt;a href=&quot;#172-%ED%95%98%EC%9D%B4%ED%8D%BC-%EC%BB%A8%EB%B2%84%EC%A7%80%EB%93%9C-%EC%9D%B8%ED%94%84%EB%9D%BC-%EC%8A%A4%ED%86%A0%EB%A6%AC%EC%A7%80&quot; aria-label=&quot;172 하이퍼 컨버지드 인프라 스토리지 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Proxmox VE는 하이퍼 컨버지드 스토리지 인프라를 배포하기 위한 통합 지원을 제공합니다. 예를 들어, 웹 인터페이스만을 사용하여 다음 두 가지 스토리지 기술을 배포하고 관리할 수 있습니다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Ceph: 자가 치유 및 자가 관리가 가능한 신뢰할 수 있고 고도고 확장 가능한 공유 스토리지 시스템입니다. Proxmox VE 노드에서 Ceph 서비스를 관리하는 방법을 확인하십시오.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ZFS: 데이터 손상에 대한 광범위한 보호 기능, 다양한 RAID 모드, 빠르고 저렴한 스냅샷 등의 기능을 제공하는 통합된 파일 시스템 및 논리적 볼륨 관리자입니다. Proxmox VE 노드에서 ZFS의 강력한 기능을 활용하는 방법을 알아보십시오.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;이 외에도 Proxmox VE는 다양한 추가 스토리지 기술을 통합할 수 있는 지원을 제공합니다. 이에 대한 자세한 내용은 스토리지 관리자 챕터에서 확인할 수 있습니다.&lt;/p&gt;
&lt;h2 id=&quot;18-왜-오픈-소스인가&quot; style=&quot;position:relative;&quot;&gt;1.8. 왜 오픈 소스인가&lt;a href=&quot;#18-%EC%99%9C-%EC%98%A4%ED%94%88-%EC%86%8C%EC%8A%A4%EC%9D%B8%EA%B0%80&quot; aria-label=&quot;18 왜 오픈 소스인가 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Proxmox VE는 Linux 커널을 사용하며 Debian GNU/Linux 배포판을 기반으로 합니다. Proxmox VE의 소스 코드는 &lt;a href=&quot;https://www.gnu.org/licenses/agpl-3.0.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;GNU Affero General Public License&lt;/a&gt;, 버전 3에 짜라 공개됩니다. 이는 언제든지 소스 코드를 검사하거나 프로젝트에 직접 기여할 수 있음을 의미합니다.&lt;/p&gt;
&lt;p&gt;Proxmox에서는 가능한 한 오픈 소스 소프트웨어를 사용할 것을 약속합니다. 오픈 소스 소프트웨어를 사용하면 모든 기능에 완전히 접근할 수 있으며, 높은 보안성과 신뢰성을 보장합니다. 우리는 모든 사람이 소프트웨어의 소스 코드에 접근하여 실행하고, 이를 기반으로 빌드하거나, 프로젝트에 변경사항을 제출할 권리가 있어야 한다고 생각합니다. 모든 사람이 기여하도록 권장되며, Proxmox는 제품이 항상 전문적인 품질 기준을 충족하도록 보장합니다.&lt;/p&gt;
&lt;p&gt;오픈 소스 소프트웨어는 또한 비용을 낮추고 핵심 인프라를 단일 벤더에 종속되지 않게 합니다.&lt;/p&gt;
&lt;h2 id=&quot;19-proxmox-ve의-이점&quot; style=&quot;position:relative;&quot;&gt;1.9. Proxmox VE의 이점&lt;a href=&quot;#19-proxmox-ve%EC%9D%98-%EC%9D%B4%EC%A0%90&quot; aria-label=&quot;19 proxmox ve의 이점 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;오픈 소스 소프트웨어&lt;/li&gt;
&lt;li&gt;벤더 종속 없음&lt;/li&gt;
&lt;li&gt;Linux 커널&lt;/li&gt;
&lt;li&gt;빠른 설치와 쉬운 사용&lt;/li&gt;
&lt;li&gt;웹 기반 관리 인터페이스&lt;/li&gt;
&lt;li&gt;REST API&lt;/li&gt;
&lt;li&gt;활성화된 큰 커뮤니티&lt;/li&gt;
&lt;li&gt;낮은 관리 비용 및 간단한 배포&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;110-도움-받기&quot; style=&quot;position:relative;&quot;&gt;1.10. 도움 받기&lt;a href=&quot;#110-%EB%8F%84%EC%9B%80-%EB%B0%9B%EA%B8%B0&quot; aria-label=&quot;110 도움 받기 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id=&quot;1101-proxmox-ve-위키&quot; style=&quot;position:relative;&quot;&gt;1.10.1. Proxmox VE 위키&lt;a href=&quot;#1101-proxmox-ve-%EC%9C%84%ED%82%A4&quot; aria-label=&quot;1101 proxmox ve 위키 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;주요 정보 출처는 &lt;a href=&quot;https://pve.proxmox.com/wiki/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Proxmox VE 위키&lt;/a&gt; 입니다. 이 위키는 참고 문서와 사용자 기여 콘텐츠를 결합하여 제공합니다.&lt;/p&gt;
&lt;h3 id=&quot;1102-커뮤니티-지원-포럼&quot; style=&quot;position:relative;&quot;&gt;1.10.2. 커뮤니티 지원 포럼&lt;a href=&quot;#1102-%EC%BB%A4%EB%AE%A4%EB%8B%88%ED%8B%B0-%EC%A7%80%EC%9B%90-%ED%8F%AC%EB%9F%BC&quot; aria-label=&quot;1102 커뮤니티 지원 포럼 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Proxmox VE는 완전히 오픈 소스이므로, 사용자들이 &lt;a href=&quot;https://forum.proxmox.com/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Proxmox VE 커뮤니티 포럼&lt;/a&gt;을 통해 지식을 공유하고 토론할 것을 항상 권장합니다. 포럼은 Proxmox 지원팀이 관리하며, 전 서계의 많은 사용자 기반을 보유하고 있습니다. 이러한 대규모 포럼은 정보를 얻기 위한 훌륭한 장소입니다.&lt;/p&gt;
&lt;h3 id=&quot;1103-메일링-리스트&quot; style=&quot;position:relative;&quot;&gt;1.10.3. 메일링 리스트&lt;a href=&quot;#1103-%EB%A9%94%EC%9D%BC%EB%A7%81-%EB%A6%AC%EC%8A%A4%ED%8A%B8&quot; aria-label=&quot;1103 메일링 리스트 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;메일링 리스트를 통해 Proxmox VE 커뮤니티와 이메일로 빠르게 소통할 수 있습니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;사용자 메일링 리스트: &lt;a href=&quot;http://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-user&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Proxmox VE User List&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Proxmox VE는 완전히 오픈 소스이며 기여를 환영합니다! 개발자들의 주요 소통 채널은 다음과 같습니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;개발자 메일링 리스트: &lt;a href=&quot;http://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Proxmox VE Development Discussion&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;1104-상업적-지원&quot; style=&quot;position:relative;&quot;&gt;1.10.4. 상업적 지원&lt;a href=&quot;#1104-%EC%83%81%EC%97%85%EC%A0%81-%EC%A7%80%EC%9B%90&quot; aria-label=&quot;1104 상업적 지원 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Proxmox Server Solutions GmbH는 &lt;a href=&quot;https://proxmox.com/en/proxmox-virtual-environment/pricing&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Proxmox VE 구독 서비스 플랜&lt;/a&gt;으로 이용할 수 있는 엔터프라이즈 지원도 제공합니다. 구독한 모든 사용자는 Proxmox VE &lt;a href=&quot;https://pve.proxmox.com/pve-docs/pve-admin-guide.html#sysadmin_enterprise_repo&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;엔터프라이즈 저장소&lt;/a&gt;에 접근할 수 있으며, 기본, 표준 또는 프리미엄 구독을 통해 Proxmox 고객 포털에도 접근할 수 있습니다. 고객 포털은 Proxmox VE 개발자로부터 보장된 응답 시간을 제공하는 도움말과 지원을 제공합니다.&lt;/p&gt;
&lt;p&gt;대량 할인 또는 일반적인 추가 정보가 필요하다면 &lt;a href=&quot;mailto:sales@proxmox.com&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;sales@proxmox.com&lt;/a&gt;으로 문의하십시오.&lt;/p&gt;
&lt;h3 id=&quot;1105-버그-트래커&quot; style=&quot;position:relative;&quot;&gt;1.10.5. 버그 트래커&lt;a href=&quot;#1105-%EB%B2%84%EA%B7%B8-%ED%8A%B8%EB%9E%98%EC%BB%A4&quot; aria-label=&quot;1105 버그 트래커 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Proxmox는 &lt;a href=&quot;https://bugzilla.proxmox.com/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;공개 버그 트래커&lt;/a&gt;를 운영합니다. 문제가 발생하면 그곳에 보고서를 제출하십시오. 문제는 버그일 수도 있고 새로운 기능이나 개선 사항 요청일 수도 있습니다. 버그 트래커는 문제를 추적하는 데 도움을 주며, 문제가 해결되면 알림을 보냅니다.&lt;/p&gt;
&lt;h2 id=&quot;111-프로젝트-역사&quot; style=&quot;position:relative;&quot;&gt;1.11. 프로젝트 역사&lt;a href=&quot;#111-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EC%97%AD%EC%82%AC&quot; aria-label=&quot;111 프로젝트 역사 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;이 프로젝트는 2007년에 시작되었고, 2008년에 첫 번째 안정 버전이 출시되었습니다. 당시 우리는 컨테이너를 위해 OpenVZ를, 가상 머신을 위해 KVM을 사용했습니다. 클러스터링 기능은 제한적이었고, 사용자 인터페이스는 간단한 서버 생성 웹 페이지였습니다.&lt;/p&gt;
&lt;p&gt;그러나 우리는 빠르게 새로운 기능을 개발하였으며, &lt;a href=&quot;https://corosync.github.io/corosync/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Corosync&lt;/a&gt; 클러스터 스택을 사용하고 새로운 Proxmox 클러스터 파일 시스템(pmxcfs)을 도입한 것은 큰 진전이었습니다. 이로 인해 사용자는 클러스터의 복잡성을 완전히 숨길 수 있었습니다. 16개의 노드 클러스터를 관리하는 것이 단일 노드를 관리하는 것만큼 간단해졌습니다.&lt;/p&gt;
&lt;p&gt;또한 우리는 JSON-Schema로 작성된 완전한 선언적 명세를 가진 새로운 REST API를 도입했습니다. 이를 통해 다른 사람들이 Proxmox VE를 그들의 인프라에 통합할 수 있었으며, 추가적인 서비스를 제공하는 것이 쉬워졌습니다.&lt;/p&gt;
&lt;p&gt;새로운 REST API 덕분에 기존 사용자 인터페이스를, JavaScript를 사용하는 현대적인 HTML5 어플리케이션으로 교체할 수 있었습니다. 또한, 오래된 Java 기반 VNC 콘솔 코드를 &lt;a href=&quot;https://kanaka.github.io/noVNC/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;noVNC&lt;/a&gt;로 교체했습니다. 이제 웹 브라우저만 있으면 VM을 관리할 수 있습니다.&lt;/p&gt;
&lt;p&gt;다양한 스토리지 유형에 대한 지원도 또 다른 큰 과제였습니다. 특히, Proxmox VE는 2014년에 기본적으로 ZFS on Linux를 제공한 첫 번째 배포판이었습니다. 또 다른 이정표는 하이퍼바이저 노드에서 &lt;a href=&quot;https://ceph.com/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Ceph&lt;/a&gt; 스토리지를 실행하고 관리할 수 있는 기능이었습니다. 이러한 설정은 매우 비용 효율적입니다.&lt;/p&gt;
&lt;p&gt;우리가 시작할 때는 KVM에 대한 상업적 지원을 제공하는 최초의 회사 중 하나였습니다. KVM 프로젝트 자체는 지속적으로 발전했으며, 현재는 널리 사용되는 하이퍼바이저입니다. 각 릴리즈마다 새로운 기능이 추가됩니다. 우리는 모든 스토리지 유형에서 스냅샷 백업을 생성할 수 있는 KVM 라이브 백업 기능을 개발했습니다.&lt;/p&gt;
&lt;p&gt;버전 4.0에서 가장 눈에 띄는 변화는 OpenVZ에서 &lt;a href=&quot;https://linuxcontainers.org/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;LXC&lt;/a&gt;로의 이동이었습니다. 이제 컨테이너는 깊이 통합되어 있으며, 가상 머신과 동일한 스토리지 및 네트워크 기능을 사용할 수 있습니다.&lt;/p&gt;
&lt;h2 id=&quot;112-proxmox-ve-문서-개선&quot; style=&quot;position:relative;&quot;&gt;1.12. Proxmox VE 문서 개선&lt;a href=&quot;#112-proxmox-ve-%EB%AC%B8%EC%84%9C-%EA%B0%9C%EC%84%A0&quot; aria-label=&quot;112 proxmox ve 문서 개선 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Proxmox VE 문서에 대한 기여와 개선은 항상 환영합니다. 기여하는 방법에는 여러 가지가 있습니다.&lt;/p&gt;
&lt;p&gt;문서에서 오류를 발견하거나 개선할 부분이 있다고 생각되면, &lt;a href=&quot;https://bugzilla.proxmox.com/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Proxmox 버그 트래커&lt;/a&gt;에 버그를 등록하여 수정 제안을 해주십시오.&lt;/p&gt;
&lt;p&gt;새로운 콘텐츠를 제안하고 싶다면, 다음 옵션 중 하나를 선택하십시오:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;위키: 특정 설정, 사용 방법 가이드, 또는 튜토리얼에 대한 기여는 위키가 적절한 옵션입니다.&lt;/li&gt;
&lt;li&gt;참고 문서: 모든 사용자에게 도움이 될 일반적인 콘텐츠는 참고 문서에 기여하는 것이 좋습니다. 여기에는 Proxmox VE 기능의 설치, 구성, 사용 및 문제 해결 방법에 대한 모든 정보가 포함됩니다. 참고 문서는 &lt;a href=&quot;https://en.wikipedia.org/wiki/AsciiDoc&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;asciidoc&lt;/a&gt; 형식으로 작성됩니다. 문서를 편집하려면 git 저장소를 클론해야 합니다. git://git.proxmox.com/git/pve-docs.git; 그런 다음 &lt;a href=&quot;https://git.proxmox.com/?p=pve-docs.git;a=blob_plain;f=README.adoc;hb=HEAD&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;README.adoc&lt;/a&gt; 문서를 따르십시오.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Proxmox VE 코드베이스 작업에 관심이 있다면, &lt;a href=&quot;https://pve.proxmox.com/wiki/Developer_Documentation&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;개발자 문서&lt;/a&gt; 위키 글이 시작하는 방법을 안내해 드릴 것입니다.&lt;/p&gt;
&lt;h2 id=&quot;113-proxmox-ve-번역&quot; style=&quot;position:relative;&quot;&gt;1.13. Proxmox VE 번역&lt;a href=&quot;#113-proxmox-ve-%EB%B2%88%EC%97%AD&quot; aria-label=&quot;113 proxmox ve 번역 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Proxmox VE 사용자 인터페이스는 기본적으로 영어로 제공됩니다. 그러나 커뮤니티의 기여 덕분에 다른 언어로의 번역도 가능합니다. 새로운 언어 추가, 최신 기능 번역, 불완전하거나 일관성이 없는 번역 개선에 대한 지원을 환영합니다.&lt;/p&gt;
&lt;p&gt;번역 파일 관리를 위해 &lt;a href=&quot;https://www.gnu.org/software/gettext/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;gettext&lt;/a&gt;를 사용합니다. &lt;a href=&quot;https://poedit.net/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Poedit&lt;/a&gt;과 같은 도구는 번역 파일을 편집하기 위한 멋진 사용하 인터페이스를 제공하지만, 사용하기 편한 편집기를 사용해도 됩니다. 번역에는 프로그래밍 지식이 필요하지 않습니다.&lt;/p&gt;
&lt;h3 id=&quot;1131-git을-사용한-번역&quot; style=&quot;position:relative;&quot;&gt;1.13.1. git을 사용한 번역&lt;a href=&quot;#1131-git%EC%9D%84-%EC%82%AC%EC%9A%A9%ED%95%9C-%EB%B2%88%EC%97%AD&quot; aria-label=&quot;1131 git을 사용한 번역 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;언어 파일은 &lt;a href=&quot;https://git.proxmox.com/?p=proxmox-i18n.git&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;git 저장소&lt;/a&gt;로 제공됩니다. git에 익숙한 경우, &lt;a href=&quot;https://pve.proxmox.com/wiki/Developer_Documentation&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;개발자 문서&lt;/a&gt;에 따라 기여하십시오.&lt;/p&gt;
&lt;p&gt;새 번역을 만들려면 다음을 수행하십시오.(&lt;LANG&gt;을 언어 ID로 대체):&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;git clone git://git.proxmox.com/git/proxmox-i18n.git
cd proxmox-i18n
make init-&amp;lt;LANG&amp;gt;.po&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;기존에 있던 언어를 편집하려면 원하는 편집기를 사용하여 다음을 수행하십시오.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;poedit &amp;lt;LANG&amp;gt;.po&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;1132-git-없이-번역&quot; style=&quot;position:relative;&quot;&gt;1.13.2 git 없이 번역&lt;a href=&quot;#1132-git-%EC%97%86%EC%9D%B4-%EB%B2%88%EC%97%AD&quot; aria-label=&quot;1132 git 없이 번역 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;git에 익숙하지 않아도 Proxmox VE 번역에 기여할 수 있습니다. 시작하려면 &lt;a href=&quot;https://git.proxmox.com/?p=proxmox-i18n.git;a=tree&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;여기&lt;/a&gt;에서 언어 파일을 다운로드하십시오. 개선하고자 하는 언어를 찾아 해당 언어 파일의 “raw” 링크를 우클릭하고 “다른 이름으로 저장…”을 선택하십시오. 파일을 변경한 후 최종 번역을 서명된 &lt;a href=&quot;https://pve.proxmox.com/wiki/Developer_Documentation#Software_License_and_Copyright&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;기여자 라이센스 계약서&lt;/a&gt;와 함께 office(at)proxmox.com으로 직접 보내십시오.&lt;/p&gt;
&lt;h3 id=&quot;1133-번역-테스트&quot; style=&quot;position:relative;&quot;&gt;1.13.3 번역 테스트&lt;a href=&quot;#1133-%EB%B2%88%EC%97%AD-%ED%85%8C%EC%8A%A4%ED%8A%B8&quot; aria-label=&quot;1133 번역 테스트 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;번역을 Proxmox VE에서 사용하려면 먼저 .po 파일을 .js 파일로 변환해야 합니다. 같은 저장소에 있는 다음 스크립트를 호출하여 이 작업을 수행할 수 있습니다:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;./po2js.pl -t pve xx.po &amp;gt;pve-lang-xx.js&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;생성된 파일 &lt;code class=&quot;language-text&quot;&gt;pve-lang-xx.js&lt;/code&gt;를 Proxmox 서버의 &lt;code class=&quot;language-text&quot;&gt;/usr/share/pve-i18n&lt;/code&gt; 디렉토리에 복사하여 테스트할 수 있습니다.&lt;/p&gt;
&lt;p&gt;또는 저장소의 루트에서 다음 명령을 실행하여 deb 패키지를 빌드할 수 있습니다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;make deb&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;중요: 이러한 방법 중 어느 것이든 작동하려면 시스템에 다음 perl 패키지가 설치되어 있어야 합니다. Debian/Ubuntu에서는 다음과 같이 설치할 수 있습니다:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;apt-get install perl liblocale-po-perl libjson-perl&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;1134-번역-보내기&quot; style=&quot;position:relative;&quot;&gt;1.13.4. 번역 보내기&lt;a href=&quot;#1134-%EB%B2%88%EC%97%AD-%EB%B3%B4%EB%82%B4%EA%B8%B0&quot; aria-label=&quot;1134 번역 보내기 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;완성된 번역(.po 파일)을 서명된 기여자 라이센스 계약서와 함께 office(at)proxmox.com으로 Proxmox 팀에 보낼 수 있습니다. 개발 경험이 있는 경우, 패치로 작성하여 Proxmox VE 개발 메일링 리스트에 보낼 수도 있습니다. 자세한 내용은 &lt;a href=&quot;https://pve.proxmox.com/wiki/Developer_Documentation&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;개발자 문서&lt;/a&gt;를 참조하십시오.&lt;/p&gt;
&lt;h1 id=&quot;후기&quot; style=&quot;position:relative;&quot;&gt;후기&lt;a href=&quot;#%ED%9B%84%EA%B8%B0&quot; aria-label=&quot;후기 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;지금까지는 &lt;a href=&quot;#12-%EC%9C%A0%EC%97%B0%ED%95%9C-%EC%8A%A4%ED%86%A0%EB%A6%AC%EC%A7%80-%EC%98%B5%EC%85%98&quot;&gt;1.2.&lt;/a&gt;에서 ZFS 로컬 스토리지에 VM 디스크 이미지를 올려서 사용했고, 큰 문제는 없었다. 하지만 최근에 인텔 N100 노드를 하나 추가하면서 클러스터링 작업을 진행하면서 마이그레이션 기능도 잘 사용하고 있다. 마이그레이션 작업은 VM/CT를 중단시키는 과정이 필수적인데, 작은 크기의 VM/CT를 마이그레이션 할때야 금방 가능하지만, 용량이 커진다면 문제가 발생할 것 같다. 그리고 이 방식은 양쪽 노드의 디스크 공간에 여유가 있어야 할 것이다. 하지만 CIFS 스토리지를 VM 이미지, CT에 사용한다면 이러한 다운타임을 해결할 수 있다고 하니 TrueNAS에 SSD만으로 구성된 전용 스토리지를 만들고 이것을 이용해 VM 이미지, CT를 저장하는 방법을 적용해봐야 겠다.&lt;/p&gt;
&lt;p&gt;또한 현재 여러 지인에게 Proxmox 계정을 생성해 주고, 서버를 사용할 수 있게 해줬는데, 결국에 reverse proxy나 제대로 된 네트워크 셋팅을 하려면 pfsense로의 접근도 필요하다, 하지만 이때 적절한 권한을 매번 생성하고 관리해 주는 것이 굉장히 귀찮고 어려웠다. Proxmox가 &lt;a href=&quot;#11-%EC%A4%91%EC%95%99-%EA%B4%80%EB%A6%AC&quot;&gt;REST API&lt;/a&gt;를 사용하여 다른 관리 도구로 쉽게 통합될 수 있다고 하니, pfsense의 API도 적절히 사용하고 &lt;a href=&quot;https://www.terraform.io/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Terraform&lt;/a&gt;을 이용해서 종합적으로 제어할 수 있는 환경을 만들어보고 싶다.&lt;/p&gt;
&lt;h1 id=&quot;참고&quot; style=&quot;position:relative;&quot;&gt;참고&lt;a href=&quot;#%EC%B0%B8%EA%B3%A0&quot; aria-label=&quot;참고 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;&lt;a href=&quot;https://pve.proxmox.com/pve-docs/pve-admin-guide.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Proxmox VE Administration Guide&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;글의 저작권과 관련된 사항은 Proxmox의 라이센스를 따릅니다.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[pfSense 2.7 업그레이드 후 Telegraf 오류 해결 방법]]></title><description><![CDATA[1 오류 pfSense CE 2.6 버전에서 2.7버전으로 업그레이드 한 이후로 위와 같은 에러가 지속적으로 발생하는 것을 발견했다. 그리고 원래 상단바 Service -> Telegraf를 선택해서 telegraf 설정을 GUI…]]></description><link>https://vulcan.site/pfsense-telegraf-error/</link><guid isPermaLink="false">https://vulcan.site/pfsense-telegraf-error/</guid><pubDate>Sun, 28 Jul 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h1 id=&quot;1-오류&quot; style=&quot;position:relative;&quot;&gt;1 오류&lt;a href=&quot;#1-%EC%98%A4%EB%A5%98&quot; aria-label=&quot;1 오류 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;pfSense CE 2.6 버전에서 2.7버전으로 업그레이드 한 이후로&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;PHP Fatal error: Uncaught TypeError: implode(): Argument #1 ($pieces) must be of type array, string given in /usr/local/pkg/telegraf.inc:132
Stack trace:
#0 /usr/local/pkg/telegraf.inc(132): implode(&apos;,&apos;, NULL)
#1 /etc/inc/pkg-utils.inc(709) : eval()&apos;d code(1): telegraf_resync_config()
#2 /etc/inc/pkg-utils.inc(709): eval()
#3 /etc/rc.start_packages(66): sync_package(&apos;Telegraf&apos;)
#4 {main}
thrown in /usr/local/pkg/telegraf.inc on line 132&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;위와 같은 에러가 지속적으로 발생하는 것을 발견했다. 그리고 원래 상단바 Service -&gt; Telegraf를 선택해서 telegraf 설정을 GUI로 관리할 수 있었는데, 이 Telegraf 선택지가 사라졌다. Telegraf는 pfSense에서 수집 정보들을 DB로 전송해 주는 역할을 한다. 하지만 이 오류가 발생하면 더 이상 telegraf가 작동하지 않는다. 하지만 telegraf를 한번 삭제한 이후에 pfSense를 재시작하고 재시작 직후 teletraf는설치하면 이전 설정대로 telegraf가 작동한다. 하지만 오류는 여전하고 GUI에의 접근 또한 불가능하다.&lt;/p&gt;
&lt;h1 id=&quot;2-왜-이런-오류가-생겼을까&quot; style=&quot;position:relative;&quot;&gt;2 왜 이런 오류가 생겼을까?&lt;a href=&quot;#2-%EC%99%9C-%EC%9D%B4%EB%9F%B0-%EC%98%A4%EB%A5%98%EA%B0%80-%EC%83%9D%EA%B2%BC%EC%9D%84%EA%B9%8C&quot; aria-label=&quot;2 왜 이런 오류가 생겼을까 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;h2 id=&quot;21-오류가-발생한-코드&quot; style=&quot;position:relative;&quot;&gt;2.1 오류가 발생한 코드&lt;a href=&quot;#21-%EC%98%A4%EB%A5%98%EA%B0%80-%EB%B0%9C%EC%83%9D%ED%95%9C-%EC%BD%94%EB%93%9C&quot; aria-label=&quot;21 오류가 발생한 코드 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;telegraf.inc&lt;/code&gt;파일에서 발생했다. 이 파일을 살펴보면 &lt;code class=&quot;language-text&quot;&gt;telegraf_resync_config&lt;/code&gt;작업을 수행하는데, 이는 설정값대로 &lt;code class=&quot;language-text&quot;&gt;/usr/local/etc/telegraf.conf&lt;/code&gt; 파일을 다시 동기화 해주는 코드가 작성돼 있다. 이 작업은 GUI에서 telegraf 설정값을 바꿨을 때, telegraf를 재설치 했을 때 동작한다. (추가로 다른 조건이 있을 수 있지만 이 두 조건은 확실하다.)&lt;/p&gt;
&lt;p&gt;먼저 error가 발생한 코드를 살펴보도록 하자. pfSense의 Edit File을 통해 살펴볼 수 있다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre class=&quot;language-php&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;//      /usr/local/pkg/telegraf.inc&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;/* Ping Monitor Configuration */&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$telegraf_conf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;ping_enable&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;empty&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$telegraf_conf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;ping_host_1&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                        &lt;span class=&quot;token variable&quot;&gt;$monitor_hosts&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;&quot;&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$telegraf_conf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;ping_host_1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;&quot;&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;empty&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$telegraf_conf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;ping_host_2&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                        &lt;span class=&quot;token variable&quot;&gt;$monitor_hosts&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;&quot;&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$telegraf_conf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;ping_host_2&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;&quot;&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;empty&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$telegraf_conf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;ping_host_3&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                        &lt;span class=&quot;token variable&quot;&gt;$monitor_hosts&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;&quot;&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$telegraf_conf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;ping_host_3&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;&quot;&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;empty&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$telegraf_conf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;ping_host_4&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                        &lt;span class=&quot;token variable&quot;&gt;$monitor_hosts&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;&quot;&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$telegraf_conf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;ping_host_4&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;&quot;&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

                &lt;span class=&quot;token variable&quot;&gt;$monitor_hosts&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;implode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;,&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$monitor_hosts&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;      &lt;span class=&quot;token comment&quot;&gt;// line 132&lt;/span&gt;

                &lt;span class=&quot;token variable&quot;&gt;$cfg&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.=&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;\n[[inputs.ping]]\n&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;token variable&quot;&gt;$cfg&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.=&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;\turls = [&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$monitor_hosts&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;]&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;token variable&quot;&gt;$cfg&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.=&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;\n\tdeadline = 0\n\n&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;/* deadline (-w) function not supported in BSD ping */&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;오류가 발생한 라인의 코드를 살펴보면 &lt;code class=&quot;language-text&quot;&gt;$telegraf_conf&lt;/code&gt;에서 &lt;code class=&quot;language-text&quot;&gt;ping_host_*&lt;/code&gt;의 값들을 가져와서 아래와 같은 형태로 만들어준다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;[[inputs.ping]]
	urls = [&quot;host.1.ip.addr&quot;,&quot;host.2.ip.addr&quot;,&quot;host.3.ip.addr&quot;,&quot;host.4.ip.addr&quot;]
	deadline = 0&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;이 부분은 telegraf가 ping메세지를 지정된 IP로 보내고 결과를 받아 목표로하는 서버가 살아있는지 확인할 수 있게 해준다. 필수적인 사항은 아니고, pfSense의 telegraf 설정에서 비활성화할 수 있다.&lt;/p&gt;
&lt;h2 id=&quot;22-오류가-발생한-곳&quot; style=&quot;position:relative;&quot;&gt;2.2 오류가 발생한 곳&lt;a href=&quot;#22-%EC%98%A4%EB%A5%98%EA%B0%80-%EB%B0%9C%EC%83%9D%ED%95%9C-%EA%B3%B3&quot; aria-label=&quot;22 오류가 발생한 곳 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;error 메시지에서는 &lt;code class=&quot;language-text&quot;&gt;telegraf.inc&lt;/code&gt;의 line 132에서 &lt;code class=&quot;language-text&quot;&gt;implode(&apos;,&apos;, NULL)&lt;/code&gt;때문에 error가 발생했음을 알 수 있다. &lt;code class=&quot;language-text&quot;&gt;telegraf.inc&lt;/code&gt;파일의 line 132를 보면 &lt;code class=&quot;language-text&quot;&gt;$monitor_hosts = implode(&quot;,&quot;, $monitor_hosts);&lt;/code&gt;라는 코드가 있는데, 여기서 &lt;code class=&quot;language-text&quot;&gt;$monitor_hosts&lt;/code&gt;가 &lt;code class=&quot;language-text&quot;&gt;NULL&lt;/code&gt;이라는 것이다. 왜 그럴까? 먼저 line 132 이전에 if 문에서 &lt;code class=&quot;language-text&quot;&gt;ping_host_*&lt;/code&gt;값들을 &lt;code class=&quot;language-text&quot;&gt;$monitor_hosts&lt;/code&gt; array에 추가해 주는 것을 알 수 있다. 그런데 만약 &lt;code class=&quot;language-text&quot;&gt;telegraf_conf&lt;/code&gt;에 &lt;code class=&quot;language-text&quot;&gt;ping_host_*&lt;/code&gt;값이 없다면? &lt;code class=&quot;language-text&quot;&gt;$monitor_hosts&lt;/code&gt;에는 아무것도 들어가지 않을 것이다. PHP에서는 변수가 명시적으로 초기화되지 않아도 사용될 때 자동으로 생성된다. 그러나 변수가 명시적으로 초기화되지 않은 경우 해당 변수는 &lt;code class=&quot;language-text&quot;&gt;NULL&lt;/code&gt; 값을 가질 수 있다. 때문에 if문을 지나면서 한 번도 조건을 만족하지 못했다면 &lt;code class=&quot;language-text&quot;&gt;$monitor_hosts&lt;/code&gt;는 &lt;code class=&quot;language-text&quot;&gt;NULL&lt;/code&gt;이 될 수 있다.&lt;/p&gt;
&lt;p&gt;pfSense CE 2.7은 PHP 8버전을 사용한다. PHP 8버전에서는 &lt;code class=&quot;language-text&quot;&gt;implode&lt;/code&gt;를 &lt;code class=&quot;language-text&quot;&gt;NULL&lt;/code&gt; 값과 함께 호출하는 것이 허용되지 않는다. 때문에 &lt;code class=&quot;language-text&quot;&gt;implode(&apos;,&apos;, NULL)&lt;/code&gt;과 같은 형식은 error를 발생시킨다.&lt;/p&gt;
&lt;h2 id=&quot;23-왜-업그레이드-이후에-에러가-발생했을까&quot; style=&quot;position:relative;&quot;&gt;2.3 왜 업그레이드 이후에 에러가 발생했을까?&lt;a href=&quot;#23-%EC%99%9C-%EC%97%85%EA%B7%B8%EB%A0%88%EC%9D%B4%EB%93%9C-%EC%9D%B4%ED%9B%84%EC%97%90-%EC%97%90%EB%9F%AC%EA%B0%80-%EB%B0%9C%EC%83%9D%ED%96%88%EC%9D%84%EA%B9%8C&quot; aria-label=&quot;23 왜 업그레이드 이후에 에러가 발생했을까 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;pfSense CE 2.7 업그레이드 노트를 살펴보면 PHP 버전이 7.4.X 버전에서 8.2.6 버전으로 업그레이드된 것을 알 수 있다. PHP 7버전에서는 &lt;code class=&quot;language-text&quot;&gt;implode&lt;/code&gt;를 &lt;code class=&quot;language-text&quot;&gt;NULL&lt;/code&gt; 값과 함께 호출하는 것이 허용됐다. 구현에 따라 &lt;code class=&quot;language-text&quot;&gt;implode&lt;/code&gt;의 반환 값이 &lt;code class=&quot;language-text&quot;&gt;NULL&lt;/code&gt; 또는 빈 문자열이 된다. 때문에 &lt;code class=&quot;language-text&quot;&gt;$monitor_hosts&lt;/code&gt;에 아무것도 들어가지 않았다고 하더라도 error가 발생하지 않는다.&lt;/p&gt;
&lt;p&gt;하지만 위에서 설명한 것과 같이 PHP 8버전에서는 더 엄격한 type검사를 시행하고, 때문에 &lt;code class=&quot;language-text&quot;&gt;implode&lt;/code&gt;를 &lt;code class=&quot;language-text&quot;&gt;NULL&lt;/code&gt; 값과 함께 호출하면 error가 발생한다. 그 때문에 pfSense 2.6에서 2.7버전으로 업그레이드를 하면서, PHP 버전이 8버전으로 업그레이드됐고, 이것이 문제를 일으킨 것이다.&lt;/p&gt;
&lt;h2 id=&quot;24-이것은-왜-방지되지-않았을까&quot; style=&quot;position:relative;&quot;&gt;2.4 이것은 왜 방지되지 않았을까?&lt;a href=&quot;#24-%EC%9D%B4%EA%B2%83%EC%9D%80-%EC%99%9C-%EB%B0%A9%EC%A7%80%EB%90%98%EC%A7%80-%EC%95%8A%EC%95%98%EC%9D%84%EA%B9%8C&quot; aria-label=&quot;24 이것은 왜 방지되지 않았을까 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;우선 telegraf는 urls가 비어있다고 하더라도 아무런 문제 없이 동작한다. &lt;code class=&quot;language-text&quot;&gt;telegraf/plugins/inputs/ping/ping.go&lt;/code&gt;을 보자.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;go&quot;&gt;&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;p &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;Ping&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Gather&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;acc telegraf&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Accumulator&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;error&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; host &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;range&lt;/span&gt; p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Urls &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;wg&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Add&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
		&lt;span class=&quot;token keyword&quot;&gt;go&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;host &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
			&lt;span class=&quot;token keyword&quot;&gt;defer&lt;/span&gt; p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;wg&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Done&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

			&lt;span class=&quot;token keyword&quot;&gt;switch&lt;/span&gt; p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Method &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
			&lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;native&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
				p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pingToURLNative&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;host&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; acc&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
			&lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
				p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pingToURL&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;host&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; acc&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
			&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
		&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;host&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

	p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;wg&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Wait&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

	&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;nil&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;여기서 ping을 시도한다. 여기서 &lt;code class=&quot;language-text&quot;&gt;p.Urls&lt;/code&gt;가 비어있다고 하더라도, ping작업을 수행하지 않을 뿐 문제는 생기지 않는다. &lt;code class=&quot;language-text&quot;&gt;p.wg.Add(1)&lt;/code&gt;과 &lt;code class=&quot;language-text&quot;&gt;p.wg.Done()&lt;/code&gt;역시 호출되지 않기에 &lt;code class=&quot;language-text&quot;&gt;p.wg.wait()&lt;/code&gt;이 즉시 호출된다. 그 때문에 동기화 문제도 발생하지 않는다.&lt;/p&gt;
&lt;p&gt;지금은 pfSense의 Telegraf 설정에서 &lt;code class=&quot;language-text&quot;&gt;Enable Ping Monitor&lt;/code&gt;옵션을 켜고 &lt;code class=&quot;language-text&quot;&gt;Ping Host&lt;/code&gt;에 아무것도 적지 않고 저장하면 아래와 같은 Crash Report를 내보낸다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;PHP Fatal error:  Uncaught TypeError: implode(): Argument #1 ($array) must be of type array, string given in /usr/local/pkg/telegraf.inc:132
Stack trace:
#0 /usr/local/pkg/telegraf.inc(132): implode()
#1 /usr/local/www/pkg_edit.PHP(245) : eval()&apos;d code(1): telegraf_resync_config()
#2 /usr/local/www/pkg_edit.PHP(245): eval()
#3 {main}
  thrown in /usr/local/pkg/telegraf.inc on line 132&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;하지만 이것은 위에서 서술한 PHP error가 발생해서 나온 Crash Report일 뿐이지, pfSense에서 Telegraf 설정 GUI에서 Save를 눌렀을 때 pfSense가 자체적으로 format을 검증하고 에러를 내는 것이 아니다. 그 때문에 pfSense CE 2.6버전에서는 Crash Report 없이 정상적으로 저장됐을 것이다.&lt;/p&gt;
&lt;p&gt;Ping Host는 입력하는 창은 아래와 같이 돼 있다.
&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 597px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/afd1b2058875356d65d585ade9002da9/17602/Ping_Host_input.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 36.075949367088604%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAYAAAAIy204AAAACXBIWXMAAA7DAAAOwwHHb6hkAAABMUlEQVQoz4WRuW7CQBRF/VVIBAVbdrxipHjHxs4XRATsmpY4rAIkKioQDT95opkmqaA4Gs28W5z7Rnnt98lHBVVVkec55bhAMyz6dsTQ9xgMBvi+j+M62LYt767rSoa+j+d5vHS7dDoder0eiqqqWKYlB6NRThSGmJbN51dD09Q0TUNd15LZbCbP/2+CyWQiZ2VZomiahqapvJkmWTYiDAIcx+an/Wa73bJer9lsNg8RmePxyHQ6RdENg/KjIksz0jQlL3JZZ7VacTgc2O/3T9ntdpxOJ2mp6LpOkqaEQUgSxyRpIvfVtq0MCgNh+giR+TPUdeIkIXgPiKKIOI5wHIfFYiGDwlRUesRyuZSmYpeKISpXFVmWURQF43Isf/J8PnO73bher0+5XC7c73fm8zm/OmxGSx2qDhIAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;Ping Host Input&quot;
        title=&quot;Ping Host Input&quot;
        src=&quot;/static/afd1b2058875356d65d585ade9002da9/17602/Ping_Host_input.png&quot;
        srcset=&quot;/static/afd1b2058875356d65d585ade9002da9/c26ae/Ping_Host_input.png 158w,
/static/afd1b2058875356d65d585ade9002da9/6bdcf/Ping_Host_input.png 315w,
/static/afd1b2058875356d65d585ade9002da9/17602/Ping_Host_input.png 597w&quot;
        sizes=&quot;(max-width: 597px) 100vw, 597px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;여기서 분명 &lt;code class=&quot;language-text&quot;&gt;Ping Host 1&lt;/code&gt;은 &lt;code class=&quot;language-text&quot;&gt;(optional)&lt;/code&gt;표시가 없다. 그런데 비우고 저장해도 pfSense에서는 경고를 보내지 않는다. pfSense 2.7버전 이전에서 &lt;code class=&quot;language-text&quot;&gt;Enable Ping Monitor&lt;/code&gt; 옵션을 켜고 &lt;code class=&quot;language-text&quot;&gt;Ping Host&lt;/code&gt;에 아무것도 적지 않고 저장한 사람들은 모두 같은 오류가 발생했을 것이다. 또한 이 오류에 대해서 여러 버그 리포트를 봤는데, 많은 사람들은 해당 문제를 재현하지 못했다고 말하고 있었다. 이것은 아마도 &lt;code class=&quot;language-text&quot;&gt;Enable Ping Monitor&lt;/code&gt; 옵션이 꺼진 상태에서 pfSense 2.6에서 2.7버전으로 업그레이드했기 때문에 문제가 발생하지 않았을 것으로 생각된다.&lt;/p&gt;
&lt;h1 id=&quot;3-어떻게-해결할까&quot; style=&quot;position:relative;&quot;&gt;3 어떻게 해결할까?&lt;a href=&quot;#3-%EC%96%B4%EB%96%BB%EA%B2%8C-%ED%95%B4%EA%B2%B0%ED%95%A0%EA%B9%8C&quot; aria-label=&quot;3 어떻게 해결할까 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;h2 id=&quot;31-ping-host에-ip-추가&quot; style=&quot;position:relative;&quot;&gt;3.1 Ping Host에 IP 추가&lt;a href=&quot;#31-ping-host%EC%97%90-ip-%EC%B6%94%EA%B0%80&quot; aria-label=&quot;31 ping host에 ip 추가 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;위에서 설명했듯이 &lt;code class=&quot;language-text&quot;&gt;Ping Host&lt;/code&gt;에 IP가 하나도 들어있지 않아서 발생하는 문제다. 때문에 &lt;code class=&quot;language-text&quot;&gt;Ping Host&lt;/code&gt;에 한 개 이상 IP를 추가하면 오류를 해결할 수 있다. 그런데 앞서 &lt;a href=&quot;#1-%EC%98%A4%EB%A5%98&quot;&gt;1 오류&lt;/a&gt;에서 “GUI로 관리할 수 있었는데, 이 Telegraf 선택지가 사라졌다.”라고 했다. 그럼 어떻게 설정을 수정할 수 있을까?&lt;/p&gt;
&lt;p&gt;pfSense는 &lt;code class=&quot;language-text&quot;&gt;/conf/config.xml&lt;/code&gt;이 모든 package들의 configuration이 저장된다. 이 파일을 열어보면 &lt;code class=&quot;language-text&quot;&gt;&amp;lt;telegraf&gt;&lt;/code&gt;에 &lt;code class=&quot;language-text&quot;&gt;&amp;lt;ping_host_1&gt;&amp;lt;/ping_host_1&gt;&lt;/code&gt;항목이 있다. 여기에 아래와 같이 IP를 추가하고 저장해주면 된다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;xml&quot;&gt;&lt;pre class=&quot;language-xml&quot;&gt;&lt;code class=&quot;language-xml&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;ping_host_1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;db.server.ip.addr&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;ping_host_1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;32-ping-monitor-옵션-비활성화&quot; style=&quot;position:relative;&quot;&gt;3.2 Ping Monitor 옵션 비활성화&lt;a href=&quot;#32-ping-monitor-%EC%98%B5%EC%85%98-%EB%B9%84%ED%99%9C%EC%84%B1%ED%99%94&quot; aria-label=&quot;32 ping monitor 옵션 비활성화 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;위에 &lt;a href=&quot;#21-%EC%98%A4%EB%A5%98%EA%B0%80-%EB%B0%9C%EC%83%9D%ED%95%9C-%EC%BD%94%EB%93%9C&quot;&gt;코드&lt;/a&gt;를 살펴보면 &lt;code class=&quot;language-text&quot;&gt;if ($telegraf_conf[&quot;ping_enable&quot;]) {&lt;/code&gt;여기에 &lt;code class=&quot;language-text&quot;&gt;ping_enable&lt;/code&gt;옵션이 켜져 있는지 확인하는 코드가 있다. 만약 Ping Monitor 옵션이 커져있다면, 문제가 되는 line 132 또한 실행되지 않을 것이다. 이 또한 &lt;code class=&quot;language-text&quot;&gt;/conf/config.xml&lt;/code&gt;에 &lt;code class=&quot;language-text&quot;&gt;&amp;lt;ping_enable&gt;on&amp;lt;/ping_enable&gt;&lt;/code&gt;항목이 있다. 여기서 아래와 같이 &lt;code class=&quot;language-text&quot;&gt;on&lt;/code&gt;을 지워주면 Ping Monitor 옵션을 비활성화한 것이다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;xml&quot;&gt;&lt;pre class=&quot;language-xml&quot;&gt;&lt;code class=&quot;language-xml&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;ping_enable&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;ping_enable&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;이것으로 오류를 해결할 수 있다.&lt;/p&gt;
&lt;h2 id=&quot;33-telegrafinc-변경&quot; style=&quot;position:relative;&quot;&gt;3.3 telegraf.inc 변경&lt;a href=&quot;#33-telegrafinc-%EB%B3%80%EA%B2%BD&quot; aria-label=&quot;33 telegrafinc 변경 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;처음에는 문제의 근본적인 원인인 &lt;code class=&quot;language-text&quot;&gt;telegraf.inc&lt;/code&gt; 파일을 변경해서 해결할 수 있다고 생각했다. 하지만 &lt;code class=&quot;language-text&quot;&gt;telegraf.inc&lt;/code&gt; 파일은 package를 재설치하거나 pfSense를 재부팅할 때 다시 서버에서 가져온다. 그 때문에 수정은 영구적이지 않다. 또한 &lt;code class=&quot;language-text&quot;&gt;telegraf.inc&lt;/code&gt; 파일을 수정하고 해당 패키지를 재실행할 방법 또한 마땅치 않다. 하지만 근본적으로는 이 부분이 해결돼야 한다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre class=&quot;language-php&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;        &lt;span class=&quot;token comment&quot;&gt;/* Ping Monitor Configuration */&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$telegraf_conf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;ping_enable&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token variable&quot;&gt;$monitor_hosts&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;empty&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$telegraf_conf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;ping_host_1&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                        &lt;span class=&quot;token variable&quot;&gt;$monitor_hosts&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;&quot;&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$telegraf_conf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;ping_host_1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;&quot;&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;empty&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$telegraf_conf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;ping_host_2&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                        &lt;span class=&quot;token variable&quot;&gt;$monitor_hosts&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;&quot;&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$telegraf_conf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;ping_host_2&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;&quot;&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;empty&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$telegraf_conf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;ping_host_3&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                        &lt;span class=&quot;token variable&quot;&gt;$monitor_hosts&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;&quot;&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$telegraf_conf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;ping_host_3&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;&quot;&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;empty&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$telegraf_conf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;ping_host_4&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                        &lt;span class=&quot;token variable&quot;&gt;$monitor_hosts&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;&quot;&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$telegraf_conf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;ping_host_4&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;&quot;&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

                &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;empty&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$monitor_hosts&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;token variable&quot;&gt;$monitor_hosts&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;implode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;,&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$monitor_hosts&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;      &lt;span class=&quot;token comment&quot;&gt;// line 132&lt;/span&gt;

                    &lt;span class=&quot;token variable&quot;&gt;$cfg&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.=&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;\n[[inputs.ping]]\n&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                    &lt;span class=&quot;token variable&quot;&gt;$cfg&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.=&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;\turls = [&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$monitor_hosts&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;]&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                    &lt;span class=&quot;token variable&quot;&gt;$cfg&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.=&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;\n\tdeadline = 0\n\n&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;/* deadline (-w) function not supported in BSD ping */&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;위와 같이 &lt;code class=&quot;language-text&quot;&gt;$monitor_hosts&lt;/code&gt;를 &lt;code class=&quot;language-text&quot;&gt;array()&lt;/code&gt;로 초기화하고 빈 배열인지 확인하고 다음 과정을 진행하면 될 것이다.&lt;/p&gt;
&lt;p&gt;이 해결 방법을 떠올리고 해당 패키지에 기여를 하고 싶어서 검색하다 pfSense package 저장소를 발견했는데, 완전히 같은 방법으로 이미 &lt;a href=&quot;https://github.com/pfsense/FreeBSD-ports/blob/devel/net-mgmt/pfSense-pkg-Telegraf/files/usr/local/pkg/telegraf.inc&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;해결&lt;/a&gt;돼 있어서 놀랐다. 조금 더 관심을 두고 빨리 해결하고자 했으면 좋았을 것 같다. 또한 pfSense CE 2.8.0, pfSense Plus 24.08버전에서는 해당 패치가 포함돼 문제가 해결될 것 같다.&lt;/p&gt;
&lt;h1 id=&quot;후기&quot; style=&quot;position:relative;&quot;&gt;후기&lt;a href=&quot;#%ED%9B%84%EA%B8%B0&quot; aria-label=&quot;후기 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;이 문제는 pfSense CE 2.7버전 업데이트 직후 부터 보고됐었다. 하지만 그동안 해결 방법이 알려지지 않았고, 최근에 발견한 이 &lt;a href=&quot;https://redmine.pfSense.org/issues/14861&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;문서&lt;/a&gt; 이외에는 해결 방법을 찾을 수 없었다. 그리고 해당 문서에서 또한 친절한 해결 절차에 대해서는 쓰여있지 않았다. 때문에 이 글을 작성하게 됐다. 같은 오류로 많은 스트레스를 받은 사람들이 이 글로 오류를 해결했기를 바란다.&lt;/p&gt;
&lt;p&gt;이 글에는 표현이 이상하거나 틀린 내용이 있을 수 있습니다. 모든 지적은 환영합니다.&lt;/p&gt;
&lt;h1 id=&quot;참고&quot; style=&quot;position:relative;&quot;&gt;참고&lt;a href=&quot;#%EC%B0%B8%EA%B3%A0&quot; aria-label=&quot;참고 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/influxdata/telegraf/tree/master/plugins/inputs/ping&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;telegraf inputs.ping&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.PHP.net/manual/en/function.implode.PHP&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;PHP implode&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.PHP.net/manual/en/migration80.incompatible.PHP&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;PHP manual Backward Incompatible Changes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.netgate.com/pfSense/en/latest/releases/2-7-0.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;pfSense CE 2.7 upgrade note&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://redmine.pfSense.org/issues/14861&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;pfSense issues&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/pfsense/FreeBSD-ports/blob/devel/net-mgmt/pfSense-pkg-Telegraf/files/usr/local/pkg/telegraf.inc&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;issue fixed&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[How to Fix Telegraf Errors After Upgrading to pfSense 2.7]]></title><description><![CDATA[1 Error After upgrading from pfSense CE version 2.6 to version 2.7, I encountered the following error continuously: Additionally, I noticed…]]></description><link>https://vulcan.site/pfsense-telegraf-error/en/</link><guid isPermaLink="false">https://vulcan.site/pfsense-telegraf-error/en/</guid><pubDate>Sun, 28 Jul 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h1 id=&quot;1-error&quot; style=&quot;position:relative;&quot;&gt;1 Error&lt;a href=&quot;#1-error&quot; aria-label=&quot;1 error permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;After upgrading from pfSense CE version 2.6 to version 2.7, I encountered the following error continuously:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;PHP Fatal error: Uncaught TypeError: implode(): Argument #1 ($pieces) must be of type array, string given in /usr/local/pkg/telegraf.inc:132
Stack trace:
#0 /usr/local/pkg/telegraf.inc(132): implode(&apos;,&apos;, NULL)
#1 /etc/inc/pkg-utils.inc(709) : eval()&apos;d code(1): telegraf_resync_config()
#2 /etc/inc/pkg-utils.inc(709): eval()
#3 /etc/rc.start_packages(66): sync_package(&apos;Telegraf&apos;)
#4 {main}
thrown in /usr/local/pkg/telegraf.inc on line 132&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Additionally, I noticed that the option to manage Telegraf settings through the GUI, which was previously accessible under Service -&gt; Telegraf, has disappeared. Telegraf in pfSense is responsible for sending collected information to a database. However, with this error, Telegraf no longer functions.&lt;/p&gt;
&lt;p&gt;By uninstalling Telegraf, restarting pfSense, and then reinstalling Telegraf immediately after the restart, it resumes working with the previous settings. Despite this, the error persists and GUI access remains unavailable.&lt;/p&gt;
&lt;h1 id=&quot;2-why-does-this-error-occur&quot; style=&quot;position:relative;&quot;&gt;2 Why Does This Error Occur?&lt;a href=&quot;#2-why-does-this-error-occur&quot; aria-label=&quot;2 why does this error occur permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;h2 id=&quot;21-code-causing-the-error&quot; style=&quot;position:relative;&quot;&gt;2.1 Code Causing the Error&lt;a href=&quot;#21-code-causing-the-error&quot; aria-label=&quot;21 code causing the error permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The error occurs in the &lt;code class=&quot;language-text&quot;&gt;telegraf.inc&lt;/code&gt; file. This file contains the code responsible for performing the &lt;code class=&quot;language-text&quot;&gt;telegraf_resync_config&lt;/code&gt; task, which resynchronizes the &lt;code class=&quot;language-text&quot;&gt;/usr/local/etc/telegraf.conf&lt;/code&gt; file according to the configuration values. This task is executed when Telegraf settings are changed via the GUI or when Telegraf is reinstalled (there might be additional conditions, but these two are confirmed).&lt;/p&gt;
&lt;p&gt;First, let’s examine the code where the error occurs. You can view this using pfSense’s Edit File feature.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre class=&quot;language-php&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;//      /usr/local/pkg/telegraf.inc&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;/* Ping Monitor Configuration */&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$telegraf_conf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;ping_enable&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;empty&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$telegraf_conf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;ping_host_1&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                        &lt;span class=&quot;token variable&quot;&gt;$monitor_hosts&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;&quot;&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$telegraf_conf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;ping_host_1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;&quot;&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;empty&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$telegraf_conf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;ping_host_2&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                        &lt;span class=&quot;token variable&quot;&gt;$monitor_hosts&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;&quot;&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$telegraf_conf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;ping_host_2&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;&quot;&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;empty&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$telegraf_conf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;ping_host_3&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                        &lt;span class=&quot;token variable&quot;&gt;$monitor_hosts&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;&quot;&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$telegraf_conf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;ping_host_3&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;&quot;&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;empty&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$telegraf_conf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;ping_host_4&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                        &lt;span class=&quot;token variable&quot;&gt;$monitor_hosts&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;&quot;&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$telegraf_conf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;ping_host_4&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;&quot;&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

                &lt;span class=&quot;token variable&quot;&gt;$monitor_hosts&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;implode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;,&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$monitor_hosts&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;      &lt;span class=&quot;token comment&quot;&gt;// line 132&lt;/span&gt;

                &lt;span class=&quot;token variable&quot;&gt;$cfg&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.=&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;\n[[inputs.ping]]\n&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;token variable&quot;&gt;$cfg&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.=&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;\turls = [&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$monitor_hosts&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;]&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;token variable&quot;&gt;$cfg&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.=&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;\n\tdeadline = 0\n\n&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;/* deadline (-w) function not supported in BSD ping */&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Examining the code at the line where the error occurs, the values of &lt;code class=&quot;language-text&quot;&gt;ping_host_*&lt;/code&gt; are fetched from &lt;code class=&quot;language-text&quot;&gt;$telegraf_conf&lt;/code&gt; and formatted as follows:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;[[inputs.ping]]
	urls = [&quot;host.1.ip.addr&quot;,&quot;host.2.ip.addr&quot;,&quot;host.3.ip.addr&quot;,&quot;host.4.ip.addr&quot;]
	deadline = 0&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This section allows Telegraf to send ping messages to specified IP addresses and receive results to verify if the target servers are alive. It is not a mandatory feature and can be disabled in the pfSense Telegraf settings.&lt;/p&gt;
&lt;h2 id=&quot;22-location-of-the-error&quot; style=&quot;position:relative;&quot;&gt;2.2 Location of the Error&lt;a href=&quot;#22-location-of-the-error&quot; aria-label=&quot;22 location of the error permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The error message indicates that the error occurs at line 132 of &lt;code class=&quot;language-text&quot;&gt;telegraf.inc&lt;/code&gt; due to &lt;code class=&quot;language-text&quot;&gt;implode(&apos;,&apos;, NULL)&lt;/code&gt;. When examining line 132 of the &lt;code class=&quot;language-text&quot;&gt;telegraf.inc&lt;/code&gt; file, the code &lt;code class=&quot;language-text&quot;&gt;$monitor_hosts = implode(&quot;,&quot;, $monitor_hosts);&lt;/code&gt; is found, implying that &lt;code class=&quot;language-text&quot;&gt;$monitor_hosts&lt;/code&gt; is &lt;code class=&quot;language-text&quot;&gt;NULL&lt;/code&gt;. Why does this happen? Before line 132, the &lt;code class=&quot;language-text&quot;&gt;if&lt;/code&gt; statements attempt to add &lt;code class=&quot;language-text&quot;&gt;ping_host_*&lt;/code&gt; values to the &lt;code class=&quot;language-text&quot;&gt;$monitor_hosts&lt;/code&gt; array. If there are no &lt;code class=&quot;language-text&quot;&gt;ping_host_*&lt;/code&gt; values in &lt;code class=&quot;language-text&quot;&gt;telegraf_conf&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;$monitor_hosts&lt;/code&gt; remains empty.&lt;/p&gt;
&lt;p&gt;In PHP, variables are automatically created when they are first used, even if they are not explicitly initialized. However, if a variable is not explicitly initialized, it can have a &lt;code class=&quot;language-text&quot;&gt;NULL&lt;/code&gt; value. Therefore, if none of the conditions in the &lt;code class=&quot;language-text&quot;&gt;if&lt;/code&gt; statements are satisfied, &lt;code class=&quot;language-text&quot;&gt;$monitor_hosts&lt;/code&gt; can end up being &lt;code class=&quot;language-text&quot;&gt;NULL&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;pfSense CE 2.7 uses PHP version 8. In PHP 8, calling &lt;code class=&quot;language-text&quot;&gt;implode&lt;/code&gt; with a &lt;code class=&quot;language-text&quot;&gt;NULL&lt;/code&gt; value is not allowed. As a result, the format &lt;code class=&quot;language-text&quot;&gt;implode(&apos;,&apos;, NULL)&lt;/code&gt; will trigger an error.&lt;/p&gt;
&lt;p&gt;This change in PHP’s behavior means that the previously acceptable code now results in an error in pfSense 2.7. The solution involves ensuring that &lt;code class=&quot;language-text&quot;&gt;$monitor_hosts&lt;/code&gt; is always initialized as an array before it is used in the &lt;code class=&quot;language-text&quot;&gt;implode&lt;/code&gt; function. This can be done by initializing &lt;code class=&quot;language-text&quot;&gt;$monitor_hosts&lt;/code&gt; as an empty array before the &lt;code class=&quot;language-text&quot;&gt;if&lt;/code&gt; statements.&lt;/p&gt;
&lt;h2 id=&quot;23-why-did-the-error-occur-after-the-upgrade&quot; style=&quot;position:relative;&quot;&gt;2.3 Why Did the Error Occur After the Upgrade?&lt;a href=&quot;#23-why-did-the-error-occur-after-the-upgrade&quot; aria-label=&quot;23 why did the error occur after the upgrade permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Reviewing the pfSense CE 2.7 upgrade notes, it becomes clear that the PHP version was upgraded from 7.4.X to 8.2.6. In PHP 7, it was permissible to call &lt;code class=&quot;language-text&quot;&gt;implode&lt;/code&gt; with a &lt;code class=&quot;language-text&quot;&gt;NULL&lt;/code&gt; value. Depending on the implementation, the return value of &lt;code class=&quot;language-text&quot;&gt;implode&lt;/code&gt; could be either &lt;code class=&quot;language-text&quot;&gt;NULL&lt;/code&gt; or an empty string. Therefore, even if &lt;code class=&quot;language-text&quot;&gt;$monitor_hosts&lt;/code&gt; contained nothing, no error would occur.&lt;/p&gt;
&lt;p&gt;However, as previously explained, PHP 8 enforces stricter type checking. As a result, calling &lt;code class=&quot;language-text&quot;&gt;implode&lt;/code&gt; with a &lt;code class=&quot;language-text&quot;&gt;NULL&lt;/code&gt; value triggers an error. Consequently, when upgrading from pfSense 2.6 to 2.7, the PHP version was also upgraded to version 8, which introduced this issue.&lt;/p&gt;
&lt;p&gt;The change in PHP’s behavior due to the version upgrade directly caused the problem. The code that worked correctly in PHP 7.4.X no longer functions as expected in PHP 8.2.6 because of the stricter type enforcement, leading to the observed error.&lt;/p&gt;
&lt;h2 id=&quot;24-why-wasnt-this-prevented&quot; style=&quot;position:relative;&quot;&gt;2.4 Why Wasn’t This Prevented?&lt;a href=&quot;#24-why-wasnt-this-prevented&quot; aria-label=&quot;24 why wasnt this prevented permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;First, it’s important to note that Telegraf functions without any issues even if the URLs are empty. Let’s look at the relevant code in &lt;code class=&quot;language-text&quot;&gt;telegraf/plugins/inputs/ping/ping.go&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;go&quot;&gt;&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;p &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;Ping&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Gather&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;acc telegraf&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Accumulator&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;error&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; host &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;range&lt;/span&gt; p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Urls &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;wg&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Add&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
		&lt;span class=&quot;token keyword&quot;&gt;go&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;host &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
			&lt;span class=&quot;token keyword&quot;&gt;defer&lt;/span&gt; p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;wg&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Done&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

			&lt;span class=&quot;token keyword&quot;&gt;switch&lt;/span&gt; p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Method &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
			&lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;native&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
				p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pingToURLNative&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;host&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; acc&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
			&lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
				p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pingToURL&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;host&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; acc&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
			&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
		&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;host&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

	p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;wg&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Wait&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

	&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;nil&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In this code, the ping operation is attempted. Even if &lt;code class=&quot;language-text&quot;&gt;p.Urls&lt;/code&gt; is empty, no issues arise; the ping task simply doesn’t execute. Since &lt;code class=&quot;language-text&quot;&gt;p.wg.Add(1)&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;p.wg.Done()&lt;/code&gt; aren’t called, &lt;code class=&quot;language-text&quot;&gt;p.wg.Wait()&lt;/code&gt; is invoked immediately, avoiding any synchronization issues.&lt;/p&gt;
&lt;p&gt;Currently, if you enable the “Enable Ping Monitor” option in pfSense’s Telegraf settings and save without specifying any “Ping Host,” you get a crash report like the following:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;PHP Fatal error:  Uncaught TypeError: implode(): Argument #1 ($array) must be of type array, string given in /usr/local/pkg/telegraf.inc:132
Stack trace:
#0 /usr/local/pkg/telegraf.inc(132): implode()
#1 /usr/local/www/pkg_edit.PHP(245) : eval()&apos;d code(1): telegraf_resync_config()
#2 /usr/local/www/pkg_edit.PHP(245): eval()
#3 {main}
  thrown in /usr/local/pkg/telegraf.inc on line 132&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;However, this crash report is generated by the PHP error described earlier and is not a result of pfSense’s internal format validation upon saving the Telegraf settings via the GUI. This means that in pfSense CE 2.6, it would have saved without any crash reports.&lt;/p&gt;
&lt;p&gt;The “Ping Host” input fields are displayed as follows:
&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 597px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/afd1b2058875356d65d585ade9002da9/17602/Ping_Host_input.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 36.075949367088604%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAYAAAAIy204AAAACXBIWXMAAA7DAAAOwwHHb6hkAAABMUlEQVQoz4WRuW7CQBRF/VVIBAVbdrxipHjHxs4XRATsmpY4rAIkKioQDT95opkmqaA4Gs28W5z7Rnnt98lHBVVVkec55bhAMyz6dsTQ9xgMBvi+j+M62LYt767rSoa+j+d5vHS7dDoder0eiqqqWKYlB6NRThSGmJbN51dD09Q0TUNd15LZbCbP/2+CyWQiZ2VZomiahqapvJkmWTYiDAIcx+an/Wa73bJer9lsNg8RmePxyHQ6RdENg/KjIksz0jQlL3JZZ7VacTgc2O/3T9ntdpxOJ2mp6LpOkqaEQUgSxyRpIvfVtq0MCgNh+giR+TPUdeIkIXgPiKKIOI5wHIfFYiGDwlRUesRyuZSmYpeKISpXFVmWURQF43Isf/J8PnO73bher0+5XC7c73fm8zm/OmxGSx2qDhIAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;Ping Host Input&quot;
        title=&quot;Ping Host Input&quot;
        src=&quot;/static/afd1b2058875356d65d585ade9002da9/17602/Ping_Host_input.png&quot;
        srcset=&quot;/static/afd1b2058875356d65d585ade9002da9/c26ae/Ping_Host_input.png 158w,
/static/afd1b2058875356d65d585ade9002da9/6bdcf/Ping_Host_input.png 315w,
/static/afd1b2058875356d65d585ade9002da9/17602/Ping_Host_input.png 597w&quot;
        sizes=&quot;(max-width: 597px) 100vw, 597px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Here, “Ping Host 1” does not have an &lt;code class=&quot;language-text&quot;&gt;(optional)&lt;/code&gt; label. Even so, pfSense does not issue a warning if left blank and saved. Therefore, anyone who enabled the “Enable Ping Monitor” option and saved without specifying a “Ping Host” prior to version 2.7 would have encountered the same error after upgrading.&lt;/p&gt;
&lt;p&gt;Various bug reports on this issue indicate that many users could not reproduce the problem. This is likely because they upgraded from pfSense 2.6 to 2.7 with the “Enable Ping Monitor” option disabled, preventing the issue from occurring.&lt;/p&gt;
&lt;h1 id=&quot;3-how-to-fix-it&quot; style=&quot;position:relative;&quot;&gt;3 How to Fix It?&lt;a href=&quot;#3-how-to-fix-it&quot; aria-label=&quot;3 how to fix it permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;h2 id=&quot;31-add-an-ip-to-ping-host&quot; style=&quot;position:relative;&quot;&gt;3.1 Add an IP to Ping Host&lt;a href=&quot;#31-add-an-ip-to-ping-host&quot; aria-label=&quot;31 add an ip to ping host permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;As explained earlier, the issue arises because there are no IP addresses specified in &lt;code class=&quot;language-text&quot;&gt;Ping Host&lt;/code&gt;. Adding at&lt;/p&gt;
&lt;p&gt;least one IP address to &lt;code class=&quot;language-text&quot;&gt;Ping Host&lt;/code&gt; will resolve the error. However, as noted in &lt;a href=&quot;#1-error&quot;&gt;1 Error&lt;/a&gt;, the option to manage Telegraf settings via the GUI has disappeared. So, how can we modify the settings?&lt;/p&gt;
&lt;p&gt;pfSense stores the configuration for all packages in &lt;code class=&quot;language-text&quot;&gt;/conf/config.xml&lt;/code&gt;. Opening this file, you’ll find an entry for &lt;code class=&quot;language-text&quot;&gt;&amp;lt;telegraf&gt;&lt;/code&gt; that includes &lt;code class=&quot;language-text&quot;&gt;&amp;lt;ping_host_1&gt;&amp;lt;/ping_host_1&gt;&lt;/code&gt;. You can add an IP address to this entry as follows:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;xml&quot;&gt;&lt;pre class=&quot;language-xml&quot;&gt;&lt;code class=&quot;language-xml&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;ping_host_1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;db.server.ip.addr&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;ping_host_1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Save the changes, and this should resolve the error by ensuring that at least one IP address is specified.&lt;/p&gt;
&lt;h2 id=&quot;32-disable-ping-monitor-option&quot; style=&quot;position:relative;&quot;&gt;3.2 Disable Ping Monitor Option&lt;a href=&quot;#32-disable-ping-monitor-option&quot; aria-label=&quot;32 disable ping monitor option permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In the code examined in &lt;a href=&quot;#21-code-causing-the-error&quot;&gt;2.1 Code Causing the Error&lt;/a&gt;, there is a check &lt;code class=&quot;language-text&quot;&gt;if ($telegraf_conf[&quot;ping_enable&quot;]) {&lt;/code&gt; that verifies whether the &lt;code class=&quot;language-text&quot;&gt;ping_enable&lt;/code&gt; option is turned on. If the Ping Monitor option is disabled, line 132, which causes the issue, will not be executed. This option is also present in &lt;code class=&quot;language-text&quot;&gt;/conf/config.xml&lt;/code&gt; as &lt;code class=&quot;language-text&quot;&gt;&amp;lt;ping_enable&gt;on&amp;lt;/ping_enable&gt;&lt;/code&gt;. Removing the &lt;code class=&quot;language-text&quot;&gt;on&lt;/code&gt; value will disable the Ping Monitor option.&lt;/p&gt;
&lt;p&gt;To disable it, modify the entry to:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;xml&quot;&gt;&lt;pre class=&quot;language-xml&quot;&gt;&lt;code class=&quot;language-xml&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;ping_enable&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;ping_enable&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This will turn off the Ping Monitor option and prevent the error from occurring. Save the changes, and the issue should be resolved.&lt;/p&gt;
&lt;h2 id=&quot;33-modify-telegrafinc&quot; style=&quot;position:relative;&quot;&gt;3.3 Modify telegraf.inc&lt;a href=&quot;#33-modify-telegrafinc&quot; aria-label=&quot;33 modify telegrafinc permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Initially, it seemed that modifying the &lt;code class=&quot;language-text&quot;&gt;telegraf.inc&lt;/code&gt; file to fix the root cause of the problem would be a viable solution. However, the &lt;code class=&quot;language-text&quot;&gt;telegraf.inc&lt;/code&gt; file is re-downloaded from the server whenever the package is reinstalled or pfSense is rebooted. This means any changes made to the file are not permanent. Additionally, there is no straightforward way to restart the package after modifying the &lt;code class=&quot;language-text&quot;&gt;telegraf.inc&lt;/code&gt; file. Nonetheless, addressing the issue at its core is essential.&lt;/p&gt;
&lt;p&gt;Here is the modified code:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre class=&quot;language-php&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;/* Ping Monitor Configuration */&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$telegraf_conf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;ping_enable&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$monitor_hosts&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;empty&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$telegraf_conf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;ping_host_1&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$monitor_hosts&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;&quot;&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$telegraf_conf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;ping_host_1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;&quot;&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;empty&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$telegraf_conf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;ping_host_2&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$monitor_hosts&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;&quot;&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$telegraf_conf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;ping_host_2&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;&quot;&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;empty&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$telegraf_conf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;ping_host_3&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$monitor_hosts&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;&quot;&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$telegraf_conf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;ping_host_3&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;&quot;&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;empty&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$telegraf_conf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;ping_host_4&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$monitor_hosts&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;&quot;&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$telegraf_conf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;ping_host_4&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token string single-quoted-string&quot;&gt;&apos;&quot;&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;empty&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$monitor_hosts&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$monitor_hosts&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;implode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;,&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$monitor_hosts&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// line 132&lt;/span&gt;

        &lt;span class=&quot;token variable&quot;&gt;$cfg&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.=&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;\n[[inputs.ping]]\n&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$cfg&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.=&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;\turls = [&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$monitor_hosts&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;]&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$cfg&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.=&lt;/span&gt; &lt;span class=&quot;token string double-quoted-string&quot;&gt;&quot;\n\tdeadline = 0\n\n&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;/* deadline (-w) function not supported in BSD ping */&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;By initializing &lt;code class=&quot;language-text&quot;&gt;$monitor_hosts&lt;/code&gt; as an array and checking if it is empty before proceeding, the issue can be resolved.&lt;/p&gt;
&lt;p&gt;Upon thinking of this solution and wanting to contribute to the package, I discovered the pfSense package repository. To my surprise, the issue was already &lt;a href=&quot;https://github.com/pfsense/FreeBSD-ports/blob/devel/net-mgmt/pfSense-pkg-Telegraf/files/usr/local/pkg/telegraf.inc&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;resolved&lt;/a&gt; using this exact method. Additionally, it seems that this patch will be included in pfSense CE 2.8.0 and pfSense Plus 24.08, resolving the problem in future versions.&lt;/p&gt;
&lt;h1 id=&quot;conclusion&quot; style=&quot;position:relative;&quot;&gt;Conclusion&lt;a href=&quot;#conclusion&quot; aria-label=&quot;conclusion permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;This issue was reported immediately after the pfSense CE 2.7 update. However, no solution was widely known until recently, apart from this &lt;a href=&quot;https://redmine.pfSense.org/issues/14861&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;document&lt;/a&gt;, which did not provide a detailed resolution process. Hence, I decided to write this post. I hope this guide helps others who have been stressed by the same error to resolve it successfully.&lt;/p&gt;
&lt;p&gt;Please note that there may be awkward expressions or inaccuracies in this post. All constructive feedback is welcome.&lt;/p&gt;
&lt;h1 id=&quot;references&quot; style=&quot;position:relative;&quot;&gt;References&lt;a href=&quot;#references&quot; aria-label=&quot;references permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/influxdata/telegraf/tree/master/plugins/inputs/ping&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Telegraf inputs.ping&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.php.net/manual/en/function.implode.php&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;PHP implode&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.php.net/manual/en/migration80.incompatible.php&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;PHP Manual Backward Incompatible Changes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.netgate.com/pfSense/en/latest/releases/2-7-0.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;pfSense CE 2.7 Upgrade Notes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://redmine.pfSense.org/issues/14861&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;pfSense Issues&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/pfsense/FreeBSD-ports/blob/devel/net-mgmt/pfSense-pkg-Telegraf/files/usr/local/pkg/telegraf.inc&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;issue fixed&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[우분투 lvm 확장하기]]></title><description><![CDATA[0 환경 proxmox 7.4 ubuntu 20.04 VM 확장하기 전 상태는 아래와 같다.  1 과정 우분투 머신에 디스크를 추가해준다. 추가한 디스크 확인  pvscan해서 확인 후 로 추가한 디스크를 볼륨에 추가한다.  이후 로 VG…]]></description><link>https://vulcan.site/expand-ubuntu-lvm/</link><guid isPermaLink="false">https://vulcan.site/expand-ubuntu-lvm/</guid><pubDate>Mon, 02 Oct 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h1 id=&quot;0-환경&quot; style=&quot;position:relative;&quot;&gt;0 환경&lt;a href=&quot;#0-%ED%99%98%EA%B2%BD&quot; aria-label=&quot;0 환경 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;proxmox 7.4&lt;/li&gt;
&lt;li&gt;ubuntu 20.04 VM&lt;/li&gt;
&lt;li&gt;확장하기 전 상태는 아래와 같다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 630px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/1f55763a6b5bc2d88c363111b8a35f23/84cc5/df-h_before.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 37.34177215189873%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAYAAAAIy204AAAACXBIWXMAAA7DAAAOwwHHb6hkAAAA40lEQVQoz3WR2QqDQBAE13vv24j5//+c0A3RQPBhcBcn1dVG9b1LrUVijDKOo8zzLMMwiFLqGmOtGK1Fay0hBHHOibVWck68r+t67x/HIdZZgpZl4XOaJi7hDjh+5L2XEDzPMUVCSync+Q1X53leKdu2XaDvGdY+eBohDOCUEu8xBp5hfgPfbzHG/NX8HXwO7x2DAGJt76TWKq/jJfu+sz6rt9YEtVOKj0BYwab3TnMIoC6ArTcGlpL5jkCkQP0JCBsAsfsFAlZqZUjOmQNzRd2SWenRMNx/CIHWEABLtMNACjsfY3Ca6L7FTMwAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;df-h_before&quot;
        title=&quot;df-h_before&quot;
        src=&quot;/static/1f55763a6b5bc2d88c363111b8a35f23/f058b/df-h_before.png&quot;
        srcset=&quot;/static/1f55763a6b5bc2d88c363111b8a35f23/c26ae/df-h_before.png 158w,
/static/1f55763a6b5bc2d88c363111b8a35f23/6bdcf/df-h_before.png 315w,
/static/1f55763a6b5bc2d88c363111b8a35f23/f058b/df-h_before.png 630w,
/static/1f55763a6b5bc2d88c363111b8a35f23/84cc5/df-h_before.png 898w&quot;
        sizes=&quot;(max-width: 630px) 100vw, 630px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;h1 id=&quot;1-과정&quot; style=&quot;position:relative;&quot;&gt;1 과정&lt;a href=&quot;#1-%EA%B3%BC%EC%A0%95&quot; aria-label=&quot;1 과정 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;우분투 머신에 디스크를 추가해준다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;sudo su
fdisk -l | grep &amp;quot;/dev/sd&amp;quot;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;추가한 디스크 확인&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 630px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/7a8359e9439017a2df1cf21a374d4cbc/c6d67/fdisk.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 18.354430379746837%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAYAAACOXx+WAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAvklEQVQY00WQy64DIQxDUYeW1/AOMLRVN/3/b/RVchddIDCyjp2oSgQqBVfJWK2iE6G1hrkmCv9fl+iUEs7zFB1CQO/sWeI5jgPGGDlqh4DtHMh7aKUQc0arVUzWWgE756C1/g+aE/fHA63/QlurEsY+9fUen5yRc8JNa+y9MecQGLd5vV/w3qHUgudzSzMGjkECZ11rxZgDY06oEiPIGCxrsXKWpBiTGPnNN8OISEJ77zJyjFGgDON18Kq47R9HOl593G0ExgAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;fdisk&quot;
        title=&quot;fdisk&quot;
        src=&quot;/static/7a8359e9439017a2df1cf21a374d4cbc/f058b/fdisk.png&quot;
        srcset=&quot;/static/7a8359e9439017a2df1cf21a374d4cbc/c26ae/fdisk.png 158w,
/static/7a8359e9439017a2df1cf21a374d4cbc/6bdcf/fdisk.png 315w,
/static/7a8359e9439017a2df1cf21a374d4cbc/f058b/fdisk.png 630w,
/static/7a8359e9439017a2df1cf21a374d4cbc/c6d67/fdisk.png 734w&quot;
        sizes=&quot;(max-width: 630px) 100vw, 630px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;pvscan해서 확인 후 &lt;code class=&quot;language-text&quot;&gt;pvcreate&lt;/code&gt;로 추가한 디스크를 볼륨에 추가한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;pvscan
pvcreate /dev/sdb
pvscan&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 630px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/d413a32053127d94b9292536d014f9d6/6c745/pvcreate.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 22.78481012658228%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAFCAYAAABFA8wzAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAzElEQVQY022PR44DMQwENQmjnMP4/w9to2kbe9lDgwJBlopqzoExBlhzyei943ketNaQc4ZSCvtxwFoLrTWcszDG4L5vnOeJ4zzhvcO+7zKrWqvSSCkh5ySQ2iqccyilwHuPEALmWlIZggk1RsubnxG+bRvUehZKyQKba6LWKsatdwHGGJFyQoxBrAi6rutj818ImHPKqbQigNY0pR2HCHDeiwl7DOE0Ypy1f8AxPiatN1n4LRFinZVFnvW8XjJHe9YQw/dsA62NyPD9BmTpcR10A0z1AAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;pvcreate&quot;
        title=&quot;pvcreate&quot;
        src=&quot;/static/d413a32053127d94b9292536d014f9d6/f058b/pvcreate.png&quot;
        srcset=&quot;/static/d413a32053127d94b9292536d014f9d6/c26ae/pvcreate.png 158w,
/static/d413a32053127d94b9292536d014f9d6/6bdcf/pvcreate.png 315w,
/static/d413a32053127d94b9292536d014f9d6/f058b/pvcreate.png 630w,
/static/d413a32053127d94b9292536d014f9d6/6c745/pvcreate.png 893w&quot;
        sizes=&quot;(max-width: 630px) 100vw, 630px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;이후 &lt;code class=&quot;language-text&quot;&gt;vgextend&lt;/code&gt;로 VG에 추가해줍니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;vgextend ubuntu-vg /dev/sdb&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 630px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/8d94e3cbc22850ff6fc2552b02ea2714/3cd52/vgextend.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 18.354430379746837%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAYAAACOXx+WAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAApElEQVQY022QyQ7DMAhErSxKvcUr2P7/D50K1ObSHkZmpOEBNmMOMBOIOjoRiBljMGqtIPFE4MGaKSWj9461JmIMMMb8ShpKKRpuraG2qq+1Fud5qvZ9x7Ztqm/9FyYSEH+2CjEgxqgbySYCPo5Dg857HeKcw8ta3Pf9DLuuS73Uhpj0PIEKLOeMtRZyTgqNIWjjmFP9nBMpJf2iO0mmPRd67/EGtDpb2oeh1jkAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;vgextend&quot;
        title=&quot;vgextend&quot;
        src=&quot;/static/8d94e3cbc22850ff6fc2552b02ea2714/f058b/vgextend.png&quot;
        srcset=&quot;/static/8d94e3cbc22850ff6fc2552b02ea2714/c26ae/vgextend.png 158w,
/static/8d94e3cbc22850ff6fc2552b02ea2714/6bdcf/vgextend.png 315w,
/static/8d94e3cbc22850ff6fc2552b02ea2714/f058b/vgextend.png 630w,
/static/8d94e3cbc22850ff6fc2552b02ea2714/3cd52/vgextend.png 857w&quot;
        sizes=&quot;(max-width: 630px) 100vw, 630px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;lvscan&lt;/code&gt;으로 용량을 확장할 lvm의 경로를 확인합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;lvscan&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 630px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/a9369bdc4f293b11a00e1cc288b5fe1d/a4262/lvscan.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 5.69620253164557%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAABCAYAAADeko4lAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAQ0lEQVQI1yWKywrAMAgEe/IRFeLBWkj//ze3JD0sMwx7zZxY70JmYgyFu8PM0H2jqtBPQ/XvEX6ciA739ldE4OFgZnyb2RcJRjU4dgAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;lvscan&quot;
        title=&quot;lvscan&quot;
        src=&quot;/static/a9369bdc4f293b11a00e1cc288b5fe1d/f058b/lvscan.png&quot;
        srcset=&quot;/static/a9369bdc4f293b11a00e1cc288b5fe1d/c26ae/lvscan.png 158w,
/static/a9369bdc4f293b11a00e1cc288b5fe1d/6bdcf/lvscan.png 315w,
/static/a9369bdc4f293b11a00e1cc288b5fe1d/f058b/lvscan.png 630w,
/static/a9369bdc4f293b11a00e1cc288b5fe1d/a4262/lvscan.png 814w&quot;
        sizes=&quot;(max-width: 630px) 100vw, 630px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;lvextend -l +100%FREE -n [lvm 경로]&lt;/code&gt;로 확장.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;lvextend -l +100%FREE -n /dev/ubuntu-vg/ubuntu-lv&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 630px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/1ca5fc4c07ed6de7da6879bd77927995/29c1d/lvextend.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 5.063291139240507%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAABCAYAAADeko4lAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAPklEQVQI1zXHQQrAQAgEwRx2PAiKGd3/P3UCQg4NXU9kinzV02JTM71fVbp3RHIdEYoMubvMTDDo4AjA+u8DoAUW8HlZI70AAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;lvextend&quot;
        title=&quot;lvextend&quot;
        src=&quot;/static/1ca5fc4c07ed6de7da6879bd77927995/f058b/lvextend.png&quot;
        srcset=&quot;/static/1ca5fc4c07ed6de7da6879bd77927995/c26ae/lvextend.png 158w,
/static/1ca5fc4c07ed6de7da6879bd77927995/6bdcf/lvextend.png 315w,
/static/1ca5fc4c07ed6de7da6879bd77927995/f058b/lvextend.png 630w,
/static/1ca5fc4c07ed6de7da6879bd77927995/40601/lvextend.png 945w,
/static/1ca5fc4c07ed6de7da6879bd77927995/78612/lvextend.png 1260w,
/static/1ca5fc4c07ed6de7da6879bd77927995/29c1d/lvextend.png 1375w&quot;
        sizes=&quot;(max-width: 630px) 100vw, 630px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;resize2fs&lt;/code&gt;로 확장.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;resize2fs /dev/ubuntu-vg/ubuntu-lv&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 630px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/295466f0fc6d9913d524811e48a1766e/1c3a5/resize2fs.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 12.025316455696203%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAACCAYAAABYBvyLAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAYElEQVQI102NSQ7AIAwDkSAsQQ2E5f9PdRXUVj2M4vgwdnNO7L3RWkPXDlXFGArrRS6klJBzBjOjlHJyjBFEBO89QggH+w035sBaC3ZNICJH9mJ9rYz8yEz6h2v9hogCbj7xLVUzHxJjAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;resize2fs&quot;
        title=&quot;resize2fs&quot;
        src=&quot;/static/295466f0fc6d9913d524811e48a1766e/f058b/resize2fs.png&quot;
        srcset=&quot;/static/295466f0fc6d9913d524811e48a1766e/c26ae/resize2fs.png 158w,
/static/295466f0fc6d9913d524811e48a1766e/6bdcf/resize2fs.png 315w,
/static/295466f0fc6d9913d524811e48a1766e/f058b/resize2fs.png 630w,
/static/295466f0fc6d9913d524811e48a1766e/40601/resize2fs.png 945w,
/static/295466f0fc6d9913d524811e48a1766e/1c3a5/resize2fs.png 981w&quot;
        sizes=&quot;(max-width: 630px) 100vw, 630px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;df -h&lt;/code&gt;로 확장됐는지 확인.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;df -h&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 630px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/44534eea2c41f9de6b2ebd1a46fe4137/3a737/df-h_after.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 37.34177215189873%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAYAAAAIy204AAAACXBIWXMAAA7DAAAOwwHHb6hkAAAA8klEQVQoz3WR666EIAyE1QXlUgQBRd7/QWfTuuvmnMQfTSGUrzPtUGvFljeEEKCUgtZa4qUUpmnCMAyw1koYY6SOiOCcQ0oR6xowz7PUSRytgcgLhIHqA/rex3EEBUIIJJlCQIwrvPfYtg2z1j8Yx9n73WVZFslK6/vMcFbEAG7gvBcgZ/6XUhK1P+DZReGfLv/isnm5YDhbNdailIJSi7xba676XDJaa4gxPgI9kaiqexXlPE+2m3O+gTElUSzA49il4An4tcm1+jMOVsd/zn6C99D7KfaHfd9lyzyjZ4X+XgpvmmcWUxRgaweYwaKcs3gDkWGbBhCZHV0AAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;df-h_after&quot;
        title=&quot;df-h_after&quot;
        src=&quot;/static/44534eea2c41f9de6b2ebd1a46fe4137/f058b/df-h_after.png&quot;
        srcset=&quot;/static/44534eea2c41f9de6b2ebd1a46fe4137/c26ae/df-h_after.png 158w,
/static/44534eea2c41f9de6b2ebd1a46fe4137/6bdcf/df-h_after.png 315w,
/static/44534eea2c41f9de6b2ebd1a46fe4137/f058b/df-h_after.png 630w,
/static/44534eea2c41f9de6b2ebd1a46fe4137/3a737/df-h_after.png 897w&quot;
        sizes=&quot;(max-width: 630px) 100vw, 630px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;h1 id=&quot;참고&quot; style=&quot;position:relative;&quot;&gt;참고&lt;a href=&quot;#%EC%B0%B8%EA%B3%A0&quot; aria-label=&quot;참고 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;&lt;a href=&quot;https://nirsa.tistory.com/232&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;https://nirsa.tistory.com/232&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[10분만에 우분투 커널 컴파일하기]]></title><description><![CDATA[…]]></description><link>https://vulcan.site/ubuntu-kernel-compile/</link><guid isPermaLink="false">https://vulcan.site/ubuntu-kernel-compile/</guid><pubDate>Tue, 19 Sep 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h1 id=&quot;0-시작하기에-앞서&quot; style=&quot;position:relative;&quot;&gt;0 시작하기에 앞서&lt;a href=&quot;#0-%EC%8B%9C%EC%9E%91%ED%95%98%EA%B8%B0%EC%97%90-%EC%95%9E%EC%84%9C&quot; aria-label=&quot;0 시작하기에 앞서 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;이 글을 쓰게 된 이유는 학교에서 현재 “리눅스 시스템 응용 설계”라는 과목을 수강하고 있기 때문이다. 이 과목에서는 당연히 수없이 많은 커널 컴파일을 해야 할 수 있고, 때문에 그 과정을 간단하게 정리하고자 글을 썼다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://vulcan.site/first_article/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;블로그 첫 글&lt;/a&gt;을 보면 알겠지만 나는 44core 시스템을 보유하고 있다. 보통의 경우 커널 컴파일은 굉장히 오래 걸릴 수도있으니, 여유를 가지고 진행하자.&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;1-우분투-설치&quot; style=&quot;position:relative;&quot;&gt;1 우분투 설치&lt;a href=&quot;#1-%EC%9A%B0%EB%B6%84%ED%88%AC-%EC%84%A4%EC%B9%98&quot; aria-label=&quot;1 우분투 설치 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;VirtualBox나 듀얼부팅으로 ubuntu 서버 버전 혹은 데스크탑 버전을 설치해준다. 이외에 본인이 편한 환경에 설치해주면 된다.&lt;/li&gt;
&lt;li&gt;디스크 용량은 40GB 이상으로 설정해주자.&lt;/li&gt;
&lt;li&gt;작업을 편하게 하기 위해 SSH 접속 환경을 셋팅해준다.&lt;/li&gt;
&lt;li&gt;커널을 설치하기 이전에 업데이트를 해준다.&lt;/li&gt;
&lt;li&gt;이후 현재 커널 버전을 확인해준다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;sudo apt update &amp;amp;&amp;amp; upgrade      #업데이트
uname -a                        #커널 버전 확인&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&quot;2-커널-다운로드&quot; style=&quot;position:relative;&quot;&gt;2 커널 다운로드&lt;a href=&quot;#2-%EC%BB%A4%EB%84%90-%EB%8B%A4%EC%9A%B4%EB%A1%9C%EB%93%9C&quot; aria-label=&quot;2 커널 다운로드 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://mirrors.edge.kernel.org/pub/linux/kernel/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;https://mirrors.edge.kernel.org/pub/linux/kernel/&lt;/a&gt; 해당 사이트에서 원하는 버전의 커널을 다운받는다.&lt;/li&gt;
&lt;li&gt;강의에서 5.4.214버전을 사용하기 때문에 해당 버전으로 진행하겠다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;cd /usr/src/
sudo wget https://mirrors.edge.kernel.org/pub/linux/kernel/v5.x/linux-5.4.214.tar.gz    #다운로드
sudo tar -xzvf linux-5.4.214.tar.gz     #압축 해제
sudo cp linux-headers-5.4.0-162-generic/.config linux-5.4.214   #config 파일 복사&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;config 수정&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;cd linux-5.4.214/
sudo nano .config   #config 파일 수정
#아래 두 줄을 수정해준다.
#CONFIG_SYSTEM_TRUSTED_KEYS=&amp;quot;debian/canonical-certs.pem&amp;quot; -&amp;gt; CONFIG_SYSTEM_TRUSTED_KEYS = &amp;quot;&amp;quot;
#CONFIG_SYSTEM_REVOCATION_KEYS=&amp;quot;debian/canonical-certs.pem&amp;quot; -&amp;gt; CONFIG_SYSTEM_REVOCATION_KEYS=&amp;quot;&amp;quot;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;필요 패키지 설치&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;sudo apt install build-essential libncurses5 libncurses5-dev bin86 kernel-package libssl-dev bison flex libelf-dev dwarves  #필요 패키지 설치
sudo reboot     #재부팅&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;menuconfig&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;cd /usr/src/linux-5.4.214/
sudo make menuconfig&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;load -&gt; ok -&gt; exit -&gt; yes&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;커널 이름 변경 (optional)&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;sudo nano Makefile&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 417px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/b6204cae5b2e9279edcab6eb09c6a6f8/f27fb/kernel-name.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 32.911392405063296%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAYAAAAIy204AAAACXBIWXMAAA7DAAAOwwHHb6hkAAABG0lEQVQoz4WQ2U7DQAxFPbTN0jZpMnGSyVaSqWhUeIAHvoz/lw7qglSpCB6u5GsfX1mWfMqx75Z8zrHeoscSO1v0pOhR0VHRD736l1tvVtQr2t1mh5u8ItooiW4pWiVOQkSEyMZIKIiRi5dAkJUgC0GWd7Xc/NMde/ATQ98zjRP7fqApa5J4zVKEdby5QEbMFf5Z+kvO1agqXddR1TVZmhKKsI0iCi1+X/or2HvPNI34g2fY71mvVmTpjrpxpMn2AoVRSGAClp9LxP5zYds2NGfVFcPQU1YVbddR5BnBOSwMqFxFvamIv2Lk7foCszAYYx4DT68zhbUXY62lLEu6tsUWluF5pG0chSrpLiHZpDjncI2j7zuyPHsI/AblyaAQi+GHZQAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;kernel-name&quot;
        title=&quot;kernel-name&quot;
        src=&quot;/static/b6204cae5b2e9279edcab6eb09c6a6f8/f27fb/kernel-name.png&quot;
        srcset=&quot;/static/b6204cae5b2e9279edcab6eb09c6a6f8/c26ae/kernel-name.png 158w,
/static/b6204cae5b2e9279edcab6eb09c6a6f8/6bdcf/kernel-name.png 315w,
/static/b6204cae5b2e9279edcab6eb09c6a6f8/f27fb/kernel-name.png 417w&quot;
        sizes=&quot;(max-width: 417px) 100vw, 417px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;h1 id=&quot;3-커널-컴파일&quot; style=&quot;position:relative;&quot;&gt;3 커널 컴파일&lt;a href=&quot;#3-%EC%BB%A4%EB%84%90-%EC%BB%B4%ED%8C%8C%EC%9D%BC&quot; aria-label=&quot;3 커널 컴파일 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;코어 수 확인&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;grep -c processor /proc/cpuinfo     #176&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;compile&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;sudo make -j176
sudo make modules_install
sudo make install&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&quot;4-kernel-변경&quot; style=&quot;position:relative;&quot;&gt;4 kernel 변경&lt;a href=&quot;#4-kernel-%EB%B3%80%EA%B2%BD&quot; aria-label=&quot;4 kernel 변경 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;Boot kernel 순서 확인&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;awk -F\&amp;#39; &amp;#39;/menuentry / {print $2}&amp;#39; /boot/grub/grub.cfg&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;test@test:/usr/src/linux-5.4.214$ awk -F\&apos; &apos;/menuentry / {print $2}&apos; /boot/grub/grub.cfg
Ubuntu                                                  ----&gt;&gt; 1
Ubuntu, with Linux 5.4.214.test                         ----&gt;&gt; 1&gt;0
Ubuntu, with Linux 5.4.214.test (recovery mode)         ----&gt;&gt; 1&gt;1
Ubuntu, with Linux 5.4.0-162-generic                    ----&gt;&gt; 1&gt;2
Ubuntu, with Linux 5.4.0-162-generic (recovery mode)    ----&gt;&gt; 1&gt;3&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;sudo nano /etc/default/grub     #grub 파일 수정&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 630px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/b8a98d872c165e9e0c386df42621c322/20982/grub.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 17.72151898734177%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAYAAACOXx+WAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAoElEQVQY05VPWwrDMAzLo6XNq8mSNY3LusJ6i93/Xho19Gsw2IewLUtGFvN8BxEh5YRsbpjeAZo0OtFBCPE/iBYcxwu1VkxTgA8O3nuEEKCU/DJIKaGU4nrNF3dCcMKV0FpDzpkP5Vy4r3VGjBHWWuZPlFIQ4wRjDLTWMNbw3jnHgQRRw3Pf0ZYFRCu27YGYEov6vmfhaR7HkblhGH6+/AGD0Fi2SGYzLwAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;grub&quot;
        title=&quot;grub&quot;
        src=&quot;/static/b8a98d872c165e9e0c386df42621c322/f058b/grub.png&quot;
        srcset=&quot;/static/b8a98d872c165e9e0c386df42621c322/c26ae/grub.png 158w,
/static/b8a98d872c165e9e0c386df42621c322/6bdcf/grub.png 315w,
/static/b8a98d872c165e9e0c386df42621c322/f058b/grub.png 630w,
/static/b8a98d872c165e9e0c386df42621c322/20982/grub.png 778w&quot;
        sizes=&quot;(max-width: 630px) 100vw, 630px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;sudo update-grub                #grub 업데이트
sudo reboot                     #재부팅&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&quot;5-kernel-변경-확인&quot; style=&quot;position:relative;&quot;&gt;5 kernel 변경 확인&lt;a href=&quot;#5-kernel-%EB%B3%80%EA%B2%BD-%ED%99%95%EC%9D%B8&quot; aria-label=&quot;5 kernel 변경 확인 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;uname -a&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;커널 버전이 잘 변경된 것을 확인할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 630px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/bc5a35ed910e32cbcce49e4bce122ed1/0f529/before.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 4.430379746835443%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAABCAYAAADeko4lAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAOUlEQVQI103HOwrAMAzA0E7+Yezg5v5XVYdA6PBAeqqbqqLXYmZOd7P3S2YSEbg7IoKaonqY2fX/D4LIFnaibpUTAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;before&quot;
        title=&quot;before&quot;
        src=&quot;/static/bc5a35ed910e32cbcce49e4bce122ed1/f058b/before.png&quot;
        srcset=&quot;/static/bc5a35ed910e32cbcce49e4bce122ed1/c26ae/before.png 158w,
/static/bc5a35ed910e32cbcce49e4bce122ed1/6bdcf/before.png 315w,
/static/bc5a35ed910e32cbcce49e4bce122ed1/f058b/before.png 630w,
/static/bc5a35ed910e32cbcce49e4bce122ed1/40601/before.png 945w,
/static/bc5a35ed910e32cbcce49e4bce122ed1/0f529/before.png 1259w&quot;
        sizes=&quot;(max-width: 630px) 100vw, 630px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;
&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 630px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/7ed3d83cec3dfaaaf81343738a4e104d/96e86/after.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 4.430379746835443%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAABCAYAAADeko4lAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAOklEQVQI10WKQQrAMAzDdkriJtBA+/+vatDCdjASwk93U7NYe1GVuDsjB5KQAjM7HhH/dPn18xWZyQtwWxY55Wi6OAAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;after&quot;
        title=&quot;after&quot;
        src=&quot;/static/7ed3d83cec3dfaaaf81343738a4e104d/f058b/after.png&quot;
        srcset=&quot;/static/7ed3d83cec3dfaaaf81343738a4e104d/c26ae/after.png 158w,
/static/7ed3d83cec3dfaaaf81343738a4e104d/6bdcf/after.png 315w,
/static/7ed3d83cec3dfaaaf81343738a4e104d/f058b/after.png 630w,
/static/7ed3d83cec3dfaaaf81343738a4e104d/40601/after.png 945w,
/static/7ed3d83cec3dfaaaf81343738a4e104d/96e86/after.png 1089w&quot;
        sizes=&quot;(max-width: 630px) 100vw, 630px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Proxmox VM에 GPU 패스쓰루(Passthrough)하기]]></title><description><![CDATA[0 환경 자세한 서버의 하드웨어는 블로그 첫 글을 참고하시기 바랍니다. PVE 7.4-16버전, 가상머신은 ubuntu-server 20.04버전입니다. nvidia GPU로 테스트했습니다. 다른 제조사의 GPU…]]></description><link>https://vulcan.site/proxmox-GPU-passthrough/</link><guid isPermaLink="false">https://vulcan.site/proxmox-GPU-passthrough/</guid><pubDate>Mon, 18 Sep 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h1 id=&quot;0-환경&quot; style=&quot;position:relative;&quot;&gt;0 환경&lt;a href=&quot;#0-%ED%99%98%EA%B2%BD&quot; aria-label=&quot;0 환경 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;자세한 서버의 하드웨어는 &lt;a href=&quot;https://vulcan.site/first_article/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;블로그 첫 글&lt;/a&gt;을 참고하시기 바랍니다.&lt;/li&gt;
&lt;li&gt;PVE 7.4-16버전, 가상머신은 ubuntu-server 20.04버전입니다.&lt;/li&gt;
&lt;li&gt;nvidia GPU로 테스트했습니다. 다른 제조사의 GPU의 경우 방법이 다를 수 있습니다.&lt;/li&gt;
&lt;li&gt;메인보드의 BIOS에서 Passthrough와 관련된 셋팅이 돼있어야 합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;1-pve-설정&quot; style=&quot;position:relative;&quot;&gt;1 PVE 설정&lt;a href=&quot;#1-pve-%EC%84%A4%EC%A0%95&quot; aria-label=&quot;1 pve 설정 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;nano /etc/default/grub      #grub 파일 수정&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;아래의 내용을 추가해 준다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;GRUB_CMDLINE_LINUX_DEFAULT=&quot;quiet intel_iommu=on iommu=pt pcie_acs_override=downstream,multifunction nofb nomodeset video=vesafb:off,efifb:off,pci=noaer,pci=nommconf&quot;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;update-grub                 #grub 업데이트
nano /etc/modules           #modules 파일 수정&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;아래 내용을 추가해 준다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;vfio
vfio_iommu_type1
vfio_pci
vfio_virqfd&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;nano /etc/modprobe.d/blacklist.conf     #blacklist.conf 파일 수정&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;아래 내용을 추가해 준다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;blacklist nouveau
blacklist nvidia
blacklist radeon&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;vfio 정보를 등록해준다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;lspci -v | grep NVIDIA              #00:00 형식의 값을 찾는다.
lspci -n -s 00:00                   #xxxx:xxxx 형식의 값을 찾는다.
nano /etc/modprobe.d/vfio.conf      #vfio.conf 파일 수정&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;아래 내용을 추가해 준다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;options vfio-pci ids=xxxx:xxxx,xxxx:xxxx disable_vga=1&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;update-initramfs -u     #initramfs 업데이트
reboot                  #재부팅&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&quot;2-vm-설정&quot; style=&quot;position:relative;&quot;&gt;2 VM 설정&lt;a href=&quot;#2-vm-%EC%84%A4%EC%A0%95&quot; aria-label=&quot;2 vm 설정 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;h2 id=&quot;부팅-전-설정&quot; style=&quot;position:relative;&quot;&gt;부팅 전 설정&lt;a href=&quot;#%EB%B6%80%ED%8C%85-%EC%A0%84-%EC%84%A4%EC%A0%95&quot; aria-label=&quot;부팅 전 설정 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Create VM 창을 기준으로 설명&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 630px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/bf366eb81898265c1e0952c4fd57c6fc/073e9/VM-general.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 70.25316455696203%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAAA7DAAAOwwHHb6hkAAABXklEQVQ4y52Ty07DMBBF/R2woMrDcd5NlLRJmz5EpVJBJfYsuwQJ9RP484vuSK6gSUXE4siTeObOjMdWQfsEs3lFXHeIqwVMVkJrH1rrHkEQXFbf9/tECZRzfId++0KaF4hDgyiKLoRhiDiOBWsbY5AkiYj20BqqWzTIkwiO46DrOsxmM2RZhul0ijzPZU3TVP4vl0tUVSXC3KOfhd9MpDbbLYqixGQyQdM0mM/ng4Ke541CMTOzMogCRVH8oixLEWV2m4Q2/a9h5SK4Xq8l2J7bNTy3/X6Pw+EgXTCwruteYnamWCbPj+vg5Hxf9larFXa7nQQzAQuxFVvkDIeuxzUUZUUUbdtW2rMV2XZpS8t/CRHarutKJ8RWPdTN6ArH+BE11nG04K1B/A8PihMj9p2OxcZpxgUGgQkFdTqdcD6f5dnxtfwcxq0rxORN26KuKrj1Ix4WR9w/f+Du5RPf9dqj4A4Dt1UAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;general&quot;
        title=&quot;general&quot;
        src=&quot;/static/bf366eb81898265c1e0952c4fd57c6fc/f058b/VM-general.png&quot;
        srcset=&quot;/static/bf366eb81898265c1e0952c4fd57c6fc/c26ae/VM-general.png 158w,
/static/bf366eb81898265c1e0952c4fd57c6fc/6bdcf/VM-general.png 315w,
/static/bf366eb81898265c1e0952c4fd57c6fc/f058b/VM-general.png 630w,
/static/bf366eb81898265c1e0952c4fd57c6fc/073e9/VM-general.png 719w&quot;
        sizes=&quot;(max-width: 630px) 100vw, 630px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;System
&lt;ul&gt;
&lt;li&gt;Machine : q35&lt;/li&gt;
&lt;li&gt;BIOS : OVMF (UEFI)&lt;/li&gt;
&lt;li&gt;EFI Storage를 설정해준다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 630px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/1b022d1cd0237aef6a193786977b2db0/6bbf7/VM-system.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 70.88607594936708%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAAA7DAAAOwwHHb6hkAAABh0lEQVQ4y51Ty07DMBD0fyCQaBI3Dydx06bpI0nTNhwQAol7OfWMlBM/wIcPGtOEPlXgMFon3h3P7NoiSDKo0QxqOIGXP0Lmz3D9AK7rQkqJfr9v0K7b6DjOKXwFoXWMNE0ReRL9hw3k5hNxliPRMVzPQxAEBt5uzYOUUt1Bh5AQ8/kcZblAoBQWxRx1VSCOImg9gNYag8EAURRhMplgtVqB+bPZDOv1GnVdYzwemwOYwyiWyyWqqoJtWUiGQwQqNGq4SUWM/Cb5dDpFGIbG9lnLjvOtkCp6vR5GoxHKsjQt8H3/wG6SJGafRW0vz0HkeY6iKIxkFtEC1yQhKcG+URn/7w/nLGGWZaBtWiMZyVkcx3FHQpW2bcOyrM7avu0DQhbQMpVEZhjaRJJRJdW1V2gfx0QdIcnYbPaHVqiEOG72JUUnhCzmQFo7lxKvEXWEv0n6C8Sl+/RfiGvX4BI4qJ8n50Luothut2iaxjwp9vIaOVWQjM8vS4e4r99w+/qBm6d33L00+AI9BKS8PFMC+wAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;system&quot;
        title=&quot;system&quot;
        src=&quot;/static/1b022d1cd0237aef6a193786977b2db0/f058b/VM-system.png&quot;
        srcset=&quot;/static/1b022d1cd0237aef6a193786977b2db0/c26ae/VM-system.png 158w,
/static/1b022d1cd0237aef6a193786977b2db0/6bdcf/VM-system.png 315w,
/static/1b022d1cd0237aef6a193786977b2db0/f058b/VM-system.png 630w,
/static/1b022d1cd0237aef6a193786977b2db0/6bbf7/VM-system.png 716w&quot;
        sizes=&quot;(max-width: 630px) 100vw, 630px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Disks
&lt;ul&gt;
&lt;li&gt;Bus/Device : SATA&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 630px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/300b662b1c9722095018a7200c210439/6bbf7/VM-disks.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 70.88607594936708%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAB6klEQVQ4y4VUy47TQBD0L3DghhZie2b8iu14/Igdr6M8BQikXTgQIeDCKRdWSFxA/HuhmuxEzq6AQ6nH6p6q6p6WnTArEes5It0irnrEuYbIavh5izBQUEpBSmlgz4xCiBHkKUYJnKIo0LUt8ixDoTVanUK9/gpxc4ciTRAnU8RxjDAMkSTJOVqRh3A2mw1u391iu9vjzcsd1NsjxPYjhqbAvO3geZ4ppANG3/fNmS55Zp6weYeKQRAgCEMoKZHPB9TXGyglocsSTdMYR+yEThn5TTLmlssl+r5HVVXGvTOeB5WGfoHddmNEWLjf7zGbzVCWJdI0xTAMqOvaEOZ5bnKEHcOZ0LaldYm26wwB3RAkyrLMOKRQFEWmlqSTyQSu657bfkTIi1prQ2KdsR1G5gi6IVgzBoUuCKnIy6vVCl3XmQI6Yo0FZ7ZYLDCdnl7fjsuu1AUhwcESY9djkGy9XpsubAc8U4DiJ0JevCe0SzpeFXnOCfMQbI+zIxkF2A1HYQgDKSA9F9J3oXzvrwtrwbEQPPMh7KPY/XT8eAZ3Wp2QaEipHrU5xtjtQzFD+LQ/wD/8hvjwC0+2R4gghpTiv07HDzWG8+XzJ3y/+2YW2n3x/OJn8C+yeduiqTTc9QFX73/i2asjrm5+4A96CKmXh25l7AAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;disks&quot;
        title=&quot;disks&quot;
        src=&quot;/static/300b662b1c9722095018a7200c210439/f058b/VM-disks.png&quot;
        srcset=&quot;/static/300b662b1c9722095018a7200c210439/c26ae/VM-disks.png 158w,
/static/300b662b1c9722095018a7200c210439/6bdcf/VM-disks.png 315w,
/static/300b662b1c9722095018a7200c210439/f058b/VM-disks.png 630w,
/static/300b662b1c9722095018a7200c210439/6bbf7/VM-disks.png 716w&quot;
        sizes=&quot;(max-width: 630px) 100vw, 630px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Hardware - Add - PCI Device - 원하는 GPU를 선택
&lt;ul&gt;
&lt;li&gt;All functions : 체크&lt;/li&gt;
&lt;li&gt;Primary GPU : 체크 해제&lt;/li&gt;
&lt;li&gt;ROM-Bar : 체크&lt;/li&gt;
&lt;li&gt;PCI-Express : 체크&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 588px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/88631cdcd64f17d26e8e4c18e18e4b82/9bbaf/PCI-GPU.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 12.025316455696203%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAACCAYAAABYBvyLAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAVElEQVQI123NUQoAIQgE0O6TWH8pIvVR9z/ShMHGsuzHMAiPMZkZ5pwYY4CZUWtFzhlEdBN3uLUW3P2YsG/zuKSqZ6yUclD0dzDSWkPvHSJyH/8Nbu76PvUYzQUmAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;pci-gpu&quot;
        title=&quot;pci-gpu&quot;
        src=&quot;/static/88631cdcd64f17d26e8e4c18e18e4b82/9bbaf/PCI-GPU.png&quot;
        srcset=&quot;/static/88631cdcd64f17d26e8e4c18e18e4b82/c26ae/PCI-GPU.png 158w,
/static/88631cdcd64f17d26e8e4c18e18e4b82/6bdcf/PCI-GPU.png 315w,
/static/88631cdcd64f17d26e8e4c18e18e4b82/9bbaf/PCI-GPU.png 588w&quot;
        sizes=&quot;(max-width: 588px) 100vw, 588px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;이후 우분투 서버를 설치해주고 SSH에 접속할 수 있는 환경을 만들어두고 IP를 기억해두자.&lt;/p&gt;
&lt;h2 id=&quot;부팅-후-설정&quot; style=&quot;position:relative;&quot;&gt;부팅 후 설정&lt;a href=&quot;#%EB%B6%80%ED%8C%85-%ED%9B%84-%EC%84%A4%EC%A0%95&quot; aria-label=&quot;부팅 후 설정 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;먼저 VM을 꺼준다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;nano /etc/pve/qemu-server/000.conf      #000.conf 파일 수정 000은 VM ID이다.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;아래 내용을 추가해 준다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;cpu: host,hidden=1&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;GPU ROM dump&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;cd /sys/bus/pci/devices/0000:00:00.0/   #0000:00:00.0에서 00:00부분에 이전에 lspci에서 썼던 번호를 쓴다.
echo 1 &amp;gt; rom
cat rom &amp;gt; /tmp/image00.rom              #image00.rom에서 00부분에 이전에 lspci에서 썼던 번호를 쓴다.
echo 0 &amp;gt; rom
cd ~/NVIDIA-vBIOS-VFIO-Patcher
python nvidia_vbios_vfio_patcher.py -i /tmp/image00.rom -o /tmp/image00.patched.rom --disable-footer-strip
#image00.rom에서 00부분에 이전에 lspci에서 썼던 번호를 쓴다.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;ROM 파일 복사&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;cp /tmp/image00.pached.rom /usr/share/kvm/gpu00.pached.rom  #00부분에 이전에 lspci에서 썼던 번호를 쓴다.
nano /etc/pve/qemu-server/000.conf      #000.conf 파일 수정 000은 VM ID이다.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;아래 내용을 추가해 준다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;00부분에 이전에 lspci에서 썼던 번호를 쓴다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;hostpci0: 0000:00:00,pcie=1,x-vga=1,romfile=gpu00.patched.rom&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Hardware - PCI Device
&lt;ul&gt;
&lt;li&gt;All functions : 체크&lt;/li&gt;
&lt;li&gt;Primary GPU : 체크&lt;/li&gt;
&lt;li&gt;ROM-Bar : 체크&lt;/li&gt;
&lt;li&gt;PCI-Express : 체크&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 587px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/e111ecb5681ed2bc66553a6d54abe257/d72eb/PCI-GPU2.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 10.759493670886075%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAACCAYAAABYBvyLAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAATklEQVQI13WNQQrAMAgE858k6tUcIvr/P21RSOihPSyyMsw2VYWZYa0FIgIzo/eOMcZN9sPlFZHi3szh2t4bEVGPP2EmRe5ew3POkn4JH8y/PsVzjEFeAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;pci-gpu2&quot;
        title=&quot;pci-gpu2&quot;
        src=&quot;/static/e111ecb5681ed2bc66553a6d54abe257/d72eb/PCI-GPU2.png&quot;
        srcset=&quot;/static/e111ecb5681ed2bc66553a6d54abe257/c26ae/PCI-GPU2.png 158w,
/static/e111ecb5681ed2bc66553a6d54abe257/6bdcf/PCI-GPU2.png 315w,
/static/e111ecb5681ed2bc66553a6d54abe257/d72eb/PCI-GPU2.png 587w&quot;
        sizes=&quot;(max-width: 587px) 100vw, 587px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;h2 id=&quot;드라이버-설치&quot; style=&quot;position:relative;&quot;&gt;드라이버 설치&lt;a href=&quot;#%EB%93%9C%EB%9D%BC%EC%9D%B4%EB%B2%84-%EC%84%A4%EC%B9%98&quot; aria-label=&quot;드라이버 설치 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;VM을 켜준다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;sudo apt update &amp;amp;&amp;amp; upgrade
lshw -C display     #GPU확인
sudo apt install nvidia-driver-535      #GPU에 맞는 버전의 드라이버 설치
sudo apt update &amp;amp;&amp;amp; upgrade
sudo reboot         #재부팅
nvidia-smi&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;아래의 이미지가 뜬다면 성공한것이다.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 630px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/2367ddbf2fa45a1eb95da094247c2e69/38a65/nvidia-smi.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 22.78481012658228%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAFCAYAAABFA8wzAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAs0lEQVQY0z2QWRLEIAhEjZpFcZtUkvvflKlHynx0IdDdIK6UoiKiOWcVyZpS0hCCLstiMeW3Buc4DuOBdV01S/7yfd+t5lprCkiA996MGFRr1d6bmQFE27Zpbc36YPyGRTzgOCMXsS0QYIhoDgL0GEa/tfoZUGcom/fR9Xnu17D3rrUyUcwQxBjNZJ4E4XVfn9l5nvaTEKNx0Ywx1JGwERHCNOQ9z0CfnE0mf956wodgX/4D4eFt3My6wjkAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;nvidia-smi&quot;
        title=&quot;nvidia-smi&quot;
        src=&quot;/static/2367ddbf2fa45a1eb95da094247c2e69/f058b/nvidia-smi.png&quot;
        srcset=&quot;/static/2367ddbf2fa45a1eb95da094247c2e69/c26ae/nvidia-smi.png 158w,
/static/2367ddbf2fa45a1eb95da094247c2e69/6bdcf/nvidia-smi.png 315w,
/static/2367ddbf2fa45a1eb95da094247c2e69/f058b/nvidia-smi.png 630w,
/static/2367ddbf2fa45a1eb95da094247c2e69/40601/nvidia-smi.png 945w,
/static/2367ddbf2fa45a1eb95da094247c2e69/38a65/nvidia-smi.png 1075w&quot;
        sizes=&quot;(max-width: 630px) 100vw, 630px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;h1 id=&quot;오류&quot; style=&quot;position:relative;&quot;&gt;오류&lt;a href=&quot;#%EC%98%A4%EB%A5%98&quot; aria-label=&quot;오류 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;오류가 나면 아래 스크립트를 실행하고 위의 내용을 진행해준다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;echo 1 &amp;gt; /sys/bus/pci/devices/0000\:00\:00.0/remove     #0000:00:00.0에서 00:00부분에 이전에 lspci에서 썼던 번호를 쓴다.
echo 1 &amp;gt; /sys/bus/pci/rescan&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Plex Media server 마이그레이션하기]]></title><description><![CDATA[0. 마이그레이션을 하게 된 이유 지금까지 Plex 미디어 서버를 영상, 노래 스트리밍 용도로 잘 활용해 왔다. 다만 서버의 CPU는 Xeon이기 때문에 내장그래픽은 당연히 없고 설치되어 있는 QUADRO® P4000은 주로 Stable…]]></description><link>https://vulcan.site/plex-migration/</link><guid isPermaLink="false">https://vulcan.site/plex-migration/</guid><pubDate>Sun, 17 Sep 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h1 id=&quot;0-마이그레이션을-하게-된-이유&quot; style=&quot;position:relative;&quot;&gt;0. 마이그레이션을 하게 된 이유&lt;a href=&quot;#0-%EB%A7%88%EC%9D%B4%EA%B7%B8%EB%A0%88%EC%9D%B4%EC%85%98%EC%9D%84-%ED%95%98%EA%B2%8C-%EB%90%9C-%EC%9D%B4%EC%9C%A0&quot; aria-label=&quot;0 마이그레이션을 하게 된 이유 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;지금까지 Plex 미디어 서버를 영상, 노래 스트리밍 용도로 잘 활용해 왔다. 다만 서버의 CPU는 Xeon이기 때문에 내장그래픽은 당연히 없고 설치되어 있는 QUADRO® P4000은 주로 Stable Diffusion이나 기타 작업을 할 때 여러 가상머신에서 사용하기 때문에 Plex의 하드웨어 트랜스코더로 사용하기에는 적절하지 않다. 그리고 보유하고 있는 미디어들이 점점 증가하면서 메타데이터의 용량이 늘어나게 되었고, 기존에 Plex가상머신에 할당해 두었던 20GB가 가득 차게 되었다. 때문에 중고 QUADRO® P2000을 구매하여 이를 이용해 하드웨어 트랜스코더로 이용해서 Plex서버를 마이그레이션 해보고자 한다.&lt;/p&gt;
&lt;p&gt;나는 proxmox 위에서 돌아가는 ubuntu 20.04가상머신에서 해당 내용을 진행했다. 하지만 다른 OS도 진행은 크게 다르지 않다.&lt;/p&gt;
&lt;h1 id=&quot;1-준비&quot; style=&quot;position:relative;&quot;&gt;1. 준비&lt;a href=&quot;#1-%EC%A4%80%EB%B9%84&quot; aria-label=&quot;1 준비 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;먼저 구동되고 있던 Plex 서버의 웹 gui에서 설정 &gt; 라이브러리 &gt; “변경사항이 발견될때 부분적인 스캔 실행”을 체크 해제해 준다.&lt;/li&gt;
&lt;li&gt;로그아웃 해줍니다.&lt;/li&gt;
&lt;li&gt;Plex 미디어 서버가 구동되고 있는 머신에서 Plex를 종료해 준다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;sudo systemctl stop plexmediaserver.service         #서비스 종료
sudo systemctl status plexmediaserver.service       #종료 상태 확인&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;active상태가 아니면 종료된 상태이다.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 353px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/fe6925881c39f938ad90e920697f0ba4/6c115/plex-active.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 18.9873417721519%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAYAAACOXx+WAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAA1ElEQVQY00WMyW6EMBQECfaAWczi9dk4TPL/H1nRcMmh1a1Sq7rt2qlJiDFwv9+01rhq5ThP6lUREUIMiGSmecYH/7DP/7NzTmit6LqOlBOd0ophGDDGIFJIKXHf9xPnTqy1BBe4SuVuN5Iy67LiDkeRSpXKbnfc6ZEkH3H32L/6npwzMUZSipRSWOYZ9erZysZRDnxz2LCiR40VyxJXzu+TNa74FvDf7l+olKLUwr7vbNtGTJFlmumXnulnQnvNUAeG9KI3PWMzjHVk+p2eNm3EvA1/y1NfJhPka58AAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;plex&quot;
        title=&quot;plex&quot;
        src=&quot;/static/fe6925881c39f938ad90e920697f0ba4/6c115/plex-active.png&quot;
        srcset=&quot;/static/fe6925881c39f938ad90e920697f0ba4/c26ae/plex-active.png 158w,
/static/fe6925881c39f938ad90e920697f0ba4/6bdcf/plex-active.png 315w,
/static/fe6925881c39f938ad90e920697f0ba4/6c115/plex-active.png 353w&quot;
        sizes=&quot;(max-width: 353px) 100vw, 353px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;h1 id=&quot;2-새로운-plex-media-서버-설치&quot; style=&quot;position:relative;&quot;&gt;2. 새로운 Plex Media 서버 설치&lt;a href=&quot;#2-%EC%83%88%EB%A1%9C%EC%9A%B4-plex-media-%EC%84%9C%EB%B2%84-%EC%84%A4%EC%B9%98&quot; aria-label=&quot;2 새로운 plex media 서버 설치 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;마이그레이션 할 대상 서버에 Plex Media 서버를 설치해 준다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;echo deb https://downloads.plex.tv/repo/deb public main | sudo tee /etc/apt/sources.list.d/plexmediaserver.list
curl https://downloads.plex.tv/plex-keys/PlexSign.key | sudo apt-key add
sudo apt update &amp;amp;&amp;amp; upgrade
sudo apt install plexmediaserver&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;설치가 되었는지 확인한다. 위의 이미지처럼 active상태면 설치가 된 상태이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;sudo systemctl status plexmediaserver.service       #서비스 상태 확인&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;서버에 로그인만 해주고 로그아웃하고 종료해 줍니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;sudo systemctl stop plexmediaserver.service         #서비스 종료
sudo systemctl status plexmediaserver.service       #종료 상태 확인&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&quot;3-서버-데이터-복사&quot; style=&quot;position:relative;&quot;&gt;3 서버 데이터 복사&lt;a href=&quot;#3-%EC%84%9C%EB%B2%84-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EB%B3%B5%EC%82%AC&quot; aria-label=&quot;3 서버 데이터 복사 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;마이그레이션 할 대상 서버에 기존 서버와 똑같은 위치에 미디어들을 이동시켜 줍니다. cifs같은 경우라면 같은 위치에 마운트 해줍니다.&lt;/li&gt;
&lt;li&gt;이후에 &lt;code class=&quot;language-text&quot;&gt;Plex Media Server&lt;/code&gt;를 기존 서버에서 대상 서버로 이동시켜 줍니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;sudo rsync -avzhP USERNAME@기존_서버_IP:/var/lib/plexmediaserver/Library/Application\ Support/Plex\ Media\ Server /var/lib/plexmediaserver/Library/Application\ Support/&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;전송이 완료되면 재부팅해 줍니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;sudo reboot                                         #서비스 시작
sudo systemctl status plexmediaserver.service       #active상태 확인&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&quot;4-최종-확인&quot; style=&quot;position:relative;&quot;&gt;4 최종 확인&lt;a href=&quot;#4-%EC%B5%9C%EC%A2%85-%ED%99%95%EC%9D%B8&quot; aria-label=&quot;4 최종 확인 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;Plex 서버의 웹 gui에 로그인해서 라이브러리 스캔을 해줍니다.&lt;/li&gt;
&lt;li&gt;마이그레이션 완료!&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;참고&quot; style=&quot;position:relative;&quot;&gt;참고&lt;a href=&quot;#%EC%B0%B8%EA%B3%A0&quot; aria-label=&quot;참고 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;&lt;a href=&quot;https://support.plex.tv/articles/201370363-move-an-install-to-another-system/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;https://support.plex.tv/articles/201370363-move-an-install-to-another-system/&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[gatsby로 블로그 만들기]]></title><description><![CDATA[0. 시작하기에 앞서 이 블로그는 이창희님이 만든 gatsby-starter-lavender 블로그 테마와 김성현님의 gatsby-starter-lavender…]]></description><link>https://vulcan.site/blog-gatsby/</link><guid isPermaLink="false">https://vulcan.site/blog-gatsby/</guid><pubDate>Sun, 09 Jul 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h1 id=&quot;0-시작하기에-앞서&quot; style=&quot;position:relative;&quot;&gt;0. 시작하기에 앞서&lt;a href=&quot;#0-%EC%8B%9C%EC%9E%91%ED%95%98%EA%B8%B0%EC%97%90-%EC%95%9E%EC%84%9C&quot; aria-label=&quot;0 시작하기에 앞서 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;이 블로그는 &lt;a href=&quot;https://xo.dev/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;이창희&lt;/a&gt;님이 만든 &lt;a href=&quot;https://github.com/blurfx/gatsby-starter-lavender&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;gatsby-starter-lavender&lt;/a&gt; 블로그 테마와 &lt;a href=&quot;https://witch.work/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;김성현&lt;/a&gt;님의 &lt;a href=&quot;https://github.com/witch-factory/witch-blog&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;gatsby-starter-lavender&lt;/a&gt;를 기반으로 작성되었다.&lt;/p&gt;
&lt;p&gt;다른 블로그의 글들을 참고하면서 항상 리눅스 커맨드의 의미에 대해서 잘 모르고 무지성으로 ctrl CV를 해왔던 것 같다. 어느 정도 심도 있는 글이 아닌 이런 튜토리얼에 가까운 글에서는 커맨드의 의미에 대해서 간단하게라도 설명하는 부분이 있었으면 좋을 것 같다고 언제나 생각해 왔다. 적어도 이번 튜토리얼에서는 그동안 생각해 왔던 것을 실천할 예정이다.&lt;/p&gt;
&lt;h1 id=&quot;1-환경&quot; style=&quot;position:relative;&quot;&gt;1. 환경&lt;a href=&quot;#1-%ED%99%98%EA%B2%BD&quot; aria-label=&quot;1 환경 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;&lt;a href=&quot;https://vulcan.site/first_article/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;블로그 첫 글&lt;/a&gt;을 보면 알 수 있듯이 나는 집에서 proxmox가 올라간 서버를 굴리고 있다. 때문에 proxmox에서 제공하는 ubuntu-20.04-standard_20.04-1_amd64 템플릿에서 진행하였다. lxc container는 unprivileged mode로 생성하였다. 아마 대부분의 linux 환경에서 동작하는데 문제는 없을 것이라고 생각한다. 로컬서버가 있다면 활용해도 되고, 클라우드 서비스를 이용해도 된다.&lt;/p&gt;
&lt;p&gt;이 글에서는 Vercel, Netlify, Gatsby Cloud등을 활용해서 Deploy하는 방법에 대해선 소개하지 않는다. 추후에 기회가 된다면 이 방법들도 소개해 보도록 하겠다.&lt;/p&gt;
&lt;h1 id=&quot;2-설치&quot; style=&quot;position:relative;&quot;&gt;2. 설치&lt;a href=&quot;#2-%EC%84%A4%EC%B9%98&quot; aria-label=&quot;2 설치 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;아래 커맨드를 따라가면 된다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;adduser USERNAME                    #유저 추가
usermod -aG sudo USERNAME           #sudo 그룹에 추가(이 아래는 추가한 유저로 진행)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;“USERNAME”은 유저 이름이다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;sudo apt update &amp;amp;&amp;amp; sudo apt upgrade
sudo apt install git                #깃 설치
git clone YOUR_GIT_URL              #git repo에서 git clone
cd MY_BLOG_STARTER/                 #clone한 repo로 이동
sudo apt install npm                #npm 설치
sudo npm install -g n               #nodejs 버전관리 플러그인
sudo n lts                          #lts 버전
sudo n prune                        #이전 버전 삭제
sudo npm install                    #패키지 설치
sudo npm install -g npm@latest      #npm 최신 버전
sudo npm install -g gatsby-cli      #gatsby 설치
gatsby build                        #gatsby build&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;“YOUR_GIT_URL”은 생성한 깃 레포지토리의 주소이다.&lt;/p&gt;
&lt;p&gt;“MY_BLOG_STARTER”는 클론된 디렉토리이다.&lt;/p&gt;
&lt;p&gt;사용된 버전&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 630px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/a0296d95645d7930a742d4d98b1b01a5/a1dd2/version.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 21.51898734177215%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAYAAACOXx+WAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAe0lEQVQY05WOWw5EIQhD9aooKsbX/rfaCcws4M5HQ0vgpG7vg7UWmBnMBa038601dBEQEbz3cM69k8L22eDK9qwwymRw9aUUhBDeA++9UIkIeu/WVqRbrq0i54znef4HzjlxzsEYw7xOhaWUrHlS/TxRQozRst6ovnvCB72NVck7oM9HAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;version&quot;
        title=&quot;version&quot;
        src=&quot;/static/a0296d95645d7930a742d4d98b1b01a5/f058b/version.png&quot;
        srcset=&quot;/static/a0296d95645d7930a742d4d98b1b01a5/c26ae/version.png 158w,
/static/a0296d95645d7930a742d4d98b1b01a5/6bdcf/version.png 315w,
/static/a0296d95645d7930a742d4d98b1b01a5/f058b/version.png 630w,
/static/a0296d95645d7930a742d4d98b1b01a5/a1dd2/version.png 838w&quot;
        sizes=&quot;(max-width: 630px) 100vw, 630px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;아래와 같이 빌드되면 성공이다&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 466px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/92bf588debf3a4605916eddf2c4eac1d/fc1a1/build.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 10.126582278481013%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAACCAYAAABYBvyLAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAb0lEQVQI10XNMQ7DIBBE0bVjCykOGHYXAiL3v+aPQpPiaYpfjOz2QFSQJkgRruvFGJ2strZWx7xyHgchBGK66f2N18q2bYuI/O2HIuKc4cn4dFR1cXdaa8w5MTNijKQ7UUpZfYxBLoq5kXNe/Xf+BURPLnGRMFgIAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;build-sucsess&quot;
        title=&quot;build-sucsess&quot;
        src=&quot;/static/92bf588debf3a4605916eddf2c4eac1d/fc1a1/build.png&quot;
        srcset=&quot;/static/92bf588debf3a4605916eddf2c4eac1d/c26ae/build.png 158w,
/static/92bf588debf3a4605916eddf2c4eac1d/6bdcf/build.png 315w,
/static/92bf588debf3a4605916eddf2c4eac1d/fc1a1/build.png 466w&quot;
        sizes=&quot;(max-width: 466px) 100vw, 466px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;빌드가 성공하면 해당 디렉토리에 public 디렉토리가 생성된다.&lt;/p&gt;
&lt;h1 id=&quot;3-nginx-설정&quot; style=&quot;position:relative;&quot;&gt;3. nginx 설정&lt;a href=&quot;#3-nginx-%EC%84%A4%EC%A0%95&quot; aria-label=&quot;3 nginx 설정 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;웹서버로 nginx를 사용해서 정적 웹페이지를 띄워준다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;sudo apt install nginx                              #nginx 설치
sudo nano /etc/nginx/sites-available/static.site    #설정파일 편집&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;아래 설정을 복붙해준다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;nginx&quot;&gt;&lt;pre class=&quot;language-nginx&quot;&gt;&lt;code class=&quot;language-nginx&quot;&gt;&lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;server&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;listen&lt;/span&gt;       YOUR_PORT_NUMBER&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;server_name&lt;/span&gt;  0.0.0.0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;charset&lt;/span&gt;      utf-8&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;index&lt;/span&gt;        index.htm index.html&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;root&lt;/span&gt;         YOUR_PUBLIC_FILE_PATH&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;“YOUR_PORT_NUMBER”를 원하는 포트 번호로, YOUR_PUBLIC_FILE_PATH를 빌드된 public 디렉토리 경로로 바꿔야한다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;sudo ln -s /etc/nginx/sites-available/static.site /etc/nginx/sites-enabled/     #링크
sudo nginx -t                                                                   #테스트
sudo service nginx reload                                                       #nginx reload&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;ip a&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 630px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/631bba5d874ea018b968557fcef8a8f2/2eb79/find_ip.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 22.78481012658228%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAFCAYAAABFA8wzAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAsUlEQVQY04WPyQ7DIAxEyUKisAhsMJdW/f+/nMpWg6peeniyjOAx45gZXTpqrcg5I6WEEAJiDLiuy0gp2jzPEzFGHMdh6K7Te49lWeCcg1PJGAIT924Q0RQr96N1XQ19/IvJFE1GzChEkDHQWrO0KiylWOpt27Dv+0zm/W77ff6N0zSvIXgy4zEGuLWZWETsA71TakGtZVZW2bfw3l3OCaN3iAo+lVVETCZjJqs5K/3hDcU1bx/oo8KrAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;find_ip&quot;
        title=&quot;find_ip&quot;
        src=&quot;/static/631bba5d874ea018b968557fcef8a8f2/f058b/find_ip.png&quot;
        srcset=&quot;/static/631bba5d874ea018b968557fcef8a8f2/c26ae/find_ip.png 158w,
/static/631bba5d874ea018b968557fcef8a8f2/6bdcf/find_ip.png 315w,
/static/631bba5d874ea018b968557fcef8a8f2/f058b/find_ip.png 630w,
/static/631bba5d874ea018b968557fcef8a8f2/40601/find_ip.png 945w,
/static/631bba5d874ea018b968557fcef8a8f2/2eb79/find_ip.png 1256w&quot;
        sizes=&quot;(max-width: 630px) 100vw, 630px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;위 커맨드를 쳐서 나오는 아이피 + 위에 설정한 포트 번호로 접속하면 된다.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 630px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/ea901921d97170c2e3d6cf927cccc4d6/9b29b/result.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 54.43037974683544%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAABYlAAAWJQFJUiTwAAAA60lEQVQoz6WRQU7DMBBFc5PGnhkHx3Fiu5BWKosKiTN0y/0v8VGckGJBCILFW/nP8x+7CuEI30e0bYIRD2P6GfGwbYK1EczdStMM98yCiM/zw3BCVWvChCKCYs5oZtRECF2Hl+sVfYh4aDtY5+H8AC1S5DM0eTQqzYIVuqNYYMUgxRExzaTjCNcFKCqzmcVRCj+hiJGezoiPJzTWLVtwZj7/fm5TeFAKl+dX3G5vGM8XHJQuLtuaq7baTbTOgUQK2Z602g4yas3raj+1+tXKXwX/FG612mu62/DjPcsf5r83JDForM2waXYbvgP0+juuMLcUtQAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;result&quot;
        title=&quot;result&quot;
        src=&quot;/static/ea901921d97170c2e3d6cf927cccc4d6/f058b/result.png&quot;
        srcset=&quot;/static/ea901921d97170c2e3d6cf927cccc4d6/c26ae/result.png 158w,
/static/ea901921d97170c2e3d6cf927cccc4d6/6bdcf/result.png 315w,
/static/ea901921d97170c2e3d6cf927cccc4d6/f058b/result.png 630w,
/static/ea901921d97170c2e3d6cf927cccc4d6/40601/result.png 945w,
/static/ea901921d97170c2e3d6cf927cccc4d6/78612/result.png 1260w,
/static/ea901921d97170c2e3d6cf927cccc4d6/9b29b/result.png 3840w&quot;
        sizes=&quot;(max-width: 630px) 100vw, 630px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;잘 나오는 것을 볼 수 있다.&lt;/p&gt;
&lt;h1 id=&quot;4-crontab-설정&quot; style=&quot;position:relative;&quot;&gt;4. crontab 설정&lt;a href=&quot;#4-crontab-%EC%84%A4%EC%A0%95&quot; aria-label=&quot;4 crontab 설정 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;작성한 글은 깃허브에 올라가게 된다. 다만 글을 쓸때마다 서버에 접속해서 git pull을 하고 gatsby build를 해주는 것을 번거로운 일이다. 때문에 이것을 crontab과 간단한 스크립트로 자동화하도록 하자.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;sudo nano MY_BLOG_STARTER/build.sh      #build 스크립트 작성&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;아래 스크립트로 복붙한다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;git pull
gatsby build&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;sudo nano /etc/crontab                  #crontab 수정&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;맨 밑에 아래 명령어를 복붙한다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;*/30 * * * * USERNAME cd MY_BLOG_STARTER &amp;amp;&amp;amp; bash build.sh   #30분 마다 실행된다.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;“USERNAME”은 유저 이름이다.&lt;/p&gt;
&lt;p&gt;“MY_BLOG_STARTER”는 클론된 디렉토리이다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;sudo service cron reload                #cron reload&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;proxmox의 CPU모니터링 그래프를 보면 30분마다 실행되고 빌드가 되면서 CPU 사용량이 올라가는 것을 볼 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 630px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/e8e1561272c7def35b497bb86eb27ec9/2bcd1/proxmox-cpu-graph.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 31.645569620253163%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAYAAADDl76dAAAACXBIWXMAABYlAAAWJQFJUiTwAAAA2klEQVQY052NW27DIBQFvZiYx72AiUsdWYp5uG72v6NTAW6a/PZjBJojhsGHBVO4wVr7b7y3CCHAuQkDM0Fr/YZSGtZJEPf7+67aaayCJvXyRjWGyXuwMU0SUUNJwrIKOKehFT19pzpGWCScr8G/rTZ6kF+DGlIQ7vmC+UO2eHW/W6W6dRsRFnHu50c1SMRQZKCIoSvMGAUjPS74XCWEPP0TwigM4jHidhcQ0oAMt/dKE4Z5npFyQUwZMXe2mPD1yNiP6gu2lLC1vSCV7vbviP3oLpeMVHb46xU/6fy5LfLQXMcAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;graph&quot;
        title=&quot;graph&quot;
        src=&quot;/static/e8e1561272c7def35b497bb86eb27ec9/f058b/proxmox-cpu-graph.png&quot;
        srcset=&quot;/static/e8e1561272c7def35b497bb86eb27ec9/c26ae/proxmox-cpu-graph.png 158w,
/static/e8e1561272c7def35b497bb86eb27ec9/6bdcf/proxmox-cpu-graph.png 315w,
/static/e8e1561272c7def35b497bb86eb27ec9/f058b/proxmox-cpu-graph.png 630w,
/static/e8e1561272c7def35b497bb86eb27ec9/40601/proxmox-cpu-graph.png 945w,
/static/e8e1561272c7def35b497bb86eb27ec9/78612/proxmox-cpu-graph.png 1260w,
/static/e8e1561272c7def35b497bb86eb27ec9/2bcd1/proxmox-cpu-graph.png 1561w&quot;
        sizes=&quot;(max-width: 630px) 100vw, 630px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;h1 id=&quot;참고&quot; style=&quot;position:relative;&quot;&gt;참고&lt;a href=&quot;#%EC%B0%B8%EA%B3%A0&quot; aria-label=&quot;참고 permalink&quot; class=&quot;heading-anchor after&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;&lt;a href=&quot;https://www.wsgvet.com/staticsite/18&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;https://www.wsgvet.com/staticsite/18&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://study-melody.tistory.com/45&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;https://study-melody.tistory.com/45&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://happist.com/553442/%EC%84%9C%EB%B2%84%EC%97%90%EC%84%9C-%EC%9E%90%EB%8F%99-%EC%8B%A4%ED%96%89%EC%9D%84-%EA%B0%80%EB%8A%A5%EC%BC%80-%ED%95%B4%EC%A3%BC%EB%8A%94-crontab%ED%81%AC%EB%A1%A0%ED%83%AD-%EC%84%A4%EC%A0%95&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;https://happist.com/553442/%EC%84%9C%EB%B2%84%EC%97%90%EC%84%9C-%EC%9E%90%EB%8F%99-%EC%8B%A4%ED%96%89%EC%9D%84-%EA%B0%80%EB%8A%A5%EC%BC%80-%ED%95%B4%EC%A3%BC%EB%8A%94-crontab%ED%81%AC%EB%A1%A0%ED%83%AD-%EC%84%A4%EC%A0%95&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[블로그 첫 글]]></title><description><![CDATA[Dashboard : Grafana 하드웨어 Type Name Q’ty CPU Intel(R) Xeon(R) CPU E5-2696 v4 @ 2.20GHz 2ea(2 Sockets) RAM SAMSUNG DDR4-3200 ECC/REG (32GB…]]></description><link>https://vulcan.site/first_article/</link><guid isPermaLink="false">https://vulcan.site/first_article/</guid><pubDate>Sun, 21 May 2023 00:00:00 GMT</pubDate><content:encoded>&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Dashboard : &lt;a href=&quot;https://grafana.vulcan.site/d/lddZaVA4z/main?orgId=3&amp;#x26;refresh=10s&amp;#x26;kiosk&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Grafana&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;하드웨어&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;left&quot;&gt;Type&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;Name&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;Q’ty&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;CPU&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;Intel(R) Xeon(R) CPU E5-2696 v4 @ 2.20GHz&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;2ea(2 Sockets)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;RAM&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;SAMSUNG DDR4-3200 ECC/REG (32GB)&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;8ea&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;MAINBOARD&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;HUANANZHI- F8D PLUS&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;1ea&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;SSD&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;SK hynix GOLD P31 NVMe 2TB&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;2ea(ZFS MIRROR)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;SK hynix GOLD P31 NVMe 500GB&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;2ea(ZFS STRIPE)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;GPU&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;NVIDIA® QUADRO® P4000&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;1ea&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;NVIDIA® QUADRO® P2000&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;1ea&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;NET card&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;RTL8125B 2.5G quad port NETWORK adapter&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;1ea&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;Chelsio T540-CR Quad Port SFP+ 10GbE&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;1ea&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;Mellanox MCX354A-FCBT CONNECTX-3&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;1ea&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;HBA card&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;LSI 9207-8i 6Gbs SAS HBA P20&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;1ea&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;HDD&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;Seagate 14TB HDD Exos X16 ST14000NM001G 14T SATA 6 Gb/s 7200RPM&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;8ea(6ea ZFS RAIDZ2, 2ea spare)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;CASE&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;Fractal Design Define 7 XL Black&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;1ea&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;CPU cooler&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;DEEPCOOL AG620&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;2ea&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;POWER&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;Seasonic FOCUS GOLD GM-750 Modular&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;1ea&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;UPS&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;BX1600MI-GR&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;1ea&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Virtual Machine&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Hypervisor &amp;#x26; Host OS : PROXMOX&lt;/li&gt;
&lt;li&gt;Fierwall &amp;#x26; Router : pfsense&lt;/li&gt;
&lt;li&gt;Proxy : HA Proxy&lt;/li&gt;
&lt;li&gt;VPN : OpenVPN&lt;/li&gt;
&lt;li&gt;DNS Resolver : unbound&lt;/li&gt;
&lt;li&gt;Local DNS : Pi-hole&lt;/li&gt;
&lt;li&gt;NAS : TureNAS Scale&lt;/li&gt;
&lt;li&gt;Cloud : Nextcloud&lt;/li&gt;
&lt;li&gt;Media Stream : Plex&lt;/li&gt;
&lt;li&gt;UPS control : NUT server&lt;/li&gt;
&lt;li&gt;Monitoring : Grafana(lm-sensors, Telegraf, InfluxDB, Prometheus, Tautulli)&lt;/li&gt;
&lt;li&gt;Stable Diffusion Webui&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Container&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;blog&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item></channel></rss>