[쿠버네티스] - kind 와 kubectl 을 이용해서 pod 생성

2024. 10. 29. 11:56현대 오토에버 SW 스쿨 - 클라우드/쿠버네티스

SMALL

1. Kind 와 Kubectl 을 설치

1) kind 

  • 쿠버네티스 클러스터를 간단하게 구성하기 위한 애플리케이션
  • 런타임이 docker
  • 하나의 컴퓨터에서 별도의 가상머신 없이도 여러 개의 노드 구성 가능

2) kubectl

  • 쿠버네티스 클러스터가 동작 중이면 중지
minikube stop
minikube delete -all
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"

curl -LO "https://dl.k8s.io/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl.sha256"

echo "$(cat kubectl.sha256)  kubectl" | sha256sum --check

sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl

kubectl version --client
[ $(uname -m) = x86_64 ] && curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.24.0/kind-linux-amd64
chmod +x ./kind
sudo mv ./kind /usr/local/bin/kind
  • 확인
  • 기본 클러스터 (Master 1개와 Worker 1개) 생성
    • kind create cluster
  • 클러스터 삭제 
    • kind delete cluster
  • 여러 개의 노드 생성
#yaml 파일 작성

	kind: Cluster
	apiVersion: kind.x-k8s.io/v1alpha4
	nodes:
			- role: control-plane
			- role: worker
			- role: worker
  • 클러스터 생성 
    • kind create cluster --config kind.yml
  • 클러스터 확인
    • docker ps
  • 하나의 Master Node 와 3개의 Worker Node 를 가진 클러스터를 위한 설정 파일 생성
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
- role: worker
- role: worker
- role: worker
  • 생성
    • kind create cluster --config kind-example-config.yml
  • 확인
    • kubectl get nodes

2. kubenetes 에서 linux 기본 요소 사용

1) 파드 실행을 위한 전제 조건

  • 쿠버네티스에서 사용하는 리눅스의 프로그램
  • swapoff : CPU 와 메모리 설정을 존중하는 방식
    • 쿠버네티스를 실행하기 위한 전제 조건인 memory swapping(docker 의 기본) 을 비활성화
    • memory swapping: 실제 메모리가 부족할 때 디스크 공간을 이요해 부족한 메모리를 대체할 수 있는 기술, 가상메모리
  • iptables: 네트워크 프록시에 대한 핵심 요구사항
    • pod 로 보내는 iptables 규칙을 생성
    • cluster -> iptables 생성 :: 파드이름 : 파드 ip형식 
  • mount : 경로의 특정 위치에 리소스를 연결, 디바이스를 홈 디렉터리에 디렉터리로 노출
  • systemd: 모든 컨테이너를 관리하기 위해 실행되는 핵심 프로세스인 kubelet 을 시작
  • nsenter: 네트워킹, 스토리지 또는 프로세스 측면에서 다양한 namespace 로 들어가 진행 상태를 확인할 수 있는 도구
  • unshare: 프로세스가 네트워크, 마운트 또는 PID 관점에서 격리되어 실행되는 하위 프로세스를 만들 수 있게 해주는 명령
  • ps : 실행 중인 프로그램을 나열하는 명령 -> kubelet 이 프로세스 실행/종료 를 계속 확인
  • 파드 생성 - yml 파일 생성
apiVersion: v1

kind: Pod

metadata:
  name: core-k8s
  labels:
    role: just-an-example
    app: my-example-app
    organization: friends-of-manning
    creator: adam

spec:
  containers:
    - name: any-lod-name-will-do
      image: docker.io/busybox:latest
      command: ['sleep', '10000']
      ports:
      - name: webapp-port
        containerPort: 80
        protocol: TCP
  • 파드 생성 : kubectl create -f pod.yml
  • 파드 제거 : kubectl delete pod core-k8s
  • 리눅스에서 현재 실행 중인 프로세스 개수 세기 : ps -ax | wc -l
    • pod 가 리눅스 내부적으로 프로세스로 실행되는 것 확인

리눅스에서 pod 가 생성되는 과정

  1. pod 생성 명령
  2. API server (etcd : 파드 생성)
  3. Scheduler : pod 를 어느 node 에 생성할 지 결정
  4. return api server : pod 를 생성되었다고 전달
  5. 실제 node 로 가서 파드를 생성함 (시간 걸림)
  6. but, return api server pod 를 생성하였다고 전달

=> create 와 delete 는 바로바로 진행되는 것이 아님

 

2) 의존성 탐색

  • pod 는 다음 관점에서 일반적인 프로그램
    • 키보드 입력, 파일 나열 등을 사용할 수 있게 해주는 공유 라이브러리, OS 에 특화된 저수준 유틸리티를 사용
    • 네트워크 호출이나 수신이 될 수 있도록 TCP/IP 스택의 구현과 함께 동작할 수 있는 클라이언트에 엑세스
    • 다른 프로그램이 자신의 메모리를 덮어쓰지 않도록 보장하기 위한 일정의 메모리 주소 공간이 필요
  • 파드 생성시 kubelet 이 수행하는 동작
    • 프로그램이 실행되기 위한 격리된 홈(CPU, Memory, Namespace 제한을 갖음)을 생성
    • 홈이 이더넷과 연결이 되는지 확인
    • DNS 를 확인 or 스토리지에 엑세스하기 위한 일부 기본 파일에 대한 엑세스 권한을 프로그램에 부여
    • 프로그램에게 다른 pod 로 이동해서 시작하는 것이 안전하다고 알려줌 -> 실제 pod 가 만들어지는 시점
    • 프로그램이 종료될 때까지 대기
    • 프로그램이 종료되면 사용한 공간과 자원을 정리
    • kubectl -> kubenetes -> kubelet -> linux 로 전달함
    • 리눅스는 플랫폼
  • kubelet 은 리눅스의 시스템 관리자의 역할
  • pod 에 대한 상세 정보 출력 : kubectl get pods -o yaml
  • 원하는 정보를 출력하고자 할 때 jsonpath 옵션을 이용
  • 파드 상태에 대한 쿼리
    • kubectl get pods -o=jsonpath='{.items[0].status.phase}'
  • 파드의 IP 주소 확인
    • kubectl get pods -o=jsonpath='{.items[0].status.podIP}'
  • 호스트 컴퓨터의 IP 주소 확인
    • kubectl get pods -o=jsonpath='{.items[0].status.hostIP}'
  • 파드에 마운트한 데이터 검사
    •  kubectl exec -it core-k8s -- sh
    • mount | grep resolv.conf
    • 수행 결과 : /dev/sda3 on /etc/resolv.conf type ext4 (rw,relatime,errors=remount-ro)
    • 실제 마운트 된 host computer 의 volume 을 의미
    • 실제로는 /var/lib/containerd 의 디렉터리에 위치한 내용 

3. 처음부터 Pod 만들기

1) chroot 를 사용해 격리 프로세스 생성

  • 기본적인 컨테이너는 bash shell 을 실행하는데 필요한 것 이외에 전현 다른 것이 없는 디렉터리
  • 과정
  1. 실행할 프로그램과 프로그램이 실행되어야 할 파일 시스템의 위치를 결정
  2. 프로세스가 실행할 환경을 만드는데 lib64 디렉터리에는 여러 리눅스 프로그램이 있음
  3. bash 와 같은 프로그램을 실행하기 위해 필요해 새로운 루트로 불러와야 함
  4. 실행하고 싶은 프로그램을 chroot 처리된 위치로 복사

2) 프로세스 데이터 제공: 볼륨 제공 기능

  • 컨테이너는 클라우드나 호스트 시스템과 같은 다른 곳에 있는 storage 를 엑세스
  • mount 명령을 수행 -> 디바이스를 OS 의 루트 디렉터리 아래에 있는 모든 디렉터리에 노출하는 것이 가능
  • kubernetes 에서 hostpath 를 이용한 볼륨 마운트 방식 -> 누구나 /tml 내용을 조작하거나 읽을 수 있음
  • 운영환경에서는 hostPath 기능이 종종 비활성화

3) unshare 를 이용한 프로세스 보안

  • chroot 를 이용 -> 격리된 프로세스 생성 가능
  • chroot 를 사용 -> 기본적으로 현재 쉘의 하위 프로세스로 만들어짐
  • 현재 실행한 쉘에서 프로세스를 죽임 -> 상위 프로세스에서는 하위 프로세스 kill 가능
  • 새로 실행되는 프로세스의 PID 를 1로 해서 다른 곳에 해당 프로세스를 kill 할 수 없도록 설정
  • unshare -p -f -mount-proc=/home/namespace/box/proc chroot /home/namespace/box /bin/bash
    • 해당 명령으로 생성된 프로세스는 자신의 PID 가 1 이라고 생각
    • 컨테이너 내부에서 exec 로 실행한 프로세스들은 자신의 하위 프로세스로 간주

4) Network namespace 생성

  • (chroot 로 실행한 것과 kubenetes 의 pod) 와 docker 의 container 의 차이점
    • chroot 와 unshare 명령으로 프로세스를 생성 시 모든 프로세스가 하나의 네트워크 (eth0) 가 생성
    • 하지만 다른 network 를 갖도록 프로세스를 만들고자 할 때는 unshare -p -f -n -mount-proc=/home/namespace/box/proc chroot /home/namespace/box /bin/bash 명령으로 프로세스를 실행
    • -n 옵션을 추가하면 eth0 하위에 훨씬 더 많은 동작중인 네트워크가 만들어 집니다.

5) cgroup 을 이용한 CPU 조정

  • container 를 만들 때
  • 리소스 제한을 두게 되면 linux 에서는 /sys/fs/cgroup/리소스이름/chroot 로 실행한 이름/여기에 제한된 자원에 대한 내용 이 설정

6) 실제 파드

  • 앞의 명령어들로 pod 와 유사한 프로세스를 만들 수 있지만 현실적으로 위의 기능만 가지고 pod 를 직접 생성하는 것은 어려움
  • 마이크로서비스는 다른 많은 서비스와 통신해야 할 수도 있고 해당 서비스에 새로운 인증서를 mount 해야 하기함
  • DNS 를 이용해서 다른 서비스를 탐색도 해야 함
  • 대규모 환경에서 마이크로서비스를 관리하기 위한 kubenetes 모델의 최대 장점은 내부 DNS 를 사용한다는 것 
  • 모든 쿠버네티스 컨테이너는 통신을 위해 다음 사항이 필요
  • 클러스터 내부나 pod - pod 연결을 위해 직접 라우팅 된 트래픽
  • 다른 pod 나 인터넷에 엑세스하기 위한 라우팅된 트래픽
  • 정적 IP 주소를 사용하는 서비스 뒤에 endpoint 역할을 위한 로드밸런싱된 트래픽
  • 위의 작업 허용을 위해 kubenetes 의 다른 부분에 게시되어야 하는 pod 의 메타데이터가 필요 : API Server 가 하는일임
  • 시간이 지나면서 상태가 업데이트되고 채우지도록 상태를 모니터링해야함 : kubelet 이 하는 일
  • pod 는 컨테이너 명령과 도커 이미지보다 많은 것을 설정
  • pod 는 상태가 게시되는 방법에 따라 label 과 spec 를 갖게 됨
  • pod 의 label 을 가지고 IP 주소와 DNS 규칙이 최신 상태로 유지되는것을 보장
  • iptables 를 이용한 kube-proxy 의 쿠버네티스 서비스 구현 방법
  • 서비스: IP 에 엑세스하면 여러 엔드포인트 중 서비스가 가능한 하나로 자동으로 전달시켜주는 객체
  • 실제 이러한 네트워킹 규칙은 iptables 프로그램을 사용해 저수준 네트워크 라우팅을 수행해주는 kube-proxy에 의해 완전하게 구현
  • 파드를 만들면 아래와 구문이 수행
    • iptables -A INPUT -s 파드의IP -j DROP
    • #들어오는 모든 트래픽을 폐기
  • 쿠버네티스에서는 위의 명령문 이외의 기능을 포함
  • 서비스 엔드포인트로 트래픽을 받아들이는 능력
  • 자체 엔드포인트에서 외부로 트래픽을 보내는 능력
  • 진행 중인 TCP 연결을 추적하는 능력
  • 파드를 생성할 때는 실제로 실행되고 라우팅이 가능한 소프트웨어 정의 네트워크(SDN)이 필요하기 때문에 파드를 재사용하지 않습니다.
  • Kube-dns
  • 특징
    • 어떤 쿠버네티스 클러스터에서도 사용 가능
    • 특별한 권한을 가지지 않으며 호스트 네트워크가 아닌 일반적인 pod 네트워크를 사용
    • 트래픽을 DNS 포트 표준으로 널리 알려진 53 번 포트로 전송
  • 기본적으로 어떤 트래픽도 받을 수 없음
  • 라우팅 규칙 확인 : ip route
  • 서비스를 만들면 서비스에 해당하는 트래픽을 전송 -> endpoint 로 전송하기 위해 라우팅 테이블  & DNS 에 pod 의 실제 위치를 매핑

4. pod 내 프로세스에서 cgroups 사용

1) 프로세스와 스레드

  • 쿠버네티스의 스케줄러의 PID 를 확인

2) pod 의 리소스 사용량 설정

  • yml 파일 생성
  • pod 생성 위치 확인
  • pod 생성 컴퓨터에 접속
  • 컨테이너에 접속
  • 자원 사용량 확인
  • 사용량을 설정하지 않은 경우 yml 파일 수정
    • pod 생성 및 접속 
    • 무한 작업 수행 명령
    • 다른 터미널에서 접속시
      • pod 가 생성된 노드 확인
      • 노드의 container ID 확인
      • docker 에 접속
      • 자원 사용량 확인
  • 리소스 사용량을 제한하지 않거나 제한을 하더라도 정수 단위로 설정하면 리소스 전체를 사용하는 일이 벌어질 수 있음
  • pod 의 리소스 확인

3) 쿠버네티스에서 스왑을 사용할 수 없는 이유

  • 메모리 스왑을 이용 -> 유후 프로세스에서 메모리 할당이 갑자기 느려질 수 있음
  • 성능이 심하게 가변적일 수 있음

4) HugePages

  • 쿠버네티스 초기에는 지원하지 않았던 개념
  • 쿠버네티스가 초창기에는 웹 중심 기술로 발전했기 때문에 페이지의 크기를 4KB 로 고정시켜 놓고 사용해도 아무런 문제 없었음
  • 최근들어 쿠버네티스를 데이터 센서 기술로 사용 -> 페이지의 크기 조정 필요
    • Elastic Search 나 Cassnadra 와 같은 데이터베이스를 쿠버네티스를 이용해서 배포하기 시작
  • 리소스 설정시 : hugepages-2Mi: 199Mi
  • 데이터 센터와 관련된 컨테이너를 만들 때는 매우 중요

5) 리눅스 커널 모니터링

  • 현실에서는 위와 같은 데이터를 수동을 curating 하지 않음
  • 일반적으로 시스템 매트릭과 전반적인 추세에 대해 컨테이너 시스템 레벨 OS 정보를 하나의 시계열 대시보드에 집계
  • -> 긴급 상황 발생 시 문제의 시간 범위 파악 -> 다양한 관점에서 문제 심층분석
  • 클라우드 native 애플리케이션 모니터링과 쿠버네티스 자체 모니터링을 위한 업계 표준인 프로메테우스를 많이 사용함
  • 프로메테우스 

장점

  1. 클러스터 오버런을 발생시킬 수 있는 쿠버네티스가 볼 수없는 은밀한 프로세스 확인 가능
  2. 클러스터가 OS 와 상호작용하는 방식의 버그를 발견할 수 있는 커널 수준의 격리 도구를 사용 -> 쿠버네티스가 인식하는 리소스에 직접 매핑 가능
  3. kubelet 과 컨테이너 런타임을 통해 대규모 환경에서 컨테이너의 구현방법을 자세하게 살펴볼 수 있는 도구

Metric(수량화 가능한 값) 유형

  1. gauge : 특정 시간에 초당 얼마나 많은 요청을 수신하는지 표시
  2. histogram: 다양한 유형의 이벤트를 시간 간격으로 표시
  3. counter: 지속적으로 증가하는 이벤트의 개수

 

반응형
LIST