Help us understand the problem. What is going on with this article?

ArgoでCIパイプラインを構築する

実現したいこと

argo workflowを使ってCIパイプラインを構築する
今回はリポジトリのクローンまで
対象はGithubプライベートリポジトリ(内容は前回と同じ)

環境

  • Golang 1.13.5
  • Docker 18
  • AWS 東京リージョン

argoはAWS EKSクラスターに配置

やったこと

Argoの導入

基本的には Argo公式ドキュメントに沿って進める

前提としてEKSにCI用クラスタ ci-cluster を作成しておく

# namespaceの作成
kubectl create ns argo

# install.yamlをダウンロードしてargo namespaceにapply
kubectl apply -n argo -f https://raw.githubusercontent.com/argoproj/argo/v2.2.1/manifests/install.yaml

# default namespaceのサービスアカウントにadmin権限を付与
kubectl create rolebinding default-admin --clusterrole=admin --serviceaccount=default:default

とりあえずexampleを動かす

Argoはyamlでパイプラインを記述する
例として公式exampleのconflip.yamlを実行する

coinflip.yaml

# The coinflip example combines the use of a script result,
# along with conditionals, to take a dynamic path in the
# workflow. In this example, depending on the result of the
# first step, 'flip-coin', the template will either run the
# 'heads' step or the 'tails' step.
apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
  generateName: coinflip-
spec:
# entorypointで指定されたtemplates.nameが起動時に実行される
  entrypoint: cinflip
  templates:
  # ここからパイプラインの構成
  - name: coinflip
    steps:
    # name: タスクの名前
    - - name: flip-coin
        # 実際のタスクの処理への参照
        template: flip-coin
    # - - name: stage-name で直列のタスクになる
    - - name: heads
        template: heads
        when: "{{steps.flip-coin.outputs.result}} == heads"
    # - name: stage-name で直前のタスクと並列のタスクになる
      - name: tails
        template: tails
        when: "{{steps.flip-coin.outputs.result}} == tails"
  # パイプラインの構成ここまで


  # タスクの中身の定義
  - name: flip-coin
    # タスク毎にPodが立ち上がるのでそれぞれのタスクで起動するイメージを指定する
    script:
      image: python:alpine3.6
      # タスク内で実行するコマンドの言語指定 今回はpython
      command: [python]
    # 実際に実行させる処理
      source: |
        import random
        result = "heads" if random.randint(0,1) == 0 else "tails"
        print(result)

  - name: heads
    container:
      image: alpine:3.6
      # タスク内で実行するコマンドの言語指定 今回はshell
      command: [sh, -c]
      args: ["echo \"it was heads\""]

  - name: tails
    container:
      image: alpine:3.6
      command: [sh, -c]
      args: ["echo \"it was tails\""]

パイプラインの実行はargo submitで行う

argo submit coinflip.yaml

Name:                coinflip-pwk7p
Namespace:           argo
ServiceAccount:      default
Status:              Pending
Created:             Thu Jan 23 09:52:11 +0900 (1 second from now)

これで argo namespace上にタスク毎のPodが立ち上がりそれぞれ順に実行される
今回であれば作成されるPodは3つ
作成されるPod名は以下の通り
${metadata.generateName}{パイプライン毎のプレフィクス}-{タスク毎のプレフィクス}
今回であれば例えばcoinflip-pwk7p-4162510633


UIツールでパイプラインを監視する

argoにはUIツールが備わっているので,パイプラインの構成が複雑になる場合などに有用である.
前段でinstall.yamlを使ってargoの起動をした場合は,既にargo-ui-{プレフィクス}という名前のPodが立てられているはず.
以下のコマンドでUIツールをlocalhost:8001にポートフォワードする

kubectl -n argo port-forward deployment/argo-ui 8001:8001

これでブラウザでパイプラインの実行を確認できるようになった.


UIツールをインターネットから確認する

localhostから確認しているUIツールをインターネット経由で確認できるようにする
これで,確認のために毎回ポートフォワードする必要がなくなる

argo-ui serviceのTypeを ClusterIPからLoadBalancerに変更する

argoを導入した際のinstall.yamlを編集する

.
.
.
apiVersion: v1
kind: Service
metadata:
  name: argo-ui
  namespace: argo
# TypeをLoadBalancerに変更
spec:
  type: LoadBalancer
  # アクセス元IPアドレスを制限したい場合は記述
  loadBalancerSourceRanges:
    - "ALLOWED ACCESS IP"
  ports:
  - port: 80
    targetPort: 8001
  selector:
    app: argo-ui
.
.
.

これを再度 applyすればLoadBalancerのエンドポイントからargo-uiにアクセスできる

Githubから

大筋は公式exampleのinput-artifact-git.yaml

apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
  generateName: input-artifact-git-
spec:
  entrypoint: git-clone
  templates:
  - name: git-clone
    inputs:
      artifacts:
      - name: argo-source
        path: /src
        git:
          repo: https://github.com/argoproj/argo.git
          revision: "v2.1.1"
    container:
      image: golang:1.10
      command: [sh, -c]
      args: ["git status && ls && cat VERSION"]
      workingDir: /src

このパイプラインはgit-cloneタスク1つのみの単純なもので
git-cloneも実行しているコマンドは git status && ls && cat VERSION" のみ
ただ,このタスクの実行前にgitリポジトリのリソースを入力Artifactとして/src配下に配置している

今回は myOrg/myRepo リポジトリのmasterブランチをクローンしたいので以下のようになる

apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
  generateName: input-artifact-git-
spec:
  entrypoint: git-clone
  templates:
  - name: git-clone
    inputs:
      artifacts:
      - name: argo-source
        # リポジトリの中身を配置するディレクトリ
        path: /src
        # gitリポジトリ指定
        git:
          repo: https://github.com/myOrg/myRepo.git
          revision: "master"
    container:
      image: golang:1.10
      command: [sh, -c]
      args: ["git status && ls && cat VERSION"]
      workingDir: /src

プライベートリポジトリからクローンする

前段の方法ではパブリックリポジトリしかクローンできない
プライベートリポジトリからクローンする場合にはgitの認証情報を登録する必要がある

再びinput-artifact-git.yamlを参考にすると下記のようになる

apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
  generateName: input-artifact-git-
spec:
  entrypoint: git-clone
  templates:
  - name: git-clone
    inputs:
      artifacts:
      - name: argo-source
        # リポジトリの中身を配置するディレクトリ
        path: /src
        # gitリポジトリ指定
        git:
          repo: https://github.com/myOrg/myRepo.git
          revision: "master"
          # gitの認証情報を指定
          # kubernetes Secretから github-creds.usernameを取得する
          usernameSecret:
            name: github-creds
            key: username
          # kubernetes Secretから github-creds.passwordを取得する
          passwordSecret:
            name: github-creds
            key: password

    container:
      image: golang:1.10
      command: [sh, -c]
      args: ["git status && ls && cat REDOME.md"]
      workingDir: /src

パイプラインの定義ファイルに直接認証情報を書くのではなくKubernetesのSecretsに格納された認証情報を呼び出す
今回は github-credsに usernameとpasswordという名前で登録しておく


動かす

argo submit input-artifact-git.yaml

ちゃんとクローンできた

完成

とりあえずgitプライベートリポジトリからクローンができるところまで完成
この後testだったりbuildだったりを記述していく
ここから先は他のciツールと大差ない(と思っている)

つまづいたところは,

  • Secret内の認証情報をタスク内で参照するところ
  • admin権限を付与するサービスアカウントを間違えていたこと
  • タスク内でechoやprintした内容が各podのログに出力されていたこと

各タスクのログはタスクを実行するPodに出力されるのでエラーが起きた際には,
どのタスク内でパイプラインが止まったのかを見て,そのPodの中に入るといった手順が必要
stern などのPod横断で監視できるツールを導入するのが良さそう

そのあと

gitクローンだけではCIとはとても呼べないので,このあとはクローンしたリソースを使ってtest/build/imageプッシュをしていく

また,手動でパイプラインを動かしているのでgithubのwebhookを使って,masterブランチのpushをトリガーにパイプラインの実行ができるようにargo eventsを導入する

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした