쿠버네티스 오브젝트 (Service, Volume, ConfigMap)
지난 포스팅에 이어 쿠버네티스의 오브젝트에 대하여 알아보겠습니다.
Service
Pod은 IP를 가지고, 다른 Pod과 통신할 수 있습니다.
하지만 Pod은 쉽게 삭제되고, 생성될 수 있기 때문에 쿠버네티스는 고정된 IP를 가진 서비스를 만들고 서비스를 통해 Pod에 접근합니다.
Service(ClusterIP) 만들기
ClusterIP는 클러스터 내부에 새 IP를 할당하고, 여러 Pod을 바라보는 로드밸런서 기능을 제공합니다.
그리고 서비스 이름을 내부 도메인 서버에 등록하고 Pod간 서비스 이름으로 통신할 수 있습니다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis
spec:
selector:
matchLabels:
app: counter
tier: db
template:
metadata:
labels:
app: counter
tier: db
spec:
containers:
- name: redis
image: redis
ports:
- containerPort: 6379
protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
name: redis
spec:
ports:
- port: 6379
protocol: TCP
selector:
app: counter
tier: db
redis라는 이름의 서비스를 만드는 yaml 파일입니다.
selector을 통해 접근할 Pod을 지정하고, ports를 통해 연결되는 port를 지정합니다.
Service(NodePort) 만들기
ClusterIP는 클러스터 내부에서만 접근할 수 있으므로 클러스터 외부에서 접근하려면 NodePort 서비스를 사용해야 합니다.
apiVersion: v1
kind: Service
metadata:
name: counter-np
spec:
type: NodePort
ports:
- port: 3000
protocol: TCP
nodePort: 31000
selector:
app: counter
tier: app
이전과 달라진 점은 nodePort가 추가된 것과 type이 명시되었다는 것입니다.
해당 서비스가 외부 IP의 31000포트와 연결됩니다.
spec.ports.nodePort
는 노드에 오픈할 Port로 미지정시 30000~32768번 포트중 하나로 자동 할당됩니다.
또한 NodePort는 ClusterIP의 기능을 기본으로 포함합니다.
Service(LoadBalancer) 만들기
NodePort는 하나의 노드에 할당되어 해당 노드가 사라진다면 다른 노드를 통해 접근이 불가능합니다.
3개의 노드가 있을 때, 어떠한 노드로 접근하더라도 NodePort로 연결할 수 있지만 어떤 노드가 살아있는지는 알 수 없습니다.
이를 해결해 정상적인 노드에 접근하기 위해 모든 노드를 바라보는 LoadBalancer가 필요합니다.
LoadBalancer을 이용하면 NodePort에 요청하는 것이 아닌 LoadBalancer에 요청하고, LoadBalancer은 정상 노드에 자동으로 연결해줘 NodePort의 단점을 해결할 수 있습니다.
apiVersion: v1
kind: Service
metadata:
name: counter-lb
spec:
type: LoadBalancer
ports:
- port: 30000
targetPort: 3000
protocol: TCP
selector:
app: counter
tier: app
Volume
Pod 안의 컨테이너는 Pod이 제거될 때, 내부 저장 데이터 또한 모두 사라집니다.
데이터베이스의 경우 데이터가 유실되지 않도록 별도의 저장소에 데이터를 저장하고 새 데이터베이스 컨테이너를 만들 때 이전 데이터를 가져와 동기화를 해야합니다.
이 때 사용하는 기술은 Volume입니다.
제 환경이 로컬이기 때문에 클라우드와 같은 외부 스토리지를 이용하지 않고, local저장소를 이용하는 방법을 알아봅니다.
Volume(Local) 사용하기
apiVersion: v1
kind: Pod
metadata:
name: sidecar
spec:
containers:
- name: app
image: busybox
args:
- /bin/sh
- -c
- >
while true;
do
echo "$(date)\n" >> /var/log/example.log;
sleep 1;
done
volumeMounts:
- name: varlog
mountPath: /var/log
- name: sidecar
image: busybox
args: [/bin/sh, -c, "tail -f /var/log/example.log"]
volumeMounts:
- name: varlog
mountPath: /var/log
volumes:
- name: varlog
emptyDir: {}
---
apiVersion: v1
kind: Pod
metadata:
name: host-log
spec:
containers:
- name: log
image: busybox
args: ["/bin/sh", "-c", "sleep infinity"]
volumeMounts:
- name: varlog
mountPath: /host/var/log
volumes:
- name: varlog
hostPath:
path: /var/log
일반적인 Pod의 생성과 함께 volumes를 이용해 볼륨을 생성하고, 컨테이너 생성에 해당 볼륨을 마운트했습니다.
ConfigMap
지금까지 여러 오브젝트를 만들면서 여러 env를 직접 지정했습니다.
이렇게 yaml파일마다 env를 지정하기보다 설정, 환경변수를 외부로 빼고 관리할 수 있는 방법을 알아봅니다.
ConfigMap 파일로 관리하기
global:
scrape_interval: 15s
scrape_configs:
- job_name: prometheus
metrics_path: /prometheus/metrics
static_configs:
- targets:
- localhost:9090
kubectl create cm my-config --from-file=config-file.yml
kubectl get cm
kubectl describe cm/my-config
이렇게 생성한 ConfigMap을 연결할 Pod에 volumes로 연결합니다.
apiVersion: v1
kind: Pod
metadata:
name: alpine
spec:
containers:
- name: alpine
image: alpine
command: ["sleep"]
args: ["100000"]
volumeMounts:
- name: config-vol
mountPath: /etc/config
volumes:
- name: config-vol
configMap:
name: my-config
이렇게 연결한 configfile은 볼륨으로 마운트한 디렉토리에 생성되게 됩니다.
env파일로 만들기
configMap을 env포멧으로 만들어 사용할 때에는
hello=world
haha=hoho
위와 같이 파일을 만들고, 이전과 동일하게 사용합니다.
YAML파일로 선언하기
apiVersion: v1
kind: ConfigMap
metadata:
name: my-config
data:
hello: world
kuber: netes
multiline: |-
first
second
third
volume이 아닌 환경변수로 사용하기
위에서는 파일 자체를 volume으로 연결해 사용했지만, 환경변수로 바로 사용할 수도 있습니다.
apiVersion: v1
kind: Pod
metadata:
name: alpine-env
spec:
containers:
- name: alpine
image: alpine
command: ["sleep"]
args: ["100000"]
env:
- name: hello
valueFrom:
configMapKeyRef:
name: my-config
key: hello
위와 같이 env에서 valueFrom을 이용해 바로 값을 가져와 사용할 수 있습니다.
마침
여기까지 쿠버네티스의 기본적인 Object를 알아보았습니다.
물론 Secret, Ingress와 같은 중요한 오브젝트도 존재하지만, 간략하게 정리해보았습니다.
감사합니다.
'Devops' 카테고리의 다른 글
AWS ECS + Fargate 를 이용해 애플리케이션 배포하기 (1) | 2024.01.01 |
---|---|
AWS EC2 서버에 Nginx 설치하기 (0) | 2023.11.05 |
AWS EC2 서버에 Docker 설치하기 (0) | 2023.11.05 |
[Kubernetes] 쿠버네티스 오브젝트(Pod, ReplicaSet, Deployment) (0) | 2022.08.29 |
[Kubernetes] 쿠버네티스 간단 개념 정리 (0) | 2022.08.29 |
[Kafka] docker를 이용해 kafka 환경 구축하기 (0) | 2022.08.16 |