서비스 생성
서비스는 파드 집합에 대한 안정적인 접근을 가능하게 하는 추상화 계층이다. (실행중인 애플리케이션 → 서비스로 노출 feat. selector)
서비스는 동일한 기능을 수행하는 파드들에게 단일 IP 주소와 DNS 이름을 제공하며 로드 밸런싱과 트래픽 라우팅을 관리한다. 그렇기 때문에 클러스터 목표 상태(desired state)와 일치하도록 생성되고 삭제되는 과정에서 동적으로 관리해줄 수 있게 된다.
새로운 디렉토리에 rs yaml 파일 생성
# ㅣion-rs.yaml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: lion
labels:
app: lion
spec:
replicas: 3
selector:
matchLabels:
app: lion
template:
metadata:
labels:
app: lion
spec:
containers:
- name: lion
image: teacherssamko/simple-web:v3
ports:
- containerPort: 8000
livenessProbe:
httpGet:
path: /
port: 8000
k create -f lion-rs.yaml
# result
kimminhyeok@Ivans-Mac 0904 % k get po
NAME READY STATUS RESTARTS AGE
lion-4j644 1/1 Running 1 (31s ago) 2m22s
lion-79bj6 1/1 Running 1 (31s ago) 2m22s
lion-kpzvs 1/1 Running 1 (31s ago) 2m22s
kimminhyeok@Ivans-Mac 0904 % k get rs
NAME DESIRED CURRENT READY AGE
lion 3 3 3 2m26s
create svc yaml
# lion-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: lion
spec:
selector:
app: lion
ports: # TCP 로 80 포트로 받아서 8000 으로 보내주겠다.
- protocol: TCP
port: 80
targetPort: 8000
selector.app 에 설정되어 있는 lion 이라는 레이블을 가진 파드들에게 서비스를 넘겨주는 구조이다.
k create -f lion-svc.yaml
k get svc
# result
kimminhyeok@Ivans-Mac 0904 % k get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 2d21h
lion ClusterIP 10.102.129.95 <none> 80/TCP 4s
여기서 클러스터 아이디는 안쪽에서 열린 주소 이기 때문에 로컬에서 바로 접속이 불가능 하다.
# 로컬에서 접속시도 후 실패
kimminhyeok@Ivans-Mac 0904 % curl <http://10.102.129.95>
curl: (28) Failed to connect to 10.102.129.95 port 80 after 75008 ms: Couldn't connect to server
그래서 파드 하나를 골라서 실행을 시키면,
k exec lion-4j644 -- curl <http://10.102.129.95>
# or execute service
k exec lion-4j644 -- curl -s <http://10.102.129.95>
# result
kimminhyeok@Ivans-Mac 0904 % k exec lion-4j644 -- curl <http://10.102.129.95>
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 17 0 17 0 0 1637 0 --:--:-- --:--:-- --:--:-- 2428
Too many requests%
kimminhyeok@Ivans-Mac 0904 % k exec lion-4j644 -- curl -s <http://10.102.129.95>
Host Name: lion-4j644 / v=2 / Request: 1 /
클러스터 IP 가 클러스터 내부에서만 접근이 가능한 주소인 것을 확인 할 수 있다.
Issue: CrashLoopBackOff
kimminhyeok@Ivans-Mac 0904 % k get po
NAME READY STATUS RESTARTS AGE
lion-4j644 0/1 CrashLoopBackOff 6 (87s ago) 14m
lion-79bj6 0/1 CrashLoopBackOff 6 (77s ago) 14m
lion-kpzvs 0/1 CrashLoopBackOff 6 (77s ago) 14m
CrashLoopBackOff
파드의 컨테이너가 반복적으로 실패하고 재시작되고 있음을 보여준다.
가능성 있는 원인들
- 애플리케이션 코드 오류
- 리소스 제한
- 설정 오류
- 종속성 문제
Solution: CrashLoopBackOff
해결방안으로, rs 를 삭제하지 않고 파드들만 삭제하여 rs 가 다시 되살릴 수 있게 한다.
k delete -l app=lion
kimminhyeok@Ivans-Mac 0904 % k delete po -l app=lion
pod "lion-4j644" deleted
pod "lion-79bj6" deleted
pod "lion-kpzvs" deleted
kimminhyeok@Ivans-Mac 0904 % k get po
NAME READY STATUS RESTARTS AGE
lion-5qz46 1/1 Running 1 (4s ago) 114s
lion-tc6k2 1/1 Running 1 (4s ago) 114s
lion-zj7w6 1/1 Running 1 (4
컨테이너가 죽는 현상을 막기 위해 이미지를 업데이트헀다.
v3 → v4
이후 다시 rs 를 실행시키고 같은 방법으로 요청을 넣어본다.
# 서비스 실행 후 확인
kimminhyeok@Ivans-Mac 0904 % k get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 2d21h
lion ClusterIP 10.102.129.95 <none> 80/TCP 21m
# 하나의 파드로 직접 들어와서 요청을 보냈지만, 서비스의 IP 주소, 클러스터 주소로
# 요청을 보내고 있어서 랜덤 파드에서 응답이 돌아오고 있다.
kimminhyeok@Ivans-Mac 0904 % k exec -it lion-hccsb -- sh
/app # curl <http://10.102.129.95>
Host Name: lion-ljn8v / v=4 / Request: 40 /
/app # curl <http://10.102.129.95>
Host Name: lion-j5hfb / v=4 / Request: 40 /
/app # curl <http://10.102.129.95>
Host Name: lion-j5hfb / v=4 / Request: 41 /
/app # curl <http://10.102.129.95>
Host Name: lion-hccsb / v=4 / Request: 41 /
/app # curl <http://10.102.129.95>
Host Name: lion-hccsb / v=4 / Request: 42 /
/app # curl <http://10.102.129.95>
Host Name: lion-hccsb / v=4 / Request: 43 /
/app # curl <http://10.102.129.95>
Host Name: lion-hccsb / v=4 / Request: 45 /
/app # curl <http://10.102.129.95>
Host Name: lion-j5hfb / v=4 / Request: 43 /
/app #
요청을 일관적으로 하나의 파드에서 전달받고 싶으면
# wide search
kimminhyeok@Ivans-Mac 0904 % k get po -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
lion-hccsb 1/1 Running 0 5m 10.244.0.192 minikube <none> <none>
lion-j5hfb 1/1 Running 0 5m 10.244.0.191 minikube <none> <none>
lion-ljn8v 1/1 Running 0 5m 10.244.0.193 minikube <none> <none>
curl 을 해당 파드의 IP 로 직접 보내주면 된다.
요청을 하나의 파드로 잡아 줄 수 도 있는데, 서비스에서 요청을 보낼 때 지정한 파드의 주소로 매핑하게 해주면 된다.
k edit svc lion
# sessionAffinity: None -> ClientIP
# svc yaml
apiVersion: v1
kind: Service
metadata:
creationTimestamp: "2023-09-04T01:25:21Z"
name: lion
namespace: default
resourceVersion: "86392"
uid: c89b1ee4-caab-40cd-b0c3-47904d9cf79a
spec:
clusterIP: 10.102.129.95
clusterIPs:
- 10.102.129.95
internalTrafficPolicy: Cluster
ipFamilies:
- IPv4
ipFamilyPolicy: SingleStack
ports:
- port: 80
protocol: TCP
targetPort: 8000
selector:
app: lion
sessionAffinity: ClientIP
kimminhyeok@Ivans-Mac 0904 % k get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 2d22h
lion ClusterIP 10.102.129.95 <none> 80/TCP 42m
kimminhyeok@Ivans-Mac 0904 % k exec lion-hccsb -- curl -s <http://10.102.129.95>
Host Name: lion-j5hfb / v=4 / Request: 472 /
kimminhyeok@Ivans-Mac 0904 % k exec lion-hccsb -- curl -s <http://10.102.129.95>
Host Name: lion-j5hfb / v=4 / Request: 473 /
kimminhyeok@Ivans-Mac 0904 % k exec lion-hccsb -- curl -s <http://10.102.129.95>
Host Name: lion-j5hfb / v=4 / Request: 474 /
포트를 이름으로 지정해서 서비스 하기
# lion-rs.yaml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: lion
labels:
app: lion
spec:
replicas: 3
selector:
matchLabels:
app: lion
template:
metadata:
labels:
app: lion
spec:
containers:
- name: lion
image: teacherssamko/simple-web:v4
ports:
- containerPort: 8000
name: http
livenessProbe:
httpGet:
path: /
port: 8000
initialDelaySeconds: 3
periodSeconds: 3
# lion-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: lion
spec:
selector:
app: lion
ports: # TCP 로 80 포트로 받아서 8000 으로 보내주겠다.
- protocol: TCP
port: 80
targetPort: http
name: http
k create -f lion-rs.yaml
k create -f lion-svc.yaml
kimminhyeok@Ivans-Mac 0904 % k get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 2d22h
lion ClusterIP 10.103.220.139 <none> 80/TCP 4s
kimminhyeok@Ivans-Mac 0904 %
kimminhyeok@Ivans-Mac 0904 % k exec lion-r9dbs -- curl -s <http://10.103.220.139>
Host Name: lion-r9dbs / v=4 / Request: 75 /
따로 포트번호를 지정하지 않고 이름만으로도 연결 지을 수 있는 것을 확인
지금은 rs 를 먼저 생성하고 svc 를 생성하면서 연결 시켰기 때문에 파드에는 서비스 정보값이 안들어가 있다. 기존에 있는 파드를 레이블로 삭제하여 재생성 되게 하면 환경 변수값이 저장된다.
# previous
kimminhyeok@Ivans-Mac 0904 % k exec lion-r9dbs -- env
HOME=/root
PYTHON_GET_PIP_SHA256=
PYTHON_GET_PIP_URL=https:
PYTHON_SETUPTOOLS_VERSION=
PYTHON_PIP_VERSION=2
PYTHON_VERSION=3
LANG=C.UTF-
KUBERNETES_PORT_443_TCP_PROTO=t
KUBERNETES_PORT_443_TCP=t
KUBERNETES_PORT=t
KUBERNETES_SERVICE_PORT_HTTPS=
KUBERNETES_SERVICE_PORT=
KUBERNETES_SERVICE_HOST=
KUBERNETES_PORT_443_TCP_ADDR=
KUBERNETES_PORT_443_TCP_PORT=
HOSTNAME=lion-r9dbs
삭제후 재 검색
kimminhyeok@Ivans-Mac 0904 % k delete po -l app=lion
pod "lion-r9dbs" deleted
pod "lion-vhdgt" deleted
pod "lion-xqvkt" deleted
kimminhyeok@Ivans-Mac 0904 % k get po
NAME READY STATUS RESTARTS AGE
lion-27zpp 1/1 Running 0 33s
lion-m5qq5 1/1 Running 0 33s
lion-qg4fm 1/1 Running 0 33s
kimminhyeok@Ivans-Mac 0904 % k exec lion-27zpp -- env
HOME=/root
PYTHON_GET_PIP_SHA256=
PYTHON_GET_PIP_URL=
PYTHON_SETUPTOOLS_VERSION=
PYTHON_PIP_VERSION=
PYTHON_VERSION=
LANG=C.UTF-
KUBERNETES_PORT_443_TCP=
KUBERNETES_SERVICE_PORT_HTTPS=
KUBERNETES_SERVICE_PORT=
LION_PORT_80_TCP_PROTO=
LION_PORT=tcp://10.103.220.139:80
LION_SERVICE_PORT_HTTP=80
KUBERNETES_PORT_443_TCP_PROTO=t
KUBERNETES_PORT=
KUBERNETES_SERVICE_HOST=
LION_PORT_80_TCP=tcp://10.103.220.139:80
LION_SERVICE_HOST=10.103.220.139
KUBERNETES_PORT_443_TCP_ADDR=
KUBERNETES_PORT_443_TCP_PORT=
LION_PORT_80_TCP_ADDR=10.103.220.139
LION_PORT_80_TCP_PORT=80
LION_SERVICE_PORT=80
HOSTNAME=lion-27zpp
kimminhyeok@Ivans-Mac 0904 % k get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 2d22h
lion ClusterIP 10.103.220.139 <none> 80/TCP 8m50s
DNS 를 이용해서 조회하기
kimminhyeok@Ivans-Mac 0904 % k exec -it lion-m5qq5 -- sh
/app # curl <http://lion.default.svc.cluster.local>
Host Name: lion-27zpp / v=4 / Request: 124 /
/app #
/app # curl
Host Name: lion-qg4fm / v=4 / Request: 133 /
Node port
노드포트는 쿠버네티스에서 외부 트래픽을 클러스터 내부의 특정 서비스로 라우팅 하는 방법중 하나이다.
노드포트는 클러스터 내 모든 노드의 특정 포트에 트래픽을 노출시키고 이를 적절한 파드로 포워딩 한다.
apiVersion: v1
kind: Service
metadata:
name: lion-nodeport
spec:
type: NodePort
selector:
app: lion
ports:
# 기본적으로 그리고 편의상 `targetPort` 는 `port` 필드와 동일한 값으로 설정된다.
- port: 80
targetPort: http
Ingress
쿠바네티스 클러스트 내의 서비스에 외부 HTTP/HTTPS 트래픽을 라우팅하는 API 오브젝트이다. 고급 라우팅, SSL 종료 및 도메인 기반 라우팅을 지원한다.
<https://kubernetes.io/ko/docs/concepts/services-networking/ingress/>
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: lion
# annotations:
# nginx.ingress.kubernetes.io/rewrite-target: /
spec:
# ingressClassName: nginx-example
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: lion-nodeport
port:
number: 80
host: lion.example.com # dns
ReadinessProbe
Health check 처럼 간단한 명령어로 상태확인 가능
# lion-rs.yaml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: lion
labels:
app: lion
spec:
replicas: 3
selector:
matchLabels:
app: lion
template:
metadata:
labels:
app: lion
spec:
containers:
- name: lion
image: teacherssamko/simple-web:v1
ports:
- containerPort: 8000
name: http
livenessProbe:
httpGet:
path: /
port: 8000
initialDelaySeconds: 3
periodSeconds: 3
readinessProbe:
exec:
command:
- ls
- /var/ready
컨테이너 내부 안쪽에서 해당 명령어가 실행되고 안쪽에 ready 정보가 없어서 실제로 READY 상태가 되지 않은 것을 확인 가능하다.
svc 내에서도 endpoint 가 이어져 있지 않은 것을 확인가능
k get p
#
kimminhyeok@Ivans-Mac fourtune % k get po
NAME READY STATUS RESTARTS AGE
fortune 2/2 Running 0 98m
lion-fvrw8 0/1 Running 0 160m
lion-qlr4h 0/1 Running 0 160m
lion-v2-j4njd 1/1 Running 0 3h24m
lion-v2-jmgv4 1/1 Running 0 3h24m
lion-v2-nf44r 1/1 Running 0 3h24m
lion-zh79z 0/1 Running 0 160m
k describe svc lion-nodeport
#
Name: lion-nodeport
Namespace: default
Labels: <none>
Annotations: <none>
Selector: app=lion
Type: NodePort
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.97.6.65
IPs: 10.97.6.65
Port: <unset> 11180/TCP
TargetPort: http/TCP
NodePort: <unset> 30003/TCP
Endpoints:
Session Affinity: None
External Traffic Policy: Cluster
Events: <none>
도커 명령어로 내부에 직접 정보값을 생상하게 되면,
k exec lion-fvrw8 -- touch /var/ready
k exec lion-qlr4h -- touch /var/ready
kimminhyeok@Ivans-Mac fourtune % k get po
NAME READY STATUS RESTARTS AGE
fortune 2/2 Running 0 109m
lion-fvrw8 1/1 Running 0 171m
lion-qlr4h 1/1 Running 0 171m
lion-v2-j4njd 1/1 Running 0 3h35m
lion-v2-jmgv4 1/1 Running 0 3h35m
lion-v2-nf44r 1/1 Running 0 3h35m
lion-zh79z 0/1 Running 0 171m
kimminhyeok@Ivans-Mac fourtune % k describe svc lion-nodeport
Name: lion-nodeport
Namespace: default
Labels: <none>
Annotations: <none>
Selector: app=lion
Type: NodePort
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.97.6.65
IPs: 10.97.6.65
Port: <unset> 11180/TCP
TargetPort: http/TCP
NodePort: <unset> 30003/TCP
Endpoints: 10.244.0.215:8000,10.244.0.217:8000
Session Affinity: None
External Traffic Policy: Cluster
Events: <none>
Volume
emptyDir 볼륨으로 일시적인 데이터를 저장하여 파드가 생성될 때 생성되고 파드가 삭제될 때 제거되는 형태로 사용하면서 사용법에 대해 익혀본다.
간단하게 문구를 출력하는 프로그램을 도커파일로 만들어 이미지로 허브에 올려 볼륨 매핑으로 정보를 출력한다.
리눅스환경에서 제공하는 fortune library
# fortuneloop.sh
#!/bin/bash
mkdir -p /var/www
while true
do
echo $(date) Wrting fortune to /var/www/index.html
/usr/games/fortune > /var/www/index.html
sleep 10
done
# Dockerfile
FROM ubuntu:latest
RUN apt-get update && apt-get -y install fortune
ADD fortuneloop.sh /bin/fortuneloop.sh
RUN chmod +x /bin/fortuneloop.sh
ENTRYPOINT ["/bin/fortuneloop.sh"]
# fortune-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: fortune
spec:
containers:
- name: html-generator
image: ivan...
volumeMounts:
- name: html
mountPath: /var/www
- name: web-server
image: nginx:alpine
ports:
- containerPort: 80
**volumeMounts**:
- name: html
mountPath: /usr/share/nginx/html
readOnly: true
volumes:
- name: html
emptyDir: {}
Docker hub 에 올릴 이미지 만들기
docker build -t ivaninitworld/fortune:latest .
이미지를 docker hub 로 올리기
docker push ivaninitworld/fortune:latest
fortune-pod 실행
k create -f fortune-pod.yaml
실행된 파드에서 출력값 가져오기
k exec fortune -c html-generator -- cat /var/www/index.html
k exec fortune -c web-server -- cat /usr/share/nginx/html/index.html
#
kimminhyeok@Ivans-Mac fourtune % k exec fortune -c web-server -- cat /usr/share/nginx/html/index.html
You will be reincarnated as a toad; and you will be much happier.
kimminhyeok@Ivans-Mac fourtune % k exec fortune -c html-generator -- cat /var/www/index.html
You will be reincarnated as a toad; and you will be much happier.
Port-forward
k port-forward fortune 8080:80
#
kimminhyeok@Ivans-Mac fourtune % k port-forward fortune 8080:80
Forwarding from 127.0.0.1:8080 -> 80
Forwarding from [::1]:8080 -> 80
Handling connection for 8080
...
..
.
다른 터미널을 열어서
curl -s <http://localhost:8080>
#
kimminhyeok@Ivans-Mac k8s % curl -s <http://localhost:8080>
The Public is merely a multiplied "me."
-- Mark Twain
'Dev. > Kubernetes & Helm' 카테고리의 다른 글
Kubernetes: ConfigMap (0) | 2023.09.18 |
---|---|
Kubernetes: svc - pod 구조 이해 (0) | 2023.09.17 |
Kubernetes: 리소스 생성해보기 (0) | 2023.09.15 |
Kubernetes: 명령어와 익숙해지기 (0) | 2023.09.15 |
Kubernetes: Intro (0) | 2023.09.12 |
댓글