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

【编者的话】当我们有了一个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:

这两个镜像可以直接从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-ciCircleCIWercker。从目前GitHub上开源项目的使用情况来看,Travis-ci的使用率更高一些。

适用于企业级的:Jenkins

不仅包括CI/CD功能的DevOps平台:JFrogSpinnakerFabric8

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: golang

build:

steps:
- setup-go-workspace

- script:
    name: go get
    code: |
      cd $WERCKER_SOURCE_DIR
      go version
      go get -u github.com/Masterminds/glide
      export PATH=$WERCKER_SOURCE_DIR/bin:$PATH
      glide install
# Build the project
- script:
    name: go build
    code: |
      go build
- script:
    name: copy files to wercker output 
    code: |
      cp -R ./ ${WERCKER_OUTPUT_DIR}
deploy:
steps:
- internal/docker-push:
   username: $USERNAME
   password: $PASSWORD
   cmd: /pipeline/source/k8s-app-monitor-agent
   port: "3000"
   tag: latest
   repository: 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:latest
    imagePullPolicy: Always
    name: app
    ports:
    - containerPort: 8080
    env: 
    - name: APP_PORT
      value: "3000"
    - name: SERVICE_NAME
      value: "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-agent
      servicePort: 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

参考

以上内容根据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应用

时间: 2024-08-03 21:32:58

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

DockOne微信分享(一三七):Kubernetes主机和容器的监控方案

本文讲的是DockOne微信分享(一三七):Kubernetes主机和容器的监控方案[编者的话]随着Docker容器云的广泛应用,大量的业务软件运行在容器中,这使得对Docker容器的监控越来越重要.传统的监控系统大多数是针对物理机或者虚拟机设计的,而容器的特点不同与传统的物理机或者虚拟机,如果还是采用传统的监控系统,则会增加监控复杂程度,那么如何对容器进行监控呢? [3 天烧脑式基于Docker的CI/CD实战训练营 | 北京站]本次培训围绕基于Docker的CI/CD实战展开,具体内容包括:

DockOne微信分享(一二六):Kubernetes在微服务化游戏中的探索实践

本文讲的是DockOne微信分享(一二六):Kubernetes在微服务化游戏中的探索实践[编者的话]随着Kubernetes的持续火热,那在线游戏领域又将如何使用,又将碰到哪些问题,以及带来哪些价值? 本次分享将为大家介绍微服务化架构游戏领域中,Kubernetes支撑技术方案选型,功能优化以及实践过程中的一些思考. [3 天烧脑式容器存储网络训练营 | 深圳站]本次培训以容器存储和网络为主题,包括:Docker Plugin.Docker storage driver.Docker Volu

DockOne微信分享(八十七):基于Docker的开发云提高资源利用率的实践

本文讲的是DockOne微信分享(八十七):基于Docker的开发云提高资源利用率的实践[编者的话]Docker的出现,为更简便.更细粒度地对云资源的调控提供了一个强有力的支撑,WeX5开发者云基于Rancher+Docker,在如何提高物理资源利用率的课题上做了一些探索和研究,在保障用户体验良好的前提下,大大提高了物理资源的利用率,有效地降低了运营成本. 一般情况下,开发者从无到有开发一个可用于公网访问的HTML5的App应用的流程是这样的:配置开发环境.开发应用.本地调试.租用公网服务器.注

DockOne微信分享(一二八):容器化部署OpenStack的正确姿势

本文讲的是DockOne微信分享(一二八):容器化部署OpenStack的正确姿势[编者的话]当前,以OpenStack为代表的IaaS开源技术和以Docker为代表的PaaS/CaaS容器技术日益成熟,二者如何强强联合,一直是业界颇为关心的焦点领域.本次分享主要是和大家交流基于Docker容器运行和部署OpenStack.那么,安装OpenStack都有哪些方法呢?对于很多刚接触OpenStack的新人而言,安装无疑是一大挑战,同时也直接提高了学习OpenStack云计算的技术门槛. [3 天

DockOne微信分享(一零三):Kubernetes 有状态集群服务部署与管理

本文讲的是DockOne微信分享(一零三):Kubernetes 有状态集群服务部署与管理[编者的话]本次分享将深入介绍Kubernetes如何满足有状态集群服务对容器编排系统提出的新需求,包括如何使用Kubernetes的动态存储请求与分配机制来实现服务状态的持久化存储,以及与高效部署和运行有状态集群服务相关的Kubernetes新特性,如Init Container.PetSet (StatefulSet)等.最后通过一个MySQL集群实例详解在Kubernetes中如何轻松部署一个高可用的

DockOne微信分享(一三二):58 赶集基于 Docker 的自动化部署实践

本文讲的是DockOne微信分享(一三二):58 赶集基于 Docker 的自动化部署实践[编者的话]随着 58 业务的发展,机器和服务数量也日益庞大,在多环境下,服务的管理和依赖难以维护.基于 Docker 带来的技术红利,我们借助 Docker 和 Kubernetes 提供了镜像的自动打包,单一镜像在测试-沙箱-生产-稳定四个环境的流转,以及测试环境统一的 Nginx 入口.至此,开发同学可以不再为资源和环境问题困扰,提高了生产效率. [3 天烧脑式容器存储网络训练营 | 深圳站]本次培训

DockOne微信分享(一零四):艺龙部署体系的演进

本文讲的是DockOne微信分享(一零四):艺龙部署体系的演进[编者的话]随着公司业务规模的逐渐扩大,传统的基于机器层面的部署系统在面对服务扩缩容.故障迁移.成本控制等方面已经越来越力不从心,于是,我们开始将容器技术与当前公司内部已有的自动化运维体系相结合,来实现一套艺龙的容器云平台,以期解决上述问题. 原有部署平台的架构设计 在讲解部署系统之前,我先给大家讲一下目前艺龙自动化运维的业务模型.早期艺龙的运维,因为规模较小,通常人工处理,当规模大了以后,就开始尝试基于Puppet等脚本的方式操作.

DockOne微信分享(九十六):爱油科技基于SpringCloud的微服务实践

本文讲的是DockOne微信分享(九十六):爱油科技基于SpringCloud的微服务实践[编者的话]本次分享主要介绍了爱油科技基于Docker和Spring Cloud将整体业务微服务化的一些实践经验,主要包括: 微服务架构的分层和框架选型 服务发现和配置管理 服务集成和服务质量保证 基于领域驱动设计 实施DevOps 从单体应用到微服务 单体应用 对于单体应用来说,优点很多,例如: 小而美,结构简单易于开发实现 部署门槛低,单个Jar包或者网站打包即可部署 可快速实现多实例部署 然而随着业务

DockOne微信分享(一二一):喜马拉雅FM测试环境的Docker化实践案例

本文讲的是DockOne微信分享(一二一):喜马拉雅FM测试环境的Docker化实践案例[编者的话]随着容器技术的流行,作为线上应用Docker的铺垫,喜马拉雅FM从16年开始推进测试环境Docker化.本次分享将重点为大家介绍我们在Docker化的过程中如何进行技术选型.环境搭建,特别是实践中碰到的一些问题及其解决方案. [3 天烧脑式 Docker 训练营 | 上海站]随着Docker技术被越来越多的人所认可,其应用的范围也越来越广泛.本次培训我们理论结合实践,从Docker应该场景.持续部