{"id":1196,"date":"2019-02-05T21:21:31","date_gmt":"2019-02-05T21:21:31","guid":{"rendered":"https:\/\/www.appservgrid.com\/paw93\/?p=1196"},"modified":"2019-02-10T01:49:55","modified_gmt":"2019-02-10T01:49:55","slug":"deploying-a-scalable-jenkins-cluster-with-docker-and-rancher","status":"publish","type":"post","link":"https:\/\/www.appservgrid.com\/paw93\/index.php\/2019\/02\/05\/deploying-a-scalable-jenkins-cluster-with-docker-and-rancher\/","title":{"rendered":"Deploying a scalable Jenkins cluster with Docker and Rancher"},"content":{"rendered":"<p>Containerization brings several benefits to traditional CI platforms where builds share hosts: build dependencies can be isolated, applications can be tested against multiple environments (testing a Java app against multiple versions of JVM), on-demand build environments can be created with minimal stickiness to ensure test fidelity, Docker Compose can be used to quickly bring up environments which mirror development environments. Lastly, the inherent isolation offered by Docker Compose-based stacks allow for concurrent builds &#8212; a sticking point for traditional build environments with shared components.<\/p>\n<p>One of the immediate benefits of containerization for CI is that we can leverage tools such as Rancher to manage distributed build environments across multiple hosts. In this article, we\u2019re going to launch a distributed Jenkins cluster with Rancher Compose. This work builds upon the\u00a0<a href=\"https:\/\/www.digitalocean.com\/community\/tutorials\/how-to-manage-jenkins-with-rancher-on-ubuntu-14-04\">earlier work<\/a>** **by one of the authors, and further streamlines the process of spinning up and scaling a Jenkins stack.<\/p>\n<h1 id=\"our-jenkins-stack\">Our Jenkins Stack<\/h1>\n<p><a href=\"http:\/\/cdn.rancher.com\/wp-content\/uploads\/2015\/08\/01132750\/jenkins_master_slave1.png\"><img decoding=\"async\" src=\"http:\/\/cdn.rancher.com\/wp-content\/uploads\/2015\/08\/01132750\/jenkins_master_slave1.png\" alt=\"jenkins\\_master\\_slave\" \/><\/a>\u00a0For our stack, we\u2019re using Docker in Docker (DIND) images for Jenkins\u00a0<a href=\"https:\/\/github.com\/rancher\/jenkins-master\">master<\/a>**\u00a0<strong>and\u00a0<a href=\"https:\/\/github.com\/rancher\/jenkins-slave\">slave<\/a><\/strong>\u00a0**running on top of Rancher compute nodes launched in Amazon EC2. With DIND, each Jenkins container runs a Docker daemon within itself. This allows us to create build pipelines for dockerized applications with Jenkins.<\/p>\n<h1 id=\"prerequisites\">Prerequisites<\/h1>\n<ul>\n<li>[AWS EC2 account]<\/li>\n<li>[IAM credentials for docker machine]<\/li>\n<li>[Rancher Server v0.32.0+]<\/li>\n<li>[Docker 1.7.1+]<\/li>\n<li>[Rancher Compose]<\/li>\n<li>[Docker Compose]<\/li>\n<\/ul>\n<h1 id=\"setting-up-rancher\">Setting up Rancher<\/h1>\n<h3 id=\"step-1-setup-an-ec2-host-for-rancher-server\">Step 1: Setup an EC2 host for Rancher server<\/h3>\n<p>First thing first, we need an EC2 instance to run the Rancher server. We recommend going with\u00a0<a href=\"https:\/\/aws.amazon.com\/marketplace\/pp\/B00JV9TBA6\/ref=mkt_wir_Ubuntu14\">Ubuntu 14.04 AMI<\/a>\u00a0for it\u2019s up-to-date kernel. Make sure[ to configure the security group for the EC2 instance with access to port 22 (SSH) and 8080 (rancher web interface):]<\/p>\n<p><a href=\"http:\/\/cdn.rancher.com\/wp-content\/uploads\/2015\/08\/01132811\/launch_ec2_instance_for_rancher_step_21.png\"><img decoding=\"async\" src=\"http:\/\/cdn.rancher.com\/wp-content\/uploads\/2015\/08\/01132811\/launch_ec2_instance_for_rancher_step_21.png\" alt=\"launch\\_ec2\\_instance\\_for\\_rancher\\_step\\_2\" \/><\/a><\/p>\n<p>[Once the instance starts, the first order of business is to ][install the latest version of Docker by following the steps below (for Ubuntu 14.04):]<\/p>\n<ol>\n<li>[sudo apt-get update]<\/li>\n<li>[curl -sSL\u00a0<a href=\"https:\/\/get.docker.com\/\">https:\/\/get.docker.com\/<\/a>\u00a0| sh (requires sudo password)]<\/li>\n<li>[sudo usermod -aG docker ubuntu]<\/li>\n<li>[Log out and log back in to the instance]<\/li>\n<\/ol>\n<p>At this point you should be able to run docker without sudo.<\/p>\n<h3 id=\"step-2-run-and-configure-rancher\">[Step 2: Run and configure Rancher]<\/h3>\n<p>[To install and run the latest version of Rancher (v0.32.0 at the time of writing), follow the instructions in the\u00a0<a href=\"http:\/\/docs.rancher.com\/rancher\/installing-rancher\/installing-server\/\">docs<\/a>. In a few minutes your Rancher server should be up and ready to serve requests on port 8080. ][If you browse to\u00a0<code>http:\/\/YOUR_EC2_PUBLIC_IP:8080\/<\/code>\u00a0you will be greeted with a welcome page and a notice asking you to configure access. ][This is an important step to prevent unauthorized access to your Rancher server. Head over to the settings section and follow the instructions\u00a0<a href=\"http:\/\/docs.rancher.com\/rancher\/configuration\/access-control\/\">here<\/a>\u00a0to configure access control. ]<\/p>\n<p><a href=\"http:\/\/cdn.rancher.com\/wp-content\/uploads\/2015\/08\/01132730\/rancher_setup_step_1.png\"><img decoding=\"async\" src=\"http:\/\/cdn.rancher.com\/wp-content\/uploads\/2015\/08\/01132730\/rancher_setup_step_1.png\" alt=\"rancher\\_setup\\_step\\_1\" \/><\/a><\/p>\n<p>[We typically create a separate environment for hosting all developer facing tools, e.g., Jenkins, Seyren, Graphite etc to isolate them from the public facing live services. To this end, we\u2019re going to create an environment called *Tools. *From the environments menu (top left), select\u00a0<em>\\\u201cmanage environments\\\u201d<\/em>\u00a0and create a new environment. Since we\u2019re going to be working in this environment exclusively, let\u2019s go ahead and make this our default environment by selecting\u00a0<em>\\\u201cset as default login environment\\\u201d<\/em>\u00a0from the environments menu. ]<\/p>\n<p><a href=\"http:\/\/cdn.rancher.com\/wp-content\/uploads\/2015\/08\/01132732\/rancher_setup_step_2_add_tools_env.png\"><img decoding=\"async\" src=\"http:\/\/cdn.rancher.com\/wp-content\/uploads\/2015\/08\/01132732\/rancher_setup_step_2_add_tools_env.png\" alt=\"rancher\\_setup\\_step\\_2\\_add\\_tools\\_env\" \/><\/a><\/p>\n<p>The next step is to tell Rancher about our hosts. For this tutorial, we\u2019ll launch all hosts with Ubuntu 14.04. Alternatively, you can add an existing host using the\u00a0<a href=\"http:\/\/docs.rancher.com\/rancher\/rancher-ui\/infrastructure\/hosts\/custom\/\">custom host<\/a>** **option in Rancher. Just make sure that your hosts are running Docker 1.7.1+.<\/p>\n<p><a href=\"http:\/\/cdn.rancher.com\/wp-content\/uploads\/2015\/08\/01132734\/rancher_setup_step_3_add_ec2_host.png\"><img decoding=\"async\" src=\"http:\/\/cdn.rancher.com\/wp-content\/uploads\/2015\/08\/01132734\/rancher_setup_step_3_add_ec2_host.png\" alt=\"rancher\\_setup\\_step\\_3\\_add\\_ec2\\_host\" \/><\/a><\/p>\n<p>One of the hosts (<code>JENKINS_MASTER_HOST<\/code>) is going to run Jenkins master and would need some additional configuration. First, we need to open up access to port 8080 (default Jenkins port). You can do that by updating the security group used by that instance fom the AWS console. In our case, we updated the security group\u00a0<em>( \\\u201crancher-machine\\\u201d )<\/em>\u00a0which was created by rancher. Second, we need to attach an additional EBS-backed volume to host Jenkins configuration. Make sure that you allocate enough space for the volume, based on how large your build workspaces tend to get. In addition, make sure the flag \\\u201cdelete on termination\\\u201d is unchecked. That way, the volume can be re-attached to another instance and backed up easily:<\/p>\n<div><\/div>\n<div>[![launch\\_ec2\\_ebs\\_volume\\_for\\_jenkins](http:\/\/cdn.rancher.com\/wp-content\/uploads\/2015\/08\/01132712\/launch_ec2_ebs_volume_for_jenkins.png)](http:\/\/cdn.rancher.com\/wp-content\/uploads\/2015\/08\/01132712\/launch_ec2_ebs_volume_for_jenkins.png)<\/div>\n<p>Lastly, let\u2019s add a couple of labels for the\u00a0<code>JENKINS_MASTER_HOST<\/code>; 1) add a label called \\\u201cprofile\\\u201d with the value as \\\u201cjenkins\\\u201d and 2) add a label called \\\u201cjenkins-master\\\u201d with the value \\\u201ctrue\\\u201c. We\u2019re going to use these labels later to schedule master and slave containers on our hosts.<\/p>\n<h3 id=\"step-3-download-and-install-rancher-compose-cli\">Step 3: Download and install rancher-compose CLI<\/h3>\n<p>As a last step, we need to install the rancher-compose CLI on our development machine. To do that, head over to the applications tab in Rancher and download the rancher compose CLI for your system. All you need is to add the\u00a0<em>path-to-your-rancher-compose-CLI<\/em>\u00a0to your *PATH *environment variable.<\/p>\n<p><a href=\"http:\/\/cdn.rancher.com\/wp-content\/uploads\/2015\/08\/01132747\/rancher_setup_step_5_install_rancher_compose.png\"><img decoding=\"async\" src=\"http:\/\/cdn.rancher.com\/wp-content\/uploads\/2015\/08\/01132747\/rancher_setup_step_5_install_rancher_compose.png\" alt=\"rancher\\_setup\\_step\\_5\\_install\\_rancher\\_compose\" \/><\/a><\/p>\n<p>With that, our rancher server is ready and we can now launch and manage containers with it.<\/p>\n<h1 id=\"launching-jenkins-stack-with-rancher\">Launching Jenkins stack with Rancher<\/h1>\n<h3 id=\"step-1-stack-configuration\">Step 1: Stack configuration<\/h3>\n<p>Before we launch the Jenkins stack, we need to create a new Rancher API key from\u00a0<em>API &amp; Keys<\/em>\u00a0section under\u00a0<em>settings<\/em>. Save the API key pair some place safe as we\u2019re going to need it with rancher-compose. For the rest of the article, we refer to the API key pair as [<code>RANCHR_API_KEY<\/code>\u00a0and\u00a0<code>RANCHER_API_KEY_SECRET<\/code>]. Next, open up a terminal to fetch the latest version of Docker and Rancher Compose templates from Github:<\/p>\n<div class=\"highlight\">\n<pre>git clone https:\/\/github.com\/rancher\/jenkins-rancher.git\r\ncd jenkins-rancher<\/pre>\n<\/div>\n<p>Before we can use these templates, let\u2019s quickly update the configuration. First, open up the Docker Compose file and update the Jenkins username and password to a username and password of your choice. Let\u2019s call these credentials\u00a0<code>JENKINS_USER<\/code>and\u00a0<code>JENKINS_PASSWORD<\/code>. These credentials will be used by the Jenkins slave to talk to master. Second, update the host tag for slave and master to match the tags you specified for your rancher compute hosts. Make sure that the<em>io.rancher.scheduler.affinity:host_label<\/em>\u00a0has a value of \\\u201cprofile=jenkins\\\u201d for\u00a0<em>jenkins-slave.<\/em>\u00a0Similarly, for\u00a0<em>jenkins-master<\/em>, make sure that the value for\u00a0<em>io.rancher.scheduler.affinity:host_label<\/em>\u00a0is \\\u201cjenkins-master=true\\\u201c. This will ensure that rancher containers are only launched on the hosts that you want to limit them to. For example, we are limiting our Jenkins master to only run on a host with an attached EBS volume and access to port 8080.<\/p>\n<div class=\"highlight\">\n<pre>jenkins-slave:\r\n  environment:\r\n    JENKINS_USERNAME: jenkins\r\n    JENKINS_PASSWORD: jenkins\r\n    JENKINS_MASTER: http:\/\/jenkins-master:8080\r\n  labels:\r\n    io.rancher.scheduler.affinity:host_label: profile=jenkins\r\n  tty: true\r\n  image: techtraits\/jenkins-slave\r\n  links:\r\n  - jenkins-master:jenkins-master\r\n  privileged: true\r\n  volumes:\r\n  - \/var\/jenkins\r\n  stdin_open: true\r\njenkins-master:\r\n  restart: 'no'\r\n  labels:\r\n    io.rancher.scheduler.affinity:host_label: jenkins-master=true\r\n  tty: true\r\n  image: techtraits\/jenkins-master\r\n  privileged: true\r\n  stdin_open: true\r\n  volume_driver: \/var\/jenkins_home\r\njenkins-lb:\r\n  ports:\r\n  - '8080'\r\n  tty: true\r\n  image: rancher\/load-balancer-service\r\n  links:\r\n  - jenkins-master:jenkins-master\r\n  stdin_open: true<\/pre>\n<\/div>\n<h3 id=\"step-2-create-the-jenkins-stack-with-rancher-compose\">Step 2: Create the Jenkins stack with Rancher compose<\/h3>\n<div>[Now we&#8217;re all set to launch the Jenkins stack. Open up a terminal, navigate to the \\&#8221;jenkins-rancher\\&#8221; directory and type: ]<\/div>\n<div><\/div>\n<div class=\"highlight\">\n<pre>rancher-compose --url http:\/\/RANCHER_HOST:RANCHER_PORT\/v1\/ --access-key RANCHER_API_KEY --secret-key RANCHER_API_KEY_SECRET --project-name jenkins --verbose create<\/pre>\n<\/div>\n<div>[The output of the rancher compose command should look something like:]<\/div>\n<blockquote><p><strong><em>[DEBU[0000] Opening compose file: docker-compose.yml]<\/em><\/strong><strong><em>[ DEBU[0000] Opening rancher-compose file: \/home\/mbsheikh\/jenkins-rancher\/rancher-compose.yml]<\/em><\/strong><strong><em>[ DEBU[0000] [0\/3] [jenkins-slave]: Adding]<\/em><\/strong><strong><em>[ DEBU[0000] Found environment: jenkins(1e9)]<\/em><\/strong><strong><em>[ DEBU[0000] Launching action for jenkins-master]<\/em><\/strong><strong><em>[ DEBU[0000] Launching action for jenkins-slave]<\/em><\/strong><strong><em>[ DEBU[0000] Launching action for jenkins-lb]<\/em><\/strong><strong><em>[ DEBU[0000] Project [jenkins]: Creating project]<\/em><\/strong><strong><em>[ DEBU[0000] Finding service jenkins-master]<\/em><\/strong><strong><em>[ DEBU[0000] [0\/3] [jenkins-master]: Creating]<\/em><\/strong><strong><em>[ DEBU[0000] Found service jenkins-master]<\/em><\/strong><strong><em>[ DEBU[0000] [0\/3] [jenkins-master]: Created]<\/em><\/strong><strong><em>[ DEBU[0000] Finding service jenkins-slave]<\/em><\/strong><strong><em>[ DEBU[0000] Finding service jenkins-lb]<\/em><\/strong><strong><em>[ DEBU[0000] [0\/3] [jenkins-slave]: Creating]<\/em><\/strong><strong><em>[ DEBU[0000] Found service jenkins-slave]<\/em><\/strong><strong><em>[ DEBU[0000] [0\/3] [jenkins-slave]: Created]<\/em><\/strong><strong><em>[ DEBU[0000] Found service jenkins-lb]<\/em><\/strong><strong><em>[ DEBU[0000] [0\/3] [jenkins-lb]: Created]<\/em><\/strong><\/p><\/blockquote>\n<p>Next, verify that we have a new stack with three services:<\/p>\n<p><a href=\"http:\/\/cdn.rancher.com\/wp-content\/uploads\/2015\/08\/01132728\/rancher_compose_2_jenkins_stack_created.png\"><img decoding=\"async\" src=\"http:\/\/cdn.rancher.com\/wp-content\/uploads\/2015\/08\/01132728\/rancher_compose_2_jenkins_stack_created.png\" alt=\"rancher\\_compose\\_2\\_jenkins\\_stack\\_created\" \/><\/a><\/p>\n<p>Before we start the stack, let\u2019s make sure that the services are properly linked. Go to your stack\u2019s settings and select \\\u201cView Graph\\\u201d which should display the links between various services:<\/p>\n<p><a href=\"http:\/\/cdn.rancher.com\/wp-content\/uploads\/2015\/08\/01132729\/rancher_compose_3_jenkins_stack_graph.png\"><img decoding=\"async\" src=\"http:\/\/cdn.rancher.com\/wp-content\/uploads\/2015\/08\/01132729\/rancher_compose_3_jenkins_stack_graph.png\" alt=\"rancher\\_compose\\_3\\_jenkins\\_stack\\_graph\" \/><\/a><\/p>\n<h3 id=\"step-3-start-the-jenkins-stack-with-rancher-compose\">Step 3: Start the Jenkins stack with Rancher compose<\/h3>\n<p>To start the stack and all of Jenkins services, we have a couple of options; 1) select \\\u201cStart Services\\\u201d option from Rancher UI, or 2) invoke rancher-compose CLI with the following command:<\/p>\n<div class=\"highlight\">\n<pre>rancher-compose --url http:\/\/RANCHER_HOST:RANCHER_PORT\/v1\/ --access-key RANCHER_API_KEY --secret-key RANCHER_API_KEY_SECRET --project-name jenkins --verbose start<\/pre>\n<\/div>\n<p>Once everything is running, find out the public IP of the host running \\\u201cjenkins-lb\\\u201d from the Rancher UI and browse to\u00a0<a href=\"http:\/\/host_ip_of_jenkins_lb:8080\/\">http:\/\/HOST_IP_OF_JENKINS_LB:8080\/<\/a>. If everything is configured correctly, you should see the Jenkins landing page. At this point, both your Jenkins master and slave(s) should be running; however, if you check the logs for your Jenkins slave, you would see 404 errors where the Jenkins slave is unable to connect to the Jenkins master. We need to configure Jenkins to allow for slave connections.<\/p>\n<h1 id=\"configuring-and-testing-jenkins\">Configuring and Testing Jenkins<\/h1>\n<p>In this section, we\u2019ll go through the steps needed to configure and secure our Jenkins stack. First, let\u2019s create a Jenkins user with the same credentials (JENKINS_USER and JENKINS_PASSWORD) that you specified in your docker compose configuratio[n file. ]Next, to enable security for Jenkins, navigate to \\\u201cmanage Jenkins\\\u201d and select \\\u201cenable security\\\u201d from the security configuration. Make sure to specify 5000 as a fixed port for \\\u201cTCP port for JNLP slave agents\\\u201c. Jenkins slaves communicate with the master node on this port.<\/p>\n<p><a href=\"http:\/\/cdn.rancher.com\/wp-content\/uploads\/2015\/08\/01132748\/setup_jenkins_1_security.png\"><img decoding=\"async\" src=\"http:\/\/cdn.rancher.com\/wp-content\/uploads\/2015\/08\/01132748\/setup_jenkins_1_security.png\" alt=\"setup\\_jenkins\\_1\\_security\" \/><\/a><\/p>\n<p>For the Jenkins slave to be able to connect to the master, we first need to install the\u00a0<a href=\"https:\/\/wiki.jenkins-ci.org\/display\/JENKINS\/Swarm+Plugin\">Swarm plugin<\/a>. The plugin can be installed from the \\\u201cmanage plugins\\\u201d section in Jenkins. Once you have the swarm plugin installed, your Jenkins slave should show up in the \\\u201cBuild Executor Status\\\u201d tab:<\/p>\n<p><a href=\"http:\/\/cdn.rancher.com\/wp-content\/uploads\/2015\/08\/01132749\/setup_jenkins_2_slave_shows_up.png\"><img decoding=\"async\" src=\"http:\/\/cdn.rancher.com\/wp-content\/uploads\/2015\/08\/01132749\/setup_jenkins_2_slave_shows_up.png\" alt=\"setup\\_jenkins\\_2\\_slave\\_shows\\_up\" \/><\/a><\/p>\n<p>Finally, to complete the master-slave configuration, head over to \\\u201cmanage Jenkins\\\u201c. You should now see a notice about enabling master security subsystem. Go ahead and enable the subsystem; it can be used to control access between master and slaves:<\/p>\n<p><a href=\"http:\/\/cdn.rancher.com\/wp-content\/uploads\/2015\/08\/01132812\/setup_jenkins_3_master_slave_security_subsystem.png\"><img decoding=\"async\" src=\"http:\/\/cdn.rancher.com\/wp-content\/uploads\/2015\/08\/01132812\/setup_jenkins_3_master_slave_security_subsystem.png\" alt=\"setup\\_jenkins\\_3\\_master\\_slave\\_security\\_subsystem\" \/><\/a><\/p>\n<p>Before moving on, let\u2019s configure Jenkins to work with Git and Java based projects. To configure git, simply install the git plugin. Then, select \\\u201cConfigure\\\u201d from \\\u201cManage Jenkins\\\u201d settings and set up the JDK and maven installers you want to use for your projects:<\/p>\n<p>[<a href=\"http:\/\/cdn.rancher.com\/wp-content\/uploads\/2015\/08\/01132813\/setup_jenkins_4_jdk_7.png\"><img decoding=\"async\" src=\"http:\/\/cdn.rancher.com\/wp-content\/uploads\/2015\/08\/01132813\/setup_jenkins_4_jdk_7.png\" alt=\"setup\\_jenkins\\_4\\_jdk\\_7\" \/><\/a>]<\/p>\n<p><a href=\"http:\/\/cdn.rancher.com\/wp-content\/uploads\/2015\/08\/01132814\/setup_jenkins_5_maven_3.png\"><img decoding=\"async\" src=\"http:\/\/cdn.rancher.com\/wp-content\/uploads\/2015\/08\/01132814\/setup_jenkins_5_maven_3.png\" alt=\"setup\\_jenkins\\_5\\_maven\\_3\" \/><\/a><\/p>\n<p>The steps above should be sufficient for building docker or maven based Java projects. To test our new Jenkins stack, let\u2019s create a docker based job. Create a new \\\u201cFreestyle Project\\\u201d type job named \\\u201cdocker-test\\\u201d and add the following build step and select \\\u201cexecute shell\\\u201d with the following commands:<\/p>\n<div class=\"highlight\">\n<pre>docker -v\r\ndocker run ubuntu \/bin\/echo hello world\r\ndocker stop $(docker ps -a -q)\r\ndocker rm $(docker ps -a -q)\r\ndocker rmi $(docker images -q)<\/pre>\n<\/div>\n<p>Save the job and run. In the console output, you should see the version of docker running inside your Jenkins container and the output for other docker commands in our job.<\/p>\n<p><strong>Note:<\/strong>\u00a0The stop, rm and rmi commands used in the above shell script stops and cleans up all containers and images. Each Jenkins job should only touch it\u2019s own containers, and therefore, we recommend deleting this job after a successful test.<\/p>\n<h1 id=\"scaling-jenkins-with-rancher\">Scaling Jenkins with Rancher<\/h1>\n<p>This is an area where Rancher really shines; it makes managing and scaling Docker containers trivially easy. In this section we\u2019ll show you how to scale up and scale down the number of Jenkins slaves based on your needs.<\/p>\n<p>In our initial setup, we only had one EC2 host registered with Rancher and all three services (Jenkins load balancer, Jenkins master and Jenkins slave) running on the same host. It looks like:<\/p>\n<p><a href=\"http:\/\/cdn.rancher.com\/wp-content\/uploads\/2015\/08\/01132829\/rancher_one_host.png\"><img decoding=\"async\" src=\"http:\/\/cdn.rancher.com\/wp-content\/uploads\/2015\/08\/01132829\/rancher_one_host.png\" alt=\"rancher\\_one\\_host\" \/><\/a><\/p>\n<p>We\u2019re now going to register another host by following the instructions\u00a0<a href=\"http:\/\/docs.rancher.com\/rancher\/rancher-ui\/infrastructure\/hosts\/\">here<\/a>:<\/p>\n<p><a href=\"http:\/\/cdn.rancher.com\/wp-content\/uploads\/2015\/08\/01132830\/rancher_setup_step_4_hosts1.png\"><img decoding=\"async\" src=\"http:\/\/cdn.rancher.com\/wp-content\/uploads\/2015\/08\/01132830\/rancher_setup_step_4_hosts1.png\" alt=\"rancher\\_setup\\_step\\_4\\_hosts\" \/><\/a><\/p>\n<p><img decoding=\"async\" src=\"http:\/\/cdn.rancher.com\/wp-content\/uploads\/2015\/08\/01132831\/jenkins_scale_up1.png\" alt=\"jenkins\\_scale\\_up\" \/>To launch more Jenkins slaves, simply click \\\u201cScale up\\\u201d from your \\\u201cJenkins\\\u201d stack in Rancher. That\u2019s it! Rancher will immediately launch a new Jenkins slave container. As soon as the slave container starts, it will connect with Jenkins master and will show up in the list of build hosts:<\/p>\n<p><a href=\"http:\/\/cdn.rancher.com\/wp-content\/uploads\/2015\/08\/01132709\/jenkins_scale_up_2.png\"><img decoding=\"async\" src=\"http:\/\/cdn.rancher.com\/wp-content\/uploads\/2015\/08\/01132709\/jenkins_scale_up_2.png\" alt=\"jenkins\\_scale\\_up\\_2\" \/><\/a><\/p>\n<p>To scale down, select \\\u201cedit\\\u201d from jenkins-slave settings and adjust the number of slaves to your liking:<\/p>\n<p><a href=\"http:\/\/cdn.rancher.com\/wp-content\/uploads\/2015\/08\/01132707\/jenkins_scale_down.png\"><img decoding=\"async\" src=\"http:\/\/cdn.rancher.com\/wp-content\/uploads\/2015\/08\/01132707\/jenkins_scale_down.png\" alt=\"jenkins\\_scale\\_down\" \/><\/a><\/p>\n<p>In a few seconds you\u2019ll see the change reflected in Jenkins list of available build hosts. Behind the scenes, Rancher uses labels to schedule containers on hosts. For more details on Rancher\u2019s container scheduling, we encourage you to check out the\u00a0<a href=\"http:\/\/docs.rancher.com\/rancher\/concepts\/scheduling\/\">documentation<\/a>.<\/p>\n<h1 id=\"conclusion\">Conclusion<\/h1>\n<p>In this article, we built Jenkins with Docker and Rancher. We deployed up a multi-node Jenkins platform with Rancher Compose which can be launched with a couple of commands and scaled as needed. Rancher\u2019s cross-node networking allows us to seamlessly scale the Jenkins cluster on multiple nodes and potentially across multiple clouds with just a few clicks. Another significant aspect of our Jenkins stack is the DIND containers for Jenkins master and slave, which allows the Jenkins setup to be readily used for dockerized and non dockerized applications.<\/p>\n<p>In future articles, we\u2019re going to use this Jenkins stack to create build pipelines and highlight CI best practices for dockerized applications. To learn more about managing applications through the upgrade process, please join our next online meetup where we\u2019ll dive into the details of how to manage deployments and upgrades of microservices with Docker and Rancher.<\/p>\n<p><a href=\"https:\/\/rancher.com\/deploying-a-scalable-jenkins-cluster-with-docker-and-rancher\/\" target=\"_blank\" rel=\"noopener\">Source<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Containerization brings several benefits to traditional CI platforms where builds share hosts: build dependencies can be isolated, applications can be tested against multiple environments (testing a Java app against multiple versions of JVM), on-demand build environments can be created with minimal stickiness to ensure test fidelity, Docker Compose can be used to quickly bring up &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/www.appservgrid.com\/paw93\/index.php\/2019\/02\/05\/deploying-a-scalable-jenkins-cluster-with-docker-and-rancher\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Deploying a scalable Jenkins cluster with Docker and Rancher&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3],"tags":[],"class_list":["post-1196","post","type-post","status-publish","format-standard","hentry","category-kubernetes"],"_links":{"self":[{"href":"https:\/\/www.appservgrid.com\/paw93\/index.php\/wp-json\/wp\/v2\/posts\/1196","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.appservgrid.com\/paw93\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.appservgrid.com\/paw93\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.appservgrid.com\/paw93\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.appservgrid.com\/paw93\/index.php\/wp-json\/wp\/v2\/comments?post=1196"}],"version-history":[{"count":1,"href":"https:\/\/www.appservgrid.com\/paw93\/index.php\/wp-json\/wp\/v2\/posts\/1196\/revisions"}],"predecessor-version":[{"id":1225,"href":"https:\/\/www.appservgrid.com\/paw93\/index.php\/wp-json\/wp\/v2\/posts\/1196\/revisions\/1225"}],"wp:attachment":[{"href":"https:\/\/www.appservgrid.com\/paw93\/index.php\/wp-json\/wp\/v2\/media?parent=1196"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.appservgrid.com\/paw93\/index.php\/wp-json\/wp\/v2\/categories?post=1196"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.appservgrid.com\/paw93\/index.php\/wp-json\/wp\/v2\/tags?post=1196"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}