✍️ 필사 모드: 함수형 프로그래밍의 실용 가치 심화 가이드 — Monad, Functor, 순수 함수, Haskell, Erlang/Elixir, Gleam, Effect-TS, Phoenix LiveView까지 (2025)
한국어TL;DR — 함수형 프로그래밍은 '수학자의 취미'가 아니라 동시성과 분산의 시대의 필수 사고 방식이 됐다. React Hooks는 함수형 상태 관리, Redux는
reduce, RxJS는 Observable Monad, Swift/Rust/Kotlin의Option/Result는 Maybe/Either Monad, Erlang/Elixir는 99.9999999%(nine nines) 가용성을 순수 함수 + 액터 모델로 달성한다. 2024-2025년 실무에서는 Effect-TS(TypeScript), Gleam(BEAM 위 타입 기반 언어), Elixir + Phoenix LiveView, Roc(Elm 후계자), Unison(분산 순수 언어) 같은 새로운 세대가 부상했다. 이 글은 '부작용 관리'라는 함수형의 본질이 왜 클라우드 시대에 더 중요해졌는지, Monad를 범주론 없이 어떻게 이해하는지, 그리고 현대 언어들이 함수형으로부터 무엇을 배웠는지를 추적한다.
왜 지금 다시 함수형인가
함수형 프로그래밍(FP)은 1958년 LISP로 시작해 1980-90년대 Haskell, ML 계열로 꽃 피웠지만, 산업계에서는 '학계의 언어' 취급을 받아왔다. 그런데 2010년대 중반부터 상황이 바뀌었다:
- 2015: React가 불변 props + pure render function 선언, 함수형의 대중화 시작
- 2016: Redux —
state = reducer(state, action), 사실상reduce함수 - 2017: React Hooks 제안 (공식화는 2019) — class component 대신 함수
- 2019: Rust 1.0이 'ownership + Result/Option'으로 함수형 아이디어 전면 채택
- 2020: Swift 5.5 —
async/await + Task + Result함수형 완성 - 2021: Kotlin의
Result<T>, Java의Optional<T>주류화 - 2023: TypeScript Effect-TS 1.0 — "Haskell of TypeScript" 표방
- 2024: Gleam 1.0 — BEAM(Erlang VM) 위의 타입 기반 함수형 언어
- 2024: Zed Editor, Fly.io Phoenix LiveView — Elixir 생태계 부활
- 2025: WhatsApp(20억 사용자), Discord, Pinterest, Bleacher Report가 Erlang/Elixir 확대
왜 지금? 3가지 이유:
- 동시성 — Cloud 시대의 수만 동시 요청 + 락/상태 공유의 지옥 → 불변성과 메시지 패싱이 해법
- 신뢰성 — 분산 시스템의 부분 실패(partial failure) → "let it crash" 철학의 재평가
- 타입 안전성 — 함수형의 대수적 타입(sum types, pattern matching)이 버그 감소에 결정적
순수 함수 — 모든 것의 출발점
순수 함수(Pure Function): 같은 입력 → 항상 같은 출력, 부작용 없음.
// 순수
function add(a, b) { return a + b }
function double(arr) { return arr.map(x => x * 2) }
// 불순 (부작용)
let counter = 0
function incCounter() { counter++; return counter } // 외부 상태 변경
function logAndAdd(a, b) {
console.log(a, b) // I/O 부작용
return a + b
}
function fetchUser(id) {
return fetch(`/api/users/${id}`) // 네트워크 부작용
}
순수 함수의 실전 가치
- 테스트 용이 — 입력만 주면 재현 가능, mock 불필요
- 병렬화 가능 — 공유 상태가 없어 스레드 안전 기본
- 메모이제이션 가능 — 같은 입력은 캐시 가능 (React.memo, useMemo)
- 추론 가능 — 코드를 읽는 사람이 "전역 상태 변경이 없다"고 믿을 수 있음
- 재구성 가능 — 조합, 합성(compose)이 예측 가능
참조 투명성(Referential Transparency): 함수 호출을 그 결과값으로 치환해도 프로그램 의미가 변하지 않음. 순수 함수의 다른 이름.
부작용은 사라지지 않는다
현실의 프로그램은 I/O, DB, 네트워크 없이 못 돈다. 함수형의 핵심 통찰은 부작용을 없애는 게 아니라 경계에 모으고 타입으로 표현하는 것.
- Haskell:
IO a타입으로 부작용 표현 - Rust:
Result<T, E>타입으로 실패 표현 - Effect-TS:
Effect<R, E, A>— requirement, error, value - Elm: Cmd/Sub — 런타임에 부작용 위임
불변성 — 변경을 금지하는 설계
// 가변 (Mutable)
const arr = [1, 2, 3]
arr.push(4) // arr 자체 변경
const obj = { a: 1 }
obj.a = 2 // obj 자체 변경
// 불변 (Immutable)
const arr2 = [1, 2, 3]
const arr3 = [...arr2, 4] // 새 배열
const obj2 = { a: 1 }
const obj3 = { ...obj2, a: 2 } // 새 객체
왜 불변이 중요한가
- 변경 추적 용이 — React의 "prev === next" 비교가 O(1)
- 동시성 안전 — 여러 스레드가 동시에 읽어도 문제없음
- 시간 여행 디버깅 — Redux DevTools가 가능한 이유
- Undo/Redo 간단 — 과거 상태를 그냥 유지
- Memoization 쉬움 — 같은 참조 = 같은 값 (일반적으로)
Persistent Data Structure — 불변의 성능 비용 해결
순진한 불변은 매 변경마다 전체 복사 → O(n). Persistent Data Structure는 구조 공유(structural sharing)로 O(log n) 달성.
- Immutable.js — List, Map, Set
- Immer — "draft에 변경 쓰면 내부에서 불변 복사"
- Clojure — Hash Array Mapped Trie 기본 내장
- Scala — Vector, HashMap persistent
// Immer 사용 예
import { produce } from 'immer'
const state = { users: [{ id: 1, name: 'Alice' }] }
const nextState = produce(state, draft => {
draft.users.push({ id: 2, name: 'Bob' })
draft.users[0].name = 'Alice Updated'
})
// state는 불변 유지, nextState는 새 객체
고차 함수 — 함수를 값으로
// map, filter, reduce는 고차 함수
[1, 2, 3].map(x => x * 2) // [2, 4, 6]
[1, 2, 3].filter(x => x > 1) // [2, 3]
[1, 2, 3].reduce((acc, x) => acc + x, 0) // 6
// 함수 합성 (compose)
const compose = (...fns) => x => fns.reduceRight((acc, fn) => fn(acc), x)
const toString = x => x.toString()
const exclaim = s => s + '!'
const shout = s => s.toUpperCase()
const greet = compose(shout, exclaim, toString)
greet(42) // '42!'
// Curry — 부분 적용
const curry = (fn) => {
return function curried(...args) {
if (args.length >= fn.length) return fn(...args)
return (...more) => curried(...args, ...more)
}
}
const add = curry((a, b, c) => a + b + c)
add(1)(2)(3) // 6
add(1, 2)(3) // 6
파이프라인 — 좌에서 우로
// |> 연산자 (TC39 Stage 2 제안)
const result = users
|> (xs => xs.filter(u => u.active))
|> (xs => xs.map(u => u.email))
|> (xs => xs.join(', '))
// 현재 가능한 패턴 — pipe 함수
const pipe = (...fns) => x => fns.reduce((acc, fn) => fn(acc), x)
const result = pipe(
filter(u => u.active),
map(u => u.email),
xs => xs.join(', ')
)(users)
Elixir는 |> 연산자가 언어 내장:
users
|> Enum.filter(& &1.active)
|> Enum.map(& &1.email)
|> Enum.join(", ")
Option / Maybe — null 없는 세계
Tony Hoare가 null을 "billion-dollar mistake"라 부른 이유: NullPointerException. 함수형 언어는 Option 타입으로 '값 없음'을 타입으로 표현.
// Rust
fn find_user(id: u64) -> Option<User> {
if id == 0 { None } else { Some(User { id, name: "Alice".into() }) }
}
match find_user(42) {
Some(user) => println!("{}", user.name),
None => println!("not found"),
}
// 연쇄
find_user(42)
.map(|u| u.name)
.unwrap_or("anonymous".into())
// TypeScript + fp-ts
import * as O from 'fp-ts/Option'
import { pipe } from 'fp-ts/function'
const findUser = (id: number): O.Option<User> =>
id === 0 ? O.none : O.some({ id, name: 'Alice' })
const result = pipe(
findUser(42),
O.map(u => u.name),
O.getOrElse(() => 'anonymous')
)
-- Haskell
findUser :: Int -> Maybe User
findUser 0 = Nothing
findUser id = Just User { userId = id, userName = "Alice" }
main = do
case findUser 42 of
Just u -> putStrLn (userName u)
Nothing -> putStrLn "not found"
Result / Either — 실패를 타입으로
예외는 함수 시그니처에 드러나지 않아 '보이지 않는 제어 흐름'을 만든다. Result / Either는 성공/실패를 타입으로 표현.
// Rust
fn divide(a: f64, b: f64) -> Result<f64, String> {
if b == 0.0 { Err("division by zero".into()) }
else { Ok(a / b) }
}
let result = divide(10.0, 2.0)?; // ? 연산자로 에러 자동 전파
// Effect-TS (2024)
import { Effect } from 'effect'
const divide = (a: number, b: number): Effect.Effect<never, string, number> =>
b === 0
? Effect.fail("division by zero")
: Effect.succeed(a / b)
const program = Effect.gen(function* () {
const x = yield* divide(10, 2)
const y = yield* divide(x, 0) // 실패
return x + y
})
// 실행 시 Effect.runPromise
Effect.runPromiseExit(program).then(console.log)
// { _tag: 'Failure', cause: { ... 'division by zero' ... } }
Monad — 도대체 뭔가
Monad는 함수형의 악명 높은 개념. 범주론에서 비롯했지만, **실무 관점에서는 '연쇄 가능한 wrapping 타입'**으로 이해하면 충분.
정의 (실용적)
Monad는 다음 두 연산을 제공하는 타입:
of(x)— 값x를 Monad로 감싸기 (unit,pure,return)flatMap(f)— Monad 안의 값에 함수f적용,f는 Monad 반환 (bind,>>=)
// Maybe Monad (의사 코드)
type Maybe<T> = { tag: 'some', value: T } | { tag: 'none' }
const of = <T>(x: T): Maybe<T> => ({ tag: 'some', value: x })
const flatMap = <A, B>(m: Maybe<A>, f: (a: A) => Maybe<B>): Maybe<B> =>
m.tag === 'some' ? f(m.value) : m
// 사용
const parseInt = (s: string): Maybe<number> => {
const n = Number(s)
return isNaN(n) ? { tag: 'none' } : { tag: 'some', value: n }
}
const addTen = (n: number): Maybe<number> => of(n + 10)
const result = flatMap(parseInt("42"), addTen) // { tag: 'some', value: 52 }
const result2 = flatMap(parseInt("abc"), addTen) // { tag: 'none' }
왜 Monad인가
Monad는 부작용을 타입으로 표현하고 순차 처리하는 도구. 다양한 '부작용'이 같은 인터페이스를 따르게 만든다:
- Maybe/Option — '값 없음'
- Either/Result — 실패
- Promise / Future / IO — 비동기/I/O
- List — 비결정성 (여러 결과)
- State — 상태 변경
- Reader — 환경 의존
- Writer — 로그 누적
Monad Laws (실전은 안 외워도 되지만 이해는 있어야)
- Left Identity:
of(x).flatMap(f) === f(x) - Right Identity:
m.flatMap(of) === m - Associativity:
m.flatMap(f).flatMap(g) === m.flatMap(x => f(x).flatMap(g))
이 법칙이 지켜져야 '연쇄 연산'이 기대대로 동작.
do-notation — Monad 체인을 쉽게
Haskell:
-- flatMap 체인을 do-notation으로
main = do
line <- getLine
let n = read line :: Int
print (n * 2)
-- 탈당한(풀어쓴) 형태
main = getLine >>= \line ->
let n = read line :: Int in
print (n * 2)
TypeScript (Effect-TS):
const program = Effect.gen(function* () {
const user = yield* fetchUser(1)
const posts = yield* fetchPosts(user.id)
return { user, posts }
})
JavaScript async/await도 Promise Monad의 do-notation이다!
Functor, Applicative, Monad — 3층 구조
함수형 타입 클래스(type class)의 계층:
- Functor —
map만 있음. "값을 감싼 컨테이너에 함수를 적용"Array.prototype.map,Promise.prototype.then(limited)
- Applicative — Functor +
of+ap. "여러 값을 동시 조합"- validation에서 여러 에러 수집
- Monad — Applicative +
flatMap. "이전 결과에 의존하는 연쇄"- Promise chain, do-notation
// Functor — Maybe<number> + (number => string) → Maybe<string>
map(Some(42), x => x.toString()) // Some("42")
// Applicative — Maybe<number> + Maybe<number> + ((a, b) => c) → Maybe<c>
ap(Some((a: number) => (b: number) => a + b), Some(1), Some(2)) // Some(3)
// Monad — Maybe<number> + (number => Maybe<string>) → Maybe<string>
flatMap(Some(42), x => x > 0 ? Some(x.toString()) : None)
Haskell — "수학자의 언어"의 교훈
Haskell은 1990년에 탄생한 pure, lazy, statically-typed 함수형 언어. 실무에는 니치하지만, 현대 언어들에 준 영향은 거대하다.
Haskell이 만든 혁신
- Type Class — ad-hoc polymorphism (Rust trait, Scala implicit, Swift protocol의 뿌리)
- Algebraic Data Type (ADT) — sum + product type (Rust enum, Swift enum, TS discriminated union)
- Pattern Matching — 모든 현대 언어가 채택
- Monad — IO를 순수 함수로 표현
- Lazy Evaluation — 무한 리스트
[1..]
-- 피보나치 무한 리스트 (지연 평가)
fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
take 10 fibs -- [0,1,1,2,3,5,8,13,21,34]
-- 타입 클래스 정의
class Eq a where
(==) :: a -> a -> Bool
instance Eq Int where
x == y = primEqInt x y
-- ADT
data Shape = Circle Double | Rectangle Double Double | Triangle Double Double Double
area :: Shape -> Double
area (Circle r) = pi * r * r
area (Rectangle w h) = w * h
area (Triangle a b c) = sqrt (s * (s-a) * (s-b) * (s-c))
where s = (a + b + c) / 2
Haskell의 실무 사용처
- Facebook Sigma — Haskell로 스팸 차단 시스템 (하루 100억 요청)
- GitHub Semantic — 코드 분석
- Standard Chartered — 금융 모델링
- Target — 가격 최적화
- Mercury — 뱅킹 (2020년부터)
Haskell은 '배우기 어렵지만 쓰면 좋은 언어'의 표본. 성능과 안정성이 필요한 좁은 도메인에서 여전히 강력.
Erlang/Elixir — "99.9999999%" 가용성
1986년 Ericsson이 전화 교환기용으로 만든 Erlang. 2012년 José Valim이 만든 Elixir는 Erlang VM(BEAM) 위에 Ruby 문법을 얹은 언어.
BEAM의 4가지 초능력
- Lightweight Process — 각 프로세스 300-400 바이트, 수백만 개 동시 실행 가능
- Preemptive Scheduler — 멀티코어에 자동 분산, GC 개별 프로세스
- Message Passing — shared memory 없음, 메시지로만 통신 (액터 모델)
- Hot Code Swap — 런타임에 코드 교체, 다운타임 없이 업그레이드
"Let It Crash" 철학
defmodule Worker do
use GenServer
def handle_call(:dangerous_op, _from, state) do
# 이 연산이 실패하면...
result = dangerous_call()
{:reply, result, state}
end
end
# Supervisor가 크래시 감지 → 자동 재시작
defmodule MyApp.Supervisor do
use Supervisor
def init(_) do
children = [
{Worker, []},
# 1분에 3번 이상 죽으면 최상위로 escalate
]
Supervisor.init(children, strategy: :one_for_one, max_restarts: 3, max_seconds: 60)
end
end
원칙: 방어적 코드를 쓰지 말고, 실패하게 두고, Supervisor가 재시작. 이것이 **OTP(Open Telecom Platform)**의 핵심.
Phoenix + LiveView — "WebSocket으로 React 없이 실시간 UI"
defmodule MyAppWeb.CounterLive do
use Phoenix.LiveView
def mount(_params, _session, socket) do
{:ok, assign(socket, count: 0)}
end
def handle_event("inc", _value, socket) do
{:noreply, assign(socket, count: socket.assigns.count + 1)}
end
def render(assigns) do
~H"""
<div>
<p>Count: <%= @count %></p>
<button phx-click="inc">+1</button>
</div>
"""
end
end
서버가 WebSocket으로 DOM diff를 푸시. React 없이 SPA 수준 UX. Fly.io, Supabase Realtime, Discord가 대규모로 운용.
실사용 사례
- WhatsApp — 2명의 엔지니어로 2백만 동접 (2012), 현재 20억 사용자
- Discord — Elixir로 5백만 동접 서버
- Pinterest — 알림 시스템 Erlang
- Goldman Sachs, Klarna, Bleacher Report — 핀테크/미디어
Gleam — 2024년 1.0, BEAM 위 타입 언어
Elixir가 동적 타입이라면, Gleam(Louis Pilfold, 2016-)은 정적 타입 + BEAM. 2024년 3월 1.0 릴리스.
import gleam/io
pub type Shape {
Circle(radius: Float)
Square(side: Float)
}
pub fn area(shape: Shape) -> Float {
case shape {
Circle(r) -> 3.14159 *. r *. r
Square(s) -> s *. s
}
}
pub fn main() {
let c = Circle(radius: 5.0)
io.debug(area(c))
}
특징:
- Rust 수준의 타입 추론
- Elixir/Erlang 모듈과 양방향 호환
- JavaScript로 컴파일도 가능 (브라우저 타겟)
- 문법은 Rust-ish
2024-2025년 BEAM 진영의 뜨거운 언어.
Clojure, F#, Scala, OCaml — 하이브리드 함수형
Clojure
- JVM 위의 LISP 방언 (Rich Hickey, 2007)
- 불변성 기본, persistent data structure
- 매크로로 언어 확장
- core.async로 CSP (Go 영향)
- 사용처: Walmart, Nubank, NASA
(defn add [a b] (+ a b))
(->> [1 2 3 4 5]
(filter odd?)
(map #(* % %))
(reduce +)) ; 35
F#
- Microsoft (Don Syme, 2005), OCaml 기반 + .NET
- Computation Expression (Haskell do-notation 유사)
- Jet.com, Walmart Labs, 많은 금융권
Scala
- JVM 위의 하이브리드 OOP + FP (Martin Odersky, 2003)
- Twitter, LinkedIn, Spotify 백엔드
- 3.0(2021)부터 syntax 단순화
- Play, Akka, Apache Spark의 언어
OCaml
- 프랑스 INRIA, 1996
- Jane Street(금융), Facebook(Flow, Hack), Docker (초기), Coq 증명 보조기
- Rust의 컴파일러 초기도 OCaml로 작성
React, Redux, RxJS — JavaScript의 함수형 상속
React의 핵심 아이디어는 UI = f(state). 순수 함수로 UI를 모델링.
// React 컴포넌트는 pure function of props
function Greeting({ name }) {
return <h1>Hello, {name}</h1>
}
// useState는 immutable update
function Counter() {
const [count, setCount] = useState(0)
return <button onClick={() => setCount(c => c + 1)}>{count}</button>
}
Redux는 (state, action) => state 정확히 reduce:
function reducer(state, action) {
switch (action.type) {
case 'INC': return { ...state, count: state.count + 1 }
case 'DEC': return { ...state, count: state.count - 1 }
default: return state
}
}
RxJS는 Observable Monad — 시간에 따른 값의 스트림:
const click$ = fromEvent(button, 'click').pipe(
map(e => e.clientX),
filter(x => x > 100),
debounceTime(300)
)
click$.subscribe(x => console.log(x))
Effect-TS — TypeScript의 Haskell
2024년 1.0 릴리스. Scala ZIO의 TypeScript 판.
import { Effect, pipe, Layer } from 'effect'
// Effect<R, E, A>
// R: 필요한 서비스(dependency)
// E: 에러 타입
// A: 성공 값
interface Logger {
log: (msg: string) => Effect.Effect<never, never, void>
}
const Logger = Context.Tag<Logger>()
const program = Effect.gen(function* () {
const logger = yield* Logger
yield* logger.log("starting...")
const user = yield* fetchUser(1)
yield* logger.log(`got user ${user.name}`)
return user
})
// 실행 시 Layer 주입
const LoggerLive = Layer.succeed(Logger, {
log: (msg) => Effect.sync(() => console.log(msg))
})
Effect.runPromise(pipe(program, Effect.provide(LoggerLive)))
특징:
- DI + Error handling + Async + Retry + Fiber(가벼운 스레드)를 타입 안전하게 통합
- 대규모 TypeScript 앱에서 Monad Transformer 지옥 없이 가능
- 학습 곡선 가파름, 하지만 복잡한 시스템에서 생산성 급상승
동시성 모델들
Actor 모델 (Erlang/Elixir/Akka)
- 독립적 프로세스 + 메시지 박스
- 공유 메모리 없음
- 수백만 병행성
CSP (Go, Clojure core.async)
- 채널을 통한 통신
- "Don't communicate by sharing memory; share memory by communicating"
Software Transactional Memory (STM)
- 메모리를 DB 트랜잭션처럼 다룸
- Haskell
STM, Clojureref
Promise/Future (JavaScript, Rust, Python, Swift)
- 값의 '미래 약속'
async/await로 동기식 코드 스타일
2024-2025 주목할 함수형 언어
Roc (Richard Feldman, Elm 후계자)
- 2024년 0.1 공개, LLVM 기반
- Elm의 단순함 + 성능
- Platform 개념: DB, web, CLI 별로 다른 platform 선택
Unison
- "분산 순수 프로그래밍"
- 함수 = 해시. 동일 함수는 네트워크로 전송 안 하고 해시만 참조
- 분산 AI/ML 워크플로우에 관심
Koka (Daan Leijen, Microsoft)
- Algebraic Effects — Monad의 대안
- "effect system" 연구 언어
Lean 4
- Microsoft + 수학 증명 + 일반 프로그래밍 병합
- Terence Tao가 수학 증명에 활용
10가지 흔한 안티패턴
- Monad 지옥 — 모든 것을 Monad로 감싸 가독성 파괴. 경계에서만 써라.
- Pure purity — I/O 전부 회피하려다 비실용적. 부작용 경계에 모아라.
reduce남발 — 복잡한 reducer는 가독성 파괴. 여러 개의 map/filter로 쪼개라.- Lazy evaluation 오남용 — 디버그 어려움, 메모리 누수.
- Curry 강요 — JS/TS에서 모든 함수를 curry하면 IDE 타입 힌트 망가짐.
- Immutable 강박 — 로컬 변수는 가변이어도 됨. 경계만 불변 유지.
- 고계 함수 체이닝 길이 과도 — 10단계
.map.filter.reduce는 명령형이 더 읽힘. - Monad transformer stack — 4-5층 되면 Effect-TS/Koka 같은 대안 고려.
- Actor 모델 오해 — 모든 것을 Actor로 만들면 오버엔지니어링. CPU 집약 작업은 데이터 지향.
- Dynamic FP 착각 — 타입 없이 FP 하면 Monad 체이닝이 지옥. 타입 있는 언어에서 시작.
실전 학습 체크리스트 (2025)
- map/filter/reduce 체인을 자유자재로 — 모든 언어에서
- Option/Result 타입 사용 — Rust, Swift, Kotlin부터
- Pattern Matching + ADT — TS discriminated union, Rust enum
- 불변 데이터 구조 선택 — Immer, Immutable.js, Clojure, Scala
- Promise chain ≒ Monad 이해
- RxJS 기본 operators — map, filter, mergeMap, switchMap
- React Hooks의 함수형 본질 — useMemo, useCallback = memoization
- Actor 또는 CSP 패턴 — Elixir GenServer 또는 Go channel
- Effect-TS 또는 fp-ts — 복잡한 TS 앱에서 실험
- 하스켈 단기 탐험 — 2주 튜토리얼, 사고 방식 확장
- Elixir + Phoenix LiveView — 실시간 UI 경험
- Monad 법칙 이해(암기 말고 직관)
다음 글 예고 — "Kubernetes는 왜 이렇게 복잡한가" — 클러스터 운영의 진짜 비용, Service Mesh, GitOps, Platform Engineering 심화
함수형 프로그래밍이 '개별 코드의 신뢰성'을 높인다면, Kubernetes와 Cloud Native는 '시스템 전체의 신뢰성'을 다룬다. 2014년 Google이 내부 Borg 경험을 오픈소스로 공개한 이후, K8s는 사실상 클라우드의 운영 체제가 됐다. 하지만 그 복잡도는 악명 높다.
다음 글에서는:
- K8s가 해결한 문제와 새로 만든 문제
- Pod, Service, Deployment, Ingress — 기본 구성 요소
- Control Plane 아키텍처 — etcd, API Server, Scheduler, Controller
- Networking — CNI, kube-proxy, Service Mesh (Istio, Linkerd, Cilium)
- Service Mesh 논쟁 — sidecar vs Ambient Mesh
- GitOps 혁명 — ArgoCD, Flux
- Helm vs Kustomize vs Jsonnet — 매니페스트 관리
- Platform Engineering — Backstage, IDP (Internal Developer Platform)
- Operator 패턴 — CRD로 K8s 확장
- 멀티클러스터 전략 — Karmada, Cluster API, KubeFed
- 비용 최적화 — OpenCost, Kubecost, Karpenter
- 2025 K8s 트렌드 — WASM, eBPF, Gateway API
을 다룬다. 'Kubernetes는 정말 필요한가'라는 본질적 질문부터 실전 운영 레시피까지, 클라우드 네이티브 세계의 전 지형도를 정리한다.
현재 단락 (1/431)
함수형 프로그래밍(FP)은 1958년 **LISP**로 시작해 1980-90년대 Haskell, ML 계열로 꽃 피웠지만, 산업계에서는 '학계의 언어' 취급을 받아왔다. 그런데 2...