LoginSignup
20
11

More than 5 years have passed since last update.

逆引き Kubernetes オブジェクト

Last updated at Posted at 2016-11-19

まえおき

Kubernetes を使い始めたのだが、公式のドキュメントが難解すぎたので目的別に整理した。

各ノードでコンテナを起動したい

Daemon Set を使う。
以下の例では、ホストの /var/log/myapp ディレクトリに出力された myapp.log ファイルを logstash コンテナで監視する。簡略化のため Logstash はファイルの中身をそのまま出力している。通常は Filter Plugin を併用し Output Plugin で Elasticsearch に送る。

ホストのディレクトリをマウントするLogstashの例
+-----------------------------------+
| node                              |
|                     +----------+  |
|                     | logstash |  |
|                     |          |  |
|  /var/log/myapp <-mount-*/log  |  |
|                     +----------+  |
+-----------------------------------+
sample-logstash.yml
kind: DaemonSet
apiVersion: extensions/v1beta1
metadata:
  name: logstash
spec:
  template:
    metadata:
      labels:
        app: daemon
    spec:
      volumes:
      - name: log
        hostPath:
          path: /var/log/myapp
      containers:
      - name: logstash # ホストの /var/log/myapp/myapp.log を出力するだけのコンテナ
        image: logstash
        args:
        - -e
        - |
          input {
            file { path => '/log/myapp.log' }
          }
          output {
            stdout { codec => rubydebug }
          }
        volumeMounts:
        - name: log # ホストの /var/log/myapp ディレクトリに当たる
          mountPath: /log

コンテナからコンテナに問い合わせたい

コンテナからコンテナに問い合わせたい(多対一の場合)

Service を使う。
Pod は Service に対応させられた Pod の名前解決ができることを利用する。
以下の例では logstash コンテナが elasticsearch コンテナに/log/myapp.log パスにあるログを送信する。簡略化のため /log/myapp.log には 30 秒おきに hello と書き込むコンテナを立てている。通常は /log/myapp.log パスにログを出力するようなアプリケーションを立てる。
Service を使うことで logstash コンテナが elasticsearch という名前で elasticsearch コンテナに問い合わせられるようになっている。

多コンテナ対1コンテナで問い合わせる例
+---------------+     +---------------+      +---------------+
| [ReplicaSet]  |     | [Service]     |      | [Pod]         |
|  +----------+ |     | elasticsearch |      | elasticsearch |
|  | [Pod]    | |     |               |      |               |
|  | logstash *----+--*name resolution*----->*:9200/tcp      |
|  +----------+ |  |  +---------------+      +---------------+
|  | [Pod]    | |  |
|  | logstash *----+
|  +----------+ |  |
|  | [Pod]    | |  |
|  | logstash *----+
|  +----------+ |
+---------------+
sample-elasticsearch.yml
kind: Service
apiVersion: v1
metadata:
  name: elasticsearch
spec:
  selector:
    app: elasticsearch
  ports:
  - port: 9200
    targetPort: 9200
---
kind: Pod
apiVersion: v1
metadata:
  name: elasticsearch
  labels:
    app: elasticsearch
spec:
  containers:
  - name: elasticsearch
    image: elasticsearch:2.4.1 # 5.0 だと起動に失敗したので前バージョン
    ports:
    - containerPort: 9200
---
kind: ReplicaSet
apiVersion: extensions/v1beta1
metadata:
  name: logstash
spec:
  replicas: 3
  template:
    metadata:
      labels:
        app: logstash
    spec:
      volumes:
      - name: log
      containers:
      - name: logstash # /log/myapp.log のログを elasticsearch に送るだけのコンテナ
        image: logstash:2.4.0-1 # Elasticsearch に合わせたバージョン
        args:
        - -e
        - |
          input {
            file { path => '/log/myapp.log' }
          }
          output {
            stdout {
              codec => rubydebug
            }
            elasticsearch {
              hosts => ['elasticsearch']
            }
          }
        volumeMounts:
        - name: log
          mountPath: /log
      - name: hello # /log/myapp.log に hello と30秒毎に書き込むだけのコンテナ
        image: centos
        args:
        - bash
        - -c
        - |
          while true; do
            echo hello >> /log/myapp.log
            sleep 30
          done
        volumeMounts:
        - name: log
          mountPath: /log

なお、Elasticsearch に Logstash から送信されたログを確認するためには、

kubectl run -it --rm centos --image centos

としてbashを起動したコンテナの中で、

curl elasticsearch:9200/logstash-*/_search?pretty

と実行すればよい。コンテナはそのままexitbashを終了すれば自動的に削除される。

コンテナからコンテナに問い合わせたい(一対一の場合)

Service を使ってもよいが Pod を使うと単純に書ける。
Pod の中の他のコンテナは localhost で問い合わせられる。
以下の例では Elasticsearch と Kibana をセットで立てる。

sample-ek.yml
kind: Pod
apiVersion: v1
metadata:
  name: ek
  labels:
    app: ek
spec:
  containers:
  - name: elasticsearch
    image: elasticsearch:2.4.1 # 5.0 だと起動に失敗したので前バージョン
  - name: kibana
    image: kibana:4.6.2 # Elasticsearch に合わせたバージョン
    env:
    - name: ELASTICSEARCH_URL
      value: http://localhost:9200 # elasticsearch コンテナに繋がる
    ports:
    - containerPort: 5601

クラスタの外からコンテナにアクセスしたい

クラスタのノードが1台しかない場合

NodePort タイプのServiceを使う。
NodePort タイプはコンテナが起動したノードの
IPアドレスでアクセスできるようになる。
以下の例では、前節で作った Kibana に
http://(ノードのIPアドレス):30601 でアクセスできるようになる。

  • もちろん、ファイアウォールやセキュリティグループなどが間にあれば 接続を許可する設定が必要になる。
  • ちなみに、ポート番号が30601になっているのは、 ノードで使用可能なポート番号が デフォルトでは30000~32767に設定されているためである。
sample-ek-svc.yml
kind: Service
apiVersion: v1
metadata:
  name: ek-svc
spec:
  ports:
  - port: 5601
    targetPort: 5601
    nodePort: 30601
  selector:
    app: ek
  type: NodePort

クラスタのノードが複数台ある場合

Kubernetes の外部にロードバランサを調達する。
Google Container Engine のようなクラウドサービスでは、
LoadBalancer タイプの Service を使うことで
ロードバランサの作成をサポートしている。
以下の例では、前節で作った Kibana に
http://{ロードバランサのIPアドレス}:5601 でアクセスできるようになる。

sample-ek-lb.yml
kind: Service
apiVersion: v1
metadata:
  name: ek-lb
spec:
  ports:
  - port: 5601
    targetPort: 5601
  selector:
    app: ek
  type: LoadBalancer

コンテナの数を増やしたい

Replica Set や Job を使う。
Replica Set は継続的に実行されるようなコンテナを使用する。
Job は実行の完了を想定しているようなコンテナを使用する。

Replica Set

Replica Set は稼働中のコンテナが指定した数になるまで立て続ける。
デーモンのような、処理が終了しないことが想定されている場合に使う。

Job

Job は exit 0 で終了したコンテナの数が指定回数を満たすまで
コンテナを新規に立て続ける。
バッチのような、デーモンとは違って、
処理が終了することが想定されている場合に使う。

Dockerイメージをプルするときに認証したい

Secret を使う。

公式のドキュメント にその手順が書かれている通り、
まずは Secret を作成し、
それから Secret を使用してイメージのプルを行うように設定すればよい。

次のコマンドを使って Secret を作成できる。

kubectl create secret docker-registry

たとえば、

kubectl create secret docker-registry my-secret --docker-username=myname --docker-password=mypass --docker-email=myname@example.com

とすれば my-secret という名前で Secret を作成できる。
Secret の中には Base64 エンコードされた上記の情報が含まれるようになるので、
取り扱いには十分に注意しなければならない。

次に Secret を使用するように設定する。

イメージをプルするときにデフォルトで上記の認証情報を使用したい場合は、
Service Account に Secret を設定する。
Service Account は Namespace ごとに作成されており、
Namespace に属するオブジェクトがデフォルトで使用する Service Account があるので、
そこに設定を追加する。

デフォルトの Namespace の デフォルト Service Account に設定する場合は、

kubectl edit sa default

とし、(sa は serviceaccount のエイリアス)
エディタが起動するので、

imagePullSecrets:
- name: my-secret

を末尾に追加し、保存してエディタを終了する。

Pod ごとに使用する Secret を分けたい場合は、
以下の例のように Pod に Secret を設定する。

kind: Pod
apiVersion: v1
metadata:
  name: sample-foo
spec:
  containers:
  - name: sample-foo
    image: httpd
  imagePullSecrets:
  - name: my-secret

コンテナに番号を付けて管理したい

Stateful Set を使う。

コンテナが自身の番号を知るには、ホスト名から切り出す。
ホスト名は {Stateful Set 名}-{番号} となっている。

20
11
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
20
11