写在前面

牢牢占据容器技术统治地位的 Kubernetes,其重要性想必不言而喻,我保证本文是最详尽的 Kubernetes 技术文档,从我在后台排版了这么漫长的时间就能看出来。废话不多说 — —

以下为译文:

为什么银行肯花大价钱雇我做 Kubernetes 如此简单的工作?——我一直很奇怪这一点,因为我觉得任何人都可以在 3 个小时内学会这项技术。

如果你怀疑我说的,就来挑战一下吧!读完本文,你绝对可以学会如何在 Kubernetes 集群上运行基于微服务的应用程序。我保证你可以做到,因为我就是这样向我的客户介绍 Kubernetes 的。

本文的教程与其他资源有何不同?有很大不同。大多数的教程都从最简单的内容讲起:Kubernetes 的概念和 kubectl 的命令。本文则是基于读者了解应用程序的开发、微服务和 Docker 容器等基础之上。

本文中,我们会涉及的内容包括:

  • 在计算机上运行基于微服务的应用程序;
  • 为微服务应用程序的每个服务建立容器映像;
  • Kubernetes 的基本介绍;
  • 在 Kubernetes 管理的集群内部署基于微服务的应用程序。

通过一步步深入学习,让大家能够领会 Kubernetes 的简单易用。只有你了解它的使用环境时,才能轻松掌握 Kubernetes。废话不多说,我们开始吧。

应用程序示范

如下应用程序有一个功能:每次输入接受一个句子;使用文本分析,计算句子所表达的情绪。

图1:情感分析网络应用

从技术的角度看来,这个应用程序包含 3 个微服务,每个都包含特定功能:

  • SA-Frontend:前端, Nginx 网络服务器,提供 ReactJS 静态文件;
  • SA-WebAp:网络应用, Java 网络应用程序,处理来自前端的请求;
  • SA-Logic:逻辑处理, Python 应用程序,执行情感分析。

你需要知道微服务是无法独立工作的,它们引入了“关注点分离”(separation of concerns),但是它们之间依然需要交互。

图2:情感分析网络应用中的数据流

我们可以通过微服务之间的数据流来描述这种交互:

  • 客户端应用程序请求初始页面 index.html(index.html 页面会反过来加载 ReactJS 应用程序的脚本);
  • 用户与应用程序的交互触发到 Spring 网络应用的请求;
  • Spring 网络应用将请求发送给 Python 应用做情感分析;
  • Python 应用计算情感值,并返回结果;
  • Spring 网络应用将结果返回给 React 应用(然后由 React 应用将结果显示给用户)。

点击此处下载这些应用程序的代码:https://github.com/rinormaloku/k8s-mastery。现在就可以克隆这个代码仓库,接下来我们要做更加精彩的东西。

在计算机上运行基于微服务的应用程序

我们需要启动所需的 3 个服务。让我们从最有意思的部分——前端应用程序开始。

设置 React 的本地部署

为了运行 React 应用程序,首先你需要在计算机上安装 NodeJS 和 NPM。安装好这些后,在终端中进入目录 sa-frontend。然后运行如下命令:

npm install

该命令会将 React 应用程序的所有 Javascript 依赖都下载到文件夹 node_modules 中(package.json 文件中定义了所有依赖)。在所有依赖都解决后,运行如下命令:

npm start

这样就可以了!我们运行了 React 应用程序,现在可以通过默认端口 localhost:3000 访问该应用程序了。你可以自由修改代码,并从浏览器中观察即时效果。这里用到了热模块替换(即在运行时用替换模块来减少页面刷新次数)技术,可以减轻前端开发的工作。

准备好 React 应用的产品环境

为了搭建产品环境,我们需要建立应用程序的静态网页,并通过网络服务器提供服务。

为了搭建 React 应用程序,首先在终端中进入目录 sa-frontend。然后运行如下命令:

npm run build

该命令会在项目的文件目录中生成一个名叫“build”的文件夹。该文件夹内包含了 ReactJS 应用程序所需的所有静态文件。

利用 Nginx 提供静态文件

首先安装并启动 Nginx 网络服务器。然后将 sa-frontend/build 目录内的文件移动到 [nginx安装目录]/html。

如此一来,我们就可以通过 [nginx安装目录]/html/index.html 来访问 index.html 文件了,而它是 Nginx 服务的默认文件。

默认情况下,Nginx 网络服务器会监听端口 80。你可以通过修改 [nginx安装目录]/conf/nginx.conf 文件中的 server.listen 字段来指定不同的端口。

打开浏览器,并访问端口 80,可以看到 ReactJS 应用程序加载成功。

图3:Nginx 提供的 React 应用程序服务

在输入框“Type your sentence”(输入句子)中输入句子,然后点击 SEND(发送)按钮,但是页面会返回错误 404(你可以检查浏览器的控制台)。为什么?让我们检查一下代码。

检查代码

我们可以在 App.js 文件中看到,点击“SEND”按钮会触发 analyzeSentence。该方法的代码如下所示(我们对每一段代码进行了编号“#号码”,具体解释如下所示):

analyzeSentence() {
    fetch('http://localhost:8080/sentiment', {  // #1
        method: 'POST',
        headers: {
            'Content-Type': 'application/json'
        },
        body: JSON.stringify({
                       sentence: this.textField.getValue()})// #2
    })
        .then(response => response.json())
        .then(data => this.setState(data));  // #3
}

#1:POST 方法调用的 URL(应用程序应该在该 URL 上监听访问);

#2:发送到应用程序的请求主体如下所示:

{
    sentence: “I like yogobella!”
}

#3:返回值将更新该组件的状态,而状态的变更将重新渲染这个组件。如果我们收到数据(即包含用户输入的句子和极性的 JSON 对象),那么我们会显示组件 polarityComponent,因为满足条件而且我们可以如下定义该组件:

const polarityComponent = this.state.polarity !== undefined ?
    <Polarity sentence={this.state.sentence}
              polarity={this.state.polarity}/> :
    null;

一切看起来都很好。但是我们还差什么呢?你可能已经发现我们没有在 localhost:8080 上设置任何东西!我们必须启动 Spring 网络应用程序监听这个端口!

图4:缺失的 Spring 网络应用程序微服务

建立 Spring 网络应用程序

为了设置 Spring 网络应用程序,你必须安装 JDK8 和 Maven,并设置它们的环境变量。设置好后,我们继续下个部分。

将应用程序打包成 Jar 文件

在终端中进入 sa-webapp 目录,并运行如下命令:

mvn install

该命令会在目录 sa-webapp 中生成一个名叫 target 的文件夹。target 文件夹内有打包好的 Java 应用程序包:’sentiment-analysis-web-0.0.1-SNAPSHOT.jar’。

启动应用程序

进入 target 目录,并通过如下命令启动应用程序:

java -jar sentiment-analysis-web-0.0.1-SNAPSHOT.jar

等等……出错了。应用程序启动失败,我们可以看到如下异常信息:

Error creating bean with name 'sentimentController': Injection of autowired dependencies failed; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'sa.logic.api.url' in value "${sa.logic.api.url}"

这里显示的重要信息是 SentimentController 中的 sa.logic.api.url。我们检查一下这段代码。

检查代码

@CrossOrigin(origins = "*")
@RestController
public class SentimentController {
@Value("${sa.logic.api.url}")    // #1
    private String saLogicApiUrl;
@PostMapping("/sentiment")
    public SentimentDto sentimentAnalysis(
                            @RequestBody SentenceDto sentenceDto) {
        RestTemplate restTemplate = new RestTemplate();
return restTemplate.postForEntity(
                saLogicApiUrl + "/analyse/sentiment",    // #2
                sentenceDto, SentimentDto.class)
                .getBody();
    }
}

#1:SentimentController 有一个名叫 saLogicApiUrl 的字段。这个字段的赋值是由 sa.logic.api.url 属性定义的。
#2:saLogicApiUrl 与值“/analyse/sentiment”连接在一起,共同构成了 Sentiment Analysis 请求的 URL。

定义属性

在 Spring 中默认的属性资源是 application.properties(具体位置在 sa-webapp/src/main/resources 中)。但是这不是定义属性的唯一方式,我们可以通过之前的命令完成属性定义:

java -jar sentiment-analysis-web-0.0.1-SNAPSHOT.jar  --sa.logic.api.url=WHAT.IS.THE.SA.LOGIC.API.URL

应该由 Python 应用程序运行时定义的值初始化该属性,如此一来 Spring 网络应用程序就可以知道在运行时把信息传递到哪里了。

为了简单起见,我们假设在 localhost:5000 上运行 Python 应用程序。请记得哦!

运行如下命令,然后我们来看看最后一个服务:Python 应用程序。

java -jar sentiment-analysis-web-0.0.1-SNAPSHOT.jar   --sa.logic.api.url=http://localhost:5000

图5:缺失的 Python 网络应用程序微服务

建立 Python 应用程序

为了启动 Python 应用程序,首先我们需要安装 Python3 和 Pip,以及设置它们的环境变量。

安装依赖

在终端中进入 sa-logic/sa (代码库),然后运行如下命令:

python -m pip install -r requirements.txt
python -m textblob.download_corpora

启动应用

在利用 Pip 安装好依赖后,我们就可以通过运行如下命令启动应用程序了:

python sentiment_analysis.py
* Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)

这意味着应用程序已经启动,并在 localhost 的端口 5000 上监听 HTTP 请求了。

检查代码

让我们检查代码,看看处理逻辑部分的 Python 应用程序在干什么:

from textblob import TextBlob
from flask import Flask, request, jsonify
app = Flask(__name__)                                   #1
@app.route("/analyse/sentiment", methods=['POST'])      #2
def analyse_sentiment():
    sentence = request.get_json()['sentence']           #3
    polarity = TextBlob(sentence).sentences[0].polarity #4
    return jsonify(                                     #5
        sentence=sentence,
        polarity=polarity
    )
if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)                #6 

#1:实例化一个 Flask 对象;
#2:定义 POST 请求访问的路径;
#3:从请求主体内抽出“sentence”属性;
#4:初始化匿名 TextBlob 对象,并从第一个句子(我们只有一个)中获取极性;
#5:在相应体内返回句子和极性;
#6:运行 flask 对象应用来监听 localhost:5000 上的请求。

所有的服务都设置好,可以互相交流了。试试看重开前端的 localhost:80。

图6:微服务架构完成

运行效果:

在下面一节中,我们将介绍如何在 Docker 容器内启动这些服务,因为这是在 Kubernetes 集群内运行这些服务的前提条件。

来自:CSDN(微信号:CSDNnews),作者:Rinor Maloku,译者:弯月,责编:郭芮

【三小时学会Kubernetes!(零) 】系统结构及相关示例微服务介绍的更多相关文章

  1. 三小时学会Kubernetes:容器编排详细指南

    三小时学会Kubernetes:容器编排详细指南 如果谁都可以在三个小时内学会Kubernetes,银行为何要为这么简单的东西付一大笔钱? 如果你心存疑虑,我建议你不妨跟着我试一试!在完成本文的学习后 ...

  2. [转载]三小时学会Kubernetes:容器编排详细指南

    原翻译by梁晓勇 原英文:Learn Kubernetes in Under 3 Hours: A Detailed Guide to Orchestrating Containers 我很奇怪,为什 ...

  3. 【三小时学会Kubernetes!(五) 】完成整个架构

    完成整个架构 现在我们学习了完成架构的所有必须的资源,因此这一节会非常快.图 22 中灰色的部分是需要做的事情.让我们从底部开始:部署 sa-logic 的部署. 图 22:当前应用程序状态 部署 S ...

  4. 【三小时学会Kubernetes!(二) 】Kubernetes 简介及Pod实践

    Kubernetes 简介 我向你保证我没有夸大其词,读完本文你会问“为什么我们不称它为 Supernetes?” Kubernetes 是什么? 从容器启动微服务后,我们有一个问题,让我们通过如下问 ...

  5. 【三小时学会Kubernetes!(四) 】Deployment实践

    Deployment 部署 Kubernetes 部署可以帮助每一个应用程序的生命都保持相同的一点:那就是变化.此外,只有挂掉的应用程序才会一尘不变,否则,新的需求会源源不断地涌现,更多代码会被开发出 ...

  6. 【三小时学会Kubernetes!(三) 】Service实践

    服务Service Kubernetes 服务资源可以作为一组提供相同服务的 Pod 的入口.这个资源肩负发现服务和平衡 Pod 之间负荷的重任,如图 16 所示. 图16:Kubernetes 服务 ...

  7. 【三小时学会Kubernetes!(一) 】容器简介及为每个服务创建镜像

    容器是什么 Kubernetes 是容器管理平台.可想而知我们需要容器去管理它们.但是容器是什么?Docker 官方文档的最佳答案如下: 容器映像是轻量级的.独立的.可执行软件包,包含所有可运行的东西 ...

  8. 三小时攻克 Kubernetes!

    我保证本文是最详尽的 Kubernetes 技术文档,从我在后台排版了这么漫长的时间就能看出来.废话不多说——牢牢占据容器技术统治地位的 Kubernetes,其重要性想必不言而喻. 以下为译文: 为 ...

  9. 【架构】Kubernetes和Spring Cloud哪个部署微服务更好?

    Spring Cloud 和Kubernetes都自称自己是部署和运行微服务的最好环境,但是它们在本质上和解决不同问题上是有很大差异的.在本文中,我们将看到每个平台如何帮助交付基于微服务的架构(MSA ...

随机推荐

  1. 你没见过的python语法

    目录: 1.不一样的列表 2.改变type中的规则,创建类:类属性大写 3.%s字串格式化,不用元组用字典 4.没有参数抛出异常 5.字符串签名加f 格式化字符串 6.attr库 1.不一样的列表 l ...

  2. FB05付款清帐Function

    函数组:FIPI-->内部FI过帐接口1.CALL FUNCTION 'POSTING_INTERFACE_START'. -->Initial information for inter ...

  3. win下如何解决在chrome的同源访问问题

    引子:本来是想验证如果在网页中包含多个框架,那么就会存在两个以上的不同全局环境,如果从一个框架引用另一个框架的数据比如数组a,那么用 instanceof 判断这个数组a是不是另个框架Array的实例 ...

  4. Selenium IDE界面学习

  5. ITL(Interested Transaction List)理解

    一.ITL描述: ITL(Interested Transaction List)是Oracle数据块内部的一个组成部分,位于数据块头(block header),itl由xid,uba,flag,l ...

  6. extern,头文件和ifndif宏

    转自:CSDN->fpmystar 用#include可以包含其他头文件中变量.函数的声明,为什么还要extern关键字,如果我想引用一个全局变量或函数f(),我只要直接在源文件中包含#incl ...

  7. Hadoop RPC实例

    本文发表于本人博客. 上次写了个hadoop伪分布环境搭建的笔记了,今天来说下hadoop分布式构建的基础RPC,这个RPC在提交Job任务的时候底层就是创建了RPC来实现远程过程调用服务端. 我们首 ...

  8. window7主题破解与恢复(复制)

    window7主题破解与恢复 1 2 3 分步阅读 windows7主题破解后可以换自己喜欢的主题,但也有一些弊端.这里帮助打家破解与恢复. 工具/原料 UniversalThemePatcher.e ...

  9. [笔记] Python实现全排列算法

    所谓全排列,就是给定数组,将所有的可能排列组合都枚举出来,n个元素共有n!种排列组合. 举例,对于['1', '2', '3'],全排列结果为:123,132,213,231,312,321,共有3! ...

  10. 两句话,实现android 4.4以上实现沉浸式状态栏

    效果图如下,就是状态栏和actionbar保持一致的颜色,非常漂亮 1:在Activity的OnCreate函数 if (Build.VERSION.SDK_INT >= Build.VERSI ...