LoginSignup
10
8

More than 3 years have passed since last update.

KubernetesのLabel / NodeSelector / Annotationの使い方

Last updated at Posted at 2019-06-21

概要

Kubernetesのmanifestファイルの書き方について説明する。
このページでは、以下の3つについて説明する。

目次

Labelの使い方

Labelは他のリソースから参照するときに利用する。
以下の例では、ServiceからDeploymentへリクエストを流すために各種labelを合わせている。

deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: sample-deployment
spec:
  replicas: 2
  selector:
    matchLabels:
      # 後述のspec.template.metadata.labels.appと合わせる
      app: sample-app
  template:
    metadata:
      labels:
        # 上記のspec.selector.matchLabels.appと合わせる
        app: sample-app
    spec:
      containers:
        # Dockerコンテナ名
        - name: http-container
          # 利用するDockerイメージ
          image: php:7.0-apache
          # localイメージ利用。ただし、localに指定したイメージが存在しない場合はレポジトリを参照する
          imagePullPolicy: IfNotPresent
          ports:
            # service.ymlで定義する外部公開用port設定の箇所と名前を合わせることでbindされる
            # nameは15文字以内でないとエラーになる
            - name: ha-inner-port
              # コンテナ内のport
              containerPort: 80
service.yml
apiVersion: v1
kind: Service
metadata:
  name: sample-service
spec:
  selector:
    # deployment.ymlのspec.selector.matchLabels.appと合わせる
    app: sample-app
  ports:
    - name: ha-outer-port
      # 外部公開するport
      port: 8080
      # deployment.ymlで定義したport名と合わせることでbindされる
      targetPort: ha-inner-port
  type: NodePort

apply

$ sudo kubectl apply -f pod.yml
pod/nginx created

LABELを確認

$ sudo kubectl get all --show-labels
NAME                                     READY   STATUS    RESTARTS   AGE   LABELS
pod/sample-deployment-85f4cb9d7c-2qncx   1/1     Running   0          20s   app=sample-app,pod-template-hash=85f4cb9d7c


NAME                     TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)          AGE    LABELS
service/kubernetes       ClusterIP   10.96.0.1     <none>        443/TCP          111m   component=apiserver,provider=kubernetes
service/sample-service   NodePort    10.98.7.194   <none>        8080:32661/TCP   20s    app=http-service


NAME                                READY   UP-TO-DATE   AVAILABLE   AGE   LABELS
deployment.apps/sample-deployment   1/1     1            1           20s   <none>

NAME                                           DESIRED   CURRENT   READY   AGE   LABELS
replicaset.apps/sample-deployment-85f4cb9d7c   1         1         1       20s   app=sample-app,pod-template-hash=85f4cb9d7c

動作確認

WEBページが閲覧できれば、ServiceからDeploymentへのリクエストが流れたことになる。

$ curl $(sudo minikube service sample-service --url)
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>403 Forbidden</title>
</head><body>
<h1>Forbidden</h1>
<p>You don't have permission to access /
on this server.<br />
</p>
<hr>
<address>Apache/2.4.25 (Debian) Server at 172.21.115.122 Port 32691</address>
</body></html>

LabelSelectorの使い方

LabelSelectorには以下の2種類がある。

  • matchLabels
  • matchExpressions

matchLabels

指定したLabelと全て一致したものが対象になる。

matchLabels:
  app: nginx
  tier: frontend

matchExpressions

matchExpressionsでは、operatorを使い、柔軟な条件を設定することができる。
operatorには以下を指定することができる。

  • In
  • NotIn
  • Exists
  • DoesNotExists

具体的な書き方は以下の通り。

matchExpressions:
# envがprodかstgのいずれかである場合
- key: env
  operator: In
  values: [prod, stg]
# appがprodかstgのいずれかでもない場合
- key: app
  operator: NotIn
  values: [sample001, sample002]
# appが存在する場合
- key: app
  operator: Exists
# tierが存在する場合
- key: tier
  operator: DoesNotExist

envがprodもしくはstgの場合という条件を設定する。

matchExpressions:
- key: env
  operator: In
  values: [prod, stg]

この条件でマッチするもの、しないものは以下のとおりである。

マッチする

labels:
  app: sample-app
  tier: frontend
  env: prod

マッチする

labels:
  app: sample-app
  tier: frontend
  env: stg

マッチしない

labels:
  app: sample-app
  tier: frontend
  env: dev

参考:Kubernetes道場 8日目 - ReplicaSet / Deploymentについて

NodeSelectorの使い方

NodeSelectorとは、Podを特定のNodeにスケジューリングする仕組みである。
ここでもLabelSelectorを使うが、先述のものとは違い、matchExpressionsは使えず、完全一致のみとなる。

例として、environment: devというLabelを持ったNodeにPodをスケジューリングさせてみる。
まずは、存在しないLabelを指定しスケジューリングされないことを確認し、その後に、存在するLabelを指定してスケジューリングさせるという手順で行う。

Podを定義

environment: devのNodeにスケジューリングする設定にする。

apiVersion: v1
kind: Pod
metadata:
  name: node-selector
spec:
  containers:
  - name: nginx
    image: nginx
  # 以下でNodeの指定をする
  nodeSelector:
    environment: dev
  terminationGracePeriodSeconds: 0

ラベルを確認

しかし、environment: devは存在していない。

$ sudo kubectl get node --show-labels
NAME       STATUS   ROLES    AGE     VERSION   LABELS
minikube   Ready    master   3h35m   v1.14.3   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=minikube,kubernetes.io/os=linux,node-role.kubernetes.io/master=

スケジューリング失敗

存在しないNodeのLabelを指定した場合は、エラーとなりスケジューリングされない。

$ sudo kubectl describe pod/node-selector
# **snip**
Events:
  Type     Reason            Age                From               Message
  ----     ------            ----               ----               -------
  Warning  FailedScheduling  24s (x2 over 24s)  default-scheduler  0/1 nodes are available: 1 node(s) didn't match node selector.

NodeにLabelを貼る。

以下のコマンドでNodeにenvironment: devというLabelを貼る。

$ sudo kubectl label node/minikube environment=dev

environment=devがLabelに追加された。

$ sudo kubectl get node --show-labels
NAME       STATUS   ROLES    AGE     VERSION   LABELS
minikube   Ready    master   3h41m   v1.14.3   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,environment=dev,kubernetes.io/arch=amd64,kubernetes.io/hostname=minikube,kubernetes.io/os=linux,node-role.kubernetes.io/master=

スケジューリングされたことを確認

これでPodがNodeにスケジューリングされた。

$ sudo kubectl describe pod/node-selector
# **snip**
Events:
  Type     Reason            Age                    From               Message
  ----     ------            ----                   ----               -------
  Warning  FailedScheduling  2m28s (x5 over 6m30s)  default-scheduler  0/1 nodes are available: 1 node(s) didn't match node selector.
  Normal   Scheduled         101s                   default-scheduler  Successfully assigned default/node-selector to minikube
  Normal   Pulled            100s                   kubelet, minikube  Container image "nginx:alpine" already present on machine
  Normal   Created           100s                   kubelet, minikube  Created container nginx
  Normal   Started           100s                   kubelet, minikube  Started container nginx

$ sudo kubectl get pod
NAME            READY   STATUS    RESTARTS   AGE
node-selector   1/1     Running   0          7m16s

Annotationの使い方

Labelと同じようなことができるが、Labelと違い、metadataなどをもたせるのが一般的らしい。

You can use Kubernetes annotations to attach arbitrary non-identifying metadata to objects. Clients such as tools and libraries can retrieve this metadata.

apiVersion: v1
kind: Pod
metadata:
  name: annotations-demo
  annotations:
    imageregistry: "https://hub.docker.com/"
spec:
  containers:
  - name: nginx
    image: nginx:1.7.9
    ports:
    - containerPort: 80

関連記事

参考

10
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
8