在本文中,我将介绍容器,解释Kubernetes,并教你如何使用CircleCI将应用程序容器化和部署到Kubernetes集群。
Docker?什么是Docker?

使用容器,开发人员可以轻松将镜像(重新)部署到任何操作系统。 只需安装Docker,执行命令,你的应用程序即可启动并运行。哦,不要担心主机操作系统中新版本库的任何不一致。此外,您可以在同一主机上启动很多容器——不管是相同的应用程序还是其他应用程序,都没关系。
看起来Docker是一个很棒的工具。但是我应该如何以及在何处启动容器?运行容器的方式有很多选择:
AWS Elastic Container Service(AWS Fargate或具有水平和垂直自动伸缩的预留实例);
Azure或Google Cloud中具有预定义Docker镜像的云实例(包含模板,实例组和自动缩放);
在你自己的服务器上;
当然还有Kubernetes!Kubernetes是2014年由Google工程师专门为虚拟化和容器创建的。
Kubernetes?那是什么?
那我为什么要用Kubernetes呢?
看起来很有前途,特别是如果它会省钱!让我们来谈谈它!
Kubernetes日复一日地更加受欢迎。让我们更深入地研究一下这幕后的内容。

Kubernetes是整个系统的名称,但与你的汽车一样,有许多小部件可以完美地彼此协同工作以使Kubernetes发挥其各种作用。让我们来了解它们分别是什么。
主节点(Master Node)——整个Kubernetes集群的控制面板。主节点的组件可以在群集中的任何节点上运行。关键组成部分是:
API Server:所有REST命令的入口点,是用户可以访问的主节点的唯一组件。
Datastore:Kubernetes群集使用的强大,一致且高可用的键值存储。
Scheduler:监视新创建的Pod并将它们分配给节点。Pod和Services部署到节点上主要由Scheduler来控制。
Controller manager:管理着处理集群中日常任务的所有控制器。
Worker Node:主要的节点代理,也称为minion(旧版本Kubernetes的叫法)。Pod在这里运行。工作节点包含所有必要的服务,这些服务包括管理容器之间的网络,与主节点通信以及将资源分配给已调度容器等。
Docker:运行在每个工作节点上,用来下载镜像和启动容器。
Kubelet:监视Pod的状态并确保容器已启动并运行。它还与数据存储通信,获取有关服务的信息并记录新创建的服务的详细信息。
Kube-proxy:单个工作节点上的服务的网络代理和负载均衡。它负责流量路由。
Kubectl:一个CLI工具,供用户与Kubernetes API Server进行通信。
那什么是Pod和Services?
Service是在多个Pod之上的抽象,通常需要在它上面有层代理,以便其他服务通过虚拟IP地址与其通信。
一个简单部署例子

我将使用简单的Ruby on Rails应用程序和GKE作为运行Kubernetes的平台。实际上,你可以在AWS或Azure中使用Kubernetes,甚至可以在你自己的硬件中创建集群,或使用你minikube在本地运行Kubernetes,所有的选项你都可以在这个页面Setup - Kubernetes[1]上找到。
这个app的源码你可以在GitHub - d-kononov/simple-rails-app-in-k8s[2]里找到。
要创建新的Rails应用程序,请执行:
rails new blog
在 config/database.yml文件中配置生产MySQL连接:
production:
adapter: mysql2
encoding: utf8
pool: 5
port: 3306
database: <%= ENV['DATABASE_NAME'] %>
host: 127.0.0.1
username: <%= ENV['DATABASE_USERNAME'] %>
password: <%= ENV['DATABASE_PASSWORD'] %>
创建Article model、controller、views和migration,请执行:
rails g scaffold Article title:string description:text
添加Gems到Gemfile:
gem 'mysql2', '< 0.6.0', '>= 0.4.4'
gem 'health_check'
创建Docker镜像,请下载Dockerfile[3],并执行:
docker build -t REPO_NAME/IMAGE_NAME:TAG . && docker push REPO_NAME/IMAGE_NAME:TAG
是时候创建一个Kubernetes集群了。打开GKE页面并创建Kubernetes集群。创建集群后,单击“连接”按钮并复制命令——确保你已安装和配置了 gCloud CLI工具(如何[4])和kubectl。在PC上执行复制的命令并检查与Kubernetes集群的连接;执行 kubectl cluster-info。
该应用程序已准备好部署到Kubernetes群集。让我们创建一个MySQL数据库。在gCloud控制台中打开SQL页面,为应用程序创建一个MySQL数据库实例。实例准备就绪后,创建用户和数据库并复制实例连接名称。
此外,我们需要在 API和服务页面中创建一个 service account密钥,以便从sidecar容器访问MySQL数据库。您可以在此处[5]找到有关该流程的更多信息。 将下载的文件重命名为 service-account.json。 我们稍后会用到这个文件。
我们准备将我们的应用程序部署到Kubernetes,但首先,我们应该为我们的应用程序创建 secret——在Kubernetes中创建用于存储敏感数据的secret对象。上传之前下载的 service-account.json文件:
kubectl create secret generic mysql-instance-credentials \
--from-file=credentials.json=service-account.json
为应用程序创建secrets:
kubectl create secret generic simple-app-secrets \
--from-literal=username=$MYSQL_PASSWORD \
--from-literal=password=$MYSQL_PASSWORD \
--from-literal=database-name=$MYSQL_DB_NAME \
--from-literal=secretkey=$SECRET_RAILS_KEY
请不要忘记替换必要的配置,或者记得正确地设置环境变量。
在创建deployment之前,让我们看一下deployment.yaml[6]。我把三个文件连成一个;第一部分是一个Service,它将公开端口80并转发到端口80和到3000的所有连接。该Service有一个selector,Service通过它知道哪个Pod应该转发连接。
该文件的下一部分是Deployment,它描述了将在Pod中启动的部署策略容器,环境变量,资源,探针,每个容器的mounts以及其他信息。
最后一部分是Horizontal Pod Autoscaler。HPA有一个非常简单的配置。请记住,如果您未在部署部分中为容器设置资源,则HPA将无法运行。
您可以在GKE编辑页面中为Kubernetes集群配置Vertical Autoscaler。它也有一个非常简单的配置。
是时候将它发布到GKE集群了!首先,我们通过rake-tasks-job.yaml[7]进行部署。 执行:
kubectl apply -f rake-tasks-job.yaml
这个Job对于CI/CD很有用。
kubectl apply -f deployment.yaml
上面这条命令用来创建Service、Deployment和HPA。
然后通过 kubectlgetpods-w命令来检查你的Pod:
NAME READY STATUS RESTARTS AGE
sample-799bf9fd9c-86cqf 2/2 Running 0 1m
sample-799bf9fd9c-887vv 2/2 Running 0 1m
sample-799bf9fd9c-pkscp 2/2 Running 0 1m
现在让我们为应用创建一个Ingress:
创建一个静态IP: gcloud compute addresses create sample-ip--global
创建Ingress: kubectl apply-f ingress.yaml
检查Ingress是否创建成功和查看它的IP地址: kubectlgetingress-w
为你的应用创建域名或者子域名
让我们使用CircleCI创建一个CI/CD管道。实际上,使用CircleCI创建CI/CD管道很容易,但请记住,快而脏的未经过测试的全自动部署过程仅适用于小型项目,但请不要在严肃的项目上这样做。如果任何新代码在生产中出现问题,那么你将会损失巨大。这就是为什么你应该考虑设计一个强大的部署过程,在完全推出之前启动canary任务,在canary启动后检查日志中的错误,等等。
目前,我们有一个简单的小项目,所以让我们创建一个完全自动化,无测试的CI/CD部署过程。首先,您应该将CircleCI与您的代码仓库进行集成——你可以在此处[8]找到具体内容。 然后我们应该创建一个包含CircleCI系统指令的配置文件。Config看起来很简单。要点是GitHub仓库中有两个分支:master和production。
主分支用于开发,用于新代码。当有人将新代码推送到主分支时,CircleCI启动主分支构建和测试代码的工作流。
生产分支用于将新版本部署到生产环境。生产分支的工作流程如下:推送新代码(如果从主分支到生产开放PR则更好)以触发新的构建和部署过程;在构建过程中,CircleCI创建新的Docker镜像,将其推送到GCR并创建新的部署;如果失败,CircleCI将触发回滚过程。
在运行任何构建之前,您应该在CircleCI中配置项目。在API和GCloud中的Service页面中创建一个新的service account,具有以下角色:完全访问GCR和GKE,打开下载的JSON文件并复制内容,然后在CircleCI的项目设置中创建一个新的环境变量GCLOUDSERVICEKEY并将service account文件的内容粘贴为值。 此外,您需要创建下一个env vars:GOOGLEPROJECTID(可以在GCloud控制台主页上找到它),GOOGLECOMPUTEZONE(GKE集群的区域)和GOOGLECLUSTERNAME(GKE集群名称)。
CircleCI的最后一步(部署)如下所示:
kubectl patch deployment sample -p '{"spec":{"template":{"spec":{"containers":[{"name":"sample","image":"gcr.io/test-d6bf8/simple:'"$CIRCLE_SHA1"'"} ] } } } }'
if ! kubectl rollout status deploy/sample; then
echo "DEPLOY FAILED, ROLLING BACK TO PREVIOUS"
kubectl rollout undo deploy/sample
# Deploy failed -> notify slack
else
echo "Deploy succeeded, current version: ${CIRCLE_SHA1}"
# Deploy succeeded -> notify slack
fi
deployment.extensions/sample patched
Waiting for deployment "sample" rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for deployment "sample" rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for deployment "sample" rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for deployment "sample" rollout to finish: 1 old replicas are pending termination...
Waiting for deployment "sample" rollout to finish: 1 old replicas are pending termination...
Waiting for deployment "sample" rollout to finish: 1 old replicas are pending termination...
Waiting for deployment "sample" rollout to finish: 2 of 3 updated replicas are available...
Waiting for deployment "sample" rollout to finish: 2 of 3 updated replicas are available...
deployment "sample" successfully rolled out
Deploy succeeded, current version: 512eabb11c463c5431a1af4ed0b9ebd23597edd9
总结
是!Kubernetes太棒了!使用Kubernetes,你的系统将更加稳定,易于管理,并使你成为系统的“船长”。更不用说,Kubernetes对系统施加了一些魔法,并为您的营销提供了+100分!
现在你已经掌握了基础知识,可以进一步将其转换为更高级的配置。我计划在以后的文章中介绍更多内容,但与此同时,有一个挑战:使用位于集群内的有状态数据库(包括用于备份的sidecar Pod)为应用程序创建一个强大的Kubernetes集群,在其中安装Jenkins用于CI/CD管道,让Jenkins使用Pod作为构建的slave。使用certmanager为Ingress添加/获取SSL证书。使用Stackdriver为应用程序创建监控和报警系统。
Kubernetes非常棒,因为它很容易扩展,没有供应商锁定,并且,因为你为实例付费,所以可以省钱。然而,不是每个人都是Kubernetes专家或者有时间建立一个新的集群。这里有一个可选方案:关于如何构建有效的初始部署管道并执行更少的操作任务,我的同事Toptaler Amin Shah Gilani使用Heroku,GitLab CI以及他能想到的其他自动化部署工具做了一套教程CI/CD:如何部署有效的初始化部署管道[9]。
相关链接:
https://kubernetes.io/docs/setup/
https://github.com/d-kononov/simple-rails-app-in-k8s
https://github.com/d-kononov/simple-rails-app-in-k8s/blob/master/Dockerfile
https://cloud.google.com/kubernetes-engine/docs/quickstart
https://cloud.google.com/sql/docs/mysql/connect-kubernetes-engine#2createaserviceaccount
https://github.com/d-kononov/simple-rails-app-in-k8s/blob/master/-kubernetes/deployment.yaml
https://github.com/d-kononov/simple-rails-app-in-k8s/blob/master/-kubernetes/rake-tasks-job.yaml
https://circleci.com/integrations/
https://www.toptal.com/devops/effective-ci-cd-deployment-pipeline
原文链接:https://www.toptal.com/kubernetes/what-is-kubernetes