증상
GeoServer가 설치된 Tomcat과 로컬 연동 시 CORS 오류 발생.
해결
GeoServer가 설치된 Tomcat의 web.xml에 아래 내용 추가:
nginx 리버스 프록시 설정
nginx를 앞에 세우고 들어오는 주소에따라 원하는 서버로 연결해주는 역할

기본설정
REST API URI 설계 원칙 (RFC-3986)
URI 설계 규칙
| 규칙 | 올바른 예 | 잘못된 예 |
|---|---|---|
슬래시(/)는 계층 관계 표현 | /vehicles/suv/q6 | — |
URI 마지막에 / 미포함 | /vehicles/suv/q6 | /vehicles/suv/q6/ |
하이픈(-)으로 가독성 향상 | /vehicles/suv/qseries/6 | — |
밑줄(_) 사용 금지 | /vehicles/suv/q6 | /vehicles/suv/q_series/6 |
| 소문자 사용 | /vehicles/suv/q6 | /Vehicles/SUV/Q6 |
| 파일 확장자 미포함 | /vehicles/suv/q6 | /vehicles/suv/q6.jsp |
| 언어 의존적 확장자 미사용 | /vehicles/suv/q6 | /vehicles/suv/q6.do |
| 구현 의존적 경로 미사용 | /vehicles/suv/q6 | /servlet/vehicles/suv/q6 |
| 세션 ID 미포함 | /vehicles/suv/q6 | /vehicles/suv/q6?session-id=abcdef |
| Method명 미사용 | /vehicles/suv/q6 | /vehicles/suv/q6?action=intro |
| 명사는 복수형 사용 | /vehicles/suv/q6 | /vehicle/suv/q6 |
| 컨트롤러는 동사/동사구 | /vehicles/suv/q6/re-order | — |
| CRUD는 HTTP 메서드로 표현 | DELETE /vehicles/q7/{car-id} | GET /vehicles/q7/delete/{car-id} |
변하는 경로 부분
CNI - Calico 네트워크 설정
- CNI
- 컨테이너 네트워크 표준
- 네트워크 계층 구현 방식의 공통된 인터페이스를 제공하여 컨테이너 런타임과 오케스트레이터간의 구현방식의 난립을 방지. k8s는 Pod간 통신을 위해서 사용
- kubernetes
- k8s는 ‘kubenet’ 자체적 CNI Plugin을 제공하지만 매우 제한적. 3rd-party Plugin을 많이 사용함
- CNI 필요성
- 각 노드에 존재하는 container network의 IP대역이 동일 → Pod들이 같은 IP 할당 받을 가망성이 높음
- 노드 별 노드 안에 있는 Pod IP만 식별 가능하기에 Pod의 IP가 다르게 할당되었다 하더라고 해당 POD가 어느 노드에 존재하는지 확인불가
- 중복되지 않는 IP를 부여해줄 역할 → CNI Plugin
- CNI는 worker node에 중복되지 않는 subnet부여 및 Worker node에서 실행되는 Pod는 해당 subnet에 포함된 IP를 제공 받음
- CNI는 Pod 생성 \~ 삭제 시마다 호출되는 API 규격과 인터페이스를 정의함
- CNI 구성 이점
- CNI가 브릿지 인터페이스를 만들고, 컨테이너 네트워크 대역대를 나누어 테이블 생성
- Pod들은 CNI에 의해 제공되는 고유 IP를 갖는다
- 클러스터내의 모든 Pod간 네트워크가 자동 구성되어 Service가 없어도 Pod간 통신 가능
- CNI Provider는 캡슐화 네트워크(VXLAN(Virtual Extensible Lan), IP-in-IP)와 비 캡슐화 네트워크(BGP(Border Gateway Protocol) 모델을 사용하여 네트워크 망 구현
- Calico 설치(3rd-party Plugin)
- https://docs.tigera.io/archive calico 버전 확인
HAProxy 로드밸런서 설정
######################################
# 1️⃣ HAProxy + Keepalived 설치
######################################
sudo apt update
sudo apt install -y haproxy keepalived
######################################
# 2️⃣ HAProxy 설정 (공통)
######################################
cat <<EOF | sudo tee /etc/haproxy/haproxy.cfg
global
log /dev/log local0
maxconn 2000
user haproxy
group haproxy
defaults
log global
mode tcp
option tcplog
timeout connect 10s
timeout client 1m
timeout server 1m
frontend k8s_apiserver
bind *:6443
default_backend k8s_masters
backend k8s_masters
balance roundrobin
option tcp-check
server master1 10.10.10.21:6443 check
server master2 10.10.10.22:6443 check
server master3 10.10.10.23:6443 check
EOF
sudo systemctl restart haproxy
sudo systemctl enable haproxy
######################################
# 3️⃣ Keepalived 설정 - master1 전용
######################################
ip link show
# ❗ NIC_NAME 변수는 실제 인터페이스 이름으로 교체 필요 (예: eth0, ens33)
NIC_NAME="eth0"
cat <<EOF | sudo tee /etc/keepalived/keepalived.conf
vrrp_instance VI_1 {
state MASTER
interface ${NIC_NAME}
virtual_router_id 51
priority 120
advert_int 1
authentication {
auth_type PASS
auth_pass 1234
}
virtual_ipaddress {
10.10.10.100
}
}
EOF
sudo systemctl restart keepalived
sudo systemctl enable keepalived
######################################
# 4️⃣ Keepalived 설정 - master2 전용
######################################
# ❗ NIC_NAME 변수는 실제 인터페이스 이름으로 교체 필요 (예: eth0, ens33)
NIC_NAME="enp2s0"
cat <<EOF | sudo tee /etc/keepalived/keepalived.conf
vrrp_instance VI_1 {
state BACKUP
interface ${NIC_NAME}
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1234
}
virtual_ipaddress {
10.10.10.100
}
}
EOF
sudo systemctl restart keepalived
sudo systemctl enable keepalived
######################################
# ✅ VIP / 포트 / 헬스체크 확인
######################################
# VIP 확인
ip addr | grep 10.10.10.100
# 6443 포트 리슨 중인지 확인
sudo ss -ntlp | grep 6443
# API 서버 응답 확인 (API가 열려 있다면)
curl -k <https://10.10.10.100:6443/livez>
######################################
# 🚀 Kubernetes 마스터 초기화 명령어
######################################
sudo kubeadm init \\\\
--control-plane-endpoint="10.10.10.100:6443" \\\\
--upload-certs \\\\
--pod-network-cidr=10.244.0.0/16Intel i9-12900 서버 KVM + Kubernetes 마스터 노드 VM 생성 가이드
목적: KVM 가상화 기반에서 Ubuntu Server를 활용한 Kubernetes 마스터 노드를 퍼포먼스 코어 1개(P-core, 2스레드) + 효율 코어 1개(E-core, 1스레드) 기반으로 생성하고 운영
1. CPU 가상화 지원 확인
K9S - Kubernetes CLI 관리 도구
Kubernetes 클러스터를 터미널에서 사용하기 위한 오픈소스 CLI 도구
- 명령어를 입력하지 않아도 직관적으로 작업 수행가능
- UI를 통한 리소스의 생성, 업데이트, 로깅, 제거 가능
- https://github.com/derailed/k9s/releases
Kubernetes ConfigMap
- 개발 , 테스트, 운영환경에 사용되는 각기 다른 환경 값의 분리 필요한 상황으로 애플리케이션 Image는 동일하게 사용하고 필요한 환경 구성값을 configMap으로 만들어 사용
- 개발 환경은 SSH를 통한 보안 접근 해제
- 테스트환경은 지정된 USER 및 Key를 이용한 SSH 보안 접근 사용
- 운영환경은 테스트 환경과 다르게 지정된 USER 및 Key를 이용한 보안 접근 허용
- 기밀이 요구되는 데이터는 secret으로 생성해 Pod에 적용해서 사용
- 애플리케이션 레벨이 아닌 Object레벨의 환경 설정 관리 할때 사용
- 애플리케이션 레벨에서 환경 구성 변경시 소스코드와의 의존성이 높고, 설정 값 변경 시마다 코드 수정이 불가피하여 개발속도가 지연 될 수 있다.
- 민첩성을 강조하는 Cloud Native 환경에서 애플리케이션 개발은 애플리케이션 코드와 분리된 configMap, Secret object 사용을 통해 신속하게 적용 가능
- configMap, Secret은 중앙 관리 방식으로 애플리케이션 코드에서 구성 및 민감한 정보를 분리하도록 설계된 Kubernetes API object → kubectl api-resources Dockerfile
Kubernetes DaemonSet
- Deployment와 유사하지만 노드단위 배포로 이루어지기에 Replicas 옵션은 없다
- 노드의 백그라운드에서 항상 Pod를 데몬으로 실행할 수 있게 해주는 workload resource
- 모니터링 시스템, 로그 수집 에이전트, 노드 데이터 백업과 같은 장기간 지속되는 작업
- 업데이트 전략 기본은 RollingeUpdate (or OnDelete)
- “OnDelete” → 이전 데몬이 종료된 경우에만 교최
- Taint와 toleration 옵션을 사용하여 특정 노드에 배포 선택 가능
- 대규모 클러스터인경우 nodeSelector를 사용하여 특정 노드 선택가능
- 로그 수집할 노드에 라벨링 → kubectl label node 노드명 log-collect-node=true