写点什么

Docker 和 Kubernetes 应用程序打包:Metaparticle、Pulumi 与 Ballerina 比较

  • 2018-08-06
  • 本文字数:11706 字

    阅读完需:约 38 分钟

本文要点

  • 随着微服务架构的出现,软件行业正向着云原生应用程序开发和部署发展。
  • Docker 和 Kubernetes 是现代化云原生部署自动化的关键要素。
  • 目前常见的做法是借助容器创建可复制的应用程序包,但是,这涉及手工编写(和维护)YAML 部署描述文件。
  • Metaparticle、Ballerina 和 Pulumi 是三个开源项目,分别提供了自己的方法,解决 Docker 和 Kubernetes 应用程序部署中的应用打包问题。
  • 本文探讨了使用每种框架部署一个简单的“HelloWorld”应用所需要的步骤。

随着微服务架构的出现,软件行业正向着云原生应用程序开发和部署发展。双披萨团队、敏捷性、再现性、CI/CD 在当前生产力快速创新的软件行业中扮演越来越重要的角色。

Docker Kubernetes 是现代化云原生部署自动化的关键要素。常见的做法是借助容器把开发出的应用程序创建成可复制的应用程序包。Docker 使开发人员能够创建可重复的运行时环境,并在其中使用一个简单、可重复的方式定义依赖和配置应用程序。Kubernetes 是一个开源容器编排平台,使这些应用程序容器可以跨多个主机部署,并且提供了可扩展性和高可用性。这需要编写 Dockerfile 和 Kubernetes YAML 部署描述文件,这很痛苦,而且容易出错。

Metaparticle Ballerina Pulumi 是三个开源项目,分别提供了自己解决这个问题的方法。最近,我发现了三个讨论这些方法的推特。

第一个是 Andress Guisado介绍 Metaparticle 如何提供一个标准库用于创建可直接部署到 Kubernetes 的云原生应用程序。Brendan Burns 在年初的 KubeCon 大会上宣布了 Metapaticle,Andress 那时就认为这将是 2018 年的一大焦点。

在 Istio 社区聚会上接触到 Ballerina 之后,Dan Ciruli 就发推特说,Ballerina 是一门有趣的语言,因为它可以自动生成Kubernetes 和Istio YAML,作为构建过程的一部分。他进一步表示,这是一个很棒的主意,他认为其他框架也将采用这种方式。

第三个是 Ustun Ozgur 在推特上说,与繁琐的YAML 文件相比,Pulumi 把基础设施定义成代码所做的工作对于DevOps 而言就像React 针对Web 开发所做的工作。

在本文中,我将比较这三个项目如何帮助你在像 Kubernetes 这样的容器编排平台中自动化应用程序代码部署,而不必手工编写 YAML。下文将详细介绍这些方法。

Metaparticle

Metaparticle/Package 简化了构建和部署容器镜像的任务。这一个库集合使程序员可以使用他们熟悉的代码构建和部署容器。目前,它支持 Java、.NET core、Javascript(NodeJS)、Go、Python 和 Ruby 编程语言。

让我们看下如何使用 Metaparticle 把 Java 代码部署到 Kubernetes 中。

前提条件:

  1. Docker/ Kubernetes
  2. 命令行工具 mp-compiler
  3. maven 依赖 io.metaparticle:metaparticle-package

下面的代码启动一个 Kubernetes pod,其中包含一个打印“Hello World!”的 HTTP 服务: 

复制代码
package io.metaparticle.tutorial;
import io.metaparticle.annotations.Package;
import io.metaparticle.annotations.Runtime;
import static io.metaparticle.Metaparticle.Containerize;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;
public class Main {
private static final int port = 8080;
@Runtime(ports = {port},
replicas = 4,
publicAddress = true,
executor = "metaparticle"
)
@Package(repository = "docker.io/lakwarus",
jarFile = "target/metaparticle-package-tutorial-0.1-SNAPSHOT-jar-with-dependencies.jar", publish = true)
public static void main(String[] args) {
Containerize(() -> {
try {
HttpServer server = HttpServer.create(new InetSocketAddress(port), 0);
server.createContext("/", new HttpHandler() {
@Override
public void handle(HttpExchange t) throws IOException {
String msg = "Hello World!";
t.sendResponseHeaders(200, msg.length());
OutputStream os = t.getResponseBody();
os.write(msg.getBytes());
os.close();
System.out.println("[" + t.getRequestURI() + "]");
}
});
server.start();
} catch (IOException ex) {
ex.printStackTrace();
}
});
}
}
{1}

有几点需要注意:

  • 引入 io.metaparticle.annotations.Package 和 io.metaparticle.annotations.Runtime;
  • @Package 注解描述如何打包应用程序;
  • @Runtime 注解描述应用程序的运行时配置;
  • 把 main 函数封装在 Containerize 函数中,后者会启动 Metaparticle 代码。

编译代码:

复制代码
mvn compile

这会创建一个包含所有依赖的 jar 文件。

运行代码:

复制代码
mvn exec:java -Dexec.mainClass=io.metaparticle.tutorial.Main

这会生成 Dockerfile 和 Docker 镜像,并把它推送到特定的注册中心。然后,它会在配置好的 Kubernetes 集群中使用 4 个 pod 启动一个 Kubernetes 部署。

访问服务:

你需要创建一个代理来访问服务。

复制代码
$ kubectl port-forward deployment/io-metaparticle-tutorial-main 8080:8080
$ curl http://localhost:8080/
Hello World!

要点:

  • 不会创建 YAML/JSON;
  • 完全自动部署;
  • 支持多种语言;
  • 支持有限的 Kubernetes 服务和部署功能,仅支持 clusterIP 服务;
  • 需要把用户代码封装在 Containerize() 块中,然后,你的代码不能以独立模式运行。

Ballerina

Ballerina 是一门新开源的云原生编程语言,设计用来把代码优先的敏捷性引入应对跨端点集成的挑战中。Ballerina 为 API、分布事务、断路器、流处理、数据访问、JSON、XML、gRPC 及许多其他集成挑战提供了一流的支持。

Ballerina 可以推断周围的架构;编译器可以感知环境,自动生成 Docker 镜像和 YAML,把微服务直接部署到像 Docker 和 Kubernetes 这样的基础设施中。

让我们看下如何使用 Ballerina Kubernetes 注解把代码部署到 Kubernetes。

前提条件:

  1. Ballerina
  2. Docker/Kubernetes

下面的代码启动一个打印“Hello World!”的 HTTP 服务:

复制代码
import ballerina/http;
import ballerinax/kubernetes;
@kubernetes:Service {
serviceType: "NodePort",
name: "hello-world"
}
endpoint http:Listener listener {
port: 9090
};
@kubernetes:Deployment {
image: "lakwarus/helloworld",
name: "hello-world"
}
@http:ServiceConfig {
basePath:"/"
}
service<http:Service> helloWorld bind listener {
@http:ResourceConfig {
path: "/"
}
sayHello(endpoint outboundEP, http:Request request) {
http:Response response = new;
response.setTextPayload("Hello World! \n");
_ = outboundEP->respond(response);
}
}

有几点需要注意:

  • 引入 ballerinax/kubernetes 包
  • @kubernetes:以 Ballerina 服务为基础的服务

编译代码:

编译hello_world_k8s.bal文件。编译成功后会打印运行 Kubernetes 工件的命令:

复制代码
$> ballerina build hello_world_k8s.bal
@kubernetes:Docker          - complete 3/3
@kubernetes:Deployment      - complete 1/1
@kubernetes:Service         - complete 1/1
运行下面的命令部署 Kubernetes 工件: 
kubectl apply -f ./kubernetes/

Ballerina 编译器将生成 hello_containers_k8s.balx、Dockerfile、Docker 镜像和 Kubernetes 工件,结构如下:

复制代码
$> tree
.
├── hello_world_k8s.bal
├── hello_world_k8s.balx
└── kubernetes
    ├── docker
    │   └── Dockerfile
    ├── hello_world_k8s_svc.yaml
    └── hello_world_k8s_deployment.yaml

运行代码kubectl apply -f ./kubernetes/把应用部署到 Kubernetes,并可以通过 Kubernetes NodePort 访问。

访问服务:

复制代码
$> kubectl get svc
NAME                    TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
hello-world           NodePort    10.96.118.214    <none>        9090:32045/TCP   1m
$> curl http://localhost:<32045>/
Hello, World!

要点:

  • Ballerina 提供 Kubernetes 原生支持;
  • 应该使用 Ballerina 编写代码;
  • 基于代码中定义的注解生成部署工件;
  • 部署不是完全自动的,需要运行 kubectl 命令;
  • 支持许多 Kubernetes 功能,如所有类型的 Kubernetes 服务、部署、Ingress、Secret、持久卷、ConfigMap、活性探针和横向 pod 自动扩展;
  • 不需要修改或封装用户代码;Ballerina 代码使用注解修饰对象;Ballerina 编译器把注解解析成可读可处理的 AST。

Pulumi

Pulumi 是一个云开发平台,使创建云程序变得简单高效。你可以使用自己最喜欢的语言编写云程序,Pulumi 将自动保持基础设施最新:“跳过 YAML,只要编写代码”。Pulumi 支持多语言、多云,其引擎和包生态都可以扩展。

目前,它支持 JavaScript、TypeScript、Python 和 Go 编程语言。支持的云平台包括 Amazon Web Services、 Microsoft Azure、谷歌云平台和 Kubernetes。

Pulumi 主要是针对基础设施代码自动化,而不是应用程序代码自动化。你可以使用你喜欢的编程语言,自动化基础设施部署。

Pulumi 对公共无服务器提供商如 AWS Lambda 的 FaaS 部署提供开箱即用的支持,但是在本文中,我将重点介绍在 Docker 和 Kubernetes 上的自动化部署。

前提条件:

  1. Docker/Kubernetes
  2. 安装 Pulumi(curl -fsSL https://get.pulumi.com/ | sh)
  3. 配置Pulumi 和Kubernetes 集群

让我们看下如何使用 TypeScript 和 Pulumi 部署一个“helloworld”示例应用程序。

我已经创建了一个“helloworld”示例应用程序(对 HTTP 请求打印“Hello World”)以及相应的 Docker 镜像(lakwarus/helloworld:latest)。现在,我将使用 TypeScript 以及 Pulumi 库编写简单的代码,把我的应用部署到 Kubernetes,而不必手工编写 YAML 工件。

创建 Pulumi 项目:

复制代码
$> pulumi new
Please choose a template: typescript
This command will walk you through creating a new Pulumi project.
Enter a value or leave blank to accept the default, and press <ENTER>.
Press ^C at any time to quit.
project name: (hello)
project description: hello world
Created project 'hello'.
stack name: (hello-dev)
Created stack 'hello-dev'.
Installing dependencies...
added 113 packages in 12.549s
Finished installing dependencies.
New project is configured and ready to deploy with 'pulumi update'.

使用下面的依赖项更新 package.json:

复制代码
{
"name": "hello",
"main": "bin/index.js",
"typings": "bin/index.d.ts",
"scripts": {
"build": "tsc"
},
"devDependencies": {
"typescript": "^2.7.2",
"@types/node": "latest"
},
"dependencies": {
"@pulumi/kubernetes": "^0.14.0",
"@pulumi/pulumi": "^0.14.0",
"npm": "^6.1.0"
}
}

在 index.ts 文件中编辑应用程序和部署信息。这里,我只添加 pod 配置,不过,你可以把它扩展到其他 Kubernetes 功能。

复制代码
import * as pulumi from "@pulumi/pulumi";
import * as k8s from "@pulumi/kubernetes";
let helloPod = new k8s.core.v1.Pod("hello", {
metadata: {
name: "hello",
},
spec: {
containers: [{
name: "hello",
image: "lakwarus/helloworld",
ports: [{
containerPort: 9090,
}],
}],
},
});

编译并运行代码:

复制代码
$> npm update
$> npm run build
$> pulumi update
Previewing update of stack 'hello-dev'
Previewing changes:
Type Name Plan Info
+ pulumi:pulumi:Stack hello-hello-dev create
+ └─ kubernetes:core:Pod hello create
info: 2 changes previewed:
+ 2 resources to create
Do you want to perform this update? yes
Updating stack 'hello-dev'
Performing changes:
Type Name Status Info
+ pulumi:pulumi:Stack hello-hello-dev created
+ └─ kubernetes:core:Pod hello created
info: 2 changes performed:
+ 2 resources created
Update duration: 10.132746709s

访问服务:

复制代码
$ kubectl port-forward pod/hello 9090:9090
$ curl http://localhost:9090/
Hello World!

要点:

  • 主要是针对基础设施代码自动化;
  • 可以使用喜欢的编程语言控制你的基础设施;
  • 应用程序代码应该在函数(如 AWS Lambda)中,或者需要在可以用于自动化部署的 Docker 镜像中;
  • 支持几乎所有的公有云提供商和 Kubernetes;
  • 仅用几行代码就可以创建复杂的部署,而不必手工编写 YAML;
  • 完全自动;
  • 潜在的供应商锁定,因为你需要有一个 http://pulumi.io 账户。

小结

随着微服务架构的出现,软件行业正向着云原生应用程序开发和部署发展。Docker 和 Kubernetes 是现代化云原生部署自动化的关键要素。不过,目前需要人工创建 YAML 部署描述文件,这个过程很繁琐,而且容易出错。

在 Kubernetes 部署应用程序的其中一种流行方式是采用不同的工具和框架。 Draft Gitkube Helm Ksonnet Skaffold 都是在这方面处于领先地位的流行工具,有一篇非常有趣的文章“ Draft、Gitkube、Helm、Ksonnet、Metaparticle 和 Skaffold 对比”,比较了这些帮助开发人员在 Kubernetes 上构建和部署应用的工具。虽然所有这些工具的工作流程都不一样,但它们解决的是同一个问题,即提高在 Kubernetes 上部署应用程序的敏捷性和效率。

Metaparticle、Ballerina 和 Pulumi 提供了不同的方法,供开发人员借助编程语言本身处理部署自动化,而不必手写 YAML。这正在成为一种趋势,将改变软件行业中的 DevOps 实践。

关于作者

Lakmal Warusawithana 是世界最大开源集成供应商 WSO2 的高级主管兼架构师。Lakmal 长期从事与开源、云、DevOps 技术相关的工作,是 Apache Stratos PaaS 项目的副总裁。2015 年,Lakmal 与人合伙创建了 thinkCube,成为开发更适合电信运营商的下一代协作式云计算产品的先驱。他负责整体的工程流程,特别关注 thinkCube 解决方案的扩展性和服务交付。在与人联合创建 thinkCube 之前,Lakmal 在 ITABS 工作了四年,该公司致力于基于 Linux 的服务器部署,提供了一个简单易用的自定义服务管理接口。Lakmal 还在各种会议上发表演讲,包括 ApacheCon、 CloudOpen、QCon、JaxLondon、Cloud Expo、Cloudstack 协作大会、WSO2Con 及许多技术聚会。Lakmal 拥有斯里兰卡科伦坡大学计算机科学理学士(荣誉)学位。

查看英文原文: Packaging Applications for Docker and Kubernetes: Metaparticle vs Pulumi vs Ballerina

2018-08-06 18:032502
用户头像

发布了 1008 篇内容, 共 432.9 次阅读, 收获喜欢 346 次。

关注

评论 1 条评论

发布
暂无评论
发现更多内容

融合趋势下基于 Flink Kylin Hudi 湖仓一体的大数据生态体系

Apache Flink

flink

为什么我愿意持续做这样一件看似没有价值的事情

帅安技术

坚持 持续写作 长期价值

【AI全栈二】视频流多目标多类别无延迟高精度高召回目标追踪

cv君

音视频 目标检测 视频跟踪 引航计划

趣题与算法(1)

阳龙生

使用Agora SDK开发React Native视频通话App

声网

RTC React Native 声网 RTE

斗智亦斗棋,零售云市场的“楚河汉界”突围赛

脑极体

面试4轮字节Java研发岗,最终拿下Offer(原题复盘)

码农之家

编程 程序员 互联网 面试 字节

最新分享:如何避免线程安全的坑?看这一篇就够了

学Java关注我

Java 编程 程序员 架构 计算机

如何在云中构建数字核心

云计算

架构实战营作业2

冷酷小绵羊

方寸之间,书写天地

石云升

4月日更 1 周年盛典 我和写作平台的故事 InfoQ 写作平台 1 周年

浅谈JVM和垃圾回收

leonsh

Java JVM JVM虚拟机原理 垃圾回收算法

计算机原理学习笔记 Day10

穿过生命散发芬芳

计算机原理 4月日更

知乎万赞回答:程序员面试为什么被要求造航母,而工作拧螺丝?

Java架构师迁哥

欢迎参与 KubeVela 官方文档翻译活动

阿里巴巴云原生

容器 云原生 开发工具 OAM 资源调度

【全球年青人召集令】Hello World,Hello 2050

阿里巴巴云原生

容器 开发者 云原生 活动

浅谈在探索数分之路上的“数据思维”论述

小飞象@木木自由

数据分析 数据分析体系 数据思维 数据分析方法论

Linux free 命令

一个大红包

linux命令 4月日更

开源 1 年半 star 破 1.2 万的 Dapr 是如何在阿里落地的?

阿里巴巴云原生

Java 微服务 云原生 中间件 API

翻译:《实用的Python编程》09_03_Distribution

codists

Python

奇绩创坛2021秋季创业营开始报名

奇绩创坛

Excelize 2.4.0 正式版发布, 新支持 152 项公式函数

xuri

GitHub 开源 Excel Go 语言 Excelize

架构实战营 模块2 课后作业

༺NPE༻

Python 爬虫实战(一) 爬取自如网租房信息

U2647

python 爬虫 4月日更

推进智慧城市建设 博睿数据亮相长三角城市数字化转型高峰论坛

博睿数据

数字化转型高峰论坛

简单了解InnoDB底层原理

leonsh

MySQL 数据库 innodb

GitHub面试题库+阿里巴巴2021年Java岗面试26大核心专题,成功助我砍下7家大厂Offer

Java架构追梦

Java 阿里巴巴 架构 面试

如何提高Linux水平

cdhqyj

未来已来,HarmonyOS 开发者日全记录

清秋

华为 开发 物联网 新闻 HarmonyOS

深入理解Java虚拟机-HotSpot

华章IT

Java JVM 虚拟机

百度大脑3月新品推荐:EasyDL视频目标追踪全新发布

百度大脑

百度大脑 EasyDL

Docker和Kubernetes应用程序打包:Metaparticle、Pulumi与Ballerina比较_DevOps & 平台工程_Lakmal Warusawithana_InfoQ精选文章