웹사이트 검색

Kubernetes 클러스터의 핵심 구성요소


이 페이지에서

  1. Kubernetes 컨트롤 플레인\n
    1. kube-apiserver
    2. kube-controller-manager
    3. kube 스케줄러
    4. etcd 데이터베이스

    1. 쿠벨렛
    2. kube 프록시\n
    3. 컨테이너 런타임

    1. Pod – Kubernetes의 기반

    1. 볼륨
    2. 영구 볼륨, 영구 볼륨 클레임 및 스토리지 클래스

    Kubernetes는 선언적 구성 및 자동화를 용이하게 하는 컨테이너화된 워크로드 및 서비스를 관리하기 위한 오픈 소스 플랫폼입니다. Kubernetes라는 이름은 조타수 또는 조종사를 의미하는 그리스어에서 유래되었습니다. 이식 가능하고 확장 가능하며 빠르게 성장하는 생태계를 가지고 있습니다. Kubernetes의 서비스와 도구는 널리 사용 가능합니다.

    이 기사에서는 각 컨테이너가 구성되는 것부터 팟(Pod)의 컨테이너가 각 작업자에 걸쳐 배포되고 예약되는 방식에 이르기까지 주요 Kubernetes 구성 요소에 대한 10,000피트 뷰를 살펴보겠습니다. 컨테이너화된 애플리케이션을 위한 오케스트레이터로서 Kubernetes를 기반으로 하는 솔루션을 배포하고 설계할 수 있으려면 Kubernetes 클러스터의 전체 세부 사항을 이해하는 것이 중요합니다.

    다음은 이 기사에서 다룰 내용에 대한 간략한 설명입니다.

    • 제어판 구성요소
    • Kubernetes 작업자의 구성 요소
    • 기본 빌딩 블록으로서의 포드
    • Kubernetes 서비스, 로드 밸런서 및 인그레스 컨트롤러
    • Kubernetes 배포 및 데몬 세트
    • Kubernetes의 영구 스토리지

    쿠버네티스 컨트롤 플레인

    Kubernetes 마스터 노드는 핵심 제어 영역 서비스가 있는 곳입니다. 모든 서비스가 동일한 노드에 있어야 하는 것은 아닙니다. 그러나 중앙 집중화 및 실용성을 위해 이러한 방식으로 배포되는 경우가 많습니다. 이는 분명히 서비스 가용성 문제를 제기합니다. 그러나 여러 노드를 보유하고 가용성이 높은 마스터 노드 집합을 달성하기 위한 부하 분산 요청을 제공하여 쉽게 극복할 수 있습니다.

    마스터 노드는 다음 네 가지 기본 서비스로 구성됩니다.

    • kube-apiserver
    • kube 스케줄러
    • kube-controller-manager
    • etcd 데이터베이스

    마스터 노드는 베어메탈 서버, 가상 머신 또는 프라이빗 또는 퍼블릭 클라우드에서 실행할 수 있지만 컨테이너 워크로드를 실행하는 것은 권장되지 않습니다. 이에 대해서는 나중에 자세히 알아보겠습니다.

    다음 다이어그램은 Kubernetes 마스터 노드 구성요소를 보여줍니다.

    kube-apiserver

    API 서버는 모든 것을 하나로 묶는 것입니다. 서비스, 팟(Pod), Ingress 등과 같은 API 객체를 생성, 업데이트 및 삭제하기 위해 매니페스트를 수신하는 것은 클러스터의 프런트엔드 REST API입니다.

    kube-apiserver는 우리가 대화해야 하는 유일한 서비스입니다. 또한 클러스터 상태를 등록하기 위해 etcd 데이터베이스에 쓰고 통신하는 유일한 것입니다. kubectl 명령어를 사용하면 상호작용을 위한 명령어를 보낼 것입니다. 이것이 쿠버네티스와 관련하여 스위스 군용 칼이 될 것입니다.

    kube-컨트롤러-매니저

    간단히 말해서 kube-controller-manager 데몬은 단순성을 위해 단일 바이너리로 제공되는 무한 제어 루프 세트입니다. 클러스터의 정의된 원하는 상태를 감시하고 이를 달성하는 데 필요한 모든 비트와 조각을 이동하여 달성되고 만족되는지 확인합니다. kube-controller-manager는 단순한 컨트롤러가 아닙니다. 여기에는 클러스터의 여러 구성 요소를 감시하는 여러 루프가 포함되어 있습니다. 그 중 일부는 서비스 컨트롤러, 네임스페이스 컨트롤러, 서비스 계정 컨트롤러 등입니다. Kubernetes GitHub 리포지토리(https://github.com/kubernetes/kubernetes/tree/master/pkg/controller)에서 각 컨트롤러와 해당 정의를 찾을 수 있습니다.

    큐브 스케줄러

    kube-scheduler는 포드 리소스 요구 사항을 충족하기에 충분한 공간이 있는 노드에 새로 생성된 포드를 예약합니다. 기본적으로 kube-apiserver 및 kube-controller-manager에서 큐에 넣은 다음 스케줄러에 의해 사용 가능한 노드로 예약되는 새로 생성된 pod를 수신합니다. kube-scheduler 정의는 https://github.com/kubernetes/kubernetes/blob/master/pkg/scheduler에서 찾을 수 있습니다.

    컴퓨팅 리소스 외에도 kube-scheduler는 노드 선호도 및 반선호도 규칙을 읽어 노드가 해당 포드를 실행할 수 있는지 여부를 확인합니다.

    etcd 데이터베이스

    etcd 데이터베이스는 Kubernetes 클러스터의 상태를 저장하는 데 사용되는 매우 안정적인 일관된 키-값 저장소입니다. 여기에는 노드가 실행 중인 포드의 현재 상태, 클러스터에 현재 있는 노드 수, 해당 노드의 상태, 실행 중인 배포 복제본 수, 서비스 이름 등이 포함됩니다.

    앞에서 언급했듯이 kube-apiserver만이 etcd 데이터베이스와 통신합니다. kube-controller-manager가 클러스터의 상태를 확인해야 하는 경우 etcd 저장소에 직접 쿼리하는 대신 etcd 데이터베이스에서 상태를 가져오기 위해 API 서버를 통과합니다. 스케줄러가 포드가 중지되었거나 다른 노드에 할당되었음을 알려야 하는 경우 kube-scheduler에서도 마찬가지입니다. API 서버에 알리고 API 서버는 현재 상태를 etcd 데이터베이스에 저장합니다.

    etcd를 사용하여 Kubernetes 마스터 노드의 모든 주요 구성 요소를 다루었으므로 클러스터를 관리할 준비가 되었습니다. 그러나 클러스터는 마스터로만 구성되는 것이 아닙니다. 애플리케이션을 실행하여 무거운 작업을 수행할 노드가 여전히 필요합니다.

    Kubernetes 작업자 노드

    Kubernetes에서 이 작업을 수행하는 작업자 노드를 단순히 노드라고 합니다. 이전에는 2014년경에 Minions라고 불렸지만 나중에 이 용어는 Salts 용어와 혼동되고 사람들이 Salt가 Kubernetes에서 중요한 역할을 한다고 생각하게 하여 노드로만 대체되었습니다.

    이러한 노드는 전체 클러스터를 관리하는 데 사용할 수 있어야 하므로 마스터 노드에 컨테이너나 로드를 두는 것이 권장되지 않으므로 워크로드를 실행하는 유일한 위치입니다. 노드는 구성 요소 측면에서 매우 단순합니다. 작업을 수행하는 데 세 가지 서비스만 필요합니다.

    • 큐벨렛
    • Kube 프록시\n
    • 컨테이너 런타임

    이 세 가지 구성 요소를 조금 더 자세히 살펴보겠습니다.

    큐브렛

    kubelet은 하위 수준의 Kubernetes 구성요소이며 kube-apiserver 다음으로 가장 중요한 구성요소 중 하나입니다. 이 두 구성 요소는 모두 클러스터에서 포드/컨테이너를 프로비저닝하는 데 필수적입니다. kubelet은 Kubernetes 노드에서 실행되고 포드 생성을 위해 API 서버를 수신 대기하는 서비스입니다. kubelet은 포드의 컨테이너가 정상인지 확인하고 시작/중지하는 역할만 담당합니다. kubelet은 생성되지 않은 컨테이너를 관리할 수 없습니다.

    kubelet은 컨테이너 런타임 인터페이스(CRI)를 통해 컨테이너 런타임과 통신하여 목표를 달성합니다. CRI는 다른 컨테이너 런타임과 통신할 수 있는 gRPC 클라이언트를 통해 kubelet에 플러그 기능을 제공합니다. 앞서 언급했듯이 Kubernetes는 컨테이너를 배포하기 위해 여러 컨테이너 런타임을 지원하며 이것이 다양한 엔진에 대한 다양한 지원을 달성하는 방법입니다.

    https://github.com/kubernetes/kubernetes/tree/master/pkg/kubelet을 통해 kubelet의 소스 코드를 확인할 수 있습니다.

    큐브 프록시

    kube-proxy는 클러스터의 각 노드에 상주하는 서비스이며 pod, 컨테이너, 노드 간의 통신을 가능하게 하는 서비스입니다. 이 서비스는 kube-apiserver에서 정의된 서비스의 변경 사항을 감시하고(서비스는 Kubernetes에서 일종의 논리적 로드 밸런서입니다. 이 기사의 뒷부분에서 서비스에 대해 자세히 알아볼 것입니다.) 트래픽을 다음으로 전달하는 iptables 규칙을 통해 네트워크를 최신 상태로 유지합니다. 올바른 끝점. 또한 Kube-proxy는 서비스 뒤에 있는 pod 간에 임의 부하 분산을 수행하는 iptables에 규칙을 설정합니다.

    다음은 kube-proxy에서 만든 iptables 규칙의 예입니다.

    -A KUBE-SERVICES -d 10.0.162.61/32 -p tcp -m comment --comment \기본/예: 끝점 없음\ -m tcp --dport 80 -j REJECT --reject-with icmp-port - 도달 불가능

    이것은 엔드포인트가 없는 서비스입니다(뒤에 포드가 없음).

    컨테이너 런타임

    컨테이너를 가동하려면 컨테이너 런타임이 필요합니다. 포드가 실행되도록 노드 커널에 컨테이너를 생성하는 기본 엔진입니다. kubelet은 이 런타임과 통신하고 필요할 때 컨테이너를 가동하거나 중지합니다.

    현재 Kubernetes는 Docker, rkt, runc, runsc 등과 같은 모든 OCI 호환 컨테이너 런타임을 지원합니다.

    이 https://github.com/opencontainers/runtime-spec을 참조하여 OCI Git-Hub 페이지의 모든 사양에 대해 자세히 알아볼 수 있습니다.

    클러스터를 형성하는 모든 핵심 구성 요소를 살펴보았으므로 이제 이러한 구성 요소로 수행할 수 있는 작업과 Kubernetes가 컨테이너화된 애플리케이션을 오케스트레이션하고 관리하는 데 어떻게 도움이 되는지 살펴보겠습니다.

    쿠버네티스 개체

    Kubernetes 개체는 정확히 다음과 같습니다. 클러스터의 상태를 나타내는 논리적 영구 개체 또는 추상화입니다. 객체를 유지하고 객체가 존재하는지 확인할 수 있도록 해당 객체의 원하는 상태가 무엇인지 Kubernetes에 알리는 일을 담당하는 사람은 당신입니다.

    객체를 생성하려면 상태와 사양이라는 두 가지가 필요합니다. 상태는 Kubernetes에서 제공하며 개체의 현재 상태입니다. Kubernetes는 원하는 상태에 따라 필요에 따라 해당 상태를 관리하고 업데이트합니다. 반면 사양 필드는 Kubernetes에 제공하는 항목이며 원하는 객체를 설명하기 위해 알려주는 항목입니다. 예를 들어 컨테이너를 실행하려는 이미지, 실행하려는 해당 이미지의 컨테이너 수 등입니다.

    각 개체에는 수행하는 작업 유형에 대한 특정 사양 필드가 있으며 kubectl을 사용하여 kube-apiserver로 전송되는 YAML 파일에 이러한 사양을 제공하게 됩니다. kubectl은 이를 JSON으로 변환하고 API 요청으로 보냅니다. . 이 문서의 뒷부분에서 각 개체와 해당 사양 필드에 대해 자세히 알아볼 것입니다.

    다음은 kubectl로 전송된 YAML의 예입니다.

    고양이 << EOF | kubectl create -f -kind: ServiceapiVersion: v1metadata: 이름: frontend-servicespec: 선택기: 웹: 프런트엔드 포트: - 프로토콜: TCP 포트: 80 targetPort: 9256EOF

    객체 정의의 기본 필드는 맨 처음 필드이며 이러한 필드는 객체마다 다르지 않으며 매우 자명합니다. 간단히 살펴보겠습니다.

    • 종류: 종류 필드는 포드, 서비스, 배포 등 정의하는 객체 유형을 Kubernetes에 알려줍니다.\n
    • apiVersion: Kubernetes는 여러 API 버전을 지원하기 때문에 정의를 보낼 REST API 경로를 지정해야 합니다.\n
    • 메타데이터: 이것은 중첩된 필드입니다. 즉, 메타데이터에 여러 하위 필드가 더 있음을 의미합니다. 여기서 개체 이름과 같은 기본 정의를 작성하고 특정 네임스페이스에 할당하고 레이블에 태그를 지정합니다. 객체를 다른 Kubernetes 객체와 연결하기 위해\n

    이제 가장 많이 사용되는 필드와 그 내용을 살펴보았습니다. https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md에서 Kuberntes API 규칙에 대해 자세히 알아볼 수 있습니다.

    개체의 일부 필드는 개체가 생성된 후 나중에 수정할 수 있지만 수정하려는 개체 및 필드에 따라 달라집니다.

    다음은 생성할 수 있는 다양한 Kubernetes 개체의 짧은 목록입니다.

    • 포드
    • 볼륨
    • 서비스
    • 배포
    • 인그레스
    • 비밀
    • ConfigMap

    그리고 더 많은 것이 있습니다.

    이러한 각 항목을 자세히 살펴보겠습니다.

    포드 - Kubernetes의 기반

    포드는 쿠버네티스에서 가장 기본적인 객체이자 가장 중요한 객체입니다. 모든 것이 그들 주위를 돌고 있습니다. 쿠버네티스는 포드를 위한 것이라고 말할 수 있습니다! 다른 모든 개체는 이를 제공하기 위해 여기에 있으며 포드가 수행하는 모든 작업은 포드가 원하는 상태를 달성하도록 만드는 것입니다.

    그렇다면 포드는 무엇이며 포드가 왜 그렇게 중요한가요?

    포드는 동일한 네트워크 네임스페이스, 동일한 프로세스 간 통신(IPC), 경우에 따라 Kubernetes 버전에 따라 동일한 프로세스 ID(PID) 네임스페이스에서 하나 이상의 컨테이너를 함께 실행하는 논리적 개체입니다. 이는 그들이 우리 컨테이너를 실행할 것이기 때문에 관심의 중심이 될 것이기 때문입니다. Kubernetes의 요점은 컨테이너 오케스트레이터가 되는 것이며 포드를 사용하면 오케스트레이션이 가능합니다.

    이전에 언급한 바와 같이 동일한 포드의 컨테이너는 서로 로컬이므로 localhost를 통해 서로 통신할 수 있는 "버블"에 있습니다. 포드의 한 컨테이너는 네트워크 네임스페이스를 공유하기 때문에 다른 컨테이너와 동일한 IP 주소를 갖지만 대부분의 경우 일대일 기반, 즉 포드당 단일 컨테이너로 실행됩니다. . Pod당 여러 컨테이너는 기본 애플리케이션과 빠르고 탄력적인 방식으로 통신해야 하는 데이터 푸셔 또는 프록시와 같은 도우미가 애플리케이션에 필요한 경우와 같이 매우 특정한 시나리오에서만 사용됩니다.

    포드를 정의하는 방법은 모든 포드 사양 및 정의를 포함하는 YAML을 통해 다른 Kubernetes 개체에 대해 수행하는 것과 동일한 방식입니다.

    kind: PodapiVersion: v1metadata:name: hello-podlabels: hello: podspec: containers: - name: hello-container image: alpine args: - echo - \Hello World\

    포드를 만들기 위해 사양 필드 아래에 필요한 기본 포드 정의를 살펴보겠습니다.

    • 컨테이너: 컨테이너는 배열입니다. 따라서 그 아래에 여러 하위 필드 집합이 있습니다. 기본적으로 포드에서 실행될 컨테이너를 정의합니다. 컨테이너의 이름, 스핀 오프가 될 이미지, 실행에 필요한 인수 또는 명령을 지정할 수 있습니다. 인수와 명령의 차이점은 CMD와 ENTRYPOINT의 차이점과 동일합니다. 방금 살펴본 모든 필드는 컨테이너 배열에 대한 것입니다. 그것들은 팟(Pod) 사양의 직접적인 일부가 아닙니다.
    • restartPolicy: 이 필드는 정확히 다음과 같습니다. Kubernetes에 컨테이너로 수행할 작업을 알려주고 종료 코드가 0이거나 0이 아닌 경우 포드의 모든 컨테이너에 적용됩니다. Never, OnFailure 또는 Always 옵션 중에서 선택할 수 있습니다. restartPolicy가 정의되지 않은 경우 항상 기본값이 됩니다.\n

    이것은 포드에서 선언할 가장 기본적인 사양입니다. 다른 사양은 사용 방법 및 다양한 다른 Kubernetes 개체와 상호 작용하는 방법에 대한 배경 지식이 조금 더 필요합니다. 이 기사의 뒷부분에서 다시 살펴볼 것입니다. 그 중 일부는 다음과 같습니다.

    • 볼륨
    • 환경\n
    • 포트
    • dns정책
    • initContainers
    • 노드 선택기
    • 리소스 제한 및 요청\n

    클러스터에서 현재 실행 중인 포드를 보려면 kubectl get pods를 실행할 수 있습니다.

    [email :~$kubectl get podsNAME READY STATUS RESTARTS AGEbusybox 1/1 Running 120 5d

    또는 Pod를 지정하지 않고 kubectl describe pods를 실행할 수 있습니다. 그러면 클러스터에서 실행 중인 모든 포드에 대한 설명이 출력됩니다. 이 경우 현재 실행 중인 유일한 Pod이므로 busybox pod만 됩니다.

    [이메일 보호] : ~ $kubectl 설명 podsname : busyboxnamespace : defaultPriority : 0PriorityClassName : 노드 : AKS-AgentPool-10515745-2/10.240.0.6start 시간 : Wed, 19 Sep 2018 14:23:30- 0600LABELS : 주석 : 상태 : runningip : 10.244.1.7containers : busybox : [...] (가독성을 위해 잘린 출력) 이벤트 : 메시지에서 나이를 입력하십시오 ------------ --- ---- -------Normal Pulled 45s(x121 over 5d) kubelet, aks-agentpool-10515745-2 컨테이너 이미지 \busybox\가 machineNormal에 이미 있음 44s 생성됨(x121 over 5d) kubelet , aks-agentpool-10515745-2 생성된 containerNormal 시작 44초(x121 over 5d) kubelet, aks-agentpool-10515745-2 시작 컨테이너

    포드는 치명적입니다. 죽거나 삭제되면 복구할 수 없습니다. 해당 IP와 실행 중이던 컨테이너는 사라질 것입니다. 그들은 완전히 일시적입니다. 볼륨으로 마운트된 팟(Pod)의 데이터는 설정 방법에 따라 존속할 수도 있고 존속하지 못할 수도 있습니다. 포드가 죽고 손실되면 모든 마이크로 서비스가 실행 중인지 어떻게 확인할 수 있습니까? 글쎄요, 배포가 답입니다.

    배포

    단일 포드에서 실행되는 애플리케이션의 인스턴스를 두 개 이상 갖는 것이 그다지 효율적이지 않기 때문에 포드 자체는 그다지 유용하지 않습니다. 서로 다른 팟(Pod)에 수백 개의 애플리케이션 사본을 모두 찾을 수 있는 방법 없이 프로비저닝하면 정말 빨리 손을 댈 수 없게 됩니다.

    여기에서 배포가 시작됩니다. 배포를 통해 컨트롤러로 포드를 관리할 수 있습니다. 이를 통해 실행하려는 개수를 결정할 수 있을 뿐만 아니라 컨테이너가 실행 중인 이미지 버전이나 이미지 자체를 변경하여 업데이트를 관리할 수도 있습니다. 배포는 대부분의 시간 동안 작업하게 될 것입니다. 앞에서 언급한 포드 및 기타 개체뿐만 아니라 배포를 사용하면 YAML 파일 내에 자체 정의가 있습니다.

    apiVersion: apps/v1kind: Deploymentmetadata: name: nginx-deployment labels: deployment: nginxspec: replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image : nginx:1.7.9 포트: - 컨테이너 포트: 80

    그들의 정의를 탐구하기 시작하자.

    YAML 시작 부분에는 apiVersion, 종류, 메타데이터와 같은 보다 일반적인 필드가 있습니다. 하지만 사양에서 이 API 개체에 대한 특정 옵션을 찾을 수 있습니다.

    사양에서 다음 필드를 추가할 수 있습니다.

    선택기: 선택기 필드를 사용하면 배포에서 변경 사항이 적용될 때 대상으로 지정할 포드를 알 수 있습니다. 선택기 아래에 matchLabels 및 matchExpressions라는 두 개의 필드를 사용할 수 있습니다. matchLabels를 사용하면 선택기가 포드의 라벨(키-값 쌍)을 사용합니다. 여기서 지정하는 모든 라벨은 AND 처리됩니다. 즉, 광고 모음에는 matchLabels에서 지정하는 모든 라벨이 있어야 합니다.

    복제본: 복제 컨트롤러를 통해 배포를 계속 실행해야 하는 포드 수를 명시합니다. 예를 들어 3개의 복제본을 지정하고 포드 중 하나가 죽으면 복제 컨트롤러는 복제본 사양을 원하는 상태로 보고 스케줄러에게 새 포드를 예약하도록 알립니다. 현재 상태는 포드가 죽은 이후 2입니다.

    RevisionHistoryLimit: 배포를 변경할 때마다 이 변경 사항은 배포 개정으로 저장되며 나중에 이전 상태로 되돌리거나 변경된 내용을 기록할 수 있습니다. kubectl rollout history deployment/<배포 이름>으로 기록을 참조할 수 있습니다. revisionHistoryLimit를 사용하면 저장하려는 레코드 수를 나타내는 숫자를 설정할 수 있습니다.

    전략: 이를 통해 업데이트 또는 수평 포드 확장을 처리할 방법을 결정할 수 있습니다. 기본값인 rollingUpdate를 덮어쓰려면 유형 키를 작성해야 합니다. 여기에서 recreate 또는 rollingUpdate의 두 값 중에서 선택할 수 있습니다.

    다시 만들기는 배포를 업데이트하는 빠른 방법이지만 모든 포드를 삭제하고 새 포드로 교체하지만 이러한 유형의 전략에는 시스템 다운타임이 있을 것임을 고려해야 합니다. 반면에 rollingUpdate는 더 매끄럽고 느리며 데이터를 재조정할 수 있는 상태 저장 애플리케이션에 이상적입니다. rollingUpdate는 maxSurge 및 maxUnavailable이라는 두 개의 필드를 추가로 엽니다.

    첫 번째는 업데이트를 수행할 때 원하는 총량보다 많은 팟(Pod) 수입니다. 예를 들어 포드가 100개이고 maxSurge가 20%인 배포는 업데이트하는 동안 포드가 최대 120개까지 증가합니다. 다음 옵션을 사용하면 100개의 포드 시나리오에서 새 포드로 교체하기 위해 기꺼이 죽이려는 포드의 수를 백분율로 선택할 수 있습니다. maxUnavailable이 20%인 경우 포드 20개만 종료되고 나머지 배포를 계속 교체하기 전에 새 포드로 교체됩니다.

    템플릿: 배포에서 관리할 포드의 모든 사양과 메타데이터를 포함하는 중첩된 포드 사양 필드입니다.

    우리는 배포를 통해 포드를 관리하고 포드를 통해 원하는 상태로 유지할 수 있음을 확인했습니다. 이 모든 pod는 여전히 클러스터 네트워크라는 곳에 있습니다. 클러스터 네트워크는 Kubernetes 클러스터 구성요소만 서로 통신할 수 있고 고유한 IP 범위 집합이 있는 폐쇄형 네트워크입니다. 외부에서 포드와 어떻게 대화합니까? 신청서에 어떻게 도달합니까? 여기서 서비스가 시작됩니다.

    서비스:

    이름 서비스는 실제로 Kubernetes에서 수행하는 서비스를 완전히 설명하지 않습니다. Kubernetes 서비스는 트래픽을 포드로 라우팅합니다. 서비스는 팟(Pod)을 하나로 묶는 것이라고 말할 수 있습니다.

    프런트엔드 포드가 포드의 IP 주소를 통해 백엔드 포드와 통신하는 일반적인 프런트엔드/백엔드 유형의 애플리케이션이 있다고 상상해 봅시다. 백엔드의 포드가 죽으면 백엔드와의 통신이 끊어집니다. 새 팟이 죽은 팟과 동일한 IP 주소를 가지지 않을 뿐만 아니라 이제 새 IP 주소를 사용하도록 앱을 재구성해야 하기 때문입니다. 이 문제 및 유사한 문제는 서비스로 해결됩니다.

    서비스는 서비스 뒤에 있는 포드를 기반으로 iptables 규칙을 생성하도록 kube-proxy에 지시하는 논리적 객체입니다. 서비스는 서비스 뒤의 포드가 호출되는 방식인 엔드포인트를 구성합니다. 이는 배포에서 제어할 포드, 선택기 필드, 포드 레이블을 아는 것과 같은 방식입니다.

    이 다이어그램은 서비스에서 라벨을 사용하여 트래픽을 관리하는 방법을 보여줍니다.

    서비스는 kube-proxy가 트래픽을 라우팅하는 규칙을 생성하도록 할 뿐만 아니라; 또한 kube-dns라는 것을 트리거합니다.

    Kube-dns는 DNS 서버 및 전달자를 제공하는 클러스터에서 실행되는 SkyDNS 컨테이너가 포함된 pod 집합으로, 서비스에 대한 레코드를 생성하고 경우에 따라 사용 편의성을 위한 pod도 생성합니다. 서비스를 만들 때마다 서비스 내부 클러스터 IP 주소를 가리키는 DNS 레코드가 service-name.namespace.svc.cluster.local 형식으로 생성됩니다. Kubernetes DNS 사양에 대한 자세한 내용은 https://github.com/kubernetes/dns/blob/master/docs/specification.md에서 확인할 수 있습니다.

    예시로 돌아가서 이제 백엔드 포드와 통신하기 위해 서비스 FQDN(정규화된 도메인 이름)과 통신하도록 애플리케이션을 구성하기만 하면 됩니다. 이렇게 하면 포드와 서비스의 IP 주소는 중요하지 않습니다. 서비스 뒤의 포드가 죽으면 서비스는 A 레코드를 사용하여 모든 것을 처리합니다. 프런트엔드에 모든 트래픽을 my-svc로 라우팅하도록 지시할 수 있기 때문입니다. 서비스의 논리는 다른 모든 것을 처리합니다.

    Kubernetes에서 생성할 객체를 선언할 때마다 생성할 수 있는 여러 유형의 서비스가 있습니다. 필요한 작업 유형에 가장 적합한 것이 무엇인지 살펴보겠습니다.

    ClusterIP: 기본 서비스입니다. ClusterIP 서비스를 생성할 때마다 Kubernetes 클러스터 내에서만 라우팅할 수 있는 클러스터 내부 IP 주소로 서비스를 생성합니다. 이 유형은 클러스터 외부로 나가지 않고 서로 대화만 하면 되는 팟(Pod)에 이상적입니다.

    NodePort: 이 유형의 서비스를 생성하면 기본적으로 30000에서 32767까지 임의의 포트가 할당되어 트래픽을 서비스의 엔드포인트 포드로 전달합니다. 포트 배열에서 노드 포트를 지정하여 이 동작을 재정의할 수 있습니다. 이것이 정의되면 :를 통해 포드에 액세스할 수 있습니다. 이는 노드 IP 주소를 통해 클러스터 외부에서 포드에 액세스하는 데 유용합니다.

    LoadBalancer: 대부분의 경우 클라우드 공급자에서 Kubernetes를 실행하게 됩니다. LoadBalancer 유형은 클라우드 공급자 API를 통해 공용 IP 주소를 서비스에 할당할 수 있으므로 이러한 상황에 이상적입니다. 클러스터 외부에서 Pod와 통신하려는 경우에 이상적인 서비스입니다. LoadBalancer를 사용하면 공용 IP 주소를 할당할 수 있을 뿐만 아니라 Azure를 사용하여 가상 사설망에서 개인 IP 주소를 할당할 수도 있습니다. 따라서 인터넷에서 또는 프라이빗 서브넷에서 내부적으로 포드와 통신할 수 있습니다.

    서비스에 대한 YAML의 정의를 검토해 보겠습니다.

    apiVersion: v1kind: Servicemetadata: 이름: my-servicespec: 선택기: 앱: 프런트 엔드 유형: NodePort 포트: - 이름: http 포트: 80 targetPort: 8080 nodePort: 30024 프로토콜: TCP

    서비스 YAML은 매우 간단하며 생성하는 서비스 유형에 따라 사양이 달라집니다. 그러나 고려해야 할 가장 중요한 것은 포트 정의입니다. 다음을 살펴보겠습니다.

    • port: 노출되는 서비스 포트입니다.
    • targetPort: 서비스가 트래픽을 보내는 포드의 포트입니다.\n
    • nodePort: 노출될 포트입니다.

    이제 클러스터의 포드와 통신하는 방법을 이해했지만 포드가 종료될 때마다 데이터 손실 문제를 관리하는 방법을 여전히 이해해야 합니다. 여기에서 영구 볼륨(PV)이 사용됩니다.

    Kubernetes 및 영구 스토리지

    컨테이너 세계의 영구 스토리지는 심각한 문제입니다. 컨테이너 실행 전체에서 지속되는 유일한 스토리지는 이미지 레이어이며 읽기 전용입니다. 컨테이너가 실행되는 계층은 읽기/쓰기가 가능하지만 컨테이너가 중지되면 이 계층의 모든 데이터가 삭제됩니다. 포드의 경우에도 마찬가지입니다. 컨테이너가 죽으면 여기에 기록된 데이터가 사라집니다.

    Kubernetes에는 팟(Pod)에서 스토리지를 처리하는 오브젝트 세트가 있습니다. 첫 번째로 논의할 것은 볼륨입니다.

    볼륨

    볼륨은 영구 스토리지와 관련하여 가장 큰 문제 중 하나를 해결합니다. 우선, 볼륨은 실제로 객체가 아니라 포드 사양의 정의입니다. 포드를 생성할 때 포드 사양 필드에서 볼륨을 정의할 수 있습니다. 이 팟(Pod)의 컨테이너는 마운트 네임스페이스에 볼륨을 마운트할 수 있으며 컨테이너 재시작 또는 충돌 시 볼륨을 사용할 수 있습니다. 그러나 볼륨은 포드에 연결되어 있으며 포드가 삭제되면 볼륨도 함께 사라집니다. 볼륨의 데이터는 또 다른 이야기입니다. 데이터 지속성은 해당 볼륨의 백엔드에 따라 다릅니다.

    Kubernetes는 여러 유형의 볼륨 또는 볼륨 소스를 지원하고 로컬 노드의 파일 시스템 맵, 클라우드 공급자 가상 디스크 및 소프트웨어 정의 스토리지 지원 볼륨에 이르는 API 사양에서 호출하는 방법을 지원합니다. 로컬 파일 시스템 마운트는 일반 볼륨과 관련하여 가장 일반적으로 볼 수 있는 마운트입니다. 로컬 노드 파일 시스템 사용의 단점은 클러스터의 모든 노드에서 데이터를 사용할 수 없고 포드가 예약된 해당 노드에서만 사용할 수 있다는 점입니다.

    볼륨이 있는 포드가 YAML에서 어떻게 정의되는지 살펴보겠습니다.

    apiVersion: v1kind: Podmetadata: 이름: test-pdspec: 컨테이너: - 이미지: k8s.gcr.io/test-webserver 이름: 테스트 컨테이너 volumeMounts: - 마운트 경로: /test-pd 이름: 테스트 볼륨 볼륨: - 이름: 테스트 볼륨 hostPath: 경로: /data 유형: 디렉터리

    사양에 따라 볼륨이라는 필드가 있고 볼륨마운트라는 또 다른 필드가 있다는 점에 유의하세요.

    첫 번째 필드(볼륨)는 해당 포드에 대해 생성하려는 볼륨을 정의하는 곳입니다. 이 필드에는 항상 이름과 볼륨 소스가 필요합니다. 소스에 따라 요구 사항이 달라집니다. 이 예에서 소스는 노드 로컬 파일 시스템인 hostPath입니다. hostPath는 디렉토리, 파일, 블록 기기, Unix 소켓에 이르기까지 여러 유형의 매핑을 지원합니다.

    두 번째 필드인 volumeMounts에는 볼륨을 마운트하려는 컨테이너 내부의 경로를 정의하는 mountPath가 있습니다. 이름 매개변수는 사용할 볼륨을 포드에 지정하는 방법입니다. 이는 볼륨 아래에 여러 유형의 볼륨을 정의할 수 있고 포드가 어떤 유형인지 알 수 있는 유일한 방법은 이름이기 때문에 중요합니다.

    https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.11/#volume-v1-core에서 다양한 유형의 볼륨에 대해 자세히 알아볼 수 있습니다.

    포드와 함께 볼륨이 죽는 것은 이상적이지 않습니다. 우리는 지속되는 스토리지가 필요하며 이것이 PV의 필요성이 된 이유입니다.

    영구 볼륨, 영구 볼륨 클레임 및 스토리지 클래스

    볼륨과 PV의 주요 차이점은 볼륨과 달리 PV는 실제로 Kubernetes API 객체이므로 별도의 항목처럼 개별적으로 관리할 수 있으므로 포드가 삭제된 후에도 지속된다는 것입니다.

    이 하위 섹션에 PV, PVC(영구 볼륨 클레임) 및 스토리지 클래스가 모두 혼합되어 있는 이유가 궁금할 수 있습니다. 이는 모두 서로 의존하기 때문이며 스토리지 프로비저닝을 위해 서로 상호 작용하는 방식을 이해하는 것이 중요합니다. 우리 포드를 위해.

    PV와 PVC부터 시작하겠습니다. 볼륨과 마찬가지로 PV에는 스토리지 소스가 있으므로 볼륨과 동일한 메커니즘이 여기에 적용됩니다. 논리 단위 번호(LUN)를 제공하는 소프트웨어 정의 스토리지 클러스터, 가상 디스크를 제공하는 클라우드 제공업체 또는 Kubernetes 노드에 대한 로컬 파일 시스템이 있지만 여기서는 볼륨 소스라고 하는 대신 영구라고 합니다. 대신 볼륨 유형

    PV는 스토리지 어레이의 LUN과 매우 유사합니다. 생성하지만 매핑은 없습니다. 그것들은 사용되기를 기다리는 할당된 저장 공간일 뿐입니다. PVC는 LUN 매핑과 같습니다. PVC는 PV에 백업되거나 바인딩되며 컨테이너에 사용할 수 있도록 포드에서 실제로 정의하고 연결하고 사용할 수 있게 만드는 것입니다.

    포드에서 PVC를 사용하는 방식은 일반 볼륨과 완전히 동일합니다. 두 개의 필드가 있습니다. 하나는 사용할 PVC를 지정하는 필드이고 다른 하나는 해당 PVC를 사용할 컨테이너를 포드에 알리는 필드입니다.

    PVC API 개체 정의의 YAML에는 다음 코드가 있어야 합니다.

    apiVersion: v1kind: PersistentVolumeClaimmetadata: 이름: gluster-pvc 사양: accessModes: - ReadWriteMany 리소스: 요청: 스토리지: 1Gi

    포드용 YAML에는 다음 코드가 있어야 합니다.

    종류: PodapiVersion: v1metadata: 이름: mypodspec: 컨테이너: - 이름: myfrontend 이미지: nginx volumeMounts: - mountPath: \/mnt/gluster\ 이름: 볼륨 볼륨: - 이름: 볼륨 persistVolumeClaim: claimName: gluster-pvc

    Kubernetes 관리자가 PVC를 생성할 때 이 요청이 충족되는 두 가지 방법이 있습니다.

    • 정적: 여러 PV가 이미 생성되었으며 사용자가 PVC를 생성하면 요구 사항을 충족할 수 있는 모든 사용 가능한 PV가 해당 PVC에 바인딩됩니다.\n
    • 동적: 일부 PV 유형은 PVC 정의를 기반으로 PV를 생성할 수 있습니다. PVC가 생성되면 PV 유형은 동적으로 PV 객체를 생성하고 백엔드에 스토리지를 할당합니다. 이것이 동적 프로비저닝입니다. 동적 프로비저닝의 문제는 스토리지 클래스라고 하는 세 번째 유형의 Kubernetes 스토리지 객체가 필요하다는 것입니다.\n

    저장소 클래스는 저장소를 계층화하는 방법과 같습니다. 느린 스토리지 볼륨을 프로비저닝하는 클래스 또는 초고속 SSD 드라이브가 있는 클래스를 만들 수 있습니다. 그러나 스토리지 클래스는 단순한 계층화보다 약간 더 복잡합니다. PVC를 생성하는 두 가지 방법에서 언급했듯이 스토리지 클래스는 동적 프로비저닝을 가능하게 합니다. 클라우드 환경에서 작업할 때 모든 PV에 대해 모든 백엔드 디스크를 수동으로 생성하고 싶지는 않습니다. 스토리지 클래스는 클라우드 공급자 API와 통신하는 데 필요한 볼륨 플러그인을 호출하는 프로비저닝 도구를 설정합니다. 모든 프로비저너에는 지정된 클라우드 공급자 또는 스토리지 공급자와 통신할 수 있도록 고유한 설정이 있습니다.

    다음과 같은 방법으로 스토리지 클래스를 프로비저닝할 수 있습니다. Azure-disk를 디스크 프로비저너로 사용하는 스토리지 클래스의 예입니다.

    종류: StorageClassapiVersion: storage.k8s.io/v1metadata: 이름: my-storage-classprovisioner: kubernetes.io/azure-diskparameters: storageaccounttype: Standard_LRS 종류: Shared

    각 스토리지 클래스 프로비저너 및 PV 유형에는 볼륨뿐만 아니라 요구 사항과 매개변수가 다르며 작동 방식과 용도에 대한 일반적인 개요가 이미 있습니다. 특정 스토리지 클래스 및 PV 유형에 대한 학습은 환경에 따라 다릅니다. 다음 링크를 클릭하면 각각에 대해 자세히 알아볼 수 있습니다.

    • https://kubernetes.io/docs/concepts/storage/storage-classes/#provisioner
    • https://kubernetes.io/docs/concepts/storage/persistent-volumes/#types-of-persistent-volumes

    이 기사에서는 쿠버네티스가 무엇인지, 그 구성요소, 오케스트레이션을 사용하면 어떤 이점이 있는지 알아보았습니다. 이를 통해 각 Kubernetes API 객체, 목적 및 사용 사례를 쉽게 식별할 수 있습니다. 이제 마스터 노드가 클러스터를 제어하는 방법과 작업자 노드의 컨테이너 스케줄링을 이해할 수 있어야 합니다.

    이 기사가 유용했다면 '건축가를 위한 Linux 실습'이 도움이 될 것입니다. 이 책에서는 Linux 구성 요소 및 기능에서 하드웨어 및 소프트웨어 지원에 이르기까지 모든 것을 다루며 효과적인 Linux 기반 솔루션을 구현하고 조정하는 데 도움이 됩니다. Linux 설계 방법론과 솔루션 설계의 핵심 개념에 대한 개요를 살펴봅니다. Linux 시스템 관리자, Linux 지원 엔지니어, DevOps 엔지니어, Linux 컨설턴트 또는 아키텍처 관련 지식을 배우거나 확장하려는 사람이라면 이 책이 적합합니다.