Argo Workflowsをkind: Package
にしてtanzuコマンドからインストールする。
以下の方針で進めていく。
- Ingressを利用し、Ingress ControllerはContourを利用する
- TLS証明書はcert-managerに任せる
- TLS証明書は自己署名証明書を利用
- デプロイ先はTanzu Kubernetes Grid
前提
以下がインストールされていること。
- Carvelツール(kapp, imgpkg, kbld, kapp-controllerを利用)
- tanzuコマンド
tanzuコマンドはTCE版か製品版を利用する。
また、push/pullが可能なContainer Registryが必要となる。
今回は自前で立てたHarborを利用した。
ベースとなるManifestの作成
こちらのQuick StartだとIngressが含まれない。
自作してもいいが、面倒なのでHelmからManifestを作成する。bitnami版とコミュニティ版があるが、コミュニティ版の方が更新頻度が高いため、今回はコミュニティ版を利用する。
まず最初に、helmのvalues.yamlを引き抜き、ベースとなるManifestを作りやすくするための値を設定する。
helm repo add argo https://argoproj.github.io/argo-helm
helm inspect values argo/argo-workflows > ./argo-workflow-helm-valus.yaml
helmのvalues.yamlを修正した結果がこちら。ServiceAccountの作成を有効にしたのと、Ingress周りを修正した。
--- argo-workflow-helm-valus.yaml.orig 2022-06-30 11:56:08.607490890 +0900
+++ argo-workflow-helm-valus.yaml 2022-06-30 12:21:44.990590637 +0900
@@ -29,7 +29,7 @@
namespace:
serviceAccount:
# -- Specifies whether a service account should be created
- create: false
+ create: true
# -- Annotations applied to created service account
annotations: {}
# -- Service account which is used to run workflows
@@ -402,7 +402,7 @@
# ref: https://kubernetes.io/docs/user-guide/ingress/
ingress:
# -- Enable an ingress resource
- enabled: false
+ enabled: true
# -- Additional ingress annotations
annotations: {}
# -- Additional ingress labels
@@ -413,8 +413,8 @@
# -- List of ingress hosts
## Hostnames must be provided if Ingress is enabled.
## Secrets must be manually created in the namespace
- hosts: []
- # - argoworkflows.example.com
+ hosts:
+ - argoworkflows.example.com
# -- List of ingress paths
paths:
@@ -423,25 +423,25 @@
# -- Ingress path type. One of `Exact`, `Prefix` or `ImplementationSpecific`
pathType: Prefix
# -- Additional ingress paths
- extraPaths: []
+ extraPaths:
# - path: /*
# backend:
# serviceName: ssl-redirect
# servicePort: use-annotation
## for Kubernetes >=1.19 (when "networking.k8s.io/v1" is used)
- # - path: /*
- # pathType: Prefix
- # backend:
- # service
- # name: ssl-redirect
- # port:
- # name: use-annotation
+ - path: /*
+ pathType: Prefix
+ backend:
+ service:
+ name: ssl-redirect
+ port:
+ name: use-annotation
# -- Ingress TLS configuration
- tls: []
- # - secretName: argoworkflows-example-tls
- # hosts:
- # - argoworkflows.example.com
+ tls:
+ - secretName: argoworkflows-tls
+ hosts:
+ - argoworkflows.example.com
clusterWorkflowTemplates:
# -- Create a ClusterRole and CRB for the server to access ClusterWorkflowTemplates.
作成したvalues.yamlを元に、Argo WorkflowのManifestを作成する。
helm template -f argo-workflow-helm-valus.yaml argo-workflows argo/argo-workflows --include-crds > ./argo-workflow.yaml
--include-crds
を忘れないこと。
次に作成したManifestを書き換えるoverlay.yamlとパラメタ用values.yamlを作成する。
Manifestの整理用に、一旦ディレクトリを作成して元のファイルを移動する。
mkdir -p package/config
mv argo-workflow.yaml package/config/
cd package/config/
ytt overlayの作成&動作確認
ベースとなるManifest(argo-workflow.yaml)を書き換えるoverlayを作成する。overlayで追加・修正する項目は以下とする。
- Namespace名の書き換え
- Host名の書き換え
- 証明書のためのIssuer、Certificateの追加
- Ingressにcert-managerを使うためのannotation追加
overlayのyamlは今回は分かりやすいよう分けて作る。
最初にNamespaceの書き換えを実装する。
cat <<'EOF' > ./overlay_namespace.yaml
#@ load("@ytt:overlay", "overlay")
#@ load("@ytt:data", "data")
apiVersion: v1
kind: Namespace
metadata:
name: #@ data.values.namespace
---
#@overlay/match by=overlay.not_op(overlay.subset({"kind":"Namespace"})),expects="1+"
---
metadata:
#@overlay/match missing_ok=True
namespace: #@ data.values.namespace
---
#@overlay/match by=overlay.subset({"kind":"ClusterRoleBinding"}),expects="1+"
---
subjects:
#@overlay/match by="kind"
- kind: ServiceAccount
namespace: #@ data.values.namespace
---
#@overlay/match by=overlay.subset({"kind":"RoleBinding"}),expects="1+"
---
subjects:
#@overlay/match by="kind"
- kind: ServiceAccount
namespace: #@ data.values.namespace
EOF
最初にNamespaceを作り、Namespace以外のリソースのmetadataにnamespaceを埋め込んでいる。値はvalues.yamlから引っ張ってきたいので、ここではdataから引くようにしている。
また、ClusterRoleBinding/RoleBindingのsubejects:
でnamespaceを参照している部分は見落としやすいため注意。
次にHost名の書き換えを実装する。
cat <<'EOF' > ./overlay_hostname.yaml
#@ load("@ytt:overlay", "overlay")
#@ load("@ytt:data", "data")
#@overlay/match by=overlay.subset({"kind":"Ingress"})
---
spec:
rules:
#@overlay/match by=overlay.index(0)
- host: #@ data.values.hostname
tls:
#@overlay/match by=overlay.index(0)
- hosts:
#@overlay/match by=overlay.index(0)
#@overlay/replace
- #@ data.values.hostname
EOF
こちらもHost名を外部から与えられるようdataから引く。
次に、TLS周りのoverlayを作成する。
cat <<'EOF' > ./overlay_tls.yaml
#@ load("@ytt:overlay", "overlay")
#@ load("@ytt:data", "data")
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: argo-workflow-selfsigned-issuer
namespace: #@ data.values.namespace
spec:
selfSigned: { }
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: argo-workflow-ca
namespace: #@ data.values.namespace
spec:
commonName: argo-workflow-ca
isCA: true
issuerRef:
kind: Issuer
name: argo-workflow-selfsigned-issuer
secretName: argo-workflow-ca
---
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: argo-workflow-ca-issuer
namespace: #@ data.values.namespace
spec:
ca:
secretName: argo-workflow-ca
---
#@overlay/match by=overlay.subset({"kind":"Ingress"})
---
metadata:
#@overlay/match missing_ok=True
#@overlay/match-child-defaults missing_ok=True
annotations:
cert-manager.io/issuer: "argo-workflow-ca-issuer"
EOF
cert-manager用のIssuer、Certificateの作成と、Ingressのannotationに利用するIssuerを指定した。
最後にvalues.yamlを作成する。
cat <<'EOF' > ./values.yaml
#@data/values-schema
---
#@schema/desc "Namespace"
namespace: argo-workflow
#@schema/desc "Hostname"
hostname: argo-workflow.hogehoge.com
EOF
一旦このタイミングで作成したManifestが正常に動作するか確認する。
ytt -f ./ | kapp deploy -a argo-workflow -y -n default -f -
ここでは一旦Ingressが起動するのと、TLS証明書関係のSecretが作成されたことまで確認する。
$ kubectl get ingress -n argo-workflow
NAME CLASS HOSTS ADDRESS PORTS AGE
argo-workflows-server <none> argo-workflow.hogehoge.com 10.206.222.235 80, 443 50s
$ kubectl get secret -n argo-workflow |grep tls
argo-workflow-ca kubernetes.io/tls 3 112s
argoworkflows-tls kubernetes.io/tls 3 112s
気になる人はブラウザでのアクセスもしてみると良い。
動作確認が終わったら削除する。
kapp delete -a argo-workflow -y -n default
kind: Package
, kind: PackageMetadata
,kind: PackageRepository
の作成
tanzuコマンドで扱うためのプロセスは以下となる。
- 先程作ったManifestをimage bundle化してContainer Registoryにupload
-
kind: Package
,kind: PackageMetadata
を作成してimage bundle化 -
kind: PackageRepository
を作成してapply
3が完了した時点で、tanzuコマンドからArgo Workflowをインストール出来るようになる。
image bundleのupload
まず、image bundle化してContainer Registoryに登録する。
image bundleは以下のような構成を期待する。
bundle/
├── .imgpkg/images.yml
└── config/
そのため、最初にディレクトリを作成する。
cd ..
mkdir .imgpkg
次にImagesLockリソースを.imgpkg/images.ymlに作成する。
ytt -f config/ | kbld -f - --imgpkg-lock-output .imgpkg/images.yml
コマンドが成功したら、以下のようなファイルが見れるはずだ。
$ cat .imgpkg/images.yml
---
apiVersion: imgpkg.carvel.dev/v1alpha1
images:
- annotations:
kbld.carvel.dev/id: quay.io/argoproj/argocli:v3.3.8
image: quay.io/argoproj/argocli@sha256:41891b95aca23018ba65b320ff3ce10a98ee3cb39261f02fd74867c68414e814
- annotations:
kbld.carvel.dev/id: quay.io/argoproj/workflow-controller:v3.3.8
image: quay.io/argoproj/workflow-controller@sha256:6d4b11db67c41352088040830b1ab715d3cec762ac37656459e72bd17e0c452c
kind: ImagesLock
これをimgpkgコマンドを使ってContainer Registryにimage bundle形式でuploadする。
docker login myharbor.hoge
imgpkg push -b myharbor.hoge/myapp/argo-workflow-bundle -f ./
なお、コマンド成功時に出てくる、
Pushed 'myharbor.hoge/myapp/argo-workflow-bundle@sha256:7db7f72a79845387b427f7148a7f15db2a71a35159145f0700a414b15eed8a18'
Succeeded
↑のPushedから先のイメージ名は後で使うので控えておく。
kind: Package
, kind: PackageMetadata
の作成
ワークディレクトリを変えて、それぞれを作成してく。
mkdir ../package-bundle
cd ../package-bundle
PackageMetadataを作っていく。nameとdisplayName以外は適当なので、好みで変更すること。
cat << EOF > ./argo-workflow-pkgmeta.yaml
apiVersion: data.packaging.carvel.dev/v1alpha1
kind: PackageMetadata
metadata:
name: argo-workflow.hoge.fuga
spec:
displayName: "argo-workflow"
longDescription: "ArgoCD Workflow for TKG user"
shortDescription: "ArgoCD Workflow"
providerName: IT Dept.
maintainers:
- name: John Doe
categories:
- "Argo"
supportDescription: "Please see https://argoproj.github.io/argo-workflows/"
EOF
次にPackageを作るのだが、Manifest内のvaluesSchemaの項目を埋めるのにimage bundle内のvalues.yamlを利用したいため、overlayさせる形式で記載する。
cat <<EOF > ./argo-workflow-template.yaml
#@ load("@ytt:data", "data")
#@ load("@ytt:yaml", "yaml")
---
apiVersion: data.packaging.carvel.dev/v1alpha1
kind: Package
metadata:
name: #@ "argo-workflow.hoge.fuga." + data.values.version
spec:
refName: argo-workflow.hoge.fuga
version: #@ data.values.version
releaseNotes: |
Initial release of Argo Workflow for TKG user
valuesSchema:
openAPIv3: #@ yaml.decode(data.values.openapi)["components"]["schemas"]["dataValues"]
template:
spec:
fetch:
- imgpkgBundle:
image: myharbor.hoge/myapp/argo-workflow-bundle@sha256:7db7f72a79845387b427f7148a7f15db2a71a35159145f0700a414b15eed8a18
template:
- ytt:
paths:
- "./config"
- kbld:
paths:
- "-"
- ".imgpkg/images.yml"
deploy:
- kapp: {}
EOF
ここでのimage名は、先程imgpkg pushで控えていたimage名を入れている。
先程作成したimage bundleのvalues.yamlをOpenAPIv3形式に変換し、それを上記Packageの雛形と結合してPackageのManifestを生成する。
ytt -f ../bundle/config/values.yaml --data-values-schema-inspect -o openapi-v3 > argo-workflow-schema-openapi.yml
ytt -f ./argo-workflow-template.yaml --data-value-file openapi=./argo-workflow-schema-openapi.yml -v version="3.3.8" > argo-workflow-package-3.3.8.yaml
作成したものを、先程image bundle化した手順と同じようにimage bundle化してuploadする。
ただし、ディレクトリ構成に縛りがあり、packages以下にManifestを置く必要がある。今回は以下のようにする。
bundle/
├── .imgpkg/
└── packages/
└── argo-workflow/
├── metadata.yaml
└── 3.3.8/
└── package.yaml
ディレクトリの作成およびリネーム、移動を実施する。
mkdir -p bundle/{.imgpkg,packages/argo-workflow/3.3.8}
mv argo-workflow-package-3.3.8.yaml bundle/packages/argo-workflow/3.3.8/package.yaml
mv argo-workflow-pkgmeta.yaml bundle/packages/argo-workflow/metadata.yaml
kbld -f bundle/packages/ --imgpkg-lock-output bundle/.imgpkg/images.yml
imgpkg push -b myharbor.hoge/myapp/argo-workflow-pkg-bundle -f ./bundle
kind: PackageRepository
の作成
PackageRepositoryを作成し、tanzuコマンドが認識できるようにする。
cat <<EOF > ./argo-workflow-repo.yaml
apiVersion: packaging.carvel.dev/v1alpha1
kind: PackageRepository
metadata:
name: argo-repo
namespace: tanzu-package-repo-global
spec:
fetch:
imgpkgBundle:
image: myharbor.hoge/myapp/argo-workflow-pkg-bundle:latest
secretRef:
name: myimagerepo
---
apiVersion: v1
kind: Secret
metadata:
name: myimagerepo
namespace: tanzu-package-repo-global
annotations:
secretgen.carvel.dev/image-pull-secret: ""
type: kubernetes.io/dockerconfigjson
stringData:
.dockerconfigjson: |
{
"auths": {
"myharbor.hoge": {
"username": "user",
"password": "xxxx",
"auth": ""
}
}
}
EOF
なお、今回はどこからでもPackageがインストール出来るよう、配置するNamespaceをGlobal Namespaceにしている。
非TKG環境などでは名前が異なるため注意。Global Namespaceの確認方法はkapp-controllerの引数から確認できる。
$ kubectl get deploy -n tkg-system kapp-controller -o yaml | grep packaging-global-namespace | tail -n 1
- -packaging-global-namespace=tanzu-package-repo-global
また、Secretを設定しているのは、PackageRepositoryのカスタムリソースがimageをpullする際にContainer Registoryへの認証情報を要求するためである。
作成したPackageRepositoryのManifestをapplyし、状態がReconcile succeeded
になるまで待つ。
$ kubectl get packagerepository -A
NAMESPACE NAME AGE DESCRIPTION
tanzu-package-repo-global argo-repo 24s Reconcile succeeded
tanzu-package-repo-global tanzu-standard 38d Reconcile succeeded
tbs-install tbs-repository 37d Reconcile succeeded
tkg-system tanzu-core 38d Reconcile succeeded
これで準備はOK。
tanzuコマンドによるインストール
tanzuコマンドで利用可能なバージョンなどを確認する。
$ tanzu package available list
NAME DISPLAY-NAME SHORT-DESCRIPTION LATEST-VERSION
argo-workflow.hoge.fuga argo-workflow ArgoCD Workflow 3.3.8
cert-manager.tanzu.vmware.com cert-manager Certificate management 1.5.3+vmware.2-tkg.1
contour.tanzu.vmware.com contour An ingress controller 1.18.2+vmware.1-tkg.1
external-dns.tanzu.vmware.com external-dns This package provides DNS synchronization functionality. 0.10.0+vmware.1-tkg.1
fluent-bit.tanzu.vmware.com fluent-bit Fluent Bit is a fast Log Processor and Forwarder 1.7.5+vmware.2-tkg.1
grafana.tanzu.vmware.com grafana Visualization and analytics software 7.5.7+vmware.2-tkg.1
harbor.tanzu.vmware.com harbor OCI Registry 2.3.3+vmware.1-tkg.1
multus-cni.tanzu.vmware.com multus-cni This package provides the ability for enabling attaching multiple network interfaces to pods in Kubernetes 3.7.1+vmware.2-tkg.2
prometheus.tanzu.vmware.com prometheus A time series database for your metrics 2.27.0+vmware.2-tkg.1
設定できる値も確認する。
$ tanzu package available get argo-workflow.hoge.fuga/3.3.8 --values-schema -n tanzu-package-repo-global
KEY DEFAULT TYPE DESCRIPTION
hostname argo-workflow.hogehoge.com string Hostname
namespace argo-workflow string Namespace
values.yamlを作成する。
cat <<EOF > ./values.yaml
---
namespace: argo-workflow-edit
hostname: argo-workflow.fugafuga.com
EOF
tanzuコマンドでインストールする前に、kind: Package
がimage bundleを引くためのSecretを登録する。
tanzu secret registry add harbor-registry \
--username user \
--password xxxx \
--server myharbor.hoge \
--export-to-all-namespaces -n default -y
Secretを登録後、packageをインストールする。
tanzu package install argo-workflow -n default -p argo-workflow.hoge.fuga -v 3.3.8 -f ./values.yaml --poll-timeout 30m
正常にインストールされると、tanzu package installed get`で
Reconcile succeeded`が表示される。
$ tanzu package installed get argo-workflow
NAME: argo-workflow
PACKAGE-NAME: argo-workflow.hoge.fuga
PACKAGE-VERSION: 3.3.8
STATUS: Reconcile succeeded
CONDITIONS: [{ReconcileSucceeded True }]
USEFUL-ERROR-MESSAGE:
先程設定したNamespaceにIngressも作成される。
$ kubectl get ing -A
NAMESPACE NAME CLASS HOSTS ADDRESS PORTS AGE
argo-workflow-edit argo-workflows-server <none> argo-workflow.fugafuga.com 10.206.222.235 80, 443 4m58s
ブラウザでログインすると認証方法を聞かれるので、Tokenによるアクセスでログインする。
表示されているリンク先のToken取得方法に従ってTokenを出力し、出力結果をログイン画面の入力ウィンドウにコピペする。
SECRET=$(kubectl get sa default -n default -o=jsonpath='{.secrets[0].name}')
ARGO_TOKEN="Bearer $(kubectl get secret $SECRET -o=jsonpath='{.data.token}' | base64 --decode)"
echo $ARGO_TOKEN
なお、適当なServiceAccountのTokenでログインすると、Argo Workflowsのカスタムリソースへのアクセス権限がなくて何も出来ないので、実際に使う際は適切なServiceAccountのTokenを取得すること。