knative / serving

Kubernetes-based, scale-to-zero, request-driven compute
https://knative.dev/docs/serving/
Apache License 2.0
5.57k stars 1.16k forks source link

Service (services.serving.knative.dev) is very confusing. #1397

Closed n3wscott closed 5 years ago

n3wscott commented 6 years ago

/area API /kind dev /kind doc

tl;dr: Rename Service to Function.

Argument

Taking Core Kubernetes' Service resource, and comparing it to the Knative Service resource, I am very confused about the naming of this object. And some will say this is a bikeshed topic but disagree: If future users/customers are unable to quickly understand the abstractions being made inside of Knative, they will have a hard time getting value from the project.

Currently we would need to say the following: The Service manages a Route and the Configuration. A Configuration produces one or more Revisions. The Route exposes the Revision via a Service.

Proposal

Rename Service to Function.

Then we could say the following: The Function manages a Route and the Configuration. A Configuration produces one or more Revisions. The Route exposes the Revision via a Service.

At the end of the day, the user is wanting to use the project to host functions, and (a super cool feature of this project!!!) is that you can define your Function from external source and the machine serves that for you!!! NEAT! Likely even in the typical non-k8s way to talk about services, what is being represented by a Revision is not a full application (aka, not really a service). An application is likely assembled from many Functions and external services. (Compare that to: An application assembled from many services and external services.)

There is likely history here, please educate me.

bbrowning commented 6 years ago

Without getting into what things should be named, I will admit that I was confused for several days about how a Knative Service differed from a Kubernetes Service. And why they were named the same.

pmorie commented 6 years ago

I know a lot of time has been invested in choosing the name of the knative service resource, but I think we should reconsider the choice:

Generally, if something is confusing to the development team, users are going to have an even harder time understanding. I think it would pay dividends to have an umbiguous name for the Service|Steve concept - more productive discussions and easier for users to understand.

Full disclosure: I've already built another k8s component (the 'service-catalog') that used Service in resource names, and whenever I talk about the technical details with anyone I have to devote time to disambiguating k8s service and 'service-catalog service'.

@n3wscott for the background on the name you can check out https://github.com/knative/serving/issues/412

scothis commented 6 years ago

I think we've all enjoyed a good laugh during the working group calls when someone asks if they mean the "native service" or the "Knative service". It's confusing to people who are new to the project and for those who have been around for a while when communicating verbally.

I'm 👍 on change, but 👎 on Function since a Revision can represent a function, application or container. Naming is hard.

n3wscott commented 6 years ago

Thanks for the #412 context @pmorie. I was looking for that! Component and Module have a lot of other mean. Node is confusing. ServerlessService is ... speaks for itself. I like Workload.

Other suggestions:

I honestly like Steve more than Service.

pmorie commented 6 years ago

Others:

n3wscott commented 6 years ago

One more: Kservice

markfisher commented 6 years ago

I think in general it's confusing when an "umbrella" resource ends up triggering generation of another resource with the same name. In this case we have:

(Knative)Service -> Route, (k8s)Service, Configuration

In my opinion, there is a similar dissonance in the Knative Configuration since that triggers creation of Revisions, and those in turn create Container resources that include the image as well as "configuration" such as EnvVars. The Knative Configuration resource seems like it should have a name that implies a larger scope of responsibility.

Of the alternate names mentioned thus far for the Knative Service, I think I'd prefer "Workload", but I was also thinking "Application" might work - although that is just one of the 3 types of workload (Function, App, Container) so has a similar issue to "Function". Although I tend to view a Function as just a specific type of Application that happens to use an Invoker base so that a developer can just provide the Function code, where the Invoker plays the "Application" role (Inversion of Control).

josephburnett commented 6 years ago

I prefer the name Workload as the top-level entity because of it generic nature. It's just some stuff to do, independent of the implementation details. It's also what that view is called in the Google Cloud Console, which seems natural to me. All the top-level stuff.

All the other names I've seen so far insinuate behavior. I expect Service to be the K8s Service. Function and Application hint at code structure. ContainerService is redundant because this is Kubernetes and everything goes in a container. Kservice is cute but doesn't clarify the role and scope of the top-level resource. Seed can have too many different meanings, like PRNG seed. Code is close, but leaves out containers as a workload.

grantr commented 6 years ago

Kubernetes is threatening to stake a claim on Application as well: https://github.com/kubernetes-sigs/application

steren commented 6 years ago

As mentioned above, please take the time to read issue #412 where this resource was introduced and and its name picked. In particular, look at the results of a previous user research study.

Naming is hard: it's not very useful to express opinions or tastes. What matters most is to agree on a methodology and a set of constraints, that we then use.

A few points I want to highlight:

markfisher commented 6 years ago

The "set of constraints" should include not using names that conflict with common Kubernetes resources, especially if the latter resources are among those that are generated by the newly defined resource (as is the case with the Knative Service ultimately generating k8s Services via the Route). Even though Knative users will be operating at a higher level, the k8s Service in particular is still going to be among those that any user deploying workloads to Kubernetes continues to be aware of and interact with, because it is the core resource for defining addressable endpoints in Kubernetes. Users will interact with k8s Services when integrating with third-party applications or middleware installed via Helm as well as defining ExternalName-typed k8s Services for interacting with addressable endpoints outside of the cluster. Finally, the k8s Service plays an important role as the interaction point for Istio resource configuration, and that in turn is an important part of Knative. There is no chance that a user of Knative will not need to be aware of the k8s Service resource, and therefore any Knative user is going to face the confusion that this conflicting name creates.

asciimike commented 6 years ago

There is no chance that a user of Knative will not need to be aware of the k8s Service resource, and therefore any Knative user is going to face the confusion that this conflicting name creates.

I would like to push back against this given the personas link @steren added above.

If we create the end product properly, "developers" should not need to understand anything about k8s in order to use it: they simply provide a container image or source and have their function/app/container running. As Steren said, we don't expect them to use kubectl or ever see actual k8s resources. We have solid user research from #412 indicating that "service" is the right term for these folks.

"Operators" managing knative will 100% need to be familiar with k8s terminology, and will need to understand that k8s, Istio, knative, service-catalog, and likely many other product provide "services" as a high level construct. As @kelseyhightower told us, k8s namespacing exists to help solve these issues.

Assuming operational overhead is low (which, if it isn't, the product isn't likely to gain widespread adoption, because if everyone has to understand k8s anyways, what value are we adding?): the vast majority of folks interacting with knative will be developers with no knowledge of k8s. Given this, we'd like to optimize for minimizing developer confusion, as operators are already familiar with k8s concepts (or will have to become so) and will be able to quickly find issues like this one and like #412 describing why things are the way they are.

We spent months arguing about naming internally before results from the research above came back, and found having actual data on what our users thought helped immensely. Moving forward, if folks think they have a better name, I'd ask that they provide research indicating how users find the current name confusing, and how a proposed name is less confusing to that group of users.

I know many of the folks on this thread weren't involved in those discussions or in the research process, so I understand it may be hard to feel bought in to this decision. Ideally #412 provides good background and data to help you feel comfortable--otherwise, please let us know how we can follow up on our own research to solidify results (or, prove our previous research incorrect).


As a side note here, there are still open questions in my mind about if Istio is the right level of abstraction for developers, or if it's in the operator realm. For example: a common developer scenario involves setting up Auth token validation, and Istio RBAC is likely not what that group wants/expects. Something more akin to what's exposed in Ambassador in their AuthService or more ideally something like what Cloud Endpoints Open API spec auth offers is likely to solve their problems faster and with less overhead. I would expect that we'll see an an "abstracted Istio" akin to what's provided in knative at some point, providing this high level functionality.

markfisher commented 6 years ago

In light of the DevOps movement, it seems misguided to view the Developer and Operator roles as being as completely distinct as you've described. The personas may represent ideals, but in reality things will often be blurrier. One thing developers appreciate about the Kubernetes model is that resources are layered so that a higher level experience is available without turning the system into a black box. For example, a developer can push Deployments while still monitoring at the Pod level when necessary. Of course Knative will provide an even higher level experience, but I would find it quite unfortunate if the same model of layering were not viewed as a significant asset.

For the record I have read #412 and am not convinced. As for the user research, I don't think a poll of 47 users where roughly 25% agreed to a name is such "solid" evidence that this should not remain open for debate. You have a larger community now, and many of us are registering concerns about the confusion this name causes as we imagine the community continuing to grow.

I understand the role of namespaces for Kubernetes resources, but I'd be interested to hear @kelseyhightower's opinion on the particular points being raised here. Having a "Service" whose Controller ends up generating another "Service" seems wrong regardless of those 2 types being in different namespaces.

josephburnett commented 6 years ago

Thanks @steren for the background and research data. It appears incongruous to me that we have named our organization Knative (Kubernetes native) but are naming its resources as if the user doesn't know anything about Kubernetes.

Perhaps in our naming of Knative resources we should consider primarily the Operator, who understands K8s and expects Knative to be coherent with existing concepts.

Regarding the Developer, perhaps we should assume that the overall product will be repackaged in such a way that they don't have to think about K8s resources. Along with tooling to provide them with a better user experience than kubectl. At that point, the product provider can rename the system concepts to suit their needs, Service being the most intuitive name for the top-level resource.

steren commented 6 years ago

Regarding the Developer, perhaps we should assume that the overall product will be repackaged in such a way that they don't have to think about K8s resources.

I want to comment on this last point: I consider consistency between API, CLI and UI important. Also, consistency between the Knative API and all "packaged Knative" matters: tooling (e.g. a CI/CD tool) should work seamlessly across all of these because they share the same API, and these tools will need to pick a name. Developers who are familiar with a resource model in one provider should not have to learn new names when switching or using tools.

The Developer persona should not be removed from this discussion, on the opposite, I claim this is the persona we have to pay most attention to because they represent the end user of this product. Notably, Knative Contributors are most likely not in the target audience because they understand too well the insides of Knative or the Operator role. This is why doing research with each Persona matter.

josephburnett commented 6 years ago

Last week I conducted research with 47 developers to assess names for Steve. https://github.com/knative/serving/issues/412#issuecomment-377058905

@tliberman, was this research done for the Developer persona specifically? What about the Operator persona?

My theory is that the Operator would find Service a confusing name for the top-level Knative resource. This would show up in MaxDiff, no?

Knative Contributors are most likely not in the target audience

Agree.

mattmoor commented 6 years ago

cc @sebgoa

sebgoa commented 6 years ago

I know naming is hard but the current situation with Service is as mentioned couple times a difficult CLI experience:

kubectl get services.serving.knative.dev
NAME                CREATED AT
helloworld-python   14m

In the user survey it is mentioned that the Service will be in a namespace (https://github.com/knative/serving/issues/412#issuecomment-377073705 , comment that I don't understand). But here being a new API group kubectl UX is painful.

To avoid emotions, maybe we can re-run a wider study with the group working on Slack.

asciimike commented 6 years ago

@sebgoa namespacing means what you're showing above: having to type the fully qualified name services.serving.knative.dev instead of just services. Agreed it creates a less than ideal kubectl experience. As has been mentioned above, we don't believe that kubectl will be the primary developer interface for knative; instead, we'll have a more imperative, task oriented CLI that that offers commands like knative services list (which may just call kubectl get services.serving.knative.dev under the hood, but is easier for non-k8s devs to understand). FWIW, I believe @mattmoor mentioned that we could provide "short names" to make the operator experience mentioned above less painful. Maybe this is where kservice or similar could come in.

asciimike commented 6 years ago

@josephburnett if we survey the slack group (who I assume is primarily composed mainly of knative contributors), we'll likely get results very similar to what we've seen on this thread and internally at Google.

That said, I agree that it's likely that operators or other k8s-first developers will find the multiple Services confusing. I think this is a necessary tradeoff.

If we build this product primarily for k8s developers (or "people like us"), we won't expand the market, and I worry that we won't see significant adoption. The vast majority of the worlds developers don't know k8s, and adding autoscaling or source-to-container builds to k8s won't automatically make everyone want to use k8s directly. I think we need to provide a higher level abstraction that breaks some from k8s in order to meet developers where they are.

The fact that knative is built on k8s provides necessary escape hatches for developers who grow beyond what is provided and need custom functionality or different scale/performance/cost characteristics. We know that a small percentage of high value customers will need to do this, but we also know that a large percentage of customers who want to become high value customers are attracted to this, even though the vast majority of customers will never grow to the size where they actually need it.


I think it's also a "bug" (in expectations, not technically) in our docs we tell developers to "install knative on their k8s cluster" since this is really an operator action, until we have hosted knative implementations that developers can simply start using without any knowledge of k8s. IMO we should really be striving for the developer experience being "try a tutorial on this tiny hosted version we have, or go to your favorite cloud provider and deploy immediately" while the operator version should have "install on k8s so your devs can have the above experience."

sebgoa commented 6 years ago

@mcdonamp this is not a k8s namespace, it is a custom API group.

Each Service could exist in a different true k8s namespace and then we would have something like:

kubectl get services.serving.knative.dev -n foobar

I am a big fan of using kubectl even for extensions. We could have a knative CLi that abstracts all of this, but we should be able to fall back on kubectl, benefit from the API discovery process and just do kubectl get Steve without having to know the API group.

mattmoor commented 6 years ago

FWIW, Service isn't just overloaded for us, it is also overloaded by Istio (see: VirtualService), but they at least had the good sense to qualify it to avoid the unwieldy domain qualification.

I think what surprises me is that we chose Service despite Component being remarkably close (given the sample size) and having no overloading.

Ultimately, I'm still calling Service "Steve" because for my persona Service is just too overloaded.

asciimike commented 6 years ago

Yep, I was using namespace in the generic sense, not the k8s sense.

We may be a big fan of it, but the majority of the worlds developers are not us.

I'd rather have a "90% painless, 9% possible" experience than a "90% possible but painful, 9% painless" breakdown. I'm worried that if we optimize for the less common "developer needs to break out of the knative CLI and go to straight to kubectl" we'll end up creating the latter rather than the former.

Obviously, if we start getting developer feedback that 90% of developers want to use kubectl directly, then we'll have some serious thinking to do. But in the absence of that, I think we need to design for where developer are while creating an onramp (even if it's a little bumpy) rather than forcing a unit step function jump in knowledge to start using the product.

asciimike commented 6 years ago

@mattmoor I believe component was thrown out because of gcloud components and the somewhat generic nature of component (calling it a thing seems to feel as useful--at least service is tied to things like "microservice" [which I think was also in the running]). ¯_(ツ)_/¯

@steren has told me he doesn't remember this being the case, so I may be wrong here.

mattmoor commented 6 years ago

Well IMO, given what's available for knative today, Steve is a net negative.

Steve makes it so that I don't have to set up a Route; which is great for one-time setup (lowers barrier to entry).

However, Steve makes it harder to get status via kubectl (we haven't furnished anything else), which is a recurring cost. This is entirely from our choice to overload, and the absence of a knative CLI to compensate (I also agree with Seb that a native kubectl UX should be a consideration).

I believe component was thrown out because of gcloud components

I would have pushed back on this, had I been involved and had this context.

Ignoring the vendor-bias that's inherent in this decision, gcloud doesn't suffer the same level of collision as kubectl because anything surfaced would be under a higher-level service grouping e.g. gcloud foo components. While I agree that this is unfortunate conceptual overloading for gcloud, it is IMO a far lesser evil than the path we have chosen.

My $0.02.

asciimike commented 6 years ago

Totally agree that gcloud components is a terrible reason for not going for component. I believe both you and @evankanderson were in the room for that discussion (maybe on 3/26, or during that week?), though I can't find it written down in my notes.

I think it is a consideration, but I don't think we should optimize for kubectl unless we have committed to having developers use that as the primary interface long term. Yes, it's all we have now, but I anticipate that we'll want to have a non-kubectl experience at some point in the near future. @dewitt or @steren probably have more thoughts on that though.

tliberman commented 6 years ago

was this research done for the Developer persona specifically? What about the Operator persona?

@josephburnett The research from #412 was intended to represent the perspective of developers. I did not specifically recruit participants who matched the operator persona.

Participants were recruited who matched the following criteria (and a few others I'll ignore because they're not relevant to the conversation):

My theory is that the Operator would find Service a confusing name for the top-level Knative resource. This would show up in MaxDiff, no?

It's possible, but I don't know enough about the existing participants to be able to separate out their data and draw that conclusion. Also, I didn't ask participants about resource naming in relation to other resources. However, during the group discussion portion of the study sessions, I found participants generally took things like that into consideration when making suggestions and doing the max/diff exercise. Though, no one brought up the conflict with k8s.

steren commented 6 years ago

For the record, I do not recall that gcloud components was in our earlier naming discussion and influenced our decision.

As we can see in my comment on the original issue, we prioritized the top result from the study. What this comment does not capture is why not Component, I think it was because of the genericity of the word.

tliberman commented 6 years ago

I don't think "component" was a contender in the various threads on Steve. The conversation occurred in the meeting where the research from #412 was presented. Because "service" and "component" were the top choices from the maxdiff exercise, we did discuss "component" since we were trying to avoid all of the conflicts with "service". I do remember that we ultimately eliminated "component" because of the conflict with gcloud components

dprotaso commented 6 years ago

Reading this section of the spec/overview gives me the indication I would use a Knative Service mostly for orchestration of certain rollout strategies. What are thoughts about calling it an Orchestrator?

Secondly, I'd be fine for having Service as a temporary name and redoing the study with a broader audience after Knative is announced and public. Given the APIs are alpha provides us the luxury of allowing a rename at a future point.

josephburnett commented 6 years ago

Thanks @tliberman! Where can I read more about the study you conducted? I'm interested in what came up during the group discussion.

Would it be possible to run another study, this time focusing on the Operator persona? I suspect they would be more likely to notice a conflict with Kubernetes names: operator persona

tliberman commented 6 years ago

@josephburnett Myself and UX Researchers on Istio and GKE are working to plan more research to help address general naming issues. I'll bring up the suggestion of being sure to include the operator persona.

steren commented 6 years ago

@dprotaso you can read the description of issue #412 to understand why this resource was introduced. The main reason is that we were missing a higher level concept.

markfisher commented 6 years ago

I like to look for clues in the way something is described when the writer is not thinking too hard about names. In this case, the opening statement describing the project here provides a clue:

extends Kubernetes to provide the missing middleware that developers need to create modern, source-centric, container-based, cloud-native applications.

(emphasis mine)

So perhaps we should consider "Application" as the top-level thing after all?

steren commented 6 years ago

As @grantr noted above, Application is something that is or will be defined in Kubernetes: https://github.com/kubernetes-sigs/application So this proposal has the same issue as Service

markfisher commented 6 years ago

IIUC that Application resource would be a competing alternative to what is currently the Knative Service which is a case where differing API groups for the resource definition would indeed provide delineation. So it's not the same issue since the Knative resource is not itself triggering creation of the resource with the conflicting name as happens today with Service.

asciimike commented 6 years ago

It seems like there are two "mechanical" issues with service being discussed:

@steren was addressing 1, while @markfisher was addressing 2, correct?

Switching to Application would solve 2, but not 1 (assuming k8s takes Application as well).

Though I think Application is broken for the same reason we're not picking Function or Container--it's one of the many types of things that can be deployed to knative.

n3wscott commented 6 years ago

What are thoughts about calling it an Orchestrator? https://github.com/knative/serving/issues/1397#issuecomment-403605812

This is not a bad idea but it is too long, Orca though... If k8s can use pod to mean a group of containers, why not Orca to mean a single active function/service with configuration?

markfisher commented 6 years ago

Though I think Application is broken for the same reason we're not picking Function or Container--it's one of the many types of things that can be deployed to knative.

This ^ is why I found that "welcome" statement so interesting, because it asserts that Knative's primary purpose is create "applications". As I mentioned above, I view Functions as just one type of Application (where the developer has less responsibility thanks to the Inversion of Control provided by an invoker base layer), and I would likewise argue that a "Container" is only usable within Knative if it is in fact a containerized "application" (you can't just push a vanilla "busybox" image).

asciimike commented 6 years ago

blame indicates @dewitt committed it, so I'll let him answer :)

evankanderson commented 6 years ago

FWIW, "Application" is an even more fraught name than "Service", and I'd definitely suggest steering clear of that as a resource object in our system. For many users, "Application" is tied to the little icons that live in one's pocket, and the entire constellation of backing services which enable them (e.g. "Facebook Messenger" as an application).

I think @dewitt's usage here is actually correct -- we're enabling developers to create their applications, but the application is a collection of multiple service.serving.knative.dev resources in addition to some MySQL, memcache, Istio, etc resources. For any reasonably healthy application system, there are probably a dozen ways to deploy and manage such a system, and we're aiming to play well in such a system, not to build an ecosystem deployment tool.

dewitt commented 6 years ago

FWIW, I don't feel strongly about keeping "applications" in the README. "Services" is arguably an even better word in that context.

Re Steve, we should be open to changing. That's why we're pre-1.0 after all. But the benefit of changing should outweigh the cost, and evidence from this thread suggests that selecting a better name is, at best, non-trivial. Fortunately initial user research suggests that people can relate to Service in this context (thanks, @tliberman!), and the other obvious alternatives proposed, like Function, Application, Workload, are equally overloaded or have other problems. I'm personally down on equally generic terms, like Component, because they'll eventually collide with something and don't carry inherent meaning..

In the case of Steve, we're talking about an independently routable and scalable unit of a developer's code and config. In the large, a developer's environment will contain many of these units running together to form higher-order systems. They can be bigger than single functions, and can be composed into applications.

In an operating system (or in a 12-factor app) such an independent unit of scaling could reasonably be called a "process."

But @dprotaso makes a great point that we're not public yet, so maybe we do another round of user studies once we get some more real-world usage.

steren commented 6 years ago

Related note: I suggest to introduce short names for our resources. Let's discuss this in #1588.

This could help improve the "bad kubectl experience" raised in this issue.

markfisher commented 6 years ago

@dewitt I agree most of the alternatives proposed thus far also have issues of their own, but I want to re-emphasize my primary concern with Service is the special case of dissonance caused by a resource named 'X' triggering creation of another resource named 'X'. In this case, the (knative)Service generates a Route which in turn generates a (k8s)Service.

n3wscott commented 6 years ago

I had hopped to add a shortname to Service.serving.knative.dev, but it seems k8s maps short names to the name, not the full name. ie, I added a short name of "ksvc" and k8s expands it to service rather than service.serving.knative.dev. So shortname does not help.

Additionally you can see this mapping in action when you do kubectl get knative, you get something like:

⦿ kubectl get knative
NAME                                             AGE
configurations/github-n3wscott-kopond-rcvadptr   3h
configurations/legit                             22h

NAME                                     AGE
routes/github-n3wscott-kopond-rcvadptr   3h
routes/legit                             22h

NAME                                              AGE
revisions/github-n3wscott-kopond-rcvadptr-00001   3h
revisions/legit-00001                             22h

NAME                                  AGE
svc/github-n3wscott-kopond-rcvadptr   3h
svc/legit                             22h

Note that revisions is the defined name of Revisions so in this view it is the short name or the name, whichever is configured. Service does not have a short name, but because the name conflicts with k8s.Service, we get the short name of svc for k4ve.Service

This could be a bug in kubernetes. I have modifed my shortname for k4ve.Service to be ksvc. But If I do the following:

⦿ kubectl get ksvc
NAME                              TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
github-flow                       ClusterIP   10.19.245.231   <none>        80/TCP    4h
github-flow-channel               ClusterIP   10.19.252.196   <none>        80/TCP    4h
github-n3wscott-kopond-rcvadptr   ClusterIP   10.19.241.219   <none>        80/TCP    4h
kubernetes                        ClusterIP   10.19.240.1     <none>        443/TCP   30d
legit                             ClusterIP   10.19.255.95    <none>        80/TCP    23h

you see that ksvc has been expanded and queried internally to be service, not service.serving.knative.dev. This is a list of the result of the query for kind==service.

mattmoor commented 6 years ago

cc @etune FYI

enisoc commented 6 years ago

I was able to reproduce the behavior @n3wscott described in kubectl 1.9.8 against k8s 1.10.5, just by adding a ksvc short name to the services.serving.knative.dev CRD. I would definitely call this a bug in kubectl. At the API machinery/discovery level, short names are clearly associated with specific, fully-qualified resources. It's incorrect to assume that unqualified resource names never collide, as kubectl seems to assume.

steren commented 6 years ago

I suggest to keep discussing short names in the dedicated issue: https://github.com/knative/serving/issues/1588

imikushin commented 6 years ago

Easy fix: just prefix all Knative objects with K :)

steren commented 6 years ago

We now have short names. Consequently, we can expect kservice or ksvc to be used with kubectl instead of the fully qualified name.

This removes one of the two issues described here.