「Tekton シリーズ実践 - 初めてのパイプライン」では、最初のパイプラインを実装しましたが、このパイプラインはまだ比較的単純で、基本的な機能を完了しています。この記事では、Jenkins の Jenkinsfile に基づいて独自の Tekton Pipeline をカスタマイズする方法を説明します。 まず、Jenkinsfile が次のようにどのようになっているかを見てみましょう。 def dingmes = 新しいorg 。 DevOps 。 送信DingTalk () デフBUILD_USER デフIS_IMAGE_PUSH
パイプライン エージェント Kubernetes { ラベル「jenkins-slave-${UUID.randomUUID().toString()}」 yaml "" " APIバージョン: v1 種類: ポッド 仕様: ノードセレクタ: kubernetes .io / ホスト名: node - 2 コンテナ: - 名前: gradle 画像: レジストリ。 cn - 杭州。 アリユンクス。 com / coolops / ビルダー- gradle : v2 コマンド: [ 'cat' ] 端末: 真 ボリュームマウント: - 名前: キャッシュ マウントパス: /root/.gradle/cache/ - 名前: indocker マウントパス: /var/run/docker.sock - 名前: ヘルム イメージ: registry.cn-hangzhou.aliyuncs.com/coolops/helm3:3.2.4 コマンド: [ 'cat' ] 端末: 真 - 名前: ソナー 画像: レジストリ。 cn - 杭州。 アリユンクス。 com / coolops / gradle : 5.6 .4 - jdk11 コマンド: [ 'cat' ] 端末: 真 ボリュームマウント: - 名前: ソナーキャッシュ マウントパス: /root/.gradle/cache/ 巻数: - 名前: キャッシュ ホストパス: パス: "/data/jenkins-job/${JOB_NAME}/gradle/" - 名前: indocker ホストパス: パス: "/var/run/docker.sock" - 名前: ソナーキャッシュ ホストパス: パス: "/data/jenkins-job/${JOB_NAME}/sonar/" 「」 「 」 } } 環境 APP_NAME = "${params.APP_NAME}" DOCKER_CREDENTIAL_ID = 'dockerhub-token' GIT_CREDENTIAL_ID = 'git-token' SONAR_CREDENTIAL_ID = 'ソナートークン' KUBECONFIG_CREDENTIAL_ID = 'kubeconfig-token' レジストリ= 'registry.cn-hangzhou.aliyuncs.com' DOCKERHUB_NAMESPACE = 'coolops' チャート= 'coolops/rd' CHART_USERNAME = xxx CHART_PASSWORD = xxx IMG_REPO = "$REGISTRY/$DOCKERHUB_NAMESPACE/$APP_NAME" IMG_TAG = "$GIT_COMMIT" COMMON_ARGS = "--set image.repository=$IMG_REPO \ --set image.tag=$IMG_TAG \ --set ingress.hosts[0].paths[0]=/ " }
パラメータ{ 選択肢( 説明: 'Gradle --refresh-dependencies パラメータを使用して Jar パッケージを強制的に更新する' 、 名前: 'refresh' 、 選択肢: [ 'false' 、 'true' ]) }
オプション{ タイムアウト( 時間: 30 、 単位: '分' ) }
ステージ{ ステージ( 'チェックアウトSCM' ) { 手順{ チェックアウト( scm ) } } ステージ( 'ビルドとプッシュ' ) { 手順{ コンテナ( 'Gradle' ) { withCredentials ([ usernamePassword ( credentialsId : "$DOCKER_CREDENTIAL_ID" , passwordVariable : 'DOCKER_PASSWORD' , usernameVariable : 'DOCKER_USERNAME' )]) { sh 'echo "$DOCKER_PASSWORD" | docker ログイン $REGISTRY -u "$DOCKER_USERNAME" --password-stdin' sh '' ' エクスポートEXIST_IMG = $ ( docker pull $IMG_REPO : $IMG_TAG &>/ dev / null && echo true || echo false ) $EXIST_IMG をエコーする [ $refresh == "true" - o $EXIST_IMG == "false" ] の場合 それから echo "イメージのコンパイルとプッシュを開始します" ; $refresh && gradle clean bootJar -- オンデマンドで構成-- キャッシュをビルド-- 依存関係を更新|| gradle clean bootJar -- オンデマンドで構成-- ビルドキャッシュ docker build -f Dockerfile -t $ IMG_REPO : $IMG_TAG 。 ; docker push $IMG_REPO : $IMG_TAG ; それ以外 echo "イメージは既に存在します。コンパイルをスキップします" ; フィ '' ' } } } } ステージ( 'helm3 リポジトリを追加' ) { 手順{ コンテナ( 'helm' ) { 資格情報付き([ kubeconfigContent ( credentialsId : 'kubeconfig-token' , 変数: 'kubconfig' ,)]) { sh '' ' セット+ x mkdir ~ / .kube / echo " $kubconfig " > ~ / .kube / config '' ' sh 'helm repo add coolops https://repomanage.rdc.aliyun.com/helm_repositories/66465-coolops --username=${CHART_USERNAME} --password=${CHART_PASSWORD}' } } } } } ステージ( 'Dev にデプロイ' ) { 環境 名前空間= 'coolops-dev' ENV = 'dev' } いつ{ 表現{ "$BRANCH_NAME" を返します。 ( 'dev' ) を含む } } 手順{ コンテナ( 'helm' ) { スクリプト{ ステップヘルム() } } } } ステージ( 'テストにデプロイ' ) { 環境 名前空間= 'coolops-test' ENV = 'テスト' } いつ{ 表現{ "$BRANCH_NAME" を返します。 ( 'テスト' ) を含む } } 手順{ コンテナ( 'helm' ) { スクリプト{ ステップヘルム() } } } } ステージ( 'UAT にデプロイ' ) { 環境 名前空間= 'coolops-uat' ENV = 'uat' } いつ{ 表現{ "$BRANCH_NAME" を返します。 ( 'uat' ) を含む } } 手順{ コンテナ( 'helm' ) { スクリプト{ ステップヘルム() } } } }
ステージ( 'Pre にデプロイ' ) { 環境 名前空間= 'coolops-pre' ENV = 'pre' } いつ{ 表現{ "$BRANCH_NAME" を返します。 ( 'pre' ) を含む } } 手順{ コンテナ( 'helm' ) { スクリプト{ ステップヘルム() } } } } ステージ( '本番環境にデプロイ' ) { 環境 名前空間= 'coolops-prod' ENV = 'prod' } いつ{ 表現{ "$BRANCH_NAME" を返します。 ( 'prod' ) を含む } } 手順{ コンテナ( 'helm' ) { スクリプト{ ステップヘルム() } } } } ステージ( 'Sonarqube スキャナー' ) { いつ{ 表現{ "$JOB_NAME" を返します。 含む( 'スキップ' ) } } 手順{ タイムアウト( 時間: 20 、 単位: '分' ) { catchError ( ビルド結果: '成功' 、 ステージ結果: '失敗' ) { コンテナ( 'ソナー' ) { sh 'gradle sonarqube \ -x テスト\ -Dsonar.host.url=http://sonar.coolops.cn \ -Dsonar.login=c17650fa820d985daf1f29d8a3f685d789e47e45' } } } } } } } Jenkinsfile 全体にいくつか削除を加えましたが、プロセス全体は変更されていません。一見すると、同じくらい簡単ではないでしょうか?手順を次のように整理しました。 - コード リポジトリからコードを取得します。
- コードをコンパイルしてリポジトリにプッシュします。
- 異なるブランチに応じて異なる環境にプッシュします。
- コードスキャン。
全体的なプロセスは前回の記事とあまり変わりませんが、違いは次のとおりです。 - マルチブランチパイプラインリリース。
- kubectl から helm チャートに変更しました。
- コードスキャンを追加しました。
ここでは、Helm Chart を使用してアプリケーションをデプロイします。 Alibaba Cloud の Chart リポジトリを使用します。使い方が分からない方は、Alibaba Cloud -->Yunxiao DevOps -->R&D -->Private Warehouse から申請できます。 まずタスクを作成し、次にパイプラインを組み立てます。 Helm Chartを使用してアプリケーションタスクを公開する前回の記事では、kubectl を使用してアプリケーションを公開しました。実際の使用では、Helm を使用して管理します。一貫性を維持するために、ここではまず Helm がアプリケーションを公開するためのタスクを作成します。 作成する前に、パラメータが必要な場所を確認しましょう。 - 名前空間:環境ごとに異なる名前空間があるため、複数のブランチで公開するときに名前空間を指定する必要があります。
- app_name:アプリケーション名。
- chart_name: Helm チャート名。
- args: Helm チャートの追加パラメータ。
したがって、タスクを次のように定義します。 apiバージョン: tekton.dev/v1alpha1 種類: タスク メタデータ: 名前: helm - to - k8s 仕様: ワークスペース: - 名前: ソース - 名前: kubernetesconfig マウントパス: / root / 。 キューブ パラメータ: - 名前: 画像 - 名前: タグ - 名前: 名前空間 - 名前: BRANCH_NAME - 名前: CHART_NAME - 名前: CHART_USERNAME - 名前: CHART_PASSWORD - 名前: APP_NAME 手順: - 名前: 実行- ヘルム イメージ: registry.cn-hangzhou.aliyuncs.com/coolops/helm3:3.2.4 作業ディレクトリ: $ ( ワークスペース. ソース. パス) スクリプト: | helm リポジトリにcoolops を追加しますhttps://repomanage.rdc.aliyun.com/helm_repositories/66465-coolops common_args = "--set image.repository=$(params.IMAGE) --set image.tag=$(params.TAG) --set ingress.hosts[0].paths[0]=/" helm -n $ ( params . NAMESPACE ) アップグレード$ ( params . APP_NAME ) $ ( params . CHART_NAME ) $ { common_args } || \ helm -n $ ( params.NAMESPACE ) install $ ( params.APP_NAME ) $ ( params.CHART_NAME ) $ { common_args } コードスキャンタスクJenkins ではコード スキャンが使用されるため、次のようにコード スキャン タスクがここに追加されます。 apiバージョン: tekton.dev/v1alpha1 種類: タスク メタデータ: 名前: ソナースキャナー 仕様: ワークスペース: - 名前: ソース パラメータ: - 名前: SONAR_USERNAME - 名前: SONAR_PASSWORD - 名前: SONAR_URL - 名前: APP_NAME 手順: - 名前: ソナー- スキャナー イメージ: registry.cn-hangzhou.aliyuncs.com/coolops/sonar-scanner : 2.2.0 作業ディレクトリ: $ ( ワークスペース. ソース. パス) スクリプト: | scanTime = `日付+% F -% H -% M -% S ` ソナー- スキャナー- Dsonar 。 ホスト。 url = $ ( パラメータ. SONAR_URL ) \ - ドソナー。 プロジェクトキー= $ ( パラメータ. APP_NAME ) \ - ドソナー。 プロジェクト名= $ ( パラメータ. APP_NAME ) \ - ドソナー。 プロジェクトバージョン= $ { スキャン時間} \ - ドソナー。 ログイン= $ ( パラメータ. SONAR_USERNAME ) \ - ドソナー。 パスワード= $ ( params . SONAR_PASSWORD ) \ - ドソナー。 プロジェクトの説明= "$(workspaces.source.path)" 追加する必要がある新しいタスクは 2 つだけです。次のステップはパイプラインを組み立てることです。マルチブランチリリースもパイプラインで組み立てられます。 パイプラインの統合Pipeline を統合する前に、プロセスを整理しましょう。 - プルコード。
- イメージをコンパイル、ビルド、プッシュします。
- アプリケーションをリリース----複数の環境。
- コードスキャン。
apiバージョン: tekton.dev/v1beta1 種類: パイプライン メタデータ: 名前: rd - パイプライン 仕様: ワークスペース: # ワークスペースを宣言する - 名前: rd - リポジトリ- pvc - 名前: docker - 設定 - 名前: kubernetes - 構成 パラメータ: # コードリポジトリを定義する - 名前: git_url - 名前: リビジョン タイプ: 文字列 デフォルト: "master" - 名前: gitInitImage タイプ: 文字列 デフォルト: "registry.cn-hangzhou.aliyuncs.com/coolops/tekton-git-init:v0.29" # ミラーパラメータを定義する - 名前: Dockerファイルへのパス 説明: ワークスペース内でKaniko が使用するビルドコンテキストへのパス デフォルト: 。 - 名前: イメージURL 説明: 画像リポジトリのURL - 名前: イメージタグ 説明: ビルドされたイメージに適用するタグ デフォルト: 最新 - 名前: チャート名 タイプ: 文字列 デフォルト: coolops / coolops - rd - 名前: チャートのユーザー名 タイプ: 文字列 - 名前: chart_password タイプ: 文字列 - 名前: アプリ名 タイプ: 文字列 - 名前: 名前空間 タイプ: 文字列 デフォルト: デフォルト #define コードスキャン - 名前: sonar_username タイプ: 文字列 デフォルト: 管理者 - 名前: sonar_password タイプ: 文字列 デフォルト: 管理者 - 名前: sonar_url タイプ: 文字列 タスク: # パイプラインにタスクを追加する - 名前: クローン タスク参照: 名前: git - クローン ワークスペース: - 名前: 出力 ワークスペース: rd - リポジトリ- pvc パラメータ: - 名前: URL 値: $ ( params . git_url ) - 名前: リビジョン 値: $ ( パラメータ. リビジョン) - 名前: gitInitImage 値: $ ( params . gitInitImage ) - 名前: ユニット- テスト ワークスペース: #pass ワークスペース - 名前: ソース ワークスペース: rd - リポジトリ- pvc タスク参照: 名前: ユニットテスト 実行後: - クローン - 名前: ビルド- プッシュ- イメージ パラメータ: - 名前: Dockerファイルへのパス 値: $ ( params . pathToDockerfile ) - 名前: イメージURL 値: $ ( params . imageUrl ) - 名前: イメージタグ 値: $ ( タスク. クローン. 結果. コミット) タスク参照: 名前: ビルド- プッシュ- イメージ 実行後: -ユニット- テスト ワークスペース: #pass ワークスペース - 名前: ソース ワークスペース: rd - リポジトリ- pvc - 名前: dockerconfig ワークスペース: docker - config - 名前: デプロイ先: dev いつ: - 入力: $ ( パラメータ. リビジョン) 演算子: in 値: -開発 タスク参照: 名前: helm - to - k8s パラメータ: - 名前: 画像 値: $ ( params . imageUrl ) - 名前: タグ 値: $ ( タスク. クローン. 結果. コミット) - 名前: BRANCH_NAME 値: $ ( パラメータ. リビジョン) - 名前: CHART_NAME 値: $ ( パラメータ. チャート名) - 名前: CHART_USERNAME 値: $ ( params . chart_username ) - 名前: CHART_PASSWORD 値: $ ( params . chart_password ) - 名前: APP_NAME 値: $ ( params . app_name ) - 名前: 名前空間 値: クールオプス- dev ワークスペース: - 名前: ソース ワークスペース: rd - リポジトリ- pvc - 名前: kubernetesconfig ワークスペース: kubernetes - 構成 実行後: - ビルド- プッシュ- イメージ - 名前: デプロイ- テスト いつ: - 入力: $ ( パラメータ. リビジョン) 演算子: in 値: - テスト タスク参照: 名前: helm - to - k8s パラメータ: - 名前: 画像 値: $ ( params . imageUrl ) - 名前: タグ 値: $ ( タスク. クローン. 結果. コミット) - 名前: BRANCH_NAME 値: $ ( パラメータ. リビジョン) - 名前: CHART_NAME 値: $ ( パラメータ. チャート名) - 名前: CHART_USERNAME 値: $ ( params . chart_username ) - 名前: CHART_PASSWORD 値: $ ( params . chart_password ) - 名前: APP_NAME 値: $ ( params . app_name ) - 名前: 名前空間 値: クールオプス- テスト ワークスペース: - 名前: ソース ワークスペース: rd - リポジトリ- pvc - 名前: kubernetesconfig ワークスペース: kubernetes - 構成 実行後: - ビルド- プッシュ- イメージ - 名前: デプロイ先- 事前 いつ: - 入力: $ ( パラメータ. リビジョン) 演算子: in 値: - 前 タスク参照: 名前: helm - to - k8s パラメータ: - 名前: 画像 値: $ ( params . imageUrl ) - 名前: タグ 値: $ ( タスク. クローン. 結果. コミット) - 名前: BRANCH_NAME 値: $ ( パラメータ. リビジョン) - 名前: CHART_NAME 値: $ ( パラメータ. チャート名) - 名前: CHART_USERNAME 値: $ ( params . chart_username ) - 名前: CHART_PASSWORD 値: $ ( params . chart_password ) - 名前: APP_NAME 値: $ ( params . app_name ) - 名前: 名前空間 値: クールオプス- 事前 ワークスペース: - 名前: ソース ワークスペース: rd - リポジトリ- pvc - 名前: kubernetesconfig ワークスペース: kubernetes - 構成 実行後: - ビルド- プッシュ- イメージ - 名前: 本番環境にデプロイ いつ: - 入力: $ ( パラメータ. リビジョン) 演算子: in 値: -製品 タスク参照: 名前: helm - to - k8s パラメータ: - 名前: 画像 値: $ ( params . imageUrl ) - 名前: タグ 値: $ ( タスク. クローン. 結果. コミット) - 名前: BRANCH_NAME 値: $ ( パラメータ. リビジョン) - 名前: CHART_NAME 値: $ ( パラメータ. チャート名) - 名前: CHART_USERNAME 値: $ ( params . chart_username ) - 名前: CHART_PASSWORD 値: $ ( params . chart_password ) - 名前: APP_NAME 値: $ ( params . app_name ) - 名前: 名前空間 値: クールオプス- 製品 ワークスペース: - 名前: ソース ワークスペース: rd - リポジトリ- pvc - 名前: kubernetesconfig ワークスペース: kubernetes - 構成 実行後: - ビルド- プッシュ- イメージ - 名前: ソナー- スキャナー いつ: - 入力: $ ( パラメータ. リビジョン) 演算子: in 値: - テスト タスク参照: 名前: ソナースキャナー 実行後: - クローン パラメータ: - 名前: SONAR_USERNAME 値: $ ( params . sonar_username ) - 名前: SONAR_PASSWORD 値: $ ( params . sonar_password ) - 名前: SONAR_URL 値: $ ( params . sonar_url ) - 名前: APP_NAME 値: $ ( params . app_name ) ワークスペース: - 名前: ソース ワークスペース: rd - リポジトリ- pvc PipelineRun を配置して次のように実行します。 apiバージョン: tekton.dev/v1beta1 種類: PipelineRun メタデータ: 名前: テスト- hello - world - パイプライン- 実行 仕様: パイプライン参照: 名前: rd - パイプライン パラメータ: - 名前: リビジョン 値: テスト - 名前: git_url 値 https://gitee.com/coolops/devops-hello-world.git - 名前: イメージURL 値: レジストリ。 cn - 杭州。 アリユンクス。 com / coolops / devops - hello - world - 名前: イメージタグ 値: 最新 - 名前: Dockerファイルへのパス 値: Dockerfile - 名前: チャートのユーザー名 値: ユーザー名 - 名前: chart_password 値: パスワード - 名前: アプリ名 値: hello - world - 名前: sonar_username 値: ユーザー名 - 名前: sonar_password 値: パスワード - 名前: sonar_url 値 http://sonarqube.coolops.cn ワークスペース: - 名前: rd - リポジトリ- pvc ボリュームクレームテンプレート: 仕様: アクセスモード: -ReadWriteOnce ストレージクラス名: openebs - ホストパス リソース: リクエスト: ストレージ: 1 Gi - 名前: docker - 設定 秘密: secretName : docker - config - 名前: kubernetes - 設定 秘密: secretName : kubernetes - config サービスアカウント名: tekton - build - sa 操作効果は以下のとおりです。 上記の例では、アプリケーションを同じクラスターの異なる名前空間にのみデプロイします。実際の状況では、複数のクラスターが存在する可能性があります。異なる kubernetes-configs を指定するだけです。もちろん、Tekton が配置されているクラスターが他のクラスターと通信できることを確認する必要があります。 ソナーのスキャン結果は次のとおりです。 要約するJenkins から Tekton への移行では主にパイプラインの書き換えが必要になりますが、Jenkins のプロセスは明確に定義されているため、その手順に従って Tekton に適応可能な構文に変換するだけでよいため、全体的には複雑ではありません。 |