在容器上构建持续部署,这份超详细实践指南不要错过!


作者 |?倚天码农
责编?|?刘静
出品 |?CSDN 博客


源代码库:负责存储源代码,常用的有Git和SVN;
持续集成与部署工具:负责自动编译和打包以及把可运行程序存储到可运行库。比较流行的有Jenkins,GitLab,Travis CI,CircleCI 等;
库管理器(Repository Manager):也就是图中的Repository,我们又叫运行库,负责管理程序组件。最常用的是Nexus。它是一个私有库,它的作用是管理程序组件。
管理第三方库:应用程序常常要用到很多第三方库,并且不同的技术栈需要的库不同,它们经常是存放在第三方公共库里,管理起来不是很方便。一般公司会建立一个私有管理库,来集中统一管理各种第三方软件,例如它既可以做为Maven库(Java),也可以做为镜像库(Docker),还可以做为NPM库(JavaScript),来保证公司软件的规范性;
管理内部程序的交付:所有公司在各种环境(例如DEV,QA,UAT, PROD)发布的程序都由它来管理,并赋予统一的版本号,这样任何交付都有据可查,同时便利于程序回滚。

下载源码:从源代码库(例如github)中下载源代码;
编译代码:编译语言都需要有这一步;
测试:对程序进行测试;
生成镜像:这里包含两个步骤,一个是创建镜像,另一个是存储镜像到镜像库;
部署镜像:把生成的镜像部署到容器上。

下载源码:从github下载源代码到Jenkins的运行环境;
测试:这一步暂时没有实际内容;
生成镜像:创建镜像,并上传到Docker hub;
部署镜像:将生成的镜像部署到k8s。

FROM?jenkins/jenkins:lts
USER?root
ENV?DOCKERVERSION=19.03.4
RUN?curl?-fsSLO?https://download.docker.com/linux/static/stable/x86_64/docker-${DOCKERVERSION}.tgz?\
??&&?tar?xzvf?docker-${DOCKERVERSION}.tgz?--strip?1?\
?????????????????-C?/usr/local/bin?docker/docker?\
??&&?rm?docker-${DOCKERVERSION}.tgz
RUN?curl?-LO?https://storage.googleapis.com/kubernetes-release/release/$(curl?-s?https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl?\
????&&?chmod??x?./kubectl?\
????&&?mv?./kubectl?/usr/local/bin/kubectl
vagrant@ubuntu-xenial:/$?docker?version

如果你不熟悉安装和创建Jenkins项目,请参阅在k8s上安装Jenkins及常见问题
def?POD_LABEL?=?"k8sdemopod-${UUID.randomUUID().toString()}"
podTemplate(label:?POD_LABEL,?cloud:?'kubernetes',?containers:?[
????containerTemplate(name:?'modified-jenkins',?image:?'jfeng45/modified-jenkins:1.0',?ttyEnabled:?true,?command:?'cat')
??],
??volumes:?[
?????hostPathVolume(mountPath:?'/var/run/docker.sock',?hostPath:?'/var/run/docker.sock')
??])?{
????node(POD_LABEL)?{
???????def?kubBackendDirectory?=?"/script/kubernetes/backend"
???????stage('Checkout')?{
????????????container('modified-jenkins')?{
????????????????sh?'echo?get?source?from?github'
????????????????git?'https://github.com/jfeng45/k8sdemo'
????????????}
??????????}
???????stage('Build?image')?{
????????????def?imageName?=?"jfeng45/jenkins-k8sdemo:${env.BUILD_NUMBER}"
????????????def?dockerDirectory?=?"${kubBackendDirectory}/docker/Dockerfile-k8sdemo-backend"
?????????????container('modified-jenkins')?{
???????????????withCredentials([[$class:?'UsernamePasswordMultiBinding',
?????????????????credentialsId:?'dockerhub',
?????????????????usernameVariable:?'DOCKER_HUB_USER',
?????????????????passwordVariable:?'DOCKER_HUB_PASSWORD']])?{
?????????????????sh?"""
???????????????????docker?login?-u?${DOCKER_HUB_USER}?-p?${DOCKER_HUB_PASSWORD}
???????????????????docker?build?-f?${WORKSPACE}${dockerDirectory}?-t?${imageName}?.
???????????????????docker?push?${imageName}
???????????????????"""
???????????????}
?????????????}
???????????}
???????stage('Deploy')?{
???????????container('modified-jenkins')?{
???????????????sh?"kubectl?apply?-f?${WORKSPACE}${kubBackendDirectory}/backend-deployment.yaml"
???????????????sh?"kubectl?apply?-f?${WORKSPACE}${kubBackendDirectory}/backend-service.yaml"
?????????????}
???????}
????}
}
podTemplate(label:?POD_LABEL,?cloud:?'kubernetes',?containers:?[
????containerTemplate(name:?'modified-jenkins',?image:?'jfeng45/modified-jenkins:1.0',?ttyEnabled:?true,?command:?'cat')
??],
??volumes:?[
?????hostPathVolume(mountPath:?'/var/run/docker.sock',?hostPath:?'/var/run/docker.sock')
??])
stage('Build?image')?{
????????????def?imageName?=?"jfeng45/jenkins-k8sdemo:${env.BUILD_NUMBER}"
????????????def?dockerDirectory?=?"${kubBackendDirectory}/docker/Dockerfile-k8sdemo-backend"
?????????????container('modified-jenkins')?{
???????????????withCredentials([[$class:?'UsernamePasswordMultiBinding',
?????????????????credentialsId:?'dockerhub',
?????????????????usernameVariable:?'DOCKER_HUB_USER',
?????????????????passwordVariable:?'DOCKER_HUB_PASSWORD']])?{
?????????????????sh?"""
???????????????????docker?login?-u?${DOCKER_HUB_USER}?-p?${DOCKER_HUB_PASSWORD}
???????????????????docker?build?-f?${WORKSPACE}${dockerDirectory}?-t?${imageName}?.
???????????????????docker?push?${imageName}
???????????????????"""
???????????????}
?????????????}
???????????}
#?vagrant@ubuntu-xenial:~/app/k8sdemo/script/kubernetes/backend$
#?docker?build?-t?k8sdemo-backend?.
FROM?golang:latest?as?builder
#?Set?the?Current?Working?Directory?inside?the?container
WORKDIR?/app
COPY?go.mod?go.sum?./
RUN?go?mod?download
COPY?.?.
WORKDIR?/app/cmd
#?Build?the?Go?app
#RUN?CGO_ENABLED=0?GOOS=linux?go?build?-a?-installsuffix?cgo?-o?main.exe
RUN?go?build?-o?main.exe
########?Start?a?new?stage?from?scratch?#######
FROM?alpine:latest
RUN?apk?--no-cache?add?ca-certificates
WORKDIR?/root/
RUN?mkdir?/lib64?&&?ln?-s?/lib/libc.musl-x86_64.so.1?/lib64/ld-linux-x86-64.so.2
#?Copy?the?Pre-built?binary?file?from?the?previous?stage
COPY?--from=builder?/app/cmd/main.exe?.
#?Command?to?run?the?executable
#?CMD?exec?/bin/bash?-c?"trap?:?TERM?INT;?sleep?infinity?&?wait"
CMD?
关于Go镜像文件详情,请参阅创建优化的Go镜像文件以及踩过的坑
?stage('Deploy')?{
???????????container('modified-jenkins')?{
???????????????sh?"kubectl?apply?-f?${WORKSPACE}${kubBackendDirectory}/backend-deployment.yaml"
???????????????sh?"kubectl?apply?-f?${WORKSPACE}${kubBackendDirectory}/backend-service.yaml"
?????????????}
???????}
关于k8s的部署和服务配置文件详情,请参阅把应用程序迁移到k8s需要修改什么?
。。。
??kubectl?apply?-f?/home/jenkins/workspace/test1/script/kubernetes/backend/backend-deployment.yaml
deployment.apps/k8sdemo-backend-deployment?created
[Pipeline]?sh??kubectl?apply?-f?/home/jenkins/workspace/test1/script/kubernetes/backend/backend-service.yaml
service/k8sdemo-backend-service?created
[Pipeline]?}
[Pipeline]?//?container
[Pipeline]?}
[Pipeline]?//?stage
[Pipeline]?}
[Pipeline]?//?node
[Pipeline]?}
[Pipeline]?//?podTemplate
[Pipeline]?End?of?Pipeline
Finished:?SUCCESS
?stage('Deploy')?{
???????????container('modified-jenkins')?{
???????????????sh?"kubectl?apply?-f?${WORKSPACE}${kubBackendDirectory}/backend-deployment.yaml"
???????????????sh?"kubectl?apply?-f?${WORKSPACE}${kubBackendDirectory}/backend-service.yaml"
?????????????}
???????}
查看运行结果:
vagrant@ubuntu-xenial:/home$?kubectl?get?pod
NAME???????????????????????????????????????????READY???STATUS????RESTARTS???AGE
envar-demo?????????????????????????????????????1/1?????Running???15?????????32d
k8sdemo-backend-deployment-6b99dc6b8c-8kxt9????1/1?????Running???0??????????50s
k8sdemo-database-deployment-578fc88c88-mm6x8???1/1?????Running???9??????????20d
k8sdemo-jenkins-deployment-675dd574cb-r57sb????1/1?????Running???0??????????2d23h
登录Pod并运行程序:
vagrant@ubuntu-xenial:/home$?kubectl?exec?-ti?k8sdemo-backend-deployment-6b99dc6b8c-8kxt9?--?/bin/sh
~?#?./main.exe
DEBU[0000]?connect?to?database
DEBU[0000]?dataSourceName:dbuser:dbuser@tcp(k8sdemo-database-service:3306)/service_config?charset=utf8
DEBU[0000]?FindAll()
DEBU[0000]?created=2019-10-21
DEBU[0000]?find?user:{1?Tony?IT?2019-10-21}
DEBU[0000]?find?user?list:[{1?Tony?IT?2019-10-21}]
DEBU[0000]?user?lst:[{1?Tony?IT?2019-10-21}]
结果正确。

为什么我不能用Bash?
因为你使用的子节点的容器可能使用的是精简版的Linux,例如Alpine,它是没有Bash的。 为什么我不能运行Docker命令或Kubectl?
app?=?docker.build("jfeng45/jenkins-k8sdemo")
stage('Create?Docker?images')?{
??container('docker')?{
??????app?=?docker.build("jfeng45/codedemo",?"-f?${WORKSPACE}/script/kubernetes/backend/docker/Dockerfile-k8sdemo-test?.")
??????docker.withRegistry('',?'dockerhub')?{
??????????//?Push?image?and?tag?it?with?our?build?number?for?versioning?purposes.
??????????app.push("${env.BUILD_NUMBER}")
??????}
????}
??}
stage('Create?a?d?ocker?image')?{
?????def?imageName?=?"jfeng45/codedemo:${env.BUILD_NUMBER}"
?????def?dockerDirectory?=?"${kubBackendDirectory}/docker/Dockerfile-k8sdemo-backend"
??????container('modified-jenkins')?{
????????withCredentials([[$class:?'UsernamePasswordMultiBinding',
??????????credentialsId:?'dockerhub',
??????????usernameVariable:?'DOCKER_HUB_USER',
??????????passwordVariable:?'DOCKER_HUB_PASSWORD']])?{
??????????sh?"""
????????????docker?login?-u?${DOCKER_HUB_USER}?-p?${DOCKER_HUB_PASSWORD}
????????????docker?build?-f?${WORKSPACE}${dockerDirectory}?-t?${imageName}?.
????????????docker?push?${imageName}
????????????"""
????????}
??????}
????}

sh?"kubectl?apply?-f?${WORKSPACE}${kubBackendDirectory}/backend-deployment.yaml"
sh?'kubectl?apply?-f?${WORKSPACE}${kubBackendDirectory}/backend-deployment.yaml'
??docker?inspect?-f?.?k8sdemo-backend:latest
/var/jenkins_home/workspace/k8sdec@2@tmp/durable-01e26997/script.sh:?1:?????/var/jenkins_home/workspace/k8sdec@2@tmp/durable-01e26997/script.sh:?docker:?????not?found
Vagrant.configure(2)?do?|config|
?????。。。
?????config.vm.box?=?"ubuntu/xenial64"
?????config.disksize.size?=?'16GB'
?????。。。
end




更多精彩推荐
?滴滴 AI Labs 负责人叶杰平因个人原因即将离职!CTO 张博接任
?TIOBE 9 月编程语言:C++ 突起、Java 流行度下降
?被劝退的学渣,逆袭成高级语言之父,改变编程方式却说“不喜欢写代码”!
?总计2171个BTC被盗,这个钱包漏洞的受害者越来越多
点分享 点点赞 点在看
关注公众号:拾黑(shiheibook)了解更多
[广告]赞助链接:
四季很好,只要有你,文娱排行榜:https://www.yaopaiming.com/
让资讯触达的更精准有趣:https://www.0xu.cn/
关注网络尖刀微信公众号随时掌握互联网精彩
- 1 锚定推动高质量发展这个主题 7904375
- 2 国台办回应韩国标示“中国台湾” 7809187
- 3 警方通报“小鹏汽车车展不雅视频” 7712939
- 4 中国时速350公里高铁最长隧道贯通 7619042
- 5 大疆回应多地无人机黑飞至8000米 7519614
- 6 西班牙女员工连续提前到岗被开除 7427423
- 7 央视马年春晚官宣 7333449
- 8 片仔癀4年跌60% 投资大佬仍一股不卖 7235726
- 9 中俄联合巡航引日方担忧 国防部回应 7136803
- 10 制器之器!厉害了工业母机 7042601










CSDN
