深入浅出 Docker(六):像谷歌一样部署你的应用

阅读数:23086 2015 年 3 月 13 日

话题:Google语言 & 开发架构

【编者按】Docker 是 PaaS 供应商 dotCloud 开源的一个基于 LXC 的高级容器引擎,源代码托管在 GitHub 上, 基于 Go 语言开发并遵从 Apache 2.0 协议开源。Docker 提供了一种在安全、可重复的环境中自动部署软件的方式,它的出现拉开了基于云计算平台发布产品方式的变革序幕。为了更好的促进 Docker 在国内的发展以及传播,我们决定开设《深入浅出 Docker》专栏,邀请 Docker 相关的布道师、开发人员、技术专家来讲述 Docker 的各方面内容,让读者对 Docker 有更深入的了解,并且能够积极投入到新技术的讨论和实践中。另外,欢迎加入 InfoQ Docker 技术交流群交流 Docker 的最佳实践,QQ 群号:124378115。

1. 概述

谷歌发起的开源项目从来都是广受技术圈的关注和讨论,本文将介绍的就是最新的容器编排管理系统 Kubernetes。Kubernetes 开源项目版本更新频繁,对于初次使用者来说其定义大量的技术术语并且随时会有新术语出现。在这种不稳定的技术框架之下,对使用者来说确实带来了一定的技术门槛。为了掌握 Kubernetes 的核心技术概念,本文尝试通过深入阅读官方文档资料并整理出核心的使用实践思路,以飧国内 Kubernetes 技术爱好者参考研究。

1.1 Kubernetes 是什么

Kubernetes 是一个容器集群的编排管理系统。这里对于“编排”的理解应该基于如何在跨 Docker 主机的场景之下统一管理容器集群的方法。当前的 Docker 技术主要提供单机版的容器管理实践,很多第三方厂商通过自己以往的网络经验推出自己的容器编排工具,Google 推出的 Kubernetes 技术是在这个背景下创立的开源项目。这个项目尝试要解决的问题就是简化开发和运维容器集群的工作,让开发和运维能把这个系统当一台电脑看待。这个思想在没有 Docker 容器技术之前,早已在分布式系统中得到大量应用,类如 Hadoop、Mesos、Yarn。由于虚拟化技术的限制,对于更大实例规模仍然有很大的局限性。Docker 技术出现后,本来已经很复杂的分布式系统开始尝试向更大规模的集群规模实现,这个实现标准的诱惑力让更多的厂商参与进来并尝试在原有 Mesos、Yarn 类集群调度系统中开始应用 Docker 技术。那么 Kubernetes 和 Mesos 类相比较,它的优势是没有资源调度算法,只关注容器的管理。而 Mesos、Yarn 之类调度系统本身有完善的调度系统经验,如何把 Docker 编排的架构加入到原有系统中,需要一些标准设计参考实现,这个时候 Kubernetes 的出现正好弥补了这个需要。

1.2 Kubernetes 技术术语概览

第一,在 Kubernetes 的集群环境里 Pods 是最小的可部署单元,它表示同属于一个应用的容器群的逻辑集合。

第二,Master 节点提供了集群统一视图的中心控制点。我们可以用一个 Master 节点来控制多个 Minion 节点。

第三,Minion 是一个工作节点,它将运行 Master 节点交付的任务。Minions 能运行一个或多个 Pods。它提供了在容器环境下一个应用级别的虚拟机。

通过以下概念图,我们可以更加清晰的看到 Kubernetes 的技术全貌。

让我们再深入一点,讲一讲 Kubernetes 是如何做到这些特性的。

  • Replication Controller 是 Master 上的资源控制器,确保创建、销毁 Pods 的请求能随时被 Minions 节点运行。这样可以保证集群中的 Pod 可以永远提供服务,而当 Pod 运行失败后可以立即开启新 Pod 实例,保证 Pod 实例服务的可用性可以保证。
  • Service 提供统一的名称和地址,提供针对一组 Pods 的负载均衡。这个 Service 其实就是微服务的实现,它在我们创建的 Pods 的基础之上提供一层抽象。比如我们的 Service 是一个 Job 服务,前端应用可以直接发布任务到指定的 Servcie IP 就可以了,用户对于这个 Job 服务有多少个实例提供服务不需要关心。
  • Label 是一个强制的键值对,保存在分布式存储服务 etcd 上,让 Replication Controller 能用它去实现服务发现。
  • Kubelet 是在每个 Minion 上管理容器的守护进程,它是实际管理 Docker 主机来启动容器的管理程序。
  • Master API Server 提供 RESTful K8s API 接口来校验和配置 Pod、Service 和 Replication Controller,它是统一管理集群系统的入口。

1.3 与 Docker 工具链的关系

Docker 近期推出的三大套件:Compose、Swarm、Machine 都提供了一些 Kubernetes 的功能,我们需要了解他们之间的区别,让我们能更好的利用 Kubernetes 做好基础。

  • Docker Machine 是比较底层的入口,比 Kubernetes 的实现更底层一些。Machine 提供了基础设施 IaaS 的能力,方便管理混合云状况下的 Docker 主机。类似 Google Compute Engine。
  • Docker Swarm 完全基于 Docker API 之上定义的 Cluster API。方向上是 Docker API 提供单机范围内的 API,由 Swarm 提供 Cluster 级别的 API。Google 的 Kubernetes 团队在早期 Swarm 实现讨论上提供了自己的意见
  • Docker Compose 还是单机版的开发套件,对于开发者来说,可以使用它把当前的代码构建出指定的 Docker Image,然后运行在单机上。Kubernetes 就是为了解决部署到容器集群的难度而定义的标准实现。当前 Compose 正在实现基于 Swarm 和 Machine 实现集群编排的能力,这种能力就是 Kubernetes 的直接竞争对手。

2. 使用实战

我们可以参照官方提供的各类平台安装脚本来部署 Kubernetes 集群系统,本文采用 Ubuntu 系统作为基础系统用来安装 Kubernetes 集群。官方提供的脚本按照以下几步安装即可安装成功:

首先,把 Kubernetes 的源码下载到每一台集群机器上,自行构建最新版的套件。

$ cd cluster/ubuntu-cluster
$ sudo ./build.sh
$ sudo cp ./binaries/* /opt/bin   # 复制到 /opt/bin 目录,主要是为了方便部署脚本调用。

然后,配置 Kubernetes 集群组件,假设我们的机器清单如下:

IP Address

Role

192.168.100.30

master

192.168.100.31

minion

192.168.100.32

minion

只需要到 cluster/ubuntu-cluster 目录下执行一遍 configue.sh 就可以完成配置。

比如在 master 节点 (192.168.100.30) 上:

$ sudo ./configure.sh
Welcome to use this script to configure k8s setup

Please enter all your cluster node ips, MASTER node comes first
And separated with blank space like "":  192.168.100.30 192.168.100.31 192.168.100.32

This machine acts as
  both MASTER and MINION:  	1
  only MASTER:             	2
  only MINION:             	3
Please choose a role > 2

IP address of this machine >  192.168.100.30

Configure Success

当你看到信息“Configure Success” 时代表这台机器的配置算完成了。

当然,在官方的 Ubuntu 例子中,它使用 Flannel 创建了一套覆盖网络(Overlay Network),通过这个网络实现了跨主机的容器互联互通。大家可以通过图 1flannel 网络截图知道 flannel0 和 docker0 被分在同一网段,Docker 内部容器 ip 和 docker0 网关之间是有 NAT 的,通过 flannel+etcd 提供自定义的 udp 数据包,实现跨主机的容器之间的互联,通过这个例子可以帮我们深入的理解跨主机容器互联 SDN 的主要实现思路。

图 1 flannel 网络截图

在部署完 Kubernetes 系统后我们可以通过内置的命令来验证服务是否正常。比如运行

$ kubectl get minions
NAME            	LABELS          	STATUS
192.168.100.30  	          	NotReady
192.168.100.31  	          	Ready
192.168.100.32  	          	Ready

好了,系统成功了。我在部署的过程中发现,并不是每次都能顺利完成安装。比如端口被占用,关键服务没起来等情况。那么我把这些情况总结一下,方便大家排除故障:

  • master 节点,主要的服务是 kube-apiserver、kube-controller-manager、kube-scheduler,如下截图显示需要保证能运行:

    如果没有看到运行的进程,应该去看一下运行日志,在 Ubuntu 的安装实例中,日志统一放在 /var/log/upstart/ 目录下。

  • slave 节点,主要的服务是 kube-proxy、kubelet 两个服务,如下截图显示需要保证能运行:

  • 网络相关的组件,主要是 etcd 服务,还有 SDN 的组件服务类如 Flannel。这一块出问题的情况很少,我遇到大多数问题都是集中在网络拓扑上,通过学习理解这种网络就可以基本解决问题。
  • Kubernetes 项目还不是生产级别的工程,没有在实际的场景中经过生产级别的验证。我们正好通过官方提供的 example 目录中的例子理解我们的场景中到底需要什么功能,然后反馈到社区,让 Kubernetes 越来越成熟。

3. 总结

Kubernetes 在 2014 年 9 月发布第一个版本之后,版本迭代都是按周实施的。官方还不建议用户在生产环境中使用这套系统。但是它的设计思想以及简洁的架构设计足以让我们借鉴到很多工程上的宝贵经验。在借鉴的成功案例中,红帽的 Openshift 最新版本 V3 中就成功应用了 Kubernetes 实现技术。所以,Kubernetes 项目是一个值得大家借鉴学习的优秀开源项目,通过理解它的设计思想,可以很快应用到本地的容器编排集群系统实现中。

4. 作者简介

肖德时,数人科技(www.dataman.io)CTO,致力于构建基于 Mesos/Docker 的容器云计算平台。Twitter/ 微博账号:xds2000,邮箱:xiaods@gmail.com


感谢郭蕾对本文的策划和审校。

给 InfoQ 中文站投稿或者参与内容翻译工作,请邮件至editors@cn.infoq.com。也欢迎大家通过新浪微博(@InfoQ)或者腾讯微博(@InfoQ)关注我们,并与我们的编辑和其他读者朋友交流。