프로필사진

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 컨테이너)

 

Kubernetes Namespaces VS Linux Namespaces (Pause 컨테이너)

쿠버네티스 네임스페이스 네임스페이스는 쿠버네티스에서 용도에 따라서 리소스를 논리적으로 구분하기 위해 사용하는 오브젝트이다. 리눅스의 네임스페이스와 같은 이름이기 때문에 동일한

everenew.tistory.com

 

 

 

 

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 –

 

 

모두 w1 노드에 생긴다.

 

 

마스터 노드에는 중요한 파드들이 동작하는 만큼 오염방지 세팅이 있어서, 해제해야만 파드 생성 가능하다.

 

 

이제 지워주자.

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에 파일이 생성된 것이 확인된다.

 

반응형
댓글
반응형
인기글
Total
Today
Yesterday
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
글 보관함