쿼츠 블로그를 위해 대공사

This commit is contained in:
2026-04-08 13:07:41 +09:00
parent 123642831e
commit 1319881195
606 changed files with 50625 additions and 2 deletions
@@ -0,0 +1,15 @@
1. [[단순함의 노하우(Introduction)]]
2. [[80대20 원칙(The Pareto Principle)]]
3. [[최소 기능 제품 (MVP)]]
4. [[코딩 원칙 (YAGNI, KISS, DRY)]]
5. [[유닉스 철학 (The Unix Philosophy)]]
6. [[설계와 추상화]]
7. [[디버깅과 테스트]]
8. [[협업과 지속 가능한 개발]]
@@ -0,0 +1,13 @@
[[꼭 알아둬야 할 것들]]
[[AWS Architecture로의 전환이 필요한 이유]] (As-Is)
[[온프레미스에서 EC2 기반으로]]
[[컨테이너 기반의 아키텍처]] (To-Be)
[[ECS와 EKS]]
[[EKS Cluster]]
[[AWS ECS 구성하기]]
@@ -0,0 +1,27 @@
---
id: "CMMS 마이그레이션 20260319"
created: "2026-03-19 12:58"
tags:
aliases:
---
마이그레이션: 신규 고객의 셋업작업 진행 시 필요한 데이터를 DB로 밀어넣는 과정
엑셀파일로 된 마이그레이션 필요 문서 작성 (담당자가 따로있나봄)
(원본엑셀 -> 마이그레이션 할 데이터 엑셀 )
/auth/fullmigration
( CMMS 엔터프라이즈형은 /auth/mig )
마이그레이션 페이지가 따로 만들어져있음.
여기서 엑셀파일들을 전부 다 execute migration 진행해줘야 함
너무 많은 데이터를 한번에 시도하면 문제가 될 수 있어서
분리해서 진행해야함.
파일 마이그레이션은 암호화(확장자없는) 파일을 먼저 만들고 (엑셀파일부터 작성)
...? 그다음에 뭘 또 해야한다는데 이건 이해 못함
shared-service: 마이그레이션, open API (우리는 일단 신경x) 등등의 기능들을 처리해주는 서비스
+2
View File
@@ -0,0 +1,2 @@
[[VPN으로 외부 DB에 접근]]
@@ -0,0 +1,74 @@
---
id: "Gitea & Quartz 배포 자동화 트러블슈팅 20260401"
created: "2026-04-01 13:23"
tags:
---
## 🛠️ Gitea & Quartz 배포 자동화 트러블슈팅 기록
### 1. 문제의 발단: Gitea 경로 변경 (`/git/` 누락)
기존에 설정된 Gitea의 접속 주소가 `/git/` 경로를 포함하고 있었으나, 서버 재설정 과정에서 이 경로가 빠지게 되었습니다. 이로 인해 연쇄적인 문제가 발생했습니다.
- **현상:** Gitea 웹훅(Webhook)이 서버의 수신기(`webhook` 서비스)에 신호를 보내지 못함.
- **원인:** Gitea 내부 리포지토리 설정과 외부 호출 URL이 일치하지 않아 404 에러 또는 연결 거부 발생.
---
### 2. 주요 장애 요인 및 해결 과정
#### 📂 [Level 1] 서비스 실행 실패 (ConditionPathExists)
- **에러:** `webhook.service was skipped because of an unmet condition check`.
- **원인:** 기본 설치된 `webhook` 서비스가 `/etc/webhook.conf` 파일이 있어야만 작동하도록 설정됨.
- **해결:** 서비스 파일(`systemd`)을 수정하여 해당 조건을 삭제하고, 우리가 직접 만든 `hooks.json`을 바라보도록 설정함.
#### 🔑 [Level 2] 인증 에러 (no source for value retrieval)
- **에러:** `500 | error evaluating hook: no source for value retrieval`.
- **원인:** `hooks.json`에는 비밀번호(Secret) 검사 로직이 있는데, Gitea 웹훅 설정에는 비밀번호가 비어 있거나 헤더 이름이 일치하지 않음.
- **해결:** 보안을 위해 Gitea와 서버 양쪽에 동일한 비밀번호를 설정하거나, 테스트를 위해 `trigger-rule`을 삭제하여 문턱을 낮춤.
#### 🚀 [Level 3] 스크립트 실행 환경 문제 (npx & node)
- **에러:** `npx: command not found` 또는 `node: No such file or directory`.
- **원인:** `systemd` 서비스는 사용자 터미널 환경변수(`PATH`)를 읽지 못해 NVM에 설치된 Node.js를 찾지 못함.
- **해결:** `deploy.sh` 상단에 Node.js 실행 파일이 있는 **절대 경로**를 `export PATH`로 직접 주입함.
#### 📉 [Level 4] 자원 부족 및 서버 경직 (kswapd0)
- **현상:** 빌드 시작 시 서버가 급격히 느려지며 접속이 끊김.
- **원인:** Quartz 빌드는 CPU와 메모리를 많이 사용하는데, 512MB~1GB 수준의 낮은 메모리로 인해 스왑(Swap) 현상이 심화됨.
- **해결:** 1. **Swap 확장:** 기존 스왑 파일을 **2GB**로 대폭 확장하여 물리 메모리 부족에 대비함.
2. **우선순위 조정:** 빌드 명령어 앞에 **`nice -n 19`**를 붙여 다른 서비스(Nginx, Gitea)에 영향을 주지 않도록 최적화함.
---
### 3. 최종 자동화 아키텍처 (The "Tight" Setup)
|**구성 요소**|**역할**|**최적화 포인트**|
|---|---|---|
|**Gitea**|소스 관리 및 트리거|`/git/` 경로를 제외한 클린 URL 적용|
|**Webhook**|신호 수신기 (Port 29292)|전용 서비스 등록 및 자동 시작 설정|
|**deploy.sh**|배포 스크립트|**절대 경로 사용**, **로그 파일 기록**, **우선순위 최저 설정**|
|**Swap File**|가상 메모리 (2GB)|`/etc/fstab` 등록을 통한 영구 적용|
---
### 📝 교훈
> **경로(Path)와 환경(Environment)은 언제나 명시적이어야 한다.** > 공짜 서버일수록 수동으로 자원을 배분하고 우선순위를 관리하는 **빡빡한 최적화**가 시스템의 생명줄이 된다.
+38
View File
@@ -0,0 +1,38 @@
![[Pasted image 20260407165750.png]]
/home/dihwang/webhook/deploy.sh
```bash
#!/bin/bash
if [ -f /tmp/quartz.lock ]; then exit; fi
# 1. Node와 npx가 있는 경로를 강제로 주입 (v22.22.2 기준)
export PATH=$PATH:/home/dihwang/.nvm/versions/node/v22.22.2/bin
# 2. 작업 디렉토리로 이동
cd /home/dihwang/white-smith-blog/content || exit
# 3. 최신 데이터 동기화
git pull origin master
cd ..
# 4. Quartz 빌드 (이제 npx가 node를 잘 찾을 겁니다)
nice -n 19 npx quartz build
echo "Quartz Build Completed at $(date)"
```
/home/dihwang/webhook/hook.json
```json
[
{
"id": "quartz-deploy",
"execute-command": "/home/dihwang/webhook/deploy.sh",
"command-working-directory": "/home/dihwang/white-smith-blog",
"response-message": "Deploying Quartz...",
}
]
```
+239
View File
@@ -0,0 +1,239 @@
---
id: "gitea, qurtz 설치 20260331"
created: "2026-03-31 10:41"
tags:
---
# 🌐 개인 서버(GCP) 기반 Gitea & HTTPS 구축 가이드
본 문서는 Ubuntu 25.xx 환경에서 가벼운 Git 서비스인 **Gitea**를 설치하고, **Nginx**와 **DuckDNS**를 이용해 **HTTPS** 보안 접속을 구현한 과정을 정리합니다.
## 1. 서버 기본 환경 및 Gitea 설치
가장 가벼운 바이너리 실행 방식으로 Gitea를 설치하고 전용 사용자를 생성했습니다.
- **OS:** Ubuntu 25.xx (GCP Instance)
- **사용자 생성:** `git` 시스템 사용자 생성 (`/home/git`)
- **DB:** SQLite3 (경량화를 위해 선택)
- **바이너리 경로:** `/usr/local/bin/gitea`
- **데이터 경로:** `/var/lib/gitea`
---
## 2. 도메인 및 네트워크 설정
외부 접속을 위해 무료 DDNS 주소를 확보하고 클라우드 방화벽을 조정했습니다.
- **도메인:** `white-smith.duckdns.org` (GCP 외부 IP 연결 완료)
- **포트 개방 (GCP & UFW):**
- `22/tcp`: SSH 접속 (PuTTY, SFTP)
- `80/tcp`: HTTP (인증서 발급 및 리다이렉트용)
- `443/tcp`: HTTPS (실제 서비스용)
- **보안 조치:** 불필요한 포트(20, 21, 3389 등) 차단 및 Gitea 직접 포트(3000)는 Nginx를 거치도록 외부 차단 권장.
---
## 3. HTTPS & Nginx 리버스 프록시
Nginx를 앞단에 세워 보안을 강화하고 도메인 기반 접속을 구현했습니다.
### SSL 인증서 발급
`Certbot`을 이용해 **Let's Encrypt** 무료 SSL 인증서를 발급받았습니다.
Bash
```
sudo certbot --nginx -d white-smith.duckdns.org
```
### Nginx 최종 설정 (`/etc/nginx/sites-available/gitea`)
IP 접속 시 도메인으로 자동 전환되도록 설정했습니다.
Nginx
```
# 1. HTTP -> HTTPS 리다이렉트 (IP 포함)
server {
listen 80;
server_name 34.19.79.94 white-smith.duckdns.org;
return 301 https://white-smith.duckdns.org$request_uri;
}
# 2. HTTPS 서비스 블록
server {
listen 443 ssl;
server_name white-smith.duckdns.org;
# SSL 인증서 경로 (Certbot 관리)
ssl_certificate /etc/letsencrypt/live/white-smith.duckdns.org/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/white-smith.duckdns.org/privkey.pem;
location / {
proxy_pass http://localhost:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
```
---
## 4. Gitea 내부 설정 업데이트
HTTPS 환경에 맞춰 `/etc/gitea/app.ini` 파일을 `vi`로 수정했습니다.
- **ROOT_URL:** `https://white-smith.duckdns.org/`
- **DOMAIN:** `white-smith.duckdns.org`
- **SSH_DOMAIN:** `white-smith.duckdns.org`
---
## 5. 현재 상태 요약
1. **HTTPS 접속:** `https://white-smith.duckdns.org`로 안전하게 접속 가능.
2. **IP 리다이렉트:** `34.19.79.94` 입력 시 자동으로 도메인 주소로 전환됨.
3. **파일 전송:** 포트 22번을 통해 SFTP 방식으로 안전하게 파일 관리 중.
# 🚀 Gitea & Quartz 도메인 통합 및 서버 설정 가이드
본 가이드는 단일 메인 도메인(`white-smith.duckdns.org`)에서 **Quartz(블로그)**와 **Gitea(Git 서비스)**를 충돌 없이 운영하기 위한 설정법을 다룹니다.
---
## 1. 서비스 주소 설계
동일 도메인 점유 문제를 해결하기 위해 **하위 경로(Path)** 방식으로 서비스를 분리했습니다.
- **Quartz (메인 블로그):** `https://white-smith.duckdns.org/`
- **Gitea (코드 저장소):** `https://white-smith.duckdns.org/git/`
---
## 2. Gitea 설정 수정 (`app.ini`)
Gitea가 `/git/` 경로를 인식하도록 내부 설정을 변경해야 합니다.
- **파일 위치:** `/var/lib/gitea/custom/conf/app.ini` (또는 설치 경로 내 `custom/conf/app.ini`)
- **수정 내용:**
Ini, TOML
```
[server]
ROOT_URL = https://white-smith.duckdns.org/git/
LOCAL_ROOT_URL = http://127.0.0.1:3000/
HTTP_ADDR = 127.0.0.1
HTTP_PORT = 3000
```
> **Tip:** `LOCAL_ROOT_URL`을 추가해야 내부 리다이렉션 시 404 오류를 방지할 수 있습니다.
---
## 3. Nginx 역방향 프록시 설정
`/etc/nginx/sites-available/gitea` 파일을 수정하여 두 서비스를 통합합니다.
Nginx
```
server {
listen 80;
server_name 34.19.79.94 white-smith.duckdns.org;
return 301 https://white-smith.duckdns.org$request_uri;
}
server {
listen 443 ssl;
server_name white-smith.duckdns.org;
ssl_certificate /etc/letsencrypt/live/white-smith.duckdns.org/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/white-smith.duckdns.org/privkey.pem;
# [우선순위 1] Gitea 설정
location /git/ {
proxy_pass http://127.0.0.1:3000/; # 끝에 '/' 필수
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# [우선순위 2] Quartz 설정 (메인)
location / {
proxy_pass http://127.0.0.1:8080; # Quartz 실행 포트
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
```
---
## 4. 권한 관리 및 접근 (etc 경로)
시스템 설정 파일을 편리하게 수정하기 위해 권한을 조정하거나 도구를 활용합니다.
1. **권한 변경 (추천):**
Bash
```
sudo chown -R root:$(whoami) /etc/nginx
sudo chmod -R 775 /etc/nginx
```
2. **포트 확인 명령어:**
Bash
```
sudo ss -tulpn | grep node # Quartz 포트 확인
```
3. **서비스 재시작:**
Bash
```
sudo nginx -t && sudo systemctl restart nginx
sudo systemctl restart gitea
```
---
## 5. 핵심 주의사항
- **Nginx 경로 슬래시:** `proxy_pass http://127.0.0.1:3000/;` 처럼 끝에 `/`가 있어야 `/git/` 경로가 중복되지 않고 올바르게 전달됩니다.
- **Quartz 실행:** Quartz를 `npx quartz build --serve`로 띄운 경우 해당 포트(보통 8080)가 Nginx 설정과 일치해야 합니다.
- **보안:** `/etc` 전체 권한을 `777`로 바꾸지 마세요. 필요한 폴더만 그룹 권한을 부여하는 것이 안전합니다.
+51
View File
@@ -0,0 +1,51 @@
---
id: "kui-vault 20260401"
created: "2026-04-01 14:59"
tags:
---
**Google Cloud Platform(GCP)** 를 사용해서 구축함.
### 컴퓨팅 (Compute)
사용자가 코드를 실행할 공간을 제공합니다.
- **Compute Engine (GCE):** 가상 머신(VM)을 직접 생성하고 관리하는 IaaS 서비스입니다. (AWS의 EC2와 유사)
GCE를 한대 빌려서 구축하였음
![[Pasted image 20260401150036.png]]
원래는 퍼블릭하게 공개되면 안되는 자료들을 블러처리해주는 서버를 만들려고 (kui-veil) 확보한 서버였음
![[Pasted image 20260401163033.png]]
## 🖥️ Server Information: **kui-veil**
#### 1. 기본 호스트 정보
| **항목** | **내용** |
| ---------------------- | ---------------------------------- |
| **Static Hostname** | (unset) |
| **Transient Hostname** | **kui-veil** |
| **Machine ID** | `b723eb615fc74ff3ac0de806f770d293` |
| **Boot ID** | `2ce0c86e6d704281a6c28054cc4eba0e` |
#### 2. 운영체제 및 커널
|**항목**|**내용**|
|---|---|
|**Operating System**|**Ubuntu 25.10**|
|**Kernel Version**|**Linux 6.17.0-1007-gcp**|
|**Architecture**|**x86-64** (64비트)|
#### 3. 하드웨어 및 가상화 (GCP)
|**항목**|**내용**|
|---|---|
|**Virtualization**|**google** (Google Compute Engine)|
|**Hardware Vendor**|**Google**|
|**Chassis**|**vm** 🖴|
|**Firmware Date**|2026-02-12 (약 1.5개월 전)|
### 💡 주요 특징 메모
- **최신 버전 사용 중:** 현재 **Ubuntu 25.10**을 사용 중이시네요. 이는 매우 최신 배포판으로, 최신 커널 기능과 패키지들을 지원합니다.
- **GCP 최적화:** 커널 이름에 `-gcp`가 붙어 있어, 구글 클라우드 인프라에 최적화된 환경에서 동작하고 있음을 알 수 있습니다.
- **상태 요약:** 펌웨어 날짜가 2026년 2월인 것으로 보아, 시스템이 최근에 업데이트되었거나 생성된 아주 따끈따끈한 환경입니다!
+1
View File
@@ -0,0 +1 @@
[[안드로이드 스튜디오 무선디버깅]]
@@ -0,0 +1,6 @@
[[리눅스(Linux)]]
[[리눅스의 파일시스템]]
[[유닉스(Unix)]]
[[유닉스 철학 (The Unix Philosophy)]]
+3
View File
@@ -0,0 +1,3 @@
---
title: 1. 프로젝트
---
@@ -0,0 +1,12 @@
As-Is
![[Pasted image 20260227093328.png]]https://wk.wecmms.com
https://innox.wecmms.com
### EC2기반의 아키텍처에는 다음의 한계들을 가짐
![[EC2기반 아키텍처의 한계점]]
### 한계를 극복하기 위해 나아가야 할 방향
[[서버리스(Serverless)]] 구성
: AWS가 제공해주는 [[파게이트(Fargate)]]로 구성한다.
@@ -0,0 +1,28 @@
---
id: "AWS ECS 구성하기 20260305"
created: "2026-03-05 13:29"
tags:
---
### ECS
![[ECS와 EKS#ECS(Elastic Container Service)]]
[[태스크(Task)]] 구성
1) 고객이 완벽한 물리적인 격리를 원할 경우: 3. ECS 클러스터 만들기부터 진행
2) 고객이 별도의 물리적인 격리를 원하지 않을 경우: 4. ECS 서비스 만들기부터 진행
## 🔢 목록
#### 1. [[ECS와 EKS]]
#### 2. [[ECS의 구성]]
#### 3. [[ECS 클러스터 만들기]]
#### 4. [[ECS 서비스 만들기]]
만약 [[ECR(Elastic Container Registry)]]에 등록된 컨테이너 이미지가 없다면?
이미지부터 만들어야 합니다. (도커에 대한 이해가 필요)
#### 5. [[테넌시(Tenancy)]]
- [[테넌시 구성 가이드]]
@@ -0,0 +1 @@
VPC
@@ -0,0 +1 @@
## 1.
@@ -0,0 +1,64 @@
---
id: 서비스 만들기 20260305
created: 2026-03-05 08:38
tags:
---
> [!abstract]
> [[클러스터(Cluster)]] 내부에서 동작하는 서비스를 만듭니다.
> ECS 서비스는 **"데이터 플레인 위에서 태스크가 잘 돌아가게 감시하는 역할"**을 합니다.
> [!check]
> - **개수 유지:** "태스크 3개를 항상 띄워줘"라고 설정하면, 하나가 죽었을 때 데이터 플레인(서버) 위에 새로운 태스크를 다시 올립니다.
>
> - **로드 밸런싱:** 들어오는 트래픽을 여러 태스크에 골고루 나눠줍니다.
>
> - **배포 관리:** 새로운 버전의 태스크 정의가 나오면, 기존 태스크를 하나씩 끄고 새 버전으로 교체합니다.
>
## 🔢 목록
#### 1. 서비스의 [[태스크(Task)]] 정의
![[Pasted image 20260305084812.png]]
만약 정의한 [[태스크(Task)]]가 없다면 태스크부터 정의해야 합니다.
[[ECS 태스크 만들기]]
태스크를 기반으로 ECS의 서비스가 가동되어집니다.
> [!question]
> [[태스크 정의 패밀리]]가 뭐지?
태스크 정의 패밀리를 선택하면 그 패밀리의 최신 버전이 자동으로 태스크 정의 개정에 등록됩니다.
서비스 이름을 마저 지정합니다.
#### 2. 컴퓨팅 구성 선택
![[Pasted image 20260305102304.png]]
클러스터명은 변경할 수 없어서 비활성화 되어있는 것
[[시작 유형(Launch Type)과 용량 공급자 전략(Capacity Provider Strategy)의 차이]]
참고해서 설정하면 됩니다.
#### 3. 문제 해결 구성 설정
> [!info] 개발(Dev)이나 스테이징(Staging) 환경에서는 무조건 켜두시고, 운영(Prod) 환경에서는 보안 승인을 받은 사람만 쓸 수 있게 [[IAM(Identity and Access Management)]]으로 꽉 잠가두고 켜두시는 것을 추천
![[Pasted image 20260305104853.png]]
#### 4. 배포 구성은 그대로 놔둡니다.
정확한 사용법을 확인하지 못했음.
#### 5. 네트워킹
[[VPC(Virtual Private Cloud)]]와 [[서브넷(Subnet)]], [[보안 그룹(Security Group)]]을 설정합니다.
필요한대로, 원하는대로 설정해줍니다.
#### 6. 로드밸런싱 선택
태스크로의 로드밸런싱이 필요한 경우 체크하고 사용합니다.
여기서 추가해주지 않으면 중간에 추가할 수 없어서 태스크를 새로 만들어야 합니다.
![[Pasted image 20260305110136.png]]
**자동 등록 (Target Group):** 새로운 태스크가 실행되면 ECS 서비스가 알아서 로드 밸런서의 **'대상 그룹(Target Group)'**에 해당 태스크의 IP를 등록해줍니다.**
로드 밸런싱 사용을 체크하지 않을 경우 자동 등록이 되지 않습니다.
서비스를 만들고 나면 서비스 태스크가 정상적으로 실행되기를 기다려야합니다.
![[Pasted image 20260305110258.png]]
만약 태스크 실행이 실패하였다면 태스크정보에서 로그 탭을 확인해야 합니다.
![[Pasted image 20260305111038.png]]
@@ -0,0 +1,24 @@
---
id: 클러스터 만들기 20260305
created: 2026-03-05 08:30
tags:
- cluster
- ecs
---
> [[!]]
## 🔢 목록
#### 1. [[클러스터(Cluster)]] 이름을 정한다.
![[Pasted image 20260305083155.png]]
#### 2. 인프라를 선택해준다.
![[Pasted image 20260305083442.png]]
> [!note]
> 진정한 [[서버리스(Serverless)]] 환경구축을 위해서는 [[파게이트(Fargate)]]전용으로 해준다.
>
#### 3. 나머지는 일단 그대로 둔다.
모니터링, 암호화, 태그는 우선 그대로 둡니다. (추후 필요할 경우 확인 후 설정 필요)
클러스터를 생성하고 서비스를 생성합니다.
[[ECS 서비스 만들기]]
@@ -0,0 +1,46 @@
---
id: ECS 태스크 vs k8s 파드 20260304
created: 2026-03-04 17:22
tags:
- ecs
- container
---
## 💡 생각
결국 태스크와 파드는 같다고 보면된다. 태스크는 ECS에서 쓰고 파드는 EKS에서 쓴다.
## 🤝 ECS 태스크 vs K8s 포드: 공통점
1. **컨테이너의 집합체:** 두 개념 모두 하나 이상의 컨테이너를 포함할 수 있습니다. (예: 메인 앱 + 로그 수집기)
2. **네트워크 공유:** 태스크/포드 내의 컨테이너들은 동일한 IP 주소를 공유하며 `localhost`를 통해 서로 통신합니다.
3. **스토리지 공유:** 태스크/포드 수준에서 정의된 볼륨을 내부 컨테이너들이 함께 마운트해서 쓸 수 있습니다.
4. **생명 주기:** 태스크나 포드가 죽으면 그 안의 컨테이너들도 운명을 같이 합니다.
## 🧐 굳이 차이점을 찾자면? (한 끗 차이)
개념은 같지만, 그것을 **관리하는 방식**에서 이름표가 달라집니다.
- **ECS ([[파게이트(Fargate)]] 기준):** AWS가 서버를 대신 관리해주기 때문에, 사용자가 "난 이만큼의 자원이 필요해"라고 **태스크 단위로 주문서**를 써야 합니다. 그래야 AWS가 그에 딱 맞는 가상 머신을 뒤에서 빌려줄 수 있으니까요.
- **[[쿠버네티스(Kubernetes)]]:** 보통 이미 떠 있는 **노드(Node/서버) 덩어리**가 있고, 파드는 그 안에서 자원을 조금씩 나눠 쓰는 '세입자' 같은 느낌입니다. 그래서 리소스 설정이 '실행 기준'이라기보다 '최대/최소 가이드라인'처럼 느껴질 수 있습니다.
### ECS 태스크 (Task)
ECS는 특히 **Fargate** 모드를 쓸 때, 태스크 전체가 사용할 CPU와 메모리를 **태스크 수준**에서 딱딱하게 결정해야 합니다.
- 예: "이 태스크는 무조건 0.5 vCPU와 1GB 메모리를 점유한다."
- 이 기준이 틀리면 아예 실행이 안 되거나 설정 오류가 납니다. 그래서 질문자님 말씀처럼 "태스크 = 리소스 기준이 명확히 박힌 단위"라는 인상이 강합니다.
### 쿠버네티스 파드 (Pod)
파드도 YAML 설정(Spec) 안에 각 컨테이너가 사용할 `requests`(최소 보장)와 `limits`(최대 제한)를 적습니다.
- 예: "이 컨테이너는 최소 256MB, 최대 512MB 메모리를 쓴다."
- **차이점:** 쿠버네티스는 여러 컨테이너의 합산 리소스를 보고 노드(서버)의 남는 자리에 파드를 '스케줄링'하는 데 집중합니다. ECS보다 설정이 좀 더 유연하고 복잡하게 느껴질 수 있습니다.
@@ -0,0 +1,63 @@
---
id: ECS 태스크 만들기 20260305
created: 2026-03-05 08:49
tags:
---
## 💡 생각
ECS 클러스터의 서비스가 [[태스크(Task)]]를 실행해서 서비스가 구동될 수 있습니다.
## 🔢 목록
#### 1. 태스크 정의하기
태스크는 Amazon **E**lastic **C**ontainer **S**ervice의 태스크 정의 탭에서 정의 가능합니다.
![[Pasted image 20260305085256.png]]
#### 2. [[태스크 정의 패밀리]] 이름 지정
![[Pasted image 20260305085241.png]]
#### 3. 인프라 요구 사항 지정
![[Pasted image 20260305091259.png]]
진정한 [[서버리스(Serverless)]] 환경 구축을 위해서는 AWS [[파게이트(Fargate)]]를 선택합니다.
물론 [[EC2(Elastic Compute Cloud)]]로 지정할수도 있습니다.
#### 4. OS, 아키텍처, 네트워크 모드 지정
[[ECS 태스크 정의]]
![[ECS 태스크 정의#📑 개념]]
![[Pasted image 20260305091749.png]]
여기서는 기본값으로 설정하고 진행했습니다.
#### 5. 태스크 역할 - 조건부 지정
[[태스크 역할과 태스크 실행 역할]]
![[Pasted image 20260305093459.png]]
> [!note] ecsTaskExecutionRole ?
> 사실상 default 역할인 **AmazonECSTaskExecutionRolePolicy**가 연결되어있음
![[Pasted image 20260305094500.png]]
작업 배치 - (선택 사항)
결함 주입 - 선택 사항
는 일단 지정하지 않았습니다. (아직 뭔지 모름)
#### 6. 컨테이너 생성 (1)
컨테이너의 이름과 도커 이미지의 위치를 지정합니다.
![[Pasted image 20260305094813.png]]
도커 이미지는 [[ECR(Elastic Container Registry)]]에 저장되어 있는 것을 가져다가 사용할 수 있고 (추천)
프라이빗 공간의 이미지를 가져다가 쓸 수도 있습니다 (만 추가적인 설정이 필요해 보입니다.)
#### 7. 컨테이너 생성(2)
컨테이너 포트정보를 입력합니다. [[파게이트(Fargate)]]의 경우 컨테이너 포트가 호스트 포트와 반드시 동일해야합니다. (별도로 맞춰줄 필요 없이 컨테이너 포트만 입력하면 알아서 맞춰집니다.)
![[Pasted image 20260305100339.png]]
읽기 전용 루트 파일 시스템
리소스 할당 제한 - 조건부
두가지는 일단 설정하지 않습니다. (아직 잘 모름)
#### 8. 환경 변수 설정
필요한 환경 변수가 있을 경우 추가해줍니다.
![[Pasted image 20260305100917.png]]
추가예시
![[Pasted image 20260305101005.png]]
#### 9. 로그 수집 설정
![[Pasted image 20260305101051.png]]
별도의 로그 수집 정책이 있을 경우 다른 것으로 지정 가능
@@ -0,0 +1,61 @@
---
id: ECS 태스크 정의 20260305
created: 2026-03-05 09:20
tags:
---
---
## 📑 개념
> [!abstract]
> **"실제로 어떤 하드웨어 환경에서 돌아갈지"**와 **"비용 청구서가 어떻게 나올지"**를 결정하는 핵심 데이터
## 1. 운영 체제 및 아키텍처 (OS & Architecture)
여기서 가장 중요한 건 **ARM64(AWS Graviton)**를 선택하느냐 아니냐입니다.
- **설정 내용:** `X86_64` (인텔/AMD 계열) vs `ARM64` (AWS Graviton 계열)
- **무엇이 달라지나:** * **호환성:** 내 도커 이미지를 어떤 CPU용으로 빌드했느냐에 따라 선택해야 합니다. (잘못 선택하면 실행 시 `exec format error`가 나며 죽습니다.)
- **성능:** ARM64(Graviton) 기반 인스턴스는 최신 세대 가상 머신을 사용하여 가성비가 매우 좋습니다.
- **💰 비용 차이:** **매우 중요합니다.** 일반적으로 **ARM64 아키텍처를 선택하면 x86보다 약 20% 정도 저렴**합니다. 똑같은 태스크를 돌려도 아키텍처 설정만 바꾸면 돈을 아낄 수 있습니다. (단, 이미지 빌드도 ARM용으로 해야 함)
---
## 2. 네트워크 모드 (Network Mode)
[[파게이트(Fargate)]]를 사용하신다면 사실상 `awsvpc` 모드로 고정되지만, [[EC2(Elastic Compute Cloud)]] 기반에서는 선택지가 나뉩니다.
- **awsvpc 모드 (Fargate 기본):** * **특징:** 각 태스크가 자신만의 **고유한 Private IP**를 가집니다. 마치 VPC 안에 EC2 인스턴스가 하나 더 들어온 것처럼 행동합니다.
- **장점:** 보안 그룹(Security Group)을 태스크 단위로 촘촘하게 걸 수 있습니다. (A 태스크는 DB 접근 가능, B 태스크는 불가 등)
- **Bridge / Host 모드 (EC2 전용):** * **특징:** 호스트 EC2의 IP와 포트를 공유해서 씁니다.
- **💰 비용 차이:** 네트워크 모드 자체로 돈을 더 받지는 않지만, `awsvpc` 모드 사용 시 발생하는 **데이터 전송 비용(Data Transfer Out)**이나 가용 영역(AZ) 간 통신 비용이 실질적인 비용 차이를 만듭니다.
---
## 3. 리소스 할당 (CPU & Memory)
[[파게이트(Fargate)]] 비용의 핵심입니다. "사용량만큼 낸다"는 말의 정확한 의미는 **"내가 설정한 CPU/메모리 사양만큼 예약해서 낸다"**입니다.
- **착각하기 쉬운 점:** 태스크가 실제로 CPU를 1%만 쓰고 있어도, 설정(예약)을 1 vCPU로 했다면 **1 vCPU만큼의 비용이 꼬박꼬박 나갑니다.** * **차이:** * **설정값:** 0.25 vCPU / 0.5 GB 로 설정하면 가장 저렴합니다.
- **비용 구조:** `(vCPU 가격 * 시간) + (GB당 메모리 가격 * 시간)`.
- 따라서 실제 사용량보다 너무 과하게 설정하면 서버리스인데도 돈이 많이 나올 수 있습니다.
## 📝 노트
> [!note]
> 무엇을 선택해야 유리할까?
| **설정 항목** | **추천 선택지** | **비용/효율 영향** |
| ----------- | ---------- | ------------------------------ |
| **아키텍처** | **ARM64** | **약 20% 저렴**하며 성능도 우수 (강력 추천) |
| **네트워크 모드** | **awsvpc** | 보안 관리가 쉬워지나, ENI 할당 등 관리 요소 발생 |
| **CPU/메모리** | **최소 필요량** | 설정한 수치에 비례해서 초 단위로 과금됨 |
---
+19
View File
@@ -0,0 +1,19 @@
### ECS(Elastic Container Service)
: AWS가 제공해주는 [[컨테이너 오케스트레이션]] 서비스입니다.
### EKS(Elastic kubernetes Service)
: [[쿠버네티스(Kubernetes)]]를 AWS의 다른 서비스들과 연동해서 사용할 수 있게 해주는 AWS 서비스입니다.
> [!note]
>
> - ECS와 EKS는 둘 다 [[컨테이너 오케스트레이션]]을 지원해주는 서비스입니다.
> - 컴퓨팅 자원으로 [[파게이트(Fargate)]]를 지정할 수 있습니다.
> - 표준화된 [[배포 파이프라인(Deployment Pipeline)]]을 사용할 수 있습니다.
ECS와 EKS의 핵심 목표는 ==‘컨테이너 기술의 안정적 운영’==임.
![[ECS와 EKS의 차이점]]
ECS는 AWS기반에서는 비교적 쉽고 빠르게 사용 가능 하지만 다른 환경으로의 이식이 어렵고,
EKS는 러닝커브가 가파르고 복잡도가 높지만 이식성이 매우 높음.
ECS와 EKS는 모두 [[클러스터(Cluster)]] 형태로 구현됨.
+32
View File
@@ -0,0 +1,32 @@
---
id: ECS의 구성 20260304
created: 2026-03-04 16:57
tags:
---
![[ECS와 EKS#ECS(Elastic Container Service)]]
### ECS는 [[클러스터(Cluster)]] 형태로 구성되어집니다.
![[Pasted image 20260304165810.png]]
#### [[클러스터(Cluster)]]
![[클러스터(Cluster)#📑 개념]]
### ECS Cluster는
> [!note]
> 하나의 서버에서 구동중인 [[쿠버네티스(Kubernetes)]] 엔진을 사용하는 것 같은 느낌을 주기위해서 만듭니다.
### Cluster에서 서비스가 동작됩니다.
![[Pasted image 20260304170925.png]]
### 서비스에는 [[태스크(Task)]]가 동작합니다.
![[Pasted image 20260304171641.png]]
> [!note]
> ECS의 태스크에는 태스크가 실행되기 위해 필요한 정보들, 어떤 컨테이너들을 실행해야하는지 등이 정의되어있음.
![[Pasted image 20260304171851.png]]
위와같이 태스크가 어떤 구성으로 동작해야하는지가 기록되어있고
![[Pasted image 20260304171939.png]]
어떤 컨테이너들이 실행되어야 하는지 기재되어있다.
## 💡 생각
즉, 태스크는 쿠버네티스에서 말하는 Pod를 실체화시킨 것
[[ECS 태스크 vs k8s 파드]]
+29
View File
@@ -0,0 +1,29 @@
## 📑 개념
> [!abstract]
> AWS에서 사용할 수 있는 [[컨테이너 오케스트레이션]] 엔진
> 클러스터 형태로 구현해놓았고 그걸 EKS라고 함.
## 📝 노트
> [!note]
>
>EKS Cluster의 구조는 크게 Control Plane과 Data Plane 둘로 나눠집니다.
> Control Plane은 전체적인 지휘소 역할을 하며 오케스트레이션에 필요한 모듈들이 위치하고, Data Plane은 실제 서비스가 돌아가는 자원들이 위치합니다.
>
> 이미지를 보면 5개의 Node가 보이는데 각 노드들을 컨테이너를 담고 있는 가상서버이며 그 위에 실제 서비스 단위인 컨테이너가 구동됩니다.
>
> 각 노드들에는 core-운, swing-cmms, load-balancer 컨테이너들이 구동되고 있습니다.
>
> 로드밸런서는 앞서봤던 Elastic Load Balancer를 가리키는 포인터 역할의 서비스이며 CoreDNS는 클러스터 내부의 통신을 위해 필요한 필수 서비스입니다
>
> Aws에 구현해놓은 cmms 서비스는 현재 이 다섯개의 컨테이너들로 구성되어서 실행되고 있습니다.
>
![[Pasted image 20260227162406.png]]
## EKS Cluster 기반의 아키텍처 구조도
![[Pasted image 20260227163046.png]]
## VPC 범위까지 확대
![[Pasted image 20260227163118.png]]
## 🔗 지식 연결
- **태그:** #cluster #container #kubernetes
- 관련 문서: [[ECS와 EKS의 차이점]] [[쿠버네티스(Kubernetes)]]
+22
View File
@@ -0,0 +1,22 @@
### CMMS의 SaaS 플랫폼화를 해야합니다.
##### 플랫폼화를 할 경우 장점
> [!check]
> - **운영 효율 극대화 및 비용 최적화**
>
> : 기존 EC2 기반의 1:1 관리 방식에서 벗어나 하나의 클러스터에서 여러 테넌트(고객사)를 관리함으로써 운영 공수를 획기적으로 줄입니다.
>
> - **시장 대응 속도(Time-to-Market) 가속화**
>
> : 새로운 고객사가 추가될 때마다 서버를 새로 구축할 필요가 없습니다. 미리 구성된 멀티 테넌시 환경과 커스텀 라우팅을 통해 클릭 몇 번만으로 신규 고객 전용 환경을 즉시 제공(On-boarding)할 수 있어, 비즈니스 기회를 놓치지 않고 빠르게 시장을 확대할 수 있습니다.
>
> - **서비스 안정성 및 보안성 고도화**
>
> : 파드 자동 복구기능을 통해 장애 발생 상황 대응에 인력의 투입이 필요 없어지도록 해줍니다. (관리 포인트가 줄어듦)
> [!note]
>
> - CMMS의 경우 SaaS 플랫폼화가 이미 진행되어있는 상태
> - Enterprize 요금제를 요구하는 고객을 위한 '설치형 구독형' 모델 구축을 위한 Cloud Architecture 화를 진행한 것임
> - 기본형의 SaaS CMMS는 이미 존재함
@@ -0,0 +1,8 @@
## [[EC2(Elastic Compute Cloud)]]
![[EC2(Elastic Compute Cloud)#📑 개념]]
## [[컨테이너(Container)]]
![[컨테이너(Container)#📑 개념]]
## [[파게이트(Fargate)]]
![[파게이트(Fargate)#📑 개념]]
@@ -0,0 +1,33 @@
---
id: 시작 유형(Launch Type)과 용량 공급자 전략(Capacity Provider Strategy)의 차이 20260305
created: 2026-03-05 10:24
tags:
- ecs
- fargate
---
## 💡 생각
그냥 용량 공급자 전략을 써야한다고만 기억하면 됨. (기본값도 용량 공급자 전략으로 되어있음)
> [!note]
> ECS 서비스에서 **시작 유형(Launch Type)**과 **용량 공급자 전략(Capacity Provider Strategy)**은 "내 컨테이너를 어디에 띄울 것인가"를 결정하는 두 가지 방식입니다.
>
> 과거에는 '시작 유형'만 있었지만, 현재는 더 유연한 관리를 위해 '용량 공급자 전략'을 권장하는 추세입니다. 두 방식의 핵심적인 차이를 정리해 드릴게요.
## 1. 시작 유형 (Launch Type) : "단순한 선택"
가장 직관적인 방식입니다. 태스크를 띄울 인프라를 **딱 하나만** 고정해서 선택하는 것입니다.
- **방식:** "나는 무조건 **Fargate**만 쓸 거야" 혹은 "무조건 **EC2**만 쓸 거야"라고 선언합니다.
- **특징:** 설정이 매우 간단하지만, 여러 종류의 인프라를 섞어서 쓰는 것이 불가능합니다.
- **비유:** 식당에 가서 "무조건 소고기 메뉴만 주세요"라고 고정 주문을 하는 것과 같습니다.
## 2. [[용량 공급자 전략 (Capacity Provider Strategy)]] : "유연한 배분"
> [!note] 하나 이상의 인프라(용량 공급자)를 **어떤 비율로 섞어서 쓸지** 결정하는 고도화된 방식입니다.
![[Pasted image 20260305103056.png]]
![[용량 공급자 전략 (Capacity Provider Strategy)#💡 왜 '용량 공급자 전략'을 써야 할까요? (핵심 이유)]]
@@ -0,0 +1,11 @@
순서
## 1. [[VPC(Virtual Private Cloud)]] 생성
## 2. VPC에 [[서브넷(Subnet)]] 생성
: 필요에 따라 퍼블릭,프라이빗 서브넷을 생성하면 됨.
[[Pod를 Private subnet에 두는 이유]]
## 3. 라우팅 테이블 생성
## 4. 인터넷 게이트웨이 생성
## 5. EC2 생성
@@ -0,0 +1,29 @@
To-Be
![[Pasted image 20260227094154.png]]
EC2기반의 아키텍처를 클라우드 컴퓨팅 환경에 맞게 변경한 아키텍처입니다.
다른 부분은 모두 동일하고 [[파게이트(Fargate)]]라고 적혀있는 이 부분만 달라진 것을 확인할 수 있습니다.
[[파게이트(Fargate)의 장점]]
컨테이너 기반의 아키텍처로 변경했을떄의 장점
[[가용성(Availability)]] [[보안성(Security)]]이 확보되고 프로젝트의 [[생산성(Productivity)]]이 증가되고, 프로젝트의 [[유연성(Flexibility)]]과 [[확장성(Scalability)]]확보에 유리해진다.
각각을 현재 상황에맞게 풀어서 설명해보면
[[가용성(Availability)]]: 초기설정을 잘 해 놓으면 [[컨테이너 오케스트레이션]]에 의해 서비스의 자가복구가 가능하다.
[[유연성(Flexibility)]]: 로드밸런서가 컨테이너 단위로의 접근이 가능해서 동일한 내부 포트(예: 80)를 사용하는 여러 서비스를 띄워도, 각 컨테이너가 고유 IP를 가지므로 충돌 없이 동적 라우팅이 가능하다.
[[보안성(Security)]]: [[파게이트(Fargate)]] 이용 시 OS 업데이트, 보안패치 등의 OS/인프라 레벨의 보안을 AWS가 책임져준다.
[[생산성(Productivity)]]: 서버관리 포인트가 줄어들어서 인프라 관리 등의 인프라 운영에 들어가는 반복적인 공수(Heavy Lifting)를 제거하여, 비즈니스 로직 개발 및 서비스 고도화에 인력을 집중 투입할 수 있다.
## 📝 노트
> [!note]
EC2는 가상 컴퓨팅 환경이기 때문에 장애 복구에 많은 시간이 필요하지만 fargate는 컨테이너이므로 수초내에 복구할 수 있습니다.
>
> 컨테이너 자체는 자가복구의 기능이 없지만 뒤에서 설명드릴 ECS나 EKS에서는 가능합니다.
>
> 그리고 로드밸런서가 EC2같은 서버가 아닌 컨테이너를 가리킬 수 있습니다. 그로인해 자주 사용되는 80포트등의 포트들이 중복사용으로 충돌을 일으킬 가능성이 없습니다.
>
> A컨테이너의 80포트, B컨테이너의 80포트 이런식으로 상세하게 설정할 수 있기 떄문입니다.
>
> 그리고 AWS가 보안과 서버인프라 문제를 모두 책임져주기 때문에 생산성 향상이 될 수 있습니다.
@@ -0,0 +1,18 @@
---
id: "태스크 역할과 태스크 실행 역할 20260305"
created: "2026-03-05 09:38"
tags:
---
[[태스크 역할(Task Role)]] vs [[태스크 실행 역할(Task Execution Role)]]
|**구분**|**태스크 실행 역할 (Execution Role)**|**태스크 역할 (Task Role)**|
|---|---|---|
|**누가 쓰는가?**|**ECS 에이전트 / 인프라**|**내 앱 소스 코드 (Container)**|
|**언제 쓰는가?**|태스크를 **준비하고 띄울 때**|태스크가 **실행 중일 때**|
|**필수 여부**|대부분 필수 (이미지 풀, 로그 때문)|선택 (AWS 서비스를 안 쓰면 필요 없음)|
|**예시 정책**|`AmazonECSTaskExecutionRolePolicy`|`AmazonS3FullAccess`, `AmazonDynamoDBReadOnly` 등|
### 💡 실무에서는 어떻게 설정하나용?
1. **실행 역할(Execution Role):** AWS에서 기본으로 제공하는 `AmazonECSTaskExecutionRolePolicy`를 연결해 주는 것이 국룰입니다. (이거 안 하면 로그가 안 남거나 이미지를 못 가져와서 태스크가 무한 재시작됩니다.)
2. **태스크 역할(Task Role):** 기본값은 비어있습니다. 내 앱이 S3나 DynamoDB를 써야 할 일이 생길 때만 필요한 권한을 콕 집어서 추가해 주면 됩니다.
@@ -0,0 +1,47 @@
---
id: 테넌시 선택 20260305
created: 2026-03-05 13:18
tags:
- tenancy
- cluster
- ecs
- ecr
- saas
---
[[싱글 테넌시(Single-tenancy)]] vs [[멀티 테넌시(Multi-tenancy)]]
: 결정적인 차이는 **물리적으로 격리되어있는지** 여부
### [[멀티 테넌시(Multi-tenancy)]]
멀티 테넌시를 선택할 때 가장 중요한 것은 **인프라를 공유한다**는 것입니다.
순수 멀티 테넌시는 하나의 어플리케이션 인스턴스와 하나의 DB를 여러 고객들이 공유해서 사용합니다.
> [!note] 설정값, 환경변수 등의 차이만으로 고객간의 구분을 하고 모든 인프라는 하나를 공유해서 사용
고객간의 요구사항 편차가 적을 경우에는 효율이 좋음
편차가 클 경우 대응이 매우 어렵거나 거의 불가능에 가깝습니다. (고객 수가 적으면 되긴 함)
**SaaS 솔루션:** 완전한 멀티 테넌시 (공통 기능 + DB 설정 기반 커스텀)
즉 SaaS 솔루션은 모든 고객들이 하나의 인프라를 공유해서 사용하는 경우를 의미합니다.
> [!warning] 이렇게 되면 고객간의 요구사항 편차가 클 경우 대응이 불가능함
이 문제를 해결하기 위해 하이브리드 방식을 채택합니다.
**"인프라는 공유하되 애플리케이션은 격리하는 방식"** 같은 경우입니다.
이를 **가상 싱글 테넌시(Virtual Single Tenancy)** 또는 **격리형 멀티 테넌시**라고 부르기도 합니다.
격리형 테넌시 형태로 엔터프라이즈 솔루션 형태로 구성을 해야함.
**엔터프라이즈 솔루션:** 고객별 컨테이너/네임스페이스 분리 + 이미지 커스텀
테넌시별로 별도의 컨테이너 이미지를 확보해야함
코드레벨에서 독립되어지기 때문에 클라우드형 싱글테넌시 구조와 유사한 형태의 서비스가 가능
### 엔터프라이즈 솔루션의 구조도
(고객사별 독립된 어플리케이션 인스턴스 사용 + 하나의 DB 인프라 사용)
![[Pasted image 20260305140832.png]]
VPC레벨까지도 격리를 원하는 고객사의 경우에는 위의 이미지대로 별도의 ECS Cluster를 구성
그정도까지 아니면 하나의 공용 ECS Cluster에 [[태스크(Task)]]만 별도로 추가
## 🔗 관련 노트
- [[클러스터(Cluster)]]
- [[ECR(Elastic Container Registry)]]
@@ -0,0 +1,50 @@
---
id: 80대20 원칙(The Pareto Principle) 20260318
created: 2026-03-18 10:08
tags:
- 클린코드
aliases:
---
## 💡 생각
코드를 단순화하는 것은 어려운 일이기 때문에 모든 코드를 단순화하는 것은 엄청난 낭비가 될 수 있다.
그렇기 때문에 전체 가치의 80%를 창출해내는 20%의 자주 쓰이는 코드를 단순화하는 것에 집중해야 한다.
## 🔗 관련 노트
- [[단순한 코드]], [[파레토의 법칙]](80:20의 법칙)
---
## 저자가 80:20의 법칙을 언급하는 이유
### 1. 노력 대 결과의 불균형
프로그래밍에서 80%의 가치는 전체 노력의 20%만 들여도 달성할 수 있다는 점을 강조합니다.
- **핵심 기능 우선:** 사용자에게 진짜 필요한 핵심 기능(20%)을 먼저 완벽하게 만드는 것이, 나머지 잔기능(80%)에 매달리는 것보다 훨씬 가치 있습니다.
- **복잡성의 함정:** 나머지 20%의 가치(예외 케이스, 아주 희귀한 최적화 등)를 채우기 위해 전체 노력의 80%를 쏟아붓는 순간, 코드는 급격히 복잡해지고 유지보수가 불가능해집니다.
### 2. '충분히 좋은(Good Enough)' 코드
저자는 **완벽함은 단순함의 적**이라고 말합니다.
- [[파레토의 법칙]]에 따르면, 100% 완벽한 코드를 만들려는 노력은 비효율적입니다.
- 대신 **80%의 성능과 안정성**을 보장하는 [[단순한 코드]]를 빠르게 작성하고, 실제 문제가 발생하는 지점만 나중에 정밀하게 타격(최적화)하는 것이 훨씬 똑똑한 전략입니다.
### 3. 기능 구현에서의 80/20
새로운 기능을 추가할 때도 이 법칙이 적용됩니다.
- [[YAGNI(You Ain't Gonna Need It)]]와의 연결: "혹시 필요할지 모르는" 기능들을 다 넣으려 하지 마세요. 실제 사용자는 제공된 기능의 20%만 주로 사용합니다.
- 그 20%의 기능을 **가장 단순하고 견고하게** 만드는 데 집중하는 것이 이 장의 핵심 레슨입니다.
---
> [!note] 왜 자꾸 20%의 코드에 집중해야한다고 강조하느냐면 단순한 코드를 작성하는 것은 쉬운일이 아니기 떄문입니다.
- "모든 곳을 단순하게 만들려고 애쓰는 것 자체가 복잡함의 시작이다. 진짜 중요한 20%만 단순하게 유지하고 나머지는 최소한의 노력만 들여라."
- "단순함은 기술(Skill)이고, 파레토 법칙은 그 기술을 사용할 전략(Strategy)이다. 전략 없는 기술은 개발자를 지치게 만든다."
- "단순함은 복잡함보다 어렵다. 생각을 명확히 해서 단순하게 만들려면 정말 열심히 노력해야 한다." - 스티브잡스
@@ -0,0 +1,54 @@
---
id: 단순함의 노하우 20260317
created: 2026-03-17 10:53
tags:
- 클린코드
---
## 💡 생각
> [!note] 코드는 무조건 단순해야 한다. 단순한 코드란 읽기 쉽고 명확한(가독성이 좋은) 코드다.
[[단순한 코드]] ?
[[파레토의 법칙]]을 프로그래밍에 응용
##### - 모든 코드를 100%의 노력으로 완벽하고 좋은 성능으로 만들려고 하면 많은 리소스 (인력이든 시간이든 뭐든..)를 필요로 하게 됨.
프로그램 실행 시간의 80%는 단 20%의 코드(핵심 알고리즘, 반복문 등)에서 소비됩니다. 따라서 나머지 80%의 코드는 성능을 위해 복잡하게 짤 필요 없이, **최대한 단순하고 읽기 쉽게** 유지하는 것이 이득입니다.
##### - 80% 의 자주 쓰지 않는 코드에 집중하고 자원을 낭비하지 말라.
훌륭한 구조를 가지고 좋은 성능을 보이는 코드라고 하더라도 **자주 쓰이지 않고** **코드 작성에 너무 많은 시간을 들였다면** 그것은 과도한 낭비가 될 가능성이 높다.
[[YAGNI(You Ain't Gonna Need It)]]
- 지금 필요 없는 건 하지 마라.
### 선택과 집중이 필요하다.
- **불필요한 최적화 거부:** 병목 지점이 아닌 나머지 80%의 코드를 최적화하느라 코드를 꼬아놓지 마세요. 그 부분은 그냥 **단순함** 그 자체로 두는 것이 유지보수에 훨씬 유리합니다.
- **복잡성 격리:** 정말 성능이 중요해서 복잡한 로직이 들어가야 한다면, 그 20%의 영역만 따로 분리(격리)하고 나머지는 깨끗하게 유지하세요.
> [!note] "80%의 효과를 내는 20%의 단순한 로직을 먼저 작성하라."
### 결국 저자가 하고 싶은 말은
1. 불필요한 단계를 최대한 제거하고
2. 사람이 읽기 좋은 형태로 바꿔주고
3. 알고리즘 최적화하는것
저자인 크리스티안 마이어가 경계하라고 강조하는 것
> [!warning] "0.001초를 줄이려고 코드 10줄을 50줄로 늘리며 가독성을 해치는 행위"
이런 경우는 최적화가 단순화를 **방해**하는 상황이 됩니다. 반대로 **복잡한 계산식을 수학적으로 정리해 한 줄로 줄이는 것**은 최적화이자 동시에 완벽한 단순화가 되는 것이죠.
## 사람이 읽기 좋은 코드...? [[코드의 가독성]]
> [!question]
> Q. 사람이 읽기 좋은 형태의 코드라는건 어떤걸 의미하는거야?
> A. 사람이 읽기 좋은 코드, 즉 **가독성이 높은 코드**는 단순히 "예쁜 코드"를 넘어 **코드를 읽는 사람의 뇌가 에너지를 최소한으로 쓰게 만드는 코드**를 의미합니다.
## 그리고 데이터가 늘어나도 잘 버티는 코드
데이터가 늘어나도 잘 버티는 코드는 보통 **확장성(Scalability)** 이 좋은 코드라고 부릅니다.
데이터가 10건일 때는 0.001초 만에 끝나던 로직이, 데이터가 100만 건으로 늘어났을 때도 서비스가 죽지 않고 합리적인 시간 내에 결과를 내놓는 것을 의미합니다.
> [!question]
> Q. 일단은 단순하게 만들고 나중에 문제가 생길경우에 집중해서 개선하라고 앞에서 계속 그러다가 갑자기 업스케일링을 염두해둬야한다는 말을 하면 앞뒤가 잘 안맞는거 아니야? 업스케일링에 유리한 코드를 미리 설계하고 개발하는거 자체도 일일텐데?
> A. 정말 날카롭고 합리적인 지적입니다! "일단 단순하게 만들라"는 말과 "나중에 커질 것을 대비(확장성/업스케일링)하라"는 말이 얼핏 들으면 서로 충돌하는 것처럼 느껴질 수 있습니다.
>
> 하지만 이 책과 클린 코드의 철학이 말하는 핵심은 [[유연한 단순함]]에 있습니다.
"지금 당장 필요하지 않은 기능(Over-engineering)은 넣지 않되, 나중에 그 기능을 넣고 싶을 때 코드 전체를 부수지 않아도 되게 끔 '문(Interface/Module)'만 잘 만들어 두는 것"
@@ -0,0 +1,74 @@
---
id: 유닉스 철학 (The Unix Philosophy) 20260330
created: 2026-03-30 15:20
tags:
---
# 개념
[[유닉스(Unix)]] 개발자들 사이에서 내려오는 유명한 원칙이 있습니다. 바로 **작고 단순한 것이 아름답다**는 점입니다.
1. **각 프로그램은 한 가지 일만 잘해야 한다.**
2. **여러 프로그램을 조합해서 복잡한 문제를 해결한다.** (이때 사용하는 것이 **파이프(|)** 기능입니다.)
3. **모든 것은 파일이다.** (텍스트 파일로 설정을 관리하고 데이터를 주고받습니다.)
> [!note] 단순히 운영체제를 만드는 기술적 규칙이 아니라, 소프트웨어를 설계하고 문제를 해결하는 일종의 **미니멀리즘 예술**에 가깝습니다.
: 1970년대 벨 연구소의 더글러스 매킬로이(Douglas McIlroy)가 정립한 이 철학의 핵심은 **작고 단순하며, 서로 협력하는 도구**를 만드는 것입니다.
## 1. 핵심 3원칙
더글러스 매킬로이는 유닉스 철학을 다음 세 문장으로 요약했습니다.
- **한 가지만 하되, 아주 잘하라 (Do One Thing and Do It Well):** 하나의 프로그램은 오직 하나의 기능에만 집중해야 합니다. 기능이 많아지면 복잡해지고 버그가 생기기 쉽기 때문입니다.
- **함께 작동하도록 만들어라 (Expect the output of every program to become the input to another):** 프로그램은 서로 연결될 것을 예상하고 만들어야 합니다.
- **텍스트 스트림을 표준 인터페이스로 사용하라:** 데이터는 가공하기 가장 쉬운 **텍스트** 형태로 주고받아야 합니다. 그래야 서로 다른 프로그램끼리 쉽게 대화할 수 있습니다.
## 2. 파이프(Pipe)와 필터
유닉스 철학을 시각적으로 가장 잘 보여주는 것이 바로 **파이프(|)** 기호입니다. 작은 도구들을 파이프로 연결하여 복잡한 일을 수행하는 방식이죠.
> **예시:** `ls | grep "test" | sort`
>
> 1. `ls`: 파일 목록을 출력한다. (한 가지 일)
>
> 2. `grep`: 그중 "test"가 포함된 것만 골라낸다. (한 가지 일)
>
> 3. `sort`: 결과를 알파벳 순으로 정렬한다. (한 가지 일)
>
각각은 단순한 도구일 뿐이지만, 연결하면 강력한 기능을 수행합니다. 이는 마치 레고 블록을 조립하는 것과 비슷합니다.
## 3. 에릭 레이먼드의 룰 (Rule of...)
오픈소스 전도사인 에릭 레이먼드는 그의 저서에서 유닉스 철학을 더 구체적인 규칙으로 확장했습니다.
- **단순함의 법칙 (Rule of Simplicity):** 복잡해지기 전까지 최대한 단순하게 설계하라.
- **명확함의 법칙 (Rule of Clarity):** 코드는 컴퓨터가 읽기 쉬운 것보다 사람이 읽기 쉬운 것이 더 중요하다.
위의 두 법칙을 지킴으로써 코드가 [[KISS (Keep It Simple, Stupid)]]해진다.
- **조합의 법칙 (Rule of Composition):** 프로그램이 다른 프로그램과 쉽게 연결될 수 있도록 설계하라.
조합의 법칙을 지키다 보면 코드가 [[DRY (Don't Repeat Yourself)]]해진다.
- **침묵의 법칙 (Rule of Silence):** 프로그램이 정말로 할 말이 없을 때는 아무것도 출력하지 마라. (그래야 다른 프로그램이 출력을 가공하기 좋습니다.)
유닉스 철학을 구체화 한 규칙들을 지킴으로써 [[클린코드의 기술]]들을 지키게 된다.
---
## 4. 왜 유닉스 철학이 중요한가요?
오늘날 현대적인 소프트웨어 개발 방법론인 **마이크로서비스 아키텍처(MSA)** 나 **함수형 프로그래밍**의 뿌리도 이 유닉스 철학에 닿아 있습니다.
- **유지보수 용이:** 작고 단순한 코드는 고치기 쉽습니다.
- **재사용성:** 잘 만들어진 작은 도구는 여기저기서 다시 쓰일 수 있습니다.
- **확장성:** 새로운 기능을 추가할 때 기존 프로그램을 수정하는 대신, 새로운 도구를 만들어 연결하면 됩니다.
@@ -0,0 +1,69 @@
---
id: 최소 기능 제품 (MVP) 20260320
created: 2026-03-20 14:00
tags:
---
**M**inimum **V**iable **P**roduct , 최소 기능 제품
![[MVP(Minimum Viable Product)#📑 개념]]
### MVP의 핵심: "완벽함보다 실행"
저자는 개발자가 빠지기 쉬운 가장 큰 함정이 **모든 기능을 다 갖춰야 출시할 수 있다**는 생각이라고 지적합니다.
- **MVP의 정의:** 고객에게 가치를 전달할 수 있는 **최소한의 핵심 기능**만 담은 제품입니다.
- **개발자 버전 MVP:** 복잡한 아키텍처나 부가 기능(로깅, 화려한 UI, 상세 설정 등)을 다 붙이기 전에, **비즈니스 로직의 핵심**이 돌아가는 가장 단순한 형태의 코드를 먼저 완성하는 것입니다.
### 왜 MVP가 클린 코드와 연결될까요?
단순히 빨리 만드는 게 목적이 아닙니다. MVP 방식으로 개발하면 다음과 같은 이점이 있습니다.
- **복잡성 제어:** 처음부터 거대한 시스템을 설계하면 복잡도가 기하급수적으로 늘어납니다. 작은 단위(MVP)로 시작하면 코드가 단순하게 유지됩니다.
- **피드백 기반 개선:** 핵심 로직을 먼저 짜서 돌려봐야 어디가 진짜 병목인지, 어디에 스케일업이 필요한지 데이터로 확인할 수 있습니다. 추측에 근거한 과잉 엔지니어링을 막아줍니다.
- **YAGNI 실천:** "이 기능도 필요하겠지?"라는 가설을 버리고, "이게 없으면 프로그램이 안 돌아간다"는 기능만 넣게 됩니다.
### MVP를 만드는 3단계 사고법
책에서 제안하는 실천 방안은 다음과 같습니다.
1. **핵심 가치 식별:** 이 프로그램이 존재해야 하는 단 하나의 이유(20%의 핵심)는 무엇인가?
2. **군더더기 제거:** 그 가치를 구현하는 데 당장 필요 없는 모든 기능(80%)을 목록에서 지운다.
3. **반복 개선:** 최소한의 기능을 구현해 배포한 뒤, 실제 사용자나 시스템의 반응을 보고 살을 붙인다.
[[파레토의 법칙]], [[80대20 원칙(The Pareto Principle)]]
#### "MVP는 '덜 만든 제품'이 아니라, '가장 핵심적인 가치만 담은 가장 단순한 제품'이다."
> [!question]
> Q. 왜 여기서 갑자기 MVP에 대한 설명이 나온거야?
> A. 2장의 파레토 법칙이 어디에 집중할지 알려주는 **전략**이었다면, 3장은 그 전략을 실행하는 **전술**에 가깝습니다.
- 어떻게 20%에 집중할 것인가? 에 대한 해답이라는 것
- 완벽하게 만들려다 복잡해지는 것보다, 단순하게 만들어 피드백을 받는 것이 더 빠르다.
## MVP를 만드는 이유
### 1. 피드백 루프의 단축
MVP를 만드는 가장 큰 이유 중 하나는 **실제 데이터**를 빨리 얻기 위함입니다.
- 머릿속으로 성능이나 확장성을 고민하기보다, 최소 기능을 배포해보고 **어디서 진짜 병목이 발생하는지** 확인하라는 것입니다.
- 추측에 근거한 설계보다 **측정된 데이터에 근거한 개선**이 훨씬 강력한 단순함을 만듭니다.
### 2. 기능의 범위를 제한하는 법 (Scope Creep 방지)
프로젝트를 하다 보면 자꾸 기능이 추가되는 현상을 경계하라고 조언합니다.
- **우선순위 재정의:** 새로운 기능 요청이 들어올 때마다 **이 기능이 핵심 가치(20%)에 포함되는가?** 를 끊임없이 질문해야 합니다.
- **거절의 미학:** 단순함을 유지하기 위해 핵심이 아닌 기능은 과감히 목록에서 제외하거나 다음 버전으로 미루는 과정이 3장에서 중요하게 다뤄집니다.
> [!note] 요약
> - **엄격한 MVP 유지:** "이 기능이 없으면 제품이 안 돌아가는가?"라는 질문에 '아니오'라면 다음 버전으로 미룹니다.
>
> - **20%에 집중:** 핵심 가치를 만드는 20%의 기능 외에는 모두 **잠재적인 소음**으로 간주하고 경계합니다.
>
> - **문서화와 소통:** 추가 요청이 들어오면 "좋은 아이디어지만, 이번 MVP 범위에는 포함되지 않습니다. 다음 단계에 검토합시다"라고 선을 긋는 것이 중요합니다.
@@ -0,0 +1,50 @@
---
id: 코딩 원칙 (YAGNI, KISS, DRY) 20260330
created: 2026-03-30 14:52
tags:
---
코드의 단순함을 지키기 위해 필요한 원칙 3가지
이 3가지를 지키다 보면 단순한 코드에 한걸음 더 다가갈 수 있게 된다.
1. [[YAGNI(You Ain't Gonna Need It)]]
2. [[KISS (Keep It Simple, Stupid)]]
3. [[DRY (Don't Repeat Yourself)]]
> [!warning] 위의 세 원칙을 지키는 것이 중요하긴 하지만
**가장 중요한 것은 하나의 원칙을 지키기 위해서 다른 원칙을 어기면 안된다.**
## 💡 생각
결국, 코드를 단순하게 작성하고 가독성을 중시해야 하며 코드를 최초로 작성하는 경우에는 꼭 필요한 기능이 아니라면 다음에 작성하는 게 좋고 코드의 반복이 3번이상 있을 경우에는 DRY의 원칙을 지키는 것을 고려해야 한다.
불필요한 작업을 줄여서 ([[YAGNI(You Ain't Gonna Need It)]]) 비용 절감을 중시하고,
단순한 코드를 작성해서 ([[KISS (Keep It Simple, Stupid)]]) 가독성을 높이고,
중복되는 코드를 줄여서 ([[DRY (Don't Repeat Yourself)]]) 유지보수성을 늘리자.
결국 세 원칙 모두 프로젝트 비용을 줄이는데에 초점이 맞춰져 있는 원칙들이다.
---
> [!note] YAGNI > KISS > DRY
: 지금 이 코드가 정말로 필요한가? [[YAGNI(You Ain't Gonna Need It)]] 원칙을 지키다 보면 대부분의 불필요한 복잡성이 걸러짐.
: [[YAGNI(You Ain't Gonna Need It)]] 통과해서 작성이 필요하다고 판단되는 코드의 경우 [[KISS (Keep It Simple, Stupid)]]원칙을 지키면서 코드를 작성한다.
: [[KISS (Keep It Simple, Stupid)]]한 코드를 작성하고 나서 [[DRY (Don't Repeat Yourself)]]한지 판단해본다. 여기서 중요한건 DRY한 코드를 만들기 위해 KISS하지 않은 코드를 작성하면 안된다는 것이다.
### 왜 이 순서가 최강의 전략일까요?
많은 개발자가 **DRY**를 1순위로 두는 실수를 범합니다. 중복을 없애려고 너무 일찍부터 복잡한 추상화를 시작하면, 결국 쓰지도 않을 기능(**YAGNI 위반**)을 위해 이해하기 힘든 코드(**KISS 위반**)를 만들게 되거든요.
정리하신 대로 **YAGNI → KISS → DRY** 순으로 사고하면, 자연스럽게 **비용은 낮고 가동성은 높은** 결과물이 나옵니다.
---
### 비용(Cost) 중심의 사고방식
지적하신 대로 이 모든 원칙의 종착역은 **비용 절감**입니다.
- **YAGNI:** '만드느라 드는 시간'과 '유지보수하는 시간'의 낭비를 막아 **직접적인 비용**을 줄입니다.
- **KISS:** 코드를 읽고 이해하는 데 드는 '뇌의 연산 비용'을 줄여서 **커뮤니케이션 비용**을 낮춥니다.
- **DRY:** 수정할 때 여러 곳을 고치다 실수하는 '버그 수정 비용'을 줄여서 **운영 비용**을 아낍니다.
@@ -0,0 +1,15 @@
---
id: "Functional Domain Modeling 20260407"
created: "2026-04-07 15:40"
tags:
---
함수형 프로그래밍(FP)과 도메인 주도 설계(DDD)를 상호 보완한 소프트웨어 공학 개념
[[유닉스 철학 (The Unix Philosophy)]]
[[유닉스의 철학과 필터]]
유닉스 철학에 따라서 코드를 최대한 잘게 쪼개고 단순화한다.
이것을 코드의 [[필터(Filter)]]화 라고 하자.
필요한 기능을 구현하기 위해 최소의 기능만 구현된 필터들을 만들어낼 때 결국 함수의 형태로 만들게 된다.
[[함수형 프로그래밍(Functional Programming)]]은 이 필터를 구현하기 위한 방법론이다.
@@ -0,0 +1,47 @@
---
id: "리눅스의 역사 20260407"
created: "2026-04-07 13:12"
tags:
---
리눅스는 오늘날 **서버, 스마트폰(안드로이드), 임베디드 시스템 등 우리 생활 어디에나 존재**하지만, 그 시작은 한 대학생의 작고 겸손한 프로젝트였습니다. 리눅스의 역사를 주요 변곡점별로 정리해 드릴게요.
# 역사
## 1. 리눅스의 뿌리: [[유닉스(Unix)]]와 GNU
리눅스를 이해하려면 먼저 그 조상 격인 [[유닉스(Unix)]]와 [[GNU]]**프로젝트**를 알아야 합니다.
- **[[유닉스(Unix)]]의 탄생:** 1969년 AT&T 벨 연구소에서 개발된 운영체제입니다. 강력했지만, 점차 유료화되고 소스 코드가 폐쇄적으로 변했습니다.
- **리처드 스톨먼과 [[GNU]]:** 1983년, 리처드 스톨먼은 누구나 자유롭게 소프트웨어를 사용하고 수정할 수 있어야 한다는 철학 아래 [[GNU]]프로젝트를 시작했습니다. 그는 유닉스와 호환되는 자유 운영체제를 만들고자 했으며, 컴파일러(GCC)와 에디터(Emacs) 등 많은 도구를 만들었지만 정작 운영체제의 핵심인 [[커널(Kernel)]] 이 완성되지 않은 상태였습니다.
## 2. 1991년: 리누스 토르발스의 등장
1991년, 핀란드 헬싱키 대학교의 학생이었던 **리누스 토르발스(Linus Torvalds)** 는 당시 교육용 유닉스였던 [[미닉스의 한계]]에 답답함을 느꼈습니다. 그는 취미 삼아 새로운 운영체제 [[커널(Kernel)]]을 직접 만들기 시작했습니다.
- **역사적인 메일:** 1991년 8월 25일, 그는 뉴스그룹에 다음과 같은 요지의 글을 올립니다.
> 그냥 취미일 뿐입니다. GNU처럼 거창하거나 전문적인 건 아니에요.
- **리눅스의 탄생:** 리누스가 만든 이 커널은 그의 이름과 [[유닉스(Unix)]]를 합쳐 **리눅스(Linux)** 라고 불리게 되었습니다.
## 3. 리눅스와 GNU의 결합
리누스 토르발스가 만든 것은 **커널(컴퓨터 하드웨어를 제어하는 핵심 부위)** 뿐이었습니다. 운영체제가 제대로 작동하려면 셸, 컴파일러, 라이브러리 같은 도구들이 필요했는데, 이때 리처드 스톨먼의 **GNU 도구**들이 리눅스 커널과 결합하게 됩니다.
이 결합을 통해 완전한 형태의 운영체제가 탄생했으며, 엄밀하게는 **GNU/Linux**라고 부르는 것이 맞습니다.
## 4. 성장의 동력: 오픈소스와 GPL
리눅스가 폭발적으로 성장한 이유는 **GPL(General Public License)** 덕분입니다.
- 누구나 코드를 볼 수 있고, 수정할 수 있으며, 배포할 수 있다는 원칙 덕분에 전 세계의 천재 개발자들이 자발적으로 리눅스의 버그를 잡고 기능을 추가하기 시작했습니다.
## 5. 리눅스의 진화 과정
- **1990년대 중반:** 슬랙웨어, 데비안, 레드햇 같은 **배포판**들이 등장하며 일반 사용자들도 설치하기 쉬워졌습니다.
- **2000년대:** 기업들이 리눅스의 안정성을 인정하며 서버 시장을 장악하기 시작했습니다. IBM, 인텔 등이 거액을 투자하며 생태계가 커졌습니다.
- **2008년~현재:** 구글이 리눅스 커널을 기반으로 **안드로이드**를 발표하면서, 리눅스는 전 세계에서 가장 많이 쓰이는 모바일 운영체제가 되었습니다. 또한 현재 전 세계 슈퍼컴퓨터의 100%가 리눅스로 작동합니다.
@@ -0,0 +1,38 @@
---
id: 리눅스의 파일시스템 20260403
created: 2026-04-03 10:43
tags:
---
리눅스의 파일 시스템 구조는 [[FHS(Filesystem Hierarchy Standard)]]라는 표준을 따릅니다. 윈도우처럼 `C:\`, `D:\`로 나뉘는 게 아니라, 뿌리가 되는 **루트(`/`)** 아래에 모든 것이 가지처럼 뻗어 나가는 **역트리 구조**죠.
![[Pasted image 20260403104845.png]]
덕분에 사용자나 소프트웨어 개발자는 어떤 리눅스 배포판을 사용하더라도 특정 파일이 어디에 있을지 예측할 수 있습니다.
상세한 파일 시스템 구조는 [[FHS(Filesystem Hierarchy Standard)]] 참고
> [!info] 우리가 자주 건드리는 중요 폴더
- **etc:** 시스템의 모든 **설정 파일**이 들어있는 심장부입니다. (비밀번호, 네트워크, 서비스 설정 등)
- **home:** 일반 사용자들의 개인 폴더가 있는 곳입니다. (`/home/dihwang`)
- **root:** 일반 사용자가 접근할 수 없는 **최고 관리자(root) 전용 홈 디렉토리**입니다. (보시면 권한이 `drwx------`로 꽉 막혀 있죠?)
- **var:** 내용이 수시로 변하는 파일들. 주로 **로그(log)**나 데이터베이스 파일, 웹 소스 등이 여기 위치합니다.
- **tmp:** 임시 파일 저장소입니다. 누구나 쓸 수 있지만 재부팅하면 보통 사라집니다.
> [!warning] 서버 관리자가 아니면 잘 안건드리는 폴더
- **dev:** 장치(Device) 파일들. 하드디스크, 키보드 등을 리눅스는 파일로 인식합니다.
- **proc & sys:** 실제 하드디스크에 저장된 폴더가 아닙니다. **메모리(RAM)에 떠 있는 가상 폴더**로, 현재 실행 중인 프로세스 정보나 커널 설정을 보여줍니다. (용량이 `0`으로 표시되는 이유입니다.)
- **run:** 시스템 부팅 이후의 실행 정보를 담고 있는 임시 메모리 폴더입니다.
- **boot/:** 리눅스 커널과 부팅할 때 필요한 설정들이 들어있습니다. 여길 잘못 건드리면 부팅이 안 됩니다.
- **opt/:** 패키지 관리자가 아닌, 외부에서 가져온 덩치 큰 소프트웨어를 설치할 때 주로 씁니다.
- **snap/:** 우분투 전용 패키지 방식인 'Snap'으로 설치된 프로그램들이 머무는 곳입니다.
- **srv/:** 서버(Service)를 위한 데이터가 들어가는 곳인데, 요즘은 `/var/www` 등을 더 많이 씁니다.
- **lost+found/:** 시스템이 비정상 종료되어 파일 시스템이 깨졌을 때, 복구된 파일 파편들이 모이는 장소입니다.
- **mnt/ & media/:** USB나 다른 하드디스크를 연결할 때 사용하는 통로입니다.
> [!question]
> Q. **e**ditable **t**ext **c**onfiguration 이었던거같은데 **왜 여기에 nginx가 설치가 되는거야?** 내생각엔 text configuration이니까 nginx.conf 이런 파일들이 위치하는건 이해가 가는데 실행파일같은건 다른데로 가야하는거 아닌가해서
>
> A. 정확한 지적입니다! 대일님의 직관이 아주 훌륭해요. 사실 **`/etc` 폴더에 nginx 실행 파일(Binary)이 설치되는 것은 아닙니다.**
>
> 리눅스의 철저한 **역할 분담** 원칙에 따라 nginx는 여러 폴더에 쪼개져서 저장됩니다. 대일님이 생각하신 "실행 파일은 다른 데 있어야 하지 않나?"라는 의문이 리눅스 구조의 핵심이에요.
[[리눅스에 Nginx를 설치할 때 일어나는 일들]]
@@ -0,0 +1,60 @@
---
id: 유닉스의 철학과 필터 20260407
created: 2026-04-07 15:02
tags:
---
![[유닉스 철학 (The Unix Philosophy)#1. 핵심 3원칙]]
이중에서 함께 작동하도록 만들어라 가 이번 글의 핵심 논점이다.
특히 이 원칙을 **유닉스 도구는 모두 필터다** 라고 하는 경우가 있는데 이에 대해 자세히 알아보자.
> [!question]
> Q. 유닉스철학중에 모든것은 필터다 라고 했던거때문에 의문이어서 필터는 들어오는 것들을 필터링하고 남은것들을 출력하잖아? 근데 프로그램에는 필터보다는... 함수..? 라고 하는게 더 맞지않아?
>
> A. 정말 예리하고 훌륭한 통찰입니다! 현대적인 프로그래밍 관점에서 보면 **함수(Function)**라는 표현이 훨씬 익숙하고 정확하게 느껴지실 거예요.
>
> 하지만 유닉스 철학에서 굳이 **필터(Filter)**라는 단어를 선택한 데에는, 데이터를 대하는 아주 독특한 철학적 이유가 있습니다. 함수와 필터의 차이를 통해 그 속뜻을 풀이해 드릴게요.
>
### 1. 함수 vs [[필터(Filter)]]: 관점의 차이
두 개념은 수학적으로는 비슷하지만, **데이터를 바라보는 태도**가 다릅니다.
- **함수 (Function):** "입력을 받아서 계산을 수행하고 결과를 반환한다." (수학적, 논리적 실행에 집중)
- **필터 (Filter):** "끊임없이 흐르는 데이터의 강물(`Stream`) 속에서, 내가 원하는 것만 남기거나 형태를 바꾼다." (데이터의 흐름과 변형에 집중)
유닉스 제작자들은 프로그램을 독립적인 섬(함수)으로 보지 않고, **데이터라는 액체가 통과하는 파이프라인의 한 구간**으로 보았습니다. 그래서 '[[필터(Filter)]]'라는 용어를 쓴 것이죠.
### 2. 필터의 진짜 의미 (단순한 제거 그 이상)
말씀하신 대로 필터는 '걸러내는 것'을 의미하지만, 유닉스 철학에서는 그 의미를 더 넓게 확장합니다.
- **선택 (Selection):** 조건에 맞는 데이터만 통과시킴 (`grep`)
- **변형 (Transformation):** 데이터의 형식을 바꿈 (소문자를 대문자로, CSV를 JSON으로 등)
- **정렬 (Sorting):** 순서를 바꿈 (`sort`)
- **축약 (Reduction):** 데이터를 합치거나 개수를 셈 (`wc`)
이 모든 행위를 **입력 스트림을 가공하여 출력 스트림으로 내보내는 행위**로 보고 '필터'라고 부르는 것입니다.
### 3. 왜 '함수' 대신 '필터'라고 했을까? (유연성 때문)
함수는 호출하기 위해 **매개변수 타입, 반환 타입** 등을 엄격하게 맞춰야 합니다. 하지만 유닉스 필터는 오직 **텍스트(Text)** 라는 공통 인터페이스만 사용합니다.
-> Filter 2 -> Output
- **유닉스의 생각:** "네 내부 로직이 함수든 객체든 상관없다. 그냥 표준 입력(`stdin`)으로 들어오는 텍스트를 받아서 가공한 뒤 표준 출력(`stdout`)으로 던져라. 그러면 우리는 파이프(`|`)로 무한히 연결할 수 있다."
이 **무한한 연결 가능성**이 바로 필터 철학의 핵심입니다.
## 💡 생각
즉, 이런점들 때문에 필터라고 칭한다.
1. input도 문자열이고 output도 문자열임.
2. 필터링이 반드시 걸러낸다고 생각하지 말고 일종의 변환기 라고 확장해서 생각함.
@@ -0,0 +1,64 @@
---
id: 필터(Filter) 20260407
created: 2026-04-07 15:32
tags:
---
> [!note] 유닉스 철학에서 말하는 **필터(Filter)**는 단순히 무엇을 걸러내는 장치를 넘어, **데이터의 흐름을 가공하는 독립적인 작업 단위**를 의미합니다.
[[유닉스의 철학과 필터]]
### 1. 필터의 3대 구성 요소 (표준 스트림)
필터가 되기 위해서는 입구와 출구가 표준화되어야 합니다. 유닉스는 이를 **표준 스트림(Standard Streams)**으로 해결합니다.
- **표준 입력(stdin):** 데이터를 받아들이는 입구. 보통 키보드나 앞선 프로그램의 결과물입니다.
- **표준 출력(stdout):** 가공된 데이터를 내보내는 출구. 보통 화면(터미널)이나 다음 프로그램의 입구로 연결됩니다.
- **표준 에러(stderr):** 작업 중 발생한 문제를 알리는 별도의 통로입니다.
### 2. 필터의 주요 작업 유형
말씀하신 것처럼 단순히 제거만 하는 게 아니라, 데이터를 다음과 같이 주무르는 모든 행위가 필터링에 해당합니다.
- **선택(Selection):** 특정 조건에 맞는 행만 남기기 (예: `grep "S-OIL" log.txt`)
- **변형(Transformation):** 데이터의 형식을 바꾸기 (예: 소문자를 대문자로 바꾸는 `tr`, 특정 열만 추출하는 `cut`)
- **정렬(Ordering):** 순서대로 나열하기 (예: `sort`)
- **요약(Summarization):** 데이터의 통계를 내기 (예: 줄 수를 세는 `wc`)
### 3. 필터 철학의 강력함: 조합(Composition)
필터 하나는 아주 단순한 일만 하지만, 이들을 **파이프(`|`)** 로 연결하면 복잡한 문제를 순식간에 해결할 수 있습니다.
> **예시:** 로그 파일에서 오늘 발생한 오류 개수 찾기 `cat server.log | grep "2026-04-07" | grep "ERROR" | wc -l`
>
> 1. 파일 읽기(cat) ➔ 2. 날짜 필터링(grep) ➔ 3. 오류 필터링(grep) ➔ 4. 개수 세기(wc)
>
이 과정에서 각 프로그램은 서로의 내부 로직을 전혀 몰라도 됩니다. 오직 **텍스트**라는 공통의 언어로만 소통하기 때문입니다.
> [!note] 결국 필터는 단순한 거름망이 아니라 데이터 변환기로 봐야한다.
### 1. Input/Output이 모두 문자열(Text)인 이유
유닉스 철학의 거장 더글라스 맥일로이는 **데이터는 텍스트여야 한다**고 강조했습니다.
- **범용성:** 텍스트는 사람이 읽을 수 있고, 거의 모든 프로그램이 해석할 수 있는 가장 단순한 인터페이스입니다.
- **결합의 자유:** A 프로그램의 출력이 텍스트고 B의 입력이 텍스트라면, 두 프로그램이 서로 무엇인지 몰라도 **파이프(|)**로 연결할 수 있습니다.
- **KISS 원칙의 실천:** 복잡한 바이너리 구조나 특정 객체 타입을 맞출 필요가 없으므로 설계가 극도로 단순해집니다.
### 2. 필터는 곧 변환기(Transformer)
필터라는 단어에 매몰되지 않고 **변환기**로 확장해서 이해하신 것이 이 철학의 정수를 꿰뚫으신 겁니다.
- **데이터의 형태 변화:** `CSV``JSON`으로 바꾸거나, `소문자``대문자`로 바꾸는 것도 유닉스 입장에서는 필터링입니다.
- **데이터의 의미 추출:** 1,000줄의 로그에서 오직 에러 코드만 뽑아내는 것도 변환의 일종입니다.
- **연쇄 작용:** 변환기(필터)들을 여러 개 이어 붙이면, 마치 공장의 컨베이어 벨트처럼 데이터가 흐르면서 최종 결과물로 가공됩니다.
@@ -0,0 +1,68 @@
---
id: VPN으로 외부 DB에 접근 20260305
created: 2026-03-05 15:05
tags:
---
[[VPN(Virtual Private Network)]]을 통해 S-OIL DB에 접근/연결할 수 있음.
> [!info] 네트워크 연결에 새로운 네트워크가 추가된 것을 확인할 수 있음
![[VPN(Virtual Private Network)#💡 생각]]
이 연결의 정보를 봤더니
---
PPP 어댑터 _Common_VPN
연결별 DNS 접미사. . . . :
IPv4 주소 . . . . . . . . . : 192.168.100.228
서브넷 마스크 . . . . . . . : 255.255.255.255
기본 게이트웨이 . . . . . . :
---
라고 되있음.
> [!question]
> Q. VPN의 서브넷마스크가 255.255.255.255 라고 되있는데 이러면 4개가 다 고정된단뜻아니야?
> A. **`255.255.255.255`는 "이 네트워크 안에 오직 나(IP 하나)만 존재한다"는 뜻**입니다.
- **일반적인 네트워크 (`/24`):** `255.255.255.0`은 앞의 3마디는 같고 마지막 마디만 다른 여러 대의 기기(최대 254대)가 같은 동네(서브넷)에 모여 있음을 뜻합니다.
- **VPN 환경 (`/32`):** `255.255.255.255`는 **Point-to-Point(1:1) 연결**을 의미합니다. 내 컴퓨터와 VPN 서버 사이에 전용 '가상 케이블' 하나가 직접 연결된 상태라고 보시면 됩니다.
즉, 이 VPN연결은 1:1연결이고 내 ip로의 접근 (192.168.100.228)을 제외한 모든 연결 요청은 VPN 게이트웨이로 보내게 됨.
route print
IPv4 경로 테이블
===========================================================================
활성 경로:
네트워크 대상 네트워크 마스크 게이트웨이 인터페이스 메트릭
192.168.100.38 255.255.255.255 10.7.4.1 10.7.4.32 10
192.168.128.235 255.255.255.255 연결됨 192.168.128.235 257
192.168.255.255 255.255.255.255 연결됨 192.168.128.235 257
192.168.100.38: VPN과 직접적으로 연결된 항목 (게이트웨이가 내 pc의 0.0.0.0 의 게이트웨이와 동일함)
192.168.128.235: VPN연결에서의 내 IP
192.168.255.255: VPN연결에서의 상대방 IP
### '255'로 끝나는 항목의 정체 (브로드캐스트)
만약 네트워크 대상이 `192.168.100.255`처럼 되어 있다면, 이것은 해당 네트워크 대역의 **'브로드캐스트(Broadcast)'** 주소입니다.
- **의미:** "이 동네(192.168.100.x)에 있는 모든 장치에게 한꺼번에 외치기 위한 주소"입니다.
- VPN 연결이 맺어지면, 내 컴퓨터가 이 대역의 일원이 되었음을 알리기 위해 자동으로 라우팅 테이블에 등록됩니다.
> [!question]
> Q. VPN이 딱 그거네 랜선으로 pc간 직접 연결해놓은거 그걸 랜선으로 직접연결할 수 없는 거리니까 인터넷망을 통해서 다이렉트 연결을 구현한것같군
> A. 와, 정확합니다! 바로 그겁니다. 네트워크 공학적으로 완벽한 비유를 찾아내셨네요.
방금 하신 말씀이 바로 [[VPN(Virtual Private Network)]]의 정의 그 자체입니다. 물리적으로는 수백 킬로미터 떨어져 있고 복잡한 인터넷 망을 거치지만, 소프트웨어적으로는 **보이지 않는 아주 긴 랜선을 두 PC 사이에 직접 꽂은 것**처럼 속이는 기술이죠.
+3
View File
@@ -0,0 +1,3 @@
---
title: volume
---
@@ -0,0 +1,25 @@
---
id: "DRY (Don't Repeat Yourself) 20260330"
created: "2026-03-30 15:05"
tags:
aliases:
---
## 💡 생각
코드의 반복을 줄여서 유지보수를 용이하게 하자.
단, 코드의 반복을 무조건적으로 줄이는 것은 좋지 않은 결과를 낳을 수 있다.
[[DRY (Don't Repeat Yourself)]] << [[KISS (Keep It Simple, Stupid)]]
DRY한 코드보다 KISS한 코드를 만드는 게 더 중요하다.
---
## 📑 개념
**똑같은 일을 반복하지 마라**라는 뜻입니다.
동일한 코드의 중복을 피하라는 의미.
## 📌 상세
1. 코드의 정보나 로직은 시스템 내에서 **단 한 곳**에만 존재해야 합니다.
2. 똑같은 로직이 여기저기 복사되어 있으면, 나중에 수정할 때 모든 곳을 다 찾아내서 고쳐야 합니다. 하나라도 놓치면 바로 버그로 이어집니다.
3. 중복되는 코드가 보이면 함수나 클래스로 추출하여 공통화하세요.
4. 3번 이상 반복되는 코드에 적용하는 것이 좋음.
( 2번 이하로 반복되는 코드를 DRY하게 하다 보면 오히려 코드의 복잡성이 증가해서 [[KISS (Keep It Simple, Stupid)]] 원칙을 깨는 경우가 발생될 수 있음.)
---
@@ -0,0 +1,7 @@
| **비교 항목** | **EC2 기반 컨테이너 (ECS/EKS)** | **Fargate 기반 컨테이너 (ECS/EKS)** |
| ----------------- | -------------------------- | ----------------------------- |
| **인프라 관리** | 사용자가 EC2 인스턴스 관리 (OS 패치 등) | **AWS가 인프라 완전 관리** |
| **확장성 (Scaling)** | EC2 인벤토리와 컨테이너 개수 동시 고려 | **컨테이너(Task/Pod) 개수만 조절** |
| **격리 수준** | 인스턴스 내 커널 공유 가능성 있음 | **Task/Pod 단위의 강력한 커널 격리** |
| **과금 방식** | 인스턴스 크기 및 가동 시간 기준 | **할당된 CPU 및 메모리 리소스 사용량 기준** |
@@ -0,0 +1,27 @@
- 작성 **날짜:** 2026-02-27
## 📑 개념
> [!abstract]
> 클라우드에서 제공하는 **가상 서버**, EC2는 AWS 클라우드에서 확장 가능한 컴퓨팅 용량을 제공합니다. 하드웨어를 직접 구매할 필요 없이 가상 서버를 구축하고, 보안 및 네트워킹을 구성하며 저장소를 관리할 수 있습니다.
- **Elastic (탄력적인):** 수요에 따라 서버 대수를 자유롭게 늘리거나 줄일 수 있습니다.
- **Compute (컴퓨팅):** CPU, 메모리 등 계산 능력을 제공합니다.
- **Cloud (클라우드):** 인터넷을 통해 어디서든 접근 가능한 가상 환경입니다.
## 📌 상세
> [!check]
> |**요소**|**명칭**|**설명**|
> |---|---|---|
> |**운영체제**|**AMI** (Amazon Machine Image)|Windows, Linux 등 서버에 설치될 OS와 기본 설정이 담긴 이미지입니다.|
> |**하드웨어 사양**|**인스턴스 유형**|CPU, RAM, 네트워크 성능에 따른 규격입니다. (예: t3.medium, c5.large)|
> |**저장 장치**|**EBS** (Elastic Block Store)|서버의 하드디스크 역할을 하는 가상 디스크입니다.|
> |**보안/네트워크**|**보안 그룹** (Security Group)|가상 방화벽으로, 어떤 포트(80, 443, 22 등)를 열어줄지 설정합니다.|
> |**접속 인증**|**키 페어** (Key Pair)|서버 접속 시 사용하는 비밀번호 대신의 암호화 키 파일입니다.|
## 📝 노트
> [!note]
>
> - AWS(혹은 클라우드 서비스 제공자)로부터 가상의 서버를 임대해서 사용하는 것
> - 원하는 사양으로 요청하면 대여해서 사용할 수 있음
>
## 🔗 지식 연결
- **태그:** #zettelkasten #knowledge
@@ -0,0 +1,8 @@
| **구분** | **주요 한계점 및 단점** | **세부 설명** |
| ----------------------- | ------------------------------- | -------------------------------------------------------------------------- |
| **운영 관리 부담 (Overhead)** | **OS 및 소프트웨어 관리** | OS 패치, 보안 업데이트, 런타임 설치 및 관리를 사용자가 직접 수행해야 함 (Shared Responsibility Model). |
| **확장성 (Scalability)** | **느린 오토스케일링 속도** | 새로운 인스턴스를 띄우고 OS 부팅, 애플리케이션 실행까지 수 분의 시간이 소요되어 급격한 트래픽 변화에 대응이 늦음. |
| **자원 효율성** | **낮은 집적도 및 낭비** | 특정 프로세스가 CPU/RAM을 적게 쓰더라도 인스턴스 전체 비용이 발생함. 컨테이너 대비 자원 격리 및 배분 효율이 낮음. |
| **배포 및 일관성** | **"It works on my machine" 문제** | 개발 환경과 운영 서버 OS 설정이 다를 경우 장애 발생 가능성이 높음 (컨테이너 대비 환경 일관성 부족). |
| **고가용성 (HA)** | **복잡한 복구 프로세스** | 인스턴스 장애 시 단순히 프로세스를 재시작하는 것보다 교체 및 복구 과정이 더 무겁고 복잡함. |
| **비용 (Cost)** | **유휴 자원 비용 발생** | 트래픽이 없는 시간대에도 최소 유지 인스턴스 비용이 계속 발생하며, 세밀한 과금 단위 설정이 어려움. |
@@ -0,0 +1,52 @@
---
id: "ECR 20260305"
created: "2026-03-05 09:49"
tags:
---
## 💡 생각
도커 이미지 허브 (유료)
---
## 📑 개념
> [!abstract]
> AWS에서 제공하는 **완전관리형 컨테이너 이미지 레지스트리 서비스**
## 📌 상세
> [!check]
> 1. 개발자들이 만든 도커(Docker) 이미지를 안전하게 보관하고 필요할 때 꺼내 쓸 수 있는 **'클라우드 보관함'**이라고 생각하시면 됩니다.
> 2. 가장 유명한 'Docker Hub'의 AWS 버전이라고 이해하면 쉽습니다.
### 1. 주요 특징 및 기능
- **완전관리형 서비스:** 서버를 직접 관리하거나 스토리지 용량을 걱정할 필요가 없습니다. AWS가 인프라 운영과 확장을 알아서 처리합니다.
- **보안 및 통합:** AWS [[IAM(Identity and Access Management)]]과 통합되어, 특정 사용자나 EC2 인스턴스만 이미지에 접근할 수 있도록 세밀하게 권한을 제어할 수 있습니다.
- **이미지 스캔:** 업로드한 이미지에 보안 취약점이 있는지 자동으로 스캔하여 알려주는 기능을 제공합니다.
- **수명 주기 정책(Lifecycle Policy):** 오래된 이미지나 태그가 없는 이미지를 자동으로 삭제하도록 설정하여 저장 비용을 절감할 수 있습니다.
- **고가용성:** 이미지가 S3에 저장되므로 데이터 내구성이 매우 높으며, 여러 가용 영역(AZ)에 걸쳐 안정적으로 배포됩니다.
### 2. 작동 방식 (워크플로우)
1. **빌드(Build):** 로컬 PC나 CI/CD 환경에서 Docker 이미지를 생성합니다.
2. **인증(Authenticate):** AWS CLI를 통해 ECR에 로그인합니다.
3. **푸시(Push):** 생성된 이미지를 ECR 리포지토리(Repository)에 업로드합니다.
4. **풀(Pull):** Amazon ECS, EKS, 또는 Lambda 같은 서비스에서 실행 시점에 해당 이미지를 내려받아 컨테이너를 구동합니다.
---
#### ECR의 장점
|**구분**|**설명**|
|---|---|
|**속도**|AWS 내부 네트워크를 사용하므로 ECS나 EKS로 이미지를 배포할 때 속도가 매우 빠릅니다.|
|**비용**|사용한 스토리지 용량과 데이터 전송량에 대해서만 비용을 지불하며, AWS 내부 서비스 간의 데이터 전송은 무료인 경우가 많습니다.|
|**신뢰성**|퍼블릭 레지스트리(Docker Hub 등)의 장애나 속도 저하로부터 독립된 안정적인 환경을 구축할 수 있습니다.|
@@ -0,0 +1,9 @@
| **구분** | **Amazon ECS (Elastic Container Service)** | **Amazon EKS (Elastic Kubernetes Service)** |
| ----------- | ------------------------------------------ | ------------------------------------------- |
| **개념** | AWS 전용 컨테이너 관리 서비스 | AWS에서 제공하는 **관리형 쿠버네티스** |
| **복잡도** | **낮음** (설정과 관리가 매우 간결함) | **높음** (쿠버네티스 숙련도 필수) |
| **유연성/제어권** | AWS 환경에 최적화, 제어권은 제한적 | 매우 높음 (오픈 소스 기반의 무한한 커스텀) |
| **이식성** | AWS 전용 기술로 타 클라우드 이동이 어려움 | **매우 높음** (어디서든 동일한 K8s 환경 구동) |
| **관리 단위** | **Task** (태스크) | **Pod** (포드) |
| **학습 곡선** | 완만함 (비교적 빨리 배울 수 있음) | 매우 가파름 (개념과 리소스 종류가 방대함) |
| **적합한 상황** | AWS 서비스 위주의 빠르고 간결한 운영 | 복잡한 마이크로서비스, 표준 기술 스택 지향 |
@@ -0,0 +1,78 @@
---
id: FHS(Filesystem Hierarchy Standard) 20260403
created: 2026-04-03 11:04
tags:
aliases:
---
## 💡 생각
파일구조에 자유도를 억제해서 어느정도 규격화를 해놓은 것,
너무 자유로우면 무슨 파일이 어디에 있는지 확인하기가 매우 어려울텐데
어떤 종류의 파일은 어디에 있어야 하고 이런 규칙을 정의해서
어떤 리눅스를 사용하든 어느정도의 규칙이 존재하기 때문에 원하는 파일을 어느정도 쉽게 찾아갈 수 있게끔 함
---
## 📑 개념
뿌리가 되는 **루트(`/`)** 아래에 모든 것이 가지처럼 뻗어 나가는 **역트리 구조**
리눅스나 유닉스 계열 운영체제를 사용하다 보면 폴더 구조가 왜 이렇게 복잡한지 궁금할 때가 있죠.
**FHS(Filesystem Hierarchy Standard)**는 바로 이런 혼란을 방지하기 위해 파일과 디렉터리의 위치를 정의한 표준 규격입니다.
덕분에 사용자나 소프트웨어 개발자는 어떤 리눅스 배포판을 사용하더라도 특정 파일이 어디에 있을지 예측할 수 있습니다.
## 📌 상세
- **/ (root)**: 모든 파일과 디렉터리의 시작점
: 모든 디렉토리의 시작점입니다. 윈도우의 `C:\`와 비슷하지만, 리눅스에서는 모든 장치(하드디스크, USB 등)가 이 아래의 특정 폴더에 연결(마운트)됩니다.
--- 📂 주요 디렉토리
- **/bin**: 필수적인 사용자 명령 파일 (Binaries)
: 모든 사용자가 쓸 수 있는 기본 명령어들이 들어 있습니다.
- **/sbin**: 시스템 관리용 실행 파일 (System Binaries)
: 시스템 관리자(Root)가 사용하는 명령어들이 모여 있습니다.
- **/etc**: 시스템 설정 파일 (Editable Text Configurations)
: **가장 중요한 폴더 중 하나입니다.** 시스템의 모든 **설정 파일**이 들어 있습니다.
: 사용자 정보(`/etc/passwd`), 네트워크 설정, 설치된 프로그램의 환경 설정 등이 모두 여기에 텍스트 파일로 저장됩니다.
- **/home**: 일반 사용자들의 홈 디렉터리
: 일반 사용자들의 개인 공간, 예를 들어 계정명이 `dihwang`이라면 `/home/dihwang` 폴더가 생기고, 그 안에 바탕화면, 다운로드, 개인 설정 등이 저장됩니다.
: 관리자(root)를 제외한 모든 사용자는 자신의 홈 디렉토리 밖에서는 파일을 맘대로 만들거나 지울 수 없습니다.
- **/root**: 시스템 관리자(root)의 홈 디렉터리
: 시스템 최고 관리자인 **root 사용자의 홈 디렉토리**입니다. 일반 사용자 홈 디렉토리(`/home`)와는 별도로 관리됩니다.
---
--- ⚙️ 시스템 운영을 위한 폴더들
- **/usr**: 사용자 관련 모든 프로그램과 데이터 (User System Resources)
: 사용자가 설치한 프로그램과 데이터들이 모이는 곳입니다. 윈도우의 `C:\Program Files`와 가장 비슷합니다.
: `/usr/bin`: 나중에 설치한 응용 프로그램들의 실행 파일.
: `/usr/lib`: 프로그램 실행에 필요한 공유 라이브러리들.
- **/var**: 가변적인 데이터 저장소 (Variable)
: **내용이 수시로 변하는 데이터**가 저장됩니다.
: `/var/log`: 시스템 로그가 쌓이는 곳입니다. 서버가 왜 죽었는지 확인할 때 필수입니다.
: `/var/www`: 웹 서버(Apache, Nginx)의 소스 파일들이 기본적으로 위치하는 곳입니다.
- **/tmp**: 임시 파일 저장소 (Temporary)
: **임시 파일** 저장소입니다. 부팅 시나 일정 시간이 지나면 자동으로 삭제되는 파일들이 머뭅니다. 누구나 파일을 쓰고 지울 수 있습니다.
- **/dev**: 장치 파일 (Devices)
: 리눅스는 **모든 것을 파일로 관리한다**는 철학이 있습니다. 마우스, 키보드, 하드디스크 같은 물리적인 장치들도 이 폴더 안에 파일 형태로 존재합니다.
- **/mnt**: 수동으로 마운트하는 임시 지점 (Mount)
: 관리자가 수동으로 하드디스크 등을 연결할 때 쓰는 임시 장소.
- **/media**: 외부 장치 자동 마운트 지점 (USB, CD-ROM 등)
: USB나 CD-ROM을 꽂으면 자동으로 연결되는 곳.
- **/opt**: 추가 패키지 소프트웨어 설치 (Optional)
- **/boot**: 부팅 관련 핵심 파일
- **/srv**: 시스템이 제공하는 서비스 데이터 (Service)
: 요즘은 `/var/www` 등을 더 많이 씁니다.
- **/tmp**: 임시 파일 저장소 (Temporary)
- **/lib**: 공유 라이브러리 및 커널 모듈 (Libraries)
---
+38
View File
@@ -0,0 +1,38 @@
---
id: "GNU 20260407"
created: "2026-04-07 14:17"
tags:
aliases:
---
## 💡 생각
이곳에 하나의 생각 또는 아이디어를 작성합니다.
---
## 📑 개념
**GNU(그누)** 는 리처드 스톨먼이 1983년에 시작한 **자유 소프트웨어 프로젝트**이자, 그 결과로 만들어진 **운영체제**의 이름입니다.
GNU라는 이름은 **GNU is Not Unix**(GNU는 유닉스가 아니다)의 약자로, 자기 자신을 이름 안에 포함해 정의하는 재귀적 약어입니다.
## 1. GNU 프로젝트의 목적
당시에는 소프트웨어 소스 코드를 기업이 독점하고 유료로 판매하는 것이 당연시되었습니다. 리처드 스톨먼은 이에 반대하며 **누구나 소프트웨어를 실행하고, 복제하고, 수정하고, 배포할 수 있는 자유**를 누려야 한다고 주장했습니다. 이를 실현하기 위해 완전히 자유로운 운영체제를 밑바닥부터 만드는 것이 프로젝트의 목표였습니다.
## 2. 주요 구성 요소
운영체제는 단순히 커널(알맹이)만 있다고 작동하지 않습니다. GNU 프로젝트는 운영체제에 필요한 거의 모든 도구를 직접 만들었습니다.
- **GCC (GNU Compiler Collection):** 프로그램을 만드는 컴파일러
- **Glibc:** 시스템 자원을 사용하기 위한 기본 라이브러리
- **Bash:** 사용자의 명령을 입력받는 셸
- **Emacs:** 강력한 기능을 가진 텍스트 에디터
이러한 도구들은 현재 리눅스 환경에서도 표준처럼 사용되고 있습니다.
## 3. GNU와 리눅스의 관계 (중요!)
GNU 프로젝트는 운영체제의 거의 모든 구성 요소를 완성했지만, 정작 시스템의 두뇌 역할을 하는 **커널(Hurd)** 개발이 늦어지고 있었습니다.
이때 1991년, 리누스 토르발스가 **리눅스 커널**을 공개했습니다. GNU 프로젝트가 만든 수많은 소프트웨어와 리눅스 커널이 결합하면서 비로소 완벽하게 작동하는 자유 운영체제가 탄생했습니다. 우리가 흔히 부르는 리눅스는 정확히 말하면 **GNU/리눅스**인 셈입니다.
@@ -0,0 +1,60 @@
---
id: "IAM(Identity and Access Management) 20260316"
created: "2026-03-16 13:35"
tags:
---
## 💡 생각
사용자(User)가 가지는 권한이 무엇인지를 나열하고 필요한 사용자 혹은 그룹에 필요한 권한들을 원하는대로 부여할 수 있도록 구성해놓은 웹 서비스
AWS의 고유개념이 아니고 정보 보안 분야에서는 오랫동안 존재해온 표준적인 개념이자 기술 프레임워크.
---
## 📑 개념
"누가(인증)", "어떤 리소스에(권한)" 접근할 수 있는지를 중앙에서 관리를 해서 리소스에 대한 접근을 안전하게 제어할 수 있게 해주는 웹 서비스입니다.
## 📌 IAM의 핵심 구성 요소
- **사용자 (User):** 실제 사람이나 서비스(애플리케이션)를 나타냅니다. 고유한 보안 자격 증명(ID/PW 또는 Access Key)을 가집니다.
- **그룹 (Group):** 사용자들의 집합입니다. 그룹에 권한을 부여하면 그 그룹에 속한 모든 사용자가 동일한 권한을 상속받습니다. (예: `Developers` 그룹, `Admins` 그룹)
- **역할 (Role):** 특정 사용자에게 귀속되지 않고, **필요할 때만 잠시 빌려 쓰는 권한**입니다. 주로 EC2 서버나 Lambda 함수 같은 AWS 서비스가 다른 서비스에 접근할 때 사용합니다.
- **정책 (Policy):** "무엇을 할 수 있는지"를 정의한 **JSON 문서**입니다. 사용자, 그룹, 역할에 이 정책을 연결(Attach)하여 권한을 부여합니다.
### 주요 기능과 특징
| **기능** | **설명** |
| ------------------------- | ------------------------------------------------------------------ |
| **세분화된 권한 제어** | 특정 S3 버킷의 파일만 읽게 하거나, 특정 시간대에만 접속을 허용하는 등 매우 정밀한 설정이 가능합니다. |
| **다요소 인증 (MFA)** | 아이디/비번 외에 OTP(Google Authenticator 등)를 추가하여 보안을 한층 강화할 수 있습니다. |
| **자격 증명 연동 (Federation)** | 기업의 기존 계정(Active Directory 등)이나 구글/페이스북 계정으로 AWS에 로그인할 수 있게 지원합니다. |
| **비용 무료** | IAM 서비스 자체 사용에 따른 추가 비용은 없습니다. |
## 📝 노트
> [!note]
>
> ## IAM 설계의 황금률: "최소 권한의 원칙"
>
> 보안 사고를 막기 위해 IAM을 운영할 때 가장 중요한 원칙은 **최소 권한의 원칙 (Least Privilege)**입니다.
>
> - 사용자에게 업무에 **꼭 필요한 권한만** 부여합니다.
>
> - 루트(Root) 계정은 가급적 사용하지 않고, 일상 업무용 IAM 사용자를 따로 만들어 사용합니다.
>
---
![[Pasted image 20260316134417.png]]
사용자가 하나 있고 역할은 21개가 있고 정책은 1개가 생성되어있음.
![[Pasted image 20260316134502.png]]
![[Pasted image 20260316134525.png]]
사용자는 dihwang 하나가 있는데 AdministratorAccess 라는 이름의 정책을 가지고있다.
![[Pasted image 20260316134705.png]]
이 AdministratorAccess 정책에는 총 464개의 권한이 있다.
즉, dihwang 사용자는 464개의 기능을 사용할 권한이 있다는 뜻이 된다.
@@ -0,0 +1,36 @@
---
id: KISS (Keep It Simple, Stupid) 20260330
created: 2026-03-30 14:53
tags:
aliases:
---
## 💡 생각
[[단순한 코드]]를 만들어야 한다. 가독성을 항상 최우선시 하자.
단순한 형태로 쉽게쉽게 읽히는 코드를 만드는 게 중요하다.
코드의 유연성 확보는 그 다음 문제다.
---
## 📑 개념
**단순하게 유지해, 이 바보야**라는 뜻입니다. (여기서 바보는 나 자신이나 동료를 뜻하는 애칭 섞인 농담입니다.)
해결책은 항상 **가장 단순한 형태**여야 합니다.
## 📌 상세
코드가 똑똑해 보이고 화려할수록, 나중에 버그가 생겼을 때 고치기가 수십 배 더 힘들어집니다. 진짜 실력자는 어려운 문제를 어렵게 푸는 사람이 아니라, **어려운 문제를 누구나 이해할 수 있게 단순하게 푸는 사람**입니다.
복잡한 디자인 패턴이나 최신 기술을 억지로 끼워 넣지 마세요. `if-else`로 충분하다면 그렇게 짜는 것이 가장 좋습니다.
> [!question]
> Q. kiss의 경우 나도 많이 궁금했고 어려웠던건데 디자인 패턴이나 MVC패턴같은 개발 패턴들을 굳이 쓰지말고 일단은 단순하게 if-else 로 만들어란 뜻으로 해석해야 하는거야?
> A. 네, 정확하게 짚으셨습니다! **KISS** 원칙의 핵심은 **정답을 미리 정해놓고 끼워 맞추는 것이 아니라, 문제에 대한 가장 직관적인 해결책부터 시작하라**는 것입니다.
단순 if-else 로 구성된 코드가 무조건 잘못된 게 아님.
미래에 내가 다시 보거나 내가 아닌 다른사람이 내 코드를 읽었을 때 코드의 의도가 잘 이해되면 잘 만든 코드임.
디자인 패턴은 패턴의 이해가 필요하고 곧장 읽히지는 않기 때문에 디자인 패턴을 적용한 코드가 항상 가독성이 좋은 코드일수는 없음.
일단은 if-else 등의 단순한 형태로 작동되는 코드를 만드는 것이 중요함.
## 📝 노트
> [!note]
>
> - 코드의 중복이 발생되고 코드의 유연성이 떨어진다고 판단될 때 디자인 패턴을 적용하면 됨
>
---
@@ -0,0 +1,16 @@
---
id: "MVP(Minimum Viable Product) 20260320"
created: "2026-03-20 14:00"
tags:
aliases:
---
## 💡 생각
당장 꼭 필요한 기능만 포함된 최소한의 제품을 최대한 빠르게 만들어내는 게 핵심 가치
미완성본을 말하는 것이 아닌 최소한의 기능은 정상적으로 동작해야함.
---
## 📑 개념
직역하면 **생존 가능한 최소한의 제품**을 의미합니다.
단순히 '대충 만든 제품'이나 '미완성본'이 아니라, **고객에게 가치를 제공할 수 있는 핵심 기능만 담은 가장 작은 단위의 결과물**입니다.
---
@@ -0,0 +1,34 @@
### 1. 공격 표면(Attack Surface)의 최소화
파드가 퍼블릭 서브넷에 있고 공인 IP(Public IP)를 직접 가지고 있다면, 전 세계 누구나 해당 파드에 직접 접속을 시도할 수 있습니다.
- **위험성:** 애플리케이션 코드의 작은 취약점이나 설정 오류만으로도 서버 전체가 해킹당할 수 있습니다.
- **해결:** 프라이빗 서브넷에 두면 외부에서는 아예 길 자체가 없어서 직접 접근이 불가능해집니다.
### 2. 단일 진입점 강제 (로드 밸런서 활용)
사용자는 파드에 직접 붙는 것이 아니라, **로드 밸런서(ALB/NLB)**라는 검증된 관문을 통해서만 들어와야 합니다.
- 로드 밸런서는 퍼블릭 서브넷에서 외부 요청을 안전하게 걸러서 받고, 내부 네트워크를 통해 프라이빗 서브넷에 있는 파드에게 전달합니다.
- 이 구조를 통해 트래픽 제어, SSL 인증서 관리, WAF(웹 방화벽) 적용이 훨씬 쉬워집니다.
### 3. IP 주소 자원 관리
퍼블릭 IP는 전 세계적으로 한정된 자원이며 비용이 발생합니다.
- 쿠버네티스 특성상 파드는 수십, 수백 개가 생성되었다가 사라집니다. 이때마다 퍼블릭 IP를 할당하는 것은 매우 비효율적이고 비용 낭비가 심합니다.
- 내부망(Private IP)을 사용하면 주소 부족 걱정 없이 자유롭게 스케일링할 수 있습니다.
### 4. 아키텍처의 논리적 분리 (Tiering)
현대적인 3-Tier 아키텍처 원칙을 따르기 위함입니다.
- **Public Tier:** 로드 밸런서, 배스천 호스트 (외부 소통 창구)
- **Private Tier:** 애플리케이션 서버, 데이터베이스 (실제 핵심 데이터와 로직)
@@ -0,0 +1,27 @@
- 작성 **날짜:** 2026-02-27
## 📑 개념
> [!abstract]
> "AWS 클라우드 안에서 완벽하게 격리된, 사용자가 직접 정의하는 **가상 네트워크 환경**"
> AWS가 만든 개념인데 현재는 클라우드 표준처럼 사용됨
## 📌 VPC의 핵심 구성 요소
> [!check]
|**구성 요소**|**명칭**|**설명**|**비유**|
|---|---|---|---|
|**CIDR 블록**|**IP 주소 범위**|VPC에서 사용할 IP 주소의 범위를 정의 (예: `10.0.0.0/16`)|내 구역의 **전체 주소지**|
|**서브넷 (Subnet)**|**망 분할**|VPC를 더 작은 단위로 쪼갠 네트워크. 퍼블릭과 프라이빗으로 나뉨|큰 건물을 **여러 개의 방**으로 나눔|
|**라우팅 테이블**|**길잡이**|네트워크 트래픽이 어디로 가야 할지 알려주는 이정표|건물 내의 **복도와 안내판**|
|**인터넷 게이트웨이**|**IGW**|VPC와 인터넷 사이의 통로. 이게 있어야 외부 통신 가능|건물의 **정문 (바깥 세상으로 나가는 문)**|
|**NAT 게이트웨이**|**NAT**|프라이빗 서브넷의 서버가 보안을 유지하며 외부로만 나갈 때 사용|안에서는 밖을 보지만, **밖에서는 안을 못 보는 창문**|
## 📝 노트
> [!note]
>
> - 관련 사례나 반대되는 개념이 있다면 여기에 기록하세요.
>
> - 본인의 언어로 풀어서 쓰는 것이 제텔카스텔의 핵심입니다.
>
## 🔗 지식 연결
- **태그:** #zettelkasten #knowledge
@@ -0,0 +1,33 @@
---
id: "VPN(Virtual Private Network) 20260305"
created: "2026-03-05 15:00"
tags:
---
## 💡 생각
또다른 네트워크 연결 통로라고 생각하면 됨. 실제로 VPN 연결 시 네트워크 연결에 새로운 네트워크 연결이 추가됨.
![[Pasted image 20260305150408.png]]
---
## 📑 개념
가상 사설망, **인터넷상에 나만의 안전한 비밀 통로를 만드는 기술**이라고 생각하면 됨.
## 📌 상세
VPN 사용 시 주요 장점
| **장점** | **설명** |
| -------------- | -------------------------------------------------- |
| **보안 강화** | 공공장소(카페, 공항)의 무료 와이파이를 쓸 때 해킹 위험으로부터 데이터를 보호합니다. |
| **IP 주소 우회** | 나의 실제 위치(IP 주소)를 숨기고 VPN 서버가 있는 국가의 IP로 바꿀 수 있습니다. |
| **검열 및 차단 해제** | 특정 국가에서 접속이 막힌 사이트나 콘텐츠(해외 넷플릭스 등)에 접근할 수 있습니다. |
| **익명성 보장** | 방문하는 웹사이트나 서비스 제공자가 나의 실제 신원을 파악하기 어렵게 만듭니다. |
VPN 사용 시 주의할 점
- **속도 저하:** 데이터를 암호화하고 먼 거리에 있는 서버를 거치기 때문에 인터넷 속도가 평소보다 느려질 수 있습니다.
- **무료 VPN의 위험성:** "공짜" VPN 중 일부는 사용자의 활동 로그를 수집해 광고주에게 팔거나 보안이 취약할 수 있습니다. 가급적 신뢰할 수 있는 유료 서비스를 권장합니다.
- **완벽한 익명성은 없음:** VPN 업체는 내가 어떤 데이터를 주고받는지 알 수 있습니다. 따라서 '노 로그(No-log, 활동 기록을 남기지 않음)' 정책을 가진 업체를 선택하는 것이 중요합니다.
---
+45
View File
@@ -0,0 +1,45 @@
---
id: "Woodpecker 20260320"
created: "2026-03-20 16:56"
tags:
aliases:
---
## 💡 생각
이거 아주 괜찮을거같음
아주 경량화되어 사용하기 쉽고 빠릿빠릿한 젠킨스
(물론 계속 써봐야겠지만..)
---
## 📑 개념
Woodpecker CI는 오픈 소스 기반의 경량 CI/CD 엔진으로, 과거 유명했던 Drone CI에서 포크(Fork)되어 발전한 도구입니다. 복잡한 설정보다는 **간결함**과 **컨테이너 기반의 확장성**을 중시하는 팀에게 특히 매력적인 선택지입니다.
## 📌 상세
## 1. Woodpecker의 핵심 철학
Woodpecker는 모든 파이프라인 단계를 **도커(Docker) 컨테이너** 내에서 실행합니다. 이로 인해 환경 격리가 확실하며, 필요한 도구를 설치하기 위해 에이전트를 더럽힐 필요가 없습니다.
- **설정의 간소화:** `.woodpecker.yml`이라는 YAML 파일 하나로 전체 파이프라인을 정의합니다.
- **오픈 소스 정신:** 완전히 무료이며, 커뮤니티에 의해 유지보수됩니다. (Drone CI가 기업화되면서 라이선스 제약이 생긴 것에 반발하여 나온 프로젝트입니다.)
- **경량화:** 리소스 소모가 매우 적어 개인 서버나 사양이 낮은 VPS에서도 원활하게 돌아갑니다.
---
## 2. 작동 방식 (Architecture)
Woodpecker는 크게 두 가지 컴포넌트로 구성됩니다.
- **Server:** 웹 UI를 제공하고, GitHub, GitLab, Gitea와 같은 소스 코드 관리 도구(Forge)와 연동하여 웹훅(Webhook)을 처리합니다.
- **Agent:** 실제로 파이프라인 작업을 수행하는 주체입니다. 서버로부터 할당받은 작업을 컨테이너를 띄워 실행합니다.
## 주요 장점
- **멀티 플랫폼 지원:** x86_64는 물론이고 ARM64(라즈베리 파이 등)에서도 완벽하게 작동합니다.
- **다양한 Backend:** 기본적으로 Docker를 사용하지만, 최근에는 로컬 프로세스 실행이나 [[쿠버네티스(Kubernetes)]] 기반의 실행도 지원하기 시작했습니다.
- **플러그인 생태계:** Docker 이미지를 플러그인처럼 사용할 수 있습니다. 예를 들어, 빌드가 끝나고 Slack 메시지를 보내고 싶다면 이미 만들어진 Slack 플러그인 이미지를 파이프라인에 추가하기만 하면 됩니다.
@@ -0,0 +1,41 @@
---
id: "YAGNI(You Ain't Gonna Need It) 20260317"
created: "2026-03-17 16:54"
tags:
aliases:
---
## 💡 생각
지금 당장 꼭 필요한 것만 만들어라. 미리 먼저 만들지 마라
---
## 📑 개념
소프트웨어 개발 원칙 중 하나로 직역하면 **그거 필요 없을걸요** 또는 **미리 만들지 마세요**라는 뜻을 담고 있습니다.
개발자가 미래에 필요할 것으로 예상되는 기능을 미리 구현하지 말고, **실제로 그 기능이 필요한 시점이 되었을 때 구현하라**는 핵심 메시지를 전달합니다.
## 📌 상세
### 1. YAGNI가 필요한 이유
많은 개발자가 나중에 이 기능이 추가될 때를 대비해 미리 구조를 잡거나 범용적인 코드를 작성하려는 유혹에 빠지곤 합니다. 하지만 이런 **추측에 기반한 개발(Speculative Development)**은 다음과 같은 부작용을 낳습니다.
- **시간 낭비:** 결국 쓰이지 않게 될 기능을 만드느라 현재 꼭 필요한 작업에 집중하지 못하게 됩니다.
- **코드 복잡성 증가:** 당장 필요 없는 코드가 들어가면 전체적인 시스템 구조가 복잡해지고, 나중에 코드를 읽거나 수정하기 더 어려워집니다.
- **유지보수 비용 발생:** 사용되지 않는 기능이라도 버그가 생기면 수정해야 하고, 의존성 업데이트나 리팩토링 시 고려 대상이 되어 짐이 됩니다.
- **잘못된 예측:** 미래의 요구사항은 변하기 마련입니다. 미리 만들어둔 기능이 나중에 정작 필요한 형태와 달라서 결국 다시 만들어야 하는 경우가 많습니다.
### 2. YAGNI를 실천하는 방법
- **현재의 요구사항에 집중:** 오늘 해결해야 할 문제와 기능에만 충실하게 코드를 작성합니다.
- **확장성보다는 단순성:** 나중에 확장될 것을 대비해 복잡한 추상화 계층을 미리 만들기보다는, 지금 당장 이해하기 쉽고 단순한 구조를 유지합니다.
- **리팩토링의 힘:** 나중에 정말로 기능 확장이 필요해졌을 때, 그때 가서 코드를 리팩토링하여 기능을 추가하는 것이 훨씬 효율적입니다.
## 📝 노트
> [!note]
>
> - 작업의 가치는 그것이 실제로 사용될 때 발생합니다.
---
+3
View File
@@ -0,0 +1,3 @@
---
title: note
---
@@ -0,0 +1,6 @@
| **비교 항목** | **가상 머신 (EC2 등 VM)** | **컨테이너 (Docker 등)** |
| --------- | -------------------------------------- | --------------------------------- |
| **구조** | OS 위에 가상 하이퍼바이저와 **별도의 Guest OS**가 필요함 | 호스트의 **OS 커널을 공유**하며 프로세스 단위로 격리됨 |
| **무게** | GB 단위 (매우 무겁고 부팅이 느림) | **MB 단위** (매우 가볍고 즉시 실행됨) |
| **효율성** | 리소스 낭비가 큼 (OS마다 자원을 잡아먹음) | 필요한 자원만 사용하므로 집적도가 높음 |
| **이식성** | 환경 설정에 따라 작동 여부가 달라짐 | **"어디서든 동일하게 실행"**됨을 보장함 |
@@ -0,0 +1,20 @@
- 작성 **날짜:** 2026-02-27
## 📑 개념
> [!abstract]
> 시스템이 장애 없이 정상적으로 서비스를 제공할 수 있는 상태
> 언제든지 이상없이 잘 사용할 수 있는것도 가용성으로 봄
## 📝 상세 설명
> [!note]
>
> -
>
$$가용성(\%) = \frac{업타임(정상 운영 시간)}{업타임 + 다운타임(장애 시간)} \times 100$$
## 🔗 지식 연결
- **태그:** #zettelkasten #knowledge
@@ -0,0 +1,54 @@
---
id: "고차 함수(Higher-Order Function) 20260407"
created: "2026-04-07 15:55"
tags:
aliases:
---
## 💡 생각
이곳에 하나의 생각 또는 아이디어를 작성합니다.
---
## 📑 개념
함수를 다루는 함수라고 생각하면 쉬워요.
함수가 다음 중 **하나 이상**을 수행한다면 고차 함수라고 부릅니다.
## 고차 함수의 두 가지 조건
### 1. 함수를 인자로 전달받음
다른 함수를 매개변수(Parameter)로 넘겨받아 실행하는 경우입니다. 이때 인자로 전달되는 함수를 보통 **콜백 함수(Callback Function)** 라고 부릅니다.
- **예시:** `Array.prototype.map()`, `filter()`, `forEach()`
``` javascript
const numbers = [1, 2, 3];
// 여기서 map은 고차 함수이고, (n => n * 2)는 콜백 함수입니다.
const doubled = numbers.map(n => n * 2);
```
### 2. 함수를 결과로 반환함
함수 실행의 결과물로 새로운 함수를 만들어 내보내는 경우입니다. 이 방식은 **클로저(Closure)** 나 **커링(Currying)** 기법을 구현할 때 자주 쓰입니다.
- **예시:**
``` javascript
function makeMultiplier(multiplier) {
// 함수 자체를 반환합니다.
return function(value) {
return value * multiplier;
};
}
const triple = makeMultiplier(3);
console.log(triple(10)); // 30
```
---
## 왜 고차 함수를 쓰나요?
고차 함수를 사용하면 코드의 **추상화 수준**을 높일 수 있습니다.
1. **코드의 재사용성:** 복잡한 로직(반복문, 조건문 등)은 고차 함수 내부에 숨기고, 실제 수행할 구체적인 작업만 함수로 갈아 끼울 수 있습니다.
2. **가독성 향상:** `for` 문을 돌리며 배열을 수정하는 대신, `filter`나 `map` 같은 명칭을 사용함으로써 코드가 무엇을 하려는지 의도를 명확히 드러낼 수 있습니다.
3. **함수형 프로그래밍:** 데이터를 직접 변경하지 않고 새로운 데이터를 생성하는 방식(불변성 유지)을 구현하기에 최적입니다.
+42
View File
@@ -0,0 +1,42 @@
---
id: 단순한 코드 20260318
created: 2026-03-18 09:55
tags:
aliases:
---
## 💡 생각
결국 단순한 코드는
가독성이 좋아야 하고: [[코드의 가독성]]
유연성이 좋아야 한다. [[유연한 단순함]] [[유연성(Flexibility)]]
단순한 코드를 만들기 위해서는 이 두가지를 고민해야 하는데 이 자체가 고도의 작업이다.
---
> [!question]
> Q. 단순한 코드라는게 가독성도 생각해야하고 스케일업도 고민해야해서 코드를 단순하게 만드는대에도 공수가 든다. 이렇게 이해하면 되는거야?
> A. 네, 정확합니다! **단순함은 거저 얻어지는 것이 아니라, 치열한 고민과 비용(공수)이 들어가는 결과물**이라고 이해하시는 게 가장 올바른 접근입니다.
>
> 많은 초보 개발자들이 "그냥 생각나는 대로 빨리 짜는 것"을 단순하다고 착각하지만, 숙련된 개발자에게 단순함은 **불필요한 것을 깎아내는 고도의 설계 작업**을 의미합니다.
## 📌 상세
### 단순함은 '방치'가 아니라 '정제'입니다
코드를 단순하게 만들기 위해 공수가 드는 이유는 다음과 같은 **판단 과정**이 필요하기 때문입니다.
- **가독성 고민:** "나중에 내가 이 코드를 다시 봤을 때, 10초 안에 로직을 파악할 수 있는가?"를 고민하며 변수명을 고치고 함수를 쪼개는 작업이 추가됩니다.
- **스케일업(유연성) 고민:** "지금은 간단히 짜지만, 나중에 로직이 추가될 때 코드 전체를 다 뜯어고쳐야 하나?"를 생각하며 최소한의 확장성(인터페이스 분리 등)을 확보하는 데 시간이 듭니다.
## 그래서 [[파레토의 법칙]]을 여기서 적용해야합니다.
모든 코드를 이렇게 정성 들여 단순하게 만들려면 시간이 너무 많이 걸립니다. 그래서 **20%에 집중**해야 합니다.
- **핵심 20% (비즈니스 로직, 복잡한 쿼리):** 가독성과 유연성을 위해 **충분한 공수**를 들여서 단순화합니다. 여기가 복잡하면 나중에 감당이 안 되기 때문입니다.
- **나머지 80% (일회성 툴, 단순 UI 연결 등):** 여기에는 너무 많은 공수를 들이지 않습니다. 적당히 돌아가게만 짜는 것이 오히려 전체적인 효율(단순함)을 높이는 길입니다.
- [[80대20 원칙(The Pareto Principle)]]
## 📝 노트
> [!note] 스티브 잡스의 유명한 말
> "단순함은 복잡함보다 어렵다. 생각을 명확히 해서 단순하게 만들려면 정말 열심히 노력해야 한다."
---
@@ -0,0 +1,60 @@
---
id: 리눅스에 Nginx를 설치할 때 일어나는 일들 20260403
created: 2026-04-03 11:14
tags:
aliases:
---
### Nginx는 어디에 흩어져 있나요?
Nginx를 설치하면 보통 다음과 같이 각기 다른 폴더에 파일들이 들어갑니다.
| **파일 종류** | **위치 (경로)** | **설명** |
| ------------------ | ----------------- | ------------------------------------------- |
| **실행 파일 (Binary)** | `/usr/sbin/nginx` | 실제 프로그램을 돌리는 "근육"입니다. `/etc`가 아니라 여기에 있습니다. |
| **설정 파일 (Conf)** | `/etc/nginx/` | `nginx.conf` 등이 위치하는 "두뇌"입니다. |
| **기본 웹 콘텐츠** | `/var/www/html` | 웹사이트에 보여줄 HTML 파일들이 있는 "창고"입니다. |
| **로그 파일** | `/var/log/nginx/` | 접속 기록이나 에러가 쌓이는 "일기장"입니다. |
[[FHS(Filesystem Hierarchy Standard)]] 참고
### 왜 `/etc/nginx`가 눈에 잘 띌까요?
우리가 Nginx를 다룰 때 가장 많이 수정하고 접근하는 곳이 `/etc/nginx`이기 때문입니다.
실행 파일인 `/usr/sbin/nginx`는 우리가 직접 건드릴 일이 거의 없습니다. 하지만 "포트 번호를 바꾼다", "도메인을 연결한다" 같은 작업을 할 때는 무조건 `/etc/nginx` 안에 있는 텍스트 설정 파일들을 편집해야 하죠. 그래서 마치 Nginx가 거기 설치된 것처럼 느껴질 수 있습니다.
### 리눅스의 '관습' (설정과 실행의 분리)
리눅스에서 `/etc`**"시스템의 상태를 결정하는 텍스트 데이터"**만 담기로 약속되어 있습니다.
- **이유 1 (백업):** 서버를 옮길 때 `/usr`(프로그램)는 새로 설치하면 되지만, `/etc`(내 설정)는 백업하지 않으면 다 날아갑니다. 그래서 설정만 따로 모아두는 거죠.
- **이유 2 (보안):** 실행 파일이 있는 곳은 읽기 전용으로 보호하고, 설정 파일이 있는 곳만 관리자가 수정할 수 있게 권한을 나누기 위함입니다.
### 💡 확인해보기
궁금하시다면 터미널에 아래 명령어를 입력해 보세요. Nginx 실행 파일이 어디 있는지 바로 알려줄 거예요.
```bash
which nginx
```
아마 `/usr/sbin/nginx`라고 답할 겁니다.
> [!question]
> Q. 아.. /usr 가 사용자 관련 모든 프로그램과 데이터가 있는 폴더고 거기의 system binary sbin 아래에 설치가 된거구나?
> A. 정확합니다! 이해력이 정말 빠르시네요. 리눅스의 설계를 완벽하게 꿰뚫어 보셨습니다.
>
> 방금 말씀하신 내용을 조금 더 구체적으로 연결해 보면 리눅스의 구조가 더 선명해질 거예요.
## 🏗️ /usr 디렉토리의 논리적 구조
리눅스에서 `/usr`는 **User System Resources**의 약자로, 시스템 운영에 필수적인 최소한의 도구(루트 폴더의 `/bin`)를 제외한 **나머지 모든 응용 프로그램**이 거주하는 거대한 도시와 같습니다.
### /usr/bin vs /usr/**s**bin
두개의 `sbin`의 차이는 **누가 실행하는가**에 있습니다.
- **`/usr/bin` (User Binaries):** 일반 사용자가 일상적으로 쓰는 프로그램들입니다. (예: `python`, `git`, `curl` 등)
- **`/usr/sbin` (System Binaries):** 시스템 관리자(Root) 권한이 필요한, 시스템 전체에 영향을 주는 프로그램들입니다.
- **Nginx**는 웹 서버라는 시스템 서비스를 제공하기 때문에 관리자 권한이 필수적이고, 그래서 `sbin`에 위치하게 됩니다.
@@ -0,0 +1,52 @@
---
id: "리눅스와 유닉스의 파일 시스템 20260407"
created: "2026-04-07 13:15"
tags:
aliases:
---
## 💡 생각
아무튼 둘은 거의 비슷하고 리눅스의 경우 기준점을 정해놓고 가능하면 기준을 지키려고 노력하고 유닉스는 기준점이 딱히 없고 버전마다 차이점이 존재할 가능성이 높다.
---
## 📑 개념
유닉스(UNIX)와 리눅스(Linux)의 파일 시스템은 뿌리가 같기 때문에 구조적으로 매우 흡사하지만, 탄생 배경과 발전 과정에 따라 몇 가지 중요한 차이점이 있습니다. 두 시스템 모두 **계층적 트리 구조**를 사용하며 모든 것을 파일로 취급한다는 철학을 공유합니다.
## 📌 상세
## 1. 기본 구조 및 철학 (유사점)
두 시스템 모두 최상위 루트 디렉터리($/$)를 기점으로 하는 단일 트리 구조를 가집니다.
[[FHS(Filesystem Hierarchy Standard)]]라는 표준을 따르기 때문에 주요 디렉터리의 역할은 거의 동일합니다.
- **/bin, /sbin**: 실행 파일
- **/etc**: 설정 파일
- **/home**: 사용자 데이터 (유닉스는 시스템에 따라 `/usr/users` 등을 사용하기도 함)
- **/dev**: 하드웨어 장치 파일
## 2. 주요 차이점
### 디렉터리 배치 표준 (FHS vs 전통적 유닉스)
- **리눅스**: [[FHS(Filesystem Hierarchy Standard)]]라는 엄격한 표준을 만들어 배포판(Ubuntu, CentOS 등) 간의 호환성을 유지합니다. 예를 들어 가변 데이터는 반드시 `/var`에, 사용자 설치 프로그램은 `/usr/local`에 두는 식입니다.
- **유닉스**: 시스템마다 독자적인 전통을 따릅니다. 예를 들어 **Solaris**나 **HP-UX**, **AIX**는 로그 파일이나 시스템 설정 파일의 위치가 리눅스와 미세하게 다를 수 있으며, `/opt` 디렉터리를 더 적극적으로 활용하여 추가 소프트웨어를 관리하는 경향이 있습니다.
### 파일 시스템 종류 (FS Types)
- **리눅스**: 기본적으로 **Ext4**를 가장 많이 사용하며, 최근에는 대용량 데이터와 스냅샷에 유리한 **Btrfs**, **XFS** 등을 채택합니다. 오픈 소스 특성상 새로운 파일 시스템 도입이 매우 빠릅니다.
- **유닉스**: 각 벤더사가 개발한 고유의 고성능 파일 시스템을 사용합니다.
- **Solaris**: ZFS (현존하는 가장 강력한 파일 시스템 중 하나)
- **IBM AIX**: JFS/JFS2
- **HP-UX**: VxFS (Veritas Filesystem)
### 가상 파일 시스템 (VFS) 활용
- **리눅스**: `/proc`이나 `/sys` 같은 **가상 파일 시스템**을 통해 커널 정보와 하드웨어 상태를 실시간으로 노출하는 데 매우 적극적입니다.
- **유닉스**: 유닉스도 `/proc`을 사용하지만, 리눅스만큼 상세한 정보를 제공하지 않거나 시스템 관리를 위해 별도의 전용 명령어를 사용하는 경우가 더 많습니다.
결론적으로, 사용자 입장에서는 디렉터리 구조가 거의 비슷해 보이지만 **내부적인 관리 메커니즘**과 **사용 가능한 파일 시스템의 종류**에서 큰 차이가 발생합니다.
@@ -0,0 +1,30 @@
---
id: 멀티 테넌시(Multi-tenancy) 20260305
created: 2026-03-05 13:02
tags:
---
## 💡 생각
하나의 인스턴스가 여러 테넌시에 서비스를 제공해준다. 보통의 클라우드형 서비스는 멀티 테넌시라고 보면 됨.
---
## 📑 개념
하나의 소프트웨어 인스턴스가 **여러 명의 사용자(테넌트)**에게 서비스를 제공하는 구조**
아파트 한 동에 여러 가구가 살면서 엘리베이터나 복도를 공유하는 것과 비슷합니다.
## 📌 상세
- **특징:** 데이터베이스나 애플리케이션 실행 환경을 공유하지만, 각 사용자의 데이터는 논리적으로 격리되어 서로 볼 수 없습니다.
- **장점:** * **비용 효율성:** 자원을 공유하므로 사용료가 저렴합니다.
- **업데이트 용이:** 서비스 제공자가 한 번만 업데이트하면 모든 사용자가 최신 기능을 쓸 수 있습니다.
- **단점:** * **보안 우려:** 논리적으로는 격리되어 있지만, 물리적으로 같은 자원을 쓰기 때문에 보안 민감도가 높은 기업은 꺼릴 수 있습니다.
- **성능 간섭:** 특정 테넌트가 자원을 과하게 쓰면 다른 테넌트의 속도가 느려질 수 있습니다 (Noisy Neighbor 현상).
- **예시:** 구글 드라이브, 네이버 MYBOX, **대부분의 SaaS**(Slack, Notion 등).
---
## 🔗 관련 노트
- [[테넌시(Tenancy)]]
- [[싱글 테넌시(Single-tenancy)]]
@@ -0,0 +1,43 @@
---
id: 멀티유저(Multi-user) 20260407
created: 2026-04-07 13:21
tags:
- operating-system
- os
aliases:
---
![[윈도우 서버의 멀티 유저#💡 생각]]
참고: [[윈도우 서버의 멀티 유저]]
---
## 📑 개념
**멀티유저(Multi-user) 시스템**은 하나의 컴퓨터 자원(CPU, 메모리, 저장장치 등)을 여러 사용자가 **동시에** 혹은 **시분할 방식**으로 공유하여 사용할 수 있는 환경을 의미합니다. 단순히 여러 명의 계정이 있는 것을 넘어, 시스템이 각 사용자의 작업을 독립적으로 처리하고 관리하는 능력이 핵심입니다.
## 📌 상세
## 1. 멀티유저 시스템의 핵심 메커니즘
시스템이 여러 사용자를 동시에 수용하기 위해 내부적으로는 다음과 같은 기술적 처리가 이루어집니다.
- **자원 공유와 할당:** 운영체제(OS)가 CPU 스케줄링을 통해 각 사용자에게 아주 짧은 시간 동안 자원을 배분합니다. 사용자 입장에서는 마치 혼자 시스템을 사용하는 것처럼 느껴지지만, 실제로는 시스템이 매우 빠르게 사용자들을 전환하며 작업을 처리합니다.
- **사용자 인증 및 권한 관리:** 각 사용자는 고유의 ID와 비밀번호를 통해 시스템에 접속하며, 시스템은 특정 사용자에게 허용된 파일이나 프로그램에만 접근할 수 있도록 보안 정책을 적용합니다.
- **데이터 독립성 및 보안:** 한 사용자의 작업이 다른 사용자의 데이터나 프로그램 실행에 영향을 주지 않도록 **프로세스 격리**와 **메모리 보호** 기능을 수행합니다.
## 2. 주요 특징
|**특징**|**설명**|
|---|---|
|**자원 효율성**|고가의 서버 자원을 한 명의 사용자가 독점하지 않고 여러 명이 나누어 사용함으로써 하드웨어 활용도를 극대화합니다.|
|**데이터 공유**|동일한 데이터베이스나 파일 시스템에 접근하여 협업하거나 정보를 공유하기 용이합니다.|
|**동시성 제어**|여러 사용자가 같은 데이터를 동시에 수정하려 할 때 데이터 무결성을 유지하기 위한 잠금(Locking) 기술이 적용됩니다.|
|**원격 접속**|물리적으로 떨어진 위치에서도 네트워크를 통해 시스템에 접속하여 작업할 수 있습니다.|
## 3. 대표적인 사례
- **서버용 운영체제:** Linux, Unix, Windows Server 등은 설계 단계부터 멀티유저를 상정하고 만들어졌습니다. 수백 명의 개발자가 하나의 서버에 SSH로 접속해 코딩하는 환경이 대표적입니다.
- **메인프레임:** 대규모 금융 기관이나 정부 기관에서 수천 건의 트랜잭션을 동시에 처리하는 대형 시스템입니다.
- **클라우드 컴퓨팅:** AWS, Azure와 같은 환경도 물리적인 서버 자원을 전 세계 수많은 사용자가 멀티테넌트(Multi-tenant) 방식으로 나누어 사용하는 멀티유저의 확장된 개념입니다.
+81
View File
@@ -0,0 +1,81 @@
---
id: 미닉스의 한계 20260407
created: 2026-04-07 13:51
tags:
aliases:
---
## 💡 생각
자유로운 유닉스를 만들기 위해 직접 OS를 만들었다는게 대단하고 그걸 누구나 자유롭게 쓸 수 있도록 공개한게 정말 대단하다.
---
## 📑 개념
리눅스 개발자인 리누스 토르발즈가 리눅스를 개발하게 된 이유.
## 1. 하드웨어 성능 활용의 제한 (386 프로세서)
당시 리누스는 최신 사양이었던 **Intel 80386** 프로세서가 탑재된 PC를 구입했습니다. 이 CPU는 32비트 보호 모드와 강력한 멀티태스킹 기능을 갖추고 있었죠.
- **미닉스의 한계:** 미닉스는 교육용이라는 목적 때문에 사양이 낮은 구형 컴퓨터에서도 돌아가야 했습니다. 그래서 386 CPU의 강력한 성능(세그먼트 하드웨어 등)을 제대로 활용하지 못하고 16비트 기반에 머물러 있었습니다.
( CPU가 한번의 연산으로 처리할 수 있는 데이터의 양의 차이가 어마어마하게 많이 났다. )
```
- **16비트:** 한 번에 $2^{16}$ (65,536)가지의 상태를 표현하고 처리합니다.
- **32비트:** 한 번에 $2^{32}$ (약 42억 9천만)가지의 상태를 처리합니다.
```
( CPU가 데이터를 처리할 때 접근하는 메모리 주소양의 한계의 차이가 어마어마하게 많이 났다. )
```
- **16비트:** 주소를 65,536개까지만 만들 수 있습니다. 용량으로 따지면 겨우 **64KB**입니다. 이 한계를 극복하려고 예전에는 메모리를 쪼개서 관리하는 복잡한 방식을 썼습니다.
- **32비트:** 약 42억 개의 주소를 가질 수 있습니다. 우리가 흔히 아는 **4GB** 메모리까지 인식할 수 있는 단계입니다.
```
- **리누스의 선택:** 그는 자신의 386 컴퓨터 성능을 끝까지 뽑아낼 수 있는 운영체제를 직접 만들고 싶어 했습니다.
( 이런 이유때문에 OS를 개발하기러 했다고..?;; 나였으면 미닉스 말고 유닉스를 샀을텐데)
---
## 2. 라이선스와 폐쇄적인 운영
미닉스는 네덜란드의 앤드류 타넨바움 교수가 운영체제 원리를 가르치기 위해 만든 소프트웨어였습니다.
- **미닉스의 한계:** 미닉스는 오픈 소스가 아니었습니다. 책을 사야 소스코드를 볼 수 있었고, 상업적으로 이용하거나 소스코드를 마음대로 수정해서 배포하는 것이 엄격히 제한되었습니다.
- **리누스의 선택:** 리누스는 ==누구나 자유롭게 기여하고 개선할 수 있는 시스템==을 원했습니다. (이후 리눅스가 GPL 라이선스를 채택하며 폭발적으로 성장한 배경이 됩니다.)
---
## 3. 터미널 에뮬레이터 기능의 부재
실질적으로 리누스가 개발을 시작하게 된 아주 구체적이고 현실적인 이유입니다.
- **미닉스의 한계:** 리누스는 학교 서버에 접속하기 위해 [[터미널 에뮬레이터(Terminal Emulator)]]가 필요했습니다. 하지만 미닉스에 내장된 기능은 그의 마음에 들지 않았고 성능도 부족했습니다.
- **리누스의 선택:** 처음에는 단순히 "성능 좋은 터미널 프로그램"을 만들기 위해 어셈블리어로 하드웨어를 직접 제어하는 코드를 짜기 시작했습니다. 그런데 이 코드가 점점 커지면서 파일 시스템이 붙고 작업 스케줄러가 붙더니 결국 리눅스 [[커널(Kernel)]]이 된 것입니다.
##### 리누스 토르발즈가 이걸 왜 직접 만들었을까?
리누스가 미닉스를 쓸 때 가장 답답했던 건, 학교의 거대한 유닉스 서버에 접속해서 공부하고 싶은데 미닉스에 내장된 터미널 프로그램의 성능이 너무 안 좋았기 때문입니다.
- **성능 문제:** 글자가 화면에 찍히는 속도가 느리거나, 특정 특수 문자가 깨지는 등의 문제가 있었습니다.
- **직접 개발:** 그래서 그는 386 CPU의 기능을 활용해 하드웨어를 직접 제어하며 **"화면에 글자를 아주 빠르게 뿌려주는 기능"** 과 **"키보드 입력을 서버로 바로 보내는 기능"** 을 담은 자신만의 터미널 에뮬레이터를 만들기 시작했습니다.
그 결과물이 점점 살이 붙어 오늘날 전 세계 서버를 지배하는 **리눅스**가 된 것이죠.
---
## 4. 철학적 차이 (마이크로 커널 vs 모놀리식 커널)
이 부분은 타넨바움 교수와 리누스 토르발즈 사이의 유명한 논쟁(TanenbaumTorvalds debate)으로도 잘 알려져 있습니다.
- **미닉스의 설계 (마이크로 커널):** 기능들을 잘게 쪼개어 안정성을 높이는 구조였지만, 당시 기술로는 속도가 느리고 구조가 너무 복잡했습니다.
- **리눅스의 설계 (모놀리식 커널):** 리누스는 성능을 최우선으로 생각하여 모든 핵심 기능을 하나로 묶은 구조를 선택했습니다. 결과적으로 리눅스는 미닉스보다 훨씬 빠르고 강력한 성능을 보여주었습니다.
결국 리누스 토르발즈는 **"내 마음에 쏙 드는, 최신 하드웨어를 제대로 쓰는, 자유로운 유닉스가 없다면 내가 직접 만들겠다"** 는 생각으로 리눅스를 시작한 셈입니다.
당시 리누스가 리눅스를 처음 발표하며 미닉스 뉴스그룹에 올린 메일에서 **단순히 취미일 뿐이고, GNU처럼 크고 전문적인 건 아니다(just a hobby, won't be big and professional like gnu)** 라고 겸손하게 말했던 것은 아주 유명한 일화입니다.
---
@@ -0,0 +1,27 @@
- 작성 **날짜:** 2026-02-27
## 📑 개념
> [!abstract]
> 코드가 작성된 순간부터 실제 사용자에게 서비스되기까지의 모든 과정(빌드, 테스트, 배포)을 자동화한 일련의 단계
흔히 **CI/CD 파이프라인**이라고도 부릅니다.
## 📌 파이프라인의 주요 단계
> [!check]
> |**단계**|**명칭**|**주요 작업**|
> |---|---|---|
> |**1. Source**|**코드 관리**|개발자가 코드를 수정하고 저장소(Git)에 푸시(Push)하는 단계.|
> |**2. Build**|**컴파일/패키징**|코드를 실행 가능한 파일로 만들거나 컨테이너 이미지(Docker)로 빌드하는 단계.|
> |**3. Test**|**검증**|단위 테스트, 통합 테스트 등을 통해 코드의 결함이나 성능을 체크하는 단계.|
> |**4. Deploy**|**출시**|검증된 결과물을 실제 서버(EC2, Fargate 등)에 배포하여 서비스를 업데이트하는 단계.|
"소스 코드의 변경 사항을 사용자에게 전달하는 과정을 **표준화하고 자동화한 워크플로우**"
## 📝 노트
> [!note]
>
> - 주요 단계들을 표준화하고 자동화한 워크플로우를 배포 파이프라인이라고 함.
> - Jenkins가 CI/CD 엔진, 즉 배포 파이프라인 엔진임
> - git으로 코드를 푸시하면 푸시된 코드를 기준으로 Build, Test, Deploy 까지 자동으로 진행해주는걸 의미함
> - CI/CD엔진으로 AWS의 CodePipeline 이 있고 Github의 Actions 가 있음
>
## 🔗 지식 연결
- **태그:** #zettelkasten #knowledge
@@ -0,0 +1,50 @@
---
id: 보안 그룹(Security Group) 20260305
created: 2026-03-05 10:54
tags:
---
## 💡 생각
방화벽이 허용(비허용)하는 범위를 그룹핑했다는 의미로 보안그룹이라고 이름붙인 것 같음.
방화벽을 유연하고 쉽게 적용할 수 있도록 해놓은 형태
하나 이상의 보안그룹을 동시에 설정 가능함. (합집합 형태로 적용됨)
> [!example]
> 보안그룹1: A,B 허용
> 보안그룹2: B,C,D 허용
> 보안그룹 1,2 모두 지정하면 A,B,C,D 모두 허용됨
---
## 📑 개념
**"인스턴스(가상 서버)를 감싸고 있는 가상 방화벽"**입니다.**
## 📌 상세
### 1. 허용(Allow) 규칙만 설정 가능
보안 그룹에는 "이 IP는 차단해!"라는 거부(Deny) 규칙을 만들 수 없습니다. 기본적으로 모든 통로를 막아두고, **"이 포트와 이 IP만 들어오게 해줘"**라는 허용 규칙만 추가하는 방식(화이트리스트)입니다.
### 2. 상태 저장(Stateful) 방식
가장 똑똑한 기능 중 하나입니다.
- **인바운드(Inbound):** 밖에서 안으로 들어오는 요청이 허용되었다면,
- **아웃바운드(Outbound):** 안에서 나가는 응답은 별도의 설정 없이도 **자동으로 허용**됩니다. (반대도 마찬가지입니다.)
### 3. 인스턴스 단위의 보안
네트워크 전체(서브넷)를 막는 ACL(Network ACL)과 달리, 보안 그룹은 **개별 인스턴스 단위**로 적용됩니다. 예를 들어, 웹 서버용 보안 그룹과 DB 서버용 보안 그룹을 따로 만들어 각각 채워줄 수 있습니다.
### 4. 언제든지 변경 가능
규칙을 수정하면 해당 보안 그룹을 사용하는 모든 인스턴스에 **즉시 적용**됩니다. 서버를 껐다 켤 필요가 없습니다.
## 📝 노트
> [!note]
>
> - 관련 사례나 반대되는 개념이 있다면 여기에 기록하세요.
>
> - 본인의 언어로 풀어서 쓰는 것이 제텔카스텔의 핵심입니다.
>
---
+23
View File
@@ -0,0 +1,23 @@
- 작성 **날짜:** 2026-02-27
## 📑 개념
> [!abstract]
> 시스템, 데이터, 그리고 네트워크를 **비인가된 접근, 수정, 파괴**로부터 보호하는 능력
## 📌 상세
| **요소** | **설명** | **핵심 가치** |
| ------------------------- | ----------------------------------- | ------------- |
| **기밀성 (Confidentiality)** | 허가된 사용자만이 정보에 접근할 수 있어야 함. | 암호화, 접근 제어 |
| **무결성 (Integrity)** | 데이터가 전송되거나 저장될 때 임의로 수정되지 않아야 함. | 디지털 서명, 해시 함수 |
| **가용성 (Availability)** | 인가된 사용자가 필요할 때 언제든 자원을 사용할 수 있어야 함. | DDoS 방어, 이중화 |
## 📝 상세 설명
> [!note]
>
> - 말그대로 외부의 공격으로부터 보호가 잘 되어지는지를 말함
>
## 🔗 지식 연결
- **태그:** #zettelkasten #knowledge
@@ -0,0 +1,34 @@
- 작성 **날짜:** 2026-02-27
## 📑 개념
> [!abstract]
> 투입된 자원(시간, 인력, 비용) 대비 얻어낸 산출물(결과물, 가치)의 비율
>
> IT 아키텍처 관점에서의 생산성은 단순히 코드를 빨리 짜는 것을 넘어, 얼마나 효율적으로 서비스를 운영하고 비즈니스 가치를 빠르게 시장에 전달할 수 있느냐(**Time-to-Market**)에 초점이 맞춰져 있습니다.
### 1. 생산성의 정의
경제학적 관점과 소프트웨어 공학적 관점에서의 생산성은 다음과 같이 정의됩니다.
$$생산성 = \frac{Output (산출물)}{Input (투입 자원)}$$
- **IT에서의 Input:** 개발 시간, 운영 인력, 인프라 비용, 기술 부채.
- **IT에서의 Output:** 배포된 기능의 수, 서비스 안정성, 고객 만족도, 매출 가치.
### 2. 생산성을 결정짓는 3대 요소
|**요소**|**세부 내용**|
|---|---|
|**도구 및 기술 (Tools)**|자동화 도구(CI/CD), 클라우드 서비스(Fargate 등), 효율적인 프레임워크 사용.|
|**프로세스 (Process)**|애자일(Agile) 방법론, 코드 리뷰 체계, 명확한 문서화(PARA/제텔카스텐 등).|
|**인적 자원 (People)**|개발자의 숙련도, 팀 간의 원활한 커뮤니케이션, 집중할 수 있는 환경.|
## 📝노트
> [!note]
>
> - 즉 생산성이 좋다는건 투입되는 리소스 대비 산출물이 많은 경우를 의미함
> - 생산성 측정에 가치도 포함되어있기 때문에 단순히 양이 많다고 생산성이 좋은건 아니다
## 🔗 지식 연결
- **태그:** #zettelkasten #knowledge
@@ -0,0 +1,17 @@
- 작성 **날짜:** 2026-02-27
## 📑 개념
> [!abstract]
> **서버리스(Serverless)**는 이름 그대로 "서버가 없다"는 뜻이 아니라, **"사용자가 서버를 관리할 필요가 없는 컴퓨팅 모델"**을 의미합니다. 인프라의 복잡한 추상화를 통해 개발자는 오직 **코드(비즈니스 로직)**에만 집중할 수 있는 환경을 말합니다.
## 📌 상세
> [!check]
|**특징**|**세부 설명**|
|---|---|
|**관리 서버 없음**|OS 설치, 패치, 하드웨어 관리에 신경 쓸 필요가 없음.|
|**유연한 확장성**|트래픽에 따라 자원이 자동으로 늘어나거나 줄어듦 (Auto-scaling).|
|**사용량 기반 과금**|서버를 켜둔 시간이 아니라, 실제 코드가 실행된 시간/횟수만큼만 비용 지불.|
|**고가용성 내장**|클라우드 제공사가 여러 가용 영역에 걸쳐 리소스를 분산하여 안정성 보장.|
## 🔗 지식 연결
- **태그:** #zettelkasten #knowledge
+33
View File
@@ -0,0 +1,33 @@
- 작성 **날짜:** 2026-02-27
## 📑 개념
> [!abstract]
> 거대한 네트워크인 [[VPC(Virtual Private Cloud)]]를 더 효율적이고 안전하게 관리하기 위해 **더 작은 단위로 쪼갠 가상 네트워크**
**참고로 VPC도 서브넷도 모두 논리적인 개념, 물리적인 동작은 가용 영역에서 이루어짐**
## 📌 서브넷을 나누는 이유
> [!check]
> - **보안 (Security):** 인터넷에 연결될 공간과 외부로부터 완전히 격리될 공간을 분리하기 위해서입니다.
>
> - **성능 (Performance):** 네트워크 트래픽이 한꺼번에 몰리는 것을 방지하고 관리 효율성을 높입니다.
>
> - **조직화:** 용도별(웹 서버용, DB용, 관리용 등)로 자원을 그룹화하여 관리하기 위함입니다.
## 📝 노트
> [!note]
>
> - VPC가 아파트 단지라면 서브넷은 아파트단지의 동이라고 생각하면 됨.
> - AWS의 클라우드를 VPC 단위로 쪼개서 사용하고 그 VPC는 서브넷 단위로 쪼개서 사용함
> - 서브넷 단위로 분할하지 않으면 VPC로 접근하는 요청들은 VPC내에있는 모든 서비스들에게 전달해주어야함. 이를 막기위해 존재하는 개념(한번에 모든 동을 다 찾아가지 않게끔)
### 서브넷의 종류
| **구분** | **퍼블릭 서브넷 (Public)** | **프라이빗 서브넷 (Private)** |
| --------- | ----------------------------- | ---------------------------- |
| **특징** | 외부 인터넷과 양방향 통신 가능 | 외부 인터넷에서 직접 접근 불가 |
| **연결 방식** | **인터넷 게이트웨이(IGW)**와 연결됨 | 인터넷 게이트웨이와 연결되지 않음 |
| **배치 자원** | 로드 밸런서(ALB), 배스천 호스트(Bastion) | **백엔드 서버(.NET)**, 데이터베이스(DB) |
| **비유** | 아파트 정문 안내소 (누구나 방문 가능) | 아파트 내부의 안방 (가족만 접근 가능) |
## 🔗 지식 연결
- **태그:** #zettelkasten #knowledge
@@ -0,0 +1,70 @@
---
id: 순수 함수(Pure Function) 20260407
created: 2026-04-07 15:50
tags:
aliases:
---
## 💡 생각
[[유닉스의 철학과 필터]] 에서의 필터의 개념 중 한가지만 잘하게 + 함께 동작하게 를 지키기 위해서 지켜져야 할 최소한의 조건. 왜냐하면 순수하지 않은 필터는 함께 동작하기가 굉장히 어려워질 수 있고 동작중에 외부의 값을 바꿔버리면서 동작이 제대로 되지 않거나 멈춰버릴수도 있기 때문임.
---
## 📑 개념
외부 상태에 의존하지 않고 오직 입력값에만 반응하며, 외부에 아무런 영향을 주지 않는 '깨끗한' 함수를 의미합니다.
순수 함수가 되기 위해서는 다음 두 가지 조건을 반드시 만족해야 합니다.
## 1. 동일한 입력에는 항상 동일한 출력 (Deterministic)
함수가 실행되는 시점이나 환경에 상관없이, **매개변수(Input)**가 같다면 결과값은 늘 똑같아야 합니다.
- **순수 함수 예시:**
``` javascript
function add(a, b) {
return a + b;
}
```
이 함수는 언제 어디서 실행하든 `add(2, 3)`을 호출하면 무조건 **5**를 반환합니다.
- **비순수 함수 예시:**
``` javascript
let tax = 0.1;
function calculatePrice(price) {
return price + (price * tax); // 외부 변수 tax에 의존
}
```
외부의 `tax` 값이 바뀌면 결과가 달라지므로 순수 함수가 아닙니다. `Math.random()`이나 현재 시간을 가져오는 함수도 실행할 때마다 결과가 달라지기 때문에 비순수 함수에 해당합니다.
## 2. 부수 효과가 없음 (No Side Effects)
함수 내부에서 함수 밖의 상태를 변경하거나, 외부와 상호작용(입출력 등)을 하지 않아야 합니다.
- **피해야 할 부수 효과들:**
- 외부 변수 수정
- 객체나 배열 등 참조형 데이터의 원본 수정
- 콘솔 출력(`console.log`)이나 파일 쓰기
- 네트워크 요청(API 호출)
---
## 순수 함수의 장점
왜 굳이 이렇게 엄격하게 함수를 만들까요? 그 이유는 다음과 같은 이점 때문입니다.
1. **예측 가능성:** 코드가 어떻게 동작할지 머릿속으로 그리기가 훨씬 쉬워집니다.
2. **테스트 용이성:** 외부 환경을 설정(Mocking)할 필요 없이 입력값만 넣으면 되므로 단위 테스트가 매우 간편합니다.
3. **디버깅 효율:** 함수 내부에서 외부를 건드리지 않으니, 버그가 생겼을 때 추적 범위가 확 좁아집니다.
4. **캐싱(Memoization):** 동일 입력에 동일 출력이 보장되므로, 계산이 복잡한 경우 결과를 저장해두고 재사용할 수 있어 성능 최적화에 유리합니다.
> [!note] 프로젝트를 진행할 때 모든 함수를 순수 함수로 만들 수는 없지만(결국 화면 출력이나 데이터 저장이 필요하니까요), 가능한 많은 로직을 순수 함수로 분리하면 전체적인 코드의 안정성이 크게 올라갑니다.
@@ -0,0 +1,28 @@
---
id: 신호 대 소음비(Signal-to-Noise Ratio) 20260317
created: 2026-03-17 17:24
tags:
aliases:
---
## 💡 생각
신호 대 소음비가 높다는건 아무리 생각해도 신호 대비 소음의 비율이 높다는걸로 보이는데..
그냥 신호 대 소음비 라는거를 고유명사처럼 생각하는게 편할듯
신호 대 소음비가 높다 -> 의미있는 정보의 비중이 높다
---
## 📑 개념
**무엇이 신호고 무엇이 소음인가?**
**신호 대 소음비를 높인다**는 말은 **불필요한 소음(노이즈)을 최대한 제거해서 순수한 정보(신호)만 남긴다** 는 뜻
## 📌 상세
신호중에 소음의 비율이 얼마인가? 라고 생각했는데...
> [!question]
> Q. 신호 대 소음비가 높단건 신호 : 소음 중 소음의 비율이 크다는거아냐?
> A. 아, 그렇게 생각하실 수도 있겠네요! 수학적인 분수 구조를 떠올려보시면 바로 이해가 되실 거예요.
> **신호 대 소음비($SNR$)**는 말 그대로 **신호($Signal$)를 소음($Noise$)으로 나눈 값**입니다.
$$SNR = \frac{\text{Signal}}{\text{Noise}}$$
- **신호 대 소음비가 높다:** 노래 소리(신호)는 쩌렁쩌렁한데 지지직거리는 잡음(소음)은 거의 안 들리는 상태입니다. 아주 깨끗하게 들리겠죠?
- **신호 대 소음비가 낮다:** 노래 소리는 작은데 잡음이 너무 커서 노래가 묻히는 상태입니다. 짜증이 나고 듣기 힘듭니다.
---
@@ -0,0 +1,41 @@
---
id: "싱글 테넌시(Single-tenancy) 20260305"
created: "2026-03-05 13:06"
tags:
---
## 💡 생각
이곳에 하나의 생각 또는 아이디어를 작성합니다.
---
## 📑 개념
하나의 소프트웨어 인스턴스가 **단 한 명의 사용자**만을 위해 독립적으로 운영되는 구조
단독 주택에 한 가족만 사는 것과 같습니다.
## 📌 상세
- **특징:** 사용자마다 전용 인프라와 데이터베이스가 할당됩니다.
- **장점:**
- **높은 보안성:** 물리적/논리적으로 완전히 격리되어 있어 보안이 강력합니다.
- **커스터마이징:** 해당 사용자만을 위한 맞춤 설정이 자유롭습니다.
- **단점:** * **비용 부담:** 인프라 구축 및 유지보수 비용이 높습니다.
- **관리 복잡도:** 각 사용자별로 업데이트나 관리를 따로 해야 합니다.
- **예시:** 온프레미스 서버 구축, 특정 기업용 전용 클라우드 서비스.
## 📝 노트
> [!note]
>
> - 관련 사례나 반대되는 개념이 있다면 여기에 기록하세요.
>
> - 본인의 언어로 풀어서 쓰는 것이 제텔카스텔의 핵심입니다.
>
---
## 🔗 관련 노트
[[테넌시(Tenancy)]], [[멀티 테넌시(Multi-tenancy)]]
@@ -0,0 +1,27 @@
---
id: "안드로이드 스튜디오 무선디버깅 20260407"
created: "2026-04-07 11:15"
tags:
aliases:
---
### android studio <-> smart phone 무선 디버깅 방법
휴대폰의 설정 > 개발자 옵션으로 들어갑니다.
무선 디버깅 항목을 누릅니다 (스위치만 켜지 말고, 글자를 눌러 상세 페이지로 진입하세요).
화면에 보이는 'IP 주소 및 포트' 정보를 확인합니다.
예: 192.168.0.15:42135 (이 포트는 매번 바뀝니다!)
안드로이드스튜디오에서 터미널을 연다 (alt + f12)
터미널에 아래와같이 입력한다.
#### 1. 혹시 모를 찌꺼기 프로세스 정리
adb kill-server
adb start-server
#### 2. 기기에 표시된 IP와 포트로 직접 연결
adb connect 192.168.0.15:42135
adb 권한 타임아웃 해제
개발자 옵션에 있는 'ADB 권한 타임아웃 해제(Disable adb authorization timeout)' 기능은 보안과 편의성 사이의 균형을 조절하는 옵션입니다.
간단히 설명하자면, "이 PC를 신뢰할까요?"라고 물어봤던 그 인증 유효기간을 무제한으로 늘려주는 기능입니다.
사용자님처럼 안드로이드 스튜디오로 개인 프로젝트나 업무를 하시는 분들은 이 기능을 '켬(Enable)' 상태로 두는 것을 추천합니다.
@@ -0,0 +1,62 @@
---
id: "용량 공급자 전략 (Capacity Provider Strategy) 20260305"
created: "2026-03-05 10:32"
tags:
---
## 💡 생각
이곳에 하나의 생각 또는 아이디어를 작성합니다.
---
## 📑 개념
> [!abstract]
> 하나 이상의 인프라(용량 공급자)를 **어떤 비율로 섞어서 쓸지** 결정하는 고도화된 방식입니다.
> "평소엔 **[[파게이트(Fargate)]]**를 쓰되, 비용 절감을 위해 일부는 **[[파게이트 스팟(Fargate Spot)]]**을 섞어서 써줘" 같은 전략을 짤 수 있습니다.
## 📌 상세
- **방식:** "평소엔 **[[파게이트(Fargate)]]**를 쓰되, 비용 절감을 위해 일부는 **[[파게이트 스팟(Fargate Spot)]]**을 섞어서 써줘" 같은 전략을 짤 수 있습니다.
- **핵심 요소:**
- **Base (기본값):** 최소한 이만큼은 특정 공급자에서 실행해라 (예: 최소 2개는 안정적인 Fargate에서 실행).
- **Weight (가중치):** 추가로 늘어나는 태스크는 어떤 비율로 나눌 것인가 (예: Fargate 1 : Fargate Spot 3 비율로 확장).
- **비유:** "기본 식사 2인분은 코스 요리로 주고, 그 이후 추가되는 음식은 뷔페식 3 : 단품 1 비율로 섞어와주세요"라고 정교하게 주문하는 것과 같습니다.
### 기본 (Base)
- **의미:** "무슨 일이 있어도 **최소 이만큼의 개수**는 이 공급자에서 실행해라."
- **작동 방식:** 서비스가 시작될 때 가장 먼저 채워지는 숫자입니다.
- **예시:** 만약 `기본`을 2로 설정하면, 전체 태스크가 10개든 100개든 상관없이 처음 2개는 무조건 지정된 공급자(Fargate)에서 실행됩니다.
### 가중치 (Weight)
- **의미:** "기본(Base) 개수를 채우고 남은 태스크들을 **어떤 비율**로 나눌 것인가?"
- **작동 방식:** 여러 공급자를 추가했을 때 상대적인 비율로 계산됩니다.
- **예시:** `FARGATE(가중치 1)``FARGATE_SPOT(가중치 3)`으로 설정하면, 기본 개수를 채운 후 추가되는 4개의 태스크 중 1개는 Fargate, 3개는 Spot에 배치됩니다.
### 💡 왜 '용량 공급자 전략'을 써야 할까요? (핵심 이유)
가장 큰 장점은 **비용 절감과 자동 스케일링**입니다. 특히 **[[EC2(Elastic Compute Cloud)]]**를 사용하신다면, 시작 유형 방식은 서버(EC2)가 모자랄 때 태스크 실행이 실패하지만, 용량 공급자를 쓰면 ECS가 직접 **Auto Scaling Group(ASG)**에 명령을 내려서 서버를 새로 받아온 뒤 그 위에 [[태스크(Task)]]를 띄워줍니다.
**[[파게이트(Fargate)]]**를 쓰실 때도 [[파게이트 스팟(Fargate Spot)]]을 적절히 섞으면 성능은 유지하면서 비용을 최대 70%까지 아낄 수 있기 때문에, ==요즘은 대부분 이 전략 방식을 사용합니다.==
---
### 추천 시나리오
**시나리오: "안정성도 챙기고 돈도 아끼고 싶을 때"**
|**용량 공급자**|**기본 (Base)**|**가중치 (Weight)**|**설명**|
|---|---|---|---|
|**FARGATE**|**2**|**1**|**최소 2개**는 절대 꺼지지 않는 일반 Fargate로 유지 (안정성)|
|**FARGATE_SPOT**|**0**|**3**|그 이후 늘어나는 태스크는 **75% 비율**로 저렴한 Spot 사용 (비용 절감)|
### 왜 이렇게 하나요?
1. **안정성:** `FARGATE_SPOT`은 AWS에서 자원이 부족하면 예고 없이 꺼질 수 있습니다. 하지만 `Base`를 일반 `FARGATE`로 잡아두면, 서버가 아예 먹통이 되는 사태를 방지할 수 있습니다.
2. **비용:** 트래픽이 몰려 태스크가 10개, 20개로 늘어날 때, 늘어난 분량의 대부분(75%)을 훨씬 저렴한 Spot으로 돌려 비용을 대폭 아낄 수 있습니다.
@@ -0,0 +1,69 @@
---
id: 윈도우 서버의 멀티 유저 20260407
created: 2026-04-07 13:26
tags:
aliases:
---
## 💡 생각
> [!question]
> Q. 윈도우서버의 경우에는 누가 원격접속중일 떄 내가 접속시도를 하면 같은 화면을 둘 이상의 사용자가 동시에 보게되거나 심하면 먼저 접속했던 유저가 접속종료되버리더라고. 윈도우 서버는 이런 멀티유저 환경을 고려하지 않고 설계된거야?
>
> A. 결론부터 말씀드리면, **윈도우 서버(Windows Server) 역시 완벽한 멀티유저를 지원하도록 설계된 운영체제**입니다. 하지만 일반적인 PC용 윈도우(Windows 10/11)와는 라이선스 정책과 기본 설정값이 다르기 때문에 겪으신 현상이 발생하게 됩니다.
왜 나는 윈도우 서버는 멀티 유저를 제대로 지원하지 않는다고 착각한걸까?
---
## 📑 개념
[[멀티유저(Multi-user)]]
![[멀티유저(Multi-user)#📑 개념]]
하지만 나는 종종 mstsc로 윈도우 서버에 접속할 때 누군가의 '어?' 소리를 들은적이 있고 또 내가 작업중에 로그아웃이 되버려서 '어??' 소리를 낸 적이 있다.
이런일이 왜 발생했던걸까?
현재 겪으신 상황은 크게 두 가지 관점에서 이해할 수 있습니다.
## 1. 윈도우의 기본 모드: 관리용 원격 데스크톱 (Admin Mode)
윈도우 서버를 설치하면 기본적으로 **최대 2명**까지 동시 접속을 허용합니다.
- **목적:** 서버 설정 및 유지보수(관리용)입니다.
- **작동 방식:** 만약 2명의 관리자가 이미 접속해 있는 상태에서 3번째 사람이 접속을 시도하면, 시스템은 기존 사용자 중 한 명을 끊어버리거나(Kick), 접속을 거부합니다.
- **화면 공유 현상:** 만약 두 명의 사용자가 **동일한 사용자 계정(예: Administrator)** 으로 접속을 시도하면, 설정에 따라 기존 세션을 뺏어오거나(세션 리커넥트), 같은 화면을 보게 되는 경우가 생깁니다.
## 2. 진정한 멀티유저 환경: 원격 데스크톱 서비스 (RDS)
수십 명의 사용자가 각자의 독립된 바탕화면을 가지고 동시에 작업하려면, 윈도우 서버에서 **RDS(Remote Desktop Services)** 역할을 활성화해야 합니다.
- **독립된 세션:** RDS 환경에서는 각 사용자가 접속할 때마다 운영체제가 **개별적인 가상 데스크톱 환경(Session)** 을 생성해 줍니다. 따라서 옆 사람이 무엇을 하는지 서로 간섭할 수 없습니다.
- **라이선스(CAL):** 윈도우 서버는 기본적으로 관리용 2인 외에 추가 사용자가 접속하려면 **RDS CAL**이라는 별도의 라이선스 비용을 요구합니다. MS의 비즈니스 모델상, 멀티유저 기능을 "유료 옵션"으로 분리해 둔 셈입니다.
**관리 효율성:** 서버 점검을 위해 관리자 두 명 정도만 들어오면 충분하다는 판단입니다.
(돈이 더 큰 이유인거같다.)
## 3. 요약 및 해결책
윈도우 서버가 [[멀티유저(Multi-user)]]를 고려하지 않은 것이 아니라, **비용과 설정의 문제**입니다.
- **먼저 접속한 유저가 튕기는 이유:** 허용된 동시 접속 세션 수(기본 2개)를 초과했거나, 동일한 계정으로 중복 로그인을 시도했기 때문입니다.
- **해결 방법:**
1. **서로 다른 계정 사용:** 사용자마다 개별 계정을 생성하여 접속하면 관리 모드에서도 최대 2명까지는 독립적으로 사용 가능합니다.
2. **RDS 역할 설치:** 3인 이상의 동시 접속이 필요하다면 서버 역할에서 `Remote Desktop Services`를 설치하고 라이선스를 등록해야 합니다.
3. **그룹 정책(gpedit.msc) 수정:** `컴퓨터 구성 -> 관리 템플릿 -> Windows 구성 요소 -> 터미널 서비스 -> 원격 데스크톱 세션 호스트 -> 연결` 항목에서 **원격 데스크톱 서비스 사용자를 하나의 원격 데스크톱 서비스 세션으로 제한** 옵션을 사용 안 함으로 설정하면 동일 계정으로도 여러 세션을 열 수 있습니다.
> [!note] 결국.. 돈이 문제였다
라이센스 문제였을줄이야..
> [!question]
> Q. RDS 역할을 활성화하면 라이센스문제 상관없이 되는거야 아니면 RDs 역할도 설정하고 라이센스비도 내야지 3명이상 동시접속이 가능한거야?
> A. 결론부터 말씀드리면, **RDS 역할 활성화와 라이선스 구매(비용 지불)가 모두 이루어져야** 3명 이상의 동시 접속이 가능합니다.
그냥.. 서버는 리눅스 쓰자. (공짜인데다가 성능도 좋고...)
+54
View File
@@ -0,0 +1,54 @@
---
id: "유닉스(Unix) 20260407"
created: "2026-04-07 13:13"
tags:
aliases:
---
## 💡 생각
HP-UX도 운좋게 사용했는데 앞으로 내가 유닉스를 또 쓸 일이 있을까?
그리고 사실.. 리눅스랑 크게 다른 것 같지도 않았다.
---
## 📑 개념
**유닉스(Unix)** 는 1960년대 후반부터 개발된 **컴퓨터 운영체제(OS)** 로, 현대 컴퓨팅 환경의 뿌리가 되는 아주 중요한 시스템입니다. 오늘날 우리가 사용하는 리눅스, macOS, 안드로이드 등이 모두 유닉스의 철학과 구조를 계승하고 있습니다.
## 📌 상세
## 1. 유닉스의 핵심 특징
유닉스는 처음부터 **다중 사용자**와 **다중 작업**을 염두에 두고 설계되었습니다.
- **멀티태스킹(Multi-tasking):** 여러 개의 프로세스를 동시에 실행할 수 있습니다.
- [[멀티유저(Multi-user)]] 여러 사람이 동시에 시스템에 접속해서 사용할 수 있습니다.
- **계층적 파일 시스템:** 모든 데이터를 디렉터리(폴더) 구조로 관리하며, 심지어 하드웨어 장치까지도 파일로 취급합니다.
[[리눅스와 유닉스의 파일 시스템]]
- **높은 이식성:** 대부분 C언어로 작성되어 있어, 다양한 하드웨어 환경에 맞춰 수정하고 설치하기가 매우 쉽습니다.
## 2. 유닉스의 시스템 구조
유닉스는 크게 세 가지 계층으로 나뉩니다.
- [[커널(Kernel)]]: 운영체제의 심장부입니다. 하드웨어를 제어하고 메모리, 프로세스, 파일 시스템 등을 관리하는 가장 핵심적인 역할을 합니다.
- **셸(Shell):** 사용자와 커널 사이의 다리 역할을 합니다. 사용자가 명령어를 입력하면 이를 해석해서 커널에 전달합니다. (예: bash, zsh 등)
- **유틸리티/애플리케이션:** 사용자가 실제로 사용하는 프로그램들입니다. 컴파일러, 편집기, 네트워크 도구 등이 여기에 해당합니다.
## 3. [[유닉스 철학 (The Unix Philosophy)]]
![[유닉스 철학 (The Unix Philosophy)#개념]]
---
## 4. 유닉스의 계보와 영향
유닉스는 시간이 지나면서 여러 갈래로 발전했습니다.
- **BSD 계열:** 캘리포니아 대학교 버클리 캠퍼스에서 발전시킨 버전으로, 현재의 **macOS**와 **iOS**의 기반이 되었습니다.
- **System V 계열:** 상용 유닉스의 표준이 된 버전입니다.
- **리눅스(Linux):** 유닉스는 아니지만 유닉스의 작동 방식을 본떠 만든 **유닉스 계열(Unix-like)** 운영체제입니다. 현재 서버와 모바일 시장의 절대 강자죠.
+22
View File
@@ -0,0 +1,22 @@
- 작성 **날짜:** 2026-02-27
## 📑 개념
> [!abstract]
> "변화에 얼마나 쉽고 빠르게 대응할 수 있는가?"
## 📌 상세
> [!check]
> - **환경의 유연성:** 온프레미스에서 클라우드로, 또는 윈도우에서 리눅스로 실행 환경을 옮길 때의 용이성.
>
> - **구조의 유연성:** 마이크로서비스 아키텍처(MSA)처럼 특정 기능을 수정할 때 전체 시스템에 영향을 주지 않고 독립적으로 변경할 수 있는 능력.
>
> - **기술의 유연성:** 특정 벤더(Vendor Lock-in)에 종속되지 않고 필요에 따라 다양한 오픈 소스나 도구를 조합할 수 있는 상태.
## 📝 노트
> [!note]
>
> - 어떠한 상황에 얼마나 유연하게 잘 대응할 수 있는지, 단어 뜻 그대로 이해하면 될듯
>
## 🔗 지식 연결
- **태그:** #zettelkasten #knowledge
+50
View File
@@ -0,0 +1,50 @@
---
id: "유연한 단순함 20260318"
created: "2026-03-18 09:22"
tags:
aliases:
---
## 💡 생각
복잡하게 생각하지 말고 단순하게 개발하되 유연한 코드를 만들어야한다.
---
### 1. '미리 구현하는 것'과 '길을 열어두는 것'의 차이
업스케일링을 염두에 둔다는 것이 처음부터 복잡한 분산 처리 시스템이나 거대한 프레임워크를 도입하라는 뜻이 아닙니다.
- **나쁜 설계 (과잉 엔지니어링):** "나중에 사용자가 100만 명이 될지 모르니, 지금 당장 Redis 캐시를 붙이고 마이크로서비스로 쪼개자!" → **단순함 위반 (YAGNI)**
- **좋은 설계 (확장성 고려):** "지금은 로컬 DB를 쓰지만, 나중에 DB가 바뀌거나 서버가 늘어날 수 있으니 **로직과 데이터 접근 코드를 분리**해두자." → **유연한 단순함**
즉, **나중에 고치기 힘들게 코드를 꼬아놓지 않는 것** 자체가 업스케일링을 준비하는 가장 단순한 방법입니다.
### 2. 파레토 법칙의 재해석
데이터가 늘어날 때 문제가 생기는 지점은 대개 전체 코드의 20%도 안 됩니다.
- **단순화:** 80%의 일반적인 로직은 최대한 읽기 쉽고 단순하게 짭니다.
- **업스케일링 대비:** 나머지 20%의 핵심 로직(예: 데이터 조회, 대량 처리)에서 **확장 가능한 패턴(Interface 사용, 비동기 처리 등)**을 적용하는 것입니다.
이것은 모든 곳에 힘을 주는 것이 아니라, **성능의 급소가 될 만한 곳에만 최소한의 설계적 장치**를 해두는 전략입니다.
### 3. '버티는 코드'의 진짜 의미: 가독성
역설적이게도 데이터가 늘어나서 문제가 생겼을 때, 그 문제를 가장 빨리 해결할 수 있는 코드는 **단순한 코드**입니다.
- 코드가 단순하면 어디가 병목인지 금방 찾을 수 있습니다.
- 코드가 단순하면 최적화된 알고리즘으로 교체하기가 매우 쉽습니다.
- 반면, 미리 업스케일링을 한답시고 복잡하게 짜놓은 코드는 정작 문제가 터졌을 때 수정하기가 훨씬 어렵습니다.
## 📝 노트
> [!note]
>
> - **"추측에 근거해서 미리 복잡한 기능을 만들지 말되(단순함), 나중에 그 기능을 개선해야 할 때 코드 전체를 갈아엎지 않아도 되게끔 '벽'을 잘 세워두라(확장성)"**
>
---
@@ -0,0 +1,46 @@
---
id: "최적화(Optimization) 20260317"
created: "2026-03-17 16:59"
tags:
aliases:
---
## 💡 생각
이곳에 하나의 생각 또는 아이디어를 작성합니다.
---
## 📌 상세
### 1. 설계의 최적화 = 구조의 단순화
흔히 최적화라고 하면 '기교를 부려 속도를 높이는 것'을 생각하기 쉽지만, 가장 높은 수준의 최적화는 **불필요한 단계를 제거**하는 것입니다.
- **복잡한 로직:** A를 거쳐 B를 확인하고 C를 실행한다.
- **최적화된 로직:** 바로 C를 실행해도 문제가 없음을 발견하고 중간 과정을 삭제한다.
- **결과:** 성능은 빨라지고(최적화), 코드는 짧아집니다(단순화).
### 2. 인지적 최적화 (Cognitive Optimization)
코드는 컴퓨터만 읽는 게 아니라 사람도 읽습니다. 읽기 복잡한 코드는 디버깅과 유지보수 시간을 엄청나게 잡아먹죠.
- **단순한 코드**는 개발자가 코드를 이해하는 데 드는 **뇌의 연산 비용(Cognitive Load)**을 최소화해 줍니다.
- 결과적으로 전체 개발 프로세스의 성능을 높이는 '사람을 위한 최적화'가 되는 셈입니다.
### 3. 알고리즘적 최적화
예를 들어, 데이터를 찾을 때 전체를 다 뒤지는 `O(n)` 방식보다, 정렬된 데이터에서 이진 탐색을 하는 `O(log n)` 방식이 훨씬 빠릅니다.
- 때로는 효율적인 알고리즘(최적화)을 선택하는 것이, 지저분한 예외 처리를 잔뜩 넣어둔 이전 코드보다 훨씬 **간결하고 명확(단순화)**할 수 있습니다.
## 📝 노트
> [!note]
>
> - 관련 사례나 반대되는 개념이 있다면 여기에 기록하세요.
>
> - 본인의 언어로 풀어서 쓰는 것이 제텔카스텔의 핵심입니다.
>
---
+40
View File
@@ -0,0 +1,40 @@
---
id: 커널(Kernel) 20260407
created: 2026-04-07 13:40
tags:
- operating-system
- os
- hardware
- computer
- computer-science
aliases:
---
## 💡 생각
실제 하드웨어 자원을 관리하고 사용자의 요청에 하드웨어를 조작해주는 관리자.
사용자 <-> 하드웨어 사이의 인터페이스는 모두 커널이 해준다고 보면 됨.
---
## 📑 개념
운영체제(OS)의 **커널(Kernel)** 은 한마디로 **컴퓨터의 심장이자 모든 자원을 관리하는 관리자**라고 할 수 있습니다. 사용자가 실행하는 프로그램과 컴퓨터의 하드웨어 사이에서 다리 역할을 수행하는 아주 핵심적인 소프트웨어 계층입니다.
## 1. 커널의 핵심 기능
커널은 사용자가 직접 하드웨어를 제어하지 못하게 막으면서, 대신 안전하고 효율적으로 자원을 배분합니다.
- **프로세스 관리**: 여러 개의 프로그램이 동시에 실행될 수 있도록 CPU 사용 시간을 나누고 관리합니다.
- **메모리 관리**: 각 프로그램이 어느 정도의 메모리를 사용할지 결정하고, 서로의 영역을 침범하지 못하게 보호합니다.
- **파일 시스템 관리**: 하드디스크나 SSD에 데이터를 저장하고 읽어오는 방식을 제어합니다.
- **장치 드라이버 제어**: 모니터, 키보드, 마우스 등 각종 하드웨어와 통신하여 명령을 전달합니다.
- **시스템 호출(System Call) 제공**: 응용 프로그램이 하드웨어 자원을 쓰고 싶을 때 커널에 요청할 수 있는 통로를 제공합니다.
---
### 우리 주변의 커널 예시
- **Linux 커널**: 안드로이드 스마트폰, 서버용 OS, 임베디드 기기 등에서 널리 쓰이는 대표적인 **단일형 커널**입니다.
- **NT 커널**: 우리가 쓰는 **Windows**의 핵심입니다. **혼합형 커널** 구조를 가지고 있습니다.
- **XNU 커널**: macOS와 iOS의 뿌리가 되는 커널로, 마이크로 커널(Mach)과 단일형 커널(BSD)의 특징을 결합한 형태입니다.
@@ -0,0 +1,51 @@
- 작성 **날짜:** 2026-02-27
## 📑 개념
> [!abstract]
> 수많은 [[컨테이너(Container)]]의 배포, 관리, 확장, 네트워킹을 자동화하는 **'통합 관리 시스템'**입니다.
> 컨테이너를 기반으로 주요 기능들을 자동화해서 실제로 구동시켜주는 시스템
## 📌 상세
> [!check]
> |**핵심 기능**|**세부 설명**|**기대 효과**|
> |---|---|---|
> |**자동 배치 (Scheduling)**|컨테이너를 실행하기 가장 적절한 서버를 찾아 자동으로 할당|자원 효율성 극대화|
> |**자가 치유 (Self-healing)**|죽은 컨테이너를 감지하고 자동으로 재시작 또는 교체|**고가용성(HA) 확보**|
> |**오토 스케일링 (Scaling)**|트래픽 부하에 따라 컨테이너 개수를 유연하게 조절|성능 유지 및 비용 최적화|
> |**로드 밸런싱 (LB)**|여러 컨테이너에 트래픽을 고르게 분산|서비스 안정성 향상|
> |**무중단 배포 (Rolling Update)**|서비스 중단 없이 순차적으로 새 버전 업데이트|운영 연속성 보장|
### 아키텍처 구조 (Conceptual View)
컨테이너 오케스트레이션은 크게 **지휘부(Control Plane)**와 **실행부(Data Plane)**로 나뉩니다.
> [!abstract] **지휘부 (Control Plane / Master)**
>
> - 시스템의 상태를 결정하고 명령을 내리는 두뇌 역할.
>
> - 어떤 컨테이너를 어디에 띄울지 결정(Scheduling)하고 상태를 감시함.
>
> [!abstract] **실행부 (Data Plane / Worker Node)**
>
> - 실제로 컨테이너가 돌아가는 작업 공간(서버).
>
> - 지휘부의 명령을 받아 컨테이너를 실행하고 상태를 보고함.
>
|**구분**|**서비스 명칭**|**특징**|
|---|---|---|
|**오케스트레이터 (지휘자)**|**Amazon ECS / EKS**|컨테이너를 관리하는 룰과 정책을 설정함.|
|**컴퓨팅 엔진 (연주자)**|**EC2 / Fargate**|실제 컨테이너가 실행되는 물리적/가상적 인프라.|
## 📝 노트
> [!note]
>
> - 컨테이너를 사용해서 [[가용성(Availability)]]과 [[확장성(Scalability)]]문제를 해결해주는 엔진
> - 컨테이너를 알아서 잘 사용할 수 있도록 도와주는 엔진
> - 학습커브는 존재함. ([[쿠버네티스(Kubernetes)]] 학습 필요)
> (AWS의 경우 이 학습커브를 완화해주는 ECS 서비스를 제공함.)
>
## 🔗 지식 연결
- **태그:** #zettelkasten #knowledge
@@ -0,0 +1,22 @@
- 작성 **날짜:** 2026-02-27
## 📑 개념
> [!abstract]
> 컨테이너(Container)는 애플리케이션과 그 실행에 필요한 모든 것(코드, 런타임, 시스템 도구, 라이브러리, 설정 등)을 하나로 묶은 **표준화된 소프트웨어 패키지**입니다.
## 📌 상세
> [!check]
> ### 핵심 개념: "운송용 컨테이너와 같다"
>
> 항구의 컨테이너가 안에 무엇이 들었든(전자제품이든 가구든) 규격화되어 배에 쉽게 실을 수 있듯이, 소프트웨어 컨테이너도 어떤 환경(개발자 PC, 테스트 서버, 클라우드)에서든 **동일하게 작동**하도록 규격화된 것입니다.
## 📝 노트
> [!note]
>
> - 컨테이너 기술을 사용하기 쉽게 엔진화해놓은것이 도커입니다.
![[가상 머신(VM) vs 컨테이너]]
## 🔗 지식 연결
- **태그:** #docker
+53
View File
@@ -0,0 +1,53 @@
---
id: 코드의 가독성 20260317
created: 2026-03-17 17:19
tags:
aliases:
---
## 💡 생각
글로 읽을 땐 무슨 말인지 어렴풋이 짐작이 되지만 실제로 해보면 가독성이 좋은 코드를 만드는 건 어렵다.
문장처럼 읽히는 코드와 인지 부하의 최소화는 함수형 프로그래밍이 좋은 대응책인 것 같고,
---
## 📑 개념
**가독성이 높은 코드**는 단순히 "예쁜 코드"를 넘어 **코드를 읽는 사람의 뇌가 에너지를 최소한으로 쓰게 만드는 코드**를 의미합니다.
## 📌 가독성이 좋은 코드의 기준
### 1. 문장처럼 읽히는 코드 (의도 노출)
코드를 봤을 때 "어떻게(How)" 작동하는지 분석하기 전에, "무엇을(What)" 하려는지 바로 이해되어야 합니다.
- **나쁜 예:** `if (user.Status == 1 && user.Age > 19 && user.HasPaid)` (숫자 1이 무엇을 의미하는지 한참 생각해야 함)
- **좋은 예:** `if (user.IsActiveAdultMember())` (함수 이름만으로 의도가 명확함)
### 2. 인지 부하(Cognitive Load)의 최소화
사람의 단기 기억력은 한계가 있습니다. 한 번에 머릿속에 담아야 할 정보가 많을수록 읽기 힘든 코드가 됩니다.
- **낮은 중첩도:** `if` 문 안에 `if`, 그 안에 `for` 루프가 여러 번 겹쳐 있으면 뇌는 각 단계의 조건을 기억하느라 과부하가 걸립니다. (Early Return 패턴 등으로 중첩을 제거하는 것이 좋습니다.)
- **작은 함수:** 하나의 함수가 100줄이라면 흐름을 놓치기 쉽습니다. 5~10줄 내외의 작은 함수로 쪼개면 각각의 책임이 명확해집니다.
### 3. 일관성 (Consistency)
사람은 패턴을 인식하는 데 능숙합니다. 코드 전체에서 동일한 규칙이 적용되어 있다면 다음에 올 내용을 예측할 수 있게 됩니다.
- 변수 명명 규칙(CamelCase vs snake_case), 폴더 구조, 에러 처리 방식 등이 프로젝트 전체에서 일관되어야 합니다.
- **"놀람 최소화의 원칙(Principle of Least Astonishment)":** 코드를 읽었을 때 "어? 이게 왜 여기서 이렇게 동작하지?"라는 당혹감이 없어야 합니다.
### 4. [[신호 대 소음비(Signal-to-Noise Ratio)]]
코드에서 진짜 중요한 로직(신호)은 강조하고, 형식적인 문법이나 군더더기(소음)는 줄이는 것입니다.
- **불필요한 주석 제거:** 코드만으로 설명이 가능하다면 주석은 소음일 뿐입니다.
- **단순한 추상화:** 너무 복잡한 디자인 패턴을 남용하면 실제 비즈니스 로직을 찾기 힘들어집니다.
---
@@ -0,0 +1,23 @@
- 작성 **날짜:** 2026-02-27
K8s (K뒤에 8글자가 있다고 이렇게 표기하기도 함)
## 📑 개념
> [!abstract]
"수많은 컨테이너를 지휘하여 **사용자가 원하는 상태(Desired State)**로 유지해 주는 거대한 자동화 관리 시스템"
컨테이너화된 애플리케이션의 배포, 확장 및 관리를 자동화해 주는 오픈 소스 [[컨테이너 오케스트레이션]] 플랫폼**입니다.
구글이 내부에서 사용하던 시스템을 기반으로 탄생했으며, 현재 전 세계 컨테이너 관리 시스템의 표준으로 자리 잡고 있습니다.
## 📌 핵심 기능
> [!check]
> **① 선언적 구성 (Declarative Configuration)** "컨테이너 3개를 띄워줘"라고 명령서(YAML 파일)를 던지면, 쿠버네티스가 현재 상태를 확인하고 명령서와 일치하도록 스스로 자원을 조정합니다.
> **② 자가 치유 (Self-healing)** 컨테이너가 죽으면 즉시 감지하여 새로운 컨테이너를 다시 띄웁니다. 노드 자체가 죽어도 해당 노드에 있던 컨테이너들을 다른 건강한 노드로 옮겨서 실행합니다.
> **③ 무중단 배포 및 롤백** 서비스를 중단하지 않고 애플리케이션 버전을 업데이트할 수 있으며, 문제가 생기면 즉시 이전 버전으로 되돌리는(Rollback) 기능을 제공합니다.
## 📝 노트
> [!note]
>
> - 컨테이너 오케스트레이션을 해주는 엔진, 사용방법을 정확히 알고 쓰기가 까다로움.
> (알아야 할 내용이 많다.)
> - 하지만 온라인 서비스 운영에 반드시 필요한 기능들을 다 지원해준다.
## 🔗 지식 연결
- **태그:** #zettelkasten #knowledge
+45
View File
@@ -0,0 +1,45 @@
- 작성 **날짜:** 2026-02-27
## 📑 개념
> [!abstract]
> **"여러 개의 독립된 자원을 하나의 거대한 단일 시스템처럼 보이게 만드는 기술"**입니다.
> "여러 대의 컴퓨터(Node)를 네트워크로 연결하여, 외부에서는 마치 한 대의 고성능 컴퓨터처럼 작동하게 만드는 집합체"
## 📌 클러스터의 목적
> [!check]
> |**구분**|**해결하려는 문제**|**클러스터의 역할**|
> |---|---|---|
> |**신뢰성 (Reliability)**|한 대가 고장 나면 서비스 중단|**장애 극복(Failover):** 다른 컴퓨터가 즉시 업무를 대신함|
> |**성능 (Performance)**|한 대의 성능으로는 처리 불가|**병렬 처리:** 작업을 쪼개어 여러 대가 동시에 수행|
> |**확장성 (Scalability)**|성능을 더 높여야 하는 상황|**수평 확장:** 컴퓨터를 옆으로 계속 이어 붙임|
신뢰성과 확장성을 확보하고 고성능 처리를 하기 위함
### 클러스터의 핵심 구성 요소
**① 노드 (Node)** 클러스터에 참여하는 개별 컴퓨터입니다. 물리 서버일 수도 있고 가상 머신(VM)일 수도 있습니다.
**② 전용 네트워크 (Cluster Interconnect)** 노드들끼리 데이터를 주고받고 서로의 생사를 확인(Heartbeat)하기 위한 초고속 통신망입니다.
**③ 클러스터 웨어 (Clusterware/Middleware)** 여러 대의 노드를 하나로 묶어 관리하는 소프트웨어 층입니다. 누가 대장(Master)인지, 누가 죽었는지, 작업을 어디에 보낼지 결정합니다.
### 💡 한눈에 보는 비유: "오케스트라"
- **연주자 한 명:** 개별 컴퓨터 (Node)
- **오케스트라 전체:** 클러스터 (Cluster)
- **지휘자:** 클러스터 웨어 (관리 시스템)
- **관객(사용자):** 관객은 개별 연주자의 연습 상태가 아니라, 오케스트라가 만들어내는 **하나의 완성된 교향곡(서비스)**을 듣습니다. 연주자 한 명이 잠시 자리를 비워도(장애) 다른 연주자가 메워주어 곡은 계속 연주됩니다.
[[컨테이너 오케스트레이션]]
컨테이너 오케스트레이션은 즉 하나의 완성된 서비스 형태의 컨테이너 오케스트레이션을 의미
## 📝 노트
> [!note]
>
> - 여러개의 컴퓨터를 하나의 추상적인 단위로 묶어서 하나의 컴퓨터처럼 쓸수있게 해주는 기술
> - 즉, 여러 노드의 합으로 하나의 슈퍼컴퓨터를 구성하는 것
>
## 🔗 지식 연결
- **태그:** #zettelkasten #knowledge
@@ -0,0 +1,22 @@
---
id: "태스크 실행 역할(Task Execution Role) 20260305"
created: "2026-03-05 09:35"
tags:
---
## 💡 생각
태스크가 동작하기 위해 필요한 권한들을 정의해놓는다고 생각하면 됨.
---
## 📑 개념
> [!abstract]
> "태스크를 실행하기 위해 ECS 서비스가 빌려 쓰는 권한"
태스크가 실제로 구동되기 **전**과 구동되는 **과정**에서 필요한 권한
## 📌 주요 용도
> [!check]
> - **ECR 이미지 풀(Pull):** 프라이빗 저장소에서 도커 이미지를 다운로드할 권한.
>
> - **CloudWatch Logs:** 로그를 기록하기 위해 로그 그룹에 접근할 권한.
>
> - **Secrets Manager / Parameter Store:** 환경 변수에 담을 비밀번호나 설정값을 가져올 권한.
---
@@ -0,0 +1,32 @@
---
id: "태스크 역할(Task Role) 20260305"
created: "2026-03-05 09:38"
tags:
---
## 💡 생각
태스크의 컨테이너에서 구동되는 애플리케이션의 권한을 지정해줄 수 있음.
애플리케이션이 AWS의 서비스에 직접 접근해서 사용하는 경우에 설정이 필요함
---
## 📑 개념
> [!abstract]
> "내 애플리케이션(코드)이 실행 중에 직접 사용하는 권한"
> 태스크가 **실행된 후**, 내 소스 코드(Java, Python, Node.js 등) 안에서 AWS SDK를 통해 다른 서비스를 호출할 때 필요한 권한입니다.
## 📌 주요 용도
> [!check]
> - **S3 버킷 접근:** 사용자가 업로드한 파일을 저장하거나 읽을 때.
>
> - **DynamoDB/RDS:** 데이터베이스에 데이터를 쓰고 읽을 때.
>
> - **SQS/SNS:** 메시지를 보내거나 받을 때.
## 📝 노트
> [!note]
>
> - 관련 사례나 반대되는 개념이 있다면 여기에 기록하세요.
>
> - 본인의 언어로 풀어서 쓰는 것이 제텔카스텔의 핵심입니다.
>
---
@@ -0,0 +1,44 @@
---
id: 태스크 정의 패밀리 20260305
created: 2026-03-05 09:04
tags:
---
## 💡 생각
태스크는 인스턴스, 태스크 정의 패밀리는 객체와 같다고 보면 된다.
즉, 붕어빵(태스크)과 붕어빵틀(태스크 정의 패밀리)의 사이와 같다.
> [!question]
> Q. 태스크 이름이라고 하면 되지 왜 태스크 정의 패밀리 이름 이라고 이상하게 이름붙여놓은거야?
> A. 그 마음 100% 이해합니다! 처음에 AWS ECS를 접하면 **"그냥 태스크 이름(Task Name)이라고 하면 될걸, 왜 굳이 '패밀리(Family)'라는 거창한 단어를 붙여서 헷갈리게 할까?"**라는 생각이 들기 마련이죠.
이게 단순히 이름을 어렵게 지은 게 아니라, **'버전 관리'**라는 개념 때문에 그렇습니다.
## 1. 태스크 정의는 "한 번 쓰면 수정 불가능(Immutable)" 하기 때문입니다
AWS ECS에서 **태스크 정의(Task Definition)**는 한 번 만들면 내용을 고칠 수 없습니다. 만약 이미지 태그를 `v1`에서 `v2`로 바꾸고 싶다면, 기존 것을 수정하는 게 아니라 **새로운 버전**을 구워내야 합니다.
이때, **"이 설계도들은 다 같은 용도의 설계도들이야"**라고 묶어주는 그룹 이름이 바로 **패밀리(Family)**입니다.
- **Family Name:** `my-web-app` (성씨)
- **Revision 1:** `my-web-app:1` (첫째)
- **Revision 2:** `my-web-app:2` (둘째)
- **Revision 3:** `my-web-app:3` (셋째)
## 2. '태스크 이름'과 구분하기 위해서입니다
만약 이걸 그냥 '태스크 이름'이라고 불러버리면, **실제로 돌아가고 있는 실행 객체(Running Task)**와 구분이 안 됩니다.
- **태스크 정의 패밀리 (Family):** "웹 서버를 띄우기 위한 **설계도 세트**" (붕어빵 틀의 종류)
- **태스크 (Task):** "지금 서버에서 **실제로 돌아가고 있는 프로세스**" (틀에서 찍어낸 실제 붕어빵)
만약 질문자님이 `my-web-app`이라는 패밀리 이름을 정했다면, 그 설계도로 10개의 **태스크**를 띄울 수 있습니다. 이때 "태스크 이름이 뭐야?"라고 물으면 "10개 중에 어떤 거?"라고 되묻게 되죠. 그래서 **설계도의 이름**은 '패밀리'라고 불러서 확실히 구분 짓는 것입니다.
## 3. 서비스(Service)와의 연결 고리
ECS **서비스**를 만들 때 "어떤 태스크를 돌릴래?"라고 물어보는데, 이때 특정 버전(`:1`)을 지정할 수도 있지만, 보통은 **패밀리 이름**을 지정합니다. 그러면 서비스는 **"아, 이 패밀리(가족) 중에서 가장 최신 버전(Latest Revision)을 가져다가 쓰면 되겠구나!"**라고 판단합니다.
+29
View File
@@ -0,0 +1,29 @@
---
id: 태스크(Task) 20260304
created: 2026-03-04 17:12
tags:
---
## 💡 생각
컴퓨터가 처리하는 작업 단위에 더해 어떻게 처리를 해야 하는지 에 대한 모든 정보들을 담아 놓은 실행 단위
태스크 단위로 프로그램을 실행한다. 이런 느낌인 듯
---
## 📑 개념
> [!abstract]
> 컴퓨터가 처리하는 **'작업 단위'**를 말합니다.
## 📝 ECS에서의 태스크
> [!note]
> 태스크는 단순히 컨테이너 하나만을 의미하지 않습니다. 하나의 태스크 안에는 다음과 같은 요소들이 포함됩니다.
- **하나 이상의 컨테이너:** 보통은 하나의 메인 애플리케이션 컨테이너가 들어가지만, 로그 수집이나 프록시 역할을 하는 '사이드카(Sidecar)' 컨테이너를 함께 묶어 실행할 수도 있습니다.
- **공유 자원:** 태스크 내의 컨테이너들은 **동일한 네트워크 네임스페이스(IP 주소)**와 **스토리지 볼륨**을 공유합니다. 즉, 태스크 안의 컨테이너끼리는 `localhost`로 통신이 가능합니다.
- **실행 환경 설정:** CPU, 메모리 제한, IAM 역할(권한), 네트워크 모드 등이 태스크 단위로 설정됩니다.
---
## 🔗 관련 노트
- [[IAM(Identity and Access Management)]]
**Tags:** #task
@@ -0,0 +1,51 @@
---
id: 터미널 에뮬레이터(Terminal Emulator) 20260407
created: 2026-04-07 14:01
tags:
aliases:
---
## 💡 생각
이곳에 하나의 생각 또는 아이디어를 작성합니다.
---
## 📑 개념
**터미널 에뮬레이터(Terminal Emulator)** 는 쉽게 말해 **"진짜 물리적인 터미널 기계가 없어도, 소프트웨어로 그 기계가 있는 것처럼 흉내 내어 컴퓨터와 대화하게 해주는 프로그램"** 입니다.
이 개념을 이해하려면 과거의 하드웨어 터미널이 무엇이었는지 먼저 아는 것이 중요합니다.
---
## 1. 과거의 "진짜" 터미널 (Hard Terminal)
아주 옛날에는 컴퓨터(메인프레임)가 집채만 했습니다. 그래서 사용자는 컴퓨터 본체에 직접 앉을 수 없었고, **화면과 키보드만 달린 입력 장치**를 멀리 떨어진 곳에 두고 통신선으로 연결해서 썼습니다. 이걸 **터미널(단말기)** 이라고 불렀습니다.
- **본체:** 계산과 처리를 담당 (거대한 서버)
- **터미널:** 명령어를 입력하고 결과를 화면에 뿌려주는 역할만 수행 (두뇌가 없음)
![[Pasted image 20260407140335.png]]
## 2. 터미널 "에뮬레이터"의 등장
세월이 흘러 개인용 PC(데스크톱)가 보급되면서, 더 이상 화면만 달린 커다란 터미널 기계가 필요 없게 되었습니다. 하지만 서버나 운영체제는 여전히 과거 터미널 방식의 **텍스트 기반 명령어**로 대화하도록 설계되어 있었죠.
그래서 PC 안에서 **"마치 내가 예전의 그 터미널 기계인 것처럼 속여서"** 운영체제와 대화할 수 있게 해주는 소프트웨어를 만들었는데, 이것이 바로 터미널 에뮬레이터입니다.
- **하는 일:** 사용자가 키보드로 친 글자를 운영체제에 전달하고, 운영체제가 보낸 텍스트 결과를 화면에 예쁘게 그려줍니다.
- **대표적인 예:** * **Windows:** 명령 프롬프트(CMD), PowerShell, Windows Terminal
- **macOS:** Terminal.app, iTerm2
- **Linux:** GNOME Terminal, xterm
> [!warning] 셸(Shell)과의 차이점 (중요!)
많은 분이 헷갈려 하시는데, 둘은 역할이 다릅니다.
- **터미널 에뮬레이터:** 글자가 보여지는 **창(Window)** 그 자체입니다. (껍데기)
- **셸(Shell):** 그 창 안에서 내 명령을 해석해서 실행해주는 **프로그램(통역사)** 입니다. (예: bash, zsh)
즉 터미널 에뮬레이터는 putty와 매우 비슷하다고 보면 됨.
+40
View File
@@ -0,0 +1,40 @@
---
id: "테넌시(Tenancy) 20260305"
created: "2026-03-05 13:01"
tags:
---
## 💡 생각
테넌시가 차용, 임대차 뭐 그런 뜻이니까 결국 컴퓨팅 환경을 임대해서 쓴다 그런 느낌으로 이해하면 됨
---
## 📑 개념
사전적 의미로 '임대차' 또는 '차용'을 뜻하지만, IT와 클라우드 컴퓨팅 환경에서는 **소프트웨어 인스턴스나 컴퓨팅 자원을 공유하는 방식**을 의미합니다.
## 📌 상세
1. [[멀티 테넌시(Multi-tenancy)]]
2. [[싱글 테넌시(Single-tenancy)]]
### 비교 요약
| **구분** | **멀티 테넌시 (Multi-tenancy)** | **싱글 테넌시 (Single-tenancy)** |
| --------- | -------------------------- | --------------------------- |
| **비유** | 아파트, 호텔 | 단독 주택 |
| **자원 공유** | 여러 테넌트가 공유 | 단일 테넌트 전용 |
| **비용** | 저렴함 (SaaS 모델) | 비쌈 (전용 서버 모델) |
| **보안** | 양호 (논리적 격리) | 최고 (물리적 격리) |
| **적합한 곳** | 일반 사용자, 중소기업 | 대기업, 금융권, 정부 기관 |
## 📝 노트
> [!note]
>
> - 온프레미스와 싱글 테넌시는 서로 다른 개념
|**구분**|**온프레미스 (On-premise)**|**싱글 테넌시 (Single-tenancy)**|
|---|---|---|
|**관점**|**어디에** 서버가 있는가?|**누가** 이 자원을 독점하는가?|
|**위치**|우리 회사 내부 전산실|어디든 상관없음 (회사 내부 or 클라우드)|
|**반대 개념**|퍼블릭 클라우드 (Public Cloud)|멀티 테넌시 (Multi-tenancy)|
---
모든 온프레미스는 대개 싱글 테넌시 구조를 가집니다 (자사 서비스만 돌리니까요). 하지만 모든 싱글 테넌시가 온프레미스인 것은 아닙니다. 요즘은 클라우드 환경에서도 보안이나 성능을 위해 싱글 테넌시 방식을 많이 사용합니다.

Some files were not shown because too many files have changed in this diff Show More