Google Cloud Platform II:在Google Container Engine上持续部署Docker应用程序

We previously looked at how to deploy a Docker application to Google Cloud Platform (GCP) with Google Container Engine(GKE) using Kubernetes.

我们之前曾研究过如何使用Kubernetes使用Google Container Engine(GKE)将Docker应用程序部署到Google Cloud Platform(GCP)。

This gave us the opportunity to appreciate the role that Kubernetes plays in managing/orchestrating GKE clusters with ease.

这使我们有机会了解Kubernetes在轻松管理/协调GKE集群中所扮演的角色。

One thing that we missed out on was how deploying Docker containers pans out when working in a team that employs Continuous Integration / Continuous Deployment (CI/CD) where frequent updates of an application are made by each member of the team and, well, continously deployed to staging or production.

我们错过的一件事是,在使用持续集成/持续部署(CI / CD)的团队中工作时,部署Docker容器的工作如何顺利进行,该团队的每个成员都对应用程序进行频繁的更新,并且不断地部署到阶段或生产。

As you would imagine, things can quickly get out of hand when each team member individually pushes their own version of the image to the Google Container Registry.

就像您想象的那样,当每个团队成员将自己的图像版本分别推送到Google Container Registry时,事情很快就会失控。

The image tags may conflict, be out of date or buggy images may be pushed to production and the world as we know it would come to a stop.

图片标签可能会发生冲突,过时或有问题的图片可能会投入生产,而我们所知道的世界将会停止。

CircleCI的持续部署 ( Continuous Deployment with CircleCI )

CircleCI is one of the most popular CI/CD tools in use today alongside TravisCI and Codeship. We wil be using CircleCI to continuously deploy our application just like we would in a distributed team.

TravisCI和Codeship之外,CircleCI是当今使用最广泛的CI / CD工具之一。 我们将使用CircleCI来持续部署我们的应用程序 ,就像在分布式团队中一样。

To achieve this, we will do the following:

为此,我们将执行以下操作:

  • Write tests for our application.

    为我们的应用编写测试。
  • Configure CircleCI to authenticate with our GKE cluster.

    配置CircleCI以通过我们的GKE集群进行身份验证。
  • Add a circle.yml configuration file for the application deployment process.

    为应用程序部署过程添加一个circle.yml配置文件。
  • If the tests pass on CircleCI, update the containerized app to GKE.

    如果测试通过CircleCI,请将容器化的应用更新为GKE。

Sounds good? Sweet! Let's get started!

听起来不错? 甜! 让我们开始吧!

添加测试 ( Adding Tests )

We'll use supertest to test the routes in index.js in the test and mocha test framework to run the test.

我们将在测试和Mocha测试框架中使用supertest测试index.js中的路由以运行测试。

npm install --save-dev mocha supertest

Once installed, create test/index_test.js in the application route and add the test below.

安装后,在应用程序路由中创建test/index_test.js并在下面添加测试。

test/index_test.js

测试/ index_test.js

//Load supertest and the app instance.
const request = require('supertest');
const app = require('../index').app;

describe('Index Tests', () => {
    describe('GET /', () => {
        //Should return status code 200 with JSON message: welcome to root
        it('Should return root message', (done) => {
            request(app)
                .get('/')
                .expect(200)
                .expect(JSON.stringify('welcome to root'))
                .end(done);
        });
    });
});

The test makes a GET request to the root of our project and asserts that a JSON string is given back with a 200 status code. Add the test command in the scripts section of our package,json file.

该测试向我们项目的根目录发出GET请求,并断言返回了JSON字符串并带有200状态代码。 在我们的package,json文件的scripts部分中添加test命令。

package.json

package.json

...
"scripts": {
    "test": "node_modules/.bin/mocha",
    "start": "node index.js"
  },
...

View the test result by running npm test. You should get the following.

通过运行npm test查看测试结果。 您应该获得以下内容。

Test result

整合CircleCI (Integrating CircleCI)

With our tests passing, let's add a circle.yml file and instruct CircleCI how to run our tests using mocha. Luckily, every CircleCI build comes preinstalled with mocha so all we need to do is instruct it to use mocha.

通过测试之后,让我们添加一个circle.yml文件,并指示CircleCI如何使用mocha运行我们的测试。 幸运的是,每个CircleCI构建都预装了Mocha,因此我们需要做的就是指示它使用Mocha。

Note that by default, CircleCI will try to run npm test.

请注意,默认情况下,CircleCI将尝试运行npm test

test:
    override:
    - mocha

将项目添加到CircleCI (Add Project to CircleCI)

Once everything is set up, push the code to a Gihub repository, login to CircleCI with Github then go to CircleCI > Add Projects and build your repository. If everything is correctly set up, you should have a succesful build.

一切设置完成后,将代码推送到Gihub存储库,使用Github登录到CircleCI,然后转到CircleCI>添加项目并构建您的存储库。 如果一切设置正确,则应该成功完成构建。

CircleCI build

With this, let's make CircleCI do all the heavy lifting for us.

这样,让CircleCI为我们完成所有繁重的工作。

在CircleCI上验证GKE集群 ( Authenticating The GKE Cluster on CircleCI )

The objective of this section is to simply let CircleCI know that we own the scotch-cluster. When creating the Deployments and Services locally, we followed the following protocol:

本节的目的是简单地让CircleCI知道我们拥有scotch scotch-cluster 。 在本地创建部署和服务时,我们遵循以下协议:

  • Login to Google - Using the gcloud init in the initial setup or gcloud auth login later on.

    登录到gcloud init在初始设置中使用gcloud init或稍后再使用gcloud auth login
  • Set the default project - gcloud config set project scotch-155622

    设置默认项目gcloud config set project scotch-155622
  • Set the default cluster - gcloud config set container/cluster scotch-cluster

    设置默认集群gcloud config set container/cluster scotch-cluster
  • Get the cluster credentials - gcloud container clusters get-credentials scotch-cluster --zone us-central1-a --project scotch-155622

    获取集群凭证gcloud container clusters get-credentials scotch-cluster --zone us-central1-a --project scotch-155622
  • Gone ahead to be awesome.

    变得很棒。

But how do we authenticate CircleCI? We cannot exactly use gcloud auth login can we? That would mean allowing access to our gmail accounts. Sounds wrong, doesn't it?

但是我们如何认证CircleCI? 我们不能完全使用gcloud auth login吗? 那意味着允许访问我们的Gmail帐户。 听起来不对,不是吗?

And it is! Gladly, Google Cloud Platform provides Service Accounts which come in handy.

是的! 很高兴地,Google Cloud Platform提供了方便的服务帐户

A service account is a special account that can be used by services and applications running on your Google Compute Engine instance to interact with other Google Cloud Platform APIs. Applications can use service account credentials to authorize themselves to a set of APIs and perform actions within the permissions granted to the service account and virtual machine instance.

服务帐户是一个特殊帐户,供您在Google Compute Engine实例上运行的服务和应用程序用来与其他Google Cloud Platform API进行交互的帐户。 应用程序可以使用服务帐户凭据来授权自己使用一组API,并在授予服务帐户和虚拟机实例的权限内执行操作。

Let's set up our service account!

让我们设置我们的服务帐户!

生成服务帐户 (Generating a Service Account)

To create a new service account, go to the Service Accounts Page and select your project. You will be required to generate a Service account ID / email here. Go ahead and enter a name for the account and select a role for the service account, in our case, Service Account Actor.

要创建一个新的服务帐户,请转到“ 服务帐户”页面并选择您的项目。 您将需要在此处生成服务帐户ID /电子邮件。 继续,输入帐户名称,然后选择服务帐户的角色,在本例中为Service Account Actor

Service Accounts page

You can also create a service account ID using the gcloud command.

您还可以使用gcloud命令创建服务帐户ID。

gcloud iam service-accounts create scotch-sa --display-name"Scotch Service Account"

Once the service account is created, a JSON file will be downloaded to your local system. We will use that in the next section.

创建服务帐户后,会将JSON文件下载到您的本地系统。 我们将在下一部分中使用它。

环境变量 (Environment Variables)

It's always easier to set up frequently used data as environment variables in any project. Better yet, if some of these variables are sensitive, like our service account token, they are best stored away from our codebase.

在任何项目中,将常用数据设置为环境变量总是更容易。 更好的是,如果其中一些变量是敏感的,例如我们的服务帐户令牌,则最好将其存储在远离我们的代码库的位置。

To get started, let's add the project ID, cluster name, deployment name, container name and the compute zone of our cluster in circle.yml, these are the less sensitive details we can afford to add our configuration file.

首先,让我们在circle.yml添加项目ID,集群名称,部署名称,容器名称和集群的计算区域,这些是我们可以负担得起的添加配置文件的较不敏感的细节。

circle.yml

circle.yml

machine:
  environment:
    PROJECT_ID: scotch-155622
    CLUSTER_NAME: scotch-cluster
    COMPUTE_ZONE: us-central1-a
    #As specified in Deployment.yml
    DEPLOYMENT_NAME: scotch-dep
    CONTAINER_NAME: node-app

test:
    override:
    - mocha

Simple and neat.

简单而整洁。

Now to store the service account JSON file as an environment variable. It would be catastrophic if we decided to add it in the publicly accessible circle.yml file. Lucky for us, CircleCI allows us to set environment variables for each project.

现在将服务帐户JSON文件存储为环境变量。 如果我们决定将其添加到可公开访问的circle.yml文件中,将是灾难性的。 对我们来说幸运的是,CircleCI允许我们为每个项目设置环境变量。

First, let's encode our JSON file into base64 format so that we can store it as a string. For Linux and OS X users, run the following command to decode and copy the encoded string:

首先,让我们将JSON文件编码为base64格式,以便我们可以将其存储为字符串。 对于Linux和OS X用户,运行以下命令以解码和复制编码的字符串:

base64 scotch-2efb8709c63d.json| pbcopy

Next, go to CircleCI > Builds > Repository settings > Environment Variables > Add Variable and add the service key and Account ID.

接下来,转到CircleCI>构建>存储库设置>环境变量>添加变量,然后添加服务密钥和帐户ID。

CircleCI environment variable

We now have access to $SERVICE_KEY and $ACCOUNT_ID in our CircleCI build.

现在,我们可以在CircleCI版本中访问$SERVICE_KEY$ACCOUNT_ID

提供我们的部署环境 (PROVISIONING OUR DEPLOYMENT ENVIRONMENT)

Just like we did in our local environment, we need to make sure that gcloud and kubectl command-line tools are installed as well as good old Docker. Once again, CircleCI comes pre-installed with both, we just have to make sure they are up to date before we do anything.

就像我们在本地环境中所做的一样,我们需要确保已安装gcloudkubectl命令行工具以及良好的旧Docker。 再一次,CircleCI都预装了两者,我们只需要确保它们是最新的就可以进行任何操作。

Once they are updated, We need to:-

更新后,我们需要:-

  • Check for any changes in the deployment branch (master in our case)

    检查部署分支中的任何更改(在本例中为master
  • Decode the service account and authenticate the build

    解码服务帐户并验证构建
  • Set the default project, cluster and compute zone

    设置默认项目,群集和计算区域
  • Get the credentials for the scotch-cluster

    获取scotch-cluster的凭据
  • Start Docker

    启动Docker

circle.yml

circle.yml

machine:
  environment:
    PROJECT_ID: scotch-155622
    CLUSTER_NAME: scotch-cluster
    COMPUTE_ZONE: us-central1-a
    #As specified in Deployment.yml
    DEPLOYMENT_NAME: scotch-dep
    CONTAINER_NAME: node-app

test:
    override:
    - mocha

#Ensure that gcloud and kubectl are updated.
dependencies:
  pre:
    - sudo /opt/google-cloud-sdk/bin/gcloud --quiet components update --version 120.0.0
    - sudo /opt/google-cloud-sdk/bin/gcloud --quiet components update --version 120.0.0 kubectl

deployment:
    production:
        branch: master
        commands:
        # Save the string to a text file
        - echo $SERVICE_KEY > key.txt
        # Decode the Service Account
        - base64 -i key.txt -d > ${HOME}/gcloud-service-key.json
        # Authenticate CircleCI with the service account file
        - sudo /opt/google-cloud-sdk/bin/gcloud auth activate-service-account ${ACCOUNT_ID} --key-file ${HOME}/gcloud-service-key.json
        # Set the default project
        - sudo /opt/google-cloud-sdk/bin/gcloud config set project $PROJECT_ID
        # Set the default container
        - sudo /opt/google-cloud-sdk/bin/gcloud --quiet config set container/cluster $CLUSTER_NAME
        # Set the compute zone
        - sudo /opt/google-cloud-sdk/bin/gcloud config set compute/zone $COMPUTE_ZONE
        # Get the cluster credentials.
        - sudo /opt/google-cloud-sdk/bin/gcloud --quiet container clusters get-credentials $CLUSTER_NAME
        # Start good old Docker
        - sudo service docker start

推出应用程序更新 ( Rolling Out Application Updates )

更新circle.yml配置 (Updating circle.yml configuration)

For those of us with a hankering to finally get to the good stuff, welcome to Docker town! We are about to get this container rolling. Up until now, we have been preparing our Continous Deployment environment but we are yet to actually even build an image. Fret not!

对于那些渴望最终获得好东西的人,欢迎来到Docker小镇! 我们将使这个容器滚动。 到目前为止,我们一直在准备我们的持续部署环境,但实际上还没有建立映像。 不用担心!

If you recall where we last left things, when deploying from our local system, the last step of our journey involves the following:

如果您还记得我们最后剩下的东西,那么从本地系统进行部署时,旅程的最后一步涉及以下内容:

  • Building a Docker image from our application and correctly tagging it.

    从我们的应用程序构建一个Docker映像并正确标记它。
  • Pushing the Docker image to the GCP Container Registry.

    将Docker映像推送到GCP容器注册表。

Well let's add one more step to that grand process. Once a new image is pushed, we will need to set it as the latest image from which our Docker container, the Kubernetes Deployment is run from.

好吧,让我们在这一宏伟的过程中再增加一步。 推送新映像后,我们需要将其设置为运行Docker容器Kubernetes Deployment的最新映像。

Note that we are using $CIRCLE_SHA1 which is CircleCI's environment variable of the latest git commit hash since it will always be unique. You can however adopt any tagging model that your team fancies such as Semantic Versioning.

请注意,我们使用的是$CIRCLE_SHA1 ,它是CircleCI最新git commit哈希的环境变量,因为它始终是唯一的。 但是,您可以采用团队喜欢的任何标记模型,例如语义版本控制。

Here is a look at the final circle.yml configuration in the commands section

这是命令部分的最后一个circle.yml配置

dependencies:
    .
    .
    .
       # Build a Docker image and use the Github commit hash ($CIRCLE_SHA1) as the tag
       - docker build -t gcr.io/${PROJECT_ID}/node-app:$CIRCLE_SHA1 .
       # Push the Image to the GCP Container Registry
       - sudo /opt/google-cloud-sdk/bin/gcloud docker -- push gcr.io/${PROJECT_ID}/node-app:$CIRCLE_SHA1
        # Update the default image for the deployment
        - sudo /opt/google-cloud-sdk/bin/kubectl set image deployment/${DEPLOYMENT_NAME} ${CONTAINER_NAME}=gcr.io/${PROJECT_ID}/node-app:$CIRCLE_SHA1

This will recreate the pods and ensure the user has the most updated application running without any impact or downtime on their side. This is achieved by destroying one pod at a time before moving on to the next one.

这将重新创建Pod,并确保用户正在运行最新的应用程序,而不会对其造成任何影响或停机。 这是通过一次摧毁一个吊舱,然后再移至下一个吊舱来实现的。

Here is a snapshot of the pods recreation process. Notice how fast the pods come alive!

这是豆荚休闲过程的快照。 请注意豆荚存活的速度!

Pods recreation

进行应用程序更新 (Making an application update)

To see the update in action, let's add a new route in our application.

要查看实际的更新,让我们在应用程序中添加一条新路由。

index.js

index.js

...
app.get('/baz', (req, res) => {
  res.status(200).json('Baz!');
});
...

Commit the changes and push to Github. Once the CircleCI build is succesful, visit the /baz route.

提交更改并推送到Github。 一旦CircleCI构建成功,请访问/ baz路线。

GKE image update

Works like a charm!

奇迹般有效!

Take a look at the Container Registry, and you'll notice that we have a swanky new image with a newer tag.

看一下Container Registry,您会注意到我们有一个带有新标签的时髦新图像。

GKE Container Registry update

结论 ( Conclusion )

In this article, we were able to continously deploy our containerized application with CircleCI builds to Google Cloud Platform's Google Container Engine (GKE) with ease. There is still alot more out there to learn on GCP.

在本文中,我们能够轻松地将CircleCI构建的容器化应用程序连续部署到Google Cloud Platform的Google Container Engine(GKE)。 关于GCP的知识还有很多。

Go forth and conquer!

来征服!

翻译自: https://scotch.io/tutorials/google-cloud-platform-ii-continuously-deploying-a-docker-application-on-google-container-engine

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值