[{"data":1,"prerenderedAt":1124},["ShallowReactive",2],{"post-document:\u002Fbasic\u002Fos\u002F2026\u002F08\u002F24\u002Fdocker-os-basics\u002F":3},{"id":4,"title":5,"body":6,"categories":1105,"date":1108,"description":1109,"extension":1110,"image":1111,"key_concepts":1111,"last_modified_at":1111,"legacyPath":1112,"meta":1113,"navigation":1115,"part":1111,"path":1116,"published":1115,"robots":1111,"seo":1117,"series":1111,"stem":1118,"strengths":1111,"summary":1111,"tags":1119,"tradeoffs":1111,"__hash__":1123},"posts\u002Fposts\u002FBasic\u002F2026-08-24-docker-os-basics.md","Docker를 이해하기 위한 운영체제 기초",{"type":7,"value":8,"toc":1082},"minimark",[9,37,45,50,55,58,68,71,77,83,89,92,96,101,104,124,127,133,136,142,145,151,157,160,168,174,176,180,185,188,194,197,206,209,212,218,225,227,231,236,239,262,265,271,274,276,282,285,291,298,300,304,309,312,318,321,327,329,335,338,358,361,368,370,374,377,382,385,390,396,399,402,408,410,414,417,423,430,436,439,445,448,450,454,457,464,470,473,479,481,490,497,503,505,509,514,517,523,526,532,535,569,571,575,580,582,604,607,613,616,622,625,631,633,637,642,645,654,657,663,666,681,684,687,689,693,700,706,709,715,718,724,727,733,736,742,744,748,753,756,762,765,771,774,776,780,783,788,791,797,800,813,816,822,825,831,833,837,842,845,851,854,860,863,869,872,874,878,883,889,892,911,914,920,922,926,929,934,936,942,945,951,954,956,960,965,971,974,980,982,988,991,993,997,1000,1006,1009,1016,1023,1025,1029,1032,1038,1041,1047,1051,1057,1063,1066,1072,1078],[10,11,12,13,17,18,17,21,17,24,17,27,17,30,17,33,36],"p",{},"Docker를 이해하려면 먼저 ",[14,15,16],"code",{},"Process",", ",[14,19,20],{},"Kernel",[14,22,23],{},"Memory",[14,25,26],{},"CPU",[14,28,29],{},"Thread",[14,31,32],{},"Filesystem",[14,34,35],{},"Network","가 무엇인지 알아야 합니다.",[10,38,39,40,44],{},"이 글에서는 Docker를 공부할 때 자주 만나는 개념을 ",[41,42,43],"strong",{},"운영체제 기초 단어장","처럼 정리합니다. 처음부터 모든 내용을 외우기보다는 각 개념이 어떻게 연결되는지 이해하는 것이 중요합니다.",[46,47,49],"h2",{"id":48},"_1-program","1. Program",[10,51,52],{},[41,53,54],{},"프로그램 = 실행 가능한 코드가 저장된 파일",[10,56,57],{},"예:",[59,60,66],"pre",{"className":61,"code":63,"language":64,"meta":65},[62],"language-text","nginx\njava\npython\nchrome\n","text","",[14,67,63],{"__ignoreMap":65},[10,69,70],{},"아직 실행되지 않았다면 디스크에 저장된 파일일 뿐입니다.",[59,72,75],{"className":73,"code":74,"language":64,"meta":65},[62],"SSD\n\n\u002Fusr\u002Fbin\u002Fpython\n\u002Fusr\u002Fbin\u002Fnginx\n\u002Fapp\u002Fmy-server.jar\n\n→ 아직 실행되지 않음\n",[14,76,74],{"__ignoreMap":65},[10,78,79,80,82],{},"프로그램을 실행하면 ",[41,81,16],{},"가 됩니다.",[59,84,87],{"className":85,"code":86,"language":64,"meta":65},[62],"Program\n   ↓ 실행\nProcess\n",[14,88,86],{"__ignoreMap":65},[90,91],"hr",{},[46,93,95],{"id":94},"_2-process","2. Process",[10,97,98],{},[41,99,100],{},"프로세스 = 실행 중인 프로그램",[10,102,103],{},"예를 들어:",[59,105,109],{"className":106,"code":107,"language":108,"meta":65,"style":65},"language-bash shiki shiki-themes github-light github-dark","python server.py\n","bash",[14,110,111],{"__ignoreMap":65},[112,113,116,120],"span",{"class":114,"line":115},"line",1,[112,117,119],{"class":118},"sScJk","python",[112,121,123],{"class":122},"sZZnC"," server.py\n",[10,125,126],{},"를 실행하면 Linux Kernel이 Python 프로세스를 만듭니다.",[59,128,131],{"className":129,"code":130,"language":64,"meta":65},[62],"Program\nserver.py\n   ↓\nPython 실행\n   ↓\nProcess 생성\n",[14,132,130],{"__ignoreMap":65},[10,134,135],{},"프로세스에는 보통 다음과 같은 정보와 자원이 포함됩니다.",[59,137,140],{"className":138,"code":139,"language":64,"meta":65},[62],"Process\n\nPID\nCPU 실행 상태\nMemory\nFile Descriptor\nNetwork Socket\n환경 변수\n권한\n",[14,141,139],{"__ignoreMap":65},[10,143,144],{},"예를 들어 Chrome을 3개 실행했다고 생각해보면:",[59,146,149],{"className":147,"code":148,"language":64,"meta":65},[62],"Chrome 프로그램 파일\n        ↓\n ┌──────┼──────┐\n ↓      ↓      ↓\nPID 101 PID 102 PID 103\nProcess Process Process\n",[14,150,148],{"__ignoreMap":65},[10,152,153,154],{},"같은 프로그램이라도 ",[41,155,156],{},"여러 프로세스가 존재할 수 있습니다.",[10,158,159],{},"Docker에서 가장 중요한 연결점:",[161,162,163],"blockquote",{},[10,164,165],{},[41,166,167],{},"컨테이너도 결국 Linux에서 실행되는 프로세스입니다.",[59,169,172],{"className":170,"code":171,"language":64,"meta":65},[62],"Docker Container\n       ↓\n격리된 Process\n       ↓\nLinux Kernel\n",[14,173,171],{"__ignoreMap":65},[90,175],{},[46,177,179],{"id":178},"_3-pid","3. PID",[10,181,182],{},[41,183,184],{},"PID = Process ID",[10,186,187],{},"Linux가 프로세스를 구분하기 위해 붙이는 번호입니다.",[59,189,192],{"className":190,"code":191,"language":64,"meta":65},[62],"PID 1    systemd\nPID 421  nginx\nPID 532  java\nPID 991  postgres\n",[14,193,191],{"__ignoreMap":65},[10,195,196],{},"Linux에서:",[59,198,200],{"className":106,"code":199,"language":108,"meta":65,"style":65},"ps\n",[14,201,202],{"__ignoreMap":65},[112,203,204],{"class":114,"line":115},[112,205,199],{"class":118},[10,207,208],{},"를 입력하면 실행 중인 프로세스를 확인할 수 있습니다.",[10,210,211],{},"Docker Container 내부에서는 PID Namespace 때문에 Host와 다른 PID 목록을 볼 수 있습니다.",[59,213,216],{"className":214,"code":215,"language":64,"meta":65},[62],"Host\n\nPID 1000 nginx\n\n        ↓ PID Namespace\n\nContainer 내부에서는\n\nPID 1 nginx\n",[14,217,215],{"__ignoreMap":65},[10,219,220,221,224],{},"실제 프로세스는 같지만 ",[41,222,223],{},"보이는 프로세스 공간을 격리","한 것입니다.",[90,226],{},[46,228,230],{"id":229},"_4-cpu","4. CPU",[10,232,233],{},[41,234,235],{},"CPU = 명령어를 실제로 실행하는 장치",[10,237,238],{},"프로그램 코드가:",[59,240,243],{"className":241,"code":242,"language":119,"meta":65,"style":65},"language-python shiki shiki-themes github-light github-dark","a = 10\nb = 20\nc = a + b\n",[14,244,245,250,256],{"__ignoreMap":65},[112,246,247],{"class":114,"line":115},[112,248,249],{},"a = 10\n",[112,251,253],{"class":114,"line":252},2,[112,254,255],{},"b = 20\n",[112,257,259],{"class":114,"line":258},3,[112,260,261],{},"c = a + b\n",[10,263,264],{},"라면 CPU가 실제 계산을 수행합니다.",[59,266,269],{"className":267,"code":268,"language":64,"meta":65},[62],"Program Code\n     ↓\nProcess\n     ↓\nCPU\n     ↓\n명령어 실행\n",[14,270,268],{"__ignoreMap":65},[10,272,273],{},"CPU에는 Core가 있습니다.",[10,275,57],{},[59,277,280],{"className":278,"code":279,"language":64,"meta":65},[62],"8 Core CPU\n\nCore 1\nCore 2\nCore 3\nCore 4\nCore 5\nCore 6\nCore 7\nCore 8\n",[14,281,279],{"__ignoreMap":65},[10,283,284],{},"여러 프로세스가 CPU를 번갈아 사용합니다.",[59,286,289],{"className":287,"code":288,"language":64,"meta":65},[62],"CPU Core\n\n시간 →\n────────────────────────\n\nChrome\n       Java\n             Python\n                    Chrome\n",[14,290,288],{"__ignoreMap":65},[10,292,293,294,297],{},"이렇게 실행 대상을 바꾸는 것을 ",[41,295,296],{},"Context Switching","이라고 합니다.",[90,299],{},[46,301,303],{"id":302},"_5-memory-ram","5. Memory \u002F RAM",[10,305,306],{},[41,307,308],{},"Memory = 실행 중인 프로그램이 데이터를 임시로 저장하는 공간",[10,310,311],{},"디스크보다 훨씬 빠르지만 전원을 끄면 내용이 사라집니다.",[59,313,316],{"className":314,"code":315,"language":64,"meta":65},[62],"SSD\n프로그램 저장\n\n        ↓ 실행\n\nRAM\nProcess 데이터 저장\n\n        ↓\n\nCPU\n계산\n",[14,317,315],{"__ignoreMap":65},[10,319,320],{},"전체 구조:",[59,322,325],{"className":323,"code":324,"language":64,"meta":65},[62],"SSD\n │\n │ 프로그램 읽기\n ↓\nRAM\n │\n │ 데이터 전달\n ↓\nCPU\n",[14,326,324],{"__ignoreMap":65},[10,328,57],{},[59,330,333],{"className":331,"code":332,"language":64,"meta":65},[62],"RAM 16GB\n\nChrome       3GB\nIntelliJ     2GB\nDocker       4GB\nPostgreSQL   1GB\nOS           3GB\n기타         3GB\n",[14,334,332],{"__ignoreMap":65},[10,336,337],{},"Docker에서:",[59,339,341],{"className":106,"code":340,"language":108,"meta":65,"style":65},"docker run --memory=512m nginx\n",[14,342,343],{"__ignoreMap":65},[112,344,345,348,351,355],{"class":114,"line":115},[112,346,347],{"class":118},"docker",[112,349,350],{"class":122}," run",[112,352,354],{"class":353},"sj4cs"," --memory=512m",[112,356,357],{"class":122}," nginx\n",[10,359,360],{},"처럼 메모리 사용량을 제한할 수 있습니다.",[10,362,363,364,367],{},"이 제한은 ",[41,365,366],{},"cgroup","을 통해 Kernel이 수행합니다.",[90,369],{},[46,371,373],{"id":372},"_6-kernel","6. Kernel",[10,375,376],{},"Docker를 이해할 때 특히 중요한 개념입니다.",[10,378,379],{},[41,380,381],{},"Kernel = 운영체제의 핵심 부분으로, 하드웨어와 프로그램 사이를 관리하는 소프트웨어",[10,383,384],{},"쉽게 말하면 다음과 같습니다.",[161,386,387],{},[10,388,389],{},"Kernel은 모든 프로세스와 하드웨어 자원을 관리하는 관리자입니다.",[59,391,394],{"className":392,"code":393,"language":64,"meta":65},[62],"Application\n\nChrome\nSpring\nPostgreSQL\nDocker Container\n      ↓\n────────────────\nLinux Kernel\n────────────────\nCPU\nRAM\nDisk\nNetwork\n",[14,395,393],{"__ignoreMap":65},[10,397,398],{},"프로그램이 직접 RAM이나 SSD를 마음대로 제어하면 위험합니다.",[10,400,401],{},"그래서 Kernel이 중간에서 관리합니다.",[59,403,406],{"className":404,"code":405,"language":64,"meta":65},[62],"Process\n\n\"파일 읽어줘\"\n\"메모리 줘\"\n\"네트워크 보내줘\"\n\"새 Process 만들어줘\"\n\n        ↓\n\nKernel\n\n        ↓\n\nCPU \u002F RAM \u002F SSD \u002F Network\n",[14,407,405],{"__ignoreMap":65},[90,409],{},[46,411,413],{"id":412},"_7-user-space와-kernel-space","7. User Space와 Kernel Space",[10,415,416],{},"운영체제는 크게 두 영역으로 생각할 수 있습니다.",[59,418,421],{"className":419,"code":420,"language":64,"meta":65},[62],"User Space\n\nChrome\nJava\nPython\nnginx\nPostgreSQL\n\n──────────────────\n\nKernel Space\n\nLinux Kernel\n\n──────────────────\n\nHardware\n\nCPU\nRAM\nSSD\nNIC\n",[14,422,420],{"__ignoreMap":65},[10,424,425,426,429],{},"일반 프로그램은 ",[41,427,428],{},"User Space","에서 실행됩니다.",[10,431,432,433,429],{},"Kernel만 ",[41,434,435],{},"Kernel Space",[10,437,438],{},"두 공간을 분리하는 이유는 일반 프로그램의 문제가 운영체제 전체에 영향을 주는 것을 막기 위해서입니다.",[59,440,443],{"className":441,"code":442,"language":64,"meta":65},[62],"Chrome 버그 발생\n→ Chrome만 죽음\n\nChrome이 Kernel 메모리에 직접 접근 가능\n→ OS 전체가 죽을 수도 있음\n",[14,444,442],{"__ignoreMap":65},[10,446,447],{},"그래서 두 공간의 권한을 분리합니다.",[90,449],{},[46,451,453],{"id":452},"_8-system-call","8. System Call",[10,455,456],{},"그렇다면 프로그램은 Kernel의 기능을 어떻게 사용할까요?",[10,458,459,460,463],{},"프로그램은 ",[41,461,462],{},"System Call","을 사용합니다.",[59,465,468],{"className":466,"code":467,"language":64,"meta":65},[62],"Application\n    ↓\nSystem Call\n    ↓\nKernel\n    ↓\nHardware\n",[14,469,467],{"__ignoreMap":65},[10,471,472],{},"대표적인 System Call:",[59,474,477],{"className":475,"code":476,"language":64,"meta":65},[62],"open()   → 파일 열기\nread()   → 데이터 읽기\nwrite()  → 데이터 쓰기\nfork()   → 프로세스 생성\nexec()   → 프로그램 실행\nsocket() → 네트워크 Socket 생성\n",[14,478,476],{"__ignoreMap":65},[10,480,57],{},[59,482,484],{"className":241,"code":483,"language":119,"meta":65,"style":65},"f = open(\"hello.txt\")\n",[14,485,486],{"__ignoreMap":65},[112,487,488],{"class":114,"line":115},[112,489,483],{},[10,491,492,493,496],{},"Python 코드에서는 ",[14,494,495],{},"open()","으로 보이지만 내부적으로는 Kernel에 파일을 열어달라고 요청합니다.",[59,498,501],{"className":499,"code":500,"language":64,"meta":65},[62],"Python\n   ↓\nopen()\n   ↓\nSystem Call\n   ↓\nLinux Kernel\n   ↓\nFilesystem\n   ↓\nSSD\n",[14,502,500],{"__ignoreMap":65},[90,504],{},[46,506,508],{"id":507},"_9-thread","9. Thread",[10,510,511],{},[41,512,513],{},"Thread = 프로세스 내부의 실행 흐름",[10,515,516],{},"프로세스 하나 안에 여러 Thread가 존재할 수 있습니다.",[59,518,521],{"className":519,"code":520,"language":64,"meta":65},[62],"Process\n\nMemory\nHeap\nFiles\n\n ├── Thread 1\n ├── Thread 2\n ├── Thread 3\n └── Thread 4\n",[14,522,520],{"__ignoreMap":65},[10,524,525],{},"예를 들어 Spring 서버:",[59,527,530],{"className":528,"code":529,"language":64,"meta":65},[62],"Spring Process\n\nThread 1 → 사용자 A 요청\nThread 2 → 사용자 B 요청\nThread 3 → 사용자 C 요청\nThread 4 → 사용자 D 요청\n",[14,531,529],{"__ignoreMap":65},[10,533,534],{},"Process와 Thread 차이:",[536,537,538,551],"table",{},[539,540,541],"thead",{},[542,543,544,548],"tr",{},[545,546,547],"th",{},"개념",[545,549,550],{},"의미",[552,553,554,562],"tbody",{},[542,555,556,559],{},[557,558,16],"td",{},[557,560,561],{},"실행 중인 프로그램 단위",[542,563,564,566],{},[557,565,29],{},[557,567,568],{},"Process 내부의 실행 단위",[90,570],{},[46,572,574],{"id":573},"_10-stack","10. Stack",[10,576,577],{},[41,578,579],{},"Stack = 함수 호출과 지역 변수를 저장하는 메모리 영역",[10,581,57],{},[59,583,587],{"className":584,"code":585,"language":586,"meta":65,"style":65},"language-java shiki shiki-themes github-light github-dark","void hello() {\n    int x = 10;\n}\n","java",[14,588,589,594,599],{"__ignoreMap":65},[112,590,591],{"class":114,"line":115},[112,592,593],{},"void hello() {\n",[112,595,596],{"class":114,"line":252},[112,597,598],{},"    int x = 10;\n",[112,600,601],{"class":114,"line":258},[112,602,603],{},"}\n",[10,605,606],{},"실행하면 대략:",[59,608,611],{"className":609,"code":610,"language":64,"meta":65},[62],"Stack\n\nhello()\n ├── x = 10\n └── return address\n",[14,612,610],{"__ignoreMap":65},[10,614,615],{},"함수가 끝나면 자동으로 제거됩니다.",[59,617,620],{"className":618,"code":619,"language":64,"meta":65},[62],"함수 호출\n\nStack\n↓\n생성\n\n함수 종료\n↓\n제거\n",[14,621,619],{"__ignoreMap":65},[10,623,624],{},"Thread마다 자신의 Stack을 가지고 있습니다.",[59,626,629],{"className":627,"code":628,"language":64,"meta":65},[62],"Process\n\nHeap\n\nThread 1 Stack\nThread 2 Stack\nThread 3 Stack\n",[14,630,628],{"__ignoreMap":65},[90,632],{},[46,634,636],{"id":635},"_11-heap","11. Heap",[10,638,639],{},[41,640,641],{},"Heap = 동적으로 생성된 객체를 저장하는 메모리 영역",[10,643,644],{},"Java 예:",[59,646,648],{"className":584,"code":647,"language":586,"meta":65,"style":65},"User user = new User();\n",[14,649,650],{"__ignoreMap":65},[112,651,652],{"class":114,"line":115},[112,653,647],{},[10,655,656],{},"대략:",[59,658,661],{"className":659,"code":660,"language":64,"meta":65},[62],"Stack\n\nuser\n │\n │ reference\n ↓\n\nHeap\n\nUser Object\n",[14,662,660],{"__ignoreMap":65},[10,664,665],{},"Spring에서:",[59,667,669],{"className":584,"code":668,"language":586,"meta":65,"style":65},"@Service\nUserService\n",[14,670,671,676],{"__ignoreMap":65},[112,672,673],{"class":114,"line":115},[112,674,675],{},"@Service\n",[112,677,678],{"class":114,"line":252},[112,679,680],{},"UserService\n",[10,682,683],{},"같은 객체들도 JVM Heap에 존재합니다.",[10,685,686],{},"Java에서는 Garbage Collector가 Heap을 관리합니다.",[90,688],{},[46,690,692],{"id":691},"_12-virtual-memory","12. Virtual Memory",[10,694,695,696,699],{},"Virtual Memory는 프로세스가 실제 RAM 주소를 직접 사용하지 않고 ",[41,697,698],{},"자신만의 메모리 공간이 있다고 생각하게 만드는 기술","입니다.",[59,701,704],{"className":702,"code":703,"language":64,"meta":65},[62],"Process A\n\n0x0000\n0x0001\n0x0002\n...\n\nProcess B\n\n0x0000\n0x0001\n0x0002\n...\n",[14,705,703],{"__ignoreMap":65},[10,707,708],{},"둘 다 같은 주소를 사용하는 것처럼 보이지만 Kernel이 실제 RAM 주소로 변환합니다.",[59,710,713],{"className":711,"code":712,"language":64,"meta":65},[62],"Process Virtual Address\n\n       ↓\n\nKernel\n\nPage Table\n\n       ↓\n\nPhysical RAM\n",[14,714,712],{"__ignoreMap":65},[10,716,717],{},"덕분에:",[59,719,722],{"className":720,"code":721,"language":64,"meta":65},[62],"Process A\n",[14,723,721],{"__ignoreMap":65},[10,725,726],{},"가",[59,728,731],{"className":729,"code":730,"language":64,"meta":65},[62],"Process B\n",[14,732,730],{"__ignoreMap":65},[10,734,735],{},"의 메모리를 마음대로 읽지 못합니다.",[10,737,738,739,699],{},"즉 ",[41,740,741],{},"프로세스 격리의 핵심 기술 중 하나",[90,743],{},[46,745,747],{"id":746},"_13-file-system","13. File System",[10,749,750],{},[41,751,752],{},"File System = 파일과 디렉터리를 저장하고 관리하는 방식",[10,754,755],{},"Linux:",[59,757,760],{"className":758,"code":759,"language":64,"meta":65},[62],"\u002F\n├── bin\n├── etc\n├── home\n├── usr\n├── var\n└── tmp\n",[14,761,759],{"__ignoreMap":65},[10,763,764],{},"Docker 컨테이너도 자기만의 파일시스템이 있는 것처럼 보인다.",[59,766,769],{"className":767,"code":768,"language":64,"meta":65},[62],"Container A\n\n\u002F\n├── bin\n├── app\n└── etc\n\nContainer B\n\n\u002F\n├── bin\n├── app\n└── etc\n",[14,770,768],{"__ignoreMap":65},[10,772,773],{},"하지만 실제로는 Linux Kernel의 Filesystem 기능과 Namespace를 이용합니다.",[90,775],{},[46,777,779],{"id":778},"_14-file-descriptor","14. File Descriptor",[10,781,782],{},"File Descriptor는 Linux에서 중요한 개념입니다.",[10,784,785],{},[41,786,787],{},"File Descriptor = 프로세스가 열어놓은 파일이나 I\u002FO 자원을 나타내는 번호",[10,789,790],{},"기본적으로:",[59,792,795],{"className":793,"code":794,"language":64,"meta":65},[62],"0 = stdin\n1 = stdout\n2 = stderr\n",[14,796,794],{"__ignoreMap":65},[10,798,799],{},"그래서:",[59,801,803],{"className":106,"code":802,"language":108,"meta":65,"style":65},"echo hello\n",[14,804,805],{"__ignoreMap":65},[112,806,807,810],{"class":114,"line":115},[112,808,809],{"class":353},"echo",[112,811,812],{"class":122}," hello\n",[10,814,815],{},"를 실행하면:",[59,817,820],{"className":818,"code":819,"language":64,"meta":65},[62],"Process\n   ↓\nstdout\nFD 1\n   ↓\nTerminal\n",[14,821,819],{"__ignoreMap":65},[10,823,824],{},"Docker가 로그를 받을 수 있는 것도 이 구조와 관련이 있습니다.",[59,826,829],{"className":827,"code":828,"language":64,"meta":65},[62],"Container nginx\n\nstdout\nstderr\n   ↓\ncontainerd-shim\n   ↓\nDocker logs\n",[14,830,828],{"__ignoreMap":65},[90,832],{},[46,834,836],{"id":835},"_15-socket","15. Socket",[10,838,839],{},[41,840,841],{},"Socket = 네트워크 통신을 위한 프로세스의 통신 endpoint",[10,843,844],{},"Spring 서버가:",[59,846,849],{"className":847,"code":848,"language":64,"meta":65},[62],"localhost:8080\n",[14,850,848],{"__ignoreMap":65},[10,852,853],{},"에서 기다린다고 하면:",[59,855,858],{"className":856,"code":857,"language":64,"meta":65},[62],"Spring Process\n\nSocket\nIP : 0.0.0.0\nPort : 8080\n",[14,859,857],{"__ignoreMap":65},[10,861,862],{},"클라이언트가 연결하면:",[59,864,867],{"className":865,"code":866,"language":64,"meta":65},[62],"Browser\n   ↓\nTCP\n   ↓\nSocket :8080\n   ↓\nSpring Process\n",[14,868,866],{"__ignoreMap":65},[10,870,871],{},"Docker에서는 Network Namespace를 이용해서 컨테이너마다 네트워크 환경을 분리합니다.",[90,873],{},[46,875,877],{"id":876},"_16-port","16. Port",[10,879,880],{},[41,881,882],{},"Port = 한 컴퓨터에서 어떤 프로세스로 네트워크 데이터를 전달할지 구분하는 번호",[59,884,887],{"className":885,"code":886,"language":64,"meta":65},[62],"Computer\nIP 192.168.0.10\n\n22   → SSH\n80   → nginx\n3306 → MySQL\n8080 → Spring\n",[14,888,886],{"__ignoreMap":65},[10,890,891],{},"Docker:",[59,893,895],{"className":106,"code":894,"language":108,"meta":65,"style":65},"docker run -p 8080:80 nginx\n",[14,896,897],{"__ignoreMap":65},[112,898,899,901,903,906,909],{"class":114,"line":115},[112,900,347],{"class":118},[112,902,350],{"class":122},[112,904,905],{"class":353}," -p",[112,907,908],{"class":122}," 8080:80",[112,910,357],{"class":122},[10,912,913],{},"이면:",[59,915,918],{"className":916,"code":917,"language":64,"meta":65},[62],"Host\n\n8080\n ↓\nDocker Network\n ↓\nContainer\n80\n ↓\nnginx\n",[14,919,917],{"__ignoreMap":65},[90,921],{},[46,923,925],{"id":924},"_17-namespace","17. Namespace",[10,927,928],{},"Namespace는 Docker의 격리 구조를 이해할 때 매우 중요합니다.",[10,930,931],{},[41,932,933],{},"Namespace = 프로세스가 볼 수 있는 시스템 자원을 격리하는 Linux Kernel 기능",[10,935,57],{},[59,937,940],{"className":938,"code":939,"language":64,"meta":65},[62],"PID Namespace\n→ 다른 프로세스 안 보이게\n\nNetwork Namespace\n→ 네트워크 따로\n\nMount Namespace\n→ 파일시스템 따로\n\nUTS Namespace\n→ hostname 따로\n\nIPC Namespace\n→ IPC 따로\n",[14,941,939],{"__ignoreMap":65},[10,943,944],{},"이러한 격리를 통해 컨테이너는 다음과 같이 독립된 환경을 사용하는 것처럼 느낍니다.",[59,946,949],{"className":947,"code":948,"language":64,"meta":65},[62],"\"나 혼자 컴퓨터를 사용하는 것 같은데?\"\n",[14,950,948],{"__ignoreMap":65},[10,952,953],{},"라고 느끼게 만듭니다.",[90,955],{},[46,957,959],{"id":958},"_18-cgroup","18. cgroup",[10,961,962],{},[41,963,964],{},"cgroup = 프로세스가 사용할 수 있는 자원의 양을 제한하고 측정하는 Linux Kernel 기능",[59,966,969],{"className":967,"code":968,"language":64,"meta":65},[62],"Container A\n\nCPU ≤ 2 Core\nMemory ≤ 2GB\n\nContainer B\n\nCPU ≤ 4 Core\nMemory ≤ 8GB\n",[14,970,968],{"__ignoreMap":65},[10,972,973],{},"Kernel이 실제로 자원 사용량을 제한합니다.",[59,975,978],{"className":976,"code":977,"language":64,"meta":65},[62],"Process\n   ↓\ncgroup\n   ↓\nCPU \u002F RAM 제한\n",[14,979,977],{"__ignoreMap":65},[10,981,799],{},[59,983,986],{"className":984,"code":985,"language":64,"meta":65},[62],"Namespace\n= 무엇을 볼 수 있는가\n\ncgroup\n= 얼마나 사용할 수 있는가\n",[14,987,985],{"__ignoreMap":65},[10,989,990],{},"이렇게 구분하면 두 개념을 쉽게 이해할 수 있습니다.",[90,992],{},[46,994,996],{"id":995},"_19-context-switch","19. Context Switch",[10,998,999],{},"CPU 하나가 여러 프로세스를 실행할 때 아주 빠르게 실행 대상을 바꾼다.",[59,1001,1004],{"className":1002,"code":1003,"language":64,"meta":65},[62],"CPU\n\n시간 →\n\nProcess A\n        Process B\n                  Process C\n                            Process A\n",[14,1005,1003],{"__ignoreMap":65},[10,1007,1008],{},"전환할 때 CPU 상태를 저장하고 다시 불러와야 합니다.",[10,1010,1011,1012,1015],{},"이 과정을 ",[41,1013,1014],{},"Context Switch","라고 합니다.",[10,1017,1018,1019,1022],{},"Context Switch가 너무 많으면 성능 비용, 즉 ",[41,1020,1021],{},"Overhead","가 발생합니다.",[90,1024],{},[46,1026,1028],{"id":1027},"_20-전체-연결","20. 전체 연결",[10,1030,1031],{},"지금까지 살펴본 개념을 하나로 연결하면 다음과 같습니다.",[59,1033,1036],{"className":1034,"code":1035,"language":64,"meta":65},[62],"                   Application\n              Spring \u002F nginx \u002F DB\n                       │\n                       │ Process\n                       ▼\n              ┌─────────────────┐\n              │   User Space    │\n              │                 │\n              │ Process         │\n              │ ├─ Thread       │\n              │ ├─ Stack        │\n              │ ├─ Heap         │\n              │ ├─ Socket       │\n              │ └─ File         │\n              └────────┬────────┘\n                       │\n                   System Call\n                       │\n───────────────────────┼────────────────────\n                       ▼\n              ┌─────────────────┐\n              │  Linux Kernel   │\n              │                 │\n              │ Process 관리    │\n              │ Memory 관리     │\n              │ Filesystem      │\n              │ Network         │\n              │ Namespace       │\n              │ cgroup          │\n              └────────┬────────┘\n                       │\n───────────────────────┼────────────────────\n                       ▼\n              ┌─────────────────┐\n              │    Hardware     │\n              │                 │\n              │ CPU             │\n              │ RAM             │\n              │ SSD             │\n              │ Network Card    │\n              └─────────────────┘\n",[14,1037,1035],{"__ignoreMap":65},[10,1039,1040],{},"그리고 Docker를 여기다 올리면:",[59,1042,1045],{"className":1043,"code":1044,"language":64,"meta":65},[62],"Docker\n\ndocker run nginx\n        ↓\ndockerd\n        ↓\ncontainerd\n        ↓\nrunc\n        ↓\n\nLinux Kernel\n\nNamespace 설정\ncgroup 설정\nrootfs 설정\n        ↓\n\nnginx Process\n        ↓\n\nCPU \u002F RAM \u002F Network \u002F Disk 사용\n",[14,1046,1044],{"__ignoreMap":65},[46,1048,1050],{"id":1049},"학습-우선순위","학습 우선순위",[10,1052,1053,1054],{},"처음부터 전부 외울 필요는 없습니다. ",[41,1055,1056],{},"아래 순서대로 개념의 연결 관계를 익히는 것을 추천합니다.",[59,1058,1061],{"className":1059,"code":1060,"language":64,"meta":65},[62],"1. Program\n   ↓\n2. Process\n   ↓\n3. Thread\n   ↓\n4. CPU\n   ↓\n5. Memory\n   ↓\n6. Kernel\n   ↓\n7. User Space \u002F Kernel Space\n   ↓\n8. System Call\n   ↓\n9. Filesystem\n   ↓\n10. Network \u002F Socket \u002F Port\n    ↓\n11. Namespace\n    ↓\n12. cgroup\n",[14,1062,1060],{"__ignoreMap":65},[10,1064,1065],{},"특히 Docker를 공부하고 있다면 다음 관계를 먼저 기억하면 됩니다.",[59,1067,1070],{"className":1068,"code":1069,"language":64,"meta":65},[62],"Program\n→ 실행하면 Process\n\nProcess\n→ CPU에서 실행되고 Memory를 사용함\n\nKernel\n→ Process와 CPU\u002FMemory\u002FNetwork를 관리함\n\nDocker Container\n→ Kernel이 실행하는 Process를\n   Namespace로 격리하고\n   cgroup으로 자원을 제한한 것\n",[14,1071,1069],{"__ignoreMap":65},[10,1073,1074,1075,699],{},"이 ",[41,1076,1077],{},"4줄이 Docker를 이해하기 위한 운영체제 기초의 핵심",[1079,1080,1081],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}",{"title":65,"searchDepth":252,"depth":252,"links":1083},[1084,1085,1086,1087,1088,1089,1090,1091,1092,1093,1094,1095,1096,1097,1098,1099,1100,1101,1102,1103,1104],{"id":48,"depth":252,"text":49},{"id":94,"depth":252,"text":95},{"id":178,"depth":252,"text":179},{"id":229,"depth":252,"text":230},{"id":302,"depth":252,"text":303},{"id":372,"depth":252,"text":373},{"id":412,"depth":252,"text":413},{"id":452,"depth":252,"text":453},{"id":507,"depth":252,"text":508},{"id":573,"depth":252,"text":574},{"id":635,"depth":252,"text":636},{"id":691,"depth":252,"text":692},{"id":746,"depth":252,"text":747},{"id":778,"depth":252,"text":779},{"id":835,"depth":252,"text":836},{"id":876,"depth":252,"text":877},{"id":924,"depth":252,"text":925},{"id":958,"depth":252,"text":959},{"id":995,"depth":252,"text":996},{"id":1027,"depth":252,"text":1028},{"id":1049,"depth":252,"text":1050},[1106,1107],"Basic","OS","2026-08-24 00:10:00 +0900","Program, Process, CPU, Memory, Kernel부터 Namespace와 cgroup까지 Docker 학습에 필요한 운영체제 핵심 개념을 흐름에 따라 정리한다.","md",null,"\u002Fbasic\u002Fos\u002F2026\u002F08\u002F24\u002Fdocker-os-basics\u002F",{"layout":1114},"post",true,"\u002Fposts\u002Fbasic\u002F2026-08-24-docker-os-basics",{"title":5,"description":1109},"posts\u002FBasic\u002F2026-08-24-docker-os-basics",[1107,1120,1121,16,20,1122,366],"Linux","Docker","Namespace","wdaSS4FnM4_mqUCSev1sOiiFtEoVPG4ZH7d9V2Dg8q4",1788744787246]