「みんなの翻訳」は、世界中の文書をみんなで協力して翻訳するサイトです。

みんなの翻訳ロゴ
ブクタブ
翻訳サイト

カテゴリ一覧

このサイトについて 新規登録はこちら お試し翻訳

一覧

2017/07/28

メンテナンス終了のお知らせ

2017/7/25-2017/7/28に実施したメンテナンスは、2017/7/28/14:20に終了いたしました。 ご協力をいただき、ありが…

List

Hnoss

English⇒Japanese

ajhjhaf

English⇒Japanese

shikimi

English⇒Japanese

hanako

English⇒Japanese

ホーム > 翻訳記事

翻訳記事

【GitLab 公式 を訳してみた】Kubernetes エクゼキュータ

 GitLab Runner>エクゼキュータ>Kubernetesエクゼキュータ

目次
>概要
>全体の作業工程
>Kubernetes APIに接続する

>キーワード
 >エクゼキュータ・サービスアカウントを設定する
 >Kubernetesの名前空間を上書きする
 >デフォルトのKubernetesサービスアカウントを上書きする
 >ベアラトークンの設定(Kubernetes APIを呼び出すときに必要)
 >Podアノテーションを上書きする
>「config toml」ファイルから、キーワードを定義する

>ボリュームを使う
 >hostPathボリューム
 >PVCボリューム
 >Config Mapボリューム
 >Secretボリューム
 >Empty Dirボリューム

>Dockerをビルドに使う上での注意点
 >「/var/run/docker.sock」が外部に公開されてしまうリスク
 >「docker:dind」を使うリスク
 >gitが適用されない問題
 >リソースの分割で生じる問題

 

  GitLab ランナーでは、kubernetesクラスター上でアプリをビルドする際に、Kubernetesを利用することができます。
 ただし、それにはKubernetesエクゼキュータの利用が必須です。

  DockerエクゼキュータがGitLab CIで使用された場合、ランナーはクラスター内のKubernetes APIへ接続します。そこではGitLab CIに課せられたそれぞれのjobに対して、podが作成されます。
 Podとは、とてもかいつまんでいえば、ビルドコンテナにサービス(GitLab CI yaml の serviceで定義可能)などの追加コンテナを付属させたものです。

 これらのコンテナには、それぞれ名前があります。

  • build」 ビルドコンテナのこと。
  • svc-X」 サービスコンテナ。Xの部分には、[0-9]+までの数字が入る。


 これらのコンテナが同じKubernetes podに入っているため、ローカルホストアドレスはどちらも同じ扱いになります。
 アクセスするには、次の要件にご注意ください。

  • サービスコンテナが各自のDNS名でアクセスできない点。その代わりにローカルホストが使用される。
  • 同じポートで使用できないサービスがあること。(例:同時に複数のmysqlサービスを同じポートで動かすことはできない。)


 全体の作業工程

  Kubernetesエクゼキュータでビルドする際には、大まかに次のような手順を踏みます。

  1. 準備:KubernetesクラスターでPodを作成する。ここでビルド用とサービス用のコンテナが作成される。
  2. ビルド前:キャッシュをクローン、リストアして、前のステージからアーティファクトをダウンロードしてくる。これはPodに付属している専用コンテナ上で実行される。
  3. ビルド:ユーザービルド。
  4. ビルド後:キャッシュを作成し、GitLabにアーティファクトをアップロードする。この工程もPodに付属している専用コンテナ上で実行される。



 Kubernetes APIに接続する

  Kubernetes APIに接続するには、次の要件を満たしてください。

  • host: Kubernetes API serverのホストURLで、任意で指定できる(指定しなかった場合は、自動探知機能が働く)
  • cert_file: Kubernetes API serverの ユーザーログイン認証
  • cert_file: Kubernetes API serverの ユーザー認証秘密鍵
  • ca_file: Kubernetes API serverの認証局証明書。こちらは任意のものを取り付ける。


 ユーザーアカウントには、権限認証を取り付けなくてはいけません。このあたりの設定は、Pods側の名前空間を指定する機能で補うことができるでしょう。

  もしも、GitLab CI Runnerそのものが、Kubernetes クラスターの中にインストールされていた場合は、上記の設定がなくてもランナーがKubernetes APIを自動で発見してくれるので、安心です。
 Kubernetesを継続的に使用する開発形態なら、ランナーもKubernetesクラスター内に設置しておいた方がそつがないといえます。

 クラスター外からビルドを実施する場合は、ランナーがクラスター内Kubernetes APIに到達できるように、上記のキーワードをランナー側にあらかじめ設定しておくことが大切です。

 

  キーワード

  Kubernetes内で動かしているランナーなら、次のキーワードが役に立つはずです。

  • namespace: Kubernetes Podsに名前空間を定義する
  • namespace_overwrite_allowed: 正規表現を用いて、名前空間に与えられている環境変数を上書きする(詳しくは『Kubernetesの名前空間を上書きする』で解説)。これを設定しなかった場合は、名前空間を変更する機能が使えない。
  • privileged: 特権認証フラグをつけて、コンテナを運用する
  • cpu_limit: ビルドコンテナに対するCPU配分上限を指定する
  • memory_limit: ビルドコンテナに対するメモリ配分上限を指定する
  • service_cpu_limit: サービスコンテナをビルドする際にかかるCPU配分上限を指定する
  • service_memory_limit: サービスコンテナをビルドする際にかかるメモリ配分上限を指定する
  • helper_cpu_limit: ヘルパーコンテナをビルドする際にかかるCPU配分上限を指定する
  • helper_memory_limit: ヘルパーコンテナをビルドする際にかかるメモリ配分上限を指定する
  • cpu_request: ビルドコンテナに対するCPU配分下限を指定する
  • memory_request: ビルドコンテナに対するメモリ配分下限を指定する
  • service_cpu_request: サービスコンテナをビルドする際にかかるCPU配分下限を指定する
  • service_memory_request: サービスコンテナをビルドする際にかかるメモリ配分下限を指定する
  • helper_cpu_request: ヘルパーコンテナをビルドする際にかかるCPU配分下限を指定する
  • helper_memory_request: ヘルパーコンテナをビルドする際にかかるメモリ配分下限を指定する
  • pull_policy: イメージのプルポリシーを指定する。「never」「if-not-present」「always」の3モードがあります。無設定だった場合は、クラスターがデフォルトの設定を使用する。
  • node_selector: string=stringにおける、key=value(キーワード=数値)の組み合わせ数に上限を指定する。ここで上限を設置しておくと、kubernetesのノード数と全ての「キーワード=数値」ペア数が一致するようになる。
  • image_pull_secrets: Dockerイメージを引用する際の認証に使われる秘密アレイ
  • helper_image: [応用的な機能] レポジトリをクローンしたり、アーティファクトをアップロードする際に使われる、デフォルトのヘルパーイメージを無効化する
  • terminationGracePeriodSeconds: Podに停止信号を送って、強制的にプロセスを停止するまでの秒数を指定する
  • poll_interval: ランナーがPodの動作状況を調査する頻度を、秒数で指定する。[デフォルトでは3秒。]
  • poll_timeout: ランナーがビルドのために作成されたコンテナに接続するための制限時間を、秒数で指定する。(これはランナーが1つの工程、クラスターにどれくらいの所要時間を設けるかの目安になる。)[デフォルトでは180秒。]
  • pod_labels: ランナーによって作成された、ビルドポッドそれぞれにラベルを追加する。ここで定められたラベルは、環境変数としての役割を担うことができる。
  • pod_annotations: ランナーによって作成された、各ビルドポットにアノテーションのセットを設ける。ここで定められたラベルは、環境変数としての役割を担うことができる。Podのアノテーションはビルド毎に上書きすることが可能である。
  • pod_annotations_overwrite_allowed: 正規表現を用いて、Podアノテーションの内容を環境変数に変更する。これを設定しなかった場合は、Podアノテーションを変更する機能が使えない。
  • service-account: Kubernetes APIを呼び出すときに使われるデフォルトのサービスアカウントを指定する。
  • service_account_overwrite_allowed:  正規表現を用いて、サービスアカウントの内容を環境変数に変更する。これを設定しなかった場合は、サービスアカウントを変更する機能が使えない。
  • bearer-token: ビルドポッドを起動する際に使われる、デフォルトのベアラトークンを指定する。
  • bearer_token_overwrite_allowed: ビルドポッドを作成するのに使われるベアラトークンを指定する際に、ブーリアンの使用を許可する
  • volumes: コンフィグファイルから設定する項目で、ビルドコンテナをマウントするボリュームをリスト形式で指定する。詳しくは後述の『ボリュームを使う』にて。


  エクゼキュータ・サービスアカウントを設定する

 これは先ほど登場した「KUBERNETES_SERVICE_ACCOUNT」環境変数か、「--service-account」フラグを使うことで設定できます。

 

  Kubernetesの名前空間を上書きする

  ちなみに、Kubernetes の名前空間は、「gitlab-ci.yml」から変更可能です。
 その際に使用する環境変数は、「KUBERNETES_NAMESPACE_OVERWRITE」です。

  名前空間の扱いを可変にしておくことで、CIにの目的に応じて独立した権限を作り上げたり、ポッドのセットを作成してデプロイするのは誰にするかなど、プロジェクトの役割を明確にできます。
 ランナーによって作成されたPodは、名前空間を書き換えます。これによって、CIステージ間で発生するコンテナ間のアクセスが、より無駄なく明確に区別されるようになります。

======================
variables:
 KUBERNETES_NAMESPACE_OVERWRITE: ci-${CI_COMMIT_REF_NAME}
======================

  さらに、名前空間を作成しておくだけで、CIの運用はその名義で実施されるようになります。「namespace_overwrite_allowed」は正規表現で設定しますので、変更も簡単です。この設定を放っておくと、それらの操作ができません。

 

  デフォルトのKubernetesサービスアカウントを上書きする

  Kubernetes のサービスアカウントは、「gitlab-ci.yml」から変更可能です。 
 その際に使用する環境変数は、「KUBERNETES_SERVICE_ACCOUNT_OVERWRITE」です。

  この設定は、名前空間とサービスアカウントを関連付けることによく使われます。
 特に、ロールベースアクセス制御の設定を簡略化するときなどに有効です。

======================
variables:
 KUBERNETES_SERVICE_ACCOUNT_OVERWRITE: ci-service-account
======================

  名前空間を上書きして、クラスター内のRBAC設定をする際に、ぜひお使いください。

  さらに、サービスアカウントを設定しておくだけで、CIの運用はその名義で実施されるようになります。「KUBERNETES_SERVICE_ACCOUNT_OVERWRITE_ALLOWED」は、正規表現で設定します。
 この設定を放っておくと、これらの操作ができません。

 

  ベアラトークンの設定(Kubernetes APIを呼び出すときに必要)

  この設定は、名前空間と、サービスアカウントの設定を済ませた状態で取り組んでください。
 Kubernetesはビルドポッドを作成する際に、APIを呼び出します。そのAPIを呼び出すのに、ベアラトークンが必要です。
 これは、プロジェクトの所有者が、プロジェクトの秘密変数として制定するのが望ましいとされます。
 ※ベアラトークンの設定前に、Host コンフィグキーワードを指定しておいてください。
 

======================
variables:
 KUBERNETES_BEARER_TOKEN: thebearertokenfromanothernamespace(外部名前空間から指定した、ベアラトークン)
======================

 

  Podアノテーションを上書きする

  Kubernetes のPodアノテーションは、「gitlab-ci.yml」から変更可能です。
その際に使用する環境変数は、「KUBERNETES_POD_ANNOTATIONS_*」です。そこに「key=value」という数値を用いて設定します。

  Podのアノテーションは「key=value」を変更することで上書きできます。

  同時に複数のアノテーションを設定することも可能です。

======================
variables:
 KUBERNETES_POD_ANNOTATIONS_1: "Key1=Val1"
 KUBERNETES_POD_ANNOTATIONS_2: "Key2=Val2"
 KUBERNETES_POD_ANNOTATIONS_3: "Key3=Val3"
======================

 

  「config toml」ファイルから、キーワードを定義する

 
全てのキーワードをGitLab ランナーの「config.toml」で指定すると、プロジェクトでの設定が一斉に済ませられます。

「config.toml」設定例:

============================================
concurrent = 4
 [[runners]]
  name = "Kubernetes Runner"
  url = "https://gitlab.com/ci"
  token = "......"
  executor = "kubernetes"
  [runners.kubernetes]
   host = "https://45.67.34.123:4892"
   cert_file = "/etc/ssl/kubernetes/api.crt"
   key_file = "/etc/ssl/kubernetes/api.key"
   ca_file = "/etc/ssl/kubernetes/ca.crt"
   namespace = "gitlab"
   namespace_overwrite_allowed = "ci-.*"
   bearer_token_overwrite_allowed = true
   privileged = true
   cpu_limit = "1"
   memory_limit = "1Gi"
   service_cpu_limit = "1"
   service_memory_limit = "1Gi"
   helper_cpu_limit = "500m"
   helper_memory_limit = "100Mi"
   poll_interval = 5
   poll_timeout = 3600
   [runners.kubernetes.node_selector]
    gitlab = "true"
============================================

 

  ボリュームを使う

  端的にいえば、この設定は、ビルドコンテナを特定のボリュームにマウントさせることが目的です。
 hostPath、PVC、configMap、Kubernetesの Secretボリュームに対応しています。
 これらのボリュームにつきましては、いくつ使っても構いません。(種類さえ合っていれば、量的なことは問われません。)
 

  設定例:

============================================
concurrent = 4

 [[runners]]
  # usual configuration
  executor = "kubernetes"
  [runners.kubernetes]
   [[runners.kubernetes.volumes.host_path]]
   name = "hostpath-1"
   mount_path = "/path/to/mount/point"
   read_only = true
   host_path = "/path/on/host"
   [[runners.kubernetes.volumes.host_path]]
    name = "hostpath-2"
    mount_path = "/path/to/mount/point_2"
    read_only = true
    [[runners.kubernetes.volumes.pvc]]
     name = "pvc-1"
     mount_path = "/path/to/mount/point1"
     [[runners.kubernetes.volumes.config_map]]
      name = "config-map-1"
      mount_path = "/path/to/directory"
       [runners.kubernetes.volumes.config_map.items]
       "key_1" = "relative/path/to/key_1_file"
       "key_2" = "key_2"
       [[runners.kubernetes.volumes.secret]]
        name = "secrets"
        mount_path = "/path/to/directory1"
        read_only = true
        [runners.kubernetes.volumes.secret.items]
         "secret_1" = "relative/path/to/secret_1_file"
         [[runners.kubernetes.volumes.empty_dir]]
          name = "empty_dir"
          mount_path = "/path/to/empty_dir"
          medium = "Memory"
============================================

 

  hostPathボリューム

  hostPathボリュームは、Kubernetesに対し、Pod内のコンテナからどのホストパスをマウントするかを指定する項目です。

 

オプション 種類 必須か 説明
name string yes ボリューム名
mount_path string yes コンテナがマウントすべきボリュームにパスを設ける
host_path string no ボリュームとしてマウントさせたいホストのパス。これが指定されなかった場合は、「mount_path」が代わりに使われる
read_only boolean no ボリュームを読み込み限定モードにするかどうか(デフォルトでは『false』)

 

 

  PVCボリューム

  PVCボリュームは、Kubernetesに対し、どのPersistentVolumeClaimを使用するかを指定する項目です。このボリュームはKubernetes内で具体的に定義され、コンテナの内部にマウントされるものです。

 

オプション 種類 必須か 説明
name string yes ボリューム名兼、「PersistentVolumeClaim」名として使われる
mount_path string yes コンテナがマウントすべきボリュームにパスを設ける
read_only boolean no リュームを読み込み限定モードにするかどうか(デフォルトでは『false』)

 

 

  Config Mapボリューム

  ConfigMapボリュームは、Kubernetesに対し、どのconfigMapを使用するかを指定する項目です。このボリュームはKubernetesクラスター内で具体的に定義され、コンテナの内部にマウントされるものです。

 

オプション 種類 必須か 説明
name string yes ボリューム名兼、「configMap」名として使われる
mount_path string yes コンテナがマウントすべきボリュームにパスを設ける
read_only boolean no リュームを読み込み限定モードにするかどうか(デフォルトでは『false』)
items map[string]string no configMapの鍵にKey-to-path mapping を使うかどうかを設定する

 

  configMapボリュームを使用している際に、configMapから指定された鍵はそれぞれファイルに変換され、特定のマウントパスが組まれているディレクトリに格納されます。

  デフォルトの設定でも鍵の管理法は定められており、configMapキーが変換されるファイル名は、そのまま設定用の数値として扱うことができます。

  デフォルトの設定は、「items」オプションで変更可能です。
 

  「items」オプションは、鍵同士のマッピングを定義します。これらは実際に鍵としても使われますし、configMapの数値を保存している場所へのパス(ボリュームのマウントパス関連)としても扱われます。

  「items」オプションでは指定された鍵のみを対象とし、ボリュームを追加することの他には、全項目がスキップされます。

 注:期限が切れた鍵でjobを実施しようとすると、Podを作成する段階で失敗します。


 

  Secretボリューム

  Secretボリュームは、Kubernetesに対し、どの「secret」を使用するかを指定する項目です。このボリュームはKubernetes内で具体的に定義され、コンテナの内部にマウントされるものです。

 

オプション 種類 必須か 説明
name string yes ボリューム名兼、「secret」名として使われる
mount_path string yes コンテナがマウントすべきボリュームにパスを設ける
read_only boolean no ボリュームを読み込み限定モードにするかどうか(デフォルトでは『false』)
items map[string]string no secretの鍵にKey-to-path mapping を使うかどうかを設定する

 

  secretボリュームを使用している際に、configMapから指定された鍵はそれぞれファイルに変換され、特定のマウントパスが組まれているディレクトリに格納されます。

  デフォルトの設定でも鍵の管理法は定められており、secretキーが変換されたファイル名は、そのまま設定用の数値として扱うことができます。

  デフォルトの設定は、「items」オプションで変更可能です。
 

  「items」オプションは、鍵同士のマッピングを定義します。これらは実際に鍵としても使われますし、secretの数値を保存している場所へのパス(ボリュームのマウントパス関連)としても扱われます。

  「items」オプションでは指定された鍵のみを対象とし、ボリュームを追加することの他には、全項目がスキップされます。

 注:期限が切れた鍵でjobを実施しようとすると、Podを作成する段階で失敗します。


 

  Empty Dirボリューム

  emptyDirボリュームは、Kubernetesに対し、コンテナの中からどの空ディレクトリをマウントするかを指定する項目です。

 

オプション 種類 必須か 説明
name string yes ボリューム名
mount_path string yes コンテナがマウントすべきボリュームにパスを設ける
medium String no "Memory" をtmpfsに配置させる設定。そのままではノードディスクストレージに格納されている(デフォルトでは"")

 

 

  Dockerをビルドに使う上での注意点

  Kubernetesクラスターが動作している状態で、ビルドにDockerコンテナを使う場合ですが、2つほど注意点がございます。
 ほとんどの手順は、 gitlab-ci説明書の『Dockerでアプリをビルドする』というページに書いてある通りなのですが、
 Kubernetesクラスターでビルドをしていくとなると、少し事情が異なる部分が生じます。

 

  「/var/run/docker.sock」が外部に外部に公開されてしまうリスク

  「/var/run/docker.sock」が外部に公開されてしまう、とありますが、そこからビルドコンテナの内部までもを覗かれてしまうリスクがあるところが、さらに怖いところです。
 「runners.kubernetes.volumes.host_path」オプションを使用することも、同様のリスクが伴います。

 ビルドコンテナに関連しているコンテナが、同じクラスター内にある場合などは特に、このオプションがセキュリティリスクを高めてしまいます。

 

  docker:dind」を使うリスク

  「docker:dind」機能は、docker-in-dockerイメージを使用しているときに使われる機能で、これ自体はKubernetesと連携しているときにも使えます。しかし、コンテナが特権モードでしか動かせなくなってしまうところが難点です。
 あらゆるセキュリティルスクを考慮しなくてはならない状況では、この機能を手放しでお勧めできるわけではありません。
 理由として、ビルドにKubernetesを使用している状態で、「.gitlab-ci.yaml」からDockerデーモン(たいていserviceコンテナ)を使用する場合、Dockerコンテナと Kubernetes Podとは、別のコンテナとして扱われていることが挙げられます。
 Pod内にあるコンテナ同士は、ボリュームとIPアドレスを共有しており、やり取りがローカルホスト内で完結するようにできています。
 「docker:dind」コンテナは「/var/run/docker.sock」を共有していません。そこで、dockerバイナリは「/var/run/docker.sock」をなるべく使うようにデフォルトで設定されています。
 Dockerバイナリに使用させるファイルを変更するには、tcpを使って、Dockerデーモンと交信を試みます。ビルドコンテナの環境変数を「DOCKER_HOST=tcp://localhost:2375」などのように設定してください。

 

  gitが適用されない問題

  Kubernetesをビルドに使用した状態で、Dockerイメージにビルドを試みることは、無益です。KubernetesからはDockerイメージにgitを移植することができません。
 それでもjobを実行するには「GIT_STRATEGY=none」を環境変数に追加して、「fetch」や「clone」を必要としないビルド方法を考えるしかありません。
 ビルドに使われるPodは、長期にわたって使用されることを想定しておらず、jobを経るにつれてその内容が変わっていきます。コードのテストをした後、ビルド、Dockerサービスコンテナの立ち上げの時点で、それぞれ全く別のPodを使用していると考えてください。

 ビルド工程にKubernetesとDockerを併用していると、「could not find git binary」という、エラーが表示されることがよくあります。
 Dockerサービスからも、「symlinks」が発見できなかったなどと表示されることがあります。なぜなら、本来ビルドに必要なgitコードを発見できなかったからです。

 

  リソースの分割で生じる問題

  「docker:dind」、「/var/run/docker.sock」の双方の問題において、Dockerデーモンがホストマシンのカーネル最深部に、安易に接続しやすいことが深く関わっています。
 たとえPodにいかなる制約(limits)を設けたとしても、それがDockerイメージの特性でまったく意味を無さなくなることが十分にありうるのです。
 Dockerデーモンは与えられたノードの資源をいっぱいまで使い果たします。そこでは、Kubernetesから作成されたビルド用Dockerコンテナが、作成時点にどれだけ強固な制約をかけられていようと、無効化されてしまいます。
 

  対策の1つとして、ビルドコンテナにはホストカーネルにあまり触れさせないような工夫が必要です。とくに特権モードが必要な操作(『/var/run/docker.sock』の使用・外部への暴露)などには注意が必要です。
 ここで「node_selector」オプションを使うのは、あらかじめラベル数に制限を設けることで、コンテナに必要以上にノードを乱用していないかなど、不審な動きに一定の監視がつけられるからです。
 たとえば、他のサービスコンテナたちが何らかのノードを使用している間、ビルドコンテナには「role=ci」というラベルがあるノードでしか活動できないように設定できます。

 Edit this page

 

 
PDF
更新日:2018-01-14 15:35:57 Hnoss 0  del.icio.usに追加   はてなブックマークに追加   twitterに投稿   facebookでshare
[ 原文 ] https://docs.gitlab.com/runner/executors/kubernetes.html 原文ページプロジェクト並びにドキュメントファイルは、MIT Licenseのもと公開されています。(URL:https://gitlab.com/gitlab-com/gitlab-docs/blob/master/LICENSE) この記事の文章は、訳者の判断によりCreative Commons BY (version 3.0) を適用するものとします。
翻訳者ページをみる

この記事の翻訳者

Hnoss さんの翻訳記事

【GitLab 公式 を訳してみた】API設定でパイプラインにトリガーを設ける

GitLab Documentation > GitLab Continuous Integration (GitLab CI) >API設定でパイプラインにトリガーを設ける 注: GitLab CE 7.14にて導入。 GitLab 8.12にて「job permiss…2018-01-22 14:29:44

【GitLab 公式 を訳してみた】 .gitlab-ci.yml 設定メニュー

 (訳者より: Qiitaにてynott様が公開されたバージョン もありますよ。向こうのほうが先輩です)  目次: > .gitlab-ci.yml とは  > image と services  > before_scr…2018-01-22 00:55:43

【GitLab 公式 を訳してみた】パイプラインのスケジュール

GitLab Documentation > User documentation > Projects > パイプラインのスケジュール 注: この機能はGitLab Runner 9.1から導入されました。当初の機能名は、「 Trigge…2018-01-16 20:15:49

【GitLab 公式 を訳してみた】CIサービス設定例

GitLab Documentation > GitLab Continuous Integration (GitLab CI) >CIサービス設定例  ベースイメージにリンクして使うためのDockerコンテナは、GitLab CIで「 service 」キー…2018-01-14 16:19:15