33

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

 5 years ago
source link: http://www.infoq.com/cn/articles/metaparticle-pulumi-ballerina?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

本文要点

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

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

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

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

第一个是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();
           }
       });
   }
}

有几点需要注意:

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

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

关于作者

1lakmal-warusawithana-1532344653376.jpg 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


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK