MAC 주소 쉽게 이해하기: 네트워크 식별자의 역할과 의미

하드웨어 식별자, MAC 주소와 역할과 구조

🔍 MAC 주소란?

MAC 주소(Media Access Control Address)는 네트워크와 연결된 각 장치(Network Interface Card, NIC)의 고유 식별자다.

이는 하드웨어 수준에서 장치를 식별하기 위한 값으로, 보통 16진수 형식의 48bit(6bytes) 주소로 표현된다.

각 바이트는 : 또는 -를 사용해 구분하며, 샘플은 다음과 같다.

00:1A:2B:3C:4D:5E


🧬 MAC 주소 구조

MAC 주소는 일반적으로 다음과 같이 구성된다.

OUI (Organizationally Unique Identifier): 앞의 3바이트는 제조사 식별 코드 (예: Apple, Intel 등)로 위 샘플에서는 00:1A:2B가 OUI이다.

Device Identifier: 뒤의 3바이트는 각 제조사가 장치에 부여하는 고유 번호

MAC 주소는 제조 시 하드웨어에 고정되어 부여되며, 중복이 거의 없도록 관리된다.

3바이트(24비트)는 이론적으로 최대 16,777,215개의 고유 번호를 구분할 수 있지만, 실제로는 브로드캐스트·멀티캐스트 등 특수 용도로 예약된 비트와 주소 범위가 존재하므로, 하나의 식별 코드로 관리 가능한 고유 번호의 수는 이보다 훨씬 적다.

단적인 예로, 아이폰의 경우 한 대의 기기 안에도 Wi-Fi MAC 주소와 Bluetooth MAC 주소 두 개가 존재한다. 지금까지 판매된 아이폰의 누적 대수가 수억 대에 달하기 때문에, 단일 OUI만으로는 모든 기기를 식별하기 어려워 여러 개의 OUI를 사용하고 있다.

MAC 주소는 IEEE(Institute of Electrical and Electronics Engineers)에서 관리하고 있으며, 애플에서만 수백 개 이상의 OUI를 보유한 것으로 알려져 있다.


📡 MAC 주소는 어디서 사용될까?

MAC 주소는 주로 **데이터링크 계층(OSI 2계층)**에서 사용된다.

예를 들어:

  • 같은 네트워크(서브넷) 내에서 A → B로 데이터를 전송할 때, IP 주소는 목적지를 논리적으로 식별하지만 실제 이더넷 프레임은 MAC 주소를 통해 정확한 장비를 찾아 전송한다.

    IP 주소와 MAC 주소의 데이터 전달 방식

📘 MAC vs IP 주소의 차이

항목MAC 주소IP 주소
계층OSI 2계층 (데이터링크)OSI 3계층 (네트워크)
성격물리적(고유) 식별자논리적(변경 가능) 식별자
예시00:1A:2B:3C:4D:5E192.168.1.1
변경 가능성일반적으로 불변 (수정도 가능하긴 함)네트워크 변경에 따라 변동

🔄 통신 과정에서의 MAC 주소 역할

  1. A 컴퓨터가 B의 IP 주소를 알고 있을 때,
  2. 같은 네트워크라면 **ARP(Address Resolution Protocol)**를 통해 해당 IP에 대응하는 MAC 주소를 요청
  3. B가 MAC 주소를 응답하고, A는 그 MAC 주소를 프레임의 목적지 주소로 설정하여 전송
  4. 이 프레임은 MAC 주소를 기준으로 B에 도달

💡 MAC 주소는 인터넷 전체에서 사용될까?

MAC 주소는 로컬 네트워크(같은 서브넷) 내에서만 사용된다.

서브넷을 넘어서는 통신에서는 IP 주소 기반 라우팅이 작동하며, 라우터는 다음 홉(HOP)의 MAC 주소만 사용하여 전달을 이어간다.

따라서 MAC 주소는 직접 연결된 네트워크에서만 의미를 가진다.


🔐 보안과 MAC 주소

MAC 주소는 고유하지만 주의할 점이 있다.

  • 🛠️ 소프트웨어적으로 위조(Spoofing) 가능
  • 🔒 일부 네트워크에서는 MAC 주소 기반 접근 제어(ACL) 적용
  • 🧭 MAC 필터링을 사용하는 네트워크에서는 등록되지 않은 MAC은 접근 불가

🧪 MAC 주소 확인 방법

MAC OS

ifconfig | grep ether

혹은:

networksetup -listallhardwareports

WINDOWS OS

ipconfig /all

✍️ 마무리

MAC 주소는 네트워크의 시작점에서 중요한 역할을 한다.

하드웨어의 신분증 같은 MAC 주소 덕분에 우리는 수많은 장치 간 정확한 데이터 전송을 경험할 수 있다.

IP 주소와 MAC 주소를 통한 데이터 전달 방식

목적지를 알려주는 IP 주소, 길을 알려주는 MAC 주소

인터넷이나 사내 네트워크에서 우리가 데이터를 요청하거나 API 통신을 수행할 때, 실제로는 수많은 네트워크 장비와 프로토콜이 이 작업을 처리한다. 특히 중요한 두 가지 개념이 바로 IP 주소MAC 주소다.

OSI 7계층 중 네트워크 계층(IP 주소)과 데이터 링크 계층(MAC 주소)에서 실제 데이터 전송에 어떤 역할을 하고, 어떻게 협력하여 목적지까지 데이터를 정확히 전달하는지를 알아보자.


✅ IP 주소와 MAC 주소, 무엇이 다른가?

항목IP 주소MAC 주소
종류논리 주소 (변경 가능)물리 주소 (고유값)
용도목적지 찾기 (라우팅)실제 전송 대상 식별
계층네트워크 계층 (3계층)데이터 링크 계층 (2계층)
범위세계적 식별자 (라우팅용)동일 네트워크(서브넷) 내 식별자

🔁 실제 데이터 전송 흐름 요약

예시: A 기기(192.168.1.2) → B 기기(192.168.2.3)로 전송할 경우

1. 출발지 A는 B의 IP 주소만 알고 있다.

2. A는 자신의 서브넷 마스크(예: 255.255.255.0, 하단 설명 참고)를 기준으로 B가 같은 서브넷(동일 네트워크)에 있는지 판단한다.

3. A와 B가 다른 서브넷이라면, A는 우선 기본 게이트웨이(라우터)의 MAC 주소를 ARP(하단 설명 참고)로 요청한다.

4. ARP 응답으로 게이트웨이의 MAC 주소를 받아 프레임(데이터 링크 계층에서 사용되는 데이터 전송 단위)을 작성해 전송한다.

5. 게이트웨이 라우터는 패킷(네트워크 계층에서 사용되는 데이터 전송 단위)을 디캡슐화하고 목적지 IP 주소를 확인한다.

6. 자신의 라우팅 테이블(하단 설명 참고)을 검색해 다음 목적지를 결정하고, 그 다음 라우터의 MAC 주소를 찾아 전송한다.

7. 이 과정은 목적지에 도달할 때까지 각 라우터에서 반복된다.

8. 최종 목적지 라우터는 B와 같은 서브넷에 있는 경우, B의 MAC 주소를 찾아 마지막 전송을 한다.


🔁 이 모든 과정은 패킷마다 반복된다

데이터는 실제로 수백 개의 작은 패킷으로 나뉘어 전송되며, 패킷은 최대 1500bytes, 프레임은 최대 패킷에 헤더(14bytes)와 검증 데이터 FCS(4bytes)가 추가된 1518bytes 크기를 가질 수 있다.

각 패킷은:

– IP 헤더 + TCP/UDP 헤더 → 3계층
– MAC 헤더 → 2계층

으로 캡슐화되며, 전달 중 계층마다 디캡슐화 및 재캡슐화가 발생한다.


🚥 홉(Hop)과 경로

– 각 라우터를 1홉(Hop)이라고 부른다.
– 한국에서 google.com까지는 대략 15~20홉 정도의 라우터를 거쳐 데이터가 전달된다.


🎯 MAC 주소만으로는 목적지를 못 찾는 이유

MAC 주소는 LAN(Local Area Network)에서만 유효하다.

라우터 밖의 MAC 주소는 알 수 없기 때문에 전 세계 통신은 IP 기반으로 경로를 계산하고, MAC 주소는 그때그때 다음 홉의 MAC 주소만 사용한다.


✍️ 예시 흐름 정리

[A] 192.168.1.2
  ↓ (ARP 요청 → 게이트웨이 MAC 획득)
[라우터 1] → [라우터 2] → ... → [최종 라우터]
  ↓ (B의 MAC 획득)
[B] 192.168.2.3

🧩 서브넷 마스크(Subnet Mask)란?

서브넷 마스크IP 주소를 네트워크 영역과 호스트 영역으로 나누기 위한 도구다.

즉, “이 IP 주소에서 어디까지가 네트워크고, 어디부터가 개별 장치(호스트)냐?“를 판단하는 기준이 된다.


🎯 왜 필요할까?

– IP 주소만 봐서는 이 기기가 **같은 네트워크(서브넷)**에 있는지 알 수 없다.
– 서브넷 마스크를 통해 IP 주소 범위를 구분하고, 같은 서브넷이면 직접 통신, 다르면 라우터(게이트웨이)를 통해 통신한다.


📘 예시로 이해하기

– IP 주소: 192.168.1.10
– 서브넷 마스크: 255.255.255.0 → /24

이 경우:

– 192.168.1까지가 네트워크 주소
– .10은 호스트 주소 (즉, 네트워크 내 개별 장치)

즉, 192.168.1.X는 모두 같은 서브넷


🧠 CIDR 표기

표기서브넷 마스크사용 가능한 호스트 수
/8255.0.0.0약 1,600만 개
/16255.255.0.0약 65,000개
/24255.255.255.0약 254개
/30255.255.255.2522개 (라우터 간 링크용)
/32255.255.255.2551개(단일 주소)


🧪 같은 서브넷인지 확인하는 방법

두 IP 주소가 같은 서브넷인지 확인하려면:

1. 두 IP 주소를 이진수로 변환
2. 서브넷 마스크를 이진수로 변환
3. IP & 서브넷 마스크 계산 → 나온 네트워크 주소가 같으면 같은 서브넷

예를 들어:
– A: 192.168.1.10
– B: 192.168.1.20
– 서브넷 마스크: 255.255.255.0
→ A와 B 모두 192.168.1.0 네트워크에 있음 → 같은 서브넷


🔍 ARP (Address Resolution Protocol)란?

ARP는 “이 IP 주소에 해당하는 MAC 주소를 알려줘!“라고 네트워크에 브로드캐스트 요청을 보내는 프로토콜.

– A → 네트워크 전체에 ARP Request
– 해당 IP 가진 기기 → ARP Reply로 MAC 주소 응답
– A는 받은 MAC 주소로 이더넷 프레임 구성하여 전송


🧠 라우팅 테이블이란?

라우터는 목적지 IP를 보고 “어느 방향으로 보내야 할지” 결정하는 라우팅 테이블을 가지고 있다.

예시

목적지 IP 범위넥스트 홉 (Next Hop)인터페이스
192.168.2.0/2410.1.1.2eth1
0.0.0.0/010.1.1.1 (기본 경로)eth0

– 192.168.2.3 → 192.168.2.0/24에 포함됨 → 해당 인터페이스로 전송
– 범위에 없으면 기본 경로로 전송 (보통 인터넷 게이트웨이)



MAC 주소(MAC Address)에 대한 공식적인 정보는 IEEE (Institute of Electrical and Electronics Engineers)에서 관리

패키지 매니저 pnpm, 새로운 의존성 관리 방식(vs npm/yarn)

기존의 호이스팅 방식과 pnpm의 의존성 트리 유지 방식

pnpm은 Performant NPM, 즉 높은 성능을 내는 npm이라는 의미이다.

npm은 공식적으로 ‘줄여쓴 약자가 아니다(npm is not an acronym)’라고 하지만 누구에게나 Node Package Manager라고 하면 쉽게 설명이 된다…

회사 프로젝트에서도 npm yarn yarn berry를 거쳐 현재는 pnpm을 기본으로 사용하고 있으며, 특성상 낮은 노드 버전 유지가 필요한 곳만 npm을 사용하고 있다.

그렇다면 다른 패키지 매니저와 비교해 pnpm의 특징을 먼저 살펴보자.

특징pnpmnpm / yarn
속도빠름(병렬 처리)다소 느림
효율성좋음(글로벌 캐싱, 링크 사용)낮음(중복 저장 가능성)
호환성npm 호환Node.js 기본
의존성 관리엄격함(충돌 방지 장점)느슨함
모노레포 지원워크스페이스 지원yarn 일부 지원
pnpm과 npm/yarn의 차이

pnpm의 의존성 관리 방식은 기존의 호이스팅(hoisting) 방식을 사용하는 패키지 매니저와 차별화된다. 호이스팅 방식과 pnpm 고유의 의존성 트리 유지 방식을 비교해보자.

호이스팅 방식

전통적인 패키지 매니저(npm, yarn)에서 사용되는 방식으로, 의존성을 프로젝트 루트의 node_modules 디렉토리로 끌어올리는 것을 의미한다.
모든 의존성을 루트 디렉토리에 설치하여, 하위 패키지에서 해당 의존성을 마치 루트에 설치된 것처럼 접근이 가능하도록 한다.

호이스팅 방식의 장점

1. 간단한 접근 : 모든 패키지가 같은 디렉토리에 설치되므로, 의존성을 찾는 데 간단한 구조를 갖는다.

2. 중복 제거 : 중복된 의존성을 상위로 끌어올려 디스크 사용량이 줄어든다.

호이스팅 방식의 단점

1. 의존성 충돌 : 서로 다른 패키지가 동일한 이름의 의존성을 서로 다른 버전으로 요구할 때, 하나의 버전만 설치되므로 충돌 발생 가능성 존재한다.

2. 의존성 숨김 문제 : 하위 패키지가 암묵적으로 루트에 있는 의존성에 접근하게 되어, 의존성을 명시하지 않고 사용할 위험이 있다.

따라서 패키지가 다른 프로젝트에서 독립적으로 작동하지 않을 가능성이 높아진다.

pnpm 고유의 의존성 트리 유지 방식

pnpm은 의존성을 독립적으로 관리하며, 각 패키지의 의존성 트리를 유지한다. 또한 “flat” 구조 대신 하드 링크와 심볼릭 링크를 사용하여, 의존성이 설치된 위치를 참조만 한다.

작동 방식

.pnpm 디렉토리

모든 의존성은 루트의 node_modules 디렉토리 내부 .pnpm 디렉토리에 설치된다. 중복된 의존성은 단일 디렉토리에 저장하고, 필요한 위치에서 해당 파일에 심볼릭 링크를 생성한다.

독립적 의존성 트리

각 패키지는 자신만의 node_modules를 가지고, 필요한 의존성을 .pnpm에서 참조한다.

예를 들면 다음과 같은 구조다.

project/
├── node_modules/
│   ├── package-a/
│   │   └── node_modules/
│   │       └── dependency-a@1.0.0 -> .pnpm/dependency-a@1.0.0
│   ├── package-b/
│   │   └── node_modules/
│   │       └── dependency-a@2.0.0 -> .pnpm/dependency-a@2.0.0

따라서 package-a와 package-b는 서로 다른 버전의 dependency-a를 독립적으로 사용할 수 있다.

pnpm 방식의 장점

1. 의존성 충돌 방지 : 각 패키지가 독립적으로 의존성을 관리하므로, 서로 다른 버전의 의존성을 문제없이 사용할 수 있다.

2. 빠른 설치 : 동일한 의존성을 중복 다운로드하지 않고, 심볼릭 링크를 통해 참조하므로 속도가 빠르다.

3. 디스크 공간 절약 : .pnpm 디렉토리에 모든 의존성을 공유 저장하므로 중복 설치를 방지한다.

4. 명시적 의존성 사용 : 패키지는 반드시 자신이 명시적으로 선언한 의존성만 접근이 가능하며, 루트에 설치된 의존성에 암묵적으로 의존하지 않는다.

pnpm 방식의 단점

1. 복잡한 디렉토리 구조 : 심볼릭 링크를 사용하여 디렉토리 구조가 일반적인 방식보다 복잡해 보일 수 있다.

2. 호환성 문제 : 일부 오래된 라이브러리나 스크립트가 node_modules 트리 구조를 가정한 방식으로 동작할 경우 문제가 생길 수 있다.


pnpm의 의존성 관리 방식은 의존성 충돌 방지, 디스크 공간 절약, 명시적 의존성 관리에 강점을 가지고 있다. 특히 대규모 프로젝트에서 각 패키지의 독립적 의존성을 관리에 매우 유용하다.

참고
https://docs.npmjs.com
https://pnpm.io

렌더링 엔진과 특징 분석하기(webkit, blink, gecko)

독립 발전하는 웹 브라우저 렌더링 엔진

웹 브라우저의 대표적인 렌더링 엔진은 Webkit, Blink, Gecko 세 가지가 있다.

각각의 발전사와 점유율, 특징을 살펴보자.

1. 엔진의 점유율

각 엔진의 점유율은 해당 엔진을 사용하는 브라우저의 점유율 추정치로 살펴보면 다음과 같다.

엔진BlinkWebkitGecko
점유율75%20%3%
브라우저Google Chrome(65%)
Microsoft Edge(5%)
Opera(2.5%)
Samsung Internet(2.5%)
Brabe
Vivaldi
Safari(19%)
iOS용 모든 브라우저
Mozilla Firefox
Statcounter Global Stats – Browser Market Share 참고

‘iOS용 모든 브라우저’는 애플 OS에서 사용되는 크롬, 엣지 등은 Webkit, 이외의 윈도우, 안드로이드 등의 OS에서 사용되는 크롬, 엣지는 Blink를 사용한다는 의미가 된다.

따라서 애플 기기의 브라우저는 모두 Webkit을 사용하며, 이는 전체에서 대략 20%가 된다.

이 같은 특성을 봤을 때 맥 OS에서 개발하고 크롬의 호환성 OK 여부를 결정할 것이 아니라 실제 OS를 변경하여 브라우저 테스트의 필요성이 제기된다.

2. 발전사

Webkit

Webkit은 애플에서 개발한 오픈소스 렌더링 엔진으로 KHTML(1998년부터 사용된 HTML 렌더링 엔진)과 KJS(JavaScript 엔진)을 기반으로 2002년부터 개발되었다.

웹 브라우저에서 웹 페이지를 렌더링하기 위해 사용되며, HTML, CSS, JavaScript 등을 해석하여 사용자가 볼 수 있는 형태로 화면에 렌더링한다.

2003년 Safari 브라우저 출시와 함께 Webkit을 공식적으로 발표했으며, 2005년 오픈소스화하여 현재까지 애플 생태계 전반에 걸쳐 기본 렌더링 엔진으로 사용된다.

Webkit의 구성 요소는 다음과 같다.

WebCore – HTML, CSS, SVG, 이미지 등의 렌더링과 관련된 부분을 처리하는 핵심 렌더링 엔진

JavaScriptCore(Nitro 엔진) – JavaScript 코드를 해석하고 실행하는 엔진으로 성능이 개선된 Nitro 엔진이 주로 사용됨. Webkit을 사용하는 브라우저는 기본적으로 별도의 JavaScript 엔진이 필요없음

Web Inspector – 내장 디버깅 도구로 DOM, css, 네트워크 ㅇㅎ청 등의 분석과 디버깅이 가능

플랫폼 특정 코어 – 운영 체제와 엔진을 연결하거나 플랫폼 간의 차이를 추상화, 특정 플랫폼에서의 성능 최적화 등을 담당

Webkit의 특징으로는 웹 표준을 준수하여 최신 웹 표준을 지원하며 지속적인 최적화를 통해 성능과 에너지 효율성이 강화되었다. 특히 모바일 기기에서 배터리 소모 최소화에 중점을 둔다.

초기부터 경량화된 구조와 빠른 렌더링 속도가 장점이며 높은 에너지 효율성과 함께 애플 생태계에 최적화된 성능과 안정성을 보여준다.

그러나 애플 중심 개발과 강한 통제로 인해 애플 생태계 외에서는 기술 채택이 더디며 타플랫폼의 기여가 제한적이고 점유율이 낮다.

Blink

2013년 구글이 Webkit을 fork하여 만든 렌더링 엔진이다. Chrome 브라우저도 초기에는 Webkit을 사용했지만 아키텍쳐와 개발 방식이 맞지 않아 Blink를 개발하게 되었다.

초기 버전은 상당히 많은 부분의 코드를 공유했지만 독자적인 개발 노선을 걷기 시작하고 멀티 프로세스 아키텍쳐에 집중하여 다양한 운영 체제와 디바이스에서 원활히 작동하도록 설계되었다.

Chromium(구글 주도 오픈소스 웹 브라우저 프로젝트)은 Blink 엔진을 사용하므로 Chromium을 기반으로 하는 브라우저는 모두 Blink 렌더링 엔진을 사용한다.

Blink의 주요 구성 요소는 다음과 같다.

DOM core – HTML 파싱과 DOM 트리 생성 및 조작 지원

Layout&Render Engine – 레이아웃 계산 및 렌더 트리 생성

CSS Parser&Style Engine – CSS 파싱 및 스타일 계산

DevTools – 개발자용 디버깅 및 성능 분석 도구

참고로 Blink는 내부에 JavaScript 엔진을 포함하지 않고 외부 엔진인 V8 엔진을 사용한다.

특징으로는 멀티 프로세스 모델과 통합되어 각 탭이 독립적으로 실행되므로 보안이 강화된다. 렌더링 성능 향상을 위해 GPU를 적극 사용하고 멀티 프로세스 구조로 빠른 성능과 광범위한 생태계가 장점이다.

시장 점유율이 집중화되면서 경쟁이 줄고 웹 기술 발전이 특정 기업에 의존 경향을 보이는 것과 메모리, CPU 사용량이 많아 리소스 소모가 크고 해당 생태계에 속한 브라우저의 독립성이 감소하는 단점이 있다.

Gecko

1997년 Netscape에서 개발을 시작하였으며, 2004년 Firefox의 핵심 엔진으로 채택되었다. 2017년 Quantum 프로젝트를 통해 멀티스레드 지원, GPU 활용, 웹 표준 강화 등을 강화했다.

주요 구성 요소로는 HTML parser, CSS parser, Rendering Engine 등이 있으며, Gecko에 통합된 JavaScript 엔진은 SpiderMonkey를 사용하며 개발자 도구인 Developer Tools도 제공한다.

특징으로는 Servo 프로젝트 기술 통합을 통해 Stylo CSS 엔진을 도입하고 멀티스레드 렌더링을 지원하며 GPU 가속 활용이 강화되었다. 강력한 개인정보 보호 및 확장성이 장점이지만 낮은 시장 점유율과 Blink보다 리소스 사용량이 많은 것이 단점이다.


출처
Chromium Documentation
Google Developers Blog
Webkit Official
Mozilla Developer Network(MDN)

맥 nvm 14 버전 설치 오류 해결(nvm install 14)

apple silicon,nvm node 버전 14 설치하기

비교적 오래된 프로젝트에서는 호환성 문제로 인해 노드 버전을 낮춰서 작업하는 상황이 발생한다.

이 때 NVM을 사용하면 편리하게 노드 버전을 변경할 수 있다.

하지만 특정 버전(특히 node 14)은 설치가 되지 않고 에러 메시지가 끝없이 올라가는 상황이 발생한다.

이 때는 아키텍쳐(맥 실리콘, M1, M2, M3 등)이 원인인 상황이 많으므로 로제타2(Rosetta2)를 사용해 아키텍쳐를 x86_64로 전환해야 한다.

먼저 로제타2가 설치되어 있는지 확인하기 위해 다음 커맨드를 입력한다.

$ /usr/bin/pgrep oahd

프로세스 ID가 반환되면 이미 설치되어 있는 상태이다.

설치되어 있지 않다면 먼저 로제타2를 설치한다.

로제타2 설치 방법 (애플 서포트 페이지)

이제 터미널에서 다음 커맨드를 입력해보자.

$ arch

arm64가 출력되면 다음 커맨드를 사용해 x86_64로 전환한다.

arch -x86_64 zsh

다시 arch 커맨드를 입력해보면 변환된 아키텍쳐가 반환되는 것을 확인할 수 있다.

이제 nvm install 14를 문제없이 설치할 수 있다.

페이지 이동 후 쿠키가 사라지는 문제(Next.js, setHeader, writeHead)

설정한 쿠키가 페이지 이동 후 사라질 때 의심해 볼 상황

getServerSideProps에서 writeHead 또는 setHeader로 쿠키를 설정하고 redirect 시

등록된 쿠키가 사라지는 상황이 있다.

redirect된 페이지에서 쿠키가 사라진다면 헤더 설정의 문제를 확인해 봐야 한다.

합리적으로 의심해 볼 수 있는 문제는 페이지 이동 후 쿠키가 사라졌으므로 쿠키의 사용 범위에 대한 설정 문제이다.

Path=/ 설정은 쿠키가 모든 경로에서 유효하도록 설정하는 옵션이다. 이 옵션을 통해 모든 페이지에서 쿠키에 접근할 수 있도록 설정하므로 해당 옵션이 누락되면 페이지 이동 시 쿠키가 사라지는 문제가 발생한다.

setHeader와 writeHead를 사용해 path=/를 포함하는 쿠키 설정 예제를 확인해보자.
HttpOnly는 클라이언트의 자바스크립트에서 쿠키에 접근할 수 없도록 설정하는 옵션이다.

export async function getServerSideProps({ req, res }) {

  res.setHeader('Set-Cookie', 'myCookie=value; Path=/; HttpOnly; Max-Age=3600');

  return {
    redirect:{
      destination: '/new-page', // redirect할 페이지
      permanent: false
    }
  }
}

writeHead의 사용도 확인해보자.

export async function getServerSideProps({ req, res }) {
  const cookieVal = 'myCookie=value; Path=/; HttpOnly; Max-Age=3600';

  res.writeHead(302, {
    Location: 'new-page', // redirect할 페이지
    'Set-Cookie': cookieVal,
    'Custom-Header': 'Custom', // 커스텀 헤더
  });
  
  res.end();

  return {
    props: {}
  };
}

writeHead의 첫 번째 파라미터는 HTTP 응답 상태 코드, 두 번째는 헤더 객체를 설정한다.

헤더 객체 내부의 Location 필드로 redirect 페이지를 설정할 수도 있고, return 문에 redirect를 전달하면서 페이지를 설정할 수도 있다.

Next.js의 기본 권장 방식은 return 문에서 redirect를 전달하는 방법이다.

그렇다면 writeHead와 setHeader의 차이점은 무엇일까?

  • writeHead는 상태 코드를 설정(setHeader는 불가능)할 수 있는 등의 세세한 설정을 할 수 있다.
  • setHeader는 응답이 시작(res.end())되기 전 여러 번 호출이 가능하지만 writeHead는 한번만 호출한다.

따라서 상태 코드와 여러 헤더를 동시에 설정하려면 writeHead, 개별적으로 헤더를 추가하고 수정할 때는 setHeader를 사용하는 것이 좋다.

이와 같이 Path=/를 추가하면 이동하는 페이지에 상관없이 애플리케이션에서 쿠키를 확인할 수 있다.


추가 참고 : Next.js 공식 문서(Setting Headers)

다양한 이미지 파일 종류 알아보기(WEBP, PNG, SVG, JPG, TIFF….)

Webp, png, svg, gif, psd, eps, tiff

이미지 파일 종류는 크게 웹용(WEBP, PNG, SVG, JPG, GIF)과 인쇄용(PSD, EPS, TIFF)으로 나눌 수 있다.

1. 웹용 이미지 데이터

– SVG
벡터(Vector) 그래픽을 기반으로 하는 이미지 데이터. 크기를 조절해도 품질이 저하되지 않으며 텍스트 기반이므로 코드로 이미지를 수정할 수 있다. 로고, 아이콘, 일러스트 등에 적합하며 PNG보다 더 작은 용량을 유지할 수 있다.

– PNG
무손실 압축 중 작은 파일 용량이 장점인 래스터(Raster) 형식의 이미지 데이터. 그림이나 로고 등 간단한 이미지에 적합하며 SVG에 비해 브라우저 호환성, 투명 배경, 필터 효과, 복잡한 색상과 세부 사항 표현 등에 더 유용하다.
무손실 압축이지만 해상도 제한으로 인해 크기에 따라 품질이 저하될 수 있다.

– WEBP
구글이 개발한 이미지 형식으로 손실과 무손실 압축을 모두 지원한다. 손실은 JPG, 무손실은 PNG와 유사한 방식으로 품질을 유지하고 파일의 크기를 줄인다. 알파 채널을 지원하여 투명 배경을 사용할 수 있고 여러 장의 사진을 사용해 애니메이션을 만들 수 있다. 동일 품질 대비 JPG, PNG보다 약 30% 가량 크기가 작으며, 웹 이미지 최적화 등에 사용된다.

– JPG
JPEG라고도 하며, 사진이나 그라데이션 등 여러 색상을 포함하는 이미지에 적절하다. 손실 압축을 사용하므로 용량이 작지만 같은 이미지를 계속 JPG로 덮어쓰게 되면 계속되는 손실 압축으로 인해 화질 저하가 계속 발생하게 된다.

– GIF
색의 수가 256색으로 파일 용량이 작으며, 여러 이미지의 배열을 통해 움직이는 영상을 만들 수 있다. 무손실 압축 방식을 사용하지만 색상 수의 제한으로 인해 일부 사항이 손실될 수 있다.

2. 인쇄용 데이터

– TIFF
이미지를 압축하지 않고 저장하는 형식의 데이터. 인쇄 및 그래픽 작업에서 인기가 많으며 저장을 반복해도 화질 저하가 발생하지 않는다. 무손실 방식이므로 파일 크기가 크고 압축, 최적화가 부족하여 웹용으로는 적절하지 않으며, 대부분의 브라우저에서 제대로 지원되지 않는다.

– PSD
포토샵 저장 형식으로 레이어 정보를 포함해 저장할 수 있다. 레이어 정보를 포함하면 용량이 커지므로 저장 시 레이어 병합을 통해 용량을 줄일 수 있다. 포토샵 기능을 활용해 복잡한 이미지를 만들 수 있으며, 고해상도 이미지를 저장할 수 있다. 브라우저가 지원하지 않으므로 JPG, PNG등으로 변환해야 한다.

– EPS
어도비 PortScript로 만든 형식의 데이터. 저해상도와 고해상도를 가지고 있어 저해상도로 작업하고 고해상도로 출력할 수 있다. 벡터 그래픽 장점을 최대한 활용할 수 있으며, 주로 인쇄에 적합하다.


MDN – SVG
Wikipedia – PNG
Wikipedia – WebP

spec.template: Invalid value 에러


~~~ is invalid. spec.template: Invalid value

yaml을 작성하고 kubectl apply -f sample.yaml과 같이 적용할 때 spec.template에러가 뜨는 상황이 있다.

이 에러가 뜬다면 해당 yaml로 파드를 처음 생성하는 것이 아니며 ,수정 사항이 조건에 위배되기 때문이다.

spec.Completions
spec.Selector
spec.Template
 

이 항목들은 수정이 불가하도록 지정되어 있다. 따라서 spec.template를 수정하는 apply하는 상황에서 발생한 에러이다.

수정이 불가하므로 신규 생성만 가능하다.

간단한 해결 방법으로 해당 yaml을 kubectl delete -f sample.yaml로 제거한 뒤 다시 apply를 적용하면 에러가 해결되는 것을 확인할 수 있다.


참고 : https://github.com/kubernetes/kubernetes/issues/89657

bash에서 vim 설치(feat.한글 설정)

bash: vim: command not found

경량화를 추구하는 컨테이너에는 기본 에디터가 제공되지 않으므로 필요 시 직접 설치해야 한다.

간단하게 bash에서 vim 에디터를 설치하는 방법과 한글 설정(UTF-8, CP949)까지 알아보자.

1. vim 에디터 설치

$ apt-get update

Hit:1 http://deb.debian.org/debian bookworm InRelease
Get:2 http://deb.debian.org/debian bookworm-updates InRelease [55.4 kB]
Hit:3 http://deb.debian.org/debian-security bookworm-security InRelease
$ apt install vim

Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following additional packages will be installed:
  libsodium23 vim-common vim-runtime xxd
Suggested packages:
  ctags vim-doc vim-scripts
The following NEW packages will be installed:
  libsodium23 vim vim-common vim-runtime xxd
0 upgraded, 5 newly installed, 0 to remove and 40 not upgraded.
Need to get 8962 kB of archives.
After this operation, 41.8 MB of additional disk space will be used.
Do you want to continue? [Y/n] 

bash에서 두 커맨드를 실행하고 y를 눌러주면 끝이다(권한 문제가 발생하면 sudo를 앞에 붙인다).

그런데 한글이나 일본어 등을 사용하려면 인코딩이 필요하다.

UTF-8을 설정해보자.

vim 인코딩 설정(UTF-8)

설치한 vim을 사용해 /etc/vim/vimrc을 열고 하단에 다음 내용을 추가한다.

" Source a global configuration file if available
if filereaedable("/etc/vim/vimrc.local")
  source /etc/vim/vimrc.local
endif

//추가하는 부분
set encoding=utf-8
set fileencodings=utf-8,cp949

utf-8은 mac, cp949는 windows에서 사용하는 인코딩 방식이다.

저장하면 vim에서 한글 등이 사람 언어로 표시된다.

알기 쉬운 BEM 알아보기(CSS)

block__element_modifier모듈 기반의 방법론 (+mix)

공식 문서(https://en.bem.info)에서는 BEM을 이렇게 설명한다.

BEM(Block, Element, Modifier)는 컴포넌트 기반 접근 방식이다. 기본 아이디어는 사용자 인터페이스(UI)를 독립된 블록으로 나누는 것이다. 이를 통해 복잡한 UI도 쉽고 빠르게 개발할 수 있으며, 기존 코드를 재사용할 수 있는 장점이 있다.

BEM은 모듈을 Block, Element, Modifier 단위로 분해하며, 각 앞 글자를 따서 BEM으로 부른다. BEM은 러시아 Yandex사에서 개발한 방법론으로 실제로 이 방법에 기반한 CSS 설계 기법이 널리 사용되고 있지만 BEM은 CSS에만 국한되지는 않는다.

그렇다면 BEM의 공통 규칙과 모듈의 개별 규칙을 알아보자.

CSS style을 위한 BEM 공통 규칙

– ID 셀렉터와 태그 셀렉터를 사용하지 않는다.
– 네스팅된 셀렉터 사용을 최소화한다.
– CSS 클래스 네이밍 컨벤션을 사용하여 이름 충돌을 피하고 셀렉터의 목적을 명확하게 한다.
– Blocks, Elements, Modifiers를 구분하여 사용한다.
– Blocks를 재사용한다.

BEM의 네이밍 규칙

모두 소문자를 사용하며, 두 단어는 하이픈(-)으로 연결한다.

Blockblock, block-two
Elementblock 이름을 상속받아 언더스코어 두 개(__)로 연결block__element, block-two__element-two
ModifierBlock/Element 이름 상속받아 언더스코어 하나(_)로 연결. 키-값 쌍은 스네이크 케이스(_)를 사용.
block_modifier, block__element_modifier, element_key_value
Modifier
(MindBEMding)
Block/Element 이름 상속받아 하이픈 두개(–)로 연결. 키-값에서 키는 생략가능.block–modifier, element–value

모듈의 개별 규칙

논리적, 기능적으로 독립되어 재사용이 가능한 모듈로 정의한다. 클래스 이름은 ‘형태’가 아니라 ‘목적, 용도’를 나타내야 한다.

EX) head, logo, menu (O)
blue-button, small-title (X)

block은 다른 block 내부에서도 사용할 수 있으며, modifier를 통해 위치나 모양을 변경할 수 있다.

그림 – block의 중첩(출처: en.bem.info)

Element

block을 구성하며 block 내부에서만 사용하는 모듈로 정의한다. 예를 들어 menu__item은 menu라는 block을 구성하며 menu 밖에서는 사용할 수 없으므로 element가 된다.

그림 – block을 구성하는 element(출처:en.bem.info)


element 클래스 이름도 block과 동일하게 ‘형태’가 아니라 ‘용도’를 나타내야 한다.
element는 선택적 요소이므로 사용하지 않아도 상관없지만 element 이름을 중첩하여 사용하지 않는다.

EX) block__element__element, menu__button__icon (X)

Modifier

block/element의 모양이나 동작을 정의하는 모듈이다.
modifier는 선택적 요소이므로 사용하지 않아도 상관없지만 단독으로는 사용할 수 없고 block/element와 함께 사용해야 한다.
같은 block이라도 modifier에 따라 모양이 변할 수 있으며, modifier는 런타임이나 block에 따라 바뀔 수 있다.
modifier 클래스 이름은 형태(크기, 색, 상태, 동작)을 나타내야 한다. 형태로 나누면 boolean, key-value 두 가지가 있으며, 각각의 예는 다음과 같다.

– boolean : ex) active, disabled
– key-value : ex) color_red, line_doubled (스네이크 케이스로 표현)

modifier의 수는 제한이 없으므로 여러 개를 붙일 수 있지만 동일한 스타일은 중복하지 않는다.

MIX

mix는 하나의 요소에 역할이 다른 여러 클래스를 사용하는 기법이다.
장점은 코드를 복사하지 않고 기존의 스타일과 조합해서 새로운 모듈로 사용할 수 있다.
block+element, block+block, element+element 등의 mix를 사용할 수 있으며, 샘플 코드를 통해 확인할 수 있다.

<!-- HTML -->
<div class="header">
  <div class="logo header__logo"></div>
</div>

/* CSS */
.logo {
  width:100px;
  height:50px;
}
.header__logo {
  margin: 12px;
}

다른 요소와 관계된 레이아웃과 관련된 부분은 mix, block 내부의 문제는 modifier를 사용하는 것이 좋다.
mix는 독립성과 재사용성이 높은 상태를 유지하는 장점이 있다.


참고
https://en.bem.info
– 다양한 예제로 배우는 CSS 설계 실전 가이드