kubernetes-ci-cd/README.md

429 строки
13 KiB
Markdown
Исходник Постоянная ссылка Обычный вид История

2017-04-28 00:31:05 +03:00
# Linux.com Kubernetes CI/CD Blog Series by Kenzan
2017-03-30 12:17:57 +03:00
The kubernetes-ci-cd project is [Kenzan's](http://techblog.kenzan.com/) crossword puzzle application that runs as several containers in Kubernetes (we call it the Kr8sswordz Puzzle). It showcases Kubernetes features like spinning up multiple pods and running a load test at scale. It also features Jenkins running on its own a container and a JenkinsFile script to demonstrate how Kubernetes can be integrated into a full CI/CD pipeline.
To get it up and running, see the following week-by-week Linux.com blog posts, or simply follow the directions below.
2017-06-09 23:43:22 +03:00
[Linux.com Part 1](https://www.linux.com/blog/learn/chapter/Intro-to-Kubernetes/2017/5/set-cicd-pipeline-kubernetes-part-1-overview)
2017-06-09 23:42:59 +03:00
2017-06-09 23:43:22 +03:00
[Linux.com Part 2](https://www.linux.com/blog/learn/chapter/Intro-to-Kubernetes/2017/6/set-cicd-pipeline-jenkins-pod-kubernetes-part-2)
2017-06-09 23:42:59 +03:00
[Linux.com Part 3](https://www.linux.com/blog/learn/chapter/intro-to-kubernetes/2017/6/run-and-scale-distributed-crossword-puzzle-app-cicd-kubernetes-part-3)
2017-08-04 19:44:02 +03:00
[Linux.com Part 4](https://www.linux.com/blog/learn/chapter/intro-to-kubernetes/2017/6/set-cicd-distributed-crossword-puzzle-app-kubernetes-part-4)
To generate this readme: `node readme.js`
2017-03-30 12:17:57 +03:00
2017-04-28 00:31:05 +03:00
## Interactive Tutorial Version
To complete the tutorial using the interactive script:
2017-03-30 12:17:57 +03:00
2017-04-28 00:31:05 +03:00
* Clone this repository.
2017-04-04 01:48:19 +03:00
2017-04-28 00:31:05 +03:00
* To ensure you are starting with a clean slate: `minikube delete; sudo rm -rf ~/.minikube; sudo rm -rf ~/.kube`
2017-04-04 01:48:19 +03:00
2017-04-28 00:31:05 +03:00
* To run: `npm install`
2017-04-04 01:48:19 +03:00
2017-04-28 00:31:05 +03:00
Begin the desired section:
2017-04-04 05:16:37 +03:00
2017-04-28 00:31:05 +03:00
* `npm run part1`
* `npm run part2`
* `npm run part3`
* `npm run part4`
## Manual Tutorial Version
To complete the tutorial manually, follow the steps below.
2017-04-04 18:44:23 +03:00
2017-04-04 21:21:21 +03:00
2017-06-12 20:37:53 +03:00
## Part 1
2017-04-04 21:21:21 +03:00
2017-04-28 00:31:05 +03:00
#### Step1
2017-04-04 18:44:23 +03:00
2017-04-28 00:31:05 +03:00
Start up the Kubernetes cluster with Minikube, giving it some extra resources.
2017-04-04 18:44:23 +03:00
`minikube start --memory 8000 --cpus 2 --kubernetes-version v1.6.0`
2017-04-04 18:44:23 +03:00
2017-04-28 00:31:05 +03:00
#### Step2
2017-04-04 18:44:23 +03:00
2017-04-28 00:31:05 +03:00
Enable the Minikube add-ons Heapster and Ingress.
2017-04-04 18:44:23 +03:00
`minikube addons enable heapster; minikube addons enable ingress`
2017-04-28 00:31:05 +03:00
#### Step3
2017-04-04 18:44:23 +03:00
2017-04-28 00:31:05 +03:00
Wait 20 seconds, and then view the Minikube Dashboard, a web UI for managing deployments.
2017-04-04 18:44:23 +03:00
`sleep 20; minikube service kubernetes-dashboard --namespace kube-system`
2017-04-28 00:31:05 +03:00
#### Step4
2017-04-04 18:44:23 +03:00
2017-04-28 00:31:05 +03:00
Deploy the public nginx image from DockerHub into a pod. Nginx is an open source web server that will automatically download from Docker Hub if its not available locally.
2017-04-04 18:44:23 +03:00
`kubectl run nginx --image nginx --port 80`
2017-04-28 00:31:05 +03:00
#### Step5
2017-04-04 18:44:23 +03:00
2017-04-28 00:31:05 +03:00
Create a service for deployment. This will expose the nginx pod so you can access it with a web browser.
2017-04-04 18:44:23 +03:00
`kubectl expose deployment nginx --type NodePort --port 80`
2017-04-28 00:31:05 +03:00
#### Step6
2017-04-04 18:44:23 +03:00
2017-04-28 00:31:05 +03:00
Launch a web browser to test the service. The nginx welcome page displays, which means the service is up and running.
2017-04-04 18:44:23 +03:00
`minikube service nginx`
2017-04-28 00:31:05 +03:00
#### Step7
2017-04-04 18:44:23 +03:00
2017-04-28 00:31:05 +03:00
Set up the cluster registry by applying a .yml manifest file.
2017-04-04 18:44:23 +03:00
`kubectl apply -f manifests/registry.yml`
2017-04-28 00:31:05 +03:00
#### Step8
2017-04-04 18:44:23 +03:00
2017-04-28 00:31:05 +03:00
Wait for the registry to finish deploying. Note that this may take several minutes.
2017-04-04 18:44:23 +03:00
`kubectl rollout status deployments/registry`
2017-04-28 00:31:05 +03:00
#### Step9
2017-04-04 18:44:23 +03:00
2017-04-28 00:31:05 +03:00
View the registry user interface in a web browser.
2017-04-04 18:44:23 +03:00
`minikube service registry-ui`
2017-04-28 00:31:05 +03:00
#### Step10
2017-04-04 18:44:23 +03:00
Lets make a change to an HTML file in the cloned project. Open the /applications/hello-kenzan/index.html file in your favorite text editor (for example, you can use nano by running the command 'nano applications/hello-kenzan/index.html' in a separate terminal). Change some text inside one of the <p> tags. For example, change “Hello from Kenzan!” to “Hello from Me!”. Save the file.
2017-04-04 18:44:23 +03:00
`echo ''`
2017-04-04 18:44:23 +03:00
2017-04-28 00:31:05 +03:00
#### Step11
2017-04-04 18:44:23 +03:00
2017-04-28 00:31:05 +03:00
Now lets build an image, giving it a special name that points to our local cluster registry.
2017-04-04 18:44:23 +03:00
`docker build -t 127.0.0.1:30400/hello-kenzan:latest -f applications/hello-kenzan/Dockerfile applications/hello-kenzan`
2017-04-28 00:31:05 +03:00
#### Step12
2017-04-04 18:44:23 +03:00
2017-04-28 00:31:05 +03:00
Weve built the image, but before we can push it to the registry, we need to set up a temporary proxy. By default the Docker client can only push to HTTP (not HTTPS) via localhost. To work around this, well set up a container that listens on 127.0.0.1:30400 and forwards to our cluster.
2017-04-04 18:44:23 +03:00
2017-04-04 21:25:06 +03:00
`docker stop socat-registry; docker rm socat-registry; docker run -d -e "REGIP=`minikube ip`" --name socat-registry -p 30400:5000 chadmoon/socat:latest bash -c "socat TCP4-LISTEN:5000,fork,reuseaddr TCP4:`minikube ip`:30400"`
2017-04-04 18:44:23 +03:00
2017-04-28 00:31:05 +03:00
#### Step13
2017-04-04 18:44:23 +03:00
2017-04-28 00:31:05 +03:00
With our proxy container up and running, we can now push our image to the local repository.
2017-04-04 18:44:23 +03:00
`docker push 127.0.0.1:30400/hello-kenzan:latest`
2017-04-28 00:31:05 +03:00
#### Step14
2017-04-04 18:44:23 +03:00
2017-04-28 00:31:05 +03:00
The proxys work is done, so you can go ahead and stop it.
2017-04-04 18:44:23 +03:00
`docker stop socat-registry;`
2017-04-28 00:31:05 +03:00
#### Step15
2017-04-04 18:44:23 +03:00
2017-04-28 00:31:05 +03:00
With the image in our cluster registry, the last thing to do is apply the manifest to create and deploy the hello-kenzan pod based on the image.
2017-04-04 18:44:23 +03:00
`kubectl apply -f applications/hello-kenzan/k8s/deployment.yaml`
2017-04-28 00:31:05 +03:00
#### Step16
2017-04-04 18:44:23 +03:00
2017-04-28 00:31:05 +03:00
Launch a web browser and view the service.
2017-04-04 18:44:23 +03:00
2017-06-12 20:37:53 +03:00
`minikube service hello-kenzan`
2017-04-04 21:21:21 +03:00
2017-06-12 20:37:53 +03:00
## Part 2
2017-04-04 21:21:21 +03:00
2017-04-28 00:31:05 +03:00
#### Step1
2017-04-04 18:44:23 +03:00
2017-04-28 00:31:05 +03:00
Install Jenkins, which well use to create our automated CI/CD pipeline. It will take the pod a minute or two to roll out.
2017-04-04 18:44:23 +03:00
`kubectl apply -f manifests/jenkins.yml; kubectl rollout status deployment/jenkins`
2017-04-28 00:31:05 +03:00
#### Step2
2017-04-04 18:44:23 +03:00
2017-04-28 00:31:05 +03:00
Open the Jenkins UI in a web browser.
2017-04-04 18:44:23 +03:00
`minikube service jenkins`
2017-04-04 18:44:23 +03:00
2017-04-28 00:31:05 +03:00
#### Step3
2017-04-04 18:44:23 +03:00
2017-04-28 00:31:05 +03:00
Display the Jenkins admin password with the following command, and right-click to copy it. IMPORTANT: BE CAREFUL NOT TO PRESS CTRL-C TO COPY THE PASSWORD AS THIS WILL STOP THE SCRIPT.
2017-04-04 18:44:23 +03:00
`kubectl exec -it `kubectl get pods --selector=app=jenkins --output=jsonpath={.items..metadata.name}` cat /root/.jenkins/secrets/initialAdminPassword`
2017-04-04 18:44:23 +03:00
2017-04-28 00:31:05 +03:00
#### Step4
Switch back to the Jenkins UI. Paste the Jenkins admin password in the box and click Continue. Click Install suggested plugins and wait for the process to complete.
`echo ''`
#### Step5
Create an admin user and credentials, and click Save and Finish. (Make sure to remember these credentials as you will need them for repeated logins.) Click Start using Jenkins.
`echo ''`
#### Step6
We now want to create a new pipeline for use with our Hello-Kenzan app. On the left, click New Item. Enter the item name as "Hello-Kenzan Pipeline", select Pipeline, and click OK.
`echo ''`
#### Step7
Under the Pipeline section at the bottom, change the Definition to be "Pipeline script from SCM".
`echo ''`
2017-04-04 18:44:23 +03:00
2017-04-28 00:31:05 +03:00
#### Step8
Change the SCM to Git.
`echo ''`
#### Step9
Change the Repository URL to be the URL of your forked Git repository, such as https://github.com/[GIT USERNAME]/kubernetes-ci-cd. Click Save. On the left, click Build Now to run the new pipeline.
`echo ''`
#### Step10
Now view the Hello-Kenzan application.
2017-04-04 18:44:23 +03:00
`minikube service hello-kenzan`
2017-04-28 00:31:05 +03:00
#### Step11
2017-04-04 18:44:23 +03:00
2017-04-28 00:31:05 +03:00
Push a change to your fork. Run job again. View the changes.
2017-04-04 18:44:23 +03:00
2017-06-12 20:37:53 +03:00
`minikube service hello-kenzan`
2017-04-04 21:21:21 +03:00
2017-06-12 20:37:53 +03:00
## Part 3
2017-04-04 21:21:21 +03:00
2017-04-28 00:31:05 +03:00
#### Step1
2017-04-04 01:48:19 +03:00
2017-04-28 00:31:05 +03:00
Start the etcd operator and service on the cluster. You may notice errors showing up as it is waiting to start up the cluster. This is normal until it starts.
2017-04-04 01:48:19 +03:00
2017-04-04 11:00:50 +03:00
`scripts/etcd.sh`
2017-04-04 01:48:19 +03:00
2017-04-28 00:31:05 +03:00
#### Step2
2017-04-04 01:48:19 +03:00
2017-04-28 00:31:05 +03:00
Now that we have an etcd service, we need an etcd client. The following command will set up a directory within etcd for storing key-value pairs, and then run the etcd client.
2017-04-04 18:44:23 +03:00
`kubectl create -f manifests/etcd-job.yml`
2017-04-28 00:31:05 +03:00
#### Step3
2017-04-04 18:44:23 +03:00
2017-04-28 00:31:05 +03:00
Check the status of the job in step 2 to make sure it deployed.
2017-04-04 18:44:23 +03:00
`kubectl describe jobs/etcd-job`
2017-04-28 00:31:05 +03:00
#### Step4
2017-04-04 18:44:23 +03:00
2017-04-28 00:31:05 +03:00
The crossword application is a multi-tier application whose services depend on each other. We will create three services in Kubernetes ahead of time, so that the deployments are aware of them.
2017-04-04 18:44:23 +03:00
`kubectl apply -f manifests/all-services.yml`
2017-04-04 18:44:23 +03:00
2017-04-28 00:31:05 +03:00
#### Step5
2017-04-04 18:44:23 +03:00
2017-04-28 00:31:05 +03:00
Now we're going to walk through an initial build of the monitor-scale service.
2017-04-04 18:44:23 +03:00
2017-04-28 00:31:05 +03:00
`docker build -t 127.0.0.1:30400/monitor-scale:`git rev-parse --short HEAD` -f applications/monitor-scale/Dockerfile applications/monitor-scale`
2017-04-04 18:44:23 +03:00
2017-04-28 00:31:05 +03:00
#### Step6
2017-04-04 18:44:23 +03:00
2017-04-28 00:31:05 +03:00
Set up a proxy so we can push the monitor-scale Docker image we just built to our cluster's registry.
2017-04-04 18:44:23 +03:00
`docker stop socat-registry; docker rm socat-registry; docker run -d -e "REGIP=`minikube ip`" --name socat-registry -p 30400:5000 chadmoon/socat:latest bash -c "socat TCP4-LISTEN:5000,fork,reuseaddr TCP4:`minikube ip`:30400"`
2017-04-04 18:44:23 +03:00
2017-04-28 00:31:05 +03:00
#### Step7
2017-04-04 18:44:23 +03:00
2017-04-28 00:31:05 +03:00
Push the monitor-scale image to the registry.
2017-04-04 18:44:23 +03:00
`docker push 127.0.0.1:30400/monitor-scale:`git rev-parse --short HEAD``
2017-04-04 18:44:23 +03:00
2017-04-28 00:31:05 +03:00
#### Step8
2017-04-04 18:44:23 +03:00
2017-04-28 00:31:05 +03:00
The proxys work is done, so go ahead and stop it.
2017-04-04 18:44:23 +03:00
`docker stop socat-registry`
2017-04-04 18:44:23 +03:00
2017-04-28 00:31:05 +03:00
#### Step9
2017-04-04 18:44:23 +03:00
2017-04-28 00:31:05 +03:00
Open the registry UI and verify that the monitor-scale image is in our local registry.
2017-04-04 18:44:23 +03:00
`minikube service registry-ui`
2017-04-04 18:44:23 +03:00
2017-04-28 00:31:05 +03:00
#### Step10
2017-04-04 18:44:23 +03:00
2017-04-28 00:31:05 +03:00
Create the monitor-scale deployment and service.
2017-04-04 18:44:23 +03:00
2017-04-28 00:31:05 +03:00
`sed 's#127.0.0.1:30400/monitor-scale:latest#127.0.0.1:30400/monitor-scale:'`git rev-parse --short HEAD`'#' applications/monitor-scale/k8s/deployment.yaml | kubectl apply -f -`
2017-04-04 18:44:23 +03:00
2017-04-28 00:31:05 +03:00
#### Step11
2017-04-04 18:44:23 +03:00
2017-04-28 00:31:05 +03:00
Wait for the monitor-scale deployment to finish.
2017-04-04 18:44:23 +03:00
`kubectl rollout status deployment/monitor-scale`
2017-04-04 18:44:23 +03:00
2017-04-28 00:31:05 +03:00
#### Step12
2017-04-04 18:44:23 +03:00
2017-04-28 00:31:05 +03:00
View pods to see the monitor-scale pod running.
`kubectl get pods`
2017-04-28 00:31:05 +03:00
#### Step13
2017-04-28 00:31:05 +03:00
View services to see the monitor-scale service.
`kubectl get services`
2017-04-28 00:31:05 +03:00
#### Step14
2017-04-28 00:31:05 +03:00
View ingress rules to see the monitor-scale ingress rule.
`kubectl get ingress`
2017-04-28 00:31:05 +03:00
#### Step15
2017-04-28 00:31:05 +03:00
View deployments to see the monitor-scale deployment.
`kubectl get deployments`
2017-04-28 00:31:05 +03:00
#### Step16
2017-04-28 00:31:05 +03:00
We will run a script to bootstrap the puzzle and mongo services, creating Docker images and storing them in the local registry. The puzzle.sh script runs through the same build, proxy, push, and deploy steps we just ran through manually for both services.
2017-04-28 00:31:05 +03:00
`scripts/puzzle.sh`
2017-04-28 00:31:05 +03:00
#### Step17
2017-04-28 00:31:05 +03:00
Check to see if the puzzle and mongo services have been deployed.
2017-04-28 00:31:05 +03:00
`kubectl rollout status deployment/puzzle`
2017-04-28 00:31:05 +03:00
#### Step18
2017-04-28 00:31:05 +03:00
Bootstrap the kr8sswordz frontend web application. This script follows the same build proxy, push, and deploy steps that the other services followed.
2017-04-28 00:31:05 +03:00
`scripts/kr8sswordz-pages.sh`
2017-04-28 00:31:05 +03:00
#### Step19
2017-04-28 00:31:05 +03:00
Check to see if the frontend has been deployed.
`kubectl rollout status deployment/kr8sswordz`
2017-04-28 00:31:05 +03:00
#### Step20
2017-04-28 00:31:05 +03:00
Check out all the pods that are running.
`kubectl get pods`
2017-04-28 00:31:05 +03:00
#### Step21
Start the web application in your default browser. You may have to refresh your browser so that the puzzle appears properly.
2017-06-12 20:37:53 +03:00
`minikube service kr8sswordz`
2017-04-28 00:31:05 +03:00
2017-06-12 20:37:53 +03:00
## Part 4
2017-04-28 00:31:05 +03:00
#### Step1
Enter the following command to open the Jenkins UI in a web browser. Log in to Jenkins using the username and password you previously set up.
`minikube service jenkins`
#### Step2
Well want to create a new pipeline for the puzzle service that we previously deployed. On the left in Jenkins, click New Item.
`echo ''`
#### Step3
Enter the item name as "Puzzle-Service", click Pipeline, and click OK.
`echo ''`
#### Step4
Under the Build Triggers section, select Poll SCM. For the Schedule, enter the the string H/5 * * * * which will poll the Git repo every 5 minutes for changes.
`echo ''`
#### Step5
In the Pipeline section, change the Definition to "Pipeline script from SCM". Set the SCM property to GIT. Set the Repository URL to your forked repo (created in Part 2), such as https://github.com/[GIT USERNAME]/kubernetes-ci-cd.git. Set the Script Path to applications/puzzle/Jenkinsfile
`echo ''`
#### Step6
When you are finished, click Save. On the left, click Build Now to run the new pipeline. You should see it successfully run through the build, push, and deploy steps in a few minutes.
`echo ''`
#### Step7
View the Kr8sswordz application.
`minikube service kr8sswordz`
#### Step8
Spin up several instances of the puzzle service by moving the slider to the right and clicking Scale. For reference, click on the Submit button, noting that the green hit does not register on the puzzle services.
`echo ''`
#### Step9
Edit applications/puzzle/common/models/crossword.js in your favorite text editor (for example, you can use nano by running the command 'nano applications/puzzle/common/models/crossword.js' in a separate terminal). You'll see a commented section on lines 42-43 that indicates to uncomment a specific line. Uncomment line 43 by deleting the forward slashes and save the file.
2017-04-28 00:31:05 +03:00
`echo ''`
2017-04-28 00:31:05 +03:00
#### Step10
Commit and push the change to your forked Git repo.
`echo ''`
#### Step11
In Jenkins, open up the Puzzle-Service pipeline and wait until it triggers a build. It should trigger every 5 minutes.
`echo ''`
#### Step12
After it triggers, observe how the puzzle services disappear in the Kr8sswordz Puzzle app, and how new ones take their place.
`echo ''`
#### Step13
2017-04-28 00:31:05 +03:00
Try clicking Submit to test that hits now register as light green.
2017-04-04 01:48:19 +03:00
`echo ''`
## LICENSE
Copyright 2017 Kenzan, LLC <http://kenzan.com>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.