
# 1) Pod를 ClusterIP로 노출
kubectl expose pod nginx1 --port=80 --target-port=80 --type=ClusterIP
# → "service/nginx exposed" 메시지 출력됨
# (클러스터 내부 통신용)
# 2) 외부(Ubuntu 등)에서 접근하려면 NodePort 타입 사용
kubectl expose pod nginx2 --port=80 --target-port=80 --type=NodePort
# 3) Deployment 단위로도 노출 가능
kubectl expose deployment nginx-deployment --port=80 --target-port=80 --type=NodePort
INTERNAL-IP
kubectl get nodes -o wide 명령으로 확인 가능.Service의 CLUSTER-IP
kubectl get svc -o wide 명령으로 확인 가능.Pod의 IP
kubectl get pods -o wide 명령으로 확인 가능.정리:
- 내부 통신: ClusterIP
- 외부 접근: NodePort / LoadBalancer / Ingress

kubectl get po -o wide

kubectl get node -o wide

kubectl get svc -o wide

외부에서 연결된 worker-1의 ip(NodePort):port 번호로 접속이 가능하고,


내부에서 vagrant ssh worker-1으로 접속 후,
lynx http://클러스터ip로 접속이 가능하다.
지금처럼 kubeadm+Vagrant 같은 베어메탈/VM 환경에서는 type: LoadBalancer가 외부 IP를 못 받아서 <pending>이 뜹니다.
이걸 진짜 숫자 IP로 바꾸는 표준 방법이 바로 MetalLB를 설치하는 거예요.
아래 순서 그대로 하면 EXTERNAL-IP 칸에 예: 192.168.57.200 이런 식으로 실제 IP가 뜨게 됩니다.
먼저 컨트롤러/스피커를 설치합니다.
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.13.10/config/manifests/metallb-native.yaml
metallb-system 네임스페이스가 생기고확인:
kubectl get pods -n metallb-system
Running 이면 다음으로 갑니다.
예를 들어 노드들이 192.168.57.x 대역을 쓰고 있고
192.168.57.200 ~ 192.168.57.210 은 비어 있다면 그 구간을 LoadBalancer용 IP로 쓰게 하면 됩니다.
아래 파일을 하나 만들어요: metallb-ip-pool.yaml
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: default-address-pool
namespace: metallb-system
spec:
addresses:
- 192.168.57.200-192.168.57.210
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
name: l2advertisement
namespace: metallb-system
spec:
ipAddressPools:
- default-address-pool
적용:
kubectl apply -f metallb-ip-pool.yaml
이제 MetalLB가 “LoadBalancer 달라”는 서비스에 이 범위 안에서 IP를 하나 뽑아줄 준비가 된 거예요.
이미 ingress-nginx-controller 서비스가 type: LoadBalancer로 되어 있으니
MetalLB가 잡아갈 수 있습니다. 그냥 다시 한 번 보면 돼요:
kubectl get svc -n ingress-nginx
조금 지나면
ingress-nginx-controller LoadBalancer 10.x.x.x 192.168.57.200 80:... 443:...
↑ 여기!
처럼 EXTERNAL-IP 자리에 아까 풀에 적어둔 IP 중 하나가 박힙니다.
만약 바로 안 뜨면 서비스만 살짝 건드려주세요:
kubectl -n ingress-nginx patch svc ingress-nginx-controller \
-p '{"spec": {"type": "LoadBalancer"}}'
(이미 LoadBalancer여도 한 번 패치하면 MetalLB가 다시 계산합니다.)
이제 브라우저에서
http://192.168.57.200
이렇게 접속하면 돼요. (위에서 정한 IP에 맞춰서)
<pending> 없애고 싶다 → MetalLB 설치 + IP 풀 지정


이제 Pod와 Service를 연결해보자. 먼저 YAML 파일에서 파드들을 묶어주는 Deployment를 생성하고, 컨테이너의 호스트_명을 반환하는 웹 서버 이미지를 생성한다.
외부에서 파드에 접근하려면 Service를 설정해야 하는데 다음 세 가지 방법 중에 하나를 사용하면 된다.
| 서비스 타입 | 설명 |
|---|---|
| ClusterIP | 쿠버네티스 내부에서 Pod에 접근할 때 사용, 외부로 Pod를 노출하지 않아 외부에서 Pod에 접근 불가 |
| NodePort | Pod에 접근할 수 있는 포트를 모든 노드에게 동일하게 개방, 외부에서 해당 노드와 포트로 Pod에 접근 가능 |
| LoadBalancer | 로드밸런서를 동적으로 프로비저닝해서 Pod에 연결, 하지만 AWS, GCP 등에서만 사용 가능 |
이 ExternalName Service는 쿠버네티스 내의 Pod들을 외부 시스템과 연계할 때 포트나 IP 주소 대신 이름을 사용하도록 요건한다.
이 Service를 생성하면 외부 도메인을 가리키게 할 수 있는데, 예를 들어 쿠버네티스 내부의 Pod들이 external-svc 이름으로 요청을 보내면 쿠버네티스의 DNS가 외부 kahn.edu 도메인에 접근시킬 수 있다.
다만, 실습은 정식 도메인이 있어야 하기 때문에 생략한다.
각 네임스페이스는 논리적으로 리소스를 구분하지만, 물리적으로 완전히 분리된 것은 아니다.
즉, 하나의 노드 안에 여러 개의 네임스페이스가 존재할 수 있다.
이를 하나의 네트워크 안의 VLAN/Subnet 개념으로 이해할 수 있다.
네임스페이스의 주요 역할은 리소스를 그룹화하고 관리 단위를 구분하는 것이다.
kubectl 명령어에서 -l 옵션으로 라벨(label) 을 이용해 리소스를 그룹화할 수 있다.
예시:
curl hostname-svc-clusterip-ns.production(NS).svc(객체):8080 --silent | grep Hello
→ Service.production(NS).object 형식으로 NS를 지정하여 해당 Pod에 접근할 수 있다.
쿠버네티스에는 특정 네임스페이스에 종속된 객체와
전체 클러스터에 영향을 미치는 비종속 객체(Non-Namespaced) 가 존재한다.
kubectl api-resources --namespace productionproduction 네임스페이스에 속한 객체들이 출력된다.pods, services, replicasets, deployments클러스터 전체에 영향을 주는 객체로, 네임스페이스에 속하지 않는다.
대표 예:
nodes, persistentVolume, namespaces, apiServices, tokenreviews 등
확인 명령어:
kubectl api-resources --namespaced=false
Pods, Services, Deployments 등)Nodes, PersistentVolume 등)kubectl 명령 실행 시 --namespace production을 지정하면 해당 네임스페이스 내에서만 작동.--namespace 옵션을 지정해도 의미가 없다.Deployment YAML 파일 내에서 LOG_LEVEL 값을 직접 수정하지 않고 ConfigMap을 사용하면,
환경 변수를 객체로 분리하여 효율적으로 관리할 수 있다.
ConfigMap을 이용하면 여러 설정값을 한 번에 변경하거나,
Deployment와 분리하여 독립적으로 관리할 수 있는 장점이 있다.
spec:
containers:
- name: my-webserver
env:
valueFrom:
configMapKeyRef:
name: log-level-configmap ## LOG_LEVEL을 ConfigMap에서 설정
## 이후 ConfigMap에서 LOG_LEVEL 값을 WARN 등으로 변경 시
## 두 YAML 파일(env 참조 포함) 모두 자동 반영됨
key: LOG_LEVEL
image: alicek106/rr-test:echo-hostname
kubectl create configmap log-level-configmap --from-literal=LOG_LEVEL=INFO
또는 여러 설정을 한 번에 지정할 경우:
kubectl create configmap log-config --from-literal=LOG_LEVEL=INFO --from-literal=MODE=PROD
즉, ConfigMap을 사용하면 환경 변수 값을 하드코딩하지 않고 외부에서 쉽게 수정할 수 있으며,
애플리케이션 재배포 없이도 설정값이 자동으로 반영되도록 관리할 수 있다.