写点什么

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:032626
用户头像

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

关注

评论 1 条评论

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

怎么用Redis分布式锁才能确保万无一失?,15个经典面试问题及答案

Java 程序员 后端

恕我直言,我怀疑你们并不会用 Java 枚举,java分布式架构面试题

Java 程序员 后端

意犹未尽的一篇Nginx原理详解,面试官看了都忍不住点赞(1)

Java 程序员 后端

手把手讲解-一个复杂动效的自定义绘制3,最全153道Spring全家桶面试题

Java 程序员 后端

技术分享成就现在的我:中间件兴趣圈荣获CSDN2020博客之星亚军

Java 程序员 后端

快速鸟瞰并发编程,-呕心沥血整理的架构技术【2】,分层展示的架构图

Java 程序员 后端

总结历年各大厂面试官传授的面试经验+阿里P8级架构师整理的Java高频核心知识点

Java 程序员 后端

成功入职阿里,薪资翻倍~ 感谢这份顶级版,linux教程入门教程PDF

Java 程序员 后端

手把手教你应用三种工厂模式在SpringIOC中创建对象实例【案例详解】

Java 程序员 后端

成功拿到大厂offer的我熬夜整理了这份Java高频面试题(含答案)

Java 程序员 后端

我上高中的弟弟都能看懂的Docker学习教程,你看看讲的怎么样

Java 程序员 后端

我丢,去面试初级Java开发岗位,被问到泛型,mysql索引原理面试题

Java 程序员 后端

我凭借这1000道java高频真题,顺利拿下京东、饿了么,java高级开发面试总结

Java 程序员 后端

我出息了,给 JDK 上报了一个 BUG,mongodb入门到精通

Java 程序员 后端

想进阿里、京东?这些多线程并发的技术要点你需要知道,Java程序员怎么优雅迈过30K+这道坎

Java 程序员 后端

我是全网最硬核的Java中间件领域作者,CSDN最值得关注的博主,大家同意吗

Java 程序员 后端

快醒醒吧!互联网大厂面试必问的JVM底层原理,你还搞不清楚

Java 程序员 后端

怎么可能?面试会被Spring难住?Spring框架从入门到精通

Java 程序员 后端

怎样成为全栈工程师(Full Stack Developer)(1),已拿offer

Java 程序员 后端

意犹未尽的一篇Nginx原理详解,面试官看了都忍不住点赞

Java 程序员 后端

成为架构师之前,你一定要懂的-CAP-定理,Java程序员必备书籍

Java 程序员 后端

我在北京已经几年了,Java百度网盘

Java 程序员 后端

总是说spring难学?看完这些spring的注解及其解释,对你来说就是So-easy!

Java 程序员 后端

我用思维导图整理好了Java并发基础知识,还学不会就没救了!

Java 程序员 后端

我画了19张图,彻底帮你搞定Redis,mybatisgenerator教程

Java 程序员 后端

我见过最详细的Redis解析:不懂Redis为什么高性能?如何做高可用

Java 程序员 后端

我,48岁,上海外企高管,9次Java面试经验总结

Java 程序员 后端

怎样成为全栈工程师(Full Stack Developer),sqlproformysql使用教程

Java 程序员 后端

懵逼!阿里一面就被虐了,幸获内推华为技术四面,kafka高性能原理

Java 程序员 后端

手撕ArrayList底层,透彻分析源码,mysql索引优化面试题

Java 程序员 后端

扫盲帖:聊聊微服务与分布式系统,Java校招面试指南

Java 程序员 后端

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