ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Kubernetes] 레이블과 셀렉터
    공부/데이터 2023. 3. 5. 12:22

    레이블

    레이블은 파드와 같은 오브젝트에 첨부된 키-값 쌍으로, 오브젝트의 특성을 식별하는 데 사용됩니다. 이는 사용자에게 중요하지만, 코어 시스템에 직접적인 의미는 없습니다. 레이블은 오브젝트의 하위 집합을 선택하고 구성하는 데 사용될 수 있습니다. 레이블은 오브젝트 생성 또는 생성 이후에 붙일 수 있으며, 각 오브젝트마다 키와 값으로 정의할 수 있습니다. Kubernetes에서는 리소스에 레이블(Label)을 달아, 리소스에 대한 여러 가지 정보를 기반으로 선택하거나 그룹화할 수 있습니다.

    "metadata": {
      "labels": {
        "key1" : "value1",
        "key2" : "value2"
      }
    }

    레이블은 UI와 CLI에서 쿼리 및 검색에 효율적이며, 식별되지 않는 정보는 어노테이션으로 기록해야 합니다.

    사용 동기

    레이블을 사용하면 조직 구조와 시스템 오브젝트를 느슨하게 결합한 상태로 매핑할 수 있고, 매핑 정보를 클라이언트에 저장할 필요가 없습니다.

    서비스 배포와 배치 프로세싱 파이프라인은 다차원적인 엔티티입니다(예: 다중 파티션 또는 배포, 다중 릴리스 트랙, 다중 계층, 계층 속 여러 마이크로 서비스들). 관리에는 크로스-커팅 작업이 필요한 경우가 많은데, 이 작업은 사용자보다는 인프라에 의해 결정된 엄격한 계층 표현인 캡슐화를 깨트리게 됩니다.

    레이블 예시:

    • "release" : "stable", "release" : "canary"
    • "environment" : "dev", "environment" : "qa", "environment" : "production"
    • "tier" : "frontend", "tier" : "backend", "tier" : "cache"
    • "partition" : "customerA", "partition" : "customerB"
    • "track" : "daily", "track" : "weekly"

    이 예시는 일반적인 레이블이며, 사용자는 자신만의 규칙에 따라 개발할 수 있습니다. 오브젝트에 붙은 레이블 키는 고유해야 합니다.

    구문과 캐릭터 셋

    레이블은 키와 값의 쌍입니다. 유효한 레이블 키는 선택한 접두사와 이름으로 구성되며, 접두사와 이름은 슬래시(/)로 구분됩니다. 이름은 63자 미만으로, 알파벳과 숫자([a-z0-9A-Z])로 시작하고 끝나며, 대시(-), 밑줄(_), 점(.)과 함께 사용할 수 있습니다. 접두사는 선택 사항입니다. 접두사를 지정한 경우, 접두사는 DNS의 하위 도메인이어야 하며, 점(.)과 전체 253자 이하의 슬래시(/)로 구분된 DNS 레이블이어야 합니다.

    접두사를 생략하면 키 레이블은 개인용으로 간주됩니다. 따라서 최종 사용자의 오브젝트에 자동화된 시스템 컴포넌트(예: kube-scheduler, kube-controller-manager, kube-apiserver, kubectl 또는 다른 타사의 자동화 구성 요소)의 접두사를 지정해야 합니다.

    kubernetes.io/k8s.io/ 접두사는 쿠버네티스의 핵심 컴포넌트로 예약되어 있습니다.

    유효한 레이블 값은 다음과 같습니다.

    • 63자 이하 (공백일 수도 있음)
    • (공백이 아니라면) 시작과 끝은 알파벳과 숫자([a-z0-9A-Z])
    • 중간에는 알파벳과 숫자, 대시(``), 밑줄(_), 점(.) 가능

    아래는 파드에 environment: production 과 app: nginx 2개의 레이블이 있는 구성 파일 레이블의 예시입니다.

    apiVersion: v1
    kind: Pod
    metadata:
      name: label-demo
      labels:
        environment: production
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80

    여러 개의 Pod을 관리하는 Replication Controller가 있다고 가정할 때, 각각의 Pod에 app: my-app이라는 레이블에 같은 값을 부여함으로써, Replication Controller는 이 레이블을 기반으로 Pod을 관리할 수 있는 예시입니다.

    apiVersion: v1
    kind: Pod
    metadata:
      name: my-pod
      labels:
        app: my-app
    spec:
      containers:
      - name: my-container
        image: nginx
        ports:
        - containerPort: 80
    

    셀렉터

    리소스의 선택을 가능하게하는 셀렉터(Selector)는 레이블로 표시된 리소스를 기반으로 선택할 수 있게합니다. 셀렉터는 레이블 쿼리에 대한 key-value 쌍을 지정하여 해당 리소스를 선택합니다. 이름과 UID와 달리 레이블은 고유하지 않습니다. 일반적으로 많은 오브젝트가 동일한 레이블을 가질 것으로 예상됩니다. 셀렉터를 사용하면 클라이언트와 사용자는 오브젝트를 식별할 수 있습니다.

    API는 현재 일치성 기준과 집합성 기준이라는 두 종류의 셀렉터를 지원하며, 셀렉터는 쉼표로 구분된 다양한 요구사항에 따라 만들 수 있습니다. 다양한 요구사항이 있는 경우 쉼표 기호가 AND(&&) 연산자로 구분되는 역할을 합니다. 비어 있거나 지정되지 않은 셀렉터는 상황에 따라 다릅니다. 셀렉터를 사용하는 API 유형은 유효성과 의미를 문서화해야 합니다.

    일치성 기준 요건

    일치성 기준 또는 불일치 기준 요구사항으로 레이블의 키와 값의 필터링을 허용하며, 일치하는 오브젝트는 추가 레이블을 가질 수 있습니다. 연산자는 =,==,!=만 가능하며, 처음 두 개의 연산자는 일치성(그리고 동의어), 나머지는 불일치를 의미합니다.

    environment = production
    tier != frontend

    전자는 environment를 키로 가지는 모든 리소스 중 production 값을 선택하며, 후자는 tier를 키로 가지는 리소스 중 frontend이 아닌 모든 리소스와 공백 값을 가지는 리소스를 선택합니다. environment=production,tier!=frontend와 같이 쉼표를 사용하여 frontend를 제외한 production을 필터링할 수 있습니다.

    파드가 노드를 선택하는 기준을 지정하는 것은 일치성 기준 레이블 요건의 하나의 사용 시나리오입니다.

    파드는 "accelerator=nvidia-tesla-p100" 레이블을 가진 노드를 선택하는 예시입니다.

    apiVersion: v1
    kind: Pod
    metadata:
      name: cuda-test
    spec:
      containers:
        - name: cuda-test
          image: "registry.k8s.io/cuda-vector-add:v0.1"
          resources:
            limits:
              nvidia.com/gpu: 1
      nodeSelector:
        accelerator: nvidia-tesla-p100

    또 다른 예시로 앞서 생성한 app: my-app 레이블이 부여된 Pod 중에서, app: my-app 레이블을 가진 Pod 하나를 선택하려면, 다음과 같은 셀렉터를 사용할 수 있습니다.

    apiVersion: v1
    kind: ReplicationController
    metadata:
      name: my-controller
    spec:
      replicas: 2
      selector:
        app: my-app
      template:
        metadata:
          labels:
            app: my-app
        spec:
          containers:
          - name: my-container
            image: nginx
            ports:
            - containerPort: 80
    

    집합성 기준 요건

    집합성 기준 레이블 요건에 따라 값 집합을 키로 필터링할 수 있습니다. in,notinexists(키 식별자만 해당)의 3개의 연산자를 지원합니다.

    environment in (production, qa)
    tier notin (frontend, backend)
    partition
    !partition
    
    • 첫 번째 예시: 키가 environment이고 값이 production 또는 qa인 모든 리소스 선택
    • 두 번째 예시: 키가 tier이고 값이 frontendbackend를 가지는 리소스를 제외한 모든 리소스와 키로 tier를 가지고 값을 공백으로 가지는 모든 리소스 선택
    • 세 번째 예시: 키가 partition을 포함하는 모든 리소스 선택
    • 네 번째 예시: 키가 partition을 포함하지 않는 모든 리소스 선택

    쉼표는 AND 연산자로 작동합니다. 따라서 partition,environment notin (qa)와 같이 사용하면, 키가 partition이거나 키가 environment이고 값이 qa가 아닌 리소스를 필터링할 수 있습니다. 집합성 기준 셀렉터는 일반적으로 environment=productionenvironment in (production)을 같은 것으로 간주합니다. 유사하게 !=notin도 같은 것으로 간주합니다.

    집합성 기준 요건은 일치성 기준 요건과 조합해서 사용할 수 있습니다.

    partition in (customerA, customerB),environment!=qa

    API

    LIST와 WATCH 필터링

    LIST와 WATCH 작업은 셀렉터를 사용하여 반환되는 오브젝트 집합을 필터링할 수 있습니다. URL 쿼리 문자열을 사용하여 두 가지 요건을 선택할 수 있습니다.

    • 일치성 요건: ?labelSelector=environment%3Dproduction,tier%3Dfrontend
    • 집합성 요건: ?labelSelector=environment+in+%28production%2Cqa%29%2Ctier+in+%28frontend%29

    두 가지 셀렉터 스타일 모두 REST 클라이언트를 통해 선택된 리소스를 확인하거나 목록을 볼 수 있습니다. 예를 들어, kubectlapiserver를 대상으로 셀렉터를 이용할 수 있습니다.

    kubectl get pods -l environment=production,tier=frontend
    kubectl get pods -l 'environment in (production),tier in (frontend)'
    kubectl get pods -l 'environment in (production, qa)'
    kubectl get pods -l 'environment,environment notin (frontend)'

    API 오브젝트에서 참조 설정

    쿠버네티스에서 일부 오브젝트는 셀렉터를 사용하여 파드와 같은 다른 리소스 집합을 선택합니다. (services, replicationcontrollers)

    서비스와 레플리케이션 컨트롤러

    services에서 지정하는 파드 집합은 셀렉터로 정의하며, replicationcontrollers가 관리하는 파드의 오브젝트 그룹도 셀렉터로 정의합니다. 서비스와 레플리케이션 컨트롤러의 셀렉터는 json 또는 yaml 파일의 일치성 기준 요구사항에만 매핑됩니다.

    "selector": {
        "component" : "redis",
    }
    selector:
        component: redis

    json 또는 yaml 예시에서 셀렉터는 component=redis 또는 component in (redis) 과 동일합니다.

    세트-기반 요건을 지원하는 리소스

    Job, Deployment, ReplicaSet, DaemonSet 등의 새로운 리소스는 집합성 기준 요건도 지원합니다.

    selector:
      matchLabels:
        component: redis
      matchExpressions:
        - {key: tier, operator: In, values: [cache]}
        - {key: environment, operator: NotIn, values: [dev]}

    matchLabels{key,value} 쌍과 매칭됩니다. matchLabels에서 매칭된 단일 {key,value}matchExpressions의 요소와 같으며, key 필드는 "key"로, operator는 "In"이며, values에는 "value"만 나열됩니다. matchExpressions은 파드 셀렉터의 요건 목록입니다. 유효한 연산자에는 In, NotIn, Exists 및 DoNotExist가 포함됩니다. In 및 NotIn은 설정된 값이 있어야 합니다. matchLabelsmatchExpressions 모두 AND로 되어 있어 일치하기 위해서는 모든 요건을 만족해야 합니다.

    노드 셋 선택

    레이블을 이용해 파드가 스케줄링될 수 있는 노드셋을 제한하는 방법이 있습니다.

    레퍼런스

    https://kubernetes.io/ko/docs/concepts/overview/working-with-objects/labels/#레이블-셀렉터

    댓글