Container Engine での Jenkins

このトピックでは、Google Container Engine で Jenkins を使用するためのおすすめの方法について説明します。このソリューションを実装するには、Container Engine での Jenkins の設定をご覧ください。

Jenkins は、ビルド、テスト、デプロイ パイプラインを柔軟に調整できるオープンソースのオートメーション サーバーです。Container Engine は、強力なクラスタ マネージャでコンテナのオーケストレーション システムである Kubernetes のホストされたバージョンです。

継続的配信(CD)パイプラインを設定する必要がある場合、Container Engine に Jenkins をデプロイすることで、標準の VM ベースのデプロイを上回る次のような重要なメリットがもたらされます。

  • ビルドプロセスでコンテナを使用すると、1 つの仮想ホストで異なるオペレーティング システムに対してジョブを実行することができます。

  • Container Engine は、各ビルドが以前のビルドと同じクリーンな環境で実行できるように、エフェメラル ビルド エグゼキュータを提供します。

    • ビルド エグゼキュータが短命な一因は、ビルドが活発に実行されているときには Container Engine クラスタのみが使用され、バッチ処理ジョブなどの他のクラスタタスクのために利用可能なリソースを残すためです。

    • ビルド エグゼキュータは数秒で起動します。

  • Container Engine は Google のグローバル ロードバランサを利用して、ウェブ トラフィックをインスタンスにルーティングします。ロードバランサは、SSL ターミネーションを処理し、Google のバックボーン ネットワークを介して、ユーザーに最も近い POP(point of presence)からの最速パスのいずれかにあるウェブ フロント エンドにユーザーをルーティングするグローバル IP アドレスを提供します。

Container Engine クラスタのデプロイ

Container Engine クラスタをデプロイする際には、次のサービスに対して認証スコープを有効にします。

  • Google Cloud Storage - storage-rw

    • Jenkins は、Google Container Registry(Cloud Storage にコンテンツを保存するサービス)にアクセスする必要があります。
  • Google Cloud Source Repositories - projecthosting

    • Cloud Source Repositories は、自分のソースコードに使用できる非公開レポジトリを提供します。Jenkins はこれらのレポジトリから pull して、可能な限り迅速にコードをビルド、テスト、デプロイできます。

たとえば、クラスタを作成する際に、次のようなコードを使用することができます。

gcloud container clusters create jenkins-cd \
         --network jenkins \
         --scopes "https://www.googleapis.com/auth/projecthosting,storage-rw"

他の Google サービスを利用する場合は、追加のスコープを追加することができます。

Jenkins マスターのデプロイ

以下の図は、マルチノードの Kubernetes クラスタで Jenkins をデプロイするためのアーキテクチャを示しています。

Jenkins と Kubernetes アーキテクチャ

Jenkins マスターを Kubernetes クラスタ内の別の名前空間にデプロイします。名前空間を使用することで、Jenkins のデプロイ用に割り当てを作成したり、Jenkins をクラスタ内で他のデプロイから論理的に分離したりすることができます。

Kubernetes の名前空間を作成するには、次のコマンドを入力します。

kubectl create namespace jenkins

Jenkins サービスの作成

Jenkins は、クラスタがアクセスする必要がある 2 つのサービスを提供します。これらのサービスを別々にデプロイすることで、これらを個別に管理して名前を付けることができます。

  • ポート 8080 上で外部に公開されている NodePort サービスは、ポッドと外部ユーザーが Jenkins のユーザー インターフェースにアクセスすることを許可します。このタイプのサービスは、HTTP ロードバランサによって負荷分散することができます。

  • ポート 50000 上の内部の非公開 ClusterIP サービスは、Jenkins エグゼキュータがクラスタ内から Jenkins マスターと通信するために使用します。

以降のセクションでは、サービス定義のサンプルを示します。

---
  kind: Service
  apiVersion: v1
  metadata:
    name: jenkins-ui
    namespace: jenkins
  spec:
    type: NodePort
    selector:
      app: master
    ports:
      - protocol: TCP
        port: 8080
        targetPort: 8080
        name: ui
---
  kind: Service
  apiVersion: v1
  metadata:
    name: jenkins-discovery
    namespace: jenkins
  spec:
    selector:
      app: master
    ports:
      - protocol: TCP
        port: 50000
        targetPort: 50000
        name: slaves

Jenkins のデプロイの作成

Jenkins マスターを、レプリカ数 1 のデプロイとして導入します。これにより、クラスタ内で常に 1 つの Jenkins マスターが実行されていることが保証されます。Jenkins マスターポッドが停止するか、ポッドが実行されているノードがシャットダウンすると、Kubernetes はクラスタ内の他の場所でポッドを再起動します。

スケジュールされる前に、デプロイ定義の一環としてリクエストと制限を設定し、コンテナに一定量の CPU とメモリリソースがクラスタ内にあることが保証されるようにすることが重要です。そうしないと、CPU またはメモリの不足により、マスターがダウンする場合があります。

Jenkins ホーム ボリュームには、XML 設定ファイルと設定を構成するプラグイン JAR ファイルが格納されています。次のおすすめの設定や方法を考慮してください。

  • ホーム ディレクトリを格納するための永続ディスクを作成して、Jenkins マスターを実行しているポッドがダウンした場合でも、重要な設定データが保持されことを保証します。

  • ディスクは 10 GB 以上にします。

  • ボリュームが作成されたら、仮想マシンに接続して、ボリュームをフォーマットする必要があります。その後、すべての仮想マシンからボリュームをマウント解除して接続を解除します。これでデプロイでボリュームを使用することができます。

次のコードは、サンプルのデプロイ定義を示しています。

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: jenkins
  namespace: jenkins
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: master
    spec:
      containers:
      - name: master
        image: jenkins/jenkins:2.67
        ports:
        - containerPort: 8080
        - containerPort: 50000
        readinessProbe:
          httpGet:
            path: /login
            port: 8080
          periodSeconds: 10
          timeoutSeconds: 5
          successThreshold: 2
          failureThreshold: 5
        env:
        - name: JENKINS_OPTS
          valueFrom:
            secretKeyRef:
              name: jenkins
              key: options
        - name: JAVA_OPTS
          value: '-Xmx1400m'
        volumeMounts:
        - mountPath: /var/jenkins_home
          name: jenkins-home
        resources:
          limits:
            cpu: 500m
            memory: 1500Mi
          requests:
            cpu: 500m
            memory: 1500Mi
      volumes:
      - name: jenkins-home
        gcePersistentDisk:
          pdName: jenkins-home
          fsType: ext4
          partition: 1

Jenkins への接続

Kubernetes クラスタ内のすべてのポッドは、ホスト名 master.jenkins.svc とポート 8080 を使用して、Jenkins のユーザー インターフェースにアクセスすることができます。

Jenkins ポッドが作成されたら、ロードバランサのエンドポイントを作成して、Cloud Platform の外側から接続することができます。次のおすすめの設定や方法を考慮してください。

  • SSL ターミネーションを使って、設定しやすい L7 ロードバランサに Kubernetes の上りリソースを使用します。

  • Kubernetes シークレットを使用して、ロードバランサに SSL 証明書を提供します。tls.certtls.key の値を使用し、上りリソース設定でこれらの値を参照します。

Jenkins の設定

Jenkins のセキュリティ保護

初めて Jenkins に接続したら、すぐに Jenkins をセキュリティ保護することが重要です。内部ユーザー データベースを利用する、Jenkins の標準的なセキュリティの設定チュートリアルの簡単な手順に沿って操作できます。この設定を行うことで、追加のインフラストラクチャを必要としなくとも、匿名ユーザーをロックアウトする機能を利用できるようになります。

プラグインのインストール

次のプラグインをインストールして、Jenkins と Container Engine との相互作用を高めることができます。

  • Kubernetes プラグインは、認証に Kubernetes サービス アカウントを使用すること、および異なるベースイメージを使用してラベル付きのエグゼキュータの設定を作成することができます。このプラグインは、エグゼキュータが必要な場合にポッドを作成して、ジョブが終了したらそのポッドを破壊します。

  • Google Authenticated Source プラグインは、Cloud Source Repositories などの Cloud Platform サービスにアクセスする際に、自分のサービス アカウントの認証情報を使用できるようにします。

こちらの指示に沿ってプラグインをインストールします。

Container Engine 用に Jenkins を設定

Container Engine 用に Jenkins を設定する詳しい手順(ビルド エグゼキュータの設定、認証情報の追加など)については、Container Engine 用に Jenkins を設定をご覧ください。

Docker イメージのカスタマイズ

ポッド テンプレートを作成する際に、既存の Docker イメージを提供するか、ビルド時の依存関係のほとんどがインストールされたカスタム イメージを作成できます。カスタム イメージを使用すると、全体のビルド時間を短縮し、より一貫性のあるビルド環境を作成することができます。

カスタムの Docker イメージでは、Jenkins JNLP スレーブ エージェントをインストールして設定する必要があります。JNLP エージェントは、Jenkins ジョブの実行とジョブ ステータスのレポートを調整するため、Jenkins マスターと通信するソフトウェアです。

オプションとして、FROM jenkinsci/jnlp-slave をイメージ設定に追加することができます。たとえば、アプリケーションのビルドプロセスが Go のランタイムに依存している場合、次の Dockerfile を作成して、既存のイメージを独自の依存関係とビルド アーティファクトを使用して拡張することができます。

FROM jenkinsci/jnlp-slave
RUN apt-get update && apt-get install -y golang

次に、以下のコマンドを実行して、イメージをビルドしてプロジェクトの Container Registry レポジトリにアップロードします。

docker build -t gcr.io/[PROJECT]/my-jenkins-image .
gcloud docker -- push gcr.io/[PROJECT]/my-jenkins-image

これで、ポッド テンプレートを作成するとき、Docker イメージ フィールドに次の文字列を設定できます。[PROJECT] は実際のプロジェクト名、[IMAGE_NAME] はイメージ名に置き換えます。

gcr.io/[PROJECT]/[IMAGE_NAME]

上記の例は、Jenkins ジョブの開始時に、Go 言語のランタイムが事前にインストールされていることを保証します。

Jenkins のアップグレード

Jenkins マスターをアップグレードするには、デプロイ マニフェストを編集して、image プロパティのタグ値をアップグレード後のバージョンに変更します。Jenkins バージョンが定義されているマニフェストの場所の例については、こちらのマニフェスト ファイルをご覧ください。利用可能なバージョンのリストについては、Docker の Jenkins イメージタグ リストをご覧ください。

ファイルを編集したら、次のコマンドを使用して、変更をデプロイします。

kubectl apply -f jenkins.yaml

次のステップ

このページは役立ちましたか?評価をお願いいたします。

フィードバックを送信...