xargsの結果をリダイレクトでファイルに出力する時に無限ループにしない
特定のディレクトリにあるファイルを全部catして、結果をファイルに保存したい時に最初に以下のように書いてみた。
find . -type f | xargs cat > all.txt
やってみるとわかるが、これだと無限に実行が終了せずにall.txtにどんどんデータが書き込まれてファイルサイズが巨大になっていく。
対処
対処法としてはxargsで直接catに渡さずにshコマンドを経由して実行すると解決した
find . -type f| xargs -I@ sh -c 'cat "@" >> names.txt '
ワイがお世話になっているKubernetes関連のツール達
Kubernetes関連のツールで普段よくお世話になっているツール達を紹介します。 ここには無いオススメツールがあればぜひtwitter: @tomiokasyogoに教えていただけるととても喜びます。
TL;DR
- https://github.com/derailed/k9s
- https://github.com/jonmosco/kube-ps1
- https://github.com/ahmetb/kubectx
- https://github.com/wercker/stern
- https://kube-forwarder.pixelpoint.io/
k9s
UIがリッチなkubernetes用のCLI。brewなら
$ brew install derailed/k9s/k9s
でインストール出来る。
起動する時には基本的にこれ。
$ k9s
Deployment、Pod、Logなどすべてのリソースをいい感じのUIで確認できて、vimライクなコマンド操作でスムーズに操作が可能 ワードでの絞り込みも簡単にかけられる。また設定ファイルを書くとUIをカスタマイズすることも可能
kupe-ps1
自分が今、どのクラスタ・namespaceを触っているかをコマンドラインに出してくれるツール。オペミスを防ぐために必須。
$ brew update $ brew install kube-ps1
をした後に Zshなら
source /path/to/kube-ps1.sh PROMPT='$(kube_ps1)'$PROMPT
Bashだと
source /path/to/kube-ps1.sh PS1='[\u@\h \W $(kube_ps1)]\$ '
としておくと、Promptで今、どのクラスタを触っているかが分かる。prd, stgのクラスタは赤、devなら青とかしておくとよりわかりやすい。
(下はdocker-for-desktop
)
kubectx
kubernetesのクラスタをコマンド一つで切り替えられる macOSなら
$ brew update $ brew install kubectx
で入れられる
ただ、kubect
まで kubectl
までと同じで補完が微妙なので私は alias kx="kubectx"
のエイリアスに設定している
kx
まで打って、あとはTab連打で以下のようにpecoが接続先クラスタを出してれる。
stern
「ワイはただ、ログをええ感じにgrepしたいだけなんや...!」という人におすすめ。
複数Pod、Deploymentを跨いだログも簡単に出せるのでログを見るときはだいたいsternを使ってる option等も豊富で色々できるが、とりあえず
$ stern ${Deployment名} |grep xxxx
だけでも十分なくらい優秀。
kube-forwarder
これまでCLIが多かったが、これはGUI。 port-forward先をコンテキストごとに複数登録できて、使いたいときにはボタン一つで簡単にport-forwardを開始できる。 makefileとかで頑張ってる人はこれに乗り換えると幸せになれるかも。 ただgrpcで使うと微妙にうまく動作しないことがある。
https://github.com/txn2/kubefwdGUIはやだよ、CLIじゃ無いと無理!って人は kubefwdとかいいんじゃないんでしょうか
Kubernetes Meetup Tokyo #26参加日記
12/3に開催されたKubernetes Meetup Tokyo #26にブログ枠で参加して来ました。
簡単なメモ程度ですが記事させていただきます。
イベントのcannpassのページはこちらです
KubeCon + CloudNativeCon North America 2019 Overview
まずはIan LewisさんによるKubeCon全体の振り返りです。 KubeConの参加者は年々増えており、今回のKubeConでは12000近い参加者が参加していたそうです。また、各国別の参加者ではなんと日本が3番目に多かったそうです
他にも印象的だったKeynoteの紹介などがされていました
Your Path to Production Ready Kubernetes hosted by Weaveworks
- AI関連のプロダクトでk8sを使用
- 初海外,初KubeCon
- 資料は公開されている https://docs.google.com/presentation/d/1xuuEm3E0fryak2Yl3ej_DnplrhHi2WjVSHLxBOYBUZ4/edit
- WeaveCloudのトライアルアカウントを利用
- WeaveCloudのUI綺麗、GitOpsが簡単にできるので体験が良さそう
- クラスタ側、アプリケーション側の両方でチェックリストがある
- RED(Request, Error, Dea
Keynote: Seamless Customer Experience at Walmart Stores Powered by Kubernetes@Edge
Junichi Yoshise さん(@jyoshise), Hewlett Packard Enterprise
https://www.youtube.com/watch?v=sfPFrvDvdlk
- もともとクラウドに置いていた物をedgeに置いた
- エッジコンピューティングのメリット: low latency, 大規模データを扱うので、通信の問題、接続が失われた場合でもエッジで独立して対処できる。クラウドに頼らない
- 考慮しなければいけない問題が多そう
- 店舗にラックおくのはきつい
- EdgeのケースはMobile
- KubeEdge: https://github.com/kubeedge/kubeedge
- ServiveMesh(特定のサービスだけクラウドに流したいみたいな)はIstioで
- 息を吸うようにOperaoter作る
Running Apache Samza on Kubernetes - Weiqing Yang, LinkedIn Corporation
吉村翔太 (@yosshi_), NTT Communications
- Apache Samza: ストリーミング処理用
- https://github.com/apache/samza
- 他はSpark, Flink
- 新versionとサポートの期限の違いが1年しかない
- Linkdinで開発され、2011年にOSS化
- pertition: サーバーがpersition分作成される
- Samzaの説明はあまり理解しきれなかった...
How Yelp Moved Security From the App to the Mesh with Envoy and OPA
鳥居隆史 さん(@ttorii0609), Dell EMC
- サンディエゴの雨が6ヶ月ぶりだった
- 注目したのはSerivceMeshとSecurity
- Default クラスタのセキュリティはざる
- OPAに注目していた
- computerと人間の両方を認証しよう
- マイグレーションはエンドユーザにやらせず自動化する
- ここまで統一かされていればよいが実際のプロジェクトでそこまでできるかはイメージできない
- プロセスをテクノロジーに合わせていく姿勢、ツールは自作
The Release Team Shadow Program - Mentoring For the Future - Guinevere Saenger, GitHub & Lachlan Evenson, Microsoft
Yang Li (@idealhack), Kubernetes community
- kubernetes コミュニティ
- 新しくコミュニティに参加したメンバーは困っている https://static.sched.com/hosted_files/kccncna19/60/The%20Release%20Team%20Shadow%20Program%20-%20Mentoring%20For%20The%20Future.pdf
- Kubernetesに新しくコントリビュートしようとする場合、何から始めたらいいかさっぱりわからないよね。そこでシャドウプログラミングをやるよ!!!ハンドブックを作ってるんだって
- https://github.com/kubernetes/sig-release/tree/master/release-team
Kubernetes Meetup Tokyo #25に参加してきた
Kubernetes Meetup Tokyoとは
Kubernetes Meetup Tokyoは、Kubernetesのユーザが集まり、KubernetesやKubernetes周辺のソフトウェアについて、情報交換、交流をするイベントとなっています。
※当日の様子は下記で配信されています
入門、Kubernetes Persistent Volume
発表者: 坂下 幸徳(Twitter: @ysakashita3, GitHub: ysakashita), 所属: ゼットラボ株式会社
KubernetesのPV(Persistent Volume)に関する発表でした。用語の整理から、ストレージの種別、k8s内部における動き、よくあるQAなどとても丁寧にまとまった内容で、普段PVを頻繁に利用していない私でもスムーズに理解することができました。
PVに不安を感じる方はぜひ一度見て見ると良いと思います
KubernetesにおけるCSIについて
発表者: 早川 大貴 (Twitter: bells17_, Github: bells17), 所属: 株式会社IDCフロンティア
Kubernetesなどのコンテナオーケストレータにおけるストレージを利用する際の共通仕様であるCSI (Container Storage Interface)に関する発表でした。
CSIが必要とされている背景や、CSIによってどういった点が定められているのかがまとめられていて興味深い内容でした。 またボリュームプラグインのソースコードをKubernetesから除外することで、Kubeletなどのimageのサイズが小さくできるのも嬉しいと感じる点でした。
How to develop the high-available Redis database application on Kubernetes
発表者: Ran Xu (Github: fengzixu Twitter: Haierdi0715)
最後のセッションは英語での発表でした。 調べたのですがスライドは確認できませんでした。
内容としてはRedis ClusterをマネジメントするOperatorに関する内容でした。
@inductorさんがTwitter上で実況してくださっていたのがとてもわかりやすくて助かりました
⬇︎このあたりから [https://twitter.com/inductor/status/1194573349914988544:embed]
Kuberneteはクラスタ管理やインフラ管理に長けていることを利用し、高信頼性なデータ保持性、高可用性をもったRedis Clusterを構築することが目的のようでした。
時間の関係上スキップされた内容が多かったのですが、Redis Clusterを関するControllerやRedis ClusterにアクセスするためのSLB (Super Load Balancer)と呼ばれるLBを実装した話がとても印象的でした。
発表の最後にこのRedis OperatorがOSS化される準備ができているとのことをおっしゃられていたので公開されるのが待ち遠しいです。
LT
LTは予定の都合により参加できなかったのですが、どれも面白い内容+参考になる情報が盛りだくさんでした。
※LTを含むスライドはこちらで確認できます
Workload-identityでGKEのPodに権限を与える
従来のGKEでの認証情報の渡し方
既存のGKEクラスタでは使用したリソースへのアクセス・編集権限を持ったGCPのサービスアカウントを発行し、サービスアカウントのjsonキーをkubernetesリソースであるSecretに登録し、マウントすることでアプリケーションから他のGCPリソースへのアクセス権限を渡していると思います。
しかし、この手法ではSecretをどの様に管理するかによってセキュリティリスクが大きく異なります。KMSなどのKey Management Serviceを利用することでセキュリティリスクを削減することも出来ますが、それでもjsonファイル一つで認証情報がすべてわかってしまう為、キーが漏洩する危険性は常に付きまとっています。
Workload Identity
Workload IdentityとはGKE上で動作しているPodがGCSなどの他のGCPリソースを使用する際の認証情報を渡す為の手法です。
Workload IdentiyではKubernetes上のServiceAccountとGCP上のServiceAccountを紐づけることでサービスアカウントの認証情報を直接Podに渡すことなく認証を行うことができる手法です。 (このブログでは両方が”ServiceAccount”では説明がややこしくなってしまうので、公式ドキュメントになぞってKubernetesのリソースであるServiceAccountをKSA、GCPの認証用アカウントであるServiceAccountをGSAとしています)
Google Cloud Nextで登場したスライドの図がとてもわかりやすくなっています。最後に発表のリンクを貼っておきます
KSAとGSAを紐づけることで、図の様にMetadata Serverからアクセストークンを取得し利用することが出来ます。
実際に使ってみる
それでは実際に使ってみたいと思います
準備
workload-identityを有効にしたGKEクラスタを作成します
$ gcloud beta container clusters create ${cluster-name} \ --cluster-version=1.12 \ --identity-namespace=${project-id}.svc.id.goog \ --zone=asia-northeast1-c
次にGSAを作成します。この時点ではなんの権限も付与していません
$ gcloud iam service-accounts create workload-identify-sa-k8s
次にクラスタ内に新しくecho
というnamespaceと、echo
namespace内に今回使用するKSAを作成します
- namespaceの作成
$ kubectl create namespace echo
- KSAの作成
$ kubectl create sa -n echo workload-identify-sa
次に2つのGSAとKSA間にCloud IAMポリシーバインディングを作成して、KubernetesサービスアカウントがGoogleサービスアカウントを使用できるようにします。このバインドにより、KubernetesサービスアカウントがGoogleサービスアカウントとして機能できるようになります。
$ gcloud iam service-accounts add-iam-policy-binding \ --role roles/iam.workloadIdentityUser \ --member "serviceAccount:${project-id}.svc.id.goog[echo/workload-identity-sa-k8s]" \ workload-identify-sa@${project-id}.iam.gserviceaccount.com
GCP側の設定が完了したので、次にKSA側にGSAの情報を付与します。 付与する時にはKSAにGKA名が入ったアノテーション を追加することで付与することができます
$ kubectl annotate sa \ --namespace echo \ workload-identity-sa-k8s \ iam.gke.io/gcp-service-account=workload-identify-sa@${project-id}.iam.gserviveaccount.com $ kubectl describe sa -n echo workload-identity-sa-k8s Name: workload-identity-sa-k8s Namespace: echo Labels: <none> Annotations: iam.gke.io/gcp-service-account: workload-identify-sa@${project-id}.iam.gserviveaccount.com Image pull secrets: <none> Mountable secrets: workload-identity-sa-k8s-token-6qhd4 Tokens: workload-identity-sa-k8s-token-6qhd4 Events: <none>
KSAではSAに紐づくTokenがSecretとして同時に作成されます。
ServiceAccountをDeployment等で指定すると同時にSecretが/var/run/secrets/kubernetes.io/serviceaccount
にマウントされてKSAのTokenや証明書の情報を参照することができます。
実際にKSAとGSAが紐づいているかを確認する
google/cloud-sdkのイメージを利用して実際にKSAとGSAが紐づいているのかを確認します。 下記のコマンドで一時的なPodをデプロイします
$ kubectl run -it \ --generator=run-pod/v1 \ --image google/cloud-sdk \ --serviceaccount workload-identity-sa-k8s \ --namespace echo \ workload-identity-test
デプロイが完了するとターミナルがPod内でコマンドを実行することができるので
$ gcloud auth list
とタイプしてみましょう。そうすると先ほど指定したGSAのリストがActivateされていることが確認できると思います。
実際にアプリケーションから利用する
実際にアプリケーションから非公開のGCSバケットにアクセスしてデータを取得してみようと思います。 以下のコマンドでバケットを作成し、適当なファイルをおきます
$ gsutil mb gs://workload-identity $ gsutil cp aa.txt gs://workload-identity/aagsutil cp aa.txt gs://workload-identity/aa.txt
次にバケットの読み取り権限を付与します
$ gsutil acl ch -u gcs workload-identify-sa@${project-id}.iam.gserviveaccount.com:READER gs://workload-identity/aa.txt
あとは以下の様なコードを書くことでGCSのオブジェクトを読み込むことができます
package main import ( "context" "fmt" "io" "net/http" "golang.org/x/oauth2" "golang.org/x/oauth2/google" ) func main() { http.HandleFunc("/", helloWorld) http.ListenAndServe(":8080", nil) } func helloWorld(w http.ResponseWriter, r *http.Request) { ctx := context.Background() ts, err := google.DefaultTokenSource(ctx) if err != nil { fmt.Fprintf(w, "Can't read object!,%s", err) return } gcs := oauth2.NewClient(ctx, ts) resp, err := gcs.Get(fmt.Sprintf("https://storage.cloud.google.com/%s/%s", "workload-identity", "aa")) if err != nil { fmt.Fprintf(w, "Can't read object!,%s", err) return } defer resp.Body.Close() io.Copy(w, resp.Body) }
DefaultTokenSource
のコメントに書いてありますが DefaultTokenSource
は以下の様な順番でクレデンシャル情報を探します
// It looks for credentials in the following places, // preferring the first location found: // // 1. A JSON file whose path is specified by the // GOOGLE_APPLICATION_CREDENTIALS environment variable. // 2. A JSON file in a location known to the gcloud command-line tool. // On Windows, this is %APPDATA%/gcloud/application_default_credentials.json. // On other systems, $HOME/.config/gcloud/application_default_credentials.json. // 3. On Google App Engine standard first generation runtimes (<= Go 1.9) it uses // the appengine.AccessToken function. // 4. On Google Compute Engine, Google App Engine standard second generation runtimes // (>= Go 1.11), and Google App Engine flexible environment, it fetches // credentials from the metadata server.
今回の場合、4番にある様にGKEのMetadata Serviceに問い合わせ、IAMからTokenを取得することでアクセスが可能になっています。 コードだとこの辺りでしょうか
https://github.com/golang/oauth2/blob/master/google/default.go#L107-L113
// Fourth, if we're on Google Compute Engine, an App Engine standard second generation runtime, // or App Engine flexible, use the metadata server. if metadata.OnGCE() { id, _ := metadata.ProjectID() return &DefaultCredentials{ ProjectID: id, TokenSource: ComputeTokenSource("", scopes...), }, nil }
運用を考えて
実際にWorkload-identityを使用する場合、現状のGSAをSecretで渡す形式より良いと感じる部分は以下の点です
- KSAと紐づけられるのでキー漏洩の心配が無くなる
- KSAはnamespaceで区切れる=namespaceごとに開発チームを分けることで、管理がしやすくなる
ただ、使用する際にはマニフェストのAnnotationに書くだけなのでnamespaceのKSAを指定しておけば紐づくGSAも使えてしまうというのは少し気になります。(Secretを利用した場合でも同じですが) ちゃんとやるなら開発チームやサービスごとにnamespaceを分けるのは必須の様な気がします。
総合的にみるとGCP内で認証プロセスが完結し、開発者が認証情報を直接触らなくていいだけでかなりメリットが大きい機能だと思います。 認証プロセスだけ少し複雑なのでちゃんと理解する必要がありますが、ぜひ使っていきたい機能ですね。
参考サイト、発表
https://cloud.google.com/kubernetes-engine/docs/how-to/workload-identity
KnativeなCI/CDツールのTektonを使って、GKE上でイメージのビルド、GKEへのデプロイを行う
What is Tekton?
Tektonはk8sネイティブなCI/CDを構築するためのプロジェクトです。 CDF (Continuous Delivery Foundation)のメンバーでもあります。
Tektonの目指しているゴールとしてはクラウドプラットフォームやオンプレ環境などに依存しないCI/CD環境を構築することのようです。
READMEを参考にするとTektonは、
1. Cloud Native
・Kunernetes上で実行可能
・コンテナを実行ブロックの単位として扱える
2. Decoupled
・一つのパイプラインで複数のクラスタにデプロイできる
・パイプラインを構築するTaskは単独で実行可能
・複数のgitリポジトリを簡単に扱える
3. Typed
・リソースは入力によって変更可能
(例:例えばImageのビルドを簡単にkanikoにしたりbuildkitにしたりできる)
Tektonに関してもっとよく知りたい方にはCloud Next '19の以下のセッションが参考になると思います。
Tektonに登場する概念
Tektonに登場する概念ついて説明します。
Step
もっとも基本的な単位、kubernetesのPodと同じように定義できる
Task
複数のStepによって構成される。Stepごとに動作させるコンテナやリソースは指定できる。
Pipline
Taskを組み合わせたもの、実行する順番などを指定することもできる。また、複数あるTaskは同じノードで実行される訳ではない。
PiplineResources
Taskで利用されるインプットやアウトプットを指定するためのリソースとしてPiplineResources
があります。
例えば、
・TaskにインプットとしてGitHubのソースコードを利用
・TaskのアウトプットとしてDockerイメージを作り出す。また、作ったイメージはGCRやDockerHubなどのイメージレジストリーにPushされる
といった場合にそれぞれの入力や出力をPiplineResources
を利用して定義します。
TaskRun && PipelineRun
TaskやPipelineを実際に実行するためのリソースがTaskRun
とPiplineRun
です。
TaskRun
とPipelineRun
ではこれまでに定義したTask、Pipelineに対してPipelineで定義したリソースおよび、トリガーの情報、引数などを実際に渡します。
イメージとしてはTask、Pipelineでどのようなタイプのリソースを使ってどんな処理をするのかを定義しておいて、TaskRunとPipelineRunで実際のリソースを渡してあげるようなイメージです。
PipelineResourceとTask、TaskRunの関係を大雑把に示したものが以下の図になります。Pipelineは少し違いますが考え方は大体同じです。
それでは実際に、Tektonを使ってGoのコードのテスト、Dockerイメージのビルド&GCRへのプッシュ、GKEへのデプロイを行って行きます。
下準備
GKEクラスタの構築とTektonのデプロイ
Google Cloudのクイックスタートを参考にして、GKEクラスタを構築、およびkubectlコマンドでGKEクラスタにアクセスできるようにしてきます。
またこちらを参考にcluster-admin権限を取得、TektonPipelineリソースをGKEにデプロイします。TektonリソースはCRDsとしてデプロイされるのでコマンド一つでGKE上で使用できるようになります。
Kanikoのためのサービスアカウントの登録
今回はDockerイメージのビルドにKanikoを利用しているのでこちらのサイトを参考にしてGCRのeditor権限を持ったサービスアカウントを作成してSecretとして登録しておきます。今回は単にSecretとして利用していますが、プロダクションで利用する際にはKMSなどを使用した方がセキュリティ的に安全です。
ClusterRoleBindの設定
今回のデモではkubernetesクラスタにデプロイするので、クラスタのAdmin権限を持ったServiceAccountが必要になります。exampleのClusterRoleBindingリソースを参考にAdmin権限を付与したServiceAccountを登録します。今回の例ではdefaultに付与しています。GKEにうまくデプロイできない場合にはこのあたりをもう一度見直す必要があります。
流れ
今回のデモでは、
- Goアプリケーションのテスト
- Dockerイメージのビルド
- kubectlコマンドでGKEクラスタにそのままデプロイ
の順番で行います。
PipelineResourcesの登録
まずはPipelineで利用するPipelineResources
を登録します。
今回使用するリソースは、アプリケーションのGitHubリポジトリのURLと、イメージをPushするGCRを指定しています。以下のようなYamlファイルを用意してapplyします。
apiVersion: tekton.dev/v1alpha1 kind: PipelineResource metadata: name: tekton-sample-resource-image spec: type: image params: - name: url value: gcr.io/${YOUR_PROJECT}}/tekton-sample-image # modify to your GCR path. --- apiVersion: tekton.dev/v1alpha1 kind: PipelineResource metadata: name: tekton-sample-resource-git spec: type: git params: - name: revision value: master - name: url value: https://github.com/tommy-sho/tekton-sample.git # modify to your git repository
ここで重要なのは、spec.type
の部分です。Tektonでは各リソースの種類がtype
として指定されています。
kubectl get PipelineResource
でPipelineResource
が以下のように登録されていることが確認できます。
NAME AGE tekton-sample-resource-git 6m tekton-sample-resource-image 6m
Taskの登録
イメージのビルドとプッシュ
次にTask
を登録します。KanikoによるDockerイメージのビルドとGCRへのプッシュを行うタスクを以下のようなYamlファイルで定義します。
apiVersion: tekton.dev/v1alpha1 kind: Task metadata: name: build-image spec: inputs: resources: - name: app type: git params: - name: pathToDockerFile description: The path to the dockerfile to build default: /workspace/app/Dockerfile - name: pathToContext description: The build context used by Kaniko (https://github.com/GoogleContainerTools/kaniko#kaniko-build-contexts) default: /workspace/app/ # <- ここのpathはworkspace/resource名/のプレフィックスがつく outputs: resources: - name: builtImage type: image steps: - name: build-and-push image: gcr.io/kaniko-project/executor command: - /kaniko/executor args: - --dockerfile=${inputs.params.pathToDockerFile} - --destination=${outputs.resources.builtImage.url} - --context=${inputs.params.pathToContext} volumeMounts: - name: kaniko-secret mountPath: /secret env: - name: GOOGLE_APPLICATION_CREDENTIALS value: /secret/kaniko-secret.json volumes: - name: kaniko-secret secret: secretName: kaniko-secret
ここで注意する必要があるのはparmsで指定しているpathのプレフィックスです。現在(2019/5)では、type:git
のPipelineResource
は/workspace/リソース名
以下に配置されます。今回は、input.resource
にapp
という名前のリソースにしているので/workspace/app
以下にGitHubのコードが展開されます。
GKEへのデプロイ
GKEへのデプロイはkubectlが利用できるlachie83/k8s-kubectl
イメージを利用しました。Yamlファイルは以下のようになっています。
apiVersion: tekton.dev/v1alpha1 kind: Task metadata: name: deploy-kubectl spec: inputs: resources: - name: app type: git params: - name: path description: Path to the manifest to apply steps: - name: run-kubectl image: lachlanevenson/k8s-kubectl command: ['kubectl'] args: - 'apply' - '-f' - '${inputs.params.path}'
単純にkubetcl apply
を叩いているだけです。デプロイに使うマニフェストを渡しています。
Pipelineの設定
さて、PipelineResourceとTaskが定義できたのでいよいよPipelineを定義していきます。Pipelineを定義したYamlファイルは以下のようになっています。
apiVersion: tekton.dev/v1alpha1 kind: Pipeline metadata: name: sample-pipline spec: resources: - name: app type: git - name: image type: image tasks: - name: build-push-image taskRef: name: build-image params: - name: pathToDockerFile value: /workspace/app/Dockerfile - name: pathToContext value: /workspace/app resources: inputs: - name: app resource: app outputs: - name: builtImage resource: image - name: deploy runAfter: [build-push-image] taskRef: name: deploy-kubectl params: - name: path value: /workspace/app/manifest.yaml resources: inputs: - name: app resource: app
特に難しいことはありません。spec.resources
でPipelineの中で利用するPipelineResource
を定義しておいて、spec.tasks
で実行するTaskを並べています。
また、それぞれのTaskに対して、使用するparams
とresources
を定義します。
もしTaskに実行する順番(ex. line -> test -> build -> deployなど)がある場合には、runAfter
で依存関係を明示することができます。宣言しなかった場合にはそれぞれPodが立って並列で実行されます。
PipelineRunの定義
さてまだあります。PipelineRun
です。Pipeline
では最初にPipelineResource
を定義して、Taskの中でどのresource
を使用するかを定義していますが、またresource
のタイプのみしか明らかになっていないので、PipelineRun
で実際にどのPipelineResource
を使用するのかを宣言します。
PipelineRun
は以下のようにしました。
apiVersion: tekton.dev/v1alpha1 kind: PipelineRun metadata: name: pipeline-run spec: pipelineRef: name: sample-pipline trigger: type: manual resources: - name: app resourceRef: name: tekton-sample-resource-git - name: image resourceRef: name: tekton-sample-resource-image
使用するPipelineResource
とtrigger
が定義されています。最初の方で定義したPipelineResource
とPipeline
を結びつけています。
現在(2019/5)ではtrigger
はGitHubへのPushや、Slackなどを使ったチャットオペレーションには対応していない状態です。こちらのRoadmapによると2019年以内には対応する予定のようです。
実際にPipelineRunしてみる
これで準備ができたので、今までに定義したリソースをapplyした後で、PipelineRun
をapplyしてみます。
kubectl get tekton-pipelines
コマンドでTektonPipelineのリソースが確認できます。
$ > kubectl get tekton-pipelines NAME AGE pipeline.tekton.dev/sample-pipline 2m NAME STATUS STARTTIME COMPLETIONTIME pipelinerun.tekton.dev/pipeline-run True 2m 37s NAME AGE pipelineresource.tekton.dev/tekton-sample-resource-git 2m pipelineresource.tekton.dev/tekton-sample-resource-image 2m NAME AGE task.tekton.dev/build-image 2m task.tekton.dev/deploy-kubectl 2m NAME SUCCEEDED REASON STARTTIME COMPLETIONTIME taskrun.tekton.dev/pipeline-run-build-push-image-6jbcm True 2m 43s taskrun.tekton.dev/pipeline-run-deploy-782tv True 43s 37s
一番下の部分がPipelineの中の各TaskでSUCCEEDED
が True
になっていることがわかります。
Taskが正しく完了しなかった場合にはSUCCEEDED
がFalse
になります。
実際にGKEにデプロイされたかどうかを確認します。
$ > kubectl get pods NAME READY STATUS RESTARTS AGE pipeline-run-build-push-image-dhjvh-pod-51492d 0/3 Completed 0 1m pipeline-run-deploy-wr7cm-pod-1a4ff9 0/3 Completed 0 26s sample-6d96898c4c-hk847 1/1 Running 0 20s sample-6d96898c4c-tr4hd 1/1 Running 0 20s
正しくデプロイされているようです。Taskで利用されたPodも確認できます。
まとめ
KnativeなCI/CDツールとして期待されているTektonを触って見ました。 今回は触っていませんが、DashBoradを作成してPipelineの実行状況の確認などもできるようです。 リポジトリをみるとTekton自体まだ開発が始まって間もないプロジェクトなのでまだ機能的には足りないと感じる部分はありますが、Kubernetes上でCI/CDパイプラインを構築できる点やカスタマイズ性の高さは触っていても非常に高いと感じたのでこれからの開発に要注目して行きたいとおもいます。 あとこのマスコットキャラも近未来感があって好きだったりします。
もし、うまく動かない、記事に変な点があったりする場合には気軽にコメントや連絡してください。
参考サイト、記事
GKEクラスタ内からMemoryStoreにアクセスするならIP エイリアスを有効に
IPエイリアス
IPエイリアスに関してはこちらの公式サイトにて説明があります。 IPエイリアスを有効にすることで、GCPの他のプロダクトやサービスを操作できるようになります。
公式サイトにある手順の中で、IPエイリアスを設定する部分をよく読まずにGKEクラスタをぽちぽち立てていたところ、GKEのクラスタ内部からMemoryStoreにアクセスできない事案が発生しました。調べた結果IPエイリアスが無効(Disable)になっておりMemoryStoreにアクセスできない状態だったみたいです。
IP エイリアスを有効にする
IPエイリアスを有効にするためには、GKEクラスタを立ち上げる際に、
gcloud container clusters create visitcount-cluster --num-nodes=3 --enable-ip-alias
引用:https://cloud.google.com/memorystore/docs/redis/connect-redis-instance-gke
のように--enable-ip-alias
をオプションでつけることで有効にすることができます。
コンソールから設定する場合にはNetworking
のEnable VPC-native (using alias IP)
にチェックを入れることで有効にできます。(下図)
しかし、下にも書いてあるようにもうすぐデフォルトで有効になるようなので必要なのは今だけだと思います。