Tekton Pipelines’a bir önceki makale ile yaptığımız giriş ile “Merhaba Dünya” örneğimizi yapmıştık. Bu makalemde gerçek kullanıma daha uygun bir örnek üzerinden giderek bir aspnet core uygulaması için Sürekli Entegrasyon (CI) akışını gerçekleştireceğiz.
Sürekli Entegrasyon akışı için önceki makalede gördüğümüz Task ve Pipeline CRD tanımlarına ihtiyacımız olacak. Bu tanımlara ek olarak bir PipelineResource CRD tanımıda gerçekleştireceğiz. Hatırlatmak gerekirse, PipelineResource, bir pipeline içerisideki task’lara ait girdi ya da çıktı tanımıdır. PipelineResource nesnesi sayesinde, örneğimizde de yapacağımız gibi, bir task’a git deposu girdi olarak verilebilir.
Makalemin devamında CI tanımını yapacağımız projemizi github depomda bulabilirsiniz. CI tanımını iki farklı yoldan sizlere anlatacağım. İlk yolumuz daha uzun olmakla birlikte aynı zamanda size Tekton Pipelines’ın kullanımı hakkında daha fazla bilgi verecektir. Uzun yol aynı zamanda karışık CI süreçlerinizde kullanabileceğiniz fikirler de verecektir.
Uzun (ya da Manuel) Yol
Uzun yolda sürekli entegrasyon sürecinin her bir adımını biz gerçekleştireceğiz. Aşağıdaki tanım ile Github üzerinde hazırladığım örnek AspNet Core projesine ait git deposu master branşı için bir PipelineResource oluşturuyoruz;
apiVersion: tekton.dev/v1alpha1 kind: PipelineResource metadata: name: tekton-ornek-repo spec: type: git params: - name: revision value: master - name: url value: https://github.com/fatihboy/tekton-ornek
Sırada pipeline için kullanacağımız task tanımında. Taskımıza girdi olarak az önce tanımladığımız tekton-ornek-repo PipelineResource’unu vererek git deposundan kodların yerele çekilmesini sağlayabiliriz;
apiVersion: tekton.dev/v1alpha1 kind: Task metadata: name: build-tekton-ornek spec: inputs: resources: - name: tekton-ornek-repo type: git steps: ...
Artık elimizde git deposunun bir kopyası olduğuna göre sırada ilk adımımızda. İlk adımda basit olarak bir nuget geri yüklemesi yapacağız. Bu işlemi ihtiyacımız olan tüm araçların yer aldığı Microsoft tarafından sunulan DotNet Core SDK imajı içerisinde gerçekleştireceğiz;
apiVersion: tekton.dev/v1alpha1 kind: Task metadata: name: build-tekton-ornek spec: inputs: resources: - name: tekton-ornek-repo type: git steps: - name: nuget-restore image: mcr.microsoft.com/dotnet/core/sdk:3.0-buster command: - /bin/sh - -c args: - dotnet restore TektonOrnek.sln workingDir: /workspace/tekton-ornek-repo ...
Gördüğünüz gibi Tekton bizim için karmaşık detayları yönetiyor. Git deposunun bir kopyasını yerele aldıktan sonra bu dosyalara ulaşabilmemiz için podumuz içerisindeki nuget-restore isimli container’ıda git deposu dosyaların olduğu /workspace/tekton-ornek-repo klasörünü bağlıyor. 18. satırdaki workingDir direktifi ile command (11-13. satırlar) ve args (14-15. satırlar) direktiflerinde verdiğimiz komutun bu klasörde çalıştırılması sağlanmakta.
Nuget paketlerini geri yükledikten sonra sırada artık derleme işlemi var. Bunun için task’a yeni bir adım daha eklemeli ve dotnet core’un klasik derleme komutunu çalıştırmalıyız. Bu adım için yine Microsoft tarafından sunulan DotNet Core SDK imajını kullanacağız.
apiVersion: tekton.dev/v1alpha1 kind: Task metadata: name: build-tekton-ornek spec: inputs: resources: - name: tekton-ornek-repo type: git steps: - name: nuget-restore image: mcr.microsoft.com/dotnet/core/sdk:3.0-buster command: - /bin/sh - -c args: - dotnet restore TektonOrnek.sln workingDir: /workspace/tekton-ornek-repo - name: build image: mcr.microsoft.com/dotnet/core/sdk:3.0-buster command: - /bin/sh - -c args: - dotnet build TektonOrnek/TektonOrnek.csproj -c Release -o /workspace/tekton-ornek-repo/build --no-restore workingDir: /workspace/tekton-ornek-repo ...
build adımını incelendiğinizde nuget-restore adımıyla oldukça benzer olduğunu görebilirsiniz. Aralarındaki tek fark 25. satırdaki derleme komutu. Bir önceki adımda nuget paketlerini yüklediğimiz için build adımında --no-restore
parametresini kullanarak yeniden yüklenmelerini engellemeyi tercih ettim.
Derleme işleminin başarılı olması ardından artık uygulamayı yayınlayabiliriz. Bunun için oluşturduğum publish adımını aşağıda inceleyebilirsiniz;
apiVersion: tekton.dev/v1alpha1 kind: Task metadata: name: build-tekton-ornek spec: inputs: resources: - name: tekton-ornek-repo type: git steps: - name: nuget-restore image: mcr.microsoft.com/dotnet/core/sdk:3.0-buster command: - /bin/sh - -c args: - dotnet restore TektonOrnek.sln workingDir: /workspace/tekton-ornek-repo - name: build image: mcr.microsoft.com/dotnet/core/sdk:3.0-buster command: - /bin/sh - -c args: - dotnet build TektonOrnek/TektonOrnek.csproj -c Release -o /workspace/tekton-ornek-repo/build --no-restore workingDir: /workspace/tekton-ornek-repo - name: publish image: mcr.microsoft.com/dotnet/core/sdk:3.0-buster command: - /bin/sh - -c args: - dotnet publish TektonOrnek/TektonOrnek.csproj -c Release -o /workspace/tekton-ornek-repo/publish --no-restore workingDir: /workspace/tekton-ornek-repo ...
Gerçekçi bir sürekli entegrasyon senaryosu olması adına son adımda birim testlerinin çalıştıralım;
apiVersion: tekton.dev/v1alpha1 kind: Task metadata: name: build-tekton-ornek spec: inputs: resources: - name: tekton-ornek-repo type: git steps: - name: nuget-restore image: mcr.microsoft.com/dotnet/core/sdk:3.0-buster command: - /bin/sh - -c args: - dotnet restore TektonOrnek.sln workingDir: /workspace/tekton-ornek-repo - name: build image: mcr.microsoft.com/dotnet/core/sdk:3.0-buster command: - /bin/sh - -c args: - dotnet build TektonOrnek/TektonOrnek.csproj -c Release -o /workspace/tekton-ornek-repo/build --no-restore workingDir: /workspace/tekton-ornek-repo - name: publish image: mcr.microsoft.com/dotnet/core/sdk:3.0-buster command: - /bin/sh - -c args: - dotnet publish TektonOrnek/TektonOrnek.csproj -c Release -o /workspace/tekton-ornek-repo/publish --no-restore workingDir: /workspace/tekton-ornek-repo - name: unit-test image: mcr.microsoft.com/dotnet/core/sdk:3.0-buster command: - /bin/sh - -c args: - dotnet test TektonOrnek.sln workingDir: /workspace/tekton-ornek-repo
Task’ımızı tamamladıktan sonra artık bir Pipeline oluşturabiliriz;
apiVersion: tekton.dev/v1alpha1 kind: Pipeline metadata: name: tekton-ornek-pipeline spec: resources: - name: tekton-ornek-repo type: git tasks: - name: build taskRef: name: build-tekton-ornek resources: inputs: - name: tekton-ornek-repo resource: tekton-ornek-repo
Son olarak; oluşturduğumuz Pipeline’ı çalıştırmak için aşağıdaki içerikle bir PipelineRun’a ihtiyacımız bulunuyor;
apiVersion: tekton.dev/v1alpha1 kind: PipelineRun metadata: name: tekton-ornek-pipelinerun spec: pipelineRef: name: tekton-ornek-pipeline resources: - name: tekton-ornek-repo resourceRef: name: tekton-ornek-repo
Yukarıdaki tüm CRD’leri aşağıdaki komutla tekton-ornek.yaml dosyasında toplayabilirsiniz;
cat > tekton-ornek.yaml <<EOF apiVersion: tekton.dev/v1alpha1 kind: PipelineResource metadata: name: tekton-ornek-repo spec: type: git params: - name: revision value: master - name: url value: https://github.com/fatihboy/tekton-ornek --- apiVersion: tekton.dev/v1alpha1 kind: Task metadata: name: build-tekton-ornek spec: inputs: resources: - name: tekton-ornek-repo type: git steps: - name: nuget-restore image: mcr.microsoft.com/dotnet/core/sdk:3.0-buster command: - /bin/sh - -c args: - dotnet restore TektonOrnek.sln workingDir: /workspace/tekton-ornek-repo - name: build image: mcr.microsoft.com/dotnet/core/sdk:3.0-buster command: - /bin/sh - -c args: - dotnet build TektonOrnek/TektonOrnek.csproj -c Release -o /workspace/tekton-ornek-repo/build --no-restore workingDir: /workspace/tekton-ornek-repo - name: publish image: mcr.microsoft.com/dotnet/core/sdk:3.0-buster command: - /bin/sh - -c args: - dotnet publish TektonOrnek/TektonOrnek.csproj -c Release -o /workspace/tekton-ornek-repo/publish --no-restore workingDir: /workspace/tekton-ornek-repo - name: unit-test image: mcr.microsoft.com/dotnet/core/sdk:3.0-buster command: - /bin/sh - -c args: - dotnet test TektonOrnek.sln workingDir: /workspace/tekton-ornek-repo --- apiVersion: tekton.dev/v1alpha1 kind: Pipeline metadata: name: tekton-ornek-pipeline spec: resources: - name: tekton-ornek-repo type: git tasks: - name: build taskRef: name: build-tekton-ornek resources: inputs: - name: tekton-ornek-repo resource: tekton-ornek-repo --- apiVersion: tekton.dev/v1alpha1 kind: PipelineRun metadata: name: tekton-ornek-pipelinerun spec: pipelineRef: name: tekton-ornek-pipeline resources: - name: tekton-ornek-repo resourceRef: name: tekton-ornek-repo EOF
Aşağıdaki komutu kullanarak yaml dosyasının uygulanmasını sağlayabilirsiniz;
kubectl apply -f tekton-ornek.yaml
Tekton komut satırı arayüzünü kurduysanız aşağıdaki komutla PipelineRun durumunu hakkında bilgi alabilirsiniz;
tkn pipelinerun describe tekton-ornek-pipelinerun

Benzer şekilde, PipelineRun çalışma logları aşağıdaki komutla görülebilir;
tkn pipelinerun logs tekton-ornek-pipelinerun

Kısa (ya da otomatik) Yol
Kısayolda ilerlemek için Google tarafından Kubernetes üzerinde container imajları oluşturmamızı sağlayan açık kaynak kodlu bir proje olan Kaniko projesinden faydalanacağız. Kaniko projesi konteynar imajları oluşturmak için Docker daemon’ı kullanmak yerine Dockerfile’ı kullanarak tamamen userspace’de çalışmaktadır. Bu özelliğiyle Kubernetes ve özellikle de Openshift üzerinde kullanıma daha uygundur.
Kaniko, konteynar imajı oluşturmak amacıyla gcr.io/kaniko-project/executor imajını sunmaktadır. Temel amacı sürekli entegrasyon olmayan Kaniko bir depo’dan (git, yerel dizin, S3 Bucket v.b.) aldığı Dockerfile’ı kullanarak bir konteynar imajı oluşturur. Biz sürekli entegrasyon sürecine dair adımlarımızı Dockerfile içerine ekleyerek amacımıza ulaşacağız. Bu şekilde yapılandırdığım Dockerfile’ı aşağıda bulabilirsiniz;
FROM mcr.microsoft.com/dotnet/core/aspnet:3.0-buster-slim AS base WORKDIR /app EXPOSE 80 FROM mcr.microsoft.com/dotnet/core/sdk:3.0-buster AS build WORKDIR /src COPY TektonOrnek.sln . COPY TektonOrnek/TektonOrnek.csproj TektonOrnek/ COPY BirimTestleri/BirimTestleri.csproj BirimTestleri/ RUN dotnet restore TektonOrnek.sln COPY TektonOrnek/ TektonOrnek/ WORKDIR /src/TektonOrnek RUN dotnet build TektonOrnek.csproj -c Release -o /app/build FROM build AS publish RUN dotnet publish TektonOrnek.csproj -c Release -o /app/publish FROM build AS testrunner WORKDIR /src COPY BirimTestleri/ BirimTestleri/ RUN dotnet test TektonOrnek.sln --logger:trx FROM base AS final WORKDIR /app COPY --from=publish /app/publish . ENTRYPOINT ["dotnet", "TektonOrnek.dll"]
Konteynar imajımızın yukarıdaki Dockerfile yardımıyla başarılı şekilde oluşturulması demek uzun yoldaki adımlarımıza paralel olarak sürekli entegrasyonun başarıyla tamamlandığı anlamına da gelecektir. Aşağıdaki task tanımı bize istediğimiz adımı üretecektir;
apiVersion: tekton.dev/v1alpha1 kind: Task metadata: name: build-tekton-ornek spec: steps: - name: build image: gcr.io/kaniko-project/executor:v0.15.0 args: - --dockerfile=Dockerfile - --context=git://github.com/fatihboy/tekton-ornek - --no-push
Kaniko’ya geçtiğimiz parametrelerden --no-push
parametresi üretilen konteynar imajının herhangi bir konteynar deposuna gönderilmemesini sağlayacaktır. Pipeline ve PipelineRun CRD’leri uzun yoldakine benzer olmakla birlikte bir resource bölümü bulunmamaktadır.
Aşağıdaki komutla gerekli CRD tanımlarının yer aldığı tekton-ornek-kaniko.yaml dosyası oluşturulabilir;
cat > tekton-ornek-kaniko.yaml <<EOF apiVersion: tekton.dev/v1alpha1 kind: Task metadata: name: build-tekton-ornek spec: steps: - name: build image: gcr.io/kaniko-project/executor:v0.15.0 args: - --dockerfile=Dockerfile - --context=git://github.com/fatihboy/tekton-ornek - --no-push --- apiVersion: tekton.dev/v1alpha1 kind: Pipeline metadata: name: tekton-ornek-pipeline spec: tasks: - name: build taskRef: name: build-tekton-ornek --- apiVersion: tekton.dev/v1alpha1 kind: PipelineRun metadata: name: tekton-ornek-pipelinerun spec: pipelineRef: name: tekton-ornek-pipeline EOF
Aşağıdaki komutu kullanarak yaml dosyasının uygulanmasını sağlayabilirsiniz;
kubectl apply -f tekton-ornek-kaniko.yaml
Tekton komut satırı arayüzünü kurduysanız aşağıdaki komutla PipelineRun durumunu hakkında bilgi alabilirsiniz;
tkn pipelinerun describe tekton-ornek-pipelinerun

Benzer şekilde, PipelineRun çalışma logları aşağıdaki komutla görülebilir;
tkn pipelinerun logs tekton-ornek-pipelinerun


Tekton Pipelines Katalog
Tekton Pipelines Task CRD özellikle PipelineResource CRD’si ile birlikte kullanıldığında yeniden kullanılabilir görev yapıları ortaya çıkmaktadır. Bu da yeniden kullanılabilir Tekton Pipelines bileşenlerinden oluşan bir katalog mantığı ortaya çıkarmaktadır. Sık kullanılan CI ve CD süreçleri için daha şimdiden Tekton Katalog, Openshift Tekton Katalog gibi github depoları ortaya çıktı bile.
Bu Tekton Pipelines kataloglarını inceleyerek yeniden kullanılabilir bileşenler sayesinde kendi CI/CD pipeline’ınızı kolayca ortaya çıkartabilirsiniz.