Skip to content

NimTechnology

Trình bày các công nghệ CLOUD một cách dễ hiểu.

  • Kubernetes & Container
    • Docker
    • Kubernetes
      • Ingress
      • Pod
    • Helm Chart
    • OAuth2 Proxy
    • Isito-EnvoyFilter
    • Apache Kafka
      • Kafka
      • Kafka Connect
      • Lenses
    • Vault
    • Longhorn – Storage
    • VictoriaMetrics
    • MetalLB
    • Kong Gateway
  • CI/CD
    • ArgoCD
    • ArgoWorkflows
    • Argo Events
    • Spinnaker
    • Jenkins
    • Harbor
    • TeamCity
    • Git
      • Bitbucket
  • Coding
    • DevSecOps
    • Terraform
      • GCP – Google Cloud
      • AWS – Amazon Web Service
      • Azure Cloud
    • Golang
    • Laravel
    • Python
    • Jquery & JavaScript
    • Selenium
  • Log, Monitor & Tracing
    • DataDog
    • Prometheus
    • Grafana
    • ELK
      • Kibana
      • Logstash
  • BareMetal
    • NextCloud
  • Toggle search form

[Spinnaker] Design mode deploy automatically via template spinnaker!

Posted on May 15, 2022June 23, 2022 By nim No Comments on [Spinnaker] Design mode deploy automatically via template spinnaker!

Contents

Toggle
  • 1) Create token github and heml chart
  • 2) Design template spinnaker
  • 3) Design pipeline spinnaker through json file.
    • 3.1) Pipeline is created UI but it base on template.
    • 3.2) Create Pipeline via Json file and Run pipeline through command.
  • 4) A few special Case
    • 4.1) expectedArtifacts

1) Create token github and heml chart

Đâu tiên bạn cũng cần chuẩn bị github và token, helm chart
Bạn sẽ cần tìm hiểu link sau:
https://nimtechnology.com/2022/05/14/spinnaker-design-cd-on-kubernetes-by-spinnaker/#1_Preparing

2) Design template spinnaker

Mình sẽ cần cung cấp cho bạn 1 template mẫu:

{
  "schema": "v2",
  "variables": [
    {
      "type": "<type>",
      "defaultValue": <value>,
      "description": "<description>",
      "name": "<varName>"
    }
  ],
  "id": "<templateName>",          # The pipeline instance references the template using this
  "protect": <true | false>,
  "metadata": {
    "name": "displayName",          # The display name shown in Deck
    "description": "<description>",
    "owner": "example@example.com",
    "scopes": ["global"]            # Not used
  },
    "pipeline": {                     # Contains the templatized pipeline itself
    "lastModifiedBy": "anonymous",  # Not used
    "updateTs": "0",                # Not used
    "parameterConfig": [],          # Same as in a regular pipeline
    "limitConcurrent": true,        # Same as in a regular pipeline
    "keepWaitingPipelines": false,  # Same as in a regular pipeline
    "description": "",              # Same as in a regular pipeline
    "triggers": [],                 # Same as in a regular pipeline
    "notifications": [],            # Same as in a regular pipeline
    "stages": [                     # Contains the templated stages
      {
        # This one is an example stage:
        "waitTime": "${ templateVariables.waitTime }",  # Templated field.
        "name": "My Wait Stage",
        "type": "wait",
        "refId": "wait1",
        "requisiteStageRefIds": []
      }
    ]
  }
}

Hoặc bạn lấy template ở link này:
https://spinnaker.io/docs/reference/pipeline/templates/

Đầu tiên chúng ta sẽ tạo ra các stage.
Theo mình cách dễ nhất là bạn chỉnh trên UI xong bạn export ra Json -> rổi thế vào file bên trên.

[Spinnaker] Design CD on Kubernetes by Spinnaker
Bạn có thể tham khảo bài này để tạo bằng tay trước

state đâu tiên:

#######stage 1 Get Manifest
    {
      "account": "cluster1",
      "app": "manual-create-app",
      "cloudProvider": "kubernetes",
      "location": "default",
      "manifestName": "deployment default-nimtechnology",
      "mode": "static",
      "name": "Get Manifest",
      "refId": "1",
      "requisiteStageRefIds": [],
      "type": "findArtifactsFromResource"
    }

MÌnh sẽ giải thích các thành phần cần thiết
account: context trong kubeconfig hay còn gọi là tên cluster k8s
app: tên application của spinnaker
location: là namespace
manifestName: nó gồm 2 thành phần là <Kind: deployment, ingress,…> <nameOfWordload>

mode: nếu là static thì nó sẽ đọc theo những j bạn chỉ định ở manifestName.
name: đặt tên cho stage này
type: findArtifactsFromResource => chức năng của stage này là lấy thông tin workload đang run trên k8s nên ta chọn type này

Nếu chúng ta làm template thì với 1 mục đích là tải sử dụng nhiều lần với nhiều deployment khác nhau.
Chúng ta phải define các variables
mình sẽ đưa line code ví dụ.

"manifestName": "${ templateVariables.kind } ${ templateVariables.workloadName }",
mình change như ảnh

với từng variable thì chúng ta cần định nghĩa chúng

"variables": [
    {
      "type": "string",
      "defaultValue": deployment,
      "description": "kind Of workload such as: deployemt, statefulset",
      "name": "kind"
    },
    {
      "type": "string",
      "defaultValue": nimtechnology,
      "description": "this is the workload name",
      "name": "workloadName"
    }
  ]

defaultValue: Chỗ này nghĩ là nếu bạn không đưa data vào thì mặc định lấy value ở đây để sử dụng.

Mình sẽ thay vào đây

Tiếp theo là bạn chỉnh thêm phần sau:

"id": "<templateName>",          # The pipeline instance references the template using this
  "protect": <true | false>,
  "metadata": {
    "name": "displayName",          # The display name shown in Deck
    "description": "<description>",
    "owner": "example@example.com",
    "scopes": ["global"]            # Not used
  }

id: định danh của template, khi bạn muốn sử dụng thì giọi ID của template
protect: bạn để là false
metadata:
name: Tên của template, dụng để hiển thị bên ngoài
owner: Bạn có thể để email hoặc thông tin của bạn ở đây

Giờ thì mình có 1 template như sau:

{
  "schema": "v2",
  "variables": [
    {
      "type": "string",
      "defaultValue": "deployment",
      "description": "kind Of workload such as: deployemt, statefulset",
      "name": "kind"
    },
    {
      "type": "string",
      "defaultValue": "nimtechnology",
      "description": "this is the workload name",
      "name": "workloadName"
    }
  ],
  "id": "nimtSpinnakerTemplateV1",
  "protect": false,
  "metadata": {
    "name": "Nimtechnology Spinnaker Template V1",
    "description": "Study spinnaker together!!!",
    "owner": "mr.nim94@gmail.com",
    "scopes": ["global"] 
  },
    "pipeline": {                     
    "lastModifiedBy": "anonymous",  
    "updateTs": "0",                
    "parameterConfig": [],        
    "limitConcurrent": true,      
    "keepWaitingPipelines": false,
    "description": "",            
    "triggers": [],               
    "notifications": [],          
    "stages": [                   
      {
      "account": "cluster1",
      "app": "manual-create-app",
      "cloudProvider": "kubernetes",
      "location": "default",
      "manifestName": "${ templateVariables.kind } ${ templateVariables.workloadName }",
      "mode": "static",
      "name": "Get Manifest",
      "refId": "1",
      "requisiteStageRefIds": [],
      "type": "findArtifactsFromResource"
    }

    ]
  }
}

Giờ bạn cần chạy lên spinnaker CLI
Tham khảo link sau:
Install Spin CLI and config it to integrate with Google OAuth2

Bạn cần tạo ra 1 file config:

##file: config-nimtechnology
###########

Gate:
  Endpoint: http://spin.nimtechnology.com/gate

Bạn gõ command:

spin application list --config config-nimtechnology

mình sử dụng command spin để lưu template lại

spin pt save --file template-spin-nimtechnology-v1.json --config config-nimtechnology

Mình gặp lỗi:

Encountered an error with saving pipeline template map[application:global buildTime:1.652552232113e+12 endTime:1.65255223227e+12 execution:map[application:global authentication:map[allowedAccounts:[cluster1 dockerhub] user:anonymous] buildTime:1.652552232113e+12 canceled:false description:Create pipeline template 'Nimtechnology Spinnaker Template V1' endTime:1.65255223227e+12 id:01G31WKV5HQ2D4WJ6XC3DKRMKN initialConfig:map[] keepWaitingPipelines:false limitConcurrent:false notifications:[] origin:api stages:[map[context:map[beforeStagePlanningFailed:true exception:map[details:map[error:Unexpected Task Failure errors:[No StageDefinitionBuilder implementation for createV2PipelineTemplate(alias: null) found (knownTypes: googleCloudBuild,upsertDeliveryConfig,shrinkCluster,reorderPipelines,upsertLoadBalancers,resumeRolloutManifest,modifyAsgLaunchConfiguration,remote,upsertEntityTags,deleteSnapshot,deregisterInstancesFromLoadBalancer,bulkUpsertEntityTags,quickPatch,deleteLaunchConfiguration,destroyAsg,runJob,deployCloudFormation,checkPreconditions,determineTargetReference,clouddriverClearAltTablespace,upsertSecurityGroup,manualJudgment,upsertLoadBalancer,getProperties,modifyGceAutoscalingPolicy,disableCluster,deployService,script,restoreSnapshot,gremlin,disableManifest,terminateInstanceAndDecrementServerGroup,copyAmazonLoadBalancer,rollbackCluster,disableInstancesInDiscovery,cloneServerGroup,updatePipeline,deleteLaunchTemplate,bakeCloudFoundryManifest,setStatefulDisk,wait,monitorPipeline,serverGroupForceCacheRefresh,statefullyUpdateBootImage,deleteTencentCloudScheduledAction,upsertDisruptionBudget,saveSnapshot,upsertAmazonDNS,findImage,scaleManifest,awsCodeBuild,undoRolloutManifest,noop,upsertAsgScheduledActions,enableInstancesInDiscovery,deleteEntityTags,concourse,destroyService,findArtifactsFromResource,registerInstancesWithLoadBalancer,jenkins,rebootInstances,rollbackServerGroup,upsertServerGroupTags,captureSourceServerGroupCapacity,upsertPluginInfo,destroyJob,cloudOperation,bulkQuickPatch,deployManifest,scaleDownCluster,findImageFromTags,pipeline,upsertScalingPolicy,upsertProject,detachInstances,updateApplication,preconfiguredWebhook,createApplication,deleteDeliveryConfig,unmapLoadBalancers,terminateInstanceAndDecrementAsg,modifyAwsScalingProcess,rollingPush,shareService,enableServerGroup,disableServerGroup,savePipelinesFromArtifact,webhook,deleteLoadBalancer,createServiceKey,resizeServerGroup,waitUntil,patchManifest,deploy,deleteManifest,lambdaFunction,upsertAmazonLoadBalancer,evaluateVariables,determineTargetServerGroup,updateJobProcesses,deleteImage,enableManifest,setPreferredPluginRelease,jira,deleteSecurityGroup,upsertAsgTags,enableAsg,wercker,waitForCondition,deleteProject,updateLaunchTemplate,preconfiguredJob,copySecurityGroup,mapLoadBalancers,restrictExecutionDuringTimeWindow,loadPluginRelease,terminateInstances,savePipeline,pauseRolloutManifest,startAppEngineServerGroup,dependsOnExecution,upsertTencentCloudScheduledActions,updateSecurityGroupsForServerGroup,modifyScalingProcess,upsertApplication,applySourceServerGroupCapacity,updateLaunchConfig,findArtifactFromExecution,bakeManifest,upsertAppEngineLoadBalancers,stopAppEngineServerGroup,copyLastAsg,pinServerGroup,upsertImageTags,deleteApplication,modifyScalingGroup,cloudFoundryCreateServiceBindings,rollingRestartManifest,bulkDestroyServerGroup,disableAsg,modifyAsg,unshareService,pageApplicationOwner,createServerGroup,deleteAmazonLoadBalancer,deleteScalingPolicy,bake,travis,destroyServerGroup,deleteServiceKey,deployAppEngineConfiguration)] stackTrace:com.netflix.spinnaker.orca.StageResolver$NoSuchStageDefinitionBuilderException: No StageDefinitionBuilder implementation for createV2PipelineTemplate(alias: null) found (knownTypes: googleCloudBuild,upsertDeliveryConfig,shrinkCluster,reorderPipelines,upsertLoadBalancers,resumeRolloutManifest,modifyAsgLaunchConfiguration,remote,upsertEntityTags,deleteSnapshot,deregisterInstancesFromLoadBalancer,bulkUpsertEntityTags,quickPatch,deleteLaunchConfiguration,destroyAsg,runJob,deployCloudFormation,checkPreconditions,determineTargetReference,clouddriverClearAltTablespace,upsertSecurityGroup,manualJudgment,upsertLoadBalancer,getProperties,modifyGceAutoscalingPolicy,disableCluster,deployService,script,restoreSnapshot,gremlin,disableManifest,terminateInstanceAndDecrementServerGroup,copyAmazonLoadBalancer,rollbackCluster,disableInstancesInDiscovery,cloneServerGroup,updatePipeline,deleteLaunchTemplate,bakeCloudFoundryManifest,setStatefulDisk,wait,monitorPipeline,serverGroupForceCacheRefresh,statefullyUpdateBootImage,deleteTencentCloudScheduledAction,upsertDisruptionBudget,saveSnapshot,upsertAmazonDNS,findImage,scaleManifest,awsCodeBuild,undoRolloutManifest,noop,upsertAsgScheduledActions,enableInstancesInDiscovery,deleteEntityTags,concourse,destroyService,findArtifactsFromResource,registerInstancesWithLoadBalancer,jenkins,rebootInstances,rollbackServerGroup,upsertServerGroupTags,captureSourceServerGroupCapacity,upsertPluginInfo,destroyJob,cloudOperation,bulkQuickPatch,deployManifest,scaleDownCluster,findImageFromTags,pipeline,upsertScalingPolicy,upsertProject,detachInstances,updateApplication,preconfiguredWebhook,createApplication,deleteDeliveryConfig,unmapLoadBalancers,terminateInstanceAndDecrementAsg,modifyAwsScalingProcess,rollingPush,shareService,enableServerGroup,disableServerGroup,savePipelinesFromArtifact,webhook,deleteLoadBalancer,createServiceKey,resizeServerGroup,waitUntil,patchManifest,deploy,deleteManifest,lambdaFunction,upsertAmazonLoadBalancer,evaluateVariables,determineTargetServerGroup,updateJobProcesses,deleteImage,enableManifest,setPreferredPluginRelease,jira,deleteSecurityGroup,upsertAsgTags,enableAsg,wercker,waitForCondition,deleteProject,updateLaunchTemplate,preconfiguredJob,copySecurityGroup,mapLoadBalancers,restrictExecutionDuringTimeWindow,loadPluginRelease,terminateInstances,savePipeline,pauseRolloutManifest,startAppEngineServerGroup,dependsOnExecution,upsertTencentCloudScheduledActions,updateSecurityGroupsForServerGroup,modifyScalingProcess,upsertApplication,applySourceServerGroupCapacity,updateLaunchConfig,findArtifactFromExecution,bakeManifest,upsertAppEngineLoadBalancers,stopAppEngineServerGroup,copyLastAsg,pinServerGroup,upsertImageTags,deleteApplication,modifyScalingGroup,cloudFoundryCreateServiceBindings,rollingRestartManifest,bulkDestroyServerGroup,disableAsg,modifyAsg,unshareService,pageApplicationOwner,createServerGroup,deleteAmazonLoadBalancer,deleteScalingPolicy,bake,travis,destroyServerGroup,deleteServiceKey,deployAppEngineConfiguration)
	at com.netflix.spinnaker.orca.DefaultStageResolver.getStageDefinitionBuilder(DefaultStageResolver.java:75)
	at com.netflix.spinnaker.orca.pipeline.util.StageNavigator.lambda$ancestors$0(StageNavigator.java:51)
	at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195)
	at java.base/java.util.Collections$2.tryAdvance(Collections.java:4747)
	at java.base/java.util.Collections$2.forEachRemaining(Collections.java:4755)
	at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
	at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:913)
	at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
	at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:578)
	at com.netflix.spinnaker.orca.pipeline.util.StageNavigator.ancestors(StageNavigator.java:53)
	at com.netflix.spinnaker.orca.q.handler.AuthenticationAware$DefaultImpls.withAuth(AuthenticationAware.kt:32)
	at com.netflix.spinnaker.orca.q.handler.CompleteStageHandler.withAuth(CompleteStageHandler.kt:72)
	at com.netflix.spinnaker.orca.q.handler.CompleteStageHandler$handle$1.invoke(CompleteStageHandler.kt:119)
	at com.netflix.spinnaker.orca.q.handler.CompleteStageHandler$handle$1.invoke(CompleteStageHandler.kt:72)
	at com.netflix.spinnaker.orca.q.handler.OrcaMessageHandler$withStage$1.invoke(OrcaMessageHandler.kt:85)
	at com.netflix.spinnaker.orca.q.handler.OrcaMessageHandler$withStage$1.invoke(OrcaMessageHandler.kt:46)
	at com.netflix.spinnaker.orca.q.handler.OrcaMessageHandler$DefaultImpls.withExecution(OrcaMessageHandler.kt:95)
	at com.netflix.spinnaker.orca.q.handler.CompleteStageHandler.withExecution(CompleteStageHandler.kt:72)
	at com.netflix.spinnaker.orca.q.handler.OrcaMessageHandler$DefaultImpls.withStage(OrcaMessageHandler.kt:74)
	at com.netflix.spinnaker.orca.q.handler.CompleteStageHandler.withStage(CompleteStageHandler.kt:72)
	at com.netflix.spinnaker.orca.q.handler.CompleteStageHandler.handle(CompleteStageHandler.kt:85)
	at com.netflix.spinnaker.orca.q.handler.CompleteStageHandler.handle(CompleteStageHandler.kt:72)
	at com.netflix.spinnaker.q.MessageHandler$DefaultImpls.invoke(MessageHandler.kt:36)
	at com.netflix.spinnaker.orca.q.handler.OrcaMessageHandler$DefaultImpls.invoke(OrcaMessageHandler.kt)
	at com.netflix.spinnaker.orca.q.handler.CompleteStageHandler.invoke(CompleteStageHandler.kt:72)
	at com.netflix.spinnaker.orca.q.audit.ExecutionTrackingMessageHandlerPostProcessor$ExecutionTrackingMessageHandlerProxy.invoke(ExecutionTrackingMessageHandlerPostProcessor.kt:72)
	at com.netflix.spinnaker.q.QueueProcessor$callback$1$1.run(QueueProcessor.kt:90)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
	at java.base/java.lang.Thread.run(Thread.java:834)
] exceptionType:NoSuchStageDefinitionBuilderException operation:createV2PipelineTemplate:ConstructAfterStages shouldRetry:false timestamp:1.652552232204e+12] pipelineTemplate:eyJpZCI6Im5pbXRTcGlubmFrZXJUZW1wbGF0ZVYxIiwibWV0YWRhdGEiOnsiZGVzY3JpcHRpb24iOiJTdHVkeSBzcGlubmFrZXIgdG9nZXRoZXIhISEiLCJuYW1lIjoiTmltdGVjaG5vbG9neSBTcGlubmFrZXIgVGVtcGxhdGUgVjEiLCJvd25lciI6Im1yLm5pbTk0QGdtYWlsLmNvbSIsInNjb3BlcyI6WyJnbG9iYWwiXX0sInBpcGVsaW5lIjp7ImRlc2NyaXB0aW9uIjoiIiwia2VlcFdhaXRpbmdQaXBlbGluZXMiOmZhbHNlLCJsYXN0TW9kaWZpZWRCeSI6ImFub255bW91cyIsImxpbWl0Q29uY3VycmVudCI6dHJ1ZSwibm90aWZpY2F0aW9ucyI6W10sInBhcmFtZXRlckNvbmZpZyI6W10sInN0YWdlcyI6W3siYWNjb3VudCI6ImRlZmF1bHQiLCJjb21wbGV0ZU90aGVyQnJhbmNoZXNUaGVuRmFpbCI6ZmFsc2UsImNvbnRpbnVlUGlwZWxpbmUiOnRydWUsImZhaWxPbkZhaWxlZEV4cHJlc3Npb25zIjpmYWxzZSwiZmFpbFBpcGVsaW5lIjpmYWxzZSwibG9jYXRpb24iOiJkZWZhdWx0IiwibWFuaWZlc3ROYW1lIjoiJHsgdGVtcGxhdGVWYXJpYWJsZXMua2luZCB9ICR7IHRlbXBsYXRlVmFyaWFibGVzLndvcmtsb2FkTmFtZSB9IiwibW9kZSI6InN0YXRpYyIsIm5hbWUiOiJHZXQgTWFuaWZlc3QiLCJyZWZJZCI6IjEiLCJyZXF1aXNpdGVTdGFnZVJlZklkcyI6W10sInJlc3RyaWN0RXhlY3V0aW9uRHVyaW5nVGltZVdpbmRvdyI6ZmFsc2UsInR5cGUiOiJmaW5kQXJ0aWZhY3RzRnJvbVJlc291cmNlIn1dLCJ0cmlnZ2VycyI6W10sInVwZGF0ZVRzIjoiMCJ9LCJwcm90ZWN0IjpmYWxzZSwic2NoZW1hIjoidjIiLCJ2YXJpYWJsZXMiOlt7ImRlZmF1bHRWYWx1ZSI6ImRlcGxveW1lbnQiLCJkZXNjcmlwdGlvbiI6ImtpbmQgT2Ygd29ya2xvYWQgc3VjaCBhczogZGVwbG95ZW10LCBzdGF0ZWZ1bHNldCIsIm5hbWUiOiJraW5kIiwidHlwZSI6InN0cmluZyJ9LHsiZGVmYXVsdFZhbHVlIjoibmltdGVjaG5vbG9neSIsImRlc2NyaXB0aW9uIjoidGhpcyBpcyB0aGUgd29ya2xvYWQgbmFtZSIsIm5hbWUiOiJ3b3JrbG9hZE5hbWUiLCJ0eXBlIjoic3RyaW5nIn1dfQ== user:anonymous] endTime:1.652552232204e+12 id:01G31WKV5HW68GM1AFPD7JFPNB name:createV2PipelineTemplate outputs:map[] refId:0 requisiteStageRefIds:[] status:TERMINAL tasks:[] type:createV2PipelineTemplate]] startTime:1.652552232138e+12 status:TERMINAL systemNotifications:[] trigger:map[artifacts:[] dryRun:false expectedArtifacts:[] notifications:[] parameters:map[] rebake:false resolvedExpectedArtifacts:[] strategy:false type:manual user:anonymous] type:ORCHESTRATION] id:01G31WKV5HQ2D4WJ6XC3DKRMKN name:Create pipeline template 'Nimtechnology Spinnaker Template V1' startTime:1.652552232138e+12 status:TERMINAL steps:[] variables:[map[key:pipelineTemplate value:eyJpZCI6Im5pbXRTcGlubmFrZXJUZW1wbGF0ZVYxIiwibWV0YWRhdGEiOnsiZGVzY3JpcHRpb24iOiJTdHVkeSBzcGlubmFrZXIgdG9nZXRoZXIhISEiLCJuYW1lIjoiTmltdGVjaG5vbG9neSBTcGlubmFrZXIgVGVtcGxhdGUgVjEiLCJvd25lciI6Im1yLm5pbTk0QGdtYWlsLmNvbSIsInNjb3BlcyI6WyJnbG9iYWwiXX0sInBpcGVsaW5lIjp7ImRlc2NyaXB0aW9uIjoiIiwia2VlcFdhaXRpbmdQaXBlbGluZXMiOmZhbHNlLCJsYXN0TW9kaWZpZWRCeSI6ImFub255bW91cyIsImxpbWl0Q29uY3VycmVudCI6dHJ1ZSwibm90aWZpY2F0aW9ucyI6W10sInBhcmFtZXRlckNvbmZpZyI6W10sInN0YWdlcyI6W3siYWNjb3VudCI6ImRlZmF1bHQiLCJjb21wbGV0ZU90aGVyQnJhbmNoZXNUaGVuRmFpbCI6ZmFsc2UsImNvbnRpbnVlUGlwZWxpbmUiOnRydWUsImZhaWxPbkZhaWxlZEV4cHJlc3Npb25zIjpmYWxzZSwiZmFpbFBpcGVsaW5lIjpmYWxzZSwibG9jYXRpb24iOiJkZWZhdWx0IiwibWFuaWZlc3ROYW1lIjoiJHsgdGVtcGxhdGVWYXJpYWJsZXMua2luZCB9ICR7IHRlbXBsYXRlVmFyaWFibGVzLndvcmtsb2FkTmFtZSB9IiwibW9kZSI6InN0YXRpYyIsIm5hbWUiOiJHZXQgTWFuaWZlc3QiLCJyZWZJZCI6IjEiLCJyZXF1aXNpdGVTdGFnZVJlZklkcyI6W10sInJlc3RyaWN0RXhlY3V0aW9uRHVyaW5nVGltZVdpbmRvdyI6ZmFsc2UsInR5cGUiOiJmaW5kQXJ0aWZhY3RzRnJvbVJlc291cmNlIn1dLCJ0cmlnZ2VycyI6W10sInVwZGF0ZVRzIjoiMCJ9LCJwcm90ZWN0IjpmYWxzZSwic2NoZW1hIjoidjIiLCJ2YXJpYWJsZXMiOlt7ImRlZmF1bHRWYWx1ZSI6ImRlcGxveW1lbnQiLCJkZXNjcmlwdGlvbiI6ImtpbmQgT2Ygd29ya2xvYWQgc3VjaCBhczogZGVwbG95ZW10LCBzdGF0ZWZ1bHNldCIsIm5hbWUiOiJraW5kIiwidHlwZSI6InN0cmluZyJ9LHsiZGVmYXVsdFZhbHVlIjoibmltdGVjaG5vbG9neSIsImRlc2NyaXB0aW9uIjoidGhpcyBpcyB0aGUgd29ya2xvYWQgbmFtZSIsIm5hbWUiOiJ3b3JrbG9hZE5hbWUiLCJ0eXBlIjoic3RyaW5nIn1dfQ==] map[key:user value:anonymous] map[key:exception value:map[details:map[error:Unexpected Task Failure errors:[No StageDefinitionBuilder implementation for createV2PipelineTemplate(alias: null) found (knownTypes: googleCloudBuild,upsertDeliveryConfig,shrinkCluster,reorderPipelines,upsertLoadBalancers,resumeRolloutManifest,modifyAsgLaunchConfiguration,remote,upsertEntityTags,deleteSnapshot,deregisterInstancesFromLoadBalancer,bulkUpsertEntityTags,quickPatch,deleteLaunchConfiguration,destroyAsg,runJob,deployCloudFormation,checkPreconditions,determineTargetReference,clouddriverClearAltTablespace,upsertSecurityGroup,manualJudgment,upsertLoadBalancer,getProperties,modifyGceAutoscalingPolicy,disableCluster,deployService,script,restoreSnapshot,gremlin,disableManifest,terminateInstanceAndDecrementServerGroup,copyAmazonLoadBalancer,rollbackCluster,disableInstancesInDiscovery,cloneServerGroup,updatePipeline,deleteLaunchTemplate,bakeCloudFoundryManifest,setStatefulDisk,wait,monitorPipeline,serverGroupForceCacheRefresh,statefullyUpdateBootImage,deleteTencentCloudScheduledAction,upsertDisruptionBudget,saveSnapshot,upsertAmazonDNS,findImage,scaleManifest,awsCodeBuild,undoRolloutManifest,noop,upsertAsgScheduledActions,enableInstancesInDiscovery,deleteEntityTags,concourse,destroyService,findArtifactsFromResource,registerInstancesWithLoadBalancer,jenkins,rebootInstances,rollbackServerGroup,upsertServerGroupTags,captureSourceServerGroupCapacity,upsertPluginInfo,destroyJob,cloudOperation,bulkQuickPatch,deployManifest,scaleDownCluster,findImageFromTags,pipeline,upsertScalingPolicy,upsertProject,detachInstances,updateApplication,preconfiguredWebhook,createApplication,deleteDeliveryConfig,unmapLoadBalancers,terminateInstanceAndDecrementAsg,modifyAwsScalingProcess,rollingPush,shareService,enableServerGroup,disableServerGroup,savePipelinesFromArtifact,webhook,deleteLoadBalancer,createServiceKey,resizeServerGroup,waitUntil,patchManifest,deploy,deleteManifest,lambdaFunction,upsertAmazonLoadBalancer,evaluateVariables,determineTargetServerGroup,updateJobProcesses,deleteImage,enableManifest,setPreferredPluginRelease,jira,deleteSecurityGroup,upsertAsgTags,enableAsg,wercker,waitForCondition,deleteProject,updateLaunchTemplate,preconfiguredJob,copySecurityGroup,mapLoadBalancers,restrictExecutionDuringTimeWindow,loadPluginRelease,terminateInstances,savePipeline,pauseRolloutManifest,startAppEngineServerGroup,dependsOnExecution,upsertTencentCloudScheduledActions,updateSecurityGroupsForServerGroup,modifyScalingProcess,upsertApplication,applySourceServerGroupCapacity,updateLaunchConfig,findArtifactFromExecution,bakeManifest,upsertAppEngineLoadBalancers,stopAppEngineServerGroup,copyLastAsg,pinServerGroup,upsertImageTags,deleteApplication,modifyScalingGroup,cloudFoundryCreateServiceBindings,rollingRestartManifest,bulkDestroyServerGroup,disableAsg,modifyAsg,unshareService,pageApplicationOwner,createServerGroup,deleteAmazonLoadBalancer,deleteScalingPolicy,bake,travis,destroyServerGroup,deleteServiceKey,deployAppEngineConfiguration)] stackTrace:com.netflix.spinnaker.orca.StageResolver$NoSuchStageDefinitionBuilderException: No StageDefinitionBuilder implementation for createV2PipelineTemplate(alias: null) found (knownTypes: googleCloudBuild,upsertDeliveryConfig,shrinkCluster,reorderPipelines,upsertLoadBalancers,resumeRolloutManifest,modifyAsgLaunchConfiguration,remote,upsertEntityTags,deleteSnapshot,deregisterInstancesFromLoadBalancer,bulkUpsertEntityTags,quickPatch,deleteLaunchConfiguration,destroyAsg,runJob,deployCloudFormation,checkPreconditions,determineTargetReference,clouddriverClearAltTablespace,upsertSecurityGroup,manualJudgment,upsertLoadBalancer,getProperties,modifyGceAutoscalingPolicy,disableCluster,deployService,script,restoreSnapshot,gremlin,disableManifest,terminateInstanceAndDecrementServerGroup,copyAmazonLoadBalancer,rollbackCluster,disableInstancesInDiscovery,cloneServerGroup,updatePipeline,deleteLaunchTemplate,bakeCloudFoundryManifest,setStatefulDisk,wait,monitorPipeline,serverGroupForceCacheRefresh,statefullyUpdateBootImage,deleteTencentCloudScheduledAction,upsertDisruptionBudget,saveSnapshot,upsertAmazonDNS,findImage,scaleManifest,awsCodeBuild,undoRolloutManifest,noop,upsertAsgScheduledActions,enableInstancesInDiscovery,deleteEntityTags,concourse,destroyService,findArtifactsFromResource,registerInstancesWithLoadBalancer,jenkins,rebootInstances,rollbackServerGroup,upsertServerGroupTags,captureSourceServerGroupCapacity,upsertPluginInfo,destroyJob,cloudOperation,bulkQuickPatch,deployManifest,scaleDownCluster,findImageFromTags,pipeline,upsertScalingPolicy,upsertProject,detachInstances,updateApplication,preconfiguredWebhook,createApplication,deleteDeliveryConfig,unmapLoadBalancers,terminateInstanceAndDecrementAsg,modifyAwsScalingProcess,rollingPush,shareService,enableServerGroup,disableServerGroup,savePipelinesFromArtifact,webhook,deleteLoadBalancer,createServiceKey,resizeServerGroup,waitUntil,patchManifest,deploy,deleteManifest,lambdaFunction,upsertAmazonLoadBalancer,evaluateVariables,determineTargetServerGroup,updateJobProcesses,deleteImage,enableManifest,setPreferredPluginRelease,jira,deleteSecurityGroup,upsertAsgTags,enableAsg,wercker,waitForCondition,deleteProject,updateLaunchTemplate,preconfiguredJob,copySecurityGroup,mapLoadBalancers,restrictExecutionDuringTimeWindow,loadPluginRelease,terminateInstances,savePipeline,pauseRolloutManifest,startAppEngineServerGroup,dependsOnExecution,upsertTencentCloudScheduledActions,updateSecurityGroupsForServerGroup,modifyScalingProcess,upsertApplication,applySourceServerGroupCapacity,updateLaunchConfig,findArtifactFromExecution,bakeManifest,upsertAppEngineLoadBalancers,stopAppEngineServerGroup,copyLastAsg,pinServerGroup,upsertImageTags,deleteApplication,modifyScalingGroup,cloudFoundryCreateServiceBindings,rollingRestartManifest,bulkDestroyServerGroup,disableAsg,modifyAsg,unshareService,pageApplicationOwner,createServerGroup,deleteAmazonLoadBalancer,deleteScalingPolicy,bake,travis,destroyServerGroup,deleteServiceKey,deployAppEngineConfiguration)
	at com.netflix.spinnaker.orca.DefaultStageResolver.getStageDefinitionBuilder(DefaultStageResolver.java:75)
	at com.netflix.spinnaker.orca.pipeline.util.StageNavigator.lambda$ancestors$0(StageNavigator.java:51)
	at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195)
	at java.base/java.util.Collections$2.tryAdvance(Collections.java:4747)
	at java.base/java.util.Collections$2.forEachRemaining(Collections.java:4755)
	at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
	at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:913)
	at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
	at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:578)
	at com.netflix.spinnaker.orca.pipeline.util.StageNavigator.ancestors(StageNavigator.java:53)
	at com.netflix.spinnaker.orca.q.handler.AuthenticationAware$DefaultImpls.withAuth(AuthenticationAware.kt:32)
	at com.netflix.spinnaker.orca.q.handler.CompleteStageHandler.withAuth(CompleteStageHandler.kt:72)
	at com.netflix.spinnaker.orca.q.handler.CompleteStageHandler$handle$1.invoke(CompleteStageHandler.kt:119)
	at com.netflix.spinnaker.orca.q.handler.CompleteStageHandler$handle$1.invoke(CompleteStageHandler.kt:72)
	at com.netflix.spinnaker.orca.q.handler.OrcaMessageHandler$withStage$1.invoke(OrcaMessageHandler.kt:85)
	at com.netflix.spinnaker.orca.q.handler.OrcaMessageHandler$withStage$1.invoke(OrcaMessageHandler.kt:46)
	at com.netflix.spinnaker.orca.q.handler.OrcaMessageHandler$DefaultImpls.withExecution(OrcaMessageHandler.kt:95)
	at com.netflix.spinnaker.orca.q.handler.CompleteStageHandler.withExecution(CompleteStageHandler.kt:72)
	at com.netflix.spinnaker.orca.q.handler.OrcaMessageHandler$DefaultImpls.withStage(OrcaMessageHandler.kt:74)
	at com.netflix.spinnaker.orca.q.handler.CompleteStageHandler.withStage(CompleteStageHandler.kt:72)
	at com.netflix.spinnaker.orca.q.handler.CompleteStageHandler.handle(CompleteStageHandler.kt:85)
	at com.netflix.spinnaker.orca.q.handler.CompleteStageHandler.handle(CompleteStageHandler.kt:72)
	at com.netflix.spinnaker.q.MessageHandler$DefaultImpls.invoke(MessageHandler.kt:36)
	at com.netflix.spinnaker.orca.q.handler.OrcaMessageHandler$DefaultImpls.invoke(OrcaMessageHandler.kt)
	at com.netflix.spinnaker.orca.q.handler.CompleteStageHandler.invoke(CompleteStageHandler.kt:72)
	at com.netflix.spinnaker.orca.q.audit.ExecutionTrackingMessageHandlerPostProcessor$ExecutionTrackingMessageHandlerProxy.invoke(ExecutionTrackingMessageHandlerPostProcessor.kt:72)
	at com.netflix.spinnaker.q.QueueProcessor$callback$1$1.run(QueueProcessor.kt:90)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
	at java.base/java.lang.Thread.run(Thread.java:834)
] exceptionType:NoSuchStageDefinitionBuilderException operation:createV2PipelineTemplate:ConstructAfterStages shouldRetry:false timestamp:1.652552232204e+12]] map[key:beforeStagePlanningFailed value:true]]]

Bạn kiểm tra bạn đã enable template hay chưa?

hal config features edit --pipeline-templates true

Sau đó mình đã chạy thành công

Cách bạn thấy là nó đã nhận template
Bạn có thể view template.

3) Design pipeline spinnaker through json file.

Bước tiếp theo chúng ta tạo 1 pipeline để tải sử dụng template trên

reference links:
https://spinnaker.io/guides/spin/app/

spin application save --application-name my-app --owner-email someone@example.com --cloud-providers "kubernetes" --config config-nimtechnology

3.1) Pipeline is created UI but it base on template.

Bằng UI spinnaker:

Bạn chọn 1 application và tạo 1 pipeline trong application đó.

Bạn điền tên workload và kind của workload

Bạn kiểm tra lại các config và click save change
xanh lè như hình là ok nhé

Với cách run bằng UI thì chắc chắn là kho làm automation vậy chúng ta cần làm như sau:

3.2) Create Pipeline via Json file and Run pipeline through command.

sau đó bạn tạo 1 file json và paste nối dụng vào

Nếu bạn chạy câu lệnh

spin pi save --file pipeline-spin-nimtechnology.json --config config-nimtechnology

thi bạn sẽ bị báo lỗi

Required pipeline key 'name' missing...

Required pipeline key 'application' missing...

Submitted pipeline is invalid: map[exclude:[] keepWaitingPipelines:%!s(bool=false) lastModifiedBy:anonymous limitConcurrent:%!s(bool=true) notifications:[] parameterConfig:[] schema:v2 stages:[] template:map[artifactAccount:front50ArtifactCredentials reference:spinnaker://nimtSpinnakerTemplateV1 type:front50/pipelineTemplate] triggers:[] type:templatedPipeline updateTs:1652627797000 variables:map[kind:deployment workloadName:default-nimtechnology]]

Vì là trong json chưa có tên pipeline và pipeline trên thuộc application nào?

{
  "name": "pipeline-is-created-by-command",
  "application": "my-app",
  "exclude": [],
  "keepWaitingPipelines": false,
  "lastModifiedBy": "anonymous",
  "limitConcurrent": true,
  "notifications": [],
  "parameterConfig": [],
  "schema": "v2",
  "stages": [],
  "template": {
    "artifactAccount": "front50ArtifactCredentials",
    "reference": "spinnaker://nimtSpinnakerTemplateV1",
    "type": "front50/pipelineTemplate"
  },
  "triggers": [],
  "type": "templatedPipeline",
  "updateTs": "1652627797000",
  "variables": {
    "kind": "deployment",
    "workloadName": "default-nimtechnology"
  }
}
giờ đã ngon
spin pipeline execute --name pipeline-is-created-by-command --application my-app 
Đã chạy pipeline
Đã ngon

4) A few special Case

Mình cũng đã có migrate 1 số template cúa spinnaker sang template mình xin tổng hợp thêm một số trường hợp sau:

4.1) expectedArtifacts

Ơ các ví dụ trên thì chắc chắn là bạn chưa thấy mình lưu ý key này

Bạn sẽ thấy là expectedArtifacts nó nằm ở ngoài chứ không nám trong stages
{
  "appConfig": {},
  "expectedArtifacts": [
    {
      "defaultArtifact": {
        "customKind": true,
        "id": "c3e4adf6-9f9f-418f-b1af-2a4de93d792f"
      },
      "displayName": "docker-talaria",
      "id": "834eae41-e13b-49ca-95d6-9801a587a85a",
      "matchArtifact": {
        "artifactAccount": "docker-registry",
        "id": "78cf7ac2-a881-4ff7-b4a3-68eda1a271c6",
        "name": "asia.gcr.io//talaria",
        "type": "docker/image"
      },
      "useDefaultArtifact": false,
      "usePriorArtifact": false
    }
  ],
  "keepWaitingPipelines": false,
  "lastModifiedBy": "uc.dang@.vn",
  "limitConcurrent": true,
  "notifications": [
    {
      "address": "-build",
      "level": "pipeline",
      "message": {
        "pipeline.failed": {
          "text": "<@UHGA1UJ1F>"
        }
      },
      "type": "slack",
      "when": [
        "pipeline.failed"
      ]
    }
  ],
  "parameterConfig": [
    {
      "default": "none",
      "description": "",
      "hasOptions": false,
      "label": "type",
      "name": "type",
      "options": [
        {
          "value": "none"
        },
        {
          "value": ""
        }
      ],
      "pinned": false,
      "required": false
    },
    {
      "default": "false",
      "description": "",
      "hasOptions": true,
      "label": "",
      "name": "dryRun",
      "options": [
        {
          "value": "false"
        },
        {
          "value": "true"
        }
      ],
      "pinned": false,
      "required": false
    }
  ],
  "roles": [
    "devops-admin"
  ],
  "stages": [
    {
      "expectedArtifacts": [
        {
          "defaultArtifact": {
            "customKind": true,
            "id": "396d49b8-78c3-4f2a-92fe-5ca2a1f78081"
          },
          "displayName": "talaria-apiv2-helm-canary",
          "id": "52638c19-89cc-4067-87a1-7b0f0c3eb621",
          "matchArtifact": {
            "id": "fd0fd41b-ecd1-4307-802d-2a06c61a9a56",
            "name": "talaria-apiv2-canary",
            "type": "embedded/base64"
          },
          "useDefaultArtifact": false,
          "usePriorArtifact": false
        }

Vậy lúc này bạn tạo ra 1 expectedArtifacts và nó nằm trong pipeline

    "description": "Deploy image",
    "name": "dockerRepo"
  }

 ],
 "id": "generic-v2",
 "protect": false,
 "metadata": {
  "name": "Generic v2",
  "description": "A generic template for basic use cases. No trigger configured",
  "owner": "khai.phan@nimtechnology.vn",
  "scopes": ["global"]
 },
 "pipeline": {
   "application": "test",
   "expectedArtifacts": [ #you can paste the content of expectedArtifacts at here
    {
     "defaultArtifact": {
      "artifactAccount": "jenkins-artifacts",
      "id": "67432764-b5aa-4392-948d-88920fa2e295",
      "name": "gs://nimtechnology-prod-cicd-b20d-jenkins-artifacts/${ templateVariables.projectName }--values-${ templateVariables.profile }",
      "reference": "gs://nimtechnology-prod-cicd-b20d-jenkins-artifacts/${ templateVariables.projectName }--values-${ templateVariables.profile }",
      "type": "gcs/object"
     },
     "displayName": "${ templateVariables.projectName }--values-${ templateVariables.profile }",
     "id": "8732f548-dfb4-4f52-9e2d-a52ff1c94a8a",
     "matchArtifact": {
      "artifactAccount": "jenkins-artifacts",
      "id": "515a0e61-57a8-4973-8ded-e53d5464d58b",
      "name": "gs://nimtechnology-prod-cicd-b20d-jenkins-artifacts/${ templateVariables.projectName }--values-${ templateVariables.profile }",
      "type": "gcs/object"
     },
     "useDefaultArtifact": true,
     "usePriorArtifact": false
    },
    {
     "defaultArtifact": {
Spinnaker

Post navigation

Previous Post: [Spinnaker] Design CD on Kubernetes by Spinnaker
Next Post: [Code] Beautiful code offline – On PC – On Laptop

More Related Articles

[Spinnaker/K8s] Add many Kubernetes clusters into spinnaker. Spinnaker
[spinnaker] Command spin receive status 500 Spinnaker
[Spinnaker-Github-Helm-K8S]Hướng dẫn cấu hình Spinnaker deploy lên kubernetes dựa vào Helm CI/CD
[Spinnaker] Design CD on Kubernetes by Spinnaker Spinnaker
[Spinnaker] clouddriver.kubernetes.op.job.KubectlJobExecutor$KubectlException: Deploy failed Kubernetes
[Spinnaker] Pipelines of an application hung. Spinnaker

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Tham Gia Group DevOps nhé!
Để Nim có nhiều động lực ra nhiều bài viết.
Để nhận được những thông báo mới nhất.

Recent Posts

  • [Azure/Loadbalancer] Creating an internal load balancer on Azure Kubernetes Service (AKS). May 13, 2025
  • [Azure] The subscription is not registered to use namespace ‘Microsoft.ContainerService’ May 8, 2025
  • [Azure] Insufficient regional vcpu quota left May 8, 2025
  • [WordPress] How to add a Dynamic watermark on WordPress. May 6, 2025
  • [vnet/Azure] VNet provisioning via Terraform. April 28, 2025

Archives

  • May 2025
  • April 2025
  • March 2025
  • February 2025
  • January 2025
  • December 2024
  • November 2024
  • October 2024
  • September 2024
  • August 2024
  • July 2024
  • June 2024
  • May 2024
  • April 2024
  • March 2024
  • February 2024
  • January 2024
  • December 2023
  • November 2023
  • October 2023
  • September 2023
  • August 2023
  • July 2023
  • June 2023
  • May 2023
  • April 2023
  • March 2023
  • February 2023
  • January 2023
  • December 2022
  • November 2022
  • October 2022
  • September 2022
  • August 2022
  • July 2022
  • June 2022
  • May 2022
  • April 2022
  • March 2022
  • February 2022
  • January 2022
  • December 2021
  • November 2021
  • October 2021
  • September 2021
  • August 2021
  • July 2021
  • June 2021

Categories

  • BareMetal
    • NextCloud
  • CI/CD
    • Argo Events
    • ArgoCD
    • ArgoWorkflows
    • Git
      • Bitbucket
    • Harbor
    • Jenkins
    • Spinnaker
    • TeamCity
  • Coding
    • DevSecOps
    • Golang
    • Jquery & JavaScript
    • Laravel
    • NextJS 14 & ReactJS & Type Script
    • Python
    • Selenium
    • Terraform
      • AWS – Amazon Web Service
      • Azure Cloud
      • GCP – Google Cloud
  • Kubernetes & Container
    • Apache Kafka
      • Kafka
      • Kafka Connect
      • Lenses
    • Docker
    • Helm Chart
    • Isito-EnvoyFilter
    • Kong Gateway
    • Kubernetes
      • Ingress
      • Pod
    • Longhorn – Storage
    • MetalLB
    • OAuth2 Proxy
    • Vault
    • VictoriaMetrics
  • Log, Monitor & Tracing
    • DataDog
    • ELK
      • Kibana
      • Logstash
    • Fluent
    • Grafana
    • Prometheus
  • Uncategorized
  • Admin

Copyright © 2025 NimTechnology.