Tektonは、Kubernetes上で動作する、強力で柔軟なオープンソースのCI/CDフレームワークです。Kubernetesのカスタムリソース定義 (CRD) を利用して、パイプラインを定義し、実行します。Tektonは、クラウドネイティブなアプリケーション開発とデプロイメントを促進するために設計されており、コンテナイメージのビルド、テスト、デプロイメントなどのタスクを自動化できます。
Spring BootのHelloWorld APIをTektonのPipelineでデプロイする方法を説明します。この例では、以下のステップを実行します。
1. Spring Boot HelloWorld APIの作成:
Spring Initializr を使用して、シンプルなHelloWorld APIを作成します。
- Dependencies: Spring Web を選択
- Group: com.example
- Artifact: hello-world
src/main/java/com/example/helloworld/HelloWorldApplication.java を編集して、RestControllerを追加します。
package com.example.helloworld;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
@RestController
public class HelloWorldApplication {
public static void main(String[] args) {
SpringApplication.run(HelloWorldApplication.class, args);
}
@GetMapping("/")
public String hello() {
return "Hello, World!";
}
}
2. Dockerfileの作成:
- プロジェクトのルートディレクトリに Dockerfile を作成します。
FROM openjdk:17-jdk-slim
COPY target/*.jar app.jar
ENTRYPOINT ["java", "-jar", "app.jar"]
3. Kubernetesマニフェストの作成:
- k8s/deployment.yaml を作成します。
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-world
spec:
replicas: 1
selector:
matchLabels:
app: hello-world
template:
metadata:
labels:
app: hello-world
spec:
containers:
- name: hello-world
image: <YOUR_DOCKER_REGISTRY>/hello-world:latest # イメージ名は後で置き換えます
ports:
- containerPort: 8080
- k8s/service.yaml を作成します。
apiVersion: v1
kind: Service
metadata:
name: hello-world
spec:
selector:
app: hello-world
ports:
- protocol: TCP
port: 80
targetPort: 8080
type: LoadBalancer
4. Gitリポジトリにプッシュ:
- 作成したコード、Dockerfile、KubernetesマニフェストをGitリポジトリにプッシュします。
5. Tekton Taskの定義:
- GitリポジトリからコードをチェックアウトするTask (git-clone.yaml):
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: git-clone
spec:
params:
- name: url
type: string
description: The git repository url to clone from
- name: revision
type: string
description: The git revision to checkout (branch, tag, sha, ref…)
default: "main"
- name: subdirectory
type: string
description: The subdirectory inside the git repository
default: ""
- name: deleteExisting
type: string
description: Clean out the contents of the volume if it exists
default: "true"
workspaces:
- name: output
description: The workspace consisting of the cloned repo.
steps:
- name: clone
image: alpine/git:v1.17
workingDir: $(workspaces.output.path)
securityContext:
runAsUser: 0
script: |
#!/usr/bin/env sh
set -eux
REPO_URI="${inputs.params.url}"
CHECKOUT_REV="${inputs.params.revision}"
SUB_PATH="${inputs.params.subdirectory}"
if [ "${inputs.params.deleteExisting}" = "true" ] ; then
rm -rf /tekton/home/*
fi
git init .
git remote add origin "${REPO_URI}"
git fetch --depth 1 origin "${CHECKOUT_REV}"
git checkout FETCH_HEAD
if [ ! -z "${SUB_PATH}" -a "${SUB_PATH}" != "." ] ; then
mkdir -p "${SUB_PATH}"
rsync -a ./ "${SUB_PATH}"
fi
ls -lR
- DockerイメージをビルドするTask (build-push.yaml):
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: build-push
spec:
params:
- name: IMAGE
type: string
description: The name of the image to build
- name: DOCKERFILE
type: string
description: Path to the Dockerfile
default: Dockerfile
- name: CONTEXT
type: string
description: Path to the build context
default: .
workspaces:
- name: source
description: Directory containing the source code
steps:
- name: build-and-push
image: docker:20.10.7-dind
securityContext:
privileged: true
workingDir: $(workspaces.source.path)
script: |
#!/usr/bin/env sh
set -eux
dockerd-entrypoint.sh &
sleep 10
docker build -t $(inputs.params.IMAGE) -f $(inputs.params.DOCKERFILE) $(inputs.params.CONTEXT)
docker push $(inputs.params.IMAGE)
- KubernetesにデプロイするTask (kubectl-apply.yaml):
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: kubectl-apply
spec:
params:
- name: manifest_dir
type: string
description: The directory containing the Kubernetes manifests
workspaces:
- name: source
description: Directory containing the source code
steps:
- name: apply
image: bitnami/kubectl:latest
workingDir: $(workspaces.source.path)
script: |
#!/usr/bin/env sh
set -eux
kubectl apply -f $(inputs.params.manifest_dir)
6. Tekton Pipelineの定義 (pipeline.yaml):
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
name: hello-world-pipeline
spec:
params:
- name: git-url
type: string
description: The git repository url to clone from
- name: image-name
type: string
description: The name of the image to build
workspaces:
- name: shared-workspace
tasks:
- name: fetch-source
taskRef:
name: git-clone
workspaces:
- name: output
workspace: shared-workspace
params:
- name: url
value: $(params.git-url)
- name: build-and-push
taskRef:
name: build-push
workspaces:
- name: source
workspace: shared-workspace
params:
- name: IMAGE
value: $(params.image-name)
runAfter:
- fetch-source
- name: deploy
taskRef:
name: kubectl-apply
workspaces:
- name: source
workspace: shared-workspace
params:
- name: manifest_dir
value: k8s
runAfter:
- build-and-push
7. Tekton PipelineRunの定義 (pipelinerun.yaml):
apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
name: hello-world-pipelinerun
spec:
pipelineRef:
name: hello-world-pipeline
params:
- name: git-url
value: <YOUR_GIT_REPOSITORY_URL> # GitリポジトリのURLに置き換えます
- name: image-name
value: <YOUR_DOCKER_REGISTRY>/hello-world:latest # Dockerレジストリとイメージ名に置き換えます
workspaces:
- name: shared-workspace
volumeClaimTemplate:
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
手順:
1.Taskの適用:
kubectl apply -f git-clone.yaml
kubectl apply -f build-push.yaml
kubectl apply -f kubectl-apply.yaml
2.Pipelineの適用:
kubectl apply -f pipeline.yaml
3.PipelineRunの適用:
- と /hello-world:latest を適切な値に置き換えてください。
kubectl apply -f pipelinerun.yaml
4.PipelineRunの監視:
kubectl get pipelinerun hello-world-pipelinerun -w
補足:
- Dockerレジストリ: Dockerイメージをプッシュするためには、Dockerレジストリが必要です。Docker Hub、Google Container Registry、Amazon ECRなどを使用できます。
- Kubernetesクラスタ: Kubernetesクラスタが必要です。Minikube、Kind、GKE、EKS、AKSなどを使用できます。
- kubectl: Kubernetesクラスタにアクセスするために、kubectlコマンドラインツールが必要です。
- Tekton Dashboard: Tekton Dashboardをインストールすると、パイプラインの実行状況をGUIで確認できます。
- Workspace: Task間でデータを共有するために、Workspaceを使用しています。この例では、shared-workspaceという名前のWorkspaceを定義し、各Taskで共有しています。
- Service Account: Kubernetesクラスタにアクセスするために、適切な権限を持つService Accountが必要です。必要に応じて、Service Accountを作成し、PipelineRunに紐付けてください。
- Docker in Docker: Dockerイメージをビルドするために、build-push Taskでは、Docker in Docker (dind) を使用しています。securityContext: privileged: true を設定する必要があります。
この例は、基本的なSpring Boot HelloWorld APIをTektonでデプロイする方法を示しています。必要に応じて、TaskやPipelineをカスタマイズし、より複雑なCI/CDパイプラインを構築できます。