Kubernetes
Kubernetes(k8s)由Google创建,现已成为最受欢迎的开源编排系统,用于管理多个主机容器化应用,提供了为分布式系统构建和部署可伸缩且可靠的应用程序所需的机制。我们正处在一个时代,服务的正常运行时间必须接近99.9%,要实现这一点,就必须拥有一种机制,即使存在系统崩溃,它们也不能失败。这些类型的系统必须具有某些特性,必须在某些意外发生的时候,工作负载可以在简单维护或部署的情况下进行扩展,停机时间必须为零。
Kubernetes上的Flink部署
可以使用会话集群或作业集群两种模式将Apache Flink部署在Kubernetes上。会话集群是一个运行中的独立集群,可以运行多个作业,Kubernetes的视角来看,会话集群由三个组件组成:
- 指定JobManager的部署对象
- 指定TaskManager的部署对象
- 以及公开JobManager的REST API的Service对象
作业集群为每个作业部署专用集群。
在下一节中,我们将讨论有关Kubernetes的一些基本概念。
Pod
Pod是可以在Kubernetes中创建和管理的最小的可部署计算单元。
Pod是容器的集合,可能包含一个或多个共享名称空间,卷和网络堆栈的应用程序。容器之间是紧密耦合的,因为它们共享网络堆栈,因此可以使用本地主机相互通信。
部署在其他Pod中的容器无法使用本地主机进行通信,因为它们具有不同的IP地址,并且应该使用Pod IP地址进行交互。
您可以在Kubernetes网站上找到有关Pod的更多详细信息。
ReplicaSets
ReplicaSet的目的是维持在任何给定时间运行的稳定的副本Pod集。因此,它通常用于保证指定数量的相同Pod的可用性。
ReplicaSet使管理和确保运行预定数量的复制Pod的工作更加轻松,而无需创建Pod的手动副本,从而避免了时间和错误。由ReplicaSets管理的Pod可能会失败,并且新实例将自动重新安排。
您可以在Kubernetes网站上找到有关副本集的更多详细信息。
Service
将运行在一组Pod上的应用程序公开为网络服务的抽象方法。
由于Kubernetes是一个动态系统,可以调度新Pod或缩小Pod的规模,甚至禁用它们,因此Pod被认为是短暂的。每个Pod都有一个IP地址,该地址在Pod死亡的整个时间(如果由控制器进行管理)都会更改,这意味着与该Pod交互的所有服务都必须更新IP,否则对该服务的请求将失败。
解决此类问题的必要措施是进行服务发现,以解决查找在服务正常工作的给定地址处侦听的进程的问题。
Kubernetes使用Service对象解决了这个问题,该对象定义了一个标签选择器,并且属于该服务的Pod具有该标签。这意味着分配给服务的IP地址不会随时间变化。
您可以在Kubernetes网站上找到有关该服务的更多详细信息。
Deployments
部署为Pod和ReplicaSet提供声明性更新。
使用Deployment对象,您可以有效地管理发布过程,而不会造成停机或错误。部署由在Kubernetes集群上运行的名为部署控制器的服务控制。
您可以在Kubernetes网站上找到有关部署的更多详细信息。
在Kubernetes上创建Flink集群
现在该安装Kubernetes集群了。首先需要安装Minikube,它将在虚拟机内部运行单节点Kubernetes集群。
除了Minikube之外,您还需要命令行工具Kubectl,它允许您对Kubernetes集群运行命令。但是,如果您在Minikube中遇到问题,则可能有必要在Minikube中使用HTTP/HTTPS代理。
如示例1中所示启动集群。
minikube start命令是从下载启动镜像并启动Virtualbox VM开始的。注意:在我们的示例VirtualBox中,必须指定Minikube将使用哪个VM驱动程序,如果要使用其他驱动程序,可以执行以下命令:
minikube start — vm-driver=<driver_name>
Minikube是使用Kubernetes版本v1.17.3启动的,但您可以自由配置该版本以外的版本:
minikube start — kubernetes-version <kubernetes_version>.
运行我们的Flink会话集群
使用会话集群对于使用不同的Kubernetes资源是必要的,如上所述,这是必需的:
- 指定JobManager的部署对象
- 指定TaskManager的部署对象
- 以及公开JobManager的REST API的Service对象
让我们从1)开始,并创建一个部署对象以实例化JobManager。
此部署对象使用容器镜像Flink-1.10.0 创建单个JobManager,并公开用于RPC通信的容器端口,blob服务器,用于可查询状态服务器和Web UI。
移至2)将创建部署对象以实例化TaskManager。
TaskManager部署指定两个实例,这些实例可用于运行JobManager计划的作业。 Docker容器镜像与JobManager相同,并且启动工作程序的命令与JobManager的启动不同。
最后,3)创建了服务对象,该对象在我们的集群中非常重要,因为它将JobManager暴露给TaskManager,否则,工作Pod将无法连接到主控制Pod。
您可能已经注意到,服务类型定义为NodePort,这是由于我们想在Kubernetes集群外部与JobManager进行交互而添加的。
是时候启动我们的Flink集群了,为此,我们将上面构建的定义添加到Kubernetes,执行以下命令:
kubectl create -f jobmanager.yaml
kubectl create -f jobmanager-service.yaml
kubectl create -f taskmanger.yaml
要查看部署状态:
kubectl get deployments
检查Pod的启动状态:
kubectl get pods
现在我们的Kubernetes集群运行Flink集群,其中两个插槽中有一个JobManager和两个TaskManager以运行作业。
重要的是要记住,TaskManager可以配置有一定数量的处理插槽,这些插槽可以同时执行多个任务。这些任务可以是同一应用程序的子任务,也可以是不同应用程序的子任务。看起来更好,我们可以区分三种并行性:
- 工作并行
- 任务并行
- 数据并行
数据并行性是一种对数据进行分区的功能,如果您已经使用Apache Kafka,则可以让多个运算符执行这些数据子集,该概念类似于主题的每个分区。任务并行性变得更容易,来自不同操作员的任务属于同一应用程序。
构建 Flink Job
我们的应用程序将是基于Apache Flink文档构建的类似示例,该示例将对Web套接字中使用5秒钟的批处理实现计数单词Ola出现次数(该单词是葡萄牙语的一个单词,与hello的含义相同)。该示例是使用scala 2.12和maven进行依赖关系管理和项目管理的。
要运行该应用程序,您需要运行命令行netcat打开一个TCP连接,该连接将用于侦听和发送数据:
nc -lk 9999
在该项目的根目录下运行命令之后,转到Github上的项目并克隆该项目:
mvn clean package
并将在目标/streaming-job-ola-word-1.0-SNAPSHOT.jar中的应用程序代码中生成一个jar。
运行我们的第一个Flink作业
运行我们的应用程序意味着可以访问Flink的Web UI,这不是强制性的,例如,您可以通过Flink的Rest API或Flink实用程序来进行部署和启动作业应用程序。
要知道Flink的Web UI的端点,Minikube提供了一个检索服务URL的命令:
minikube service jobmanager --url
Flink的仪表板暴露在端口32076上,如下所示:
Flink群集具有两个TaskManager实例,这些实例先前是在非Flink作业运行时创建的。要运行一个作业,您可以提交先前创建的作业,您可以单击“提交新作业”选项,然后使用“新增”按钮将该作业上传到Flink,然后单击上载的作业,然后单击“提交”按钮。
提交后,作业将自动启动,因为存在运行作业的可用任务。
要与作业进行交互,如果您还记得,可以使用命令工具netcat:
nc -lk 9999
然后您就可以开始向我们的Job发送信息了。
您可以查看此交互的响应,并查看Taskmanager的日志。
结论
不要忘记阅读Flink文档和Kubernetes文档,因为社区是非常活跃的参考,他们正在不断改进项目。
下一个故事是关于如何在Flink群集上获得高可用性的。流应用程序的大多数用例都要求长期运行,并满足将集群准备为此要求所必需的。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。