Skip to content
This repository has been archived by the owner on Jun 19, 2024. It is now read-only.

Add the posibility to dynamically set the number of replicas in the Kubernetes Deployment file #1354

Open
codependent opened this issue Aug 13, 2018 · 10 comments
Labels
cat/bug Bug which needs fixing status/never-stale Pin this issue to get never marked as stale by stale-bot

Comments

@codependent
Copy link

codependent commented Aug 13, 2018

Description

Let's suppose I have a Jenkins pipeline pipeline with two stages deploy-staging and deploy-pro. sh "./mvnw fabric8:resource" generates a kubernetes.yaml file with this number of replicas:

  spec:
    replicas: 1

Now, image in want one replica for staging but n for production. I can manually do kubectl scale deployment --replicas=2 but as soon as I do mvn fabric8:apply with for instance a new image to use, the replicas will be downscaled to 1 again.

It'd be great to have a fabric8.replicas property to allow us to override this value.

Info

  • f-m-p version : 3.5.41

  • Maven version (mvn -v) : Apache Maven 3.5.3

  • Kubernetes / OpenShift setup and version : Kubernetes 1.11

@rhuss
Copy link
Contributor

rhuss commented Aug 13, 2018

Depending how you generate you resource descriptors, you can already do this.

I.e. if you are relying on the enricher to generate a default Deployment, then just set the property fabric8.enricher.fmp-controller.replicaCount to the the number you want, or alternatively put this into the configuration:

<enricher>
  <config>
    <fmp-controller>
      <replicaCount>2</replicaCount>
    </fmp-controller>
  </config>
</enricher>

Of in the general case, you can also use a fragment by putting a file name-deployment.yml (with name the name of your app) into src/main/fabric8 with the fragment:

spec:
  replicas: 2

@codependent
Copy link
Author

codependent commented Aug 13, 2018

@rhuss thanks for your quick reply, I am using a generator so the enricher property fits perfectly. However I am having trouble making this all fit in a Jenkins pipeline, could you suggest how to do it, please?

This was my initial scenario:

  1. First I build and push the docker image:
stage("Build and Push Docker Image"){
    sh "./mvnw fabric8:build"
    ...
    sh "./mvnw fabric8:push"
}
  1. I build the staging resources and apply them (replicaCount 1)
stage("Deploy Staging") {
            agent {
                label 'jenkins-slave'
            }
            steps {
                container('jenkins-slave') {
                    script {
                        sh "./mvnw fabric8:resource -Dfabric8.enricher.fmp-controller.replicaCount=1"
                        sh "./mvnw fabric8:apply -Dfabric8.namespace=staging"
                    }
                }
            }
        }
  1. I build the pro resources and apply them (replicaCount 4)
stage("Deploy Production") {
            agent {
                label 'jenkins-slave'
            }
            steps {
                container('jenkins-slave') {
                    script {
                        sh "./mvnw fabric8:resource -Dfabric8.enricher.fmp-controller.replicaCount=4"
                        sh "./mvnw fabric8:apply -Dfabric8.namespace=production"
                    }
                }
            }
        }

The problem here is: in the "Build and Push Docker Image" stage an image is pushed to my private registry with this tag: 0.0.1-SNAPSHOTsnapshot-180813-094821-0461 but in the "Deploy Staging" stage the generated kubernetes.yaml points at an unknown image 0.0.1-SNAPSHOTsnapshot-180813-095003-0795 and the startup of the application fails (ImagePullBackOff).

Thus, I am forced to execute in the same stage this so the tag used in the image push and the kubernetes.yml resource is the same:

sh "./mvnw fabric8:build" 
sh "./mvnw fabric8:push"
sh "./mvnw fabric8:resource -Dfabric8.enricher.fmp-controller.replicaCount=1"

Now I cannot customize the replica count per environment since I cannot separate the fabric8:resource generation per environment.

Any suggestion?

@rhuss
Copy link
Contributor

rhuss commented Aug 13, 2018

Actually the time based tagging of snapshot images is flawed if build and resource are not called at the same time. While this could be potentially be fixed (a long the same lines as skaffold) with some temporary files, I highly recommend to change the naming strategy.

See also #1093 for further explanation.

You can change the strategy by setting the property fabric8.generator.name=%g/%a:%l (the possible placeholders are explained here)

Does this help ?

@codependent
Copy link
Author

The downside I see is that relying on latest (%l) could lead to some uncertainty about what you have in Staging:

You build a dev image (1.0.0-SNAPSHOT) and apply it to the staging env.

Someone builds a pro image (1.0.0) and applies it to the prod env.

You don't know the new image exists and for some reason restart your pod. It's gonna pull latest again which is 1.0.0 not 1.0.0-SNAPSHOT anymore.

@codependent
Copy link
Author

codependent commented Aug 13, 2018

I have also come across a problem using %l for SNAPSHOT versions. Google Cloud Registry complaints about using the same tag (latest) since it already exists:

[ERROR] Failed to execute goal io.fabric8:fabric8-maven-plugin:3.5.41:push (default-cli) on project gke-springboot-sample: Cannot temporarily tag apps-internas-212606/prfl/gke-springboot-sample:latest with eu.gcr.io/mygcproject/gke-springboot-sample:latest because target image already exists. Please remove this and retry. -> [Help 1]
org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal io.fabric8:fabric8-maven-plugin:3.5.41:push (default-cli) on project gke-springboot-sample: Cannot temporarily tag mygcproject/gke-springboot-sample:latest with eu.gcr.io/mygcproject/gke-springboot-sample:latest because target image already exists. Please remove this and retry.

Config:

    <plugin>
                <groupId>io.fabric8</groupId>
                <artifactId>fabric8-maven-plugin</artifactId>
                <version>3.5.41</version>
                <configuration>
                    <generator>
                        <includes>
                            <include>spring-boot</include>
                        </includes>
                        <config>
                            <spring-boot>
                                <registry>eu.gcr.io</registry>
                                <name>mygcproject/%a:%l</name>
                            </spring-boot>
                        </config>
                    </generator>
                    <enricher>
                        <config>
                            <fmp-controller>
                                <pullPolicy>Always</pullPolicy>
                            </fmp-controller>
                        </config>
                    </enricher>
                </configuration>

@stale
Copy link

stale bot commented Nov 11, 2018

This issue has been automatically marked as stale because it has not had any activity since 90 days. It will be closed if no further activity occurs within 7 days. Thank you for your contributions!

@stale stale bot added the status/stale Issue/PR considered to be stale label Nov 11, 2018
@stale stale bot closed this as completed Nov 18, 2018
@mab
Copy link

mab commented Mar 4, 2020

Hello @rhuss, is the property fabric8.enricher.fmp-controller.replicaCount dropped with the plugin 4.x.x? I currently using the latest plugin 4.4.0 and setting the property has no effect on the generated deployment.yml as it had in 3.5.x. With 4.x.x I need to explicitly set replicas: ${fabric8.enricher.fmp-controller.replicaCount}

@rohanKanojia
Copy link
Member

Seems like a regression, we split DefaultControllerEnricher to two enrichers in 4.x versions. Could you please provide a reproducible sample if possible? We'll try to fix it before next release(coming in 1-2 weeks)

@rohanKanojia rohanKanojia reopened this Mar 4, 2020
@stale stale bot removed the status/stale Issue/PR considered to be stale label Mar 4, 2020
@mab
Copy link

mab commented Mar 6, 2020

Seems like a regression, we split DefaultControllerEnricher to two enrichers in 4.x versions. Could you please provide a reproducible sample if possible? We'll try to fix it before next release(coming in 1-2 weeks)

I created a minimal example and in this it is working for both versions 3.5.42 and 4.4.0. The benefit of having the property setting it implicitly over setting it explicitly is minimal. So feel free to close the ticket again.

@stale
Copy link

stale bot commented Jun 5, 2020

This issue has been automatically marked as stale because it has not had any activity since 90 days. It will be closed if no further activity occurs within 7 days. Thank you for your contributions!

@stale stale bot added the status/stale Issue/PR considered to be stale label Jun 5, 2020
@rohanKanojia rohanKanojia added the status/never-stale Pin this issue to get never marked as stale by stale-bot label Jun 5, 2020
@stale stale bot removed the status/stale Issue/PR considered to be stale label Jun 5, 2020
@rohanKanojia rohanKanojia removed the status/never-stale Pin this issue to get never marked as stale by stale-bot label Jun 5, 2020
@manusa manusa added status/never-stale Pin this issue to get never marked as stale by stale-bot cat/bug Bug which needs fixing labels Jun 19, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
cat/bug Bug which needs fixing status/never-stale Pin this issue to get never marked as stale by stale-bot
Projects
None yet
Development

No branches or pull requests

5 participants