作者都是各自领域经过审查的专家,并撰写他们有经验的主题. 我们所有的内容都经过同行评审,并由同一领域的Toptal专家验证.
德米特里·科诺诺夫的头像

他在科诺诺夫

Dmitriy是一名软件工程师,在web开发和DevOps方面拥有12年的经验. 他的专长是云服务, DevOps, 和Kubernetes, 专注于基础设施成本降低和大容量实例管理. 德米特里拥有吉尔吉斯国立技术大学计算机科学硕士学位.

工作经验

12

Share

刚才, 我们使用的是庞大的web应用程序:庞大的代码库不断增加新的功能和特性,直到它们变得庞大, 行动迟缓的, 难以管理巨头. Now, 越来越多的开发者, 架构师, 和DevOps专家都认为使用微服务比使用一个巨大的庞然大物要好. 通常, 使用基于微服务的架构意味着将你的单体拆分为至少两个应用:前端应用和后端应用(API)。. 在决定使用微服务之后,出现了一个问题: 在什么环境下运行微服务更好? 为了使我的服务稳定、易于管理和部署,我应该选择什么? 简单的回答是:使用Docker!

在本文中, 我将向你们介绍集装箱, 解释Kubernetes, 教你如何使用CircleCI将应用程序容器化并部署到Kubernetes集群.

Docker? Docker是什么??

Docker是一个旨在使DevOps(和您的生活)更轻松的工具. 使用Docker,开发人员可以创建、部署和运行应用程序 容器. 容器允许开发人员将应用程序与所需的所有部分打包, 比如库和其他依赖项, 然后用一个包裹寄出去.

比较部署在主机上的应用程序与. 打包在容器中的应用程序

比较部署在主机上的应用程序与. 打包在容器中的应用程序

使用容器,开发人员可以轻松地(重新)将映像部署到任何操作系统. 只要安装Docker,执行一个命令,你的应用程序就启动并运行了. 哦,不要担心与主机操作系统中新版本的库不一致. 此外,您可以在同一台主机上启动更多容器—是同一应用程序还是其他应用程序? 没关系.

看起来Docker是一个很棒的工具. 但是我应该如何以及在哪里发射集装箱?

There are a lot of options for how and where to run 容器: AWS Elastic Container Service (AWS Fargate or a reserved instance with horizontal and vertical auto-scaling); a cloud instance with predefined Docker image in Azure or Google Cloud (with templates, 实例组, and auto-scaling); on your own server with Docker; or, 当然, Kubernetes! Kubernetes是谷歌的工程师在2014年专门为虚拟化和容器创建的.

Kubernetes? 那是什么??

Kubernetes是一个允许你运行容器的开源系统, 管理它们, 自动化部署, 规模部署, 创建和配置入口, 部署无状态或有状态应用程序, 还有很多其他的东西. 基本上, 您可以启动一个或多个实例并安装Kubernetes,将它们作为Kubernetes集群来操作. 然后获取Kubernetes集群的API端点,进行配置 kubectl (一个管理Kubernetes集群的工具),Kubernetes已经准备好了.

那我为什么要用它呢?

使用Kubernetes,您可以最大限度地利用计算资源. 与Kubernetes, 您将成为您的船(基础设施)的船长,Kubernetes将为您提供帆. 使用Kubernetes,您的服务将是HA. 最重要的是,有了Kubernetes,你可以节省很多钱.

看起来很有前途! 尤其是如果它能省钱的话! 我们再多谈谈吧!

Kubernetes越来越受欢迎. 让我们更深入地研究一下幕后的情况.

底层:Kubernetes是什么?

Kubernetes是什么? 组成Kubernetes的组件

组成Kubernetes的组件

Kubernetes是整个系统的名称, 但就像你的车, 有许多小的部分完美和谐地协同工作,使Kubernetes发挥作用. 让我们来学习它们是什么.

主节点- 整个Kubernetes集群的控制面板. 主服务器的组件可以在集群中的任何节点上运行. 主要组成部分是:

  • API服务器: 所有REST命令的入口点, 主节点中唯一可由用户访问的组件.
  • 数据存储: Kubernetes集群使用的强大、一致和高可用的键值存储.
  • 调度程序: 监视新创建的pod并将它们分配给节点. 将pod和服务部署到节点上是由于调度器.
  • 控制器经理: 运行集群中处理日常任务的所有控制器.
  • 工作者节点: 主节点代理,也称为辅助节点. 舱在这里运行. 工作节点包含管理容器之间网络连接所需的所有服务, 与主节点通信, 并将资源分配给预定的容器.
  • Docker: 在每个工作节点上运行,并下载映像和启动容器.
  • Kubelet: 监视pod的状态,并确保容器处于启动和运行状态. 它还与数据存储通信, 获取有关服务的信息并写入有关新创建服务的详细信息.
  • Kube-proxy: 单个工作节点上服务的网络代理和负载平衡器. 它负责交通路由.
  • Kubectl: 用于用户与Kubernetes API服务器通信的CLI工具.

什么是豆荚和服务?

Pods 是Kubernetes集群中最小的单元,它就像一栋巨大建筑墙上的一块砖. pod是一组需要一起运行并且可以共享资源(Linux名称空间)的容器, cgroups, IP地址). 豆荚的寿命并不长.

服务 抽象是建立在许多pod之上的吗, 通常需要顶部的代理,以便其他服务通过虚拟IP地址与之通信.

简单部署示例

不同的利益相关者如何与kubernetes驱动的应用程序交互

不同的利益相关者如何与kubernetes驱动的应用程序交互

我将使用一个简单的Ruby on Rails应用程序和GKE作为运行Kubernetes的平台. 实际上, 您可以在AWS或Azure中使用Kubernetes,甚至可以在您自己的硬件中创建集群,或者在本地使用Kubernetes minikube-你能找到的所有选项 this page.

这个应用程序的源文件可以在 这个GitHub存储库.

要创建一个新的Rails应用程序,执行:

Rails新博客

配置用于生产的MySQL连接 配置/数据库.yml文件:

生产:
  适配器:mysql2
  编码:utf8
  pool: 5
  端口:3306
  database: <%= ENV['DATABASE_NAME'] %>
  主持人:127.0.0.1
  username: <%= ENV['DATABASE_USERNAME'] %>
  password: <%= ENV['DATABASE_PASSWORD'] %>

要创建一个Article模型、控制器、视图和迁移,执行:

文章标题:字符串描述:文本

向Gemfile中添加gems:

gem 'mysql2', '< 0.6.0', '>= 0.4.4'
宝石的health_check

要创建Docker映像,请抓取我的 Dockerfile 和执行:

docker build -t REPO_NAME/IMAGE_NAME:TAG . && docker push REPO_NAME/IMAGE_NAME:TAG

现在是创建Kubernetes集群的时候了. 打开GKE页面,创建Kubernetes集群. 创建集群时, 点击“连接按钮”并复制命令-确保您有gCloud CLI工具(how to) and kubectl 已安装并配置. Execute the copied command on your PC and check the connection to the Kubernetes cluster; execute kubectl cluster-info.

应用程序已经准备好部署到k8s集群. 让我们创建一个MySQL数据库. 在gCloud控制台中打开SQL页面,为应用程序创建一个MySQL DB实例. 当实例准备好后,创建用户和DB并复制 实例连接名称.

控件中创建一个服务帐户密钥 API & 服务 从sidecar容器访问MySQL数据库的页面. 你可以找到更多关于这个过程的信息 here. 将下载的文件重命名为 服务帐户.json. 我们稍后会回到那个文件.

我们已经准备好将应用程序部署到Kubernetes,但首先,我们应该创建 秘密 在Kubernetes中创建一个用于存储敏感数据的秘密对象. 上传之前下载的文件 服务帐户.json file:

Kubectl创建secret generic mysql-instance-credentials
——从文件=凭证.json =服务帐户.json

为应用程序创建秘密:

Kubectl创建秘密通用simple-app-秘密 \
——文字=用户名= $ MYSQL_PASSWORD \
密码——文字= = $ MYSQL_PASSWORD \
——文字=数据库名称= $ MYSQL_DB_NAME \
——文字= secretkey = SECRET_RAILS_KEY美元

不要忘记用您的值替换值或设置环境变量.

在创建部署之前,让我们看一下 部署文件. I concatenated three files into one; the first part is a service which will expose port 80 and forward all connections coming to port 80 to 3000. 服务有一个选择器,服务知道它应该将连接转发到哪个pod.

文件的下一部分是部署, 哪个描述了部署策略——将在pod中启动的容器, 环境变量, 资源, probes, 每个集装箱的安装座, 还有其他信息.

最后一部分是水平Pod自动缩放器. HPA 有一个非常简单的配置. 请记住,如果您没有在部署部分为容器设置资源, HPA 不起作用.

您可以在GKE编辑页面中为Kubernetes集群配置垂直自动缩放器. 它的结构也很简单.

现在是时候将其发送到GKE集群了! 首先,我们应该通过 job. 执行:

Kubectl apply -f rake-tasks-job.yaml -此工作将对CI/CD过程有用.

Kubectl apply -f 部署.yaml -创建服务、部署和HPA.

然后通过执行以下命令来检查您的pod: Kubectl得到pod -w

Name ready status重启年龄
运行0米
2 .运行0米
sample-799bf9fd9c-pkscp 2/2

现在让我们为应用程序创建一个入口:

  1. 创建静态IP: Gcloud计算地址创建sample-ip——global
  2. 创建入口(file): Kubectl应用- fingress.yaml
  3. 检查入口是否已经创建,并抓取IP: Kubectl进入-w
  4. 为您的应用程序创建域/子域.

CI/CD

让我们使用CircleCI创建一个CI/CD管道. 实际上, 使用CircleCI很容易创建CI/CD管道, 但是要记住, 一个不需要这样的测试的快速而又肮脏的全自动部署过程将适用于小型项目, 但请不要为了严肃的事这么做,因为, 如果任何新代码在生产中有问题, 你会赔钱的. 这就是为什么您应该考虑设计一个健壮的部署流程, 在全面推出之前启动金丝雀任务, 在金丝雀启动后检查日志中的错误, 等等.......

目前, 我们有一个小的, 简单的项目, 我们来创建一个全自动的, 没有测试, CI/CD部署流程. 首先,您应该将CircleCI集成到您的存储库中——您可以找到所有的指令 here. 然后,我们应该创建一个配置文件,其中包含CircleCI系统的说明. Config 看起来很简单. 重点是,在GitHub仓库中有两个分支: master and 生产.

  1. 主分支 是为了开发,为了新代码. 当有人将新代码推送到主分支时, CircleCI为主分支构建和测试代码启动一个工作流.
  2. 生产部门 是为了将新版本部署到生产环境中. 生产分支的工作流程如下:推送新代码(或者更好的代码), open PR from the master branch to 生产) to trigger a new build and 部署 process; during the build, CircleCI创建新的Docker镜像, pushes it to the GCR and creates a new rollout for the 部署; if the rollout fails, CircleCI触发回滚过程.

在运行任何构建之前,您应该在CircleCI中配置一个项目. 在API中创建一个新的服务帐户,并在GCloud中使用以下角色创建一个服务页面:完全访问GCR和GKE, 打开下载的JSON文件并复制内容, 然后在CircleCI的项目设置中创建一个新的环境变量 GCLOUD_SERVICE_KEY 并将服务帐户文件的内容粘贴为值. 此外,您需要创建下一个嫉妒: GOOGLE_PROJECT_ID (你可以在GCloud控制台主页上找到它), GOOGLE_COMPUTE_ZONE (用于GKE集群的区域),以及 GOOGLE_CLUSTER_NAME (GKE集群名称).

CircleCI的最后一步(部署)看起来像:

Kubectl补丁部署示例-p '{"spec":{"template":{"spec":{"容器":[{"name":"sample",“图像”:“gcr.io / test-d6bf8 /简单:“CIRCLE_SHA1美元 "'"}]}}}}'
if ! kubectl rollout status deploy/sample; then
  回显"部署失败,回滚到先前"
  Kubectl rollout undo deploy/sample
  # Deploy failed -> notify slack
else
  “部署成功,当前版本:${CIRCLE_SHA1}”
  # Deploy succeeded -> notify slack
fi
部署.扩展/样本补丁
等待部署“示例”rollout完成:3个新副本中有2个已经更新...
等待部署“示例”rollout完成:3个新副本中有2个已经更新...
等待部署“示例”rollout完成:3个新副本中有2个已经更新...
等待部署“示例”rollout完成:1个旧副本正在等待终止...
等待部署“示例”rollout完成:1个旧副本正在等待终止...
等待部署“示例”rollout完成:1个旧副本正在等待终止...
等待部署“示例”rollout完成:3个更新副本中有2个可用...
等待部署“示例”rollout完成:3个更新副本中有2个可用...
成功地推出了部署“示例”
部署成功,当前版本:512eabb11c463c5431a1af4ed0b9ebd23597ed9

结论

看起来创建新的Kubernetes集群的过程并不是那么难! CI/CD过程非常棒!

Yes! Kubernetes非常棒! 与Kubernetes, 你的系统会更稳定, 很容易管理, 让你成为你的系统的船长. 更不用说, Kubernetes将这个系统游戏化了一点,并将为你的营销加分100分!

现在你已经掌握了基础知识, 您可以进一步将其转换为更高级的配置. 我计划在以后的文章中介绍更多内容, 但与此同时, 这里有一个挑战:为您的应用程序创建一个健壮的Kubernetes集群,并在集群中放置一个有状态的DB(包括用于备份的sidecar Pod), 为CI/CD管道在同一个Kubernetes集群中安装Jenkins, 让詹金斯用豆荚做奴隶. 使用certmanager为您的入口添加/获取SSL证书. 使用Stackdriver为您的应用程序创建一个监视和警报系统.

Kubernetes很棒,因为它很容易扩展, 没有供应商锁定, and, 因为你要为实例付费, 你省钱了. 然而,并不是每个人都是 Kubernetes专家 或者有时间为另一个视图设置一个新的集群, Toptaler的同事Amin Shah Gilani提出了使用Heroku的理由, GitLab CI, 为了编写更多的代码,做更少的操作任务,他已经想出了大量的自动化 如何构建有效的初始部署管道.

了解基本知识

  • Docker是什么??

    Docker是开发人员/系统管理员/开发人员构建的工具, ship, 运行分布式应用程序, 是否在笔记本电脑上, 数据中心虚拟机, 或者是云.

  • Kubernetes是什么?

    Kubernetes是一个开源系统,它允许您管理容器化的工作负载(pod)和服务, 自动化部署, 规模部署, 创建和配置入口, 部署无状态或有状态应用程序, 还有很多其他的东西.

  • Kubernetes是用Go写的吗?

    是的,Docker也是用Go语言编写的.

  • 什么是Kubernetes pod /容器?

    pod是一起部署在同一主机上的一组容器. 如果豆荚有一个容器, 您一般可以将“pod”一词替换为“container”,并准确理解其概念.

  • 集装箱化是什么意思?

    应用程序容器化是一种操作系统级别的虚拟化方法,用于部署和运行分布式应用程序,而无需为每个应用程序启动整个虚拟机(VM).

  • 在生产环境中使用Kubernetes可以吗?

    Yes. 第一次释放是在四年前. 从那时起,Kubernetes已经成为一个强大而稳定的平台.

就这一主题咨询作者或专家.
预约电话
德米特里·科诺诺夫的头像
他在科诺诺夫

位于 吉尔吉斯斯坦比什凯克,

成员自 2018年5月31日

作者简介

Dmitriy是一名软件工程师,在web开发和DevOps方面拥有12年的经验. 他的专长是云服务, DevOps, 和Kubernetes, 专注于基础设施成本降低和大容量实例管理. 德米特里拥有吉尔吉斯国立技术大学计算机科学硕士学位.

Toptal作者都是各自领域经过审查的专家,并撰写他们有经验的主题. 我们所有的内容都经过同行评审,并由同一领域的Toptal专家验证.

工作经验

12

世界级的文章,每周发一次.

订阅意味着同意我们的 隐私政策

世界级的文章,每周发一次.

订阅意味着同意我们的 隐私政策

Toptal开发者

加入总冠军® 社区.