Commit Graph

48 Commits

Author SHA1 Message Date
Khaled Henidak (Kal)
a53e2eaeab
move IPv6DualStack feature to stable. (#104691)
* kube-proxy

* endpoints controller

* app: kube-controller-manager

* app: cloud-controller-manager

* kubelet

* app: api-server

* node utils + registry/strategy

* api: validation (comment removal)

* api:pod strategy (util pkg)

* api: docs

* core: integration testing

* kubeadm: change feature gate to GA

* service registry and rest stack

* move feature to GA

* generated
2021-09-24 16:30:22 -07:00
Tim Hockin
017a430dcd Svc REST: Move patchAllocatedValues to storage pkg
All the meaningful callers of it are in that pkg anyway.  Removes 1
FIXME.
2021-09-11 11:30:01 -07:00
Tim Hockin
4ff4160e34 Svc REST: Move normalizeClusterIPs to storage pkg
All the meaningful callers of it are in that pkg anyway.  Removes some
FIXMEs.
2021-09-11 11:30:01 -07:00
Tim Hockin
ca8cfdcae9 Svc REST: Fix single<->dual-stack updates
This removes the old rest_tests and adds significantly more coverage.
Maybe too much.  The v4,v6 and v6,v4 tables are identical but for the
order of families.

This exposed that `trimFieldsForDualStackDowngrade` is called too late
to do anything (since we don't run strategy twice any more).  I moved
similar logic to `PatchAllocatedValues` but I hit on some unclarity.

Specifically, consider a PATCH operation.

Assume I have a valid dual-stack service (with 2 IPs, 2 families, and
policy either require or prefer). What fields can I patch, on their own,
to trigger a downgrade to single-stack?

I think patching policy to "single" is pretty clear intent.

But what if I leave policy and only patch `ipFamilies` down to a single
value (without violating the "can't change first family" rule)?

Or what if I patch `clusterIPs` down to a single IP value?

After much discussion, we decided to make a small API change (OK since
we are beta).  When you want a dual-stack Service you MUST specify the
`ipFamilyPolicy`.  Now we can infer less and avoid ambiguity.
2021-09-11 11:30:01 -07:00
Tim Hockin
ccf3376570 Svc REST: De-layer Update
This is the last layered method.  All allocator logic is moved to the
beginUpdate() path.  Removing the now-useless layer will happen in a
subsequent commit.
2021-09-11 11:30:00 -07:00
Tim Hockin
634055bded Svc REST: De-layer Create
Gut the "outer" Create() and move it to the inner BeginCreate().  This
uses a "transaction" type to make cleanup functions easy to read.

Background:

Service has an "outer" and "inner" REST handler.  This is because of how we do IP and port allocations synchronously, but since we don't have API transactions, we need to roll those back in case of a failure.  Both layers use the same `Strategy`, but the outer calls into the inner, which causes a lot of complexity in the code (including an open-coded partial reimplementation of a date-unknown snapshot of the generic REST code) and results in `Prepare` and `Validate` hooks being called twice.

The "normal" REST flow seems to be:

```
mutating webhooks
generic REST store Create {
    cleanup = BeginCreate
    BeforeCreate {
        strategy.PrepareForCreate {
            dropDisabledFields
        }
        strategy.Validate
        strategy.Canonicalize
    }
    createValidation (validating webhooks)
    storage Create
    cleanup
    AfterCreate
    Decorator
}
```

Service (before this commit) does:

```
mutating webhooks
svc custom Create {
    BeforeCreate {
        strategy.PrepareForCreate {
            dropDisabledFields
        }
        strategy.Validate
        strategy.Canonicalize
    }
    Allocations
    inner (generic) Create {
        cleanup = BeginCreate
        BeforeCreate {
            strategy.PrepareForCreate {
                dropDisabledFields
            }
            strategy.Validate
            strategy.Canonicalize
        }
        createValidation (validating webhooks)
        storage Create
        cleanup
        AfterCreate
        Decorator
    }
}
```

After this commit:

```
mutating webhooks
generic REST store Create {
    cleanup = BeginCreate
        Allocations
    BeforeCreate {
        strategy.PrepareForCreate {
            dropDisabledFields
        }
        strategy.Validate
        strategy.Canonicalize
    }
    createValidation (validating webhooks)
    storage Create
    cleanup
    AfterCreate
        Rollback allocations on error
    Decorator
}
```

This same fix pattern will be applied to Delete and Update in subsequent
commits.
2021-09-11 10:51:45 -07:00
Tim Hockin
d13c920606 Svc: Move ETP clearing to dropTypeDependentFields
I  am not sure why ExternalTrafficPolicy was different, but this is more
consistent with other field clearing logic.
2021-09-11 10:45:30 -07:00
Tim Hockin
73503a4936 Fix a small regression in Service updates
Prior to 1.22 a user could change NodePort values within a service
during an update, and the apiserver would allocate values for any that
were not specified.

Consider a YAML like:

```
apiVersion: v1
kind: Service
metadata:
  name: foo
spec:
  type: NodePort
  ports:
  - name: p
    port: 80
  - name: q
    port: 81
  selector:
    app: foo
```

When this is created, nodeport values will be allocated for each port.
Something like:

```
apiVersion: v1
kind: Service
metadata:
  name: foo
spec:
  clusterIP: 10.0.149.11
  type: NodePort
  ports:
  - name: p
    nodePort: 30872
    port: 80
    protocol: TCP
    targetPort: 9376
  - name: q
    nodePort: 31310
    port: 81
    protocol: TCP
    targetPort: 81
  selector:
    app: foo
```

If the user PUTs (kubectl replace) the original YAML, we would see that
`.nodePort = 0`, and allocate new ports.  This was ugly at best.

In 1.22 we fixed this to not allocate new values if we still had the old
values, but instead re-assign them.  Net new ports would still be seen
as `.nodePort = 0` and so new allocations would be made.

This broke a corner case as follows:

Prior to 1.22, the user could PUT this YAML:

```
apiVersion: v1
kind: Service
metadata:
  name: foo
spec:
  type: NodePort
  ports:
  - name: p
    nodePort: 31310 # note this is the `q` value
    port: 80
  - name: q
    # note this nodePort is not specified
    port: 81
  selector:
    app: foo
```

The `p` port would take the `q` port's value.  The `q` port would be
seen as `.nodePort = 0` and a new value allocated.  In 1.22 this results
in an error (duplicate value in `p` and `q`).

This is VERY minor but it is an API regression, which we try to avoid,
and the fix is not too horrible.

This commit adds more robust testing of this logic.
2021-08-30 12:42:17 -07:00
Tim Hockin
80dda49ce2 Service: Fix semantics for Update wrt allocations
It is not uncommon for users to Create a Service and not specify things
like ClusterIP and NodePort, which we then allocate for them.  They same
that YAML somewhere and later use it again in an Update, but then it
fails.

That's because we detected them trying to set a ClusterIP from a value
to "", which is not allowed.  If it was just NodePort, they would
actually succeed and reallocate a new port.

After this change, we try to "patch" updates where the user did not
specify those values from the old object.
2021-07-07 17:09:12 -07:00
Andrew Sy Kim
4d38d21880 apis: remove Service topologyKeys
Signed-off-by: Andrew Sy Kim <kim.andrewsy@gmail.com>
2021-06-03 22:17:45 -04:00
Jordan Liggitt
8c8a4cf3e4 Add WarningsOnCreate,WarningsOnUpdate 2021-05-18 10:42:36 -04:00
Kevin Delgado
a1fac8cbd9 Server-Side Apply: Status Wiping/Reset Fields
Adds and implements ResetFieldsProvder interface in order to ensure that
the fieldmanager no longer owns fields that get reset before the object
is persisted.

Co-authored-by: Kevin Wiesmueller <kwiesmul@redhat.com>
Co-authored-by: Kevin Delgado <kevindelgado@google.com>
2021-03-10 01:02:18 +00:00
Fangyuan Li
7ed2f1d94d Implements Service Internal Traffic Policy
1. Add API definitions;
2. Add feature gate and drops the field when feature gate is not on;
3. Set default values for the field;
4. Add API Validation
5. add kube-proxy iptables and ipvs implementations
6. add tests
2021-03-07 16:52:59 -08:00
Xudong Liu
72da0b1bb0 Add LoadBalancerClass field in service
KEP-1959: https://github.com/kubernetes/enhancements/tree/master/keps/sig-cloud-provider/1959-service-lb-class-field
2021-03-04 17:11:50 -08:00
David Eads
37cc89ed8d finish removal of exportoptions 2021-01-22 13:47:31 -05:00
Lars Ekman
a0e613363a service.spec.AllocateLoadBalancerNodePorts followup 2020-11-24 08:10:43 +01:00
Laszlo Janosi
c970a46bc1
Mixed protocol support for Services with type=LoadBalancer (#94028)
* Mixed protocol support for Services with type=LoadBalancer

KEP: https://github.com/kubernetes/enhancements/blob/master/keps/sig-network/20200103-mixed-protocol-lb.md
Add new feature gate to control the support of mixed protocols in Services with type=LoadBalancer
Add new fields to the ServiceStatus
  Add Ports to the LoadBalancerIngress, so cloud provider implementations can report the status of the requested load balanc
er ports
  Add ServiceCondition to the ServiceStatus so Service controllers can indicate the conditions of the Service

* regenerate conflicting stuff
2020-11-13 13:21:04 -08:00
Lars Ekman
1f4d852f2f Add service.spec.AllocateLoadBalancerNodePorts 2020-11-13 07:37:22 +01:00
Patrik Cyvoct
d29665cc17
Revert "Merge pull request #92312 from Sh4d1/kep_1860"
This reverts commit ef16faf409, reversing
changes made to 2343b8a68b.
2020-11-11 10:26:53 +01:00
Patrik Cyvoct
7bdf2af648
fix review
Signed-off-by: Patrik Cyvoct <patrik@ptrk.io>
2020-11-07 10:00:51 +01:00
Patrik Cyvoct
0153b96ab8
fix review
Signed-off-by: Patrik Cyvoct <patrik@ptrk.io>
2020-11-07 10:00:27 +01:00
Tim Hockin
a4c9330683 Populate ClusterIPs on read
Old stored services will not have the `clusterIPs` field when read back
without this.

This includes some renaming for clarity and expanded comments, and a new
test for default on read.
2020-10-29 20:40:39 -07:00
Tim Hockin
4f8fb1d3ca Wipe some fields on service "type" updates
Service has had a problem since forever:

- User creates a service type=LoadBalancer
- We silently allocate them a NodePort
- User changes type to ClusterIP
- We fail the operation because they did not clear NodePort

They never asked for or used the NodePort!

Dual-stack introduced some dependent fields that get auto-wiped on
updates.  This carries it further.

If you squint, you can see Service as a big, messy discriminated union,
with type as the discriminator. Ignoring fields for non-selected
union-modes seems right.

This introduces the potential for an apply loop. Specifically, we will
accept YAML that we did not previously accept. Apply could see the
field in local YAML and not in the server and repeatedly try to patch it
in. But since that YAML is currently an error, it seems like a very low
risk. Almost nobody actually specifies their own NodePort values.

To mitigate this somewhat, we only auto-wipe on updates. The same YAML
would fail to create. This is a little inconsistent. We could
auto-wipe on create, too, at the risk of more potential impact.

To do this properly, we need to know the old and new values, which means
we can not do it in defaulting or conversion. So we do it in strategy.

This change also adds unit tests and updates e2e tests to rely on and
verify this behavior.
2020-10-28 10:41:26 -07:00
Tim Hockin
c5f3e560e4 Make some methods into non-methods 2020-10-28 10:41:26 -07:00
Khaled Henidak (Kal)
6675eba3ef
dual stack services (#91824)
* api: structure change

* api: defaulting, conversion, and validation

* [FIX] validation: auto remove second ip/family when service changes to SingleStack

* [FIX] api: defaulting, conversion, and validation

* api-server: clusterIPs alloc, printers, storage and strategy

* [FIX] clusterIPs default on read

* alloc: auto remove second ip/family when service changes to SingleStack

* api-server: repair loop handling for clusterIPs

* api-server: force kubernetes default service into single stack

* api-server: tie dualstack feature flag with endpoint feature flag

* controller-manager: feature flag, endpoint, and endpointSlice controllers handling multi family service

* [FIX] controller-manager: feature flag, endpoint, and endpointSlicecontrollers handling multi family service

* kube-proxy: feature-flag, utils, proxier, and meta proxier

* [FIX] kubeproxy: call both proxier at the same time

* kubenet: remove forced pod IP sorting

* kubectl: modify describe to include ClusterIPs, IPFamilies, and IPFamilyPolicy

* e2e: fix tests that depends on IPFamily field AND add dual stack tests

* e2e: fix expected error message for ClusterIP immutability

* add integration tests for dualstack

the third phase of dual stack is a very complex change in the API,
basically it introduces Dual Stack services. Main changes are:

- It pluralizes the Service IPFamily field to IPFamilies,
and removes the singular field.
- It introduces a new field IPFamilyPolicyType that can take
3 values to express the "dual-stack(mad)ness" of the cluster:
SingleStack, PreferDualStack and RequireDualStack
- It pluralizes ClusterIP to ClusterIPs.

The goal is to add coverage to the services API operations,
taking into account the 6 different modes a cluster can have:

- single stack: IP4 or IPv6 (as of today)
- dual stack: IPv4 only, IPv6 only, IPv4 - IPv6, IPv6 - IPv4

* [FIX] add integration tests for dualstack

* generated data

* generated files

Co-authored-by: Antonio Ojea <aojea@redhat.com>
2020-10-26 13:15:59 -07:00
Clayton Coleman
c6b833ac3c service: fix IPFamily validation and defaulting problems
If the dual-stack flag is enabled and the cluster is single stack IPv6,
the allocator logic for service clusterIP does not properly handle rejecting
a request for an IPv4 family. Return a 422 Invalid on the ipFamily field
when the dual stack flag is on (as it would when it hits beta) and the
cluster is configured for single-stack IPv6.

The family is now defaulted or cleared in BeforeCreate/BeforeUpdate,
and is either inherited from the previous object (if nil or unchanged),
or set to the default strategy's family as necessary. The existing
family defaulting when cluster ip is provided remains in the api
section. We add additonal family defaulting at the time we allocate
the IP to ensure that IPFamily is a consequence of the ClusterIP
and prevent accidental reversion. This defaulting also ensures that
old clients that submit a nil IPFamily for non ClusterIP services
receive a default.

To properly handle validation, make the strategy and the validation code
path condition on which configuration options are passed to service
storage. Move validation and preparation logic inside the strategy where
it belongs. Service validation is now dependent on the configuration of
the server, and as such ValidateConditionService needs to know what the
allowed families are.
2020-05-23 11:08:19 -04:00
Rob Scott
6a33727632
Adding AppProtocol to Service and Endpoints Ports 2020-02-25 17:42:34 -08:00
Roc Chan
c9cf3f5b72 Service Topology implementation
* Implement Service Topology for ipvs and iptables proxier
* Add test files
* API validation
2019-11-15 13:36:43 +08:00
Khaled Henidak(Kal)
5e8ccda71c phase 2: api types + defaulting + validation + disabled fields handling 2019-08-28 15:59:43 +00:00
Tim Hockin
ec60426793 Add dropDisbledFields() to service 2019-08-22 21:36:39 -07:00
Jordan Liggitt
4271384966 Call conditional validation from create/update strategies 2019-02-05 23:09:31 -05:00
Mike Danese
54fd2aaefd replace request.Context with context.Context 2018-04-24 08:59:00 -07:00
Dr. Stefan Schimanski
012b085ac8 pkg/apis/core: mechanical import fixes in dependencies 2017-11-09 12:14:08 +01:00
Dr. Stefan Schimanski
7773a30f67 pkg/api/legacyscheme: fixup imports 2017-10-18 17:23:55 +02:00
zhengjiajin
a88e8e2158 fix issue(#47976)Invalid value error when creating service from exported config 2017-09-06 18:10:19 +08:00
deads2k
ec397c4374 convert default predicates to use the default 2017-08-07 09:05:17 -04:00
Clayton Coleman
2568a92119
Grow signature for predicate attributes to include init status 2017-06-02 22:09:04 -04:00
Dr. Stefan Schimanski
536460e1d9 Mechanical fixup imports: pkg/genericapiserver 2017-02-03 08:15:45 +01:00
deads2k
1ef5d26079 move pkg/storage to apiserver 2017-01-31 19:07:33 -05:00
deads2k
11e8068d3f move pkg/fields to apimachinery 2017-01-19 09:50:16 -05:00
Dr. Stefan Schimanski
3d9449a353 genericapiserver: fix imports 2017-01-19 13:06:47 +01:00
deads2k
a3e71b2cef move name generation to generic api server storage helpers 2017-01-16 16:04:04 -05:00
deads2k
31b6ba4e94 mechanicals 2017-01-13 16:33:09 -05:00
deads2k
6a4d5cd7cc start the apimachinery repo 2017-01-11 09:09:48 -05:00
Dr. Stefan Schimanski
87dd990bb7 Move pkg/api.{Context,RequestContextMapper} into pkg/genericapiserver/api/request 2017-01-03 14:57:33 +01:00
Wojciech Tyczynski
36e6cd19e1 Cache fields for filtering in watchCache. 2016-11-29 09:48:09 +01:00
Hongchao Deng
6f3ac807fd pass SelectionPredicate instead of Filter to storage layer 2016-09-26 09:47:19 -07:00
deads2k
561f8d75a5 move core resource registry packages 2016-09-21 10:11:50 -04:00