{"id":11304,"date":"2017-04-09T07:30:17","date_gmt":"2017-04-09T05:30:17","guid":{"rendered":"https:\/\/blog.zhaw.ch\/icclab\/?p=11304"},"modified":"2019-08-05T14:35:26","modified_gmt":"2019-08-05T12:35:26","slug":"running-google-cloud-functions-in-openshift","status":"publish","type":"post","link":"https:\/\/blog.zhaw.ch\/icclab\/running-google-cloud-functions-in-openshift\/","title":{"rendered":"Running Google Cloud Functions in OpenShift"},"content":{"rendered":"\n<p>by <a href=\"https:\/\/blog.zhaw.ch\/icclab\/josef-spillner\/\">Josef Spillner<\/a><\/p>\n\n\n<p>Have you created a highly popular and frequently used JavaScript (<a href=\"https:\/\/nodejs.org\/en\/\">Node.js<\/a>) functions for execution in <a href=\"https:\/\/cloud.google.com\/functions\/\">Google Cloud Functions<\/a>? In this case, the economics of FaaS turn against you due to the per-invocation pricing. You might want to have more options for both testing the same function locally and for deploying it into an environment with fixed monthly pricing. This blog post explains step-by-step how to migrate functions from FaaS environments into a fixed per-month pricing container environment. The running example will be Node.js functions running in Google Cloud Functions albeit the procedure is similarly applicable to other combinations.<\/p>\n<p><!--more--><\/p>\n<p>The prerequisite to this HOWTO is that you have a Google Cloud account with at least one deployed function. Furthermore, this tutorial describes the migration path into a Docker container running at <a href=\"https:\/\/appuio.ch\/\">APPUiO<\/a>, the Swiss Container Platform, using an OpenShift-managed combination of <a href=\"https:\/\/blog.zhaw.ch\/icclab\/snafu-the-swiss-army-knife-of-serverless-computing\/\">Snafu<\/a> and a persistent volume container to safeguard your functions. An account into an OpenShift instance is therefore also necessary. The APPUiO public cloud runs the latest version 3.4 which improves the user experience over previous versions and is therefore used in the tutorial. The HOWTO will show the process both on the GUI path and on the command-line path of OpenShift, and subsequently the command-line operations of Snafu.<\/p>\n<p>The initial setting in the Google Cloud will be a set of deployed functions. The list of functions can be retrieved with <em>gcloud beta functions list<\/em> or via the web interface which is shown in the following screenshot.<\/p>\n<p><a href=\"https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/google-functions.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-11307 size-medium\" src=\"https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/google-functions-300x107.png\" alt=\"\" width=\"300\" height=\"107\" srcset=\"https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/google-functions-300x107.png 300w, https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/google-functions-768x274.png 768w, https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/google-functions-1024x365.png 1024w, https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/google-functions-500x178.png 500w, https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/google-functions.png 1054w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a>The function referenced above is the unmodified hello world function offered by the provider. For a better understanding of its invocation later on, its implementation is shown in the following.<\/p>\n<p><a href=\"https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/google-samplefunction.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-11308 size-medium\" src=\"https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/google-samplefunction-296x300.png\" alt=\"\" width=\"296\" height=\"300\" srcset=\"https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/google-samplefunction-296x300.png 296w, https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/google-samplefunction.png 684w\" sizes=\"auto, (max-width: 296px) 100vw, 296px\" \/><\/a>In order to run this function in a container through Snafu, the open source <a href=\"https:\/\/github.com\/serviceprototypinglab\/snafu\">Swiss Army Knife of Serverless Computing<\/a>, first prepare your container execution environment. The following screenshot shows how a dockerised version of Snafu can be imported in the OpenShift web console.<\/p>\n<p>(The recommended way is to build the image locally from the <a href=\"https:\/\/github.com\/serviceprototypinglab\/snafu\/blob\/master\/Dockerfile\">Dockerfile<\/a> by navigating to Catalog -&gt; Python 3.5, although this route has not been tested for this HOWTO.)<\/p>\n<p><a href=\"https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/appuio-deployimage.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-11309\" src=\"https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/appuio-deployimage-300x120.png\" alt=\"\" width=\"300\" height=\"120\" srcset=\"https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/appuio-deployimage-300x120.png 300w, https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/appuio-deployimage-768x307.png 768w, https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/appuio-deployimage-1024x409.png 1024w, https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/appuio-deployimage-500x200.png 500w, https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/appuio-deployimage.png 1183w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a>Subsequently, you will have to choose a name for the deployment. The running example uses just <em>functions<\/em> but any other name can be chosen as well. Beside the name, more deployment options can be configured although the default values are suitable.<\/p>\n<p><a href=\"https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/appuio-stream.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-11310\" src=\"https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/appuio-stream-300x94.png\" alt=\"\" width=\"300\" height=\"94\" srcset=\"https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/appuio-stream-300x94.png 300w, https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/appuio-stream-768x241.png 768w, https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/appuio-stream-500x157.png 500w, https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/appuio-stream.png 900w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a>Once confirmed, you will be taken to the overview screen. The application is now already running but data would be lost during restarts. Therefore, adding a volume container to manage files for a certain part of the instance filesystem is going to be the next step.<\/p>\n<p><a href=\"https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/appuio-overview.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-11311\" src=\"https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/appuio-overview-300x133.png\" alt=\"\" width=\"300\" height=\"133\" srcset=\"https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/appuio-overview-300x133.png 300w, https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/appuio-overview-768x341.png 768w, https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/appuio-overview-1024x455.png 1024w, https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/appuio-overview-500x222.png 500w, https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/appuio-overview.png 1091w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a>The storage configuration consists of two steps. First, a volume claim for a certain size needs to be configured (in this case for 512 MiB and named <em>functions-storage<\/em>) and second, it needs to be integrated into the container instances. Snafu reads user-supplied functions in single-tenant mode from <em>\/opt\/functions-local<\/em> which is therefore the directory of choice for persisting functions across container scaling or restarts.<\/p>\n<p><a href=\"https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/appuio-storage.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-11312\" src=\"https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/appuio-storage-300x216.png\" alt=\"\" width=\"300\" height=\"216\" srcset=\"https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/appuio-storage-300x216.png 300w, https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/appuio-storage-768x552.png 768w, https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/appuio-storage-417x300.png 417w, https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/appuio-storage.png 858w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><a href=\"https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/appuio-addstorage.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-11313\" src=\"https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/appuio-addstorage-300x218.png\" alt=\"\" width=\"300\" height=\"218\" srcset=\"https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/appuio-addstorage-300x218.png 300w, https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/appuio-addstorage-768x558.png 768w, https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/appuio-addstorage-413x300.png 413w, https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/appuio-addstorage.png 976w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a>During the reconfiguration, the container is automatically restarted and includes the specified directory from the volume. The OpenShift overview page nicely displays an animated rolling update mechanism which is triggered by any such reconfiguration.<\/p>\n<p><a href=\"https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/appuio-rollingupdate.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-11314\" src=\"https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/appuio-rollingupdate-300x116.png\" alt=\"\" width=\"300\" height=\"116\" srcset=\"https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/appuio-rollingupdate-300x116.png 300w, https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/appuio-rollingupdate-768x297.png 768w, https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/appuio-rollingupdate-500x194.png 500w, https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/appuio-rollingupdate.png 987w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a>Note that compared to the previous overview screenshot, the application is now publicly accessible through an endpoint represented by the given URL. This endpoint terminates a route which was configured through OpenShift&#8217;s route configuration as shown below.<\/p>\n<p><a href=\"https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/appuio-addroute.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-11315\" src=\"https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/appuio-addroute-300x215.png\" alt=\"\" width=\"300\" height=\"215\" srcset=\"https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/appuio-addroute-300x215.png 300w, https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/appuio-addroute-768x551.png 768w, https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/appuio-addroute-1024x734.png 1024w, https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/appuio-addroute-418x300.png 418w, https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/appuio-addroute.png 1163w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>Alternatively, the entire application setup can be performed on the command line using OpenShift&#8217;s <em>oc<\/em> command line tool. The following snipped shows both the commands entered and the expected answers.<\/p>\n<pre>oc new-app --name functions jszhaw\/snafu\n\n--&gt; Found Docker image fee4903 (32 minutes old) from Docker Hub for \"jszhaw\/snafu\"\n\n&nbsp;&nbsp;&nbsp; * An image stream will be created as \"functions:latest\" that will track this image\n&nbsp;&nbsp;&nbsp; * This image will be deployed in deployment config \"functions\"\n&nbsp;&nbsp;&nbsp; * Port 10000\/tcp will be load balanced by service \"functions\"\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * Other containers can access this service through the hostname \"functions\"\n&nbsp;&nbsp;&nbsp; * WARNING: Image \"jszhaw\/snafu\" runs as the 'root' user which may not be permitted by your cluster administrator\n\n--&gt; Creating resources ...\n&nbsp;&nbsp;&nbsp; imagestream \"functions\" created\n&nbsp;&nbsp;&nbsp; deploymentconfig \"functions\" created\n&nbsp;&nbsp;&nbsp; service \"functions\" created\n--&gt; Success\n&nbsp;&nbsp;&nbsp; Run 'oc status' to view your app.\n\noc volume dc\/functions --add --name=functions-storage --type pvc --claim-name=functions-pvc --claim-size=256Mi --overwrite --mount-path=\/opt\/functions-local\n\nwarning: volume \"functions-storage\" did not previously exist and was not overriden. A new volume with this name has been created instead.persistentvolumeclaims\/functions-pvc\ndeploymentconfig \"functions\" updated\n\noc expose service functions\n\nroute \"functions\" exposed<\/pre>\n<p>The last step of the setup after the GUI or command line setup is the verification that Snafu runs correctly. This can be done by navigating to the pods overview, loading one of the pods associated with the application (before scaling there is just one), and using the pod&#8217;s terminal which offers unprivileged shell access.<\/p>\n<p><a href=\"https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/appuio-terminal.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-11316\" src=\"https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/appuio-terminal-300x179.png\" alt=\"\" width=\"300\" height=\"179\" srcset=\"https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/appuio-terminal-300x179.png 300w, https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/appuio-terminal-500x298.png 500w, https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/appuio-terminal.png 718w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a>With this preparation, the function migration can begin. First, log into the Google Cloud from the running environment. Notice how the enforced authentication uses OAuth which works nice in web browsers but is somewhat cumbersome in command-line environments. You can copy and paste the shown URL, but will have to type the generated Google token manually into the terminal. Notice further that there are no permissions specifically for Google Cloud Functions; instead, the local application needs to be granted access to a combination of other services hosted in Google Cloud. And finally notice how the unprivileged user does neither have a home directory nor any other user-related data and therefore a custom home directory needs to be set for the Google Cloud SDK to work.<\/p>\n<p><a href=\"https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/migration-gcloudlogin.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-11317\" src=\"https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/migration-gcloudlogin-300x105.png\" alt=\"\" width=\"300\" height=\"105\" srcset=\"https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/migration-gcloudlogin-300x105.png 300w, https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/migration-gcloudlogin-500x176.png 500w, https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/migration-gcloudlogin.png 666w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><a href=\"https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/google-permissions.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-11318\" src=\"https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/google-permissions-199x300.png\" alt=\"\" width=\"199\" height=\"300\" srcset=\"https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/google-permissions-199x300.png 199w, https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/google-permissions.png 458w\" sizes=\"auto, (max-width: 199px) 100vw, 199px\" \/><\/a>After the project, select the project which hosts your functions (via its id, not the user-visible name) and then run the Snafu import tool, specifying the Google Cloud as its source. The import works flawlessly and the JavaScript functions are placed into the right folder which is backed up by a volume container.<\/p>\n<p><a href=\"https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/migration-finish.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-11319\" src=\"https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/migration-finish-300x75.png\" alt=\"\" width=\"300\" height=\"75\" srcset=\"https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/migration-finish-300x75.png 300w, https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/migration-finish.png 459w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a>The running Snafu service contains an autodeployer which by now has already picked up the function. Still it can also be executed directly on the command line to verify its functionality, as shown below.<\/p>\n<p><a href=\"https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/snafu-execution.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-11320\" src=\"https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/snafu-execution-300x130.png\" alt=\"\" width=\"300\" height=\"130\" srcset=\"https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/snafu-execution-300x130.png 300w, https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/snafu-execution-500x216.png 500w, https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/snafu-execution.png 522w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a>Overall, this process only takes a few minutes and leads to an environment which can be used to test or host the functions inside an already-paid-for container instance. As a research prototype, anything beyond simple functions may not work, although the limitations will be gradually eliminated.<\/p><div class=\"pt-sm\">Schlagw\u00f6rter: <a href=\"https:\/\/blog.zhaw.ch\/icclab\/tag\/cloud-migration\/\">cloud migration<\/a>, <a href=\"https:\/\/blog.zhaw.ch\/icclab\/tag\/faas\/\">faas<\/a>, <a href=\"https:\/\/blog.zhaw.ch\/icclab\/tag\/openshift\/\">openshift<\/a>, <a href=\"https:\/\/blog.zhaw.ch\/icclab\/tag\/snafu\/\">snafu<\/a>, <a href=\"https:\/\/blog.zhaw.ch\/icclab\/tag\/tooling\/\">tooling<\/a><br><\/div>","protected":false},"excerpt":{"rendered":"<p>Have you created a highly popular and frequently used JavaScript (Node.js) functions for execution in Google Cloud Functions? In this case, the economics of FaaS turn against you due to the per-invocation pricing. You might want to have more options for both testing the same function locally and for deploying it into an environment with [&hellip;]<\/p>\n","protected":false},"author":486,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"ngg_post_thumbnail":0,"footnotes":""},"categories":[1,15],"tags":[561,820,238,853,777],"features":[],"class_list":["post-11304","post","type-post","status-publish","format-standard","hentry","category-allgemein","category-howtos","tag-cloud-migration","tag-faas","tag-openshift","tag-snafu","tag-tooling"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v27.2 (Yoast SEO v27.2) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Running Google Cloud Functions in OpenShift - Service Engineering (ICCLab &amp; SPLab)<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/blog.zhaw.ch\/icclab\/running-google-cloud-functions-in-openshift\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Running Google Cloud Functions in OpenShift\" \/>\n<meta property=\"og:description\" content=\"Have you created a highly popular and frequently used JavaScript (Node.js) functions for execution in Google Cloud Functions? In this case, the economics of FaaS turn against you due to the per-invocation pricing. You might want to have more options for both testing the same function locally and for deploying it into an environment with [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/blog.zhaw.ch\/icclab\/running-google-cloud-functions-in-openshift\/\" \/>\n<meta property=\"og:site_name\" content=\"Service Engineering (ICCLab &amp; SPLab)\" \/>\n<meta property=\"article:published_time\" content=\"2017-04-09T05:30:17+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2019-08-05T12:35:26+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/google-functions-300x107.png\" \/>\n<meta name=\"author\" content=\"icclab\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"icclab\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"5 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/blog.zhaw.ch\/icclab\/running-google-cloud-functions-in-openshift\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/blog.zhaw.ch\/icclab\/running-google-cloud-functions-in-openshift\/\"},\"author\":{\"name\":\"icclab\",\"@id\":\"https:\/\/blog.zhaw.ch\/icclab\/#\/schema\/person\/045c6bde7e681e689e4fc051d8932563\"},\"headline\":\"Running Google Cloud Functions in OpenShift\",\"datePublished\":\"2017-04-09T05:30:17+00:00\",\"dateModified\":\"2019-08-05T12:35:26+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/blog.zhaw.ch\/icclab\/running-google-cloud-functions-in-openshift\/\"},\"wordCount\":924,\"commentCount\":0,\"image\":{\"@id\":\"https:\/\/blog.zhaw.ch\/icclab\/running-google-cloud-functions-in-openshift\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/google-functions-300x107.png\",\"keywords\":[\"cloud migration\",\"faas\",\"openshift\",\"snafu\",\"tooling\"],\"articleSection\":[\"*.*\",\"HowTos\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/blog.zhaw.ch\/icclab\/running-google-cloud-functions-in-openshift\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/blog.zhaw.ch\/icclab\/running-google-cloud-functions-in-openshift\/\",\"url\":\"https:\/\/blog.zhaw.ch\/icclab\/running-google-cloud-functions-in-openshift\/\",\"name\":\"Running Google Cloud Functions in OpenShift - Service Engineering (ICCLab &amp; SPLab)\",\"isPartOf\":{\"@id\":\"https:\/\/blog.zhaw.ch\/icclab\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/blog.zhaw.ch\/icclab\/running-google-cloud-functions-in-openshift\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/blog.zhaw.ch\/icclab\/running-google-cloud-functions-in-openshift\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/google-functions-300x107.png\",\"datePublished\":\"2017-04-09T05:30:17+00:00\",\"dateModified\":\"2019-08-05T12:35:26+00:00\",\"author\":{\"@id\":\"https:\/\/blog.zhaw.ch\/icclab\/#\/schema\/person\/045c6bde7e681e689e4fc051d8932563\"},\"breadcrumb\":{\"@id\":\"https:\/\/blog.zhaw.ch\/icclab\/running-google-cloud-functions-in-openshift\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/blog.zhaw.ch\/icclab\/running-google-cloud-functions-in-openshift\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/blog.zhaw.ch\/icclab\/running-google-cloud-functions-in-openshift\/#primaryimage\",\"url\":\"https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/google-functions.png\",\"contentUrl\":\"https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/google-functions.png\",\"width\":1054,\"height\":376},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/blog.zhaw.ch\/icclab\/running-google-cloud-functions-in-openshift\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Startseite\",\"item\":\"https:\/\/blog.zhaw.ch\/icclab\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Running Google Cloud Functions in OpenShift\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/blog.zhaw.ch\/icclab\/#website\",\"url\":\"https:\/\/blog.zhaw.ch\/icclab\/\",\"name\":\"Service Engineering (ICCLab &amp; SPLab)\",\"description\":\"A Blog of the ZHAW Zurich University of Applied Sciences\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/blog.zhaw.ch\/icclab\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/blog.zhaw.ch\/icclab\/#\/schema\/person\/045c6bde7e681e689e4fc051d8932563\",\"name\":\"icclab\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/secure.gravatar.com\/avatar\/7b13169e03783f50e96b96fa2ff222b9c530d13c3125f077c7c44f729b857a51?s=96&d=mm&r=g\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/7b13169e03783f50e96b96fa2ff222b9c530d13c3125f077c7c44f729b857a51?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/7b13169e03783f50e96b96fa2ff222b9c530d13c3125f077c7c44f729b857a51?s=96&d=mm&r=g\",\"caption\":\"icclab\"},\"url\":\"https:\/\/blog.zhaw.ch\/icclab\/author\/icclab\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Running Google Cloud Functions in OpenShift - Service Engineering (ICCLab &amp; SPLab)","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/blog.zhaw.ch\/icclab\/running-google-cloud-functions-in-openshift\/","og_locale":"en_US","og_type":"article","og_title":"Running Google Cloud Functions in OpenShift","og_description":"Have you created a highly popular and frequently used JavaScript (Node.js) functions for execution in Google Cloud Functions? In this case, the economics of FaaS turn against you due to the per-invocation pricing. You might want to have more options for both testing the same function locally and for deploying it into an environment with [&hellip;]","og_url":"https:\/\/blog.zhaw.ch\/icclab\/running-google-cloud-functions-in-openshift\/","og_site_name":"Service Engineering (ICCLab &amp; SPLab)","article_published_time":"2017-04-09T05:30:17+00:00","article_modified_time":"2019-08-05T12:35:26+00:00","og_image":[{"url":"https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/google-functions-300x107.png","type":"","width":"","height":""}],"author":"icclab","twitter_card":"summary_large_image","twitter_misc":{"Written by":"icclab","Est. reading time":"5 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/blog.zhaw.ch\/icclab\/running-google-cloud-functions-in-openshift\/#article","isPartOf":{"@id":"https:\/\/blog.zhaw.ch\/icclab\/running-google-cloud-functions-in-openshift\/"},"author":{"name":"icclab","@id":"https:\/\/blog.zhaw.ch\/icclab\/#\/schema\/person\/045c6bde7e681e689e4fc051d8932563"},"headline":"Running Google Cloud Functions in OpenShift","datePublished":"2017-04-09T05:30:17+00:00","dateModified":"2019-08-05T12:35:26+00:00","mainEntityOfPage":{"@id":"https:\/\/blog.zhaw.ch\/icclab\/running-google-cloud-functions-in-openshift\/"},"wordCount":924,"commentCount":0,"image":{"@id":"https:\/\/blog.zhaw.ch\/icclab\/running-google-cloud-functions-in-openshift\/#primaryimage"},"thumbnailUrl":"https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/google-functions-300x107.png","keywords":["cloud migration","faas","openshift","snafu","tooling"],"articleSection":["*.*","HowTos"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/blog.zhaw.ch\/icclab\/running-google-cloud-functions-in-openshift\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/blog.zhaw.ch\/icclab\/running-google-cloud-functions-in-openshift\/","url":"https:\/\/blog.zhaw.ch\/icclab\/running-google-cloud-functions-in-openshift\/","name":"Running Google Cloud Functions in OpenShift - Service Engineering (ICCLab &amp; SPLab)","isPartOf":{"@id":"https:\/\/blog.zhaw.ch\/icclab\/#website"},"primaryImageOfPage":{"@id":"https:\/\/blog.zhaw.ch\/icclab\/running-google-cloud-functions-in-openshift\/#primaryimage"},"image":{"@id":"https:\/\/blog.zhaw.ch\/icclab\/running-google-cloud-functions-in-openshift\/#primaryimage"},"thumbnailUrl":"https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/google-functions-300x107.png","datePublished":"2017-04-09T05:30:17+00:00","dateModified":"2019-08-05T12:35:26+00:00","author":{"@id":"https:\/\/blog.zhaw.ch\/icclab\/#\/schema\/person\/045c6bde7e681e689e4fc051d8932563"},"breadcrumb":{"@id":"https:\/\/blog.zhaw.ch\/icclab\/running-google-cloud-functions-in-openshift\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/blog.zhaw.ch\/icclab\/running-google-cloud-functions-in-openshift\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/blog.zhaw.ch\/icclab\/running-google-cloud-functions-in-openshift\/#primaryimage","url":"https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/google-functions.png","contentUrl":"https:\/\/blog.zhaw.ch\/icclab\/files\/2017\/04\/google-functions.png","width":1054,"height":376},{"@type":"BreadcrumbList","@id":"https:\/\/blog.zhaw.ch\/icclab\/running-google-cloud-functions-in-openshift\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Startseite","item":"https:\/\/blog.zhaw.ch\/icclab\/"},{"@type":"ListItem","position":2,"name":"Running Google Cloud Functions in OpenShift"}]},{"@type":"WebSite","@id":"https:\/\/blog.zhaw.ch\/icclab\/#website","url":"https:\/\/blog.zhaw.ch\/icclab\/","name":"Service Engineering (ICCLab &amp; SPLab)","description":"A Blog of the ZHAW Zurich University of Applied Sciences","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/blog.zhaw.ch\/icclab\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/blog.zhaw.ch\/icclab\/#\/schema\/person\/045c6bde7e681e689e4fc051d8932563","name":"icclab","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/7b13169e03783f50e96b96fa2ff222b9c530d13c3125f077c7c44f729b857a51?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/7b13169e03783f50e96b96fa2ff222b9c530d13c3125f077c7c44f729b857a51?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/7b13169e03783f50e96b96fa2ff222b9c530d13c3125f077c7c44f729b857a51?s=96&d=mm&r=g","caption":"icclab"},"url":"https:\/\/blog.zhaw.ch\/icclab\/author\/icclab\/"}]}},"_links":{"self":[{"href":"https:\/\/blog.zhaw.ch\/icclab\/wp-json\/wp\/v2\/posts\/11304","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.zhaw.ch\/icclab\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.zhaw.ch\/icclab\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.zhaw.ch\/icclab\/wp-json\/wp\/v2\/users\/486"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.zhaw.ch\/icclab\/wp-json\/wp\/v2\/comments?post=11304"}],"version-history":[{"count":5,"href":"https:\/\/blog.zhaw.ch\/icclab\/wp-json\/wp\/v2\/posts\/11304\/revisions"}],"predecessor-version":[{"id":12530,"href":"https:\/\/blog.zhaw.ch\/icclab\/wp-json\/wp\/v2\/posts\/11304\/revisions\/12530"}],"wp:attachment":[{"href":"https:\/\/blog.zhaw.ch\/icclab\/wp-json\/wp\/v2\/media?parent=11304"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.zhaw.ch\/icclab\/wp-json\/wp\/v2\/categories?post=11304"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.zhaw.ch\/icclab\/wp-json\/wp\/v2\/tags?post=11304"},{"taxonomy":"features","embeddable":true,"href":"https:\/\/blog.zhaw.ch\/icclab\/wp-json\/wp\/v2\/features?post=11304"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}