쿠버네티스 클러스터: 아파트 단지
아파트 단지 안에는 여러 방(파드) 존재
방은 얼마든지 생성되고 사라질 수 있고 이사(스케줄링)도 함
→ 클라이언트 입장에서는 방의 IP 주소가 계속 바뀜
그래서 등장하게 된 것이 서비스
서비스는 고정된 IP를 받음
택배함으로 요청을 보내면 쿠버네티스가 살아있는 파드 중 하나에게 연결
**$ kubectl get service**
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.233.0.1 <none> 443/TCP 2d16h
**$ kubectl get endpoints**
NAME ENDPOINTS AGE
kubernetes 192.168.56.11:6443 2d16h
서비스가 있다면 그에 상응하는 엔드포인트도 존재(Name 동일)
엔드포인트의 IP 주소: api 서버로 접근할 수 있는 주소
실습 전 디렉터리 정리
vagrant@kube-control1:~/k8s$ mkdir ex04
vagrant@kube-control1:~/k8s$ cd ex04
서비스 생성
$ vim myapp-svc.yml
apiVersion: v1
kind: Service
metadata:
name: myapp-svc
spec:
ports:
- port: 80
targetPort: 8080
selector:
app: myapp-rs
**$ kubectl apply -f myapp-svc.yml**
service/myapp-svc created
생성한 서비스 확인
**$ kubectl get service myapp-svc**
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
myapp-svc ClusterIP 10.233.27.50 <none> 80/TCP 45s
서비스와 함께 생성됐을 엔드포인트도 확인
**$ kubectl get endpoints myapp-svc**
NAME ENDPOINTS AGE
myapp-svc <none> 2m24s
이름 동일
서비스에 연결할 파드 생성(엔드포인트 연결)
# 기존에 썼던 파일 현재 작업 디렉터리로 가져옴
$ cp ../ex03/myapp-rc.yml .
$ vim myapp-rc.yml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
**name: myapp-rs**
spec:
# 복제본 개수 지정
replicas: 5
selector:
matchLabels:
**app: myapp-rs**
template:
metadata:
# 다수의 파드들의 레이블
labels:
**app: myapp-rs**
spec:
containers:
- name: myapp
image: ghcr.io/c1t1d0s7/go-myweb:alpine
ports:
- containerPort: 8080
서비스 셀렉터에 적었던 레이블(app: myapp-rs)와 동일하게 수정
# 파일 이름 수정
**$ mv myapp-rc.yml myapp-rs.yml**
# 구동
**$ kubectl apply -f myapp-rs.yml**
replicaset.apps/myapp-rs created
# 엔드포인트 다시 확인
**$ kubectl get endpoints myapp-svc**
NAME ENDPOINTS AGE
myapp-svc 10.233.118.91:8080,10.233.118.92:8080,10.233.73.94:8080 + 2 more... 8m40s
엔드포인트 생긴거 확인 가능
→ 레플리카셋으로 생성한 파드들의 IP
파드들의 IP 주소 확인
**$ kubectl get pods -o wide**
NAME ... IP NODE NOMINATED NODE READINESS GATES
myapp-rs-4b55g ... 10.233.74.28 kube-node2 <none> <none>
myapp-rs-gjph2 ... 10.233.118.92 kube-node3 <none> <none>
myapp-rs-rpz4j ... 10.233.73.94 kube-node1 <none> <none>
myapp-rs-s7vwj ... 10.233.74.29 kube-node2 <none> <none>
myapp-rs-wb84r ... 10.233.118.91 kube-node3 <none> <none>
네트워크 통신 확인
**$ kubectl run nettool -it --image=ghcr.io/c1t1d0s7/network-multitool --rm bash
nettool:/#**
쉘 접속 종료시 컨테이너도 종료되도록 --rm 옵션
Cluset-IP 로 요청 보내서 파드 id 확인
nettool:/# curl http://10.233.27.50
Hello World!
myapp-rs-s7vwj
nettool:/# curl http://10.233.27.50
Hello World!
myapp-rs-4b55g
nettool:/# curl http://10.233.27.50
Hello World!
myapp-rs-gjph2
nettool:/# curl http://10.233.27.50
Hello World!
myapp-rs-wb84r
nettool:/# curl http://10.233.27.50
Hello World!
myapp-rs-rpz4j
고정된 Cluster-IP 로 보내면 파드들에게 각각 자동으로 로드밸런싱되는 걸 확인 가능
멀티포트 서비스 설정
$ cp myapp-svc.yml myapp-svc-multiport.yml
$ vim myapp-svc-multiport.yml
apiVersion: v1
kind: Service
metadata:
name: myapp-svc
spec:
**ports:
- name: http
port: 80
targetPort: 8080
- name: https
port: 443
targetPort: 8443**
selector:
app: myapp-rs
다중 포트 지정 시 이름을 명시해야 함
멀티포트 서비스 구동
**$ kubectl apply -f myapp-svc-multiport.yml**
service/myapp-svc created
생성된 서비스 및 엔드포인트 확인
**$ kubectl get service myapp-svc**
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
myapp-svc ClusterIP 10.233.50.186 <none> 80/TCP,443/TCP 49s
**$ kubectl get endpoints myapp-svc**
NAME ENDPOINTS AGE
myapp-svc 10.233.118.91:8443,10.233.118.92:8443,10.233.73.94:8443 + 7 more... 98s
레플리카셋 및 파드 확인
**$ kubectl get rs**
NAME DESIRED CURRENT READY AGE
myapp-rs 5 5 5 28m
**$ kubectl get pods**
NAME READY STATUS RESTARTS AGE
myapp-rs-4b55g 1/1 Running 0 28m
myapp-rs-gjph2 1/1 Running 0 28m
myapp-rs-rpz4j 1/1 Running 0 28m
myapp-rs-s7vwj 1/1 Running 0 28m
myapp-rs-wb84r 1/1 Running 0 28m
쿠버네티스 클러스터는 파드를 생성할 때 파드 내부의 환경변수에 서비스의 내용을 명시함
nettool이 어떻게 clusterIp를 찾아갈 수 있었을까?
쿠버네티스 파드에서는 다른 서비스를 찾는 방법은 2가지
1. 환경 변수
2. DNS
환경 변수 확인
$ kubectl run nettool -it --image=ghcr.io/c1t1d0s7/network-multitool --rm bash
nettool:/# env
KUBERNETES_SERVICE_HOST=10.233.0.1
DNS로 확인하기
**$ kubectl get all -n kube-system -l k8s-app=kube-dns**
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/coredns ClusterIP 10.233.0.3 <none> 53/UDP,53/TCP,9153/TCP 2d17h
DNS 정보 파일
: /etc/resolve.conf
파드에서 DNS 정보 확인
**$ kubectl run nettool -it --image=ghcr.io/c1t1d0s7/network-multitool --rm bash
nettool:/# cat /etc/resolv.conf**
search default.svc.cluster.local svc.cluster.local cluster.local
nameserver 169.254.25.10
options ndots:5
| 구성 요소 | 타입 | 위치 | 역할 |
|---|---|---|---|
| CoreDNS | Deployment | kube-system 네임스페이스 (예: kube-control1, kube-node3 등 일부 노드에만) | 클러스터 전체의 중앙 DNS 서버 |
| NodeLocal DNS Cache (nodelocaldns) | DaemonSet | 모든 노드에 1개씩 (4/4 표시된 이유) | 각 노드에서 로컬 DNS 캐시 역할 |
| Pod의 /etc/resolv.conf | 설정 파일 | 모든 Pod 내부 | DNS 질의가 갈 “nameserver” 를 169.254.25.10(노드 로컬 주소)로 지정 |
curl http://myapp-svc.default.svc.cluster.local┌──────────────────────────────┐
│ ① Pod 내부 (/etc/resolv.conf)│
│ nameserver 169.254.25.10 │
└──────────────┬───────────────┘
│
▼
┌──────────────────────────────┐
│ ② NodeLocal DNS Cache │
│ (DaemonSet, 127.0.0.1:53 ↔ 169.254.25.10)│
│ - 각 노드에 1개씩 존재 │
│ - 최근 질의 캐싱 │
│ - CoreDNS로 요청 전달 (miss 시) │
└──────────────┬───────────────┘
│
▼
┌──────────────────────────────┐
│ ③ CoreDNS (kube-system) │
│ - 중앙 DNS 서버 (Service: 10.96.0.10) │
│ - Service/Pod 이름 → IP 변환 │
│ - 외부 도메인은 upstream forward │
└──────────────┬───────────────┘
│
▼
┌──────────────────────────────┐
│ ④ 외부 DNS (예: 8.8.8.8) │
│ - CoreDNS가 포워딩 │
└──────────────────────────────┘
즉, CoreDNS도 다른 앱처럼 Pod로 실행됨 → 다만 사용자가 만든 앱이 아니라 쿠버네티스 시스템에서 만들고 관리하는 앱일 뿐CoreDNS는 쿠버네티스가 기본으로 설치하는 시스템 구성요소 중 하나이며,
“Deployment 형태로 동작하는 일반 Pod 세트”
로컬 DNS 캐시 확인
**$ kubectl get daemonsets.apps -n kube-system -l k8s-app=kube-dns -o wide**
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE CONTAINERS IMAGES SELECTOR
nodelocaldns 4 4 4 4 4 kubernetes.io/os=linux 2d17h node-cache registry.k8s.io/dns/k8s-dns-node-cache:1.22.28 k8s-app=node-local-dns
**$ kubectl get pods -n kube-system -l k8s-app=kube-dns -o wide**
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
coredns-d665d669-4d59s 1/1 Running 0 2d17h 10.233.118.66 kube-node3 <none> <none>
coredns-d665d669-9w6ls 1/1 Running 0 2d17h 10.233.70.1 kube-control1 <none> <none>
coreDNS는 특정 노드에서만 구동
**$ kubectl get pods -n kube-system -l k8s-app=kube-dns -o wide**
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
coredns-d665d669-4d59s 1/1 Running 0 2d17h 10.233.118.66 kube-node3 <none> <none>
coredns-d665d669-9w6ls 1/1 Running 0 2d17h 10.233.70.1 kube-control1 <none> <none>
특정 clusterIP를 사용하는 서비스로 접근할 수 있는 방식
서비스의 ip주소로 접근
# curl 10.233.63.185
Hello World!
myapp-rc-multiport-5ptlg
<서비스 이름>.<네임스페이스>.<리소스 종류>.<클러스터 도메인>
**nettool:/# curl myapp-svc-multiport**
Hello World!
myapp-rc-multiport-8pbkv
**nettool:/# curl myapp-svc-multiport.default**
Hello World!
myapp-rc-multiport-vttct
**nettool:/# curl myapp-svc-multiport.default.svc**
Hello World!
myapp-rc-multiport-747kw
**nettool:/# curl myapp-svc-multiport.default.svc.cluster.local**
Hello World!
myapp-rc-multiport-p2w7f
$ kubectl run nettool -it --image=ghcr.io/c1t1d0s7/network-multitool --rm bash 무한로딩, 접속 안됨 원인 파악**vagrant@kube-control1:~$ kubectl get pods -o wide**
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
myapp-rs-2gphq 1/1 Running 0 31m 10.233.74.31 kube-node2 <none> <none>
myapp-rs-96pd8 1/1 Running 0 31m 10.233.73.101 kube-node1 <none> <none>
myapp-rs-kvn8r 1/1 Running 0 31m 10.233.118.93 kube-node3 <none> <none>
myapp-rs-plfv4 1/1 Running 0 31m 10.233.74.30 kube-node2 <none> <none>
myapp-rs-wz6ss 1/1 Running 0 31m 10.233.118.94 kube-node3 <none> <none>
nettool 0/1 ContainerCreating 0 41s <none> kube-node1 <none> <none>
**vagrant@kube-control1:~$ kubectl describe pod nettool**
...
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 58s default-scheduler Successfully assigned default/nettool to kube-node1
Warning FailedCreatePodSandBox 57s kubelet Failed to create pod sandbox: rpc error: code = Unknown desc = failed to setup network for sandbox "f70b7825d0a16c329c9b57aa86acc9025629ba505c2bb5efbfeb83ca6c6c9501": plugin type="calico" failed (add): error getting ClusterInformation: connection is unauthorized: Unauthorized
Warning FailedCreatePodSandBox 57s kubelet Failed to create pod sandbox: rpc error: code = Unknown desc = failed to setup network for sandbox "88662ddfd4c50c01be8eadf80eb10bc6df35fb2d17d3cb06288406d74fa703b9": plugin type="calico" failed (add): error getting ClusterInformation: connection is unauthorized: Unauthorized
Warning FailedCreatePodSandBox 56s kubelet Failed to create pod sandbox: rpc error: code = Unknown desc = failed to setup network for sandbox "c98ab3359a8ef8148a7ab64aee0d35d95c9afebc417f6a9690914713601baf8f": plugin type="calico" failed (add): error getting ClusterInformation: connection is unauthorized: Unauthorized
Warning FailedCreatePodSandBox 55s kubelet Failed to create pod sandbox: rpc error: code = Unknown desc = failed to setup network for sandbox "d20ea232588faa5e962a19cab85b0a7503fece341aab8ba680b398f4db70a5b7": plugin type="calico" failed (add): error getting ClusterInformation: connection is unauthorized: Unauthorized
Warning FailedCreatePodSandBox 54s kubelet Failed to create pod sandbox: rpc error: code = Unknown desc = failed to setup network for sandbox "4526f8fbc1e468d33d05a406e68ee5b26f27de70534bf77c7d36e9b754602f58": plugin type="calico" failed (add): error getting ClusterInformation: connection is unauthorized: Unauthorized
Warning FailedCreatePodSandBox 53s kubelet Failed to create pod sandbox: rpc error: code = Unknown desc = failed to setup network for sandbox "2ba82edb88df172f6ca35d03a4e0f881f4d3b6e9f9f4f5c770793a90fb519d27": plugin type="calico" failed (add): error getting ClusterInformation: connection is unauthorized: Unauthorized
Warning FailedCreatePodSandBox 52s kubelet Failed to create pod sandbox: rpc error: code = Unknown desc = failed to setup network for sandbox "a676777c157d183e059f3a841b878ece14ab5549dbe15a16d7f14ca26926ed1f": plugin type="calico" failed (add): error getting ClusterInformation: connection is unauthorized: Unauthorized
Warning FailedCreatePodSandBox 51s kubelet Failed to create pod sandbox: rpc error: code = Unknown desc = failed to setup network for sandbox "335b7990e2536334ec86d87e4e93f974e4c939992d58911dcb88eca4fb713ace": plugin type="calico" failed (add): error getting ClusterInformation: connection is unauthorized: Unauthorized
Warning FailedCreatePodSandBox 50s kubelet Failed to create pod sandbox: rpc error: code = Unknown desc = failed to setup network for sandbox "6deb2c78cbf72fa0a3be03d952a362517a4ab95149496b9af996e31a8db3e152": plugin type="calico" failed (add): error getting ClusterInformation: connection is unauthorized: Unauthorized
Normal SandboxChanged 46s (x12 over 57s) kubelet Pod sandbox changed, it will be killed and re-created.
Warning FailedCreatePodSandBox 46s (x4 over 49s) kubelet (combined from similar events): Failed to create pod sandbox: rpc error: code = Unknown desc = failed to setup network for sandbox "7cfde278ce139b3c85ab5ee1f578c0c760f00c7f7d7e2acd1a09bfc670cda0ab": plugin type="calico" failed (add): error getting ClusterInformation: connection is unauthorized: Unauthorized
핵심 에러: Failed to create pod sandbox: rpc error: code = Unknown desc = failed to setup network for sandbox "f70b7825d0a16c329c9b57aa86acc9025629ba505c2bb5efbfeb83ca6c6c9501": plugin type="calico" failed (add): error getting ClusterInformation: connection is unauthorized: Unauthorized 해결**$ kubectl -n kube-system rollout restart ds/calico-node**
daemonset.apps/calico-node restarted
**$ kubectl -n kube-system rollout restart deploy/calico-kube-controllers**
deployment.apps/calico-kube-controllers restarted: 클라이언트와 파드의 연결을 담당Service는 쿠버네티스에서 Pod의 네트워크 접근을 안정적으로 제공하는 추상화 객체
Pod는 언제든 새로 생성되거나 삭제될 수 있어 IP가 계속 바뀜
→ 이때 Service가 “고정된 IP와 DNS 이름”을 제공해서, 외부나 내부에서 안정적으로 Pod에 접근할 수 있게 해줌
서비스 타입(유형)
**$ kubectl get service**
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.233.0.1 <none> 443/TCP 46h
ClusterIP
: 기본 서비스 타입 (생략 시 자동 적용)
: 클러스터 내부에서만 파드에 접근될 수 있도록 함
→ 내부 파드들끼리 통신
: 외부에서는 접근 불가
NodePort
: 외부 접근이 필요한 경우 ClusterIP 위에 노출되는 상위 타입
: 각 노드의 특정 포트를 통해 외부 접근을 제공하는 유형
→ NAT 를 사용하는 클러스터 내에서 각 노드들의 지정된 포트를 외부에 노출시켜줌
파드들의 차이: 포트 번호
<NodeIP>:<NodePort>
로 클러스터 외부에서 서비스에 접근할 수 있도록 함
내부적으로는 여전히 ClusterIP로 라우팅됨.
모든 노드가 동일한 포트 개방
LoadBalancer
: ClusterIP + NodePort + 공인 IP
: 외부 공인 IP가 할당되어 외부 사용자가 직접 접속 가능
: 외부용 LoadBalancer를 생성하고 서비스에 고정된 공인 IP를 할당
→ IP 및 포트 번호를 활용해 클러스터 외부에서 서비스에 접근 가능
: 내부적으로는 NodePort/ClusterIP로 연결됨
ExternalName
LoadBalancer
└── NodePort
└── ClusterIP
ClusterIP: 내부 트래픽 라우팅 (Pod 간)
NodePort: ClusterIP + 노드 포트 개방 (외부 진입점 추가)
LoadBalancer: NodePort + 클라우드 퍼블릭 IP 부여 (외부 트래픽 자동 분산)
즉, LoadBalancer → NodePort → ClusterIP 순서로 포워딩
[외부 클라이언트]
→ LoadBalancer(공인 IP)
→ NodePort(노드 포트)
→ ClusterIP(가상 서비스 IP)
→ Pod(컨테이너)
보통 로드밸런서를 사용함
→ 로드밸런서는 결국 공인 IP+NodePort+ClusterIP
문제점
그러나, 기본적으로 파드는
파드 종료 후 재시작되면 IP 주소가 재할당됨
→ ClusterIP 는 파드 IP 를 가지고 로드밸런싱하므로 재할당되면 연결이 끊어짐
→ 무중단 서비스 제공 불가
해결 방법
Headless Service
: ClusterIP가 없는(Service Type: ClusterIP, clusterIP: None) 서비스
즉,
중간 로드밸런싱 계층(ClusterIP)을 제거하고,
DNS 이름을 통해 직접 Pod IP 목록을 반환
**$ cp myapp-rs.yml myapp-rs-nodeport.yml
$ kubectl apply -f myapp-rs-nodeport.yml**
replicaset.apps/myapp-rs created
노드포트 서비스 yml 파일 작성
$ vim myapp-svc-np.yml
apiVersion: v1
kind: Service
metadata:
name: myapp-svc-np
spec:
type: NodePort
ports:
- port: 80
targetPort: 8080
nodePort: 31111
selector:
app: myapp-rs
type 을 따로 명시(ClusterIP는 기본값이라 지정 안한 것)
nodePort 는 꼭 지정하지 않아도 됨 → 30000-32767 범위에서 랜덤 지정
노드포트 서비스 구동
**$ kubectl apply -f myapp-svc-np.yml**
service/myapp-svc-np created
# 확인
**$ kubectl get service myapp-svc-np**
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
myapp-svc-np NodePort 10.233.47.158 <none> 80:31111/TCP 12s
확인
$ curl 192.168.56.21:31111
Hello World!
myapp-rs-47nvm
$ curl 192.168.56.22:31111
Hello World!
myapp-rs-v7t4l
$ curl 192.168.56.23:31111
Hello World!
myapp-rs-v7t4l
: AWS 제공하는 ELB를 사용하여 로컬의 서비스와 연결이 가능하도록 만드는 기능
$ cp myapp-svc-np.yml myapp-svc-lb.yml
$ vim myapp-svc-lb.yml
apiVersion: v1
kind: Service
metadata:
name: myapp-svc-lb
spec:
type: LoadBalancer
ports:
- port: 80
targetPort: 8080
selector:
app: myapp-rs
로드밸런서 서비스 구동 및 확인
**$ kubectl apply -f myapp-svc-lb.yml**
service/myapp-svc-lb created
**$ kubectl get service myapp-svc-lb**
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
myapp-svc-lb LoadBalancer 10.233.47.178 192.168.56.201 80:30629/TCP 9s
**$ kubectl get endpoints**
NAME ENDPOINTS AGE
kubernetes 192.168.56.11:6443 2d19h
myapp-svc-lb 10.233.118.96:8080,10.233.73.103:8080,10.233.74.32:8080 14s
myapp-svc-np 10.233.118.96:8080,10.233.73.103:8080,10.233.74.32:8080 85m
통신 확인
**$ curl 192.168.56.201**
Hello World!
myapp-rs-c2b48
: 클러스터 외부에서 내부에 존재하는 쿠버네티스 서비스에 접근하기 위해 HTTP/HTTPS를 활용한 라우팅 규칙을 제공하는 오브젝트
외부 노출 서비스가 많을 경우 노드포트 사용 시 노드의 각 서비스별 포트를 개방해야 함
→ 인그레스가 HTTP/HTTPS 요청 주소를 구분해 각 서비스에 라우팅 가능
인그레스를 사용하려면 인그레스 컨트롤러 필요
nginx 인그레스 컨트롤러가 가장 대중적으로 사용하는 컨트롤러
nginx ingress controller 확인
**$ kubectl get pod -n ingress-nginx -o wide**
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
ingress-nginx-controller-7m9bb 1/1 Running 0 2d20h 10.233.73.65 kube-node1 <none> <none>
ingress-nginx-controller-vpqql 1/1 Running 0 2d20h 10.233.74.2 kube-node2 <none> <none>
ingress-nginx-controller-zxpr4 1/1 Running 0 2d20h 10.233.118.65 kube-node3 <none> <none>
인그레스는 서비스와 같이 동작하기 때문에 노드별로 배치될 서비스에 라우팅해주기 위해 각 노드별로 하나씩 nginx 인그레스 컨트롤러가 존재함
.spec.service.name: 라우팅할 기본 백엔드 서비스 이름, 규칙에 매칭되지 않는 트래픽은 기본 백엔드로 전송됨.spec.defaultBackend.service.port.number: 라우팅할 기본 백엔드 서비스의 포트.spec.rules.host: URL 호스트.spec.rules.http.paths.path: URL의 경로.spec.rules.http:paths.pathType: URL의 경로 유형/를 기준으로 일치시킴.spec.rules.http.paths.path.backend: 라우팅할 서비스 밴엔드.spec.rules.http.paths.path.backend.service.name: 라우팅할 서비스 이름.spec.rules.http.paths.path.backend.service.port.number: 서비스 포트$ vim myapp-ing.yml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: myapp-ing
spec:
defaultBackend:
service:
name: myapp-svc-np
port:
number: 80
rules:
- host: myapp.example.com
http:
paths:
- path: /
pathType: Exact
backend:
service:
name: myapp-svc-np
port:
number: 80
**$ kubectl get ingresses.networking.k8s.io**
NAME CLASS HOSTS ADDRESS PORTS AGE
myapp-ing <none> myapp.example.com 192.168.56.21,192.168.56.22,192.168.56.23 80 45s
**$ curl --resolve myapp.example.com:80:192.168.56.21 myapp.example.com**
Hello World!
myapp-rs-47nvm
현재 외부 DNS가 없기 때문에 myapp.example.com FQDN의 A 레코드를 반환하지 못함
curl --resolve 옵션을 사용하여 일시적으로 FQDN의 주소를 ip주소로 매핑
다중 경로 인그레스 설정
**$ vim myapp-ing-multi-paths.yml**
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: myapp-ing
spec:
defaultBackend:
service:
name: myapp-svc-np
port:
number: 80
rules:
- host: myapp.example.com
http:
paths:
- path: /web1
pathType: Exact
backend:
service:
name: myapp-svc-ext-np1
port:
number: 80
- path: /web2
pathType: Exact
backend:
service:
name: myapp-svc-ext-np2
port:
number: 80
$ kubectl describe ingresses.networking.k8s.io myapp-ing
Rules:
Host Path Backends
---- ---- --------
myapp.example.com
/web1 myapp-svc-ext-np1:80 (<error: services "myapp-svc-ext-np1" not found>)
/web2 myapp-svc-ext-np2:80 (<error: services "myapp-svc-ext-np2" not found>)
다중 호스트 인그레스 설정
$ vim myapp-ing-multi-hosts.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: myapp-ing
spec:
defaultBackend:
service:
name: myapp-svc-np
port:
number: 80
rules:
- host: web1.example.com
http:
paths:
- path: /
pathType: Exact
backend:
service:
name: myapp-svc-ext-np1
port:
number: 80
- host: web2.example.com
http:
paths:
- path: /
pathType: Exact
backend:
service:
name: myapp-svc-ext-np2
port:
number: 80
**$ kubectl describe ingresses.networking.k8s.io myapp-ing**
Rules:
Host Path Backends
---- ---- --------
web1.example.com
/ myapp-svc-ext-np1:80 (<error: services "myapp-svc-ext-np1" not found>)
web2.example.com
/ myapp-svc-ext-np2:80 (<error: services "myapp-svc-ext-np2" not found>)
컨테이너 생성되면 볼륨 같이 생성
일반적으로 컨테이너를 제거하면 생성된 볼륨도 같이 제거
영구 설정을 하면 볼륨 영구적으로 사용 가능
: 공유 디렉토리
파드는 생성과 동시에 볼륨이 생성되지만 임시로 사용할 볼륨이어도 내부 디렉토리로 공유하자는 취지
.spec.volumes: 볼륨 정의.spec.volumes.name: 볼륨의 이름.spec.volumes.<TYPE>: 볼륨의 종류.spec.volumes.emptyDir: emptyDir 타입의 볼륨 정의.spec.volumes.name: 볼륨의 이름.spec.containers.volumeMounts: 컨테이너 마운트 할 볼륨을 선언.spec.containers.volumeMounts.name: 사용할 볼륨 이름.spec.volumes.name 필드의 이름 참조.spec.containers.volumeMounts.mountPath: 컨테이너 내의 마운트 포인트$ vim myapp-rs-emptydir.yml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: myapp-rs-fortune
spec:
# 복제본 개수 지정
replicas: 1
selector:
matchLabels:
app: myapp-rs-fortune
template:
metadata:
# 다수의 파드들의 레이블
labels:
app: myapp-rs-fortune
spec:
containers:
- name: web-server
image: nginx:alpine
volumeMounts:
- name: web-fortune
mountPath: /usr/share/nginx/html
readOnly: true
ports:
- containerPort: 80
- name: html-generator
image: ghcr.io/c1t1d0s7/fortune
volumeMounts:
- name: web-fortune
mountPath: /var/htdocs
volumes:
- name: web-fortune
emptyDir: {}
$ vim myapp-svc-emptydir.yml
apiVersion: v1
kind: Service
metadata:
name: myapp-svc-emptydir
spec:
type: LoadBalancer
ports:
- port: 80
targetPort: 80
selector:
app: myapp-rs-fortune
컨테이너 접속해서 내부 파일 확인
**$ kubectl exec myapp-rs-fortune-2875c -c web-server -- cat /usr/share/nginx/html/index.html**
Dear Miss Manners:
My home economics teacher says that one must never place one's
elbows on the table. However, I have read that one elbow, in between
courses, is all right. Which is correct?
Gentle Reader:
For the purpose of answering examinations in your home
economics class, your teacher is correct. Catching on to this
principle of education may be of even greater importance to you now
than learning correct current table manners, vital as Miss Manners
believes that is.
**$ kubectl exec myapp-rs-fortune-2875c -c html-generator -- cat /var/htdocs/index.html**
Bug, n.:
An aspect of a computer program which exists because the
programmer was thinking about Jumbo Jacks or stock options when s/he
wrote the program.
Fortunately, the second-to-last bug has just been fixed.
-- Ray Simard
**$ curl http://192.168.56.201**
A New York City judge ruled that if two women behind you at the movies
insist on discussing the probable outcome of the film, you have the
right to turn around and blow a Bronx cheer at them.
공유 볼륨 확인 시 노드 먼저 확인
**$ kubectl get pods -o wide**
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
myapp-rs-fortune-2875c 2/2 Running 0 7m58s 10.233.73.104 kube-node1 <none> <none>
uid 확인
**$ kubectl get pod myapp-rs-fortune-2875c -o jsonpath='{.metadata.uid}'**
0155d67a-eebd-4252-85fe-49b40223c7e4
vagrant 접속(kube-node1)
**vagrant@kube-node1:~$ sudo ls /var/lib/kubelet/pods/0155d67a-eebd-4252-85fe-49b40223c7e4/volumes/kubernetes.io~empty-dir/web-fortune**
index.html