说明
- 本文介绍在kubernetes集群中如何安装hexo的方法,并且通过jenkins集成kubernetes的api,调用kubernetes集群实现自动化构建docker镜像并推送到dockerhub,最后通过argocd实现自动化部署。达到kubernetes+jenkins+argocd+github+docker的devops自动化。
- 本文的前置条件较多,需要有kubernetes集群,jenkins,argocd,dockerhub,github等基础知识,本文不做过多介绍。
- 本方法实现难度较高,需要有一定的kubernetes基础,和一点开发能力。
- 自用部署可以采取稍微简单一点的docker部署等方法,本文不做过多介绍。
1. hexo项目的相关文件与配置编写
1.1. dockerfile编写
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| FROM node:alpine
LABEL maintainer="gucat@gucat.cn"
ENV NODE_ENV=production
RUN npm config set registry https://registry.npmmirror.com
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories && \ apk --no-cache add tzdata && \ cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \ apk --no-cache del tzdata && \ mkdir /blog
RUN npm install hexo-cli -g
COPY ./blog /blog
RUN cd /blog && \ npm install --production
WORKDIR /blog
EXPOSE 4000
ENTRYPOINT ["hexo", "server"]
|
1.2. jenkinsfile简单版流水线编写
- 这部分的配置较多,需要将github和gitee的认证信息配置到jenkins中,这里不做过多介绍。
- 在kubernetes中构建镜像的方法比较多,如docker-in-docker/dind-rootless、Kubernetes IN Docker、Kaniko、BuildKit、Buildah、Img等架构,本文采用kaniko的方式进行构建。
- kaniko的构建方式比较特殊,需要提前在kubernetes集群中创建secret,将dockerhub的认证信息存储到secret中,然后在jenkinsfile中调用secret进行认证,最后进行构建。
- webhook的配置,我采用的是github的webhook通知jenkins,jenkins再调用kubernetes的api进行构建,这样的好处是可以在jenkins中进行更多的操作,比如构建前的检查,构建后的通知等。
- 拉取的代码从gitee拉取,为什么不从github拉取呢?因为github在国内访问速度太慢了,gitee的速度还可以。所以我做了不同仓库的镜像同步,代码推送到gitee后,会自动同步到github,然后github通知jenkins有push事件,jenkins再调用kubernetes的api创建需要的临时pod进行构建。
- 镜像构建完成后kaniko会自动推送到dockerhub。
- 最后argocd会自动从hub仓库拉取镜像部署到kubernetes集群中。
- argocd自动化需要准备好相关配置清单,这里不做过多介绍。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
|
def nodeSelector = 'jenkins-slave=master' def gitRepoUrl = 'https://gitee.com/qblyxs/gucat-official-website.git' def branch = 'master' def gitCredentialsId = 'gitee-auth-qblyxs' def imageName = 'qblyxs/gucat-web'
def imageTag = '1.0.1'
podTemplate( nodeSelector: "${nodeSelector}", containers: [ containerTemplate(name: 'kaniko', image: 'qblyxs/kaniko:v1.9.2-debug', command: 'sleep', args: '10d')], volumes: [ secretVolume(secretName: 'kaniko-secret', mountPath: '/kaniko/.docker/') ] ) { node(POD_LABEL) { stage('拉取代码') { git branch: "${branch}", credentialsId: "${gitCredentialsId}", url: "${gitRepoUrl}" } stage('使用kaniko构建镜像并推送DockerHub') { container('kaniko') { stage('Build a Container') { timeout(time:10, unit:'SECONDS') { echo '等待镜像准备中...'} sh "ls /kaniko/.docker/" sh "ls " sh "/kaniko/executor --context=. --destination=${imageName}:${imageTag}" } } } } }
|
- 关于工作镜像的制作,可以使用node镜像进行制作,缺点是node镜像比较大,构建时间比较长。
- 也可以使用nginx镜像进行制作,缺点是nginx配置稍微比较麻烦,需要自己准备
nginx.conf
配置文件,且坑比较多。
- 如果使用node镜像制作那么hexo的构建流程需要放到node镜像中,因为node镜像运行hexo server需要很多的node依赖。
- 如果使用nginx镜像制作那么hexo的构建流程可以直接在jenkins流水线中完成,因为nginx镜像只需要静态文件即可。
- jenkins流水线中构建node镜像的方法我写到了注释部分,有兴趣的可以自己尝试一下。jenkins构建完成后生成public目录,然后将public目录复制到nginx镜像中即可。
- 本文采用的node镜像制作工作镜像,所以我将hexo的源代码COPY到镜像中。
- 这个实现起来比较灵活,也可以通过k8s的volume挂载的方式将源代码挂载到镜像中,这样就可以实现源代码和镜像分离,方便后续的维护。
- 方法比较多,不一一列举,有兴趣的可以自己尝试一下。
1.3 完善好源代码
- 关于hexo的源代码建议放到一个目录中,例如
blog
目录。仓库根目录下只放一些必要的文件,例如Dockerfile
、Jenkinsfile
、nginx.conf
等关键文件。
- 将kubernetes部署的配置清单放到专门的
deploy
目录中,方便后续的维护和argocd的读取。
1.4 部署文件准备
1.4.1 namespace
1 2 3 4 5
| --- apiVersion: v1 kind: Namespace metadata: name: gucat
|
1.4.2 deployment
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| apiVersion: apps/v1 kind: Deployment metadata: name: gucat-web-deployment namespace: gucat spec: replicas: 1 selector: matchLabels: app: gucat-web template: metadata: labels: app: gucat-web spec: nodeSelector: memos: enable containers: - name: gucat-web image: qblyxs/gucat-web:1.0.1 imagePullPolicy: Always ports: - containerPort: 4000 ---
|
1.4.3 service
1 2 3 4 5 6 7 8 9 10 11 12 13
| apiVersion: v1 kind: Service metadata: name: gucat-web-service namespace: gucat spec: type: ClusterIP selector: app: gucat-web ports: - name: http port: 4000 targetPort: 4000
|
1.4.4 ingress
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: gucat.vip namespace: gucat spec: ingressClassName: nginx rules: - host: www.gucat.vip http: paths: - backend: service: name: gucat-web-service port: number: 4000 path: / pathType: Prefix - host: gucat.vip http: paths: - backend: service: name: gucat-web-service port: number: 4000 path: / pathType: Prefix
|
🎉🎉🎉至此,我们的部署文件已经准备好了,接下来我们就可以推送仓库进行构建部署了。
2. 推送仓库进行构建部署
2.1 推送仓库
- 将我们的源代码推送到仓库中,例如我这里使用的是
gitee
仓库,仓库地址为https://gitee.com/qblyxs/gucat-official-website.git
。
- 在gitee设置中设置好
仓库镜像管理
,将代码自动同步到github
仓库中,这样就可以实现github
和gitee
的代码同步。
- 在
github
仓库中设置好webhook
,代码自动同步后通知到jenkins
。
2.2 构建部署
- 在
jenkins
中新建一个pipeline
流水线项目,这里我使用的是多分支流水线
。将github
仓库的地址填写到源码管理
中。
pipeline
脚本中配置了gitee
的认证信息,这个信息需要提前在jenkins凭据
中设置好。
3. argocd配置项目
3.1 argocd配置项目
- 在
argocd
中新建一个application
应用,将github
仓库的地址填写到源码管理
中。也可以填写gitee
仓库的地址,因为github
和gitee
的代码是同步的。
SYNC POLICY
选择Automatic
自动同步,这样代码更新后会自动同步到argocd
中。
DESTINATION
中设置Cluster URL
为https://kubernetes.default.svc
。当然也可以部署到外部的k8s
集群中,只需要将Cluster URL
设置为外部集群的api-server
地址并配置好token
即可。Namespace
不用设置,因为我们deploy
清单中已经编写好了。
PROJECT
中设置PROJECT
为default
。PROJECT
是argocd
中的一个概念,可以理解为argocd
中的一个项目,可以将多个application
应用放到一个PROJECT
中。
SYNC OPTIONS
中可以设置Prune Resources
为true
。这样当我们删除application
应用时,argocd
会自动删除k8s
集群中的资源。
- 当然完成前三个步骤后,就可以了,其他的可以根据自己的需求进行设置。
4. 最后展示下我的流水线
argocd负责将服务部署到kubernetes集群中,并实时监控服务健康状态 使用Jenkins和ArgoCD实现Hexo项目自动化部署到Kubernetes K8S集群的完整教程