Argo CD を使用して GitOps パイプラインを変換する

Argo CD を使用して GitOps パイプラインを変換する

Argo CD は、宣言型 GitOps コンセプトに従う Kubernetes の継続的デプロイメント ツールです。 Argo CD は、Git リポジトリが変更されると、アプリケーションを自動的に同期してデプロイします。

Argo CD は GitOps モデルに従い、Git リポジトリを真のソースとして使用して、目的のアプリケーション状態を定義します。 Argo CD はさまざまな Kubernetes マニフェストをサポートしています。

  • カスタマイズ
  • ヘルムチャート
  • ksonnet アプリケーション
  • jsonnet ファイル
  • YAML/json マニフェストのプレーン ディレクトリ
  • 構成管理プラグインとして構成されたカスタム構成管理ツール

Argo CD は、指定されたターゲット環境に目的のアプリケーション状態を自動的に展開します。アプリケーションのデプロイメントでは、ブランチやタグの更新を追跡したり、Git コミット時にマニフェストの指定されたバージョンに固定したりできます。

建築

ArgoCD アーキテクチャ

Argo CD は、実行中のアプリケーションを継続的に監視し、現在のライブ状態と目的のターゲット状態 (Git リポジトリで指定) を比較する Kubernetes コントローラーを介して実装されます。デプロイされたアプリケーションの実際の状態は、ターゲットの状態とは異なります。   OutOfSync   Argo CD はこれらの違いを報告し、状態を目的のターゲット状態に自動または手動で同期するためのツールを提供します。 Git リポジトリ内の目的のターゲット状態に加えられた変更は、指定されたターゲット環境に自動的に適用され、フィードバックされます。

以下は、Argo CD の主なコンポーネントの簡単な紹介です。

API サービス: API サービスは、Web UI、CLI、CI/CD システムで使用されるインターフェースを公開する gRPC/REST サービスです。以下の機能があります。

  • アプリケーション管理とステータスレポート
  • アプリケーション操作を実行する(例:同期、ロールバック、ユーザー定義操作)
  • ストレージ リポジトリとクラスター資格情報管理 (K8s Secrets オブジェクトとして保存)
  • 外部IDプロバイダーへの認証と承認
  • RBAC
  • Git Webhook イベントのリスナー/フォワーダー

リポジトリ サービス: リポジトリ サービスは、アプリケーション マニフェストを保持する Git リポジトリのローカル キャッシュを維持する内部サービスです。次の入力が提供された場合、Kubernetes マニフェストを生成して返す役割を担います。

  • URLの保存
  • リビジョンバージョン(コミット、タグ、ブランチ)
  • アプリケーションパス
  • テンプレート構成: パラメーター、ksonnet 環境、helm values.yaml など。

アプリケーション コントローラー: アプリケーション コントローラーは、実行中のアプリケーションを継続的に監視し、現在のライブ状態と目的のターゲット状態 (リポジトリで指定) を比較する Kubernetes コントローラーです。アプリケーションの OutOfSync 状態を検出し、状態を同期するためのアクションを実行します。ユーザー定義のライフサイクル イベント (PreSync、Sync、PostSync) のフックを呼び出す役割を担います。

インストール

もちろん、前提条件として、kubectl からアクセスできる Kubernetes クラスターが必要です。以下のコマンドを直接使用できます。ここでは最新の v2.8.4 バージョンをインストールします。

 $ kubectl create namespace argocd $ kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/v2.8.4/manifests/install.yaml

実稼働環境で使用する場合は、次のコマンドを使用して HA 高可用性バージョンをデプロイできます。

 $ kubectl create namespace argocd $ kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/v2.8.4/manifests/ha/install.yaml

これにより、新しい名前空間 argocd が作成され、そこに Argo CD サービスとアプリケーション リソースがデプロイされます。

 $ kubectl get pods -n argocd NAME READY STATUS RESTARTS AGE argocd-application-controller-0 1/1 Running 0 103s argocd-applicationset-controller-68b9bdbd8b-jzcpf 1/1 Running 0 103s argocd-dex-server-6b7745757-6mxwk 1/1 Running 0 103s argocd-notifications-controller-5b56f6f7bb-jqpng 1/1 Running 0 103s argocd-redis-f4cdbff57-dr8jc 1/1 Running 0 103s argocd-repo-server-c4f79b4d6-7nh6n 1/1 Running 0 103s argocd-server-895675597-fr42g 1/1 Running 0 103s

UI、SSO、マルチクラスター管理などの機能には興味がなく、アプリケーションの変更をクラスターに同期するだけの場合は、コア コンポーネントを直接インストールできます: kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/v2.8.4/manifests/core-install.yaml。

次に、Argo CD の操作を容易にするために、CLI ツールをローカルにインストールします (対応するバージョンを選択)。

 $ curl -sSL -o /usr/local/bin/argocd https://github.com/argoproj/argo-cd/releases/download/v2.8.4/argocd-linux-amd64

argocd CLI に実行権限を付与します。

 $ chmod +x /usr/local/bin/argocd

これで、argocd コマンドが使用できるようになります。 Mac を使用している場合は、 brew install argocd を使用して直接インストールできます。

Argo CD は、gRPC サーバー (CLI によって使用される) と HTTP/HTTPS サーバー (UI によって使用される) を実行します。両方のプロトコルは、argocd-server サーバーによって次のポートで公開されます。

  • 443 - HTTPS の実装
  • 80 - HTTP (HTTPS にリダイレクト)

Ingress を構成することでサービスを公開できます。その他の Ingress コントローラーの設定については、公式ドキュメント https://argo-cd.readthedocs.io/en/stable/operator-manual/ingress/ を参照してください。

Argo CD は同じポート (443) で複数のプロトコル (gRPC/HTTPS) を提供するため、nginx.ingress.kubernetes.io/backend-protocol アノテーションは 1 つのバックエンド プロトコル (HTTP、HTTPS、GRPC、GRPCS など) しか受け入れることができないため、argocd サービスに対して単一の nginx ingress オブジェクトとルールを定義するのは少し面倒です。

単一のイングレス ルールとホスト名を使用して Argo CD APIServer を公開するには、nginx.ingress.kubernetes.io/ssl-passthrough アノテーションを使用して TLS 接続をパススルーし、Argo CD APIServer で TLS を検証する必要があります。

 apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: argocd-server-ingress namespace: argocd annotations: nginx.ingress.kubernetes.io/force-ssl-redirect: "true" nginx.ingress.kubernetes.io/ssl-passthrough: "true" spec: ingressClassName: nginx rules: - host: argocd.k8s.local http: paths: - path: / pathType: Prefix backend: service: name: argocd-server port: name: https

上記のルールは、使用されているプロトコルを検出し、適切に応答する Argo CD APIServer 上の TLS を検証します。 nginx.ingress.kubernetes.io/ssl-passthrough アノテーションでは、nginx-ingress-controller のコマンドライン引数に --enable-ssl-passthrough フラグを追加する必要があることに注意してください。

ingress-nginx の各 Ingress オブジェクトは 1 つのプロトコルのみをサポートするため、別の方法として 2 つの Ingress オブジェクトを定義します。 1 つは HTTP/HTTPS 用、もう 1 つは gRPC 用です。

以下は HTTP/HTTPS Ingress オブジェクトです。

 apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: argocd-server-http-ingress namespace: argocd annotations: nginx.ingress.kubernetes.io/force-ssl-redirect: "true" nginx.ingress.kubernetes.io/backend-protocol: "HTTP" spec: ingressClassName: nginx rules: - http: paths: - path: / pathType: Prefix backend: service: name: argocd-server port: name: http host: argocd.k8s.local tls: - hosts: - argocd.k8s.local secretName: argocd-secret # do not change, this is provided by Argo CD

gRPC プロトコルに対応する Ingress オブジェクトは次のとおりです。

 apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: argocd-server-grpc-ingress namespace: argocd annotations: nginx.ingress.kubernetes.io/backend-protocol: "GRPC" spec: ingressClassName: nginx rules: - http: paths: - path: / pathType: Prefix backend: service: name: argocd-server port: name: https host: grpc.argocd.k8s.local tls: - hosts: - grpc.argocd.k8s.local secretName: argocd-secret # do not change, this is provided by Argo CD

次に、TLS を無効にして APIServer を実行する必要があります。 argocd-server デプロイメントを編集して、argocd-server コマンドに --insecure フラグを追加するか、argocd-cmd-params-cm ConfigMap で server.insecure: "true" を設定します。

作成が完了すると、argocd.k8s.local を通じて Argo CD サービスにアクセスできるようになります。ただし、ここで設定する証明書は自己署名されているため、初めてアクセスするときに安全ではないというメッセージが表示されることに注意してください。ただ強制的にジャンプするだけです。

デフォルトでは、管理者アカウントの初期パスワードは自動的に生成され、Argo CD インストールの名前空間にある argocd-initial-admin-secret という名前の Secret オブジェクトのパスワード フィールドにプレーン テキストで保存されます。次のコマンドで取得できます。

 $ kubectl -n argocd get secret argocd-initial-admin-secret -o jsnotallow="{.data.password}" | base64 -d && echo

ユーザー名 admin と上記のパスワード出力を使用してダッシュボードにログインします。

アルゴCDUI

ArgoCD CLI コマンドライン ツールを使用してログインすることもできます。

 $ argocd login grpc.argocd.k8s.local WARNING: server certificate had error: tls: failed to verify certificate: x509: certificate signed by unknown authority. Proceed insecurely (y/n)? y Username: admin Password: 'admin:login' logged in successfully Context 'grpc.argocd.k8s.local' updated

ここでのログイン アドレスは、gRPC によって公開されるサービス アドレスであることに注意してください。

CLI に正常にログインしたら、次のコマンドを使用してパスワードを変更できます。

 $ argocd account update-password *** Enter current password: *** Enter new password: *** Confirm new password: Password updated Context 'argocd.k8s.local' updated $ argocd version argocd: v2.8.4+c279299 BuildDate: 2023-09-13T19:43:37Z GitCommit: c27929928104dc37b937764baf65f38b78930e59 GitTreeState: clean GoVersion: go1.20.7 Compiler: gc Platform: darwin/arm64 argocd-server: v2.8.4+c279299 BuildDate: 2023-09-13T19:12:09Z GitCommit: c27929928104dc37b937764baf65f38b78930e59 GitTreeState: clean GoVersion: go1.20.6 Compiler: gc Platform: linux/amd64 Kustomize Version: v5.1.0 2023-06-19T16:58:18Z Helm Version: v3.12.1+gf32a527 Kubectl Version: v0.24.2 Jsonnet Version: v0.20.0

クラスターの構成

Argo CD は複数のクラスターへのアプリケーションのデプロイをサポートしているため、アプリケーションを外部クラスターにデプロイする場合は、まず外部クラスターの認証情報を Argo CD に登録する必要があります。内部的にデプロイする場合 (Argo CD を実行している同じクラスター、デフォルトでは構成は不要)、アプリケーションの K8S APIServer アドレスとして https://kubernetes.default.svc を直接使用できます。

まず、現在の kubeconfig 内のすべてのクラスター コンテキストを一覧表示します。

 $ kubectl config get-contexts -o name kubernetes-admin@kubernetes orbstack

リストからコンテキスト名を選択し、argocd cluster add CONTEXTNAME に指定します。たとえば、orbstack コンテキストの場合は、次のコマンドを実行します。

 $ argocd cluster add orbstack

アプリケーションを作成する

Git リポジトリ https://github.com/argoproj/argocd-example-apps.git は、Argo CD の動作を示すために使用できるゲストブック アプリケーションを含むサンプル リポジトリです。

CLI 経由でアプリケーションを作成する

argocd app create xxx コマンドを使用してアプリケーションを作成できます。

 $ argocd app create --help Create an application Usage: argocd app create APPNAME [flags] Examples: # Create a directory app argocd app create guestbook --repo https://github.com/argoproj/argocd-example-apps.git --path guestbook --dest-namespace default --dest-server https://kubernetes.default.svc --directory-recurse # Create a Jsonnet app argocd app create jsonnet-guestbook --repo https://github.com/argoproj/argocd-example-apps.git --path jsonnet-guestbook --dest-namespace default --dest-server https://kubernetes.default.svc --jsonnet-ext-str replicas=2 # Create a Helm app argocd app create helm-guestbook --repo https://github.com/argoproj/argocd-example-apps.git --path helm-guestbook --dest-namespace default --dest-server https://kubernetes.default.svc --helm-set replicaCount=2 # Create a Helm app from a Helm repo argocd app create nginx-ingress --repo https://charts.helm.sh/stable --helm-chart nginx-ingress --revision 1.24.3 --dest-namespace default --dest-server https://kubernetes.default.svc # Create a Kustomize app argocd app create kustomize-guestbook --repo https://github.com/argoproj/argocd-example-apps.git --path kustomize-guestbook --dest-namespace default --dest-server https://kubernetes.default.svc --kustomize-image gcr.io/heptio-images/ks-guestbook-demo:0.1 # Create a app using a custom tool: argocd app create kasane --repo https://github.com/argoproj/argocd-example-apps.git --path plugins/kasane --dest-namespace default --dest-server https://kubernetes.default.svc --config-management-plugin kasane Flags: ......

次のコマンドを実行するだけです。

 $ argocd app create guestbook --repo https://github.com/argoproj/argocd-example-apps.git --path guestbook --dest-server https://kubernetes.default.svc --dest-namespace default application 'guestbook' created

UI 経由でアプリケーションを作成する

CLIツールでアプリケーションを作成するだけでなく、UIインターフェースでアプリケーションを作成し、   argocd.k8s.local  ページにログイン後、   +New App  以下のように、新しいアプリケーション ボタンを作成します。

新しいアプリ

アプリケーションに guestbook という名前を付け、デフォルトのプロジェクトを使用し、同期ポリシーを手動に設定します。

アプリケーションを構成する

次に、以下のリポジトリ URL を https://github.com/argoproj/argocd-example-apps.git に設定します。いくつかの理由により、Gitee リポジトリ アドレス https://gitee.com/cnych/argocd-example-apps を使用します。リビジョンを HEAD に設定し、パスを guestbook に設定します。次に、下の [宛先] セクションで、クラスターを inCluster に設定し、名前空間を default に設定します。

クラスターの構成

上記の情報を入力したら、ページ上部の「作成」をクリックしてゲストブック アプリケーションを作成します。作成が完了すると、現在のアプリケーションが  OutOfSync  州:

ゲストブックアプリケーション

デフォルトでは、Argo CD は 3 分ごとに Git リポジトリをチェックし、実際のアプリケーション ステータスが Git で宣言された予想されるステータスと一致しているかどうかを判断します。そうでない場合、ステータスは OutOfSync に変換されます。デフォルトでは、syncPolicy を介して自動同期が設定されていない限り、更新はトリガーされません。

CRD経由で作成

CLI とダッシュボードを通じてアプリケーションを作成するだけでなく、次に示すように、アプリケーション リソース オブジェクトを宣言してアプリケーションを直接作成することもできます。

 apiVersion: argoproj.io/v1alpha1 kind: Application metadata: name: guestbook spec: destination: namespace: default server: "https://kubernetes.default.svc" source: path: guestbook repoURL: "https://github.com/cnych/argocd-example-apps" targetRevision: HEAD project: default syncPolicy: automated: null

アプリケーションをデプロイする

上記のアプリケーションを作成するときに使用した同期戦略は手動であるため、アプリケーションは作成後に自動的にデプロイされず、手動でアプリケーションをデプロイする必要があります。 CLI および UI インターフェイスを介して同期することもできます。

CLIを使用して同期する

アプリケーションが作成されたら、次のコマンドでそのステータスを表示できます。

 $ argocd app get argocd/guestbook Name: argocd/guestbook Project: default Server: https://kubernetes.default.svc Namespace: default URL: https://grpc.argocd.k8s.local/applications/guestbook Repo: https://gitee.com/cnych/argocd-example-apps Target: HEAD Path: guestbook SyncWindow: Sync Allowed Sync Policy: <none> Sync Status: OutOfSync from HEAD (f3736e6) Health Status: Missing GROUP KIND NAMESPACE NAME STATUS HEALTH HOOK MESSAGE Service default guestbook-ui OutOfSync Missing apps Deployment default guestbook-ui OutOfSync Missing

アプリケーションはまだデプロイされておらず、Kubernetes リソースもまだ作成されていないため、アプリケーションのステータスは最初は OutOfSync 状態になります。アプリケーションを同期 (デプロイ) するには、次のようなコマンドを実行します。

 $ argocd app sync argocd/guestbook

このコマンドは、Git リポジトリからリソース リストを取得し、kubectl apply を実行してアプリケーションをデプロイします。上記のコマンドを実行すると、ゲストブック アプリケーションがクラスター内で実行されます。これで、リソース コンポーネント、ログ、イベントを表示し、ヘルス ステータスを評価できるようになりました。

UI経由で同期する

同期を開始するには、UI インターフェイスに同期ボタンを追加するだけです。

同期操作

同期が完了すると、リソースのステータスを確認したり、アプリケーション ログ情報を直接表示したりできるようになります。

同期完了

kubectl を通じてデプロイされたリソースを表示することもできます。

 $ kubectl get pods NAME READY STATUS RESTARTS AGE guestbook-ui-6c96fb4bdc-bdwh9 1/1 Running 0 3m3s ➜ ~ kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE guestbook-ui ClusterIP 10.100.170.117 <none> 80/TCP 3m16s kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 42d

Git リポジトリから同期した guestbook ディレクトリの下のリソース ステータスも同期されており、同期が成功したことが証明されています。

組立ラインの変革

以前、Jenkins Pipeline を通じてアプリケーションをクラスターに正常にデプロイしましたが、従来のアクティブ プッシュ方式を使用しました。次に、このプロセスを GitOps パイプラインに変換して、Git を通じてアプリケーションのデプロイメントを管理できるようにする必要があります。

使用されたコード リポジトリは https://github.com/cnych/drone-k8s-demo にあり、実験のために内部の gitlab 環境に移行されました。

以前の Jenkins パイプラインでは、helm を通じてアプリケーションをデプロイしました。これで、イメージをビルドしてイメージ リポジトリにプッシュし、git リポジトリ内の values ファイルを変更し、Argo CD を使用してアプリケーションを同期的にデプロイするなど、パイプラインの CD 部分を変更するだけで済みます。

まず、アプリケーション デプロイメント リソース リストを別の構成リポジトリ http://gitlab.k8s.local/cnych/k8s-devops-demo-config.git に配置し、以前のアプリケーションの helm ディレクトリをリポジトリにアップロードします。これにより、Argo CD との接続が容易になります。プロジェクト全体には、アプリケーション展開用の Helm Chart テンプレートのみが含まれています。

設定リポジトリ

複数のチームがあり、各チームが多数のアプリケーションを管理する必要がある場合は、Argo CD の別の概念である「プロジェクト」が必要になります。 Argo CD のプロジェクトを使用して、アプリケーションをグループ化できます。異なるチームが異なるプロジェクトを使用するため、マルチテナント環境が実現します。このプロジェクトでは、よりきめ細かいアクセス制御もサポートされています。

  • デプロイメント コンテンツ (信頼できる Git リポジトリ) を制限する。
  • ターゲットのデプロイメント環境 (ターゲット クラスターと名前空間) を制限します。
  • デプロイされるリソースの種類を制限します (例: RBAC、CRD、DaemonSets、NetworkPolicy など)。
  • アプリケーションに RBAC を提供するためのプロジェクト ロールを定義します (OIDC グループや JWT トークン バインディングなど)。

たとえば、demo という名前のプロジェクトを作成し、このプロジェクトの下にアプリケーションを作成します。以下に示すように、AppProject オブジェクトを作成するだけです。

 apiVersion: argoproj.io/v1alpha1 kind: AppProject metadata: # 项目名name: demo namespace: argocd spec: # 目标destinations: # 此项目的服务允许部署的namespace,这里为全部- namespace: "*" # 此项目允许部署的集群,这里为默认集群,即为Argo CD部署的当前集群server: https://kubernetes.default.svc # 允许的数据源sourceRepos: - http://gitlab.k8s.local/cnych/k8s-devops-demo-config.git

このオブジェクトにはいくつかのコア プロパティがあります。

  • sourceRepos: プロジェクト内のアプリケーションがマニフェストを取得できるリポジトリ参照。
  • 宛先: プロジェクト内のアプリケーションをデプロイできるクラスターと名前空間。
  • ロール: プロジェクト内のリソース アクセスに対して定義されたロール。

オブジェクトを作成するだけです:

 $ kubectl get appproject -n argocd NAME AGE default 47h demo 6s

次に、Argo CD の設定ページに移動し、+ CONNECT REPO をクリックしてリポジトリを追加します。

リポジトリを接続

ここでのパスワードには AccessToken を使用する必要があることに注意してください。AccessToken は、GitLab のページ http://gitlab.k8s.local/-/profile/personal_access_tokens にアクセスして作成できます。

GitLabトークン

詳細な構成情報については、ドキュメント https://argo-cd.readthedocs.io/en/stable/operator-manual/declarative-setup/ を参照してください。プロジェクトが作成されたら、環境にデプロイされたアプリケーション インスタンスを表すアプリケーションをプロジェクトの下に作成します。

 apiVersion: argoproj.io/v1alpha1 kind: Application metadata: name: devops-demo namespace: argocd spec: destination: namespace: default server: "https://kubernetes.default.svc" project: demo syncPolicy: automated: prune: true selfHeal: true source: path: helm # 从Helm 存储库创建应用程序时,chart 必须指定path repoURL: "http://gitlab.k8s.local/cnych/k8s-devops-demo-config.git" targetRevision: HEAD helm: parameters: - name: replicaCount value: "2" valueFiles: - my-values.yaml

ここでは、devops-demo という名前のアプリケーションを定義します。アプリケーション ソースは helm パスから取得され、my-values.yaml ファイルを使用します。さらに、source.helm.parameters を通じてパラメータを構成することもできます。

同期戦略では、自動方式を使用するように選択できます。この戦略では、構成できるプロパティが 2 つあります。

  • リソースのプルーニング: 有効にすると、Git リポジトリ内のリソースを削除すると、環境内の対応するリソースも自動的に削除されます。

リソースの削除

  • 自己修復: 自動的に修復し、Git リポジトリのステータスに基づいて強制的に実行されます。環境内での手動変更は有効になりません。

自動回復

正常に作成された後、このアプリケーションには劣化エラーが発生します。これは、値のイメージがデフォルトで最新に設定されており、イメージをイメージ リポジトリにプッシュしていないため、エラーが発生するためです。

アプリのステータス

次に、Jenkins Pipeline パイプラインを変更し、CD 部分を変更します。

 podTemplate(cloud: "Kubernetes", nodeSelector: "kubernetes.io/hostname=node2", containers: [ containerTemplate(name: 'golang', image: 'golang:1.18.3-alpine3.16', command: 'cat', ttyEnabled: true), containerTemplate(name: 'docker', image: 'docker:latest', command: 'cat', ttyEnabled: true), containerTemplate(name: 'kubectl', image: 'cnych/kubectl', command: 'cat', ttyEnabled: true), containerTemplate(name: 'helm', image: 'cnych/helm', command: 'cat', ttyEnabled: true), containerTemplate(name: 'yq', image: 'cnych/yq-jq:git', command: 'cat', ttyEnabled: true) ], serviceAccount: 'jenkins', envVars: [ envVar(key: 'DOCKER_HOST', value: 'tcp://docker-dind:2375') // 环境变量]) { node(POD_LABEL) { def myRepo = checkout scm def gitConfigRepo = "gitlab.k8s.local/cnych/k8s-devops-demo-config.git" def gitCommit = myRepo.GIT_COMMIT def gitBranch = myRepo.GIT_BRANCH // 获取git commit id 作为镜像标签def imageTag = sh(script: "git rev-parse --short HEAD", returnStdout: true).trim() // 仓库地址def registryUrl = "harbor.k8s.local" def imageEndpoint = "course/devops-demo" // 镜像def image = "${registryUrl}/${imageEndpoint}:${imageTag}" stage('单元测试') { echo "测试阶段" } stage('代码编译打包') { try { container('golang') { echo "2.代码编译打包阶段" sh """ export GOPROXY=https://goproxy.io GOOS=linux GOARCH=amd64 go build -v -o demo-app """ } } catch (exc) { println "构建失败- ${currentBuild.fullDisplayName}" throw(exc) } } stage('构建Docker 镜像') { withCredentials([[$class: 'UsernamePasswordMultiBinding', credentialsId: 'docker-auth', usernameVariable: 'DOCKER_USER', passwordVariable: 'DOCKER_PASSWORD']]) { container('docker') { echo "3. 构建Docker 镜像阶段" sh """ docker login ${registryUrl} -u ${DOCKER_USER} -p ${DOCKER_PASSWORD} docker build -t ${image} . docker push ${image} """ } } } stage('修改Config Repo') { withCredentials([[$class: 'UsernamePasswordMultiBinding', credentialsId: 'gitlab-auth', usernameVariable: 'GIT_USER', passwordVariable: 'GIT_PASSWORD']]) { container('yq') { echo "3. 修改Config Repo 仓库Values" // Bed6gAYq sh """ git clone http://${GIT_USER}:${GIT_PASSWORD}@${gitConfigRepo} cd k8s-devops-demo-config yq write -i -y helm/my-values.yaml image.tag "${imageTag}" git add helm/my-values.yaml git config --global user.name "cnych" git config --global user.email "[email protected]" git commit -m "update image tag to ${imageTag}" git push http://${GIT_USER}:${GIT_PASSWORD}@${gitConfigRepo} """ } } } stage('运行Kubectl') { withCredentials([file(credentialsId: 'kubeconfig', variable: 'KUBECONFIG')]) { container('kubectl') { sh "mkdir -p ~/.kube && cp ${KUBECONFIG} ~/.kube/config" echo "5.查看应用" sh "kubectl get all -n kube-ops -l app=devops-demo" } } } } }

上記のパイプラインでは、アプリケーションがイメージにビルドされた後、Config Repo ウェアハウス内の値ファイルを直接変更してウェアハウスに送信し、Argo CD がアプリケーションを自動的に同期的にデプロイするようにします。

Argo CD はデフォルトでは Config Repo の変更をリアルタイムで監視しないため、変更をより速く検出したい場合は Git Webhook を使用できます。

デフォルトでは、Argo CD は 3 分ごとに Git リポジトリをポーリングしてマニフェストの変更を検出します。ポーリングの遅延を解消するために、API サーバーを Webhook イベントを受信するように構成できます。 Argo CD は、GitHub、GitLab、Bitbucket、Bitbucket Server、Gogs からの Git Webhook 通知をサポートしています。

同様に、k8s-devops-demo-config リポジトリの下に webhook を作成することもできます。 Git プロバイダーで構成されたペイロード URL では、Argo CD インスタンスの /api/webhook エンドポイントを使用する必要があります (例: https://argocd.example.com/api/webhook)。

GitLabウェブフック

次に、argocd-secret Kubernetes シークレットで、上記で設定した Git プロバイダーの webhook キーを使用して、次のいずれかのシークレットを設定します。

GitLabトークン

$ kubectl edit secret argocd-secret -n argocd apiVersion: v1 kind: Secret metadata: name: argocd-secret namespace: argocd type: Opaque data: ... stringData: # github webhook secret webhook.github.secret: shhhh! it's a GitHub secret # gitlab webhook secret webhook.gitlab.secret: shhhh! it's a GitLab secret # bitbucket webhook secret webhook.bitbucket.uuid: your-bitbucket-uuid # bitbucket server webhook secret webhook.bitbucketserver.secret: shhhh! it's a Bitbucket server secret # gogs server webhook secret webhook.gogs.secret: shhhh! it's a gogs server secret

stringData を直接使用してシークレットを構成できるため、手動でエンコードする必要はありません。

DevOps デモ

GitOps の中核は Git であるため、GitOps の自動同期デプロイメントを実現するために、クラスターにデプロイされたすべてのリソース インベントリ ファイルを Git リポジトリでホストする必要があります。上記では、CI パイプラインの Git リポジトリ内のリソース リスト ファイルを変更しました。実際、他の方法で変更することもできます。たとえば、Argo CD では、新しいツール Argo CD Image Updater も提供されています。

Argo CD イメージ アップデータ

Argo CD Image Updater は、Argo CD によって管理される Kubernetes ワークロードのコンテナ イメージを自動的に更新するツールです。このツールは、Kubernetes ワークロードでデプロイされたコンテナ イメージの新しいバージョンをチェックし、Argo CD を使用して許可された最新バージョンに自動的に更新できます。これは、argocd app set --helm-set image.tag=v1.0.1 と同様に、Argo CD アプリケーションに適切なアプリケーション パラメータを設定することによって機能しますが、完全に自動化されています。

Argo CD イメージ アップデーターは、Argo CD で構成されているアプリケーションを定期的にポーリングし、対応するイメージ リポジトリに新しいバージョンがあるかどうかを照会します。リポジトリ内にイメージの新しいバージョンが見つかり、バージョン制約が満たされている場合、Argo CD イメージ アップデータは、アプリケーションをイメージの新しいバージョンで更新するように Argo CD に指示します。

アプリケーションの自動同期ポリシーに応じて、Argo CD は新しいイメージ バージョンを自動的に展開するか、アプリケーションを同期していないものとしてマークします。アプリケーションを同期することで、手動でイメージの更新をトリガーできます。

特徴

  • Argo CD によって管理され、Helm または Kustomize ツールによってビルドされたアプリケーション イメージを更新します。
  • さまざまな更新戦略に従ってアプリケーション イメージを更新します。
  • semver: 指定されたイメージ制約に従って、許可される最高バージョンに更新します。
  • latest: 最後に作成されたイメージタグに更新します。
  • name: アルファベット順に並べられたリストの最後のラベルに更新します。
  • ダイジェスト: 変更可能なタグの最新のプッシュバージョンに更新します。
  • 広く使用されているコンテナ イメージ レジストリのサポート。
  • 構成によるプライベート コンテナ イメージ リポジトリのサポート。
  • 変更は Git に書き戻すことができます。
  • マッチャー関数を使用して、イメージ リポジトリによって返されるタグのリストをフィルター処理する機能。
  • Kubernetes クラスターで実行するか、コマンド ラインからスタンドアロンで使用することもできます。
  • アプリケーションの並列更新を実行する機能。

また、現在このツールの使用にはいくつかの制限があることにも注意してください。

  • コンテナ イメージを更新するアプリケーションは、Argo CD を使用して管理する必要があります。 Argo CD で管理されていないワークロードはサポートされません。
  • Argo CD イメージ アップデータは、マニフェストが Kustomize または Helm を使用してレンダリングされるアプリケーションのコンテナー イメージのみを更新できます。特に、Helm の場合、テンプレートはパラメータ (image.tag) の使用をサポートする必要があります。
  • イメージ プル キーは、Argo CD イメージ アップデーターが実行されている (またはアクセスできる) 同じ Kubernetes クラスターに存在する必要があります。現在、他のクラスターからこれらのシークレットを取得する方法はありません。

インストール

Argo CD と同じ Kubernetes 名前空間クラスターで Argo CD Image Updater を実行することをお勧めしますが、必須ではありません。実際、Kubernetes クラスターで Argo CD Image Updater を実行する必要も、Kubernetes クラスターにアクセスする必要もありません。ただし、Kubernetes にアクセスできないと一部の機能が利用できない可能性があるため、最初のインストール方法を強くお勧めします。

イメージ アップデーターを実行する最も簡単な方法は、Argo CD が実行されている名前空間に Kubernetes ワークロードとしてインストールすることです。これには構成は必要なく、ワークロードに影響はありません。

 kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj-labs/argocd-image-updater/stable/manifests/install.yaml

Argo CD Image Updater をインストールすると、変更されたリソース リストを CI パイプラインのコード リポジトリに手動で送信しなくても、イメージが変更されたかどうかを直接監視できるようになります。

これで以前のアプリを削除できます。

 $ argocd app delete devops-demo --cascade Are you sure you want to delete 'devops-demo' and all its resources? [y/n] y application 'devops-demo' deleted

次に、新しい Application オブジェクトを作成します。対応するリソース リストは次のようになります。

 # demo-app2.yaml apiVersion: argoproj.io/v1alpha1 kind: Application metadata: name: devops-demo2 annotations: argocd-image-updater.argoproj.io/image-list: myalias=cnych/devops-demo # Write repository name argocd-image-updater.argoproj.io/myalias.allow-tags: regexp:^.*$ argocd-image-updater.argoproj.io/myalias.pull-secret: pullsecret:argocd/dockerhub-secret argocd-image-updater.argoproj.io/myalias.update-strategy: latest # There are several ways to update the image, but I'm using digest. argocd-image-updater.argoproj.io/write-back-method: git argocd-image-updater.argoproj.io/git-branch: main argocd-image-updater.argoproj.io/myalias.force-update: "true" namespace: argocd spec: destination: namespace: argocd server: https://kubernetes.default.svc project: demo source: path: helm # 从Helm 存储库创建应用程序时,chart 必须指定path repoURL: http://gitlab.k8s.local/cnych/k8s-devops-demo-config.git targetRevision: main helm: parameters: - name: replicaCount value: "2" valueFiles: - my-values.yaml syncPolicy: automated: prune: true selfHeal: true syncOptions: - CreateNamespace=true

この新しいリソース オブジェクトには、Argo CD イメージ アップデーターを構成するために使用されるいくつかの注釈が追加されました。これらの構成は、コンテナ イメージを自動的に更新するためのポリシー、パラメーター、および関連情報を指定するために使用されます。これらの注釈の詳細な説明は次のとおりです。

  • argocd-image-updater.argoproj.io/image-list: このアノテーションは、アプリケーションで使用されるイメージ リストを定義します。
  • argocd-image-updater.argoproj.io/allow-tags: このアノテーションは、更新が許可されるイメージタグを指定します。正規表現を使用できます。 -
  • argocd-image-updater.argoproj.io/<alias>.pull-secret: このアノテーションは、イメージをプルするために使用される Secret を指定します。
  • argocd-image-updater.argoproj.io/update-strategy: このアノテーションは、イメージ更新戦略を定義します。ここでの値は latest であり、更新に最新のイメージ タグを使用することを意味します。指定できるその他の値には、digest、name、semver などがあります。
  • argocd-image-updater.argoproj.io/write-back-method: このアノテーションは、更新された構成の書き戻し方法を定義します。 git は、更新された構成を Git リポジトリに書き戻すことを意味します。
  • argocd-image-updater.argoproj.io/git-branch: このアノテーションは、更新された構成が Git リポジトリに書き戻されるブランチを定義します。

上記で pull-secret アノテーションを設定したことに注意してください。 Docker Hub を使用している場合は、個人センターでアクセス トークンを作成する必要があります。

docker アクセストークン

次に、次のコマンドを使用してシークレットを作成します。

 kubectl create -n argocd secret docker-registry dockerhub-secret \ --docker-username xxxx \ --docker-password xxxx \ --docker-server "https://registry-1.docker.io"

次に、アプリケーションを作成します。

 $ kubectl apply -f demo-app2.yaml

作成後、アプリケーションは初めて同期的にデプロイされます。次に、Jenkins Pipeline パイプラインを変更できます。イメージ構築に関わる部分のみを残し、残りは削除する必要があります。

 podTemplate(cloud: "Kubernetes", containers: [ containerTemplate(name: 'golang', image: 'golang:1.18.3-alpine3.16', command: 'cat', ttyEnabled: true), containerTemplate(name: 'docker', image: 'docker:latest', command: 'cat', ttyEnabled: true), containerTemplate(name: 'kubectl', image: 'cnych/kubectl', command: 'cat', ttyEnabled: true) ], serviceAccount: 'jenkins', envVars: [ envVar(key: 'DOCKER_HOST', value: 'tcp://docker-dind:2375') // 环境变量]) { node(POD_LABEL) { def myRepo = checkout scm def gitCommit = myRepo.GIT_COMMIT def gitBranch = myRepo.GIT_BRANCH // 获取git commit id 作为镜像标签def imageTag = sh(script: "git rev-parse --short HEAD", returnStdout: true).trim() // 仓库地址def registryUrl = "docker.io" def imageEndpoint = "cnych/devops-demo" // 镜像def image = "${registryUrl}/${imageEndpoint}:${imageTag}" stage('单元测试') { echo "测试阶段" } stage('代码编译打包') { try { container('golang') { echo "2.代码编译打包阶段" sh """ export GOPROXY=https://goproxy.io GOOS=linux GOARCH=amd64 go build -v -o demo-app """ } } catch (exc) { println "构建失败- ${currentBuild.fullDisplayName}" throw(exc) } } stage('构建Docker 镜像') { withCredentials([[$class: 'UsernamePasswordMultiBinding', credentialsId: 'docker-auth', usernameVariable: 'DOCKER_USER', passwordVariable: 'DOCKER_PASSWORD']]) { container('docker') { echo "3. 构建Docker 镜像阶段" sh """ docker login ${registryUrl} -u ${DOCKER_USER} -p ${DOCKER_PASSWORD} docker build -t ${image} . docker push ${image} """ } } } }

上記のパイプラインを再送信した後、最終的にアプリケーション画像を画像リポジトリにプッシュします。

次に、Argo CD Image Updaterは、2分ごとに画像リポジトリから画像バージョンの変更を取得します。新しい画像バージョンが見つかると、新しいバージョンを自動的に使用して、クラスター内のワークロードの画像を更新し、画像バージョンをGitリポジトリに書き戻します。 Argo CD Image Updaterのログ変更を確認できます。

 $ kubectl logs -f argocd-image-updater-56d94c674d-npgqp -n argocd # ...... time="2023-09-19T06:39:12Z" level=info msg="Starting image update cycle, considering 1 annotated application(s) for update" time="2023-09-19T06:39:16Z" level=info msg="Setting new image to cnych/devops-demo:a6268b3" alias=myalias applicatinotallow=devops-demo2 image_name=cnych/devops-demo image_tag=739a588 registry= time="2023-09-19T06:39:16Z" level=info msg="Successfully updated image 'cnych/devops-demo:739a588' to 'cnych/devops-demo:a6268b3', but pending spec update (dry run=false)" alias=myalias applicatinotallow=devops-demo2 image_name=cnych/devops-demo image_tag=739a588 registry= time="2023-09-19T06:39:16Z" level=info msg="Committing 1 parameter update(s) for application devops-demo2" applicatinotallow=devops-demo2 time="2023-09-19T06:39:16Z" level=info msg="Starting configmap/secret informers" time="2023-09-19T06:39:17Z" level=info msg="Configmap/secret informer synced" time="2023-09-19T06:39:17Z" level=info msg="Initializing http://gitlab.k8s.local/cnych/k8s-demo-config.git to /tmp/git-devops-demo23205764981" time="2023-09-19T06:39:17Z" level=info msg="rm -rf /tmp/git-devops-demo23205764981" dir= execID=14972 time="2023-09-19T06:39:17Z" level=info msg="secrets informer cancelled" time="2023-09-19T06:39:17Z" level=info msg="configmap informer cancelled" time="2023-09-19T06:39:17Z" level=info msg=Trace args="[rm -rf /tmp/git-devops-demo23205764981]" dir= operation_name="exec rm" time_ms=4.474982 time="2023-09-19T06:39:17Z" level=info msg="git fetch origin --tags --force" dir=/tmp/git-devops-demo23205764981 execID=08213 time="2023-09-19T06:39:17Z" level=info msg=Trace args="[git fetch origin --tags --force]" dir=/tmp/git-devops-demo23205764981 operation_name="exec git" time_ms=492.78976600000004 time="2023-09-19T06:39:17Z" level=info msg="git config user.name argocd-image-updater" dir=/tmp/git-devops-demo23205764981 execID=35e12 time="2023-09-19T06:39:17Z" level=info msg=Trace args="[git config user.name argocd-image-updater]" dir=/tmp/git-devops-demo23205764981 operation_name="exec git" time_ms=1.4469750000000001 time="2023-09-19T06:39:17Z" level=info msg="git config user.email [email protected]" dir=/tmp/git-devops-demo23205764981 execID=6515c time="2023-09-19T06:39:17Z" level=info msg=Trace args="[git config user.email [email protected]]" dir=/tmp/git-devops-demo23205764981 operation_name="exec git" time_ms=1.593801 time="2023-09-19T06:39:17Z" level=info msg="git checkout --force main" dir=/tmp/git-devops-demo23205764981 execID=e5492 time="2023-09-19T06:39:17Z" level=info msg=Trace args="[git checkout --force main]" dir=/tmp/git-devops-demo23205764981 operation_name="exec git" time_ms=5.05169 time="2023-09-19T06:39:17Z" level=info msg="git clean -fdx" dir=/tmp/git-devops-demo23205764981 execID=5cca4 time="2023-09-19T06:39:17Z" level=info msg=Trace args="[git clean -fdx]" dir=/tmp/git-devops-demo23205764981 operation_name="exec git" time_ms=1.8230989999999998 time="2023-09-19T06:39:17Z" level=info msg="git commit -a -F /tmp/image-updater-commit-msg2911699728" dir=/tmp/git-devops-demo23205764981 execID=ac1b3 time="2023-09-19T06:39:17Z" level=info msg=Trace args="[git commit -a -F /tmp/image-updater-commit-msg2911699728]" dir=/tmp/git-devops-demo23205764981 operation_name="exec git" time_ms=7.143674 time="2023-09-19T06:39:17Z" level=info msg="git push origin main" dir=/tmp/git-devops-demo23205764981 execID=136ad time="2023-09-19T06:39:18Z" level=info msg=Trace args="[git push origin main]" dir=/tmp/git-devops-demo23205764981 operation_name="exec git" time_ms=874.7453360000001 time="2023-09-19T06:39:18Z" level=info msg="Successfully updated the live application spec" applicatinotallow=devops-demo2 time="2023-09-19T06:39:18Z" level=info msg="Processing results: applicatinotallow=1 images_cnotallow=1 images_skipped=0 images_updated=1 errors=0" time="2023-09-19T06:41:18Z" level=info msg="Starting image update cycle, considering 1 annotated application(s) for update" time="2023-09-19T06:41:21Z" level=info msg="Processing results: applicatinotallow=1 images_cnotallow=1 images_skipped=0 images_updated=0 errors=0" time="2023-09-19T06:43:21Z" level=info msg="Starting image update cycle, considering 1 annotated application(s) for update" # ......

また、書き留め回して、ArgoCD画像上向きはリポジトリのvalues.yamlファイルを直接変更するのではなく、ヘルムチャートvalues.yamlを上書きするために特別に使用される.argocd-source-devops-demo2.yamlファイルを作成することにも注意してください。

config Repo

変更を自動的に送信した後、Argo CDはアプリケーションを同期して自動的に展開します。

<<:  公共サービス機関が適切なクラウドネイティブ プラットフォームを選択する方法

>>:  VMware は、アジア太平洋地域におけるイノベーションと変革をリードする顧客を表彰する Customer Achievement Awards を授与します。

推薦する

ウクライナのライファイゼン銀行のCTOが戦時中のクラウド移行について語る

オーストリアのライファイゼン銀行インターナショナルの子会社であるライファイゼン銀行ウクライナは、ロシ...

データセンターの華氏68度という温度制限は過去のものとなった。仮想化によりサーバーが沸騰します。

[51CTO.com 6月18日海外ニュースの見出しの速報] データセンターを68度に冷却するのはす...

清華紫光クラウドは、「クラウド、データ、インテリジェンス」の3次元機能を構築し続け、クラウドとインテリジェンスをユビキタス化する。

今日のデジタル経済時代では、クラウドへの移行はほとんどの企業の間でコンセンサスとなっています。クラウ...

調査レポート: パブリッククラウドストレージはお金の無駄

[[270235]]昨年末、Cohesity の調査によると、IT 幹部の 47% が自社の IT ...

ウェブサイトのユーザーエクスペリエンス分析: 画像最適化手法についての簡単な説明

ウェブサイトの最適化では、画像が適切に最適化されていれば、ページの読み込み速度が向上し、ウェブサイト...

Weibo マーケティングを改善するための中小企業向けソリューション

以前、「中小企業のマイクロブログマーケティングプロセスにおける問題の分析と要約」というタイトルの記事...

企業はジュメイからビジネスの真の意味を探り、他人の真似をしないべきだ

「美に焦点を当て、大人の美しさを促進する」という意味を持つジュメイは、シンプルで面白く、信頼できる化...

価値はウェブサイトの生命力です。2012 年は人類と SEO がまだ到来していません。

SEO、この記事を読んでいるあなたはSEOにとても詳しいと思います。SEOが2012年に入ったとき、...

ウェブサイトの最適化におけるロングテールキーワードの役割

2018年最もホットなプロジェクト:テレマーケティングロボットがあなたの参加を待っていますロングテー...

SAP は支出管理をデジタル化し、不確実な状況でも成功するためにグローバルリーダーと提携

SAPは先日、世界経済の不確実性が企業のデジタル変革を加速させ続ける中、2020年第3四半期に280...

伝統的なインターネット産業は自らを変革しなければ生き残れない

蔡文生氏はこう語った。「未来は、インターネットを理解しているが伝統的な産業を理解していない人たちでは...

ALTタグのSEO効果の分析例

画像の ALT 属性値にはまだこの段階で SEO 効果があるのか​​どうかについて議論している初心者...

知られざる驚くべき外部リンクテクニックを発見

現在、多くのウェブマスターが、外部リンクを投稿するのが難しい、また、投稿しても追加されないと不満を述...

Sina Weiboがマーケティングのための「マイクロタスク」プラットフォームを立ち上げ。大手アカウントの終焉か?

admin5.comの10月19日の記事によると、新浪微博の公式タスク送信プラットフォーム「Micr...

電子商取引のサンプル:Wanbiao.comの顧客単価10,000元

薛曼子さんと小曼さん(左)はスイスの時計ブランドDAVOSAを訪問し、同ブランドの創設者(右)から温...