Go, Vantage point
가까운 곳을 걷지 않고 서는 먼 곳을 갈 수 없다.
Github | https://github.com/overnew/
Blog | https://everenew.tistory.com/
티스토리 뷰
Pod 생성 후 동작
# 파드 실행
kubectl run myweb --image=nginx
현재 세팅 중인 디폴트 Namespace에 생긴다.
kubectl delete pod myweb
yaml 파일로 실행
한땀한땀 커맨드 넣기는 명령형은 힘들다.
그냥 yaml로 만들어 버리자.
k run myweb --image nginx --dry-run -o yaml
--dry-run 옵션은 실제로 만드는게 아니라 리허설 옵션
실행되지 않고 yaml 파일만 생성한다.
없는 내용은 디폴트값으로 만들어진다.
apiVersion은 적합한 것으로 맞춰지게 생성된다.
# yaml 파일에 출력 결과 저장
k run myweb --image nginx --dry-run -o yaml > myweb.yaml
#yaml 파일로 pod 생성
kubectl apply -f myweb.yaml
#Get pod를 모니터링
watch -d 'kubectl get pod -o wide'
생성 명령어 멱등성 확인하기
여러 번 apply해도 desired 개수는 변경되지 않는다.
이는 멱등성 때문이다.
멱등성은 같은 연산을 여러 번 반복해도 결과가 바뀌지 않는 것을 의미한다.
명령어가 실행할 코드의 변화가 없으니까, 동일 컨테이너가 실행 중이면 추가 실행하지 않는다.
컨테이너의 리소스 파일이 바뀌면 추가 실행됨.
# 직접 yaml 파일 생성 후 실행
k apply -f miweb.yaml
cat > miweb.yaml
apiVersion: v1
kind: Pod
metadata:
name: miweb
spec:
containers:
- image: nginx:latest
name: miweb-container
ports:
- containerPort: 80
protocol: TCP
#정보 확인
kubectl get pod -o wide
해당 pod로 통신이 된다.
80 port listen도 확인이 됨.
하나의 pod에 두개의 container실행하기
#miweb2.yaml
apiVersion: v1
kind: Pod
metadata:
name: myweb2
spec:
containers:
- name: myweb2-nginx
image: nginx
ports:
- containerPort: 80 #Nginx는 80번 포트 사용
protocol: TCP
- name: myweb2-netshoot
image: nicolaka/netshoot #간단한 네트워크가 사용가능한 이미지
command: ["/bin/bash"]
args: ["-c", "while true; do sleep 5; curl localhost; done"] #5초마다 자신의 80 번 포트에 curl
해당 yaml파일로 Pod 실행 시, 요구 개수가 2개가된다.
k describe pod myweb2
describe로 확인해보면 두 개의 컨테이너가 확인된다.
컨테이너가 두 개여도 파드는 하나라서 ip는 하나이다.
이에 대해서는 아래에서 설명한다.
Pod IP로의 Curl은 누가 응답을 해줄까?
파드의 ip로 curl 요청을 보내면 정상적으로 응답이 온다.
이를 확인해보기 위해 컨테이너에 접속하자.
# netshoot에 zsh로 접속
k exec -it myweb2 -c myweb2-netshoot -- zsh
netshoot에서 Localhost로 curl해도 nginx가 응답한다.
netshoot이 명령어에 의해 계속 curl이 5초 후에 실행하여 log가 남고 있다.
netshoot 컨테이너의 ip는 pod의 ip와 같다.
Netshoot에서 확인해보면 자신의 80포트가 열려있다.
반면 프로세스를 확인하며 netshoot에서 동작하는 명령어만 동작하고 있다.
# Nginx 접속
k exec -it myweb2 -c myweb2-nginx -- /bin/bash
apt install net-tools 설치해서 ip를 확인해보면, 동일한 ip가 찍힌다.
Nginx도 80번 포트를 리스닝 중이다.
이러한 현상의 원인은 하나의 네트워크를 공유하도록 설정하는 리눅스의 네임스페이스와 Pause 컨테이너 때문이다.
Kubernetes Namespaces VS Linux Namespaces (Pause 컨테이너)
Pod Label
Pod 별로 label을 붙여보자.
cat > label.yaml
apiVersion: v1
kind: Pod
metadata:
name: myweb1
labels:
environment: production # key-value 형태로 라벨링
app: nginx
spec:
containers:
- image: nginx
name: myweb1
ports:
- containerPort: 80
protocol: TCP
---
apiVersion: v1
kind: Pod
metadata:
name: myweb2
labels:
environment: dev
app: nginx
spec:
containers:
- image: nginx
name: myweb2
ports:
- containerPort: 80
protocol: TCP
모니터링 하면서 Pod를 생성해 보자.
watch -d 'kubectl get pod -owide’ #pod의 상세정보 모니터링
실행 시, 파드 두개가 생성이 된다.
kubectl apply -f label.yaml
Pod들의 라벨링 확인
kubectl get pod --show-labels
특정 라벨만 확인
kubectl get pod -l environment=production
kubectl get pod -l app=nginx
이러한 태그 정보를 클라우드에서도 메타 데이터로 잘 활용해야 한다.
Label의 파드를 모두 지운다.
kubectl delete pod -l environment=production
파드에 붙여둔 라벨을 지우기
kubectl label pod myweb2 app-
(app=nginx 라벨이 제거된다.)
파드들을 생성하고 이후에 라벨을 붙이려면, 수백개의 파드에 일일이 라벨을 붙여야 할 수 있다.
따라서 미리 파드를 만들 때부터 라벨를 생각 해 둘수록, 이후에 효율적인 운영이 가능하다.
다른 실습을 위해 지워두자.
kubectl delete pod –all
NodeSelector
기본적으로는 스케줄러가 배치할 노드를 정해주지만, Node의 붙여두는 Label을 활용하면 파드를 원하는 노드에 넣을 수 있다.
이를 Node Selector 기능이라고 한다.
노드마다 다른 컴퓨팅 파워를 가지고 있을 수 있기 때문에, 특정 역할을 하는 파드는 적절한 노드에 배치할 때 사용할 수 있다. (예를 들면 머신러닝 파드는 고성능 GPU를 사용하는 노드로)
엔지니어는 충분히 자원을 활용하는 방법을 생각해야, 하고 그 중에 하나가 라벨을 붙여서 생성하는 것이다.
# Node의 라벨 보기
k get nodes --show-labels
마스터만 워커 노드와는 다른 레이블을 가지고 있다.
특정 워커 노드에 라벨 하나를 붙여주자.
#워커 노드1에 cloud=babo 라벨 붙여주기
kubectl label node k8s-w1 cloud=babo
cp label.yaml labels.yaml #사용하던 파일을 복사해서 필요한 부분만 바꾸자.
nano labels.yaml
#라벨로 특정 노드에 배치하기
실행해보면, Node w1에 생성이 되었다.
k apply -f labels.yaml
실제로 배치되는 것이 맞는지, 여러번 생성 해보자.
cat labels.yaml | sed "s/name: myweb/name: myweb2/g" | kubectl apply -f –
cat labels.yaml | sed "s/name: myweb/name: myweb3/g" | kubectl apply -f –
cat labels.yaml | sed "s/name: myweb/name: myweb4/g" | kubectl apply -f –
마스터 노드에는 중요한 파드들이 동작하는 만큼 오염방지 세팅이 있어서, 해제해야만 파드 생성 가능하다.
이제 지워주자.
kubectl delete pod –all
Pod 명령어 매개변수 설정
k run cmd-args --image nginx
Args는 원하는데로 생성 가능하다.
cat > cmd-args.yaml
apiVersion: v1
kind: Pod
metadata:
name: cmd-args
spec:
restartPolicy: OnFailure
containers:
- image: nginx
name: cmd-args-nginx
ports:
- containerPort: 80
protocol: TCP
command: ["/bin/echo"] # 커멘트 list
args: ["hello"] # 매개변수 세팅
# 설정된 매개변수 확인
k logs cmd-args
Pod 환경변수 세팅
cat > env.yaml
apiVersion: v1
kind: Pod
metadata:
name: mynginx
spec:
containers:
- image: nginx:latest
name: mynginx
ports:
- containerPort: 80
env:
- name: MYPASSWORD #환경 변수의 name
value: QWE123 #환경 변수의 value
pod의 환경변수를 넣어준다.
k exec mynginx -- env | grep MYPASSWORD
환경 변수는 보통 중요한 데이터를 담고 있는데, yaml 파일에 노출되는 것은 보안적인 문제가 있다.
따라서 secret map과 config map으로 민감 정보를 관리한다.
Pod Volume
삭제 시, 파드 내부의 데이터도 삭제된다.
필요한 데이터는 볼륨 디스트크를 공유시키자.
문제는 공유된 볼륨에 수정할 시, 공유 받는 모든 파드들이 문제가 발생 가능하다. 따라서 ReadOnly로 만들어 주어야 좋다.
# hostpath.yaml
cat > hostpath.yaml
apiVersion: v1
kind: Pod
metadata:
name: hostpath
spec:
containers:
- name: hostpath
image: busybox
args: [ "tail", "-f", "/dev/null" ]
volumeMounts: #볼륨 마운트 진행
- name: hostpath-volume
mountPath: /etc/data #컨테이너의 볼륨 path
volumes:
- name: hostpath-volume
hostPath:
path: /cloud #host path, 없으면 자동 생성
host의 w2 노드에 생성되었다.
따라서 파드가 생성된 쪽의 node를 확인해보면 볼륨이 생성된다.
마스터에서 kubectl로 컨테이너에게 파일 생성 명령을 내려보자.
kubectl exec hostpath -- touch /etc/data/babo.txt #-- cmd로 명령어 전달
w2 노드의 /cloud에 파일이 생성된 것이 확인된다.
'개발 > Kubernetes' 카테고리의 다른 글
Kubernetes Replicasets 사용하기 (label) (0) | 2024.03.04 |
---|---|
Kubernetes Pod 상태 체크, Probe, restartPolicy (0) | 2024.03.03 |
Kubernetes Kubectl 기본 명령어 정리 (0) | 2024.03.03 |
Kubernetes Namespaces VS Linux Namespaces (Pause 컨테이너) (0) | 2024.03.03 |
KubeSpary로 Kubernetes 설치하기 (0) | 2024.03.03 |