openshift_我很抱歉openshift我已经把你视为理所当然

openshift

I have been asked by a few customers (I work at Red Hat) about application development on Red Hat OpenShift. In particular, I get asked what the differences are in developing on OpenShift as opposed to other Kubernetes distributions.

一些客户(我在Red Hat工作)向我询问了有关Red Hat OpenShift上的应用程序开发的信息。 特别是,我被问到与其他Kubernetes发行版相比,在OpenShift上进行开发有什么区别。

So the first thing I put them straight on is that Kubernetes is Kubernetes, OpenShift is a platform that is Kubernetes just like AKS or EKS are platforms that are Kubernetes. Each of these platforms add value that address their target user groups. Once that is out of the way then the question is around what value does one platform add over another.

因此,我首先要直言不讳的是,Kubernetes是Kubernetes,OpenShift是一个Kubernetes平台,就像AKS或EKS是Kubernetes平台一样。 这些平台中的每一个都增加了针对其目标用户组的价值。 一旦解决了这个问题,那么问题就出在一个平台与另一个平台之间会增加什么价值。

So, I thought I would write a post with the conclusion of “hey, there’s no difference in getting your code running in AKS, EKS, DIY Kubernetes or “ANother Kubernetes Platform” (I’m going to call this AKP) or on OpenShift, the answer… they are all really easy!”

因此,我以为我会写一篇结论为“嘿,让您的代码在AKS,EKS,DIY Kubernetes或“ ANother Kubernetes平台” (我将其称为AKP)或OpenShift上运行没有区别) ,答案……它们真的很简单!”

但… (But…)

You know, I never started this post with the intention of writing an “OpenShift is great” piece, I was really looking at exploring the newbie developer process and showing that OpenShift is Kubernetes (because…it is!) and the same as developing in AKP, hosted or not.

您知道,我从未以写“ OpenShift很棒”为目的开始这篇文章,我真的是在探索新手开发人员的过程,并表明OpenShift是Kubernetes(因为……是!),并且与在AKP,是否托管。

However, the further I was getting into writing this, the more I realised that OpenShift has been spoiling me all of these years without me noticing! Yes, it is 100% Kubernetes (as much as anything other than the head of the upstream project can be 100%), but it’s just… well, easy! Getting things going as a developer is just easy, there are far fewer “oh, hang on I need to download and figure out how to do this” moments and more “Done” moments!

但是,我写得越深入,我越发意识到OpenShift多年来一直在困扰着我,而我却没有注意到! 是的,它是100%的Kubernetes(除了上游项目负责人以外的其他任何事情都可以是100%),但这只是……很好,很容易! 以开发人员的身份开展工作非常容易,“哦,请耐心等待,我需要下载并弄清楚如何做到这一点”的时刻少得多,而更多的“完成”时刻!

So, I am going to tell you a story of “Hello World” and how I got a simple app deployed and running on both AKP and OpenShift (I’m assuming that you already understand Kubernetes so this isn’t a Kube tutorial). Are you sitting comfortably!

因此,我将告诉您一个“ Hello World”的故事,以及如何在AKP和OpenShift上部署并运行一个简单的应用程序(我假设您已经了解Kubernetes,所以这不是Kube教程)。 您坐得舒适吗?

To keep this opinionated post shorter, I’ve created a companion post with step by step details of getting “Hello World” running: I’m Sorry OpenShift I have taken you for granted (the evidence)

为了使这篇自以为是的文章简短一些,我创建了一个随行文章,其中包含逐步运行“ Hello World”的详细信息:对不起OpenShift,我认为您是理所当然的(证据)

集群 (The Clusters)

So I needed one OpenShift and one AKP. Am I willing to build my own full clusters? Hell no, I’m not really that way inclined! I wanted a simple setup, so for OpenShift I used “Code Ready Containers”, a fully featured single node OpenShift cluster running on my laptop.

所以我需要一个OpenShift和一个AKP。 我愿意建立自己的完整集群吗? 地狱不,我不是真的那么倾向! 我想要一个简单的设置,因此对于OpenShift,我使用了“代码就绪容器” ,它是在笔记本电脑上运行的全功能单节点OpenShift集群。

Image for post

For my AKP cluster I needed something similar, so I used “Minikube”. Both tools originate from the same open source projects so are very similar and they both stand up a virtualized single node cluster of Kubernetes or OpenShift.

对于我的AKP集群,我需要类似的东西,因此我使用了“ Minikube” 。 这两个工具都来自相同的开源项目,因此非常相似,并且都位于Kubernetes或OpenShift的虚拟化单节点集群中。

I didn’t go down the public cloud route as there are things that mean paying for compute, registries, network, data transfer, etc. Who wants to pay for a “Hello World”!

我没有沿着公共云路线走,因为有些事情意味着要为计算,注册,网络,数据传输等支付费用。谁愿意为“ Hello World”支付费用!

Both of these tools were really simple to set up, but be warned, they do need a fair amount of resources and a hypervisor already installed on your laptop.

这两个工具的设置都很简单,但是要注意,它们确实需要大量的资源,并且笔记本电脑上已经安装了虚拟机监控程序。

The Code

代码

I’m testing out the build/deploy/run process here, so the code really isn’t that important, what I need is something that will respond to an API endpoint to return a simple “hello” string.

我在这里测试构建/部署/运行过程,因此代码实际上并不那么重要,我需要的是可以响应API端点以返回简单“ hello”字符串的东西。

Image for post

I’m using Java with the Quarkus framework, not just because it’s cool, but also incredibly good at turning Java into a true container native language with a tiny footprint, super fast startup times second to none, microprofile libraries, and more (I like Quarkus, can you tell)!

我将Java与Quarkus框架一起使用,不仅因为它很酷,而且还非常擅长将Java变成真正的容器本地语言,而且占用空间很小,超快速的启动时间是无与伦比的,微配置文件库等等(我喜欢夸鲁克斯,你能告诉我!

I start with the code, it’s not really that important, but the code base I am using is here.

我从代码开始,并不是那么重要,但是我正在使用的代码库在这里

在另一个Kubernetes平台(AKP)上运行。 (Running on Another Kubernetes Platform (AKP).)

So I am going to start with my AKP cluster on minikube, let’s go! First things first is to get my code into a container image. This is the easy bit, right?

因此,我将从minikube上的AKP集群开始,让我们开始吧! 首先要做的就是将我的代码放入容器映像中。 这很容易,对吧?

How do I build container images on AKP… oh hang on, I forgot that plain old Kuberentes is not really a platform made for building things, it’s a runtime expecting container images to be presented to it. I’ll need to go and build my container image outside of my AKP environment. Not really an issue as I am not exactly re-inventing the wheel, but something I need to do to move forward. I have a few choices:

我如何在AKP上构建容器映像…等等,我忘了普通的Kuberentes并不是真正的用于构建事物的平台,它是一个运行时,期望将容器映像呈现给它。 我需要在AKP环境之外构建容器映像。 并不是一个真正的问题,因为我并没有完全重新发明轮子,而是我需要做一些前进的事情。 我有几种选择:

1 -Use Docker Build

1-使用Docker构建

2 -Use Buildah

2-使用Buildah

3 -why bother going for more let’s just go for one of the two above.

3-为什么要花更多的钱,让我们只选择上面的两个之一。

To build my AKP container image, I use Docker build, as I can act as root on my work laptop and can install Docker as root, fine for me, but probably not fine for others. You can get around this by using VM’s that have root privileges. Buildah on the other hand can build container images without needing root privileges, I mean why do you need to be root to tar up some files! Still, most folks will use Docker so I go down this route.

为了构建我的AKP容器映像,我使用Docker构建,因为我可以在工作笔记本电脑上以root身份运行,并且可以以root身份安装Docker,这对我来说很好,但对其他人可能不适合。 您可以通过使用具有root特权的VM来解决此问题。 另一方面,Buildah可以构建容器映像而无需root特权,我的意思是为什么您需要root用户才能打包某些文件! 尽管如此,大多数人还是会使用Docker,所以我顺其自然。

Image for post

While looking at building the container image, I realise that Quarkus has included a maven goal for getting my “Hello World” containerised. Thanks Quarkus! That’s “Hello World” into a container and tested locally though a single maven command.

在构建容器映像时,我意识到Quarkus包含了将我的“ Hello World”容器化的目标。 感谢Quarkus! 那就是将“ Hello World”放入一个容器中,并通过单个maven命令在本地进行测试。

Testing my container results in something truly awesome…

测试我的容器会带来真正的震撼……

Image for post

OK, code built, I now need to get the container into my Kubernetes cluster. There’s a few ways to do this but I just want simple. I can use kubectl commands to create a deployment directly from my container image right? Simple, I like it.

好的,代码已构建,现在我需要将容器放入Kubernetes集群中。 有几种方法可以做到这一点,但我只是想简单一点。 我可以使用kubectl命令直接从我的容器映像创建部署,对吗? 简单,我喜欢。

Image for post

Hold on a minute, that doesn’t work as it can’t find the image, I need the container image to be in a registry somewhere!

稍等片刻,由于找不到图像,这不起作用,我需要将容器图像放在注册表中的某个地方!

…it’s around this point that I take a furtive look over my shoulder at my OpenShift setup. It was so much easier to do a hello world there, I’m sure I didn’t need to do anything extra! Maybe I have overlooked some of the simplicity in the old girl, I’m sorry OpenShift, I’ll get back to you in a moment.

…大约在这一点上,我在OpenShift设置上偷偷摸摸地看了一眼。 在那打个招呼世界要容易得多,我敢肯定我不需要做任何额外的事情! 也许我忽略了老女孩的一些简单性,对不起OpenShift,我稍后会再与您联系。

让我们继续... (Let’s crack on…)

So I need my container image to live somewhere, luckily we have dockerhub which has to be the goto container registry for our hello world. Dockerhub has a free tier with generous data transfer allowances. Docker images are usually fairly large so be aware of the data movement costs when looking at any of the public cloud registries. I really don’t need a private repository for my “Hello World” container code so, dockerhub is fine.

因此,我需要将容器映像放置在某个地方,幸运的是,我们有dockerhub ,它必须是您好世界的goto容器注册表。 Dockerhub具有免费层,并提供大量数据传输配额。 Docker映像通常很大,因此在查看任何公共云注册表时,请注意数据移动的成本。 我的“ Hello World”容器代码确实不需要私有存储库,因此dockerhub很好。

I do a simple push of my image from local into dockerhub.

我将映像从本地简单推送到dockerhub中。

Image for post

Ok, code sorted, build sorted, image sorted and repository sorted. Getting it running in AKP is the next step. Let’s try the kubectl create command again, now that I have my image available.

好的,对代码进行排序,对构建进行排序,对图像进行排序以及对存储库进行排序。 下一步是使其在AKP中运行。 现在我有了可用的映像,让我们再次尝试kubectl create命令。

Image for post

成功! (Success!)

By running this command, AKP will go ahead and create a deployment with pods running my container image in the cluster! That’s simple (once I’d done the build dance) and quite cool.

通过运行此命令,AKP将继续进行操作,并使用在集群中运行我的容器映像的Pod创建部署! 这很简单(一旦我完成了构建舞蹈),就很酷。

Wohoo, we have it deployed! Now how do I call my Restful endpoint?

Wohoo,我们已经部署了它! 现在如何称呼我的Restful端点?

Image for post

As shown above, I need a Kubernetes service and also something like a load balancer to get traffic into my service (other options do exist).

如上所示,我需要一个Kubernetes服务以及类似负载平衡器的服务来将流量传入我的服务(确实存在其他选项)。

Ok, so the kubectl create deployment does not create a Kubernetes service but I do need one to access my code running in the container.

好的,因此kubectl create部署不会创建Kubernetes服务,但是我确实需要一个服务来访问容器中运行的代码。

In my AKP, I can “expose” my deployment which creates a Kubernetes service, providing a single ip endpoint that provides access to my pods that hold my container instances running on a node somewhere.

在我的AKP中,我可以“公开”我的部署,该部署创建一个Kubernetes服务,并提供一个ip终结点,该终结点提供对我的pod的访问权限,这些pod保持容器实例在某个地方的节点上运行。

Image for post

I’m now asking myself sensible questions so that I don’t get caught by surprise:

我现在正在问自己一些明智的问题,这样我就不会惊讶:

Does ‘kubectl expose’ create an externally addressable ip for my service?”

'kubectl暴露'为我的服务创建一个外部可寻址的ip吗?”

Well… yes or… no! It depends on how you configure the expose command, where you are running your cluster and how it’s set up with load balancers!

好吧……是还是……否! 这取决于您如何配置Exposure命令,在何处运行集群以及如何通过负载均衡器进行设置!

If I am using a cloud provider I can set the expose type=LoadBalancer, a hook to let the underlying cloud provider create a load balancer (ELB for instance) and configure an externally addressable IP for your service. That’s quite cool, but be aware of additional costs and differences in how each cloud needs to be configured.

如果使用的是云提供商,则可以设置暴露类型= LoadBalancer ,这是一个挂钩,可让基础云提供商创建负载均衡器(例如ELB)并为您的服务配置外部可寻址IP。 这很酷,但是请注意额外的成本以及每个云的配置方式的差异。

If I am using my Minikube cluster, I need a little more. I need to install a load balancer (HAProxy, NGINX, etc.) and I need to configure a Kubernetes Ingress objectfor the connection of the load balancer to my service.

如果我正在使用Minikube集群,则需要更多。 我需要安装负载均衡器(HAProxy,NGINX等),并且需要配置Kubernetes Ingress对象以将负载均衡器连接到我的服务。

Oh my, I have taken the OpenShift router for granted so much that OpenShift Routes are just there no fuss. Bah, ok, let me go and find a load balancer for my plain old Kuberenetes.

哦,我的手下,我已经把OpenShift路由器视为理所当然,以至于OpenShift路由没有大惊小怪。 ah,好吧,让我去找一个普通的老Kuberenetes的负载均衡器。

Image for post

Fortunately, I am using minikube, which has some platform features to make it easier to create components like ingress controllers. Minikube comes with an Nginx ingress controller which just needs enabling through the CLI. That saves me some tinkering and configuration pain to get a load balancer installed in the cluster, thanks Minikube!

幸运的是,我正在使用minikube,它具有一些平台功能,可以更轻松地创建诸如入口控制器之类的组件。 Minikube带有Nginx入口控制器,只需要通过CLI启用即可。 Minikube,这使我省去了一些麻烦和配置上的麻烦,以便在群集中安装负载均衡器。

Hopefully, the last piece in the Hello World marathon is to configure an ingress object for my service, which I do and all is good!

希望Hello World马拉松的最后一步是为我的服务配置一个入口对象,我这样做了,一切都很好!

Image for post

Finally, I can get my “Hello World” service to say hello to me when I curl it from the outside world in AKP. That was, not exactly difficult, but certainly not painless, as shown by the process steps below.

最后,当我从AKP中从外界卷曲时,我可以使用“ Hello World”服务向我打招呼。 如下面的处理步骤所示,这并不是完全困难,但肯定不是没有痛苦的。

Image for post

在Openshift上运行 (Running on Openshift)

So I’m done with my AKP build. I want to move on to OpenShift.

这样我就完成了AKP构建。 我想继续进行OpenShift。

I’m going to start with building, deploying, and running my “Hello World”. The simplest way to do this in OpenShift is by executing the new-app command (in case you are not familiar, then the Openshift CLI “oc” command maintains the same APIs as kubectl but adds some additional capabilities. You can execute any kubectl command using oc).

我将从构建,部署和运行“ Hello World”开始。 在OpenShift中执行此操作的最简单方法是执行new-app命令(如果您不熟悉,则Openshift CLI“ oc”命令与kubectl维护相同的API,但增加了一些附加功能。您可以执行任何kubectl命令使用oc)。

Image for post
Image for post

The new-app command that I use points to two things; a base container image, called a builder image, and my source code location. On executing this command, OpenShift does the following:

我使用的new-app命令指向两点: 基本容器映像(称为构建器映像)和我的源代码位置。 执行此命令时,OpenShift将执行以下操作:

  • Created a build pod to do “stuff” for building the app

    创建了一个构建容器来完成构建应用程序的“工作”
  • Created an OpenShift Build config

    创建一个OpenShift构建配置
  • Pulled the builder image into OpenShift’s internal docker registry.

    将构建器映像拉入OpenShift的内部docker注册表中。
  • Cloned the “Hello World” repo locally

    在本地克隆“ Hello World”存储库
  • Seen that there’s a maven pom, so compiled the application using maven

    看到有一个maven pom,所以使用maven编译了应用程序
  • Created a new container image with the compiled java application and pushed this container image into the internal container registry

    使用已编译的Java应用程序创建一个新的容器映像,并将该容器映像推送到内部容器注册表中
  • Created a Kubernetes Deployment with pod spec, service spec etc.

    使用Pod规范,服务规范等创建了Kubernetes部署
  • Kicked off a deploy of the container image.

    启动了容器映像的部署。
  • Removed the build pod.

    删除了构建容器。

And that’s it. From my one command I have turned my source code into a running application in OpenShift. I’ve done nothing else, nothing!

就是这样。 通过一个命令,我将源代码转换为OpenShift中正在运行的应用程序。 我什么也没做

The only other thing I need to do is expose the service to the outside world similar to my AKP.

我唯一需要做的另一件事就是类似于我的AKP将服务公开给外界。

Image for post
Image for post

The expose command creates an OpenShift route, which configures ingress for my “Hello World” all configured with the OpenShift router (an HAProxy Load Balancer by default).

Exposure命令将创建一个OpenShift路由,该路由将为所有配置有OpenShift路由器(默认为HAProxy负载均衡器)的“ Hello World”配置入口。

而已! (That’s it!)

两个命令! (Two commands!)

I was trying to think of ways to talk about how all of the complexities of the process are abstracted, but thought that showing the two commands says it all!

我试图思考讨论如何抽象出流程的所有复杂性的方法,但是我认为显示两个命令就说明了一切!

I originally wanted to write about the fact that OpenShift is Kubernetes and no different to building applications on Kubernetes. But, in writing the post it just made me appreciate OpenShift a whole lot more. Yes OpenShift is Kubernetes, but it’s more, OpenShift has pedigree as an enterprise platform, for building, managing, and running containerised applications. OpenShift has just made the Kubernetes developer experience so much better, faster, and more productive. There’s so many things in there to help me with my application development.

我最初想写一个事实,即OpenShift是Kubernetes,与在Kubernetes上构建应用程序没有什么不同。 但是,在撰写这篇文章时,它使我更加欣赏OpenShift。 是的,OpenShift是Kubernetes,但更重要的是,OpenShift在谱系方面已作为企业平台,用于构建,管理和运行容器化应用程序。 OpenShift刚刚使Kubernetes开发人员的体验变得更好,更快,效率更高。 那里有很多东西可以帮助我进行应用程序开发。

Like?

喜欢?

Like building container images. In my AKP build, I needed Docker installed locally, an account with a cloud container registry somewhere, and possibly some scripting to build and push my image to my cloud registry. And that’s before I even get to Kubernetes!

就像建立容器图片一样。 在我的AKP构建中,我需要在本地安装Docker,在某个地方具有云容器注册表的帐户,并可能需要一些脚本来构建并将映像推送到我的云注册表。 那是在我甚至还没有去Kubernetes之前!

Building containers has always been an integral part of the platform in the form of OpenShift Build configurations. Part of the value of OpenShift is in building container images as a core part of the platform Kubernetes APIs and built into the web console.

以OpenShift Build配置的形式,构建容器一直是平台不可或缺的一部分。 OpenShift的部分价值在于将容器映像构建为平台Kubernetes API的核心部分,并内置到Web控制台中。

I used OpenShift’s Source 2 Image (S2I) process for my Hello World (Originally this was called Source TO Image, but the STI acronym wasn’t the best! ) Anyway… S2I has a number of ways to take source (code or binaries) and turn that source into a container image running in my OpenShift cluster.

我在Hello World中使用了OpenShift的Source 2 Image(S2I)流程(最初称为Source TO Image,但STI的缩写不是最好的!)…S2I有多种获取源代码(代码或二进制文件)的方法并将该来源转换为在我的OpenShift集群中运行的容器映像。

I needed only two things:

我只需要两件事:

  • My source code in a git repo (although could have built from binaries or Dockerfiles)

    我在git repo中的源代码(尽管可以从二进制文件或Dockerfiles构建)

  • A builder image to base the build from (There are many base container images, I used OpenJDK)

    基于构建器的构建器映像(有很多基础容器映像,我使用过OpenJDK)

“I’m sorry OpenShift I have taken you for granted, you do so much for me getting my code running with your S2I“

“对不起,OpenShift我已将您视为理所当然,您为我做的很多事情使我的代码与您的S2I一起运行”

As a developer getting up and running with my “Hello World” I just want to switch it on and work… like it does in OpenShift! Seriously, just point the OpenShift at the source code and a builder pod is created to make the image build happen! OpenShift has its own container build tooling, so with my CRC installed there’s no need to even install Docker!

当开发人员开始使用“ Hello World”并运行时,我只想打开它并开始工作……就像在OpenShift中一样! 认真地说,只需将OpenShift指向源代码,然后会创建一个构建器pod来进行映像构建! OpenShift拥有自己的容器构建工具,因此安装了我的CRC甚至不需要安装Docker!

“I’m sorry OpenShift I have taken you for granted, with your ever so simple image building “

“很抱歉,OpenShift我以您如此简单的图像构建将您视为理所当然”

OpenShift also has another magic thing up it’s sleeve (ok, magic might be a bit strong), it has an internal container registry, so no need for hub.docker.io or any other registry! It’s right there, in the OpenShift cluster and integrated into my image build process. I didn’t even have to do anything extra, the build just pushes the resulting image into the internal registry by default.

OpenShift还具有另一个不可思议的功能(好的,魔术可能有点强大),它具有一个内部容器注册表,因此不需要hub.docker.io或任何其他注册表! 就在这里,在OpenShift集群中,并集成到我的图像构建过程中。 我什至不需要做任何额外的事情,该构建只是默认情况下将生成的图像推送到内部注册表中。

“I’m sorry OpenShift I have taken you for granted, looking after my images in your registry “

“对不起,OpenShift我已将您视为理所当然,正在照顾您注册表中的图像”

OpenShift created a concept called Route for exposing services externally (with additional capabilities such as splitting traffic between multiple backends, sticky sessions, etc). Actually, the design principles behind Routes heavily influenced the Kubernetes Ingress design. I’m not going to go into Openshift networking here, but it’s just easy and nothing additional to do for my Hello World!!

OpenShift创建了一个称为Route的概念,用于在外部公开服务(具有其他功能,例如在多个后端之间分离流量,粘性会话等)。 实际上,Routes背后的设计原则在很大程度上影响了Kubernetes Ingress设计。 我不打算在这里进入Openshift联网,但这很简单,而且我的Hello World无需做任何其他工作!!

“I’m sorry OpenShift I have taken you for granted, you take care of networking so that I don’t need to!“

“对不起,OpenShift我已将您视为理所当然,您会很好地处理网络,这样我就不需要了!”

There are so many more OpenShift features for developers that I haven’t touched on like:

对于开发人员,我还有很多未涉及的OpenShift功能,例如:

  • ODO cli, specifically aimed at simplifying developers command lines.

    ODO cli ,专门旨在简化开发人员的命令行。

  • The developer console in OpenShift, an application centric view of the world.

    OpenShift中的开发者控制台,以应用程序为中心的世界观。
  • IDE plugins for VSCode etc.

    VSCode等的IDE插件
  • OpenShift Operators that give you one click databases, middleware and tons of other things, take a look at Operatorhub.io.

    OpenShift Operators为您提供一键式数据库,中间件和大量其他功能,请查看Operatorhub.io

  • Code Ready Workspaces for a read made integrated into OpenShift developer environment

    用于Read Read的Code Ready工作区已集成到OpenShift开发人员环境中

  • Openshift Pipelines for dev build pipeline

    用于开发构建管道的Openshift管道

  • Not to mention all of the cool tech that is integrated, tested and supported in OpenShift like Serverless through KNative, Service Mesh through Istio/Kiali/Jeager and a heap of other things.

    更不用说在OpenShift中集成,测试和支持的所有出色技术,例如通过KNative通过Serverless,通过Istio / Kiali / Jeager通过Service Mesh以及大量其他东西。

In all, although I am biased, The developer experience is so much more on OpenShift than any other platform. Red Hat had invested a huge amount in this important area, as Kubernetes is nothing without the development of applications that run on the platform.

总体而言,尽管我有偏见,但OpenShift上的开发人员经验要比其他任何平台都要多。 红帽已经在这个重要领域投入了巨资,因为如果不开发在平台上运行的应用程序,Kubernetes就是什么。

Want to give OpenShift a go, then head to https://www.openshift.com/try.

想要尝试一下OpenShift,然后前往https://www.openshift.com/try

Take a look at my other post for the nuts and bolts of Hello World, and also take a look at Red Hat Developers site for more awesome blogs and writing.

看看我的其他文章Hello World的细节,也看看Red Hat Developers网站上的博客和写作。

翻译自: https://medium.com/@graemecolman/im-so-sorry-openshift-i-ve-taken-you-for-granted-f36fb47ea4d9

openshift

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值