0、前言

如果还不知道kubernetes下如何实现jenkins slave可以参考我的另一个博文Kubernetes Jenkins动态创建Slave

1、Go服务构建

我们需要通过自定义镜像底包,能够让该底包拥有启动go程序的基本功能和日志重定向输出到指定目录下,方便日志收集,编辑完相关文件后,我们需要通过docker命令去构建镜像,构建完毕后将其推送到harbor base仓库,该名为base的仓库需要手动去harbor上创建。

1.1、制作Go服务镜像底包

1.编写Dockerfile以及相关的启动脚本

  • Dcokerfile
  1. FROM alpine
  2. USER root
  3. RUN apk add tzdata && /bin/cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime &&\
  4. echo 'Asia/Shanghai' >/etc/timezone &&\
  5. mkdir /opt/logs
  6. WORKDIR /opt/project_dir/
  7. ADD entrypoint.sh /entrypoint.sh
  8. CMD ["/entrypoint.sh"]
  • entrypoint.sh
  1. #!/bin/sh
  2. APP_NAME=${APP_NAME:-"app"}
  3. exec ${APP_NAME} >> /opt/logs/stdout.log 2>&1

APP_NAME:启动的二进制文件名,这个可以手动传入或者默认为名为app

2.构建镜像并上传到harbor仓库

  1. $ docker build ./ -t harbor.od.com/base/go-run:1.14.2-1
  2. Sending build context to Docker daemon 3.072kB
  3. Step 1/6 : FROM alpine
  4. ---> a187dde48cd2
  5. Step 2/6 : USER root
  6. ---> Using cache
  7. ---> f0673624a0e0
  8. Step 3/6 : RUN apk add tzdata && /bin/cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' >/etc/timezone && mkdir /opt/logs
  9. ---> Using cache
  10. ---> e91f2e8a4919
  11. Step 4/6 : WORKDIR /opt/project_dir/
  12. ---> Using cache
  13. ---> 6afa8e9ddd43
  14. Step 5/6 : ADD entrypoint.sh /entrypoint.sh
  15. ---> Using cache
  16. ---> 7a7efe533a5f
  17. Step 6/6 : CMD ["/entrypoint.sh"]
  18. ---> Using cache
  19. ---> 17d85fd60af3
  20. Successfully built 17d85fd60af3
  21. Successfully tagged harbor.od.com/base/go-run:1.14.2-1
  22. $ docker push harbor.od.com/base/go-run:1.14.2-1
  23. The push refers to repository [harbor.od.com/base/go-run]
  24. 20c042b1ca31: Mounted from base/go-test
  25. 98e20bd596b3: Mounted from base/go-test
  26. f4ee0579d5d8: Mounted from base/go-test
  27. beee9f30bc1f: Mounted from base/go-test
  28. 1.14.2-1: digest: sha256:49dda47c11a3148fdfd60fe4850ada128e6550fb33c1a6284caadf0e6ea8016d size: 1153

1.2、制作slave基础镜像底包

我们是基于jenkins slave方式去构建项目,并且使用pipeline来实现流程化,我们都知道slave运行的是一个pod,那么pod里可以有多个容器,而这些一个一个的容器就是执行我们对应操作的环境,所以我们需要通过制作一些镜像来满足我们的需求。

镜像需求:

1、编译golang应用:golang:v1.14.2

2、打包镜像并推送到harbor:

1.2.1、Golang镜像

该镜像主要用于构建golang应用,我们是在基于golang v1.14.2环境下开发的golang程序,所以这里镜像版本就选择:golang:v1.14.2

  1. $ docker pull golang:v1.14.2
  2. $ docker tag a1c86c0786 harbor.od.com/public/golang:v1.14.2
  3. $ docker push harbor.od.com/public/golang:v1.14.2

1.2.2、Docker镜像

该镜像主要用于将编译好的golang项目打包成镜像并推送到harbor,但需要定制化一下镜像,需要将一台已经实现docker login 登录到harbor仓库所生成的配置文件,路径为:/root/.docker/config.json,与原始Docker镜像一起打包生成新的Docker镜像并推送到本地仓库。

1.准备镜像文件

  1. $ docker pull docker:19.03
  2. $ docker tag e036013d6d10 harbor.od.com/public/docker:v19.03
  3. $ docker push harbor.od.com/public/docker:v19.03

2.准备Dockerfile和config.json

  • Dockerfile
  1. FROM harbor.od.com/public/docker:v19.03
  2. USER root
  3. ADD config.json /root/.docker/config.json

3.将/root/.docker/config.json文件拷贝到Dockerfile目录下

  1. {
  2. "auths": {
  3. "harbor.od.com": {
  4. "auth": "YWRtaW46SGFyYm9yMTIzNDU="
  5. }
  6. },
  7. "HttpHeaders": {
  8. "User-Agent": "Docker-Client/19.03.6 (linux)"
  9. }
  10. }

4.制作并推送镜像

  1. $ docker build ./ -t harbor.od.com/public/docker:v19.03
  2. $ docker push harbor.od.com/public/docker:v19.0

2、Jenkins流水线

2.1、创建流水线

1.添加参数化构建

  1. - Choice Parameterrapp_project
  2. Valuezj-skyquery
  3. Describe:项目名必须和git仓库名一致
  4. - Choice Parameterrimage_name
  5. Valueapp/skyquery
  6. Describe:镜像名称:仓库名/镜像名
  7. - String Parameterrgit_ver
  8. Valuezmaster
  9. DescribeGit仓库分支或Commit ID
  10. - String Parameterradd_tag
  11. Value
  12. Describe:打包镜像tag,一般为日期时间
  13. - Choice Parameterrgit_repo
  14. Valuehttps://gitee.com/jasonminghao/zj-skyquery.git
  15. Describe:代码仓库地址
  16. - Choice Parameterrbase_image
  17. Valuebase/go-run:1.14.2-1
  18. Describe:基础镜像底包

2.pipeline代码

  1. podTemplate(cloud:'kubernetes',containers: [
  2. containerTemplate(
  3. name: 'go-build',
  4. envVars: [
  5. envVar(key: 'GO111MODULE', value: 'on'),
  6. envVar(key: 'GOPROXY', value: 'https://goproxy.io'),
  7. envVar(key: 'CGO_ENABLED', value: '0'),
  8. envVar(key: 'GOOS', value: 'linux')
  9. ],
  10. image: 'harbor.od.com/infra/golang:v1.14.2',
  11. ttyEnabled: true,
  12. command: 'cat'),
  13. containerTemplate(
  14. name: 'docker',
  15. ttyEnabled: true,
  16. image: 'harbor.od.com/public/docker:v19.03'),
  17. ],
  18. volumes: [
  19. nfsVolume(mountPath: '/go/pkg/mod', readOnly: false, serverAddress: 'hdss7-200.host.com', serverPath: '/data/nfs-volume/go-pkg/'),
  20. hostPathVolume(hostPath: '/run/docker.sock', mountPath: '/run/docker.sock')
  21. ]
  22. ){
  23. node(POD_LABEL) {
  24. stage('Get a Go project') {
  25. // 从git仓库拉取代码
  26. checkout([$class: 'GitSCM', branches: [[name: "${params.git_ver}"]], browser: [$class: 'GitLab', repoUrl: ''], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: 'git', name: 'git', refspec: 'refs/changes/*:refs/changes/*', url: "${params.git_repo}"]]])
  27. container('go-build') {
  28. stage('Build a go project') {
  29. // 将go应用构建名为app的可执行二进制文件
  30. sh "go build -o app"
  31. }
  32. }
  33. }
  34. stage('Docker build') {
  35. container('docker') {
  36. stage('create dir'){
  37. sh "mkdir -p /tmp/${params.app_project}/project_dir && mv ./app /tmp/${params.app_project}/project_dir"
  38. stage('build docker iamge'){
  39. sh """
  40. echo "FROM harbor.od.com/${params.base_image}" >/tmp/${params.app_project}/Dockerfile
  41. echo "ADD ./project_dir /opt/project_dir" >>/tmp/${params.app_project}/Dockerfile
  42. """
  43. sh "cd /tmp/${params.app_project}/ && pwd && docker build ./ -t harbor.od.com/${params.image_name}:${params.git_ver}_${params.add_tag} && docker push harbor.od.com/${params.image_name}:${params.git_ver}_${params.add_tag} "
  44. }
  45. }
  46. }
  47. }
  48. }
  49. }

我们在podTemplate里需要导入以下几个变量(pipeline已通过env实现)

  1. // 如果运行的golang镜像没有以下变量会导致无法执行go build以及可执行文件无法在linux上运行
  2. GO111MODULE = on
  3. GOPROXY = "https://goproxy.io"
  4. CGO_ENABLED = 0
  5. GOOS = linux

之前我们遇到过一个问题,golang应用构建成功,也有二进制文件,但是我们将其通过deployment交付到k8s的时候容器会启动失败,并且报错是 not found,但是把编译的文件拿到linux上可正常运行,就是在docker里运行失败,最后我们去网上查了一些资料,通过增加CGO_ENABLED=0 参数重新编译即可解决该问题。

2.2、流水线构建

1.填写参数构建

2.构建后的结果

3、golang资源配置清单

3.1、准备资源配置清单

1.deployment

  1. kind: Deployment
  2. apiVersion: extensions/v1beta1
  3. metadata:
  4. name: sky-query
  5. namespace: app
  6. labels:
  7. name: sky-query
  8. spec:
  9. replicas: 1
  10. selector:
  11. matchLabels:
  12. name: sky-query
  13. template:
  14. metadata:
  15. labels:
  16. app: sky-query
  17. name: sky-query
  18. spec:
  19. containers:
  20. - name: sky-query
  21. image: harbor.od.com/app/skyquery:master_20200424_1725
  22. ports:
  23. - containerPort: 80
  24. protocol: TCP
  25. imagePullPolicy: IfNotPresent
  26. imagePullSecrets:
  27. - name: harbor
  28. restartPolicy: Always
  29. terminationGracePeriodSeconds: 30
  30. securityContext:
  31. runAsUser: 0
  32. schedulerName: default-scheduler
  33. strategy:
  34. type: RollingUpdate
  35. rollingUpdate:
  36. maxUnavailable: 1
  37. maxSurge: 1
  38. revisionHistoryLimit: 7
  39. progressDeadlineSeconds: 600

2.svc

  1. kind: Service
  2. apiVersion: v1
  3. metadata:
  4. name: sky-query
  5. namespace: app
  6. spec:
  7. ports:
  8. - protocol: TCP
  9. port: 80
  10. targetPort: 80
  11. selector:
  12. name: sky-query

3.ingress

  1. kind: Ingress
  2. apiVersion: extensions/v1beta1
  3. metadata:
  4. name: sky-query
  5. namespace: app
  6. spec:
  7. rules:
  8. - host: sk-query.od.com
  9. http:
  10. paths:
  11. - path: /
  12. backend:
  13. serviceName: sky-query
  14. servicePort: 80

3.2、应用资源配置清单

  1. $ kubectl apply -f ./
  2. deployment.extensions/sky-query created
  3. ingress.extensions/sky-query created
  4. service/sky-query created

查看pod运行状态

  1. $ kubectl get pods -n app
  2. NAME READY STATUS RESTARTS AGE
  3. sky-query-55474c768d-x8qj5 1/1 Running 0 2m10s

3.3、浏览器访问golang业务

我们是通过ingress实现域名访问golang业务,以为是实验环境,我部署了内部自建dns,那我就直接将A记录添加到dns中,那么各位如果没有自建dns,直接将解析添加到hosts文件中。

1.域名解析

  1. $ vim /var/named/od.com.zone
  2. sk-query A 10.4.7.10
  3. $ systemctl restart named

2.浏览器访问

Golang交付至Kubernetes的更多相关文章

  1. Spring Cloud服务注册中心交付至kubernetes

    前言 服务发现原则: 各个微服务在启动时,会将自己的网络地址等信息注册到服务发现组件中,服务发现组件会存储这些信息 服务消费者可以从服务发现组件中查询到服务提供者的网络地址,并使用该地址来远程调用服务 ...

  2. 微服务交付至kubernetes流程

    目录 1.微服务简介 2.K8s部署微服务考虑的问题 3.项目迁移到k8s流程 1.微服务简介 微服务优点 服务组件化 每个服务独立开发.部署,有效避免一个服务的修改引起整个系统重新部署 技术栈灵活 ...

  3. Kubernetes 中的渐进式交付:蓝绿部署和金丝雀部署

    渐进式交付是持续交付的下一步, 它将新版本部署到用户的一个子集,并在将其滚动到全部用户之前对其正确性和性能进行评估, 如果不匹配某些关键指标,则进行回滚. 这里有一些有趣的项目,使得渐进式交付在 Ku ...

  4. Kubernetes Jenkins动态创建Slave

    目录 0.前言 1.Jenkins部署 2.配置jenkins动态slave 3.dubbo服务构建 3.1.制作dubbo镜像底包 3.2.制作slave基础镜像 3.2.1.Maven镜像 3.2 ...

  5. image management in kubernet

    Image How can I edit an existing docker image metadata? docker-copyedit Registry Disk kubevirtis a g ...

  6. 编译Kubelet二进制文件

    1. 环境 系统:CentOS 7.2 Go:1.10.3 Kubernetes:1.10.4 2. 安装最新版go 编译的Kubernetes 1.10.4要求go版本在1.9.3以上,使用下面的y ...

  7. 当 K8s 集群达到万级规模,阿里巴巴如何解决系统各组件性能问题?

    作者 | 阿里云容器平台高级技术专家 曾凡松(逐灵) 本文主要介绍阿里巴巴在大规模生产环境中落地 Kubernetes 的过程中,在集群规模上遇到的典型问题以及对应的解决方案,内容包含对 etcd.k ...

  8. 01. Go 语言简介

    Go语言简介 引用原文地址:http://m.biancheng.net/golang/ Go语言也称 Golang,兼具效率.性能.安全.健壮等特性.这套Go语言教程(Golang教程)通俗易懂,深 ...

  9. [转帖]当 K8s 集群达到万级规模,阿里巴巴如何解决系统各组件性能问题?

    改天学习一下. https://www.cnblogs.com/alisystemsoftware/p/11570806.html   当 K8s 集群达到万级规模,阿里巴巴如何解决系统各组件性能问题 ...

随机推荐

  1. thinkphp 路径 (纯转)

    TP中有不少路径的便捷使用方法,比如模板中使用的__URL__,__ACTION__等,如果你对这些路径不是很明白,用起来说不定就会有这样或那样的问题,抑或出了错也不知道怎么改,现在我们看一下这些路径 ...

  2. WePY的开发环境的安装

    2020-03-24 1.安装Node.js 官网:https://nodejs.org/ 两个版本 LTS为稳定的长期支持版本 Current为最新的版本 安装完毕后,cmd下输入 node -v ...

  3. Go相关面试题目总结(日常更新)

    1.go的深拷贝与浅拷贝 深拷贝 会赋值全部的内容 内容一样但是地址不一样 修改任何一个后地址不一样 内容也会一样 changeName(h1)对象传到函数里面也是深拷贝 b := a 这是深拷贝 会 ...

  4. JVM中内存分配策略及堆和栈的比较

    最近愈发对JVM底层的运行 原理产生了兴趣,遂查阅相关资料以备忘. 内存分配策略 根据编译原理的观点,程序运行时的内存分配,有三种策略,分别为静态的.堆式的.栈式的. 静态存储分配指的是在编译时就能确 ...

  5. 在MVC三层项目中如何使用Log4Net

    --前期准备(添加到队列中) 0-1在新建后的MVC项目中的[Models]中添加一个类,用于处理异常信息,并继承自HandleErrorAttribute public class MyExcept ...

  6. js之for与forEach循环的区别

    回武汉打卡第四天,武汉加油,逆战必胜!今天咱们探讨一下for循环和forEach()循环的区别. 首先,for循环在最开始执行循环的时候,会建立一个循环变量i,之后每次循环都是操作这个变量,也就是说它 ...

  7. P1203 [USACO1.1]Broken Necklace(模拟-枚举)

    P1203 [USACO1.1]坏掉的项链Broken Necklace 题目描述 你有一条由N个红色的,白色的,或蓝色的珠子组成的项链(3<=N<=350),珠子是随意安排的. 这里是 ...

  8. async和await是如何实现异步编程?

    目录 异步编程样例 样例解析 浅谈Promise如何实现异步执行 参考 1.异步编程样例 样例: // 等待执行函数 function sleep(timeout) { return new Prom ...

  9. CentOS8中安装maven

    下载maven,具体目录可根据实际情况而定 # wget http://mirrors.cnnic.cn/apache/maven/maven-3/3.3.9/binaries/apache-mave ...

  10. PTA数据结构与算法题目集(中文) 7-11

    PTA数据结构与算法题目集(中文)  7-11 7-11 关键活动 (30 分)   假定一个工程项目由一组子任务构成,子任务之间有的可以并行执行,有的必须在完成了其它一些子任务后才能执行.“任务调度 ...