CITools > DevOpsSuite >

目次

概要

  • Concourseは、Pivotal Software, Inc. によって開発されているシンプル、スケーラブルが特徴のCIツールです。
  • はじめはPaaSのCound Foundry用に開発されましたが、OSSとして公開されており汎用のCIツールとして利用することが可能です。

インストール

by DockerCompose

  • info.pngDocker Repositoryに詳しい説明がありますので、あらかじめご参照ください。
  • note.pngホストOSの動作要件としてtux.pngLinux Kernel 3.19以上が必要となりますので、残念ながらcentos.pngCentOS 7は利用できません。debian.pngDebian 9かubuntu.pngUbuntu 16.04を利用するとよいでしょう。
  • 以下のセットアップでは、筆者の作成したcake.pngconcourse-ciクックブックを使用しています。
  1. 最も簡単なセットアップは、以下の chef-client コマンドのローカルモードを利用した方法です。Dockerエンジンがセットアップされた後、Docker Composeがインストールされ、Concourseサービス用の docker-compose.yml ファイルが生成されます。
    Ubuntu:$ sudo apt-get install ca-certificates curl git
    CentOS:$ sudo yum     install ca-certificates curl git
    $ curl -L https://omnitruck.chef.io/install.sh | sudo bash -s -- -v 12
    $ git clone git://git.osdn.net/gitroot/metasearch/grid-chef-repo.git
    $ cd grid-chef-repo/
    $ sudo chef-client -z -c solo.rb -j nodes/local-concourse-on-docker.json
    1. lightbulb.png設定のカスタマイズは、roles/concourse.rb で行うことができます。もし、DockerエンジンやDocker Composeがすでにインストール済みで、このクックブックでセットアップされたくない場合には、以下の skip_setup 属性を true にすることによりスキップすることができます。また同時にCLIツール fly をインストールしたい場合には、run_listの recipe[concourse-ci::fly] をアンコメントアウトします。
      1. # ...
      2. run_list(
      3.   #'recipe[ssl_cert::server_key_pairs]',  # for https
      4.   'role[docker]',
      5.   #'recipe[concourse-ci::fly]',
      6. )
      7.  
      8. override_attributes(
      9.   'docker-grid' => {
      10.     'engine' => {
      11.       #'skip_setup' => true,  # default: false
      12.     },
      13.     'compose' => {
      14.       #'skip_setup' => true,  # default: false
      15.     },
      16.   },
      17.   'concourse-ci' => {
      18.     # ...
      19.   },
      20. )
    2. Concourseの起動オプション(環境変数)の詳細については、以下のコマンドで確認することができます。
      $ docker run --rm concourse/concourse web --help
      $ docker run --rm concourse/concourse worker --help
  2. メッセージに従い、docker-compose コマンドでサービスを起動させます。

暗号化設定

  • ver. 3.1.0以降でデータの暗号化がサポートされました。必ず設定しましょう。
  • 有効にするには、web サブコマンドのパラメータ( --encryption-key)あるいは環境変数(CONCOURSE_ENCRYPTION_KEY)で16あるいは32バイト長のランダムキーを設定します。Docker Composeの場合には別ファイル(.env等)に切り出しアクセス権を適切に設定するとよいでしょう。
    • なお、cake.pngconcourse-ciクックブックでは、このキーをChefVaultで管理する仕組を提供しています。

OAuth認可設定

  • web サブコマンドのパラメータあるいは環境変数で、デフォルトである main チームの認証または認可方法を設定できます。以下は環境変数でOAuth認可を設定した場合の例です。
  • この例では、GitLabにアカウントのある全ユーザが main チームにパイプラインを作成することが可能になります。GitLab側の許可スコープは、api (Access your API)のみで十分です。
    環境変数設定例備考
    CONCOURSE_GENERIC_OAUTH_DISPLAY_NAME'GitLab'
    CONCOURSE_GENERIC_OAUTH_CLIENT_ID<CLIENT_ID>Docker Composeの場合には別ファイル(.env等)に切り出すとよいでしょう。
    CONCOURSE_GENERIC_OAUTH_CLIENT_SECRET<CLIENT_SECRET>同上
    CONCOURSE_GENERIC_OAUTH_AUTH_URL'https://gitlab.io.example.com/oauth/authorize'
    CONCOURSE_GENERIC_OAUTH_TOKEN_URL'https://gitlab.io.example.com/oauth/token'
    • なお、cake.pngconcourse-ciクックブックでは、このクライアントIDとシークレットをChefVaultで管理する仕組を提供しています。

既知の問題

独自サーバ証明書を用いた環境でinputs/outputsをともなったタスクのfly executeが失敗する

  • 自己署名や内部の独自CAで署名したサーバ証明書を用いたHTTPS環境では、今のところfly executeにCA証明書を渡す(または、非推奨ですが証明書のチェックを無効にする)手段がないため、inputs/outputsの遣り取り時に利用されている(archiveリソースでラップされている) curl が必ず失敗します。
    1. task-with-inputs.yml: 例としてこのような簡単なタスクを定義します。
      1. ---
      2. platform: linux
      3.  
      4. image_resource:
      5.   type: docker-image
      6.   source:
      7.     repository: alpine
      8.  
      9. inputs:
      10. - name: src-git
      11.  
      12. run:
      13.   path: /bin/sh
      14.   args:
      15.   - -c
      16.   - |
      17.     cat ./src-git/dummy.txt
      18.     echo '['`date '+%Y/%m/%d %H:%M:%S'`'] Success!'
    2. 実行すると必ず失敗します。inputs/outputsの遣り取りがないタスクについては問題ありません。
      $ fly -t mycc e -c task-with-inputs.yml -i src-git=./
      executing build 176
        % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                       Dload  Upload   Total   Spent    Left  Speed
        0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
      curl: (60) SSL certificate problem: unable to get local issuer certificate
      More details here: https://curl.haxx.se/docs/sslcerts.html
      
      curl performs SSL certificate verification by default, using a "bundle"
       of Certificate Authority (CA) public keys (CA certs). If the default
       bundle file isn't adequate, you can specify an alternate file
       using the --cacert option.
      If this HTTPS server uses a certificate signed by a CA represented in
       the bundle, the certificate verification probably failed due to a
       problem with the certificate (it might be expired, or the name might
       not match the domain name in the URL).
      If you'd like to turn off curl's verification of the certificate, use
       the -k (or --insecure) option.
      HTTPS-proxy has similar options --proxy-cacert and --proxy-insecure.
      gzip: invalid magic
      tar: Child returned status 1
      tar: Error is not recoverable: exiting now
      exit status 2
      failed
  • 参考リソース
    1. Forward locally configured CA cert to archive resource config #1063

特権が必要なカスタムリソースが失敗する(3.1.0以降)

  • 3.1.0以降で、環境によって特権が必要なカスタムリソース(例えばdocker-image-resourceをフォークしたもの)が以下のようなエラーで失敗することがあります。3.1.0からデフォルトでリソースコンテナの実行が非特権化されましたので、特権が必要な場合にはソースオプションに privileged: true を追加しなければなりませんが、それでもこの問題は発生します。
    mount: permission denied (are you root?)
  • 参考リソース
    1. Resources failing after upgrade to 3.1.0 #1230

トラブルシュート

独自CAのインポート

  • ConcourseはOAuth連携時にシステムのCAストアに基づきサーバ証明書の検証を行います。組織等の独自のCAを運営している場合には、あらかじめそれらのCA証明書を(Dockerの場合にはコンテナ内の)システムにインポートしておく必要があります。不備がある場合には、以下のようなエラーが発生します。
    1. concourse-web_1     | {"timestamp":"1487833602.399175644","source":"atc",
    2. "message":"atc.oauth-callback.callback.failed-to-exchange-token","log_level":2,
    3. "data":{"error":"Post https://gitlab.io.example.com/oauth/token: x509: certificate signed by unknown authority",
    4. "session":"12.1"} }
  • cake.pngconcourse-ciクックブックにはこのインポート機能があり、['concourse-ci']['with_ssl_cert_cookbook'] および ['concourse-ci']['docker-compose']['import_ca'] 属性を true にセットすることにより利用することができます。実際には、ChefVaultによりCA証明書を格納しておき、cake.pngssl_certクックブックの設定によりその証明書がロードされます。

The redirect URI included is not valid.

flyコマンドによるOAuth認可で127.0.0.1にリダイレクトされる

  • これは仕様のようです。なお、コールバックのためのリスンアドレスは以前は 0.0.0.0(ソースコードでは、:0) でしたが、今はさらにセキュアになり明示的に 127.0.0.1(同じく127.0.0.1:0) になっています。したがって、flyコマンドを実行するホストとブラウザの実行されているそれは同一である必要があります。もしリモートログインしたワークステーション上で fly login する場合には、その同じワークステーション上のテキストブラウザ等で提示されたURLにアクセスする必要があります。当然ながらトークンが遣り取りされますので、Concourse WebサーバはTLSで提供すべきです。
    $ fly -t mycc login
    logging in to team 'main'
    
    1: GitLab
    2: Basic Auth
    choose an auth method: 1
    navigate to the following URL in your browser:
    
        https://concourse.io.example.com:4443/auth/oauth?team_name=main&fly_local_port=44983
    
    or enter token manually:
  • リモートログインしたワークステーション上での別の回避方法としては、少々面倒ですがクエリパラメータ fly_local_port の部分(上の例では、"&fly_local_port=44983")を削除した上アクセスし、トークン(Bearer ...)が直接返されますのでそれをターミナルに貼り付けてログインを完了させます(これはfly loginの古いスタイルだそうです)。
  • 参考リソース
    1. UAA oAuth redirects to 127.0.0.1 #1196
    2. fly/commands/login.go
    3. atc/auth/oauth_callback_handler.go

flyコマンドの動作確認環境

  • 以下の環境にて動作を確認しています。
  1. Linux
  2. MSYS 1.0
  3. BashOnUbuntuOnWindows

主な使い方

  1. まずはログインします。-t オプションでサイトに適当なターゲット名を付与します。チーム名(-n)を省略した場合には、main になります。
    $ fly -t mycc login -c https://concourse.io.example.com:4443 -n main
    username: concourse
    password: 
    
    target saved
    • OAuth認可を利用している場合には、ブラウザで以下の応答がありログインが完了(クライアント側にトークンを保存)します。
      You've successfully logged in! You can now close this tab and return to fly.
  2. パイプラインの定義ファイルを作成し、セットします。
    1. hello.yml
      1. jobs:
      2. - name: hello-world
      3.   plan:
      4.   - task: say-hello
      5.     config:
      6.       platform: linux
      7.       image_resource:
      8.         type: docker-image
      9.         source: {repository: ubuntu}
      10.       run:
      11.         path: echo
      12.         args: ["Hello, world!"]
    2. パイプライン名を付けてセットします。
      $ fly -t mycc set-pipeline -p hello-world -c hello.yml
      jobs:
        job hello-world has been added:
          name: hello-world
          plan:
          - task: say-hello
            config:
              platform: linux
              image_resource:
                type: docker-image
                source:
                  repository: ubuntu
              run:
                path: echo
                args:
                - Hello, world!
                dir: ""
          
      apply configuration? [yN]: y
      pipeline created!
      you can view your pipeline here: https://concourse.io.example.com:4443/teams/main/pipelines/hello-world
      
      the pipeline is currently paused. to unpause, either:
        - run the unpause-pipeline command
        - click play next to the pipeline in the web ui
  3. パイプラインのポーズを解除し、実行していきます。
    $ fly -t mycc unpause-pipeline -p hello-world
    unpaused 'hello-world'
    
    $ fly -t mycc pipelines
    name         paused  public
    hello-world  no      no
    
    $ fly -t mycc trigger-job -j hello-world/hello-world
    started hello-world/hello-world #1
    
    $ fly -t mycc builds
    id  pipeline/job             build  status     start                     end                       duration
    1   hello-world/hello-world  1      succeeded  2017-02-16@22:25:27+0900  2017-02-16@22:26:56+0900  1m29s
    
    $ fly -t mycc expose-pipeline -p hello-world
    exposed 'hello-world'
    
    $ fly -t mycc pipelines
    name         paused  public
    hello-world  no      yes

チームの作成や設定

  • set-team サブコマンドで行います。
    $ fly set-team -h
    error: Usage:
      fly [OPTIONS] set-team [set-team-OPTIONS]
    
    Application Options:
      -t, --target=                                Concourse target name
      -v, --version                                Print the version of Fly and exit
          --print-table-headers                    Print table headers even for redirected output
    
    Help Options:
      -h, --help                                   Show this help message
    
    [set-team command options]
          -n, --team-name=                         The team to create or modify
    
        Authentication:
              --no-really-i-dont-want-any-auth     Ignore warnings about not configuring auth
    
        Basic Authentication:
              --basic-auth-username=               Username to use for basic auth.
              --basic-auth-password=               Password to use for basic auth.
    
        GitHub Authentication:
              --github-auth-client-id=             Application client ID for enabling GitHub OAuth.
              --github-auth-client-secret=         Application client secret for enabling GitHub OAuth.
              --github-auth-organization=ORG       GitHub organization whose members will have access.
              --github-auth-team=ORG/TEAM          GitHub team whose members will have access.
              --github-auth-user=LOGIN             GitHub user to permit access.
              --github-auth-auth-url=              Override default endpoint AuthURL for Github Enterprise.
              --github-auth-token-url=             Override default endpoint TokenURL for Github Enterprise.
              --github-auth-api-url=               Override default API endpoint URL for Github Enterprise.
    
        UAA Authentication:
              --uaa-auth-client-id=                Application client ID for enabling UAA OAuth.
              --uaa-auth-client-secret=            Application client secret for enabling UAA OAuth.
              --uaa-auth-auth-url=                 UAA AuthURL endpoint.
              --uaa-auth-token-url=                UAA TokenURL endpoint.
              --uaa-auth-cf-space=                 Space GUID for a CF space whose developers will have access.
              --uaa-auth-cf-url=                   CF API endpoint.
              --uaa-auth-cf-ca-cert=               Path to CF PEM-encoded CA certificate file.
    
        Generic OAuth Authentication (Allows access to ALL authenticated users):
              --generic-oauth-display-name=        Name for this auth method on the web UI.
              --generic-oauth-client-id=           Application client ID for enabling generic OAuth.
              --generic-oauth-client-secret=       Application client secret for enabling generic OAuth.
              --generic-oauth-auth-url=            Generic OAuth provider AuthURL endpoint.
              --generic-oauth-auth-url-param=      Parameter to pass to the authentication server AuthURL. Can be specified multiple times.
              --generic-oauth-scope=               Optional scope required to authorize user
              --generic-oauth-token-url=           Generic OAuth provider TokenURL endpoint.
  1. チームの作成とOAuthの設定例、client-idとclient-secretについてはコマンドラインに直接与えるのではなく、環境変数を経由するとよりセキュアでしょう。
    $ fly -t mycc set-team -n myteam \
        --generic-oauth-display-name 'GitLab' \
        --generic-oauth-client-id **************************************************************** \
        --generic-oauth-client-secret **************************************************************** \
        --generic-oauth-auth-url https://gitlab.io.example.com/oauth/authorize \
        --generic-oauth-token-url https://gitlab.io.example.com/oauth/token

秘密情報の扱い

  1. 定義ファイル中に必要なユーザIDやパスワードをプレイスホルダ({{mustache}}記法)で記述し、別ファイル(credentials.yml等、バージョン管理不可)の値でパイプライン設定時にリプレイスすることができます。
    1. info.pngset-pipeline: Configuring Pipelines
  2. note.pngただし、今のところ以下の制限があります。
    1. 値を丸ごと置換しなければなりません。値の一部に{{mustache}}記述を用い文字列連結をすること(たとえば、"{{NG}}value")はできません。
    2. YAMLファイルでコメントアウトした行に{{mustache}}記述が含まれた場合でもリプレイスを試みてしまいます。そして、バインド対象のパラメータ定義が見つからない場合エラーとなります。
  3. star.pngfly 3.2.0以降で新しいプレイスホルダ(((param))記法)が導入され、文字列連結が可能となりました。今後はこれを使用するとよいでしょう。

サーバメンテナンス

by DockerCompose

  1. マシンの再起動等でコンテナが停止された場合、キャッシュなどが不正に残りタスクが失敗することがあります。そのようなときには一度サービスをdownさせてからupします。
    $ sudo docker-compose down
    $ sudo docker-compose up -d

アップデート

DockerComposeの場合

  1. 最新のイメージを取得し、サービスを再起動します。
    $ sudo docker-compose down
    $ sudo docker-compose pull
    $ sudo docker-compose up -d

不良(stalled)ワーカの削除

  1. 応答のない不良ワーカを一括して削除します。
    $ export CC_TARGET=mycc
    $ fly -t $CC_TARGET ws | awk '$6=="stalled" {print $1}' | xargs -t -n 1 --no-run-if-empty fly -t $CC_TARGET prune-worker -w
  • lightbulb.pngconcourse-ciクックブックではこのクリーンアップを行うスクリプトを提供していますので、以下のようなcronの設定でDockerComposeでの起動と不良ワーカの削除を実行することができます。
    1. PATH=/usr/bin:/bin:/usr/local/bin
    2. CC_HOME=/opt/docker-compose/app/concourse
    3. CC_LOG=/var/log/concourse-cron.log
    4.  
    5. @reboot root sleep 300s && ${CC_HOME}/bin/concourse_start >> $CC_LOG 2>&1
    6. 30 */4 * * * root ${CC_HOME}/bin/fly_prune_workers_main >> $CC_LOG 2>&1

チューニング

デフォルトのリソースチェック間隔

  • リソースのチェック間隔(check_every)はデフォルトで毎分(1m)の設定ですが、webの起動パラメータ --resource-checking-interval(環境変数の場合には、CONCOURSE_RESOURCE_CHECKING_INTERVAL)でそのデフォルト値を変更することができます。関連システムへの負荷が懸念される場合には、長め(10m, 1h ...)に設定するとよいでしょう。
  • なお、このチェック間隔を低頻度に変更した場合には、timeリソースの interval が高頻度設定されている個別のリソースについて check_every 設定を適切に(それぞれの頻度に合わせて)明示設定しておく必要があります。

Tips

参考リソース

  1. https://concourse.ci/

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2018-05-03 (木) 12:51:30 (78d)