帮助中心 >  行业资讯 >  开发 >  C语言微服务在OpenShift上的部署

C语言微服务在OpenShift上的部署

2021-05-10 13:53:47 3086

一、C应用的基础镜像

容器云上C很少,最大的原因是C语言是本地编译的。今天,我们分析一下如何在容器云上运行C应用。

容器云上C应用第一个需要考虑的点是基础镜像。红帽提供基于RHEL的轻量级容器镜像UBI,大小为几十M。

谈到这里,很多人会有一个朴素的疑问:如果开发环境是SUSE,那应用在上OpenShift的时候,使用红帽基于RHEL提供的镜像,运行是否完全一致?

解决这个问题不难,也就是说,对于C应用容器化时,我们使用比UBI更为基础的容器镜像,使用Alpine Linux。这样我们将C的编译和运行的环境,做到容器镜像里。

Alpine Linux是一个由社区开发的基于musl和BusyBox的Linux操作系统,该操作系统以安全为理念,面向x86路由器、防火墙、虚拟专用网、IP电话盒及服务器而设计。

我们查看Alpine Linux的版本和Linux Kernel。我们在写dockerfile的时候,就得选对应kernel版本的Alpine Linux。我们在后面的实验使用Alpine 3.12。


1.jpg


Alpine的基础层只有6MB的大小。Alpine使用BusyBox提供外壳程序,根据MUSL C库而不是glibc构建的。MUSL是一个最小的,符合POSIX的C标准库。Alpine镜像中有诸如cp和wget之类的命令可以正常工作。BusyBox有其自己的方式来执行系统设置任务,例如添加用户和组。


2.jpg


Glibc glibc = GNU C Library
是GNU项(GNU Project)目,所实现的C语言标准库(C standard library)。广泛存在于目前最常见的桌面和服务器中的GNU/Linux类的系统中,都是用的这套C语言标准库。它实现了常见的C库的函数,支持很多种系统平台,功能很全,但是也相对比较臃肿和庞大。如果出现漏洞也影响巨大,如 glibc 幽灵漏洞等。

Musl是一个轻量级的C标准库,设计作为GNU C library (glibc)、 uClibc或Android Bionic的替代用于嵌入式操作系统和移动设备。它遵循POSIX 2008规格和 C99 标准,采用MIT许可证授权,使用Musl的Linux发行版和项目包括sabotage,bootstrap-linux,LightCube OS等等。

我们知道构建容器涉及将某些依赖项导入到映像中。Alpine有自己的存储库和自己的安装命令(apk add)。

需要注意的是,Alpine存储库中的某些库是针对glibc构建的,因此使用apk add会导入大量其他二进制文件。但从源构建大多数依赖关系要比从存储库导入更容易。

二、C应用的测试程序

solunar_ws组件是基于REST的Web服务,可在指定日期提供特定城市的日出和日落时间并设置信息。使用以下形式的URL通过CURL调用它:


3.png


solunar_ws是用C实现的基于REST的Web服务的demo,容器的总大小约为10Mb。此10Mb包括操作系统层、应用程序二进制文件和相关性,以及(在此特定情况下)完整的世界时区数据库。即使在负载下,应用程序在容器中使用的RAM也不会超过几Mb。

solunar_ws组件只有两个重要的依赖项:libmicrohttpd和tzdata(全局时区数据库)。libmicrohttpd 是 GUN 下开源的一个小型的 HTTP 库,能够方便的嵌入到系统中。支持 HTTP 1.1 可以同时侦听多个端口,具有 select, poll, pthread, thread poo 等多种模式。tzdata软件包,全称time zone and daylight-saving time(DST) data,供各个Linux系统安装以读取Time Zone Database中数据。

三、Alpine使用注意事项

Alpine的核心应用程序都与MUSL链接,而不是glibc,并且Alpine默认不包含其他C库。对于我们中的那些在Linux开发中已经习惯于glibc扩展的人来说,使用MUSL会遇到一些问题。让我们仅举几个例子。首先,MUSL没有与glibc qsort_r()函数等效的函数,该函数用于对任意数据结构进行排序。老实说。其次,MUSL在实现某些功能方面存在一些无法解释的差距。例如,用于格式化时间数据的strftime()函数缺少glibc实现所具有的说明符。

如果您需要对微服务的HTTP通信进行加密,则需要决定是在OpenShift集群中还是仅在OpenShift集群中对HTTP通信进行加密。加密到群集的流量很简单,因为我们可以配置OpenShift路由进行边缘终止。在此配置中,OpenShift路由器与微服务之间的内部流量将为纯文本。

另一方面,如果即使在OpenShift集群中也要对流量进行加密,则需要为微服务提供自己的传输层安全性(TLS)支持。libmicrohttpd库支持TLS,但是要启用该支持,我们需要使用许多GNU TLS库的开发版本来构建它。当然,这些库也必须在运行时可用于容器。

此外,您需要提供服务器证书,并为客户的管理员提供一种获取该证书的方法。您可以在OpenShift机密或ConfigMap中提供证书,然后将其作为文件挂载到pod的文件系统中。这种技术相对普遍,与C一起使用与从Java或其他任何语言使用在原理上没有什么不同。

四、运行Alpine镜像


4.png


查容器镜像构建过程:

[root@helper c]# docker build -t davidwei/capp:1.0 .

镜像构建成功后,可以通过podman -it运行,则容器中会有一个交互式会话,可用于编辑和构建代码。当然生产上我们不会用这种方式在容器云上开发C应用,意义不大。本小节只是验证我们可以基于alpine去做镜像定制化。

五、编译并实现C应用的容器化

查看如下Dockerfile,我们将C应用的编译和容器化


image.png


1.第一阶段构建

基于Alpine 3.12这个base image下载libmicrohttpd的源代码并进行构建,然后对solunar_ws进行相同操作。这些来源来自不同的地方,但是它们都是以相同的方式编译的。在此示例中,请注意,在构建Web服务之前,我们必须先构建libmicrohttpd。那是因为Web服务依赖它。

本阶段镜像构建完以后,镜像大小约为210MB。

2.第二阶段构建

第二阶段从相同的Alpine 3.12基础层开始,仅安装运行时所需的软件包,即tzdata。然后,它从先前的版本中复制容器在运行时所需的两个文件:二进制solunar_ws和库libmicrohttpd.so.12。

我们查看镜像构建过程:


image.png


7.jpg


可以使用如下命令本地运行:

#docker run -d -p 8080:8080 davidwei/capp:1.0

# docker ps

CONTAINER ID   IMAGE               COMMAND         CREATED         STATUS         PORTS                                       NAMES

87c1cf607a10   davidwei/capp:1.0   "/solunar_ws"   9 seconds ago   Up 8 seconds   0.0.0.0:8080->8080/tcp, :::8080->8080/tcp   zealous_dhawan

六、在OpenShift上部署镜像

在OCP中,我们可以:

1.从dockerfile部署应用,自动生成deployment。

2.部署容器镜像,自动生成deployment

3.手工书写deployment,部署容器镜像。

如下图所示,基于dockerfile部署应用可以自动生成deployment和route,这是第一种方法:


8.jpg


如果C应用的源码发生了变更,那么在OpenShift中就再次直接从dockerfile部署。本文我做手工docker build主要是为了方便读者理解。

为了更好地控制,执行oc create创建dc和service,如下所示(推送镜像的步骤省略)。这是第三种方法:


image.png


为应用创路由,并通过浏览器访问应用:

http://www.landui.com_name/day/london/jun%2020


10.jpg


七、总结

从本文我们可以看出,在OpenShift上运行C应用是安全没问题的。但是,由于C无法像java那样实现外部构建(mvn),因此我们不建议让C应用参与到OpenShift的CI/CD中。我们在书写dockerfile的时候,需要以alpin Linux为基础镜像,把C应用编译和运行所依赖的环境都做到容器镜像中。




提交成功!非常感谢您的反馈,我们会继续努力做到更好!

这条文档是否有帮助解决问题?

非常抱歉未能帮助到您。为了给您提供更好的服务,我们很需要您进一步的反馈信息:

在文档使用中是否遇到以下问题: