Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expecting apiVersion - networking.k8s.io/v1 instead of extensions/v1beta1 #94761

Closed
Tej-Singh-Rana opened this issue Sep 14, 2020 · 17 comments
Closed
Labels
kind/bug Categorizes issue or PR as related to a bug. sig/network Categorizes an issue or PR as relevant to SIG Network. triage/unresolved Indicates an issue that can not or will not be resolved.

Comments

@Tej-Singh-Rana
Copy link

What happened:
Manifest resource :- https://kubernetes.io/docs/concepts/services-networking/ingress/#the-ingress-resource

$ kubectl create -f ing.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: minimal-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - http:
      paths:
      - path: /testpath
        pathType: Prefix
        backend:
          service:
            name: test
            port:
              number: 80


$ kubectl get ingress
Warning: extensions/v1beta1 Ingress is deprecated in v1.14+, unavailable in v1.22+; use networking.k8s.io/v1 Ingress
NAME              CLASS    HOSTS   ADDRESS   PORTS   AGE
minimal-ingress   <none>   *                 80      13m

$ kubectl describe ingress  
Warning: extensions/v1beta1 Ingress is deprecated in v1.14+, unavailable in v1.22+; use networking.k8s.io/v1 Ingress
Name:             minimal-ingress
Namespace:        defaultAddress:
Default backend:  default-http-backend:80 (<error: endpoints "default-http-backend" not found>)
Rules:
  Host        Path  Backends
  ----        ----  --------
  *
              /testpath   test:80 (<error: endpoints "test" not found>)
Annotations:  nginx.ingress.kubernetes.io/rewrite-target: /
Events:       <none>
$ kubectl get ingress minimal-ingress -oyaml
Warning: extensions/v1beta1 Ingress is deprecated in v1.14+, unavailable in v1.22+; use networking.k8s.io/v1 Ingress
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
  creationTimestamp: "2020-09-14T07:30:33Z"
  generation: 1
  managedFields:
  - apiVersion: networking.k8s.io/v1
    fieldsType: FieldsV1
    fieldsV1:
      f:metadata:
        f:annotations:
          .: {}
          f:nginx.ingress.kubernetes.io/rewrite-target: {}
      f:spec:
        f:rules: {}
    manager: kubectl-create
    operation: Update
    time: "2020-09-14T07:30:33Z"
  name: minimal-ingress
  namespace: default
  resourceVersion: "1529"
  selfLink: /apis/extensions/v1beta1/namespaces/default/ingresses/minimal-ingress
  uid: ced9542e-450b-422d-babe-37cb10c1cdce
spec:
  rules:
  - http:
      paths:
      - backend:
          serviceName: test
          servicePort: 80
        path: /testpath
        pathType: Prefix

What you expected to happen:
I would like to know that I used apiVersion: networking.k8s.io/v1 to create an ingress in v1.19 but when I looked into the yaml file via kubectl get ingress minimal-ingress -oyaml, apiVersion is extensions/v1beta1. What kind of behaviour is this? Is it expected?
Can you please look into this and assist me to understand this issue?

Environment:

  • Kubernetes version (use kubectl version):
$ kubectl version
Client Version: version.Info{Major:"1", Minor:"19", GitVersion:"v1.19.0", GitCommit:"e19964183377d0ec2052d1f1fa930c4d7575bd50", GitTreeState:"clean", BuildDate:"2020-08-26T14:30:33Z", GoVersion:"go1.15", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"19", GitVersion:"v1.19.0", GitCommit:"e19964183377d0ec2052d1f1fa930c4d7575bd50", GitTreeState:"clean", BuildDate:"2020-08-26T14:23:04Z", GoVersion:"go1.15", Compiler:"gc", Platform:"linux/amd64"}
  • OS (e.g: cat /etc/os-release):
NAME="Ubuntu"
VERSION="18.04.4 LTS (Bionic Beaver)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 18.04.4 LTS"
VERSION_ID="18.04"
  • Kernel (e.g. uname -a): Linux 4.15.0-111-generic x86_64 x86_64 x86_64 GNU/Linux
  • Install tools: kubeadm
@Tej-Singh-Rana Tej-Singh-Rana added the kind/bug Categorizes issue or PR as related to a bug. label Sep 14, 2020
@k8s-ci-robot k8s-ci-robot added the needs-sig Indicates an issue or PR lacks a `sig/foo` label and requires one. label Sep 14, 2020
@athenabot
Copy link

/sig network

These SIGs are my best guesses for this issue. Please comment /remove-sig <name> if I am incorrect about one.

🤖 I am a bot run by vllry. 👩‍🔬

@k8s-ci-robot k8s-ci-robot added sig/network Categorizes an issue or PR as relevant to SIG Network. and removed needs-sig Indicates an issue or PR lacks a `sig/foo` label and requires one. labels Sep 14, 2020
@athenabot
Copy link

/triage unresolved

Comment /remove-triage unresolved when the issue is assessed and confirmed.

🤖 I am a bot run by vllry. 👩‍🔬

@k8s-ci-robot k8s-ci-robot added the triage/unresolved Indicates an issue that can not or will not be resolved. label Sep 14, 2020
@liggitt
Copy link
Member

liggitt commented Sep 14, 2020

This is working as expected. When you create an ingress object, it can be read via any version (the server handles converting into the requested version). kubectl get ingress is an ambiguous request, since it does not indicate what version is desired to be read.

When an ambiguous request is made, kubectl searches the discovery docs returned by the server to find the first group/version that contains the specified resource.

For compatibility reasons, extensions/v1beta1 has historically been preferred over all other api versions. Now that ingress is the only resource remaining in that group, and is deprecated and has a GA replacement, 1.20 will drop it in priority so that kubectl get ingress would read from networking.k8s.io/v1, but a 1.19 server will still follow the historical priority.

If you want to read a specific version, you can qualify the get request (like kubectl get ingresses.v1.networking.k8s.io ...) or can pass in a manifest file to request the same version specified in the file (kubectl get -f ing.yaml -o yaml)

@liggitt liggitt closed this as completed Sep 14, 2020
@Tej-Singh-Rana
Copy link
Author

Any alternative to read the new ingress explanation details from the kubectl explain command. With the kubectl explain ingresses . It's showing old ingress details. But I need to see details from the apiVersion: networking.k8s.io/v1.
I tried with the kubectl explain ingresses.v1.networking.k8s.io, kubectl explain ingresses.networking.k8s.io but not getting expected results.
Any clue for this.

@liggitt
Copy link
Member

liggitt commented Sep 21, 2020

kubectl explain predated a lot of the generic resource parsing logic, so it has a dedicated --api-version flag

This should do what you want:

kubectl explain ingresses --api-version=networking.k8s.io/v1

@Tej-Singh-Rana
Copy link
Author

Might be the reason, I am performing this in the k8s v1.18. Right now I tried in the v1.19. It worked.
Thanks. Sometimes I can't help it.

@flare-ws
Copy link

Thats not how it should work

Nobody expects such behavior, for example, helmreleases got an update conflict on a same apiversion upon a change

existing_kind: networking.k8s.io/v1beta1, Kind=Ingress, new_kind: networking.k8s.io/v1beta1, Kind=Ingress

@lgmorand
Copy link

Same issue here. that's not a logical behavior. Once a version (1.16) does not serve an api version, I do expect the new one (networking) being the default one when exporting. Why would I export a version which is already deprecated for this specific version of the cluster ?

@YuqiXiao
Copy link

Same issue. It's weird that extensions/v1beta1 ingress is deprecated but still being the default one.

taylorsilva added a commit to concourse/concourse-chart that referenced this issue Feb 9, 2021
Fixes #204

Comment describing the API changes for ingress:
kubernetes/kubernetes#94761 (comment)

Signed-off-by: Taylor Silva <[email protected]>
taylorsilva added a commit to concourse/concourse-chart that referenced this issue Feb 9, 2021
Fixes #204

Comment describing the API changes for ingress:
kubernetes/kubernetes#94761 (comment)

Signed-off-by: Taylor Silva <[email protected]>
jogu added a commit to openid-certification/conformance-suite that referenced this issue Mar 16, 2021
Existing deployments can't be upgraded as they were deployed using
APIs that kubernetes 1.16 (which google upgraded our cluster to) no
longer supports.

You'd think we would follow:

https://docs.gitlab.com/ee/topics/autodevops/troubleshooting.html#error-unable-to-recognize--no-matches-for-kind-deployment-in-version-extensionsv1beta1

but as we've customised our .gitlab-ci.yml quite heavily that method
won't work. Some of the customisation/reasons is listed here:
https://gitlab.com/openid/conformance-suite/-/wikis/gcp-deployment

So manually add a call to do the upgrade using a handy kubectl plugin.

This appears to be upgrading our ingress to a newer version. However
kubectl itself (and the gcp console) seem reluctant to show the newer
version, and kubectl convert fails to upgrade the ingress:

$ kubectl convert -f ./chart/templates/ingress.yaml --output-version "networking/v1beta1"
kubectl convert is DEPRECATED and will be removed in a future version.
In order to convert, kubectl apply the object to the cluster, then
kubectl get at the desired version.
error: networking.Ingress is not suitable for converting to "networking/v1beta1" in scheme "k8s.io/kubernetes/pkg/api/legacyscheme/scheme.go:30"

This seems to be some kubernetes oddity that others have also run into:

kubernetes/kubernetes#94761

As the currently used ingress API won't be removed until kubernetes
1.22 I think we can ignore this for now.

closes #876
@MatthiasLohr
Copy link

If you want to read a specific version, you can qualify the get request (like kubectl get ingresses.v1.networking.k8s.io ...) or can pass in a manifest file to request the same version specified in the file (kubectl get -f ing.yaml -o yaml)

Actually, that does not work for me. I'm executing kubectl get ingresses.v1beta1.networking.k8s.io -A, but I'm still getting even those ingresses which were created with networking.k8s.io/v1. Currently, I'm searching for a way to list all ingresses which I have to migrate from v1beta1 to v1 - and getting these strange outputs does not really help locating them.

@liggitt
Copy link
Member

liggitt commented Apr 12, 2021

I'm executing kubectl get ingresses.v1beta1.networking.k8s.io -A, but I'm still getting even those ingresses which were created with networking.k8s.io/v1.

That is the intended behavior. All ingress objects are available via all served apiVersions, regardless of the version they were created with (the API server converts between versions in order to return ingress objects in the requested version).

Currently, I'm searching for a way to list all ingresses which I have to migrate from v1beta1 to v1

One way is to use API server audit logs to find read/write requests to the v1beta1 endpoints to determine which manifests and clients need to be updated.

@lin404
Copy link

lin404 commented Jul 14, 2021

If you want to read a specific version, you can qualify the get request (like kubectl get ingresses.v1.networking.k8s.io ...)

It does not work. It returns the same list when use kubectl get ingresses.v1.networking.k8s.io and kubectl get ingress.v1beta1.extensions in v1.19

One way is to use API server audit logs to find read/write requests to the v1beta1 endpoints to determine which manifests and clients need to be updated.

I see many logs with read request using /apis/extensions/v1beta1/namespaces/xxxx/ingresses/xxxxx. I guess it is because When you create an ingress object, it can be read via any version as you mentioned above? It is still difficult to determine which apiversion is used by Ingress..

@liggitt
Copy link
Member

liggitt commented Jul 14, 2021

It does not work. It returns the same list when use kubectl get ingresses.v1.networking.k8s.io and kubectl get ingress.v1beta1.extensions in v1.19

The same items are returned, but in a different API version. add -o yaml to see the version returned.

@jeremyrogers
Copy link

The same items are returned, but in a different API version. add -o yaml to see the version returned.

This is not true on kubernetes 1.20.5. kubectl get ingress -oyaml will return apiVersion networking.k8s.io unless ingresses.extensions is specified, even on ingress objects created with extensions/v1beta1. As far as I can tell, the only way to check how the object was created is to use the last-applied-configuration if the object was created declaratively, or to check helm deployment objects like kubent does. I don't know a way to get the actual apiVersion of objects created imperatively outside of helm.

@liggitt
Copy link
Member

liggitt commented Jul 15, 2021

The same items are returned, but in a different API version. add -o yaml to see the version returned.

This is not true on kubernetes 1.20.5. kubectl get ingress -oyaml will return apiVersion networking.k8s.io unless ingresses.extensions is specified

I think we're talking past each other. I was agreeing with you that kubectl get ingresses.v1.networking.k8s.io and kubectl get ingress.v1beta1.extensions returned the same items... the difference between the two requests is the apiVersion those items were returned in, which you can see with -o yaml.

This is not true on kubernetes 1.20.5. kubectl get ingress -oyaml will return apiVersion networking.k8s.io unless ingresses.extensions is specified, even on ingress objects created with extensions/v1beta1.

kubectl get ingress is ambiguous, since ingress resources exist in multiple API groups/versions, so kubectl requests the highest priority group/version as listed in discovery. After Ingress was promoted to v1 in 1.19, the GA networking.k8s.io/v1 API version took priority over the beta extensions/v1beta1 version in 1.20+.

As far as I can tell, the only way to check how the object was created is to use the last-applied-configuration if the object was created declaratively, or to check helm deployment objects like kubent does. I don't know a way to get the actual apiVersion of objects created imperatively outside of helm.

The API version used to create an object is not intentionally exposed in the API... all ingress objects are available via all served apiVersions, regardless of the version they were created with (the API server converts between versions in order to return ingress objects in the requested version).

@jeremyrogers
Copy link

jeremyrogers commented Jul 15, 2021

I see, thank you for clarifying. This means that in 1.22 when ingress.extensions is removed, that all existing ingresses in a cluster will continue to work regardless of how they were created, but new ingresses will have to be created with ingress.networking.k8s.io, correct?

@liggitt
Copy link
Member

liggitt commented Jul 15, 2021

Correct. All existing Ingress objects are accessible via the new API (as they have been in 1.19+), regardless of how they were created.

API clients that talk to the API server over extensions/v1beta1 or networking.k8s.io/v1beta1 endpoints to get/create/update Ingress objects will have to change to networking.k8s.io/v1 to continue working against a 1.22+ cluster.

That includes kubectl (getting ingresses), ingress manifests, other components making Ingress API requests, and ingress controllers (responsible for watching ingress objects and reacting to them).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/bug Categorizes issue or PR as related to a bug. sig/network Categorizes an issue or PR as relevant to SIG Network. triage/unresolved Indicates an issue that can not or will not be resolved.
Projects
None yet
Development

No branches or pull requests

10 participants