<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>Cumulus(송현준)</title>
    <link>https://cumulus.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Sun, 31 May 2026 23:55:21 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>Joon0464</managingEditor>
    <image>
      <title>Cumulus(송현준)</title>
      <url>https://tistory1.daumcdn.net/tistory/4791217/attach/a0d5bed296864602a26817671264e944</url>
      <link>https://cumulus.tistory.com</link>
    </image>
    <item>
      <title>Linux systemd 완전 정복하기</title>
      <link>https://cumulus.tistory.com/158</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;systemd&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리눅스 시스템 관리에 있어서 systemd는 중요한 구성 요소 중 하나입니다. 이 글에서는 systemd가 무엇인지, 그리고 systemd에서 사용하는 유닛 파일들에 대해 자세히 알아보겠습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;systemd란?&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;systemd는 리눅스 시스템과 서비스 관리자로, 초기화 시스템(init), 시스템 서비스 관리자, 그리고 세션 관리자의 역할을 합니다. 대부분의 최신 리눅스 배포판에서는 기본 초기화 시스템으로 systemd를 사용합니다. systemd는 시스템의 부팅 과정을 책임지며, 시스템이 가동되는 동안 서비스들을 시작, 중지, 관리합니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;systemd의 주요 기능&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;병렬 처리&lt;/b&gt;: systemd는 서비스들을 병렬로 시작합니다. 이는 시스템의 부팅 시간을 단축시킵니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;유닛 파일&lt;/b&gt;: 서비스, 소켓, 디바이스 등을 관리하기 위한 설정 파일입니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;종속성 관리&lt;/b&gt;: 서비스들 사이의 종속성을 관리하여, 필요한 서비스들이 올바른 순서로 시작되도록 합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;자동 마운트&lt;/b&gt;: 외부 저장 장치를 자동으로 마운트하고 관리합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;로그 관리&lt;/b&gt;: systemd의 일부인 journald를 통해, 시스템 로그와 서비스 로그를 관리합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 init은 초기화 때 순서대로 서비스를 시작하지만 systemd는 어느 서비스든 종속성만 충족되면 시작할 수 있으므로 시작 시간을 단축시킬 수 있습니다. 언제 무엇을 어떻게 실행할 것인지 systemd에 지시하기 위한 방법으로 unit을 사용하게 됩니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;systemd unit&lt;/b&gt;&lt;/h3&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;systemd에서는 다양한 리소스를 '유닛(Unit)'으로 관리하며 서비스(.service), 마운트(.mount), 소켓(.socket) 등 다양한 유형이 있습니다. Systemd는 다양한 unit 을 통해 리눅스 시스템의 서비스와 자원을 관리합니다. 각 unit 은 시스템의 다른 부분을 관리하며, 다음은 주요 unit 의 종류와 그 설명입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. service 유닛&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;서비스나 애플리케이션을 관리하는 데 사용됩니다.&lt;/li&gt;
&lt;li&gt;어떻게 서비스가 시작되고, 중지되고, 재시작되는지를 정의합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. target 유닛&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;여러 유닛을 그룹화하여 관리하는 데 사용됩니다.&lt;/li&gt;
&lt;li&gt;시스템의 특정 상태에 도달하기 위해 필요한 유닛들을 조합할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. mount 유닛&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;파일 시스템 마운트 지점을 관리합니다.&lt;/li&gt;
&lt;li&gt;/etc/fstab에 있는 마운트 지점을 systemd unit으로 변환할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;4. timer 유닛&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;시간 기반의 작업을 스케줄링하는 데 사용됩니다.&lt;/li&gt;
&lt;li&gt;cron 대신 사용할 수 있으며, 특정 시간에 서비스를 시작하도록 할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;5. socket 유닛&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;IPC 소켓, TCP 소켓 등 네트워크 소켓을 관리합니다.&lt;/li&gt;
&lt;li&gt;서비스가 필요할 때만 서비스를 시작하도록 하는 데 사용될 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;6. device 유닛&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;시스템의 디바이스를 나타냅니다.&lt;/li&gt;
&lt;li&gt;udev 규칙에 의해 생성되며, 특정 디바이스에 대한 의존성을 정의할 때 사용됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;7. automount 유닛&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;파일 시스템 마운트 지점을 자동으로 마운트하는 데 사용됩니다.&lt;/li&gt;
&lt;li&gt;접근 시에만 마운트를 활성화하도록 설정할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;8. swap 유닛&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;swap 유닛은 스왑 공간을 관리합니다.&lt;/li&gt;
&lt;li&gt;swap 파일이나 swap 파티션을 정의하여 사용할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;9. path 유닛&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;패스 유닛은 파일 시스템의 경로를 감시하고, 변경 사항이 있을 때 서비스를 활성화합니다.&lt;/li&gt;
&lt;li&gt;특정 파일이나 디렉토리의 변화를 감지할 때 사용됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;10. snapshot 유닛&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;시스템의 현재 상태를 snapshot으로 저장합니다.&lt;/li&gt;
&lt;li&gt;시스템 설정이나 서비스 상태를 임시로 저장하고 복원할 때 사용됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;11. slice 유닛&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;시스템 프로세스를 그룹화하여 리소스 관리를 수행합니다.&lt;/li&gt;
&lt;li&gt;cgroups를 사용하여 리소스 사용량을 제한하고 관리합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;12. scope 유닛&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;시스템에서 직접 생성하지 않은 프로세스를 systemd의 관리 하에 두기 위해 사용됩니다.&lt;/li&gt;
&lt;li&gt;사용자가 직접 시작한 프로세스 또는 다른 시스템 프로세스에서 파생된 프로세스를 관리하는 데 사용할 수 있습니다.&lt;/li&gt;
&lt;li&gt;주로 시스템의 리소스 할당 및 관리를 위해 systmed에 의해 내부적으로 사용됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Unit 파일 경로&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;systemd에게 인식되려면 unit은 하나의 파일로 직렬화되어야 합니다. systemd는 아래와 같이 여러 위치에서 unit 파일을 찾습니다. 가장 중요한 파일 경로 세 가지는 다음과 같습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;code&gt;/lib/systemd/system&lt;/code&gt;&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이 디렉토리는 일반적으로 패키지 관리자에 의해 설치된 유닛 파일들을 저장합니다. 즉, 시스템에 설치된 소프트웨어나 서비스가 자동으로 생성하는 유닛 파일들이 여기에 위치합니다.&lt;/li&gt;
&lt;li&gt;사용자가 직접 수정하기보다는, 패키지 업데이트 시 변경사항을 반영하기 위해 남겨둡니다. 사용자 정의 설정이 필요한 경우, &lt;code&gt;/etc/systemd/system&lt;/code&gt;에 유닛 파일을 복사하여 수정합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;code&gt;/etc/systemd/system&lt;/code&gt;&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;시스템 관리자가 직접 생성하거나 수정한 유닛 파일들을 위한 디렉토리입니다. 여기에 배치된 파일들은 &lt;code&gt;/lib/systemd/system&lt;/code&gt;에 있는 파일들보다 우선권을 가집니다.&lt;/li&gt;
&lt;li&gt;이는 사용자가 특정 서비스의 동작 방식을 변경하고자 할 때 사용됩니다. 예를 들어, 기본 서비스 유닛 파일에 사용자 정의 옵션을 추가하거나 수정하는 경우입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;code&gt;/run/systemd/system&lt;/code&gt;&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이 디렉토리는 시스템이 실행 중일 때 생성되는 유닛 파일들을 저장합니다. 주로 시스템의 런타임 중에 발생하는 비지속적인 수정사항을 담당합니다.&lt;/li&gt;
&lt;li&gt;여기에 저장된 파일들은 시스템이 재부팅되면 사라지므로, 임시적인 변경을 위해 사용됩니다. 예를 들어, 시스템의 현재 실행 세션에만 적용될 서비스 변경사항을 반영할 때 이용됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Systemd Unit 파일 작성 방법&lt;/b&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Systemd unit 파일은 대략적으로 다음과 같은 구조로 이루어져 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;/etc/systemd/system/my-web.service&lt;span style=&quot;background-color: #ffffff; color: #1a1918; text-align: start;&quot;&gt; 파일을 생성하고 다음 내용을 입력합니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;[Unit]
Description=My Simple Web Server
After=network.target

[Service]
ExecStart=/usr/bin/python3 -m http.server 8000
WorkingDirectory=/home/user/web
User=user
Restart=on-failure

[Install]
WantedBy=multi-user.target&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;[Unit] 섹션&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;&lt;code&gt;Description&lt;/code&gt;&lt;/b&gt;: 서비스에 대한 간략한 설명입니다. 이 예제에서는 &quot;My Simple Web Server&quot;라고 설명하고 있습니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;code&gt;After&lt;/code&gt;&lt;/b&gt;: 이 서비스가 시작되기 전에 먼저 시작되어야 하는 다른 유닛을 명시합니다. 여기서는 네트워크가 준비된 후(&lt;code&gt;&lt;b&gt;network.target&lt;/b&gt;&lt;/code&gt;)에 웹 서버가 시작되도록 설정하였습니다.&lt;/li&gt;
&lt;li&gt;더 자세한 내용 및 옵션 정보는&amp;nbsp; &lt;a style=&quot;background-color: #e6f5ff; color: #0070d1; text-align: left;&quot; href=&quot;https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/9/html/using_systemd_unit_files_to_customize_and_optimize_your_system/assembly_working-with-systemd-unit-files_working-with-systemd#con_unit-file-structure_assembly_working-with-systemd-unit-files&quot;&gt;[Unit] Section Official Docs&lt;/a&gt; 를 참고하면 됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;[Service] 섹션&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;&lt;code&gt;ExecStart&lt;/code&gt;&lt;/b&gt;: 서비스를 시작할 때 실행할 명령어입니다.&amp;nbsp; 예제에서는 Python 3의 내장 HTTP 서버 모듈을 8000번 포트에서 실행하는 명령어를 사용합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;code&gt;WorkingDirectory&lt;/code&gt;&lt;/b&gt;: 서비스가 실행될 때 작업 디렉토리를 지정합니다. 여기서는 &lt;b&gt;&lt;code&gt;/home/user/web&lt;/code&gt;&lt;/b&gt;으로 설정하였습니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;code&gt;User&lt;/code&gt;&lt;/b&gt;: 서비스를 실행할 사용자를 지정합니다. 이 예제에서는 &lt;b&gt;&lt;code&gt;user&lt;/code&gt; &lt;/b&gt;사용자를 사용합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;code&gt;Restart&lt;/code&gt;&lt;/b&gt;: 서비스가 실패할 경우 재시작 정책을 정의합니다. &lt;code&gt;&lt;b&gt;on-failure&lt;/b&gt;&lt;/code&gt;로 설정하면 서비스가 실패했을 때만 재시작됩니다.&lt;/li&gt;
&lt;li&gt;더 자세한 내용 및 옵션 정보는 &lt;a style=&quot;background-color: #e6f5ff; color: #0070d1; text-align: left;&quot; href=&quot;https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/9/html/using_systemd_unit_files_to_customize_and_optimize_your_system/assembly_working-with-systemd-unit-files_working-with-systemd#ref_important-service-section-options_assembly_working-with-systemd-unit-files&quot;&gt;[Service] Section Official Docs&lt;/a&gt; &lt;span style=&quot;color: #333333; text-align: left;&quot;&gt;를 참고하면 됩니다&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;[Install] 섹션&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;&lt;code&gt;WantedBy&lt;/code&gt;&lt;/b&gt;: 이 유닛이 활성화될 때 자동으로 시작되어야 하는 대상을 지정합니다. &lt;b&gt;&lt;code&gt;multi-user.target&lt;/code&gt;&lt;/b&gt;으로 설정하면 시스템이 다중 사용자 모드로 부팅할 때 서비스가 시작됩니다.&lt;/li&gt;
&lt;li&gt;더 자세한 내용 및 옵션 정보는 &lt;a style=&quot;color: #0070d1;&quot; href=&quot;https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/9/html/using_systemd_unit_files_to_customize_and_optimize_your_system/assembly_working-with-systemd-unit-files_working-with-systemd#ref_important-install-section-options_assembly_working-with-systemd-unit-files&quot;&gt;[Install] Section Official Docs&lt;/a&gt; &lt;span style=&quot;color: #333333; text-align: left;&quot;&gt;를 참고하면 됩니다&lt;/span&gt;&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;systemctl로 관리하기&lt;/b&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에 작성한 my-web.service &lt;span style=&quot;background-color: #ffffff; color: #1a1918; text-align: start;&quot;&gt;unit 파일을 활성화하고 시작하기 위해 다음 명령어를 사용합니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1715058161637&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ sudo systemctl enable my-web.service
$ sudo systemctl daemon-reload 
$ sudo systemctl start my-web.service&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1a1918; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이제 my-web.service가 시스템 부팅 시 자동으로 시작됩니다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1a1918; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이 내용을 통해 systemd unit 파일의 종류와 기본적인 작성 방법에 대해 알아보았습니다. 추가적으로 systemctl 의 주로 사용하는 명령어는 아래와 같습니다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 328px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 31.3954%; height: 20px;&quot;&gt;&lt;b&gt;명령어&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 68.6046%; height: 20px;&quot;&gt;&lt;b&gt;설명&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 31.3954%; height: 20px;&quot;&gt;systemctl&amp;nbsp;enable&amp;nbsp;[서비스명]&lt;/td&gt;
&lt;td style=&quot;width: 68.6046%; height: 20px;&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;해당 서비스를 시스템 부팅 시 자동으로 시작하도록 설정합니다. 이 작업은 서비스의 심볼릭 링크를 생성하여 관련된 타겟에 등록합니다.&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 40px;&quot;&gt;
&lt;td style=&quot;width: 31.3954%; height: 40px;&quot;&gt;systemctl&amp;nbsp;disable&amp;nbsp;[서비스명]&lt;/td&gt;
&lt;td style=&quot;width: 68.6046%; height: 40px;&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;서비스가&amp;nbsp;시스템&amp;nbsp;부팅&amp;nbsp;시&amp;nbsp;자동으로&amp;nbsp;시작되지&amp;nbsp;않도록&amp;nbsp;설정을&amp;nbsp;해제합니다.&amp;nbsp;이는&amp;nbsp;서비스의&amp;nbsp;심볼릭&amp;nbsp;링크를&amp;nbsp;제거합니다.&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 40px;&quot;&gt;
&lt;td style=&quot;width: 31.3954%; height: 40px;&quot;&gt;systemctl&amp;nbsp;daemon-reload&lt;/td&gt;
&lt;td style=&quot;width: 68.6046%; height: 40px;&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;systemd의&amp;nbsp;설정을&amp;nbsp;다시&amp;nbsp;불러오도록&amp;nbsp;합니다.&amp;nbsp;이&amp;nbsp;명령어는&amp;nbsp;unit&amp;nbsp;파일을&amp;nbsp;수정한&amp;nbsp;후에&amp;nbsp;변경사항을&amp;nbsp;적용하기&amp;nbsp;위해&amp;nbsp;사용됩니다.&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 31.3954%; height: 20px;&quot;&gt;systemctl&amp;nbsp;start&amp;nbsp;[서비스명]&lt;/td&gt;
&lt;td style=&quot;width: 68.6046%; height: 20px;&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;지정한&amp;nbsp;서비스를&amp;nbsp;즉시&amp;nbsp;시작합니다.&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 31.3954%; height: 20px;&quot;&gt;systemctl&amp;nbsp;stop&amp;nbsp;[서비스명]&lt;/td&gt;
&lt;td style=&quot;width: 68.6046%; height: 20px;&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;지정한&amp;nbsp;서비스를&amp;nbsp;즉시&amp;nbsp;중지합니다.&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 31.3954%; height: 17px;&quot;&gt;systemctl&amp;nbsp;restart&amp;nbsp;[서비스명]&lt;/td&gt;
&lt;td style=&quot;width: 68.6046%; height: 17px;&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;지정한&amp;nbsp;서비스를&amp;nbsp;재시작합니다.&amp;nbsp;서비스를&amp;nbsp;중지한&amp;nbsp;다음&amp;nbsp;다시&amp;nbsp;시작하는&amp;nbsp;것과&amp;nbsp;동일한&amp;nbsp;효과를&amp;nbsp;가집니다.&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 31.3954%; height: 17px;&quot;&gt;systemctl&amp;nbsp;reload&amp;nbsp;[서비스명]&lt;/td&gt;
&lt;td style=&quot;width: 68.6046%; height: 17px;&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;서비스의&amp;nbsp;설정을&amp;nbsp;다시&amp;nbsp;불러옵니다.&amp;nbsp;서비스를&amp;nbsp;중지하지&amp;nbsp;않고&amp;nbsp;구성을&amp;nbsp;새로고칠&amp;nbsp;때&amp;nbsp;사용됩니다.&amp;nbsp;단,&amp;nbsp;모든&amp;nbsp;서비스가&amp;nbsp;이&amp;nbsp;기능을&amp;nbsp;지원하는&amp;nbsp;것은&amp;nbsp;아닙니다.&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 31.3954%; height: 17px;&quot;&gt;systemctl&amp;nbsp;kill&amp;nbsp;[서비스명]&lt;/td&gt;
&lt;td style=&quot;width: 68.6046%; height: 17px;&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;지정한&amp;nbsp;서비스에&amp;nbsp;신호를&amp;nbsp;보내&amp;nbsp;프로세스를&amp;nbsp;종료합니다.&amp;nbsp;특정&amp;nbsp;상황에서&amp;nbsp;서비스를&amp;nbsp;강제로&amp;nbsp;중지할&amp;nbsp;때&amp;nbsp;사용됩니다.&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 31.3954%; height: 17px;&quot;&gt;systemctl&amp;nbsp;status&amp;nbsp;[서비스명]&lt;/td&gt;
&lt;td style=&quot;width: 68.6046%; height: 17px;&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;지정한&amp;nbsp;서비스의&amp;nbsp;상태를&amp;nbsp;보여줍니다.&amp;nbsp;서비스가&amp;nbsp;활성화되어&amp;nbsp;있는지,&amp;nbsp;현재&amp;nbsp;실행&amp;nbsp;중인지,&amp;nbsp;로그&amp;nbsp;메시지는&amp;nbsp;어떤&amp;nbsp;것들이&amp;nbsp;있는지&amp;nbsp;등의&amp;nbsp;정보를&amp;nbsp;확인할&amp;nbsp;수&amp;nbsp;있습니다.&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 40px;&quot;&gt;
&lt;td style=&quot;width: 31.3954%; height: 40px;&quot;&gt;systemctl&amp;nbsp;is-enabled&amp;nbsp;[서비스명]&lt;/td&gt;
&lt;td style=&quot;width: 68.6046%; height: 40px;&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;지정한&amp;nbsp;서비스가&amp;nbsp;부팅&amp;nbsp;시&amp;nbsp;자동으로&amp;nbsp;시작되도록&amp;nbsp;설정되었는지&amp;nbsp;확인합니다.&amp;nbsp;enabled,&amp;nbsp;disabled,&amp;nbsp;static&amp;nbsp;등의&amp;nbsp;상태를&amp;nbsp;반환합니다.&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 31.3954%; height: 20px;&quot;&gt;systemctl&amp;nbsp;is-active&amp;nbsp;[서비스명]&lt;/td&gt;
&lt;td style=&quot;width: 68.6046%; height: 20px;&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;지정한&amp;nbsp;서비스가&amp;nbsp;현재&amp;nbsp;활성화(실행&amp;nbsp;중)&amp;nbsp;상태인지&amp;nbsp;확인합니다.&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 31.3954%; height: 20px;&quot;&gt;systemctl&amp;nbsp;list-units&amp;nbsp;--type=service&lt;/td&gt;
&lt;td style=&quot;width: 68.6046%; height: 20px;&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;시스템에서&amp;nbsp;현재&amp;nbsp;활성화되어&amp;nbsp;있는&amp;nbsp;모든&amp;nbsp;서비스의&amp;nbsp;목록을&amp;nbsp;보여줍니다.&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 31.3954%; height: 20px;&quot;&gt;systemctl&amp;nbsp;list-unit-files&amp;nbsp;--type=service&lt;/td&gt;
&lt;td style=&quot;width: 68.6046%; height: 20px;&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;시스템에&amp;nbsp;설치된&amp;nbsp;모든&amp;nbsp;서비스&amp;nbsp;파일의&amp;nbsp;목록과&amp;nbsp;그&amp;nbsp;상태(활성화,&amp;nbsp;비활성화)를&amp;nbsp;보여줍니다.&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;추가적으로 systemd 생태계에서 사용하기 편리하며 알아두면 좋은 커맨드라인 도구가 많이 존재합니다.&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1a1918; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;bootctl&lt;/b&gt;, &lt;b&gt;timedatectl&lt;/b&gt;, &lt;b&gt;coredumpctl&lt;/b&gt;, 그리고 &lt;b&gt;journalctl&lt;/b&gt;은 systemd 환경에서 시스템 관리와 진단을 위해 사용되는 명령어들입니다. 각각의 명령어는 아래와 같은 용도로 사용됩니다:&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal; background-color: #ffffff; color: #1a1918; text-align: start;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li style=&quot;color: #1a1918;&quot;&gt;&lt;b&gt;bootctl&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc; color: #1a1918;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;color: #1a1918;&quot;&gt;설명:&lt;span&gt;&amp;nbsp;&lt;/span&gt;bootctl&lt;span&gt;&amp;nbsp;&lt;/span&gt;명령어는 systemd-boot 부트로더와 관련된 작업을 수행하기 위해 사용됩니다. systemd-boot는 UEFI 시스템에서 사용할 수 있는 간단한 EFI 부트로더입니다.&lt;/li&gt;
&lt;li style=&quot;color: #1a1918;&quot;&gt;사용 케이스: 부트로더의 상태 확인, 부트로더 설치 또는 업데이트, 부트 항목의 관리 등을 할 때 사용합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li style=&quot;color: #1a1918;&quot;&gt;&lt;b&gt;timedatectl&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc; color: #1a1918;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;color: #1a1918;&quot;&gt;설명:&lt;span&gt;&amp;nbsp;&lt;/span&gt;timedatectl&lt;span&gt;&amp;nbsp;&lt;/span&gt;명령어는 시스템의 날짜와 시간 설정을 관리하기 위해 사용됩니다. 이 명령어를 통해 시간대(timezone) 설정, 네트워크 시간 프로토콜(NTP) 설정의 활성화나 비활성화, 현재 시간 설정 등을 할 수 있습니다.&lt;/li&gt;
&lt;li style=&quot;color: #1a1918;&quot;&gt;사용 케이스: 시스템의 현재 날짜와 시간 확인, 시간대 변경, NTP를 통한 시간 동기화 설정 등에 사용됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li style=&quot;color: #1a1918;&quot;&gt;&lt;b&gt;coredumpctl&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc; color: #1a1918;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;color: #1a1918;&quot;&gt;설명:&lt;span&gt;&amp;nbsp;&lt;/span&gt;coredumpctl&lt;span&gt;&amp;nbsp;&lt;/span&gt;명령어는 시스템에서 발생한 코어 덤프를 관리하고 검사하기 위한 도구입니다. 이 명령어를 사용하여 코어 덤프 파일의 목록을 확인하고, 특정 코어 덤프의 상세 정보를 보거나, gdb와 같은 디버거로 코어 덤프를 분석할 수 있습니다.&lt;/li&gt;
&lt;li style=&quot;color: #1a1918;&quot;&gt;사용 케이스: 프로그램이 비정상 종료되었을 때 생성된 코어 덤프의 분석, 코어 덤프 파일의 관리 등에 사용됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li style=&quot;color: #1a1918;&quot;&gt;&lt;b&gt;journalctl&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc; color: #1a1918;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;color: #1a1918;&quot;&gt;설명:&lt;span&gt;&amp;nbsp;&lt;/span&gt;journalctl&lt;span&gt;&amp;nbsp;&lt;/span&gt;명령어는 systemd의 로깅 시스템인 systemd-journald의 로그를 검색하고, 보기 위해 사용됩니다. 이 명령어를 사용하면 시스템 부팅부터 현재까지의 다양한 로그를 필터링하여 볼 수 있습니다.&lt;/li&gt;
&lt;li style=&quot;color: #1a1918;&quot;&gt;사용 케이스: 시스템의 오류 진단, 특정 기간 동안의 로그 확인, 서비스 또는 시스템 부팅 관련 로그 분석 등에 사용됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1a1918; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이 명령어들은 systemd를 사용하는 Linux 배포판에서 시스템 관리 및 문제 해결을 위한 중요한 도구들입니다.&lt;/p&gt;</description>
      <category>Linux</category>
      <author>Joon0464</author>
      <guid isPermaLink="true">https://cumulus.tistory.com/158</guid>
      <comments>https://cumulus.tistory.com/158#entry158comment</comments>
      <pubDate>Tue, 7 May 2024 20:11:21 +0900</pubDate>
    </item>
    <item>
      <title>Linux 부팅 프로세스</title>
      <link>https://cumulus.tistory.com/157</link>
      <description>&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;Linux 부팅 프로세스&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;article&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;모던 리눅스에서 소개되는 리눅스 부팅 프로세스에 대해 자세하게 설명하고자 합니다.&amp;nbsp;&lt;br /&gt;리눅스의 부트 프로세스는 일반적으로 하드웨어와 커널이 함께 동작하는 여러 단계의 작업으로 구성됩니다.&lt;br /&gt;컴퓨터의 전원이 켜진 순간부터 리눅스 운영체제가 완전히 시작될 때까지 아래의 일련의 단계로 구성됩니다.&lt;/span&gt;&lt;/blockquote&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;1단계: BIOS/UEFI&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;컴퓨터의 전원이 켜지면 BIOS(Basic Input/Output System) 또는 UEFI(Unified Extensible Firmware Interface)가 활성화됩니다. 이 펌웨어 소프트웨어는 하드웨어를 초기화하고 전원 켜기 자가 진단(POST / Power On Self Test)을 수행하여 컴퓨터의 기본 하드웨어가 제대로 작동하는지 확인합니다.&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;2단계: 부트로더&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;BIOS/UEFI에 의해 선택된 부팅 가능 장치로부터 부트로더가 제어를 넘겨받습니다. 리눅스에서는 주로 GRUB(GRand Unified Bootloader) 또는 LILO(LInux LOader) 같은 부트로더가 사용됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;3단계: 커널 초기화&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;커널은 하드웨어와 소프트웨어 간의 상호 작용을 관리하는 시스템의 핵심 부분으로, 메모리에 로드되어 자체를 초기화하고 하드웨어 장치를 설정하며 파일 시스템을 마운트합니다.&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;4단계: 루트 파일 시스템 마운트&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;커널 초기화 후, 커널은 루트 파일 시스템을 읽기 전용 모드로 마운트하여 실제 파일 시스템을 사용할 준비를 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;5단계: init 프로세스 실행&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;루트 파일 시스템을 성공적으로 마운트한 후, 커널은 &lt;b&gt;/sbin/init&lt;/b&gt; 프로그램을 실행합니다. 이 프로세스는 시스템의 첫 번째 프로세스(&lt;b&gt;PID 1&lt;/b&gt;)가 되어 시스템의 다른 모든 프로세스의 부모 역할을 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;6단계: 런레벨/타겟 초기화&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;시스템은 정의된 런레벨 혹은 타겟에 따라 다양한 서비스와 프로세스를 시작합니다. 예를 들어, 'graphical.target'은 GUI를 포함한 전체 시스템을 시작합니다. 이 단계에서는 네트워킹, 사용자 인터페이스, 시스템 로깅, 스케줄링 서비스 등 다양한 백그라운드 서비스가 시작됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;7단계: 로그인 프롬프트 제공&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;모든 서비스가 시작되면, 리눅스 시스템은 로그인 프롬프트를 제공합니다. 사용자는 텍스트 기반 로그인 또는 그래픽 사용자 인터페이스(GUI)를 통해 시스템에 로그인할 수 있습니다. GUI 환경에서는 애플리케이션을 실행하고 시스템을 사용할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;8단계: 사용자 세션 시작&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;사용자가 성공적으로 로그인하면, 사용자의 세션을 시작하고 사용자 환경을 로딩합니다. 이는 사용자가 설정한 데스크탑 환경이나 윈도우 매니저를 포함할 수 있습니다. 이제 사용자는 파일을 관리하고, 애플리케이션을 실행하고, 시스템 자원을 사용할 준비가 완료됩니다.&lt;/span&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;/span&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/article&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt; 여기까지 리눅스 부팅 프로세스에 대해 간략하게 알아보았습니다. 각 단계는 시스템이 안정적으로 운영되고 필요한 모든 자원과 서비스가 올바르게 구성되도록 보장하는 데 중요합니다. 리눅스 배포판과 구성에 따라 부팅 프로세스는 약간 다를 수 있지만, 기본적인 흐름은 대체로 비슷할 것입니다.&lt;/span&gt;&lt;/blockquote&gt;</description>
      <category>Linux</category>
      <author>Joon0464</author>
      <guid isPermaLink="true">https://cumulus.tistory.com/157</guid>
      <comments>https://cumulus.tistory.com/157#entry157comment</comments>
      <pubDate>Tue, 7 May 2024 18:50:33 +0900</pubDate>
    </item>
    <item>
      <title>Linux 접근 제어 목록(ACL) 이란?</title>
      <link>https://cumulus.tistory.com/156</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;접근 제어 목록(ACL)&lt;/b&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Access Control List (ACL)는 파일과 디렉토리에 대해 세분화된 사용자 및 그룹 권한을 설정할 수 있게 해주는 기능입니다. 기본적인 리눅스 권한 시스템은 소유자, 그룹, 기타에 대한 권한을 제공하는 반면, ACL을 통해서는 특정 사용자 또는 그룹에 대해 더 구체적인 권한을 부여할 수 있습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;ACL 사용을 위한 준비&lt;/b&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대부분의 현대 리눅스 배포판은 ACL을 지원하지만, &lt;code&gt;getfacl&lt;/code&gt; 및 &lt;code&gt;setfacl&lt;/code&gt; 명령어를 사용하기 위해서는 &lt;code&gt;acl&lt;/code&gt; 패키지를 설치해야 합니다. Ubuntu에서는 다음 명령어로 설치할 수 있습니다:&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;$ sudo apt-get update
$ sudo apt-get install acl&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;ACL 설정 방법&lt;/b&gt;&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;ACL 설정 확인:&lt;/b&gt; 파일이나 디렉토리에 대한 현재 ACL 설정을 확인하려면 &lt;code&gt;getfacl [file]&lt;/code&gt; 명령어를 사용합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;ACL 설정:&lt;/b&gt; ACL을 설정하려면 &lt;code&gt;setfacl&lt;/code&gt; 명령어를 사용합니다. 기본 형식은 &lt;code&gt;setfacl -m u:[username]:[permission] [file]&lt;/code&gt;입니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;실습 예제&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테스트 파일을 생성하고, &lt;code&gt;example.txt&lt;/code&gt;에 대해 &lt;code&gt;user1&lt;/code&gt;에게 읽기(&lt;code&gt;r&lt;/code&gt;) 및 쓰기(&lt;code&gt;w&lt;/code&gt;) 권한을 부여하고, ACL 설정을 확인한 후, &lt;code&gt;-x&lt;/code&gt; 옵션을 사용하여 &lt;code&gt;user1&lt;/code&gt;에 대한 ACL을 제거합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;추가 정보&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;디렉토리에 대한 기본 ACL을 설정하려면 &lt;code&gt;d&lt;/code&gt; 옵션을 사용할 수 있으며, 권한은 읽기(&lt;code&gt;r&lt;/code&gt;), 쓰기(&lt;code&gt;w&lt;/code&gt;), 실행(&lt;code&gt;x&lt;/code&gt;), 없음(&lt;code&gt;-&lt;/code&gt;)의 조합으로 설정할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ACL을 사용하면 전통적인 리눅스 권한 시스템에 비해 다양한 사용자와 그룹에 대한 세분화된 권한 관리가 가능해져, 특히 상세한 권한 설정이 필요할 때 유용합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;접근 제어 목록(ACL)은 파일이나 디렉토리에 대해 사용자나 그룹별로 세밀한 접근 권한을 설정할 수 있게 해주는 기능입니다. 기본적인 리눅스 권한 설정을 넘어서 더 세부적인 권한 관리를 가능하게 합니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;ACL 적용 실습 예제&lt;/b&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #1a1918; text-align: start;&quot;&gt;대부분의 현대 리눅스 배포판은 ACL을 지원하지만, &lt;/span&gt;getfacl&lt;span style=&quot;background-color: #ffffff; color: #1a1918; text-align: start;&quot;&gt;과 &lt;/span&gt;setfacl&lt;span style=&quot;background-color: #ffffff; color: #1a1918; text-align: start;&quot;&gt; 명령어를 사용하기 위해선 &lt;/span&gt;acl&lt;span style=&quot;background-color: #ffffff; color: #1a1918; text-align: start;&quot;&gt; 패키지가 설치되어 있어야 합니다. Ubuntu에서는 다음 명령어로 설치할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 테스트는 &lt;b&gt;wsl ubuntu 20.04&lt;/b&gt; 환경에서 진행하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. ACL 설치하기&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;$ sudo apt-get update
$ sudo apt-get install acl -y&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. 파일에 대한 ACL 적용 및 확인&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;# 테스트용 파일 생성
$ touch example.txt
# joon 이라는 사용자에게 example.txt 파일에 대하여 읽기 권한만 부여
$ setfacl -m u:user1:r example.txt
$ setfacl -m u:joon:r example.txt
$ getfacl example.txt
# file: example.txt
# owner: joon
# group: joon
user::rw-
user:joon:r--
user:user1:r--
group::r--
mask::r--
other::r--&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 중요한 사항은 파일의 소유자가 joon 사용자 입니다. 분명 joon 사용자와 user1에게 동일하게 읽기 권한만을 부여했지만 파일 소유자 때문에 테스트 결과에서 차이가 발생합니다. 이 차이는 뒤에 테스트 단계에서 살펴보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. joon 사용자로 파일에 내용 쓰기 테스트&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1714713772681&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;현재 접속중인 사용자가 joon임을 확인
$ whoami
joon
# example.txt에 파일 내용 작성
$ cat &amp;lt;&amp;lt; EOF &amp;gt; example.txt
&amp;gt; test
&amp;gt; EOF
# 작성된 내용 확인
$ cat example.txt
test&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;분명 읽기 권한만 주어진 joon 사용자지만 파일에 쓰기가 가능하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;4. user1 사용자로 파일에 내용 쓰기 테스트&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1714714648885&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 우선 example.txt에 others 권한에 쓰기 권한을 추가합니다.(ACL로만 쓰기가 제한되는지 확인하기 위해)
$ chmod o+w example.txt

# user1의 홈 디렉토리로 example.txt 파일을 복사해주고 권한은 그대로 유지하도록 -p 옵션을 사용합니다.
$ sudo cp -p example.txt /home/user1/example.txt

# user1의 홈 디렉토리에 존재하는 파일의 권한이 others에 w권한이 있는 것을 확인합니다.
$ sudo ls -al /home/user1/example.txt
-rw-r--rw-+ 1 joon joon 5 May  3 14:21 /home/user1/example.txt

# example.txt 파일에 acl 설정도 그대로 유지되었는지 확인합니다.
$ sudo getfacl /home/user1/example.txt
# file: home/user1/example.txt
# owner: joon
# group: joon
user::rw-
user:joon:r--
user:user1:r--
group::r--
mask::r--
other::rw-


# 유저를 user1으로 변경합니다.
$ su user1
Password:

# 현재 접속 유저 확인
user1@DESKTOP-0U76AK5:/home/joon$ whoami
user1

# 홈 디렉토리로 이동 후 파일 확인
user1@DESKTOP-0U76AK5:~$ cd $HOME &amp;amp;&amp;amp; ls -al example.txt
-rw-r--rw-+ 1 joon joon 5 May  3 14:21 example.txt

# 파일에 내용 쓰기 테스트
user1@DESKTOP-0U76AK5:~$ cat &amp;lt;&amp;lt; EOF &amp;gt; example.txt
&amp;gt; test1
&amp;gt; EOF
bash: example.txt: Permission denied

# 파일 내용을 확인하면 최초 joon 사용자가 입력했던 test 가 그대로 입력되어 있습니다.
$ cat example.txt
test&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같이 others 사용자에게 w권한이 존재하지만 파일에 내용 쓰기가 불가능합니다.&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;5. user1 사용자 ACL 제거 후 다시 테스트&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;# -x 옵션으로 ACL 설정 제거
$ sudo setfacl -x u:user1 /home/user1/example.txt

# ACL 설정 제거 확인
$ sudo getfacl /home/user1/example.txt
getfacl: Removing leading '/' from absolute path names
# file: home/user1/example.txt
# owner: joon
# group: joon
user::rw-
user:joon:r--
group::r--
mask::r--
other::rw-

# user1으로 유저 변경 후 테스트
$ su user1
Password:
user1@DESKTOP-0U76AK5:/home/joon$ cd $HOME
user1@DESKTOP-0U76AK5:~$ cat &amp;lt;&amp;lt; EOF &amp;gt; example.txt
&amp;gt; test2
&amp;gt; EOF
user1@DESKTOP-0U76AK5:~$ cat example.txt
test2&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다시 setfacl 명령어를 통해 ACL 설정을 제거하고 테스트해보면 정상적으로 파일에 쓰기가 가능한 것을 볼 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저번글 capability 설정에 이어서 리눅스 보안에 관련된 설정들이 seccomp 프로필과 ACL에 대해서 살펴보았습니다. 모던 리눅스를 계속 읽고 있는데 추가적으로 정리할 내용 있으면 블로그를 통해 다시 공유할 예정입니다.&lt;/p&gt;</description>
      <category>Linux</category>
      <category>ACL</category>
      <category>Linux</category>
      <category>ubuntu</category>
      <category>리눅스보안</category>
      <category>보안</category>
      <category>보안설정</category>
      <category>접근제어목록</category>
      <author>Joon0464</author>
      <guid isPermaLink="true">https://cumulus.tistory.com/156</guid>
      <comments>https://cumulus.tistory.com/156#entry156comment</comments>
      <pubDate>Fri, 3 May 2024 15:51:13 +0900</pubDate>
    </item>
    <item>
      <title>Linux seccomp 프로필과 접근제어목록(ACL)이란?</title>
      <link>https://cumulus.tistory.com/155</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;seccomp 프로필&lt;/b&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;seccomp 는 보안 컴퓨팅 모드(secure computing mode)로 2005년부터 사용할 수 있게 된 리눅스 커널 기능중 하나입니다.샌드박스의 기술의 기본 개념인 seccomp라는 전용 시스템 콜을 통해 프로세스가 사용할 수 있는 시스템 콜을 제한할 수 있습니다. 컨테이너와 관련되어서는 Docker와 Kubernetes 모두 seccomp를 지원하고 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #1a1918; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;다양한 Seccomp 프로필 작성 방법&lt;/b&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1a1918; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Seccomp 프로필은 JSON 형식으로 작성되며, 주로 다음과 같은 구조를 가집니다:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #1a1918; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;color: #1a1918;&quot;&gt;defaultAction: 기본적으로 적용할 행동 (SCMP_ACT_ALLOW,&lt;span&gt;&amp;nbsp;&lt;/span&gt;SCMP_ACT_ERRNO&lt;span&gt;&amp;nbsp;&lt;/span&gt;등)&lt;/li&gt;
&lt;li style=&quot;color: #1a1918;&quot;&gt;architectures: 프로필이 적용될 아키텍처&lt;/li&gt;
&lt;li style=&quot;color: #1a1918;&quot;&gt;syscalls: 시스템 호출에 대한 규칙을 정의하는 섹션
&lt;ul style=&quot;list-style-type: disc; color: #1a1918;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;color: #1a1918;&quot;&gt;names: 규칙이 적용될 시스템 호출의 이름&lt;/li&gt;
&lt;li style=&quot;color: #1a1918;&quot;&gt;action: 해당 시스템 호출에 대해 취할 행동&lt;/li&gt;
&lt;li style=&quot;color: #1a1918;&quot;&gt;args: 시스템 호출의 인자에 대한 추가 조건&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #1a1918; text-align: start;&quot;&gt;하단의 seccomp 프로필 예시는 특정 시스템 호출을 허용하고 나머지는 차단하는 방식을 보여줍니다. &lt;/span&gt;&quot;defaultAction&quot;: &quot;SCMP_ACT_ERRNO&quot;&lt;span style=&quot;background-color: #ffffff; color: #1a1918; text-align: start;&quot;&gt;는 기본적으로 모든 시스템 호출을 차단하고, 특정 시스템 호출에 대해서만 허용(&lt;/span&gt;&quot;SCMP_ACT_ALLOW&quot;&lt;span style=&quot;background-color: #ffffff; color: #1a1918; text-align: start;&quot;&gt;)하도록 설정하는 Whitelist 방식으로 작성하였습니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1714709914613&quot; class=&quot;json&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;json&quot;&gt;&lt;code&gt;{
  &quot;defaultAction&quot;: &quot;SCMP_ACT_ERRNO&quot;,
  &quot;architectures&quot;: [
    &quot;SCMP_ARCH_X86_64&quot;,
    &quot;SCMP_ARCH_X86&quot;,
    &quot;SCMP_ARCH_X32&quot;
  ],
  &quot;syscalls&quot;: [
    {
      &quot;names&quot;: [&quot;clone&quot;, &quot;fork&quot;, &quot;vfork&quot;],
      &quot;action&quot;: &quot;SCMP_ACT_ALLOW&quot;
    },
    {
      &quot;names&quot;: [&quot;execve&quot;],
      &quot;action&quot;: &quot;SCMP_ACT_ALLOW&quot;,
      &quot;args&quot;: []
    },
    {
      &quot;names&quot;: [&quot;openat&quot;],
      &quot;action&quot;: &quot;SCMP_ACT_ALLOW&quot;,
      &quot;args&quot;: [
        {
            &quot;index&quot;: 2,
            &quot;value&quot;: O_RDONLY, // 상수 O_RDONLY의 실제 값으로 대체해야 함
            &quot;op&quot;: &quot;SCMP_CMP_EQ&quot;
        }
      ]
    }
  ]
}&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1a1918; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;상단의 seccomp 프로필 예시에서는 clone, fork, vfork, 그리고 execve 시스템 호출을 허용합니다. 이는 프로세스 생성과 실행에 필수적인 시스템 호출입니다. 추가적으로, openat 시스템 호출도 특정 조건 하에 허용하는데, 여기서는 ReadOnly만 허용하기 위한 설정을 적용한 예시입니다. 자세한 설명을 위해 openat를 추가적으로 살펴보겠습니다.&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1714710607665&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;int openat(int fd, const char *path, int oflag);&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1a1918; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;openat 시스템콜은 위와같이 구성되어 있으며 상세 설명은 아래와 같습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #1a1918; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #1a1918; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;color: #1a1918;&quot;&gt;fd는 상대 경로를 해석하기 위한 디렉토리 파일 디스크립터입니다. 상대 경로 대신 절대 경로를 사용하려면&lt;span&gt;&amp;nbsp;&lt;/span&gt;AT_FDCWD를 이용합니다.&lt;/li&gt;
&lt;li style=&quot;color: #1a1918;&quot;&gt;path은 열고자 하는 파일 또는 디렉토리의 경로입니다.&lt;/li&gt;
&lt;li style=&quot;color: #1a1918;&quot;&gt;oflag는 파일을 여는 방법을 지정합니다. 예를 들어, 파일이 없을 경우 생성하거나, 읽기 전용으로 열거나 하는 등의 옵션입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉 openat는 3개의 argument로 구성된 시스템 콜이며 seccomp 프로필에서 index 2는 oflag를 가리킵니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;flag 모드&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;O_RDONLY : 파일을 읽기 전용으로 엽니다.&lt;/li&gt;
&lt;li&gt;O_WRONLY : 파일을 쓰기 전용으로 엽니다.&lt;/li&gt;
&lt;li&gt;O_RDWR : 파일을 쓰기와 읽기용으로 엽니다 .&lt;/li&gt;
&lt;li&gt;O_EXEC : 파일을 실행 전용으로 엽니다 .&lt;/li&gt;
&lt;li&gt;O_SEARCH : 디렉토리 파일을 탐색 전용으로 엽니다 .&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉 openat을 허용하지만 args의 index 2인 flag의 O_RDONLY 즉 읽기 전용으로만 허용하겠다는 의미가 됩니다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1a1918; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이러한 방식으로 seccomp 프로필을 작성함으로써, 컨테이너나 프로세스가 수행할 수 있는 시스템 호출을 세밀하게 제어할 수 있으며, 이는 보안을 강화하는 데 중요한 역할을 합니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;seccomp 프로필 예제&lt;/b&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #1a1918; text-align: start;&quot;&gt;Docker에서 &lt;/span&gt;seccomp&lt;span style=&quot;background-color: #ffffff; color: #1a1918; text-align: start;&quot;&gt; 프로파일을 사용하는 예제를 살펴보겠습니다. 먼저, 기본 &lt;/span&gt;seccomp&lt;span style=&quot;background-color: #ffffff; color: #1a1918; text-align: start;&quot;&gt; 프로파일을 사용하여 컨테이너를 실행하는 방법입니다. Docker는 기본적으로 &lt;/span&gt;seccomp&lt;span style=&quot;background-color: #ffffff; color: #1a1918; text-align: start;&quot;&gt; 프로파일을 적용을 지원합니다. 아래 실습은 WSL ubuntu 20.04 환경에서 진행되었습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. docker를 사용하여 ubuntu 20.04 이미지의 컨테이너를 실행시키고 bash shell로 접속합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1714708614414&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ docker run --rm -it ubuntu:20.04 bash
Unable to find image 'ubuntu:20.04' locally
20.04: Pulling from library/ubuntu
d4c3c94e5e10: Pull complete
Digest: sha256:874aca52f79ae5f8258faff03e10ce99ae836f6e7d2df6ecd3da5c1cad3a912b
Status: Downloaded newer image for ubuntu:20.04&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 컨테이너내에서 mkdir 명령어로 디렉터리 생성 시 아무런 문제 없이 디렉터리가 생성됩니다.&lt;/p&gt;
&lt;pre id=&quot;code_1714708825783&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# mkdir로 test 디렉터리 생성 후 확인
root@9aa95698234b:/# mkdir test &amp;amp;&amp;amp; ls -ald test
drwxr-xr-x 2 root root 4096 May  3 03:55 test
# exit을 통해 컨테이너 쉘에서 exit 합니다. --rm 옵션을 사용했었기 때문에 컨테이너는 자동으로 종료됩니다.
root@9aa95698234b:/# exit
$ docker ps -a
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 이번에는 seccomp 프로필을 적용하기 위해 우선 seccomp 프로필을 json 파일로 작성합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1714708924383&quot; class=&quot;json&quot; data-ke-language=&quot;json&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ vi profile.json
{
  &quot;defaultAction&quot;: &quot;SCMP_ACT_ALLOW&quot;,
  &quot;syscalls&quot;: [
    {
      &quot;names&quot;: [&quot;mkdir&quot;],
      &quot;action&quot;: &quot;SCMP_ACT_ERRNO&quot;
    }
  ]
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 이번에는 seccomp 프로필을 사용하여 컨테이너를 실행시키고 bash shell 로 접속합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1714709101859&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ docker run --rm -it --security-opt seccomp=./profile.json ubuntu:20.04 bash
root@9682501a844b:/#&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. mkdir로 test 디렉토리를 생성해보면 Operation not permitted 가 발생하여 수행되지 않습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1714709188971&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;root@9682501a844b:/# mkdir test || ls -ald test
mkdir: cannot create directory 'test': Operation not permitted
ls: cannot access 'test': No such file or directory
# 테스트를 마치고 exit을 통해 쉘 접속 및 컨테이너를 종료합니다.
root@9682501a844b:/# exit&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Kubernetes 에서 seccomp 프로필 적용&lt;/b&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 부분은 실습까지는 아니며, Kubernetes에서 seccomp 프로필을 적용하는 pod YAML을 간단하게 작성해보면 아래와 같습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1714709446578&quot; class=&quot;yaml&quot; data-ke-language=&quot;yaml&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;apiVersion: v1
kind: Pod
metadata:
  name: seccomp-demo
spec:
  containers:
  - name: nginx
    image: nginx
    securityContext:
      seccompProfile:
        type: Localhost
        localhostProfile: profiles/my-seccomp-profile.json&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;공식문서 링크는 아래와 같습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://kubernetes.io/ko/docs/concepts/security/pod-security-standards/&quot;&gt;https://kubernetes.io/ko/docs/concepts/security/pod-security-standards/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1714709776223&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;파드 시큐리티 스탠다드&quot; data-og-description=&quot;파드 시큐리티 스탠다드에 정의된 여러 가지 정책 레벨에 대한 세부사항&quot; data-og-host=&quot;kubernetes.io&quot; data-og-source-url=&quot;https://kubernetes.io/ko/docs/concepts/security/pod-security-standards/&quot; data-og-url=&quot;https://kubernetes.io/ko/docs/concepts/security/pod-security-standards/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/0huPh/hyVZr01r4d/KsjyKIhFrH6quNZknNVgCk/img.png?width=1727&amp;amp;height=373&amp;amp;face=0_0_1727_373,https://scrap.kakaocdn.net/dn/ls5dX/hyVZm6tP8t/NDw6jQPAPuKwsUMiRVTHsK/img.png?width=512&amp;amp;height=512&amp;amp;face=0_0_512_512&quot;&gt;&lt;a href=&quot;https://kubernetes.io/ko/docs/concepts/security/pod-security-standards/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://kubernetes.io/ko/docs/concepts/security/pod-security-standards/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/0huPh/hyVZr01r4d/KsjyKIhFrH6quNZknNVgCk/img.png?width=1727&amp;amp;height=373&amp;amp;face=0_0_1727_373,https://scrap.kakaocdn.net/dn/ls5dX/hyVZm6tP8t/NDw6jQPAPuKwsUMiRVTHsK/img.png?width=512&amp;amp;height=512&amp;amp;face=0_0_512_512');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;파드 시큐리티 스탠다드&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;파드 시큐리티 스탠다드에 정의된 여러 가지 정책 레벨에 대한 세부사항&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;kubernetes.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;</description>
      <category>Linux</category>
      <category>docker</category>
      <category>Kubernetes</category>
      <category>Linux</category>
      <category>seccomp</category>
      <category>seccompprofile</category>
      <category>secomp프로필</category>
      <category>security</category>
      <category>리눅스</category>
      <category>리눅스보안</category>
      <category>보안</category>
      <author>Joon0464</author>
      <guid isPermaLink="true">https://cumulus.tistory.com/155</guid>
      <comments>https://cumulus.tistory.com/155#entry155comment</comments>
      <pubDate>Fri, 3 May 2024 14:44:23 +0900</pubDate>
    </item>
    <item>
      <title>Linux Capability 란?</title>
      <link>https://cumulus.tistory.com/154</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;리눅스에서 Capability과 Seccomp profile는 시스템 보안 강화를 위한 중요한 메커니즘입니다. 두 기능 모두 프로세스가 운영체제와 상호작용하는 방식을 제한함으로써 보안을 향상시킬 수 있습니다. 이번 글에서는 우선 Capability에 대해 설명하도록 하겠습니다.&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Capability&lt;/b&gt;&lt;/h2&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전통적인 Unix-like 시스템에서, root 계정(UID 0)은 모든 권한을 가지고 있습니다. 이는 매우 강력하지만, 만약 root 권한을 가진 프로세스가 취약점을 갖고 있다면 시스템은 큰 위험에 노출될 수 있습니다. 리눅스 Capabilities는 root 권한을 더 세밀하게 분할하여, 특정 권한만을 프로세스에 부여할 수 있게 합니다. 예를 들어, 네트워크 소켓을 열 수 있는 권한, 시스템 시간을 변경할 수 있는 권한 등이 있습니다. 리눅스 5.2 버전에 총 38개의 `capabilities`가 있으며 널리 사용되는 capability는 아래 표와 같습니다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 173px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 21.279%; height: 20px; text-align: justify;&quot;&gt;Capability&lt;/td&gt;
&lt;td style=&quot;width: 78.721%; height: 20px; text-align: justify;&quot;&gt;의미&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 21.279%; height: 17px; text-align: justify;&quot;&gt;CAP_CHOWN&lt;/td&gt;
&lt;td style=&quot;width: 78.721%; height: 17px; text-align: justify;&quot;&gt;사용자가 파일의 UID/GID를 임의로 변경할 수 있도록 허용&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 21.279%; height: 17px; text-align: justify;&quot;&gt;CAP_KILL&lt;/td&gt;
&lt;td style=&quot;width: 78.721%; height: 17px; text-align: justify;&quot;&gt;다른 사용자에게 속한 프로세스에 신호를 보낼 수 있도록 허용&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 21.279%; height: 17px; text-align: justify;&quot;&gt;CAP_SETUID&lt;/td&gt;
&lt;td style=&quot;width: 78.721%; height: 17px; text-align: justify;&quot;&gt;UID를 변경할 수 있도록 허용&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 21.279%; height: 17px; text-align: justify;&quot;&gt;CAP_SETPCAP&lt;/td&gt;
&lt;td style=&quot;width: 78.721%; height: 17px; text-align: justify;&quot;&gt;실행 중인 프로세스의 Capability를 설정할 수 있도록 허용&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 21.279%; height: 17px; text-align: justify;&quot;&gt;CAP_NET_ADMIN&lt;/td&gt;
&lt;td style=&quot;width: 78.721%; height: 17px; text-align: justify;&quot;&gt;인터페이스 구성과 같은 다양한 네트워크 관련 작업을 허용&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 21.279%; height: 17px; text-align: justify;&quot;&gt;CAP_NET_RAM&lt;/td&gt;
&lt;td style=&quot;width: 78.721%; height: 17px; text-align: justify;&quot;&gt;RAW 와 PACKET 소켓의 사용을 허용&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 21.279%; height: 17px; text-align: justify;&quot;&gt;CAP_SYS_CHROOT&lt;/td&gt;
&lt;td style=&quot;width: 78.721%; height: 17px; text-align: justify;&quot;&gt;chroot 호출 허용&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 21.279%; height: 17px; text-align: justify;&quot;&gt;CAP_SYS_ADMIN&lt;/td&gt;
&lt;td style=&quot;width: 78.721%; height: 17px; text-align: justify;&quot;&gt;파일 시스템 마운트를 포함한 시스템 관리 작업을 허용&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 21.279%; height: 17px; text-align: justify;&quot;&gt;CAP_SYS_PTRACE&lt;/td&gt;
&lt;td style=&quot;width: 78.721%; height: 17px; text-align: justify;&quot;&gt;strace를 사용하여 프로세스를 디버그할 수 있도록 허용&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 21.279%; text-align: justify;&quot;&gt;CAP_SYS_MODULE&lt;/td&gt;
&lt;td style=&quot;width: 78.721%; text-align: justify;&quot;&gt;커널 모듈의 로딩을 허용&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;Capability는 이진 비트마스크로, 특수한 권한 집합을 나타냅니다. 각 bit는 특정권한을 의미하며, 이를 통해 프로세스에 필요한 최소한의 권한만을 정밀하게 부여할 수 있습니다. &lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Capability 사용 예시&lt;/b&gt;&lt;/h2&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CAP_NET_BIND_SERVICE capability를 사용하는 예시를 들어보겠습니다. 이 capability는 프로그램이 1024 미만의 well-known port 에서 리스닝할 수 있게 해 줍니다. &lt;br /&gt;&lt;br /&gt;포트 80 에서 리스닝하는 golang으로 작성된 간단한 웹서버 프로그램을 통해 capability 실제 사용 예시를 살펴보겠습니다.&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1) my_tcp_server.go 에 코드를 다음과 같이 작성합니다.&lt;/b&gt;&lt;/h4&gt;
&lt;pre class=&quot;bash&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;vi ./my_tcp_server.go&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;bash&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;package main

import (
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;net&quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;log&quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;fmt&quot;
)

func main() {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ln, err := net.Listen(&quot;tcp&quot;, &quot;:80&quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if err != nil {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;log.Fatal(err)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;defer ln.Close()

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// 서버 시작 메시지 추가
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fmt.Println(&quot;서버가 포트 80에서 시작되었습니다.&quot;)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;conn, err := ln.Accept()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if err != nil {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;log.Println(err)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;continue
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// HTTP 응답 메시지 작성
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;httpResponse := &quot;HTTP/1.1 200 OK\r\n&quot; +
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;Content-Type: text/plain; charset=utf-8\r\n&quot; +
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;Content-Length: 17\r\n&quot; +
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;\r\n&quot; +
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;Hello, TCP client!\n&quot;

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;conn.Write([]byte(httpResponse))
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;conn.Close()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2) go build 수행&lt;/b&gt;&lt;/h4&gt;
&lt;pre class=&quot;bash&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;$ go build my_tcp_server.go
$ ls -al my_tcp_server
-rwxr-xr-x 1 joon joon 2576489 May&amp;nbsp;&amp;nbsp;2 14:57 my_tcp_server&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;3) 서버 실행 테스트&lt;/b&gt;&lt;/h4&gt;
&lt;pre class=&quot;bash&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;$ ./my_tcp_server
2024/05/02 15:14:07 listen tcp :80: bind: permission denied&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;해당 프로그램에 CAP_NET_BIND_SERVICE capability를 부여하지 않은 상태로 일반 사용자 권한으로는 1024번 미만의 포트에서 서비스를 시작할 수 없습니다. &lt;br /&gt;하지만,&amp;nbsp;해당&amp;nbsp;프로그램에&amp;nbsp;CAP_NET_BIND_SERVICE&amp;nbsp;capability를&amp;nbsp;부여하면,&amp;nbsp;root&amp;nbsp;권한&amp;nbsp;없이도&amp;nbsp;포트&amp;nbsp;80에서&amp;nbsp;서비스를&amp;nbsp;제공할&amp;nbsp;수&amp;nbsp;있습니다.&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;4) CAP_NET_BIND_SERVICE capability 부여&lt;/b&gt;&lt;/h4&gt;
&lt;pre class=&quot;bash&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;$ sudo setcap 'cap_net_bind_service=+ep' ./my_tcp_server
$ getcap ./my_tcp_server
./my_tcp_server cap_net_bind_service=ep&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;5) 서버 실행 재시도 및 curl 접근 테스트&lt;/b&gt;&lt;/h3&gt;
&lt;pre class=&quot;bash&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;$ ./my_tcp_server
서버가 포트 80에서 시작되었습니다.

$ sudo netstat -nltp | grep 80
tcp6&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;0 :::80&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; :::*&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LISTEN&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;87600/./my_tcp_server

$ curl http://localhost
Hello, TCP client&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;위와 같이 permission denied에러 없이 서버가 정상적으로 실행되어 80번 포트를 통해 서비스되는 것을 볼 수 있습니다. netstat 명령어로 80번 포트가 Listen 상태인 것을 확인하고, curl을 통해 80번 포트로 요청을 보내고 리턴을 받아보면 잘 동작중인 것을 알 수 있습니다. 이렇게 이번 글을 통해 Linux Capability 설정을 알아보았으며, 다음 이어지는 글에서 Seccomp profile에 대해 살펴볼 예정입니다.&lt;/p&gt;</description>
      <category>Linux</category>
      <category>capability</category>
      <category>Linux</category>
      <category>security</category>
      <category>리눅스</category>
      <category>리눅스보안</category>
      <category>리눅스카파빌리티</category>
      <category>보안</category>
      <category>카파빌리티</category>
      <author>Joon0464</author>
      <guid isPermaLink="true">https://cumulus.tistory.com/154</guid>
      <comments>https://cumulus.tistory.com/154#entry154comment</comments>
      <pubDate>Thu, 2 May 2024 22:29:26 +0900</pubDate>
    </item>
    <item>
      <title>RUID EUID SUID 란?</title>
      <link>https://cumulus.tistory.com/153</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;모던리눅스 교과서&quot; 책을 읽던 중 RUID, EUID, SUID 에 대해 읽게 되었는데 이해를 위해 좀 더 찾아보고 정리하는 글입니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;RUID (Real User ID)&lt;br /&gt;RUID는 프로세스를 실행시킨 실제 사용자의 ID입니다. 이는 사용자가 시스템에 로그인할 때 할당되고, 대부분의 경우에 변경되지 않습니다.&lt;/li&gt;
&lt;li&gt;EUID (Effective User ID)&lt;br /&gt;프로세스가 시스템 리소스에 접근할 때 사용하는 ID입니다. EUID는 특히 파일이나 다른 시스템 리소스에 접근 권한을 체크할 때 중요하게 사용됩니다. 만약 어떤 프로그램이 SUID 비트가 설정된 상태로 실행된다면, 그 프로그램의 EUID는 프로그램의 소유자 ID로 설정됩니다.&lt;/li&gt;
&lt;li&gt;SUID (Set-user-ID)&lt;br /&gt;특수한 접근 권한으로, 파일을 실행할 때 실행 파일의 소유자 권한으로 실행되게 합니다. 예를 들어, root 권한으로 설정된 실행 파일을 일반 사용자가 실행하면 이 프로세스는 root의 EUID로 실행됩니다. 이를 통해 프로그램은 필요 시 높은 권한을 가지고 작업을 수행할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같이 설명되지만 역시 예제 없이는 잘 이해가 안됩니다. 아래의 예제를 통해 이해해보도록 하겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;EXAMPLE&lt;/b&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1. suid_example.c 라는 이름의 간단한 코드를 작성합니다.&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1714623660325&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;## 모든 예시는 일반 사용자 계정으로 수행하였습니다.
$ vi suid_example.c&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1714623112174&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 하단의 코드를 작성하고 저장합니다.
#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;sys/types.h&amp;gt;                                                                                                                                                                                                                          int main() {
    printf(&quot;현재 사용자 UID는 %d입니다.\n&quot;, geteuid());
    // 일반적으로 민감한 작업 추가 여기에
    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2.&amp;nbsp; 작성된 코드를 컴파일 합니다.&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1714623221001&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ gcc suid_example.c -o suid_example&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;3. 파일 소유자와 그룹 권한을 root로 설정하고 SUID 비트를 설정합니다.&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1714623330702&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ sudo chown root:root suid_example
$ sudo chmod u+s suid_example
$ ls -al suid_example
-rwsr-xr-x 1 root root 16016 May  2 13:12 suid_example&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 SUID 비트를 설정하는데 자세한 설명은 아래와 같습니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- SUID(Set User ID) 설정 (chmod 4xxx)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파일의 SUID 비트가 설정되어 있다면, 해당 파일(주로 실행 파일)을 실행할 때 실행 파일의 소유자 권한으로 실행됩니다. 위 예시와 같, root 권한으로 소유된 파일에 SUID 비트가 설정되어 있으면, 일반 사용자가 해당 파일을 실행하더라도 프로그램은 root 권한으로 실행됩니다. 파일 권한에서 's' 혹은 'S'로 표시되는데, 실행 권한(x)이 있는 상태에서 설정되면 's', 없는 상태면 'S'로 표시됩니다. &lt;br /&gt;&lt;br /&gt;&lt;b&gt;- SGID(Set Group ID) 설정 &lt;b&gt;(chmod 2xxx)&lt;/b&gt; &lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SGID는 파일의 경우 실행 시 해당 파일의 그룹 권한으로 실행되도록 하고, 디렉터리의 경우 해당 디렉터리 내에서 생성되는 파일이나 디렉터리가 부모 디렉터리의 그룹 소유권을 상속받게 합니다. 이는 공동 작업 환경에서 유용하게 사용됩니다. 파일 권한에서 's' 혹은 'S'로 표시되며, 그룹 실행 권한(g) 위치에 위치합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;- Sticky bit (chmod 1xxx)&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;해당 파일의 소유자에게만 쓰기 권한을 제공하는 설정으로 해&lt;/span&gt;&lt;span&gt;당 파일, 디렉토리가 모든 사용자에게 쓰기가 되어있다고 하더라도 해당 파일의 소유자가 아니면 쓰기에 관련된 작업을 할 수 없습니다. &lt;/span&gt;&lt;span&gt;설정되면 public 의 실행(x) 부분이 &amp;ldquo;t&amp;rdquo;, &amp;ldquo;T&amp;rdquo; 로 나타난다.대표적으로 &lt;/span&gt;&lt;span&gt;tmp 폴더가 이 목적으로 주로 사용되어, 다른 유저가 다른 유저의 tmp 정보를 읽기는 가능하지만, 쓰거나 지울 수는 없습니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1714627555686&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ ls -adl /tmp
drwxrwxrwt 10 root root 20480 May  2 13:42 /tmp&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;4. 컴파일 된 파일을 실행한다.&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1714623571030&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ ./suid_example
현재 사용자 UID는 0입니다.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;실행 결과, 프로그램이 root 권한(EUID)으로 실행되어 '현재 사용자 UID는 0입니다.'라고 출력합니다.&lt;br /&gt;이 프로세스는 실제 사용자(RUID)로부터 시작되었으나, SUID 설정으로 인해 실행 파일의 소유자(root) 권한으로 작업을 수행합니다. 이를 통해 특정 명령이나 작업에 대한 권한 제한 없이 더 높은 권한으로 실행되어야 할 필요가 있을 때 유용하게 사용될 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;추가적으로 처음에 자식 프로세스가 fork(2)를 통해 생성되면 이는 부모의 UID 복사본을 상속합니다. 또한 excute(2) 시스템 콜 중에는 프로세스의 RUID는 보존되지만 EUID와 저장된 SUID는 변경될 수 있습니다. 예를 들어 사용자가 passwd 명령을 실행할 때 사용자의 EUID는 사용자의 UID입니다. 이 UID를 1000이라고 가정하면 만약 passwd에서 suid 설정이 활성화되었다면 이를 실행할 때 사용자의 EUID는 0(root) 가 됩니다. 이 외에도 chroot를 비롯하여 여러 샌드박스 기술 등 EUID에 옇양을 미치는 경우는 다양합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;passwd 명령어가 대표적인 실제 사용 사례입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1714627258754&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ ls -al /usr/bin/passwd
-rwsr-xr-x 1 root root 59976 Feb  6 21:54 /usr/bin/passwd&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;비밀번호를 설정하는 /usr/bin/passwd 는 사실 root 만 가능하기에 root 의 권한을 잠시 빌려 일반사용자가 계정의 패스워드를 설정 가능하게 됩니다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>Linux</category>
      <category>euid</category>
      <category>Linux</category>
      <category>linuxsecurity</category>
      <category>ruid</category>
      <category>security</category>
      <category>suid</category>
      <category>리눅스</category>
      <category>리눅스보안</category>
      <author>Joon0464</author>
      <guid isPermaLink="true">https://cumulus.tistory.com/153</guid>
      <comments>https://cumulus.tistory.com/153#entry153comment</comments>
      <pubDate>Thu, 2 May 2024 19:28:13 +0900</pubDate>
    </item>
    <item>
      <title>Terraform 사용하여 GKE Cluster 배포하기</title>
      <link>https://cumulus.tistory.com/152</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://cumulus.tistory.com/151&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;2024.04.04 - [GKE Project] - Terraform을 사용하여 GKE(Google Kubernetes Engine) 배포&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이전에 준비했던 사전 설정에 이어서 진행한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. API 활성화&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 GKE Clsuter API와 Compute API 를 활성화 하기 위해 아래 과정을 진행해줍니다.&lt;/p&gt;
&lt;pre id=&quot;code_1712215677583&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 이전 포스팅에서 설정한 config에서 Project id값을 불러와 변수로 설정한다.
$ GCP_PROJECT_ID=$(gcloud config list | grep project | awk '{print $3}')

# 변수 설정을 확인해본다.
$ echo $GCP_PROJECT_ID

# GCP compute, container API 활성화
$ gcloud services enable compute.googleapis.com container.googleapis.com --project=$GCP_PROJECT_ID&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1052&quot; data-origin-height=&quot;158&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/IKRVv/btsGmCSw2HL/I2I0HgXESOw55YJkHvbXuk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/IKRVv/btsGmCSw2HL/I2I0HgXESOw55YJkHvbXuk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/IKRVv/btsGmCSw2HL/I2I0HgXESOw55YJkHvbXuk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIKRVv%2FbtsGmCSw2HL%2FI2I0HgXESOw55YJkHvbXuk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1052&quot; height=&quot;158&quot; data-origin-width=&quot;1052&quot; data-origin-height=&quot;158&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. Service Account 생성 &amp;amp; Secret key 생성&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1031&quot; data-origin-height=&quot;467&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bQfjcD/btsGnNZ3WT0/Uj7SeZekSklCrTAcjwPZIk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bQfjcD/btsGnNZ3WT0/Uj7SeZekSklCrTAcjwPZIk/img.png&quot; data-alt=&quot;IAM 및 관리자 -&amp;amp;gt; 서비스 계정 -&amp;amp;gt; 서비스 계정 만들기를 클릭한다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bQfjcD/btsGnNZ3WT0/Uj7SeZekSklCrTAcjwPZIk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbQfjcD%2FbtsGnNZ3WT0%2FUj7SeZekSklCrTAcjwPZIk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1031&quot; height=&quot;467&quot; data-origin-width=&quot;1031&quot; data-origin-height=&quot;467&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;IAM 및 관리자 -&amp;gt; 서비스 계정 -&amp;gt; 서비스 계정 만들기를 클릭한다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;546&quot; data-origin-height=&quot;360&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/5fZb4/btsGn741Vyw/sfC9UH8LnAMzZk7n0hTTJ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/5fZb4/btsGn741Vyw/sfC9UH8LnAMzZk7n0hTTJ1/img.png&quot; data-alt=&quot;서비스 계정 이름 및 설명을 작성한다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/5fZb4/btsGn741Vyw/sfC9UH8LnAMzZk7n0hTTJ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F5fZb4%2FbtsGn741Vyw%2FsfC9UH8LnAMzZk7n0hTTJ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;546&quot; height=&quot;360&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;546&quot; data-origin-height=&quot;360&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;서비스 계정 이름 및 설명을 작성한다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;569&quot; data-origin-height=&quot;532&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bil0Pc/btsGl3pj90e/ZCT068RAyCsiKIMfspv1eK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bil0Pc/btsGl3pj90e/ZCT068RAyCsiKIMfspv1eK/img.png&quot; data-alt=&quot;우선 위 3개의 관리자 권한만 추가하고 추후 권한이 필요하면 추가하는 방식으로 진행할 예정입니다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bil0Pc/btsGl3pj90e/ZCT068RAyCsiKIMfspv1eK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbil0Pc%2FbtsGl3pj90e%2FZCT068RAyCsiKIMfspv1eK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;569&quot; height=&quot;532&quot; data-origin-width=&quot;569&quot; data-origin-height=&quot;532&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;우선 위 3개의 관리자 권한만 추가하고 추후 권한이 필요하면 추가하는 방식으로 진행할 예정입니다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1144&quot; data-origin-height=&quot;367&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/7UMmA/btsGmCSxQjz/MakfuESoA24NFfFKQlkX20/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/7UMmA/btsGmCSxQjz/MakfuESoA24NFfFKQlkX20/img.png&quot; data-alt=&quot;생성된 서비스 계정 클&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/7UMmA/btsGmCSxQjz/MakfuESoA24NFfFKQlkX20/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F7UMmA%2FbtsGmCSxQjz%2FMakfuESoA24NFfFKQlkX20%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1144&quot; height=&quot;367&quot; data-origin-width=&quot;1144&quot; data-origin-height=&quot;367&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;생성된 서비스 계정 클&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;511&quot; data-origin-height=&quot;379&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/drd6Ts/btsGmOd9wyA/bfZR9PY5RGHH4JgbcwLFU0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/drd6Ts/btsGmOd9wyA/bfZR9PY5RGHH4JgbcwLFU0/img.png&quot; data-alt=&quot;키 -&amp;amp;gt; 키 추가 -&amp;amp;gt; 새 키 만들기 클릭합니다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/drd6Ts/btsGmOd9wyA/bfZR9PY5RGHH4JgbcwLFU0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdrd6Ts%2FbtsGmOd9wyA%2FbfZR9PY5RGHH4JgbcwLFU0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;511&quot; height=&quot;379&quot; data-origin-width=&quot;511&quot; data-origin-height=&quot;379&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;키 -&amp;gt; 키 추가 -&amp;gt; 새 키 만들기 클릭합니다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;532&quot; data-origin-height=&quot;322&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bDKw16/btsGooS1mBS/zKcNsvo1tO6PlrLrIt4tS1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bDKw16/btsGooS1mBS/zKcNsvo1tO6PlrLrIt4tS1/img.png&quot; data-alt=&quot;JSON을 선택하고 만들기를 클릭합니다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bDKw16/btsGooS1mBS/zKcNsvo1tO6PlrLrIt4tS1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbDKw16%2FbtsGooS1mBS%2FzKcNsvo1tO6PlrLrIt4tS1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;532&quot; height=&quot;322&quot; data-origin-width=&quot;532&quot; data-origin-height=&quot;322&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;JSON을 선택하고 만들기를 클릭합니다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1712281037478&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 환경변수에 시크릿 키 파일 경로 설정
$ mkdir ~/.gcp
$ echo &quot;export GOOGLE_APPLICATION_CREDENTIALS=/home/joon/.gcp/credential.json&quot; &amp;gt;&amp;gt; ~/.bashrc

# 환경변수 적용 및 확인
$ source ~/.bashrc
$ echo $GOOGLE_APPLICATION_CREDENTIALS
/home/joon/.gcp/credential.json&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3. tfstate 를 저장할 GCS Bucket 생성&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1713168138157&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ BUCKET_NAME=&quot;hjsong-tfstate-bucket&quot;
$ gsutil mb -p $GCP_PROJECT_ID -l ASIA-NORTHEAST3 gs://$BUCKET_NAME
Creating gs://hjsong-tfstate-bucket/...
$ gsutil versioning set on gs://$BUCKET_NAME
Enabling versioning for gs://hjsong-tfstate-bucket/...&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;backend.tf를 통해 Terraform의 state를 원격 저장소에 저장하도록 설정 가능합니다. backend.tf에서 사용하기 위한 버킷을 gsutil 명령어로 사전에 생성합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4. GKE Cluster 생성을 위한 Terraform 코드 작성&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1713168473302&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 디렉터리 구조는 아래와 같이 구성하였습니다.
# 재사용성과 유지보수가 용이하도록 모듈화하여 작성하였습니다.

GKE_Terraform_hjsong/
├── backend.tf
├── modules
│&amp;nbsp;&amp;nbsp; └── gke_cluster
│&amp;nbsp;&amp;nbsp;     ├── main.tf
│&amp;nbsp;&amp;nbsp;     ├── output.tf
│&amp;nbsp;&amp;nbsp;     └── variables.tf
├── production.tf
├── provider.tf
├── terraform.tfvars
└── variables.tf&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1713168633099&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# provider.tf

# gcp 리소스를 테라폼 코드로 작성하기 위해 우선 provider 부터 설정해야 합니다.
# 지정된 credential.json 을 통해 인증을 진행하여 terraform이 gcp에 배포할 수 있습니다.

provider &quot;google&quot; {
  credentials = file(&quot;/home/joon/.gcp/credential.json&quot;)
  project     = &quot;PROJECT_ID&quot;
  region      = &quot;asia-northeast3&quot;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이어서 모듈 디렉토리 안에 리소스를 정의하기 위한 main.tf를 작성합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1713168565477&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# modules/gke_cluster/main.tf

resource &quot;google_container_cluster&quot; &quot;gke_cluster&quot; {
  name     = var.clusterName
  location = var.region # Replace this with your desired region

  enable_shielded_nodes    = &quot;true&quot;
  remove_default_node_pool = true
  initial_node_count       = 1
  node_config {
    disk_size_gb           = var.diskSize
  }

  release_channel {
    channel = &quot;STABLE&quot;
  }

  addons_config {
    http_load_balancing {
      disabled = false
    }
  }

  networking_mode = &quot;VPC_NATIVE&quot;
  ip_allocation_policy {
    cluster_ipv4_cidr_block  = &quot;/16&quot;
    services_ipv4_cidr_block = &quot;/22&quot;
  }

  timeouts {
    create = &quot;20m&quot;
    update = &quot;20m&quot;
  }

  lifecycle {
    ignore_changes = [node_pool]
  }
}

resource &quot;google_container_node_pool&quot; &quot;primary_nodes&quot; {
  name       = &quot;${var.clusterName}-pool&quot;
  location   = var.region # Replace this with your desired region
  cluster    = google_container_cluster.gke_cluster.name
  node_count = 1

  management {
    auto_repair  = true
    auto_upgrade = true
  }

  autoscaling {
    min_node_count = var.minNode
    max_node_count = var.maxNode
  }

  timeouts {
    create = &quot;20m&quot;
    update = &quot;20m&quot;
  }

  node_config {
    preemptible  = true
    machine_type = var.machineType

    oauth_scopes = [
      &quot;https://www.googleapis.com/auth/compute&quot;,
      &quot;https://www.googleapis.com/auth/cloud-platform&quot;,
      &quot;https://www.googleapis.com/auth/devstorage.read_only&quot;,
      &quot;https://www.googleapis.com/auth/logging.write&quot;,
      &quot;https://www.googleapis.com/auth/monitoring&quot;,
    ]
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1713168885514&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# modules/gke_cluster/variables.tf

variable &quot;region&quot; {
  description = &quot;Deployment region&quot;
  default = &quot;asia-northeast3&quot;
}
variable &quot;clusterName&quot; {
  description = &quot;Name of our Cluster&quot;
}
variable &quot;diskSize&quot; {
  description = &quot;Node disk size in GB&quot;
}
variable &quot;minNode&quot; {
  description = &quot;Minimum Node Count&quot;
}
variable &quot;maxNode&quot; {
  description = &quot;maximum Node Count&quot;
}
variable &quot;machineType&quot; {
  description = &quot;Node Instance machine type&quot;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모듈에서 사용되는 변수를 정의합니다. 변수 값은 tfvars 파일에서 작성합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1713168952446&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# modules/gke_cluster/output.tf

output &quot;cluster_endpoint&quot; {
  value = google_container_cluster.gke_cluster.endpoint
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생성되는 리소스의 속성 값을 output.tf 파일을 통해 내보낼 수 있고 내보낸 값을 다른 모듈에서 import하여 사용도 가능합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1713169392391&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# main.tf

module &quot;gke_cluster&quot; {
  source = &quot;./modules/gke_cluster&quot;
  region       = var.region
  clusterName  = var.clusterName
  diskSize     = var.diskSize
  minNode      = var.minNode
  maxNode      = var.maxNode
  machineType  = var.machineType
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;프로젝트 디렉터리 내에 있는 main.tf 파일은 Terraform을 사용할 때, 루트 모듈에서 terraform plan 또는 terraform apply 명령어를 실행할 때 함께 사용됩니다. 이 모듈은 다른 모듈들을 호출하고, 하나의 모듈에서 출력된 값을 다른 모듈의 입력 값으로 전달하여 모듈들을 연결 가능합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1713170292826&quot; class=&quot;ini&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;# terraform.tfvars

region=&quot;asia-northeast3&quot;
clusterName=&quot;hjsong-gke-cluster&quot;
diskSize=50
minNode=1
maxNode=2
machineType=&quot;e2-medium&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제 변수에 입력될 값을 정의하는 파일입니다. 이 값을 통해 모듈내에 변수 처리된 곳에 값이 입력되는 방식입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1713170339863&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# variables.tf

variable &quot;region&quot; {
  description = &quot;Deployment region&quot;
  default = &quot;asia-northeast3&quot;
}
variable &quot;clusterName&quot; {
  description = &quot;Name of our Cluster&quot;
}
variable &quot;diskSize&quot; {
  description = &quot;Node disk size in GB&quot;
}
variable &quot;minNode&quot; {
  description = &quot;Minimum Node Count&quot;
}
variable &quot;maxNode&quot; {
  description = &quot;maximum Node Count&quot;
}
variable &quot;machineType&quot; {
  description = &quot;Node Instance machine type&quot;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;루트 모듈내에도 동일한 variables.tf 파일을 생성해줍니다. 모듈내의 variables.tf와 루트 모듈내의 variables.tf 의 역할 차이는 다음과 같습니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;모듈 내 variables.tf 파일의 역할&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;변수 선언 및 기본값 설정: 모듈 내 variables.tf 파일은 해당 모듈에서 사용할 입력 변수들을 선언하고, 필요한 경우 기본값을 설정합니다. 이를 통해 모듈이 독립적으로 사용될 수 있도록 합니다.&lt;/li&gt;
&lt;li&gt;재사용성 증가: 모듈을 다른 프로젝트나 환경에서 재사용할 때, variables.tf 파일에 정의된 입력 변수들을 통해 모듈의 설정을 쉽게 조정할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;모듈을 사용하는 곳(루트 모듈)의 variables.tf 파일의 역할&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;모듈 구성값 제공: main.tf와 같이 모듈을 사용하는 Terraform 구성 파일에서 variables.tf 파일은 해당 환경이나 프로젝트에 특화된 변수 값을 정의합니다. 이 변수들은 모듈에 전달되어 모듈의 동작을 구성합니다.&lt;/li&gt;
&lt;li&gt;환경별&amp;nbsp;구성&amp;nbsp;관리:&amp;nbsp;다양한&amp;nbsp;환경(예:&amp;nbsp;개발,&amp;nbsp;스테이징,&amp;nbsp;프로덕션)에&amp;nbsp;대해&amp;nbsp;각각의&amp;nbsp;variables.tf&amp;nbsp;파일을&amp;nbsp;통해&amp;nbsp;환경별로&amp;nbsp;다른&amp;nbsp;변수&amp;nbsp;값을&amp;nbsp;설정할&amp;nbsp;수&amp;nbsp;있습니다.&amp;nbsp;이를&amp;nbsp;통해&amp;nbsp;코드의&amp;nbsp;재사용성을&amp;nbsp;높이고&amp;nbsp;환경별&amp;nbsp;구성&amp;nbsp;관리를&amp;nbsp;용이하게&amp;nbsp;합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1713170542682&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# backend.tf

terraform {
 backend &quot;gcs&quot; {
   bucket  = &quot;hjsong-tfstate-bucket&quot;
   prefix  = &quot;terraform/state&quot;
 }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마지막으로 tfstate를 저장하고 관리하기 위한 버킷을 backend.tf 파일에 정의합니다. Terraform은 인프라의 현재 상태를 추적하기 위해 상태 파일(tfstate)을 사용합니다. backend.tf 파일에 버킷을 정의하는 것은 이 상태 파일을 안전하고 효율적으로 저장하고 관리하기 위한 방법입니다.&lt;/p&gt;</description>
      <category>GKE Project</category>
      <author>Joon0464</author>
      <guid isPermaLink="true">https://cumulus.tistory.com/152</guid>
      <comments>https://cumulus.tistory.com/152#entry152comment</comments>
      <pubDate>Mon, 15 Apr 2024 20:45:57 +0900</pubDate>
    </item>
    <item>
      <title>Terraform을 사용하여 GKE(Google Kubernetes Engine) 배포 - 사전 준비</title>
      <link>https://cumulus.tistory.com/151</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;GCP에서 제공하는 300달러 크래딧으로 토이 프로젝트를 진행하려는데 GKE를 계속 띄워두자니 크래딧을 너무 빨리 소모할 것 같다. Terraform도 사용해보고 IaC을 사용해서 손쉽게 올리고 내리기 위해 우선 Terraform으로 GKE를 구성해보고자 글을 작성한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. WSL에 gcloud SDK 설치 및 계정 등록&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1712208496831&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# WSL2 / Ubuntu 22.04 에 설치 진행

# Cloud SDK 를 사용하기 위해서는 Python 설치가 필수이므로 Python3를 아래와 같이 설치 진행합니다.

$ sudo apt update
$ sudo apt install -y python3 python3-pip


# 이어서 gcloud 설치를 진행합니다.
$ curl https://sdk.cloud.google.com | bash

# 쉘을 재시작하고 gcloud version을 확인하여 설치를 확인합니다.
$ exec -l $SHELL
$ gcloud version&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;362&quot; data-origin-height=&quot;134&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rx3Bp/btsGkCkZtAy/y8FRfCzfLCFmDENmDNWooK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rx3Bp/btsGkCkZtAy/y8FRfCzfLCFmDENmDNWooK/img.png&quot; data-alt=&quot;설치 버전을 확인한다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rx3Bp/btsGkCkZtAy/y8FRfCzfLCFmDENmDNWooK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Frx3Bp%2FbtsGkCkZtAy%2Fy8FRfCzfLCFmDENmDNWooK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;362&quot; height=&quot;134&quot; data-origin-width=&quot;362&quot; data-origin-height=&quot;134&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;설치 버전을 확인한다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1712212516700&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# gcloud init으로 계정 등록과정을 수행한다.
$ gcloud init&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;747&quot; data-origin-height=&quot;613&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cfWc5S/btsGlhVg3nC/7cjKZuu4ocomylRar3i7F1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cfWc5S/btsGlhVg3nC/7cjKZuu4ocomylRar3i7F1/img.png&quot; data-alt=&quot;OSError 가 발생..&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cfWc5S/btsGlhVg3nC/7cjKZuu4ocomylRar3i7F1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcfWc5S%2FbtsGlhVg3nC%2F7cjKZuu4ocomylRar3i7F1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;747&quot; height=&quot;613&quot; data-origin-width=&quot;747&quot; data-origin-height=&quot;613&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;OSError 가 발생..&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;별의 별 삽질 했는데 재부팅 후에 gcloud init 해보니 잘 된다...&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1890&quot; data-origin-height=&quot;460&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/VVLpZ/btsGkU636kD/0GiGkkytd7LK90IskmqqYk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/VVLpZ/btsGkU636kD/0GiGkkytd7LK90IskmqqYk/img.png&quot; data-alt=&quot;다시 gcloud init 명령어를 입력하고 url에 접근하여 gcp 계정으 로그인한다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/VVLpZ/btsGkU636kD/0GiGkkytd7LK90IskmqqYk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FVVLpZ%2FbtsGkU636kD%2F0GiGkkytd7LK90IskmqqYk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1890&quot; height=&quot;460&quot; data-origin-width=&quot;1890&quot; data-origin-height=&quot;460&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;다시 gcloud init 명령어를 입력하고 url에 접근하여 gcp 계정으 로그인한다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;627&quot; data-origin-height=&quot;125&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bNsBWi/btsGnHSsTH1/XAiggk1KKVLpzwWGdDGGL1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bNsBWi/btsGnHSsTH1/XAiggk1KKVLpzwWGdDGGL1/img.png&quot; data-alt=&quot;이어서 원하는 프로젝트를 생성하거나 선택하고&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bNsBWi/btsGnHSsTH1/XAiggk1KKVLpzwWGdDGGL1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbNsBWi%2FbtsGnHSsTH1%2FXAiggk1KKVLpzwWGdDGGL1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;627&quot; height=&quot;125&quot; data-origin-width=&quot;627&quot; data-origin-height=&quot;125&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;이어서 원하는 프로젝트를 생성하거나 선택하고&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;764&quot; data-origin-height=&quot;490&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ePGn8G/btsGkD5lxc2/qdvyA6AGbKo237euXWMqfk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ePGn8G/btsGkD5lxc2/qdvyA6AGbKo237euXWMqfk/img.png&quot; data-alt=&quot;default region을 선택하려면 선택하고 설정을 마친다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ePGn8G/btsGkD5lxc2/qdvyA6AGbKo237euXWMqfk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FePGn8G%2FbtsGkD5lxc2%2FqdvyA6AGbKo237euXWMqfk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;764&quot; height=&quot;490&quot; data-origin-width=&quot;764&quot; data-origin-height=&quot;490&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;default region을 선택하려면 선택하고 설정을 마친다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음 명령어로 등록된 정보를 확인할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1712213571879&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ gcloud config list&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;420&quot; data-origin-height=&quot;159&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/RqQPE/btsGmCj4xZW/WHUHDPKeM0geYQOhRir7BK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/RqQPE/btsGmCj4xZW/WHUHDPKeM0geYQOhRir7BK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/RqQPE/btsGmCj4xZW/WHUHDPKeM0geYQOhRir7BK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FRqQPE%2FbtsGmCj4xZW%2FWHUHDPKeM0geYQOhRir7BK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;420&quot; height=&quot;159&quot; data-origin-width=&quot;420&quot; data-origin-height=&quot;159&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. Terraform 설치&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이어서 Terraform 설치를 진행합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1712209755620&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 사전에 필요한 패키지를 설치합니다.
$ sudo apt-get update &amp;amp;&amp;amp; sudo apt-get install -y gnupg software-properties-common curl

# HashiCorp 의 GPG Key 등록합니다.
$ curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo apt-key add -

# Repository 등록
$ sudo apt-add-repository &quot;deb [arch=amd64] https://apt.releases.hashicorp.com $(lsb_release -cs) main&quot;

# Terraform 설치
$ sudo apt-get update &amp;amp;&amp;amp; sudo apt-get install terraform

# 자동완성 설정
$ echo &quot;terraform -install-autocomplete&quot; &amp;gt;&amp;gt; .bashrc

# 자동완성 설정 확인
$ tail -n 1 .bashrc
terraform -install-autocomplete

# .bashrc 즉시적용
$ source .bashrc

# terraform 설치 확인(버전)
$ terraform version&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;397&quot; data-origin-height=&quot;62&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bfzEaj/btsGmddJbQr/hFGZE0BdmHSGEzWN0pIhG1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bfzEaj/btsGmddJbQr/hFGZE0BdmHSGEzWN0pIhG1/img.png&quot; data-alt=&quot;설치가 완료되면 version 명령어로 확인한다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bfzEaj/btsGmddJbQr/hFGZE0BdmHSGEzWN0pIhG1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbfzEaj%2FbtsGmddJbQr%2FhFGZE0BdmHSGEzWN0pIhG1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;397&quot; height=&quot;62&quot; data-origin-width=&quot;397&quot; data-origin-height=&quot;62&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;설치가 완료되면 version 명령어로 확인한다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. VSCode 설정&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1013&quot; data-origin-height=&quot;281&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wryB3/btsGmCxCenj/XS9xQUq9X7CtcN6gK8VoS1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wryB3/btsGmCxCenj/XS9xQUq9X7CtcN6gK8VoS1/img.png&quot; data-alt=&quot;vscode에서 wsl 패키지를 설치한다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wryB3/btsGmCxCenj/XS9xQUq9X7CtcN6gK8VoS1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwryB3%2FbtsGmCxCenj%2FXS9xQUq9X7CtcN6gK8VoS1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1013&quot; height=&quot;281&quot; data-origin-width=&quot;1013&quot; data-origin-height=&quot;281&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;vscode에서 wsl 패키지를 설치한다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;wsl에서 원하는 디렉토리로 이동 후 다음 명령어를 수행한다.&lt;/p&gt;
&lt;pre id=&quot;code_1712214206161&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ code .&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;957&quot; data-origin-height=&quot;98&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/6jgeA/btsGlxjxifS/qJ64sAaTskEeRAVcTzWhrK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/6jgeA/btsGlxjxifS/qJ64sAaTskEeRAVcTzWhrK/img.png&quot; data-alt=&quot;code . 을 입력하면 패키지 설치가 진행된다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/6jgeA/btsGlxjxifS/qJ64sAaTskEeRAVcTzWhrK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F6jgeA%2FbtsGlxjxifS%2FqJ64sAaTskEeRAVcTzWhrK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;957&quot; height=&quot;98&quot; data-origin-width=&quot;957&quot; data-origin-height=&quot;98&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;code . 을 입력하면 패키지 설치가 진행된다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1007&quot; data-origin-height=&quot;758&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/9N10G/btsGnNLTMkY/W6qeHgKDICQs6IXbTTbKkK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/9N10G/btsGnNLTMkY/W6qeHgKDICQs6IXbTTbKkK/img.png&quot; data-alt=&quot;설치가 완료되면 vscode에서 다음과 같은 팝업 창이 뜨는데 Trust하고 Yes 하면 된다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/9N10G/btsGnNLTMkY/W6qeHgKDICQs6IXbTTbKkK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F9N10G%2FbtsGnNLTMkY%2FW6qeHgKDICQs6IXbTTbKkK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1007&quot; height=&quot;758&quot; data-origin-width=&quot;1007&quot; data-origin-height=&quot;758&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;설치가 완료되면 vscode에서 다음과 같은 팝업 창이 뜨는데 Trust하고 Yes 하면 된다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1712214459734&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ mkdir {프로젝트를 수행할 디렉토리 명}
$ code {위 명령어로 생성된 디렉토리 명}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1069&quot; data-origin-height=&quot;1039&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dpF3HX/btsGmuNaD9Z/hSsB6YbTcgbI9vttx5lMV0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dpF3HX/btsGmuNaD9Z/hSsB6YbTcgbI9vttx5lMV0/img.png&quot; data-alt=&quot;디렉토리를 생성하고 해당 디렉토리를 code 명령어로 열어주면 vscode에서 해당 디렉토리를 열게된다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dpF3HX/btsGmuNaD9Z/hSsB6YbTcgbI9vttx5lMV0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdpF3HX%2FbtsGmuNaD9Z%2FhSsB6YbTcgbI9vttx5lMV0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1069&quot; height=&quot;1039&quot; data-origin-width=&quot;1069&quot; data-origin-height=&quot;1039&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;디렉토리를 생성하고 해당 디렉토리를 code 명령어로 열어주면 vscode에서 해당 디렉토리를 열게된다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4. Kubectl 및 gcloud 플러그인 설치&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1712216167554&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# kubectl 최신 릴리스를 다운로드한다.
$ curl -LO &quot;https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl&quot;

# Kubectl 을 설치한다.
# sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl

# kubectl 설치 버전 확인
$ kubectl version --client&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1052&quot; data-origin-height=&quot;208&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Lcumx/btsGmMNAIhd/zP7t7338JO1xkc619qALq1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Lcumx/btsGmMNAIhd/zP7t7338JO1xkc619qALq1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Lcumx/btsGmMNAIhd/zP7t7338JO1xkc619qALq1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLcumx%2FbtsGmMNAIhd%2FzP7t7338JO1xkc619qALq1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1052&quot; height=&quot;208&quot; data-origin-width=&quot;1052&quot; data-origin-height=&quot;208&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 과정만 진행해도 상관은 없으나 편하게 사용하려면 아무래도 kubectl 자동완성까지 설정해주는게 좋다.&lt;/p&gt;
&lt;pre id=&quot;code_1712216476177&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# bash-completion 이 설치되어 있지 않다면 설치를 진행한다.
$ sudo apt-get install bash-completion

# type _init_completion 명령어를 수행해보고 명령어가 수행되는지 확인한다.
$ type _init_completion

# 수행이 잘 된다면 아래 명령어를 스킵하고, 수행되지 않는다면 다음 명령어를 수행한다.
$ echo &quot;source /usr/share/bash-completion/bash_completion&quot; &amp;gt;&amp;gt; ~/.bashrc &amp;amp;&amp;amp; source .bashrc&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 과정을 수행하면 kubectl 자동완성 기능을 사용할 수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1713159656489&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ gcloud components install gke-gcloud-auth-plugin


Your current Google Cloud CLI version is: 471.0.0
Installing components from version: 471.0.0

┌────────────────────────────────────────────┐
│    These components will be installed.     │
├────────────────────────┬─────────┬─────────┤
│          Name          │ Version │   Size  │
├────────────────────────┼─────────┼─────────┤
│ gke-gcloud-auth-plugin │   0.5.8 │ 7.9 MiB │
└────────────────────────┴─────────┴─────────┘

For the latest full release notes, please visit:
  https://cloud.google.com/sdk/release_notes

Do you want to continue (Y/n)?  Y

╔════════════════════════════════════════════════════════════╗
╠═ Creating update staging area                             ═╣
╠════════════════════════════════════════════════════════════╣
╠═ Installing: gke-gcloud-auth-plugin                       ═╣
╠════════════════════════════════════════════════════════════╣
╠═ Installing: gke-gcloud-auth-plugin                       ═╣
╠════════════════════════════════════════════════════════════╣
╠═ Creating backup and activating new installation          ═╣
╚════════════════════════════════════════════════════════════╝

Performing post processing steps...done.

Update done!&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마지막으로 kubectl gke 플러그인을 설치해주면 모든 사전 준비가 완료됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이번에는 terraform으로 IaC 개발을 수행하기 위한 사전 준비작업 과정에 대해 정리하였습니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이어서 Terraform을 작성하여 GKE 클러스터를 구성하는 과정에 대해 포스팅하도록 하겠습니다.&lt;/p&gt;</description>
      <category>GKE Project</category>
      <author>Joon0464</author>
      <guid isPermaLink="true">https://cumulus.tistory.com/151</guid>
      <comments>https://cumulus.tistory.com/151#entry151comment</comments>
      <pubDate>Thu, 4 Apr 2024 22:09:40 +0900</pubDate>
    </item>
    <item>
      <title>DevOps를 위한 쿠버네티스 마스터 강의 정리(2)</title>
      <link>https://cumulus.tistory.com/150</link>
      <description>&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;아래 강의에서 필요하거나 핵심적인 내용만 정리하였습니다.&lt;/b&gt;&lt;/h2&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;a href=&quot;https://inf.run/wAfB2&quot;&gt;https://inf.run/wAfB2&lt;/a&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;figure id=&quot;og_1710219851663&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/beFqqv/hyVxvcwbPz/6KSMU3MLRn1xdmWumu1Igk/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/cyUPIO/hyVxzstqFM/1rsTyeGTFYOBohyc1H3T11/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/cwg18G/hyVxt6POti/0yYoljmdKgHd6dkOMETIY1/img.jpg?width=1520&amp;amp;height=878&amp;amp;face=0_0_1520_878&quot; data-og-url=&quot;https://www.inflearn.com/course/%EB%8D%B0%EB%B8%8C%EC%98%B5%EC%8A%A4-%EC%BF%A0%EB%B2%84%EB%84%A4%ED%8B%B0%EC%8A%A4-%EB%A7%88%EC%8A%A4%ED%84%B0&quot; data-og-source-url=&quot;https://inf.run/wAfB2&quot; data-og-host=&quot;www.inflearn.com&quot; data-og-description=&quot;컨테이너 기반 오픈 소스 가상화 프로젝트인 &amp;quot;쿠버네티스&amp;quot;를 이용한 컨테이너 환경의 분산 시스템을 탄력적으로 실행하기 위한 프레임 워크를 활용하는 방법을 입문부터 활용까지 다룹니다., [&quot; data-og-title=&quot;데브옵스(DevOps)를 위한 쿠버네티스 마스터 강의 - 인프런&quot; data-og-type=&quot;website&quot; data-ke-align=&quot;alignCenter&quot; data-ke-type=&quot;opengraph&quot;&gt;&lt;a style=&quot;color: #000000;&quot; href=&quot;https://inf.run/wAfB2&quot; data-source-url=&quot;https://inf.run/wAfB2&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/beFqqv/hyVxvcwbPz/6KSMU3MLRn1xdmWumu1Igk/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/cyUPIO/hyVxzstqFM/1rsTyeGTFYOBohyc1H3T11/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/cwg18G/hyVxt6POti/0yYoljmdKgHd6dkOMETIY1/img.jpg?width=1520&amp;amp;height=878&amp;amp;face=0_0_1520_878');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; style=&quot;color: #000000;&quot; data-ke-size=&quot;size16&quot;&gt;데브옵스(DevOps)를 위한 쿠버네티스 마스터 강의 - 인프런&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; style=&quot;color: #909090;&quot; data-ke-size=&quot;size16&quot;&gt;컨테이너 기반 오픈 소스 가상화 프로젝트인 &quot;쿠버네티스&quot;를 이용한 컨테이너 환경의 분산 시스템을 탄력적으로 실행하기 위한 프레임 워크를 활용하는 방법을 입문부터 활용까지 다룹니다., [&lt;/p&gt;
&lt;p class=&quot;og-host&quot; style=&quot;color: #909090;&quot; data-ke-size=&quot;size16&quot;&gt;www.inflearn.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- 범위: 색션 0: 하이퍼바이저와 가상 머신의 이해 ~ 도커와 쿠버네티스 이해&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;가상화란?&lt;/b&gt;&lt;/h2&gt;
&lt;hr data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;가상화는 전통적으로 하드웨어에 종속된 리소스를 사용하여 유용한 IT 서비스를 만드는 기술&lt;/li&gt;
&lt;li&gt;가상화를 사용하면 물리적 머신의 기능을 여러 사용자 또느 ㄴ환경에 배포하여 물리적 머신을 최대한 활용 가능&lt;/li&gt;
&lt;li&gt;가상화를 통해 기업은 서버를 파티셔닝하고 여러 유형 및 버전의 운영 체제에서 애플리케이션을 실행&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;하이퍼바이저의 정의 / 가상화 원리&lt;/b&gt;&lt;/h2&gt;
&lt;hr data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;하이퍼바이저란
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;소프트웨어가 물리 리소스를 필요로 하는 가상 환경으로부터 물리 리소르를 분리&lt;/li&gt;
&lt;li&gt;호스트 컴퓨터에서 운영체제 다수를 동시에 실행하는 논리적 플랫폼&lt;/li&gt;
&lt;li&gt;Native 타입과 Hosted 타입이 존재&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Native - type1
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;해당 하드웨어/베어메탈에 하이퍼바이저를 직접 설치, 하이퍼바이저가 호스트 운영체제의 역할까지 하게 됨&lt;/li&gt;
&lt;li&gt;게스트 운영체제는 두 번째 수순으로 실행됨&lt;/li&gt;
&lt;li&gt;Xen, KVM, Xen Server 등 존재&lt;/li&gt;
&lt;li&gt;상대적으로 성능이 좋음&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Hosted - type2
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;일반 프로그램처럼 호스트 운영체제 위에서 하이퍼바이저 실행&lt;/li&gt;
&lt;li&gt;게스트 운영체제는 세번째 수준으로 실행&lt;/li&gt;
&lt;li&gt;Virtualbox, Vmware, Parrallels 등 존재&lt;/li&gt;
&lt;li&gt;상대적으로 성능이 조금 낮다&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;전가상화(Full Virtualization)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;하드웨어를 모두 가상화&lt;/li&gt;
&lt;li&gt;게스트 운영체제를 변경하지 않음&lt;/li&gt;
&lt;li&gt;물리적인 가상화를 지원하느 CPU 가상화 기술(VT필요)&lt;/li&gt;
&lt;li&gt;네이티브 방식의 가상화에서 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;반가상화(Para Virtualization)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;하드웨어를 완전히 가상화하지 않음&lt;/li&gt;
&lt;li&gt;게스트 운영체제 커널 일부 수정이 필요(오픈소스 아니면 사용 불가능)&lt;/li&gt;
&lt;li&gt;하이퍼바이저가 모든 제어를 담당하여 높은 성능을 유지&lt;/li&gt;
&lt;li&gt;Qemu가 대표적인 도구&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;컨테이너&lt;/b&gt;&lt;/h2&gt;
&lt;hr data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;컨테이너는 가상환경을 사용하여 각 마이크로 서비스를 격리하는 기술&lt;/li&gt;
&lt;li&gt;컨테이너는 가상머신처럼 하드웨어를 전부 구현하지 않기 때문에 매우 빠른 실행 가능&lt;/li&gt;
&lt;li&gt;vm과 달리 하이퍼바이저와 Guest Os 영역의 오버헤드를 없앨 수 있어 매우 가벼움&lt;/li&gt;
&lt;li&gt;가상화가 아닌 격리, HostOS와 컨테이너가 직접 통신&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;리눅스 네임스페이스&lt;/b&gt;&lt;/h2&gt;
&lt;hr data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;컨테이너를 격리하는 기술&lt;b&gt;&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;각 프로세스가 파일 시스템 마운트, 네트웤, 유저(uid), 호스트 네임(uts) 등 에 대해 시스템에 독립뷰를 제공&lt;/li&gt;
&lt;li&gt;네임스페이스 안에 동작하는 애플리케이션만 자원에 접근 가능&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;도커(Docker)&lt;/b&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;컨테이너 기술을 지원하는 프로젝트 중 하나로 다양한 운영체제에서 사용 가능한 컨테이너 런타임&lt;/li&gt;
&lt;li&gt;애플리케이션에 국한 되지 않고 의존성 및 파일 시스템까지 패키징하여 빌드, 배포, 실행을 단순화&lt;/li&gt;
&lt;li&gt;리눅스의 네임스페이스와 cgroups와 같은 커널 기능을 사용하여 가상화&lt;/li&gt;
&lt;li&gt;&lt;b&gt;containerd&lt;/b&gt;가 독립 실행형 프로젝트로 추출되어 현재 Kubernetes의 컨테이너 런타임으로 사용된다.&lt;/li&gt;
&lt;li&gt;kubernetes에서 docker를 중간에 두지 않고 containerd와 직접 통신이 가능하도록 발전, 개발 과정에서는 도커가 여전히 사용&lt;/li&gt;
&lt;li&gt;다양한 운영체제에서 사용 가능(리눅스, 윈도우 등)&lt;/li&gt;
&lt;li&gt;애플리케이션에 국한 되지 않고 의존성 및 파일 시스템까지 전부 패키징하여 빌드, 배포, 실행을 단순화&lt;/li&gt;
&lt;li&gt;리눅스의 네임스페이스와 cgropus와 같은 커널 기능을 사용하여 가상화&lt;/li&gt;
&lt;li&gt;이미지: 필요한 프로그램과 라이브러리, 소스를 설치한 뒤 만든 하나의 파일&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;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;쿠버네티스(Kubernetes)&lt;/b&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;다수의 컨테이너를 자동으로 운영하기 위한 오케스트레이션 도구&lt;/li&gt;
&lt;li&gt;많은 시스템을 통합, 컨테이너를 다루기 위한 API를 제공&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;도커의 한계&lt;/b&gt;&lt;/h2&gt;
&lt;hr data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;서비스가 커질수록 관리해야 하는 컨테이너 양이 급격하게 증가&lt;/li&gt;
&lt;li&gt;도커를 사용하여 관리를 하기엔 무리&lt;/li&gt;
&lt;li&gt;배포 및 컨테이너 배치 전략, 스케일-인, 스케일-아웃이 쉽지 않음&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;=&amp;gt; Kubernetes, docker swam등의 오케스트레이션 툴이 필요하게 된 이유&lt;/b&gt;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;컨테이너를 격리하는 기술&lt;/b&gt;&lt;/h2&gt;
&lt;hr data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;리눅스 네임스페이스
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;각 프로세스가 파일 시스템 마운트, 네트워크, 유저(uid), 호스트 네임(uts) 등에 대해 시스템에 독립 뷰를 제공&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;리눅스 컨트롤 그룹: 프로세스로 소비할 수 잇는 리소스 양(CPU, Memory, I/O, 네트워크 대역대, device 노드 등)을 제한&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>k8s</category>
      <author>Joon0464</author>
      <guid isPermaLink="true">https://cumulus.tistory.com/150</guid>
      <comments>https://cumulus.tistory.com/150#entry150comment</comments>
      <pubDate>Tue, 12 Mar 2024 18:31:02 +0900</pubDate>
    </item>
    <item>
      <title>DevOps를 위한 쿠버네티스 마스터 강의 정리(1)</title>
      <link>https://cumulus.tistory.com/149</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;아래 강의에서 필요하거나 핵심적인 내용만 정리하였습니다.&lt;/b&gt;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;a href=&quot;https://inf.run/wAfB2&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://inf.run/wAfB2&lt;/a&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;figure id=&quot;og_1710219729773&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;데브옵스(DevOps)를 위한 쿠버네티스 마스터 강의 - 인프런&quot; data-og-description=&quot;컨테이너 기반 오픈 소스 가상화 프로젝트인 &amp;quot;쿠버네티스&amp;quot;를 이용한 컨테이너 환경의 분산 시스템을 탄력적으로 실행하기 위한 프레임 워크를 활용하는 방법을 입문부터 활용까지 다룹니다., [&quot; data-og-host=&quot;www.inflearn.com&quot; data-og-source-url=&quot;https://inf.run/wAfB2&quot; data-og-url=&quot;https://www.inflearn.com/course/%EB%8D%B0%EB%B8%8C%EC%98%B5%EC%8A%A4-%EC%BF%A0%EB%B2%84%EB%84%A4%ED%8B%B0%EC%8A%A4-%EB%A7%88%EC%8A%A4%ED%84%B0&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/beFqqv/hyVxvcwbPz/6KSMU3MLRn1xdmWumu1Igk/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/cyUPIO/hyVxzstqFM/1rsTyeGTFYOBohyc1H3T11/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/cwg18G/hyVxt6POti/0yYoljmdKgHd6dkOMETIY1/img.jpg?width=1520&amp;amp;height=878&amp;amp;face=0_0_1520_878&quot;&gt;&lt;a href=&quot;https://inf.run/wAfB2&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://inf.run/wAfB2&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/beFqqv/hyVxvcwbPz/6KSMU3MLRn1xdmWumu1Igk/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/cyUPIO/hyVxzstqFM/1rsTyeGTFYOBohyc1H3T11/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/cwg18G/hyVxt6POti/0yYoljmdKgHd6dkOMETIY1/img.jpg?width=1520&amp;amp;height=878&amp;amp;face=0_0_1520_878');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;데브옵스(DevOps)를 위한 쿠버네티스 마스터 강의 - 인프런&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;컨테이너 기반 오픈 소스 가상화 프로젝트인 &quot;쿠버네티스&quot;를 이용한 컨테이너 환경의 분산 시스템을 탄력적으로 실행하기 위한 프레임 워크를 활용하는 방법을 입문부터 활용까지 다룹니다., [&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.inflearn.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- 범위: 색션 0: 쿠버네티스 이슈 ~ 마이크로서비스 성공 사례-1&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;클라우드&amp;nbsp;네이티브란?&lt;/b&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;클라우드의 장점을 최대한 활용하여 정보 시스템을 구축 및 실행하는 환경&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;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;기존 애플리케이션 vs 클라우드 네이티브 애플리케이션&lt;/b&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1. 기존 애플리케이션&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;모놀리식 구조&lt;/b&gt; -&amp;gt; 여러 서비스 단위(회원가입, 장바구니, 결제, 등등)가 하나의 소스코드로 개발되어 있는 형태&lt;/li&gt;
&lt;li&gt;크고 조밀한 결합&lt;/li&gt;
&lt;li&gt;&lt;b&gt;물리서버&lt;/b&gt;, &lt;b&gt;VM &lt;/b&gt;중심&amp;nbsp;환경&lt;/li&gt;
&lt;li&gt;수직 확장 방식 사용 (&lt;b&gt;Scale-up&lt;/b&gt;)&lt;/li&gt;
&lt;li&gt;인프라 의존적&lt;/li&gt;
&lt;li&gt;폭포수(Waterfall) 개발 방법 사용&lt;/li&gt;
&lt;li&gt;수작업 배포로 인한 긴 시간 소요&lt;/li&gt;
&lt;li&gt;단절된 개발, 운영, 보안팀&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2. 클라우드&amp;nbsp;네이티브&amp;nbsp;애플리케이션&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;마이크로서비스 구조&lt;/b&gt; -&amp;gt; 여러 서비스 단위별로 각각의 컨테이너에 올라가 각 컨테이너가 느슨하게 결합되어 전체 서비스가 동작하는 형태&lt;/li&gt;
&lt;li&gt;느슨한 결합, 서비스 기반 구조&lt;/li&gt;
&lt;li&gt;가상 &lt;b&gt;컨테이너&lt;/b&gt; 환경&lt;/li&gt;
&lt;li&gt;수평 확장 방식 사용 (&lt;b&gt;Scale-out&lt;/b&gt;)&lt;/li&gt;
&lt;li&gt;인프라 독립적이고 이식성이 보장됨&lt;/li&gt;
&lt;li&gt;애자일(Agile) 개발 방법 사용&lt;/li&gt;
&lt;li&gt;CI/CD 자동화, 짧은 시간 &amp;amp; 지속적 배포&lt;/li&gt;
&lt;li&gt;DevOps 협업&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;모놀로식 서비스 아키텍처의 단점&lt;/b&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;하나의 애플리케이션에 여러 서비스가 존재하기 때문에 인기 있는 특정 서비스로 인해 부하가 발생하여 Scale-out 하면 인기 없는 서비스까지 확장된다.&lt;/li&gt;
&lt;li&gt;종속적인 라이브러리 충돌이 잦음&lt;/li&gt;
&lt;li&gt;약간의 수정에도 전체 애플리케이션을 빌드 및 배포해야 함&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;마이크로서비스 아키텍처의 장점&lt;/b&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;각각의 기능을 하나의 서비스 단위로 구분하여 개발하기 때문에 개발자가&lt;/li&gt;
&lt;li&gt;특정 비즈니스 로직에 대해서 집중하여 개발이 가능하여 빠른 개발이 가능&lt;/li&gt;
&lt;li&gt;서비스 단위로 개발, 패키징, 빌드, 테스트, 배포로 각 서비스마다 유연한 스케줄링 가&lt;/li&gt;
&lt;li&gt;서비스 단위로 스케일 아웃이 가능 (고효율 저비용 Scale-out 구조)&lt;/li&gt;
&lt;li&gt;장애를 하나의 모듈에만 고립시켜 전체 서비스에는 영향을 미치지 않음&lt;/li&gt;
&lt;li&gt;전체 애플리케이션이 아닌 서비스 단위로 Scale-in/out을 하기 때문에 스케일 시간이 단축됨&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;-&amp;gt; 하지만 분산 시스템 환경에서 트랜젝션 보장, 테스트, 배포, 관리가 복잡해지는 문제가 있음 -&amp;gt; Kubernetes 의 필요성 대&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>k8s</category>
      <author>Joon0464</author>
      <guid isPermaLink="true">https://cumulus.tistory.com/149</guid>
      <comments>https://cumulus.tistory.com/149#entry149comment</comments>
      <pubDate>Tue, 12 Mar 2024 18:02:36 +0900</pubDate>
    </item>
  </channel>
</rss>