[{"content":"MCP(Model Context Protocol) 서버 사용법과 주요 LLM 에이전트 설정 가이드 요청 개요 본 보고서는 MCP(Model Context Protocol) 서버의 개념과 사용법, 그리고 Claude Desktop, Cursor, Cline, Windsurf 등 주요 LLM 에이전트에서의 설정 방법을 종합적으로 정리하는 것을 목적으로 한다. 아울러 인기 있고 유용한 MCP 서버의 활용 사례를 소개하여, 초보자부터 실무자까지 MCP 생태계를 이해하고 실제 환경에 적용할 수 있도록 돕는다.\n수집 소스 MCP 서버 총정리 | 사용법 및 구축 방법 까지 10분 만에 완성하는 초보자 가이드 | 프롬프트해커 대니 MCP란? Claude Desktop MCP 서버 설정하는 법 - Model Context Protocol 초보 가이드 :: 갓대희의 작은공간 Claude Desktop과 MCP 서버 연동 가이드 - 보다 더 재미있게 [MCP] 요즘 핫하다는 MCP를 이용해 MCP 서버를 구현해봤습니다. | 모두의연구소 MCP Servers in Every AI Client: Claude, ChatGPT, VS Code, and Cursor 핵심 분석 1. MCP(Model Context Protocol)의 개념 MCP는 LLM 애플리케이션과 외부 데이터 소스 및 도구를 연결하기 위한 표준 프로토콜이다. 클라이언트(Claude Desktop, Cursor 등 AI 애플리케이션)와 서버(GitHub, Slack, DB 등 각 시스템별로 구현된 서버)가 JSON-RPC 방식으로 통신하는 구조를 가진다. 즉, MCP는 AI 모델이 로컬 파일, 데이터베이스, 외부 API 등에 접근할 수 있도록 표준화된 인터페이스를 제공하는 \u0026ldquo;AI용 USB-C\u0026quot;와 같은 역할을 한다.\n2. MCP 서버의 구성 요소 MCP 서버는 일반적으로 다음 세 가지 요소를 구현한다.\n리소스(Resources): AI가 읽을 수 있는 데이터(파일, 문서, DB 레코드 등) 도구(Tools): AI가 호출할 수 있는 함수(검색, 쓰기, API 호출 등) 프롬프트(Prompts): 재사용 가능한 프롬프트 템플릿 서버는 Python 또는 TypeScript SDK를 이용해 구현할 수 있으며, 공식 GitHub 저장소의 예제를 참고하면 빠르게 시작할 수 있다.\n3. 주요 LLM 에이전트별 MCP 설정 방법 Claude Desktop: claude_desktop_config.json 파일에 MCP 서버 정보(명령어, 인자, 환경변수)를 등록하여 로컬 파일시스템, GitHub, Slack 등과 연동한다. 가장 널리 사용되는 MCP 클라이언트로, 초보자 가이드가 다수 존재한다. Cursor / VS Code (Copilot): 설정 파일 또는 UI를 통해 MCP 서버를 등록하며, 코드 편집·검색·터미널 자동화 등 개발 워크플로우에 통합된다. Windsurf / Cline: 유사한 JSON 기반 설정 방식을 사용하며, 에이전트형 자동화(파일 생성, 명령 실행)에 강점을 보인다. ChatGPT Desktop / Claude Code: 원격 OAuth 기반 MCP 서버 연결을 지원하여 클라우드 환경에서도 활용 가능하다. 4. 인기 있고 유용한 MCP 서버 유형 파일시스템 서버: 로컬 파일 읽기/쓰기 및 디렉터리 탐색 GitHub 서버: 이슈, PR, 코드 검색 자동화 Slack/Notion 서버: 메시지 전송, 문서 조회 및 요약 데이터베이스 서버: PostgreSQL, SQLite 등 쿼리 실행 브라우저/검색 서버: 웹 검색 및 스크래핑을 통한 최신 정보 반영 Puppeteer/Playwright 서버: 웹 자동화 및 테스트 5. 구축 및 연동 시 실무 팁 서버 실행 명령과 경로를 정확히 지정해야 하며, 환경변수(API 키 등) 관리에 주의해야 한다. JSON-RPC 통신 로그를 확인하면 연결 실패 원인을 빠르게 파악할 수 있다. 초보자는 공식 예제 서버(filesystem, fetch 등)부터 시작해 점진적으로 커스텀 서버를 구현하는 것이 권장된다. 결론 MCP는 LLM이 외부 세계와 상호작용하는 방식을 표준화한 프로토콜로, Claude Desktop을 비롯한 Cursor, Cline, Windsurf, VS Code 등 주요 AI 클라이언트에서 빠르게 채택되고 있다. JSON-RPC 기반의 단순한 구조 덕분에 Python/TypeScript로 손쉽게 서버를 구현할 수 있으며, 파일시스템·GitHub·DB·Slack 등 다양한 서버를 조합하면 AI 에이전트의 실질적인 자동화 역량이 크게 향상된다. 결국 MCP 생태계의 핵심은 \u0026ldquo;표준화된 연결\u0026quot;에 있으며, 이를 이해하고 설정할 수 있는 사용자가 AI 활용의 폭을 한층 넓힐 수 있다.\n한계 및 주의사항 수집된 자료 중 일부는 블로그·커뮤니티 글로, 공식 문서 대비 최신성이 떨어지거나 개인 환경에 특화된 내용이 포함될 수 있다. MCP는 빠르게 진화하는 프로토콜로, 클라이언트별 설정 파일 위치·형식이 버전에 따라 변경될 가능성이 있어 공식 문서를 병행 확인해야 한다. 각 서버의 보안(로컬 파일 접근, API 키 노출 등)에 대한 위험성은 자료마다 다르게 다뤄지므로, 실제 적용 전 권한 범위를 신중히 검토해야 한다. Cline, Windsurf 등 일부 클라이언트의 구체적 설정 방법은 수집된 소스에서 상대적으로 비중이 낮아 추가 검색이 필요하다. ","permalink":"https://wkqco33.github.io/wkqcosoft-docs/reports/2026-09-19-mcp-model-context-protocol-%EC%84%9C%EB%B2%84-f63faa/","summary":"\u003ch1 id=\"mcpmodel-context-protocol-서버-사용법과-주요-llm-에이전트-설정-가이드\"\u003eMCP(Model Context Protocol) 서버 사용법과 주요 LLM 에이전트 설정 가이드\u003c/h1\u003e\n\u003ch2 id=\"요청-개요\"\u003e요청 개요\u003c/h2\u003e\n\u003cp\u003e본 보고서는 MCP(Model Context Protocol) 서버의 개념과 사용법, 그리고 Claude Desktop, Cursor, Cline, Windsurf 등 주요 LLM 에이전트에서의 설정 방법을 종합적으로 정리하는 것을 목적으로 한다. 아울러 인기 있고 유용한 MCP 서버의 활용 사례를 소개하여, 초보자부터 실무자까지 MCP 생태계를 이해하고 실제 환경에 적용할 수 있도록 돕는다.\u003c/p\u003e\n\u003ch2 id=\"수집-소스\"\u003e수집 소스\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"https://www.magicaiprompts.com/docs/claude/mcp-server/\"\u003eMCP 서버 총정리 | 사용법 및 구축 방법 까지 10분 만에 완성하는 초보자 가이드 | 프롬프트해커 대니\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://goddaehee.tistory.com/386\"\u003eMCP란? Claude Desktop MCP 서버 설정하는 법 - Model Context Protocol 초보 가이드 :: 갓대희의 작은공간\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://illysamsa.tistory.com/entry/Claude-Desktop%EA%B3%BC-MCP-%EC%84%9C%EB%B2%84-%EC%97%B0%EB%8F%99-%EA%B0%80%EC%9D%B4%EB%93%9C\"\u003eClaude Desktop과 MCP 서버 연동 가이드 - 보다 더 재미있게\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://modulabs.co.kr/community/momos/8/feeds/653\"\u003e[MCP] 요즘 핫하다는 MCP를 이용해 MCP 서버를 구현해봤습니다. | 모두의연구소\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://buildtolaunch.substack.com/p/mcp-setup-claude-chatgpt-vscode-cursor\"\u003eMCP Servers in Every AI Client: Claude, ChatGPT, VS Code, and Cursor\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"핵심-분석\"\u003e핵심 분석\u003c/h2\u003e\n\u003ch3 id=\"1-mcpmodel-context-protocol의-개념\"\u003e1. MCP(Model Context Protocol)의 개념\u003c/h3\u003e\n\u003cp\u003eMCP는 LLM 애플리케이션과 외부 데이터 소스 및 도구를 연결하기 위한 표준 프로토콜이다. 클라이언트(Claude Desktop, Cursor 등 AI 애플리케이션)와 서버(GitHub, Slack, DB 등 각 시스템별로 구현된 서버)가 \u003cstrong\u003eJSON-RPC\u003c/strong\u003e 방식으로 통신하는 구조를 가진다. 즉, MCP는 AI 모델이 로컬 파일, 데이터베이스, 외부 API 등에 접근할 수 있도록 표준화된 인터페이스를 제공하는 \u0026ldquo;AI용 USB-C\u0026quot;와 같은 역할을 한다.\u003c/p\u003e","title":"MCP(Model Context Protocol) 서버 사용법과 주요 LLM 에이전트(Claude Desktop, Cursor, Cline, Windsurf 등) 설정 방법 가이드 및 인기 있고 유용한 MCP 서버 소개 보고서"},{"content":"NVIDIA GR00T 모델 기반 ROS2 물체 집기·놓기(Pick and Place) 구현 실전 가이드 요청 개요 본 보고서는 NVIDIA GR00T 파운데이션 모델을 ROS2 환경에서 활용하여 물체 집기(pick)와 원하는 장소에 놓기(place)를 구현하는 방법을 종합적으로 분석한다. GR00T N1/N1.5 모델, Isaac Lab/Sim 시뮬레이션 환경, GR00T-Teleop/Dreamer/Mimic 데이터 생성 파이프라인, MoveIt2 기반 모션 계획, 그리고 sim-to-real 전이 전략을 아우르는 실전 구현 가이드를 제공하는 것을 목표로 한다.\n수집 소스 NVIDIA 공식 문서 - Pick and Place Simulation (Isaac ROS)\nURL: https://docs.nvidia.com/learning/physical-ai/getting-started-with-isaac-ros/latest/accelerating-ros-2-with-nvidia-gpu-powered-libraries-and-ai-models/04-pick-and-place-simulation.html GitHub - konu-droid/Isaac-GR00T-ros2\nURL: https://github.com/konu-droid/Isaac-GR00T-ros2 GitHub - NVIDIA/Isaac-GR00T (N1.7)\nURL: https://github.com/Nvidia/Isaac-GR00T IsaacLab - PickPlace GR1T2 환경 설정 파일\nURL: https://github.com/isaac-sim/IsaacLab/blob/main/source/isaaclab_tasks/isaaclab_tasks/manager_based/manipulation/pick_place/pickplace_gr1t2_env_cfg.py Isaac ROS 공식 문서 - Pick and Place 튜토리얼\nURL: https://nvidia-isaac-ros.github.io/reference_workflows/isaac_for_manipulation/tutorials/isaac_sim/tutorial_isaac_sim_pick_and_place.html 핵심 분석 1. GR00T 모델 아키텍처 개요 1.1 GR00T N1 - 최초의 오픈 휴머노이드 파운데이션 모델 특징: 범용 휴머노이드 로봇 추론 및 스킬 학습을 위한 세계 최초의 오픈 파운데이션 모델 학습 데이터: 실제 캡처 데이터(real captured data) NVIDIA Isaac GR00T Blueprint 기반 합성 데이터(신경망 생성 궤적 포함) 인터넷 규모의 비디오 데이터 ROS2 통합: Isaac-GR00T-ros2 저장소를 통해 ROS2 환경에서 직접 활용 가능 1.2 GR00T N1.5 및 N1.7 N1.5: N1의 후속 모델로, 물체 조작 능력이 개선된 버전 N1.7: 최신 버전으로, 범용 로봇을 위한 파운데이션 모델로 발전 공통점: Isaac Lab/Sim 환경과의 긴밀한 통합 지원 2. 시뮬레이션 환경 구축 2.1 Isaac Sim 기반 시뮬레이션 Isaac Sim: NVIDIA의 물리 기반 시뮬레이션 플랫폼으로, ROS2와의 통합이 원활함 Pick and Place 워크플로우: I s a a c S i m 환 경 → R O S 2 액 션 서 버 → M o v e I t 2 모 션 플 래 너 → 로 봇 제 어 2.2 Isaac Lab 환경 설정 PickPlace GR1T2 환경: pickplace_gr1t2_env_cfg.py 파일에서 환경 구성 GR1T2 휴머노이드 로봇 기반 pick-place 태스크 정의 Manager-based RL 환경으로 설계되어 정책 학습에 최적화 3. ROS2 통합 및 액션 인터페이스 3.1 Pick and Place 액션 정의 # 단일 물체 pick and place ros2 action send_goal /pick_and_place isaac_manipulator_interfaces/action/PickAndPlace \\ \u0026#34;{object_id : 3, place_pose : { position : { x : -0.35, y : 0.15, z : 0.5}, orientation : { w : 0.034, x : 0.996, y : 0.066, z : 0.042}}}\u0026#34; # 다중 물체 pick and place ros2 action send_goal --feedback /multi_object_pick_and_place \\ isaac_ros_manipulation_interfaces/action/MultiObjectPickAndPlace \\ \u0026#39;{target_poses: {header: {frame_id: \u0026#34;base_link\u0026#34;}, poses: [{position: {x: -0.25, y: -0.35, z: 0.50}, orientation: {w: 0.017994, x: -0.677772, y: 0.734752, z: 0.020993}}]}, class_ids: [], mode: 0}\u0026#39; 3.2 MoveIt2 통합 모션 계획: MoveIt2가 pick-place 파이프라인의 모션 플래닝 담당 경로 최적화: GPU 가속 라이브러리를 통한 실시간 경로 계산 충돌 회피: Isaac Sim의 물리 엔진과 연동된 충돌 검사 4. 데이터 생성 파이프라인 4.1 GR00T-Teleop (원격 조작) 목적: 실제 로봇 조작 데이터 수집 방법: 인간 조작자의 원격 제어를 통한 데모 데이터 생성 ROS2 연동: ROS2 토픽/액션을 통한 데이터 기록 4.2 GR00T-Dreamer (합성 데이터 생성) 기능: 신경망 기반 궤적 생성을 통한 합성 데이터 생성 장점: 실제 데이터 수집 비용 절감, 다양한 시나리오 생성 가능 활용: GR00T N1 학습 데이터의 주요 구성 요소 4.3 GR00T-Mimic (모방 학습) 목적: 데모 데이터로부터 정책 학습 방법: 행동 클로닝(Behavior Cloning) 및 암시적 정책 학습 출력: pick-place 태스크를 위한 신경망 정책 5. 정책 학습 및 Sim-to-Real 전이 5.1 정책 학습 파이프라인 G G R R 0 0 0 0 T T - - T M e i l m e i o c p 정 데 책 이 터 학 습 수 집 → → I s G a R a 0 c 0 T L - a D b r e R a L m e 환 r 경 합 검 성 증 데 → 이 터 실 로 확 봇 장 전 → 이 5.2 Sim-to-Real 전이 전략 도메인 랜덤화: 물리 파라미터, 조명, 텍스처 등 다양한 변수 랜덤화 실제 데이터 파인튜닝: 시뮬레이션에서 학습된 정책을 실제 데이터로 보정 하드웨어 인더더루프(HIL): 실제 로봇에서의 점진적 테스트 6. 구현 아키텍처 6.1 전체 시스템 구성 [ [ [ I G 실 s R 제 a 0 a 0 로 c T 봇 S 정 ( i ↕ 책 ↕ S m i 모 m 시 델 - 뮬 ] t 레 o 이 - 션 R ] e a ↔ l ) [ ] R O S [ 2 I s 미 a 들 a 웨 c 어 ] L a ↔ b ↕ [ R M L o v 환 e 경 I ] t 2 모 션 플 래 너 ] 6.2 핵심 컴포넌트 GR00T-Base: 기본 모델 구조 및 추론 엔진 GR00T-1.5: 개선된 조작 능력 모델 Isaac Manipulator: GPU 가속 조작 라이브러리 결론 NVIDIA GR00T 모델은 ROS2 환경에서 물체 집기·놓기 태스크를 구현하는 데 있어 강력한 파운데이션 모델로, Isaac Sim/Lab과의 통합을 통해 시뮬레이션에서 실제 로봇까지의 전이를 효과적으로 지원한다. GR00T-Teleop, Dreamer, Mimic으로 구성된 데이터 생성 파이프라인은 고품질의 학습 데이터를 효율적으로 확보할 수 있게 해주며, MoveIt2와의 연동을 통해 실시간 모션 계획이 가능하다. 특히 Isaac ROS의 액션 인터페이스를 활용하면 ROS2 표준 방식으로 pick-place 태스크를 손쉽게 실행할 수 있다. 최신 N1.7 모델로의 발전은 범용 로봇 조작 능력의 지속적인 향상을 보여주며, sim-to-real 전이 전략의 체계적 적용을 통해 실제 로봇 배포까지의 경로가 명확해졌다.\n한계 및 주의사항 정보의 편향 가능성: 본 보고서는 주로 NVIDIA 공식 문서와 GitHub 저장소를 기반으로 작성되어, NVIDIA 생태계에 유리한 정보가 과대평가될 수 있음 버전 호환성: GR00T 모델 버전(N1, N1.5, N1.7) 간의 차이와 ROS2 배포판(예: Humble, Iron) 간의 호환성에 대한 상세 정보가 부족함 실제 성능 검증 부재: 시뮬레이션 성능과 실제 로봇에서의 성능 차이에 대한 정량적 데이터가 제시되지 않음 하드웨어 요구사항: GPU 사양, 메모리 요구량 등 실제 구현에 필요한 하드웨어 최소 사양에 대한 정보가 불충분함 추가 검토 필요 사항: 실제 산업 현장 적용 사례 및 성능 벤치마크 다른 로봇 미들웨어(예: ROS1)와의 호환성 라이선스 및 상업적 사용 제약 조건 커뮤니티 기여 및 오픈소스 생태계의 성숙도 ","permalink":"https://wkqco33.github.io/wkqcosoft-docs/reports/2026-09-09-nvidia-gr00t-%EB%AA%A8%EB%8D%B8%EC%9D%84-ros2-%ED%99%98%EA%B2%BD%EC%97%90%EC%84%9C-%EB%AC%BC%EC%B2%B4-e41bbb/","summary":"\u003ch1 id=\"nvidia-gr00t-모델-기반-ros2-물체-집기놓기pick-and-place-구현-실전-가이드\"\u003eNVIDIA GR00T 모델 기반 ROS2 물체 집기·놓기(Pick and Place) 구현 실전 가이드\u003c/h1\u003e\n\u003chr\u003e\n\u003ch2 id=\"요청-개요\"\u003e요청 개요\u003c/h2\u003e\n\u003cp\u003e본 보고서는 NVIDIA GR00T 파운데이션 모델을 ROS2 환경에서 활용하여 물체 집기(pick)와 원하는 장소에 놓기(place)를 구현하는 방법을 종합적으로 분석한다. GR00T N1/N1.5 모델, Isaac Lab/Sim 시뮬레이션 환경, GR00T-Teleop/Dreamer/Mimic 데이터 생성 파이프라인, MoveIt2 기반 모션 계획, 그리고 sim-to-real 전이 전략을 아우르는 실전 구현 가이드를 제공하는 것을 목표로 한다.\u003c/p\u003e\n\u003chr\u003e\n\u003ch2 id=\"수집-소스\"\u003e수집 소스\u003c/h2\u003e\n\u003col\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cstrong\u003eNVIDIA 공식 문서 - Pick and Place Simulation (Isaac ROS)\u003c/strong\u003e\u003c/p\u003e","title":"NVIDIA GR00T 모델을 ROS2 환경에서 물체 집기(pick)와 원하는 장소에 놓기(place)를 구현하는 방법 가이드"},{"content":"VLA(Vision-Language-Action) 모델 데이터 수집 및 학습 방법 심층 조사 보고서 요청 개요 본 보고서는 허깅페이스(Hugging Face) 생태계를 중심으로 VLA(Vision-Language-Action) 모델의 데이터 수집, 학습, 파인튜닝, 평가에 이르는 전 과정을 심층 분석한다. 특히 Open X-Embodiment, RT-1/RT-2, BridgeData 등 대표적 VLA 데이터셋의 특성과 수집 방법론, 허깅페이스 데이터셋 허브 및 LeRobot 프레임워크를 활용한 로봇 학습 파이프라인, 그리고 OpenVLA와 같은 오픈소스 모델의 학습 및 평가 절차를 단계별로 정리한다.\n수집 소스 OpenVLA 공식 웹사이트: https://openvla.github.io/ OpenVLA GitHub 저장소: https://github.com/openvla/openvla VLA Training Data 가이드 (Claru.ai): https://claru.ai/vla-training-data-guide Hugging Face - Linslab/VLA-OS-Dataset: https://huggingface.co/datasets/Linslab/VLA-OS-Dataset Hugging Face - HuggingFaceVLA 조직: https://huggingface.co/HuggingFaceVLA 핵심 분석 1. VLA 모델 개요 및 아키텍처 VLA(Vision-Language-Action) 모델은 로봇 조작 작업을 위해 비전(Vision), 언어(Language), 행동(Action)을 통합한 멀티모달 AI 모델이다. 기존의 로봇 학습 방식이 단일 태스크에 특화된 정책(policy)을 학습하는 것과 달리, VLA는 대규모 사전 학습된 비전-언어 모델(VLM)을 기반으로 로봇 행동을 출력하도록 확장한 구조를 가진다.\n핵심 아키텍처 특징:\n비전 인코더: 이미지 또는 비디오 프레임을 처리하여 시각적 특징 추출 언어 모델: 자연어 지시사항을 이해하고 토큰화 행동 디코더: 연속적인 로봇 행동(관절 위치, 그리퍼 상태 등)을 이산화된 토큰으로 출력 OpenVLA의 경우, 사전 학습된 VLM(예: Prismatic)을 기반으로 행동 토큰을 추가하여 로봇 조작 정책을 학습한다.\n2. VLA 데이터셋 수집 방법 2.1 Open X-Embodiment (OpenX) 데이터셋 OpenX는 VLA 학습을 위한 가장 대표적인 대규모 데이터셋으로, 다양한 로봇 플랫폼, 태스크, 환경에서 수집된 로봇 조작 궤적(trajectory)을 포함한다.\n주요 특징:\n규모: 970,000개 이상의 로봇 조작 궤적 (OpenVLA 학습 기준) 다양성: 다양한 로봇 임보디먼트(embodiment), 태스크, 장면 포함 형식: RLDS(Relay-Learning DataSet) 형식으로 표준화 수집 방법:\n원격 조작(Teleoperation): 인간 오퍼레이터가 로봇을 직접 조작하며 시연 데이터 수집 자동화된 데이터 수집: 스크립트 기반 자동 시연 생성 크라우드소싱: 여러 연구 기관이 데이터를 기여하고 공유 2.2 RT-1/RT-2 데이터셋 Google Robotics에서 개발한 RT-1(Robotics Transformer 1)과 RT-2는 대규모 로봇 데이터와 인터넷 규모의 비전-언어 데이터를 결합한 접근법을 사용한다.\nRT-1 특징:\n130,000개 이상의 에피소드로 구성된 로봇 조작 데이터 13개의 로봇 플랫폼에서 수집 700개 이상의 태스크 정의 RT-2 특징:\nRT-1 데이터 + 웹 규모의 비전-언어 데이터 결합 Co-Fine-Tuning 기법으로 로봇 데이터와 인터넷 데이터를 혼합 학습 언어-비전-행동의 의미론적 연결 강화 2.3 BridgeData V2 BridgeData V2는 WidowX 로봇 플랫폼을 기반으로 수집된 데이터셋으로, OpenVLA의 평가 및 파인튜닝에 널리 사용된다.\n주요 특징:\n64,000개 이상의 궤적 포함 다양한 가정 환경에서 수집 단일 로봇 플랫폼에 특화되어 있어 일관성 높음 2.4 데이터 형식: RLDS vs LeRobot 구분 RLDS LeRobot 개발 주체 Google DeepMind Hugging Face 형식 TFRecord 기반 Parquet 기반 장점 대규모 데이터 처리에 최적화 Python 생태계와의 호환성 우수 사용처 Open X-Embodiment, RT-1/RT-2 Hugging Face Hub, 커뮤니티 3. 허깅페이스 데이터셋 허브 활용 허깅페이스 데이터셋 허브는 VLA 데이터셋의 공유, 버전 관리, 배포를 위한 중앙 플랫폼 역할을 한다.\n주요 기능:\n데이터셋 카탈로그: VLA-OS-Dataset 등 다양한 로봇 데이터셋 검색 및 다운로드 버전 관리: 데이터셋의 변경 이력 추적 데이터 카드: 데이터셋의 구성, 수집 방법, 라이선스 등 메타데이터 제공 통합 API: datasets 라이브러리를 통한 간편한 데이터 로딩 HuggingFaceVLA 조직: 허깅페이스는 VLA 연구를 위한 전용 조직을 운영하며, 데이터셋, 모델, 학습 코드를 통합 제공한다. 이를 통해 연구자들은 표준화된 파이프라인을 통해 VLA 모델을 개발할 수 있다.\n4. LeRobot 프레임워크를 통한 로봇 학습 파이프라인 LeRobot는 허깅페이스가 개발한 로봇 학습 프레임워크로, VLA 모델의 데이터 수집부터 학습, 평가까지 전 과정을 지원한다.\n파이프라인 구성:\n1 2 3 4 . . . . 데 - - 데 - - - 모 - - - 평 - - - 이 이 델 가 터 원 시 터 R 이 행 사 L 분 실 시 모 격 뮬 L 미 동 학 전 o 산 및 제 뮬 델 수 레 전 D 지 습 R 레 집 조 이 처 S 토 학 A 학 배 로 이 허 작 션 리 리 큰 습 습 포 봇 션 브 → 사 화 된 또 도 환 이 는 지 평 벤 배 구 경 L 징 V 원 가 치 포 e , L 전 마 제 지 R M 체 크 공 원 o 정 b 규 로 파 o 화 딩 인 t 튜 닝 형 식 변 환 5. 파인튜닝 및 학습 절차 5.1 OpenVLA 학습 절차 사전 학습 (Pre-training):\n970K 궤적의 OpenX 데이터셋 사용 64대의 A100 GPU에서 15일간 학습 사전 학습된 VLM(Prismatic)을 기반으로 행동 디코더 추가 파인튜닝 (Fine-tuning):\nLoRA 파인튜닝:\n경량화된 파인튜닝 방식으로 적은 GPU 메모리 사용 특정 로봇 플랫폼에 빠르게 적응 학습 시간: 수 시간 ~ 수 일 전체 파인튜닝 (Full Fine-tuning):\n모든 모델 파라미터 업데이트 더 높은 성능 달성 가능 많은 GPU 리소스 필요 파인튜닝 절차:\n대상 로봇의 데이터 수집 (예: BridgeData V2) 데이터를 RLDS 형식으로 변환 사전 학습된 OpenVLA 가중치 로딩 LoRA 또는 전체 파인튜닝 설정 학습 하이퍼파라미터 튜닝 평가 및 반복 5.2 데이터 혼합 전략 VLA 학습에서 데이터 혼합은 중요한 요소이다:\n다양한 임보디먼트 혼합: 일반화 성능 향상 태스크 다양성: 지시사항 이해 능력 강화 도메인 랜덤화: 시각적 강건성 확보 6. 평가 방법 6.1 실제 로봇 평가 BridgeData V2 WidowX 평가:\n실제 WidowX 로봇에서 태스크 수행 성공률(Success Rate) 측정 다양한 태스크와 장면에서 일반화 성능 평가 평가 절차:\n평가 환경 설정 (로봇, 카메라, 물체 배치) 태스크 정의 (예: \u0026ldquo;빨간 블록을 파란 컵에 넣어\u0026rdquo;) 에피소드 실행 및 성공 여부 기록 통계적 분석 (성공률, 평균 소요 시간 등) 6.2 시뮬레이션 평가 시뮬레이션 환경에서 대규모 자동 평가 가능 다양한 난이도와 환경 구성 테스트 실제 로봇 평가 전 사전 검증 용도 6.3 벤치마크 비교 기존 VLA 모델(RT-1, RT-2, Octo 등)과의 성능 비교 동일한 데이터셋과 환경에서 공정한 비교 필요 결론 VLA 모델의 성공적인 학습을 위해서는 대규모의 다양한 로봇 조작 데이터가 필수적이며, Open X-Embodiment와 같은 공개 데이터셋이 핵심 역할을 한다. 허깅페이스는 데이터셋 허브와 LeRobot 프레임워크를 통해 VLA 데이터 수집부터 학습, 평가까지의 전 과정을 표준화하고 민주화하는 데 기여하고 있다. OpenVLA는 오픈소스 VLA 모델의 대표 사례로, 970K 궤적의 데이터로 사전 학습되고 LoRA 파인튜닝을 통해 특정 로봇에 효율적으로 적응할 수 있음을 보여준다. 데이터 형식(RLDS vs LeRobot)의 표준화와 다양한 데이터 혼합 전략이 VLA 모델의 일반화 성능을 결정하는 중요한 요소로 작용한다.\n한계 및 주의사항 데이터 편향 가능성: OpenX 데이터셋은 주로 서양권 연구 기관의 데이터로 구성되어 있어, 다양한 문화권의 환경과 물체에 대한 일반화 성능이 제한될 수 있다. 평가의 일관성 부족: 실제 로봇 평가는 환경 조건, 로봇 상태 등에 따라 결과가 달라질 수 있어 표준화된 평가 프로토콜이 필요하다. 정보의 시의성: VLA 분야는 빠르게 발전하고 있어, 본 보고서의 정보(특히 2026년 자료)는 최신 연구 동향을 완전히 반영하지 못할 수 있다. 리소스 요구사항: OpenVLA 사전 학습에 필요한 64대의 A100 GPU는 일반 연구자가 접근하기 어려운 수준으로, 경량화된 학습 방법에 대한 추가 연구가 필요하다. 실제 로봇 적용의 안전성: VLA 모델의 실제 로봇 적용 시 안전성 검증이 충분히 이루어지지 않았으며, 실패 모드에 대한 추가 분석이 필요하다. ","permalink":"https://wkqco33.github.io/wkqcosoft-docs/reports/2026-08-28-%ED%97%88%EA%B9%85%ED%8E%98%EC%9D%B4%EC%8A%A4-hugging-face-%EB%A5%BC-%ED%99%9C%EC%9A%A9%ED%95%9C-vla-v-f2c553/","summary":"\u003ch1 id=\"vlavision-language-action-모델-데이터-수집-및-학습-방법-심층-조사-보고서\"\u003eVLA(Vision-Language-Action) 모델 데이터 수집 및 학습 방법 심층 조사 보고서\u003c/h1\u003e\n\u003ch2 id=\"요청-개요\"\u003e요청 개요\u003c/h2\u003e\n\u003cp\u003e본 보고서는 허깅페이스(Hugging Face) 생태계를 중심으로 VLA(Vision-Language-Action) 모델의 데이터 수집, 학습, 파인튜닝, 평가에 이르는 전 과정을 심층 분석한다. 특히 Open X-Embodiment, RT-1/RT-2, BridgeData 등 대표적 VLA 데이터셋의 특성과 수집 방법론, 허깅페이스 데이터셋 허브 및 LeRobot 프레임워크를 활용한 로봇 학습 파이프라인, 그리고 OpenVLA와 같은 오픈소스 모델의 학습 및 평가 절차를 단계별로 정리한다.\u003c/p\u003e\n\u003ch2 id=\"수집-소스\"\u003e수집 소스\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003eOpenVLA 공식 웹사이트\u003c/strong\u003e: \u003ca href=\"https://openvla.github.io/\"\u003ehttps://openvla.github.io/\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eOpenVLA GitHub 저장소\u003c/strong\u003e: \u003ca href=\"https://github.com/openvla/openvla\"\u003ehttps://github.com/openvla/openvla\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eVLA Training Data 가이드 (Claru.ai)\u003c/strong\u003e: \u003ca href=\"https://claru.ai/vla-training-data-guide\"\u003ehttps://claru.ai/vla-training-data-guide\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eHugging Face - Linslab/VLA-OS-Dataset\u003c/strong\u003e: \u003ca href=\"https://huggingface.co/datasets/Linslab/VLA-OS-Dataset\"\u003ehttps://huggingface.co/datasets/Linslab/VLA-OS-Dataset\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eHugging Face - HuggingFaceVLA 조직\u003c/strong\u003e: \u003ca href=\"https://huggingface.co/HuggingFaceVLA\"\u003ehttps://huggingface.co/HuggingFaceVLA\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003chr\u003e\n\u003ch2 id=\"핵심-분석\"\u003e핵심 분석\u003c/h2\u003e\n\u003ch3 id=\"1-vla-모델-개요-및-아키텍처\"\u003e1. VLA 모델 개요 및 아키텍처\u003c/h3\u003e\n\u003cp\u003eVLA(Vision-Language-Action) 모델은 로봇 조작 작업을 위해 비전(Vision), 언어(Language), 행동(Action)을 통합한 멀티모달 AI 모델이다. 기존의 로봇 학습 방식이 단일 태스크에 특화된 정책(policy)을 학습하는 것과 달리, VLA는 대규모 사전 학습된 비전-언어 모델(VLM)을 기반으로 로봇 행동을 출력하도록 확장한 구조를 가진다.\u003c/p\u003e","title":"허깅페이스(Hugging Face)를 활용한 VLA(Vision-Language-Action) 모델 데이터 수집 및 학습 방법 심층 조사. VLA 데이터셋(Open X-Embodiment, RT-1/RT-2, BridgeData 등) 수집 방법, 허깅페이스 데이터셋/허브 활용, LeRobot 프레임워크를 통한 로봇 학습 파이프라인, 파인튜닝 및 학습 절차, 평가 방법까지 단계별로 정리한 보고서 보고서"},{"content":"요청 개요 본 보고서는 API 키가 필요 없이 무료로 사용 가능한 공개 API를 날씨, 뉴스, 환율, 콘텐츠, 미디어, 지식 분야로 나누어 종합적으로 조사한 결과입니다. 수집된 웹 검색 결과를 바탕으로 각 분야별 대표적인 무료 공개 API의 특징과 활용 방안을 분석하고, 개발자와 기획자에게 실질적인 도움이 될 수 있는 정보를 제공하는 것을 목표로 합니다.\n수집 소스 무료로 쓰는 민간 공개 API 모음 | BASELOAD 무료로 쓸 수 있는 API 모음집 - 날씨, 번역, 이미지 생성, 뉴스 등 | notavoid 개발자를 위한 정부 공개 API 총정리 | BASELOAD 웹 개발자가 꼭 알아야 할 무료 API 모음 (2025 최신판) | eugene-kim 2025년 추천 무료 API 모음 – 개발자와 크리에이터를 위한 필수 리스트 | jwking27 핵심 분석 1. 날씨 분야: API 키 불필요한 대표 서비스 대부분의 날씨 API는 API 키를 요구하지만, 몇몇 서비스는 무료로 키 없이 사용 가능합니다. 가장 대표적인 것은 Open-Meteo로, 전 세계 날씨 데이터를 무료로 제공하며 API 키 없이 HTTP 요청만으로 사용할 수 있습니다. 또한 Wttr.in은 커맨드라인 기반으로 동작하며, curl 명령어만으로도 날씨 정보를 받을 수 있어 개발자들에게 매우 인기가 높습니다. 이들 API는 개인 프로젝트나 프로토타입 제작 시 비용 부담 없이 활용할 수 있습니다.\n2. 뉴스 및 콘텐츠 분야 뉴스 API의 경우, NewsAPI는 개발자 등록 후 무료 키를 제공하지만, 키가 필요 없는 완전 공개 API는 제한적입니다. 다만 Hacker News API는 키 없이 최신 기술 뉴스와 커뮤니티 콘텐츠를 제공하며, Reddit API도 공개 데이터 접근 시 키 없이 사용 가능한 경우가 있습니다. 콘텐츠 분야에서는 Lorem Ipsum 생성 API, Random User Generator 등이 키 없이 사용 가능한 대표적인 예로, 개발 초기 단계에서 테스트 데이터를 채우는 데 유용합니다.\n3. 환율 및 금융 분야 환율 정보를 키 없이 제공하는 API는 상대적으로 드뭅니다. exchangerate-api.com은 무료 티어를 제공하지만 키가 필요하며, Frankfurter API는 유럽 중앙은행 데이터를 기반으로 하여 키 없이 최신 환율을 제공하는 점이 특징입니다. 국내에서는 한국은행의 ECOS(경제통계시스템) API가 공공데이터 포털을 통해 무료로 제공되지만, 신청 후 인증 키가 필요합니다. 따라서 완전한 키 없는 환율 API는 Frankfurter가 사실상 유일한 대안입니다.\n4. 미디어 및 이미지 분야 Unsplash API는 고품질 무료 이미지를 제공하지만 API 키가 필요합니다. 키 없이 사용 가능한 미디어 API로는 Picsum Photos (Lorem Picsum)가 있으며, 랜덤 이미지 URL만으로도 다양한 이미지를 로드할 수 있습니다. 또한 RoboHash는 텍스트 기반으로 로봇 이미지를 생성해주며, DiceBear 아바타 API도 키 없이 사용 가능하여 프로필 이미지 생성에 유용합니다. 비디오 분야에서는 Pexels나 Pixabay가 무료 티어를 제공하지만 키가 필요하다는 점을 유의해야 합니다.\n5. 지식 및 데이터 분야 키 없이 사용 가능한 지식 API로는 Wikipedia API가 가장 대표적입니다. 위키백과의 모든 콘텐츠를 RESTful API로 접근할 수 있으며, 요약, 검색, 카테고리 조회 등이 가능합니다. 또한 Open Library API는 도서 정보를 키 없이 조회할 수 있고, 국립중앙도서관 API도 공공데이터 포털을 통해 무료로 제공됩니다. 정부 분야에서는 공공데이터포털을 통해 기상청, 법령정보, 교통정보 등 다양한 공공 데이터를 키 발급 후 무료로 사용할 수 있습니다.\n6. 기타 유용한 키 없는 API 검색 결과를 종합하면, 개발자에게 유용한 키 없는 API는 다음과 같이 분류됩니다:\n지리/지도: OpenStreetMap (Overpass API), 위치정보 제공 기술/개발: GitHub API (공개 저장소 정보), JSONPlaceholder (테스트용 가짜 데이터) 번역/언어: MyMemory 번역 API (일일 한도 있음), LibreTranslate (오픈소스) AI/챗봇: 일부 오픈소스 모델을 활용한 무료 API가 있지만, 대부분 키가 필요함 이들 API는 대부분 공식 문서와 커뮤니티 자료가 잘 갖추어져 있어, 초보 개발자도 쉽게 접근할 수 있다는 장점이 있습니다.\n결론 무료로 사용 가능하고 API 키가 필요 없는 공개 API는 날씨, 콘텐츠, 이미지, 지식 분야에서 비교적 다양하게 존재합니다. 특히 Open-Meteo, Wttr.in, Frankfurter, Picsum Photos, Wikipedia API는 키 없이도 높은 품질의 데이터를 제공하여 개인 프로젝트와 프로토타입 제작에 매우 유용합니다. 반면, 뉴스, 환율, 미디어 분야는 대부분 무료 티어에서도 키 발급을 요구하므로, 키 없는 API를 선택할 때는 서비스의 목적과 데이터 요구량을 신중히 고려해야 합니다. 정부 공공데이터는 무료이지만 신청 및 승인 절차가 필요하다는 점을 인지하고, API 사용 시 요청 한도와 라이선스를 반드시 확인하는 것이 중요합니다.\n한계 및 주의사항 본 보고서는 수집된 웹 블로그와 가이드 자료를 바탕으로 작성되었으며, 실제 API의 무료 티어 정책은 시기와 서비스 제공자의 정책 변경에 따라 달라질 수 있습니다. 특히 키가 필요 없는 API도 일일 요청 수 제한, 상업적 사용 금지, 데이터 업데이트 주기 등 조건이 다를 수 있으므로, 실제 사용 전에 공식 문서를 반드시 확인해야 합니다. 또한 일부 API는 무료로 시작하지만 일정 사용량 초과 시 유료로 전환될 수 있어, 장기적인 프로젝트에서는 비용 발생 가능성을 염두에 두어야 합니다. 마지막으로, 본 조사는 한국어 웹 자료를 중심으로 이루어져 있어, 영어권에서 인기 있는 API가 일부 누락될 수 있습니다.\n","permalink":"https://wkqco33.github.io/wkqcosoft-docs/reports/2026-08-25-%EB%AC%B4%EB%A3%8C%EB%A1%9C-%EC%82%AC%EC%9A%A9-%EA%B0%80%EB%8A%A5%ED%95%98%EA%B3%A0-api-%ED%82%A4%EA%B0%80-%ED%95%84%EC%9A%94-%EC%97%86%EB%8A%94-%EA%B3%B5%EA%B0%9C-ap-943637/","summary":"\u003ch2 id=\"요청-개요\"\u003e요청 개요\u003c/h2\u003e\n\u003cp\u003e본 보고서는 API 키가 필요 없이 무료로 사용 가능한 공개 API를 날씨, 뉴스, 환율, 콘텐츠, 미디어, 지식 분야로 나누어 종합적으로 조사한 결과입니다. 수집된 웹 검색 결과를 바탕으로 각 분야별 대표적인 무료 공개 API의 특징과 활용 방안을 분석하고, 개발자와 기획자에게 실질적인 도움이 될 수 있는 정보를 제공하는 것을 목표로 합니다.\u003c/p\u003e\n\u003ch2 id=\"수집-소스\"\u003e수집 소스\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"https://www.baseload.co.kr/blog/2026-06-27-free-developer-apis-guide/\"\u003e무료로 쓰는 민간 공개 API 모음 | BASELOAD\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://notavoid.tistory.com/103\"\u003e무료로 쓸 수 있는 API 모음집 - 날씨, 번역, 이미지 생성, 뉴스 등 | notavoid\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://www.baseload.co.kr/blog/2026-06-27-korea-public-data-api-guide/\"\u003e개발자를 위한 정부 공개 API 총정리 | BASELOAD\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://eugene-kim.tistory.com/114\"\u003e웹 개발자가 꼭 알아야 할 무료 API 모음 (2025 최신판) | eugene-kim\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://jwking27.tistory.com/33\"\u003e2025년 추천 무료 API 모음 – 개발자와 크리에이터를 위한 필수 리스트 | jwking27\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"핵심-분석\"\u003e핵심 분석\u003c/h2\u003e\n\u003ch3 id=\"1-날씨-분야-api-키-불필요한-대표-서비스\"\u003e1. 날씨 분야: API 키 불필요한 대표 서비스\u003c/h3\u003e\n\u003cp\u003e대부분의 날씨 API는 API 키를 요구하지만, 몇몇 서비스는 무료로 키 없이 사용 가능합니다. 가장 대표적인 것은 \u003cstrong\u003eOpen-Meteo\u003c/strong\u003e로, 전 세계 날씨 데이터를 무료로 제공하며 API 키 없이 HTTP 요청만으로 사용할 수 있습니다. 또한 \u003cstrong\u003eWttr.in\u003c/strong\u003e은 커맨드라인 기반으로 동작하며, curl 명령어만으로도 날씨 정보를 받을 수 있어 개발자들에게 매우 인기가 높습니다. 이들 API는 개인 프로젝트나 프로토타입 제작 시 비용 부담 없이 활용할 수 있습니다.\u003c/p\u003e","title":"무료로 사용 가능하고 API 키가 필요 없는 공개 API 종합 조사 (날씨, 뉴스, 환율, 콘텐츠, 미디어, 지식 분야별 정리) 보고서"},{"content":"요청 개요 본 보고서는 PC나 기기의 외부 IP 주소를 확인하는 다양한 방법을 연구하고, 웹 브라우저 기반 방법과 터미널(bash 등) 기반 방법을 구분하여 정리하는 것을 목적으로 합니다. curl, dig, nslookup, ipconfig, ifconfig 등의 명령어와 whatismyip, ipify, ifconfig.me 등의 외부 IP 확인 웹사이트 및 API 서비스를 포함한 실용적인 가이드를 제공하고자 합니다.\n수집 소스 제공된 검색 결과에서는 외부 IP 주소 확인 방법과 직접적으로 관련된 유용한 정보를 찾을 수 없었습니다. 검색 결과는 주로 Claude Code CLI 가이드, AI 노코드 연결, GitHub 콘텐츠, Reddit 프로젝트 홍보 등 외부 IP 확인과 무관한 주제를 다루고 있습니다. 따라서 본 보고서는 일반적으로 알려진 표준적인 방법론을 바탕으로 작성되었으며, 구체적인 출처 URL은 다음과 같습니다:\nhttps://blakecrosley.com/ko/guides/claude-code (관련 없음) https://www.gpters.org/nocode (관련 없음) https://github.com/Beomi/beomi.github.io/blob/master/content.json (관련 없음) https://mirrors.aliyun.com/trisquel/dists/dagda/main/i18n/Translation-ko (관련 없음) https://www.reddit.com/r/github/comments/1jy8rea/promote_your_projects_here_selfpromotion/?tl=ko (관련 없음) 핵심 분석 1. 웹 브라우저를 사용하는 방법 웹 브라우저를 통한 외부 IP 확인은 가장 간단하고 직관적인 방법으로, 별도의 기술적 지식이 필요 없습니다.\n주요 외부 IP 확인 웹사이트:\nwhatismyip.com: 가장 대표적인 서비스로, IPv4와 IPv6 주소를 모두 표시하며 위치 정보, ISP 정보도 함께 제공합니다. ifconfig.me: 간결한 인터페이스로 IP 주소만 빠르게 확인할 수 있습니다. ipify.org: API 기반 서비스로, 웹 브라우저에서 접속하면 JSON 형식으로 IP 주소를 반환합니다. icanhazip.com: 접속 즉시 IP 주소만 텍스트로 표시하는 초경량 서비스입니다. ipinfo.io: IP 주소와 함께 상세한 지리적 정보, ASN 정보를 제공합니다. 사용 방법:\n웹 브라우저를 열고 위 사이트 중 하나에 접속합니다. 페이지에 표시된 IP 주소를 확인합니다. 일부 사이트는 IPv4와 IPv6를 구분하여 표시하므로, 필요에 따라 해당 주소를 복사하여 사용합니다. 장점:\n별도의 소프트웨어 설치나 명령어 학습이 필요 없음 GUI 환경에서 직관적으로 확인 가능 추가 정보(위치, ISP 등)를 함께 제공 단점:\n브라우저가 필요하므로 CLI 환경에서는 사용 불가 자동화나 스크립트 연동이 어려움 2. 터미널(bash 등)을 사용하는 방법 터미널 환경에서 외부 IP를 확인하는 방법은 서버 관리, 자동화 스크립트, 네트워크 진단 등에 유용합니다.\n2.1 curl 명령어 활용\ncurl은 가장 널리 사용되는 방법으로, 외부 IP 확인 API에 HTTP 요청을 보내 IP 주소를 받아옵니다.\n# ifconfig.me 사용 curl ifconfig.me # ipify.org 사용 (JSON 형식) curl https://api.ipify.org # icanhazip.com 사용 curl icanhazip.com # IPv4만 확인 curl -4 icanhazip.com # IPv6만 확인 curl -6 icanhazip.com # ipinfo.io 사용 (상세 정보) curl ipinfo.io 2.2 dig 명령어 활용\ndig는 DNS 조회 도구로, 외부 DNS 서버에 질의하여 공인 IP를 확인할 수 있습니다. 주로 도메인의 IP를 확인할 때 사용하지만, 외부 IP 확인에도 활용할 수 있습니다.\n# OpenDNS 서버에 질의하여 외부 IP 확인 dig +short myip.opendns.com @resolver1.opendns.com # Google DNS 서버 사용 dig +short TXT o-o.myaddr.l.google.com @ns1.google.com 2.3 nslookup 명령어 활용\nnslookup도 DNS 조회 도구로, dig와 유사한 방식으로 외부 IP를 확인할 수 있습니다.\n# OpenDNS 서버 사용 nslookup myip.opendns.com resolver1.opendns.com # Google DNS 서버 사용 nslookup -type=TXT o-o.myaddr.l.google.com ns1.google.com 2.4 ipconfig / ifconfig 명령어 활용\n이 명령어들은 주로 내부 IP 주소를 확인하는 데 사용되지만, 외부 IP 확인을 위한 기초 정보를 제공합니다.\nWindows (ipconfig):\n# 모든 네트워크 어댑터 정보 확인 ipconfig /all # IPv4 주소만 간단히 확인 ipconfig | findstr /i \u0026#34;IPv4\u0026#34; Linux/macOS (ifconfig):\n# 모든 네트워크 인터페이스 정보 확인 ifconfig # 특정 인터페이스(예: eth0)의 IP 확인 ifconfig eth0 # 최신 Linux 배포판에서는 ip 명령어 사용 권장 ip addr show 참고사항: ipconfig와 ifconfig는 내부(사설) IP 주소를 확인하는 명령어입니다. 외부 IP를 확인하려면 반드시 위에서 소개한 curl, dig, nslookup 방법을 사용해야 합니다.\n2.5 기타 유용한 명령어 조합\n# wget 사용 (curl 대체) wget -qO- ifconfig.me # Python 사용 python3 -c \u0026#34;import requests; print(requests.get(\u0026#39;https://api.ipify.org\u0026#39;).text)\u0026#34; # 여러 서비스에 동시에 질의하여 IP 일치 여부 확인 curl ifconfig.me \u0026amp;\u0026amp; echo \u0026#34;\u0026#34; \u0026amp;\u0026amp; curl icanhazip.com 3. API 서비스 활용 외부 IP 확인 API는 자동화 스크립트나 애플리케이션에서 프로그램적으로 IP를 확인할 때 유용합니다.\n주요 API 서비스:\n서비스 엔드포인트 응답 형식 특징 ipify https://api.ipify.org 텍스트/JSON 무료, 간단, CORS 지원 ifconfig.me https://ifconfig.me/ip 텍스트 다양한 포맷 지원 icanhazip https://icanhazip.com 텍스트 초경량, 빠른 응답 ipinfo.io https://ipinfo.io/ip 텍스트/JSON 상세 정보 제공 api.ip.sb https://api.ip.sb/ip 텍스트/JSON 무료, HTTPS 지원 JSON 형식으로 받기:\n# ipify에서 JSON 형식으로 받기 curl https://api.ipify.org?format=json # ipinfo.io에서 JSON 형식으로 받기 curl https://ipinfo.io/json 4. 방법별 비교 및 권장사항 방법 난이도 자동화 가능 추가 정보 권장 상황 웹 브라우저 매우 낮음 불가 위치, ISP 일반 사용자, 1회성 확인 curl 낮음 가능 제한적 스크립트, 서버 관리 dig/nslookup 중간 가능 DNS 정보 네트워크 진단, DNS 문제 해결 ipconfig/ifconfig 낮음 가능 내부 IP 정보 내부 네트워크 확인 결론 외부 IP 주소 확인은 웹 브라우저를 통한 간단한 방법부터 터미널 명령어를 활용한 고급 방법까지 다양한 경로로 가능합니다. 일반 사용자에게는 whatismyip.com 같은 웹사이트가 가장 접근성이 좋으며, 개발자나 시스템 관리자에게는 curl과 API 서비스를 조합한 방법이 자동화 측면에서 효율적입니다. dig와 nslookup은 DNS 기반으로 IP를 확인하는 대안적인 방법을 제공하며, ipconfig와 ifconfig는 내부 IP 확인에만 사용된다는 점을 유의해야 합니다. 상황에 따라 적절한 방법을 선택하는 것이 중요하며, 여러 서비스를 병행하여 IP 주소의 정확성을 검증하는 것도 좋은 방법입니다.\n한계 및 주의사항 검색 결과의 한계: 제공된 검색 결과는 외부 IP 확인 방법과 직접적인 관련이 없는 내용으로 구성되어 있어, 본 보고서는 일반적인 표준 지식에 기반하여 작성되었습니다. 따라서 특정 서비스의 최신 변경사항이나 새로운 도구가 반영되지 않았을 수 있습니다. IP 주소의 변동성: 대부분의 가정용 인터넷 연결은 동적 IP를 사용하므로, 확인한 IP 주소는 시간이 지나면 변경될 수 있습니다. 프록시/VPN 영향: 프록시 서버나 VPN을 사용 중인 경우, 확인된 IP 주소는 실제 기기의 IP가 아닐 수 있습니다. IPv4 vs IPv6: 일부 네트워크에서는 IPv4와 IPv6가 별도로 할당되므로, 확인 목적에 따라 적절한 버전을 선택해야 합니다. 보안 주의사항: 외부 IP 확인 API를 사용할 때는 신뢰할 수 있는 서비스를 이용하고, 민감한 정보를 포함한 요청을 보내지 않도록 주의해야 합니다. 명령어 호환성: ipconfig는 Windows 전용, ifconfig는 Linux/macOS 전용이므로, 사용 중인 운영체제에 맞는 명령어를 선택해야 합니다. 최신 Linux 배포판에서는 ifconfig 대신 ip 명령어 사용이 권장됩니다. ","permalink":"https://wkqco33.github.io/wkqcosoft-docs/reports/2026-08-21-pc%EB%82%98-%EA%B8%B0%EA%B8%B0%EC%9D%98-%EC%99%B8%EB%B6%80-ip-%EC%A3%BC%EC%86%8C%EB%A5%BC-%ED%99%95%EC%9D%B8%ED%95%98%EB%8A%94-%EB%B0%A9%EB%B2%95-%EC%97%B0%EA%B5%AC-%EC%9B%B9-a45920/","summary":"\u003ch2 id=\"요청-개요\"\u003e요청 개요\u003c/h2\u003e\n\u003cp\u003e본 보고서는 PC나 기기의 외부 IP 주소를 확인하는 다양한 방법을 연구하고, 웹 브라우저 기반 방법과 터미널(bash 등) 기반 방법을 구분하여 정리하는 것을 목적으로 합니다. curl, dig, nslookup, ipconfig, ifconfig 등의 명령어와 whatismyip, ipify, ifconfig.me 등의 외부 IP 확인 웹사이트 및 API 서비스를 포함한 실용적인 가이드를 제공하고자 합니다.\u003c/p\u003e\n\u003ch2 id=\"수집-소스\"\u003e수집 소스\u003c/h2\u003e\n\u003cp\u003e제공된 검색 결과에서는 외부 IP 주소 확인 방법과 직접적으로 관련된 유용한 정보를 찾을 수 없었습니다. 검색 결과는 주로 Claude Code CLI 가이드, AI 노코드 연결, GitHub 콘텐츠, Reddit 프로젝트 홍보 등 외부 IP 확인과 무관한 주제를 다루고 있습니다. 따라서 본 보고서는 일반적으로 알려진 표준적인 방법론을 바탕으로 작성되었으며, 구체적인 출처 URL은 다음과 같습니다:\u003c/p\u003e","title":"PC나 기기의 외부 IP 주소를 확인하는 방법 연구. 웹 브라우저를 사용하는 방법과 bash 등 터미널을 사용하는 방법을 각각 구분해서 정리. curl, dig, nslookup, ipconfig, ifconfig 등 명령어와 외부 IP 확인 웹사이트(whatismyip 등) 및 API 서비스(ipify, ifconfig.me 등)를 포함한 실용 가이드. 보고서"},{"content":"요청 개요 본 보고서는 리눅스 bash 환경에서 빈번하게 사용되는 핵심 커맨드(ls, cd, cp, mv, rm, cat, grep, find, chmod, ps, top, kill, curl, wget, tail, head, sed, awk, tar, zip, history, alias, env 등)의 윈도우 PowerShell 대응 버전을 정리한 자료입니다. 사용자는 마크다운 형식의 전문 보고서 작성을 요청하였으며, 이에 따라 수집된 웹 검색 결과를 바탕으로 각 커맨드의 기능적 차이와 PowerShell에서의 동등한 구현 방법을 분석합니다. 본 보고서는 리눅스 사용자가 윈도우 환경으로 전환하거나 두 환경을 병행 사용할 때 겪는 명령어 혼란을 해소하는 것을 목표로 합니다.\n수집 소스 본 보고서 작성을 위해 수집된 웹 검색 결과는 다음과 같습니다.\nGrep mit der PowerShell (https://www.powershell-user.de/grep-mit-der-powershell/): PowerShell에서 grep 명령어를 대체하는 방법에 대한 독일어 블로그 포스팅. curl - Download (https://curl.se/download.html): curl 공식 다운로드 페이지로, 다양한 운영체제(리눅스, 윈도우, macOS 등)에서의 패키지 제공 현황 확인 가능. 리눅스 기초 : 네이버 블로그 (https://m.blog.naver.com/utimegps/70018673744): 리눅스 bash 환경변수 및 기본 명령어에 대한 한국어 블로그 포스팅. Heads or Tails Online (https://headsortails.us.com/): 온라인 동전 던지기 도구로, 본 보고서의 주제와 무관한 결과로 판단됨. 상상플러스 :: 리눅스 bash에서의 환경변수와 특징 (http://comefeel.com/tt/comefeel/77): 리눅스 bash 환경변수(export, PS1, PS2 등)에 대한 한국어 블로그 포스팅. 핵심 분석 1. 기본 파일 및 디렉토리 관리 커맨드 (ls, cd, cp, mv, rm, cat) 리눅스의 ls, cd, cp, mv, rm, cat은 파일 시스템을 탐색하고 조작하는 가장 기본적인 명령어입니다. PowerShell에서는 이에 대응하는 명령어가 명확히 존재하며, 일부는 별칭(Alias)으로 제공됩니다.\nls → Get-ChildItem (별칭: ls, dir): PowerShell의 Get-ChildItem은 리눅스 ls와 유사하게 디렉토리 내용을 나열합니다. 다만, 출력 형식이 테이블 형태로 다르며, -Force 플래그를 사용해야 숨김 파일까지 표시됩니다. cd → Set-Location (별칭: cd, chdir): Set-Location은 현재 작업 디렉토리를 변경하는 명령어로, 리눅스 cd와 사용법이 동일합니다. cp → Copy-Item (별칭: cp, copy): Copy-Item은 파일이나 디렉토리를 복사합니다. 리눅스 cp와 달리 기본적으로 디렉토리 복사 시 -Recurse 옵션을 명시해야 합니다. mv → Move-Item (별칭: mv, move): Move-Item은 파일이나 디렉토리를 이동하거나 이름을 변경합니다. rm → Remove-Item (별칭: rm, del, erase): Remove-Item은 파일이나 디렉토리를 삭제합니다. 리눅스와 달리 기본적으로 확인 프롬프트가 없으므로 주의가 필요하며, 디렉토리 삭제 시 -Recurse 옵션이 필요합니다. cat → Get-Content (별칭: cat, type): Get-Content는 파일의 내용을 읽어 출력합니다. 리눅스 cat과 달리 파일 전체를 한 번에 읽는 대신 스트리밍 방식으로 처리하며, -Tail 옵션을 통해 tail 명령어처럼 사용할 수 있습니다. 2. 텍스트 처리 및 검색 커맨드 (grep, find, sed, awk, tail, head) 텍스트 검색과 스트림 편집은 리눅스 셸의 강력한 기능 중 하나입니다. PowerShell은 이러한 기능을 객체 지향적인 방식으로 제공합니다.\ngrep → Select-String (별칭: grep): Select-String은 텍스트 파일이나 문자열에서 패턴을 검색합니다. 리눅스 grep과 유사하지만, 출력 결과가 매칭된 문자열뿐만 아니라 파일명, 행 번호 등이 포함된 객체로 반환됩니다. find → Get-ChildItem -Recurse + Where-Object: 리눅스 find는 파일 시스템을 재귀적으로 탐색하여 조건에 맞는 파일을 찾습니다. PowerShell에서는 Get-ChildItem -Recurse로 파일을 나열한 후 Where-Object로 필터링하는 방식으로 구현합니다. 예: Get-ChildItem -Recurse -Filter \u0026quot;*.txt\u0026quot; | Where-Object { $_.Length -gt 1MB } tail → Get-Content -Tail: 리눅스 tail -f는 파일의 마지막 부분을 실시간으로 추적합니다. PowerShell에서는 Get-Content -Tail 10 -Wait로 동일한 기능을 구현할 수 있습니다. head → Get-Content -TotalCount: 리눅스 head는 파일의 처음 N줄을 출력합니다. PowerShell에서는 Get-Content -TotalCount 10으로 대응합니다. sed → Get-Content + ForEach-Object / -replace 연산자: 리눅스 sed는 스트림 편집기로, 텍스트 치환, 삭제, 삽입 등을 수행합니다. PowerShell에서는 Get-Content로 읽어온 각 줄에 대해 -replace 연산자나 ForEach-Object를 사용하여 처리합니다. 예: Get-Content file.txt | ForEach-Object { $_ -replace \u0026quot;old\u0026quot;, \u0026quot;new\u0026quot; } awk → Import-Csv / ForEach-Object: 리눅스 awk는 텍스트를 필드 단위로 분리하여 처리합니다. PowerShell에서는 Import-Csv로 구조화된 데이터를 처리하거나, ForEach-Object 내에서 -split 연산자를 사용하여 필드를 분리합니다. 3. 프로세스 및 시스템 관리 커맨드 (ps, top, kill, chmod) ps → Get-Process (별칭: ps): Get-Process는 실행 중인 프로세스 목록을 반환합니다. 리눅스 ps aux와 유사한 상세 정보를 보려면 Get-Process | Format-List *를 사용합니다. top → Get-Process | Sort-Object CPU: 리눅스 top은 실시간으로 CPU/메모리 사용량을 모니터링합니다. PowerShell에는 실시간 모니터링 도구가 기본 내장되어 있지 않아, Get-Process를 주기적으로 호출하거나 Get-Counter 성능 카운터를 사용하는 방식으로 대체합니다. kill → Stop-Process (별칭: kill): Stop-Process는 프로세스를 종료합니다. 리눅스 kill -9와 같은 강제 종료는 -Force 플래그로 구현합니다. chmod → Set-Acl / icacls: 리눅스 chmod는 파일 권한을 변경합니다. PowerShell에서는 Set-Acl cmdlet을 사용하거나, 윈도우의 icacls 명령어를 그대로 사용할 수 있습니다. 다만, 권한 모델(읽기/쓰기/실행 vs. 읽기/쓰기/수정)이 다르므로 완전한 1:1 대응은 어렵습니다. 4. 네트워크 및 다운로드 커맨드 (curl, wget) curl → curl.exe (PowerShell 5.0 이상): Windows 10 1803 이상부터는 curl.exe가 기본 제공되며, 리눅스 curl과 거의 동일한 옵션을 지원합니다. 다만, PowerShell에서 curl을 입력하면 Invoke-WebRequest의 별칭으로 인식될 수 있으므로, 실제 curl.exe를 사용하려면 curl.exe로 명시해야 합니다. wget → Invoke-WebRequest / wget.exe: PowerShell 3.0 이상에서 Invoke-WebRequest가 wget의 별칭으로 등록되어 있습니다. 하지만 리눅스 wget의 다운로드 전용 기능과 달리 Invoke-WebRequest는 웹 요청 전반을 처리하므로, 단순 다운로드에는 wget.exe(Windows 10 1709 이상 기본 제공)를 사용하는 것이 더 적합합니다. 5. 압축 및 아카이브 커맨드 (tar, zip) tar → tar.exe: Windows 10 1803 이상부터 tar.exe가 기본 제공되어 리눅스 tar 명령어와 동일하게 사용할 수 있습니다. zip → Compress-Archive / Expand-Archive: PowerShell 5.0 이상에서 Compress-Archive는 zip 파일을 생성하고, Expand-Archive는 압축을 해제합니다. 리눅스 zip/unzip과 기능적으로 대응하지만, 옵션의 세부 사항은 다릅니다. 6. 셸 환경 및 히스토리 커맨드 (history, alias, env) history → Get-History (별칭: h): Get-History는 현재 PowerShell 세션에서 실행한 명령어 목록을 반환합니다. 리눅스 history와 달리 세션이 종료되면 기본적으로 사라지며, PSReadLine 모듈을 통해 지속적인 히스토리 저장이 가능합니다. alias → Set-Alias / Get-Alias: Set-Alias는 별칭을 생성하고, Get-Alias는 기존 별칭을 확인합니다. 리눅스 alias와 유사하지만, PowerShell 별칭은 cmdlet 이름에 대한 단축어로, 함수나 스크립트 블록을 별칭으로 지정할 수 없다는 차이가 있습니다. env → Get-ChildItem Env: / $env:변수명: PowerShell은 환경변수를 Env: 드라이브로 노출합니다. Get-ChildItem Env:로 전체 목록을 확인하고, $env:Path와 같은 형식으로 개별 변수에 접근합니다. 리눅스 env 명령어와 달리 $env: 접두사를 사용하는 점이 특징입니다. 결론 리눅스 bash와 윈도우 PowerShell은 명령어 체계가 근본적으로 다르지만, 대부분의 핵심 커맨드에 대해 기능적으로 대응하는 cmdlet 또는 별칭이 존재합니다. 기본 파일 관리(ls, cd, cp, mv, rm, cat)는 PowerShell의 별칭을 통해 거의 동일한 사용자 경험을 제공하며, 텍스트 처리(grep, sed, awk)는 객체 지향적인 파이프라인 방식으로 대체되어 오히려 더 강력한 데이터 조작이 가능합니다. 프로세스 관리(ps, top, kill)와 네트워크 도구(curl, wget)는 Windows 10 이상에서 기본 제공되는 exe 파일 또는 PowerShell cmdlet으로 대응할 수 있습니다. 다만, chmod와 같은 권한 시스템은 윈도우의 ACL 모델과 근본적으로 달라 완전한 호환은 불가능하며, top과 같은 실시간 모니터링 도구는 별도의 구성이 필요합니다. 결론적으로, 리눅스 사용자는 PowerShell의 별칭 시스템과 파이프라인 개념을 이해하면 대부분의 작업을 효율적으로 전환할 수 있습니다.\n한계 및 주의사항 본 보고서는 제한된 웹 검색 결과(5건)를 기반으로 작성되었으며, 그중 2건(동전 던지기 사이트, 리눅스 환경변수 블로그)은 보고서 주제와 직접적인 관련이 없어 분석에 부분적으로만 활용되었습니다. PowerShell은 버전(5.1, 7.x, 7.4 등)에 따라 기본 제공되는 cmdlet과 별칭이 다를 수 있으며, Windows 10/11의 빌드 버전에 따라 curl.exe, tar.exe 등의 기본 제공 여부가 달라질 수 있습니다. 또한, 리눅스 명령어의 고급 옵션(예: sed -i의 in-place 편집, awk의 다중 패턴 처리)은 PowerShell에서 동일하게 구현하기 어려운 경우가 많아, 단순 1:1 매핑보다는 기능적 목적에 맞는 대체 방식을 고민해야 합니다. 마지막으로, 본 보고서는 공식 마이크로소프트 문서나 전문 서적을 참조하지 않았으므로, 실제 환경에서 사용 시 각 cmdlet의 공식 도움말(Get-Help)을 확인할 것을 권장합니다.\n","permalink":"https://wkqco33.github.io/wkqcosoft-docs/reports/2026-08-15-%EB%A6%AC%EB%88%85%EC%8A%A4-bash%EC%97%90%EC%84%9C-%EB%A7%8E%EC%9D%B4-%EC%82%AC%EC%9A%A9%EB%90%98%EB%8A%94-%EC%BB%A4%EB%A7%A8%EB%93%9C%EB%93%A4%EC%9D%98-%EC%9C%88%EB%8F%84%EC%9A%B0-p-c6e569/","summary":"\u003ch2 id=\"요청-개요\"\u003e요청 개요\u003c/h2\u003e\n\u003cp\u003e본 보고서는 리눅스 bash 환경에서 빈번하게 사용되는 핵심 커맨드(ls, cd, cp, mv, rm, cat, grep, find, chmod, ps, top, kill, curl, wget, tail, head, sed, awk, tar, zip, history, alias, env 등)의 윈도우 PowerShell 대응 버전을 정리한 자료입니다. 사용자는 마크다운 형식의 전문 보고서 작성을 요청하였으며, 이에 따라 수집된 웹 검색 결과를 바탕으로 각 커맨드의 기능적 차이와 PowerShell에서의 동등한 구현 방법을 분석합니다. 본 보고서는 리눅스 사용자가 윈도우 환경으로 전환하거나 두 환경을 병행 사용할 때 겪는 명령어 혼란을 해소하는 것을 목표로 합니다.\u003c/p\u003e","title":"리눅스 bash에서 많이 사용되는 커맨드들의 윈도우 PowerShell 대응 버전 정리 (ls, cd, cp, mv, rm, cat, grep, find, chmod, ps, top, kill, curl, wget,"},{"content":" 📌 Executive Summary\n초고속 LLM/SLM 서빙 엔진: vLLM은 PagedAttention 알고리즘을 도입하여 KV 캐시의 메모리 낭비를 가상 메모리 페이징 기법으로 96% 이상 줄이고, 기존 Hugging Face 대비 최대 24배 이상의 동시 처리량(Throughput)을 제공합니다. 로컬 SLM(소형 언어 모델)과의 최적 궁합: Qwen2.5-7B, Llama-3.2, Gemma-3 등 1B7B 급 SLM을 vLLM으로 구동하면 단일 GPU(VRAM 816GB) 환경에서도 극도로 낮은 지연 시간(Low Latency)과 실시간 스트리밍 처리가 가능합니다. OpenAI 표준 API 기본 내장: 추가 코드 없이 서버 구동 즉시 /v1/chat/completions 엔드포인트를 제공하여 기존 상용 LLM 클라이언트 코드를 그대로 재사용할 수 있습니다. 📊 리포트 개요 및 프레임워크 비교 항목 세부 내용 보고서 주제 vLLM 기반 로컬 소형 언어 모델(SLM) 고성능 추론 및 서빙 최적화 가이드 핵심 기술 PagedAttention, Continuous Batching, AWQ/GPTQ 양자화, OpenAI API Server 사전 요구사항 NVIDIA GPU (최소 8GB+ VRAM 권장), Python 3.8+ / CUDA 12.x 또는 Docker 추천 대상 모델 Qwen2.5-7B-Instruct, Llama-3.2-3B, Gemma-2-9B 등 🥊 vLLM vs Ollama 핵심 비교 분석 비교 항목 vLLM (프로덕션/서빙 특화) Ollama (로컬 개발/개인 챗봇 특화) 주요 목적 고처리량 프로덕션 서빙, 멀티 유저 API 백엔드 초간편 로컬 테스트, 개인용 CLI 대화 추론 백엔드 엔진 PagedAttention + CUDA 커스텀 커널 llama.cpp (GGUF 기반 CPU/GPU 하이브리드) 동시 다중 요청 처리 연속 배치(Continuous Batching) 로 동시 요청 극대화 제한적 동시성 (단일 요청 순차 처리에 최적화) 모델 형식 지원 Hugging Face SafeTensors, AWQ, GPTQ, FP8 GGUF 단일 바이너리 파일 API 호환성 OpenAI REST API 네이티브 100% 호환 독자 API + OpenAI 에뮬레이션 레이어 설치 및 운영 난이도 Python 가상환경 / CUDA / Docker 필요 (중급) 원클릭 인스톨러 / CLI 기반 (초급) 권장 사용처 사내 서비스 API 백엔드, RAG 에이전트 다중 접속 로컬 PC 개인 테스트, 데스크톱 UI 연동 🔍 핵심 분석 1. vLLM 아키텍처 및 SLM 서빙의 이점 대규모 언어 모델 서빙에서 가장 큰 병목은 생성 토큰마다 누적되는 KV(Key-Value) 캐시 메모리 낭비와 **요청 대기 지연(Latency)**입니다.\n[ 요 요 [ K K 청 청 V V 기 v 존 1 2 L 캐 캐 : : L 시 시 서 M 빙 [ [ 블 블 P 록 록 방 메 메 a 식 모 모 g 1 2 리 리 e ] d ─ ─ 사 사 A ─ ─ 전 전 t \u0026gt; \u0026gt; t 할 할 e [ [ 당 당 n t 물 물 ( ( i 리 리 미 미 o 사 사 n 메 메 용 용 모 모 ] 리 리 낭 낭 비 비 페 페 이 이 공 공 지 지 간 간 1 4 발 발 생 생 ] ] ) ) ( ] ] O S ─ ─ 가 ─ 상 ─ ─ 메 ─ 모 ─ 리 ─ ─ 기 ─ 법 \u0026gt; 적 ( 용 단 : 편 화 메 모 심 리 함 ) 낭 비 4 % 미 만 ) PagedAttention: OS의 가상 메모리 페이징 기법을 응용하여 비연속적인 메모리 공간에 KV 캐시를 유연하게 할당함으로써 메모리 단편화를 제거합니다. 연속 배치 (Continuous Batching): 먼저 끝난 요청의 자리를 기다리지 않고 새로운 요청을 즉시 배치(Batch)에 합류시켜 GPU 유휴 시간을 제거합니다. 2. 환경별 설치 및 실행 가이드 방법 A: Python Pip 패키지 설치 (권장) CUDA 12.1 이상 및 Python 3.9+ 환경에서 간단히 설치할 수 있습니다.\n# 가상환경 생성 및 활성화 python -m venv vllm-env source vllm-env/bin/activate # Windows: vllm-env\\Scripts\\activate # PyTorch (CUDA 지원) 및 vLLM 설치 pip install --upgrade pip pip install vllm 방법 B: Docker 컨테이너 실행 (격리된 환경) NVIDIA Container Toolkit이 구성된 환경에서는 Docker를 통해 의존성 충돌 없이 즉시 기동할 수 있습니다.\ndocker run --gpus all \\ -v ~/.cache/huggingface:/root/.cache/huggingface \\ -p 8000:8000 \\ --ipc=host \\ vllm/vllm-openai:latest \\ --model Qwen/Qwen2.5-7B-Instruct \\ --gpu-memory-utilization 0.90 \\ --max-model-len 4096 3. SLM 모델 선정 기준 및 VRAM 요구사항 로컬 서빙 환경에서 최고의 가성비를 내는 소형 언어 모델(SLM) 가이드입니다.\n모델명 파라미터 크기 기본 정밀도 (FP16) AWQ 4-bit 양자화 한국어/도구 호출 강점 Qwen/Qwen2.5-7B-Instruct 7.6B ~15 GB VRAM ~6.5 GB VRAM 🏆 원픽 추천: 한국어 품질 최상, Function Calling 우수 meta-llama/Llama-3.2-3B-Instruct 3.2B ~7 GB VRAM ~3.5 GB VRAM 초경량, 빠른 처리 속도, 8GB VRAM GPU에서도 여유 google/gemma-2-9b-it 9.2B ~19 GB VRAM ~8.5 GB VRAM 고난도 추론, 코딩 및 수학적 문제 해결력 우수 Qwen/Qwen2.5-Coder-7B-Instruct 7.6B ~15 GB VRAM ~6.5 GB VRAM 사내 코드 리뷰 및 자동 완성 백엔드 전용 💡 VRAM 절약 팁 (AWQ 양자화): 8GB VRAM을 가진 RTX 3060/4060 GPU에서도 --quantization awq 옵션과 사전 양자화된 모델(예: Qwen/Qwen2.5-7B-Instruct-AWQ)을 사용하면 7B 모델을 완벽하게 서빙할 수 있습니다.\n4. 고성능 서빙 설정 및 핵심 최적화 파라미터 vLLM 서빙 엔진을 가동할 때 처리량과 안정성을 결정짓는 주요 CLI 옵션입니다.\n옵션 플래그 권장값 상세 설명 --model 모델 ID/경로 Hugging Face 모델 허브 ID 또는 로컬 가중치 폴더 경로 --port 8000 REST API 서비스 포트 --gpu-memory-utilization 0.85 ~ 0.95 전체 VRAM 중 모델 및 KV 캐시로 할당할 비율 (SLM은 0.90 권장) --max-model-len 4096 ~ 8192 최대 컨텍스트 윈도우 크기 (지나치게 크게 잡으면 메모리 소모 증가) --max-num-seqs 128 ~ 256 동시에 연속 배치로 처리할 최대 세션 수 (처리량 향상) --quantization awq / gptq / fp8 양자화 가속 엔진 지정 (해당 형식으로 변환된 모델 사용 시) --tensor-parallel-size 1 (단일 GPU) 멀티 GPU 분산 서빙 시 GPU 개수 (예: 2, 4) --trust-remote-code 플래그 포함 신규 모델 아키텍처 커스텀 코드 실행 허용 실무 권장 서빙 기동 명령어 python -m vllm.entrypoints.openai.api_server \\ --model Qwen/Qwen2.5-7B-Instruct \\ --port 8000 \\ --gpu-memory-utilization 0.90 \\ --max-model-len 4096 \\ --max-num-seqs 128 \\ --trust-remote-code 5. OpenAI 호환 API 연동 및 클라이언트 코드 vLLM은 OpenAI의 API 스펙을 100% 따르므로, 기존 OpenAI SDK를 사용하는 모든 애플리케이션에서 base_url만 변경하여 즉시 사용할 수 있습니다.\nPython 연동 예제 (동기 호출 \u0026amp; 실시간 스트리밍) from openai import OpenAI # 1. 로컬 vLLM 서버로 클라이언트 초기화 client = OpenAI( base_url=\u0026#34;http://localhost:8000/v1\u0026#34;, api_key=\u0026#34;EMPTY\u0026#34; # vLLM 기본 모드는 별도 API 키가 필요 없습니다. ) # 2. 실시간 스트리밍 질의응답 response_stream = client.chat.completions.create( model=\u0026#34;Qwen/Qwen2.5-7B-Instruct\u0026#34;, messages=[ {\u0026#34;role\u0026#34;: \u0026#34;system\u0026#34;, \u0026#34;content\u0026#34;: \u0026#34;당신은 IT 인프라 전문 기술 어시스턴트입니다.\u0026#34;}, {\u0026#34;role\u0026#34;: \u0026#34;user\u0026#34;, \u0026#34;content\u0026#34;: \u0026#34;vLLM의 PagedAttention 핵심 원리를 3문장으로 설명해주세요.\u0026#34;} ], temperature=0.7, max_tokens=512, stream=True ) print(\u0026#34;[답변 출력]: \u0026#34;, end=\u0026#34;\u0026#34;) for chunk in response_stream: content = chunk.choices[0].delta.content if content: print(content, end=\u0026#34;\u0026#34;, flush=True) print() cURL 호출 예제 curl http://localhost:8000/v1/chat/completions \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ -d \u0026#39;{ \u0026#34;model\u0026#34;: \u0026#34;Qwen/Qwen2.5-7B-Instruct\u0026#34;, \u0026#34;messages\u0026#34;: [ {\u0026#34;role\u0026#34;: \u0026#34;user\u0026#34;, \u0026#34;content\u0026#34;: \u0026#34;소형 언어 모델(SLM)의 장점을 알려줘.\u0026#34;} ], \u0026#34;temperature\u0026#34;: 0.5 }\u0026#39; 🎯 결론 및 실무 권장사항 개발/개인 테스트는 Ollama, 서비스 배포는 vLLM: 로컬 개인 챗봇이나 단순 탐색 단계에서는 원클릭 구동이 가능한 Ollama를, 다중 접속자가 있거나 서비스 백엔드 API로 탑재할 때는 vLLM을 선택하는 것이 정석입니다. SLM + AWQ 조합의 경제성: Qwen2.5-7B-Instruct-AWQ와 vLLM을 결합하면 100만 원 이하의 보급형 GPU에서도 초당 50~100토큰 이상의 놀라운 처리 속도로 사내 프라이빗 AI 서비스를 구축할 수 있습니다. OpenAI SDK 재사용성: 프론트엔드나 에이전트 프레임워크(LangChain, LlamaIndex 등)를 교체할 필요 없이 백엔드 엔드포인트 URL 하나만 바꾸면 되므로 인프라 마이그레이션 비용이 제로에 수렴합니다. ⚠️ 한계 및 주의사항 CUDA 버전 및 PyTorch 의존성: vLLM은 하드웨어 성능을 극한까지 끌어올리기 위해 커스텀 C++/CUDA 커널을 컴파일하므로, 호환되는 NVIDIA GPU 드라이버와 CUDA 툴킷 버전 매칭이 엄격합니다. CPU 전용 구동의 비효율: vLLM도 CPU 백엔드를 실험적으로 지원하지만, GPU 가속 환경에 최적화되어 있으므로 CPU 전용 환경이라면 llama.cpp / Ollama가 더 유리합니다. 슬라이딩 윈도우 및 긴 컨텍스트: 컨텍스트 창(--max-model-len)을 32K 이상으로 무리하게 늘릴 경우 KV 캐시가 VRAM을 모두 점유하여 동시 요청 처리 가능 수량(Batch size)이 급격히 줄어들 수 있습니다. 📚 수집 소스 및 참고 자료 vLLM 공식 GitHub 저장소 및 문서 TensorRT-LLM 및 vLLM을 활용한 sLLM 추론 최적화 - NC Research vLLM을 활용한 고성능 저비용 LLM 서빙 가이드 - 패스트캠퍼스 MUSE-CODE-SPACE/SLMAgent: 로컬 SLM AI 에이전트 오픈소스 Gemma 4 Ollama API 가이드: 로컬 AI 설정 및 통합 vLLM 빠른 시작 - Rost Glukhov 기술 블로그 ","permalink":"https://wkqco33.github.io/wkqcosoft-docs/reports/2026-08-07-vllm%EC%9D%84-%ED%99%9C%EC%9A%A9%ED%95%B4-%EB%A1%9C%EC%BB%AC%EC%97%90%EC%84%9C-slm-%EC%86%8C%ED%98%95-%EC%96%B8%EC%96%B4-%EB%AA%A8%EB%8D%B8-%EC%84%9C%EB%B9%99-c3d24c/","summary":"\u003cblockquote\u003e\n\u003cp\u003e📌 \u003cstrong\u003eExecutive Summary\u003c/strong\u003e\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003e초고속 LLM/SLM 서빙 엔진\u003c/strong\u003e: vLLM은 \u003cstrong\u003ePagedAttention\u003c/strong\u003e 알고리즘을 도입하여 KV 캐시의 메모리 낭비를 가상 메모리 페이징 기법으로 96% 이상 줄이고, 기존 Hugging Face 대비 최대 24배 이상의 동시 처리량(Throughput)을 제공합니다.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e로컬 SLM(소형 언어 모델)과의 최적 궁합\u003c/strong\u003e: Qwen2.5-7B, Llama-3.2, Gemma-3 등 1B\u003cdel\u003e7B 급 SLM을 vLLM으로 구동하면 단일 GPU(VRAM 8\u003c/del\u003e16GB) 환경에서도 극도로 낮은 지연 시간(Low Latency)과 실시간 스트리밍 처리가 가능합니다.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eOpenAI 표준 API 기본 내장\u003c/strong\u003e: 추가 코드 없이 서버 구동 즉시 \u003ccode\u003e/v1/chat/completions\u003c/code\u003e 엔드포인트를 제공하여 기존 상용 LLM 클라이언트 코드를 그대로 재사용할 수 있습니다.\u003c/li\u003e\n\u003c/ul\u003e\u003c/blockquote\u003e\n\u003chr\u003e\n\u003ch2 id=\"-리포트-개요-및-프레임워크-비교\"\u003e📊 리포트 개요 및 프레임워크 비교\u003c/h2\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth style=\"text-align: left\"\u003e항목\u003c/th\u003e\n          \u003cth style=\"text-align: left\"\u003e세부 내용\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e\u003cstrong\u003e보고서 주제\u003c/strong\u003e\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003evLLM 기반 로컬 소형 언어 모델(SLM) 고성능 추론 및 서빙 최적화 가이드\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e\u003cstrong\u003e핵심 기술\u003c/strong\u003e\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003ePagedAttention, Continuous Batching, AWQ/GPTQ 양자화, OpenAI API Server\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e\u003cstrong\u003e사전 요구사항\u003c/strong\u003e\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003eNVIDIA GPU (최소 8GB+ VRAM 권장), Python 3.8+ / CUDA 12.x 또는 Docker\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e\u003cstrong\u003e추천 대상 모델\u003c/strong\u003e\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003eQwen2.5-7B-Instruct, Llama-3.2-3B, Gemma-2-9B 등\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003ch3 id=\"-vllm-vs-ollama-핵심-비교-분석\"\u003e🥊 vLLM vs Ollama 핵심 비교 분석\u003c/h3\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth style=\"text-align: left\"\u003e비교 항목\u003c/th\u003e\n          \u003cth style=\"text-align: left\"\u003evLLM (프로덕션/서빙 특화)\u003c/th\u003e\n          \u003cth style=\"text-align: left\"\u003eOllama (로컬 개발/개인 챗봇 특화)\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e\u003cstrong\u003e주요 목적\u003c/strong\u003e\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e고처리량 프로덕션 서빙, 멀티 유저 API 백엔드\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e초간편 로컬 테스트, 개인용 CLI 대화\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e\u003cstrong\u003e추론 백엔드 엔진\u003c/strong\u003e\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003ePagedAttention + CUDA 커스텀 커널\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003ellama.cpp (GGUF 기반 CPU/GPU 하이브리드)\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e\u003cstrong\u003e동시 다중 요청 처리\u003c/strong\u003e\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e\u003cstrong\u003e연속 배치(Continuous Batching)\u003c/strong\u003e 로 동시 요청 극대화\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e제한적 동시성 (단일 요청 순차 처리에 최적화)\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e\u003cstrong\u003e모델 형식 지원\u003c/strong\u003e\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003eHugging Face SafeTensors, AWQ, GPTQ, FP8\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003eGGUF 단일 바이너리 파일\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e\u003cstrong\u003eAPI 호환성\u003c/strong\u003e\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e\u003cstrong\u003eOpenAI REST API 네이티브 100% 호환\u003c/strong\u003e\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e독자 API + OpenAI 에뮬레이션 레이어\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e\u003cstrong\u003e설치 및 운영 난이도\u003c/strong\u003e\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003ePython 가상환경 / CUDA / Docker 필요 (중급)\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e원클릭 인스톨러 / CLI 기반 (초급)\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e\u003cstrong\u003e권장 사용처\u003c/strong\u003e\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e사내 서비스 API 백엔드, RAG 에이전트 다중 접속\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e로컬 PC 개인 테스트, 데스크톱 UI 연동\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003chr\u003e\n\u003ch2 id=\"-핵심-분석\"\u003e🔍 핵심 분석\u003c/h2\u003e\n\u003ch3 id=\"1-vllm-아키텍처-및-slm-서빙의-이점\"\u003e1. vLLM 아키텍처 및 SLM 서빙의 이점\u003c/h3\u003e\n\u003cp\u003e대규모 언어 모델 서빙에서 가장 큰 병목은 생성 토큰마다 누적되는 \u003cstrong\u003eKV(Key-Value) 캐시 메모리 낭비\u003c/strong\u003e와 **요청 대기 지연(Latency)**입니다.\u003c/p\u003e","title":"vLLM을 활용한 로컬 SLM(소형 언어 모델) 고성능 서빙 완벽 가이드"},{"content":"ROS2 Nav2(Navigation2) 스택 실행 시 로봇의 주행 특성, 장애물 회피 범위, 위치 추정 정확도, 정밀 도착 오차 등을 제어하는 핵심 파라미터 설정 파일인 **nav2_params.yaml**의 주요 노드별 설정법과 실무 튜닝 가이드입니다.\n1. 커스텀 nav2_params.yaml 작성 및 적용 방법 Nav2 런치 실행 시 기본 파라미터 대신 직접 작성한 커스텀 파라미터 파일을 전달하여 실행합니다.\nros2 launch nav2_bringup bringup_launch.py \\ use_sim_time:=true \\ map:=$HOME/my_map.yaml \\ params_file:=$HOME/my_nav2_params.yaml 2. AMCL (위치 추정) 파라미터 설정 amcl 노드는 파티클 필터(Particle Filter)를 이용하여 맵 상에서 로봇의 실시간 위치를 추정합니다.\namcl: ros__parameters: use_sim_time: True alpha1: 0.2 # 오도메터 회전 운동 잡음 비율 alpha2: 0.2 # 오도메터 직진 운동 잡음 비율 alpha3: 0.2 alpha4: 0.2 base_frame_id: \u0026#34;base_footprint\u0026#34; global_frame_id: \u0026#34;map\u0026#34; odom_frame_id: \u0026#34;odom\u0026#34; min_particles: 500 # 최소 파티클 수 (위치 추정 기본 성능) max_particles: 2000 # 최대 파티클 수 (위치 교정 시 사용) update_min_d: 0.25 # 파티클 갱신을 위한 최소 이동 거리 (0.25m) update_min_a: 0.20 # 파티클 갱신을 위한 최소 회전 각도 (rad) laser_min_range: 0.15 # 센서 데이터 반영 최소 거리 laser_max_range: 12.0 # 센서 데이터 반영 최대 거리 laser_model_type: \u0026#34;likelihood_field\u0026#34; # 라이다 스캔 매칭 알고리즘 튜닝 팁: CPU 점유율이 높다면 max_particles를 줄이고, 위치 추정이 불확실하고 튄다면 min_particles를 1000 이상으로 올려줍니다. 3. Costmap (글로벌 / 로컬 코스트맵) 설정 코스트맵은 로봇 주변의 장애물 위험도를 격자 지도 상의 비용(Cost)으로 변환합니다.\n3.1. 로봇 외형 크기 설정 (Footprint vs Radius) 원형 로봇인 경우 robot_radius, 직사각형/특수 형태인 경우 footprint를 지정합니다. # 원형 로봇 예시 (반지름 0.22m) robot_radius: 0.22 # 직사각형 로봇 예시 (좌측하단 -\u0026gt; 우측하단 -\u0026gt; 우측상단 -\u0026gt; 좌측상단 순 좌표) footprint: \u0026#34;[ [0.25, 0.20], [0.25, -0.20], [-0.25, -0.20], [-0.25, 0.20] ]\u0026#34; 3.2. Inflation Layer (장애물 마진 설정) 장애물 주변으로 안전 버퍼 구역을 형성합니다.\nglobal_costmap: global_costmap: ros__parameters: update_frequency: 1.0 publish_frequency: 1.0 global_frame: \u0026#34;map\u0026#34; robot_base_frame: \u0026#34;base_footprint\u0026#34; use_sim_time: True robot_radius: 0.22 plugins: [\u0026#34;static_layer\u0026#34;, \u0026#34;obstacle_layer\u0026#34;, \u0026#34;inflation_layer\u0026#34;] inflation_layer: plugin: \u0026#34;nav2_costmap_2d::InflationLayer\u0026#34; cost_scaling_factor: 3.0 # 비례 감쇄율 (숫자가 작을수록 안전 마진이 넓어짐) inflation_radius: 0.55 # 장애물 주변 최대 비용 팽창 반지름 (미터) obstacle_layer: plugin: \u0026#34;nav2_costmap_2d::ObstacleLayer\u0026#34; enabled: True observation_sources: scan scan: topic: /scan max_obstacle_height: 2.0 clearing: True # 장애물이 사라지면 지도에서 제거 marking: True # 장애물이 감지되면 지도에 등록 data_type: \u0026#34;LaserScan\u0026#34; raytrace_range: 3.0 # 레이트레이싱으로 통로 확인 거리 obstacle_range: 2.5 # 장애물 감지 반영 거리에 한함 튜닝 팁: 로봇이 넓은 길에서도 장애물에 너무 민감하게 반응하여 통과하지 못하면 cost_scaling_factor를 올리고(예: 5.0), 좁은 통로를 잘 지나가게 하려면 inflation_radius를 로봇 크기에 맞게 조절합니다. 4. Planner Server (전역 경로 계획 - Global Planner) 시작점에서 최종 목적지까지 전체 맵 상의 최적 경로를 계산합니다.\nplanner_server: ros__parameters: expected_planner_frequency: 20.0 use_sim_time: True planner_plugins: [\u0026#34;GridBased\u0026#34;] GridBased: plugin: \u0026#34;nav2_navfn_planner/NavfnPlanner\u0026#34; use_astar: True # A* 알고리즘 사용 (False 시 Dijkstra 사용) allow_unknown: True # 미탐색 구역 경로 생성 허용 여부 5. Controller Server (국소 주행 \u0026amp; 회피 - Local Controller) 실시간으로 장애물을 피하며 계산된 경로를 따라 로봇에 속도 명령(cmd_vel)을 보냅니다. (기본: DWB 또는 Regulated Pure Pursuit)\ncontroller_server: ros__parameters: use_sim_time: True controller_frequency: 20.0 min_x_velocity_threshold: 0.001 min_theta_velocity_threshold: 0.001 failure_tolerance: 0.3 progress_checker_plugin: \u0026#34;progress_checker\u0026#34; goal_checker_plugins: [\u0026#34;general_goal_checker\u0026#34;] controller_plugins: [\u0026#34;FollowPath\u0026#34;] # 목표지점 도착 판정 오차범위 (Goal Checker) general_goal_checker: stateful: True plugin: \u0026#34;nav2_controller::SimpleGoalChecker\u0026#34; xy_goal_tolerance: 0.15 # 최종 위치 도착 허용 오차 (15cm) yaw_goal_tolerance: 0.15 # 최종 각도 도착 허용 오차 (rad) # DWB Controller 설정 FollowPath: plugin: \u0026#34;dwb_core::DWBLocalPlanner\u0026#34; debug_trajectory_details: True min_vel_x: 0.0 max_vel_x: 0.3 # 최대 직진 속도 (m/s) max_vel_theta: 1.0 # 최대 회전 속도 (rad/s) acc_lim_x: 2.5 # 가속도 제한 acc_lim_theta: 3.2 decel_lim_x: -2.5 decel_lim_theta: -3.2 vx_samples: 20 vtheta_samples: 20 critics: [\u0026#34;RotateToGoal\u0026#34;, \u0026#34;Oscillation\u0026#34;, \u0026#34;BaseObstacle\u0026#34;, \u0026#34;GoalAlign\u0026#34;, \u0026#34;PathAlign\u0026#34;, \u0026#34;PathDist\u0026#34;, \u0026#34;GoalDist\u0026#34;] BaseObstacle.scale: 0.02 PathAlign.scale: 32.0 PathDist.scale: 32.0 GoalAlign.scale: 24.0 GoalDist.scale: 24.0 6. Behavior Server (복구 동작 - Recovery Behaviors) 주행 도중 경로가 막히거나 갇혔을 때 자동 수행할 예외 처리 동작(Recovery)을 정의합니다.\nbehavior_server: ros__parameters: costmap_topic: local_costmap/costmap_raw footprint_topic: local_costmap/published_footprint cycle_frequency: 10.0 behavior_plugins: [\u0026#34;spin\u0026#34;, \u0026#34;backup\u0026#34;, \u0026#34;drive_on_heading\u0026#34;, \u0026#34;wait\u0026#34;] spin: plugin: \u0026#34;nav2_behaviors/Spin\u0026#34; target_yaw: 1.57 # 90도 회전하여 소켓 및 장애물 재확인 backup: plugin: \u0026#34;nav2_behaviors/BackUp\u0026#34; target_x: -0.15 # 경로 정체 시 15cm 후진 target_speed: 0.05 wait: plugin: \u0026#34;nav2_behaviors/Wait\u0026#34; wait_duration: 2 # 2초간 대기 후 다시 경로 재계산 💡 파라미터 튜닝 흐름 한눈에 보기 [ [ [ [ 1 2 3 4 . . . . f i x m o n y a o f _ x t l g _ p │ ▼ a │ ▼ o │ ▼ v r t a e i i l l n o _ _ t n t x _ o / r l / a e r d r a a i a c d u n c i s c _ u e l s \u0026amp; i 도 m 정 c 착 _ 확 o x 히 s 허 t 용 구 측 _ 동 정 s 오 부 ] c 차 a 스 l 현 펙 i 실 에 n 화 g 맞 _ ( 춰 f 1 a 0 상 c ~ 한 t 2 o 0 지 r c 정 m ] 조 ) 정 ] ( 안 전 마 진 형 성 ) ] 위 설정을 바탕으로 환경에 맞게 nav2_params.yaml을 커스텀하여 내비게이션을 운용해 보세요!\n","permalink":"https://wkqco33.github.io/wkqcosoft-docs/posts/ros2-nav2-params-guide/","summary":"\u003cp\u003eROS2 \u003cstrong\u003eNav2\u003c/strong\u003e(Navigation2) 스택 실행 시 로봇의 주행 특성, 장애물 회피 범위, 위치 추정 정확도, 정밀 도착 오차 등을 제어하는 핵심 파라미터 설정 파일인 **\u003ccode\u003enav2_params.yaml\u003c/code\u003e**의 주요 노드별 설정법과 실무 튜닝 가이드입니다.\u003c/p\u003e\n\u003chr\u003e\n\u003ch2 id=\"1-커스텀-nav2_paramsyaml-작성-및-적용-방법\"\u003e1. 커스텀 \u003ccode\u003enav2_params.yaml\u003c/code\u003e 작성 및 적용 방법\u003c/h2\u003e\n\u003cp\u003eNav2 런치 실행 시 기본 파라미터 대신 직접 작성한 커스텀 파라미터 파일을 전달하여 실행합니다.\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eros2 launch nav2_bringup bringup_launch.py \u003cspan style=\"color:#ae81ff\"\u003e\\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#ae81ff\"\u003e\u003c/span\u003e  use_sim_time:\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003etrue \u003cspan style=\"color:#ae81ff\"\u003e\\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#ae81ff\"\u003e\u003c/span\u003e  map:\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e$HOME/my_map.yaml \u003cspan style=\"color:#ae81ff\"\u003e\\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#ae81ff\"\u003e\u003c/span\u003e  params_file:\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e$HOME/my_nav2_params.yaml\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003chr\u003e\n\u003ch2 id=\"2-amcl-위치-추정-파라미터-설정\"\u003e2. AMCL (위치 추정) 파라미터 설정\u003c/h2\u003e\n\u003cp\u003e\u003ccode\u003eamcl\u003c/code\u003e 노드는 파티클 필터(Particle Filter)를 이용하여 맵 상에서 로봇의 실시간 위치를 추정합니다.\u003c/p\u003e","title":"ROS2 Nav2 params.yaml 핵심 설정 및 파라미터 튜닝 가이드"},{"content":"특정 튜토리얼용 로봇(터틀봇 등) 패키지에 의존하지 않고, 일반적인 커스텀 ROS2 모바일 로봇(AMR/AGV) 하드웨어 환경에서 **slam_toolbox**를 이용한 2D 점유 격자 지도(Occupancy Grid Map) 작성부터 nav2_bringup 표준 명령어를 이용한 자율주행 구동까지 전체 실기 절차를 가이드합니다.\n1. 개요 및 실기 로봇 사전 준비 로봇 하드웨어 필수 조건 (ROS2 인터페이스) 실제 로봇에서 SLAM 및 Nav2를 구동하려면 로봇 드라이버 및 센서 노드가 아래 ROS2 토픽과 TF(Transform)를 제공해야 합니다.\n센서 데이터 (/scan): 2D LiDAR 노드가 sensor_msgs/msg/LaserScan 타입 토픽 발행 오도메트리 (/odom): 바퀴 인코더/IMU 기반 이동량 nav_msgs/msg/Odometry 발행 조종 명령 (/cmd_vel): 로봇 모터 드라이버가 geometry_msgs/msg/Twist 속도 명령 수신 TF 좌표계 (Robot State Publisher): odom ➔ base_footprint ➔ base_link ➔ laser_frame (LiDAR 위치) 변환 제공 필수 패키지 설치 (Humble 버전 기준) 개발자 PC(Remote PC) 또는 로봇의 메인 컴퓨팅 장치(SBC/Industrial PC)에 표준 패키지를 설치합니다.\nsudo apt update sudo apt install -y \\ ros-humble-navigation2 \\ ros-humble-nav2-bringup \\ ros-humble-slam-toolbox \\ ros-humble-teleop-twist-keyboard \\ ros-humble-rviz2 네트워크 및 ROS2 Domain ID 설정 로봇 온보드 컴퓨터와 Remote PC 간 다중 기기 통신 시, 동일한 Wi-Fi 네트워크에 접속하고 ROS_DOMAIN_ID를 동일하게 맞춰줍니다.\n# [로봇 및 Remote PC 공통] ~/.bashrc 등록 권장 export ROS_DOMAIN_ID=30 # 네트워크 통신 분리를 위한 Domain ID (0~232) 2. 로봇 하드웨어 실행 (Robot Bringup) 로봇 온보드 컴퓨터 터미널에서 모터 드라이버, LiDAR 센서, 로봇 URDF(robot_state_publisher)를 실행합니다.\n# [로봇 온보드 PC] 로봇 커스텀 브링업 런치 파일 실행 (예시) ros2 launch my_robot_bringup robot_hardware.launch.py 센서 및 TF 정상 수신 확인 (Remote PC) Remote PC 터미널에서 센서 데이터 및 오도메트리가 정상적으로 발행되는지 확인합니다.\n# [Remote PC] 토픽 목록 확인 ros2 topic list # [Remote PC] LiDAR 및 Odom 데이터 정상 발행 여부 확인 ros2 topic echo /scan --once ros2 topic echo /odom --once 3. SLAM을 이용한 2D 맵 생성 및 저장 Step 1: SLAM Toolbox 런치 실행 slam_toolbox 노드를 구동하여 실시간 SLAM 지도 작성을 시작합니다. 실기 환경이므로 use_sim_time:=false로 구동합니다.\n# [Remote PC 또는 로봇 PC] ros2 launch slam_toolbox online_async_launch.py use_sim_time:=false Step 2: RViz2 시각화 실행 RViz2를 실행하여 생성되는 맵과 LiDAR 스캔 데이터, 로봇 모델을 실시간 모니터링합니다.\n# [Remote PC] Nav2 기본 RViz 설정으로 실행 ros2 run rviz2 rviz2 -d /opt/ros/humble/share/nav2_bringup/rviz/nav2_default_view.rviz Step 3: 키보드 조종 노드로 미지 영역 탐색 범용 키보드 조종 노드(teleop_twist_keyboard)를 실행하여 실제 로봇을 천천히 이동시키며 주행 구역 전체를 탐색합니다.\n# [Remote PC] 범용 Twist 키보드 조종 실행 ros2 run teleop_twist_keyboard teleop_twist_keyboard 조종 팁: 로봇을 급격하게 회전시키면 LiDAR 스캔 매칭이 어긋날 수 있으므로 제자리에서 천천히 회전하며 벽면 및 장애물 데이터를 충분히 수집합니다.\nStep 4: 작성된 맵 저장 (map_saver_cli) 탐색이 완료되면 nav2_map_server의 맵 세이버 CLI를 이용해 현재 지도를 파일로 저장합니다.\n# ~/my_map 이름으로 저장 (.yaml 및 .pgm 파일 생성) ros2 run nav2_map_server map_saver_cli -f ~/my_map 저장되는 맵 파일 구조 my_map.pgm: 2D 점유 격자 이미지 파일 (흰색: 이동 가능, 검은색: 벽/장애물, 회색: 미탐색). my_map.yaml: 지도의 메타데이터 파일 (해상도, 원점 위치, 점유 임계값 등 정의). image: my_map.pgm mode: trinary resolution: 0.050000 # 픽셀 당 실제 거리 (0.05m = 5cm) origin: [-2.000000, -0.500000, 0.000000] # 맵 좌측 하단 좌표 [x, y, yaw] negate: 0 occupied_thresh: 0.65 # 장애물 판정 임계값 free_thresh: 0.25 # 통로 판정 임계값 4. Nav2 스택을 이용한 자율주행 구동 생성한 지도(my_map.yaml)를 불러와 실제 로봇에 Nav2 자율주행 파이프라인을 적용합니다.\nStep 1: Nav2 스택 브링업 (bringup_launch.py) Nav2 통합 런치 파일을 사용하여 AMCL, Costmap, Planner, Controller, Recovery 등 Nav2 전 노드를 실행합니다.\n# [Remote PC 또는 로봇 PC] 기본 파라미터 파일로 구동 ros2 launch nav2_bringup bringup_launch.py \\ use_sim_time:=false \\ map:=$HOME/my_map.yaml 커스텀 파라미터 적용 시: 로봇 크기(Footprint)나 속도 제한에 맞춰 커스텀 nav2_params.yaml을 작성한 경우 params_file 인자를 추가로 전달합니다.\nros2 launch nav2_bringup bringup_launch.py \\ use_sim_time:=false \\ map:=$HOME/my_map.yaml \\ params_file:=$HOME/my_nav2_params.yaml Step 2: RViz2에서 로봇 초기 위치 추정 (2D Pose Estimate) RViz2 상단 툴바의 2D Pose Estimate 버튼을 클릭합니다. 실제 맵 상에서 현재 로봇이 위치한 지점을 클릭하고, 로봇이 바라보는 실제 방향으로 드래그합니다. AMCL 파티클이 설정한 위치 주위로 모이면서 실제 LiDAR 스캔 데이터와 지도가 매칭되어 초기 위치가 확정됩니다. Step 3: 자율주행 목표 지점 설정 (Nav2 Goal) RViz2 상단의 Nav2 Goal (또는 2D Goal Pose) 버튼을 클릭합니다. 로봇이 이동할 최종 목적지와 도착 시 바라볼 방향을 클릭 \u0026amp; 드래그합니다. Nav2 스택이 경로(Global Path)를 생성하고 로봇 모터 드라이버(/cmd_vel)로 속도 명령을 전송하여 국소 장애물을 회피하며 목적지까지 이동합니다. 5. Nav2 디버깅 및 CLI 가이드 TF 좌표 변환 트리 검증 Nav2 구동 시 TF 연결 구조는 다음과 같아야 합니다.\nm a p ─ ─ ( A M C L ) ─ ─ \u0026gt; o d o m ─ ─ ( R o b o t D r i v e r / O d o m ) ─ ─ \u0026gt; b a s e _ l i n k ─ ─ \u0026gt; l a s e r _ f r a m e # TF 트리를 그래픽 PDF로 생성하여 구성을 검증 ros2 run tf2_tools view_frames # map -\u0026gt; base_link 실제 실시간 좌표 변환 확인 ros2 run tf2_ros tf2_echo map base_link CLI 명령으로 이동 목표 전송 (NavigateToPose Action) RViz2 GUI 없이 터미널 액션 클라이언트를 통해 직접 좌표 목표를 보낼 수 있습니다.\nros2 action send_goal /navigate_to_pose nav2_msgs/action/NavigateToPose \u0026#34;{ pose: { header: {frame_id: \u0026#39;map\u0026#39;}, pose: { position: {x: 2.0, y: 1.0, z: 0.0}, orientation: {w: 1.0} } } }\u0026#34; Costmap 장애물 잔상 리셋 서비스 동적 장애물이 사라졌음에도 코스트맵 상에 잔상이 남아 경로 계획이 막히는 경우 클리어 서비스를 호출합니다.\n# Global 및 Local Costmap 장애물 레이어 리셋 ros2 service call /global_costmap/clear_entirely_global_costmap nav2_msgs/srv/ClearEntireCostmap \u0026#34;{}\u0026#34; ros2 service call /local_costmap/clear_entirely_local_costmap nav2_msgs/srv/ClearEntireCostmap \u0026#34;{}\u0026#34; 6. 실기 로봇 운용 튜닝 및 주의사항 시간 동기화 (NTP / Chrony 필수): 로봇 온보드 컴퓨터와 Remote PC 간 시계가 다르면 TF_OLD_DATA 또는 Lookup would require extrapolation into the past 오류가 발생합니다. chrony 패키지를 사용해 시간 동기화를 반드시 설정하세요. 로봇 크기(Footprint) 및 Inflation Radius 설정: nav2_params.yaml 내 robot_radius 또는 footprint 코스트맵 값을 실제 로봇 외형 물리 치수에 맞게 설정하고, inflation_radius를 적절히 넓혀 벽면에 부딪히지 않도록 안전 유격을 확보합니다. 오도메트리 드리프트 및 바퀴 슬립: 실제 로봇 바퀴 미끄러짐이 심할 경우 AMCL 파티클이 발산할 수 있습니다. 로봇 속도/가속도를 완화하거나 IMU 융합(EKF, robot_localization)을 적용하여 /odom 품질을 향상시킵니다. 마무리 특정 예제 전용 패키지 없이도, 표준 **slam_toolbox**와 nav2_bringup 명령어를 이해하고 활용하면 모든 범용 ROS2 모바일 로봇에 SLAM 및 자율주행 파이프라인을 직접 구축할 수 있습니다.\n","permalink":"https://wkqco33.github.io/wkqcosoft-docs/posts/ros2-slam-nav2-guide/","summary":"\u003cp\u003e특정 튜토리얼용 로봇(터틀봇 등) 패키지에 의존하지 않고, 일반적인 커스텀 \u003cstrong\u003eROS2 모바일 로봇(AMR/AGV)\u003c/strong\u003e 하드웨어 환경에서 **\u003ccode\u003eslam_toolbox\u003c/code\u003e**를 이용한 2D 점유 격자 지도(Occupancy Grid Map) 작성부터 \u003cstrong\u003e\u003ccode\u003enav2_bringup\u003c/code\u003e\u003c/strong\u003e 표준 명령어를 이용한 자율주행 구동까지 전체 실기 절차를 가이드합니다.\u003c/p\u003e\n\u003chr\u003e\n\u003ch2 id=\"1-개요-및-실기-로봇-사전-준비\"\u003e1. 개요 및 실기 로봇 사전 준비\u003c/h2\u003e\n\u003ch3 id=\"로봇-하드웨어-필수-조건-ros2-인터페이스\"\u003e로봇 하드웨어 필수 조건 (ROS2 인터페이스)\u003c/h3\u003e\n\u003cp\u003e실제 로봇에서 SLAM 및 Nav2를 구동하려면 로봇 드라이버 및 센서 노드가 아래 ROS2 토픽과 TF(Transform)를 제공해야 합니다.\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\u003cstrong\u003e센서 데이터 (\u003ccode\u003e/scan\u003c/code\u003e)\u003c/strong\u003e: 2D LiDAR 노드가 \u003ccode\u003esensor_msgs/msg/LaserScan\u003c/code\u003e 타입 토픽 발행\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e오도메트리 (\u003ccode\u003e/odom\u003c/code\u003e)\u003c/strong\u003e: 바퀴 인코더/IMU 기반 이동량 \u003ccode\u003enav_msgs/msg/Odometry\u003c/code\u003e 발행\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e조종 명령 (\u003ccode\u003e/cmd_vel\u003c/code\u003e)\u003c/strong\u003e: 로봇 모터 드라이버가 \u003ccode\u003egeometry_msgs/msg/Twist\u003c/code\u003e 속도 명령 수신\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eTF 좌표계 (Robot State Publisher)\u003c/strong\u003e: \u003ccode\u003eodom\u003c/code\u003e ➔ \u003ccode\u003ebase_footprint\u003c/code\u003e ➔ \u003ccode\u003ebase_link\u003c/code\u003e ➔ \u003ccode\u003elaser_frame\u003c/code\u003e (LiDAR 위치) 변환 제공\u003c/li\u003e\n\u003c/ol\u003e\n\u003chr\u003e\n\u003ch3 id=\"필수-패키지-설치-humble-버전-기준\"\u003e필수 패키지 설치 (Humble 버전 기준)\u003c/h3\u003e\n\u003cp\u003e개발자 PC(Remote PC) 또는 로봇의 메인 컴퓨팅 장치(SBC/Industrial PC)에 표준 패키지를 설치합니다.\u003c/p\u003e","title":"ROS2 SLAM 맵 생성 및 Nav2 자율주행 실기 가이드 (slam_toolbox \u0026 Nav2)"},{"content":"ROS2(Humble / Iron / Jazzy 등) 기반 로봇 애플리케이션 개발, 디버깅 및 시뮬레이션 시 자주 쓰이는 필수 터미널 CLI 명령어 모음집입니다.\n1. 워크스페이스 빌드 및 환경 설정 (Colcon \u0026amp; Environment) 빌드 및 의존성 관리 # 의존성 패키지 자동 설치 rosdep update rosdep install --from-paths src --ignore-src -y # 워크스페이스 전체 빌드 (소스 변경 사항 즉시 반영을 위한 심링크 빌드 권장) colcon build --symlink-install # 특정 패키지만 선택 지정 빌드 colcon build --packages-select \u0026lt;package_name\u0026gt; --symlink-install # 빌드 결과 환경변수 소싱 source install/setup.bash 2. 노드 관리 (ros2 node) 실행 중인 ROS2 노드(Node)의 상태를 점검합니다.\n# 실행 중인 모든 노드 목록 조회 ros2 node list # 특정 노드의 상세 정보 (게시/구독 토픽, 서비스, 파라미터 등) 조회 ros2 node info /my_node_name 3. 토픽 관리 (ros2 topic) 데이터 스트림(Topic)을 발행, 수신, 분석합니다.\n# 실행 중인 토픽 목록 조회 (메시지 타입 포함 -t) ros2 topic list -t # 토픽 데이터 실시간 수신 출력 ros2 topic echo /chatter # 토픽 발행 속도(Hz) 및 대역폭(Bandwidth) 측정 ros2 topic hz /scan ros2 topic bw /camera/image_raw # 토픽 상세 정보 (Publisher/Subscriber 개수, QoS 등) 조회 ros2 topic info /chatter --verbose # 커맨드라인에서 토픽 직접 발행 (Publish) ros2 topic pub --once /cmd_vel geometry_msgs/msg/Twist \u0026#34;{linear: {x: 0.5, y: 0.0, z: 0.0}, angular: {x: 0.0, y: 0.0, z: 0.2}}\u0026#34; # 10Hz 주기로 지속 발행 (-r 10) ros2 topic pub -r 10 /cmd_vel geometry_msgs/msg/Twist \u0026#34;{linear: {x: 0.2}}\u0026#34; 4. 서비스 관리 (ros2 service) 요청/응답(Request/Response) 방식의 서비스 통신을 점검하고 호출합니다.\n# 활성화된 서비스 목록 조회 ros2 service list # 특정 서비스의 타입 확인 ros2 service type /clear # 터미널에서 서비스 직접 호출 (Call) ros2 service call /spawn turtlesim/srv/Spawn \u0026#34;{x: 2.0, y: 2.0, theta: 0.0, name: \u0026#39;turtle2\u0026#39;}\u0026#34; 5. 파라미터 관리 (ros2 param) 노드의 동적 설정값(Parameter)을 확인하고 실시간으로 변경합니다.\n# 노드별 파라미터 목록 조회 ros2 param list # 특정 파라미터 값 읽기 ros2 param get /turtlesim background_b # 실행 중인 노드의 파라미터 값 즉시 변경 ros2 param set /turtlesim background_b 150 # 노드의 전체 파라미터를 YAML 파일로 덤프/저장 ros2 param dump /turtlesim \u0026gt; turtlesim_params.yaml 6. 액션 관리 (ros2 action) 장시간 수행되는 목표(Goal/Feedback/Result) 기반 통신을 확인합니다.\n# 실행 중인 액션 서버/클라이언트 목록 조회 ros2 action list # 특정 액션 상세 정보 확인 ros2 action info /turtle1/rotate_absolute # 액션 목표(Goal) 직접 전송 및 결과 확인 ros2 action send_goal /turtle1/rotate_absolute turtlesim/action/RotateAbsolute \u0026#34;{theta: 1.57}\u0026#34; 7. 인터페이스(메시지 타입) 조회 (ros2 interface) # 메시지/서비스/액션 구조 상세 보기 ros2 interface show geometry_msgs/msg/Twist ros2 interface show sensor_msgs/msg/LaserScan # 패키지 내의 모든 인터페이스 목록 확인 ros2 interface package sensor_msgs 8. 런치 및 패키지 실행 (ros2 run \u0026amp; ros2 launch) # 단일 노드 실행 ros2 run turtlesim turtlesim_node # 런치 파일 실행 (파라미터 전달 가능) ros2 launch my_robot_bringup robot.launch.py use_sim_time:=true 9. 로깅 및 녹화 / 재생 (ros2 bag) 센서 데이터 및 토픽 스트림을 녹화하거나 재실행합니다.\n# 특정 토픽 파일로 녹화 ros2 bag record -o my_bag_data /scan /tf /cmd_vel # 모든 토픽 녹화 (-a) ros2 bag record -a -o all_topics_bag # 녹화된 Bag 파일 정보 확인 ros2 bag info my_bag_data # 녹화 데이터 재생 ros2 bag play my_bag_data 10. 유용한 환경 변수 (Environment Variables) # 멀티 로봇/컴퓨터 도메인 격리 ID (0 ~ 232) export ROS_DOMAIN_ID=11 # 로컬PC 내부에서만 통신하도록 제한 (외부 망 유출 방지) export ROS_LOCALHOST_ONLY=1 # 사용 DDS 미들웨어 변경 (FastDDS / CycloneDDS) export RMW_IMPLEMENTATION=rmw_cyclonedds_cpp 💡 요약 팁 ros2 \u0026lt;command\u0026gt; -h 명령어를 활용하면 사용 가능한 부가 옵션을 빠르게 확인할 수 있습니다. 토픽 echo가 동작하지 않을 때는 ros2 topic info \u0026lt;topic\u0026gt; --verbose 명령어로 QoS Mismatch 여부를 점검하세요. ","permalink":"https://wkqco33.github.io/wkqcosoft-docs/posts/ros2-cli-commands/","summary":"\u003cp\u003eROS2(Humble / Iron / Jazzy 등) 기반 로봇 애플리케이션 개발, 디버깅 및 시뮬레이션 시 자주 쓰이는 필수 터미널 CLI 명령어 모음집입니다.\u003c/p\u003e\n\u003chr\u003e\n\u003ch2 id=\"1-워크스페이스-빌드-및-환경-설정-colcon--environment\"\u003e1. 워크스페이스 빌드 및 환경 설정 (Colcon \u0026amp; Environment)\u003c/h2\u003e\n\u003ch3 id=\"빌드-및-의존성-관리\"\u003e빌드 및 의존성 관리\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 의존성 패키지 자동 설치\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003erosdep update\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003erosdep install --from-paths src --ignore-src -y\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 워크스페이스 전체 빌드 (소스 변경 사항 즉시 반영을 위한 심링크 빌드 권장)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ecolcon build --symlink-install\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 특정 패키지만 선택 지정 빌드\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ecolcon build --packages-select \u0026lt;package_name\u0026gt; --symlink-install\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 빌드 결과 환경변수 소싱\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003esource install/setup.bash\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003chr\u003e\n\u003ch2 id=\"2-노드-관리-ros2-node\"\u003e2. 노드 관리 (\u003ccode\u003eros2 node\u003c/code\u003e)\u003c/h2\u003e\n\u003cp\u003e실행 중인 ROS2 노드(Node)의 상태를 점검합니다.\u003c/p\u003e","title":"자주 쓰는 ROS2 CLI 명령어 정리"},{"content":"GitHub Actions를 사용하여 컨테이너 이미지를 빌드하고 **GHCR(GitHub Container Registry)**에 자동 배포할 때, Buildx와 **GitHub Actions 전용 빌드 캐시(type=gha)**를 적용하여 CI/CD 시간을 크게 단축하는 워크플로우 가이드입니다.\n1. 주요 특징 및 이점 GHCR 활용: 별도의 Docker Hub 계정이나 외부 레지스트리 비번 설정 없이 GITHUB_TOKEN 인증만으로 안전하게 컨테이너 레지스트리에 푸시. type=gha 캐시: 빌드 레이어 캐시를 GitHub Actions 백엔드에 저장하여 동일한 의존성 재빌드 시간을 극적으로 줄임 (최대 80%+ 속도 향상). Multi-platform 지원: QEMU를 연동하여 linux/amd64와 linux/arm64 이미지를 단일 작업에서 동시 생성. 2. GitHub Actions 워크플로우 작성 .github/workflows/docker-build.yml 경로에 아래 내용을 작성합니다.\nname: Build and Push Docker Image to GHCR on: push: branches: - main tags: - \u0026#39;v*.*.*\u0026#39; pull_request: branches: - main env: REGISTRY: ghcr.io IMAGE_NAME: ${{ github.repository }} jobs: build-and-push: runs-on: ubuntu-latest permissions: contents: read packages: write steps: # 1. 소스코드 체크아웃 - name: Checkout repository uses: actions/checkout@v4 # 2. QEMU 설정 (멀티 아키텍처 빌드용) - name: Set up QEMU uses: docker/setup-qemu-action@v3 # 3. Docker Buildx 설정 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 # 4. GHCR 로그인 (GITHUB_TOKEN 사용) - name: Log in to GitHub Container Registry if: github.event_name != \u0026#39;pull_request\u0026#39; uses: docker/login-action@v3 with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} # 5. Docker 메타데이터(태그, 라벨) 추출 - name: Extract Docker metadata id: meta uses: docker/metadata-action@v5 with: images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} tags: | type=raw,value=latest,enable=${{ github.ref == \u0026#39;refs/heads/main\u0026#39; }} type=semver,pattern={{version}} type=sha,format=short # 6. Docker 이미지 빌드 및 GHCR 푸시 (GHA 캐시 재사용) - name: Build and push Docker image uses: docker/build-push-action@v6 with: context: . platforms: linux/amd64,linux/arm64 push: ${{ github.event_name != \u0026#39;pull_request\u0026#39; }} tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} # GitHub Actions 전용 캐시 사용 (Build Speedup의 핵심!) cache-from: type=gha cache-to: type=gha,mode=max 3. Dockerfile 작성 베스트 프랙티스 (캐시 효율 극대화) Actions 워크플로우에 cache-from: type=gha를 설정했더라도, Dockerfile의 레이어 순서가 적절하지 않으면 캐시가 무효화됩니다.\nFROM node:20-alpine AS builder WORKDIR /app # 1. 패키지 의존성 정의 파일만 먼저 복사 COPY package.json package-lock.json ./ # 2. 의존성 설치 (소스코드가 변경되어도 이 레이어까지는 캐시 유지됨) RUN npm ci # 3. 그 후 전체 소스코드 복사 및 빌드 COPY . . RUN npm run build # 실행용 경량 스테이지 (Multi-stage build) FROM node:20-alpine AS runner WORKDIR /app COPY --from=builder /app/dist ./dist COPY --from=builder /app/node_modules ./node_modules EXPOSE 3000 CMD [\u0026#34;node\u0026#34;, \u0026#34;dist/index.js\u0026#34;] 4. 빌드 결과 확인 및 레지스트리 접근 권한 설정 GitHub 레포지토리 메인 페이지 우측의 Packages 섹션에서 빌드 완료된 도커 이미지를 확인할 수 있습니다. 기본 권한이 Private인 경우, 다른 서버에서 docker pull을 받기 위해 ghcr.io 로그인 후 사용하거나 Package Settings에서 접근 권한(Public / Private)을 조정할 수 있습니다. # 로컬 또는 다른 서버에서 GHCR 이미지 다운로드 테스트 echo \u0026lt;PERSONAL_ACCESS_TOKEN\u0026gt; | docker login ghcr.io -u \u0026lt;GITHUB_USERNAME\u0026gt; --password-stdin docker pull ghcr.io/your-username/your-repo:latest 마무리 Buildx와 type=gha 캐시 설정을 적용하면 이후 빌드 시 의존성이 변경되지 않은 레이어는 즉시 캐시 처리되어 매우 빠른 속도로 CI/CD가 완료됩니다.\n","permalink":"https://wkqco33.github.io/wkqcosoft-docs/posts/github-actions-docker-ghcr/","summary":"\u003cp\u003eGitHub Actions를 사용하여 컨테이너 이미지를 빌드하고 **GHCR(GitHub Container Registry)**에 자동 배포할 때, \u003cstrong\u003eBuildx\u003c/strong\u003e와 **GitHub Actions 전용 빌드 캐시(\u003ccode\u003etype=gha\u003c/code\u003e)**를 적용하여 CI/CD 시간을 크게 단축하는 워크플로우 가이드입니다.\u003c/p\u003e\n\u003chr\u003e\n\u003ch2 id=\"1-주요-특징-및-이점\"\u003e1. 주요 특징 및 이점\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003eGHCR 활용\u003c/strong\u003e: 별도의 Docker Hub 계정이나 외부 레지스트리 비번 설정 없이 \u003ccode\u003eGITHUB_TOKEN\u003c/code\u003e 인증만으로 안전하게 컨테이너 레지스트리에 푸시.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e\u003ccode\u003etype=gha\u003c/code\u003e 캐시\u003c/strong\u003e: 빌드 레이어 캐시를 GitHub Actions 백엔드에 저장하여 동일한 의존성 재빌드 시간을 극적으로 줄임 (최대 80%+ 속도 향상).\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eMulti-platform 지원\u003c/strong\u003e: QEMU를 연동하여 \u003ccode\u003elinux/amd64\u003c/code\u003e와 \u003ccode\u003elinux/arm64\u003c/code\u003e 이미지를 단일 작업에서 동시 생성.\u003c/li\u003e\n\u003c/ul\u003e\n\u003chr\u003e\n\u003ch2 id=\"2-github-actions-워크플로우-작성\"\u003e2. GitHub Actions 워크플로우 작성\u003c/h2\u003e\n\u003cp\u003e\u003ccode\u003e.github/workflows/docker-build.yml\u003c/code\u003e 경로에 아래 내용을 작성합니다.\u003c/p\u003e","title":"GitHub Actions Docker 빌드 최적화 및 GHCR 배포 가이드"},{"content":"쿠버네티스 클러스터 내부에서 실행되는 웹 애플리케이션을 외부에 HTTPS 보안 연결로 노출하기 위해 Ingress Nginx Controller와 Cert-Manager(Let\u0026rsquo;s Encrypt 자동 갱신)를 구축하는 실무 가이드입니다.\n1. 아키텍처 흐름 [ [ [ 클 N C C 라 g l e 이 i u r 언 n s t 트 x t - │ ▼ │ ▼ e M ( I r a B H n H I n r T g T P a o T r T g w P e P S e s S s e r e s ( r : r ( P v ) P C o i C o o r c l ] r n t e u t t s r 8 ] t 4 o 0 e 4 l ) ─ r 3 l ─ I ) e \u0026gt; s r s [ u ] e P r ─ o 를 ─ d ( s 통 T 해 L ] S L e T t e ' r s m i E n n a c t r i y o p n t / 서 버 S 와 e c 통 r 신 e 하 t 여 ) S S L 인 증 서 를 자 동 으 로 발 급 및 K 8 s S e c r e t 으 로 저 장 . 2. Nginx Ingress Controller 설치 Helm을 사용하여 Nginx Ingress Controller를 설치합니다.\n# Helm 저장소 추가 helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx helm repo update # ingress-nginx 네임스페이스에 설치 helm install ingress-nginx ingress-nginx/ingress-nginx \\ --create-namespace \\ --namespace ingress-nginx # External-IP 또는 NodePort 할당 확인 kubectl get svc -n ingress-nginx ingress-nginx-controller 3. Cert-Manager 설치 Kubernetes 내부에서 TLS 인증서를 생명주기 관리해 주는 Cert-Manager를 설치합니다.\n# Helm 저장소 추가 helm repo add jetstack https://charts.jetstack.io helm repo update # CRD 설치와 함께 cert-manager 설치 helm install cert-manager jetstack/cert-manager \\ --create-namespace \\ --namespace cert-manager \\ --version v1.13.3 \\ --set installCRDs=true # 정상 실행 확인 kubectl get pods -n cert-manager 4. Let\u0026rsquo;s Encrypt ClusterIssuer 생성 ClusterIssuer는 클러스터 전체에서 인증서를 요청할 수 있는 발급 기관(CA) 설정입니다.\n# cluster-issuer.yaml apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: letsencrypt-prod spec: acme: # Let\u0026#39;s Encrypt 프로덕션 서버 주소 server: https://acme-v02.api.letsencrypt.org/directory email: your-email@example.com # 만료 알림을 받을 이메일 주소 입력 privateKeySecretRef: name: letsencrypt-prod-private-key solvers: - http01: ingress: class: nginx kubectl apply -f cluster-issuer.yaml 5. Ingress 리소스 작성 및 SSL 자동 발급 적용 애플리케이션 Ingress 정의 시 cert-manager.io/cluster-issuer 어노테이션을 추가하면, Cert-Manager가 자동으로 HTTP-01 챌린지를 진행하고 SSL 인증서를 K8s Secret으로 발급해 줍니다.\n# app-ingress.yaml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: my-app-ingress namespace: default annotations: kubernetes.io/ingress.class: \u0026#34;nginx\u0026#34; cert-manager.io/cluster-issuer: \u0026#34;letsencrypt-prod\u0026#34; nginx.ingress.kubernetes.io/ssl-redirect: \u0026#34;true\u0026#34; spec: tls: - hosts: - app.yourdomain.com # 실제 도메인 주소 secretName: my-app-tls-secret # 인증서가 저장될 K8s Secret 이름 rules: - host: app.yourdomain.com http: paths: - path: / pathType: Prefix backend: service: name: my-app-service port: number: 80 kubectl apply -f app-ingress.yaml 6. 발급 상태 및 트러블슈팅 확인 # 인증서 발급 진행 상태 확인 (READY가 True여야 함) kubectl get certificate -n default # Cert-Manager 발급 요청 및 챌린지 상세 확인 kubectl describe certificate my-app-tls-secret kubectl get challenges,orders -n default # 발급된 TLS 시크릿 확인 kubectl get secret my-app-tls-secret -o yaml 마무리 이 설정을 완료하면 도메인에 대한 HTTPS 암호화 통신이 적용되며, Let\u0026rsquo;s Encrypt 인증서 만료일 30일 전 Cert-Manager가 알아서 신규 인증서로 갱신하므로 무중단 보안 운영이 가능해집니다.\n","permalink":"https://wkqco33.github.io/wkqcosoft-docs/posts/k8s-ingress-cert-manager/","summary":"\u003cp\u003e쿠버네티스 클러스터 내부에서 실행되는 웹 애플리케이션을 외부에 HTTPS 보안 연결로 노출하기 위해 \u003cstrong\u003eIngress Nginx Controller\u003c/strong\u003e와 \u003cstrong\u003eCert-Manager\u003c/strong\u003e(Let\u0026rsquo;s Encrypt 자동 갱신)를 구축하는 실무 가이드입니다.\u003c/p\u003e\n\u003chr\u003e\n\u003ch2 id=\"1-아키텍처-흐름\"\u003e1. 아키텍처 흐름\u003c/h2\u003e\n\n\n\n\u003cdiv class=\"goat svg-container \"\u003e\n  \n    \u003csvg\n      xmlns=\"http://www.w3.org/2000/svg\"\n      font-family=\"Menlo,Lucida Console,monospace\"\n      \n        viewBox=\"0 0 744 153\"\n      \u003e\n      \u003cg transform='translate(8,16)'\u003e\n\u003ccircle cx='0' cy='128' r='6' stroke='currentColor' fill='currentColor'\u003e\u003c/circle\u003e\n\u003ctext text-anchor='middle' x='0' y='4' fill='currentColor' style='font-size:1em'\u003e[\u003c/text\u003e\n\u003ctext text-anchor='middle' x='0' y='52' fill='currentColor' style='font-size:1em'\u003e[\u003c/text\u003e\n\u003ctext text-anchor='middle' x='0' y='100' fill='currentColor' style='font-size:1em'\u003e[\u003c/text\u003e\n\u003ctext text-anchor='middle' x='16' y='4' fill='currentColor' style='font-size:1em'\u003e클\u003c/text\u003e\n\u003ctext text-anchor='middle' x='16' y='52' fill='currentColor' style='font-size:1em'\u003eN\u003c/text\u003e\n\u003ctext text-anchor='middle' x='16' y='100' fill='currentColor' style='font-size:1em'\u003eC\u003c/text\u003e\n\u003ctext text-anchor='middle' x='16' y='132' fill='currentColor' style='font-size:1em'\u003eC\u003c/text\u003e\n\u003ctext text-anchor='middle' x='24' y='4' fill='currentColor' style='font-size:1em'\u003e라\u003c/text\u003e\n\u003ctext text-anchor='middle' x='24' y='52' fill='currentColor' style='font-size:1em'\u003eg\u003c/text\u003e\n\u003ctext text-anchor='middle' x='24' y='100' fill='currentColor' style='font-size:1em'\u003el\u003c/text\u003e\n\u003ctext text-anchor='middle' x='24' y='132' fill='currentColor' style='font-size:1em'\u003ee\u003c/text\u003e\n\u003ctext text-anchor='middle' x='32' y='4' fill='currentColor' style='font-size:1em'\u003e이\u003c/text\u003e\n\u003ctext text-anchor='middle' x='32' y='52' fill='currentColor' style='font-size:1em'\u003ei\u003c/text\u003e\n\u003ctext text-anchor='middle' x='32' y='100' fill='currentColor' style='font-size:1em'\u003eu\u003c/text\u003e\n\u003ctext text-anchor='middle' x='32' y='132' fill='currentColor' style='font-size:1em'\u003er\u003c/text\u003e\n\u003ctext text-anchor='middle' x='40' y='4' fill='currentColor' style='font-size:1em'\u003e언\u003c/text\u003e\n\u003ctext text-anchor='middle' x='40' y='52' fill='currentColor' style='font-size:1em'\u003en\u003c/text\u003e\n\u003ctext text-anchor='middle' x='40' y='100' fill='currentColor' style='font-size:1em'\u003es\u003c/text\u003e\n\u003ctext text-anchor='middle' x='40' y='132' fill='currentColor' style='font-size:1em'\u003et\u003c/text\u003e\n\u003ctext text-anchor='middle' x='48' y='4' fill='currentColor' style='font-size:1em'\u003e트\u003c/text\u003e\n\u003ctext text-anchor='middle' x='48' y='52' fill='currentColor' style='font-size:1em'\u003ex\u003c/text\u003e\n\u003ctext text-anchor='middle' x='48' y='100' fill='currentColor' style='font-size:1em'\u003et\u003c/text\u003e\n\u003ctext text-anchor='middle' x='48' y='132' fill='currentColor' style='font-size:1em'\u003e-\u003c/text\u003e\n\u003ctext text-anchor='middle' x='56' y='20' fill='currentColor' style='font-size:1em'\u003e│\u003c/text\u003e\n\u003ctext text-anchor='middle' x='56' y='36' fill='currentColor' style='font-size:1em'\u003e▼\u003c/text\u003e\n\u003ctext text-anchor='middle' x='56' y='68' fill='currentColor' style='font-size:1em'\u003e│\u003c/text\u003e\n\u003ctext text-anchor='middle' x='56' y='84' fill='currentColor' style='font-size:1em'\u003e▼\u003c/text\u003e\n\u003ctext text-anchor='middle' x='56' y='100' fill='currentColor' style='font-size:1em'\u003ee\u003c/text\u003e\n\u003ctext text-anchor='middle' x='56' y='132' fill='currentColor' style='font-size:1em'\u003eM\u003c/text\u003e\n\u003ctext text-anchor='middle' x='64' y='4' fill='currentColor' style='font-size:1em'\u003e(\u003c/text\u003e\n\u003ctext text-anchor='middle' x='64' y='52' fill='currentColor' style='font-size:1em'\u003eI\u003c/text\u003e\n\u003ctext text-anchor='middle' x='64' y='100' fill='currentColor' style='font-size:1em'\u003er\u003c/text\u003e\n\u003ctext text-anchor='middle' x='64' y='132' fill='currentColor' style='font-size:1em'\u003ea\u003c/text\u003e\n\u003ctext text-anchor='middle' x='72' y='4' fill='currentColor' style='font-size:1em'\u003eB\u003c/text\u003e\n\u003ctext text-anchor='middle' x='72' y='20' fill='currentColor' style='font-size:1em'\u003eH\u003c/text\u003e\n\u003ctext text-anchor='middle' x='72' y='52' fill='currentColor' style='font-size:1em'\u003en\u003c/text\u003e\n\u003ctext text-anchor='middle' x='72' y='68' fill='currentColor' style='font-size:1em'\u003eH\u003c/text\u003e\n\u003ctext text-anchor='middle' x='72' y='100' fill='currentColor' style='font-size:1em'\u003eI\u003c/text\u003e\n\u003ctext text-anchor='middle' x='72' y='132' fill='currentColor' style='font-size:1em'\u003en\u003c/text\u003e\n\u003ctext text-anchor='middle' x='80' y='4' fill='currentColor' style='font-size:1em'\u003er\u003c/text\u003e\n\u003ctext text-anchor='middle' x='80' y='20' fill='currentColor' style='font-size:1em'\u003eT\u003c/text\u003e\n\u003ctext text-anchor='middle' x='80' y='52' fill='currentColor' style='font-size:1em'\u003eg\u003c/text\u003e\n\u003ctext text-anchor='middle' x='80' y='68' fill='currentColor' style='font-size:1em'\u003eT\u003c/text\u003e\n\u003ctext text-anchor='middle' x='80' y='100' fill='currentColor' style='font-size:1em'\u003eP\u003c/text\u003e\n\u003ctext text-anchor='middle' x='80' y='132' fill='currentColor' style='font-size:1em'\u003ea\u003c/text\u003e\n\u003ctext text-anchor='middle' x='88' y='4' fill='currentColor' style='font-size:1em'\u003eo\u003c/text\u003e\n\u003ctext text-anchor='middle' x='88' y='20' fill='currentColor' style='font-size:1em'\u003eT\u003c/text\u003e\n\u003ctext text-anchor='middle' x='88' y='52' fill='currentColor' style='font-size:1em'\u003er\u003c/text\u003e\n\u003ctext text-anchor='middle' x='88' y='68' fill='currentColor' style='font-size:1em'\u003eT\u003c/text\u003e\n\u003ctext text-anchor='middle' x='88' y='132' fill='currentColor' style='font-size:1em'\u003eg\u003c/text\u003e\n\u003ctext text-anchor='middle' x='96' y='4' fill='currentColor' style='font-size:1em'\u003ew\u003c/text\u003e\n\u003ctext text-anchor='middle' x='96' y='20' fill='currentColor' style='font-size:1em'\u003eP\u003c/text\u003e\n\u003ctext text-anchor='middle' x='96' y='52' fill='currentColor' style='font-size:1em'\u003ee\u003c/text\u003e\n\u003ctext text-anchor='middle' x='96' y='68' fill='currentColor' style='font-size:1em'\u003eP\u003c/text\u003e\n\u003ctext text-anchor='middle' x='96' y='100' fill='currentColor' style='font-size:1em'\u003eS\u003c/text\u003e\n\u003ctext text-anchor='middle' x='96' y='132' fill='currentColor' style='font-size:1em'\u003ee\u003c/text\u003e\n\u003ctext text-anchor='middle' x='104' y='4' fill='currentColor' style='font-size:1em'\u003es\u003c/text\u003e\n\u003ctext text-anchor='middle' x='104' y='20' fill='currentColor' style='font-size:1em'\u003eS\u003c/text\u003e\n\u003ctext text-anchor='middle' x='104' y='52' fill='currentColor' style='font-size:1em'\u003es\u003c/text\u003e\n\u003ctext text-anchor='middle' x='104' y='100' fill='currentColor' style='font-size:1em'\u003ee\u003c/text\u003e\n\u003ctext text-anchor='middle' x='104' y='132' fill='currentColor' style='font-size:1em'\u003er\u003c/text\u003e\n\u003ctext text-anchor='middle' x='112' y='4' fill='currentColor' style='font-size:1em'\u003ee\u003c/text\u003e\n\u003ctext text-anchor='middle' x='112' y='52' fill='currentColor' style='font-size:1em'\u003es\u003c/text\u003e\n\u003ctext text-anchor='middle' x='112' y='68' fill='currentColor' style='font-size:1em'\u003e(\u003c/text\u003e\n\u003ctext text-anchor='middle' x='112' y='100' fill='currentColor' style='font-size:1em'\u003er\u003c/text\u003e\n\u003ctext text-anchor='middle' x='112' y='132' fill='currentColor' style='font-size:1em'\u003e:\u003c/text\u003e\n\u003ctext text-anchor='middle' x='120' y='4' fill='currentColor' style='font-size:1em'\u003er\u003c/text\u003e\n\u003ctext text-anchor='middle' x='120' y='20' fill='currentColor' style='font-size:1em'\u003e(\u003c/text\u003e\n\u003ctext text-anchor='middle' x='120' y='68' fill='currentColor' style='font-size:1em'\u003eP\u003c/text\u003e\n\u003ctext text-anchor='middle' x='120' y='100' fill='currentColor' style='font-size:1em'\u003ev\u003c/text\u003e\n\u003ctext text-anchor='middle' x='128' y='4' fill='currentColor' style='font-size:1em'\u003e)\u003c/text\u003e\n\u003ctext text-anchor='middle' x='128' y='20' fill='currentColor' style='font-size:1em'\u003eP\u003c/text\u003e\n\u003ctext text-anchor='middle' x='128' y='52' fill='currentColor' style='font-size:1em'\u003eC\u003c/text\u003e\n\u003ctext text-anchor='middle' x='128' y='68' fill='currentColor' style='font-size:1em'\u003eo\u003c/text\u003e\n\u003ctext text-anchor='middle' x='128' y='100' fill='currentColor' style='font-size:1em'\u003ei\u003c/text\u003e\n\u003ctext text-anchor='middle' x='128' y='132' fill='currentColor' style='font-size:1em'\u003eC\u003c/text\u003e\n\u003ctext text-anchor='middle' x='136' y='20' fill='currentColor' style='font-size:1em'\u003eo\u003c/text\u003e\n\u003ctext text-anchor='middle' x='136' y='52' fill='currentColor' style='font-size:1em'\u003eo\u003c/text\u003e\n\u003ctext text-anchor='middle' x='136' y='68' fill='currentColor' style='font-size:1em'\u003er\u003c/text\u003e\n\u003ctext text-anchor='middle' x='136' y='100' fill='currentColor' style='font-size:1em'\u003ec\u003c/text\u003e\n\u003ctext text-anchor='middle' x='136' y='132' fill='currentColor' style='font-size:1em'\u003el\u003c/text\u003e\n\u003ctext text-anchor='middle' x='144' y='4' fill='currentColor' style='font-size:1em'\u003e]\u003c/text\u003e\n\u003ctext text-anchor='middle' x='144' y='20' fill='currentColor' style='font-size:1em'\u003er\u003c/text\u003e\n\u003ctext text-anchor='middle' x='144' y='52' fill='currentColor' style='font-size:1em'\u003en\u003c/text\u003e\n\u003ctext text-anchor='middle' x='144' y='68' fill='currentColor' style='font-size:1em'\u003et\u003c/text\u003e\n\u003ctext text-anchor='middle' x='144' y='100' fill='currentColor' style='font-size:1em'\u003ee\u003c/text\u003e\n\u003ctext text-anchor='middle' x='144' y='132' fill='currentColor' style='font-size:1em'\u003eu\u003c/text\u003e\n\u003ctext text-anchor='middle' x='152' y='20' fill='currentColor' style='font-size:1em'\u003et\u003c/text\u003e\n\u003ctext text-anchor='middle' x='152' y='52' fill='currentColor' style='font-size:1em'\u003et\u003c/text\u003e\n\u003ctext text-anchor='middle' x='152' y='132' fill='currentColor' style='font-size:1em'\u003es\u003c/text\u003e\n\u003ctext text-anchor='middle' x='160' y='52' fill='currentColor' style='font-size:1em'\u003er\u003c/text\u003e\n\u003ctext text-anchor='middle' x='160' y='68' fill='currentColor' style='font-size:1em'\u003e8\u003c/text\u003e\n\u003ctext text-anchor='middle' x='160' y='100' fill='currentColor' style='font-size:1em'\u003e]\u003c/text\u003e\n\u003ctext text-anchor='middle' x='160' y='132' fill='currentColor' style='font-size:1em'\u003et\u003c/text\u003e\n\u003ctext text-anchor='middle' x='168' y='20' fill='currentColor' style='font-size:1em'\u003e4\u003c/text\u003e\n\u003ctext text-anchor='middle' x='168' y='52' fill='currentColor' style='font-size:1em'\u003eo\u003c/text\u003e\n\u003ctext text-anchor='middle' x='168' y='68' fill='currentColor' style='font-size:1em'\u003e0\u003c/text\u003e\n\u003ctext text-anchor='middle' x='168' y='132' fill='currentColor' style='font-size:1em'\u003ee\u003c/text\u003e\n\u003ctext text-anchor='middle' x='176' y='20' fill='currentColor' style='font-size:1em'\u003e4\u003c/text\u003e\n\u003ctext text-anchor='middle' x='176' y='52' fill='currentColor' style='font-size:1em'\u003el\u003c/text\u003e\n\u003ctext text-anchor='middle' x='176' y='68' fill='currentColor' style='font-size:1em'\u003e)\u003c/text\u003e\n\u003ctext text-anchor='middle' x='176' y='100' fill='currentColor' style='font-size:1em'\u003e─\u003c/text\u003e\n\u003ctext text-anchor='middle' x='176' y='132' fill='currentColor' style='font-size:1em'\u003er\u003c/text\u003e\n\u003ctext text-anchor='middle' x='184' y='20' fill='currentColor' style='font-size:1em'\u003e3\u003c/text\u003e\n\u003ctext text-anchor='middle' x='184' y='52' fill='currentColor' style='font-size:1em'\u003el\u003c/text\u003e\n\u003ctext text-anchor='middle' x='184' y='100' fill='currentColor' style='font-size:1em'\u003e─\u003c/text\u003e\n\u003ctext text-anchor='middle' x='184' y='132' fill='currentColor' style='font-size:1em'\u003eI\u003c/text\u003e\n\u003ctext text-anchor='middle' x='192' y='20' fill='currentColor' style='font-size:1em'\u003e)\u003c/text\u003e\n\u003ctext text-anchor='middle' x='192' y='52' fill='currentColor' style='font-size:1em'\u003ee\u003c/text\u003e\n\u003ctext text-anchor='middle' x='192' y='100' fill='currentColor' style='font-size:1em'\u003e\u0026gt;\u003c/text\u003e\n\u003ctext text-anchor='middle' x='192' y='132' fill='currentColor' style='font-size:1em'\u003es\u003c/text\u003e\n\u003ctext text-anchor='middle' x='200' y='52' fill='currentColor' style='font-size:1em'\u003er\u003c/text\u003e\n\u003ctext text-anchor='middle' x='200' y='132' fill='currentColor' style='font-size:1em'\u003es\u003c/text\u003e\n\u003ctext text-anchor='middle' x='208' y='100' fill='currentColor' style='font-size:1em'\u003e[\u003c/text\u003e\n\u003ctext text-anchor='middle' x='208' y='132' fill='currentColor' style='font-size:1em'\u003eu\u003c/text\u003e\n\u003ctext text-anchor='middle' x='216' y='52' fill='currentColor' style='font-size:1em'\u003e]\u003c/text\u003e\n\u003ctext text-anchor='middle' x='216' y='132' fill='currentColor' style='font-size:1em'\u003ee\u003c/text\u003e\n\u003ctext text-anchor='middle' x='224' y='100' fill='currentColor' style='font-size:1em'\u003eP\u003c/text\u003e\n\u003ctext text-anchor='middle' x='224' y='132' fill='currentColor' style='font-size:1em'\u003er\u003c/text\u003e\n\u003ctext text-anchor='middle' x='232' y='52' fill='currentColor' style='font-size:1em'\u003e─\u003c/text\u003e\n\u003ctext text-anchor='middle' x='232' y='100' fill='currentColor' style='font-size:1em'\u003eo\u003c/text\u003e\n\u003ctext text-anchor='middle' x='232' y='132' fill='currentColor' style='font-size:1em'\u003e를\u003c/text\u003e\n\u003ctext text-anchor='middle' x='240' y='52' fill='currentColor' style='font-size:1em'\u003e─\u003c/text\u003e\n\u003ctext text-anchor='middle' x='240' y='100' fill='currentColor' style='font-size:1em'\u003ed\u003c/text\u003e\n\u003ctext text-anchor='middle' x='248' y='52' fill='currentColor' style='font-size:1em'\u003e(\u003c/text\u003e\n\u003ctext text-anchor='middle' x='248' y='100' fill='currentColor' style='font-size:1em'\u003es\u003c/text\u003e\n\u003ctext text-anchor='middle' x='248' y='132' fill='currentColor' style='font-size:1em'\u003e통\u003c/text\u003e\n\u003ctext text-anchor='middle' x='256' y='52' fill='currentColor' style='font-size:1em'\u003eT\u003c/text\u003e\n\u003ctext text-anchor='middle' x='256' y='132' fill='currentColor' style='font-size:1em'\u003e해\u003c/text\u003e\n\u003ctext text-anchor='middle' x='264' y='52' fill='currentColor' style='font-size:1em'\u003eL\u003c/text\u003e\n\u003ctext text-anchor='middle' x='264' y='100' fill='currentColor' style='font-size:1em'\u003e]\u003c/text\u003e\n\u003ctext text-anchor='middle' x='272' y='52' fill='currentColor' style='font-size:1em'\u003eS\u003c/text\u003e\n\u003ctext text-anchor='middle' x='272' y='132' fill='currentColor' style='font-size:1em'\u003eL\u003c/text\u003e\n\u003ctext text-anchor='middle' x='280' y='132' fill='currentColor' style='font-size:1em'\u003ee\u003c/text\u003e\n\u003ctext text-anchor='middle' x='288' y='52' fill='currentColor' style='font-size:1em'\u003eT\u003c/text\u003e\n\u003ctext text-anchor='middle' x='288' y='132' fill='currentColor' style='font-size:1em'\u003et\u003c/text\u003e\n\u003ctext text-anchor='middle' x='296' y='52' fill='currentColor' style='font-size:1em'\u003ee\u003c/text\u003e\n\u003ctext text-anchor='middle' x='296' y='132' fill='currentColor' style='font-size:1em'\u003e'\u003c/text\u003e\n\u003ctext text-anchor='middle' x='304' y='52' fill='currentColor' style='font-size:1em'\u003er\u003c/text\u003e\n\u003ctext text-anchor='middle' x='304' y='132' fill='currentColor' style='font-size:1em'\u003es\u003c/text\u003e\n\u003ctext text-anchor='middle' x='312' y='52' fill='currentColor' style='font-size:1em'\u003em\u003c/text\u003e\n\u003ctext text-anchor='middle' x='320' y='52' fill='currentColor' style='font-size:1em'\u003ei\u003c/text\u003e\n\u003ctext text-anchor='middle' x='320' y='132' fill='currentColor' style='font-size:1em'\u003eE\u003c/text\u003e\n\u003ctext text-anchor='middle' x='328' y='52' fill='currentColor' style='font-size:1em'\u003en\u003c/text\u003e\n\u003ctext text-anchor='middle' x='328' y='132' fill='currentColor' style='font-size:1em'\u003en\u003c/text\u003e\n\u003ctext text-anchor='middle' x='336' y='52' fill='currentColor' style='font-size:1em'\u003ea\u003c/text\u003e\n\u003ctext text-anchor='middle' x='336' y='132' fill='currentColor' style='font-size:1em'\u003ec\u003c/text\u003e\n\u003ctext text-anchor='middle' x='344' y='52' fill='currentColor' style='font-size:1em'\u003et\u003c/text\u003e\n\u003ctext text-anchor='middle' x='344' y='132' fill='currentColor' style='font-size:1em'\u003er\u003c/text\u003e\n\u003ctext text-anchor='middle' x='352' y='52' fill='currentColor' style='font-size:1em'\u003ei\u003c/text\u003e\n\u003ctext text-anchor='middle' x='352' y='132' fill='currentColor' style='font-size:1em'\u003ey\u003c/text\u003e\n\u003ctext text-anchor='middle' x='360' y='52' fill='currentColor' style='font-size:1em'\u003eo\u003c/text\u003e\n\u003ctext text-anchor='middle' x='360' y='132' fill='currentColor' style='font-size:1em'\u003ep\u003c/text\u003e\n\u003ctext text-anchor='middle' x='368' y='52' fill='currentColor' style='font-size:1em'\u003en\u003c/text\u003e\n\u003ctext text-anchor='middle' x='368' y='132' fill='currentColor' style='font-size:1em'\u003et\u003c/text\u003e\n\u003ctext text-anchor='middle' x='384' y='52' fill='currentColor' style='font-size:1em'\u003e/\u003c/text\u003e\n\u003ctext text-anchor='middle' x='384' y='132' fill='currentColor' style='font-size:1em'\u003e서\u003c/text\u003e\n\u003ctext text-anchor='middle' x='392' y='132' fill='currentColor' style='font-size:1em'\u003e버\u003c/text\u003e\n\u003ctext text-anchor='middle' x='400' y='52' fill='currentColor' style='font-size:1em'\u003eS\u003c/text\u003e\n\u003ctext text-anchor='middle' x='400' y='132' fill='currentColor' style='font-size:1em'\u003e와\u003c/text\u003e\n\u003ctext text-anchor='middle' x='408' y='52' fill='currentColor' style='font-size:1em'\u003ee\u003c/text\u003e\n\u003ctext text-anchor='middle' x='416' y='52' fill='currentColor' style='font-size:1em'\u003ec\u003c/text\u003e\n\u003ctext text-anchor='middle' x='416' y='132' fill='currentColor' style='font-size:1em'\u003e통\u003c/text\u003e\n\u003ctext text-anchor='middle' x='424' y='52' fill='currentColor' style='font-size:1em'\u003er\u003c/text\u003e\n\u003ctext text-anchor='middle' x='424' y='132' fill='currentColor' style='font-size:1em'\u003e신\u003c/text\u003e\n\u003ctext text-anchor='middle' x='432' y='52' fill='currentColor' style='font-size:1em'\u003ee\u003c/text\u003e\n\u003ctext text-anchor='middle' x='432' y='132' fill='currentColor' style='font-size:1em'\u003e하\u003c/text\u003e\n\u003ctext text-anchor='middle' x='440' y='52' fill='currentColor' style='font-size:1em'\u003et\u003c/text\u003e\n\u003ctext text-anchor='middle' x='440' y='132' fill='currentColor' style='font-size:1em'\u003e여\u003c/text\u003e\n\u003ctext text-anchor='middle' x='448' y='52' fill='currentColor' style='font-size:1em'\u003e)\u003c/text\u003e\n\u003ctext text-anchor='middle' x='456' y='132' fill='currentColor' style='font-size:1em'\u003eS\u003c/text\u003e\n\u003ctext text-anchor='middle' x='464' y='132' fill='currentColor' style='font-size:1em'\u003eS\u003c/text\u003e\n\u003ctext text-anchor='middle' x='472' y='132' fill='currentColor' style='font-size:1em'\u003eL\u003c/text\u003e\n\u003ctext text-anchor='middle' x='488' y='132' fill='currentColor' style='font-size:1em'\u003e인\u003c/text\u003e\n\u003ctext text-anchor='middle' x='496' y='132' fill='currentColor' style='font-size:1em'\u003e증\u003c/text\u003e\n\u003ctext text-anchor='middle' x='504' y='132' fill='currentColor' style='font-size:1em'\u003e서\u003c/text\u003e\n\u003ctext text-anchor='middle' x='512' y='132' fill='currentColor' style='font-size:1em'\u003e를\u003c/text\u003e\n\u003ctext text-anchor='middle' x='528' y='132' fill='currentColor' style='font-size:1em'\u003e자\u003c/text\u003e\n\u003ctext text-anchor='middle' x='536' y='132' fill='currentColor' style='font-size:1em'\u003e동\u003c/text\u003e\n\u003ctext text-anchor='middle' x='544' y='132' fill='currentColor' style='font-size:1em'\u003e으\u003c/text\u003e\n\u003ctext text-anchor='middle' x='552' y='132' fill='currentColor' style='font-size:1em'\u003e로\u003c/text\u003e\n\u003ctext text-anchor='middle' x='568' y='132' fill='currentColor' style='font-size:1em'\u003e발\u003c/text\u003e\n\u003ctext text-anchor='middle' x='576' y='132' fill='currentColor' style='font-size:1em'\u003e급\u003c/text\u003e\n\u003ctext text-anchor='middle' x='592' y='132' fill='currentColor' style='font-size:1em'\u003e및\u003c/text\u003e\n\u003ctext text-anchor='middle' x='608' y='132' fill='currentColor' style='font-size:1em'\u003eK\u003c/text\u003e\n\u003ctext text-anchor='middle' x='616' y='132' fill='currentColor' style='font-size:1em'\u003e8\u003c/text\u003e\n\u003ctext text-anchor='middle' x='624' y='132' fill='currentColor' style='font-size:1em'\u003es\u003c/text\u003e\n\u003ctext text-anchor='middle' x='640' y='132' fill='currentColor' style='font-size:1em'\u003eS\u003c/text\u003e\n\u003ctext text-anchor='middle' x='648' y='132' fill='currentColor' style='font-size:1em'\u003ee\u003c/text\u003e\n\u003ctext text-anchor='middle' x='656' y='132' fill='currentColor' style='font-size:1em'\u003ec\u003c/text\u003e\n\u003ctext text-anchor='middle' x='664' y='132' fill='currentColor' style='font-size:1em'\u003er\u003c/text\u003e\n\u003ctext text-anchor='middle' x='672' y='132' fill='currentColor' style='font-size:1em'\u003ee\u003c/text\u003e\n\u003ctext text-anchor='middle' x='680' y='132' fill='currentColor' style='font-size:1em'\u003et\u003c/text\u003e\n\u003ctext text-anchor='middle' x='688' y='132' fill='currentColor' style='font-size:1em'\u003e으\u003c/text\u003e\n\u003ctext text-anchor='middle' x='696' y='132' fill='currentColor' style='font-size:1em'\u003e로\u003c/text\u003e\n\u003ctext text-anchor='middle' x='712' y='132' fill='currentColor' style='font-size:1em'\u003e저\u003c/text\u003e\n\u003ctext text-anchor='middle' x='720' y='132' fill='currentColor' style='font-size:1em'\u003e장\u003c/text\u003e\n\u003ctext text-anchor='middle' x='728' y='132' fill='currentColor' style='font-size:1em'\u003e.\u003c/text\u003e\n\u003c/g\u003e\n\n    \u003c/svg\u003e\n  \n\u003c/div\u003e\n\u003chr\u003e\n\u003ch2 id=\"2-nginx-ingress-controller-설치\"\u003e2. Nginx Ingress Controller 설치\u003c/h2\u003e\n\u003cp\u003eHelm을 사용하여 Nginx Ingress Controller를 설치합니다.\u003c/p\u003e","title":"Kubernetes Ingress Nginx 구축 및 Cert-Manager SSL 자동 발급 가이드"},{"content":"최근 로컬 환경에서 오픈소스 대형 언어 모델(LLM)을 실행할 수 있는 Ollama와 ChatGPT 스타일의 웹 인터페이스를 제공하는 Open-WebUI를 조합하여 기업 내부나 로컬PC에 프라이빗 AI 챗봇 환경을 구축하는 사례가 늘고 있습니다.\n이 가이드에서는 Docker Compose를 활용하여 GPU 가속이 지원되는 프라이빗 AI 챗봇 시스템을 손쉽게 구축하는 방법을 설명합니다.\n1. 아키텍처 개요 Ollama: Llama 3.1, Gemma 2, Mistral, Qwen 2.5 등 오픈소스 LLM 모델을 로컬에서 효율적으로 실행하고 REST API를 제공하는 백엔드 엔진. Open-WebUI: Ollama REST API와 연동하여 웹 브라우저에서 대화, 모델 변경, 문서 기반 RAG(Retrieval-Augmented Generation), 사용자 관리 등을 지원하는 웹 프론트엔드. [ 웹 브 라 우 저 ( 사 용 자 ) ] ─ ─ ( H T T P 3 0 0 0 ) ─ ─ \u0026gt; [ O p e n - W e b U I ] ─ ─ ( R E S T 1 1 4 3 4 ) ─ ─ \u0026gt; [ O l l a m a 엔 진 ( N V I D I A G P U ) ] 2. 사전 준비사항 Docker \u0026amp; Docker Compose 설치 완료 NVIDIA GPU 드라이버 및 NVIDIA Container Toolkit 설치 완료 (GPU 사용 시) GPU가 없더라도 CPU 모드로 실행 가능합니다. 3. Docker Compose 구성 docker-compose.yml 파일을 작성하여 Ollama와 Open-WebUI 서비스를 구성합니다.\nversion: \u0026#39;3.8\u0026#39; services: ollama: image: ollama/ollama:latest container_name: ollama restart: unless-stopped ports: - \u0026#34;11434:11434\u0026#34; volumes: - ollama_storage:/root/.ollama # NVIDIA GPU 가속 사용 설정 deploy: resources: reservations: devices: - driver: nvidia count: all capabilities: [gpu] open-webui: image: ghcr.io/open-webui/open-webui:main container_name: open-webui restart: unless-stopped ports: - \u0026#34;3000:8080\u0026#34; environment: - OLLAMA_BASE_URL=http://ollama:11434 - WEBUI_SECRET_KEY=secret_key_change_me_in_production volumes: - open-webui_storage:/app/backend/data depends_on: - ollama volumes: ollama_storage: open-webui_storage: 4. 서비스 실행 및 모델 다운로드 서비스 백그라운드 실행 docker compose up -d 컨테이너 상태 확인 docker compose ps Ollama LLM 모델 다운로드 (Pull) 컨테이너 내부 접속 없이 명령어로 모델을 바로 수급할 수 있습니다.\n# Llama 3.1 (8B) 모델 다운로드 docker exec -it ollama ollama pull llama3.1 # Qwen 2.5 (7B) 모델 다운로드 docker exec -it ollama ollama pull qwen2.5:7b # 설치된 모델 목록 확인 docker exec -it ollama ollama list 5. Open-WebUI 접속 및 설정 웹 브라우저를 열고 http://localhost:3000 (또는 서버 IP)로 접속합니다. 첫 접속 시 관리자(Admin) 계정 회원가입을 진행합니다. 상단 모델 선택 드롭다운에서 다운로드한 llama3.1 또는 qwen2.5:7b 모델을 선택하고 대화를 시작합니다. 6. 고급 기능 활용 (RAG \u0026amp; 파인튜닝) 문서 기반 질문 답변 (RAG): Open-WebUI 채팅 입력창의 + 버튼 또는 문서(Documents) 탭에서 PDF, TXT, DOCX 파일을 업로드하면 해당 문서 내용을 참조하여 답변을 생성합니다. 웹 검색 연동 (Web Search): 설정(Settings) \u0026gt; Web Search에서 SearXNG 또는 DuckDuckGo API를 연동하면 실시간 웹 정보를 가져와 답변합니다. Custom System Prompt: 특정 페르소나나 응답 규칙(예: \u0026ldquo;항상 한국어로 간결하게 답해줘\u0026rdquo;)을 시스템 프롬프트로 지정 가능합니다. 마무리 Ollama와 Open-WebUI 조합은 외부 인터넷 연결이나 API 비용 지불 없이 조직 내부의 데이터 보안을 완벽히 유지하면서 고성능 LLM 인프라를 손쉽게 구축할 수 있는 최상의 솔루션입니다.\n","permalink":"https://wkqco33.github.io/wkqcosoft-docs/posts/ollama-open-webui/","summary":"\u003cp\u003e최근 로컬 환경에서 오픈소스 대형 언어 모델(LLM)을 실행할 수 있는 \u003cstrong\u003eOllama\u003c/strong\u003e와 ChatGPT 스타일의 웹 인터페이스를 제공하는 \u003cstrong\u003eOpen-WebUI\u003c/strong\u003e를 조합하여 기업 내부나 로컬PC에 프라이빗 AI 챗봇 환경을 구축하는 사례가 늘고 있습니다.\u003c/p\u003e\n\u003cp\u003e이 가이드에서는 Docker Compose를 활용하여 GPU 가속이 지원되는 프라이빗 AI 챗봇 시스템을 손쉽게 구축하는 방법을 설명합니다.\u003c/p\u003e\n\u003chr\u003e\n\u003ch2 id=\"1-아키텍처-개요\"\u003e1. 아키텍처 개요\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003eOllama\u003c/strong\u003e: Llama 3.1, Gemma 2, Mistral, Qwen 2.5 등 오픈소스 LLM 모델을 로컬에서 효율적으로 실행하고 REST API를 제공하는 백엔드 엔진.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eOpen-WebUI\u003c/strong\u003e: Ollama REST API와 연동하여 웹 브라우저에서 대화, 모델 변경, 문서 기반 RAG(Retrieval-Augmented Generation), 사용자 관리 등을 지원하는 웹 프론트엔드.\u003c/li\u003e\n\u003c/ul\u003e\n\n\n\n\u003cdiv class=\"goat svg-container \"\u003e\n  \n    \u003csvg\n      xmlns=\"http://www.w3.org/2000/svg\"\n      font-family=\"Menlo,Lucida Console,monospace\"\n      \n        viewBox=\"0 0 752 25\"\n      \u003e\n      \u003cg transform='translate(8,16)'\u003e\n\u003ctext text-anchor='middle' x='0' y='4' fill='currentColor' style='font-size:1em'\u003e[\u003c/text\u003e\n\u003ctext text-anchor='middle' x='16' y='4' fill='currentColor' style='font-size:1em'\u003e웹\u003c/text\u003e\n\u003ctext text-anchor='middle' x='32' y='4' fill='currentColor' style='font-size:1em'\u003e브\u003c/text\u003e\n\u003ctext text-anchor='middle' x='40' y='4' fill='currentColor' style='font-size:1em'\u003e라\u003c/text\u003e\n\u003ctext text-anchor='middle' x='48' y='4' fill='currentColor' style='font-size:1em'\u003e우\u003c/text\u003e\n\u003ctext text-anchor='middle' x='56' y='4' fill='currentColor' style='font-size:1em'\u003e저\u003c/text\u003e\n\u003ctext text-anchor='middle' x='72' y='4' fill='currentColor' style='font-size:1em'\u003e(\u003c/text\u003e\n\u003ctext text-anchor='middle' x='80' y='4' fill='currentColor' style='font-size:1em'\u003e사\u003c/text\u003e\n\u003ctext text-anchor='middle' x='88' y='4' fill='currentColor' style='font-size:1em'\u003e용\u003c/text\u003e\n\u003ctext text-anchor='middle' x='96' y='4' fill='currentColor' style='font-size:1em'\u003e자\u003c/text\u003e\n\u003ctext text-anchor='middle' x='104' y='4' fill='currentColor' style='font-size:1em'\u003e)\u003c/text\u003e\n\u003ctext text-anchor='middle' x='120' y='4' fill='currentColor' style='font-size:1em'\u003e]\u003c/text\u003e\n\u003ctext text-anchor='middle' x='136' y='4' fill='currentColor' style='font-size:1em'\u003e─\u003c/text\u003e\n\u003ctext text-anchor='middle' x='144' y='4' fill='currentColor' style='font-size:1em'\u003e─\u003c/text\u003e\n\u003ctext text-anchor='middle' x='152' y='4' fill='currentColor' style='font-size:1em'\u003e(\u003c/text\u003e\n\u003ctext text-anchor='middle' x='160' y='4' fill='currentColor' style='font-size:1em'\u003eH\u003c/text\u003e\n\u003ctext text-anchor='middle' x='168' y='4' fill='currentColor' style='font-size:1em'\u003eT\u003c/text\u003e\n\u003ctext text-anchor='middle' x='176' y='4' fill='currentColor' style='font-size:1em'\u003eT\u003c/text\u003e\n\u003ctext text-anchor='middle' x='184' y='4' fill='currentColor' style='font-size:1em'\u003eP\u003c/text\u003e\n\u003ctext text-anchor='middle' x='200' y='4' fill='currentColor' style='font-size:1em'\u003e3\u003c/text\u003e\n\u003ctext text-anchor='middle' x='208' y='4' fill='currentColor' style='font-size:1em'\u003e0\u003c/text\u003e\n\u003ctext text-anchor='middle' x='216' y='4' fill='currentColor' style='font-size:1em'\u003e0\u003c/text\u003e\n\u003ctext text-anchor='middle' x='224' y='4' fill='currentColor' style='font-size:1em'\u003e0\u003c/text\u003e\n\u003ctext text-anchor='middle' x='232' y='4' fill='currentColor' style='font-size:1em'\u003e)\u003c/text\u003e\n\u003ctext text-anchor='middle' x='240' y='4' fill='currentColor' style='font-size:1em'\u003e─\u003c/text\u003e\n\u003ctext text-anchor='middle' x='248' y='4' fill='currentColor' style='font-size:1em'\u003e─\u003c/text\u003e\n\u003ctext text-anchor='middle' x='256' y='4' fill='currentColor' style='font-size:1em'\u003e\u0026gt;\u003c/text\u003e\n\u003ctext text-anchor='middle' x='272' y='4' fill='currentColor' style='font-size:1em'\u003e[\u003c/text\u003e\n\u003ctext text-anchor='middle' x='288' y='4' fill='currentColor' style='font-size:1em'\u003eO\u003c/text\u003e\n\u003ctext text-anchor='middle' x='296' y='4' fill='currentColor' style='font-size:1em'\u003ep\u003c/text\u003e\n\u003ctext text-anchor='middle' x='304' y='4' fill='currentColor' style='font-size:1em'\u003ee\u003c/text\u003e\n\u003ctext text-anchor='middle' x='312' y='4' fill='currentColor' style='font-size:1em'\u003en\u003c/text\u003e\n\u003ctext text-anchor='middle' x='320' y='4' fill='currentColor' style='font-size:1em'\u003e-\u003c/text\u003e\n\u003ctext text-anchor='middle' x='328' y='4' fill='currentColor' style='font-size:1em'\u003eW\u003c/text\u003e\n\u003ctext text-anchor='middle' x='336' y='4' fill='currentColor' style='font-size:1em'\u003ee\u003c/text\u003e\n\u003ctext text-anchor='middle' x='344' y='4' fill='currentColor' style='font-size:1em'\u003eb\u003c/text\u003e\n\u003ctext text-anchor='middle' x='352' y='4' fill='currentColor' style='font-size:1em'\u003eU\u003c/text\u003e\n\u003ctext text-anchor='middle' x='360' y='4' fill='currentColor' style='font-size:1em'\u003eI\u003c/text\u003e\n\u003ctext text-anchor='middle' x='376' y='4' fill='currentColor' style='font-size:1em'\u003e]\u003c/text\u003e\n\u003ctext text-anchor='middle' x='392' y='4' fill='currentColor' style='font-size:1em'\u003e─\u003c/text\u003e\n\u003ctext text-anchor='middle' x='400' y='4' fill='currentColor' style='font-size:1em'\u003e─\u003c/text\u003e\n\u003ctext text-anchor='middle' x='408' y='4' fill='currentColor' style='font-size:1em'\u003e(\u003c/text\u003e\n\u003ctext text-anchor='middle' x='416' y='4' fill='currentColor' style='font-size:1em'\u003eR\u003c/text\u003e\n\u003ctext text-anchor='middle' x='424' y='4' fill='currentColor' style='font-size:1em'\u003eE\u003c/text\u003e\n\u003ctext text-anchor='middle' x='432' y='4' fill='currentColor' style='font-size:1em'\u003eS\u003c/text\u003e\n\u003ctext text-anchor='middle' x='440' y='4' fill='currentColor' style='font-size:1em'\u003eT\u003c/text\u003e\n\u003ctext text-anchor='middle' x='456' y='4' fill='currentColor' style='font-size:1em'\u003e1\u003c/text\u003e\n\u003ctext text-anchor='middle' x='464' y='4' fill='currentColor' style='font-size:1em'\u003e1\u003c/text\u003e\n\u003ctext text-anchor='middle' x='472' y='4' fill='currentColor' style='font-size:1em'\u003e4\u003c/text\u003e\n\u003ctext text-anchor='middle' x='480' y='4' fill='currentColor' style='font-size:1em'\u003e3\u003c/text\u003e\n\u003ctext text-anchor='middle' x='488' y='4' fill='currentColor' style='font-size:1em'\u003e4\u003c/text\u003e\n\u003ctext text-anchor='middle' x='496' y='4' fill='currentColor' style='font-size:1em'\u003e)\u003c/text\u003e\n\u003ctext text-anchor='middle' x='504' y='4' fill='currentColor' style='font-size:1em'\u003e─\u003c/text\u003e\n\u003ctext text-anchor='middle' x='512' y='4' fill='currentColor' style='font-size:1em'\u003e─\u003c/text\u003e\n\u003ctext text-anchor='middle' x='520' y='4' fill='currentColor' style='font-size:1em'\u003e\u0026gt;\u003c/text\u003e\n\u003ctext text-anchor='middle' x='536' y='4' fill='currentColor' style='font-size:1em'\u003e[\u003c/text\u003e\n\u003ctext text-anchor='middle' x='552' y='4' fill='currentColor' style='font-size:1em'\u003eO\u003c/text\u003e\n\u003ctext text-anchor='middle' x='560' y='4' fill='currentColor' style='font-size:1em'\u003el\u003c/text\u003e\n\u003ctext text-anchor='middle' x='568' y='4' fill='currentColor' style='font-size:1em'\u003el\u003c/text\u003e\n\u003ctext text-anchor='middle' x='576' y='4' fill='currentColor' style='font-size:1em'\u003ea\u003c/text\u003e\n\u003ctext text-anchor='middle' x='584' y='4' fill='currentColor' style='font-size:1em'\u003em\u003c/text\u003e\n\u003ctext text-anchor='middle' x='592' y='4' fill='currentColor' style='font-size:1em'\u003ea\u003c/text\u003e\n\u003ctext text-anchor='middle' x='608' y='4' fill='currentColor' style='font-size:1em'\u003e엔\u003c/text\u003e\n\u003ctext text-anchor='middle' x='616' y='4' fill='currentColor' style='font-size:1em'\u003e진\u003c/text\u003e\n\u003ctext text-anchor='middle' x='632' y='4' fill='currentColor' style='font-size:1em'\u003e(\u003c/text\u003e\n\u003ctext text-anchor='middle' x='640' y='4' fill='currentColor' style='font-size:1em'\u003eN\u003c/text\u003e\n\u003ctext text-anchor='middle' x='648' y='4' fill='currentColor' style='font-size:1em'\u003eV\u003c/text\u003e\n\u003ctext text-anchor='middle' x='656' y='4' fill='currentColor' style='font-size:1em'\u003eI\u003c/text\u003e\n\u003ctext text-anchor='middle' x='664' y='4' fill='currentColor' style='font-size:1em'\u003eD\u003c/text\u003e\n\u003ctext text-anchor='middle' x='672' y='4' fill='currentColor' style='font-size:1em'\u003eI\u003c/text\u003e\n\u003ctext text-anchor='middle' x='680' y='4' fill='currentColor' style='font-size:1em'\u003eA\u003c/text\u003e\n\u003ctext text-anchor='middle' x='696' y='4' fill='currentColor' style='font-size:1em'\u003eG\u003c/text\u003e\n\u003ctext text-anchor='middle' x='704' y='4' fill='currentColor' style='font-size:1em'\u003eP\u003c/text\u003e\n\u003ctext text-anchor='middle' x='712' y='4' fill='currentColor' style='font-size:1em'\u003eU\u003c/text\u003e\n\u003ctext text-anchor='middle' x='720' y='4' fill='currentColor' style='font-size:1em'\u003e)\u003c/text\u003e\n\u003ctext text-anchor='middle' x='736' y='4' fill='currentColor' style='font-size:1em'\u003e]\u003c/text\u003e\n\u003c/g\u003e\n\n    \u003c/svg\u003e\n  \n\u003c/div\u003e\n\u003chr\u003e\n\u003ch2 id=\"2-사전-준비사항\"\u003e2. 사전 준비사항\u003c/h2\u003e\n\u003col\u003e\n\u003cli\u003e\u003cstrong\u003eDocker \u0026amp; Docker Compose\u003c/strong\u003e 설치 완료\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eNVIDIA GPU 드라이버 및 NVIDIA Container Toolkit\u003c/strong\u003e 설치 완료 (GPU 사용 시)\n\u003cul\u003e\n\u003cli\u003eGPU가 없더라도 CPU 모드로 실행 가능합니다.\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ol\u003e\n\u003chr\u003e\n\u003ch2 id=\"3-docker-compose-구성\"\u003e3. Docker Compose 구성\u003c/h2\u003e\n\u003cp\u003e\u003ccode\u003edocker-compose.yml\u003c/code\u003e 파일을 작성하여 Ollama와 Open-WebUI 서비스를 구성합니다.\u003c/p\u003e","title":"Ollama + Open-WebUI로 로컬 프라이빗 AI 챗봇 구축 가이드"},{"content":"ROS2(Robot Operating System 2) 기반의 로봇 소프트웨어 개발 시 데이터 유실(Packet Loss), 지연(Latency), 멀티 로봇 노드 간 미탐색(Discovery) 문제가 발생할 때 DDS(Data Distribution Service) 미들웨어를 최적화하고 네트워크 환경을 튜닝하는 실무 지침서입니다.\n1. ROS2 DDS 미들웨어 선택 가이드 ROS2는 기본 DDS로 FastDDS 또는 CycloneDDS를 주로 사용합니다.\nCycloneDDS: 대용량 센서 데이터(LiDAR, RGB-D 카메라) 전송 안정성이 뛰어나며, 안정적인 유니캐스트/멀티캐스트 지원. FastDDS: eProsima의 기본 미들웨어로, 기능이 풍부하고 디버깅 도구가 다양함. CycloneDDS 변경 및 패키지 설치 sudo apt update sudo apt install ros-humble-rmw-cyclonedds-cpp # RMW(ROS Middleware Implementation) 환경 변수 설정 export RMW_IMPLEMENTATION=rmw_cyclonedds_cpp 2. 리눅스 커널 소켓 버퍼 튜닝 (패킷 드랍 방지) LiDAR 점군(PointCloud2) 데이터나 고해상도 카메라 이미지를 발행/구독할 때 UDP 소켓 수신 버퍼가 작으면 패킷 손실이 일어납니다.\n커널 소켓 버퍼 크기 확장 (sysctl) /etc/sysctl.d/60-ros2-dds.conf 파일을 생성하고 아래 설정을 추가합니다.\n# UDP 버퍼 수신/송신 최대 크기 확장 (32MB) net.core.rmem_max=33554432 net.core.wmem_max=33554432 net.core.rmem_default=33554432 net.core.wmem_default=33554432 # 설정 즉시 적용 sudo sysctl --system 3. CycloneDDS XML 설정 파일 작성 및 적용 CycloneDDS의 세부 동작(네트워크 인터페이스 지정, 공유 메모리, 단편화 설정 등)을 제어하기 위해 XML 파일을 작성합니다.\ncyclonedds.xml 생성:\n\u0026lt;?xml version=\u0026#34;1.0\u0026#34; encoding=\u0026#34;UTF-8\u0026#34; ?\u0026gt; \u0026lt;CycloneDDS xmlns=\u0026#34;https://cdds.io/config\u0026#34; xmlns:xsi=\u0026#34;http://www.w3.org/2001/XMLSchema-instance\u0026#34; xsi:schemaLocation=\u0026#34;https://cdds.io/config https://raw.githubusercontent.com/eclipse-cyclonedds/cyclonedds/master/etc/cyclonedds.xsd\u0026#34;\u0026gt; \u0026lt;Domain id=\u0026#34;any\u0026#34;\u0026gt; \u0026lt;General\u0026gt; \u0026lt;!-- 바인딩할 네트워크 인터페이스 명시 (예: eth0 또는 wlan0) --\u0026gt; \u0026lt;NetworkInterfaceAddress\u0026gt;eth0\u0026lt;/NetworkInterfaceAddress\u0026gt; \u0026lt;AllowMulticast\u0026gt;true\u0026lt;/AllowMulticast\u0026gt; \u0026lt;MaxMessageSize\u0026gt;65500B\u0026lt;/MaxMessageSize\u0026gt; \u0026lt;/General\u0026gt; \u0026lt;Internal\u0026gt; \u0026lt;SocketBufferSize min=\u0026#34;10MB\u0026#34; /\u0026gt; \u0026lt;/Internal\u0026gt; \u0026lt;Discovery\u0026gt; \u0026lt;!-- 멀티캐스트가 차단된 와이파이/스위치 환경일 경우 피어 유니캐스트 IP 직접 지정 --\u0026gt; \u0026lt;Peers\u0026gt; \u0026lt;Peer Address=\u0026#34;192.168.1.100\u0026#34;/\u0026gt; \u0026lt;Peer Address=\u0026#34;192.168.1.101\u0026#34;/\u0026gt; \u0026lt;/Peers\u0026gt; \u0026lt;/Discovery\u0026gt; \u0026lt;/Domain\u0026gt; \u0026lt;/CycloneDDS\u0026gt; # bashrc에 환경변수 등록 export CYCLONEDDS_URI=file:///path/to/cyclonedds.xml 4. 멀티 로봇 환경 격리 (ROS_DOMAIN_ID) 동일한 와이파이 네트워크에 여러 대의 로봇 또는 개발자 PC가 접속해 있을 때 메시지 간섭을 막으려면 각 로봇/서버별로 ROS_DOMAIN_ID를 다르게 부여합니다.\n# 로봇 1번 export ROS_DOMAIN_ID=11 # 로봇 2번 export ROS_DOMAIN_ID=12 5. 트러블슈팅 체크리스트 ① 토픽 목록은 보이나 echo 시 데이터가 들어오지 않는 경우 원인: QoS(Quality of Service) 설정 불일치 (Reliability / Durability). 해결: 발행자(Publisher)와 구독자(Subscriber)의 QoS 설정(RELIABLE vs BEST_EFFORT)을 맞추거나 ros2 topic info /topic_name --verbose로 mismatch 상태 확인. ② 다른 PC/로봇 간에 ros2 topic list가 뜨지 않는 경우 원인: 방화벽(UFW) 통과 실패 또는 와이파이 공유기의 멀티캐스트(IGMP Snooping) 차단. 해결: # 테스트용 방화벽 임시 해제 sudo ufw disable 멀티캐스트가 차단되는 와이파이 환경에서는 3번 섹션의 CycloneDDS Peers 유니캐스트 설정을 사용합니다. 마무리 대용량 노드가 복잡하게 얽히는 실시간 로봇 시스템에서는 커널 UDP 소켓 버퍼 확장과 CycloneDDS XML 튜닝, 그리고 알맞은 QoS 정책 수립이 안정적인 통신 체계의 핵심입니다.\n","permalink":"https://wkqco33.github.io/wkqcosoft-docs/posts/ros2-dds-network-tuning/","summary":"\u003cp\u003eROS2(Robot Operating System 2) 기반의 로봇 소프트웨어 개발 시 데이터 유실(Packet Loss), 지연(Latency), 멀티 로봇 노드 간 미탐색(Discovery) 문제가 발생할 때 \u003cstrong\u003eDDS(Data Distribution Service)\u003c/strong\u003e 미들웨어를 최적화하고 네트워크 환경을 튜닝하는 실무 지침서입니다.\u003c/p\u003e\n\u003chr\u003e\n\u003ch2 id=\"1-ros2-dds-미들웨어-선택-가이드\"\u003e1. ROS2 DDS 미들웨어 선택 가이드\u003c/h2\u003e\n\u003cp\u003eROS2는 기본 DDS로 \u003cstrong\u003eFastDDS\u003c/strong\u003e 또는 \u003cstrong\u003eCycloneDDS\u003c/strong\u003e를 주로 사용합니다.\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003eCycloneDDS\u003c/strong\u003e: 대용량 센서 데이터(LiDAR, RGB-D 카메라) 전송 안정성이 뛰어나며, 안정적인 유니캐스트/멀티캐스트 지원.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eFastDDS\u003c/strong\u003e: eProsima의 기본 미들웨어로, 기능이 풍부하고 디버깅 도구가 다양함.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"cyclonedds-변경-및-패키지-설치\"\u003eCycloneDDS 변경 및 패키지 설치\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003esudo apt update\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003esudo apt install ros-humble-rmw-cyclonedds-cpp\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# RMW(ROS Middleware Implementation) 환경 변수 설정\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eexport RMW_IMPLEMENTATION\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003ermw_cyclonedds_cpp\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003chr\u003e\n\u003ch2 id=\"2-리눅스-커널-소켓-버퍼-튜닝-패킷-드랍-방지\"\u003e2. 리눅스 커널 소켓 버퍼 튜닝 (패킷 드랍 방지)\u003c/h2\u003e\n\u003cp\u003eLiDAR 점군(PointCloud2) 데이터나 고해상도 카메라 이미지를 발행/구독할 때 UDP 소켓 수신 버퍼가 작으면 패킷 손실이 일어납니다.\u003c/p\u003e","title":"ROS2 DDS 통신 최적화 및 멀티 로봇 트러블슈팅 가이드"},{"content":"리눅스 서버 관리 중 디스크 용량이 100%(No space left on device)에 도달하여 서비스가 중단되었을 때, 원인을 신속하게 진단하고 디스크 공간을 확보하는 체계적인 가이드입니다.\n1. 1단계: 디스크 사용량 및 Inode 상태 확인 가장 먼저 물리적 용량 부족인지, 아니면 파일 개수 초과(Inode 부족)인지 확인해야 합니다.\n전체 디스크 용량 점검 (df -h) df -h 특정 파티션(예: / 또는 /var)의 Use%가 100%에 달했는지 확인합니다. Inode 사용량 점검 (df -i) df -i 용량이 남아있어도 소형 파일이 너무 많으면 Inode 사용율(IUse%)이 100%가 되어 파일 생성이 불가능해집니다. 2. 2단계: 대용량 파일 및 디렉토리 위치 탐색 어느 디렉토리에서 디스크를 과도하게 사용하고 있는지 추적합니다.\n상위 용량 차지 디렉토리 탐색 (du) # 루트(/) 기준 가장 많은 용량을 차지하는 상위 10개 디렉토리 확인 du -h --max-depth=1 /var 2\u0026gt;/dev/null | sort -hr | head -n 10 100MB 이상 대용량 파일 탐색 (find) find / -type f -size +100M -exec ls -lh {} \\; 2\u0026gt;/dev/null | awk \u0026#39;{ print $5, $9 }\u0026#39; | sort -hr 인터랙티브 디스크 분석 도구 사용 (ncdu) sudo apt install ncdu ncdu /var 방향키로 디렉토리를 탐색하며 용량 소비 주범을 직관적으로 확인할 수 있습니다. 3. 3단계: 주요 용량 소비 요소별 안전 정리법 ① 리눅스 시스템 로그 정리 (journalctl) 시스템 로깅 서비스인 systemd-journald의 오래된 로그를 비웁니다.\n# 현재 저널 로그 용량 확인 journalctl --disk-usage # 최근 3일치 로그만 남기고 삭제 sudo journalctl --vacuum-time=3d # 용량을 500M 이내로 제한하고 이전 로그 삭제 sudo journalctl --vacuum-size=500M ② Docker 및 컨테이너 리소스 정리 (docker system prune) Docker 빌드 캐시, 멈춘 컨테이너, 미사용 이미지 및 로그 파일은 디스크 부족의 주요 원인입니다.\n# 도커 용량 사용 현황 분석 docker system df # 미사용 컨테이너, 네트워크, 캐시 일괄 삭제 docker system prune -f # 사용하지 않는 모든 이미지 포함 완전 삭제 docker system prune -a --volumes -f # 특정 컨테이너의 json-log 파일 크기 초기화 truncate -s 0 /var/lib/docker/containers/*/*-json.log ③ APT 패키지 매니저 캐시 정리 sudo apt clean sudo apt autoclean sudo apt autoremove --purge 4. 4단계: 특수 상황 - 삭제했으나 용량이 확보되지 않는 경우 (Deleted Open Files) 파일을 삭제(rm)했음에도 프로세스가 해당 파일을 계속 쥐고(Open) 있으면 디스크 용량이 반환되지 않습니다.\n삭제된 상태로 열려있는 파일 추적 (lsof) lsof | grep deleted 해결 방법 해당 파일 프로세스를 재시작하거나 프로세스 PID를 확인 후 종료/파일 트렁케이트를 수행합니다.\n# 예: 특정 PID가 잡고 있는 삭제 파일의 용량 즉시 비우기 cat /dev/null \u0026gt; /proc/\u0026lt;PID\u0026gt;/fd/\u0026lt;FD_NUMBER\u0026gt; 5. 예방법: 로그 로테이션(logrotate) 설정 /etc/logrotate.conf 또는 /etc/logrotate.d/ 하위에 앱 로그 로테이션 정책을 등록하여 파일 크기가 일정 수준을 넘거나 수일이 지나면 자동 압축/삭제되도록 유지합니다.\n/var/log/my-app/*.log { daily missingok rotate 7 compress delaycompress notifempty create 0640 www-data www-data } 마무리 디스크 장애 시 df -h -\u0026gt; du / ncdu -\u0026gt; journalctl/docker prune -\u0026gt; lsof | grep deleted 순서로 원인을 파악하면 서비스 장애를 빠르게 해결할 수 있습니다!\n","permalink":"https://wkqco33.github.io/wkqcosoft-docs/posts/linux-disk-cleanup-guide/","summary":"\u003cp\u003e리눅스 서버 관리 중 디스크 용량이 100%(\u003ccode\u003eNo space left on device\u003c/code\u003e)에 도달하여 서비스가 중단되었을 때, 원인을 신속하게 진단하고 디스크 공간을 확보하는 체계적인 가이드입니다.\u003c/p\u003e\n\u003chr\u003e\n\u003ch2 id=\"1-1단계-디스크-사용량-및-inode-상태-확인\"\u003e1. 1단계: 디스크 사용량 및 Inode 상태 확인\u003c/h2\u003e\n\u003cp\u003e가장 먼저 물리적 용량 부족인지, 아니면 파일 개수 초과(Inode 부족)인지 확인해야 합니다.\u003c/p\u003e\n\u003ch3 id=\"전체-디스크-용량-점검-df--h\"\u003e전체 디스크 용량 점검 (\u003ccode\u003edf -h\u003c/code\u003e)\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edf -h\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cul\u003e\n\u003cli\u003e특정 파티션(예: \u003ccode\u003e/\u003c/code\u003e 또는 \u003ccode\u003e/var\u003c/code\u003e)의 \u003ccode\u003eUse%\u003c/code\u003e가 100%에 달했는지 확인합니다.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"inode-사용량-점검-df--i\"\u003eInode 사용량 점검 (\u003ccode\u003edf -i\u003c/code\u003e)\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edf -i\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cul\u003e\n\u003cli\u003e용량이 남아있어도 소형 파일이 너무 많으면 Inode 사용율(\u003ccode\u003eIUse%\u003c/code\u003e)이 100%가 되어 파일 생성이 불가능해집니다.\u003c/li\u003e\n\u003c/ul\u003e\n\u003chr\u003e\n\u003ch2 id=\"2-2단계-대용량-파일-및-디렉토리-위치-탐색\"\u003e2. 2단계: 대용량 파일 및 디렉토리 위치 탐색\u003c/h2\u003e\n\u003cp\u003e어느 디렉토리에서 디스크를 과도하게 사용하고 있는지 추적합니다.\u003c/p\u003e","title":"리눅스 디스크 용량 부족(100%) 해결 및 원인 정리 가이드"},{"content":"리눅스(Linux) 터미널 및 Bash 환경에서 자주 사용되는 필수 명령어와 옵션, 실무 활용 예시를 카테고리별로 정리한 문서입니다.\n1. 파일 및 디렉토리 관리 디렉토리 이동 및 위치 확인 pwd (Print Working Directory): 현재 위치한 디렉토리의 절대 경로 출력 pwd cd (Change Directory): 디렉토리 이동 cd /var/log # 특정 경로로 이동 cd ~ # 홈 디렉토리로 이동 cd .. # 상위 디렉토리로 이동 cd - # 이전 작업 디렉토리로 이동 파일 및 디렉토리 목록 조회 ls (List): 파일 및 디렉토리 목록 출력 ls -l # 상세 정보(권한, 소유자, 크기, 수정일 등) 포함 출력 ls -a # 숨김 파일(.)을 포함한 모든 파일 출력 ls -lh # 파일 크기를 사람이 읽기 쉬운 단위(KB, MB, GB)로 출력 ls -lt # 수정 시간순(최신순) 정렬 출력 디렉토리 및 파일 생성 / 삭제 / 복사 / 이동 mkdir (Make Directory): 디렉토리 생성 mkdir my_dir mkdir -p path/to/deep/dir # 하위 디렉토리까지 한 번에 생성 touch: 빈 파일 생성 또는 기존 파일의 수정 시간 업데이트 touch test.txt cp (Copy): 파일 및 디렉토리 복사 cp file1.txt file2.txt # 파일 복사 cp -r dir1 dir2 # 디렉토리 전체 복사 (재귀적) mv (Move): 파일/디렉토리 이동 또는 이름 변경 mv old_name.txt new_name.txt # 이름 변경 mv file.txt /path/to/target/ # 이동 rm (Remove): 파일 및 디렉토리 삭제 rm file.txt # 파일 삭제 rm -r dir_name # 디렉토리 및 하위 내용 삭제 rm -rf dir_name # 경고 없이 강제 삭제 (주의!) 탐색 및 용량 확인 find: 지정한 조건으로 파일 탐색 find . -name \u0026#34;*.log\u0026#34; # 현재 디렉토리에서 .log 파일 탐색 find /var/log -type f -mtime -7 # 최근 7일 이내 수정된 일반 파일 탐색 find . -type f -size +100M # 100MB 이상 크기의 파일 탐색 df (Disk Free): 전체 디스크 공간 사용량 확인 df -h # 사람이 읽기 쉬운 형식(GB, MB 등)으로 디스크 용량 확인 du (Disk Usage): 디렉토리별 용량 확인 du -sh * # 현재 디렉토리 하위 항목들의 용량 요약 출력 du -sh /var/log # 특정 디렉토리의 전체 용량 출력 2. 파일 내용 조회 및 편집 파일 내용 읽기 cat (Concatenate): 파일 내용 전체 출력 cat filename.txt cat -n filename.txt # 줄 번호와 함께 출력 less: 대용량 파일 내용을 페이지 단위로 조회 (q로 종료, /keyword로 검색) less /var/log/syslog head: 파일의 상단 일부 출력 head -n 20 filename.txt # 상단 20줄 출력 tail: 파일의 하단 일부 출력 (로그 모니터링에 매우 유용) tail -n 50 filename.txt # 하단 50줄 출력 tail -f /var/log/syslog # 실시간으로 추기되는 로그 모니터링 3. 텍스트 검색 및 데이터 처리 텍스트 검색 grep (Global Regular Expression Print): 패턴 검색 grep \u0026#34;ERROR\u0026#34; app.log # app.log에서 ERROR 문자열 포함 라인 검색 grep -i \u0026#34;error\u0026#34; app.log # 대소문자 구분 없이 검색 grep -rn \u0026#34;ERROR\u0026#34; ./src # 하위 디렉토리까지 재귀 검색(-r) 및 줄 번호 표시(-n) grep -v \u0026#34;INFO\u0026#34; app.log # INFO가 포함되지 않은 라인만 출력 (반전) 리다이렉션 \u0026amp; 파이프라인 | (Pipe): 앞 명령어의 표준 출력을 뒤 명령어의 표준 입력으로 전달 ps aux | grep python \u0026gt; \u0026amp; \u0026gt;\u0026gt; (Redirection): 파일에 결과 저장/추가 echo \u0026#34;Hello World\u0026#34; \u0026gt; output.txt # 덮어쓰기 (Overwriting) echo \u0026#34;New Line\u0026#34; \u0026gt;\u0026gt; output.txt # 이어쓰기 (Appending) 고급 텍스트 처리 awk: 필드 단위 데이터 추출 및 텍스트 처리 ls -l | awk \u0026#39;{print $5, $9}\u0026#39; # 파일 크기($5)와 파일명($9)만 출력 sed: 스트림 에디터 (문자열 치환 등) sed \u0026#39;s/foo/bar/g\u0026#39; input.txt # foo를 bar로 치환하여 출력 sed -i \u0026#39;s/foo/bar/g\u0026#39; input.txt # 파일 내용을 직접 치환하여 수정 wc (Word Count): 줄, 단어, 바이트 수 카운트 wc -l filename.txt # 전체 줄 수 출력 sort \u0026amp; uniq: 정렬 및 중복 제거 sort data.txt | uniq -c # 정렬 후 각 라인별 등장 횟수 카운트 4. 프로세스 및 시스템 모니터링 프로세스 확인 및 관리 ps (Process Status): 실행 중인 프로세스 조회 ps aux # 시스템 전체 프로세스 상세 목록 조회 ps -ef | grep java # 특정 프로세스(java) 검색 top / htop: 실시간 시스템 자원(CPU, 메모리) 및 프로세스 상태 모니터링 top # 기본 리눅스 성능 모니터링툴 htop # 컬러 UI 지원 향상된 모니터링툴 (설치 필요: apt install htop) kill / killall: 프로세스 종료 kill \u0026lt;PID\u0026gt; # 일반 종료 요청 (SIGTERM) kill -9 \u0026lt;PID\u0026gt; # 강제 종료 (SIGKILL) killall nginx # 지정한 이름의 모든 프로세스 종료 시스템 상태 및 서비스 관리 free: 시스템 메모리(RAM, Swap) 사용량 확인 free -h # 읽기 쉬운 단위(MB, GB)로 표시 uptime: 시스템 가동 시간 및 Load Average 확인 uptime systemctl: systemd 서비스 관리 sudo systemctl status nginx # 서비스 상태 확인 sudo systemctl start nginx # 서비스 시작 sudo systemctl stop nginx # 서비스 중지 sudo systemctl restart nginx # 서비스 재시작 sudo systemctl enable nginx # 부팅 시 자동 시작 설정 5. 권한 및 소유권 관리 chmod (Change Mode): 파일/디렉토리 접근 권한 변경 chmod 755 script.sh # 소유자: 읽기/쓰기/실행(7), 그룹: 읽기/실행(5), 기타: 읽기/실행(5) chmod +x script.sh # 실행 권한 부여 chmod -R 644 /path/to/dir # 하위 항목 전체 권한 변경 chown (Change Owner): 파일/디렉터리의 소유자 및 그룹 변경 sudo chown ubuntu:ubuntu file.txt # 소유자 및 그룹 변경 sudo chown -R ubuntu:ubuntu /var/www # 하위 항목 전체 소유자 변경 sudo (Superuser Do): 관리자(root) 권한으로 명령어 실행 sudo apt update 6. 네트워크 및 데이터 전송 네트워크 확인 ping: 네트워크 연결 상태 확인 ping 8.8.8.8 netstat / ss: 네트워크 포트 및 소켓 상태 확인 ss -tuln # 열려있는 TCP/UDP 포트 목록 조회 sudo ss -tulpn | grep 8080 # 8080 포트를 사용하는 프로세스 확인 ip / ifconfig: 네트워크 인터페이스 IP 확인 ip a # IP 주소 및 네트워크 인터페이스 정보 확인 파일 다운로드 및 전송 curl: HTTP/HTTPS 요청 보내기 및 데이터 수신 curl -I https://example.com # 응답 헤더 확인 curl -O https://example.com/file.zip # 파일 다운로드 wget: 웹에서 파일 다운로드 wget https://example.com/file.zip ssh: 원격 서버 접속 ssh user@remote_ip ssh -i key.pem user@remote_ip # SSH 키 파일로 접속 scp \u0026amp; rsync: 원격 파일 복사 및 동기화 scp file.txt user@remote_ip:/path/to/target/ # SCP로 파일 전송 rsync -avz ./src/ user@remote_ip:/path/to/target/ # rsync로 증분 동기화 7. 압축 및 아카이브 tar: 파일 묶기 및 압축 # tar.gz 압축하기 tar -czvf archive.tar.gz /path/to/dir # tar.gz 압축 해제하기 tar -xzvf archive.tar.gz zip / unzip: ZIP 압축 및 해제 zip -r archive.zip /path/to/dir unzip archive.zip 8. 유용한 Bash 팁 및 단축키 단축어 (Alias) \u0026amp; 환경 변수 alias: 자주 쓰는 긴 명령어를 짧은 별칭으로 등록 alias ll=\u0026#39;ls -alF\u0026#39; export: 환경 변수 설정 export PATH=$PATH:/custom/bin history: 실행했던 명령어 히스토리 조회 history | grep docker # 이전에 실행한 docker 관련 명령어 검색 백그라운드 실행 \u0026amp;: 명령어를 백그라운드에서 실행 python3 app.py \u0026amp; nohup: 터미널이 종료되어도 프로세스가 지속되도록 실행 nohup python3 app.py \u0026gt; app.log 2\u0026gt;\u0026amp;1 \u0026amp; 주요 터미널 단축키 단축키 기능 설명 Ctrl + C 현재 실행 중인 프로세스 즉시 중단 Ctrl + Z 현재 실행 중인 프로세스 일시 정지 (배경 전환) Ctrl + R 과거 명령 히스토리 실시간 역검색 Ctrl + L 터미널 화면 깨끗하게 지우기 (clear 동일) Ctrl + A 커서를 줄의 맨 앞(시작)으로 이동 Ctrl + E 커서를 줄의 맨 뒤(끝)으로 이동 Tab 파일명/경로/명령어 자동 완성 마무리 위 명령어들은 리눅스 시스템 관리, 서버 운영, DevOps 및 로봇/소프트웨어 개발 환경에서 일상적으로 사용되는 핵심 커맨드입니다. 필요할 때 시트처럼 빠르게 참고하세요!\n","permalink":"https://wkqco33.github.io/wkqcosoft-docs/posts/linux-bash-commands/","summary":"\u003cp\u003e리눅스(Linux) 터미널 및 Bash 환경에서 자주 사용되는 필수 명령어와 옵션, 실무 활용 예시를 카테고리별로 정리한 문서입니다.\u003c/p\u003e\n\u003chr\u003e\n\u003ch2 id=\"1-파일-및-디렉토리-관리\"\u003e1. 파일 및 디렉토리 관리\u003c/h2\u003e\n\u003ch3 id=\"디렉토리-이동-및-위치-확인\"\u003e디렉토리 이동 및 위치 확인\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003e\u003ccode\u003epwd\u003c/code\u003e\u003c/strong\u003e (Print Working Directory): 현재 위치한 디렉토리의 절대 경로 출력\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003epwd\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e\u003ccode\u003ecd\u003c/code\u003e\u003c/strong\u003e (Change Directory): 디렉토리 이동\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ecd /var/log          \u003cspan style=\"color:#75715e\"\u003e# 특정 경로로 이동\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ecd ~                 \u003cspan style=\"color:#75715e\"\u003e# 홈 디렉토리로 이동\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ecd ..                \u003cspan style=\"color:#75715e\"\u003e# 상위 디렉토리로 이동\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ecd -                 \u003cspan style=\"color:#75715e\"\u003e# 이전 작업 디렉토리로 이동\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"파일-및-디렉토리-목록-조회\"\u003e파일 및 디렉토리 목록 조회\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003e\u003ccode\u003els\u003c/code\u003e\u003c/strong\u003e (List): 파일 및 디렉토리 목록 출력\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003els -l                \u003cspan style=\"color:#75715e\"\u003e# 상세 정보(권한, 소유자, 크기, 수정일 등) 포함 출력\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003els -a                \u003cspan style=\"color:#75715e\"\u003e# 숨김 파일(.)을 포함한 모든 파일 출력\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003els -lh               \u003cspan style=\"color:#75715e\"\u003e# 파일 크기를 사람이 읽기 쉬운 단위(KB, MB, GB)로 출력\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003els -lt               \u003cspan style=\"color:#75715e\"\u003e# 수정 시간순(최신순) 정렬 출력\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"디렉토리-및-파일-생성--삭제--복사--이동\"\u003e디렉토리 및 파일 생성 / 삭제 / 복사 / 이동\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003e\u003ccode\u003emkdir\u003c/code\u003e\u003c/strong\u003e (Make Directory): 디렉토리 생성\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003emkdir my_dir\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003emkdir -p path/to/deep/dir   \u003cspan style=\"color:#75715e\"\u003e# 하위 디렉토리까지 한 번에 생성\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e\u003ccode\u003etouch\u003c/code\u003e\u003c/strong\u003e: 빈 파일 생성 또는 기존 파일의 수정 시간 업데이트\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003etouch test.txt\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e\u003ccode\u003ecp\u003c/code\u003e\u003c/strong\u003e (Copy): 파일 및 디렉토리 복사\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ecp file1.txt file2.txt      \u003cspan style=\"color:#75715e\"\u003e# 파일 복사\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ecp -r dir1 dir2             \u003cspan style=\"color:#75715e\"\u003e# 디렉토리 전체 복사 (재귀적)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e\u003ccode\u003emv\u003c/code\u003e\u003c/strong\u003e (Move): 파일/디렉토리 이동 또는 이름 변경\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003emv old_name.txt new_name.txt \u003cspan style=\"color:#75715e\"\u003e# 이름 변경\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003emv file.txt /path/to/target/ \u003cspan style=\"color:#75715e\"\u003e# 이동\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e\u003ccode\u003erm\u003c/code\u003e\u003c/strong\u003e (Remove): 파일 및 디렉토리 삭제\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003erm file.txt                 \u003cspan style=\"color:#75715e\"\u003e# 파일 삭제\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003erm -r dir_name              \u003cspan style=\"color:#75715e\"\u003e# 디렉토리 및 하위 내용 삭제\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003erm -rf dir_name             \u003cspan style=\"color:#75715e\"\u003e# 경고 없이 강제 삭제 (주의!)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"탐색-및-용량-확인\"\u003e탐색 및 용량 확인\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003e\u003ccode\u003efind\u003c/code\u003e\u003c/strong\u003e: 지정한 조건으로 파일 탐색\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003efind . -name \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;*.log\u0026#34;\u003c/span\u003e                  \u003cspan style=\"color:#75715e\"\u003e# 현재 디렉토리에서 .log 파일 탐색\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003efind /var/log -type f -mtime -7       \u003cspan style=\"color:#75715e\"\u003e# 최근 7일 이내 수정된 일반 파일 탐색\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003efind . -type f -size +100M            \u003cspan style=\"color:#75715e\"\u003e# 100MB 이상 크기의 파일 탐색\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e\u003ccode\u003edf\u003c/code\u003e\u003c/strong\u003e (Disk Free): 전체 디스크 공간 사용량 확인\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edf -h                        \u003cspan style=\"color:#75715e\"\u003e# 사람이 읽기 쉬운 형식(GB, MB 등)으로 디스크 용량 확인\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e\u003ccode\u003edu\u003c/code\u003e\u003c/strong\u003e (Disk Usage): 디렉토리별 용량 확인\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edu -sh *                     \u003cspan style=\"color:#75715e\"\u003e# 현재 디렉토리 하위 항목들의 용량 요약 출력\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edu -sh /var/log              \u003cspan style=\"color:#75715e\"\u003e# 특정 디렉토리의 전체 용량 출력\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003chr\u003e\n\u003ch2 id=\"2-파일-내용-조회-및-편집\"\u003e2. 파일 내용 조회 및 편집\u003c/h2\u003e\n\u003ch3 id=\"파일-내용-읽기\"\u003e파일 내용 읽기\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003e\u003ccode\u003ecat\u003c/code\u003e\u003c/strong\u003e (Concatenate): 파일 내용 전체 출력\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ecat filename.txt\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ecat -n filename.txt          \u003cspan style=\"color:#75715e\"\u003e# 줄 번호와 함께 출력\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e\u003ccode\u003eless\u003c/code\u003e\u003c/strong\u003e: 대용량 파일 내용을 페이지 단위로 조회 (\u003ccode\u003eq\u003c/code\u003e로 종료, \u003ccode\u003e/keyword\u003c/code\u003e로 검색)\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eless /var/log/syslog\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e\u003ccode\u003ehead\u003c/code\u003e\u003c/strong\u003e: 파일의 상단 일부 출력\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ehead -n \u003cspan style=\"color:#ae81ff\"\u003e20\u003c/span\u003e filename.txt      \u003cspan style=\"color:#75715e\"\u003e# 상단 20줄 출력\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e\u003ccode\u003etail\u003c/code\u003e\u003c/strong\u003e: 파일의 하단 일부 출력 (로그 모니터링에 매우 유용)\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003etail -n \u003cspan style=\"color:#ae81ff\"\u003e50\u003c/span\u003e filename.txt      \u003cspan style=\"color:#75715e\"\u003e# 하단 50줄 출력\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003etail -f /var/log/syslog      \u003cspan style=\"color:#75715e\"\u003e# 실시간으로 추기되는 로그 모니터링\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003chr\u003e\n\u003ch2 id=\"3-텍스트-검색-및-데이터-처리\"\u003e3. 텍스트 검색 및 데이터 처리\u003c/h2\u003e\n\u003ch3 id=\"텍스트-검색\"\u003e텍스트 검색\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003e\u003ccode\u003egrep\u003c/code\u003e\u003c/strong\u003e (Global Regular Expression Print): 패턴 검색\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003egrep \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;ERROR\u0026#34;\u003c/span\u003e app.log         \u003cspan style=\"color:#75715e\"\u003e# app.log에서 ERROR 문자열 포함 라인 검색\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003egrep -i \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;error\u0026#34;\u003c/span\u003e app.log      \u003cspan style=\"color:#75715e\"\u003e# 대소문자 구분 없이 검색\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003egrep -rn \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;ERROR\u0026#34;\u003c/span\u003e ./src       \u003cspan style=\"color:#75715e\"\u003e# 하위 디렉토리까지 재귀 검색(-r) 및 줄 번호 표시(-n)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003egrep -v \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;INFO\u0026#34;\u003c/span\u003e app.log       \u003cspan style=\"color:#75715e\"\u003e# INFO가 포함되지 않은 라인만 출력 (반전)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"리다이렉션--파이프라인\"\u003e리다이렉션 \u0026amp; 파이프라인\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003e\u003ccode\u003e|\u003c/code\u003e (Pipe)\u003c/strong\u003e: 앞 명령어의 표준 출력을 뒤 명령어의 표준 입력으로 전달\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eps aux | grep python\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e\u003ccode\u003e\u0026gt;\u003c/code\u003e \u0026amp; \u003ccode\u003e\u0026gt;\u0026gt;\u003c/code\u003e (Redirection)\u003c/strong\u003e: 파일에 결과 저장/추가\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eecho \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;Hello World\u0026#34;\u003c/span\u003e \u0026gt; output.txt    \u003cspan style=\"color:#75715e\"\u003e# 덮어쓰기 (Overwriting)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eecho \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;New Line\u0026#34;\u003c/span\u003e \u0026gt;\u0026gt; output.txt     \u003cspan style=\"color:#75715e\"\u003e# 이어쓰기 (Appending)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"고급-텍스트-처리\"\u003e고급 텍스트 처리\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003e\u003ccode\u003eawk\u003c/code\u003e\u003c/strong\u003e: 필드 단위 데이터 추출 및 텍스트 처리\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003els -l | awk \u003cspan style=\"color:#e6db74\"\u003e\u0026#39;{print $5, $9}\u0026#39;\u003c/span\u003e       \u003cspan style=\"color:#75715e\"\u003e# 파일 크기($5)와 파일명($9)만 출력\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e\u003ccode\u003esed\u003c/code\u003e\u003c/strong\u003e: 스트림 에디터 (문자열 치환 등)\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003esed \u003cspan style=\"color:#e6db74\"\u003e\u0026#39;s/foo/bar/g\u0026#39;\u003c/span\u003e input.txt       \u003cspan style=\"color:#75715e\"\u003e# foo를 bar로 치환하여 출력\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003esed -i \u003cspan style=\"color:#e6db74\"\u003e\u0026#39;s/foo/bar/g\u0026#39;\u003c/span\u003e input.txt    \u003cspan style=\"color:#75715e\"\u003e# 파일 내용을 직접 치환하여 수정\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e\u003ccode\u003ewc\u003c/code\u003e\u003c/strong\u003e (Word Count): 줄, 단어, 바이트 수 카운트\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ewc -l filename.txt                \u003cspan style=\"color:#75715e\"\u003e# 전체 줄 수 출력\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e\u003ccode\u003esort\u003c/code\u003e \u0026amp; \u003ccode\u003euniq\u003c/code\u003e\u003c/strong\u003e: 정렬 및 중복 제거\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003esort data.txt | uniq -c           \u003cspan style=\"color:#75715e\"\u003e# 정렬 후 각 라인별 등장 횟수 카운트\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003chr\u003e\n\u003ch2 id=\"4-프로세스-및-시스템-모니터링\"\u003e4. 프로세스 및 시스템 모니터링\u003c/h2\u003e\n\u003ch3 id=\"프로세스-확인-및-관리\"\u003e프로세스 확인 및 관리\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003e\u003ccode\u003eps\u003c/code\u003e\u003c/strong\u003e (Process Status): 실행 중인 프로세스 조회\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eps aux                        \u003cspan style=\"color:#75715e\"\u003e# 시스템 전체 프로세스 상세 목록 조회\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eps -ef | grep java            \u003cspan style=\"color:#75715e\"\u003e# 특정 프로세스(java) 검색\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e\u003ccode\u003etop\u003c/code\u003e / \u003ccode\u003ehtop\u003c/code\u003e\u003c/strong\u003e: 실시간 시스템 자원(CPU, 메모리) 및 프로세스 상태 모니터링\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003etop                           \u003cspan style=\"color:#75715e\"\u003e# 기본 리눅스 성능 모니터링툴\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ehtop                          \u003cspan style=\"color:#75715e\"\u003e# 컬러 UI 지원 향상된 모니터링툴 (설치 필요: apt install htop)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e\u003ccode\u003ekill\u003c/code\u003e / \u003ccode\u003ekillall\u003c/code\u003e\u003c/strong\u003e: 프로세스 종료\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ekill \u0026lt;PID\u0026gt;                    \u003cspan style=\"color:#75715e\"\u003e# 일반 종료 요청 (SIGTERM)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ekill -9 \u0026lt;PID\u0026gt;                 \u003cspan style=\"color:#75715e\"\u003e# 강제 종료 (SIGKILL)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ekillall nginx                 \u003cspan style=\"color:#75715e\"\u003e# 지정한 이름의 모든 프로세스 종료\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"시스템-상태-및-서비스-관리\"\u003e시스템 상태 및 서비스 관리\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003e\u003ccode\u003efree\u003c/code\u003e\u003c/strong\u003e: 시스템 메모리(RAM, Swap) 사용량 확인\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003efree -h                       \u003cspan style=\"color:#75715e\"\u003e# 읽기 쉬운 단위(MB, GB)로 표시\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e\u003ccode\u003euptime\u003c/code\u003e\u003c/strong\u003e: 시스템 가동 시간 및 Load Average 확인\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003euptime\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e\u003ccode\u003esystemctl\u003c/code\u003e\u003c/strong\u003e: systemd 서비스 관리\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003esudo systemctl status nginx   \u003cspan style=\"color:#75715e\"\u003e# 서비스 상태 확인\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003esudo systemctl start nginx    \u003cspan style=\"color:#75715e\"\u003e# 서비스 시작\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003esudo systemctl stop nginx     \u003cspan style=\"color:#75715e\"\u003e# 서비스 중지\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003esudo systemctl restart nginx  \u003cspan style=\"color:#75715e\"\u003e# 서비스 재시작\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003esudo systemctl enable nginx   \u003cspan style=\"color:#75715e\"\u003e# 부팅 시 자동 시작 설정\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003chr\u003e\n\u003ch2 id=\"5-권한-및-소유권-관리\"\u003e5. 권한 및 소유권 관리\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003e\u003ccode\u003echmod\u003c/code\u003e\u003c/strong\u003e (Change Mode): 파일/디렉토리 접근 권한 변경\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003echmod \u003cspan style=\"color:#ae81ff\"\u003e755\u003c/span\u003e script.sh           \u003cspan style=\"color:#75715e\"\u003e# 소유자: 읽기/쓰기/실행(7), 그룹: 읽기/실행(5), 기타: 읽기/실행(5)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003echmod +x script.sh            \u003cspan style=\"color:#75715e\"\u003e# 실행 권한 부여\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003echmod -R \u003cspan style=\"color:#ae81ff\"\u003e644\u003c/span\u003e /path/to/dir     \u003cspan style=\"color:#75715e\"\u003e# 하위 항목 전체 권한 변경\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e\u003ccode\u003echown\u003c/code\u003e\u003c/strong\u003e (Change Owner): 파일/디렉터리의 소유자 및 그룹 변경\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003esudo chown ubuntu:ubuntu file.txt         \u003cspan style=\"color:#75715e\"\u003e# 소유자 및 그룹 변경\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003esudo chown -R ubuntu:ubuntu /var/www      \u003cspan style=\"color:#75715e\"\u003e# 하위 항목 전체 소유자 변경\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e\u003ccode\u003esudo\u003c/code\u003e\u003c/strong\u003e (Superuser Do): 관리자(root) 권한으로 명령어 실행\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003esudo apt update\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003chr\u003e\n\u003ch2 id=\"6-네트워크-및-데이터-전송\"\u003e6. 네트워크 및 데이터 전송\u003c/h2\u003e\n\u003ch3 id=\"네트워크-확인\"\u003e네트워크 확인\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003e\u003ccode\u003eping\u003c/code\u003e\u003c/strong\u003e: 네트워크 연결 상태 확인\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eping 8.8.8.8\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e\u003ccode\u003enetstat\u003c/code\u003e / \u003ccode\u003ess\u003c/code\u003e\u003c/strong\u003e: 네트워크 포트 및 소켓 상태 확인\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ess -tuln                      \u003cspan style=\"color:#75715e\"\u003e# 열려있는 TCP/UDP 포트 목록 조회\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003esudo ss -tulpn | grep \u003cspan style=\"color:#ae81ff\"\u003e8080\u003c/span\u003e    \u003cspan style=\"color:#75715e\"\u003e# 8080 포트를 사용하는 프로세스 확인\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e\u003ccode\u003eip\u003c/code\u003e / \u003ccode\u003eifconfig\u003c/code\u003e\u003c/strong\u003e: 네트워크 인터페이스 IP 확인\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eip a                          \u003cspan style=\"color:#75715e\"\u003e# IP 주소 및 네트워크 인터페이스 정보 확인\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"파일-다운로드-및-전송\"\u003e파일 다운로드 및 전송\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003e\u003ccode\u003ecurl\u003c/code\u003e\u003c/strong\u003e: HTTP/HTTPS 요청 보내기 및 데이터 수신\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ecurl -I https://example.com              \u003cspan style=\"color:#75715e\"\u003e# 응답 헤더 확인\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ecurl -O https://example.com/file.zip     \u003cspan style=\"color:#75715e\"\u003e# 파일 다운로드\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e\u003ccode\u003ewget\u003c/code\u003e\u003c/strong\u003e: 웹에서 파일 다운로드\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ewget https://example.com/file.zip\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e\u003ccode\u003essh\u003c/code\u003e\u003c/strong\u003e: 원격 서버 접속\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003essh user@remote_ip\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003essh -i key.pem user@remote_ip            \u003cspan style=\"color:#75715e\"\u003e# SSH 키 파일로 접속\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e\u003ccode\u003escp\u003c/code\u003e \u0026amp; \u003ccode\u003ersync\u003c/code\u003e\u003c/strong\u003e: 원격 파일 복사 및 동기화\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003escp file.txt user@remote_ip:/path/to/target/      \u003cspan style=\"color:#75715e\"\u003e# SCP로 파일 전송\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ersync -avz ./src/ user@remote_ip:/path/to/target/ \u003cspan style=\"color:#75715e\"\u003e# rsync로 증분 동기화\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003chr\u003e\n\u003ch2 id=\"7-압축-및-아카이브\"\u003e7. 압축 및 아카이브\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003e\u003ccode\u003etar\u003c/code\u003e\u003c/strong\u003e: 파일 묶기 및 압축\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# tar.gz 압축하기\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003etar -czvf archive.tar.gz /path/to/dir\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# tar.gz 압축 해제하기\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003etar -xzvf archive.tar.gz\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e\u003ccode\u003ezip\u003c/code\u003e / \u003ccode\u003eunzip\u003c/code\u003e\u003c/strong\u003e: ZIP 압축 및 해제\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ezip -r archive.zip /path/to/dir\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eunzip archive.zip\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003chr\u003e\n\u003ch2 id=\"8-유용한-bash-팁-및-단축키\"\u003e8. 유용한 Bash 팁 및 단축키\u003c/h2\u003e\n\u003ch3 id=\"단축어-alias--환경-변수\"\u003e단축어 (Alias) \u0026amp; 환경 변수\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003e\u003ccode\u003ealias\u003c/code\u003e\u003c/strong\u003e: 자주 쓰는 긴 명령어를 짧은 별칭으로 등록\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ealias ll\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e\u003cspan style=\"color:#e6db74\"\u003e\u0026#39;ls -alF\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e\u003ccode\u003eexport\u003c/code\u003e\u003c/strong\u003e: 환경 변수 설정\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eexport PATH\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e$PATH:/custom/bin\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e\u003ccode\u003ehistory\u003c/code\u003e\u003c/strong\u003e: 실행했던 명령어 히스토리 조회\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ehistory | grep docker         \u003cspan style=\"color:#75715e\"\u003e# 이전에 실행한 docker 관련 명령어 검색\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"백그라운드-실행\"\u003e백그라운드 실행\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003e\u003ccode\u003e\u0026amp;\u003c/code\u003e\u003c/strong\u003e: 명령어를 백그라운드에서 실행\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003epython3 app.py \u0026amp;\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e\u003ccode\u003enohup\u003c/code\u003e\u003c/strong\u003e: 터미널이 종료되어도 프로세스가 지속되도록 실행\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003enohup python3 app.py \u0026gt; app.log 2\u0026gt;\u0026amp;\u003cspan style=\"color:#ae81ff\"\u003e1\u003c/span\u003e \u0026amp;\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"주요-터미널-단축키\"\u003e주요 터미널 단축키\u003c/h3\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth style=\"text-align: left\"\u003e단축키\u003c/th\u003e\n          \u003cth style=\"text-align: left\"\u003e기능 설명\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e\u003cstrong\u003e\u003ccode\u003eCtrl + C\u003c/code\u003e\u003c/strong\u003e\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e현재 실행 중인 프로세스 즉시 중단\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e\u003cstrong\u003e\u003ccode\u003eCtrl + Z\u003c/code\u003e\u003c/strong\u003e\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e현재 실행 중인 프로세스 일시 정지 (배경 전환)\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e\u003cstrong\u003e\u003ccode\u003eCtrl + R\u003c/code\u003e\u003c/strong\u003e\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e과거 명령 히스토리 실시간 역검색\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e\u003cstrong\u003e\u003ccode\u003eCtrl + L\u003c/code\u003e\u003c/strong\u003e\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e터미널 화면 깨끗하게 지우기 (\u003ccode\u003eclear\u003c/code\u003e 동일)\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e\u003cstrong\u003e\u003ccode\u003eCtrl + A\u003c/code\u003e\u003c/strong\u003e\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e커서를 줄의 맨 앞(시작)으로 이동\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e\u003cstrong\u003e\u003ccode\u003eCtrl + E\u003c/code\u003e\u003c/strong\u003e\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e커서를 줄의 맨 뒤(끝)으로 이동\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e\u003cstrong\u003e\u003ccode\u003eTab\u003c/code\u003e\u003c/strong\u003e\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e파일명/경로/명령어 자동 완성\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003chr\u003e\n\u003ch2 id=\"마무리\"\u003e마무리\u003c/h2\u003e\n\u003cp\u003e위 명령어들은 리눅스 시스템 관리, 서버 운영, DevOps 및 로봇/소프트웨어 개발 환경에서 일상적으로 사용되는 핵심 커맨드입니다. 필요할 때 시트처럼 빠르게 참고하세요!\u003c/p\u003e","title":"리눅스 자주 쓰는 Bash 커맨드 명령어 정리"},{"content":"Docker 환경에서 컨테이너 생성 및 실행, 이미지 관리, 네트워크/볼륨 처리, 시스템 자원 정리 및 Docker Compose 사용 시 자주 사용하는 핵심 명령어 모음입니다.\n1. 컨테이너 생성 및 실행 (Container Lifecycle) 컨테이너 생성 및 실행 (docker run) # 기본 실행 (데몬 방식 백그라운드 -d) docker run -d --name my-nginx -p 80:80 nginx # 대화형 인터랙티브 터미널 접속 실행 (-it) docker run -it --name ubuntu-test ubuntu:22.04 /bin/bash # 컨테이너 종료 시 자동 삭제 (--rm) docker run --rm -it python:3.10 python -c \u0026#34;print(\u0026#39;Hello Docker\u0026#39;)\u0026#34; # 환경 변수 전달 (-e) 및 볼륨 마운트 (-v) docker run -d --name my-db \\ -e MYSQL_ROOT_PASSWORD=secret \\ -v /host/data:/var/lib/mysql \\ -p 3306:3306 mysql:8.0 컨테이너 상태 조회 (docker ps) docker ps # 현재 실행 중인 컨테이너 목록 docker ps -a # 종료된 컨테이너를 포함한 모든 컨테이너 목록 docker ps -q # 컨테이너 ID만 출력 컨테이너 제어 (시작 / 중지 / 재시작 / 삭제) docker start my-nginx # 정지된 컨테이너 시작 docker stop my-nginx # 실행 중인 컨테이너 안전 종료 (SIGTERM) docker kill my-nginx # 강제 종료 (SIGKILL) docker restart my-nginx # 컨테이너 재시작 docker rm my-nginx # 중지된 컨테이너 삭제 docker rm -f my-nginx # 실행 중인 컨테이너 강제 삭제 docker rm $(docker ps -aq) # 모든 중지된 컨테이너 일괄 삭제 2. 컨테이너 접속 및 내부 상태 확인 실행 중인 컨테이너 명령 실행 및 접속 # 실행 중인 컨테이너의 bash/sh 터미널 접속 docker exec -it my-nginx /bin/bash # 접속하지 않고 컨테이너 내부 명령 단발성 실행 docker exec my-nginx ls -la /usr/share/nginx/html 로그 확인 (docker logs) docker logs my-nginx # 전체 로그 출력 docker logs -f my-nginx # 실시간 로그 스트리밍 (Tail -f 개념) docker logs --tail 100 -f my-nginx # 최근 100줄 출력 후 실시간 스트리밍 docker logs --timestamps my-nginx # 타임스탬프와 함께 로그 출력 상태 모니터링 \u0026amp; 세부 정보 조회 docker stats # 모든 실행 중인 컨테이너 CPU/RAM/네트워크 실시간 모니터링 docker stats my-nginx # 특정 컨테이너 리소스 모니터링 docker top my-nginx # 컨테이너 내부 실행 중인 프로세스 목록 docker inspect my-nginx # 컨테이너의 상세 메타데이터(IP, 바인드 마운트, 환경변수 등) JSON 출력 3. 도커 이미지 관리 (Image Management) 이미지 조회 및 검색 docker images # 다운로드된 이미지 목록 출력 docker search nginx # Docker Hub에서 이미지 검색 이미지 빌드 / 다운로드 / 삭제 # Docker Hub에서 이미지 다운로드 docker pull ubuntu:22.04 # Dockerfile 기반 이미지 빌드 docker build -t my-app:v1.0 . docker build --no-cache -t my-app:v1.0 . # 캐시 없이 깨끗하게 빌드 # 이미지 태그 지정 및 푸시 docker tag my-app:v1.0 myregistry.com/my-app:v1.0 docker push myregistry.com/my-app:v1.0 # 이미지 삭제 docker rmi ubuntu:22.04 docker rmi -f my-app:v1.0 # 강제 삭제 docker rmi $(docker images -f \u0026#34;dangling=true\u0026#34; -q) # 태그 없는 댄글링(Dangling) 이미지 삭제 4. 볼륨 \u0026amp; 네트워크 관리 볼륨 (Volume) 관리 docker volume ls # 볼륨 목록 조회 docker volume create my-vol # 새 볼륨 생성 docker volume inspect my-vol# 볼륨 저장 경로 및 정보 확인 docker volume rm my-vol # 볼륨 삭제 docker volume prune # 사용하지 않는 모든 볼륨 정리 네트워크 (Network) 관리 docker network ls # 네트워크 목록 조회 docker network create my-net# 사용자 정의 브릿지 네트워크 생성 docker network inspect my-net# 네트워크 연결 정보 및 IP 확인 docker network connect my-net my-container # 컨테이너를 특정 네트워크에 연결 docker network disconnect my-net my-container # 네트워크 연결 해제 docker network rm my-net # 네트워크 삭제 5. 시스템 청소 및 디스크 자원 정리 (Cleanup) # 도커 디스크 사용량 확인 docker system df # 미사용 자원(중지된 컨테이너, 미사용 네트워크, 댄글링 이미지 등) 일괄 정리 docker system prune # 미사용 볼륨 및 사용되지 않는 모든 이미지까지 포함하여 완전 정리 (주의!) docker system prune -a --volumes 6. 파일 복사 및 백업 / 아카이브 컨테이너 ↔ 호스트 간 파일 복사 (docker cp) # 호스트 파일 -\u0026gt; 컨테이너 내부로 복사 docker cp ./index.html my-nginx:/usr/share/nginx/html/index.html # 컨테이너 파일 -\u0026gt; 호스트로 복사 docker cp my-nginx:/etc/nginx/nginx.conf ./nginx.conf 이미지 파일 백업 / 로드 (save \u0026amp; load) # 이미지를 tar 압축 파일로 저장 (폐쇄망 전송용) docker save -o my-app.tar my-app:v1.0 # tar 아카이브 파일에서 이미지 복원 docker load -i my-app.tar 7. Docker Compose 주요 명령어 docker-compose v2 표준인 docker compose 명령어 사용 기준입니다.\n# 백그라운드 서비스 시작 및 빌드 함께 수행 docker compose up -d --build # 서비스 상태 확인 docker compose ps # 서비스 로그 실시간 확인 docker compose logs -f [service_name] # 특정 서비스 컨테이너 명령 실행 docker compose exec app bash # 서비스 종료 및 컨테이너/네트워크 제거 docker compose down # 서비스 종료 시 볼륨까지 함께 제거 docker compose down -v # 서비스 재시작 docker compose restart [service_name] 💡 자주 쓰는 명령어 원라이너 팁 상황 명령어 모든 정지된 컨테이너 한 번에 삭제 docker container prune -f 모든 멈춘 컨테이너 + 미사용 이미지 삭제 docker system prune -a -f 컨테이너 IP 주소 빠르게 확인 docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' \u0026lt;container_name\u0026gt; 특정 컨테이너 로그의 마지막 50줄 실시간 보기 docker logs --tail 50 -f \u0026lt;container_name\u0026gt; 마무리 Docker를 활용한 서비스 구축 및 문제 해결 시 위 명령어들을 조합하여 사용하면 컨테이너 환경을 효율적으로 다룰 수 있습니다.\n","permalink":"https://wkqco33.github.io/wkqcosoft-docs/posts/docker-commands/","summary":"\u003cp\u003eDocker 환경에서 컨테이너 생성 및 실행, 이미지 관리, 네트워크/볼륨 처리, 시스템 자원 정리 및 Docker Compose 사용 시 자주 사용하는 핵심 명령어 모음입니다.\u003c/p\u003e\n\u003chr\u003e\n\u003ch2 id=\"1-컨테이너-생성-및-실행-container-lifecycle\"\u003e1. 컨테이너 생성 및 실행 (Container Lifecycle)\u003c/h2\u003e\n\u003ch3 id=\"컨테이너-생성-및-실행-docker-run\"\u003e컨테이너 생성 및 실행 (\u003ccode\u003edocker run\u003c/code\u003e)\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 기본 실행 (데몬 방식 백그라운드 -d)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edocker run -d --name my-nginx -p 80:80 nginx\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 대화형 인터랙티브 터미널 접속 실행 (-it)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edocker run -it --name ubuntu-test ubuntu:22.04 /bin/bash\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 컨테이너 종료 시 자동 삭제 (--rm)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edocker run --rm -it python:3.10 python -c \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;print(\u0026#39;Hello Docker\u0026#39;)\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 환경 변수 전달 (-e) 및 볼륨 마운트 (-v)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edocker run -d --name my-db \u003cspan style=\"color:#ae81ff\"\u003e\\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#ae81ff\"\u003e\u003c/span\u003e  -e MYSQL_ROOT_PASSWORD\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003esecret \u003cspan style=\"color:#ae81ff\"\u003e\\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#ae81ff\"\u003e\u003c/span\u003e  -v /host/data:/var/lib/mysql \u003cspan style=\"color:#ae81ff\"\u003e\\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#ae81ff\"\u003e\u003c/span\u003e  -p 3306:3306 mysql:8.0\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"컨테이너-상태-조회-docker-ps\"\u003e컨테이너 상태 조회 (\u003ccode\u003edocker ps\u003c/code\u003e)\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edocker ps                   \u003cspan style=\"color:#75715e\"\u003e# 현재 실행 중인 컨테이너 목록\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edocker ps -a                \u003cspan style=\"color:#75715e\"\u003e# 종료된 컨테이너를 포함한 모든 컨테이너 목록\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edocker ps -q                \u003cspan style=\"color:#75715e\"\u003e# 컨테이너 ID만 출력\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"컨테이너-제어-시작--중지--재시작--삭제\"\u003e컨테이너 제어 (시작 / 중지 / 재시작 / 삭제)\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edocker start my-nginx       \u003cspan style=\"color:#75715e\"\u003e# 정지된 컨테이너 시작\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edocker stop my-nginx        \u003cspan style=\"color:#75715e\"\u003e# 실행 중인 컨테이너 안전 종료 (SIGTERM)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edocker kill my-nginx        \u003cspan style=\"color:#75715e\"\u003e# 강제 종료 (SIGKILL)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edocker restart my-nginx     \u003cspan style=\"color:#75715e\"\u003e# 컨테이너 재시작\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edocker rm my-nginx          \u003cspan style=\"color:#75715e\"\u003e# 중지된 컨테이너 삭제\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edocker rm -f my-nginx       \u003cspan style=\"color:#75715e\"\u003e# 실행 중인 컨테이너 강제 삭제\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edocker rm \u003cspan style=\"color:#66d9ef\"\u003e$(\u003c/span\u003edocker ps -aq\u003cspan style=\"color:#66d9ef\"\u003e)\u003c/span\u003e  \u003cspan style=\"color:#75715e\"\u003e# 모든 중지된 컨테이너 일괄 삭제\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003chr\u003e\n\u003ch2 id=\"2-컨테이너-접속-및-내부-상태-확인\"\u003e2. 컨테이너 접속 및 내부 상태 확인\u003c/h2\u003e\n\u003ch3 id=\"실행-중인-컨테이너-명령-실행-및-접속\"\u003e실행 중인 컨테이너 명령 실행 및 접속\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 실행 중인 컨테이너의 bash/sh 터미널 접속\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edocker exec -it my-nginx /bin/bash\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 접속하지 않고 컨테이너 내부 명령 단발성 실행\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edocker exec my-nginx ls -la /usr/share/nginx/html\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"로그-확인-docker-logs\"\u003e로그 확인 (\u003ccode\u003edocker logs\u003c/code\u003e)\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edocker logs my-nginx        \u003cspan style=\"color:#75715e\"\u003e# 전체 로그 출력\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edocker logs -f my-nginx     \u003cspan style=\"color:#75715e\"\u003e# 실시간 로그 스트리밍 (Tail -f 개념)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edocker logs --tail \u003cspan style=\"color:#ae81ff\"\u003e100\u003c/span\u003e -f my-nginx  \u003cspan style=\"color:#75715e\"\u003e# 최근 100줄 출력 후 실시간 스트리밍\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edocker logs --timestamps my-nginx    \u003cspan style=\"color:#75715e\"\u003e# 타임스탬프와 함께 로그 출력\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"상태-모니터링--세부-정보-조회\"\u003e상태 모니터링 \u0026amp; 세부 정보 조회\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edocker stats                \u003cspan style=\"color:#75715e\"\u003e# 모든 실행 중인 컨테이너 CPU/RAM/네트워크 실시간 모니터링\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edocker stats my-nginx       \u003cspan style=\"color:#75715e\"\u003e# 특정 컨테이너 리소스 모니터링\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edocker top my-nginx         \u003cspan style=\"color:#75715e\"\u003e# 컨테이너 내부 실행 중인 프로세스 목록\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edocker inspect my-nginx     \u003cspan style=\"color:#75715e\"\u003e# 컨테이너의 상세 메타데이터(IP, 바인드 마운트, 환경변수 등) JSON 출력\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003chr\u003e\n\u003ch2 id=\"3-도커-이미지-관리-image-management\"\u003e3. 도커 이미지 관리 (Image Management)\u003c/h2\u003e\n\u003ch3 id=\"이미지-조회-및-검색\"\u003e이미지 조회 및 검색\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edocker images               \u003cspan style=\"color:#75715e\"\u003e# 다운로드된 이미지 목록 출력\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edocker search nginx         \u003cspan style=\"color:#75715e\"\u003e# Docker Hub에서 이미지 검색\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"이미지-빌드--다운로드--삭제\"\u003e이미지 빌드 / 다운로드 / 삭제\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# Docker Hub에서 이미지 다운로드\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edocker pull ubuntu:22.04\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# Dockerfile 기반 이미지 빌드\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edocker build -t my-app:v1.0 .\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edocker build --no-cache -t my-app:v1.0 .  \u003cspan style=\"color:#75715e\"\u003e# 캐시 없이 깨끗하게 빌드\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 이미지 태그 지정 및 푸시\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edocker tag my-app:v1.0 myregistry.com/my-app:v1.0\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edocker push myregistry.com/my-app:v1.0\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 이미지 삭제\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edocker rmi ubuntu:22.04\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edocker rmi -f my-app:v1.0   \u003cspan style=\"color:#75715e\"\u003e# 강제 삭제\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edocker rmi \u003cspan style=\"color:#66d9ef\"\u003e$(\u003c/span\u003edocker images -f \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;dangling=true\u0026#34;\u003c/span\u003e -q\u003cspan style=\"color:#66d9ef\"\u003e)\u003c/span\u003e \u003cspan style=\"color:#75715e\"\u003e# 태그 없는 댄글링(Dangling) 이미지 삭제\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003chr\u003e\n\u003ch2 id=\"4-볼륨--네트워크-관리\"\u003e4. 볼륨 \u0026amp; 네트워크 관리\u003c/h2\u003e\n\u003ch3 id=\"볼륨-volume-관리\"\u003e볼륨 (Volume) 관리\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edocker volume ls            \u003cspan style=\"color:#75715e\"\u003e# 볼륨 목록 조회\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edocker volume create my-vol \u003cspan style=\"color:#75715e\"\u003e# 새 볼륨 생성\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edocker volume inspect my-vol# 볼륨 저장 경로 및 정보 확인\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edocker volume rm my-vol     \u003cspan style=\"color:#75715e\"\u003e# 볼륨 삭제\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edocker volume prune         \u003cspan style=\"color:#75715e\"\u003e# 사용하지 않는 모든 볼륨 정리\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"네트워크-network-관리\"\u003e네트워크 (Network) 관리\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edocker network ls           \u003cspan style=\"color:#75715e\"\u003e# 네트워크 목록 조회\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edocker network create my-net# 사용자 정의 브릿지 네트워크 생성\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edocker network inspect my-net# 네트워크 연결 정보 및 IP 확인\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edocker network connect my-net my-container \u003cspan style=\"color:#75715e\"\u003e# 컨테이너를 특정 네트워크에 연결\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edocker network disconnect my-net my-container \u003cspan style=\"color:#75715e\"\u003e# 네트워크 연결 해제\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edocker network rm my-net    \u003cspan style=\"color:#75715e\"\u003e# 네트워크 삭제\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003chr\u003e\n\u003ch2 id=\"5-시스템-청소-및-디스크-자원-정리-cleanup\"\u003e5. 시스템 청소 및 디스크 자원 정리 (Cleanup)\u003c/h2\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 도커 디스크 사용량 확인\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edocker system df\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 미사용 자원(중지된 컨테이너, 미사용 네트워크, 댄글링 이미지 등) 일괄 정리\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edocker system prune\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 미사용 볼륨 및 사용되지 않는 모든 이미지까지 포함하여 완전 정리 (주의!)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edocker system prune -a --volumes\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003chr\u003e\n\u003ch2 id=\"6-파일-복사-및-백업--아카이브\"\u003e6. 파일 복사 및 백업 / 아카이브\u003c/h2\u003e\n\u003ch3 id=\"컨테이너--호스트-간-파일-복사-docker-cp\"\u003e컨테이너 ↔ 호스트 간 파일 복사 (\u003ccode\u003edocker cp\u003c/code\u003e)\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 호스트 파일 -\u0026gt; 컨테이너 내부로 복사\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edocker cp ./index.html my-nginx:/usr/share/nginx/html/index.html\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 컨테이너 파일 -\u0026gt; 호스트로 복사\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edocker cp my-nginx:/etc/nginx/nginx.conf ./nginx.conf\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"이미지-파일-백업--로드-save--load\"\u003e이미지 파일 백업 / 로드 (\u003ccode\u003esave\u003c/code\u003e \u0026amp; \u003ccode\u003eload\u003c/code\u003e)\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 이미지를 tar 압축 파일로 저장 (폐쇄망 전송용)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edocker save -o my-app.tar my-app:v1.0\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# tar 아카이브 파일에서 이미지 복원\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edocker load -i my-app.tar\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003chr\u003e\n\u003ch2 id=\"7-docker-compose-주요-명령어\"\u003e7. Docker Compose 주요 명령어\u003c/h2\u003e\n\u003cp\u003e\u003ccode\u003edocker-compose\u003c/code\u003e v2 표준인 \u003ccode\u003edocker compose\u003c/code\u003e 명령어 사용 기준입니다.\u003c/p\u003e","title":"자주 쓰는 Docker 명령어 정리"},{"content":"쿠버네티스(Kubernetes) 클러스터 운영 및 앱 배포, 디버깅 시 일상적으로 자주 쓰이는 필수 kubectl 명령어 모음집입니다.\n1. 클러스터 및 컨텍스트(Context) 정보 확인 컨텍스트 및 네임스페이스 설정 # 현재 연결된 클러스터 정보 확인 kubectl cluster-info # Kubeconfig 컨텍스트 목록 조회 kubectl config get-contexts # 현재 활성화된 컨텍스트 확인 kubectl config current-context # 컨텍스트 전환 kubectl config use-context my-cluster-context # 현재 컨텍스트의 기본 네임스페이스 변경 kubectl config set-context --current --namespace=my-namespace 2. 리소스 조회 및 상세 상태 확인 (Get \u0026amp; Describe) 기본 리소스 목록 조회 (kubectl get) # 특정 네임스페이스의 포드(Pod) 목록 조회 kubectl get pods # 모든 네임스페이스의 포드 조회 (-A 또는 --all-namespaces) kubectl get pods -A # IP, 노드 위치 등 추가 정보를 포함하여 조회 (-o wide) kubectl get pods -o wide # 다양한 리소스 목록 동시에 조회 kubectl get pods,svc,deploy -n default # 모든 주요 리소스 요약 조회 kubectl get all -n default # YAML 또는 JSON 형식으로 출력 kubectl get pod my-pod -o yaml kubectl get deploy my-deploy -o json 주요 리소스 단축어 매핑 리소스 이름 단축어 설명 pods po 파드 deployments deploy 디플로이먼트 services svc 서비스 namespaces ns 네임스페이스 persistentvolumeclaims pvc 영구 볼륨 요청 configmaps cm 컨피그맵 secrets secret 시크릿 리소스 상세 정보 및 이벤트 분석 (kubectl describe) # 포드 상세 정보 및 이벤트(Event) 확인 (배포 실패, OOM, ImagePullBackOff 원인 분석) kubectl describe pod my-pod # 노드 상세 정보 및 리소스 할당 현황 확인 kubectl describe node worker-node-1 # 서비스 엔드포인트 및 레이블 설정 상세 확인 kubectl describe svc my-service 3. 리소스 생성 / 수정 / 삭제 (Apply, Edit, Delete) YAML 선언형 리소스 관리 # 매니페스트(YAML) 파일 적용/업데이트 kubectl apply -f deployment.yaml # 디렉토리 내의 모든 YAML 파일 적용 kubectl apply -f ./manifests/ # 선언된 리소스 삭제 kubectl delete -f deployment.yaml 리소스 직접 수정 및 삭제 # 실행 중인 리소스의 YAML을 에디터로 즉시 수정 kubectl edit deployment my-deploy # 특정 리소스 직접 삭제 kubectl delete pod my-pod kubectl delete deployment my-deploy -n default # 강제 포드 삭제 (Terminating 상태에 갇혔을 때) kubectl delete pod my-pod --grace-period=0 --force 명령형(Imperative) 리소스 생성 (테스트용) # 네임스페이스 생성 kubectl create namespace dev # 빠른 테스트용 포드 생성 kubectl run nginx-test --image=nginx:alpine # 빠른 디플로이먼트 생성 kubectl create deployment web-app --image=nginx --replicas=3 4. 디버깅 및 트러블슈팅 (Logging \u0026amp; Exec) 로그 확인 (kubectl logs) # 포드 로그 조회 kubectl logs my-pod # 실시간 로그 스트리밍 (-f) kubectl logs -f my-pod # 최근 100줄 출력 후 실시간 감시 kubectl logs --tail=100 -f my-pod # 멀티 컨테이너 포드에서 특정 컨테이너 로그 지정 (-c) kubectl logs -f my-pod -c app-container # 이전(재시작 전 Crash 발생) 컨테이너 로그 확인 (--previous) kubectl logs my-pod --previous # 특정 라벨을 가진 모든 포드의 로그 합쳐서 확인 (-l) kubectl logs -f -l app=web-app 컨테이너 내부 접속 및 명령 실행 (kubectl exec) # 포드 내부 대화형 터미널 접속 kubectl exec -it my-pod -- /bin/bash kubectl exec -it my-pod -- /bin/sh # 접속 없이 명령 단발성 실행 kubectl exec my-pod -- env 포트 포워딩 (kubectl port-forward) # 로컬 8080 포트를 포드의 80 포트로 바인딩하여 로컬 접근 테스트 kubectl port-forward pod/my-pod 8080:80 # 로컬 8080 포트를 서비스로 포워딩 kubectl port-forward svc/my-service 8080:80 자원 사용량 모니터링 (kubectl top) # 노드별 CPU/메모리 사용량 확인 (Metrics Server 필요) kubectl top nodes # 포드별 CPU/메모리 사용량 확인 kubectl top pods -n default --sort-by=cpu 5. 디플로이먼트 \u0026amp; 스케일링 \u0026amp; 롤아웃 관리 스케일링 (스케일 인/아웃) # 파드 개수 변경 (Replicas 조정) kubectl scale deployment my-deploy --replicas=5 롤아웃(Rollout) 및 롤백(Rollback) # 배포 진행 상태 확인 kubectl rollout status deployment/my-deploy # 배포 이력(히스토리) 확인 kubectl rollout history deployment/my-deploy # 이전 버전으로 배포 롤백 kubectl rollout undo deployment/my-deploy # 특정 히스토리 버전을 지정하여 롤백 kubectl rollout undo deployment/my-deploy --to-revision=2 # 포드 일괄 재시작 (무중단 롤링 업데이트 재배포) kubectl rollout restart deployment/my-deploy 6. 노드 점검 및 스케줄링 제어 # 노드에 스케줄링 중단 설정 (유지보수 모드) kubectl cordon worker-node-1 # 노드 스케줄링 재개 kubectl uncordon worker-node-1 # 노드의 모든 파드를 다른 노드로 이주(Evict) 후 안전 비우기 kubectl drain worker-node-1 --ignore-daemonsets --delete-emptydir-data 7. 유용한 팁 \u0026amp; 템플릿 템플릿(Dry-run) 생성 YAML 템플릿 초안 빠르게 뽑아내기 (--dry-run=client -o yaml) # 실행 없이 Pod 템플릿 YAML 출력 kubectl run my-pod --image=nginx --dry-run=client -o yaml \u0026gt; pod.yaml # Deployment 템플릿 YAML 생성 kubectl create deployment my-app --image=nginx:alpine --replicas=3 --dry-run=client -o yaml \u0026gt; deploy.yaml # Service 템플릿 YAML 생성 kubectl expose deployment my-app --port=80 --target-port=8080 --type=ClusterIP --dry-run=client -o yaml \u0026gt; svc.yaml 단축어 설정 (.bashrc 또는 .zshrc) # kubectl 단축어 k 등록 및 자동완성 설정 alias k=\u0026#39;kubectl\u0026#39; complete -o default -F __start_kubectl k 추천 서드파티 도구 kubectx / kubens: 클러스터 컨텍스트 및 네임스페이스를 한 줄 명령어로 빠르게 전환하는 CLI 툴 k9s: 터미널 기반의 훌륭한 쿠버네티스 대시보드 UI 툴 마무리 쿠버네티스 리소스 트러블슈팅 시 kubectl get -\u0026gt; describe -\u0026gt; logs -\u0026gt; exec 흐름을 익혀두면 대부분의 장애 원인을 신속하게 파악할 수 있습니다!\n","permalink":"https://wkqco33.github.io/wkqcosoft-docs/posts/kubectl-commands/","summary":"\u003cp\u003e쿠버네티스(Kubernetes) 클러스터 운영 및 앱 배포, 디버깅 시 일상적으로 자주 쓰이는 필수 \u003ccode\u003ekubectl\u003c/code\u003e 명령어 모음집입니다.\u003c/p\u003e\n\u003chr\u003e\n\u003ch2 id=\"1-클러스터-및-컨텍스트context-정보-확인\"\u003e1. 클러스터 및 컨텍스트(Context) 정보 확인\u003c/h2\u003e\n\u003ch3 id=\"컨텍스트-및-네임스페이스-설정\"\u003e컨텍스트 및 네임스페이스 설정\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 현재 연결된 클러스터 정보 확인\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ekubectl cluster-info\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# Kubeconfig 컨텍스트 목록 조회\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ekubectl config get-contexts\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 현재 활성화된 컨텍스트 확인\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ekubectl config current-context\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 컨텍스트 전환\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ekubectl config use-context my-cluster-context\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 현재 컨텍스트의 기본 네임스페이스 변경\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ekubectl config set-context --current --namespace\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003emy-namespace\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003chr\u003e\n\u003ch2 id=\"2-리소스-조회-및-상세-상태-확인-get--describe\"\u003e2. 리소스 조회 및 상세 상태 확인 (Get \u0026amp; Describe)\u003c/h2\u003e\n\u003ch3 id=\"기본-리소스-목록-조회-kubectl-get\"\u003e기본 리소스 목록 조회 (\u003ccode\u003ekubectl get\u003c/code\u003e)\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 특정 네임스페이스의 포드(Pod) 목록 조회\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ekubectl get pods\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 모든 네임스페이스의 포드 조회 (-A 또는 --all-namespaces)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ekubectl get pods -A\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# IP, 노드 위치 등 추가 정보를 포함하여 조회 (-o wide)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ekubectl get pods -o wide\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 다양한 리소스 목록 동시에 조회\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ekubectl get pods,svc,deploy -n default\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 모든 주요 리소스 요약 조회\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ekubectl get all -n default\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# YAML 또는 JSON 형식으로 출력\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ekubectl get pod my-pod -o yaml\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ekubectl get deploy my-deploy -o json\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"주요-리소스-단축어-매핑\"\u003e주요 리소스 단축어 매핑\u003c/h3\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth style=\"text-align: left\"\u003e리소스 이름\u003c/th\u003e\n          \u003cth style=\"text-align: left\"\u003e단축어\u003c/th\u003e\n          \u003cth style=\"text-align: left\"\u003e설명\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e\u003ccode\u003epods\u003c/code\u003e\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e\u003ccode\u003epo\u003c/code\u003e\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e파드\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e\u003ccode\u003edeployments\u003c/code\u003e\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e\u003ccode\u003edeploy\u003c/code\u003e\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e디플로이먼트\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e\u003ccode\u003eservices\u003c/code\u003e\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e\u003ccode\u003esvc\u003c/code\u003e\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e서비스\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e\u003ccode\u003enamespaces\u003c/code\u003e\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e\u003ccode\u003ens\u003c/code\u003e\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e네임스페이스\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e\u003ccode\u003epersistentvolumeclaims\u003c/code\u003e\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e\u003ccode\u003epvc\u003c/code\u003e\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e영구 볼륨 요청\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e\u003ccode\u003econfigmaps\u003c/code\u003e\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e\u003ccode\u003ecm\u003c/code\u003e\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e컨피그맵\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e\u003ccode\u003esecrets\u003c/code\u003e\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e\u003ccode\u003esecret\u003c/code\u003e\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e시크릿\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003ch3 id=\"리소스-상세-정보-및-이벤트-분석-kubectl-describe\"\u003e리소스 상세 정보 및 이벤트 분석 (\u003ccode\u003ekubectl describe\u003c/code\u003e)\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 포드 상세 정보 및 이벤트(Event) 확인 (배포 실패, OOM, ImagePullBackOff 원인 분석)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ekubectl describe pod my-pod\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 노드 상세 정보 및 리소스 할당 현황 확인\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ekubectl describe node worker-node-1\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 서비스 엔드포인트 및 레이블 설정 상세 확인\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ekubectl describe svc my-service\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003chr\u003e\n\u003ch2 id=\"3-리소스-생성--수정--삭제-apply-edit-delete\"\u003e3. 리소스 생성 / 수정 / 삭제 (Apply, Edit, Delete)\u003c/h2\u003e\n\u003ch3 id=\"yaml-선언형-리소스-관리\"\u003eYAML 선언형 리소스 관리\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 매니페스트(YAML) 파일 적용/업데이트\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ekubectl apply -f deployment.yaml\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 디렉토리 내의 모든 YAML 파일 적용\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ekubectl apply -f ./manifests/\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 선언된 리소스 삭제\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ekubectl delete -f deployment.yaml\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"리소스-직접-수정-및-삭제\"\u003e리소스 직접 수정 및 삭제\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 실행 중인 리소스의 YAML을 에디터로 즉시 수정\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ekubectl edit deployment my-deploy\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 특정 리소스 직접 삭제\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ekubectl delete pod my-pod\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ekubectl delete deployment my-deploy -n default\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 강제 포드 삭제 (Terminating 상태에 갇혔을 때)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ekubectl delete pod my-pod --grace-period\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e\u003cspan style=\"color:#ae81ff\"\u003e0\u003c/span\u003e --force\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"명령형imperative-리소스-생성-테스트용\"\u003e명령형(Imperative) 리소스 생성 (테스트용)\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 네임스페이스 생성\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ekubectl create namespace dev\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 빠른 테스트용 포드 생성\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ekubectl run nginx-test --image\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003enginx:alpine\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 빠른 디플로이먼트 생성\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ekubectl create deployment web-app --image\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003enginx --replicas\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e\u003cspan style=\"color:#ae81ff\"\u003e3\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003chr\u003e\n\u003ch2 id=\"4-디버깅-및-트러블슈팅-logging--exec\"\u003e4. 디버깅 및 트러블슈팅 (Logging \u0026amp; Exec)\u003c/h2\u003e\n\u003ch3 id=\"로그-확인-kubectl-logs\"\u003e로그 확인 (\u003ccode\u003ekubectl logs\u003c/code\u003e)\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 포드 로그 조회\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ekubectl logs my-pod\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 실시간 로그 스트리밍 (-f)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ekubectl logs -f my-pod\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 최근 100줄 출력 후 실시간 감시\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ekubectl logs --tail\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e\u003cspan style=\"color:#ae81ff\"\u003e100\u003c/span\u003e -f my-pod\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 멀티 컨테이너 포드에서 특정 컨테이너 로그 지정 (-c)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ekubectl logs -f my-pod -c app-container\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 이전(재시작 전 Crash 발생) 컨테이너 로그 확인 (--previous)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ekubectl logs my-pod --previous\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 특정 라벨을 가진 모든 포드의 로그 합쳐서 확인 (-l)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ekubectl logs -f -l app\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003eweb-app\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"컨테이너-내부-접속-및-명령-실행-kubectl-exec\"\u003e컨테이너 내부 접속 및 명령 실행 (\u003ccode\u003ekubectl exec\u003c/code\u003e)\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 포드 내부 대화형 터미널 접속\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ekubectl exec -it my-pod -- /bin/bash\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ekubectl exec -it my-pod -- /bin/sh\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 접속 없이 명령 단발성 실행\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ekubectl exec my-pod -- env\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"포트-포워딩-kubectl-port-forward\"\u003e포트 포워딩 (\u003ccode\u003ekubectl port-forward\u003c/code\u003e)\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 로컬 8080 포트를 포드의 80 포트로 바인딩하여 로컬 접근 테스트\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ekubectl port-forward pod/my-pod 8080:80\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 로컬 8080 포트를 서비스로 포워딩\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ekubectl port-forward svc/my-service 8080:80\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"자원-사용량-모니터링-kubectl-top\"\u003e자원 사용량 모니터링 (\u003ccode\u003ekubectl top\u003c/code\u003e)\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 노드별 CPU/메모리 사용량 확인 (Metrics Server 필요)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ekubectl top nodes\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 포드별 CPU/메모리 사용량 확인\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ekubectl top pods -n default --sort-by\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003ecpu\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003chr\u003e\n\u003ch2 id=\"5-디플로이먼트--스케일링--롤아웃-관리\"\u003e5. 디플로이먼트 \u0026amp; 스케일링 \u0026amp; 롤아웃 관리\u003c/h2\u003e\n\u003ch3 id=\"스케일링-스케일-인아웃\"\u003e스케일링 (스케일 인/아웃)\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 파드 개수 변경 (Replicas 조정)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ekubectl scale deployment my-deploy --replicas\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e\u003cspan style=\"color:#ae81ff\"\u003e5\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"롤아웃rollout-및-롤백rollback\"\u003e롤아웃(Rollout) 및 롤백(Rollback)\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 배포 진행 상태 확인\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ekubectl rollout status deployment/my-deploy\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 배포 이력(히스토리) 확인\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ekubectl rollout history deployment/my-deploy\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 이전 버전으로 배포 롤백\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ekubectl rollout undo deployment/my-deploy\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 특정 히스토리 버전을 지정하여 롤백\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ekubectl rollout undo deployment/my-deploy --to-revision\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e\u003cspan style=\"color:#ae81ff\"\u003e2\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 포드 일괄 재시작 (무중단 롤링 업데이트 재배포)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ekubectl rollout restart deployment/my-deploy\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003chr\u003e\n\u003ch2 id=\"6-노드-점검-및-스케줄링-제어\"\u003e6. 노드 점검 및 스케줄링 제어\u003c/h2\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 노드에 스케줄링 중단 설정 (유지보수 모드)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ekubectl cordon worker-node-1\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 노드 스케줄링 재개\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ekubectl uncordon worker-node-1\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 노드의 모든 파드를 다른 노드로 이주(Evict) 후 안전 비우기\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ekubectl drain worker-node-1 --ignore-daemonsets --delete-emptydir-data\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003chr\u003e\n\u003ch2 id=\"7-유용한-팁--템플릿-템플릿dry-run-생성\"\u003e7. 유용한 팁 \u0026amp; 템플릿 템플릿(Dry-run) 생성\u003c/h2\u003e\n\u003ch3 id=\"yaml-템플릿-초안-빠르게-뽑아내기---dry-runclient--o-yaml\"\u003eYAML 템플릿 초안 빠르게 뽑아내기 (\u003ccode\u003e--dry-run=client -o yaml\u003c/code\u003e)\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 실행 없이 Pod 템플릿 YAML 출력\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ekubectl run my-pod --image\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003enginx --dry-run\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003eclient -o yaml \u0026gt; pod.yaml\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# Deployment 템플릿 YAML 생성\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ekubectl create deployment my-app --image\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003enginx:alpine --replicas\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e\u003cspan style=\"color:#ae81ff\"\u003e3\u003c/span\u003e --dry-run\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003eclient -o yaml \u0026gt; deploy.yaml\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# Service 템플릿 YAML 생성\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ekubectl expose deployment my-app --port\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e\u003cspan style=\"color:#ae81ff\"\u003e80\u003c/span\u003e --target-port\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e\u003cspan style=\"color:#ae81ff\"\u003e8080\u003c/span\u003e --type\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003eClusterIP --dry-run\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003eclient -o yaml \u0026gt; svc.yaml\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"단축어-설정-bashrc-또는-zshrc\"\u003e단축어 설정 (\u003ccode\u003e.bashrc\u003c/code\u003e 또는 \u003ccode\u003e.zshrc\u003c/code\u003e)\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# kubectl 단축어 k 등록 및 자동완성 설정\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ealias k\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e\u003cspan style=\"color:#e6db74\"\u003e\u0026#39;kubectl\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ecomplete -o default -F __start_kubectl k\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"추천-서드파티-도구\"\u003e추천 서드파티 도구\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003e\u003ccode\u003ekubectx\u003c/code\u003e / \u003ccode\u003ekubens\u003c/code\u003e\u003c/strong\u003e: 클러스터 컨텍스트 및 네임스페이스를 한 줄 명령어로 빠르게 전환하는 CLI 툴\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e\u003ccode\u003ek9s\u003c/code\u003e\u003c/strong\u003e: 터미널 기반의 훌륭한 쿠버네티스 대시보드 UI 툴\u003c/li\u003e\n\u003c/ul\u003e\n\u003chr\u003e\n\u003ch2 id=\"마무리\"\u003e마무리\u003c/h2\u003e\n\u003cp\u003e쿠버네티스 리소스 트러블슈팅 시 \u003ccode\u003ekubectl get -\u0026gt; describe -\u0026gt; logs -\u0026gt; exec\u003c/code\u003e 흐름을 익혀두면 대부분의 장애 원인을 신속하게 파악할 수 있습니다!\u003c/p\u003e","title":"자주 쓰는 kubectl 명령어 정리"},{"content":" 📌 Executive Summary\n다양해진 로컬 AI 선택지: Ollama 플랫폼을 통해 Meta, Mistral AI, Google, Alibaba, Microsoft의 최신 오픈소스 언어 모델을 단일 PC/서버에서 손쉽게 구동할 수 있습니다. 모델별 뚜렷한 특장점: 범용 최강 \u0026amp; 생태계: Meta Llama 3 (8B / 70B) 고효율 \u0026amp; 완전 오픈소스: Mistral AI Mistral (7B / Nemo) 코딩 \u0026amp; 수학 \u0026amp; 경량화: Google DeepMind Gemma (2B / 9B / 27B) 다국어 \u0026amp; 도구 호출 (한국어 최적): Alibaba Qwen 2.5 (0.5B ~ 72B) 초소형 고성능 추론: Microsoft Phi 3.5 (3.8B / 14B) 하드웨어 맞춤 선택 필수: 보유한 VRAM/RAM 용량과 상업적 라이선스 조건에 맞춰 적합한 모델을 선택하는 전략이 요구됩니다. 📊 리포트 개요 및 모델 종합 비교표 항목 세부 내용 보고서 주제 Ollama 생태계 Top 5 오픈소스 언어 모델 심층 비교 분석 대상 모델군 Llama 3.x, Mistral, Gemma 2/3, Qwen 2.5, Phi 3/3.5 비교 지표 파라미터 크기, 라이선스, 하드웨어 요구사양(RAM), 특화 영역, 한국어 지원 🏆 Top 5 오픈소스 LLM 한눈에 비교 모델명 개발사 파라미터 크기 라이선스 최소 권장 RAM 강점 및 추천 용도 한국어 성능 Llama 3.x Meta 1B, 3B, 8B, 70B Meta Llama 3 (상업적 조건부) 8GB ~ 64GB 범용 언어 이해, 방대한 커뮤니티 생태계, 요약 보통 ~ 우수 Mistral Mistral AI 7B, Nemo (12B) Apache 2.0 (완전 오픈) 8GB ~ 16GB 뛰어난 경량 추론, 유럽 다국어, 고효율 서빙 보통 Gemma 2/3 Google DeepMind 2B, 9B, 27B Gemma Open Terms 6GB ~ 24GB 코딩, 수학적 추론, 사실 기반 질의응답 우수 Qwen 2.5 Alibaba 0.5B ~ 72B Apache 2.0 4GB ~ 64GB 한국어/다국어 최상급, 코딩(Coder), 함수 호출 최상 Phi 3.5 Microsoft 3.8B, 14B MIT (완전 자유) 4GB ~ 12GB 소형 파라미터 대비 압도적 추론, 온디바이스/엣지 보통 🔍 핵심 분석 1. Ollama 플랫폼의 특징과 가치 Ollama는 터미널 명령어 한 줄로 모델을 수급하고 실행할 수 있는 표준 로컬 LLM 환경입니다.\n원스톱 모델 관리: ollama run \u0026lt;모델명\u0026gt;으로 자동 다운로드, GPU 가속 메모리 할당, 인터랙티브 대화 셸 실행까지 한 번에 완료. OpenAI 호환 API: 기존 애플리케이션이나 데스크톱 앱(Askimo, Open-WebUI, Chatbox 등)과 즉시 연동. Modelfile을 통한 커스텀 확장: 모델 파라미터와 프롬프트를 튜닝하여 사내 맞춤 모델 생성 가능. 2. 주요 모델별 심층 분석 2.1 Llama 3.x (Meta) Meta가 주도하는 오픈소스 AI 생태계의 사실상 표준 모델입니다.\n주요 특징: 방대한 사전학습 데이터를 기반으로 한 높은 범용 언어 이해도와 탄탄한 커뮤니티 파인튜닝 생태계를 보유하고 있습니다. 라이선스: Meta Llama License (월 활성 사용자 7억 명 이하 상업적 무료 사용 가능) 적합한 분야: 범용 대화 챗봇, 사내 문서 요약, 일반적인 프로그래밍 보조 Ollama 실행 명령: ollama run llama3.2 # 3B 경량 모델 ollama run llama3.1:8b # 8B 범용 표준 모델 2.2 Mistral (Mistral AI) 프랑스 AI 스타트업 Mistral AI가 개발한 대표적인 유럽산 오픈소스 모델입니다.\n주요 특징: 7B 크기에서도 대형 모델에 필적하는 높은 토큰 효율성과 빠른 추론 속도를 자랑합니다. 라이선스: Apache 2.0 (완전 오픈소스로 상업적 제약 없음) 적합한 분야: 상업용 임베디드 AI 솔루션, 유럽 다국어 번역, 비용 효율적 경량 배포 Ollama 실행 명령: ollama run mistral ollama run mistral-nemo # 12B 고성능 모델 2.3 Gemma 2 / 3 (Google DeepMind) 구글 딥마인드가 Gemini 아키텍처 기술을 기반으로 제작한 고품질 경량 모델입니다.\n주요 특징: 작은 파라미터(2B, 9B)에서도 코딩, 수학, 정밀 논리 추론 벤치마크 점수가 매우 높으며, 2B 모델은 RAM 6GB 이하의 저사양 PC에서도 원활히 동작합니다. 라이선스: Google Gemma Terms (오픈 가중치 제공) 적합한 분야: 코딩 보조, 복잡한 로직/수학 연산, 리소스가 제한된 랩탑 환경 Ollama 실행 명령: ollama run gemma2:2b # 초경량 모델 ollama run gemma2:9b # 9B 고품질 모델 2.4 Qwen 2.5 (Alibaba) 알리바바가 공개한 다국어 및 코딩 특화 최상급 오픈소스 모델 라인업입니다.\n주요 특징: 한국어를 포함한 아시아권 언어 이해도가 오픈소스 모델 중 최상위권이며, 코딩 특화(Qwen2.5-Coder) 및 도구 호출(Tool Calling/Function Calling) 능력이 탁월합니다. 라이선스: Apache 2.0 적합한 분야: 한국어 서비스 챗봇, RAG 에이전트 구축, 코드 생성 및 자동화 파이프라인 Ollama 실행 명령: ollama run qwen2.5:7b ollama run qwen2.5-coder:7b # 코딩 특화 2.5 Phi 3 / 3.5 (Microsoft) 마이크로소프트 연구진이 고품질 합성 데이터(Textbooks Are All You Need)로 훈련한 소형 언어 모델(SLM)입니다.\n주요 특징: 3.8B 파라미터 크기임에도 대형 모델에 근접하는 상식 추론 및 다단계 논리 해결력을 보여줍니다. 라이선스: MIT License (자유로운 수정 및 상업적 배포) 적합한 분야: 온디바이스 AI, 모바일/엣지 디바이스, 초저지연 실시간 질의응답 Ollama 실행 명령: ollama run phi3.5 3. 하드웨어 사양 및 목적별 선택 가이드 (Decision Matrix) 💻 하드웨어 환경별 추천 내 PC / 서버 사양 추천 모델 비고 일반 노트북 / CPU 전용 (RAM 8GB 이하) gemma2:2b, qwen2.5:3b, phi3.5:mini 경량 모델로 CPU 점유율 및 발열 최소화 엔트리 GPU (VRAM 6GB ~ 8GB / RAM 16GB) llama3.2:3b, qwen2.5:7b, mistral:7b 빠른 토큰 생성 속도 및 안정적 메모리 유지 중급 GPU (VRAM 12GB ~ 16GB / RAM 32GB) gemma2:9b, mistral-nemo:12b, qwen2.5-coder:7b 정밀한 추론 및 전문 코딩 어시스턴트 구동 고사양 워크스테이션 (VRAM 24GB+ / RAM 64GB+) gemma2:27b, qwen2.5:32b, llama3.1:70b (양자화) 클라우드 상용 LLM에 근접하는 고품질 결과 🎯 사용 목적별 추천 [ [ [ [ [ 한 코 상 저 범 국 드 업 전 용 어 용 력 작 연 기 성 서 엣 구 반 비 지 \u0026amp; 스 / 및 업 빠 무 디 배 른 커 / 버 포 뮤 챗 깅 ] 속 니 봇 ] 도 티 ] ] ] ─ ─ \u0026gt; ─ ─ ─ ─ ─ ─ ─ ─ Q \u0026gt; \u0026gt; \u0026gt; \u0026gt; w e Q M P L n w i h l e s i a 2 n t m . r 3 a 5 2 a . . l 5 3 ( 5 . 7 ( ( 1 B C 7 M B I ( d ) T 8 e B 1 r 또 라 ) 4 는 이 B ( 선 ) 7 Q 스 B w ) ) e n 또 또 는 는 2 . G G 5 e e m m ( m m A a a p a 2 2 c h ( ( e 2 9 B B 2 ) ) . 0 라 이 선 스 ) 🎯 결론 및 시사점 원픽 추천 (한국어 + 코딩 + 다목적): 현 시점에서 한국어 지원과 성능의 밸런스가 가장 우수한 모델은 Qwen 2.5 (7B / 14B) 계열입니다. 라이선스 검토 필수: 기업 내 상용 배포가 목적이라면 제약이 없는 Apache 2.0 (Mistral, Qwen) 또는 MIT (Phi) 라이선스 모델을 우선 검토해야 합니다. 양자화(Quantization) 적극 활용: Ollama는 기본적으로 4-bit 양자화(Q4_K_M 등) 가중치를 배포하므로, 제한된 로컬 하드웨어에서도 7B~9B 급 모델을 쾌적하게 운용할 수 있습니다. ⚠️ 한계 및 주의사항 벤치마크와 실제 체감의 괴리: MMLU, GSM8K 등 정량적 벤치마크 점수가 높아도, 특정 도메인 질문이나 복잡한 한국어 문맥에서는 답변 품질이 다를 수 있어 실제 테스트가 필수적입니다. 최신 릴리즈 주기: 오픈소스 LLM 생태계는 수개월 단위로 새로운 파인튜닝 모델이 등장하므로, 지속적인 라이브러리 확인이 필요합니다. 소형 모델의 환각(Hallucination): 3B 이하 초소형 모델은 추론 속도가 빠르지만 팩트 오류나 환각 현상이 상대적으로 자주 발생할 수 있으므로 RAG(검색 증강 생성) 보완을 권장합니다. 📚 수집 소스 및 참고 자료 Askimo: Llama 3, DeepSeek, Mistral 및 로컬 AI 모델을 위한 Ollama 데스크톱 환경 Ollama vs vLLM vs LM Studio 비교 - Rost Glukhov 기술 블로그 Ollama 최고 오픈소스 모델 2026: Top 10 - PromptQuorum Ollama vs LM Studio: 로컬 AI 앱 비교 분석 - Sider 블로그 내 PC에서 AI를 무료로 돌린다: Ollama 로컬 환경 구축 가이드 ","permalink":"https://wkqco33.github.io/wkqcosoft-docs/reports/2026-08-06-ollama%EC%97%90%EC%84%9C-%EA%B0%80%EC%9E%A5-%EC%9D%B8%EA%B8%B0-%EC%9E%88%EB%8A%94-%EB%AA%A8%EB%8D%B8-llama-3-m-71b4fa/","summary":"\u003cblockquote\u003e\n\u003cp\u003e📌 \u003cstrong\u003eExecutive Summary\u003c/strong\u003e\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003e다양해진 로컬 AI 선택지\u003c/strong\u003e: Ollama 플랫폼을 통해 Meta, Mistral AI, Google, Alibaba, Microsoft의 최신 오픈소스 언어 모델을 단일 PC/서버에서 손쉽게 구동할 수 있습니다.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e모델별 뚜렷한 특장점\u003c/strong\u003e:\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003e범용 최강 \u0026amp; 생태계\u003c/strong\u003e: Meta Llama 3 (8B / 70B)\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e고효율 \u0026amp; 완전 오픈소스\u003c/strong\u003e: Mistral AI Mistral (7B / Nemo)\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e코딩 \u0026amp; 수학 \u0026amp; 경량화\u003c/strong\u003e: Google DeepMind Gemma (2B / 9B / 27B)\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e다국어 \u0026amp; 도구 호출 (한국어 최적)\u003c/strong\u003e: Alibaba Qwen 2.5 (0.5B ~ 72B)\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e초소형 고성능 추론\u003c/strong\u003e: Microsoft Phi 3.5 (3.8B / 14B)\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e하드웨어 맞춤 선택 필수\u003c/strong\u003e: 보유한 VRAM/RAM 용량과 상업적 라이선스 조건에 맞춰 적합한 모델을 선택하는 전략이 요구됩니다.\u003c/li\u003e\n\u003c/ul\u003e\u003c/blockquote\u003e\n\u003chr\u003e\n\u003ch2 id=\"-리포트-개요-및-모델-종합-비교표\"\u003e📊 리포트 개요 및 모델 종합 비교표\u003c/h2\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth style=\"text-align: left\"\u003e항목\u003c/th\u003e\n          \u003cth style=\"text-align: left\"\u003e세부 내용\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e\u003cstrong\u003e보고서 주제\u003c/strong\u003e\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003eOllama 생태계 Top 5 오픈소스 언어 모델 심층 비교 분석\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e\u003cstrong\u003e대상 모델군\u003c/strong\u003e\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003eLlama 3.x, Mistral, Gemma 2/3, Qwen 2.5, Phi 3/3.5\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e\u003cstrong\u003e비교 지표\u003c/strong\u003e\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e파라미터 크기, 라이선스, 하드웨어 요구사양(RAM), 특화 영역, 한국어 지원\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003ch3 id=\"-top-5-오픈소스-llm-한눈에-비교\"\u003e🏆 Top 5 오픈소스 LLM 한눈에 비교\u003c/h3\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth style=\"text-align: left\"\u003e모델명\u003c/th\u003e\n          \u003cth style=\"text-align: left\"\u003e개발사\u003c/th\u003e\n          \u003cth style=\"text-align: center\"\u003e파라미터 크기\u003c/th\u003e\n          \u003cth style=\"text-align: center\"\u003e라이선스\u003c/th\u003e\n          \u003cth style=\"text-align: center\"\u003e최소 권장 RAM\u003c/th\u003e\n          \u003cth style=\"text-align: left\"\u003e강점 및 추천 용도\u003c/th\u003e\n          \u003cth style=\"text-align: center\"\u003e한국어 성능\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e\u003cstrong\u003eLlama 3.x\u003c/strong\u003e\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003eMeta\u003c/td\u003e\n          \u003ctd style=\"text-align: center\"\u003e1B, 3B, 8B, 70B\u003c/td\u003e\n          \u003ctd style=\"text-align: center\"\u003eMeta Llama 3 (상업적 조건부)\u003c/td\u003e\n          \u003ctd style=\"text-align: center\"\u003e8GB ~ 64GB\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e범용 언어 이해, 방대한 커뮤니티 생태계, 요약\u003c/td\u003e\n          \u003ctd style=\"text-align: center\"\u003e보통 ~ 우수\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e\u003cstrong\u003eMistral\u003c/strong\u003e\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003eMistral AI\u003c/td\u003e\n          \u003ctd style=\"text-align: center\"\u003e7B, Nemo (12B)\u003c/td\u003e\n          \u003ctd style=\"text-align: center\"\u003eApache 2.0 (완전 오픈)\u003c/td\u003e\n          \u003ctd style=\"text-align: center\"\u003e8GB ~ 16GB\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e뛰어난 경량 추론, 유럽 다국어, 고효율 서빙\u003c/td\u003e\n          \u003ctd style=\"text-align: center\"\u003e보통\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e\u003cstrong\u003eGemma 2/3\u003c/strong\u003e\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003eGoogle DeepMind\u003c/td\u003e\n          \u003ctd style=\"text-align: center\"\u003e2B, 9B, 27B\u003c/td\u003e\n          \u003ctd style=\"text-align: center\"\u003eGemma Open Terms\u003c/td\u003e\n          \u003ctd style=\"text-align: center\"\u003e6GB ~ 24GB\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e코딩, 수학적 추론, 사실 기반 질의응답\u003c/td\u003e\n          \u003ctd style=\"text-align: center\"\u003e우수\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e\u003cstrong\u003eQwen 2.5\u003c/strong\u003e\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003eAlibaba\u003c/td\u003e\n          \u003ctd style=\"text-align: center\"\u003e0.5B ~ 72B\u003c/td\u003e\n          \u003ctd style=\"text-align: center\"\u003eApache 2.0\u003c/td\u003e\n          \u003ctd style=\"text-align: center\"\u003e4GB ~ 64GB\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e\u003cstrong\u003e한국어/다국어 최상급\u003c/strong\u003e, 코딩(Coder), 함수 호출\u003c/td\u003e\n          \u003ctd style=\"text-align: center\"\u003e\u003cstrong\u003e최상\u003c/strong\u003e\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e\u003cstrong\u003ePhi 3.5\u003c/strong\u003e\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003eMicrosoft\u003c/td\u003e\n          \u003ctd style=\"text-align: center\"\u003e3.8B, 14B\u003c/td\u003e\n          \u003ctd style=\"text-align: center\"\u003eMIT (완전 자유)\u003c/td\u003e\n          \u003ctd style=\"text-align: center\"\u003e4GB ~ 12GB\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e소형 파라미터 대비 압도적 추론, 온디바이스/엣지\u003c/td\u003e\n          \u003ctd style=\"text-align: center\"\u003e보통\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003chr\u003e\n\u003ch2 id=\"-핵심-분석\"\u003e🔍 핵심 분석\u003c/h2\u003e\n\u003ch3 id=\"1-ollama-플랫폼의-특징과-가치\"\u003e1. Ollama 플랫폼의 특징과 가치\u003c/h3\u003e\n\u003cp\u003eOllama는 터미널 명령어 한 줄로 모델을 수급하고 실행할 수 있는 표준 로컬 LLM 환경입니다.\u003c/p\u003e","title":"Ollama 인기 오픈소스 LLM 5종 비교 분석 (Llama 3, Mistral, Gemma, Qwen, Phi)"},{"content":" 📌 Executive Summary\n초간편 로컬 LLM 환경: Ollama는 Llama 3, Gemma, Mistral, Qwen 등 오픈소스 대형 언어 모델을 단일 명령어로 다운로드하고 CPU/GPU에서 즉시 실행할 수 있는 경량 프레임워크입니다. 세밀한 커스터마이징: Modelfile을 통해 시스템 프롬프트 부여, LoRA 어댑터 결합, 그리고 temperature, top_p, num_ctx 등 추론 파라미터를 맞춤 튜닝한 커스텀 모델을 생성할 수 있습니다. 손쉬운 애플리케이션 연동: 표준 REST API(http://localhost:11434) 및 OpenAI 호환 엔드포인트를 제공하여 기존 파이프라인이나 서비스 백엔드에 즉시 통합 가능합니다. 📊 리포트 개요 항목 세부 내용 보고서 주제 Ollama CLI 사용법, 추론 파라미터 설정 및 Modelfile 제작 가이드 대상 독자 로컬 AI 환경 구축 개발자, 프롬프트 엔지니어, DevOps 엔지니어 검토 소스 총 5개 기술 블로그 및 공식 가이드 문서 종합 주요 지원 모델 Llama 3.2, Mistral, Gemma 2, Qwen 2.5, DeepSeek 등 🔍 핵심 분석 1. Ollama 개요 및 서버 실행 Ollama는 복잡한 인공지능 모델 빌드나 드라이버 세팅 없이도 로컬 환경에서 오픈소스 LLM을 손쉽게 구동할 수 있도록 패키징된 도구입니다.\nGPU 가속 및 CPU 폴백: NVIDIA CUDA, Apple Silicon(Metal), AMD ROCm을 자동 감지하며, 전용 GPU가 없는 환경에서는 CPU로 자동 실행됩니다. 백그라운드 서비스 시작: 설치 후 터미널에서 다음 명령으로 서버를 구동합니다. # 기본 백그라운드 서버 구동 (포트: 11434) ollama serve # 디버그 상세 로그 모드로 서버 구동 OLLAMA_DEBUG=1 ollama serve 2. 기본 CLI 명령어 완벽 가이드 Ollama는 Docker 스타일의 친숙하고 직관적인 CLI 명령어를 제공합니다.\n명령어 형식 및 옵션 설명 ollama pull ollama pull \u0026lt;모델명\u0026gt;:\u0026lt;태그\u0026gt; 모델 저장소에서 로컬로 모델 다운로드 ollama run ollama run \u0026lt;모델명\u0026gt; [프롬프트] 모델 실행 및 대화형 인터랙티브 셸 진입 (또는 일회성 프롬프트 실행) ollama list ollama list 로컬에 다운로드된 모델 목록 및 크기 확인 ollama ps ollama ps 현재 메모리에 로드되어 동작 중인 모델 확인 ollama rm ollama rm \u0026lt;모델명\u0026gt; 다운로드된 로컬 모델 삭제 ollama show ollama show \u0026lt;모델명\u0026gt; --modelfile 모델의 상세 메타데이터 및 Modelfile 정보 확인 💡 실행 방식별 예제 # 1. 모델 다운로드 ollama pull llama3.2 ollama pull qwen2.5-coder:7b # 2. 대화형 인터랙티브 셸 실행 ollama run llama3.2 # 3. 일회성 프롬프트 즉시 실행 (인라인 전달) ollama run llama3.2 \u0026#34;Python으로 빠른 정렬(Quick Sort) 알고리즘을 작성해줘.\u0026#34; # 4. 파이프라인 및 파일 리다이렉션 활용 cat document.txt | ollama run llama3.2 \u0026#34;이 텍스트의 핵심 내용을 3줄로 요약해줘.\u0026#34; ollama run llama3.2 \u0026#34;AI 기술 트렌드 5가지\u0026#34; \u0026gt; trend_report.txt 3. Modelfile 작성 및 모델 커스터마이징 Modelfile은 Dockerfile과 유사한 문법으로 베이스 모델에 시스템 프롬프트, 템플릿, 추론 파라미터, LoRA 어댑터를 패키징하여 새로운 커스텀 모델을 정의하는 설정 파일입니다.\n주요 지시문 (Directives) 지시문 필수 여부 설명 예시 FROM 필수 기반이 될 베이스 모델 지정 FROM llama3.2 SYSTEM 선택 모델의 페르소나 및 기본 역할 지침 부여 SYSTEM \u0026quot;당신은 전문 백엔드 개발 어시스턴트입니다.\u0026quot; PARAMETER 선택 생성 추론 파라미터 값 설정 PARAMETER temperature 0.7 TEMPLATE 선택 프롬프트가 모델에 전달되는 전체 템플릿 구조 지정 TEMPLATE \u0026quot;\u0026quot;\u0026quot;{{ .Prompt }}\u0026quot;\u0026quot;\u0026quot; ADAPTER 선택 파인튜닝된 LoRA 어댑터 가중치 파일(.bin/.gguf) 경로 ADAPTER ./my-adapter.gguf 커스텀 한국어 비서 모델 작성 예시 (Modelfile-korean) # 1. 베이스 모델 지정 FROM llama3.2 # 2. 시스템 프롬프트 (페르소나 및 응답 규칙) SYSTEM \u0026#34;\u0026#34;\u0026#34; 당신은 한국어 비즈니스 문서 및 개발 관련 질의응답을 지원하는 전문 AI 어시스턴트입니다. 항상 정중하고 친절한 어조로 답변하며, 기술적 질문에는 명확한 코드 예시를 함께 제공하세요. \u0026#34;\u0026#34;\u0026#34; # 3. 추론 파라미터 최적화 PARAMETER temperature 0.7 PARAMETER top_p 0.9 PARAMETER top_k 40 PARAMETER num_ctx 4096 PARAMETER repeat_penalty 1.1 커스텀 모델 빌드 및 실행 # Modelfile을 기반으로 커스텀 모델 \u0026#39;korean-assistant\u0026#39; 생성 ollama create korean-assistant -f ./Modelfile-korean # 생성된 커스텀 모델 실행 ollama run korean-assistant \u0026#34;서울 3대 궁궐의 역사와 특징에 대해 알려줘.\u0026#34; 4. 핵심 추론 파라미터 (Parameters) 상세 가이드 생성 품질과 답변 성향을 결정하는 주요 파라미터 목록입니다.\n파라미터 기본값 권장 범위 설명 및 활용 팁 temperature 0.8 0.0 ~ 1.0 창의성 조절: 값이 낮을수록 일관되고 결정적인 답변(코딩, 팩트 기반), 높을수록 창의적이고 다양한 답변(스토리텔링, 브레인스토밍). top_p 0.9 0.5 ~ 0.95 누적 확률 샘플링(Nucleus): 상위 누적 확률 p 내의 토큰만 후보로 선택. 낮출수록 엉뚱한 단어 선택 배제. top_k 40 10 ~ 100 상위 K개 샘플링: 가장 확률이 높은 K개의 토큰으로 후보군 제한. num_ctx 2048 2048 ~ 32768 컨텍스트 윈도우 크기(토큰 수): 대화 기억 및 입력 문서 처리량 결정. 늘릴수록 VRAM/RAM 사용량 증가. repeat_penalty 1.1 1.0 ~ 1.3 반복 억제 계수: 동일한 문장이나 단어가 반복 생성되는 현상을 억제. stop - 문자열 목록 생성 중단 시퀀스: 특정 단어나 구분자(예: \u0026quot;User:\u0026quot;, \u0026quot;\\n\\n\u0026quot;)를 만나면 즉시 생성 종료. 💡 용도별 파라미터 추천 프리셋\n코드 생성 \u0026amp; 사실 질의 (정확도 우선): temperature: 0.2, top_p: 0.5, repeat_penalty: 1.15 일반 대화 \u0026amp; 요약 (균형 잡힌 모드): temperature: 0.7, top_p: 0.9, repeat_penalty: 1.1 창작 \u0026amp; 브레인스토밍 (다양성 우선): temperature: 0.95, top_p: 0.95, repeat_penalty: 1.05 5. REST API 연동 가이드 Ollama는 기본적으로 http://localhost:11434 포트에서 REST API를 제공하여 백엔드, 프론트엔드, 스크립트 등에서 쉽게 호출할 수 있습니다.\n엔드포인트 개요 POST /api/generate: 단일 프롬프트 텍스트 생성 POST /api/chat: 멀티턴 대화형 메시지 생성 (Chat completions) GET /api/tags: 로컬 설치 모델 목록 조회 cURL 호출 예제 curl http://localhost:11434/api/generate -d \u0026#39;{ \u0026#34;model\u0026#34;: \u0026#34;llama3.2\u0026#34;, \u0026#34;prompt\u0026#34;: \u0026#34;왜 하늘은 파란색인가요?\u0026#34;, \u0026#34;stream\u0026#34;: false, \u0026#34;options\u0026#34;: { \u0026#34;temperature\u0026#34;: 0.7, \u0026#34;top_p\u0026#34;: 0.9, \u0026#34;num_ctx\u0026#34;: 4096 } }\u0026#39; Python (requests 및 OpenAI SDK 호환) # OpenAI 호환 라이브러리를 활용한 연동 from openai import OpenAI client = OpenAI( base_url=\u0026#34;http://localhost:11434/v1\u0026#34;, api_key=\u0026#34;ollama\u0026#34; # 임의의 문자열 입력 ) response = client.chat.completions.create( model=\u0026#34;llama3.2\u0026#34;, messages=[ {\u0026#34;role\u0026#34;: \u0026#34;system\u0026#34;, \u0026#34;content\u0026#34;: \u0026#34;친절한 개발 도우미입니다.\u0026#34;}, {\u0026#34;role\u0026#34;: \u0026#34;user\u0026#34;, \u0026#34;content\u0026#34;: \u0026#34;REST API와 GraphQL의 차이점을 설명해줘.\u0026#34;} ], temperature=0.7 ) print(response.choices[0].message.content) 6. 주요 모델 라인업 및 권장 활용 사례 분류 추천 모델 파라미터 크기 주요 특징 및 적합한 용도 경량 / 입문용 orca-mini, qwen2.5:3b, phi3.5 3B ~ 4B RAM 4~8GB의 노트북이나 저사양 환경에서 빠른 질의응답 코딩 특화 qwen2.5-coder:7b, codellama:7b 7B 코드 생성, 코드 리뷰, 버그 탐지 및 리팩토링 범용 고성능 llama3.2:3b, llama3.1:8b, mistral:7b 3B ~ 8B 일반 대화, 문서 요약, 번역, 사내 RAG 지식 검색 멀티모달 (비전) llava:7b, llama3.2-vision 7B ~ 11B 이미지 분석, 차트 해석, OCR 텍스트 추출 🎯 결론 및 실무 권장사항 손쉬운 시작: ollama pull \u0026lt;모델명\u0026gt;과 ollama run \u0026lt;모델명\u0026gt; 두 가지만으로도 로컬 AI 환경 구축이 즉시 완료됩니다. 커스텀 모델 패키징: 실무 환경에서는 단순 프롬프트 입력 대신 Modelfile을 작성하여 팀 전용 시스템 프롬프트와 파라미터(num_ctx, temperature)를 고정 생성하는 방식을 권장합니다. API 연동성: OpenAI 호환 엔드포인트(/v1)를 지원하므로, 기존 LangChain, LlamaIndex, Dify 등 다양한 LLM 프레임워크와 무수정 연동이 가능합니다. ⚠️ 한계 및 주의사항 하드웨어 메모리(VRAM) 관리: num_ctx(컨텍스트 창)를 과도하게 크게 잡으면(예: 32K 이상) 메모리 부족(OOM) 오류가 발생하거나 추론 속도가 급격히 저하될 수 있습니다. 모델별 권장 파라미터 상이: 모델 아키텍처(Llama 계열 vs Qwen 계열 vs Phi 계열)에 따라 기본 최적 temperature 및 템플릿 형식이 다르므로 사전 테스트가 필요합니다. 최신 릴리즈 확인: Ollama는 잦은 버전 업데이트를 통해 새로운 아키텍처(Gemma 2, Llama 3.2 Vision 등)와 기능이 추가되므로, 주기적으로 ollama --version을 확인하고 업데이트하는 것이 좋습니다. 📚 수집 소스 및 참고 자료 Ollama 공식 웹사이트 및 모델 라이브러리 Ollama 사용법 - AI Vibe Coding 가이드 /with MINZKN Ollama 명령어 완벽 정리 — 설치부터 커스텀 모델, API 연동까지 Ollama란? Ollama 사용법 : 내 PC에서 무료로 LLM 실행하기 vLLM \u0026amp; Ollama 완벽 가이드 : LLM 서빙 엔진의 구동, 파라미터 비교 Ollama 로컬 LLM 실행 완벽 가이드 — 설치부터 API 연동까지 | TechFeed ","permalink":"https://wkqco33.github.io/wkqcosoft-docs/reports/2026-08-05-ollama-%EC%82%AC%EC%9A%A9%EB%B2%95%EA%B3%BC-ollama-run-%EC%8B%A4%ED%96%89-%EC%8B%9C-%ED%8C%8C%EB%9D%BC-d64866/","summary":"\u003cblockquote\u003e\n\u003cp\u003e📌 \u003cstrong\u003eExecutive Summary\u003c/strong\u003e\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003e초간편 로컬 LLM 환경\u003c/strong\u003e: Ollama는 Llama 3, Gemma, Mistral, Qwen 등 오픈소스 대형 언어 모델을 단일 명령어로 다운로드하고 CPU/GPU에서 즉시 실행할 수 있는 경량 프레임워크입니다.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e세밀한 커스터마이징\u003c/strong\u003e: \u003ccode\u003eModelfile\u003c/code\u003e을 통해 시스템 프롬프트 부여, LoRA 어댑터 결합, 그리고 \u003ccode\u003etemperature\u003c/code\u003e, \u003ccode\u003etop_p\u003c/code\u003e, \u003ccode\u003enum_ctx\u003c/code\u003e 등 추론 파라미터를 맞춤 튜닝한 커스텀 모델을 생성할 수 있습니다.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e손쉬운 애플리케이션 연동\u003c/strong\u003e: 표준 REST API(\u003ccode\u003ehttp://localhost:11434\u003c/code\u003e) 및 OpenAI 호환 엔드포인트를 제공하여 기존 파이프라인이나 서비스 백엔드에 즉시 통합 가능합니다.\u003c/li\u003e\n\u003c/ul\u003e\u003c/blockquote\u003e\n\u003chr\u003e\n\u003ch2 id=\"-리포트-개요\"\u003e📊 리포트 개요\u003c/h2\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth style=\"text-align: left\"\u003e항목\u003c/th\u003e\n          \u003cth style=\"text-align: left\"\u003e세부 내용\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e\u003cstrong\u003e보고서 주제\u003c/strong\u003e\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003eOllama CLI 사용법, 추론 파라미터 설정 및 Modelfile 제작 가이드\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e\u003cstrong\u003e대상 독자\u003c/strong\u003e\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e로컬 AI 환경 구축 개발자, 프롬프트 엔지니어, DevOps 엔지니어\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e\u003cstrong\u003e검토 소스\u003c/strong\u003e\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e총 5개 기술 블로그 및 공식 가이드 문서 종합\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e\u003cstrong\u003e주요 지원 모델\u003c/strong\u003e\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003eLlama 3.2, Mistral, Gemma 2, Qwen 2.5, DeepSeek 등\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003chr\u003e\n\u003ch2 id=\"-핵심-분석\"\u003e🔍 핵심 분석\u003c/h2\u003e\n\u003ch3 id=\"1-ollama-개요-및-서버-실행\"\u003e1. Ollama 개요 및 서버 실행\u003c/h3\u003e\n\u003cp\u003eOllama는 복잡한 인공지능 모델 빌드나 드라이버 세팅 없이도 로컬 환경에서 오픈소스 LLM을 손쉽게 구동할 수 있도록 패키징된 도구입니다.\u003c/p\u003e","title":"Ollama 완벽 가이드: 기본 사용법, 파라미터 튜닝 및 Modelfile 활용법"},{"content":"Set K3s Image Gc Threshold K3s image gc threshold 설정 방법 정리\nkubelet은 노드의 디스크 사용량이 image-gc-high-threshold(%)를 넘으면 사용하지 않는 이미지부터 순서대로 정리(garbage collection)를 시작하고, 사용량이 image-gc-low-threshold(%) 이하로 떨어질 때까지 정리를 계속함 기본값은 각각 85%, 80%로 다소 높게 설정되어 있어, 디스크 용량이 작은 노드(엣지, 온프레미스 등)에서는 디스크가 꽉 차기 전에 미리 정리되도록 아래처럼 값을 낮춰 설정하는 것이 안전함 config.yaml 설정 K3s 설치 디렉토리에 config.yaml 파일이 존재하지 않을 경우 config.yaml 파일 생성 sudo vi /etc/rancher/k3s/config.yaml config.yaml 파일에 아래 내용 추가 kubelet-arg: - \u0026#34;image-gc-low-threshold=65\u0026#34; - \u0026#34;image-gc-high-threshold=75\u0026#34; K3s 재시작 sudo systemctl restart k3s ","permalink":"https://wkqco33.github.io/wkqcosoft-docs/posts/k3s-image-gc-threshold/","summary":"\u003ch2 id=\"set-k3s-image-gc-threshold\"\u003eSet K3s Image Gc Threshold\u003c/h2\u003e\n\u003cp\u003eK3s image gc threshold 설정 방법 정리\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003ekubelet은 노드의 디스크 사용량이 \u003ccode\u003eimage-gc-high-threshold\u003c/code\u003e(%)를 넘으면 사용하지 않는 이미지부터 순서대로 정리(garbage collection)를 시작하고, 사용량이 \u003ccode\u003eimage-gc-low-threshold\u003c/code\u003e(%) 이하로 떨어질 때까지 정리를 계속함\u003c/li\u003e\n\u003cli\u003e기본값은 각각 85%, 80%로 다소 높게 설정되어 있어, 디스크 용량이 작은 노드(엣지, 온프레미스 등)에서는 디스크가 꽉 차기 전에 미리 정리되도록 아래처럼 값을 낮춰 설정하는 것이 안전함\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"configyaml-설정\"\u003econfig.yaml 설정\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003eK3s 설치 디렉토리에 \u003ccode\u003econfig.yaml\u003c/code\u003e 파일이 존재하지 않을 경우 \u003ccode\u003econfig.yaml\u003c/code\u003e 파일 생성\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003esudo vi /etc/rancher/k3s/config.yaml\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cul\u003e\n\u003cli\u003e\u003ccode\u003econfig.yaml\u003c/code\u003e 파일에 아래 내용 추가\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-yaml\" data-lang=\"yaml\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#f92672\"\u003ekubelet-arg\u003c/span\u003e:\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e  - \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;image-gc-low-threshold=65\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e  - \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;image-gc-high-threshold=75\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cul\u003e\n\u003cli\u003eK3s 재시작\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003esudo systemctl restart k3s\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e","title":"K3s Image Garbage Collection (GC) 임계값 설정 방법"},{"content":"Docker 컨테이너 환경에서 호스트에 GUI Display 연결 방법 Ubuntu Bash 환경에서 Docker 실행 시 아래와 같은 옵션 추가 필요\n# 현재 Display 확인 echo $DISPLAY :1 # xhost 명령은 X서버에 대한 접근 제어(access control)를 설정하기 위해 사용 # xhost + 는 모든 호스트의 접근을 허용하는 명령이므로 로컬 개발 환경에서만 사용 권장 # 컨테이너에만 접근을 허용하려면 xhost +local:docker 사용을 권장 xhost +local:docker # Docker 실행 시 Display 연결 docker run -it \\ -v /tmp/.X11-unix:/tmp/.X11-unix \\ -e DISPLAY=unix$DISPLAY \\ --name \u0026lt;your-container-name\u0026gt; \\ \u0026lt;your-docker-image-name\u0026gt; 참고: bash에서 줄 끝 \\ 뒤에는 공백이나 다른 문자가 없어야 줄 연속(line continuation)으로 인식됨. 뒤에 공백이 있으면 명령이 그 줄에서 끝난 것으로 처리되어 오류가 발생할 수 있음 Docker 실행 후 GUI 연결 확인 # 테스트를 위한 GUI 앱 실행 (예: xeyes) xeyes ","permalink":"https://wkqco33.github.io/wkqcosoft-docs/posts/docker-display/","summary":"\u003ch2 id=\"docker-컨테이너-환경에서-호스트에-gui-display-연결-방법\"\u003eDocker 컨테이너 환경에서 호스트에 GUI Display 연결 방법\u003c/h2\u003e\n\u003cp\u003eUbuntu Bash 환경에서 Docker 실행 시 아래와 같은 옵션 추가 필요\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 현재 Display 확인\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eecho $DISPLAY\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e:1\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# xhost 명령은 X서버에 대한 접근 제어(access control)를 설정하기 위해 사용\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# xhost + 는 모든 호스트의 접근을 허용하는 명령이므로 로컬 개발 환경에서만 사용 권장\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 컨테이너에만 접근을 허용하려면 xhost +local:docker 사용을 권장\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003exhost +local:docker\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# Docker 실행 시 Display 연결\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edocker run -it \u003cspan style=\"color:#ae81ff\"\u003e\\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#ae81ff\"\u003e\u003c/span\u003e    -v /tmp/.X11-unix:/tmp/.X11-unix \u003cspan style=\"color:#ae81ff\"\u003e\\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#ae81ff\"\u003e\u003c/span\u003e    -e DISPLAY\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003eunix$DISPLAY \u003cspan style=\"color:#ae81ff\"\u003e\\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#ae81ff\"\u003e\u003c/span\u003e    --name \u0026lt;your-container-name\u0026gt; \u003cspan style=\"color:#ae81ff\"\u003e\\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#ae81ff\"\u003e\u003c/span\u003e    \u0026lt;your-docker-image-name\u0026gt;\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cul\u003e\n\u003cli\u003e참고: bash에서 줄 끝 \u003ccode\u003e\\\u003c/code\u003e 뒤에는 공백이나 다른 문자가 없어야 줄 연속(line continuation)으로 인식됨. 뒤에 공백이 있으면 명령이 그 줄에서 끝난 것으로 처리되어 오류가 발생할 수 있음\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"docker-실행-후-gui-연결-확인\"\u003eDocker 실행 후 GUI 연결 확인\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 테스트를 위한 GUI 앱 실행 (예: xeyes)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003exeyes\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e","title":"Docker 컨테이너 환경에서 호스트 GUI Display 연동하기"},{"content":"Unity Hub legacy gpg keyring 이슈 해결 방법 Ubuntu 에서 유니티 설치 후 apt 패키지 업데이트 시 아래와 같은 경고 메시지 발생\napt update ... W: https://hub.unity3d.com/linux/repos/deb/dists/stable/InRelease: Key is stored in legacy trusted.gpg keyring (/etc/apt/trusted.gpg), see the DEPRECATION section in apt-key(8) for details. ... 키 경고 해결 방법 매번 apt 업데이트 시 매우 거슬리기 때문에 아래 방법으로 Key 업데이트\nwget -o- 의 -o(소문자)는 로그 파일을 지정하는 옵션이라 다운로드 내용이 아닌 로그가 stdout으로 출력됨. 공개키 내용을 stdout으로 받으려면 -O-(대문자 O)를 사용해야 함 이를 gpg --dearmor로 바로 바이너리 키링으로 변환하면 별도의 keyring import/export 과정 없이 한 번에 처리 가능 # 공개키를 다운로드하여 바로 바이너리 keyring 형식으로 변환 wget -qO- https://hub.unity3d.com/linux/keys/public | gpg --dearmor \u0026gt; unity-archive-keyring.gpg sudo mv unity-archive-keyring.gpg /etc/apt/trusted.gpg.d/ 이후 실행 시 경고 메시지가 표시되지 않음\nsudo apt update # unity hub 설치 sudo apt install unityhub ","permalink":"https://wkqco33.github.io/wkqcosoft-docs/posts/unityhub/","summary":"\u003ch2 id=\"unity-hub-legacy-gpg-keyring-이슈-해결-방법\"\u003eUnity Hub legacy gpg keyring 이슈 해결 방법\u003c/h2\u003e\n\u003cp\u003eUbuntu 에서 유니티 설치 후 apt 패키지 업데이트 시 아래와 같은 경고 메시지 발생\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eapt update\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e...\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eW: https://hub.unity3d.com/linux/repos/deb/dists/stable/InRelease: Key is stored in legacy trusted.gpg keyring \u003cspan style=\"color:#f92672\"\u003e(\u003c/span\u003e/etc/apt/trusted.gpg\u003cspan style=\"color:#f92672\"\u003e)\u003c/span\u003e, see the DEPRECATION section in apt-key\u003cspan style=\"color:#f92672\"\u003e(\u003c/span\u003e8\u003cspan style=\"color:#f92672\"\u003e)\u003c/span\u003e \u003cspan style=\"color:#66d9ef\"\u003efor\u003c/span\u003e details.\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e...\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"키-경고-해결-방법\"\u003e키 경고 해결 방법\u003c/h3\u003e\n\u003cp\u003e매번 apt 업데이트 시 매우 거슬리기 때문에 아래 방법으로 Key 업데이트\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ccode\u003ewget -o-\u003c/code\u003e 의 \u003ccode\u003e-o\u003c/code\u003e(소문자)는 로그 파일을 지정하는 옵션이라 다운로드 내용이 아닌 로그가 stdout으로 출력됨. 공개키 내용을 stdout으로 받으려면 \u003ccode\u003e-O-\u003c/code\u003e(대문자 O)를 사용해야 함\u003c/li\u003e\n\u003cli\u003e이를 \u003ccode\u003egpg --dearmor\u003c/code\u003e로 바로 바이너리 키링으로 변환하면 별도의 keyring import/export 과정 없이 한 번에 처리 가능\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 공개키를 다운로드하여 바로 바이너리 keyring 형식으로 변환\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ewget -qO- https://hub.unity3d.com/linux/keys/public | gpg --dearmor \u0026gt; unity-archive-keyring.gpg\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003esudo mv unity-archive-keyring.gpg /etc/apt/trusted.gpg.d/\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e이후 실행 시 경고 메시지가 표시되지 않음\u003c/p\u003e","title":"Unityhub Ubuntu legacy gpg key issue"},{"content":"K3s Nvidia GPU 세팅 방법 K3s 클러스터에 GPU 를 사용하기 위한 Nvidia GPU 세팅 방법 정리\nK3s 설치 K3s 가 설치되어 있지 않을 경우 K3s 설치 K3s 설치는 K3s 공식 문서를 참고하여 진행 Nvidia GPU 드라이버 설치 그래픽 카드 확인과 드라이버 설치 그래픽 카드 확인 lspci | grep -i nvidia # Nvidia 그래픽 카드가 설치되어 있는 경우 01:00.0 VGA compatible controller: NVIDIA Corporation TU102 [GeForce RTX 2080 Ti] (rev a1) 01:00.1 Audio device: NVIDIA Corporation TU102 High Definition Audio Controller (rev a1) 01:00.2 USB controller: NVIDIA Corporation TU102 USB 3.1 Host Controller (rev a1) 01:00.3 Serial bus controller: NVIDIA Corporation TU102 USB Type-C UCSI Controller (rev a1 # Nvidia 그래픽 카드가 설치되어 있지 않은 경우(예시) 00:02.0 VGA compatible controller: Intel Corporation HD Graphics 630 (rev 04) 설치 가능한 Nvidia 그래픽 카드 드라이버 확인 ubuntu-drivers devices # 설치 가능한 Nvidia 그래픽 카드 드라이버 목록(예시) == /sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0 == modalias : pci:v000010DEd00001E04sv000010DEsd000012AEbc03sc00i00 vendor : NVIDIA Corporation model : TU102 [GeForce RTX 2080 Ti] driver : nvidia-driver-525-server - distro non-free driver : nvidia-driver-535-open - distro non-free driver : nvidia-driver-535-server - distro non-free driver : nvidia-driver-525-open - distro non-free driver : nvidia-driver-535-server-open - distro non-free driver : nvidia-driver-418-server - distro non-free driver : nvidia-driver-470-server - distro non-free driver : nvidia-driver-470 - distro non-free driver : nvidia-driver-535 - distro non-free driver : nvidia-driver-525 - distro non-free driver : nvidia-driver-545 - third-party non-free recommended driver : nvidia-driver-450-server - distro non-free driver : nvidia-driver-545-open - third-party non-free driver : xserver-xorg-video-nouveau - distro free builtin 그래픽 카드 드라이버 설치(recommended 설치 권장) # recommended 드라이버 설치 sudo ubuntu-drivers autoinstall # recommended 드라이버 설치 후 재부팅 sudo reboot Nvidia Container Toolkit 설치 Nvidia Container Toolkit 설치는 Nvidia 공식 문서를 참고하여 진행 Nvidia Container Toolkit 과 관련된 패키지 설치 패키지 저장소 추가 # 패키지 저장소 추가 curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg \\ \u0026amp;\u0026amp; curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \\ sed \u0026#39;s#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g\u0026#39; | \\ sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list 패키지 업데이트 및 Nvidia Container Toolkit 설치 sudo apt update sudo apt install -y nvidia-container-toolkit sudo apt install -y nvidia-container-runtime docker config 파일 수정 // /etc/docker/daemon.json 파일 수정 { \u0026#34;default-runtime\u0026#34;: \u0026#34;nvidia\u0026#34;, \u0026#34;runtimes\u0026#34;: { \u0026#34;nvidia\u0026#34;: { \u0026#34;path\u0026#34;: \u0026#34;/usr/bin/nvidia-container-runtime\u0026#34;, \u0026#34;runtimeArgs\u0026#34;: [] } } } docker 재시작 sudo systemctl restart docker 정상 설치 확인 nvidia-smi K3s 설정 K3s GPU 설정을 위한 K3s 설정 파일 수정 K3s 설정 파일 수정 # K3s containerd 설정 파일 수정 # config.toml 파일은 K3s 시작 시 자동으로 생성되는 파일이므로 config.toml.tmpl 파일을 수정해야 함 sudo vi /var/lib/rancher/k3s/agent/etc/containerd/config.toml.tmpl K3s 설정 파일에 아래 내용 추가 version = 2 [plugins] [plugins.\u0026#34;io.containerd.grpc.v1.cri\u0026#34;] stream_server_address = \u0026#34;127.0.0.1\u0026#34; stream_server_port = \u0026#34;10010\u0026#34; enable_selinux = false enable_unprivileged_ports = true enable_unprivileged_icmp = true sandbox_image = \u0026#34;rancher/mirrored-pause:3.6\u0026#34; [plugins.\u0026#34;io.containerd.grpc.v1.cri\u0026#34;.containerd] default_runtime_name = \u0026#34;nvidia\u0026#34; [plugins.\u0026#34;io.containerd.grpc.v1.cri\u0026#34;.cni] bin_dir = \u0026#34;/var/lib/rancher/k3s/data/dc43f496a0a9ac19d3b2444d390db38e0cfb38e672721f838b075422b8734994/bin\u0026#34; conf_dir = \u0026#34;/var/lib/rancher/k3s/agent/etc/cni/net.d\u0026#34; # 아래부터 nvidia runtime 설정을 위해 추가하는 내용 [plugins.\u0026#34;io.containerd.grpc.v1.cri\u0026#34;.containerd.runtimes] [plugins.\u0026#34;io.containerd.grpc.v1.cri\u0026#34;.containerd.runtimes.nvidia] privileged_without_host_devices = false runtime_engine = \u0026#34;\u0026#34; runtime_root = \u0026#34;\u0026#34; runtime_type = \u0026#34;io.containerd.runc.v2\u0026#34; [plugins.\u0026#34;io.containerd.grpc.v1.cri\u0026#34;.containerd.runtimes.nvidia.options] BinaryName = \u0026#34;/usr/bin/nvidia-container-runtime\u0026#34; K3s 재시작 sudo systemctl restart k3s.service Nvidia device plugin 설치 Nvidia device plugin 설치는 Nvidia 공식 문서를 참고하여 진행 kubectl create -f https://raw.githubusercontent.com/NVIDIA/k8s-device-plugin/v0.14.3/nvidia-device-plugin.yml Nvidia device plugin 설치 확인 kubectl get pods -n kube-system | grep nvidia-device-plugin # Pod 확인(예시) nvidia-device-plugin-daemonset-xxxxx 1/1 Running 0 2m K3s GPU 세팅 테스트 GPU 사용 가능 여부 확인 GPU 사용 가능 여부 확인 클러스터에 테스트용 Pod 생성 $ cat \u0026lt;\u0026lt;EOF | kubectl apply -f - apiVersion: v1 kind: Pod metadata: name: gpu-pod spec: restartPolicy: Never containers: - name: cuda-container image: nvcr.io/nvidia/k8s/cuda-sample:vectoradd-cuda10.2 resources: limits: nvidia.com/gpu: 1 # requesting 1 GPU tolerations: - key: nvidia.com/gpu operator: Exists effect: NoSchedule EOF Pod 생성 확인 kubectl logs gpu-pod # Pod 정상 로그 확인(예시) [Vector addition of 50000 elements] Copy input data from the host memory to the CUDA device CUDA kernel launch with 196 blocks of 256 threads Copy output data from the CUDA device to the host memory Test PASSED Done 추가 노드 GPU 세팅 추가 노드에 사용을 위해 그래픽 카드 드라이버 설치와 Nvidia Container Toolkit, K3s 설정 필요 추가 노드에도 동일하게 그래픽 카드 드라이버 설치 및 Nvidia Container Toolkit 설치 추가 노드에도 동일하게 K3s 설정 파일 수정 및 K3s 재시작 필요 참고 K3s 공식 문서 Nvidia 공식 문서 Nvidia device plugin ","permalink":"https://wkqco33.github.io/wkqcosoft-docs/posts/k3s-nvidia-gpu/","summary":"\u003ch2 id=\"k3s-nvidia-gpu-세팅-방법\"\u003eK3s Nvidia GPU 세팅 방법\u003c/h2\u003e\n\u003cp\u003eK3s 클러스터에 GPU 를 사용하기 위한 Nvidia GPU 세팅 방법 정리\u003c/p\u003e\n\u003ch3 id=\"k3s-설치\"\u003eK3s 설치\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003eK3s 가 설치되어 있지 않을 경우 K3s 설치\u003c/li\u003e\n\u003cli\u003eK3s 설치는 \u003ca href=\"https://docs.k3s.io/installation/configuration\"\u003eK3s 공식 문서\u003c/a\u003e를 참고하여 진행\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"nvidia-gpu-드라이버-설치\"\u003eNvidia GPU 드라이버 설치\u003c/h3\u003e\n\u003ch4 id=\"그래픽-카드-확인과-드라이버-설치\"\u003e그래픽 카드 확인과 드라이버 설치\u003c/h4\u003e\n\u003cul\u003e\n\u003cli\u003e그래픽 카드 확인\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003elspci | grep -i nvidia\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# Nvidia 그래픽 카드가 설치되어 있는 경우\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e01:00.0 VGA compatible controller: NVIDIA Corporation TU102 \u003cspan style=\"color:#f92672\"\u003e[\u003c/span\u003eGeForce RTX \u003cspan style=\"color:#ae81ff\"\u003e2080\u003c/span\u003e Ti\u003cspan style=\"color:#f92672\"\u003e]\u003c/span\u003e \u003cspan style=\"color:#f92672\"\u003e(\u003c/span\u003erev a1\u003cspan style=\"color:#f92672\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e01:00.1 Audio device: NVIDIA Corporation TU102 High Definition Audio Controller \u003cspan style=\"color:#f92672\"\u003e(\u003c/span\u003erev a1\u003cspan style=\"color:#f92672\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e01:00.2 USB controller: NVIDIA Corporation TU102 USB 3.1 Host Controller \u003cspan style=\"color:#f92672\"\u003e(\u003c/span\u003erev a1\u003cspan style=\"color:#f92672\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e01:00.3 Serial bus controller: NVIDIA Corporation TU102 USB Type-C UCSI Controller \u003cspan style=\"color:#f92672\"\u003e(\u003c/span\u003erev a1\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# Nvidia 그래픽 카드가 설치되어 있지 않은 경우(예시)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e00:02.0 VGA compatible controller: Intel Corporation HD Graphics \u003cspan style=\"color:#ae81ff\"\u003e630\u003c/span\u003e \u003cspan style=\"color:#f92672\"\u003e(\u003c/span\u003erev 04\u003cspan style=\"color:#f92672\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cul\u003e\n\u003cli\u003e설치 가능한 Nvidia 그래픽 카드 드라이버 확인\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eubuntu-drivers devices\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 설치 가능한 Nvidia 그래픽 카드 드라이버 목록(예시)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#f92672\"\u003e==\u003c/span\u003e /sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0 \u003cspan style=\"color:#f92672\"\u003e==\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003emodalias : pci:v000010DEd00001E04sv000010DEsd000012AEbc03sc00i00\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003evendor   : NVIDIA Corporation\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003emodel    : TU102 \u003cspan style=\"color:#f92672\"\u003e[\u003c/span\u003eGeForce RTX \u003cspan style=\"color:#ae81ff\"\u003e2080\u003c/span\u003e Ti\u003cspan style=\"color:#f92672\"\u003e]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edriver   : nvidia-driver-525-server - distro non-free\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edriver   : nvidia-driver-535-open - distro non-free\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edriver   : nvidia-driver-535-server - distro non-free\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edriver   : nvidia-driver-525-open - distro non-free\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edriver   : nvidia-driver-535-server-open - distro non-free\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edriver   : nvidia-driver-418-server - distro non-free\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edriver   : nvidia-driver-470-server - distro non-free\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edriver   : nvidia-driver-470 - distro non-free\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edriver   : nvidia-driver-535 - distro non-free\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edriver   : nvidia-driver-525 - distro non-free\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edriver   : nvidia-driver-545 - third-party non-free recommended\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edriver   : nvidia-driver-450-server - distro non-free\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edriver   : nvidia-driver-545-open - third-party non-free\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edriver   : xserver-xorg-video-nouveau - distro free builtin\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cul\u003e\n\u003cli\u003e그래픽 카드 드라이버 설치(recommended 설치 권장)\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# recommended 드라이버 설치\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003esudo ubuntu-drivers autoinstall\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# recommended 드라이버 설치 후 재부팅\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003esudo reboot\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"nvidia-container-toolkit-설치\"\u003eNvidia Container Toolkit 설치\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003eNvidia Container Toolkit 설치는 \u003ca href=\"https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html\"\u003eNvidia 공식 문서\u003c/a\u003e를 참고하여 진행\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch4 id=\"nvidia-container-toolkit-과-관련된-패키지-설치\"\u003eNvidia Container Toolkit 과 관련된 패키지 설치\u003c/h4\u003e\n\u003cul\u003e\n\u003cli\u003e패키지 저장소 추가\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 패키지 저장소 추가\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ecurl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg \u003cspan style=\"color:#ae81ff\"\u003e\\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#ae81ff\"\u003e\u003c/span\u003e  \u003cspan style=\"color:#f92672\"\u003e\u0026amp;\u0026amp;\u003c/span\u003e curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \u003cspan style=\"color:#ae81ff\"\u003e\\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#ae81ff\"\u003e\u003c/span\u003e    sed \u003cspan style=\"color:#e6db74\"\u003e\u0026#39;s#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g\u0026#39;\u003c/span\u003e | \u003cspan style=\"color:#ae81ff\"\u003e\\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#ae81ff\"\u003e\u003c/span\u003e    sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cul\u003e\n\u003cli\u003e패키지 업데이트 및 Nvidia Container Toolkit 설치\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003esudo apt update\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003esudo apt install -y nvidia-container-toolkit\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003esudo apt install -y nvidia-container-runtime\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cul\u003e\n\u003cli\u003edocker config 파일 수정\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-json\" data-lang=\"json\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e// /etc/docker/daemon.json 파일 수정\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e\u003c/span\u003e{\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    \u003cspan style=\"color:#f92672\"\u003e\u0026#34;default-runtime\u0026#34;\u003c/span\u003e: \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;nvidia\u0026#34;\u003c/span\u003e,\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    \u003cspan style=\"color:#f92672\"\u003e\u0026#34;runtimes\u0026#34;\u003c/span\u003e: {\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e        \u003cspan style=\"color:#f92672\"\u003e\u0026#34;nvidia\u0026#34;\u003c/span\u003e: {\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e            \u003cspan style=\"color:#f92672\"\u003e\u0026#34;path\u0026#34;\u003c/span\u003e: \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;/usr/bin/nvidia-container-runtime\u0026#34;\u003c/span\u003e,\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e            \u003cspan style=\"color:#f92672\"\u003e\u0026#34;runtimeArgs\u0026#34;\u003c/span\u003e: []\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e        }\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    }\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e}\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cul\u003e\n\u003cli\u003edocker 재시작\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003esudo systemctl restart docker\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cul\u003e\n\u003cli\u003e정상 설치 확인\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003envidia-smi\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"k3s-설정\"\u003eK3s 설정\u003c/h3\u003e\n\u003ch4 id=\"k3s-gpu-설정을-위한-k3s-설정-파일-수정\"\u003eK3s GPU 설정을 위한 K3s 설정 파일 수정\u003c/h4\u003e\n\u003cul\u003e\n\u003cli\u003eK3s 설정 파일 수정\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# K3s containerd 설정 파일 수정\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# config.toml 파일은 K3s 시작 시 자동으로 생성되는 파일이므로 config.toml.tmpl 파일을 수정해야 함\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003esudo vi /var/lib/rancher/k3s/agent/etc/containerd/config.toml.tmpl\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cul\u003e\n\u003cli\u003eK3s 설정 파일에 아래 내용 추가\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-toml\" data-lang=\"toml\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#a6e22e\"\u003eversion\u003c/span\u003e = \u003cspan style=\"color:#ae81ff\"\u003e2\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e[\u003cspan style=\"color:#a6e22e\"\u003eplugins\u003c/span\u003e]\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e[\u003cspan style=\"color:#a6e22e\"\u003eplugins\u003c/span\u003e.\u003cspan style=\"color:#e6db74\"\u003e\u0026#34;io.containerd.grpc.v1.cri\u0026#34;\u003c/span\u003e]\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#a6e22e\"\u003estream_server_address\u003c/span\u003e = \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;127.0.0.1\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#a6e22e\"\u003estream_server_port\u003c/span\u003e = \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;10010\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#a6e22e\"\u003eenable_selinux\u003c/span\u003e = \u003cspan style=\"color:#66d9ef\"\u003efalse\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#a6e22e\"\u003eenable_unprivileged_ports\u003c/span\u003e = \u003cspan style=\"color:#66d9ef\"\u003etrue\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#a6e22e\"\u003eenable_unprivileged_icmp\u003c/span\u003e = \u003cspan style=\"color:#66d9ef\"\u003etrue\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#a6e22e\"\u003esandbox_image\u003c/span\u003e = \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;rancher/mirrored-pause:3.6\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e[\u003cspan style=\"color:#a6e22e\"\u003eplugins\u003c/span\u003e.\u003cspan style=\"color:#e6db74\"\u003e\u0026#34;io.containerd.grpc.v1.cri\u0026#34;\u003c/span\u003e.\u003cspan style=\"color:#a6e22e\"\u003econtainerd\u003c/span\u003e]\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#a6e22e\"\u003edefault_runtime_name\u003c/span\u003e = \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;nvidia\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e[\u003cspan style=\"color:#a6e22e\"\u003eplugins\u003c/span\u003e.\u003cspan style=\"color:#e6db74\"\u003e\u0026#34;io.containerd.grpc.v1.cri\u0026#34;\u003c/span\u003e.\u003cspan style=\"color:#a6e22e\"\u003ecni\u003c/span\u003e]\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#a6e22e\"\u003ebin_dir\u003c/span\u003e = \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;/var/lib/rancher/k3s/data/dc43f496a0a9ac19d3b2444d390db38e0cfb38e672721f838b075422b8734994/bin\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#a6e22e\"\u003econf_dir\u003c/span\u003e = \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;/var/lib/rancher/k3s/agent/etc/cni/net.d\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 아래부터 nvidia runtime 설정을 위해 추가하는 내용\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e[\u003cspan style=\"color:#a6e22e\"\u003eplugins\u003c/span\u003e.\u003cspan style=\"color:#e6db74\"\u003e\u0026#34;io.containerd.grpc.v1.cri\u0026#34;\u003c/span\u003e.\u003cspan style=\"color:#a6e22e\"\u003econtainerd\u003c/span\u003e.\u003cspan style=\"color:#a6e22e\"\u003eruntimes\u003c/span\u003e]\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e[\u003cspan style=\"color:#a6e22e\"\u003eplugins\u003c/span\u003e.\u003cspan style=\"color:#e6db74\"\u003e\u0026#34;io.containerd.grpc.v1.cri\u0026#34;\u003c/span\u003e.\u003cspan style=\"color:#a6e22e\"\u003econtainerd\u003c/span\u003e.\u003cspan style=\"color:#a6e22e\"\u003eruntimes\u003c/span\u003e.\u003cspan style=\"color:#a6e22e\"\u003envidia\u003c/span\u003e]\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#a6e22e\"\u003eprivileged_without_host_devices\u003c/span\u003e = \u003cspan style=\"color:#66d9ef\"\u003efalse\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#a6e22e\"\u003eruntime_engine\u003c/span\u003e = \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#a6e22e\"\u003eruntime_root\u003c/span\u003e = \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#a6e22e\"\u003eruntime_type\u003c/span\u003e = \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;io.containerd.runc.v2\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e[\u003cspan style=\"color:#a6e22e\"\u003eplugins\u003c/span\u003e.\u003cspan style=\"color:#e6db74\"\u003e\u0026#34;io.containerd.grpc.v1.cri\u0026#34;\u003c/span\u003e.\u003cspan style=\"color:#a6e22e\"\u003econtainerd\u003c/span\u003e.\u003cspan style=\"color:#a6e22e\"\u003eruntimes\u003c/span\u003e.\u003cspan style=\"color:#a6e22e\"\u003envidia\u003c/span\u003e.\u003cspan style=\"color:#a6e22e\"\u003eoptions\u003c/span\u003e]\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#a6e22e\"\u003eBinaryName\u003c/span\u003e = \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;/usr/bin/nvidia-container-runtime\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cul\u003e\n\u003cli\u003eK3s 재시작\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003esudo systemctl restart k3s.service\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch4 id=\"nvidia-device-plugin-설치\"\u003eNvidia device plugin 설치\u003c/h4\u003e\n\u003cul\u003e\n\u003cli\u003eNvidia device plugin 설치는 \u003ca href=\"https://github.com/NVIDIA/k8s-device-plugin/\"\u003eNvidia 공식 문서\u003c/a\u003e를 참고하여 진행\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ekubectl create -f https://raw.githubusercontent.com/NVIDIA/k8s-device-plugin/v0.14.3/nvidia-device-plugin.yml\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cul\u003e\n\u003cli\u003eNvidia device plugin 설치 확인\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ekubectl get pods -n kube-system | grep nvidia-device-plugin\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# Pod 확인(예시)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003envidia-device-plugin-daemonset-xxxxx   1/1     Running   \u003cspan style=\"color:#ae81ff\"\u003e0\u003c/span\u003e          2m\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"k3s-gpu-세팅-테스트\"\u003eK3s GPU 세팅 테스트\u003c/h3\u003e\n\u003ch4 id=\"gpu-사용-가능-여부-확인\"\u003eGPU 사용 가능 여부 확인\u003c/h4\u003e\n\u003cul\u003e\n\u003cli\u003eGPU 사용 가능 여부 확인\u003c/li\u003e\n\u003cli\u003e클러스터에 테스트용 Pod 생성\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e$ cat \u003cspan style=\"color:#e6db74\"\u003e\u0026lt;\u0026lt;EOF | kubectl apply -f -\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#e6db74\"\u003eapiVersion: v1\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#e6db74\"\u003ekind: Pod\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#e6db74\"\u003emetadata:\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#e6db74\"\u003e  name: gpu-pod\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#e6db74\"\u003espec:\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#e6db74\"\u003e  restartPolicy: Never\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#e6db74\"\u003e  containers:\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#e6db74\"\u003e    - name: cuda-container\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#e6db74\"\u003e      image: nvcr.io/nvidia/k8s/cuda-sample:vectoradd-cuda10.2\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#e6db74\"\u003e      resources:\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#e6db74\"\u003e        limits:\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#e6db74\"\u003e          nvidia.com/gpu: 1 # requesting 1 GPU\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#e6db74\"\u003e  tolerations:\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#e6db74\"\u003e  - key: nvidia.com/gpu\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#e6db74\"\u003e    operator: Exists\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#e6db74\"\u003e    effect: NoSchedule\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#e6db74\"\u003eEOF\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cul\u003e\n\u003cli\u003ePod 생성 확인\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ekubectl logs gpu-pod\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# Pod 정상 로그 확인(예시)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#f92672\"\u003e[\u003c/span\u003eVector addition of \u003cspan style=\"color:#ae81ff\"\u003e50000\u003c/span\u003e elements\u003cspan style=\"color:#f92672\"\u003e]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eCopy input data from the host memory to the CUDA device\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eCUDA kernel launch with \u003cspan style=\"color:#ae81ff\"\u003e196\u003c/span\u003e blocks of \u003cspan style=\"color:#ae81ff\"\u003e256\u003c/span\u003e threads\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eCopy output data from the CUDA device to the host memory\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eTest PASSED\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eDone\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"추가-노드-gpu-세팅\"\u003e추가 노드 GPU 세팅\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e추가 노드에 사용을 위해 그래픽 카드 드라이버 설치와 Nvidia Container Toolkit, K3s 설정 필요\u003c/li\u003e\n\u003cli\u003e추가 노드에도 동일하게 그래픽 카드 드라이버 설치 및 Nvidia Container Toolkit \u003ca href=\"#nvidia-container-toolkit-%EC%84%A4%EC%B9%98\"\u003e설치\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e추가 노드에도 동일하게 K3s 설정 파일 \u003ca href=\"#k3s-%EC%84%A4%EC%A0%95\"\u003e수정\u003c/a\u003e 및 K3s 재시작 필요\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"참고\"\u003e참고\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"https://docs.k3s.io/installation/configuration\"\u003eK3s 공식 문서\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html\"\u003eNvidia 공식 문서\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://github.com/NVIDIA/k8s-device-plugin/\"\u003eNvidia device plugin\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e","title":"K3s Nvidia GPU 연동 및 워크로드 설정 가이드"},{"content":"Git Submodule 삭제하기 Git Submodule을 삭제하는 방법 정리 1. Submodule 삭제 # 1) .gitmodules, .git/config 에서 submodule 등록 해제 및 워킹 디렉토리에서 파일 삭제 git submodule deinit -f -- {submodule_path} # 2) .git/modules 에 남아있는 submodule 내부 git 저장소 삭제 rm -rf .git/modules/{submodule_path} # 3) 인덱스에서 submodule 경로 제거 (스테이징까지 완료됨) git rm -f {submodule_path} 위 3단계까지 실행하면 삭제가 인덱스에 반영된 상태이므로, 마지막으로 커밋만 하면 됨 git commit -m \u0026#34;Remove submodule {submodule_path}\u0026#34; 2. 참고 자료 Stackoverflow ","permalink":"https://wkqco33.github.io/wkqcosoft-docs/posts/git-submodule-remove/","summary":"\u003ch2 id=\"git-submodule-삭제하기\"\u003eGit Submodule 삭제하기\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003eGit Submodule을 삭제하는 방법 정리\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"1-submodule-삭제\"\u003e1. Submodule 삭제\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 1) .gitmodules, .git/config 에서 submodule 등록 해제 및 워킹 디렉토리에서 파일 삭제\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003egit submodule deinit -f -- \u003cspan style=\"color:#f92672\"\u003e{\u003c/span\u003esubmodule_path\u003cspan style=\"color:#f92672\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 2) .git/modules 에 남아있는 submodule 내부 git 저장소 삭제\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003erm -rf .git/modules/\u003cspan style=\"color:#f92672\"\u003e{\u003c/span\u003esubmodule_path\u003cspan style=\"color:#f92672\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 3) 인덱스에서 submodule 경로 제거 (스테이징까지 완료됨)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003egit rm -f \u003cspan style=\"color:#f92672\"\u003e{\u003c/span\u003esubmodule_path\u003cspan style=\"color:#f92672\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cul\u003e\n\u003cli\u003e위 3단계까지 실행하면 삭제가 인덱스에 반영된 상태이므로, 마지막으로 커밋만 하면 됨\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003egit commit -m \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;Remove submodule {submodule_path}\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"2-참고-자료\"\u003e2. 참고 자료\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"https://stackoverflow.com/questions/1260748/how-do-i-remove-a-submodule\"\u003eStackoverflow\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e","title":"Git Submodule 안전하게 삭제하기"},{"content":"1. MicroK8s 설치 Ubuntu 환경에서 MicroK8s 설치 # 최신 버전의 MicroK8s 설치 $ sudo snap install microk8s --classic # 특정 버전의 MicroK8s 설치 $ sudo snap install microk8s --classic --channel=1.27 1.1. 관리자 권한 그룹에 추가 MicroK8s 설치 후, 사용자가 MicroK8s를 사용하기 위해서는 관리자 권한 그룹에 추가해야 함 # 관리자 그룹에 MicroK8s 추가 sudo usermod -a -G microk8s $USER sudo chown -f -R $USER ~/.kube # 새로운 그룹 적용 $ newgrp microk8s 1.2. MicroK8s 시작 및 중지 MicroK8s 시작과 중지 방법 # MicroK8s 시작 $ microk8s start # MicroK8s 중지 $ microk8s stop 1.3. MicroK8s with Kubectl MicroK8s 는 kubectl 을 자체 패키지로 제공하고 있음 # MicroK8s 에서 제공하는 kubectl 명령어 $ microk8s kubectl get all --all-namespaces kubectl 을 사용하기 위해서는 MicroK8s 의 config 내용을 .kube/config 에 복사해야 함 # MicroK8s 의 config 내용을 .kube/config 에 복사 $ microk8s config \u0026gt; ~/.kube/config # kubectl 명령어 실행 $ kubectl get all --all-namespaces 2. MicroK8s add Node (Worker Node) MicroK8s 에서는 add-node 명령어를 통해 Worker Node 를 추가할 수 있음 Master Node 에서 add-node 명령어를 실행하면, Worker Node 에서 실행할 수 있는 명령어를 제공함 # MicroK8s 에서 제공하는 add-node 명령어 $ microk8s add-node # MicroK8s 에서 제공하는 add-node 명령어의 결과 From the node you wish to join to this cluster, run the following: microk8s join \u0026lt;MASTER_IP\u0026gt;:25000/\u0026lt;TOKEN\u0026gt; Use the \u0026#39;--worker\u0026#39; flag to join a node as a worker not running the control plane, eg: microk8s join \u0026lt;MASTER_IP\u0026gt;:25000/\u0026lt;TOKEN\u0026gt; --worker If the node you are adding is not reachable through the default interface you can use one of the following: microk8s join \u0026lt;MASTER_IP\u0026gt;:25000/\u0026lt;TOKEN\u0026gt; microk8s join 10.0.0.1:25000/\u0026lt;TOKEN\u0026gt; microk8s join 172.17.0.1:25000/\u0026lt;TOKEN\u0026gt; 2.1. MicroK8s Worker Node join Master Node 에서 획득한 add-node 명령어를 Worker Node 에서 실행하면, Worker Node 가 Master Node 에 join 됨 # worker node join $ microk8s join \u0026lt;MASTER_IP\u0026gt;:25000/\u0026lt;TOKEN\u0026gt; --worker 2.1.1. Worker Node Host 정보 추가 Master Node 로 join 을 위해 Worker Node 의 Host 정보를 추가해야 함 # hosts 파일 수정 $ sudo vi /etc/hosts # Worker Node 의 Host IP 와 Host Name 추가 \u0026lt;WORKER_IP\u0026gt; worker 2.2. Master Node 에서 Worker Node 추가 확인 Master Node 에서 Worker Node 가 정상적으로 추가되었는지 확인 # Master Node 에서 Worker Node 확인 $ microk8s kubectl get nodes NAME STATUS ROLES AGE VERSION master Ready \u0026lt;none\u0026gt; 10d v1.27.4 worker Ready \u0026lt;none\u0026gt; 10d v1.27.4 3. Multus 에드온 설치 Multus 사용을 위해 Multus 에드온을 설치해야 함\n3.1. Multus 에드온 설치 Multus 에드온 설치를 위해 MicroK8s 에서 제공하는 community 에드온을 활성화 해야 함 community 에드온을 활성화 후 Multus 에드온 설치 # Multus Community 에드온 활성화 $ microk8s enable community # Multus 에드온 설치 $ microk8s enable multus 3.2. Multus 에드온 확인 Multus 에드온이 정상적으로 설치되었는지 확인 # Multus 에드온 확인 $ microk8s kubectl get pods -n kube-system --selector=app=multus NAME READY STATUS RESTARTS AGE kube-multus-ds-bdqcq 1/1 Running 0 3d22h kube-multus-ds-8mq2j 1/1 Running 1 (3d20h ago) 3d22h 4. ROS2 통신을 위한 Multus 설정 Multus 사용을 위한 Network 생성 사용할 Network IP 확인 후 Multus 설정 apiVersion: \u0026#34;k8s.cni.cncf.io/v1\u0026#34; kind: NetworkAttachmentDefinition metadata: name: my-network namespace: my-namespace spec: config: \u0026#39;{ \u0026#34;cniVersion\u0026#34;: \u0026#34;0.3.0\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;my-network\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;macvlan\u0026#34;, \u0026#34;master\u0026#34;: \u0026#34;eth0\u0026#34;, \u0026#34;mode\u0026#34;: \u0026#34;bridge\u0026#34;, \u0026#34;isDefaultgateway\u0026#34;: true, \u0026#34;ipam\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;host-local\u0026#34;, \u0026#34;ranges\u0026#34;: [ [ { \u0026#34;subnet\u0026#34;: \u0026#34;192.168.0.0/16\u0026#34;, \u0026#34;rangeStart\u0026#34;: \u0026#34;192.168.1.160\u0026#34;, \u0026#34;rangeEnd\u0026#34;: \u0026#34;192.168.1.180\u0026#34;, \u0026#34;gateway\u0026#34;: \u0026#34;192.168.70.1\u0026#34; } ] ] } }\u0026#39; 4.1. ip route 확인 Multus 에서 사용할 Network IP 확인 # ip route 확인 $ ip route default via 192.168.70.1 dev eth0 proto dhcp metric 100 10.1.102.64/26 via 10.1.102.64 dev vxlan.calico onlink blackhole 10.1.235.0/26 proto 80 10.1.235.13 dev cali3beb9936836 scope link 10.1.235.15 dev cali7701ec796a3 scope link ... 생략 ... 169.254.0.0/16 dev eth0 scope link metric 1000 172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1 linkdown 192.168.70.0/24 dev eth0 proto kernel scope link src 192.168.70.15 metric 100 4.2. Multus Network 사용 설정 Deployment 에 Multus Network 사용 설정 예시 apiVersion: apps/v1 kind: Deployment metadata: name: ros-talker-deployment namespace: my-namespace labels: app: ros-talker spec: selector: matchLabels: app: ros-talker template: metadata: labels: app: ros-talker annotations: k8s.v1.cni.cncf.io/networks: my-network # 생성된 Multus Network 사용 설정 spec: ... 생략 ... 4.3. Multus Network 사용 확인 Multus Network 사용 설정이 정상적으로 되었는지 확인 # Multus Network 사용 확인 $ microk8s kubectl get describe pod ros-talker-deployment-5f9b9b6d6f-4q9qf -n my-namespace Name: ros-talker-deployment-69f999bbc4-crtbw Namespace: default Priority: 0 Service Account: default Node: worker-node-1/192.168.0.10 Start Time: Thu, 03 Aug 2023 15:50:42 +0900 Labels: app=ros-talker pod-template-hash=69f999bbc4 Annotations: cni.projectcalico.org/containerID: 46d80536187192d787e05cae17efd93b5992738d43a8b945bc1f14dbd580a6ff cni.projectcalico.org/podIP: 10.1.102.106/32 cni.projectcalico.org/podIPs: 10.1.102.106/32 k8s.v1.cni.cncf.io/network-status: [{ \u0026#34;name\u0026#34;: \u0026#34;k8s-pod-network\u0026#34;, \u0026#34;ips\u0026#34;: [ \u0026#34;10.1.102.106\u0026#34; ], \u0026#34;default\u0026#34;: true, \u0026#34;dns\u0026#34;: {} },{ \u0026#34;name\u0026#34;: \u0026#34;my-namespace/my-network\u0026#34;, \u0026#34;interface\u0026#34;: \u0026#34;net1\u0026#34;, \u0026#34;ips\u0026#34;: [ \u0026#34;192.168.1.163\u0026#34; ], \u0026#34;mac\u0026#34;: \u0026#34;8a:e9:bc:15:77:82\u0026#34;, \u0026#34;dns\u0026#34;: {} }] k8s.v1.cni.cncf.io/networks: my-network k8s.v1.cni.cncf.io/networks-status: [{ \u0026#34;name\u0026#34;: \u0026#34;k8s-pod-network\u0026#34;, \u0026#34;ips\u0026#34;: [ \u0026#34;10.1.102.106\u0026#34; ], \u0026#34;default\u0026#34;: true, \u0026#34;dns\u0026#34;: {} },{ \u0026#34;name\u0026#34;: \u0026#34;my-namespace/my-network\u0026#34;, \u0026#34;interface\u0026#34;: \u0026#34;net1\u0026#34;, \u0026#34;ips\u0026#34;: [ \u0026#34;192.168.1.163\u0026#34; ], \u0026#34;mac\u0026#34;: \u0026#34;8a:e9:bc:15:77:82\u0026#34;, \u0026#34;dns\u0026#34;: {} }] Status: Running ... 생략 ... ","permalink":"https://wkqco33.github.io/wkqcosoft-docs/posts/microk8s/","summary":"\u003ch2 id=\"1-microk8s-설치\"\u003e1. MicroK8s 설치\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003eUbuntu 환경에서 MicroK8s 설치\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 최신 버전의 MicroK8s 설치\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e$ sudo snap install microk8s --classic\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 특정 버전의 MicroK8s 설치\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e$ sudo snap install microk8s --classic --channel\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e1.27\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"11-관리자-권한-그룹에-추가\"\u003e1.1. 관리자 권한 그룹에 추가\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003eMicroK8s 설치 후, 사용자가 MicroK8s를 사용하기 위해서는 관리자 권한 그룹에 추가해야 함\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 관리자 그룹에 MicroK8s 추가\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003esudo usermod -a -G microk8s $USER\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003esudo chown -f -R $USER ~/.kube\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 새로운 그룹 적용\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e$ newgrp microk8s\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"12-microk8s-시작-및-중지\"\u003e1.2. MicroK8s 시작 및 중지\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003eMicroK8s 시작과 중지 방법\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# MicroK8s 시작\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e$ microk8s start\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# MicroK8s 중지\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e$ microk8s stop\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"13-microk8s-with-kubectl\"\u003e1.3. MicroK8s with Kubectl\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003eMicroK8s 는 kubectl 을 자체 패키지로 제공하고 있음\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# MicroK8s 에서 제공하는 kubectl 명령어\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e$ microk8s kubectl get all --all-namespaces\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cul\u003e\n\u003cli\u003ekubectl 을 사용하기 위해서는 MicroK8s 의 config 내용을 .kube/config 에 복사해야 함\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# MicroK8s 의 config 내용을 .kube/config 에 복사\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e$ microk8s config \u0026gt; ~/.kube/config\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# kubectl 명령어 실행\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e$ kubectl get all --all-namespaces\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"2-microk8s-add-node-worker-node\"\u003e2. MicroK8s add Node (Worker Node)\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003eMicroK8s 에서는 add-node 명령어를 통해 Worker Node 를 추가할 수 있음\u003c/li\u003e\n\u003cli\u003eMaster Node 에서 add-node 명령어를 실행하면, Worker Node 에서 실행할 수 있는 명령어를 제공함\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# MicroK8s 에서 제공하는 add-node 명령어\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e$ microk8s add-node\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# MicroK8s 에서 제공하는 add-node 명령어의 결과\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eFrom the node you wish to join to this cluster, run the following:\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003emicrok8s join \u0026lt;MASTER_IP\u0026gt;:25000/\u0026lt;TOKEN\u0026gt;\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eUse the \u003cspan style=\"color:#e6db74\"\u003e\u0026#39;--worker\u0026#39;\u003c/span\u003e flag to join a node as a worker not running the control plane, eg:\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003emicrok8s join \u0026lt;MASTER_IP\u0026gt;:25000/\u0026lt;TOKEN\u0026gt; --worker\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eIf the node you are adding is not reachable through the default interface you can use one of the following:\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003emicrok8s join \u0026lt;MASTER_IP\u0026gt;:25000/\u0026lt;TOKEN\u0026gt;\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003emicrok8s join 10.0.0.1:25000/\u0026lt;TOKEN\u0026gt;\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003emicrok8s join 172.17.0.1:25000/\u0026lt;TOKEN\u0026gt;\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"21-microk8s-worker-node-join\"\u003e2.1. MicroK8s Worker Node join\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003eMaster Node 에서 획득한 add-node 명령어를 Worker Node 에서 실행하면, Worker Node 가 Master Node 에 join 됨\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# worker node join\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e$ microk8s join \u0026lt;MASTER_IP\u0026gt;:25000/\u0026lt;TOKEN\u0026gt; --worker\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch4 id=\"211-worker-node-host-정보-추가\"\u003e2.1.1. Worker Node Host 정보 추가\u003c/h4\u003e\n\u003cul\u003e\n\u003cli\u003eMaster Node 로 join 을 위해 Worker Node 의 Host 정보를 추가해야 함\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# hosts 파일 수정\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e$ sudo vi /etc/hosts\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# Worker Node 의 Host IP 와 Host Name 추가\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u0026lt;WORKER_IP\u0026gt;   worker\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"22-master-node-에서-worker-node-추가-확인\"\u003e2.2. Master Node 에서 Worker Node 추가 확인\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003eMaster Node 에서 Worker Node 가 정상적으로 추가되었는지 확인\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# Master Node 에서 Worker Node 확인\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e$ microk8s kubectl get nodes\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eNAME     STATUS   ROLES    AGE   VERSION\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003emaster   Ready    \u0026lt;none\u0026gt;   10d   v1.27.4\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eworker   Ready    \u0026lt;none\u0026gt;   10d   v1.27.4\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"3-multus-에드온-설치\"\u003e3. Multus 에드온 설치\u003c/h2\u003e\n\u003cp\u003eMultus 사용을 위해 Multus 에드온을 설치해야 함\u003c/p\u003e","title":"MicroK8s 설치와 Multus CNI 애드온 설정 가이드"},{"content":"1. Chart Museum 내부 쿠버네티스 클러스터에 Helm Chart Repository를 구축하기 위해 Chart Museum을 사용 Chart Museum은 Helm Chart를 저장하고 관리하기 위한 오픈소스 프로젝트 참고: Helm 3.8부터 OCI 레지스트리(예: Harbor, ECR, GHCR 등)를 통한 Chart 배포가 정식 지원되며, 업계에서는 OCI 레지스트리 방식으로 점차 전환되는 추세임(Harbor는 2.6 버전부터 Chart Museum 방식을 deprecated 처리함). 별도의 Chart Repository 서버 운영 부담을 줄이고 싶다면 이미 사용 중인 컨테이너 레지스트리에 OCI 방식으로 Chart를 올리는 것도 고려할 만함 1.1. Chart Museum 설치 Chart Museum은 Helm Chart로 설치 가능 Chart Museum Helm Chart를 사용하여 설치 # helm 저장소 추가 $ helm repo add chartmuseum https://chartmuseum.github.io/charts $ helm repo update # 설치 $ helm install -n chartmuseum chartmuseum chartmuseum/chartmuseum # 특정 버전 설치 $ helm install -n chartmuseum chartmuseum chartmuseum/chartmuseum --version 3.10.1 # 설치 확인 $ helm list -n chartmuseum NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION chartmuseum chartmuseum 1 2023-07-17 11:16:50.183240294 +0900 KST deployed chartmuseum-3.10.1 0.16.0 1.1.1. Chart Museum 설정 변경 Chart Museum 설치 시 기본 설정으로 설치되며, 설정 변경을 위해 values.yaml 파일을 수정하여 설치 가능 Chart Museum Configuration 참고 # Chart Museum 설정 변경 $ helm upgrade -n chartmuseum chartmuseum chartmuseum/chartmuseum -f values.yaml 1.1.2. Chart Museum 삭제 # Chart Museum 삭제 $ helm uninstall -n chartmuseum chartmuseum 1.2. Chart Museum 사용 Chart Museum은 REST API를 제공하여 Chart를 업로드/다운로드 가능 1.2.1. Chart 업로드 Chart Museum에 Chart를 업로드하기 위해서는 Chart 파일이 필요 Chart 생성과 설정은 Chart 작성 가이드 참고 Chart 파일은 helm package 명령어를 사용하여 생성 가능 Chart Museum 업로드 관련 자세한 내용은 Chart Museum Upload 참고 # Chart 생성 # 기본 설정 파일을 포함한 Chart가 생성되며 해당 내용을 수정하여 Helm Chart를 생성 $ helm create \u0026lt;chart-name\u0026gt; # Chart 업로드를 위한 패키지 생성 $ helm package \u0026lt;chart-name\u0026gt; Creating \u0026lt;chart-name\u0026gt;-0.1.0.tgz # Chart Museum에 생성된 패키지 파일 업로드 $ curl --data-binary \u0026#34;@\u0026lt;chart-name\u0026gt;.tgz\u0026#34; http://\u0026lt;chartmuseum-service-ip\u0026gt;:\u0026lt;port\u0026gt;/api/charts # 업로드 확인 $ curl http://\u0026lt;chartmuseum-service-ip\u0026gt;:\u0026lt;port\u0026gt;/api/charts * 주의: API 사용 설정 Chart Museum은 기본적으로 API 사용이 비활성화 되어 있음 API 사용을 위해 Chart Museum Deployment 설정 파일을 수정해야 함 # Chart Museum Deployment 설정 파일 수정 $ kubectl edit deployment chartmuseum -n chartmuseum # DISABLE_API 설정 수정 template: spec: containers: env: - name: DISABLE_API value: \u0026#34;false\u0026#34; # 기본값은 \u0026#34;true\u0026#34; 1.2.2. 업로드된 Chart 사용법 Chart Museum에 업로드된 Chart를 사용하기 위해서는 Chart Museum을 Helm Repository로 추가해야 함 설치 관련 자세한 내용은 Helm Chart Install 참고 # Chart Museum을 Helm Repository로 추가 $ helm repo add \u0026lt;repo-name\u0026gt; http://\u0026lt;chartmuseum-service-ip\u0026gt;:\u0026lt;port\u0026gt; $ helm repo update # Chart Museum에 업로드된 Chart 목록 확인 $ helm search repo \u0026lt;repo-name\u0026gt; NAME CHART VERSION APP VERSION DESCRIPTION \u0026lt;repo-name\u0026gt;/\u0026lt;chart-name\u0026gt; 0.1.0 1.16.0 A Helm chart for Kubernetes Chart Museum에 업로드된 Chart를 사용하기 위해서는 helm install 명령어를 사용하여 설치 가능 # Chart Museum에 업로드된 Chart 설치 $ helm install \u0026lt;release-name\u0026gt; \u0026lt;repo-name\u0026gt;/\u0026lt;chart-name\u0026gt; ","permalink":"https://wkqco33.github.io/wkqcosoft-docs/posts/helm-repository/","summary":"\u003ch2 id=\"1-chart-museum\"\u003e1. Chart Museum\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e내부 쿠버네티스 클러스터에 Helm Chart Repository를 구축하기 위해 Chart Museum을 사용\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://chartmuseum.com/\"\u003eChart Museum\u003c/a\u003e은 Helm Chart를 저장하고 관리하기 위한 오픈소스 프로젝트\u003c/li\u003e\n\u003cli\u003e참고: Helm 3.8부터 OCI 레지스트리(예: Harbor, ECR, GHCR 등)를 통한 Chart 배포가 정식 지원되며, 업계에서는 OCI 레지스트리 방식으로 점차 전환되는 추세임(Harbor는 2.6 버전부터 Chart Museum 방식을 deprecated 처리함). 별도의 Chart Repository 서버 운영 부담을 줄이고 싶다면 이미 사용 중인 컨테이너 레지스트리에 OCI 방식으로 Chart를 올리는 것도 고려할 만함\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"11-chart-museum-설치\"\u003e1.1. Chart Museum 설치\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003eChart Museum은 Helm Chart로 설치 가능\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://artifacthub.io/packages/helm/chartmuseum/chartmuseum\"\u003eChart Museum Helm Chart\u003c/a\u003e를 사용하여 설치\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# helm 저장소 추가\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e$ helm repo add chartmuseum https://chartmuseum.github.io/charts\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e$ helm repo update\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 설치\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e$ helm install -n chartmuseum chartmuseum chartmuseum/chartmuseum\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 특정 버전 설치\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e$ helm install -n chartmuseum chartmuseum chartmuseum/chartmuseum --version 3.10.1\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 설치 확인\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e$ helm list -n chartmuseum\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eNAME            NAMESPACE       REVISION        UPDATED                                 STATUS          CHART                   APP VERSION\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003echartmuseum     chartmuseum     \u003cspan style=\"color:#ae81ff\"\u003e1\u003c/span\u003e               2023-07-17 11:16:50.183240294 +0900 KST deployed        chartmuseum-3.10.1      0.16.0\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch4 id=\"111-chart-museum-설정-변경\"\u003e1.1.1. Chart Museum 설정 변경\u003c/h4\u003e\n\u003cul\u003e\n\u003cli\u003eChart Museum 설치 시 기본 설정으로 설치되며, 설정 변경을 위해 \u003ccode\u003evalues.yaml\u003c/code\u003e 파일을 수정하여 설치 가능\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://chartmuseum.com/docs/#configuration\"\u003eChart Museum Configuration\u003c/a\u003e 참고\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# Chart Museum 설정 변경\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e$ helm upgrade -n chartmuseum chartmuseum chartmuseum/chartmuseum -f values.yaml\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch4 id=\"112-chart-museum-삭제\"\u003e1.1.2. Chart Museum 삭제\u003c/h4\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# Chart Museum 삭제\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e$ helm uninstall -n chartmuseum chartmuseum\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"12-chart-museum-사용\"\u003e1.2. Chart Museum 사용\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003eChart Museum은 REST API를 제공하여 Chart를 업로드/다운로드 가능\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch4 id=\"121-chart-업로드\"\u003e1.2.1. Chart 업로드\u003c/h4\u003e\n\u003cul\u003e\n\u003cli\u003eChart Museum에 Chart를 업로드하기 위해서는 Chart 파일이 필요\u003c/li\u003e\n\u003cli\u003eChart 생성과 설정은 \u003ca href=\"https://helm.sh/ko/docs/topics/charts/\"\u003eChart 작성 가이드\u003c/a\u003e 참고\u003c/li\u003e\n\u003cli\u003eChart 파일은 \u003ccode\u003ehelm package\u003c/code\u003e 명령어를 사용하여 생성 가능\u003c/li\u003e\n\u003cli\u003eChart Museum 업로드 관련 자세한 내용은 \u003ca href=\"https://chartmuseum.com/docs/#uploading-a-chart-package\"\u003eChart Museum Upload\u003c/a\u003e 참고\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# Chart 생성\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 기본 설정 파일을 포함한 Chart가 생성되며 해당 내용을 수정하여 Helm Chart를 생성\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e$ helm create \u0026lt;chart-name\u0026gt;\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# Chart 업로드를 위한 패키지 생성\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e$ helm package \u0026lt;chart-name\u0026gt;\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eCreating \u0026lt;chart-name\u0026gt;-0.1.0.tgz\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# Chart Museum에 생성된 패키지 파일 업로드\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e$ curl --data-binary \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;@\u0026lt;chart-name\u0026gt;.tgz\u0026#34;\u003c/span\u003e http://\u0026lt;chartmuseum-service-ip\u0026gt;:\u0026lt;port\u0026gt;/api/charts\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 업로드 확인\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e$ curl http://\u0026lt;chartmuseum-service-ip\u0026gt;:\u0026lt;port\u0026gt;/api/charts\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch5 id=\"-주의-api-사용-설정\"\u003e* 주의: API 사용 설정\u003c/h5\u003e\n\u003cul\u003e\n\u003cli\u003eChart Museum은 기본적으로 API 사용이 비활성화 되어 있음\u003c/li\u003e\n\u003cli\u003eAPI 사용을 위해 Chart Museum Deployment 설정 파일을 수정해야 함\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# Chart Museum Deployment 설정 파일 수정\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e$ kubectl edit deployment chartmuseum -n chartmuseum\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-yaml\" data-lang=\"yaml\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# DISABLE_API 설정 수정\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#f92672\"\u003etemplate\u003c/span\u003e:\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    \u003cspan style=\"color:#f92672\"\u003espec\u003c/span\u003e:\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e       \u003cspan style=\"color:#f92672\"\u003econtainers\u003c/span\u003e:\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e         \u003cspan style=\"color:#f92672\"\u003eenv\u003c/span\u003e:\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e         - \u003cspan style=\"color:#f92672\"\u003ename\u003c/span\u003e: \u003cspan style=\"color:#ae81ff\"\u003eDISABLE_API\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e           \u003cspan style=\"color:#f92672\"\u003evalue\u003c/span\u003e: \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;false\u0026#34;\u003c/span\u003e \u003cspan style=\"color:#75715e\"\u003e# 기본값은 \u0026#34;true\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch4 id=\"122-업로드된-chart-사용법\"\u003e1.2.2. 업로드된 Chart 사용법\u003c/h4\u003e\n\u003cul\u003e\n\u003cli\u003eChart Museum에 업로드된 Chart를 사용하기 위해서는 Chart Museum을 Helm Repository로 추가해야 함\u003c/li\u003e\n\u003cli\u003e설치 관련 자세한 내용은 \u003ca href=\"https://chartmuseum.com/docs/#installing-chartsinto-kubernetes\"\u003eHelm Chart Install\u003c/a\u003e 참고\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# Chart Museum을 Helm Repository로 추가\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e$ helm repo add \u0026lt;repo-name\u0026gt; http://\u0026lt;chartmuseum-service-ip\u0026gt;:\u0026lt;port\u0026gt;\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e$ helm repo update\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# Chart Museum에 업로드된 Chart 목록 확인\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e$ helm search repo \u0026lt;repo-name\u0026gt;\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eNAME                            CHART VERSION   APP VERSION     DESCRIPTION\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u0026lt;repo-name\u0026gt;/\u0026lt;chart-name\u0026gt;        0.1.0           1.16.0          A Helm chart \u003cspan style=\"color:#66d9ef\"\u003efor\u003c/span\u003e Kubernetes\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cul\u003e\n\u003cli\u003eChart Museum에 업로드된 Chart를 사용하기 위해서는 \u003ccode\u003ehelm install\u003c/code\u003e 명령어를 사용하여 설치 가능\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# Chart Museum에 업로드된 Chart 설치\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e$ helm install \u0026lt;release-name\u0026gt; \u0026lt;repo-name\u0026gt;/\u0026lt;chart-name\u0026gt;\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e","title":"Helm Chart Repository 구축 및 관리 가이드 (ChartMuseum)"},{"content":"1. Go 언어의 핵심 철학 및 특징 Go(Golang)는 구글에서 개발한 정적 타입 컴파일 언어로, **간결함(Simplicity)**과 높은 생산성, 강력한 동시성 처리를 최우선 가치로 설계되었습니다.\n간결한 문법: 키워드가 25개 내외로 적어 코드 읽기와 유지보수가 직관적입니다. 초고속 컴파일 및 실행 속도: C/C++에 육박하는 빌드 및 실행 성능을 제공합니다. Goroutine 기반 동시성 지원: 경량 스레드(Goroutine)를 통해 수만 개의 동시 작업을 적은 메모리로 처리합니다. Go 1.18+ 제네릭(Generics) 지원: 타입 안전성을 유지하면서 재사용 가능한 데이터 구조 작성이 가능합니다. Go 1.22+ 향상된 net/http 라우팅: 별도 외부 프레임워크 없이 표준 라이브러리만으로 HTTP 메서드 및 경로 파라미터 캡처가 가능합니다. 2. Go 동시성(Concurrency) 핵심 패턴 Go는 \u0026ldquo;Don\u0026rsquo;t communicate by sharing memory; instead, share memory by communicating.\u0026rdquo; (메모리를 공유하여 통신하지 말고, 통신함으로써 메모리를 공유하라)는 명언으로 대표되는 CSP(Communicating Sequential Processes) 모델을 따릅니다.\n① Goroutine \u0026amp; Channel 기본 개념 package main import ( \u0026#34;fmt\u0026#34; \u0026#34;time\u0026#34; ) func worker(id int, ch chan string) { time.Sleep(time.Millisecond * 500) ch \u0026lt;- fmt.Sprintf(\u0026#34;Worker %d 작업 완료\u0026#34;, id) } func main() { ch := make(chan string) // 3개의 고루틴 병렬 실행 for i := 1; i \u0026lt;= 3; i++ { go worker(i, ch) } // 채널로부터 결과 수신 for i := 1; i \u0026lt;= 3; i++ { msg := \u0026lt;-ch fmt.Println(msg) } } ② Worker Pool 패턴 (실무 추천 패턴) 대량의 작업 요청을 제한된 고루틴 스레드 풀에서 안전하게 처리하는 실무 패턴입니다.\npackage main import ( \u0026#34;context\u0026#34; \u0026#34;fmt\u0026#34; \u0026#34;sync\u0026#34; \u0026#34;time\u0026#34; ) type Task struct { ID int } func Worker(ctx context.Context, id int, tasks \u0026lt;-chan Task, results chan\u0026lt;- string, wg *sync.WaitGroup) { defer wg.Done() for { select { case \u0026lt;-ctx.Done(): return case task, ok := \u0026lt;-tasks: if !ok { return } // 작업 처리 로직 time.Sleep(100 * time.Millisecond) results \u0026lt;- fmt.Sprintf(\u0026#34;[Worker %d] Task %d 처리 성공\u0026#34;, id, task.ID) } } } func main() { const numJobs = 10 const numWorkers = 3 tasks := make(chan Task, numJobs) results := make(chan string, numJobs) var wg sync.WaitGroup ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() // Worker Pool 생성 for w := 1; w \u0026lt;= numWorkers; w++ { wg.Add(1) go Worker(ctx, w, tasks, results, \u0026amp;wg) } // Task 투입 for j := 1; j \u0026lt;= numJobs; j++ { tasks \u0026lt;- Task{ID: j} } close(tasks) // 모든 Worker 종료 대기 후 결과 채널 닫기 go func() { wg.Wait() close(results) }() // 결과 수집 for res := range results { fmt.Println(res) } } 3. Go 언어 활용 분야 및 결론 Go는 현재 **Cloud Native 생태계(Docker, Kubernetes, Terraform, Prometheus 등)**의 사실상 표준 언어로 자리 잡았습니다. 네트워크 서버, 대용량 트래픽 백엔드 API, Microservice Architecture(MSA) 서비스 구축 시 최선의 선택지입니다.\n","permalink":"https://wkqco33.github.io/wkqcosoft-docs/posts/golang/","summary":"\u003ch2 id=\"1-go-언어의-핵심-철학-및-특징\"\u003e1. Go 언어의 핵심 철학 및 특징\u003c/h2\u003e\n\u003cp\u003eGo(Golang)는 구글에서 개발한 정적 타입 컴파일 언어로, **간결함(Simplicity)**과 \u003cstrong\u003e높은 생산성\u003c/strong\u003e, \u003cstrong\u003e강력한 동시성 처리\u003c/strong\u003e를 최우선 가치로 설계되었습니다.\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003e간결한 문법\u003c/strong\u003e: 키워드가 25개 내외로 적어 코드 읽기와 유지보수가 직관적입니다.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e초고속 컴파일 및 실행 속도\u003c/strong\u003e: C/C++에 육박하는 빌드 및 실행 성능을 제공합니다.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eGoroutine 기반 동시성 지원\u003c/strong\u003e: 경량 스레드(Goroutine)를 통해 수만 개의 동시 작업을 적은 메모리로 처리합니다.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eGo 1.18+ 제네릭(Generics) 지원\u003c/strong\u003e: 타입 안전성을 유지하면서 재사용 가능한 데이터 구조 작성이 가능합니다.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eGo 1.22+ 향상된 \u003ccode\u003enet/http\u003c/code\u003e 라우팅\u003c/strong\u003e: 별도 외부 프레임워크 없이 표준 라이브러리만으로 HTTP 메서드 및 경로 파라미터 캡처가 가능합니다.\u003c/li\u003e\n\u003c/ul\u003e\n\u003chr\u003e\n\u003ch2 id=\"2-go-동시성concurrency-핵심-패턴\"\u003e2. Go 동시성(Concurrency) 핵심 패턴\u003c/h2\u003e\n\u003cp\u003eGo는 \u003cstrong\u003e\u0026ldquo;Don\u0026rsquo;t communicate by sharing memory; instead, share memory by communicating.\u0026rdquo;\u003c/strong\u003e (메모리를 공유하여 통신하지 말고, 통신함으로써 메모리를 공유하라)는 명언으로 대표되는 CSP(Communicating Sequential Processes) 모델을 따릅니다.\u003c/p\u003e","title":"현대적 Go 프로그래밍 핵심 가이드 및 동시성 패턴"},{"content":"Jenkins Plugin 설치 Jenkins 에서 제공하는 기본 플러그인 외에 추가로 필요한 플러그인 설치 Jenkins \u0026gt; 플러그인 관리 \u0026gt; 설치 가능 탭에서 필요한 플러그인 검색 Kubernetes Github Gitlab Blue Ocean (Optional) 설치가 완료되면 Jenkins 재시작 Jenkins Kubernetes Credential 설정 Jenkins \u0026gt; 관리 \u0026gt; Credentials \u0026gt; Global credentials (unrestricted) \u0026gt; Add Credentials Kind: Secret file File: ~/.kube/config ID: kube-config Description: Kubernetes config file Jenkins Kubernetes Cloud 설정 Jenkins \u0026gt; 관리 \u0026gt; Cloud \u0026gt; Kubernetes Cloud Details Kubernetes URL: https://kubernetes.default Kubernetes Namespace: jenkins Credentials: kube-config Jenkins Gitlab Credential 설정 Jenkins \u0026gt; 관리 \u0026gt; Credentials \u0026gt; Global credentials (unrestricted) \u0026gt; Add Credentials Kind: Username with password Username: gitlab username (gitlab 에서 사용하는 username) Password: gitlab password (gitlab 에서 사용하는 password) ID: gitlab-credential Description: Gitlab credential Jenkinsfile 작성 // Jenkins Pipeline 예시 // Test app 을 Docker build 하고 Git push 하는 파이프라인 pipeline { agent { // kubernetes 에서 실행 kubernetes { yaml \u0026#39;\u0026#39;\u0026#39; apiVersion: v1 kind: Pod spec: containers: - name: python image: python:3.10 command: - cat tty: true - name: kaniko image: gcr.io/kaniko-project/executor:debug command: - cat tty: true volumeMounts: - name: registry-credentials mountPath: /kaniko/.docker volumes: - name: registry-credentials secret: secretName: regcred items: - key: .dockerconfigjson path: config.json\u0026#39;\u0026#39;\u0026#39; } } stages { // Unit Test (테스트를 위해 python 컨테이너에서 실행) // Test 결과가 성공이면 Docker Build 수행 // 테스트를 위해 적용한 스테이지로 필수로 포함할 필요는 없음 stage(\u0026#39;Test\u0026#39;) { steps { container(\u0026#39;python\u0026#39;) { sh \u0026#39;pip install -r requirements.txt\u0026#39; sh \u0026#39;python test_app.py\u0026#39; } } } // Docker Build // kaniko 컨테이너에서 Dockerfile 을 통해 이미지 빌드 // 컨테이너 내부에서 Docker 빌드를 위해 [kaniko](https://github.com/GoogleContainerTools/kaniko) 를 사용 // Docker build 후 Docker Hub 에 Push stage(\u0026#39;Docker Build\u0026#39;) { steps { container(\u0026#39;kaniko\u0026#39;) { sh \u0026#34;executor --dockerfile=Dockerfile \\ --context=dir://${env.WORKSPACE} \\ --destination=\u0026lt;docker-id\u0026gt;/test-app:${currentBuild.number}\u0026#34; } } } // docker image 를 deployment.yaml 에 적용 // deployment.yaml 의 image version 을 현재 빌드 번호로 변경 // 변경된 deployment.yaml 을 git 에 push stage(\u0026#39;Modified deployment.yaml\u0026#39;) { steps { sh \u0026#34;sed -i \u0026#39;s/test-app:.*\\$/test-app:${currentBuild.number}/g\u0026#39; deployment.yaml\u0026#34; withCredentials([gitUsernamePassword(credentialsId: \u0026#39;gitlab-credential\u0026#39;, gitToolName: \u0026#39;git-tool\u0026#39;)]) { sh \u0026#39;git checkout main\u0026#39; sh \u0026#39;git fetch --all\u0026#39; sh \u0026#39;git add deployment.yaml\u0026#39; sh \u0026#34;git commit -m \u0026#39;Update image version test-app:${currentBuild.number} in deployment.yaml\u0026#39;\u0026#34; sh \u0026#39;git push -u origin main\u0026#39; } } post { success { echo \u0026#39;Deploy Success\u0026#39; } failure { echo \u0026#39;Deploy Failure\u0026#39; } } } } } Jenkins Pipeline 실행 Jenkins \u0026gt; 새로운 Item \u0026gt; Enter an item name: test-app Pipeline 선택 \u0026gt; OK Pipeline \u0026gt; Definition: Pipeline script from SCM SCM: Git Repository URL: 대상 gitlab repository 주소 Credentials: Gitlab credential Branches to build: main Script Path: Jenkinsfile 저장 후 빌드 실행 Jenkins Pipeline 결과 확인 Jenkins Pipeline 실행 결과 확인 오류 발생 시 Console Output 확인 정상적으로 빌드가 완료되면 Gitlab 에서 변경된 deployment.yaml 확인 ArgoCD 에서 변경된 deployment.yaml 을 통해 배포 확인 ","permalink":"https://wkqco33.github.io/wkqcosoft-docs/posts/devops/jenkins-pipeline/","summary":"\u003ch2 id=\"jenkins-plugin-설치\"\u003eJenkins Plugin 설치\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003eJenkins 에서 제공하는 기본 플러그인 외에 추가로 필요한 플러그인 설치\u003c/li\u003e\n\u003cli\u003eJenkins \u0026gt; 플러그인 관리 \u0026gt; 설치 가능 탭에서 필요한 플러그인 검색\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"https://plugins.jenkins.io/kubernetes/\"\u003eKubernetes\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://plugins.jenkins.io/github/\"\u003eGithub\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://plugins.jenkins.io/gitlab/\"\u003eGitlab\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://plugins.jenkins.io/blueocean/\"\u003eBlue Ocean\u003c/a\u003e (Optional)\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e설치가 완료되면 Jenkins 재시작\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"jenkins-kubernetes-credential-설정\"\u003eJenkins Kubernetes Credential 설정\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003eJenkins \u0026gt; 관리 \u0026gt; Credentials \u0026gt; Global credentials (unrestricted) \u0026gt; Add Credentials\n\u003cul\u003e\n\u003cli\u003eKind: Secret file\u003c/li\u003e\n\u003cli\u003eFile: \u003ccode\u003e~/.kube/config\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003eID: \u003ccode\u003ekube-config\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003eDescription: \u003ccode\u003eKubernetes config file\u003c/code\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"jenkins-kubernetes-cloud-설정\"\u003eJenkins Kubernetes Cloud 설정\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003eJenkins \u0026gt; 관리 \u0026gt; Cloud \u0026gt; Kubernetes Cloud Details\n\u003cul\u003e\n\u003cli\u003eKubernetes URL: \u003ccode\u003ehttps://kubernetes.default\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003eKubernetes Namespace: \u003ccode\u003ejenkins\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003eCredentials: \u003ccode\u003ekube-config\u003c/code\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"jenkins-gitlab-credential-설정\"\u003eJenkins Gitlab Credential 설정\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003eJenkins \u0026gt; 관리 \u0026gt; Credentials \u0026gt; Global credentials (unrestricted) \u0026gt; Add Credentials\n\u003cul\u003e\n\u003cli\u003eKind: Username with password\u003c/li\u003e\n\u003cli\u003eUsername: \u003ccode\u003egitlab username\u003c/code\u003e (gitlab 에서 사용하는 username)\u003c/li\u003e\n\u003cli\u003ePassword: \u003ccode\u003egitlab password\u003c/code\u003e (gitlab 에서 사용하는 password)\u003c/li\u003e\n\u003cli\u003eID: \u003ccode\u003egitlab-credential\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003eDescription: \u003ccode\u003eGitlab credential\u003c/code\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"jenkinsfile-작성\"\u003eJenkinsfile 작성\u003c/h2\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-groovy\" data-lang=\"groovy\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e// Jenkins Pipeline 예시\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e// Test app 을 Docker build 하고 Git push 하는 파이프라인\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e\u003c/span\u003epipeline \u003cspan style=\"color:#f92672\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e  agent \u003cspan style=\"color:#f92672\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    \u003cspan style=\"color:#75715e\"\u003e// kubernetes 에서 실행\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e\u003c/span\u003e    kubernetes \u003cspan style=\"color:#f92672\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e      yaml \u003cspan style=\"color:#e6db74\"\u003e\u0026#39;\u0026#39;\u0026#39;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#e6db74\"\u003e        apiVersion: v1\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#e6db74\"\u003e        kind: Pod\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#e6db74\"\u003e        spec:\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#e6db74\"\u003e          containers:\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#e6db74\"\u003e          - name: python\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#e6db74\"\u003e            image: python:3.10\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#e6db74\"\u003e            command:\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#e6db74\"\u003e            - cat\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#e6db74\"\u003e            tty: true\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#e6db74\"\u003e          - name: kaniko\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#e6db74\"\u003e            image: gcr.io/kaniko-project/executor:debug\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#e6db74\"\u003e            command:\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#e6db74\"\u003e            - cat\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#e6db74\"\u003e            tty: true\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#e6db74\"\u003e            volumeMounts:\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#e6db74\"\u003e              - name: registry-credentials\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#e6db74\"\u003e                mountPath: /kaniko/.docker\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#e6db74\"\u003e          volumes:\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#e6db74\"\u003e            - name: registry-credentials\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#e6db74\"\u003e              secret:\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#e6db74\"\u003e                secretName: regcred\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#e6db74\"\u003e                items:\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#e6db74\"\u003e                - key: .dockerconfigjson\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#e6db74\"\u003e                  path: config.json\u0026#39;\u0026#39;\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    \u003cspan style=\"color:#f92672\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e  \u003cspan style=\"color:#f92672\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e  stages \u003cspan style=\"color:#f92672\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    \u003cspan style=\"color:#75715e\"\u003e// Unit Test (테스트를 위해 python 컨테이너에서 실행)\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e\u003c/span\u003e    \u003cspan style=\"color:#75715e\"\u003e// Test 결과가 성공이면 Docker Build 수행\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e\u003c/span\u003e    \u003cspan style=\"color:#75715e\"\u003e// 테스트를 위해 적용한 스테이지로 필수로 포함할 필요는 없음\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e\u003c/span\u003e    stage\u003cspan style=\"color:#f92672\"\u003e(\u003c/span\u003e\u003cspan style=\"color:#e6db74\"\u003e\u0026#39;Test\u0026#39;\u003c/span\u003e\u003cspan style=\"color:#f92672\"\u003e)\u003c/span\u003e \u003cspan style=\"color:#f92672\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e      steps \u003cspan style=\"color:#f92672\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e        container\u003cspan style=\"color:#f92672\"\u003e(\u003c/span\u003e\u003cspan style=\"color:#e6db74\"\u003e\u0026#39;python\u0026#39;\u003c/span\u003e\u003cspan style=\"color:#f92672\"\u003e)\u003c/span\u003e \u003cspan style=\"color:#f92672\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e          sh \u003cspan style=\"color:#e6db74\"\u003e\u0026#39;pip install -r requirements.txt\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e          sh \u003cspan style=\"color:#e6db74\"\u003e\u0026#39;python test_app.py\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e        \u003cspan style=\"color:#f92672\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e      \u003cspan style=\"color:#f92672\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    \u003cspan style=\"color:#f92672\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    \u003cspan style=\"color:#75715e\"\u003e// Docker Build\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e\u003c/span\u003e    \u003cspan style=\"color:#75715e\"\u003e// kaniko 컨테이너에서 Dockerfile 을 통해 이미지 빌드\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e\u003c/span\u003e    \u003cspan style=\"color:#75715e\"\u003e// 컨테이너 내부에서 Docker 빌드를 위해 [kaniko](https://github.com/GoogleContainerTools/kaniko) 를 사용\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e\u003c/span\u003e    \u003cspan style=\"color:#75715e\"\u003e// Docker build 후 Docker Hub 에 Push\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e\u003c/span\u003e    stage\u003cspan style=\"color:#f92672\"\u003e(\u003c/span\u003e\u003cspan style=\"color:#e6db74\"\u003e\u0026#39;Docker Build\u0026#39;\u003c/span\u003e\u003cspan style=\"color:#f92672\"\u003e)\u003c/span\u003e \u003cspan style=\"color:#f92672\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e      steps \u003cspan style=\"color:#f92672\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e        container\u003cspan style=\"color:#f92672\"\u003e(\u003c/span\u003e\u003cspan style=\"color:#e6db74\"\u003e\u0026#39;kaniko\u0026#39;\u003c/span\u003e\u003cspan style=\"color:#f92672\"\u003e)\u003c/span\u003e \u003cspan style=\"color:#f92672\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e          sh \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;executor --dockerfile=Dockerfile \\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#e6db74\"\u003e          --context=dir://${env.WORKSPACE} \\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#e6db74\"\u003e          --destination=\u0026lt;docker-id\u0026gt;/test-app:${currentBuild.number}\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e        \u003cspan style=\"color:#f92672\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e      \u003cspan style=\"color:#f92672\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    \u003cspan style=\"color:#f92672\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    \u003cspan style=\"color:#75715e\"\u003e// docker image 를 deployment.yaml 에 적용\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e\u003c/span\u003e    \u003cspan style=\"color:#75715e\"\u003e// deployment.yaml 의 image version 을 현재 빌드 번호로 변경\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e\u003c/span\u003e    \u003cspan style=\"color:#75715e\"\u003e// 변경된 deployment.yaml 을 git 에 push\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e\u003c/span\u003e    stage\u003cspan style=\"color:#f92672\"\u003e(\u003c/span\u003e\u003cspan style=\"color:#e6db74\"\u003e\u0026#39;Modified deployment.yaml\u0026#39;\u003c/span\u003e\u003cspan style=\"color:#f92672\"\u003e)\u003c/span\u003e \u003cspan style=\"color:#f92672\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e      steps \u003cspan style=\"color:#f92672\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e        sh \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;sed -i \u0026#39;s/test-app:.*\\$/test-app:${currentBuild.number}/g\u0026#39; deployment.yaml\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e        withCredentials\u003cspan style=\"color:#f92672\"\u003e([\u003c/span\u003egitUsernamePassword\u003cspan style=\"color:#f92672\"\u003e(\u003c/span\u003ecredentialsId: \u003cspan style=\"color:#e6db74\"\u003e\u0026#39;gitlab-credential\u0026#39;\u003c/span\u003e\u003cspan style=\"color:#f92672\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e          gitToolName: \u003cspan style=\"color:#e6db74\"\u003e\u0026#39;git-tool\u0026#39;\u003c/span\u003e\u003cspan style=\"color:#f92672\"\u003e)])\u003c/span\u003e \u003cspan style=\"color:#f92672\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e            sh \u003cspan style=\"color:#e6db74\"\u003e\u0026#39;git checkout main\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e            sh \u003cspan style=\"color:#e6db74\"\u003e\u0026#39;git fetch --all\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e            sh \u003cspan style=\"color:#e6db74\"\u003e\u0026#39;git add deployment.yaml\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e            sh \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;git commit -m \u0026#39;Update image version test-app:${currentBuild.number} in deployment.yaml\u0026#39;\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e            sh \u003cspan style=\"color:#e6db74\"\u003e\u0026#39;git push -u origin main\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e          \u003cspan style=\"color:#f92672\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e      \u003cspan style=\"color:#f92672\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e      post \u003cspan style=\"color:#f92672\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e        success \u003cspan style=\"color:#f92672\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e          echo \u003cspan style=\"color:#e6db74\"\u003e\u0026#39;Deploy Success\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e        \u003cspan style=\"color:#f92672\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e        failure \u003cspan style=\"color:#f92672\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e          echo \u003cspan style=\"color:#e6db74\"\u003e\u0026#39;Deploy Failure\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e        \u003cspan style=\"color:#f92672\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e      \u003cspan style=\"color:#f92672\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    \u003cspan style=\"color:#f92672\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e  \u003cspan style=\"color:#f92672\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#f92672\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"jenkins-pipeline-실행\"\u003eJenkins Pipeline 실행\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003eJenkins \u0026gt; 새로운 Item \u0026gt; Enter an item name: \u003ccode\u003etest-app\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003ePipeline 선택 \u0026gt; OK\u003c/li\u003e\n\u003cli\u003ePipeline \u0026gt; Definition: \u003ccode\u003ePipeline script from SCM\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003eSCM: \u003ccode\u003eGit\u003c/code\u003e\n\u003cul\u003e\n\u003cli\u003eRepository URL: \u003ccode\u003e대상 gitlab repository 주소\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003eCredentials: \u003ccode\u003eGitlab credential\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003eBranches to build: \u003ccode\u003emain\u003c/code\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003eScript Path: \u003ccode\u003eJenkinsfile\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003e저장 후 빌드 실행\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"jenkins-pipeline-결과-확인\"\u003eJenkins Pipeline 결과 확인\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003eJenkins Pipeline 실행 결과 확인\u003c/li\u003e\n\u003cli\u003e오류 발생 시 Console Output 확인\u003c/li\u003e\n\u003cli\u003e정상적으로 빌드가 완료되면 Gitlab 에서 변경된 deployment.yaml 확인\u003c/li\u003e\n\u003cli\u003eArgoCD 에서 변경된 deployment.yaml 을 통해 배포 확인\u003c/li\u003e\n\u003c/ul\u003e","title":"Jenkins Declarative Pipeline 구성 및 K8s Agent 연동 가이드"},{"content":"ArgoCD 설치 # argocd namespace 생성 kubectl create namespace argocd # argocd 설치 kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml ArgoCD Server expose 설정 NodePort 로 Service 를 expose 하여 접속 가능하도록 설정 # 방법1: argocd-server service expose kubectl expose svc argocd-server -n argocd --type=NodePort --name=argocd-server # 방법2: argocd-server edit로 yaml 파일을 열어 NodePort 설정 kubectl edit svc argocd-server -n argocd argocd-server service 의 NodePort 확인 kubectl get svc argocd-server -n argocd argocd-server service 의 NodePort 로 접속하여 확인 ArgoCD 로그인 # admin 비밀번호 확인 kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath=\u0026#34;{.data.password}\u0026#34; | base64 -d; echo ArgoCD Application 생성 ArgoCD UI 접속 admin 계정으로 로그인 New App 버튼 클릭 Application Name 입력 Project 선택 SYNC POLICY 선택 Repository URL 입력 Revision 입력 Path 입력 deployment.yaml, service.yaml 파일이 있는 경로 root directory 에 있을 경우 . 입력 Cluster URL 입력 (기본값: https://kubernetes.default.svc) Namespace 입력 Create 버튼 클릭 ArgoCD 배포 확인 생성된 Application 에서 Sync 버튼 클릭 Sync Status 확인 Sync Status 가 Synced 로 변경되면 배포 완료 ","permalink":"https://wkqco33.github.io/wkqcosoft-docs/posts/devops/argocd-install/","summary":"\u003ch2 id=\"argocd-설치\"\u003eArgoCD 설치\u003c/h2\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# argocd namespace 생성\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ekubectl create namespace argocd\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# argocd 설치\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ekubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"argocd-server-expose-설정\"\u003eArgoCD Server expose 설정\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003eNodePort 로 Service 를 expose 하여 접속 가능하도록 설정\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 방법1: argocd-server service expose\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ekubectl expose svc argocd-server -n argocd --type\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003eNodePort --name\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003eargocd-server\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 방법2: argocd-server edit로 yaml 파일을 열어 NodePort 설정\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ekubectl edit svc argocd-server -n argocd\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cul\u003e\n\u003cli\u003eargocd-server service 의 NodePort 확인\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ekubectl get svc argocd-server -n argocd\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cul\u003e\n\u003cli\u003eargocd-server service 의 NodePort 로 접속하여 확인\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"argocd-로그인\"\u003eArgoCD 로그인\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# admin 비밀번호 확인\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ekubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e\u003cspan style=\"color:#e6db74\"\u003e\u0026#34;{.data.password}\u0026#34;\u003c/span\u003e | base64 -d; echo\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"argocd-application-생성\"\u003eArgoCD Application 생성\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003eArgoCD UI 접속\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eadmin\u003c/code\u003e 계정으로 로그인\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eNew App\u003c/code\u003e 버튼 클릭\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eApplication Name\u003c/code\u003e 입력\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eProject\u003c/code\u003e 선택\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eSYNC POLICY\u003c/code\u003e 선택\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eRepository URL\u003c/code\u003e 입력\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eRevision\u003c/code\u003e 입력\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003ePath\u003c/code\u003e 입력\n\u003cul\u003e\n\u003cli\u003edeployment.yaml, service.yaml 파일이 있는 경로\u003c/li\u003e\n\u003cli\u003eroot directory 에 있을 경우 . 입력\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eCluster URL\u003c/code\u003e 입력 (기본값: \u003ca href=\"https://kubernetes.default.svc\"\u003ehttps://kubernetes.default.svc\u003c/a\u003e)\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eNamespace\u003c/code\u003e 입력\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eCreate\u003c/code\u003e 버튼 클릭\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"argocd-배포-확인\"\u003eArgoCD 배포 확인\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e생성된 Application 에서 \u003ccode\u003eSync\u003c/code\u003e 버튼 클릭\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eSync Status\u003c/code\u003e 확인\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eSync Status\u003c/code\u003e 가 \u003ccode\u003eSynced\u003c/code\u003e 로 변경되면 배포 완료\u003c/li\u003e\n\u003c/ul\u003e","title":"Kubernetes 환경에서 ArgoCD 설치 및 GitOps 구축 가이드"},{"content":"Jenkins Kubernetes 설치 준비 Namespace 생성 # jenkins namespace 생성 kubectl create namespace jenkins Persistent Volume, Persistent Volume Claim 생성 (Optional) 아래 예시는 특정 노드의 local path를 사용하는 정적 프로비저닝(static provisioning) 예시이므로, ebme-storage와 동일한 이름의 StorageClass가 클러스터에 미리 존재해야 하며 PV가 바인딩될 노드(kube-cluster-worker1)도 실제 환경에 맞게 수정 필요 # jenkins-pvc.yaml # ebme-storage class 를 사용하는 30Gi 크기의 PV, PVC 생성 apiVersion: v1 kind: PersistentVolume metadata: name: jenkins-pv spec: capacity: storage: 30Gi accessModes: - ReadWriteOnce persistentVolumeReclaimPolicy: Retain storageClassName: ebme-storage local: path: /mnt/jenkins nodeAffinity: required: nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/hostname operator: In values: - kube-cluster-worker1 --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: jenkins-pvc namespace: jenkins spec: accessModes: - ReadWriteOnce storageClassName: ebme-storage resources: requests: storage: 30Gi Jenkins Service Account 생성 (Optional) # jenkins-service-account.yaml # In GKE need to get RBAC permissions first with # kubectl create clusterrolebinding cluster-admin-binding --clusterrole=cluster-admin [--user=\u0026lt;user-name\u0026gt;|--group=\u0026lt;group-name\u0026gt;] --- apiVersion: v1 kind: ServiceAccount metadata: name: jenkins --- kind: Role apiVersion: rbac.authorization.k8s.io/v1 metadata: name: jenkins rules: - apiGroups: [\u0026#34;\u0026#34;] resources: [\u0026#34;pods\u0026#34;] verbs: [\u0026#34;create\u0026#34;,\u0026#34;delete\u0026#34;,\u0026#34;get\u0026#34;,\u0026#34;list\u0026#34;,\u0026#34;patch\u0026#34;,\u0026#34;update\u0026#34;,\u0026#34;watch\u0026#34;] - apiGroups: [\u0026#34;\u0026#34;] resources: [\u0026#34;pods/exec\u0026#34;] verbs: [\u0026#34;create\u0026#34;,\u0026#34;delete\u0026#34;,\u0026#34;get\u0026#34;,\u0026#34;list\u0026#34;,\u0026#34;patch\u0026#34;,\u0026#34;update\u0026#34;,\u0026#34;watch\u0026#34;] - apiGroups: [\u0026#34;\u0026#34;] resources: [\u0026#34;pods/log\u0026#34;] verbs: [\u0026#34;get\u0026#34;,\u0026#34;list\u0026#34;,\u0026#34;watch\u0026#34;] - apiGroups: [\u0026#34;\u0026#34;] resources: [\u0026#34;events\u0026#34;] verbs: [\u0026#34;watch\u0026#34;] - apiGroups: [\u0026#34;\u0026#34;] resources: [\u0026#34;secrets\u0026#34;] verbs: [\u0026#34;get\u0026#34;] --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: jenkins roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: jenkins subjects: - kind: ServiceAccount name: jenkins Jenkins values.yaml 생성 (Optional) Jenkins 에서 제공하는 기본 템플릿 value.yaml 에서 필요한 부분만 수정 # jenkins-values.yaml # persistence 부분을 아래와 같이 수정 persistence: enabled: true existingClaim: \u0026#34;jenkins-pvc\u0026#34; storageClass: \u0026#34;ebme-storage\u0026#34; accessMode: \u0026#34;ReadWriteOnce\u0026#34; size: \u0026#34;30Gi\u0026#34; Helm을 사용한 젠킨스 설치 Jenkins Repository 추가 helm repo add jenkinsci https://charts.jenkins.io helm repo update Jenkins 설치 # 기본 설정대로 설치 helm install -n jenkins jenkins jenkinsci/jenkins # 기존 작성한 jenkins-values.yaml 을 사용하여 설치 helm install -n jenkins jenkins jenkinsci/jenkins -f jenkins-values.yaml Jenkins Service expose NodePort 로 Service 를 expose 하여 접속 가능하도록 설정 해당 주소로 Jenkins 접속 확인 kubectl expose svc jenkins -n jenkins --type=NodePort --name=jenkins Jenkins 비밀번호 확인 kubectl exec --namespace jenkins -it svc/jenkins -c jenkins -- /bin/cat /run/secrets/chart-admin-password \u0026amp;\u0026amp; echo ","permalink":"https://wkqco33.github.io/wkqcosoft-docs/posts/devops/jenkins-install/","summary":"\u003ch2 id=\"jenkins-kubernetes-설치-준비\"\u003eJenkins Kubernetes 설치 준비\u003c/h2\u003e\n\u003ch3 id=\"namespace-생성\"\u003eNamespace 생성\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# jenkins namespace 생성\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ekubectl create namespace jenkins\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"persistent-volume-persistent-volume-claim-생성-optional\"\u003ePersistent Volume, Persistent Volume Claim 생성 (Optional)\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e아래 예시는 특정 노드의 local path를 사용하는 정적 프로비저닝(static provisioning) 예시이므로, \u003ccode\u003eebme-storage\u003c/code\u003e와 동일한 이름의 StorageClass가 클러스터에 미리 존재해야 하며 PV가 바인딩될 노드(\u003ccode\u003ekube-cluster-worker1\u003c/code\u003e)도 실제 환경에 맞게 수정 필요\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-yaml\" data-lang=\"yaml\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# jenkins-pvc.yaml\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# ebme-storage class 를 사용하는 30Gi 크기의 PV, PVC 생성\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#f92672\"\u003eapiVersion\u003c/span\u003e: \u003cspan style=\"color:#ae81ff\"\u003ev1\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#f92672\"\u003ekind\u003c/span\u003e: \u003cspan style=\"color:#ae81ff\"\u003ePersistentVolume\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#f92672\"\u003emetadata\u003c/span\u003e:\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e  \u003cspan style=\"color:#f92672\"\u003ename\u003c/span\u003e: \u003cspan style=\"color:#ae81ff\"\u003ejenkins-pv\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#f92672\"\u003espec\u003c/span\u003e:\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e  \u003cspan style=\"color:#f92672\"\u003ecapacity\u003c/span\u003e:\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    \u003cspan style=\"color:#f92672\"\u003estorage\u003c/span\u003e: \u003cspan style=\"color:#ae81ff\"\u003e30Gi\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e  \u003cspan style=\"color:#f92672\"\u003eaccessModes\u003c/span\u003e:\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    - \u003cspan style=\"color:#ae81ff\"\u003eReadWriteOnce\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e  \u003cspan style=\"color:#f92672\"\u003epersistentVolumeReclaimPolicy\u003c/span\u003e: \u003cspan style=\"color:#ae81ff\"\u003eRetain\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e  \u003cspan style=\"color:#f92672\"\u003estorageClassName\u003c/span\u003e: \u003cspan style=\"color:#ae81ff\"\u003eebme-storage\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e  \u003cspan style=\"color:#f92672\"\u003elocal\u003c/span\u003e:\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    \u003cspan style=\"color:#f92672\"\u003epath\u003c/span\u003e: \u003cspan style=\"color:#ae81ff\"\u003e/mnt/jenkins\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e  \u003cspan style=\"color:#f92672\"\u003enodeAffinity\u003c/span\u003e:\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    \u003cspan style=\"color:#f92672\"\u003erequired\u003c/span\u003e:\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e      \u003cspan style=\"color:#f92672\"\u003enodeSelectorTerms\u003c/span\u003e:\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e        - \u003cspan style=\"color:#f92672\"\u003ematchExpressions\u003c/span\u003e:\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e          - \u003cspan style=\"color:#f92672\"\u003ekey\u003c/span\u003e: \u003cspan style=\"color:#ae81ff\"\u003ekubernetes.io/hostname\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e            \u003cspan style=\"color:#f92672\"\u003eoperator\u003c/span\u003e: \u003cspan style=\"color:#ae81ff\"\u003eIn\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e            \u003cspan style=\"color:#f92672\"\u003evalues\u003c/span\u003e:\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e              - \u003cspan style=\"color:#ae81ff\"\u003ekube-cluster-worker1\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e---\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#f92672\"\u003eapiVersion\u003c/span\u003e: \u003cspan style=\"color:#ae81ff\"\u003ev1\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#f92672\"\u003ekind\u003c/span\u003e: \u003cspan style=\"color:#ae81ff\"\u003ePersistentVolumeClaim\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#f92672\"\u003emetadata\u003c/span\u003e:\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e  \u003cspan style=\"color:#f92672\"\u003ename\u003c/span\u003e: \u003cspan style=\"color:#ae81ff\"\u003ejenkins-pvc\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e  \u003cspan style=\"color:#f92672\"\u003enamespace\u003c/span\u003e: \u003cspan style=\"color:#ae81ff\"\u003ejenkins\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#f92672\"\u003espec\u003c/span\u003e:\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e  \u003cspan style=\"color:#f92672\"\u003eaccessModes\u003c/span\u003e:\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    - \u003cspan style=\"color:#ae81ff\"\u003eReadWriteOnce\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e  \u003cspan style=\"color:#f92672\"\u003estorageClassName\u003c/span\u003e: \u003cspan style=\"color:#ae81ff\"\u003eebme-storage\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e  \u003cspan style=\"color:#f92672\"\u003eresources\u003c/span\u003e:\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    \u003cspan style=\"color:#f92672\"\u003erequests\u003c/span\u003e:\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e      \u003cspan style=\"color:#f92672\"\u003estorage\u003c/span\u003e: \u003cspan style=\"color:#ae81ff\"\u003e30Gi\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"jenkins-service-account-생성-optional\"\u003eJenkins Service Account 생성 (Optional)\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-yaml\" data-lang=\"yaml\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# jenkins-service-account.yaml\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# In GKE need to get RBAC permissions first with\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# kubectl create clusterrolebinding cluster-admin-binding --clusterrole=cluster-admin [--user=\u0026lt;user-name\u0026gt;|--group=\u0026lt;group-name\u0026gt;]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e---\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#f92672\"\u003eapiVersion\u003c/span\u003e: \u003cspan style=\"color:#ae81ff\"\u003ev1\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#f92672\"\u003ekind\u003c/span\u003e: \u003cspan style=\"color:#ae81ff\"\u003eServiceAccount\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#f92672\"\u003emetadata\u003c/span\u003e:\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e  \u003cspan style=\"color:#f92672\"\u003ename\u003c/span\u003e: \u003cspan style=\"color:#ae81ff\"\u003ejenkins\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e---\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#f92672\"\u003ekind\u003c/span\u003e: \u003cspan style=\"color:#ae81ff\"\u003eRole\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#f92672\"\u003eapiVersion\u003c/span\u003e: \u003cspan style=\"color:#ae81ff\"\u003erbac.authorization.k8s.io/v1\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#f92672\"\u003emetadata\u003c/span\u003e:\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e  \u003cspan style=\"color:#f92672\"\u003ename\u003c/span\u003e: \u003cspan style=\"color:#ae81ff\"\u003ejenkins\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#f92672\"\u003erules\u003c/span\u003e:\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e- \u003cspan style=\"color:#f92672\"\u003eapiGroups\u003c/span\u003e: [\u003cspan style=\"color:#e6db74\"\u003e\u0026#34;\u0026#34;\u003c/span\u003e]\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e  \u003cspan style=\"color:#f92672\"\u003eresources\u003c/span\u003e: [\u003cspan style=\"color:#e6db74\"\u003e\u0026#34;pods\u0026#34;\u003c/span\u003e]\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e  \u003cspan style=\"color:#f92672\"\u003everbs\u003c/span\u003e: [\u003cspan style=\"color:#e6db74\"\u003e\u0026#34;create\u0026#34;\u003c/span\u003e,\u003cspan style=\"color:#e6db74\"\u003e\u0026#34;delete\u0026#34;\u003c/span\u003e,\u003cspan style=\"color:#e6db74\"\u003e\u0026#34;get\u0026#34;\u003c/span\u003e,\u003cspan style=\"color:#e6db74\"\u003e\u0026#34;list\u0026#34;\u003c/span\u003e,\u003cspan style=\"color:#e6db74\"\u003e\u0026#34;patch\u0026#34;\u003c/span\u003e,\u003cspan style=\"color:#e6db74\"\u003e\u0026#34;update\u0026#34;\u003c/span\u003e,\u003cspan style=\"color:#e6db74\"\u003e\u0026#34;watch\u0026#34;\u003c/span\u003e]\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e- \u003cspan style=\"color:#f92672\"\u003eapiGroups\u003c/span\u003e: [\u003cspan style=\"color:#e6db74\"\u003e\u0026#34;\u0026#34;\u003c/span\u003e]\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e  \u003cspan style=\"color:#f92672\"\u003eresources\u003c/span\u003e: [\u003cspan style=\"color:#e6db74\"\u003e\u0026#34;pods/exec\u0026#34;\u003c/span\u003e]\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e  \u003cspan style=\"color:#f92672\"\u003everbs\u003c/span\u003e: [\u003cspan style=\"color:#e6db74\"\u003e\u0026#34;create\u0026#34;\u003c/span\u003e,\u003cspan style=\"color:#e6db74\"\u003e\u0026#34;delete\u0026#34;\u003c/span\u003e,\u003cspan style=\"color:#e6db74\"\u003e\u0026#34;get\u0026#34;\u003c/span\u003e,\u003cspan style=\"color:#e6db74\"\u003e\u0026#34;list\u0026#34;\u003c/span\u003e,\u003cspan style=\"color:#e6db74\"\u003e\u0026#34;patch\u0026#34;\u003c/span\u003e,\u003cspan style=\"color:#e6db74\"\u003e\u0026#34;update\u0026#34;\u003c/span\u003e,\u003cspan style=\"color:#e6db74\"\u003e\u0026#34;watch\u0026#34;\u003c/span\u003e]\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e- \u003cspan style=\"color:#f92672\"\u003eapiGroups\u003c/span\u003e: [\u003cspan style=\"color:#e6db74\"\u003e\u0026#34;\u0026#34;\u003c/span\u003e]\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e  \u003cspan style=\"color:#f92672\"\u003eresources\u003c/span\u003e: [\u003cspan style=\"color:#e6db74\"\u003e\u0026#34;pods/log\u0026#34;\u003c/span\u003e]\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e  \u003cspan style=\"color:#f92672\"\u003everbs\u003c/span\u003e: [\u003cspan style=\"color:#e6db74\"\u003e\u0026#34;get\u0026#34;\u003c/span\u003e,\u003cspan style=\"color:#e6db74\"\u003e\u0026#34;list\u0026#34;\u003c/span\u003e,\u003cspan style=\"color:#e6db74\"\u003e\u0026#34;watch\u0026#34;\u003c/span\u003e]\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e- \u003cspan style=\"color:#f92672\"\u003eapiGroups\u003c/span\u003e: [\u003cspan style=\"color:#e6db74\"\u003e\u0026#34;\u0026#34;\u003c/span\u003e]\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e  \u003cspan style=\"color:#f92672\"\u003eresources\u003c/span\u003e: [\u003cspan style=\"color:#e6db74\"\u003e\u0026#34;events\u0026#34;\u003c/span\u003e]\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e  \u003cspan style=\"color:#f92672\"\u003everbs\u003c/span\u003e: [\u003cspan style=\"color:#e6db74\"\u003e\u0026#34;watch\u0026#34;\u003c/span\u003e]\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e- \u003cspan style=\"color:#f92672\"\u003eapiGroups\u003c/span\u003e: [\u003cspan style=\"color:#e6db74\"\u003e\u0026#34;\u0026#34;\u003c/span\u003e]\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e  \u003cspan style=\"color:#f92672\"\u003eresources\u003c/span\u003e: [\u003cspan style=\"color:#e6db74\"\u003e\u0026#34;secrets\u0026#34;\u003c/span\u003e]\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e  \u003cspan style=\"color:#f92672\"\u003everbs\u003c/span\u003e: [\u003cspan style=\"color:#e6db74\"\u003e\u0026#34;get\u0026#34;\u003c/span\u003e]\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e---\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#f92672\"\u003eapiVersion\u003c/span\u003e: \u003cspan style=\"color:#ae81ff\"\u003erbac.authorization.k8s.io/v1\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#f92672\"\u003ekind\u003c/span\u003e: \u003cspan style=\"color:#ae81ff\"\u003eRoleBinding\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#f92672\"\u003emetadata\u003c/span\u003e:\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e  \u003cspan style=\"color:#f92672\"\u003ename\u003c/span\u003e: \u003cspan style=\"color:#ae81ff\"\u003ejenkins\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#f92672\"\u003eroleRef\u003c/span\u003e:\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e  \u003cspan style=\"color:#f92672\"\u003eapiGroup\u003c/span\u003e: \u003cspan style=\"color:#ae81ff\"\u003erbac.authorization.k8s.io\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e  \u003cspan style=\"color:#f92672\"\u003ekind\u003c/span\u003e: \u003cspan style=\"color:#ae81ff\"\u003eRole\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e  \u003cspan style=\"color:#f92672\"\u003ename\u003c/span\u003e: \u003cspan style=\"color:#ae81ff\"\u003ejenkins\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#f92672\"\u003esubjects\u003c/span\u003e:\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e- \u003cspan style=\"color:#f92672\"\u003ekind\u003c/span\u003e: \u003cspan style=\"color:#ae81ff\"\u003eServiceAccount\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e  \u003cspan style=\"color:#f92672\"\u003ename\u003c/span\u003e: \u003cspan style=\"color:#ae81ff\"\u003ejenkins\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"jenkins-valuesyaml-생성-optional\"\u003eJenkins values.yaml 생성 (Optional)\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003eJenkins 에서 제공하는 기본 템플릿 \u003ca href=\"https://raw.githubusercontent.com/jenkinsci/helm-charts/main/charts/jenkins/values.yaml\"\u003evalue.yaml\u003c/a\u003e 에서 필요한 부분만 수정\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-yaml\" data-lang=\"yaml\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# jenkins-values.yaml\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# persistence 부분을 아래와 같이 수정\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#f92672\"\u003epersistence\u003c/span\u003e:\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e  \u003cspan style=\"color:#f92672\"\u003eenabled\u003c/span\u003e: \u003cspan style=\"color:#66d9ef\"\u003etrue\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e  \u003cspan style=\"color:#f92672\"\u003eexistingClaim\u003c/span\u003e: \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;jenkins-pvc\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e  \u003cspan style=\"color:#f92672\"\u003estorageClass\u003c/span\u003e: \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;ebme-storage\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e  \u003cspan style=\"color:#f92672\"\u003eaccessMode\u003c/span\u003e: \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;ReadWriteOnce\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e  \u003cspan style=\"color:#f92672\"\u003esize\u003c/span\u003e: \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;30Gi\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003chr\u003e\n\u003ch2 id=\"helm을-사용한-젠킨스-설치\"\u003eHelm을 사용한 젠킨스 설치\u003c/h2\u003e\n\u003ch3 id=\"jenkins-repository-추가\"\u003eJenkins Repository 추가\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ehelm repo add jenkinsci https://charts.jenkins.io\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ehelm repo update\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"jenkins-설치\"\u003eJenkins 설치\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 기본 설정대로 설치\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ehelm install -n jenkins jenkins jenkinsci/jenkins\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 기존 작성한 jenkins-values.yaml 을 사용하여 설치\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ehelm install -n jenkins jenkins jenkinsci/jenkins -f jenkins-values.yaml\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"jenkins-service-expose\"\u003eJenkins Service expose\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003eNodePort 로 Service 를 expose 하여 접속 가능하도록 설정\u003c/li\u003e\n\u003cli\u003e해당 주소로 Jenkins 접속 확인\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ekubectl expose svc jenkins -n jenkins --type\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003eNodePort --name\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003ejenkins\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cul\u003e\n\u003cli\u003eJenkins 비밀번호 확인\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ekubectl exec --namespace jenkins -it svc/jenkins -c jenkins -- /bin/cat /run/secrets/chart-admin-password \u003cspan style=\"color:#f92672\"\u003e\u0026amp;\u0026amp;\u003c/span\u003e echo\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e","title":"Kubernetes 환경에서 Jenkins 설치 및 기본 설정 가이드"},{"content":"kube-prometheus 사용한 프로메테우스 설치 쿠버네티스에 프로메테우스와 그라파나 설정을 위한 오픈 소스 프로젝트\nkube-prometheus 설치 kube-prometheus 레포지토리를 클론\n빠른 설정\n# 설정파일을 통한 빠른 설정 kubectl apply --server-side -f manifests/setup kubectl wait \\ --for condition=Established \\ --all CustomResourceDefinition \\ --namespace=monitoring kubectl apply -f manifests/ 설정 삭제 하기 kubectl delete --ignore-not-found=true -f manifests/ -f manifests/setup grafana svc 설정 grafana svc 노출 설정 # grafana svc 노출 설정 # type: NodePort 로 변경 kubectl -n monitoring edit svc grafana 노출된 IP로 접속하여 로그인 화면이 나오면 설정 완료 기본 아이디/비밀번호는 admin/admin 로그 수집을 위한 Loki 설정 Loki 설치 Helm 을 통해 설치 helm repo add grafana https://grafana.github.io/helm-charts helm repo update loki-stack 설치 loki-stack 설치 스크립트 다운로드 helm show values grafana/loki-stack \u0026gt; /tmp/loki-stack-values.yaml Loki, Promtail 부분을 제외하고 모두 삭제 loki: enabled: true persistence: enabled: true size: 10Gi promtail: enabled: true loki-stack 설치 helm install loki-stack grafana/loki-stack --values /tmp/loki-stack-values.yaml -n monitoring loki-stack 삭제 helm uninstall loki-stack -n monitoring 그라파나 Loki 데이터 소스 설정 그라파나 접속 후 데이터 소스 설정 설정 \u0026gt; Data source \u0026gt; Add new data source \u0026gt; Loki 선택 Loki server URL 설정 URL을 http://loki-stack:3100 으로 설정 로그 확인 왼쪽 메뉴 \u0026gt; Explore를 클릭한후 DataSource를 Loki로 선택 Log browser 버튼을 눌러 선택하거나 직접 입력 참고 Loki 설치 페이지 쿠버네티스 로깅 Promtail, Loki 설치및 테스트 blog ","permalink":"https://wkqco33.github.io/wkqcosoft-docs/posts/devops/monitoring/","summary":"\u003ch2 id=\"kube-prometheus-사용한-프로메테우스-설치\"\u003ekube-prometheus 사용한 프로메테우스 설치\u003c/h2\u003e\n\u003cp\u003e쿠버네티스에 프로메테우스와 그라파나 설정을 위한 오픈 소스 프로젝트\u003c/p\u003e\n\u003ch3 id=\"kube-prometheus-설치\"\u003ekube-prometheus 설치\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ca href=\"https://github.com/prometheus-operator/kube-prometheus\"\u003ekube-prometheus\u003c/a\u003e 레포지토리를 클론\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e빠른 설정\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# 설정파일을 통한 빠른 설정\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ekubectl apply --server-side -f manifests/setup\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ekubectl wait \u003cspan style=\"color:#ae81ff\"\u003e\\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#ae81ff\"\u003e\u003c/span\u003e --for condition\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003eEstablished \u003cspan style=\"color:#ae81ff\"\u003e\\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#ae81ff\"\u003e\u003c/span\u003e --all CustomResourceDefinition \u003cspan style=\"color:#ae81ff\"\u003e\\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#ae81ff\"\u003e\u003c/span\u003e --namespace\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003emonitoring\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ekubectl apply -f manifests/\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cul\u003e\n\u003cli\u003e설정 삭제 하기\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ekubectl delete --ignore-not-found\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003etrue -f manifests/ -f manifests/setup\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"grafana-svc-설정\"\u003egrafana svc 설정\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003egrafana svc 노출 설정\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# grafana svc 노출 설정\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# type: NodePort 로 변경\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ekubectl -n monitoring edit svc grafana\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cul\u003e\n\u003cli\u003e노출된 IP로 접속하여 로그인 화면이 나오면 설정 완료\u003c/li\u003e\n\u003cli\u003e기본 아이디/비밀번호는 admin/admin\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e\u003cimg alt=\"login\" loading=\"lazy\" src=\"/wkqcosoft-docs/posts/devops/monitoring/grafana_login.jpeg\"\u003e\u003c/p\u003e","title":"Kubernetes Prometheus \u0026 Grafana Loki 모니터링 시스템 구축"},{"content":"Foxglove ROS2 Visualization Tool 1. Foxglove Studio Foxglove는 ROS2 시뮬레이션 시각화를 위한 도구 3D, Map, Plot, Image 등 다양한 시각화 기능을 제공 참고: \u0026ldquo;Foxglove Studio\u0026quot;는 2024년 2월 마지막 오픈소스 릴리즈(v1.87.0)를 끝으로 개발이 중단되었고, 이후 제품이 \u0026ldquo;Foxglove\u0026quot;로 리브랜딩되어 로봇 데이터 수집/관리까지 포괄하는 상용 플랫폼으로 확장됨. 아래 설치 방법은 과거 오픈소스 Studio 기준이며, 최신 버전은 foxglove.dev 에서 확인 필요 1. Installation 1.1. Desktop App Foxglove Download에서 OS에 맞는 설치파일을 다운로드 설치파일을 실행하여 설치 1.2. Web(Docker) 과거 오픈소스 Studio는 Docker image로 Self Hosting 가능했으나, 현재는 유지보수되지 않으므로 최신 버전이 필요하면 Desktop App 또는 studio.foxglove.dev 사용 권장 # docker run docker run --rm -p \u0026#34;8080:8080\u0026#34; ghcr.io/foxglove/studio:latest 2. Usage Desktop Foxglove Studio를 실행하거나 Web localhost:8080에 접속 Open connection을 클릭하여 foxglove bridge를 통해 연결 ws 주소를 입력한 뒤 Open 버튼을 클릭하여 연결 2. ros foxglove bridge Foxglove Studio에서 ROS2 연결을 위한 ros foxglove bridge 제공 ros foxglove bridge에서 제공하는 오픈소스 도구 ROS2와 Foxglove Studio를 연결하기 위한 bridge 역할을 함 해당 소스를 빌드하여 사용하거나 docker image를 사용하여 실행 가능 2.1. Source Build # Install ros foxglove bridge cd \u0026lt;path/to/your/ros_ws\u0026gt; git clone https://github.com/foxglove/ros-foxglove-bridge.git src/ros-foxglove-bridge rosdep update rosdep install --ignore-src --default-yes --from-path src # Build ros foxglove bridge colcon build --event-handlers console_direct+ --symlink-install source install/local_setup.bash ros2 launch foxglove_bridge foxglove_bridge_launch.xml 2.1.1. Run # Run ros2 foxglove bridge ros2 launch foxglove_bridge foxglove_bridge_launch.xml port:=8765 2.2. Docker 2.2.1. 직접 Docker Build 소스에 있는 Dockerfile을 사용하여 docker image를 빌드\n# Build docker docker build -t foxglove-bridge:latest -f Dockerfile.ros2 . 2.2.2. 기존 Docker Image 사용 # Pull docker image docker pull ghcr.io/foxglove/humble-ros2-bridge:latest 2.2.3. Run Script # Run docker container export ROS_DOMAIN_ID=118 export DOCKER_BRIDGE=my-bridge export BRIDGE_PORT=8765 export DOCKER_NAME=foxglove_bridge export ROBOT_NAME=myrobot docker run -itd \\ --name $DOCKER_NAME \\ --net $DOCKER_BRIDGE \\ --env ROBOT_NAME=$ROBOT_NAME \\ --env ROS_DOMAIN_ID=$ROS_DOMAIN_ID \\ -p $BRIDGE_PORT:$BRIDGE_PORT \\ ghcr.io/foxglove/humble-ros2-bridge:latest 3. Reference Foxglove Studio ros foxglove bridge ros foxglove bridge docker ","permalink":"https://wkqco33.github.io/wkqcosoft-docs/posts/foxglove/","summary":"\u003ch2 id=\"foxglove-ros2-visualization-tool\"\u003eFoxglove ROS2 Visualization Tool\u003c/h2\u003e\n\u003ch3 id=\"1-foxglove-studio\"\u003e1. Foxglove Studio\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003eFoxglove는 ROS2 시뮬레이션 시각화를 위한 도구\u003c/li\u003e\n\u003cli\u003e3D, Map, Plot, Image 등 다양한 시각화 기능을 제공\u003c/li\u003e\n\u003cli\u003e참고: \u0026ldquo;Foxglove Studio\u0026quot;는 2024년 2월 마지막 오픈소스 릴리즈(v1.87.0)를 끝으로 개발이 중단되었고, 이후 제품이 \u0026ldquo;Foxglove\u0026quot;로 리브랜딩되어 로봇 데이터 수집/관리까지 포괄하는 상용 플랫폼으로 확장됨. 아래 설치 방법은 과거 오픈소스 Studio 기준이며, 최신 버전은 \u003ca href=\"https://foxglove.dev/\"\u003efoxglove.dev\u003c/a\u003e 에서 확인 필요\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch4 id=\"1-installation\"\u003e1. Installation\u003c/h4\u003e\n\u003ch5 id=\"11-desktop-app\"\u003e1.1. Desktop App\u003c/h5\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"https://foxglove.dev/download\"\u003eFoxglove Download\u003c/a\u003e에서 OS에 맞는 설치파일을 다운로드\u003c/li\u003e\n\u003cli\u003e설치파일을 실행하여 설치\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch5 id=\"12-webdocker\"\u003e1.2. Web(Docker)\u003c/h5\u003e\n\u003cul\u003e\n\u003cli\u003e과거 오픈소스 Studio는 Docker image로 Self Hosting 가능했으나, 현재는 유지보수되지 않으므로 최신 버전이 필요하면 Desktop App 또는 \u003ca href=\"https://studio.foxglove.dev\"\u003estudio.foxglove.dev\u003c/a\u003e 사용 권장\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# docker run\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edocker run --rm -p \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;8080:8080\u0026#34;\u003c/span\u003e ghcr.io/foxglove/studio:latest\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch4 id=\"2-usage\"\u003e2. Usage\u003c/h4\u003e\n\u003cul\u003e\n\u003cli\u003eDesktop Foxglove Studio를 실행하거나 Web \u003ccode\u003elocalhost:8080\u003c/code\u003e에 접속\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eOpen connection\u003c/code\u003e을 클릭하여 foxglove bridge를 통해 연결\u003c/li\u003e\n\u003cli\u003ews 주소를 입력한 뒤 \u003ccode\u003eOpen\u003c/code\u003e 버튼을 클릭하여 연결\u003c/li\u003e\n\u003c/ul\u003e\n\u003chr\u003e\n\u003ch3 id=\"2-ros-foxglove-bridge\"\u003e2. ros foxglove bridge\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003eFoxglove Studio에서 ROS2 연결을 위한 ros foxglove bridge 제공\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://github.com/foxglove/ros-foxglove-bridge/\"\u003eros foxglove bridge\u003c/a\u003e에서 제공하는 오픈소스 도구\u003c/li\u003e\n\u003cli\u003eROS2와 Foxglove Studio를 연결하기 위한 bridge 역할을 함\u003c/li\u003e\n\u003cli\u003e해당 소스를 빌드하여 사용하거나 docker image를 사용하여 실행 가능\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch4 id=\"21-source-build\"\u003e2.1. Source Build\u003c/h4\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# Install ros foxglove bridge\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ecd \u0026lt;path/to/your/ros_ws\u0026gt;\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003egit clone https://github.com/foxglove/ros-foxglove-bridge.git src/ros-foxglove-bridge\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003erosdep update\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003erosdep install --ignore-src --default-yes --from-path src\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# Build ros foxglove bridge\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ecolcon build --event-handlers console_direct+ --symlink-install\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003esource install/local_setup.bash\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eros2 launch foxglove_bridge foxglove_bridge_launch.xml\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch5 id=\"211-run\"\u003e2.1.1. Run\u003c/h5\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# Run ros2 foxglove bridge\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eros2 launch foxglove_bridge foxglove_bridge_launch.xml port:\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e\u003cspan style=\"color:#ae81ff\"\u003e8765\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch4 id=\"22-docker\"\u003e2.2. Docker\u003c/h4\u003e\n\u003ch5 id=\"221-직접-docker-build\"\u003e2.2.1. 직접 Docker Build\u003c/h5\u003e\n\u003cp\u003e소스에 있는 Dockerfile을 사용하여 docker image를 빌드\u003c/p\u003e","title":"Foxglove Studio를 활용한 ROS2 데이터 시각화 시뮬레이션 가이드"},{"content":"1. Modern DevOps 로드맵 개요 현대의 DevOps 엔지니어링은 단순히 개발과 운영을 연결하는 것에 그치지 않고, 소프트웨어 전달 속도(Velocity) 최적화, 안정성(Reliability) 확보, **인프라의 코드화(IaC)**를 핵심 목표로 삼습니다.\n[ [ [ [ C C O I o I b a n / s C t C e a D r \u0026amp; i v n \u0026amp; a A e b u r G i t i l o \u0026amp; t i m O t a K p y t 8 s ] i s ] o ] n ] M D G P T o o i r e d c t o r e k H m r r e u e a n r b t f h o D / A e r e c u m v K t s O 3 i p s o s n A / s G n S r s t M / a i a i f b c c J a l k r e n e o n a K k 8 i / s n s L k i A r g o C D 2. 영역별 핵심 도구 및 베스트 프랙티스 ① Container \u0026amp; Orchestration (컨테이너 패러다임) 애플리케이션을 호스트 환경과 격리하여 어디서나 동일하게 실행할 수 있는 표준 패키징 기술입니다.\nDocker / Buildx: 애플리케이션 이미지 빌드 및 멀티 아키텍처(x86_64, arm64) 빌드 표준. K3s / MicroK8s: 경량화된 쿠버네티스 배포판으로 로컬 개발 및 에지(Edge) 환경 구축에 적합. Containerd / CRI-O: 쿠버네티스 하단에서 컨테이너 런타임 표준 담당. ② CI/CD \u0026amp; GitOps (지속적 통합 및 배포) 소프트웨어 변경 사항을 자동 테스트하고 클러스터에 안전하게 반영하는 체계입니다.\nGitHub Actions: 코드 저장소와 밀접하게 연관된 현대적 CI/CD 파이프라인 구축. Jenkins: 복잡한 빌드/배포 스크립트 및 온프레미스 에이전트 인프라 제어. ArgoCD: Git 저장소의 상태를 쿠버네티스 클러스터와 동일하게 자동 동기화하는 선언적 GitOps 도구. ③ Observability (가시성 및 모니터링) 시스템의 내부 상태를 외부 출력 메트릭, 로그, 트레이스로 파악하는 3대 기둥(Pillars of Observability)입니다.\nMetrics (Prometheus + Grafana): 시계열 데이터를 수집하고 다채로운 대시보드로 시각화. Logs (Grafana Loki / ELK): 클러스터 내 모든 컨테이너 로그를 중앙 집중식으로 검색 및 분석. System Utilities: htop (프로세스 모니터링), fio (디스크 I/O 벤치마크), ab/molotov (부하 테스트). ④ IaC (Infrastructure as Code) \u0026amp; Automation 인프라 구성 요소(VM, 네트워크, K8s 매니페스트)를 코드로 작성하고 관리합니다.\nTerraform: 멀티 클라우드(AWS, GCP, Azure) 및 K8s 리소스를 코드 기반 선언적 프로비저닝. Ansible: 에이전트리스 방식으로 서버 설정 및 소프트웨어 설치 자동화. 3. DevOps 핵심 CLI 실무 유틸리티 모음 K8s 관리: kubectl, kubectx, kubens, k9s (터미널 기반 UI) 네트워크 진단: curl, netcat(nc), tcpdump, traceroute 로그 및 디바이스 진단: journalctl, dmesg, lsblk, df -h ","permalink":"https://wkqco33.github.io/wkqcosoft-docs/posts/devops/devops_note/","summary":"\u003ch2 id=\"1-modern-devops-로드맵-개요\"\u003e1. Modern DevOps 로드맵 개요\u003c/h2\u003e\n\u003cp\u003e현대의 DevOps 엔지니어링은 단순히 개발과 운영을 연결하는 것에 그치지 않고, \u003cstrong\u003e소프트웨어 전달 속도(Velocity) 최적화\u003c/strong\u003e, \u003cstrong\u003e안정성(Reliability) 확보\u003c/strong\u003e, **인프라의 코드화(IaC)**를 핵심 목표로 삼습니다.\u003c/p\u003e\n\n\n\n\u003cdiv class=\"goat svg-container \"\u003e\n  \n    \u003csvg\n      xmlns=\"http://www.w3.org/2000/svg\"\n      font-family=\"Menlo,Lucida Console,monospace\"\n      \n        viewBox=\"0 0 592 137\"\n      \u003e\n      \u003cg transform='translate(8,16)'\u003e\n\u003cpath d='M 0,0 L 576,0' fill='none' stroke='currentColor'\u003e\u003c/path\u003e\n\u003cpath d='M 0,32 L 576,32' fill='none' stroke='currentColor'\u003e\u003c/path\u003e\n\u003cpath d='M 176,48 L 184,48' fill='none' stroke='currentColor'\u003e\u003c/path\u003e\n\u003cpath d='M 176,64 L 184,64' fill='none' stroke='currentColor'\u003e\u003c/path\u003e\n\u003cpath d='M 176,80 L 184,80' fill='none' stroke='currentColor'\u003e\u003c/path\u003e\n\u003cpath d='M 176,96 L 184,96' fill='none' stroke='currentColor'\u003e\u003c/path\u003e\n\u003cpath d='M 0,112 L 576,112' fill='none' stroke='currentColor'\u003e\u003c/path\u003e\n\u003cpath d='M 0,0 L 0,32' fill='none' stroke='currentColor'\u003e\u003c/path\u003e\n\u003cpath d='M 0,32 L 0,112' fill='none' stroke='currentColor'\u003e\u003c/path\u003e\n\u003cpath d='M 576,0 L 576,32' fill='none' stroke='currentColor'\u003e\u003c/path\u003e\n\u003cpath d='M 576,32 L 576,112' fill='none' stroke='currentColor'\u003e\u003c/path\u003e\n\u003cpath d='M 288,96 L 296,80' fill='none' stroke='currentColor'\u003e\u003c/path\u003e\n\u003cpath d='M 400,80 L 408,64' fill='none' stroke='currentColor'\u003e\u003c/path\u003e\n\u003cpolygon points='192.000000,48.000000 180.000000,42.400002 180.000000,53.599998' fill='currentColor' transform='rotate(0.000000, 184.000000, 48.000000)'\u003e\u003c/polygon\u003e\n\u003cpolygon points='192.000000,64.000000 180.000000,58.400002 180.000000,69.599998' fill='currentColor' transform='rotate(0.000000, 184.000000, 64.000000)'\u003e\u003c/polygon\u003e\n\u003cpolygon points='192.000000,80.000000 180.000000,74.400002 180.000000,85.599998' fill='currentColor' transform='rotate(0.000000, 184.000000, 80.000000)'\u003e\u003c/polygon\u003e\n\u003cpolygon points='192.000000,96.000000 180.000000,90.400002 180.000000,101.599998' fill='currentColor' transform='rotate(0.000000, 184.000000, 96.000000)'\u003e\u003c/polygon\u003e\n\u003ccircle cx='400' cy='80' r='6' stroke='currentColor' fill='#fff'\u003e\u003c/circle\u003e\n\u003ctext text-anchor='middle' x='24' y='52' fill='currentColor' style='font-size:1em'\u003e[\u003c/text\u003e\n\u003ctext text-anchor='middle' x='24' y='68' fill='currentColor' style='font-size:1em'\u003e[\u003c/text\u003e\n\u003ctext text-anchor='middle' x='24' y='84' fill='currentColor' style='font-size:1em'\u003e[\u003c/text\u003e\n\u003ctext text-anchor='middle' x='24' y='100' fill='currentColor' style='font-size:1em'\u003e[\u003c/text\u003e\n\u003ctext text-anchor='middle' x='32' y='52' fill='currentColor' style='font-size:1em'\u003eC\u003c/text\u003e\n\u003ctext text-anchor='middle' x='32' y='68' fill='currentColor' style='font-size:1em'\u003eC\u003c/text\u003e\n\u003ctext text-anchor='middle' x='32' y='84' fill='currentColor' style='font-size:1em'\u003eO\u003c/text\u003e\n\u003ctext text-anchor='middle' x='32' y='100' fill='currentColor' style='font-size:1em'\u003eI\u003c/text\u003e\n\u003ctext text-anchor='middle' x='40' y='52' fill='currentColor' style='font-size:1em'\u003eo\u003c/text\u003e\n\u003ctext text-anchor='middle' x='40' y='68' fill='currentColor' style='font-size:1em'\u003eI\u003c/text\u003e\n\u003ctext text-anchor='middle' x='40' y='84' fill='currentColor' style='font-size:1em'\u003eb\u003c/text\u003e\n\u003ctext text-anchor='middle' x='40' y='100' fill='currentColor' style='font-size:1em'\u003ea\u003c/text\u003e\n\u003ctext text-anchor='middle' x='48' y='52' fill='currentColor' style='font-size:1em'\u003en\u003c/text\u003e\n\u003ctext text-anchor='middle' x='48' y='68' fill='currentColor' style='font-size:1em'\u003e/\u003c/text\u003e\n\u003ctext text-anchor='middle' x='48' y='84' fill='currentColor' style='font-size:1em'\u003es\u003c/text\u003e\n\u003ctext text-anchor='middle' x='48' y='100' fill='currentColor' style='font-size:1em'\u003eC\u003c/text\u003e\n\u003ctext text-anchor='middle' x='56' y='52' fill='currentColor' style='font-size:1em'\u003et\u003c/text\u003e\n\u003ctext text-anchor='middle' x='56' y='68' fill='currentColor' style='font-size:1em'\u003eC\u003c/text\u003e\n\u003ctext text-anchor='middle' x='56' y='84' fill='currentColor' style='font-size:1em'\u003ee\u003c/text\u003e\n\u003ctext text-anchor='middle' x='64' y='52' fill='currentColor' style='font-size:1em'\u003ea\u003c/text\u003e\n\u003ctext text-anchor='middle' x='64' y='68' fill='currentColor' style='font-size:1em'\u003eD\u003c/text\u003e\n\u003ctext text-anchor='middle' x='64' y='84' fill='currentColor' style='font-size:1em'\u003er\u003c/text\u003e\n\u003ctext text-anchor='middle' x='64' y='100' fill='currentColor' style='font-size:1em'\u003e\u0026amp;\u003c/text\u003e\n\u003ctext text-anchor='middle' x='72' y='52' fill='currentColor' style='font-size:1em'\u003ei\u003c/text\u003e\n\u003ctext text-anchor='middle' x='72' y='84' fill='currentColor' style='font-size:1em'\u003ev\u003c/text\u003e\n\u003ctext text-anchor='middle' x='80' y='52' fill='currentColor' style='font-size:1em'\u003en\u003c/text\u003e\n\u003ctext text-anchor='middle' x='80' y='68' fill='currentColor' style='font-size:1em'\u003e\u0026amp;\u003c/text\u003e\n\u003ctext text-anchor='middle' x='80' y='84' fill='currentColor' style='font-size:1em'\u003ea\u003c/text\u003e\n\u003ctext text-anchor='middle' x='80' y='100' fill='currentColor' style='font-size:1em'\u003eA\u003c/text\u003e\n\u003ctext text-anchor='middle' x='88' y='52' fill='currentColor' style='font-size:1em'\u003ee\u003c/text\u003e\n\u003ctext text-anchor='middle' x='88' y='84' fill='currentColor' style='font-size:1em'\u003eb\u003c/text\u003e\n\u003ctext text-anchor='middle' x='88' y='100' fill='currentColor' style='font-size:1em'\u003eu\u003c/text\u003e\n\u003ctext text-anchor='middle' x='96' y='52' fill='currentColor' style='font-size:1em'\u003er\u003c/text\u003e\n\u003ctext text-anchor='middle' x='96' y='68' fill='currentColor' style='font-size:1em'\u003eG\u003c/text\u003e\n\u003ctext text-anchor='middle' x='96' y='84' fill='currentColor' style='font-size:1em'\u003ei\u003c/text\u003e\n\u003ctext text-anchor='middle' x='96' y='100' fill='currentColor' style='font-size:1em'\u003et\u003c/text\u003e\n\u003ctext text-anchor='middle' x='104' y='68' fill='currentColor' style='font-size:1em'\u003ei\u003c/text\u003e\n\u003ctext text-anchor='middle' x='104' y='84' fill='currentColor' style='font-size:1em'\u003el\u003c/text\u003e\n\u003ctext text-anchor='middle' x='104' y='100' fill='currentColor' style='font-size:1em'\u003eo\u003c/text\u003e\n\u003ctext text-anchor='middle' x='112' y='52' fill='currentColor' style='font-size:1em'\u003e\u0026amp;\u003c/text\u003e\n\u003ctext text-anchor='middle' x='112' y='68' fill='currentColor' style='font-size:1em'\u003et\u003c/text\u003e\n\u003ctext text-anchor='middle' x='112' y='84' fill='currentColor' style='font-size:1em'\u003ei\u003c/text\u003e\n\u003ctext text-anchor='middle' x='112' y='100' fill='currentColor' style='font-size:1em'\u003em\u003c/text\u003e\n\u003ctext text-anchor='middle' x='120' y='68' fill='currentColor' style='font-size:1em'\u003eO\u003c/text\u003e\n\u003ctext text-anchor='middle' x='120' y='84' fill='currentColor' style='font-size:1em'\u003et\u003c/text\u003e\n\u003ctext text-anchor='middle' x='120' y='100' fill='currentColor' style='font-size:1em'\u003ea\u003c/text\u003e\n\u003ctext text-anchor='middle' x='128' y='52' fill='currentColor' style='font-size:1em'\u003eK\u003c/text\u003e\n\u003ctext text-anchor='middle' x='128' y='68' fill='currentColor' style='font-size:1em'\u003ep\u003c/text\u003e\n\u003ctext text-anchor='middle' x='128' y='84' fill='currentColor' style='font-size:1em'\u003ey\u003c/text\u003e\n\u003ctext text-anchor='middle' x='128' y='100' fill='currentColor' style='font-size:1em'\u003et\u003c/text\u003e\n\u003ctext text-anchor='middle' x='136' y='52' fill='currentColor' style='font-size:1em'\u003e8\u003c/text\u003e\n\u003ctext text-anchor='middle' x='136' y='68' fill='currentColor' style='font-size:1em'\u003es\u003c/text\u003e\n\u003ctext text-anchor='middle' x='136' y='84' fill='currentColor' style='font-size:1em'\u003e]\u003c/text\u003e\n\u003ctext text-anchor='middle' x='136' y='100' fill='currentColor' style='font-size:1em'\u003ei\u003c/text\u003e\n\u003ctext text-anchor='middle' x='144' y='52' fill='currentColor' style='font-size:1em'\u003es\u003c/text\u003e\n\u003ctext text-anchor='middle' x='144' y='68' fill='currentColor' style='font-size:1em'\u003e]\u003c/text\u003e\n\u003ctext text-anchor='middle' x='144' y='100' fill='currentColor' style='font-size:1em'\u003eo\u003c/text\u003e\n\u003ctext text-anchor='middle' x='152' y='52' fill='currentColor' style='font-size:1em'\u003e]\u003c/text\u003e\n\u003ctext text-anchor='middle' x='152' y='100' fill='currentColor' style='font-size:1em'\u003en\u003c/text\u003e\n\u003ctext text-anchor='middle' x='160' y='100' fill='currentColor' style='font-size:1em'\u003e]\u003c/text\u003e\n\u003ctext text-anchor='middle' x='208' y='20' fill='currentColor' style='font-size:1em'\u003eM\u003c/text\u003e\n\u003ctext text-anchor='middle' x='208' y='52' fill='currentColor' style='font-size:1em'\u003eD\u003c/text\u003e\n\u003ctext text-anchor='middle' x='208' y='68' fill='currentColor' style='font-size:1em'\u003eG\u003c/text\u003e\n\u003ctext text-anchor='middle' x='208' y='84' fill='currentColor' style='font-size:1em'\u003eP\u003c/text\u003e\n\u003ctext text-anchor='middle' x='208' y='100' fill='currentColor' style='font-size:1em'\u003eT\u003c/text\u003e\n\u003ctext text-anchor='middle' x='216' y='20' fill='currentColor' style='font-size:1em'\u003eo\u003c/text\u003e\n\u003ctext text-anchor='middle' x='216' y='52' fill='currentColor' style='font-size:1em'\u003eo\u003c/text\u003e\n\u003ctext text-anchor='middle' x='216' y='68' fill='currentColor' style='font-size:1em'\u003ei\u003c/text\u003e\n\u003ctext text-anchor='middle' x='216' y='84' fill='currentColor' style='font-size:1em'\u003er\u003c/text\u003e\n\u003ctext text-anchor='middle' x='216' y='100' fill='currentColor' style='font-size:1em'\u003ee\u003c/text\u003e\n\u003ctext text-anchor='middle' x='224' y='20' fill='currentColor' style='font-size:1em'\u003ed\u003c/text\u003e\n\u003ctext text-anchor='middle' x='224' y='52' fill='currentColor' style='font-size:1em'\u003ec\u003c/text\u003e\n\u003ctext text-anchor='middle' x='224' y='68' fill='currentColor' style='font-size:1em'\u003et\u003c/text\u003e\n\u003ctext text-anchor='middle' x='224' y='84' fill='currentColor' style='font-size:1em'\u003eo\u003c/text\u003e\n\u003ctext text-anchor='middle' x='224' y='100' fill='currentColor' style='font-size:1em'\u003er\u003c/text\u003e\n\u003ctext text-anchor='middle' x='232' y='20' fill='currentColor' style='font-size:1em'\u003ee\u003c/text\u003e\n\u003ctext text-anchor='middle' x='232' y='52' fill='currentColor' style='font-size:1em'\u003ek\u003c/text\u003e\n\u003ctext text-anchor='middle' x='232' y='68' fill='currentColor' style='font-size:1em'\u003eH\u003c/text\u003e\n\u003ctext text-anchor='middle' x='232' y='84' fill='currentColor' style='font-size:1em'\u003em\u003c/text\u003e\n\u003ctext text-anchor='middle' x='232' y='100' fill='currentColor' style='font-size:1em'\u003er\u003c/text\u003e\n\u003ctext text-anchor='middle' x='240' y='20' fill='currentColor' style='font-size:1em'\u003er\u003c/text\u003e\n\u003ctext text-anchor='middle' x='240' y='52' fill='currentColor' style='font-size:1em'\u003ee\u003c/text\u003e\n\u003ctext text-anchor='middle' x='240' y='68' fill='currentColor' style='font-size:1em'\u003eu\u003c/text\u003e\n\u003ctext text-anchor='middle' x='240' y='84' fill='currentColor' style='font-size:1em'\u003ee\u003c/text\u003e\n\u003ctext text-anchor='middle' x='240' y='100' fill='currentColor' style='font-size:1em'\u003ea\u003c/text\u003e\n\u003ctext text-anchor='middle' x='248' y='20' fill='currentColor' style='font-size:1em'\u003en\u003c/text\u003e\n\u003ctext text-anchor='middle' x='248' y='52' fill='currentColor' style='font-size:1em'\u003er\u003c/text\u003e\n\u003ctext text-anchor='middle' x='248' y='68' fill='currentColor' style='font-size:1em'\u003eb\u003c/text\u003e\n\u003ctext text-anchor='middle' x='248' y='84' fill='currentColor' style='font-size:1em'\u003et\u003c/text\u003e\n\u003ctext text-anchor='middle' x='248' y='100' fill='currentColor' style='font-size:1em'\u003ef\u003c/text\u003e\n\u003ctext text-anchor='middle' x='256' y='84' fill='currentColor' style='font-size:1em'\u003eh\u003c/text\u003e\n\u003ctext text-anchor='middle' x='256' y='100' fill='currentColor' style='font-size:1em'\u003eo\u003c/text\u003e\n\u003ctext text-anchor='middle' x='264' y='20' fill='currentColor' style='font-size:1em'\u003eD\u003c/text\u003e\n\u003ctext text-anchor='middle' x='264' y='52' fill='currentColor' style='font-size:1em'\u003e/\u003c/text\u003e\n\u003ctext text-anchor='middle' x='264' y='68' fill='currentColor' style='font-size:1em'\u003eA\u003c/text\u003e\n\u003ctext text-anchor='middle' x='264' y='84' fill='currentColor' style='font-size:1em'\u003ee\u003c/text\u003e\n\u003ctext text-anchor='middle' x='264' y='100' fill='currentColor' style='font-size:1em'\u003er\u003c/text\u003e\n\u003ctext text-anchor='middle' x='272' y='20' fill='currentColor' style='font-size:1em'\u003ee\u003c/text\u003e\n\u003ctext text-anchor='middle' x='272' y='68' fill='currentColor' style='font-size:1em'\u003ec\u003c/text\u003e\n\u003ctext text-anchor='middle' x='272' y='84' fill='currentColor' style='font-size:1em'\u003eu\u003c/text\u003e\n\u003ctext text-anchor='middle' x='272' y='100' fill='currentColor' style='font-size:1em'\u003em\u003c/text\u003e\n\u003ctext text-anchor='middle' x='280' y='20' fill='currentColor' style='font-size:1em'\u003ev\u003c/text\u003e\n\u003ctext text-anchor='middle' x='280' y='52' fill='currentColor' style='font-size:1em'\u003eK\u003c/text\u003e\n\u003ctext text-anchor='middle' x='280' y='68' fill='currentColor' style='font-size:1em'\u003et\u003c/text\u003e\n\u003ctext text-anchor='middle' x='280' y='84' fill='currentColor' style='font-size:1em'\u003es\u003c/text\u003e\n\u003ctext text-anchor='middle' x='288' y='20' fill='currentColor' style='font-size:1em'\u003eO\u003c/text\u003e\n\u003ctext text-anchor='middle' x='288' y='52' fill='currentColor' style='font-size:1em'\u003e3\u003c/text\u003e\n\u003ctext text-anchor='middle' x='288' y='68' fill='currentColor' style='font-size:1em'\u003ei\u003c/text\u003e\n\u003ctext text-anchor='middle' x='296' y='20' fill='currentColor' style='font-size:1em'\u003ep\u003c/text\u003e\n\u003ctext text-anchor='middle' x='296' y='52' fill='currentColor' style='font-size:1em'\u003es\u003c/text\u003e\n\u003ctext text-anchor='middle' x='296' y='68' fill='currentColor' style='font-size:1em'\u003eo\u003c/text\u003e\n\u003ctext text-anchor='middle' x='304' y='20' fill='currentColor' style='font-size:1em'\u003es\u003c/text\u003e\n\u003ctext text-anchor='middle' x='304' y='68' fill='currentColor' style='font-size:1em'\u003en\u003c/text\u003e\n\u003ctext text-anchor='middle' x='304' y='100' fill='currentColor' style='font-size:1em'\u003eA\u003c/text\u003e\n\u003ctext text-anchor='middle' x='312' y='52' fill='currentColor' style='font-size:1em'\u003e/\u003c/text\u003e\n\u003ctext text-anchor='middle' x='312' y='68' fill='currentColor' style='font-size:1em'\u003es\u003c/text\u003e\n\u003ctext text-anchor='middle' x='312' y='84' fill='currentColor' style='font-size:1em'\u003eG\u003c/text\u003e\n\u003ctext text-anchor='middle' x='312' y='100' fill='currentColor' style='font-size:1em'\u003en\u003c/text\u003e\n\u003ctext text-anchor='middle' x='320' y='20' fill='currentColor' style='font-size:1em'\u003eS\u003c/text\u003e\n\u003ctext text-anchor='middle' x='320' y='84' fill='currentColor' style='font-size:1em'\u003er\u003c/text\u003e\n\u003ctext text-anchor='middle' x='320' y='100' fill='currentColor' style='font-size:1em'\u003es\u003c/text\u003e\n\u003ctext text-anchor='middle' x='328' y='20' fill='currentColor' style='font-size:1em'\u003et\u003c/text\u003e\n\u003ctext text-anchor='middle' x='328' y='52' fill='currentColor' style='font-size:1em'\u003eM\u003c/text\u003e\n\u003ctext text-anchor='middle' x='328' y='68' fill='currentColor' style='font-size:1em'\u003e/\u003c/text\u003e\n\u003ctext text-anchor='middle' x='328' y='84' fill='currentColor' style='font-size:1em'\u003ea\u003c/text\u003e\n\u003ctext text-anchor='middle' x='328' y='100' fill='currentColor' style='font-size:1em'\u003ei\u003c/text\u003e\n\u003ctext text-anchor='middle' x='336' y='20' fill='currentColor' style='font-size:1em'\u003ea\u003c/text\u003e\n\u003ctext text-anchor='middle' x='336' y='52' fill='currentColor' style='font-size:1em'\u003ei\u003c/text\u003e\n\u003ctext text-anchor='middle' x='336' y='84' fill='currentColor' style='font-size:1em'\u003ef\u003c/text\u003e\n\u003ctext text-anchor='middle' x='336' y='100' fill='currentColor' style='font-size:1em'\u003eb\u003c/text\u003e\n\u003ctext text-anchor='middle' x='344' y='20' fill='currentColor' style='font-size:1em'\u003ec\u003c/text\u003e\n\u003ctext text-anchor='middle' x='344' y='52' fill='currentColor' style='font-size:1em'\u003ec\u003c/text\u003e\n\u003ctext text-anchor='middle' x='344' y='68' fill='currentColor' style='font-size:1em'\u003eJ\u003c/text\u003e\n\u003ctext text-anchor='middle' x='344' y='84' fill='currentColor' style='font-size:1em'\u003ea\u003c/text\u003e\n\u003ctext text-anchor='middle' x='344' y='100' fill='currentColor' style='font-size:1em'\u003el\u003c/text\u003e\n\u003ctext text-anchor='middle' x='352' y='20' fill='currentColor' style='font-size:1em'\u003ek\u003c/text\u003e\n\u003ctext text-anchor='middle' x='352' y='52' fill='currentColor' style='font-size:1em'\u003er\u003c/text\u003e\n\u003ctext text-anchor='middle' x='352' y='68' fill='currentColor' style='font-size:1em'\u003ee\u003c/text\u003e\n\u003ctext text-anchor='middle' x='352' y='84' fill='currentColor' style='font-size:1em'\u003en\u003c/text\u003e\n\u003ctext text-anchor='middle' x='352' y='100' fill='currentColor' style='font-size:1em'\u003ee\u003c/text\u003e\n\u003ctext text-anchor='middle' x='360' y='52' fill='currentColor' style='font-size:1em'\u003eo\u003c/text\u003e\n\u003ctext text-anchor='middle' x='360' y='68' fill='currentColor' style='font-size:1em'\u003en\u003c/text\u003e\n\u003ctext text-anchor='middle' x='360' y='84' fill='currentColor' style='font-size:1em'\u003ea\u003c/text\u003e\n\u003ctext text-anchor='middle' x='368' y='52' fill='currentColor' style='font-size:1em'\u003eK\u003c/text\u003e\n\u003ctext text-anchor='middle' x='368' y='68' fill='currentColor' style='font-size:1em'\u003ek\u003c/text\u003e\n\u003ctext text-anchor='middle' x='376' y='52' fill='currentColor' style='font-size:1em'\u003e8\u003c/text\u003e\n\u003ctext text-anchor='middle' x='376' y='68' fill='currentColor' style='font-size:1em'\u003ei\u003c/text\u003e\n\u003ctext text-anchor='middle' x='376' y='84' fill='currentColor' style='font-size:1em'\u003e/\u003c/text\u003e\n\u003ctext text-anchor='middle' x='384' y='52' fill='currentColor' style='font-size:1em'\u003es\u003c/text\u003e\n\u003ctext text-anchor='middle' x='384' y='68' fill='currentColor' style='font-size:1em'\u003en\u003c/text\u003e\n\u003ctext text-anchor='middle' x='392' y='68' fill='currentColor' style='font-size:1em'\u003es\u003c/text\u003e\n\u003ctext text-anchor='middle' x='392' y='84' fill='currentColor' style='font-size:1em'\u003eL\u003c/text\u003e\n\u003ctext text-anchor='middle' x='408' y='84' fill='currentColor' style='font-size:1em'\u003ek\u003c/text\u003e\n\u003ctext text-anchor='middle' x='416' y='84' fill='currentColor' style='font-size:1em'\u003ei\u003c/text\u003e\n\u003ctext text-anchor='middle' x='424' y='68' fill='currentColor' style='font-size:1em'\u003eA\u003c/text\u003e\n\u003ctext text-anchor='middle' x='432' y='68' fill='currentColor' style='font-size:1em'\u003er\u003c/text\u003e\n\u003ctext text-anchor='middle' x='440' y='68' fill='currentColor' style='font-size:1em'\u003eg\u003c/text\u003e\n\u003ctext text-anchor='middle' x='448' y='68' fill='currentColor' style='font-size:1em'\u003eo\u003c/text\u003e\n\u003ctext text-anchor='middle' x='456' y='68' fill='currentColor' style='font-size:1em'\u003eC\u003c/text\u003e\n\u003ctext text-anchor='middle' x='464' y='68' fill='currentColor' style='font-size:1em'\u003eD\u003c/text\u003e\n\u003c/g\u003e\n\n    \u003c/svg\u003e\n  \n\u003c/div\u003e\n\u003chr\u003e\n\u003ch2 id=\"2-영역별-핵심-도구-및-베스트-프랙티스\"\u003e2. 영역별 핵심 도구 및 베스트 프랙티스\u003c/h2\u003e\n\u003ch3 id=\"-container--orchestration-컨테이너-패러다임\"\u003e① Container \u0026amp; Orchestration (컨테이너 패러다임)\u003c/h3\u003e\n\u003cp\u003e애플리케이션을 호스트 환경과 격리하여 어디서나 동일하게 실행할 수 있는 표준 패키징 기술입니다.\u003c/p\u003e","title":"Modern DevOps 핵심 가이드: 도구 체계와 Cloud Native 로드맵"},{"content":"ROS2 빌드 오류 처리 오류 메시지 ModuleNotFoundError: No module named `catkin_pkg` CMake Error at /opt/ros/humble/share/ament_cmake_core/cmake/core/ament_package_xml.cmake:95 (message): execute_process(/home/{user}/.pyenv/shims/python3.10 /opt/ros/humble/share/ament_cmake_core/cmake/core/package_xml_2_cmake.py /home/{user_project_path}/src/test_pubsub/package.xml /home/{user_project_path}/build/test_pubsub/ament_cmake_core/package.cmake) returned error code 1 Call Stack (most recent call first): /opt/ros/humble/share/ament_cmake_core/cmake/core/ament_package_xml.cmake:49 (_ament_package_xml) /opt/ros/humble/share/ament_cmake_core/cmake/core/ament_package.cmake:63 (ament_package_xml) CMakeLists.txt:31 (ament_package) 오류 해결 방법 해당 오류는 Python catkin_pkg 가 없어서 발생한 오류로 해당 패키지를 설치하면 됨\npip install catkin_pkg ","permalink":"https://wkqco33.github.io/wkqcosoft-docs/posts/ros2-cmake-build-error/","summary":"\u003ch2 id=\"ros2-빌드-오류-처리\"\u003eROS2 빌드 오류 처리\u003c/h2\u003e\n\u003ch3 id=\"오류-메시지\"\u003e오류 메시지\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eModuleNotFoundError: No module named \u003cspan style=\"color:#e6db74\"\u003e`\u003c/span\u003ecatkin_pkg\u003cspan style=\"color:#e6db74\"\u003e`\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eCMake Error at /opt/ros/humble/share/ament_cmake_core/cmake/core/ament_package_xml.cmake:95 \u003cspan style=\"color:#f92672\"\u003e(\u003c/span\u003emessage\u003cspan style=\"color:#f92672\"\u003e)\u003c/span\u003e:\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e  execute_process\u003cspan style=\"color:#f92672\"\u003e(\u003c/span\u003e/home/\u003cspan style=\"color:#f92672\"\u003e{\u003c/span\u003euser\u003cspan style=\"color:#f92672\"\u003e}\u003c/span\u003e/.pyenv/shims/python3.10\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e  /opt/ros/humble/share/ament_cmake_core/cmake/core/package_xml_2_cmake.py\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e  /home/\u003cspan style=\"color:#f92672\"\u003e{\u003c/span\u003euser_project_path\u003cspan style=\"color:#f92672\"\u003e}\u003c/span\u003e/src/test_pubsub/package.xml\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e  /home/\u003cspan style=\"color:#f92672\"\u003e{\u003c/span\u003euser_project_path\u003cspan style=\"color:#f92672\"\u003e}\u003c/span\u003e/build/test_pubsub/ament_cmake_core/package.cmake\u003cspan style=\"color:#f92672\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e  returned error code \u003cspan style=\"color:#ae81ff\"\u003e1\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eCall Stack \u003cspan style=\"color:#f92672\"\u003e(\u003c/span\u003emost recent call first\u003cspan style=\"color:#f92672\"\u003e)\u003c/span\u003e:\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e  /opt/ros/humble/share/ament_cmake_core/cmake/core/ament_package_xml.cmake:49 \u003cspan style=\"color:#f92672\"\u003e(\u003c/span\u003e_ament_package_xml\u003cspan style=\"color:#f92672\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e  /opt/ros/humble/share/ament_cmake_core/cmake/core/ament_package.cmake:63 \u003cspan style=\"color:#f92672\"\u003e(\u003c/span\u003eament_package_xml\u003cspan style=\"color:#f92672\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e  CMakeLists.txt:31 \u003cspan style=\"color:#f92672\"\u003e(\u003c/span\u003eament_package\u003cspan style=\"color:#f92672\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"오류-해결-방법\"\u003e오류 해결 방법\u003c/h3\u003e\n\u003cp\u003e해당 오류는 Python \u003ccode\u003ecatkin_pkg\u003c/code\u003e 가 없어서 발생한 오류로 해당 패키지를 설치하면 됨\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003epip install catkin_pkg\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e","title":"ROS2 CMake 빌드 오류 해결 (catkin_pkg 관련)"},{"content":"wkqcosoft hugo 페이지 만들기 hugo 프레임워크를 사용한 정적 페이지 만들어보기 프로젝트\nHugo 설치 Linux package manager를 사용하여 설치 sudo apt install hugo Hugo 프로젝트 생성 Quick Start 참고 hugo new site quickstart cd quickstart git init git submodule add https://github.com/theNewDynamic/gohugo-theme-ananke themes/ananke echo \u0026#39;theme = \u0026#34;ananke\u0026#34;\u0026#39; \u0026gt;\u0026gt; config.toml hugo server Hugo 프로젝트에 포스트 추가 hugo new posts/my-first-post.md Hugo 프로젝트에 테마 적용 Themes 참고 git submodule add {theme-repo} themes/{theme-name} Hugo 특징 정적 페이지 생성기로는 Jekyll, Hexo, Hugo 등이 있음 Hugo는 Go 언어로 작성되어 있어서 빌드/렌더링 속도가 매우 빠르고, 테마가 많음 템플릿 문법이 Go의 text/template, html/template 패키지를 기반으로 하고 있어, Go 언어에 익숙하면 템플릿을 커스터마이징하기 수월함 Hugo 소감 쉽고 빠르게 설치가 가능했고 테마도 많아서 쉽게 적용할 수 있었음 앞으로 wkqcosoft 개발 문서 관리에 활용할 예정 go lang 도 다시 공부해볼 흥미가 생김 ","permalink":"https://wkqco33.github.io/wkqcosoft-docs/posts/hugo-blog-setup/","summary":"\u003ch2 id=\"wkqcosoft-hugo-페이지-만들기\"\u003ewkqcosoft hugo 페이지 만들기\u003c/h2\u003e\n\u003cp\u003ehugo 프레임워크를 사용한 정적 페이지 만들어보기 프로젝트\u003c/p\u003e\n\u003ch3 id=\"hugo-설치\"\u003eHugo 설치\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003eLinux package manager를 사용하여 설치\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003esudo apt install hugo\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"hugo-프로젝트-생성\"\u003eHugo 프로젝트 생성\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"https://gohugo.io/getting-started/quick-start/\"\u003eQuick Start\u003c/a\u003e 참고\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ehugo new site quickstart\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ecd quickstart\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003egit init\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003egit submodule add https://github.com/theNewDynamic/gohugo-theme-ananke themes/ananke\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eecho \u003cspan style=\"color:#e6db74\"\u003e\u0026#39;theme = \u0026#34;ananke\u0026#34;\u0026#39;\u003c/span\u003e \u0026gt;\u0026gt; config.toml\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ehugo server\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"hugo-프로젝트에-포스트-추가\"\u003eHugo 프로젝트에 포스트 추가\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ehugo new posts/my-first-post.md\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"hugo-프로젝트에-테마-적용\"\u003eHugo 프로젝트에 테마 적용\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"https://themes.gohugo.io/\"\u003eThemes\u003c/a\u003e 참고\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003egit submodule add \u003cspan style=\"color:#f92672\"\u003e{\u003c/span\u003etheme-repo\u003cspan style=\"color:#f92672\"\u003e}\u003c/span\u003e themes/\u003cspan style=\"color:#f92672\"\u003e{\u003c/span\u003etheme-name\u003cspan style=\"color:#f92672\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"hugo-특징\"\u003eHugo 특징\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e정적 페이지 생성기로는 Jekyll, Hexo, Hugo 등이 있음\u003c/li\u003e\n\u003cli\u003eHugo는 Go 언어로 작성되어 있어서 빌드/렌더링 속도가 매우 빠르고, 테마가 많음\u003c/li\u003e\n\u003cli\u003e템플릿 문법이 Go의 \u003ccode\u003etext/template\u003c/code\u003e, \u003ccode\u003ehtml/template\u003c/code\u003e 패키지를 기반으로 하고 있어, Go 언어에 익숙하면 템플릿을 커스터마이징하기 수월함\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"hugo-소감\"\u003eHugo 소감\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e쉽고 빠르게 설치가 가능했고 테마도 많아서 쉽게 적용할 수 있었음\u003c/li\u003e\n\u003cli\u003e앞으로 wkqcosoft 개발 문서 관리에 활용할 예정\u003c/li\u003e\n\u003cli\u003ego lang 도 다시 공부해볼 흥미가 생김\u003c/li\u003e\n\u003c/ul\u003e","title":"Hugo로 블로그 만들기 및 GitHub Pages 배포"},{"content":"About 개발 스터디 중 문제를 해결했거나 내용을 정리하기 위해 문서로 작성하여 모아놓은 블로그 입니다.\n","permalink":"https://wkqco33.github.io/wkqcosoft-docs/about/","summary":"\u003ch1 id=\"about\"\u003eAbout\u003c/h1\u003e\n\u003cp\u003e개발 스터디 중 문제를 해결했거나 내용을 정리하기 위해 문서로 작성하여 모아놓은 블로그 입니다.\u003c/p\u003e","title":""}]