【编者的话】当我们有了一个kubernetes集群后,如何在上面开发和部署应用,应该遵循怎样的流程?本次分享将向您展示如何使用Go语言开发和部署一个Kubernetes Native应用,使用Wercker进行持续集成与持续发布,我将以一个很简单的前后端访问,获取伪造数据并展示的例子来说明。

环境声明

本文讲的是DockOne微信分享(一四一):如何开发部署Kubernetes Native应用首先声明下我们使用的集群环境:

  • Docker 1.12.5
  • flannel network host-gw
  • Kubernetes 1.6.0
  • TLS enabled

详细的部署文档和更多资料请参考:https://github.com/rootsongjc/kubernetes-handbook

应用示例

我们的这两个示例仅仅是为了演示,开发部署一个伪造的Metric并显示在Web页面上,包括两个service:

  • K8s-app-monitor-test:生成模拟的监控数据,发送http请求,获取json返回值,https://github.com/rootsongjc/k8s-app-monitor-test
  • K8s-app-monitor-agent:获取监控数据并绘图,访问浏览器获取图表,https://github.com/rootsongjc/ ... agent

这两个镜像可以直接从Docker Hub上下载:

  • jimmysong/k8s-app-monitor-test:latest
  • jimmysong/k8s-app-monitor-agent:latest

定义API

API文档见 https://github.com/rootsongjc/k8s-app-monitor-test 中的api.html文件,该文档在API blueprint中定义,使用aglio生成,打开后如图所示:

关于服务发现

K8s-app-monitor-agent服务需要访问k8s-app-monitor-test服务,这就涉及到服务发现的问题,我们在代码中直接写死了要访问的服务的内网DNS地址(kubedns中的地址,即k8s-app-monitor-test.default.svc.cluster.local)。

我们知道Kubernetes在启动Pod的时候为容器注入环境变量,这些环境变量在所有的 namespace 中共享(环境变量是不断追加的,新启动的Pod中将拥有老的Pod中所有的环境变量,而老的Pod中的环境变量不变)。但是既然使用这些环境变量就已经可以访问到对应的service,那么获取应用的地址信息,究竟是使用变量呢?还是直接使用DNS解析来发现?

答案是使用DNS,详细说明见Kubernetes中的服务发现与Docker容器间的环境变量传递源码探究。

使用Wercker构建镜像

CI工具

开源项目的构建离不开CI工具,你可能经常会在很多GitHub的开源项目首页上看到这样的东西:

这些图标都是CI工具提供的,可以直观的看到当前的构建状态,例如Wercker中可以在Application-magpie-options中看到:

将文本框中的代码复制到你的项目的README文件中,就可以在项目主页上看到这样的标志了。

现在市面上有很多流行的CI/CD工具和DevOps工具有很多,这些工具提高了软件开发的效率,增加了开发人员的幸福感。这些工具有:

适用于GitHub上的开源项目,可以直接使用GitHub账户登陆,对于公开项目可以直接使用:Travis-ci、CircleCI、Wercker。从目前GitHub上开源项目的使用情况来看,Travis-ci的使用率更高一些。

适用于企业级的:Jenkins。

不仅包括CI/CD功能的DevOps平台:JFrog、Spinnaker、Fabric8

Wercker简介

Wercker是一家为现代云服务提供容器化应用及微服务的快速开发、部署工具的初创企业,成立于2012年,总部位于荷兰阿姆斯特丹。其以容器为中心的平台可以对微服务和应用的开发进行自动化。开发者通过利用其命令行工具能够生成容器到桌面,然后自动生成应用并部署到各种云平台上面。其支持的平台包括Heroku、AWS以及Rackspace等。

Wercker于2016年获得450万美元A轮融资,此轮融资由Inkef Capital领投,Notion Capital跟投,融资所得将用于商业版产品的开发。此轮融资过后其总融资额为750万美元。

Wercker于2017年4月被Oracle甲骨文于收购。

如何使用

通过Wercker搭建CI环境只需经过三个基本步骤。

  1. 在Wercker网站中创建一个应用程序。
  2. 将wercker.yml添加到应用程序的代码库中。
  3. 选择打包和部署构建的位置。

可以使用GitHub帐号直接登录Wercker,整个创建应用CI的流程一共3步。

一旦拥有了账户,那么只需简单地点击位于顶部的应用程序菜单,然后选择创建选项即可。如果系统提示是否要创建组织或应用程序,请选择应用程序。Wercker组织允许多个Wercker用户之间进行协作,而无须提供信用卡。下图为设置新应用程序的向导页面。

选择了GitHub中的repo之后,第二步配置访问权限,最后一步Wercker会尝试生成一个wercker.yml文件(后面会讨论)。不过至少对于Go应用程序来说,这个配置很少会满足要求,所以我们总是需要创建自己的Wercker配置文件。

创建Wercker配置文件Wercker.Yml

Wercker配置文件是一个YAML文件,该文件必须在GitHub repo的最顶层目录,该文件主要包含三个部分,对应可用的三个主要管道。

  • Dev:定义了开发管道的步骤列表。与所有管道一样,可以选定一个box用于构建,也可以全局指定一个box应用于所有管道。box可以是Wercker内置的预制Docker镜像之一,也可以是Docker Hub托管的任何Docker镜像。
  • Build:定义了在Wercker构建期间要执行的步骤和脚本的列表。与许多其他服务(如Jenkins和TeamCity)不同,构建步骤位于代码库的配置文件中,而不是隐藏在服务配置里。
  • Deploy:在这里可以定义构建的部署方式和位置。

Wercker中还有工作流的概念,通过使用分支、条件构建、多个部署目标和其他高级功能扩展了管道的功能,这些高级功能读着可以自己在wercker的网站中探索。

因为我使用Wercker自动构建,构建完成后自动打包成Docker镜像并上传到Docker Hub中(需要先在Docker Hub中创建repo),如何使用Wercker做持续构建与发布,并集成Docker Hub插件请参考:https://jimmysong.io/blogs/con ... cker/

K8s-app-monitor-agent的Wercker配置文件如下:

yaml
box: golangbuild:steps:
- setup-go-workspace- script:name: go getcode: |cd $WERCKER_SOURCE_DIRgo versiongo get -u github.com/Masterminds/glideexport PATH=$WERCKER_SOURCE_DIR/bin:$PATHglide install
# Build the project
- script:name: go buildcode: |go build
- script:name: copy files to wercker output code: |cp -R ./ ${WERCKER_OUTPUT_DIR}
deploy:
steps:
- internal/docker-push:username: $USERNAMEpassword: $PASSWORDcmd: /pipeline/source/k8s-app-monitor-agentport: "3000"tag: latestrepository: jimmysong/k8s-app-monitor-agent

其中的$USERNAME$PASSWORD是Docker Hub的用户名和密码,这些是做作为Wercker构建的环境变量,在Wercker的Web端进行配置的。

此文件包含两个管道:build和deploy。在开发流程中,我们使用Wercker和Docker创建一个干净的Docker镜像,然后将它push到Docker Hub中。Wercker包含一个叫做Internal/docker-push的deploy plugin,可以将构建好的Docker镜像push到镜像仓库中,默认是Docker Hub,也可以配置成私有镜像仓库。

box键的值是Golang。这意味着我们使用的是一个基础的Docker镜像,它已经安装了Go环境。这一点至关重要,因为执行Wercker构建的基准Docker镜像需要包含应用程序所需的构建工具。

构建流程见:https://app.wercker.com/jimmys ... gent/

当然你还可以使用其他的CI工具,因为Wercker的插件比较方便,可以直接构建成Docker镜像上传到Docker Hub中,比较方便,所以我选择了Wercker。

生成了如下两个Docker镜像:

  • jimmysong/k8s-app-monitor-test:latest
  • jimmysong/k8s-app-monitor-agent:latest

启动服务

所有的Kubernetes应用启动所用的yaml配置文件都保存在那两个GitHub仓库的manifest.yaml文件中。

比如k8s-app-monitor-agentmanifest.yaml文件如下:

Yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: k8s-app-monitor-agent
namespace: default
spec:
replicas: 1
template:
metadata:labels:k8s-app: k8s-app-monitor-agent
spec:containers:- image: jimmysong/k8s-app-monitor-agent:latestimagePullPolicy: Alwaysname: appports:- containerPort: 8080env: - name: APP_PORTvalue: "3000"- name: SERVICE_NAMEvalue: "k8s-app-monitor-test"
---
apiVersion: v1
kind: Service
metadata:
name: k8s-app-monitor-agent
labels:
k8s-svc: k8s-app-monitor-agent
spec:
ports:
- port: 8080
protocol: TCP
name: http
selector:
k8s-app: k8s-app-monitor-agent

注意其中的env,包括了两个环境变量(注意:环境变量名称必须为大写字母):APP_PORTSERVICE_NAME,这两个环境变量,在 main.go的代码中我们可以看到:

Go
func drawChart(res http.ResponseWriter, req *http.Request) {
port := os.Getenv("APP_PORT")
service := os.Getenv("SERVICE_NAME")
if len(port) == 0 {port = "3000"
}
if len(service) == 0 {service = "localhost"
}

如果程序启动的时候找不到该环境变量,将会使用程序内置的默认值,当然我们不该将服务地址写死在程序内部,而应该是可配置的,在Kubernetes中最佳配置方式是环境变量或者ConfigMap。

分别在两个GitHub目录下执行kubectl create -f manifest.yaml即可启动服务。

外部访问

服务启动后需要更新Ingress配置,在ingress.yaml文件中增加以下几行:

yaml
- host: k8s-app-monitor-agent.jimmysong.io
http:paths:- path: /backend:serviceName: k8s-app-monitor-agentservicePort: 8080

保存后,然后执行kubectl replace -f ingress.yaml即可刷新Ingress。

修改本机的/etc/hosts文件,在其中加入以下一行:

172.20.0.119 k8s-app-monitor-agent.jimmysong.io

当然你也可以加入到DNS中,为了简单起见我使用hosts。

在浏览器中访问http://k8s-app-monitor-agent.jimmysong.io

刷新页面将获得新的图表。

边缘节点配置

边缘节点架构图:

选择Kubernetes的三个node作为边缘节点,并安装Keepalived,上图展示了边缘节点的配置,同时展示了向Kubernetes中添加服务的过程。

边缘节点定义

首先解释下什么叫边缘节点(Edge Node),所谓的边缘节点即集群内部用来向集群外暴露服务能力的节点,集群外部的服务通过该节点来调用集群内部的服务,边缘节点是集群内外交流的一个Endpoint。

边缘节点要考虑两个问题

  • 边缘节点的高可用,不能有单点故障,否则整个kubernetes集群将不可用
  • 对外的一致暴露端口,即只能有一个外网访问IP和端口

为了满足边缘节点的以上需求,我们使用Keepalived来实现。

在Kubernetes中添加了service的同时,在DNS中增加一个记录,这条记录需要跟ingress中的host字段相同,IP地址即VIP的地址,本示例中是172.20.0.119,这样集群外部就可以通过service的DNS名称来访问服务了。

详细操作步骤和配置请参考:https://github.com/rootsongjc/ ... on.md

参考

  • 示例的项目代码服务器端:https://app.wercker.com/jimmys ... gent/
  • 示例项目代码前端:https://github.com/rootsongjc/ ... agent
  • kubernetes-handbok:https://jimmysong.io/kubernetes-handbook/
  • 边缘节点配置:https://github.com/rootsongjc/ ... on.md

以上内容根据2017年09月14日晚微信群分享内容整理。 分享人宋净超,容器技术负责人,Kubernetes社区专家作者。曾就职于科大讯飞,在大数据平台架构与优化、云平台的开发与维护方面拥有丰富经验,目前在TalkingData从事kubernetes和云原生应用的研究和推广工作。Cloud Native Go 图书译者之一、Qcon、CNUTcon讲师,个人博客 http://jimmysong.io。 DockOne每周都会组织定向的技术分享,欢迎感兴趣的同学加微信:liyingjiesa,进群参与,您有想听的话题或者想分享的话题都可以给我们留言。

原文发布时间为:2017-09-19

本文作者:尼古拉斯

本文来自云栖社区合作伙伴Dockerone.io,了解相关信息可以关注Dockerone.io。

原文标题:DockOne微信分享(一四一):如何开发部署Kubernetes Native应用

DockOne微信分享(一四一):如何开发部署Kubernetes Native应用相关推荐

  1. DockOne微信分享( 九十):猎豹移动基于CoreOS在AWS上的项目实践

    本文讲的是DockOne微信分享( 九十):猎豹移动基于CoreOS在AWS上的项目实践[编者的话]本次分享介绍基于AWS的EC2服务如何设计和搭建适合自己业务的架构方案实现全球多region部署,介 ...

  2. DockOne微信分享( 九十一):打造百亿级数据处理量的弹性调度容器平台

    本文讲的是DockOne微信分享( 九十一):打造百亿级数据处理量的弹性调度容器平台[编者的话]本次分享介绍七牛数据处理团队的容器技术实践经验,分享七牛如何通过自主研发的容器调度框架打造易扩展.易部署 ...

  3. DockOne微信分享(八十四):Docker在B站的实施之路

    本文讲的是DockOne微信分享(八十四):Docker在B站的实施之路[编者的话]B站一直在关注Docker的发展,去年成功在核心SLB(Tengine)集群上实施了Docker.今年我们对比了各种 ...

  4. DockOne微信分享(一三一):Juice——一种基于MesosFramework的任务云框架

    本文讲的是DockOne微信分享(一三一):Juice--一种基于MesosFramework的任务云框架[编者的话]近年来,随着Mesos在生产环境中的普及,使大规模的集群管理变得简单,而基于Mes ...

  5. DockOne微信分享(一一零):Docker在沪江落地的实践

    本文讲的是DockOne微信分享(一一零):Docker在沪江落地的实践[编者的话]容器化是很多公司技术层向往又惧怕的一项热门技术,它的高效性,封装性能给开发.运维带来许多便利,但其本身也需要较强的技 ...

  6. DockOne微信分享(八十一):唯品会数据库备份恢复容器化项目实践经验总结

    本文讲的是DockOne微信分享(八十一):唯品会数据库备份恢复容器化项目实践经验总结[编者的话]本文分享了唯品会数据库Docker的异地容灾项目实践经验,项目中针对用户数据库的异地恢复场景的需求进行 ...

  7. DockOne微信分享(一三四):国内某大型酒店管理集团基于Kubernetes的实践

    本文讲的是DockOne微信分享(一三四):国内某大型酒店管理集团基于Kubernetes的实践[编者的话]随着业务的增长,架构变得越来越复杂,服务器和应用数量越来越多,随之应用的管理,配置的管理,后 ...

  8. DockOne微信分享(一零五):度量驱动的DevOps转型

    本文讲的是DockOne微信分享(一零五):度量驱动的DevOps转型[编者的话]虚拟化,容器化,云计算,自动化为DevOps运动提供了底层技术支持,新的工具链和技术栈的采用进一步降低了DevOps的 ...

  9. DockOne微信分享(六十四):基于Docker实现DevOps的一些探索

    本文讲的是DockOne微信分享(六十四):基于Docker实现DevOps的一些探索[编者的话]本次分享从DevOps介绍:Docker介绍:基于Docker实现DevOps的优势:Docker化D ...

  10. DockOne微信分享(九十九):海航生态科技舆情大数据平台容器化改造

    本文讲的是DockOne微信分享(九十九):海航生态科技舆情大数据平台容器化改造[编者的话]海航舆情监控系统能够为海航集团内部提供监控网络舆情信息,对负面信息.重大舆情及时预警,研判具体舆情或者某一舆 ...

最新文章

  1. Centos7上yum安装redis
  2. Varnish页面缓存服务
  3. LCIS code force 10D
  4. Mac系统如何配置adb路径
  5. MySQL中的find_in_set
  6. shell学习(12)- jq
  7. 网络延长器分为哪几类?其应用领域有哪些?
  8. centos7卸载mysql数据库,CentOS7 安装卸载MySQL
  9. Redis:22---客户端API:client、monitor)
  10. c# list集合根据某个字段去重_Python list、dataframe去重
  11. Mac下gradle简介与安装
  12. 如何在Xcode 4中“添加现有框架”?
  13. MSF之IIS6WebDAV执行漏洞复现
  14. 算法竞赛入门经典——1
  15. 龙芯pmon 中Nand配置说明
  16. 应届生毕业第一份工资多少?
  17. 然并卵却很拉风!360超级充电器评测_天极网
  18. Mac上用spotlight搜索输入几个字母后闪退
  19. 二、lintcode刷题记录--二叉树的路径和
  20. 浅识WebGL和Three.js

热门文章

  1. Netty的并发编程实践3:CAS指令和原子类
  2. iPhone企业应用实例分析之三:程序框架分析
  3. 幻灯片形式设计:从方法到技巧
  4. 详解tf.Session()和tf.InteractiveSession()的区别
  5. Coursera机器学习课后作业Matlab代码(1~9周)
  6. HTML样式- CSS
  7. pyQT实现自动找茬游戏
  8. Django2 SQLite3迁移到MySQL数据库
  9. 解决Ubuntu18.04使用快捷键 Ctrl+Alt+T 无法打开终端的问题
  10. Flutter 《从0到1构建大前端应用》-所有知识点架构