Jenkins-Pipeline-CI-CD-with-Helm-on-Kubernetes自动化流水线
因为忙于家里事情, 很久没有更新我的博客, 这里我将这半年多对Jenkins pipeline集成k8s实现自动化部署流水线的心得在这里分享给大家, 有不足之处, 还请大家多多指正.
这里简单的介绍一下我们这个自动化流水线所使用到的工具:
Jenkins Pipeline: 目前国内外DevOps, CI/CD比较主流的一种将我们软件开发周期所涉及到的环节通过pipeline流水线完美的串联在一起的自动化部署框架. 它提出了一种pipeline as a code的概念, 意在将我们的所有软件开发周期中涉及到的所有步骤(版本控制 - 代码检查 - 编译 - 单元测试 - 打包 - 测试环境部署 - 集成测试 - 功能测试 - 生产环境部署)通过代码的方式推送给我们的Jenkins进行pipeline自动化部署, 实现将我们的自动化流水线的配置代码化, 并同样实现版本控制.
目前Jenkins官方有两种pipeline的写法, 一种叫做Declarative Pipeline, 另外一种叫做Scripted Pipeline. 前者较为方便阅读, 适合初学者入门, 但相对对集成模块的兼容性以及pipeline逻辑编写的功能性较后者相对弱一些, 后者较为专业, 可以实现逻辑编写, 并支持很多主流集成模块, 推荐具有groovy脚本编写经验的人员使用.
具体内容详见: http://www.showerlee.com/archives/1972
Kubernetes: 目前这几年流行的一种容器化管理系统, 用于自动部署、扩展和管理容器化(containerized)应用程序的开源系统。它旨在提供“跨主机集群的自动部署、扩展以及运行应用程序容器的平台”。它支持一系列容器工具, 目前主流会使用Docker作为他的主流配置容器.使用它的原因也在于它将是目前DevOps领域的一个主流的Docker容器管理系统, 目前国内外很多公司都即将或者已经把自己的传统的虚拟机架构转向为Docker微服务架构, 这里我们非常有必要去学习如何基于k8s下去做自动化部署.
具体内容详见: http://www.showerlee.com/archives/2200
Helm: 这个应该算作k8s的一个功能性的工具, 它作为k8s的包管理工具, 非常方便的帮助我们整合k8s下零散的部署脚本为一个具体的项目包, 最终简化了Kubernetes部署应用的版本控制、打包、发布、删除、更新等操作.
具体内容详见: http://www.showerlee.com/archives/2455
这里本次自动化流水线实现的部署内容就是通过编写pipeline脚本, 将一个从Docker官方拿到的centos docker镜像容器, 进行二次安装配置, 打包为一个nignx静态网站容器, 发布到我们k8s下, 期间我们会对这个容器进行一些常规的功能测试, 从而模拟我们在k8s下实现自动化流水线交付的完整架构.
本次内容涉及到的代码可以参考我的github仓库:
https://github.com/showerlee/Jenkins-Pipeline-CI-CD-with-Helm-on-Kubernetes
Okay, Let's roll out...
安装环境
Local Desktop: MacOS
Virtual Machine: Virtual Box
Virtual System: CentOS 7.4
Jenkins: Jenkins 2.138
Kubernetes: Kubernetes 1.9
Docker: 17.03.2-ce
Helm: helm-v2.7.0
kube-master 10.110.16.14
kube-node-1 10.110.16.15
一. 系统环境配置
1.关闭SELINUX和firewall
# vi /etc/sysconfig/selinux
... SELINUX=disabled ...
# setenforce 0
# systemctl stop firewalld && systemctl disable firewalld
2.安装k8s环境.
http://www.showerlee.com/archives/2200
3.安装helm环境.
http://www.showerlee.com/archives/2455
4.安装Jenkins环境.
http://www.showerlee.com/archives/1880
二. Jenkins Pipeline配置
1.将jenkins用户添加到默认docker用户组下, 从而保证jenkins可以直接访问/var/run/docker.sock
# usermod -a -G docker jenkins
2.更改全局安全配置, 保证pipeline可以直接调用helm
进入Jenkins --> Manage Jenkins --> Configure Global Security
在Authorization下选择Project-based Matrix Authorization Strategy
配置Anonymous User具有Read Jenkins Jobs的权限
如图:
3.配置jenkins用户加载kubectl环境变量.
# mkdir -p /home/jenkins/.kube
# cp -i /etc/kubernetes/admin.conf /home/jenkins/.kube/config
# chown jenkins:jenkins /home/jenkins/.kube/config
4.配置github与dockerhub的Jenkins账户凭证, 后面pipeline对应模块需要调用.
5.创建pipeline任务
#!groovy def kubectlTest() { // Test that kubectl can correctly communication with the Kubernetes API echo "running kubectl test" sh "kubectl get nodes" } def helmLint(String chart_dir) { // lint helm chart sh "/usr/local/bin/helm lint ${chart_dir}" } def helmDeploy(Map args) { //configure helm client and confirm tiller process is installed if (args.dry_run) { println "Running dry-run deployment" sh "/usr/local/bin/helm upgrade --dry-run --debug --install ${args.name} ${args.chart_dir} --set ImageTag=${args.tag},Replicas=${args.replicas},Cpu=${args.cpu},Memory=${args.memory},DomainName=${args.name} --namespace=${args.name}" } else { println "Running deployment" sh "/usr/local/bin/helm upgrade --install ${args.name} ${args.chart_dir} --set ImageTag=${args.tag},Replicas=${args.replicas},Cpu=${args.cpu},Memory=${args.memory},DomainName=${args.name} --namespace=${args.name}" echo "Application ${args.name} successfully deployed. Use helm status ${args.name} to check" } } timeout(time: 2000, unit: 'SECONDS') { node { println "----------------------------------------------------------------------------" stage 'Check out pipeline from GitHub Repo' //git url: 'https://github.com/showerlee/Jenkins-Pipeline-CI-CD-with-Helm-on-Kubernetes.git' git branch: 'master', credentialsId: 'showerlee-github', url: 'https://github.com/showerlee/Jenkins-Pipeline-CI-CD-with-Helm-on-Kubernetes.git' // Setup the Docker Registry (Docker Hub) + Credentials registry_url = "https://index.docker.io/v1/" // Docker Hub docker_creds_id = "showerlee-dockerhub" // name of the Jenkins Credentials ID def pwd = pwd() def chart_dir = "${pwd}/charts/newegg-nginx" // Add build tag version Properties props = new Properties() File propsFile = new File("${pwd}/promote.properties") props.load(propsFile.newDataInputStream()) def build_tag_raw = props.getProperty('BUILD_TAG') float build_tag = Float.parseFloat(build_tag_raw)+0.1; println("Set current build_tag="+build_tag+" temporarily") //Set build_tag to index.html sh """ echo "<h1>Welcome Newegg Nginx Test Version: ${build_tag}</h1>" > index.html """ def inputFile = readFile('config.json') def config = new groovy.json.JsonSlurperClassic().parseText(inputFile) println "pipeline config ==> ${config}" println "----------------------------------------------------------------------------" stage 'Register DockerHub' echo "[INFO] Register Dockerhub" docker.withRegistry("${registry_url}", "${docker_creds_id}") { // Set up the container to build maintainer_name = "showerlee" container_name = "nginx-test" println "----------------------------------------------------------------------------" stage "Build Nginx Container" echo "[INFO] Building Nginx with docker.build(${maintainer_name}/${container_name}:${build_tag})" container = docker.build("${maintainer_name}/${container_name}:${build_tag}", '.') println "----------------------------------------------------------------------------" try { // Start Testing stage "Spin up Nginx Container" echo "[INFO] Spin up Nginx Container" // Run the container with the env file, mounted volumes and the ports: docker.image("${maintainer_name}/${container_name}:${build_tag}").withRun("--name=${container_name} -p 80:80 ") { c -> // wait for the django server to be ready for testing // the 'waitUntil' block needs to return true to stop waiting // in the future this will be handy to specify waiting for a max interval: // https://issues.jenkins-ci.org/browse/JENKINS-29037 // waitUntil { sh """ set +x ss -antup | grep :::80[^0-9] | grep LISTEN | wc -l | tr -d '\n' > /tmp/wait_results set -x """ wait_results = readFile '/tmp/wait_results' echo "[INFO] Wait Results(${wait_results})" if ("${wait_results}" == "1") { echo "[INFO] Nginx is listening on port 80" sh "rm -f /tmp/wait_results" return true } else { echo "[INFO] Nginx is not listening on port 80 yet" return false } } // end of waitUntil // At this point Nginx is running echo "[INFO] Docker Container is running" input 'You can check the running container on docker build server now! Click Proceed to next stage...' // this pipeline is using 3 tests // by setting it to more than 3 you can test the error handling and see the pipeline Stage View error message MAX_TESTS = 3 for (test_num = 1; test_num <= MAX_TESTS; test_num++) { println "----------------------------------------------------------------------------" echo "Running Test(${test_num})" expected_results = 0 if (test_num == 1 ) { // Test we can download the home page from the running docker container echo "[INFO] Check validation of home page" sh """ set +x docker exec -t ${container_name} curl -s http://localhost | grep Welcome | wc -l | tr -d '\n' > /tmp/test_results set -x """ expected_results = 1 } else if (test_num == 2) { // Test if port 80 is exposed echo "[INFO] Check if port 80 is exposed" sh """ set +x docker inspect --format '{{ (.NetworkSettings.Ports) }}' ${container_name} docker inspect --format '{{ (.NetworkSettings.Ports) }}' ${container_name} | grep map | grep '80/tcp:' | wc -l | tr -d '\n' > /tmp/test_results set -x """ expected_results = 1 } else if (test_num == 3) { // Test there's nothing established on the port since nginx is not running: echo "[INFO] Check if nothing established from nginx container" sh """ set +x docker exec -t ${container_name} ss -apn | grep 80 | grep ESTABLISHED | wc -l | tr -d '\n' > /tmp/test_results set -x """ expected_results = 0 } else { err_msg = "Missing Test(${test_num})" echo "[ERROR] ${err_msg}" currentBuild.result = 'FAILURE' error "Failed to finish container testing with Message(${err_msg})" } // Now validate the results match the expected results stage "Test(${test_num}) - Validate Results" test_results = readFile '/tmp/test_results' echo "[INFO] Test(${test_num}) Results($test_results) == Expected(${expected_results})" sh """ set +x if [ \"${test_results}\" != \"${expected_results}\" ]; then echo \" --------------------- Test(${test_num}) Failed--------------------\" echo \" - Test(${test_num}) Failed\" exit 1 else echo \" - Test(${test_num}) Passed\" exit 0 fi set -x """ echo "[INFO] Finished Running Test(${test_num})" // cleanup after the test run sh "rm -f /tmp/test_results" currentBuild.result = 'SUCCESS' } } } catch (Exception err) { err_msg = "Test had Exception(${err})" currentBuild.result = 'FAILURE' error "FAILED - Stopping build for Error(${err_msg})" } println "----------------------------------------------------------------------------" stage "Push to DockerHub" input 'Do you approve to push?' container.push() currentBuild.result = 'SUCCESS' println "----------------------------------------------------------------------------" stage "Push properties to git repo" echo "Push current build_tag="+build_tag+" to git repo" withCredentials([usernamePassword(credentialsId: 'showerlee-github', passwordVariable: 'GIT_PASSWORD', usernameVariable: 'GIT_USERNAME')]) { sh """ set +x git --version echo 'BUILD_TAG=${build_tag}' > ${pwd}/promote.properties git config --global user.email "showerlee@vip.qq.com" git config --global user.name "showerlee" git add ${pwd}/promote.properties ${pwd}/index.html git commit -m"Update docker tag to ${build_tag}" git push --set-upstream https://${GIT_USERNAME}:${GIT_PASSWORD}@github.com/showerlee/Jenkins-Pipeline-CI-CD-with-Helm-on-Kubernetes.git master set -x """ } println "----------------------------------------------------------------------------" } stage ('helm test') { echo "[INFO] Start helm test" // run helm chart linter echo "[INFO] Run helm chart linter" helmLint(chart_dir) // dry-run helm chart installation echo "[INFO] Dry-run helm chart installation" helmDeploy( dry_run : true, name : config.app.name, chart_dir : chart_dir, tag : build_tag, replicas : config.app.replicas, cpu : config.app.cpu, memory : config.app.memory ) println "----------------------------------------------------------------------------" } stage ('helm deploy') { input 'Do you approve to deploy?' echo "[INFO] Start helm deployment" // Deploy using Helm chart helmDeploy( dry_run : false, name : config.app.name, chart_dir : chart_dir, tag : build_tag, replicas : config.app.replicas, cpu : config.app.cpu, memory : config.app.memory ) echo "[INFO] Deployment Finished..." } /////////////////////////////////////// // // Coming Soon Feature Enhancements // // 1. Add Docker Compose testing as a new Pipeline item that is initiated after this one for "Integration" testing // 2. Make sure to set the Pipeline's "Throttle builds" to 1 because the docker containers will collide on resources like ports and names // 3. Should be able to parallelize the docker.withRegistry() methods to ensure the container is running on the slave // 4. After the tests finish (and before they start), clean up container images to prevent stale docker image builds from affecting the current test run } }
6.执行pipeline任务构建
Started by user admin Obtained Jenkinsfile from git https://github.com/showerlee/Jenkins-Pipeline-CI-CD-with-Helm-on-Kubernetes.git [Pipeline] timeout Timeout set to expire in 33 min [Pipeline] { [Pipeline] node Running on Jenkins in /var/jenkins_home/workspace/kube-helm-pipeline@2 [Pipeline] { [Pipeline] echo ---------------------------------------------------------------------------- [Pipeline] stage (Check out pipeline from GitHub Repo) Using the ‘stage’ step without a block argument is deprecated Entering stage Check out pipeline from GitHub Repo Proceeding [Pipeline] git > git rev-parse --is-inside-work-tree # timeout=10 Fetching changes from the remote Git repository > git config remote.origin.url https://github.com/showerlee/Jenkins-Pipeline-CI-CD-with-Helm-on-Kubernetes.git # timeout=10 Fetching upstream changes from https://github.com/showerlee/Jenkins-Pipeline-CI-CD-with-Helm-on-Kubernetes.git > git --version # timeout=10 using GIT_ASKPASS to set credentials github credential > git fetch --tags --progress https://github.com/showerlee/Jenkins-Pipeline-CI-CD-with-Helm-on-Kubernetes.git +refs/heads/*:refs/remotes/origin/* > git rev-parse refs/remotes/origin/master^{commit} # timeout=10 > git rev-parse refs/remotes/origin/origin/master^{commit} # timeout=10 Checking out Revision ce4fc2593333f3ed89cd5654966919b0aa97628d (refs/remotes/origin/master) > git config core.sparsecheckout # timeout=10 > git checkout -f ce4fc2593333f3ed89cd5654966919b0aa97628d > git branch -a -v --no-abbrev # timeout=10 > git branch -D master # timeout=10 > git checkout -b master ce4fc2593333f3ed89cd5654966919b0aa97628d Commit message: "Update docker tag to 1.5" > git rev-list --no-walk ce4fc2593333f3ed89cd5654966919b0aa97628d # timeout=10 [Pipeline] pwd [Pipeline] echo Set current build_tag=1.6 temporarily [Pipeline] sh [kube-helm-pipeline@2] Running shell script + echo '<h1>Welcome Newegg Nginx Test Version: 1.6</h1>' [Pipeline] readFile [Pipeline] echo pipeline config ==> [app:[memory:128Mi, replicas:3, name:newegg-nginx, cpu:10m], pipeline:[library:[branch:master], enabled:true]] [Pipeline] echo ---------------------------------------------------------------------------- [Pipeline] stage (Register DockerHub) Using the ‘stage’ step without a block argument is deprecated Entering stage Register DockerHub Proceeding [Pipeline] echo [INFO] Register Dockerhub [Pipeline] withEnv [Pipeline] { [Pipeline] withDockerRegistry $ docker login -u showerlee -p ******** https://index.docker.io/v1/ Login Succeeded [Pipeline] { [Pipeline] echo ---------------------------------------------------------------------------- [Pipeline] stage (Build Nginx Container) Using the ‘stage’ step without a block argument is deprecated Entering stage Build Nginx Container Proceeding [Pipeline] echo [INFO] Building Nginx with docker.build(showerlee/nginx-test:1.6) [Pipeline] sh [kube-helm-pipeline@2] Running shell script + docker build -t showerlee/nginx-test:1.6 . Sending build context to Docker daemon 2.164 MB Step 1/6 : FROM centos:centos7 ---> 5182e96772bf Step 2/6 : MAINTAINER showerlee ---> Using cache ---> cc77ae5c175a Step 3/6 : RUN yum -y update && yum clean all && yum install -y epel-release && yum install -y nginx iproute ---> Using cache ---> 2c718c146ba5 Step 4/6 : EXPOSE 80 ---> Using cache ---> 829b29a719e6 Step 5/6 : COPY index.html /usr/share/nginx/html/ ---> Using cache ---> 22e805b84cee Step 6/6 : CMD nginx -g daemon off; ---> Using cache ---> de02105d9033 Successfully built de02105d9033 [Pipeline] dockerFingerprintFrom [Pipeline] echo ---------------------------------------------------------------------------- [Pipeline] stage (Spin up Nginx Container) Using the ‘stage’ step without a block argument is deprecated Entering stage Spin up Nginx Container Proceeding [Pipeline] echo [INFO] Spin up Nginx Container [Pipeline] sh [kube-helm-pipeline@2] Running shell script + docker run -d --name=nginx-test -p 80:80 showerlee/nginx-test:1.6 [Pipeline] dockerFingerprintRun [Pipeline] waitUntil [Pipeline] { [Pipeline] sh [kube-helm-pipeline@2] Running shell script + set +x [Pipeline] readFile [Pipeline] echo [INFO] Wait Results(1) [Pipeline] echo [INFO] Nginx is listening on port 80 [Pipeline] sh [kube-helm-pipeline@2] Running shell script + rm -f /tmp/wait_results [Pipeline] } [Pipeline] // waitUntil [Pipeline] echo [INFO] Docker Container is running [Pipeline] input You can check the running container on docker build server now! Click Proceed to next stage... Proceed or Abort Approved by admin [Pipeline] echo ---------------------------------------------------------------------------- [Pipeline] echo Running Test(1) [Pipeline] echo [INFO] Check validation of home page [Pipeline] sh [kube-helm-pipeline@2] Running shell script + set +x [Pipeline] stage (Test(1) - Validate Results) Using the ‘stage’ step without a block argument is deprecated Entering stage Test(1) - Validate Results Proceeding [Pipeline] readFile [Pipeline] echo [INFO] Test(1) Results(1) == Expected(1) [Pipeline] sh [kube-helm-pipeline@2] Running shell script + set +x - Test(1) Passed [Pipeline] echo [INFO] Finished Running Test(1) [Pipeline] sh [kube-helm-pipeline@2] Running shell script + rm -f /tmp/test_results [Pipeline] echo ---------------------------------------------------------------------------- [Pipeline] echo Running Test(2) [Pipeline] echo [INFO] Check if port 80 is exposed [Pipeline] sh [kube-helm-pipeline@2] Running shell script + set +x map[80/tcp:[{0.0.0.0 80}]] [Pipeline] stage (Test(2) - Validate Results) Using the ‘stage’ step without a block argument is deprecated Entering stage Test(2) - Validate Results Proceeding [Pipeline] readFile [Pipeline] echo [INFO] Test(2) Results(1) == Expected(1) [Pipeline] sh [kube-helm-pipeline@2] Running shell script + set +x - Test(2) Passed [Pipeline] echo [INFO] Finished Running Test(2) [Pipeline] sh [kube-helm-pipeline@2] Running shell script + rm -f /tmp/test_results [Pipeline] echo ---------------------------------------------------------------------------- [Pipeline] echo Running Test(3) [Pipeline] echo [INFO] Check if nothing established from nginx container [Pipeline] sh [kube-helm-pipeline@2] Running shell script + set +x [Pipeline] stage (Test(3) - Validate Results) Using the ‘stage’ step without a block argument is deprecated Entering stage Test(3) - Validate Results Proceeding [Pipeline] readFile [Pipeline] echo [INFO] Test(3) Results(0) == Expected(0) [Pipeline] sh [kube-helm-pipeline@2] Running shell script + set +x - Test(3) Passed [Pipeline] echo [INFO] Finished Running Test(3) [Pipeline] sh [kube-helm-pipeline@2] Running shell script + rm -f /tmp/test_results [Pipeline] sh [kube-helm-pipeline@2] Running shell script + docker stop 05a19a7c8519a04cc03029d7273a8e2ae3363e74a03b6d4167dfbec0bf6ee978 05a19a7c8519a04cc03029d7273a8e2ae3363e74a03b6d4167dfbec0bf6ee978 + docker rm -f 05a19a7c8519a04cc03029d7273a8e2ae3363e74a03b6d4167dfbec0bf6ee978 05a19a7c8519a04cc03029d7273a8e2ae3363e74a03b6d4167dfbec0bf6ee978 [Pipeline] echo ---------------------------------------------------------------------------- [Pipeline] stage (Push to DockerHub) Using the ‘stage’ step without a block argument is deprecated Entering stage Push to DockerHub Proceeding [Pipeline] input Do you approve to push? Proceed or Abort Approved by admin [Pipeline] sh [kube-helm-pipeline@2] Running shell script + docker tag showerlee/nginx-test:1.6 index.docker.io/showerlee/nginx-test:1.6 [Pipeline] sh [kube-helm-pipeline@2] Running shell script + docker push index.docker.io/showerlee/nginx-test:1.6 The push refers to a repository [docker.io/showerlee/nginx-test] aedd55edeb74: Preparing 85e9d4859663: Preparing 1d31b5806ba4: Preparing 85e9d4859663: Layer already exists 1d31b5806ba4: Layer already exists aedd55edeb74: Retrying in 5 seconds aedd55edeb74: Retrying in 4 seconds aedd55edeb74: Retrying in 3 seconds aedd55edeb74: Retrying in 2 seconds aedd55edeb74: Retrying in 1 second aedd55edeb74: Pushed 1.6: digest: sha256:8ee214129c880a0d759837daf30c31772797fa6709f11edd9e30db6891710de4 size: 948 [Pipeline] echo ---------------------------------------------------------------------------- [Pipeline] stage (Push properties to git repo) Using the ‘stage’ step without a block argument is deprecated Entering stage Push properties to git repo Proceeding [Pipeline] echo Push current build_tag=1.6 to git repo [Pipeline] withCredentials [Pipeline] { [Pipeline] sh [kube-helm-pipeline@2] Running shell script + set +x git version 1.8.3.1 [master cdbb62c] Update docker tag to 1.6 2 files changed, 2 insertions(+), 2 deletions(-) To https://****:****@github.com/****/Jenkins-Pipeline-CI-CD-with-Helm-on-Kubernetes.git ce4fc25..cdbb62c master -> master Branch master set up to track remote branch master from https://****:****@github.com/****/Jenkins-Pipeline-CI-CD-with-Helm-on-Kubernetes.git. [Pipeline] } [Pipeline] // withCredentials [Pipeline] echo ---------------------------------------------------------------------------- [Pipeline] } [Pipeline] // withDockerRegistry [Pipeline] } [Pipeline] // withEnv [Pipeline] stage [Pipeline] { (helm test) [Pipeline] echo [INFO] Start helm test [Pipeline] echo [INFO] Run helm chart linter [Pipeline] sh [kube-helm-pipeline@2] Running shell script + /usr/local/bin/helm lint /var/jenkins_home/workspace/kube-helm-pipeline@2/charts/newegg-nginx ==> Linting /var/jenkins_home/workspace/kube-helm-pipeline@2/charts/newegg-nginx [INFO] Chart.yaml: icon is recommended 1 chart(s) linted, no failures [Pipeline] echo [INFO] Dry-run helm chart installation [Pipeline] echo Running dry-run deployment [Pipeline] sh [kube-helm-pipeline@2] Running shell script + /usr/local/bin/helm upgrade --dry-run --debug --install newegg-nginx /var/jenkins_home/workspace/kube-helm-pipeline@2/charts/newegg-nginx --set ImageTag=1.6,Replicas=3,Cpu=10m,Memory=128Mi,DomainName=newegg-nginx --namespace=newegg-nginx [debug] Created tunnel using local port: '39460' [debug] SERVER: "localhost:39460" Release "newegg-nginx" does not exist. Installing it now. [debug] CHART PATH: /var/jenkins_home/workspace/kube-helm-pipeline@2/charts/newegg-nginx NAME: newegg-nginx REVISION: 1 RELEASED: Sun Aug 26 01:38:02 2018 CHART: newegg-nginx-1.0.0 USER-SUPPLIED VALUES: Cpu: 10m DomainName: newegg-nginx ImageTag: "1.6" Memory: 128Mi Replicas: 3 COMPUTED VALUES: ContainerPort: 80 Cpu: 10m DomainName: newegg-nginx Image: showerlee/nginx-test ImagePullPolicy: Always ImageTag: "1.6" Imagetag: latest Memory: 128Mi Replicas: 3 ServicePort: 80 ServiceType: NodePort HOOKS: MANIFEST: --- # Source: newegg-nginx/templates/service.yaml apiVersion: v1 kind: Service metadata: name: newegg-nginx-newegg-nginx labels: app: newegg-nginx-newegg-nginx version: 1.0.0 release: newegg-nginx spec: type: "NodePort" ports: - port: 80 targetPort: 80 protocol: TCP selector: app: newegg-nginx-newegg-nginx --- # Source: newegg-nginx/templates/deployment.yaml apiVersion: extensions/v1beta1 kind: Deployment metadata: name: newegg-nginx-newegg-nginx labels: app: newegg-nginx-newegg-nginx version: 1.0.0 release: newegg-nginx spec: replicas: 3 template: metadata: labels: app: newegg-nginx-newegg-nginx version: 1.0.0 release: newegg-nginx spec: containers: - name: newegg-nginx image: "showerlee/nginx-test:1.6" imagePullPolicy: "Always" ports: - containerPort: 80 protocol: TCP resources: requests: cpu: "10m" memory: "128Mi" --- # Source: newegg-nginx/templates/ingress.yaml apiVersion: extensions/v1beta1 kind: Ingress metadata: name: newegg-nginx-newegg-nginx labels: app: newegg-nginx-newegg-nginx version: 1.0.0 release: newegg-nginx spec: rules: - host: newegg-nginx.buyabs.corp http: paths: - path: / backend: serviceName: newegg-nginx-newegg-nginx servicePort: 80 [Pipeline] echo ---------------------------------------------------------------------------- [Pipeline] } [Pipeline] // stage [Pipeline] stage [Pipeline] { (helm deploy) [Pipeline] input Do you approve to deploy? Proceed or Abort Approved by admin [Pipeline] echo [INFO] Start helm deployment [Pipeline] echo Running deployment [Pipeline] sh [kube-helm-pipeline@2] Running shell script + /usr/local/bin/helm upgrade --install newegg-nginx /var/jenkins_home/workspace/kube-helm-pipeline@2/charts/newegg-nginx --set ImageTag=1.6,Replicas=3,Cpu=10m,Memory=128Mi,DomainName=newegg-nginx --namespace=newegg-nginx Release "newegg-nginx" does not exist. Installing it now. NAME: newegg-nginx LAST DEPLOYED: Sun Aug 26 01:38:24 2018 NAMESPACE: newegg-nginx STATUS: DEPLOYED RESOURCES: ==> v1beta1/Ingress NAME HOSTS ADDRESS PORTS AGE newegg-nginx-newegg-nginx newegg-nginx.buyabs.corp 80 1m ==> v1/Pod(related) NAME READY STATUS RESTARTS AGE newegg-nginx-newegg-nginx-56c478c888-6n6rt 0/1 ContainerCreating 0 1m newegg-nginx-newegg-nginx-56c478c888-hsbcp 0/1 ContainerCreating 0 1m newegg-nginx-newegg-nginx-56c478c888-vdfgb 0/1 ContainerCreating 0 1m ==> v1/Service NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE newegg-nginx-newegg-nginx NodePort 10.97.200.124 <none> 80:32239/TCP 1m ==> v1beta1/Deployment NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE newegg-nginx-newegg-nginx 3 3 3 0 1m [Pipeline] echo Application newegg-nginx successfully deployed. Use helm status newegg-nginx to check [Pipeline] echo [INFO] Deployment Finished... [Pipeline] } [Pipeline] // stage [Pipeline] } [Pipeline] // node [Pipeline] } [Pipeline] // timeout [Pipeline] End of Pipeline Finished: SUCCESS
7.验证结果
这样我们就成功的利用Jenkins集成k8s+helm实现将我们的静态网站部署到我们的kubernetes集群中.
大功告成...
本文链接:http://www.showerlee.com/archives/2661
继续浏览:
hi。
helm 用于pod 里面部署服务, 1. helm 必须用 helm init 吗
2. 离线pod里面好像报错,
请问你是怎么解决的呀?
1. helmLnit用来进行部署前代码测试, 不使用不会影响部署.
2.具体要看你的报错信息是啥.