Compare commits

...

1745 Commits

Author SHA1 Message Date
Marcel Fest
b514ae2733 fix: regression on tests as we moved to context
Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
2026-09-15 17:20:53 +02:00
Marcel Fest
26eab74f3e fix(services): coordinate service, election and manager lifecycle
Serialize per-Service state behind UID locks, order events per Service, and
make readiness and watcher ownership generation-aware. Coordinate shared lease
membership so cleanup cannot cancel a recreated Service, drain cluster workers
before restart, and start the shutdown watcher before slow startup calls.

Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
2026-09-15 17:20:52 +02:00
Marcel Fest
44a67bc901 fix: regression on preserveOnLeadershipLoss
Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
2026-09-15 15:44:08 +02:00
Marcel Fest
7df2e5dd46 test(e2e): give docker kill more time under parallel load
The ARP suite runs four kind clusters against one Docker daemon, so
acknowledging a leader kill regularly exceeded the 5s budget and failed
the IPv6 failover specs before any assertion ran.

Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
2026-09-15 15:27:13 +02:00
Marcel Fest
ba8ffde3c8 fix(instance): roll back partially created instances
Instance creation added addresses, VLAN or macvlan links and DHCP
clients incrementally, so a failure part way through left the node
holding state nobody owned. Initialization now unwinds what it created,
and link cleanup only deletes attachments this instance created that no
remaining instance still uses.

Namespace-dependent tests now skip unless KUBE_VIP_REQUIRE_NETNS is set,
which CI sets on the privileged job so lost capabilities turn it red
instead of silently skipping.

Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
2026-09-15 15:27:12 +02:00
Marcel Fest
65a6a6f8f2 fix(arp): guard manager state behind a single mutex
Instances were kept in a sync.Map with a per-instance mutex for the
refcount, so lookup and refcount update were not atomic: concurrent
Insert and Remove could resurrect a deleted instance or drop a live one.
Hold one manager mutex across both, and buffer link subscriptions so a
netlink sender is never parked on an unread channel during shutdown.

Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
2026-09-15 15:27:11 +02:00
Marcel Fest
94ff8495f4 feat(wireguard): qualify service tunnel IDs by protocol
Sanitisation maps '-' onto the '_' separator, so "a-b/c" and "a/b-c"
shared one nftables chain, and TCP and UDP on the same port collided.
ServicePortIDs appends the protocol and, when sanitisation changed the
name or the ID grew too long, a hash of the raw name. It also returns
the previous port-only ID so existing chains can be migrated.

Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
2026-09-15 15:27:10 +02:00
Marcel Fest
52021d9232 fix(kubevip): reject out-of-range routing protocol values
Netlink carries the address and route protocol in a single byte, so a
configured value above 255 was silently truncated on the wire and never
matched again on readback. Reject it during config validation instead.

Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
2026-09-15 15:27:08 +02:00
Marcel Fest
776f0b18fa fix: dhcp panic and leak potential
Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
2026-09-15 15:26:45 +02:00
Marcel Fest
86ba1d09af fix(vip): synchronize shared datapath state
Serialize the interface link cache, route tracker and address configuration so
concurrent Services cannot corrupt shared state or deadlock on nested address
locks.

Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
2026-09-15 14:01:57 +02:00
Marcel Fest
6512709032 fix: flip flop on ordering when reading and writing the annotation
Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
2026-09-15 13:56:04 +02:00
Marcel Fest
1196748efc feat(lease): record VIP ownership in lease annotations
Encode the instance name, address protocol and an ordered VIP list on the
Kubernetes lease so a restarting instance can tell which tagged addresses it
still owns. Only the current holder publishes the annotation.

Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
Signed-off-by: Cellebyte <marcel.fest@live.de>
Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
2026-09-15 13:56:02 +02:00
dependabot[bot]
d557211b55 build(deps): bump golang.org/x/sys from 0.47.0 to 0.48.0
Bumps [golang.org/x/sys](https://github.com/golang/sys) from 0.47.0 to 0.48.0.
- [Commits](https://github.com/golang/sys/compare/v0.47.0...v0.48.0)

---
updated-dependencies:
- dependency-name: golang.org/x/sys
  dependency-version: 0.48.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-09-14 13:38:41 +02:00
dependabot[bot]
e4eb5e8e7f build(deps): bump github.com/onsi/ginkgo/v2 from 2.32.1 to 2.32.2
Bumps [github.com/onsi/ginkgo/v2](https://github.com/onsi/ginkgo) from 2.32.1 to 2.32.2.
- [Release notes](https://github.com/onsi/ginkgo/releases)
- [Changelog](https://github.com/onsi/ginkgo/blob/master/CHANGELOG.md)
- [Commits](https://github.com/onsi/ginkgo/compare/v2.32.1...v2.32.2)

---
updated-dependencies:
- dependency-name: github.com/onsi/ginkgo/v2
  dependency-version: 2.32.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-09-14 13:09:08 +02:00
dependabot[bot]
a7b068f9d2 build(deps): bump golang.org/x/sync from 0.22.0 to 0.23.0
Bumps [golang.org/x/sync](https://github.com/golang/sync) from 0.22.0 to 0.23.0.
- [Commits](https://github.com/golang/sync/compare/v0.22.0...v0.23.0)

---
updated-dependencies:
- dependency-name: golang.org/x/sync
  dependency-version: 0.23.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-09-14 13:08:26 +02:00
dependabot[bot]
a6bf5280d4 build(deps): bump anchore/sbom-action from 0.24.0 to 0.24.2
Bumps [anchore/sbom-action](https://github.com/anchore/sbom-action) from 0.24.0 to 0.24.2.
- [Release notes](https://github.com/anchore/sbom-action/releases)
- [Changelog](https://github.com/anchore/sbom-action/blob/main/RELEASE.md)
- [Commits](https://github.com/anchore/sbom-action/compare/v0.24.0...v0.24.2)

---
updated-dependencies:
- dependency-name: anchore/sbom-action
  dependency-version: 0.24.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-09-13 22:24:58 +02:00
Cellebyte
61a52e8f2a fix: function calls
Signed-off-by: Cellebyte <marcel.fest@live.de>
2026-09-13 22:02:01 +02:00
Cellebyte
7e2dd0d262 fix: add manager interface at the right place
Signed-off-by: Cellebyte <marcel.fest@live.de>
2026-09-13 22:02:01 +02:00
Cellebyte
7a085cb3ce fix(bgp-cp): mem-leak on stacking defers and never exit
Signed-off-by: Cellebyte <marcel.fest@live.de>
2026-09-13 22:02:01 +02:00
Marcel Fest
1f5c135fd1 use ipv6 in error message 2026-09-13 22:01:14 +02:00
Patryk Strusiewicz-Surmacki
b4771c5319 Fixed DHCP concurrency exit issues
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
2026-09-13 22:01:14 +02:00
Marcel Fest
3771ccee29 Add suggestion for IPv4/IPv6 swap 2026-09-13 21:47:08 +02:00
dependabot[bot]
ee64dceb36 build(deps): bump github.com/onsi/gomega from 1.42.1 to 1.43.0
Bumps [github.com/onsi/gomega](https://github.com/onsi/gomega) from 1.42.1 to 1.43.0.
- [Release notes](https://github.com/onsi/gomega/releases)
- [Changelog](https://github.com/onsi/gomega/blob/master/CHANGELOG.md)
- [Commits](https://github.com/onsi/gomega/compare/v1.42.1...v1.43.0)

---
updated-dependencies:
- dependency-name: github.com/onsi/gomega
  dependency-version: 1.43.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-09-09 22:34:59 +02:00
dependabot[bot]
38fabeba9e build(deps): bump golang from 1.27.0-alpine3.23 to 1.27.1-alpine3.23
Bumps golang from 1.27.0-alpine3.23 to 1.27.1-alpine3.23.

---
updated-dependencies:
- dependency-name: golang
  dependency-version: 1.27.1-alpine3.23
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-09-09 22:10:09 +02:00
dependabot[bot]
7ef1899567 build(deps): bump github.com/google/go-containerregistry
Bumps [github.com/google/go-containerregistry](https://github.com/google/go-containerregistry) from 0.21.9 to 0.22.1.
- [Release notes](https://github.com/google/go-containerregistry/releases)
- [Commits](https://github.com/google/go-containerregistry/compare/v0.21.9...v0.22.1)

---
updated-dependencies:
- dependency-name: github.com/google/go-containerregistry
  dependency-version: 0.22.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-09-09 22:09:14 +02:00
dependabot[bot]
637c3da47e build(deps): bump sigs.k8s.io/kind from 0.32.0 to 0.33.0
Bumps [sigs.k8s.io/kind](https://github.com/kubernetes-sigs/kind) from 0.32.0 to 0.33.0.
- [Release notes](https://github.com/kubernetes-sigs/kind/releases)
- [Changelog](https://github.com/kubernetes-sigs/kind/blob/main/RELEASE.md)
- [Commits](https://github.com/kubernetes-sigs/kind/compare/v0.32.0...v0.33.0)

---
updated-dependencies:
- dependency-name: sigs.k8s.io/kind
  dependency-version: 0.33.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-09-09 22:05:48 +02:00
Maximilian Rink
e666a0cdd1 fix(e2e): harden nightly etcd readiness
Signed-off-by: Maximilian Rink <maximilian.rink@telekom.de>
2026-09-09 18:07:48 +02:00
Maximilian Rink
9a2142c028 ci: bound nightly etcd stabilization
Signed-off-by: Maximilian Rink <maximilian.rink@telekom.de>
2026-09-09 18:07:48 +02:00
Maximilian Rink
0606e9477c ci: surface etcd suite failures and harden nightly artifacts
Review follow-ups: step-level continue-on-error with a run-summary warning
instead of a silently-neutral job, ginkgo JSON report so the log artifact
is never empty, always-upload coverage with if-no-files-found=error,
read-only workflow permissions, GOMAXPROCS=4 for target consistency.

Signed-off-by: Maximilian Rink <maximilian.rink@telekom.de>
2026-09-09 18:07:48 +02:00
Maximilian Rink
8a968618bf ci: add coverage output and nightly workflow with etcd e2e suite
Signed-off-by: Maximilian Rink <maximilian.rink@telekom.de>
2026-09-09 18:07:48 +02:00
dependabot[bot]
5cd138a85b build(deps): bump github.com/osrg/gobgp/v4 from 4.8.0 to 4.9.0
Bumps [github.com/osrg/gobgp/v4](https://github.com/osrg/gobgp) from 4.8.0 to 4.9.0.
- [Release notes](https://github.com/osrg/gobgp/releases)
- [Commits](https://github.com/osrg/gobgp/compare/v4.8.0...v4.9.0)

---
updated-dependencies:
- dependency-name: github.com/osrg/gobgp/v4
  dependency-version: 4.9.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-09-09 17:59:06 +02:00
dependabot[bot]
246a786fe2 build(deps): bump google.golang.org/grpc from 1.83.1 to 1.83.2
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.83.1 to 1.83.2.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.83.1...v1.83.2)

---
updated-dependencies:
- dependency-name: google.golang.org/grpc
  dependency-version: 1.83.2
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-09-09 17:57:42 +02:00
Maximilian Rink
6ee3024bc6 fix(e2e): guard etcd suite teardown after setup failure
Register the cluster handle before setup assertions so partial Kind creation can be cleaned up, while keeping teardown safe when setup fails before registration.

Signed-off-by: Maximilian Rink <maximilian.rink@telekom.de>
2026-09-09 17:23:54 +02:00
dependabot[bot]
2bc2df53fc build(deps): bump github.com/stretchr/testify from 1.11.1 to 1.12.1
Bumps [github.com/stretchr/testify](https://github.com/stretchr/testify) from 1.11.1 to 1.12.1.
- [Release notes](https://github.com/stretchr/testify/releases)
- [Commits](https://github.com/stretchr/testify/compare/v1.11.1...v1.12.1)

---
updated-dependencies:
- dependency-name: github.com/stretchr/testify
  dependency-version: 1.12.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-09-04 14:16:39 +02:00
Marcel Fest
618904dea3 fix(ci): deflake debouncer cancellation test and patch CVE-2026-56854
Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
2026-09-04 13:53:04 +02:00
Maximilian Rink
b116d5a469 chore(iptables): remove unused ListByID, Stats, StructuredStats, ParseStat (#1728)
* test(endpoints): follow WireGuard clear refactor

Signed-off-by: Maximilian Rink <maximilian.rink@telekom.de>

* chore(iptables): remove unused ListByID, Stats, StructuredStats, ParseStat

Signed-off-by: Maximilian Rink <maximilian.rink@telekom.de>

---------

Signed-off-by: Maximilian Rink <maximilian.rink@telekom.de>
2026-09-04 09:10:19 +02:00
Daniel Finneran
6cbf5aaeda Merge pull request #1723 from MaxRink/fix/fix-dhcp-robustness
fix(vip): harden DHCP client lifecycle and reply parsing
2026-09-03 15:22:21 +01:00
Daniel Finneran
dc453f07fc Merge pull request #1720 from MaxRink/fix/fix-dad-skip
fix(vip): apply per-call DAD skip instead of leaking it into persistent state
2026-09-03 15:21:04 +01:00
Daniel Finneran
14b2f51aba Merge pull request #1718 from MaxRink/fix/fix-svcctx-races
fix(servicecontext): synchronize access to shared context fields
2026-09-03 15:20:14 +01:00
Daniel Finneran
01e8fbc3e3 Merge pull request #1716 from MaxRink/fix/fix-debouncer-deadlock
fix(debouncer): prevent deadlock when forwarding to a terminating object
2026-09-03 15:18:39 +01:00
Daniel Finneran
4504649c91 Merge pull request #1710 from MaxRink/fix/fix-cluster-stop
fix(cluster): make Cluster.Stop concurrency-safe and lock Processor.Stop
2026-09-03 15:17:13 +01:00
Daniel Finneran
47f4e75183 Merge pull request #1709 from MaxRink/fix/fix-route-tracker
fix(route): insert route tracker entry only after AddRoute succeeds
2026-09-03 15:16:16 +01:00
Daniel Finneran
f589a18bd9 Merge pull request #1713 from MaxRink/fix/fix-mpbgp-family
fix(bgp): validate MP-BGP fixed-address family
2026-09-02 17:28:58 +01:00
Daniel Finneran
d79f3ddb52 Merge pull request #1714 from MaxRink/fix/fix-endpoints-locality
fix(endpoints): only use Hostname for locality when NodeName is absent
2026-09-02 17:27:19 +01:00
Daniel Finneran
1b25ce7d0e Merge pull request #1712 from MaxRink/fix/fix-annotations-nodelist
fix(manager): handle empty node list in annotations watcher
2026-09-02 17:26:22 +01:00
Daniel Finneran
96c4406d63 Merge pull request #1711 from MaxRink/fix/fix-bgp-peers
fix(bgp): honour configured peer port and keep source interface on MP-BGP fallback
2026-09-02 17:25:43 +01:00
Daniel Finneran
a51944b89d Merge pull request #1707 from MaxRink/fix/ipv6-cp-vip-e2e-timeout
test(e2e): raise IPv6 control-plane VIP reachability timeout for parallel runs
2026-09-02 17:24:42 +01:00
Daniel Finneran
a36dc36947 Merge pull request #1739 from MaxRink/fix/wireguard-clear-test
test(endpoints): follow WireGuard clear refactor
2026-09-01 18:21:42 +03:00
Daniel Finneran
47b546073a Merge pull request #1703 from MaxRink/fix/makefile-go-version
fix: align GO_VERSION with go.mod toolchain requirement
2026-09-01 10:56:39 +03:00
Justin Cichra
2b126dceed Fix bgp_attach_ip_to_interface not applied to Service VIPs (#1744)
shouldAddServiceIP() checks BGPAttachIPToInterface on a per-service
config struct. NewInstance() builds that struct fresh for each Service,
copying over most fields from the global config, missing this one. As
a result the flag has no effect regardless of its value, and BGP-mode
Service VIPs are never bound to the interface.

Copy the field at both construction sites where it's built, and add
a regression test covering the propagation.

Signed-off-by: Justin Cichra <jrcichra@yahoo.com>
2026-08-31 00:20:08 +02:00
Maximilian Rink
110d34b844 ci: retrigger flaky e2e leg
Signed-off-by: Maximilian Rink <maximilian.rink@telekom.de>
2026-08-30 23:21:18 +02:00
Maximilian Rink
5388fed92b fix: align GO_VERSION with go.mod toolchain requirement
go.mod requires go >= 1.26.4 but unit-tests-docker ran golang:1.25.6
with GOTOOLCHAIN=local and failed before running any test. Bump to
1.26.6 and stop leaving a root-owned coverage.out behind on Linux
hosts while preserving the test exit status.

Signed-off-by: Maximilian Rink <maximilian.rink@telekom.de>
2026-08-30 23:21:17 +02:00
Maximilian Rink
487859e76f test(endpoints): follow WireGuard clear refactor
Signed-off-by: Maximilian Rink <maximilian.rink@telekom.de>
2026-08-30 23:21:17 +02:00
Maximilian Rink
0e57deef3d test(e2e): raise IPv6 control-plane VIP reachability timeout for parallel runs
The IPv6 control-plane VIP reachability check used a 5s Eventually
window; under the 4-process parallel e2e run on a 4-vCPU runner NDP
convergence for the IPv6 VIP can exceed that, causing intermittent
timeouts while sibling specs pass. Raise it to a load-tolerant window
matching the IPv4 case; the reachability assertion is unchanged.

Signed-off-by: Maximilian Rink <maximilian.rink@telekom.de>
2026-08-30 23:21:14 +02:00
Maximilian Rink
b25badd185 test(endpoints): follow WireGuard clear refactor
Signed-off-by: Maximilian Rink <maximilian.rink@telekom.de>
2026-08-30 23:21:14 +02:00
Maximilian Rink
77fa726c99 test(bgp): cover peer transport options generically
Signed-off-by: Maximilian Rink <maximilian.rink@telekom.de>
2026-08-30 23:21:12 +02:00
Maximilian Rink
920a0182cb fix(bgp): honour configured peer port and keep source interface on MP-BGP fallback
Signed-off-by: Maximilian Rink <maximilian.rink@telekom.de>
2026-08-30 23:21:11 +02:00
Maximilian Rink
8d043de910 test(endpoints): follow WireGuard clear refactor
Signed-off-by: Maximilian Rink <maximilian.rink@telekom.de>
2026-08-30 23:21:11 +02:00
Maximilian Rink
b0b12cfc13 test(vip): fix errcheck lint in DHCPv4 backoff test
Signed-off-by: Maximilian Rink <maximilian.rink@telekom.de>
2026-08-30 23:21:01 +02:00
Maximilian Rink
b034c81bef fix(vip): harden DHCP client lifecycle and reply parsing
Signed-off-by: Maximilian Rink <maximilian.rink@telekom.de>
2026-08-30 23:21:00 +02:00
Maximilian Rink
ca9640227a test(endpoints): follow WireGuard clear refactor
Signed-off-by: Maximilian Rink <maximilian.rink@telekom.de>
2026-08-30 23:21:00 +02:00
Maximilian Rink
5276f0123f ci: retrigger flaky e2e leg
Signed-off-by: Maximilian Rink <maximilian.rink@telekom.de>
2026-08-30 23:20:58 +02:00
Maximilian Rink
c2e5be6d6a test(endpoints): follow WireGuard clear refactor
Signed-off-by: Maximilian Rink <maximilian.rink@telekom.de>
2026-08-30 23:20:58 +02:00
Maximilian Rink
a8293f66e4 fix(route): insert route tracker entry only after AddRoute succeeds
Signed-off-by: Maximilian Rink <maximilian.rink@telekom.de>
2026-08-28 03:03:04 +02:00
Maximilian Rink
9d72f43f62 test(endpoints): follow WireGuard clear refactor
Signed-off-by: Maximilian Rink <maximilian.rink@telekom.de>
2026-08-28 03:03:02 +02:00
Maximilian Rink
3c3096d89d fix(bgp): validate MP-BGP fixed-address family
Signed-off-by: Maximilian Rink <maximilian.rink@telekom.de>
2026-08-28 03:01:29 +02:00
Maximilian Rink
5d5c893501 test(endpoints): follow WireGuard clear refactor
Signed-off-by: Maximilian Rink <maximilian.rink@telekom.de>
2026-08-28 03:01:28 +02:00
Maximilian Rink
d417a0c8e8 fix(manager): handle empty node list in annotations watcher
Signed-off-by: Maximilian Rink <maximilian.rink@telekom.de>
2026-08-28 00:08:11 +02:00
Maximilian Rink
825ffdb20c test(endpoints): follow WireGuard clear refactor
Signed-off-by: Maximilian Rink <maximilian.rink@telekom.de>
2026-08-28 00:08:09 +02:00
Maximilian Rink
fe3a379f2d fix(debouncer): prevent deadlock when forwarding to a terminating object
Signed-off-by: Maximilian Rink <maximilian.rink@telekom.de>
2026-08-28 00:06:38 +02:00
Maximilian Rink
c42a207c26 test(endpoints): follow WireGuard clear refactor
Signed-off-by: Maximilian Rink <maximilian.rink@telekom.de>
2026-08-28 00:06:36 +02:00
Maximilian Rink
d6e5753464 fix(vip): apply per-call DAD skip instead of leaking it into persistent state
Signed-off-by: Maximilian Rink <maximilian.rink@telekom.de>
2026-08-28 00:05:25 +02:00
Maximilian Rink
5131b92810 test(endpoints): follow WireGuard clear refactor
Signed-off-by: Maximilian Rink <maximilian.rink@telekom.de>
2026-08-28 00:05:23 +02:00
Maximilian Rink
e1fd9ac3e3 fix(cluster): make Cluster.Stop concurrency-safe and lock Processor.Stop
Signed-off-by: Maximilian Rink <maximilian.rink@telekom.de>
2026-08-28 00:02:16 +02:00
Maximilian Rink
1831a05525 test(endpoints): follow WireGuard clear refactor
Signed-off-by: Maximilian Rink <maximilian.rink@telekom.de>
2026-08-28 00:02:14 +02:00
Maximilian Rink
19198d47fa test(endpoints): cover provider locality parity
Signed-off-by: Maximilian Rink <maximilian.rink@telekom.de>
2026-08-28 00:00:53 +02:00
Maximilian Rink
1af388ff9f fix(endpoints): only use Hostname for locality when NodeName is absent
Signed-off-by: Maximilian Rink <maximilian.rink@telekom.de>
2026-08-28 00:00:52 +02:00
Maximilian Rink
d1ff5f2952 test(endpoints): follow WireGuard clear refactor
Signed-off-by: Maximilian Rink <maximilian.rink@telekom.de>
2026-08-28 00:00:50 +02:00
Maximilian Rink
54881a117c fix(endpoints): preserve nil context guard
Signed-off-by: Maximilian Rink <maximilian.rink@telekom.de>
2026-08-27 23:59:48 +02:00
Maximilian Rink
426a409a5d fix(servicecontext): synchronize access to shared context fields
Signed-off-by: Maximilian Rink <maximilian.rink@telekom.de>
2026-08-27 23:59:46 +02:00
Maximilian Rink
5871bec56c test(endpoints): follow WireGuard clear refactor
Signed-off-by: Maximilian Rink <maximilian.rink@telekom.de>
2026-08-27 23:59:45 +02:00
Daniel Finneran
b7f3379514 Merge pull request #1686 from Dessalines39394/fix/star-history-chart
docs: fix broken star history chart in README
2026-08-25 19:01:39 +03:00
Marcel Fest
a15745c442 fix: pr introduced order regression 2026-08-25 13:15:21 +02:00
Marcel Fest
b684eed5a4 fix(egress): prevent stale active-endpoint overwrite (#1701)
Make the endpoint watcher the sole active-endpoint annotation writer so a Service snapshot captured during startup cannot replace a newer endpoint. Preserve intentionally empty snapshots across endpoint-to-zero-to-same transitions, select the cleared annotation from the configured egress family, reject malformed or wrong-family endpoints, and preserve the other family in dual-stack state.

Fixes #1673.

Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
2026-08-24 18:55:11 +02:00
Marcel Fest
0bdd6a9015 refactor/endpoints for different modes (#1699)
* fix(endpoints): recompute and withdraw only when no longer referenced

Track EndpointSlice/Endpoints deletions in provider state instead of stopping
the watcher or clearing unconditionally. Recompute the aggregate endpoint set
after each deletion and only withdraw local routing/BGP/DNAT state once no
tracked object still references it, matching the existing behaviour for a
Modified event that reduces endpoints to zero.

Remove the now-unreachable per-mode delete()/deleteAction() hooks, which acted
on stale pre-deletion state and could withdraw prematurely while another
object still referenced the same address. Fix the WireGuard control-plane
endpoint watcher to drop deleted objects from its cache instead of reloading
them as still current.

Assisted-by: GitHub-Copilot:unspecified
Signed-off-by: Marcel Fest <marcel.fest@telekom.de>

* feat(worker): support global leader election for BGP and WireGuard

Wire the existing global leader-election machinery into BGP.StartServices and
WireGuard.StartServices so both modes can run with a single node advertising
all services, matching the option already available for ARP and RoutingTable.

WireGuard has no multipath mechanism, so it must always run some form of
leader election (per-service or global); remove its no-election path and the
redundant services watcher previously started from OnStartedLeading, which
would have run a second time alongside the global election path.

Assisted-by: GitHub-Copilot:unspecified
Signed-off-by: Marcel Fest <marcel.fest@telekom.de>

* fix(services): drop unnecessary election guard on route teardown

route.Manager.Delete is reference-counted per route and safe to call even
when nothing is tracked for it, exactly like the existing BGP host teardown.
Remove the leader-election guard on the RoutingTable branch of deleteService
so both branches read identically and route cleanup runs consistently across
all leader-election configurations.

Assisted-by: GitHub-Copilot:unspecified
Signed-off-by: Marcel Fest <marcel.fest@telekom.de>

* fix(endpoints): treat an unknown ready condition as ready

Deferring a nil Serving to Ready matched the Serving godoc but stopped
half way: per the EndpointConditions.Ready godoc a nil Ready is an unknown
state that consumers should interpret as ready, which is what kube-proxy
does. An endpoint with both conditions unset, common in manually managed
EndpointSlices for external workloads, was therefore skipped and never
selected as a local endpoint.

Only skip the endpoint when the resolved condition is explicitly false,
and cover the condition permutations in the provider tests.

Assisted-by: GitHub-Copilot:unspecified
Signed-off-by: Marcel Fest <marcel.fest@telekom.de>

* fix(endpoints): reconcile fully on endpoint object deletion

Delete only mirrored part of AddOrModify's zero-endpoint handling, so a
deleted EndpointSlice left the datapath inconsistent in three ways.

In ARP global-leader mode the VIP clusters were left running with no
backends, because the cluster stop that AddOrModify performs was missing.
When endpoints remained, lastKnownGoodEndpoint was never revisited, so a
last known endpoint that lived in the deleted slice stayed stale: egress
rules were neither torn down nor moved and the active-endpoint annotations
were not refreshed. The EndpointSlice controller can delete a whole slice
during consolidation without touching the survivor, so no follow-up event
is guaranteed to repair this. In WireGuard mode processInstance never ran,
leaving DNAT rules pointing at removed addresses.

Extract the shared decisions into shouldProcessInstance and
handleNoEndpoints and use them from both paths, and run the same
lastKnownGoodEndpoint and annotation reconciliation after a deletion.
handleNoEndpoints also guards against a missing instance, which the
deletion path can legitimately hit. The getEndpoints error is now wrapped
with the provider label like every other error here.

Assisted-by: GitHub-Copilot:unspecified
Signed-off-by: Marcel Fest <marcel.fest@telekom.de>

* docs(bgp): call out the services election behaviour change

Enabling leader election in BGP mode now runs a global services leader.
Nothing in the configuration changed for existing deployments, but a user
who enabled it for the control plane previously got the no-leader path,
where every node advertised the service VIP over ECMP, and now gets a
single advertising node.

Record this in the changelog and warn once on startup when this path is
taken, pointing at the settings that restore the previous datapath.

Assisted-by: GitHub-Copilot:unspecified
Signed-off-by: Marcel Fest <marcel.fest@telekom.de>

* refactor(endpoints): deduplicate the control plane endpoint watcher

The watch.Deleted case duplicated the Added/Modified body except for the
provider mutation, which meant maintaining the log message and the DNAT
update in two places. Pick the mutation from the event type and share the
rest.

Also state the single-object invariant on the Endpoints provider's
DeleteObject, so its asymmetry with the slice provider is not mistaken for
an oversight.

Assisted-by: GitHub-Copilot:unspecified
Signed-off-by: Marcel Fest <marcel.fest@telekom.de>

* fix(endpoints): only ever consider active endpoints

GetLocalEndpoints skipped endpoints whose conditions said they were not
serving, but GetAllEndpoints applied no filtering at all. A service using
externalTrafficPolicy: Cluster therefore advertised backends that had
already been marked as not ready, and the two policies disagreed about
which endpoints back the same service.

Extract the condition evaluation into isServing and apply it on both
paths, and assert in the tests that Cluster and Local agree.

Assisted-by: GitHub-Copilot:unspecified
Signed-off-by: Marcel Fest <marcel.fest@telekom.de>

* refactor(endpoints): reconcile every endpoint event through one path

Now that a deletion recomputes the remaining endpoints, AddOrModify and
Delete differed only in how the event mutated the provider. Keeping two
near-identical bodies is what let their behaviour drift apart in the first
place, so fold them into a single Reconcile that dispatches the mutation
in applyEvent.

Deletions consequently pick up the parts of the add path they were still
missing: the IPv6 egress guard, the leader election start, and the
endpointless opt-in branch, which now keeps an opted-in Cluster service up
after its last EndpointSlice disappears instead of tearing it down.

Assisted-by: GitHub-Copilot:unspecified
Signed-off-by: Marcel Fest <marcel.fest@telekom.de>

---------

Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
2026-08-24 18:53:48 +02:00
Maximilian Rink
b864abf27d fix(worker): honor context cancellation in cleanRoutingTable worker (#1726)
Signed-off-by: Maximilian Rink <maximilian.rink@telekom.de>
2026-08-24 16:02:08 +02:00
Maximilian Rink
6fa38027e2 fix(wireguard): guard nil service context in endpoint clear (#1708)
The endpoint worker's delete() path calls clear(nil, nil, service), and
clear() unconditionally dereferenced svcCtx.LeaderCancel, panicking on
every service or endpoint deletion in WireGuard mode (reached via the
endpoint watcher on a Deleted event). Guard the dereference with a nil
check on svcCtx. Adds a regression test that reproduces the panic.

Signed-off-by: Maximilian Rink <maximilian.rink@telekom.de>
2026-08-24 16:00:57 +02:00
dependabot[bot]
b478234d29 build(deps): bump google.golang.org/grpc from 1.83.0 to 1.83.1 (#1731)
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.83.0 to 1.83.1.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.83.0...v1.83.1)

---
updated-dependencies:
- dependency-name: google.golang.org/grpc
  dependency-version: 1.83.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-24 09:35:27 +02:00
dependabot[bot]
03241ee27f build(deps): bump k8s.io/client-go from 0.36.3 to 0.36.4 (#1733)
Bumps [k8s.io/client-go](https://github.com/kubernetes/client-go) from 0.36.3 to 0.36.4.
- [Changelog](https://github.com/kubernetes/client-go/blob/master/CHANGELOG.md)
- [Commits](https://github.com/kubernetes/client-go/compare/v0.36.3...v0.36.4)

---
updated-dependencies:
- dependency-name: k8s.io/client-go
  dependency-version: 0.36.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-24 09:35:20 +02:00
dependabot[bot]
6e8b391685 build(deps): bump golang from 1.26.6-alpine3.23 to 1.27.0-alpine3.23 (#1729)
Bumps golang from 1.26.6-alpine3.23 to 1.27.0-alpine3.23.

---
updated-dependencies:
- dependency-name: golang
  dependency-version: 1.27.0-alpine3.23
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-24 09:35:06 +02:00
Maximilian Rink
e5ff483a23 fix: address review findings from #1698 (#1702)
* fix(e2e/services): pass metrics address as container arg

The prometheusHTTPServer env var is never read by kube-vip; environment
parsing only knows prometheus_server and ignores empty values, so every
parallel DaemonSet still tried to bind the :2112 flag default on the
shared host network. Pass the address as --prometheusHTTPServer instead,
where an empty value really disables the metrics server.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Maximilian Rink <maximilian.rink@telekom.de>

* fix(egress): restore CIDR fallback and cluster-wide SNAT exclusion

Auto-discovery dropped the kube-controller-manager fallback, breaking
clusters whose CNI does its own IPAM without Node PodCIDR allocation.
Fall back to the --cluster-cidr/--service-cluster-ip-range flags when
the ServiceCIDR or Node APIs yield nothing.

Per-node PodCIDR discovery combined with getSameFamilyCidr also
narrowed the SNAT exclusion to the local node's pod CIDR, so egress
traffic to pods on other nodes was SNAT'd to the VIP. Exclude every
same-family pod CIDR in both the nftables and iptables paths.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Maximilian Rink <maximilian.rink@telekom.de>

* test(e2e/services): fail failover tests when the VIP never recovers

leaderFailover and podFailover returned nil when the watch drained
without any post-kill update passing httpTest, so an unreachable VIP
after failover passed CI. Keep the warn-and-continue polling, but turn
the drain path into an error.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Maximilian Rink <maximilian.rink@telekom.de>

* test(e2e/services): require sustained quiet window in lease error check

A single quiet 2 s interval can coincide with the pause between failing
election retries and produce a false pass for the #1664 guard. Require
three consecutive intervals without counter growth and reset the streak
whenever the counter grows.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Maximilian Rink <maximilian.rink@telekom.de>

* fix(svcs): log service deletion only when a tracked service is removed

deleteTrackedService logged '(svcs) deleted' for every watch event of
every non-LoadBalancer service, even when nothing was tracked. Move the
log inside the svcCtx guard.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Maximilian Rink <maximilian.rink@telekom.de>

* fix(svcs): skip API refresh when egress endpoints are unchanged

updateEgressConfiguration issued a Services Get on every no-op watch
event before short-circuiting. Compare the ActiveEndpoint annotations
first and only refresh the service from the API when they differ.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Maximilian Rink <maximilian.rink@telekom.de>

* test(e2e/services): drop dead StartServiceTest and restore run summary

StartServiceTest was dead code once main.go inlined the phases, and the
E2E_KEEP_LOGS-conditional temp-dir cleanup plus the 'Testing Complete'
summary silently disappeared with it. Reinstate both in run() and
collect every test result so parallel failures are all reported instead
of collapsing to the errgroup's first error.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Maximilian Rink <maximilian.rink@telekom.de>

* style(e2e): gofmt test files

gofmt -l flagged e2e_bgp_healthcheck_test.go (the Mode == ModeBGP block
body was never re-indented) and a trailing space in e2e_sigusr1_test.go.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Maximilian Rink <maximilian.rink@telekom.de>

* ci: write ginkgo JSON reports where the artifact upload finds them

Without --output-dir ginkgo resolves the report path relative to the
suite directory, so /tmp/kube-vip-test-report-*.json landed under
testing/e2e/tmp/ and the /tmp/kube-vip-test* artifact glob missed it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Maximilian Rink <maximilian.rink@telekom.de>

* ci: scope cancel-in-progress to PRs and restore tag builds

cancel-in-progress: true also cancelled in-progress main builds on
back-to-back merges; limit cancellation to pull_request runs. The
branches: [main] filter added in the refactor dropped the tag pushes
the bare push trigger previously covered, and the release workflow
only publishes images, so restore lint/test coverage for v* tags.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Maximilian Rink <maximilian.rink@telekom.de>

* ci: fail the validation job on unformatted Go code

make check only formats '*.go pkg cmd' and merely warns, which let
unformatted files under testing/ land. Add a blocking gofmt -l check
over the whole repo that prints the offending files.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Maximilian Rink <maximilian.rink@telekom.de>

* test(e2e/services): kill kube-vip pods in the test namespace during failover

Since the parallel-phase refactor the kube-vip DaemonSet runs in the
per-test namespace, but the failover killer still listed pods in
kube-system, so it never deleted a single pod and no failover was ever
induced. The lenient drain path masked this; the strict assertion
exposed it.

Target the test namespace, gate success on events observed after at
least one actual pod kill, extend the watch window to 60s to leave
convergence margin after the ~25s kill churn, and return distinct
errors for aborted watch, zero kills, and unreachable VIP. Detach test
cleanup from the errgroup context (context.WithoutCancel) and demote
cleanup-path Fatals to errors so one failing test no longer kills
sibling teardown.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Maximilian Rink <maximilian.rink@telekom.de>

* test(e2e/bgp): raise route-destination timeout for parallel runs

With ginkgo --procs=4, sibling processes create kind clusters and load
images on the same runner; the 30s window for the first route check
overlaps that contention and flakes (observed >13s convergence even in
passing specs). Use 120s, matching the BGP health-check suite's
re-announcement timeout. Eventually returns on success, so passing
specs are unaffected.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Maximilian Rink <maximilian.rink@telekom.de>

---------

Signed-off-by: Maximilian Rink <maximilian.rink@telekom.de>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-24 09:30:19 +02:00
Daniel Finneran
bee5cfe4a2 Merge pull request #1698 from kube-vip/refactor/testing
Refactor/testing to speedup CI in Pull Requests
2026-08-21 15:42:46 +01:00
Marcel Fest
81d54050c7 test(e2e/rt): reduce cluster size for four workers
Use one control-plane node for basic route checks and three for health-check scenarios so stopping one API server preserves quorum. Four Ginkgo workers now peak at eight control-plane containers instead of twelve.

Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
2026-08-21 16:07:39 +02:00
Marcel Fest
5e9fcf642c fix: formatting
Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
2026-08-21 16:07:38 +02:00
Marcel Fest
83797e4da1 chore: remove obsolete versioned deployment examples
Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
2026-08-21 16:07:38 +02:00
Marcel Fest
ed28c49f48 test(e2e/services): isolate parallel egress watchers
Scope each egress DaemonSet to its test namespace, pin Kind's dual-stack Pod CIDRs, retain per-instance nftables tables, and grant the test service account ServiceCIDR discovery access.

Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
2026-08-21 16:07:35 +02:00
Marcel Fest
42ba1fefb2 feat(egress): discover cluster CIDRs from Kubernetes APIs
Read ServiceCIDRs and Node PodCIDRs through the Processor client, retain a Service-only controller-manager fallback, and grant generated ClusterRoles get/list/watch access to ServiceCIDRs.

Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
2026-08-21 16:07:26 +02:00
Marcel Fest
988eb0994a fix(services): tear down VIP when Service leaves LoadBalancer type
Base teardown on tracked UID state so LoadBalancer-to-ClusterIP transitions cancel the service context and remove the active instance even when the new object is ignored.

Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
2026-08-21 16:07:25 +02:00
Marcel Fest
90a3892271 test(e2e): parallelize mode scenarios
Run ARP, routing-table, and BGP modes on separate runners, shard scenario resources by Ginkgo worker, and cap routing-table mode at two workers for Kind stability.

Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
2026-08-21 16:07:24 +02:00
Marcel Fest
c553663654 fix(egress): stabilize endpoint-driven SNAT reconciliation
Wait for ready backends, isolate selectors and nftables instances, tolerate transient failover traffic, refresh late endpoint state, and preserve local traffic-policy coverage.

Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
2026-08-21 16:07:23 +02:00
Marcel Fest
b6151a4454 test(e2e/services): isolate parallel test phases
Run independent service scenarios in dedicated namespaces, add per-namespace RBAC and cleanup barriers, make goroutine cleanup cancellation-safe, and parameterize CI execution with phase timing.

Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
2026-08-21 16:07:22 +02:00
Marcel Fest
6f69d4511f test(e2e): harden cluster readiness checks
Replace fixed waits with polling, remove obsolete serialization, and align the BGP health-check mode guard with the rest of the BGP suite.

Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
2026-08-21 16:07:20 +02:00
Marcel Fest
5e2220fd4d Fix/watch err (#1697)
* refactor(errors): centralize fatal error handling

Detect wrapped PanicError values consistently and preserve their underlying causes when adding fatal context. Apply the helpers to manager, cluster, and IPVS error paths.

Assisted-by: GitHub-Copilot:unspecified
Signed-off-by: Marcel Fest <marcel.fest@telekom.de>

* fix(watchers): restart after terminal watch failures

Propagate fatal endpoint watcher failures through the owning service watcher so kube-vip releases leadership instead of remaining active with a stale watch. Treat terminal service, node, and annotation watch failures as errors while preserving clean context cancellation.

Return exhausted authorization failures to RetryWatcher, safely decode watch error objects, and replace direct go-spew diagnostics with structured logging.

Fixes #1685

Assisted-by: GitHub-Copilot:unspecified
Signed-off-by: Marcel Fest <marcel.fest@telekom.de>

* fix(services): replace state after traffic policy changes

Recreate the service context and instance as one generation when a Service change requires teardown. Ignore delayed leadership cleanup from superseded contexts so it cannot remove replacement state.

This prevents a stale Cluster-policy endpoint watcher from winning the service lease after externalTrafficPolicy changes to Local.

Assisted-by: GitHub-Copilot:unspecified
Signed-off-by: Marcel Fest <marcel.fest@telekom.de>

* fix(cli): return command errors to container runtime

Propagate manager and service command failures through Cobra so the process exits with status 1. Show usage for invocation errors while keeping runtime failures concise.

Assisted-by: GitHub-Copilot:unspecified
Signed-off-by: Marcel Fest <marcel.fest@telekom.de>

* refactor(logging): use structured errors

Replace direct stdout error output with slog records for command failures and traffic mirror qdisc lookup failures.

Assisted-by: GitHub-Copilot:unspecified
Signed-off-by: Marcel Fest <marcel.fest@telekom.de>

* fix(watchers): continue after endpoint deletion

Keep EndpointSlice watchers active when an individual endpoint object is deleted so replacement objects can be observed and service traffic can recover.

Assisted-by: GitHub-Copilot:unspecified
Signed-off-by: Marcel Fest <marcel.fest@telekom.de>

---------

Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
2026-08-20 13:03:08 +02:00
Vedant Madane
4e13a81af0 docs: link upgrade guide from README (#1696)
Point operators at the in-place upgrade docs on kube-vip.io.

Fixes #499

Signed-off-by: Vedant Madane <vedantnm@gmail.com>
2026-08-20 08:13:33 +02:00
Marcel Fest
a19500b116 fix: logrus required by our test-cases, now only transient because of containerd (#1694)
* fix: logrus required by our test-cases, now only transient because of containerd

Signed-off-by: Marcel Fest <marcel.fest@telekom.de>

* fix: duplicate log module

Signed-off-by: Marcel Fest <marcel.fest@telekom.de>

* fix(race): between service cancelling lease and lease cancelling service

Signed-off-by: Marcel Fest <marcel.fest@telekom.de>

* fix(race): again

Signed-off-by: Marcel Fest <marcel.fest@telekom.de>

---------

Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
2026-08-19 17:05:49 +02:00
秀吉
85a8c94ac5 go.mod: bump insomniacslk/dhcp past the nclient4 ReadFrom panic fix (#1689)
kube-vip's DHCP client uses nclient4, whose BroadcastRawUDPConn.ReadFrom could
compute a negative DHCP length and panic on a malformed reply. That was fixed
in insomniacslk/dhcp#583; this bumps the module past that commit.

Signed-off-by: thc1006 <84045975+thc1006@users.noreply.github.com>
2026-08-17 11:40:45 +02:00
Daniel
150983ddd0 fix wireguard connmark routing (#1691)
the connmark policy-based routing was broken by tailscale, as we collide
with their connmark range (bits 16 to 23)

Signed-off-by: Daniel Nägele <daniel@naegele.dev>
2026-08-17 10:48:43 +02:00
Patryk Strusiewicz-Surmacki
7911dcf3b9 Fallback to regular BGP if MP-BGP cannot be configured (#1683)
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
Co-authored-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
2026-08-17 10:45:24 +02:00
dependabot[bot]
9748f6366c build(deps): bump golang from 1.26.5-alpine3.23 to 1.26.6-alpine3.23 (#1693)
Bumps golang from 1.26.5-alpine3.23 to 1.26.6-alpine3.23.

---
updated-dependencies:
- dependency-name: golang
  dependency-version: 1.26.6-alpine3.23
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-17 10:33:29 +02:00
Dessalines39394
ea916c5a31 docs: point star history chart to a working provider
The star history chart in the README was broken because it relied on a data source that is now restricted by GitHub's stargazer API limits. Point the chart and its link to an alternative provider that uses a different data source requiring no API token, so the chart renders correctly again.
2026-08-12 12:52:55 +00:00
JP Flouret
6376d89fea fix(dns): compare IP families case-insensitively in getIPbyFamily (#1684)
Signed-off-by: JP Flouret <jpflouret@users.noreply.github.com>
2026-08-12 12:54:33 +02:00
Daniel Finneran
5b2a62a10b Merge pull request #1681 from kube-vip/fix/dns-lookup
Fix/dns lookup
2026-08-11 17:16:28 +01:00
Marcel Fest
202589cd33 fix(go.mod): go.sum fix
Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
2026-08-11 10:01:19 +02:00
Marcel Fest
0040633d89 fix(lint): fix golang-ci-lint Error ST1003
Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
2026-08-11 10:01:18 +02:00
Marcel Fest
dd022d89bb chore(test): bump ginkgo
Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
2026-08-11 10:01:17 +02:00
Marcel Fest
5b01e0aba7 fix(dns): dnsMode is now correctly passed as lowercase thanks #1680
Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
2026-08-11 10:01:15 +02:00
Marcel Fest
7ce55caffa chore(kube-vip): bump version to 1.2.3 (Eins, Zwei, Drei) 2026-08-10 15:49:55 +02:00
dependabot[bot]
85f1c90bcf build(deps): bump github.com/osrg/gobgp/v4 from 4.7.0 to 4.8.0 (#1676)
Bumps [github.com/osrg/gobgp/v4](https://github.com/osrg/gobgp) from 4.7.0 to 4.8.0.
- [Release notes](https://github.com/osrg/gobgp/releases)
- [Commits](https://github.com/osrg/gobgp/compare/v4.7.0...v4.8.0)

---
updated-dependencies:
- dependency-name: github.com/osrg/gobgp/v4
  dependency-version: 4.8.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-10 15:37:58 +02:00
dependabot[bot]
60cea74703 build(deps): bump github.com/google/go-containerregistry (#1677)
Bumps [github.com/google/go-containerregistry](https://github.com/google/go-containerregistry) from 0.21.7 to 0.21.9.
- [Release notes](https://github.com/google/go-containerregistry/releases)
- [Commits](https://github.com/google/go-containerregistry/compare/v0.21.7...v0.21.9)

---
updated-dependencies:
- dependency-name: github.com/google/go-containerregistry
  dependency-version: 0.21.9
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-10 15:37:47 +02:00
Patryk Strusiewicz-Surmacki
530c602152 Fixed route cleanup on startup in RT mode (#1679)
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
Co-authored-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
2026-08-10 15:36:56 +02:00
Daniel Finneran
4577f5bbe2 Merge pull request #1675 from mkowalski/rt-mode-nodad 2026-08-08 13:00:20 +03:00
Daniel Finneran
2572482658 Merge pull request #1671 from mkowalski/backend-kubernetes-addr 2026-08-08 12:59:21 +03:00
Mat Kowalski
15a8ca3881 optional DAD skip for managed VIP addresses
This PR adds an explicit configuration option `vip_skipdad`. This allows
for a proper behaviour in IPv6 networks with RT mode and ECMP. Without
this option only one node can ever hold the same IPv6 VIP what defeats
the purpose of ECMP.

While the ARP mode currently has a recovery mode for failed DAD, RT mode
misses it. It is also more feasible to use config option, as recovery
mode in RT mode would always introduce a ~5s blackholing (we know there
will be a conflict, so first attempt to add a VIP will fail and only the
next one will force IFA_F_NODAD).

For simplicitly we ignore IPv4/IPv6 checks, as kernel transparently
strips IFA_F_NODAD from v4 addresses without throwing errors.

For systems with IPv4 duplicate detection (called ACD and used e.g. in
RHEL10's NetworkManager) this code has no effect as it's only userspace
action and addresses we add via netlink bypass any check.

First discovered on a dual-stack cluster with two routing-table-mode
advertisers: the ingress VIP answered or timed out depending on which
ECMP path the flow hashed to; with NODAD both advertisers accept
traffic.

Signed-off-by: Mat Kowalski <mko@redhat.com>
2026-08-07 13:40:23 +02:00
Patryk Strusiewicz-Surmacki
7f0069a58c Update service on common lease change (#1672)
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
Co-authored-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
2026-08-07 11:14:01 +02:00
Maximilian Rink
cfd86de936 fix(services): start the leader-election loop once per service (#1668)
* fix(lease): do not let a stale cleanup cancel a recreated lease

Every object that starts leader election also starts a goroutine that calls
Manager.Delete once its context is cancelled. Manager.Delete looked the lease up
by name only, so it acted on whatever lease held that name at the time it ran,
not the one the caller was given.

When a service is torn down and rebuilt straight away, the replacement lease is
already registered by the time the old cleanup goroutine runs, so the cleanup
cancels the live replacement and removes it from the manager. The service is
then never handled again: its election loop exits, the lease keeps an empty
holderIdentity, and the VIP is never re-advertised.

This is reachable from an ordinary service update. Flipping
externalTrafficPolicy makes serviceChanged cancel the service context and
rebuild it, which reproduced the stuck lease for minutes.

Pass the lease the caller owns to Manager.Delete and ignore a stale caller,
which keeps cleanup scoped to the instance it belongs to. Callers already hold
that lease. Passing nil keeps the previous behaviour of deleting whichever lease
currently holds the name, which is what the existing tests assert.

Signed-off-by: Maximilian Rink <maximilian.rink@telekom.de>

* fix(lease): retire a lease when its service is torn down

The instance guard in Delete stops a late cleanup from cancelling a replacement
lease, but it cannot help when the replacement *is* the same instance.

A service teardown cancels the service context and leaves the lease registered,
because the cleanup that removes it is deferred to a goroutine. The rebuild that
follows calls Add, which finds that lease still in the map and hands it straight
back, so the new service context is parented to a lease the pending cleanup is
about to cancel. The service then cycles: acquire, lose, re-acquire, every few
seconds, and never settles.

Add Manager.Retire, and call it from the serviceChanged teardown next to the
svcMap purge, so the lease is out of the map before the replacement context is
built. Add also refuses to hand out a lease whose context is already cancelled,
which closes the same hazard for any other path that cancels a lease directly.

Signed-off-by: Maximilian Rink <maximilian.rink@telekom.de>

* fix(lease): keep a common lease alive for the services still using it

Review feedback from Patryk on #1669: Retire cancelled the lease context
outright, so with a common lease a modification of one service would also tear
down every sibling sharing that lease.

Retire was only ever needed for its side effect of getting the lease out of the
map before the rebuild, and Delete already does exactly that once the last
object is gone. Drop Retire and have the teardown path call Delete with its own
object name, so siblings keep the lease alive and the manager API stays
Add/Delete/Get.

TestManager_LeaseLifetimeInvariant replaces the single-scenario test with the
rule for the whole surface: a lease stays usable for exactly as long as at least
one object holds it, and a rebuild afterwards gets a fresh one. It is table
driven over 1, 2 and 4 objects, and the 2 and 4 cases fail against the reviewed
behaviour with "lease was cancelled with N object(s) still holding it".

Signed-off-by: Maximilian Rink <maximilian.rink@telekom.de>

* fix(services): start the leader-election loop once per service - #1665

startLeaderElection restarts itself until the service context is cancelled,
so it only needs to be started once per service lifetime. It was started from
startServiceHandlingIfNeeded on every AddOrModify call instead, and AddOrModify
runs on every EndpointSlice event, so endpoint churn accumulated duplicate
permanent loops for the same service, all contending on the same lease.

Guard the spawn with a sync.Once on the service context. A Once needs no
clearing: the loop is bound to the service context, which is replaced whenever
the service is recreated.

Also drop the les *atomic.Int64 parameter, which was only ever incremented.

Adds a unit test that drives AddOrModify three times and asserts the loop
starts once (fails pre-fix with 3), and an -endpointFlap service e2e test that
flaps the backend 1->0->1 five times and asserts the VIP serves traffic and the
lease has a holder again.

Signed-off-by: Maximilian Rink <maximilian.rink@telekom.de>

* test(services): fault leases and API server access in the e2e test - #1665

The endpointFlap e2e test only asserted that the service recovered after
endpoint churn, which the unfixed code also satisfies, so it did not prove
anything about the reported failure.

Inject faults that actually stress the per-service leader election and assert
convergence after each one:

- endpoint churn: backend scaled 1->0->1 five times
- lease faults: the lease is deleted, then its holderIdentity is blanked, which
  is the exact state reported in the issue
- API server faults: the apiserver is blocked from the leader for longer than
  the lease duration, so its election client loses its backend, then restored

The assertions are on the feature contract, a held lease and a served VIP,
rather than on election internals, so they stay meaningful if the
implementation changes. Duplicate loops are not observable from outside the
process; that part stays pinned by the unit test.

Signed-off-by: Maximilian Rink <maximilian.rink@telekom.de>

* test(services): assert election faults recover, via new election metrics - #1665

The previous e2e test only asserted the service recovered, which the unfixed
code also satisfies, so it proved nothing. The duplicate election loops are not
observable from outside the process, so there was nothing to assert on.

Export the missing state as metrics, replacing the write-only les *atomic.Int64
that used to sit in startLeaderElection with real instrumentation:

- kube_vip_service_election_loops{namespace,name}: live election loops, tracked
  for the lifetime of the goroutine. More than 1 per service means loops leaked.
- kube_vip_service_election_attempts_total{namespace,name}: election attempts,
  so a wedged restart loop is visible as a counter that stops advancing.
- kube_vip_service_election_errors_total{namespace,name,reason}: election
  failures, with reason="no_lease" for the service context and lease manager
  desync.

The e2e test now injects a fault per reported failure mode and asserts a signal
that is actually broken when that bug is present:

- endpoint churn, five debounce-separated flaps (#1665): loops stay <= 1
- endpointslice deletion (#1663 / #1664): no reason="no_lease" errors
- lease deletion and blanked holderIdentity (#1650): attempts keep advancing
- apiserver blocked from the leader past the lease duration: same loss path

Every fault is also followed by the feature contract: a held lease and a VIP
that serves traffic. The unit test asserts the loop gauge alongside the call
count so both layers agree.

Signed-off-by: Maximilian Rink <maximilian.rink@telekom.de>

* test(services): assert the election error counter settles, not that it is zero

Both the fixed and the unfixed branch recorded one reason="no_lease" increment
while the service was first set up, so asserting the counter is zero failed on
correct code too. The #1664 desync makes the counter climb for the lifetime of
the process, so assert it stops growing instead.

Also sample the election loop gauge a few times rather than once, since a loop
that is about to start may not be visible in a single scrape while a leaked one
never goes away.

Signed-off-by: Maximilian Rink <maximilian.rink@telekom.de>

* test(services): assert election progress after a real leadership loss

Deleting the lease object does not make the election client lose leadership, it
just recreates the lease on the next renew, so no new election attempt follows
and the progress assertion failed on correct code.

Move that assertion to the apiserver partition, which is the fault that actually
drives OnStoppedLeading and returns the election, and is therefore where the
#1650 WaitGroup deadlock would wedge the restart loop. The lease object faults
keep asserting convergence only.

Signed-off-by: Maximilian Rink <maximilian.rink@telekom.de>

* test(services): cover the remaining election fault scenarios - #1665

The suite only faulted the paths that the three known bugs live on. Add the
neighbouring ones so a regression in this subsystem is caught wherever it lands:

- VIP release on zero endpoints: with a local traffic policy and no endpoints
  anywhere, the address has to stop answering instead of black-holing traffic.
  Nothing asserted the yield half of the endpoint churn cycle before.
- externalTrafficPolicy flip: makes serviceChanged cancel the service context and
  drop it from svcMap, so the next event has to build a fresh context and lease.
  Same desync class as the endpointslice fault, reached by a different trigger.
- service event storm: 15 annotation patches, driving the spawn-once invariant
  from the service watch instead of the endpoint watch.
- follower partition: cutting a non-leader off from the apiserver must not move
  the lease, stop traffic, or leak a loop on the node that comes back.

Signed-off-by: Maximilian Rink <maximilian.rink@telekom.de>

* test(services): let the election loop count settle before asserting it

A fault that rebuilds the service context, such as the externalTrafficPolicy
flip, legitimately has the old and the new loop alive at the same moment, so a
single scrape saw 2 loops on correct code.

Poll until the count settles instead. A leaked loop only exits with its service
context, which outlives the test, so it never settles and is still caught: the
unfixed code reports 11 loops after endpoint flapping.

Signed-off-by: Maximilian Rink <maximilian.rink@telekom.de>

* test(services): fault the externalTrafficPolicy teardown path

With the lease retirement fix underneath, a service that is torn down and
rebuilt by a traffic policy change converges again, so this fault can be
asserted like the others: at most one election loop, a settled error counter, a
held lease and a served VIP.

Signed-off-by: Maximilian Rink <maximilian.rink@telekom.de>

* test(services): stop the fault suite exhausting the client rate limiter

The fault tests poll the API while waiting for convergence, and by the last
fault the shared clientset had spent client-go's default 5 QPS budget, so a
lease read failed with

    failed to get lease "kubevip-kube-vip-service": client rate limiter Wait
    returned an error: context deadline exceeded

which looked like a convergence failure but was the test's own client giving up.
Raise QPS for the harness and halve the lease polling rate.

Signed-off-by: Maximilian Rink <maximilian.rink@telekom.de>

* test(services): fault a common lease sibling teardown

Cluster-level cover for the case Patryk raised in review of #1669: two services
share one lease, the first is deleted, and the second has to keep serving on that
same lease. A teardown that cancels the lease instead of just releasing the
leaving service takes the sibling down with it.

Adds a commonLease field to the Service helper, which sets the
kube-vip.io/serviceLease annotation along with the cluster traffic policy that a
common lease requires. Also initialises the annotation map unconditionally: it
was only allocated on the egress path, so setting any other annotation first
would have nil-panicked.

Signed-off-by: Maximilian Rink <maximilian.rink@telekom.de>

---------

Signed-off-by: Maximilian Rink <maximilian.rink@telekom.de>
2026-08-06 21:48:59 +02:00
Maximilian Rink
9ff88eba50 fix(lease): do not let a stale cleanup cancel a recreated lease (#1669)
* fix(lease): do not let a stale cleanup cancel a recreated lease

Every object that starts leader election also starts a goroutine that calls
Manager.Delete once its context is cancelled. Manager.Delete looked the lease up
by name only, so it acted on whatever lease held that name at the time it ran,
not the one the caller was given.

When a service is torn down and rebuilt straight away, the replacement lease is
already registered by the time the old cleanup goroutine runs, so the cleanup
cancels the live replacement and removes it from the manager. The service is
then never handled again: its election loop exits, the lease keeps an empty
holderIdentity, and the VIP is never re-advertised.

This is reachable from an ordinary service update. Flipping
externalTrafficPolicy makes serviceChanged cancel the service context and
rebuild it, which reproduced the stuck lease for minutes.

Pass the lease the caller owns to Manager.Delete and ignore a stale caller,
which keeps cleanup scoped to the instance it belongs to. Callers already hold
that lease. Passing nil keeps the previous behaviour of deleting whichever lease
currently holds the name, which is what the existing tests assert.

Signed-off-by: Maximilian Rink <maximilian.rink@telekom.de>

* fix(lease): retire a lease when its service is torn down

The instance guard in Delete stops a late cleanup from cancelling a replacement
lease, but it cannot help when the replacement *is* the same instance.

A service teardown cancels the service context and leaves the lease registered,
because the cleanup that removes it is deferred to a goroutine. The rebuild that
follows calls Add, which finds that lease still in the map and hands it straight
back, so the new service context is parented to a lease the pending cleanup is
about to cancel. The service then cycles: acquire, lose, re-acquire, every few
seconds, and never settles.

Add Manager.Retire, and call it from the serviceChanged teardown next to the
svcMap purge, so the lease is out of the map before the replacement context is
built. Add also refuses to hand out a lease whose context is already cancelled,
which closes the same hazard for any other path that cancels a lease directly.

Signed-off-by: Maximilian Rink <maximilian.rink@telekom.de>

* fix(lease): keep a common lease alive for the services still using it

Review feedback from Patryk on #1669: Retire cancelled the lease context
outright, so with a common lease a modification of one service would also tear
down every sibling sharing that lease.

Retire was only ever needed for its side effect of getting the lease out of the
map before the rebuild, and Delete already does exactly that once the last
object is gone. Drop Retire and have the teardown path call Delete with its own
object name, so siblings keep the lease alive and the manager API stays
Add/Delete/Get.

TestManager_LeaseLifetimeInvariant replaces the single-scenario test with the
rule for the whole surface: a lease stays usable for exactly as long as at least
one object holds it, and a rebuild afterwards gets a fresh one. It is table
driven over 1, 2 and 4 objects, and the 2 and 4 cases fail against the reviewed
behaviour with "lease was cancelled with N object(s) still holding it".

Signed-off-by: Maximilian Rink <maximilian.rink@telekom.de>

---------

Signed-off-by: Maximilian Rink <maximilian.rink@telekom.de>
2026-08-06 21:46:31 +02:00
Mat Kowalski
fdbad81da2 routing table mode: honor the configured Kubernetes address for backend health checks
In the RT-mode with cp_enable, health check resolves the node address
via getNodeIPs and calls https://node-ip:6443.

In deployments where apiserver does not have a certificate for the node
IP this fails with "failed to verify certificate: x509: [...]"

When an explicit k8s address is configured via KubernetesAddr, we want
to use it for the backend health check instead of the node addresses.

Fixes: #1670

Signed-off-by: Mat Kowalski <mko@redhat.com>
2026-08-06 16:34:21 +02:00
Patryk Strusiewicz-Surmacki
d1fa3a20ec Fixed IP updater for DNS (#1667)
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
Co-authored-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
2026-08-05 17:03:10 +02:00
dependabot[bot]
1e81d048b7 build(deps): bump google.golang.org/grpc from 1.82.1 to 1.83.0 (#1661)
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.82.1 to 1.83.0.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.82.1...v1.83.0)

---
updated-dependencies:
- dependency-name: google.golang.org/grpc
  dependency-version: 1.83.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-05 09:02:09 +02:00
dependabot[bot]
bedbba70a7 build(deps): bump k8s.io/client-go from 0.36.2 to 0.36.3 (#1662)
Bumps [k8s.io/client-go](https://github.com/kubernetes/client-go) from 0.36.2 to 0.36.3.
- [Changelog](https://github.com/kubernetes/client-go/blob/master/CHANGELOG.md)
- [Commits](https://github.com/kubernetes/client-go/compare/v0.36.2...v0.36.3)

---
updated-dependencies:
- dependency-name: k8s.io/client-go
  dependency-version: 0.36.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-05 09:01:57 +02:00
dependabot[bot]
4f32829ab0 build(deps): bump k8s.io/api from 0.36.2 to 0.36.3 (#1660)
Bumps [k8s.io/api](https://github.com/kubernetes/api) from 0.36.2 to 0.36.3.
- [Commits](https://github.com/kubernetes/api/compare/v0.36.2...v0.36.3)

---
updated-dependencies:
- dependency-name: k8s.io/api
  dependency-version: 0.36.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-04 18:54:12 +02:00
dependabot[bot]
649f5f08e8 build(deps): bump k8s.io/apimachinery from 0.36.2 to 0.36.3 (#1659)
Bumps [k8s.io/apimachinery](https://github.com/kubernetes/apimachinery) from 0.36.2 to 0.36.3.
- [Commits](https://github.com/kubernetes/apimachinery/compare/v0.36.2...v0.36.3)

---
updated-dependencies:
- dependency-name: k8s.io/apimachinery
  dependency-version: 0.36.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-04 15:40:27 +02:00
Maximilian Rink
49d815775f services: recreate the lease when the service context was cancelled (#1664)
AddOrModify only calls leaseMgr.Add inside its `if svcCtx == nil` branch, but
the in-memory lease is removed independently: the cleanup goroutine started by
StartServicesLeaderElection calls leaseMgr.Delete once svcCtx.Ctx is done, and
Manager.Delete drops the lease once its last object goes away.

Several paths cancel the service context without also removing it from svcMap -
the deferred close(stopChan) in watchEndpoint, and the utils.PanicError branch
in AddOrModify. Afterwards svcMap still holds a cancelled context for that UID,
so every later watch event reuses it, skips leaseMgr.Add, and
StartServicesLeaderElection fails on

  no existing lease found for service %q with UID %q

for the lifetime of the process. Leader election never restarts and the address
is never re-advertised; only restarting the pod clears it.

This is distinct from #1650, which removed the wg.Wait() deadlock but not this
svcMap <-> leaseMgr desync. Both v1.2.1 and v1.2.2 are affected.

Drop a cancelled service context so the existing code path creates a fresh
context and a fresh lease, restoring the invariant that a service context in
svcMap always has a matching lease in the lease manager.

The alternative - having StartServicesLeaderElection call leaseMgr.Add when Get
returns nil - was rejected because it would attach the lease lifetime to the
service context rather than the watcher context, inverting the intended
ownership model.

Signed-off-by: MaxRink <github@maxrink.de>
2026-08-04 15:40:13 +02:00
Patryk Strusiewicz-Surmacki
68123d30dc Discard BGP metrics events of invalid types (#1657)
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
Co-authored-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
2026-08-03 10:40:26 +02:00
Patryk Strusiewicz-Surmacki
c3ba4a8b64 Fix default kube config path handling (#1658)
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
Co-authored-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
2026-07-31 23:50:07 +02:00
Daniel Finneran
39300b8513 Merge pull request #1656 from p-strusiewiczsurmacki-mobica/fix/unnumbered-test
Make unnumbered peers BGP test more stable
2026-07-31 17:28:57 +03:00
Patryk Strusiewicz-Surmacki
d90db3ed5b Make unnumbered peers BGP test more stable
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
2026-07-30 12:46:33 +02:00
Daniel Finneran
972e0fd611 Update version to v1.2.2 in Makefile 2026-07-29 14:25:25 +01:00
Daniel Finneran
02260149f1 Merge pull request #1653 from kube-vip/etcd
Fixes issues with seperate etcd prs
2026-07-29 16:22:13 +03:00
Dan Finneran
793766265b Fixes issues with seperate etcd prs
Signed-off-by: Dan Finneran <dan@thebsdbox.co.uk>
2026-07-29 12:19:21 +00:00
Daniel Finneran
00e0282719 Merge pull request #1652 from kube-vip/SNAT_fixes
Adds capability to stop SNAT for internal network
2026-07-29 15:15:56 +03:00
Daniel Finneran
6c94ecce64 Merge pull request #1650 from erimerdal/fix/detach-cleanup-goroutine-from-waitgroup
Leader election permanently deadlocks after ordinary leadership loss (VIP orphaned until Service is recreated)
2026-07-29 15:15:30 +03:00
Daniel Finneran
4f8f43a412 Merge pull request #1638 from kube-vip/dependabot/github_actions/actions/setup-go-7
build(deps): bump actions/setup-go from 6 to 7
2026-07-29 13:37:48 +03:00
Daniel Finneran
df84b047b9 Merge pull request #1645 from kube-vip/dependabot/go_modules/github.com/prometheus/client_golang-1.24.1
build(deps): bump github.com/prometheus/client_golang from 1.23.2 to 1.24.1
2026-07-29 12:55:53 +03:00
Daniel Finneran
0d248ba40f Merge pull request #1644 from MarijnRitzen/fix/bgp-attach-ip-to-interface
fix: optionally attach BGP service VIPs to interface
2026-07-29 11:51:20 +03:00
Dan Finneran
172d53fde8 Adds the final change to auto-find the API server.
Signed-off-by: Dan Finneran <dan@thebsdbox.co.uk>
2026-07-28 16:19:31 +00:00
dependabot[bot]
bf29c32e56 build(deps): bump github.com/prometheus/client_golang
Bumps [github.com/prometheus/client_golang](https://github.com/prometheus/client_golang) from 1.23.2 to 1.24.1.
- [Release notes](https://github.com/prometheus/client_golang/releases)
- [Changelog](https://github.com/prometheus/client_golang/blob/v1.24.1/CHANGELOG.md)
- [Commits](https://github.com/prometheus/client_golang/compare/v1.23.2...v1.24.1)

---
updated-dependencies:
- dependency-name: github.com/prometheus/client_golang
  dependency-version: 1.24.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-28 15:40:48 +00:00
Dan Finneran
da7df32d64 Adds capability to stop SNAT for internal network
Signed-off-by: Dan Finneran <dan@thebsdbox.co.uk>
2026-07-28 14:24:49 +00:00
Daniel Finneran
0d5bdd81d2 Merge pull request #1642 from p-strusiewiczsurmacki-mobica/feat/force-per-service-election
Added force per-service election feature
2026-07-28 17:03:50 +03:00
Daniel Finneran
bd3764f51b Merge pull request #1641 from thebhdn/fix/throw-error-empty-mode
fix(cmd): throw an error when no valid mode detected
2026-07-28 17:03:29 +03:00
Erim Erdal
8c8490746a Detach Cleanup Goroutine from WaitGroup
Signed-off-by: Erim Erdal <ee008915@broadcom.net>
2026-07-27 15:43:42 +01:00
dependabot[bot]
147cdd7d45 build(deps): bump golang.org/x/sync from 0.21.0 to 0.22.0 (#1648)
Bumps [golang.org/x/sync](https://github.com/golang/sync) from 0.21.0 to 0.22.0.
- [Commits](https://github.com/golang/sync/compare/v0.21.0...v0.22.0)

---
updated-dependencies:
- dependency-name: golang.org/x/sync
  dependency-version: 0.22.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-27 14:01:51 +02:00
Patryk Strusiewicz-Surmacki
8e0ed4f68a Added force per-service election feature
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
2026-07-27 10:09:34 +02:00
Marijn Ritzen
fd6006bb8b fix: optionally attach BGP service VIPs to interface
Signed-off-by: Marijn Ritzen <marijnritzen@outlook.com>
2026-07-26 22:05:11 +02:00
Daniel Finneran
dfcd6cdf9e Merge pull request #1639 from gabrielstedman/feat/allow-iface-not-up
Add an opt-in flag/env var to allow kube-vip to start when interface exists but is not up
2026-07-25 11:49:39 +03:00
dependabot[bot]
a918a20f81 build(deps): bump google.golang.org/grpc from 1.81.1 to 1.82.1 (#1643)
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.81.1 to 1.82.1.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.81.1...v1.82.1)

---
updated-dependencies:
- dependency-name: google.golang.org/grpc
  dependency-version: 1.82.1
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-25 09:06:39 +02:00
Bohdan Leshchenko
2e4b92a2ed fix(cmd): throw an error when no valid mode detected
Signed-off-by: Bohdan Leshchenko <bohdan.leshchenko1@gmail.com>
2026-07-24 13:37:48 +02:00
dependabot[bot]
899a3e5fe8 build(deps): bump actions/setup-go from 6 to 7
Bumps [actions/setup-go](https://github.com/actions/setup-go) from 6 to 7.
- [Release notes](https://github.com/actions/setup-go/releases)
- [Commits](https://github.com/actions/setup-go/compare/v6...v7)

---
updated-dependencies:
- dependency-name: actions/setup-go
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-21 14:54:26 +00:00
Daniel Finneran
3294dccbc2 Merge pull request #1630 from kube-vip/dependabot/docker/golang-1.26.5-alpine3.23
build(deps): bump golang from 1.26.4-alpine3.23 to 1.26.5-alpine3.23
2026-07-21 17:32:34 +03:00
Daniel Finneran
7a92d97866 Merge pull request #1636 from mkowalski/upstream-route-reassert-2
routing table mode: re-assert the VIP route on every healthy check cycle
2026-07-21 16:44:08 +03:00
dependabot[bot]
5fd466abc7 build(deps): bump golang from 1.26.4-alpine3.23 to 1.26.5-alpine3.23
Bumps golang from 1.26.4-alpine3.23 to 1.26.5-alpine3.23.

---
updated-dependencies:
- dependency-name: golang
  dependency-version: 1.26.5-alpine3.23
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-21 13:43:41 +00:00
Daniel Finneran
035164300c Merge pull request #1631 from kube-vip/dependabot/go_modules/golang.org/x/sys-0.47.0
Bump golang.org/x/sys from 0.46.0 to 0.47.0
2026-07-21 16:42:31 +03:00
Daniel Finneran
c13730d1b5 Merge pull request #1617 from kube-vip/dependabot/github_actions/docker/metadata-action-6.2.0
Bump docker/metadata-action from 6.1.0 to 6.2.0
2026-07-21 16:41:45 +03:00
Daniel Finneran
4235833c70 Merge pull request #1626 from p-strusiewiczsurmacki-mobica/fix/nftables-input-chain
Fixed tables creation when nftables is used, IP deletion on leadership loss and race condition in backend
2026-07-21 16:41:13 +03:00
Daniel Finneran
453e2d7a53 Merge pull request #1635 from GabboPenna/feature/nftables-egress-table-name
fix(egress): isolate nftables tables by instance
2026-07-21 16:39:46 +03:00
Gabriel
b440187e2d Adds an opt-in flag/env var ( --allowInterfaceNotUp  /  vip_allow_interface_not_up ) that lets kube-vip continue operating even when its bind interface is not up. This supports assigning the VIP even when the interface is down. Disabled by default; no change to existing behavior.
Signed-off-by: Gabriel <gabriel.stedman@proton.me>
2026-07-21 13:12:22 +01:00
Gabriele Pennacchia
60c786b537 fix(egress): isolate nftables tables by instance
Signed-off-by: Gabriele Pennacchia <gabriele@pennacchia.it>
2026-07-20 14:50:51 +02:00
Patryk Strusiewicz-Surmacki
eace4b2cc9 Fixed tables creation when nftables is used, IP deletion on leadership loss and race condition in backend.
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
2026-07-16 13:44:28 +02:00
Mat Kowalski
719950614b routing table mode: re-assert the VIP route on every healthy check cycle
In order to workaround https://github.com/FRRouting/frr/issues/22654
where zebra misses updates if multiple are bundled in the same netlink
event, we are introducing a new mechanism.

On every cycle we are re-asserting the route with an idempotent
RouteReplace. Because for a no-op replace kernel emits no notification,
we are alternating the realm attribute on every cycle. Thanks to this,
every re-asstertion is a real change which emits the notification.

Wire impact of this change is none. The prefix, nexthop, metric never
change so BGP daemons do not send UPDATE to peers.

Another option was delete+add but that one would have a real wire impact
if performed too slow.

Signed-off-by: Mat Kowalski <mko@redhat.com>
2026-07-15 14:56:25 +02:00
dependabot[bot]
2ec9c9283e Bump golang.org/x/sys from 0.46.0 to 0.47.0
Bumps [golang.org/x/sys](https://github.com/golang/sys) from 0.46.0 to 0.47.0.
- [Commits](https://github.com/golang/sys/compare/v0.46.0...v0.47.0)

---
updated-dependencies:
- dependency-name: golang.org/x/sys
  dependency-version: 0.47.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-14 12:40:00 +00:00
dependabot[bot]
b4e8760612 Bump docker/metadata-action from 6.1.0 to 6.2.0
Bumps [docker/metadata-action](https://github.com/docker/metadata-action) from 6.1.0 to 6.2.0.
- [Release notes](https://github.com/docker/metadata-action/releases)
- [Commits](https://github.com/docker/metadata-action/compare/v6.1.0...v6.2.0)

---
updated-dependencies:
- dependency-name: docker/metadata-action
  dependency-version: 6.2.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-14 12:37:38 +00:00
Daniel Finneran
18fd79aa5d Merge pull request #1628 from p-strusiewiczsurmacki-mobica/fix/arp-test-endpointslices
Use endpointslices for all dualstack tests in ARP mode
2026-07-14 13:33:12 +01:00
Daniel Finneran
4b66e20ad0 Merge pull request #1627 from mkowalski/honor-configured-kubeconfig
Honor the explicitly configured kubeconfig path in manager and backend health checks
2026-07-14 13:32:53 +01:00
Daniel Finneran
ec1d1af7bc Merge pull request #1624 from fossabot/add-license-scan-badge
Add license scan report and status
2026-07-14 13:20:31 +01:00
Daniel Finneran
4c36ffdfbc Merge pull request #1600 from thebhdn/feat/vip-lose-leadership
feat: lose leadership when interface is down
2026-07-14 13:20:06 +01:00
Daniel Finneran
250d668d61 Merge pull request #1596 from ichaytay/support-l2-ib
Added support in ipoib interfaces in ARP mode. Fixes #694
2026-07-14 13:04:47 +01:00
dependabot[bot]
a4be8cd56a Bump github.com/osrg/gobgp/v4 from 4.6.0 to 4.7.0 (#1621)
Bumps [github.com/osrg/gobgp/v4](https://github.com/osrg/gobgp) from 4.6.0 to 4.7.0.
- [Release notes](https://github.com/osrg/gobgp/releases)
- [Commits](https://github.com/osrg/gobgp/compare/v4.6.0...v4.7.0)

---
updated-dependencies:
- dependency-name: github.com/osrg/gobgp/v4
  dependency-version: 4.7.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-10 09:54:20 +02:00
dependabot[bot]
f5463fb956 Bump go.etcd.io/etcd/client/pkg/v3 from 3.6.12 to 3.6.13 (#1622)
Bumps [go.etcd.io/etcd/client/pkg/v3](https://github.com/etcd-io/etcd) from 3.6.12 to 3.6.13.
- [Release notes](https://github.com/etcd-io/etcd/releases)
- [Commits](https://github.com/etcd-io/etcd/compare/v3.6.12...v3.6.13)

---
updated-dependencies:
- dependency-name: go.etcd.io/etcd/client/pkg/v3
  dependency-version: 3.6.13
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-10 09:54:03 +02:00
Patryk Strusiewicz-Surmacki
42a216a6e5 Use endpointslices for all dualstack tests in ARP mode
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
2026-07-09 18:07:48 +02:00
Mat Kowalski
50babb8c2c backend: honor explicitly configured kubeconfig in health checks
Entry.Check hardcoded admin.conf/in-cluster config, so the routing
table mode backend gate could never pass on static pod deployments.
The manager's configured kubeconfig is now handed to the backend.

Signed-off-by: Mat Kowalski <mko@redhat.com>
2026-07-09 16:17:23 +02:00
Mat Kowalski
c84fb65538 manager: honor explicitly configured kubeconfig path
The manager only probed /etc/kubernetes/admin.conf and ~/.kube/config
before falling back to in-cluster config, ignoring k8sConfigPath /
k8s_config_file entirely. OpenShift static pods authenticate with
/etc/kubernetes/kubeconfig, so an explicitly configured path now takes
precedence, with kubernetes_addr able to point at the local API server.

Signed-off-by: Mat Kowalski <mko@redhat.com>
2026-07-09 16:17:22 +02:00
Bohdan Leshchenko
8f8bd0291a feat: restart on error
Signed-off-by: Bohdan Leshchenko <bohdan.leshchenko1@gmail.com>
2026-07-08 20:49:00 +02:00
Bohdan Leshchenko
8ae99df6e1 chore: remove unnecessary ctx
Signed-off-by: Bohdan Leshchenko <bohdan.leshchenko1@gmail.com>
2026-07-08 20:49:00 +02:00
Bohdan Leshchenko
f8fdcf8c46 feat: lose leadership when interface is down
Signed-off-by: Bohdan Leshchenko <bohdan.leshchenko1@gmail.com>
2026-07-08 20:49:00 +02:00
fossabot
ef20a3fa97 Add license scan report and status
Signed off by: fossabot <badges@fossa.com>
2026-07-07 05:34:42 -04:00
Daniel Finneran
3a97e9d91b Merge pull request #1615 from mattcarp12/feat/cmd-todos
Feat: Add help text to kubeadm and manifest subcommands
2026-07-07 09:10:49 +01:00
Daniel Finneran
d72cabeb11 Merge pull request #1592 from p-strusiewiczsurmacki-mobica/feat/nftables-vip-address
Added nftables for vip/address.go
2026-07-07 09:08:40 +01:00
Daniel Finneran
549677c5c6 Merge pull request #1562 from p-strusiewiczsurmacki-mobica/feat/debouncer
Added debouncer for watch events
2026-07-07 09:06:03 +01:00
Daniel Finneran
be0a7ddbec This enables BFD in kube-vip (#1595)
* This enables BFD in kube-vip

Signed-off-by: Dan Finneran <dan@thebsdbox.co.uk>

* Fixes from co-pilot

Signed-off-by: Dan Finneran <dan@thebsdbox.co.uk>

* Some small logging additionals and a skaffold file

Signed-off-by: Dan Finneran <dan@thebsdbox.co.uk>

* Moves logging level back to the global setting

Signed-off-by: Dan Finneran <dan@thebsdbox.co.uk>

---------

Signed-off-by: Dan Finneran <dan@thebsdbox.co.uk>
2026-07-02 18:35:44 +02:00
dependabot[bot]
5f7fded6de Bump github.com/onsi/gomega from 1.41.0 to 1.42.1 (#1611)
Bumps [github.com/onsi/gomega](https://github.com/onsi/gomega) from 1.41.0 to 1.42.1.
- [Release notes](https://github.com/onsi/gomega/releases)
- [Changelog](https://github.com/onsi/gomega/blob/master/CHANGELOG.md)
- [Commits](https://github.com/onsi/gomega/compare/v1.41.0...v1.42.1)

---
updated-dependencies:
- dependency-name: github.com/onsi/gomega
  dependency-version: 1.42.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-01 18:17:22 +02:00
Patryk Strusiewicz-Surmacki
69f9f2db32 Fixed BGP metrics (#1616)
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
Co-authored-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
2026-07-01 18:15:47 +02:00
Patryk Strusiewicz-Surmacki
dfeffa75d9 Use non-iptables image for services tests in the CI
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
2026-07-01 17:14:01 +02:00
Patryk Strusiewicz-Surmacki
5a5f6f780e Added nftables for vip/address.go
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
2026-07-01 16:57:29 +02:00
Matthew Carpenter
2699ce3833 add help text to kubeadm and manifest subcommands
Signed-off-by: Matthew Carpenter <mattcarp88@gmail.com>
2026-06-30 12:50:56 +00:00
dependabot[bot]
f2c350a4ec Bump github.com/gookit/slog from 0.6.0 to 0.7.1 (#1613)
Bumps [github.com/gookit/slog](https://github.com/gookit/slog) from 0.6.0 to 0.7.1.
- [Release notes](https://github.com/gookit/slog/releases)
- [Commits](https://github.com/gookit/slog/compare/v0.6.0...v0.7.1)

---
updated-dependencies:
- dependency-name: github.com/gookit/slog
  dependency-version: 0.7.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-30 13:21:18 +02:00
dependabot[bot]
8a277c0e76 Bump github.com/google/go-containerregistry from 0.21.6 to 0.21.7 (#1612)
Bumps [github.com/google/go-containerregistry](https://github.com/google/go-containerregistry) from 0.21.6 to 0.21.7.
- [Release notes](https://github.com/google/go-containerregistry/releases)
- [Commits](https://github.com/google/go-containerregistry/compare/v0.21.6...v0.21.7)

---
updated-dependencies:
- dependency-name: github.com/google/go-containerregistry
  dependency-version: 0.21.7
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-30 13:20:24 +02:00
dependabot[bot]
3a30addb22 Bump github.com/onsi/ginkgo/v2 from 2.29.0 to 2.32.0 (#1610)
Bumps [github.com/onsi/ginkgo/v2](https://github.com/onsi/ginkgo) from 2.29.0 to 2.32.0.
- [Release notes](https://github.com/onsi/ginkgo/releases)
- [Changelog](https://github.com/onsi/ginkgo/blob/master/CHANGELOG.md)
- [Commits](https://github.com/onsi/ginkgo/compare/v2.29.0...v2.32.0)

---
updated-dependencies:
- dependency-name: github.com/onsi/ginkgo/v2
  dependency-version: 2.32.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-30 13:20:04 +02:00
dependabot[bot]
980011ce48 Bump k8s.io/client-go from 0.36.1 to 0.36.2 (#1609)
Bumps [k8s.io/client-go](https://github.com/kubernetes/client-go) from 0.36.1 to 0.36.2.
- [Changelog](https://github.com/kubernetes/client-go/blob/master/CHANGELOG.md)
- [Commits](https://github.com/kubernetes/client-go/compare/v0.36.1...v0.36.2)

---
updated-dependencies:
- dependency-name: k8s.io/client-go
  dependency-version: 0.36.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-30 13:19:44 +02:00
Marcel Fest
4708b07343 Bump version to v1.2.1 2026-06-25 21:13:27 +02:00
dependabot[bot]
52c964f085 Bump go.etcd.io/etcd/client/v3 from 3.6.11 to 3.6.12 (#1588)
Bumps [go.etcd.io/etcd/client/v3](https://github.com/etcd-io/etcd) from 3.6.11 to 3.6.12.
- [Release notes](https://github.com/etcd-io/etcd/releases)
- [Commits](https://github.com/etcd-io/etcd/compare/v3.6.11...v3.6.12)

---
updated-dependencies:
- dependency-name: go.etcd.io/etcd/client/v3
  dependency-version: 3.6.12
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-25 21:07:30 +02:00
Mateusz Kowalski
fcd3eec73e kube-vip: wire HTTP health check into routing table mode (#1604)
Signed-off-by: Mat Kowalski <mko@redhat.com>
2026-06-25 21:06:56 +02:00
Patryk Strusiewicz-Surmacki
12928dc0e3 Upgraded x/crypto and x/net libraries (#1608)
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
Co-authored-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
2026-06-23 17:37:42 +02:00
dependabot[bot]
13c6b5ebb7 Bump go.etcd.io/etcd/client/pkg/v3 from 3.6.11 to 3.6.12 (#1589)
Bumps [go.etcd.io/etcd/client/pkg/v3](https://github.com/etcd-io/etcd) from 3.6.11 to 3.6.12.
- [Release notes](https://github.com/etcd-io/etcd/releases)
- [Commits](https://github.com/etcd-io/etcd/compare/v3.6.11...v3.6.12)

---
updated-dependencies:
- dependency-name: go.etcd.io/etcd/client/pkg/v3
  dependency-version: 3.6.12
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-22 15:44:17 +02:00
dependabot[bot]
fd924e47de Bump sigs.k8s.io/kind from 0.31.0 to 0.32.0 (#1586)
Bumps [sigs.k8s.io/kind](https://github.com/kubernetes-sigs/kind) from 0.31.0 to 0.32.0.
- [Release notes](https://github.com/kubernetes-sigs/kind/releases)
- [Changelog](https://github.com/kubernetes-sigs/kind/blob/main/RELEASE.md)
- [Commits](https://github.com/kubernetes-sigs/kind/compare/v0.31.0...v0.32.0)

---
updated-dependencies:
- dependency-name: sigs.k8s.io/kind
  dependency-version: 0.32.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-22 11:56:38 +02:00
dependabot[bot]
21f44e1cf6 Bump go.etcd.io/etcd/api/v3 from 3.6.11 to 3.6.12 (#1587)
Bumps [go.etcd.io/etcd/api/v3](https://github.com/etcd-io/etcd) from 3.6.11 to 3.6.12.
- [Release notes](https://github.com/etcd-io/etcd/releases)
- [Commits](https://github.com/etcd-io/etcd/compare/v3.6.11...v3.6.12)

---
updated-dependencies:
- dependency-name: go.etcd.io/etcd/api/v3
  dependency-version: 3.6.12
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-22 11:56:22 +02:00
Patryk Strusiewicz-Surmacki
f8402e86bf Fixed deadlock on AddIP() call in StartVipService (#1594)
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
Co-authored-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
2026-06-22 11:55:57 +02:00
Patryk Strusiewicz-Surmacki
3de813f7b0 Fix minor error handling issue in pkg/bgp/peer.go (#1601)
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
Co-authored-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
2026-06-22 10:30:09 +02:00
dependabot[bot]
3b9cbc9a53 Bump k8s.io/api from 0.36.1 to 0.36.2 (#1598)
Bumps [k8s.io/api](https://github.com/kubernetes/api) from 0.36.1 to 0.36.2.
- [Commits](https://github.com/kubernetes/api/compare/v0.36.1...v0.36.2)

---
updated-dependencies:
- dependency-name: k8s.io/api
  dependency-version: 0.36.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-22 10:26:17 +02:00
dependabot[bot]
c45a3e5c99 Bump alpine from 3.23.4 to 3.24.1 (#1607)
Bumps alpine from 3.23.4 to 3.24.1.

---
updated-dependencies:
- dependency-name: alpine
  dependency-version: 3.24.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-22 10:25:19 +02:00
dependabot[bot]
6eff71b135 Bump actions/checkout from 6 to 7 (#1606)
Bumps [actions/checkout](https://github.com/actions/checkout) from 6 to 7.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v6...v7)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-22 10:22:37 +02:00
Matt Carpenter
0a35e11038 initial commit (#1602)
Signed-off-by: Matthew Carpenter <mattcarp88@gmail.com>
2026-06-19 17:28:15 +02:00
Patryk Strusiewicz-Surmacki
23b68a4f50 Fix control-plane leaderelection restart in etcd mode (#1603)
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
Co-authored-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
2026-06-19 17:26:34 +02:00
Patryk Strusiewicz-Surmacki
7b76191604 Added debouncer for watch events
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
2026-06-17 18:18:12 +02:00
ichaytay
77123591e0 Added support in ipoib interfaces in ARP mode. Fixes #694
Signed-off-by: ichaytay <itay.hay@gmail.com>
2026-06-11 20:39:04 +02:00
Daniel Finneran
1753a02cbe Merge pull request #1593 from p-strusiewiczsurmacki-mobica/fix/ListAdvertisedRoutes
Fix ListAdvertisedRoutes
2026-06-11 19:35:09 +01:00
Patryk Strusiewicz-Surmacki
be80c3e875 Fix ListAdvertisedRoutes
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
2026-06-11 13:12:28 +02:00
Daniel Finneran
8397945d0d Merge pull request #1585 from mattcarp12/feat/bgp-route-dump
Feat: Dump BGP Routes
2026-06-11 09:50:06 +01:00
Daniel Finneran
3642d9390b Merge pull request #1584 from kavirakesh14/upgrade-gobgp-v4
feat(bgp): upgrade gobgp from v3 to v4.6.0 (part 1)
2026-06-11 09:49:23 +01:00
Matthew Carpenter
807b148be6 initial commit
Signed-off-by: Matthew Carpenter <mattcarp88@gmail.com>
2026-06-10 11:51:27 +00:00
Patryk Strusiewicz-Surmacki
de90154825 Bump Go to 1.26.4 (#1591)
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
Co-authored-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
2026-06-09 17:36:32 +02:00
Kavirakesh
ec8f631938 upgrade gobgp from v3 to v4.6.0 (part 1)
- Bump github.com/osrg/gobgp/v3 to github.com/osrg/gobgp/v4 v4.6.0
- Update all import paths from v3 to v4
- Fix AddPath/DeletePath: now take apiutil.AddPathRequest/DeletePathRequest
  with []*apiutil.Path instead of *api.AddPathRequest
- Fix getPath: rewritten using native bgp.* types (bgp.NewIPAddrPrefix,
  bgp.NewPathAttributeNextHop, bgp.NewPathAttributeMpReachNLRI)
  instead of anypb.Any wrappers
- Fix WatchEvent: now takes WatchEventMessageCallbacks{OnPeerUpdate}
  with WatchPeer() option instead of api.WatchEventRequest
- Fix callback type: WatchEventResponse_PeerEvent replaced by
  apiutil.WatchEventMessage_PeerEvent with direct struct field access
- Fix renamed constants:
    DefinedType_NEIGHBOR        -> DefinedType_DEFINED_TYPE_NEIGHBOR
    MatchSet_ANY                -> MatchSet_TYPE_ANY
    RouteAction_ACCEPT          -> RouteAction_ROUTE_ACTION_ACCEPT
    PolicyDirection_EXPORT      -> PolicyDirection_POLICY_DIRECTION_EXPORT

Closes #1581

Signed-off-by: Kavirakesh <kavirakesh007@gmail.com>
2026-06-04 22:28:55 +05:30
Daniel Finneran
29d8b53dc4 Merge pull request #1578 from Nabsku/feature/add-endpointless-reconciliation
Add endpointless reconciliation after service refactor
2026-06-01 16:21:49 +01:00
Daniel Finneran
22bdfd50d1 Merge pull request #1576 from DavideRutigliano/dhcp-broadcast
Add dhcp-broadcast annotation
2026-06-01 16:21:08 +01:00
Daniel Finneran
b822be6a52 Merge pull request #1573 from mattcarp12/fix/duplicate-vip-cleanup
Tidy - Extract duplicate code to remove VIP
2026-06-01 14:03:55 +03:00
Daniel Finneran
5431ec48ad Merge pull request #1580 from mattcarp12/fix/ipv6-check-dup
Remove duplicate IPv6 check functions
2026-06-01 14:02:13 +03:00
Matthew Carpenter
38578894b6 initial commit
Signed-off-by: Matthew Carpenter <mattcarp88@gmail.com>
2026-05-29 20:07:38 +00:00
Matthew Carpenter
43fe97938e initial commit
Signed-off-by: Matthew Carpenter <mattcarp88@gmail.com>
2026-05-29 16:54:40 +00:00
Yannick Wahner
5080b82fa0 chore: Fixed lint issues and updated CONTRIBUTING docs to reflect actual make entries
Signed-off-by: Yannick Wahner <thenabsku@gmail.com>
2026-05-29 11:36:06 +02:00
Yannick Wahner
faa14bce23 chore: update changelog for endpointless Cluster opt-in
Signed-off-by: Yannick Wahner <thenabsku@gmail.com>
2026-05-29 11:23:37 +02:00
Yannick Wahner
db5297f958 endpoints: start opted-in endpointless Cluster services
Signed-off-by: Yannick Wahner <thenabsku@gmail.com>
2026-05-29 11:23:37 +02:00
Yannick Wahner
69a1d2baa5 services: add opt-in support for endpointless Cluster LB services
Signed-off-by: Yannick Wahner <thenabsku@gmail.com>
2026-05-29 11:23:37 +02:00
Davide Rutigliano
59e8df5e80 Add dhcp-broadcast annotation
Signed-off-by: Davide Rutigliano <davide.rutigliano@suse.com>
2026-05-29 09:44:16 +02:00
Daniel Finneran
e2a0e815fe Merge pull request #1575 from kube-vip/thebsdbox-patch-1
Update Makefile for new release
2026-05-28 16:33:23 +03:00
Daniel Finneran
7bc7083351 Merge pull request #1574 from p-strusiewiczsurmacki-mobica/feat/macvlan-annotation
Added macvlan annotation for DHCP
2026-05-28 16:32:49 +03:00
Daniel Finneran
a362e26f1a Update Makefile for new release 2026-05-28 13:20:34 +03:00
Patryk Strusiewicz-Surmacki
cd4782eeda Added macvlan annotation for DHCP
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
2026-05-27 13:58:07 +02:00
Matt Carpenter
2e0ffc0122 initial commit for prometheus metrics (#1549)
Signed-off-by: Matthew Carpenter <mattcarp88@gmail.com>
2026-05-26 18:53:52 +02:00
Matt Carpenter
a7c3565be2 Fix - Backend Watch Ticker (#1565)
* initial commit

Signed-off-by: Matthew Carpenter <mattcarp88@gmail.com>

* refactor watch() function signature

Signed-off-by: Matthew Carpenter <mattcarp88@gmail.com>

---------

Signed-off-by: Matthew Carpenter <mattcarp88@gmail.com>
2026-05-26 11:15:44 +02:00
Patryk Strusiewicz-Surmacki
af467f29fa Fix and E2E tests for endpoints deletion - ARP and RT (#1572)
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
Co-authored-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
2026-05-26 11:09:30 +02:00
Bohdan Leshchenko
523d1c464a fix: refactor labeler interface, enable labeling with cp_enabled=true (#1566)
Signed-off-by: Bohdan Leshchenko <bohdan.leshchenko1@gmail.com>
2026-05-26 11:08:21 +02:00
dependabot[bot]
e74368b08e Bump go.uber.org/zap from 1.27.1 to 1.28.0 (#1570)
Bumps [go.uber.org/zap](https://github.com/uber-go/zap) from 1.27.1 to 1.28.0.
- [Release notes](https://github.com/uber-go/zap/releases)
- [Changelog](https://github.com/uber-go/zap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/uber-go/zap/compare/v1.27.1...v1.28.0)

---
updated-dependencies:
- dependency-name: go.uber.org/zap
  dependency-version: 1.28.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-26 11:05:30 +02:00
dependabot[bot]
9b0630b006 Bump docker/metadata-action from 6.0.0 to 6.1.0 (#1571)
Bumps [docker/metadata-action](https://github.com/docker/metadata-action) from 6.0.0 to 6.1.0.
- [Release notes](https://github.com/docker/metadata-action/releases)
- [Commits](https://github.com/docker/metadata-action/compare/v6.0.0...v6.1.0)

---
updated-dependencies:
- dependency-name: docker/metadata-action
  dependency-version: 6.1.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-25 09:46:36 +02:00
dependabot[bot]
2424c56760 Bump github.com/onsi/gomega from 1.40.0 to 1.41.0 (#1568)
Bumps [github.com/onsi/gomega](https://github.com/onsi/gomega) from 1.40.0 to 1.41.0.
- [Release notes](https://github.com/onsi/gomega/releases)
- [Changelog](https://github.com/onsi/gomega/blob/master/CHANGELOG.md)
- [Commits](https://github.com/onsi/gomega/compare/v1.40.0...v1.41.0)

---
updated-dependencies:
- dependency-name: github.com/onsi/gomega
  dependency-version: 1.41.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-25 09:45:18 +02:00
dependabot[bot]
7cedfbaf22 Bump github.com/google/go-containerregistry from 0.21.5 to 0.21.6 (#1569)
Bumps [github.com/google/go-containerregistry](https://github.com/google/go-containerregistry) from 0.21.5 to 0.21.6.
- [Release notes](https://github.com/google/go-containerregistry/releases)
- [Commits](https://github.com/google/go-containerregistry/compare/v0.21.5...v0.21.6)

---
updated-dependencies:
- dependency-name: github.com/google/go-containerregistry
  dependency-version: 0.21.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-25 09:44:24 +02:00
dependabot[bot]
8ed4e233cb Bump golang.org/x/sys from 0.44.0 to 0.45.0 (#1567)
Bumps [golang.org/x/sys](https://github.com/golang/sys) from 0.44.0 to 0.45.0.
- [Commits](https://github.com/golang/sys/compare/v0.44.0...v0.45.0)

---
updated-dependencies:
- dependency-name: golang.org/x/sys
  dependency-version: 0.45.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-25 09:42:15 +02:00
Daniel Finneran
e6b4175cca Merge pull request #1554 from lbohdanl/feat/vlan-support 2026-05-22 18:28:57 +01:00
Marcel Fest
800c026f59 Update VERSION to v1.2.0-rc.1 2026-05-22 07:05:22 +02:00
dependabot[bot]
00de295105 Bump github.com/onsi/ginkgo/v2 from 2.28.3 to 2.29.0 (#1555)
Bumps [github.com/onsi/ginkgo/v2](https://github.com/onsi/ginkgo) from 2.28.3 to 2.29.0.
- [Release notes](https://github.com/onsi/ginkgo/releases)
- [Changelog](https://github.com/onsi/ginkgo/blob/master/CHANGELOG.md)
- [Commits](https://github.com/onsi/ginkgo/compare/v2.28.3...v2.29.0)

---
updated-dependencies:
- dependency-name: github.com/onsi/ginkgo/v2
  dependency-version: 2.29.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-22 07:00:40 +02:00
Patryk Strusiewicz-Surmacki
7400eb2a59 Fixed deletion in ARP and RT modes when global leader election for services is used in 1.2.0-rc.0 (#1561)
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
Co-authored-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
2026-05-22 06:58:15 +02:00
Bohdan Leshchenko
326a18a4ff feat(svc): add vlan support
Signed-off-by: Bohdan Leshchenko <bohdan.leshchenko1@gmail.com>
2026-05-21 19:53:26 +02:00
Maximilian Rink
a189f15c30 fix(bgp): improve IPv6 peer parsing robustness and fix MultiHop error message (#1551)
Signed-off-by: Max Rink <github@maxrink.de>
Signed-off-by: Maximilian Rink <maximilian.rink@telekom.de>
2026-05-20 16:54:50 +02:00
dependabot[bot]
c82268d5dd Bump k8s.io/client-go from 0.36.0 to 0.36.1 (#1556)
Bumps [k8s.io/client-go](https://github.com/kubernetes/client-go) from 0.36.0 to 0.36.1.
- [Changelog](https://github.com/kubernetes/client-go/blob/master/CHANGELOG.md)
- [Commits](https://github.com/kubernetes/client-go/compare/v0.36.0...v0.36.1)

---
updated-dependencies:
- dependency-name: k8s.io/client-go
  dependency-version: 0.36.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-19 17:11:14 +02:00
dependabot[bot]
1e68553535 Bump k8s.io/api from 0.36.0 to 0.36.1 (#1558)
Bumps [k8s.io/api](https://github.com/kubernetes/api) from 0.36.0 to 0.36.1.
- [Commits](https://github.com/kubernetes/api/compare/v0.36.0...v0.36.1)

---
updated-dependencies:
- dependency-name: k8s.io/api
  dependency-version: 0.36.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-19 15:38:23 +02:00
dependabot[bot]
74221d806e Bump google.golang.org/grpc from 1.81.0 to 1.81.1 (#1559)
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.81.0 to 1.81.1.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.81.0...v1.81.1)

---
updated-dependencies:
- dependency-name: google.golang.org/grpc
  dependency-version: 1.81.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-19 15:37:54 +02:00
Patryk Strusiewicz-Surmacki
f345729b6b Fixed ARP mode with cluster policy in rc.0 (#1553)
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
Co-authored-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
2026-05-19 15:25:22 +02:00
Patryk Strusiewicz-Surmacki
72cc8c19cd Fixed services test logs (#1552)
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
Co-authored-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
2026-05-19 15:24:06 +02:00
Bohdan Leshchenko
339e7cccad fix: the comments for env vars (#1560)
Signed-off-by: Bohdan Leshchenko <bohdan.leshchenko1@gmail.com>
2026-05-18 15:14:07 +02:00
Marcel Fest
00da316fe8 bump to the first release candidate 2026-05-12 16:34:26 +02:00
dependabot[bot]
f4f8fb4269 Bump k8s.io/client-go from 0.35.4 to 0.36.0 (#1531)
Bumps [k8s.io/client-go](https://github.com/kubernetes/client-go) from 0.35.4 to 0.36.0.
- [Changelog](https://github.com/kubernetes/client-go/blob/master/CHANGELOG.md)
- [Commits](https://github.com/kubernetes/client-go/compare/v0.35.4...v0.36.0)

---
updated-dependencies:
- dependency-name: k8s.io/client-go
  dependency-version: 0.36.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-12 16:32:42 +02:00
Patryk Strusiewicz-Surmacki
8455a19b0c Refactored service handling (#1463)
* Refactored service handling

Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>

* Fix unnumbered

Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>

---------

Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
Co-authored-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
2026-05-12 16:30:19 +02:00
dependabot[bot]
cc9f51d644 Bump go.etcd.io/etcd/client/v3 from 3.6.10 to 3.6.11 (#1545)
Bumps [go.etcd.io/etcd/client/v3](https://github.com/etcd-io/etcd) from 3.6.10 to 3.6.11.
- [Release notes](https://github.com/etcd-io/etcd/releases)
- [Commits](https://github.com/etcd-io/etcd/compare/v3.6.10...v3.6.11)

---
updated-dependencies:
- dependency-name: go.etcd.io/etcd/client/v3
  dependency-version: 3.6.11
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-12 14:49:10 +02:00
dependabot[bot]
b88dc05edf Bump google.golang.org/grpc from 1.80.0 to 1.81.0 (#1547)
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.80.0 to 1.81.0.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.80.0...v1.81.0)

---
updated-dependencies:
- dependency-name: google.golang.org/grpc
  dependency-version: 1.81.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-11 17:58:34 +02:00
dependabot[bot]
d4d65f128a Bump golang.org/x/sys from 0.43.0 to 0.44.0 (#1546)
Bumps [golang.org/x/sys](https://github.com/golang/sys) from 0.43.0 to 0.44.0.
- [Commits](https://github.com/golang/sys/compare/v0.43.0...v0.44.0)

---
updated-dependencies:
- dependency-name: golang.org/x/sys
  dependency-version: 0.44.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-11 16:50:10 +02:00
dependabot[bot]
014935fb03 Bump golang from 1.26.2-alpine3.23 to 1.26.3-alpine3.23 (#1548)
Bumps golang from 1.26.2-alpine3.23 to 1.26.3-alpine3.23.

---
updated-dependencies:
- dependency-name: golang
  dependency-version: 1.26.3-alpine3.23
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-11 16:49:30 +02:00
Patryk Strusiewicz-Surmacki
bf98730fae Changed logs gathering path in the CI (#1543)
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
Co-authored-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
2026-05-08 08:16:58 +02:00
Patryk Strusiewicz-Surmacki
e7a844afef Configuration of the deprecated endpoints in the tests fixed (#1542)
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
Co-authored-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
2026-05-06 16:04:25 +02:00
dependabot[bot]
3ecf6421b1 Bump k8s.io/apimachinery from 0.35.4 to 0.36.0 (#1530)
Bumps [k8s.io/apimachinery](https://github.com/kubernetes/apimachinery) from 0.35.4 to 0.36.0.
- [Commits](https://github.com/kubernetes/apimachinery/compare/v0.35.4...v0.36.0)

---
updated-dependencies:
- dependency-name: k8s.io/apimachinery
  dependency-version: 0.36.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-06 16:01:49 +02:00
dependabot[bot]
44f2b837b1 Bump github.com/onsi/ginkgo/v2 from 2.28.1 to 2.28.3 (#1540)
Bumps [github.com/onsi/ginkgo/v2](https://github.com/onsi/ginkgo) from 2.28.1 to 2.28.3.
- [Release notes](https://github.com/onsi/ginkgo/releases)
- [Changelog](https://github.com/onsi/ginkgo/blob/master/CHANGELOG.md)
- [Commits](https://github.com/onsi/ginkgo/compare/v2.28.1...v2.28.3)

---
updated-dependencies:
- dependency-name: github.com/onsi/ginkgo/v2
  dependency-version: 2.28.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-06 13:04:19 +02:00
dependabot[bot]
d293cc6f63 Bump go.etcd.io/etcd/client/pkg/v3 from 3.6.10 to 3.6.11 (#1539)
Bumps [go.etcd.io/etcd/client/pkg/v3](https://github.com/etcd-io/etcd) from 3.6.10 to 3.6.11.
- [Release notes](https://github.com/etcd-io/etcd/releases)
- [Commits](https://github.com/etcd-io/etcd/compare/v3.6.10...v3.6.11)

---
updated-dependencies:
- dependency-name: go.etcd.io/etcd/client/pkg/v3
  dependency-version: 3.6.11
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-06 13:04:06 +02:00
dependabot[bot]
1d4757eb18 Bump github.com/cloudflare/ipvs from 0.11.0 to 0.12.0 (#1538)
Bumps [github.com/cloudflare/ipvs](https://github.com/cloudflare/ipvs) from 0.11.0 to 0.12.0.
- [Release notes](https://github.com/cloudflare/ipvs/releases)
- [Commits](https://github.com/cloudflare/ipvs/compare/v0.11.0...v0.12.0)

---
updated-dependencies:
- dependency-name: github.com/cloudflare/ipvs
  dependency-version: 0.12.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-06 13:03:43 +02:00
Patryk Strusiewicz-Surmacki
a1317bb3d1 Use golangci/golangci-lint-action in the CI (#1541)
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
Co-authored-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
2026-05-06 12:51:38 +02:00
Daniel Finneran
2e611a2654 Merge pull request #1498 from g-gaston/bgp-health-check
Add configurable control-plane health check for BGP mode
2026-05-06 10:01:08 +01:00
Guillermo Gaston
a524a6d34b Add BGP health check e2e tests
Add an e2e test for the control-plane health check that verifies route
withdrawal when an apiserver is stopped, re-announcement on recovery,
and graceful withdrawal when kube-vip itself is shut down.

Extract BGP server lifecycle (GoBGP daemon, gRPC client, peer
management) into a reusable bgp.Server type and cluster creation into an
e2e.Cluster type. This replaces the large setupEnv function and
scattered helpers in e2e_bgp_test.go with composable building blocks,
making it simpler to add new BGP test scenarios like the health check.

Consolidate the separate kube-vip-bgp.yaml.tmpl into the main
kube-vip.yaml.tmpl, using the ControlPlaneHealthCheck fields added to
KubevipManifestValues.

Signed-off-by: Guillermo Gaston <ggastonloren@nvidia.com>
2026-05-04 20:04:45 +00:00
Guillermo Gaston
dcd3236925 Add configurable health check in BGP mode
In BGP mode without leader election, every kube-vip instance announces
the same VIP. ECMP distributes traffic evenly, but if a node's
kube-apiserver goes down, kube-vip (a static pod tied to kubelet) keeps
advertising the route — sending a fraction of all API traffic into a
black hole.

An optional health check loop now polls the local kube-apiserver and
withdraws the BGP route after a configurable number of consecutive
failures, removing the dead node from the ECMP set. The route is
re-announced once the API server recovers.

Signed-off-by: Guillermo Gaston <ggastonloren@nvidia.com>
2026-05-04 20:04:45 +00:00
Patryk Strusiewicz-Surmacki
7357b4ca57 Added missing mutex lock in ARP manager (#1537)
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
Co-authored-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
2026-05-01 23:18:33 +02:00
Matt Carpenter
fed932bb4b Improve logging in election.go and set defaultBGPPort constant (#1534)
* improve logging in election.go and set defaultBGPPort constant

Signed-off-by: Matthew Carpenter <mattcarp88@gmail.com>

* update log messages per code review

Signed-off-by: Matthew Carpenter <mattcarp88@gmail.com>

---------

Signed-off-by: Matthew Carpenter <mattcarp88@gmail.com>
2026-05-01 23:17:30 +02:00
Patryk Strusiewicz-Surmacki
616e586227 Added route tracker (#1536)
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
Co-authored-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
2026-04-30 15:41:31 +02:00
Matt Carpenter
b3cb3c00d6 put arp rate validation in manager.New and use ticker for arp loop in case of context cancel (#1535)
Signed-off-by: Matthew Carpenter <mattcarp88@gmail.com>
2026-04-30 12:26:25 +02:00
Daniel Finneran
c017109eab This fixes the rules for egress allowed-networks (#1528)
* This fixes the rules for egress allowed-networks

Signed-off-by: Dan Finneran <dan@thebsdbox.co.uk>

* lint fix

Signed-off-by: Dan Finneran <dan@thebsdbox.co.uk>

* fixes a potential issue with out of bounds array access

Signed-off-by: Dan Finneran <dan@thebsdbox.co.uk>

---------

Signed-off-by: Dan Finneran <dan@thebsdbox.co.uk>
2026-04-28 22:13:13 +02:00
Akash Kumar
0dc7f606ae docs: document SELinux IPVS module setup (#1529)
Signed-off-by: Akash Kumar <meakash7902@gmail.com>
2026-04-27 19:38:16 +02:00
Patryk Strusiewicz-Surmacki
50c1080b7c Track BGP paths (#1518)
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
Co-authored-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
2026-04-27 15:32:29 +02:00
Matt Carpenter
1ad2be3f0b feat: add support for BGP unnumbered peers (#1512)
* feat: add support for BGP unnumbered peers

Signed-off-by: Matthew Carpenter <mattcarp88@gmail.com>

* add test case

Signed-off-by: Matthew Carpenter <mattcarp88@gmail.com>

* rebase to main

Signed-off-by: Matthew Carpenter <mattcarp88@gmail.com>

* fix merge conflict

Signed-off-by: Matthew Carpenter <mattcarp88@gmail.com>

---------

Signed-off-by: Matthew Carpenter <mattcarp88@gmail.com>
2026-04-26 14:32:51 +02:00
Patryk Strusiewicz-Surmacki
17512aca2e Create separate Docker network for each kind cluster in daemonset-based e2e tests (#1527)
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
Co-authored-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
2026-04-23 15:40:48 +02:00
Patryk Strusiewicz-Surmacki
40cc4c9a45 Fixed restart on node watcher error (#1511)
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
Co-authored-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
2026-04-20 08:38:34 +02:00
dependabot[bot]
c5d49246fd Bump k8s.io/api from 0.35.3 to 0.35.4 (#1523)
Bumps [k8s.io/api](https://github.com/kubernetes/api) from 0.35.3 to 0.35.4.
- [Commits](https://github.com/kubernetes/api/compare/v0.35.3...v0.35.4)

---
updated-dependencies:
- dependency-name: k8s.io/api
  dependency-version: 0.35.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-20 08:38:09 +02:00
dependabot[bot]
c217f816cf Bump k8s.io/client-go from 0.35.3 to 0.35.4 (#1522)
Bumps [k8s.io/client-go](https://github.com/kubernetes/client-go) from 0.35.3 to 0.35.4.
- [Changelog](https://github.com/kubernetes/client-go/blob/master/CHANGELOG.md)
- [Commits](https://github.com/kubernetes/client-go/compare/v0.35.3...v0.35.4)

---
updated-dependencies:
- dependency-name: k8s.io/client-go
  dependency-version: 0.35.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-20 08:37:50 +02:00
dependabot[bot]
16836f2765 Bump k8s.io/apimachinery from 0.35.3 to 0.35.4 (#1524)
Bumps [k8s.io/apimachinery](https://github.com/kubernetes/apimachinery) from 0.35.3 to 0.35.4.
- [Commits](https://github.com/kubernetes/apimachinery/compare/v0.35.3...v0.35.4)

---
updated-dependencies:
- dependency-name: k8s.io/apimachinery
  dependency-version: 0.35.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-20 06:58:22 +02:00
dependabot[bot]
9be6520bfe Bump alpine from 3.23.3 to 3.23.4 (#1525)
Bumps alpine from 3.23.3 to 3.23.4.

---
updated-dependencies:
- dependency-name: alpine
  dependency-version: 3.23.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-20 06:57:31 +02:00
Matt Carpenter
193bba1ee0 make get-gobgp a dependency of e2e-tests-bgp in Makefile (#1516)
Signed-off-by: Matthew Carpenter <mattcarp88@gmail.com>
2026-04-16 22:48:33 +02:00
Patryk Strusiewicz-Surmacki
5d63692160 Stop service status update on context cancel (#1520)
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
Co-authored-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
2026-04-16 22:48:06 +02:00
Orkun İncili
b8052ba0e6 Validate vip_subnet for legacy vip address at runtime (#1500)
* Validate vip_subnet for legacy vip address at runtime

Signed-off-by: orkun incili <orkunincili0@gmail.com>

* Fix lifecycle: only cancel on init/config failure paths

Signed-off-by: orkun incili <orkunincili0@gmail.com>

* Update changelog for failure-path cancel behavior

Signed-off-by: orkun incili <orkunincili0@gmail.com>

---------

Signed-off-by: orkun incili <orkunincili0@gmail.com>
2026-04-13 17:09:08 +02:00
dependabot[bot]
cd7c84a8a2 Bump github.com/google/go-containerregistry from 0.21.3 to 0.21.5 (#1513)
Bumps [github.com/google/go-containerregistry](https://github.com/google/go-containerregistry) from 0.21.3 to 0.21.5.
- [Release notes](https://github.com/google/go-containerregistry/releases)
- [Commits](https://github.com/google/go-containerregistry/compare/v0.21.3...v0.21.5)

---
updated-dependencies:
- dependency-name: github.com/google/go-containerregistry
  dependency-version: 0.21.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-13 11:47:20 +02:00
dependabot[bot]
70eb4c4f8b Bump golang from 1.26.1-alpine3.23 to 1.26.2-alpine3.23 (#1515)
Bumps golang from 1.26.1-alpine3.23 to 1.26.2-alpine3.23.

---
updated-dependencies:
- dependency-name: golang
  dependency-version: 1.26.2-alpine3.23
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-13 11:47:09 +02:00
dependabot[bot]
a8ede3518f Bump golang.org/x/sys from 0.42.0 to 0.43.0 (#1514)
Bumps [golang.org/x/sys](https://github.com/golang/sys) from 0.42.0 to 0.43.0.
- [Commits](https://github.com/golang/sys/compare/v0.42.0...v0.43.0)

---
updated-dependencies:
- dependency-name: golang.org/x/sys
  dependency-version: 0.43.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-13 11:47:00 +02:00
Daniel Finneran
5e2421cde6 Merge pull request #1495 from clubanderson/docs/add-kubestellar-console-install-reference
📖 Add KubeStellar Console guided install reference
2026-04-10 09:57:18 +01:00
Patryk Strusiewicz-Surmacki
d7882e9453 Added logs from /var/log/pods (#1507)
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
Co-authored-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
2026-04-09 13:53:48 +02:00
dependabot[bot]
edeac48c40 Bump go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp (#1509)
Bumps [go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp](https://github.com/open-telemetry/opentelemetry-go) from 1.37.0 to 1.43.0.
- [Release notes](https://github.com/open-telemetry/opentelemetry-go/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-go/blob/main/CHANGELOG.md)
- [Commits](https://github.com/open-telemetry/opentelemetry-go/compare/v1.37.0...v1.43.0)

---
updated-dependencies:
- dependency-name: go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp
  dependency-version: 1.43.0
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-09 07:29:37 +02:00
Marcel Fest
54d8e14f54 Revert "feat: add support for BGP unnumbered peers (#1506)" (#1508)
This reverts commit 7d33c747ff.

Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
2026-04-08 20:21:10 +02:00
Matt Carpenter
7d33c747ff feat: add support for BGP unnumbered peers (#1506)
* feat: add support for BGP unnumbered peers

Signed-off-by: Matthew Carpenter <mattcarp88@gmail.com>

* add test case

Signed-off-by: Matthew Carpenter <mattcarp88@gmail.com>

---------

Signed-off-by: Matthew Carpenter <mattcarp88@gmail.com>
2026-04-08 11:40:18 +02:00
dependabot[bot]
cd87a8e9a0 Bump go.etcd.io/etcd/client/v3 from 3.6.9 to 3.6.10 (#1501)
Bumps [go.etcd.io/etcd/client/v3](https://github.com/etcd-io/etcd) from 3.6.9 to 3.6.10.
- [Release notes](https://github.com/etcd-io/etcd/releases)
- [Commits](https://github.com/etcd-io/etcd/compare/v3.6.9...v3.6.10)

---
updated-dependencies:
- dependency-name: go.etcd.io/etcd/client/v3
  dependency-version: 3.6.10
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-07 13:00:21 +02:00
dependabot[bot]
3ee885df42 Bump go.etcd.io/etcd/client/pkg/v3 from 3.6.9 to 3.6.10 (#1502)
Bumps [go.etcd.io/etcd/client/pkg/v3](https://github.com/etcd-io/etcd) from 3.6.9 to 3.6.10.
- [Release notes](https://github.com/etcd-io/etcd/releases)
- [Commits](https://github.com/etcd-io/etcd/compare/v3.6.9...v3.6.10)

---
updated-dependencies:
- dependency-name: go.etcd.io/etcd/client/pkg/v3
  dependency-version: 3.6.10
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-07 09:55:22 +02:00
dependabot[bot]
8a63df2462 Bump google.golang.org/grpc from 1.79.3 to 1.80.0 (#1503)
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.79.3 to 1.80.0.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.79.3...v1.80.0)

---
updated-dependencies:
- dependency-name: google.golang.org/grpc
  dependency-version: 1.80.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-07 09:29:42 +02:00
dependabot[bot]
15b77ac243 Bump go.etcd.io/etcd/api/v3 from 3.6.9 to 3.6.10 (#1504)
Bumps [go.etcd.io/etcd/api/v3](https://github.com/etcd-io/etcd) from 3.6.9 to 3.6.10.
- [Release notes](https://github.com/etcd-io/etcd/releases)
- [Commits](https://github.com/etcd-io/etcd/compare/v3.6.9...v3.6.10)

---
updated-dependencies:
- dependency-name: go.etcd.io/etcd/api/v3
  dependency-version: 3.6.10
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-07 09:29:10 +02:00
Matt Carpenter
9ccf9cf928 Make node names RFC 1123 compliant (#1505)
* normalize node name - to lower case

Signed-off-by: Matthew Carpenter <mattcarp88@gmail.com>

* add unit test

Signed-off-by: Matthew Carpenter <mattcarp88@gmail.com>

---------

Signed-off-by: Matthew Carpenter <mattcarp88@gmail.com>
2026-04-06 22:35:24 +02:00
Martynas Deveikis
e475ac92ee Reintroduce BGP config via node annotations (#1499)
* Check BGP config node annotations before creating server

Signed-off-by: Martynas Deveikis <martynasdev@gmail.com>

* Add E2E test for BGP config via node annotations

Signed-off-by: Martynas Deveikis <martynasdev@gmail.com>

* Escape prefix meta chars when parsing BGP config annotations

Signed-off-by: Martynas Deveikis <martynasdev@gmail.com>

* Fail when no peer IP in BGP config annotations

Signed-off-by: Martynas Deveikis <martynasdev@gmail.com>

* Stop allowing trailing characters in BGP config annotations

Signed-off-by: Martynas Deveikis <martynasdev@gmail.com>

* Compile bgp config annotation regexes outside of loops

Signed-off-by: Martynas Deveikis <martynasdev@gmail.com>

* Allow setting multi hop via BGP config annotations

Signed-off-by: Martynas Deveikis <martynasdev@gmail.com>

---------

Signed-off-by: Martynas Deveikis <martynasdev@gmail.com>
2026-04-04 12:44:53 +02:00
Patryk Strusiewicz-Surmacki
0fc31c62c7 Added e2e tests for endpoints watcher leaderelection (#1496)
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
Co-authored-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
2026-04-04 12:43:30 +02:00
Andrew Anderson
93329a5467 Add KubeStellar Console guided install reference to README
Add a Community Tools section with a link to the KubeStellar Console
guided kube-vip installation experience, which provides step-by-step
install with pre-flight checks, validation, troubleshooting, and
rollback support.

Signed-off-by: Andrew Anderson <andy@clubanderson.com>
2026-03-31 10:26:19 -04:00
Daniel Finneran
04becb6b9e Update VERSION to v1.1.2 2026-03-30 17:29:00 +01:00
Daniel Finneran
1824ccec78 Merge pull request #1492 from kube-vip/nftables_rule_fix
This adds the capability to filter on ports individually per rule
2026-03-30 12:28:13 +01:00
dependabot[bot]
11bdf4e66a Bump k8s.io/client-go from 0.35.2 to 0.35.3 (#1493)
Bumps [k8s.io/client-go](https://github.com/kubernetes/client-go) from 0.35.2 to 0.35.3.
- [Changelog](https://github.com/kubernetes/client-go/blob/master/CHANGELOG.md)
- [Commits](https://github.com/kubernetes/client-go/compare/v0.35.2...v0.35.3)

---
updated-dependencies:
- dependency-name: k8s.io/client-go
  dependency-version: 0.35.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-30 07:56:56 +02:00
Dan Finneran
adfc1d20fc This adds the capability to filter on ports individually per rule
Signed-off-by: Dan Finneran <dan@thebsdbox.co.uk>
2026-03-29 15:16:45 +00:00
Soto Sugita
f1065a4a8c services: retry on 403 Forbidden in ServicesWatcher WatchFunc kubeadm 1.34.x onwards (#1465)
* services: retry on 403/401 in ServicesWatcher using exponential backoff

On Kubernetes 1.34+, admin.conf uses O=kubeadm:cluster-admins instead
of O=system:masters. On joining control plane nodes, kube-vip starts
before etcd is promoted from learner to full member. RBAC data is not
yet available through the learner etcd, causing a transient 403
Forbidden or 401 Unauthorized on the first Watch call.

Replace the bare Watch call in ServicesWatcher's WatchFunc with
wait.ExponentialBackoffWithContext (from k8s.io/apimachinery/pkg/util/wait,
already in go.mod). Parameters: 2s initial, 2x factor, 0.1 jitter,
30s cap, 10 steps. Non-auth errors are returned immediately. Context
cancellation stops the retry loop cleanly.

Change Processor.rwClientSet from *kubernetes.Clientset to
kubernetes.Interface to enable fake client injection in tests.
watchEndpoint() uses p.clientSet (*kubernetes.Clientset) directly for
CreateRetryWatcher, avoiding an unnecessary type assertion.

Add unit tests covering: 403/401 retry succeeds, context cancellation
during retry. Update CHANGELOG.md.

Fixes: https://github.com/kube-vip/kube-vip/issues/1464
Signed-off-by: Soto Sugita <sotosugi@amazon.co.jp>

* fix(services): refactor watchWithAuthRetry as standalone function

Extract the retry logic into a standalone watchWithAuthRetry function
to avoid changing rwClientSet from *kubernetes.Clientset to
kubernetes.Interface. Tests now directly test watchWithAuthRetry via
closures without fake clientset injection or struct type changes.

Revert Processor.rwClientSet back to *kubernetes.Clientset and remove
the type assertion in watchEndpoint().

Signed-off-by: Soto Sugita <sotosugi@amazon.co.jp>

* fix(services): simplify watchWithAuthRetry tests to table-driven style

Signed-off-by: Soto Sugita <sotosugi@amazon.co.jp>

---------

Signed-off-by: Soto Sugita <sotosugi@amazon.co.jp>
2026-03-26 13:21:15 +01:00
Daniel
50993b63f1 Enhance WireGuard nftables and endpoint handling (#1469)
* do not masquerade for local endpoints

Signed-off-by: Daniel Nägele <daniel@naegele.dev>

* fix: do not add VIP to lo in wg mode

Signed-off-by: Daniel Nägele <daniel@naegele.dev>

* fix: setup policy routing for wg interface

Signed-off-by: Daniel Nägele <daniel@naegele.dev>

* refactor: use k8s API types for protocol

Signed-off-by: Daniel Nägele <daniel@naegele.dev>

* conservatively apply packet mark

only apply the ct mark as packet mark if it matches our calculated
fwmark

Signed-off-by: Daniel Nägele <daniel@naegele.dev>

* use new nftable setup

the nftable setup now uses only one set of chains per tunnel and
utilizes named maps and sets to match NAT the connections properly

Signed-off-by: Daniel Nägele <daniel@naegele.dev>

* ensure proper cleanup

Signed-off-by: Daniel Nägele <daniel@naegele.dev>

* watch kubernetes endpoints

Signed-off-by: Daniel Nägele <daniel@naegele.dev>

* refactor wireguard nftables implementation

Signed-off-by: Daniel Nägele <daniel@naegele.dev>

* use helper for if name determination

Signed-off-by: Daniel Nägele <daniel@naegele.dev>

---------

Signed-off-by: Daniel Nägele <daniel@naegele.dev>
2026-03-24 14:25:05 +01:00
Patryk Strusiewicz-Surmacki
4108a8b32a Updated services error handling (#1481)
* Updated services error handling

Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>

* Fix service instance not found error

Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>

---------

Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
Co-authored-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
2026-03-23 20:26:46 +01:00
dependabot[bot]
e6658ff32f Bump go.etcd.io/etcd/api/v3 from 3.6.8 to 3.6.9 (#1482)
Bumps [go.etcd.io/etcd/api/v3](https://github.com/etcd-io/etcd) from 3.6.8 to 3.6.9.
- [Release notes](https://github.com/etcd-io/etcd/releases)
- [Commits](https://github.com/etcd-io/etcd/compare/v3.6.8...v3.6.9)

---
updated-dependencies:
- dependency-name: go.etcd.io/etcd/api/v3
  dependency-version: 3.6.9
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-23 13:33:54 +01:00
dependabot[bot]
4bb5103f47 Bump go.etcd.io/etcd/client/v3 from 3.6.8 to 3.6.9 (#1484)
Bumps [go.etcd.io/etcd/client/v3](https://github.com/etcd-io/etcd) from 3.6.8 to 3.6.9.
- [Release notes](https://github.com/etcd-io/etcd/releases)
- [Commits](https://github.com/etcd-io/etcd/compare/v3.6.8...v3.6.9)

---
updated-dependencies:
- dependency-name: go.etcd.io/etcd/client/v3
  dependency-version: 3.6.9
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-23 13:33:41 +01:00
dependabot[bot]
e3961d7404 Bump k8s.io/api from 0.35.2 to 0.35.3 (#1486)
Bumps [k8s.io/api](https://github.com/kubernetes/api) from 0.35.2 to 0.35.3.
- [Commits](https://github.com/kubernetes/api/compare/v0.35.2...v0.35.3)

---
updated-dependencies:
- dependency-name: k8s.io/api
  dependency-version: 0.35.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-23 12:35:34 +01:00
dependabot[bot]
b10375824f Bump anchore/sbom-action from 0.23.1 to 0.24.0 (#1487)
Bumps [anchore/sbom-action](https://github.com/anchore/sbom-action) from 0.23.1 to 0.24.0.
- [Release notes](https://github.com/anchore/sbom-action/releases)
- [Changelog](https://github.com/anchore/sbom-action/blob/main/RELEASE.md)
- [Commits](https://github.com/anchore/sbom-action/compare/v0.23.1...v0.24.0)

---
updated-dependencies:
- dependency-name: anchore/sbom-action
  dependency-version: 0.24.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-23 12:16:23 +01:00
dependabot[bot]
1981efc95b Bump go.etcd.io/etcd/client/pkg/v3 from 3.6.8 to 3.6.9 (#1483)
Bumps [go.etcd.io/etcd/client/pkg/v3](https://github.com/etcd-io/etcd) from 3.6.8 to 3.6.9.
- [Release notes](https://github.com/etcd-io/etcd/releases)
- [Commits](https://github.com/etcd-io/etcd/compare/v3.6.8...v3.6.9)

---
updated-dependencies:
- dependency-name: go.etcd.io/etcd/client/pkg/v3
  dependency-version: 3.6.9
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-23 12:11:04 +01:00
dependabot[bot]
7cd2b00cee Bump github.com/google/go-containerregistry from 0.21.2 to 0.21.3 (#1485)
Bumps [github.com/google/go-containerregistry](https://github.com/google/go-containerregistry) from 0.21.2 to 0.21.3.
- [Release notes](https://github.com/google/go-containerregistry/releases)
- [Commits](https://github.com/google/go-containerregistry/compare/v0.21.2...v0.21.3)

---
updated-dependencies:
- dependency-name: github.com/google/go-containerregistry
  dependency-version: 0.21.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-23 12:10:50 +01:00
Matej Kern
ba334acf7a fix(egress): prevent unnecessary SNAT updates and fix missed updates (#1433)
* fix(egress): prevent unnecessary SNAT updates and fix missed updates #1428

Signed-off-by: RnkeZ <matej.kern@gmail.com>

* Remove ActionUpdate from services.go

Signed-off-by: RnkeZ <matej.kern@gmail.com>

* refactor(egress): remove redundant service DeepCopy

Signed-off-by: RnkeZ <matej.kern@gmail.com>

* refactor(endpoints): pass clientSet via function parameter instead of
  storing in struct

Signed-off-by: RnkeZ <matej.kern@gmail.com>

* refactor(endpoints): pass egressUpdateFunc via parameter instead of storing in struct

Signed-off-by: RnkeZ <matej.kern@gmail.com>

* refactor(endpoints): update AddOrModify parameters

Signed-off-by: RnkeZ <matej.kern@gmail.com>

* fix formatting issues

Signed-off-by: RnkeZ <matej.kern@gmail.com>

---------

Signed-off-by: RnkeZ <matej.kern@gmail.com>
2026-03-20 15:01:34 +01:00
Daniel Finneran
3a387b87c5 Update version to v1.1.1
Bumping for a new release
2026-03-20 11:05:12 +00:00
Patryk Strusiewicz-Surmacki
ca47abfc3a Fixed services error handling (#1478)
* Fixed services error handling

Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>

* Removed redundant code

Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>

---------

Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
Co-authored-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
2026-03-20 10:44:32 +01:00
Patryk Strusiewicz-Surmacki
dcd8fe0392 Fixed leader election restart issue (#1477)
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
Co-authored-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
2026-03-19 11:29:26 +01:00
dependabot[bot]
4e0de5277d Bump google.golang.org/grpc from 1.79.2 to 1.79.3 (#1476)
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.79.2 to 1.79.3.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.79.2...v1.79.3)

---
updated-dependencies:
- dependency-name: google.golang.org/grpc
  dependency-version: 1.79.3
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-19 11:25:46 +01:00
dependabot[bot]
897a1fe6d8 Bump github.com/florianl/go-conntrack from 0.6.0 to 0.7.0 (#1470)
Bumps [github.com/florianl/go-conntrack](https://github.com/florianl/go-conntrack) from 0.6.0 to 0.7.0.
- [Release notes](https://github.com/florianl/go-conntrack/releases)
- [Commits](https://github.com/florianl/go-conntrack/compare/v0.6.0...v0.7.0)

---
updated-dependencies:
- dependency-name: github.com/florianl/go-conntrack
  dependency-version: 0.7.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-17 14:57:29 +01:00
dependabot[bot]
25f215e38d Bump anchore/sbom-action from 0.23.0 to 0.23.1 (#1471)
Bumps [anchore/sbom-action](https://github.com/anchore/sbom-action) from 0.23.0 to 0.23.1.
- [Release notes](https://github.com/anchore/sbom-action/releases)
- [Changelog](https://github.com/anchore/sbom-action/blob/main/RELEASE.md)
- [Commits](https://github.com/anchore/sbom-action/compare/v0.23.0...v0.23.1)

---
updated-dependencies:
- dependency-name: anchore/sbom-action
  dependency-version: 0.23.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-17 14:57:20 +01:00
Patryk Strusiewicz-Surmacki
52d7c23db7 Fixed BGP route advertisement in control-plane only mode (#1468)
* Fixed BGP shutdown in control-plane only mode

Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>

* Added E2E tests for control-plane only mode

Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>

---------

Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
Co-authored-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
2026-03-13 16:18:07 +01:00
Marcel Fest
64880b62ab Update to v1.1.0
Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
2026-03-09 14:12:37 +01:00
Sebastian Gaiser
494c48bf21 fix(metrics): register correct gauge for BGP session info (#1460)
PrometheusCollector() was registering bgpServer.BGPSessionInfoGauge while the worker was writing to Manager.bgpSessionInfoGauge — two separate objects representing the same metric. This caused kube_vip_manager_bgp_session_info to always appear empty in Prometheus.

Signed-off-by: Sebastian Gaiser <sebastiangaiser@users.noreply.github.com>
2026-03-09 12:44:12 +01:00
dependabot[bot]
ff93e58cfd Bump golang.org/x/sys from 0.41.0 to 0.42.0 (#1452)
Bumps [golang.org/x/sys](https://github.com/golang/sys) from 0.41.0 to 0.42.0.
- [Commits](https://github.com/golang/sys/compare/v0.41.0...v0.42.0)

---
updated-dependencies:
- dependency-name: golang.org/x/sys
  dependency-version: 0.42.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-09 11:24:00 +01:00
dependabot[bot]
857891f695 Bump docker/build-push-action from 6 to 7 (#1454)
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 6 to 7.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/v6...v7)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-09 08:06:08 +01:00
dependabot[bot]
377153bc52 Bump docker/setup-qemu-action from 3 to 4 (#1456)
Bumps [docker/setup-qemu-action](https://github.com/docker/setup-qemu-action) from 3 to 4.
- [Release notes](https://github.com/docker/setup-qemu-action/releases)
- [Commits](https://github.com/docker/setup-qemu-action/compare/v3...v4)

---
updated-dependencies:
- dependency-name: docker/setup-qemu-action
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-09 08:05:48 +01:00
dependabot[bot]
a46f0e76c5 Bump docker/setup-buildx-action from 3 to 4 (#1457)
Bumps [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) from 3 to 4.
- [Release notes](https://github.com/docker/setup-buildx-action/releases)
- [Commits](https://github.com/docker/setup-buildx-action/compare/v3...v4)

---
updated-dependencies:
- dependency-name: docker/setup-buildx-action
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-09 08:05:37 +01:00
dependabot[bot]
51725463d6 Bump docker/metadata-action from 5.10.0 to 6.0.0 (#1455)
Bumps [docker/metadata-action](https://github.com/docker/metadata-action) from 5.10.0 to 6.0.0.
- [Release notes](https://github.com/docker/metadata-action/releases)
- [Commits](https://github.com/docker/metadata-action/compare/v5.10.0...v6.0.0)

---
updated-dependencies:
- dependency-name: docker/metadata-action
  dependency-version: 6.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-09 08:05:22 +01:00
dependabot[bot]
001c467e36 Bump golang.org/x/sync from 0.19.0 to 0.20.0 (#1451)
Bumps [golang.org/x/sync](https://github.com/golang/sync) from 0.19.0 to 0.20.0.
- [Commits](https://github.com/golang/sync/compare/v0.19.0...v0.20.0)

---
updated-dependencies:
- dependency-name: golang.org/x/sync
  dependency-version: 0.20.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-09 08:05:01 +01:00
dependabot[bot]
ff33ebe6ab Bump github.com/google/go-containerregistry from 0.21.1 to 0.21.2 (#1450)
Bumps [github.com/google/go-containerregistry](https://github.com/google/go-containerregistry) from 0.21.1 to 0.21.2.
- [Release notes](https://github.com/google/go-containerregistry/releases)
- [Commits](https://github.com/google/go-containerregistry/compare/v0.21.1...v0.21.2)

---
updated-dependencies:
- dependency-name: github.com/google/go-containerregistry
  dependency-version: 0.21.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-09 08:04:43 +01:00
dependabot[bot]
97fb2bd711 Bump k8s.io/klog/v2 from 2.130.1 to 2.140.0 (#1453)
Bumps [k8s.io/klog/v2](https://github.com/kubernetes/klog) from 2.130.1 to 2.140.0.
- [Release notes](https://github.com/kubernetes/klog/releases)
- [Changelog](https://github.com/kubernetes/klog/blob/main/RELEASE.md)
- [Commits](https://github.com/kubernetes/klog/compare/v2.130.1...2.140.0)

---
updated-dependencies:
- dependency-name: k8s.io/klog/v2
  dependency-version: 2.140.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-09 08:04:27 +01:00
dependabot[bot]
e36ed5a189 Bump google.golang.org/grpc from 1.79.1 to 1.79.2 (#1449)
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.79.1 to 1.79.2.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.79.1...v1.79.2)

---
updated-dependencies:
- dependency-name: google.golang.org/grpc
  dependency-version: 1.79.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-09 08:04:10 +01:00
dependabot[bot]
342709a63e Bump golang from 1.26.0-alpine3.23 to 1.26.1-alpine3.23 (#1458)
Bumps golang from 1.26.0-alpine3.23 to 1.26.1-alpine3.23.

---
updated-dependencies:
- dependency-name: golang
  dependency-version: 1.26.1-alpine3.23
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-09 07:20:14 +01:00
dependabot[bot]
e61453ace2 Bump docker/login-action from 3 to 4 (#1459)
Bumps [docker/login-action](https://github.com/docker/login-action) from 3 to 4.
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](https://github.com/docker/login-action/compare/v3...v4)

---
updated-dependencies:
- dependency-name: docker/login-action
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-09 07:19:52 +01:00
Daniel Finneran
d62dd9313a Now will ensure egress rules are cleaned for nft-internal (#1447)
* Now will ensure egress rules are cleaned for nft-internal

Signed-off-by: Dan Finneran <dan@thebsdbox.co.uk>

* Fixed missing IPv6 rule

Signed-off-by: Dan Finneran <dan@thebsdbox.co.uk>

---------

Signed-off-by: Dan Finneran <dan@thebsdbox.co.uk>
2026-03-06 17:44:20 +01:00
Patryk Strusiewicz-Surmacki
eb18c59519 Cleanup of channels (#1444)
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
Co-authored-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
2026-03-06 16:06:02 +01:00
Olli Hauer
5f11053080 fix: skip UPNP refresh logging when no service instances (#1446)
Prevents log spam in control-plane-only deployments where
ServiceInstances is always empty. The UPNP refresh goroutine
still runs but no longer logs every 5 minutes when there's
nothing to refresh.

Fixes noise in SIEM systems and log aggregators.

Signed-off-by: Olli Hauer <ohauer@gmx.de>
2026-03-05 23:56:42 +01:00
k-jun
7caf5f656a fix: align CLI lease flag defaults with Kubernetes client-go defaults (15/10/2) (#1429)
Signed-off-by: k-jun <keijun091221@gmail.com>
2026-03-04 16:42:26 +01:00
Patryk Strusiewicz-Surmacki
88efcc7bc2 Added waitgroups (#1434)
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
Co-authored-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
2026-03-03 18:06:15 +01:00
Chris
abb4741d1f fix: don't add VIP to interface in routing table and BGP service modes (#1442)
PR #1252 (fix for #1243) removed the guard that prevented adding the
service IP to the interface in routing table mode. This made AddIP()
unconditional in StartLoadBalancerService(), causing the LoadBalancer IP
to be added to the interface on ALL nodes.

In no-election routing table mode (vip_leaderelection=false,
svc_election=false), this leads to traffic blackholing: every node has
the VIP bound to its interface, but only the node with local endpoints
can actually serve traffic when externalTrafficPolicy is Local.

The original code correctly guarded AddIP() behind `!c.EnableRoutingTable`
because in L3 modes (routing table / BGP), traffic is attracted via
routing protocols, not by having the IP present on the interface. The
endpoint watchers (endpoints_routing_table.go, endpoints_bgp.go) manage
routes/advertisements based on local endpoint presence.

Restore the guard and extend it to also cover BGP mode:
- Routing table mode: only routes are managed (by endpoint watcher or
  leader), no IP on interface
- BGP mode: only BGP advertisements are managed, no IP on interface
- ARP/L2 mode: IP is added to interface (unchanged behavior)

Control plane (cp_enable) is unaffected as vipService() has its own
independent AddIP() call.

Existing stale IPs from the buggy version are cleaned up automatically
on restart, as StartLoadBalancerService() unconditionally calls
DeleteIP() before the now-guarded AddIP().

Signed-off-by: Christopher Dziomba <christopher.dziomba@telekom.de>
2026-03-03 17:33:09 +01:00
Daniel
81cc332fd8 WireGuard for services (#1414)
* add tunnel manager

Signed-off-by: Daniel Nägele <daniel@naegele.dev>

* add wireguard endpoints and services

Signed-off-by: Daniel Nägele <daniel@naegele.dev>

* add udp support

Signed-off-by: Daniel Nägele <daniel@naegele.dev>

* fix endpoint watching

Signed-off-by: Daniel Nägele <daniel@naegele.dev>

* refactor code

Signed-off-by: Daniel Nägele <daniel@naegele.dev>

* fix after rebase

Signed-off-by: Daniel Nägele <daniel@naegele.dev>

---------

Signed-off-by: Daniel Nägele <daniel@naegele.dev>
Co-authored-by: Marcel Fest <marcel.fest@live.de>
2026-03-02 21:56:23 +01:00
dependabot[bot]
19b63cdbf6 Bump anchore/sbom-action from 0.22.2 to 0.23.0 (#1439)
Bumps [anchore/sbom-action](https://github.com/anchore/sbom-action) from 0.22.2 to 0.23.0.
- [Release notes](https://github.com/anchore/sbom-action/releases)
- [Changelog](https://github.com/anchore/sbom-action/blob/main/RELEASE.md)
- [Commits](https://github.com/anchore/sbom-action/compare/v0.22.2...v0.23.0)

---
updated-dependencies:
- dependency-name: anchore/sbom-action
  dependency-version: 0.23.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-02 21:10:22 +01:00
dependabot[bot]
61f5dc9cf9 Bump k8s.io/api from 0.35.1 to 0.35.2 (#1437)
Bumps [k8s.io/api](https://github.com/kubernetes/api) from 0.35.1 to 0.35.2.
- [Commits](https://github.com/kubernetes/api/compare/v0.35.1...v0.35.2)

---
updated-dependencies:
- dependency-name: k8s.io/api
  dependency-version: 0.35.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-02 21:09:51 +01:00
dependabot[bot]
bed8c4ccec Bump k8s.io/client-go from 0.35.1 to 0.35.2 (#1438)
Bumps [k8s.io/client-go](https://github.com/kubernetes/client-go) from 0.35.1 to 0.35.2.
- [Changelog](https://github.com/kubernetes/client-go/blob/master/CHANGELOG.md)
- [Commits](https://github.com/kubernetes/client-go/compare/v0.35.1...v0.35.2)

---
updated-dependencies:
- dependency-name: k8s.io/client-go
  dependency-version: 0.35.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-02 21:09:33 +01:00
dependabot[bot]
c74b4e4de6 Bump actions/upload-artifact from 6 to 7 (#1440)
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 6 to 7.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v6...v7)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-02 18:59:47 +01:00
dependabot[bot]
ae36ce1f04 Bump github.com/google/go-containerregistry from 0.21.0 to 0.21.1 (#1436)
Bumps [github.com/google/go-containerregistry](https://github.com/google/go-containerregistry) from 0.21.0 to 0.21.1.
- [Release notes](https://github.com/google/go-containerregistry/releases)
- [Commits](https://github.com/google/go-containerregistry/compare/v0.21.0...v0.21.1)

---
updated-dependencies:
- dependency-name: github.com/google/go-containerregistry
  dependency-version: 0.21.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-02 18:58:38 +01:00
dependabot[bot]
490163171a Bump k8s.io/apimachinery from 0.35.1 to 0.35.2 (#1435)
Bumps [k8s.io/apimachinery](https://github.com/kubernetes/apimachinery) from 0.35.1 to 0.35.2.
- [Commits](https://github.com/kubernetes/apimachinery/compare/v0.35.1...v0.35.2)

---
updated-dependencies:
- dependency-name: k8s.io/apimachinery
  dependency-version: 0.35.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-02 18:58:10 +01:00
Patryk Strusiewicz-Surmacki
afc35f335b Added context inheritance for services (#1432)
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
Co-authored-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
2026-02-25 10:51:52 +01:00
dependabot[bot]
239bd3b047 Bump github.com/florianl/go-conntrack from 0.5.0 to 0.6.0 (#1431)
Bumps [github.com/florianl/go-conntrack](https://github.com/florianl/go-conntrack) from 0.5.0 to 0.6.0.
- [Release notes](https://github.com/florianl/go-conntrack/releases)
- [Commits](https://github.com/florianl/go-conntrack/compare/v0.5.0...v0.6.0)

---
updated-dependencies:
- dependency-name: github.com/florianl/go-conntrack
  dependency-version: 0.6.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-23 08:48:15 +01:00
dependabot[bot]
df9c190248 Bump github.com/google/go-containerregistry from 0.20.7 to 0.21.0 (#1430)
Bumps [github.com/google/go-containerregistry](https://github.com/google/go-containerregistry) from 0.20.7 to 0.21.0.
- [Release notes](https://github.com/google/go-containerregistry/releases)
- [Commits](https://github.com/google/go-containerregistry/compare/v0.20.7...v0.21.0)

---
updated-dependencies:
- dependency-name: github.com/google/go-containerregistry
  dependency-version: 0.21.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-23 08:47:56 +01:00
Patryk Strusiewicz-Surmacki
208c55fbfa Improved global lease (#1426)
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
Co-authored-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
2026-02-20 23:08:50 +01:00
Daniel Finneran
0f32c712c3 Merge pull request #1427 from kube-vip/skaffold
Adds skaffold for development
2026-02-19 15:15:59 +00:00
Dan Finneran
09947db639 Fix paths to seperate manifest
Signed-off-by: Dan Finneran <dan@thebsdbox.co.uk>
2026-02-18 17:29:16 +00:00
Dan Finneran
12085ab747 Adds skaffold for development
Signed-off-by: Dan Finneran <dan@thebsdbox.co.uk>
2026-02-18 17:10:50 +00:00
dependabot[bot]
089bc2e217 Bump google.golang.org/protobuf from 1.36.10 to 1.36.11 (#1420)
Bumps google.golang.org/protobuf from 1.36.10 to 1.36.11.

---
updated-dependencies:
- dependency-name: google.golang.org/protobuf
  dependency-version: 1.36.11
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-16 11:33:16 +01:00
dependabot[bot]
edca162f8f Bump k8s.io/client-go from 0.35.0 to 0.35.1 (#1423)
Bumps [k8s.io/client-go](https://github.com/kubernetes/client-go) from 0.35.0 to 0.35.1.
- [Changelog](https://github.com/kubernetes/client-go/blob/master/CHANGELOG.md)
- [Commits](https://github.com/kubernetes/client-go/compare/v0.35.0...v0.35.1)

---
updated-dependencies:
- dependency-name: k8s.io/client-go
  dependency-version: 0.35.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-16 11:33:00 +01:00
dependabot[bot]
1240cff958 Bump golang from 1.25.7-alpine3.23 to 1.26.0-alpine3.23 (#1424)
Bumps golang from 1.25.7-alpine3.23 to 1.26.0-alpine3.23.

---
updated-dependencies:
- dependency-name: golang
  dependency-version: 1.26.0-alpine3.23
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-16 09:20:10 +01:00
dependabot[bot]
e2ac746260 Bump google.golang.org/grpc from 1.78.0 to 1.79.1 (#1422)
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.78.0 to 1.79.1.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.78.0...v1.79.1)

---
updated-dependencies:
- dependency-name: google.golang.org/grpc
  dependency-version: 1.79.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-16 09:19:42 +01:00
dependabot[bot]
463e4408f6 Bump go.etcd.io/etcd/client/v3 from 3.6.7 to 3.6.8 (#1421)
Bumps [go.etcd.io/etcd/client/v3](https://github.com/etcd-io/etcd) from 3.6.7 to 3.6.8.
- [Release notes](https://github.com/etcd-io/etcd/releases)
- [Commits](https://github.com/etcd-io/etcd/compare/v3.6.7...v3.6.8)

---
updated-dependencies:
- dependency-name: go.etcd.io/etcd/client/v3
  dependency-version: 3.6.8
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-16 09:19:27 +01:00
dependabot[bot]
3b6c40cc4b Bump k8s.io/api from 0.35.0 to 0.35.1 (#1419)
Bumps [k8s.io/api](https://github.com/kubernetes/api) from 0.35.0 to 0.35.1.
- [Commits](https://github.com/kubernetes/api/compare/v0.35.0...v0.35.1)

---
updated-dependencies:
- dependency-name: k8s.io/api
  dependency-version: 0.35.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-16 09:18:55 +01:00
Patryk Strusiewicz-Surmacki
e679ba206d Refactored manager's code for mode selection (#1395)
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
Co-authored-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
2026-02-15 21:58:24 +01:00
Patryk Strusiewicz-Surmacki
9cea0e8b8d Fixed actions failure when whoami image cannot be loaded
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
2026-02-12 22:18:46 +01:00
Patryk Strusiewicz-Surmacki
6fc134258d Reverted missing change from #623
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
2026-02-12 17:59:23 +01:00
dependabot[bot]
9be058291f Bump go.etcd.io/etcd/client/v3 from 3.6.6 to 3.6.7
Bumps [go.etcd.io/etcd/client/v3](https://github.com/etcd-io/etcd) from 3.6.6 to 3.6.7.
- [Release notes](https://github.com/etcd-io/etcd/releases)
- [Commits](https://github.com/etcd-io/etcd/compare/v3.6.6...v3.6.7)

---
updated-dependencies:
- dependency-name: go.etcd.io/etcd/client/v3
  dependency-version: 3.6.7
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-11 20:14:23 +01:00
dependabot[bot]
0addea441e Bump go.etcd.io/etcd/client/pkg/v3 from 3.6.6 to 3.6.7
Bumps [go.etcd.io/etcd/client/pkg/v3](https://github.com/etcd-io/etcd) from 3.6.6 to 3.6.7.
- [Release notes](https://github.com/etcd-io/etcd/releases)
- [Commits](https://github.com/etcd-io/etcd/compare/v3.6.6...v3.6.7)

---
updated-dependencies:
- dependency-name: go.etcd.io/etcd/client/pkg/v3
  dependency-version: 3.6.7
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-10 16:19:20 +01:00
dependabot[bot]
cc741d523f Bump anchore/sbom-action from 0.22.1 to 0.22.2
Bumps [anchore/sbom-action](https://github.com/anchore/sbom-action) from 0.22.1 to 0.22.2.
- [Release notes](https://github.com/anchore/sbom-action/releases)
- [Changelog](https://github.com/anchore/sbom-action/blob/main/RELEASE.md)
- [Commits](https://github.com/anchore/sbom-action/compare/v0.22.1...v0.22.2)

---
updated-dependencies:
- dependency-name: anchore/sbom-action
  dependency-version: 0.22.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-10 16:18:38 +01:00
dependabot[bot]
9917b46396 Bump golang.org/x/sys from 0.40.0 to 0.41.0
Bumps [golang.org/x/sys](https://github.com/golang/sys) from 0.40.0 to 0.41.0.
- [Commits](https://github.com/golang/sys/compare/v0.40.0...v0.41.0)

---
updated-dependencies:
- dependency-name: golang.org/x/sys
  dependency-version: 0.41.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-10 16:18:21 +01:00
dependabot[bot]
bc973361e9 Bump google.golang.org/grpc from 1.77.0 to 1.78.0
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.77.0 to 1.78.0.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.77.0...v1.78.0)

---
updated-dependencies:
- dependency-name: google.golang.org/grpc
  dependency-version: 1.78.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-10 16:18:11 +01:00
dependabot[bot]
f0db910b8d Bump github.com/onsi/ginkgo/v2 from 2.28.0 to 2.28.1
Bumps [github.com/onsi/ginkgo/v2](https://github.com/onsi/ginkgo) from 2.28.0 to 2.28.1.
- [Release notes](https://github.com/onsi/ginkgo/releases)
- [Changelog](https://github.com/onsi/ginkgo/blob/master/CHANGELOG.md)
- [Commits](https://github.com/onsi/ginkgo/compare/v2.28.0...v2.28.1)

---
updated-dependencies:
- dependency-name: github.com/onsi/ginkgo/v2
  dependency-version: 2.28.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-10 16:17:59 +01:00
Patryk Strusiewicz-Surmacki
dab1bb6201 Fixed E2E ARP tests
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
2026-02-10 14:19:09 +01:00
dependabot[bot]
f9f5d75183 Bump golang from 1.25.6-alpine3.23 to 1.25.7-alpine3.23 (#1409)
Bumps golang from 1.25.6-alpine3.23 to 1.25.7-alpine3.23.

---
updated-dependencies:
- dependency-name: golang
  dependency-version: 1.25.7-alpine3.23
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-10 14:05:38 +01:00
dependabot[bot]
686431af94 Bump github.com/sirupsen/logrus from 1.9.3 to 1.9.4 (#1399)
Bumps [github.com/sirupsen/logrus](https://github.com/sirupsen/logrus) from 1.9.3 to 1.9.4.
- [Release notes](https://github.com/sirupsen/logrus/releases)
- [Changelog](https://github.com/sirupsen/logrus/blob/master/CHANGELOG.md)
- [Commits](https://github.com/sirupsen/logrus/compare/v1.9.3...v1.9.4)

---
updated-dependencies:
- dependency-name: github.com/sirupsen/logrus
  dependency-version: 1.9.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-03 12:48:00 +01:00
dependabot[bot]
e0520d6864 Bump github.com/onsi/gomega from 1.39.0 to 1.39.1 (#1398)
Bumps [github.com/onsi/gomega](https://github.com/onsi/gomega) from 1.39.0 to 1.39.1.
- [Release notes](https://github.com/onsi/gomega/releases)
- [Changelog](https://github.com/onsi/gomega/blob/master/CHANGELOG.md)
- [Commits](https://github.com/onsi/gomega/compare/v1.39.0...v1.39.1)

---
updated-dependencies:
- dependency-name: github.com/onsi/gomega
  dependency-version: 1.39.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-03 07:55:39 +01:00
dependabot[bot]
374f858ead Bump sigs.k8s.io/kind from 0.30.0 to 0.31.0 (#1402)
Bumps [sigs.k8s.io/kind](https://github.com/kubernetes-sigs/kind) from 0.30.0 to 0.31.0.
- [Release notes](https://github.com/kubernetes-sigs/kind/releases)
- [Commits](https://github.com/kubernetes-sigs/kind/compare/v0.30.0...v0.31.0)

---
updated-dependencies:
- dependency-name: sigs.k8s.io/kind
  dependency-version: 0.31.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-03 07:55:17 +01:00
dependabot[bot]
e07c86b9a0 Bump anchore/sbom-action from 0.22.0 to 0.22.1 (#1403)
Bumps [anchore/sbom-action](https://github.com/anchore/sbom-action) from 0.22.0 to 0.22.1.
- [Release notes](https://github.com/anchore/sbom-action/releases)
- [Changelog](https://github.com/anchore/sbom-action/blob/main/RELEASE.md)
- [Commits](https://github.com/anchore/sbom-action/compare/v0.22.0...v0.22.1)

---
updated-dependencies:
- dependency-name: anchore/sbom-action
  dependency-version: 0.22.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-03 07:55:03 +01:00
dependabot[bot]
4efa98c676 Bump alpine from 3.23.2 to 3.23.3 (#1404)
Bumps alpine from 3.23.2 to 3.23.3.

---
updated-dependencies:
- dependency-name: alpine
  dependency-version: 3.23.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-03 07:54:53 +01:00
Daniel Finneran
ff40ff06a3 Update Makefile
Bumping version for a new release
2026-01-29 13:55:15 +00:00
Daniel Finneran
8b90925a69 Merge pull request #1384 from daniel-naegele/improve-wireguard
Improve wireguard
2026-01-28 11:13:50 +00:00
Daniel Nägele
d9e1fcd288 fix linting issues
Signed-off-by: Daniel Nägele <daniel@naegele.dev>
2026-01-27 22:55:23 +01:00
Daniel Nägele
0c30654282 add sysctl
Signed-off-by: Daniel Nägele <daniel@naegele.dev>
2026-01-27 22:55:23 +01:00
Daniel Nägele
265094df3b cleanup code
Signed-off-by: Daniel Nägele <daniel@naegele.dev>
2026-01-27 22:55:23 +01:00
Daniel Nägele
b85f411502 make nftables impl work ?!?
Signed-off-by: Daniel Nägele <daniel@naegele.dev>
2026-01-27 22:55:23 +01:00
Daniel Nägele
671046751e add IPVS
Signed-off-by: Daniel Nägele <daniel@naegele.dev>
2026-01-27 22:55:23 +01:00
Daniel Nägele
8e539558f7 fixed up wireguard
Signed-off-by: Daniel Nägele <daniel@naegele.dev>
2026-01-27 22:55:23 +01:00
Daniel Nägele
f81e42eab7 fix wg
Signed-off-by: Daniel Nägele <daniel@naegele.dev>
2026-01-27 22:55:23 +01:00
Daniel Nägele
6eec9451bf add mtu and remove routes
goal is to get close to the wg-quick config format and behaviour

Signed-off-by: Daniel Nägele <daniel@naegele.dev>
2026-01-27 22:55:23 +01:00
Daniel Nägele
5b109de522 add sloppy nftmanager DNAT impl for wireguard
Signed-off-by: Daniel Nägele <daniel@naegele.dev>
2026-01-27 22:55:23 +01:00
Daniel Nägele
92a7987f31 improve impl
Signed-off-by: Daniel Nägele <daniel@naegele.dev>
2026-01-27 22:55:23 +01:00
Daniel Nägele
058beca51b fix lint issues
Signed-off-by: Daniel Nägele <daniel@naegele.dev>
2026-01-27 22:55:23 +01:00
Daniel Nägele
ec899d1723 add minimalistic changelog
Signed-off-by: Daniel Nägele <daniel@naegele.dev>
2026-01-27 22:55:23 +01:00
Daniel Nägele
9365d21e59 impl wg manager
Signed-off-by: Daniel Nägele <daniel@naegele.dev>
2026-01-27 22:55:23 +01:00
Daniel Nägele
e148794d66 "handcraft" wg controller
Signed-off-by: Daniel Nägele <daniel@naegele.dev>
2026-01-27 22:55:22 +01:00
Patryk Strusiewicz-Surmacki
50da0c19d1 Fix IP refresh when using FQDN for VIP (#1390)
* Fix IP refresh when using FQDN for VIP

Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>

* Made AddIP a variadic function

Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>

---------

Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
Co-authored-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
2026-01-27 13:26:32 +01:00
Patryk Strusiewicz-Surmacki
16b369575b Fixed cpCluster closing for BGP and RT modes
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
2026-01-26 12:47:17 +01:00
Patryk Strusiewicz-Surmacki
dd8feefb96 Fixed cluster close
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
2026-01-26 12:47:17 +01:00
Patryk Strusiewicz-Surmacki
5818a6c661 Do not use panic()
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
2026-01-26 12:47:17 +01:00
Patryk Strusiewicz-Surmacki
33c8bc08ac Fixed context propagation
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
Co-authored-by: Ricardo Pchevuzinske Katz <ricardo.katz@gmail.com>
2026-01-26 12:47:17 +01:00
dependabot[bot]
4b802feb88 Bump github.com/onsi/gomega from 1.38.2 to 1.38.3 (#1362)
Bumps [github.com/onsi/gomega](https://github.com/onsi/gomega) from 1.38.2 to 1.38.3.
- [Release notes](https://github.com/onsi/gomega/releases)
- [Changelog](https://github.com/onsi/gomega/blob/master/CHANGELOG.md)
- [Commits](https://github.com/onsi/gomega/compare/v1.38.2...v1.38.3)

---
updated-dependencies:
- dependency-name: github.com/onsi/gomega
  dependency-version: 1.38.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-26 09:02:05 +01:00
dependabot[bot]
4e5b12bf9f Bump alpine from 3.23.0 to 3.23.2 (#1366)
Bumps alpine from 3.23.0 to 3.23.2.

---
updated-dependencies:
- dependency-name: alpine
  dependency-version: 3.23.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-26 08:17:12 +01:00
dependabot[bot]
fda288134c Bump anchore/sbom-action from 0.21.0 to 0.22.0 (#1394)
Bumps [anchore/sbom-action](https://github.com/anchore/sbom-action) from 0.21.0 to 0.22.0.
- [Release notes](https://github.com/anchore/sbom-action/releases)
- [Changelog](https://github.com/anchore/sbom-action/blob/main/RELEASE.md)
- [Commits](https://github.com/anchore/sbom-action/compare/v0.21.0...v0.22.0)

---
updated-dependencies:
- dependency-name: anchore/sbom-action
  dependency-version: 0.22.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-26 08:16:32 +01:00
dependabot[bot]
9ddb91386a Bump go.etcd.io/etcd/api/v3 from 3.6.6 to 3.6.7 (#1363)
Bumps [go.etcd.io/etcd/api/v3](https://github.com/etcd-io/etcd) from 3.6.6 to 3.6.7.
- [Release notes](https://github.com/etcd-io/etcd/releases)
- [Commits](https://github.com/etcd-io/etcd/compare/v3.6.6...v3.6.7)

---
updated-dependencies:
- dependency-name: go.etcd.io/etcd/api/v3
  dependency-version: 3.6.7
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-26 08:15:42 +01:00
dependabot[bot]
3519e638db Bump github.com/onsi/ginkgo/v2 from 2.27.2 to 2.27.3 (#1364)
Bumps [github.com/onsi/ginkgo/v2](https://github.com/onsi/ginkgo) from 2.27.2 to 2.27.3.
- [Release notes](https://github.com/onsi/ginkgo/releases)
- [Changelog](https://github.com/onsi/ginkgo/blob/master/CHANGELOG.md)
- [Commits](https://github.com/onsi/ginkgo/compare/v2.27.2...v2.27.3)

---
updated-dependencies:
- dependency-name: github.com/onsi/ginkgo/v2
  dependency-version: 2.27.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-26 08:12:00 +01:00
dependabot[bot]
60afc05a15 Bump golang.org/x/sync from 0.18.0 to 0.19.0 (#1361)
Bumps [golang.org/x/sync](https://github.com/golang/sync) from 0.18.0 to 0.19.0.
- [Commits](https://github.com/golang/sync/compare/v0.18.0...v0.19.0)

---
updated-dependencies:
- dependency-name: golang.org/x/sync
  dependency-version: 0.19.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-26 08:11:43 +01:00
dependabot[bot]
309917507a Bump k8s.io/client-go from 0.34.3 to 0.35.0 (#1365)
Bumps [k8s.io/client-go](https://github.com/kubernetes/client-go) from 0.34.3 to 0.35.0.
- [Changelog](https://github.com/kubernetes/client-go/blob/master/CHANGELOG.md)
- [Commits](https://github.com/kubernetes/client-go/compare/v0.34.3...v0.35.0)

---
updated-dependencies:
- dependency-name: k8s.io/client-go
  dependency-version: 0.35.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-26 08:11:23 +01:00
dependabot[bot]
caa46fdcbc Bump golang from 1.25.5-alpine3.23 to 1.25.6-alpine3.23 (#1393)
Bumps golang from 1.25.5-alpine3.23 to 1.25.6-alpine3.23.

---
updated-dependencies:
- dependency-name: golang
  dependency-version: 1.25.6-alpine3.23
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-26 08:10:56 +01:00
Patryk Strusiewicz-Surmacki
545199246d Fixed leaderelection retry when endpoint changes node (#1386)
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
Co-authored-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
2026-01-21 07:19:07 +01:00
Patryk Strusiewicz-Surmacki
531e3fd6c6 Bumped e2e test kubernetes version to 1.35.0 (#1387)
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
Co-authored-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
2026-01-19 15:04:09 +01:00
Brian Davis
93a2fbec34 fix common lease fix from 1.0.1 (#1383)
* fix common lease fix from 1.0.1

Test coverage specific to this issue
- TestManager_LeaderElectionRestartScenario - Simulates the bug from the issue

Additional tests for leases
- TestManager_Add_NewLease - Verifies new lease creation
- TestManager_Add_ExistingLease - Verifies returning existing lease
- TestManager_Delete_DecrementCounter - Verifies reference counting
- TestManager_Delete_CancelsContext - Verifies context cancellation on delete
- TestManager_Add_AfterDelete_CreatesNewLease - Critical test for the bug fix - verifies a new lease is created after delete
- TestManager_Add_DifferentServices - Verifies different services get different leases
- TestManager_Add_SameNameDifferentNamespace - Verifies namespace isolation
- TestManager_ConcurrentAccess - Verifies thread safety
- TestLease_StartedChannel - Verifies Started channel behavior
- TestGetName_WithoutAnnotation - Verifies default lease naming
- TestGetName_WithAnnotation - Verifies custom lease naming
- TestUsesCommon - Verifies common lease detection
- TestManager_CommonLeaseScenario - Verifies the common lease feature still works

  Affects issue #1377

Signed-off-by: Brian Davis <dbrian@vmware.com>

* handle 0 LB addresses

Signed-off-by: Brian Davis <slimm609@gmail.com>
Signed-off-by: Brian Davis <dbrian@vmware.com>

* update tests for hanging connections

Signed-off-by: Brian Davis <slimm609@gmail.com>

* fix lint and remaining tests

Signed-off-by: Brian Davis <slimm609@gmail.com>

* fix failing tests for waiting for lease

Signed-off-by: Brian Davis <slimm609@gmail.com>

* handle race in intergration test

Signed-off-by: Brian Davis <slimm609@gmail.com>

---------

Signed-off-by: Brian Davis <dbrian@vmware.com>
Signed-off-by: Brian Davis <slimm609@gmail.com>
2026-01-16 07:33:52 +01:00
hindung
a2042d46e1 Fixed an issue with default gateway interface retrieval in multi-path… (#1373)
* Fixed an issue with default gateway interface retrieval in multi-path routing scenarios

Signed-off-by: huangxd <huangxd@winhong.com>

* RouteListFiltered filtering function enhances query efficiency,
separately handles IPv4 and IPv6 route lookups to avoid unnecessary route merging operations.

Signed-off-by: huangxd <huangxd@winhong.com>

* Extract the embedded `findDefault` function from the `GetDefaultGatewayInterface` function into a separate `getDefaultRoute` function.

Signed-off-by: huangxd <huangxd@winhong.com>

* Update pkg/vip/util.go

Co-authored-by: Marcel Fest <marcel@fest4.eu>
Signed-off-by: huangxd <huangxd@winhong.com>

* Update pkg/vip/util.go

Co-authored-by: Marcel Fest <marcel@fest4.eu>
Signed-off-by: huangxd <huangxd@winhong.com>

* Update pkg/vip/util.go

Co-authored-by: Marcel Fest <marcel@fest4.eu>
Signed-off-by: huangxd <huangxd@winhong.com>

* Update pkg/vip/util.go

Co-authored-by: Marcel Fest <marcel@fest4.eu>
Signed-off-by: huangxd <huangxd@winhong.com>

* Optimize error handling in the getDefaultRoute function

Signed-off-by: huangxd <huangxd@winhong.com>

---------

Signed-off-by: huangxd <huangxd@winhong.com>
Co-authored-by: huangxd <huangxd@winhong.com>
Co-authored-by: Marcel Fest <marcel@fest4.eu>
2026-01-14 09:29:17 +01:00
Patryk Strusiewicz-Surmacki
3ce54c4f97 Added pre-pull for testing images + some minor e2e tweaks (#1380)
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
Co-authored-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
2026-01-10 22:52:20 +01:00
Patryk Strusiewicz-Surmacki
42393bf5fc Fixed endpointslices handling in dualstack clusters (#1379)
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
Co-authored-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
2026-01-10 22:02:32 +01:00
Patryk Strusiewicz-Surmacki
7e671624b0 Configurable DHCP retry (#1374)
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
Co-authored-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
2026-01-05 12:20:13 +01:00
Patryk Strusiewicz-Surmacki
9953699239 Fixed preserveVipOnLeadershipLoss setting in manifest generation (#1376)
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
Co-authored-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
2025-12-31 18:41:49 +01:00
dependabot[bot]
3a5dad57ba Bump anchore/sbom-action from 0.20.11 to 0.21.0 (#1372)
Bumps [anchore/sbom-action](https://github.com/anchore/sbom-action) from 0.20.11 to 0.21.0.
- [Release notes](https://github.com/anchore/sbom-action/releases)
- [Changelog](https://github.com/anchore/sbom-action/blob/main/RELEASE.md)
- [Commits](https://github.com/anchore/sbom-action/compare/v0.20.11...v0.21.0)

---
updated-dependencies:
- dependency-name: anchore/sbom-action
  dependency-version: 0.21.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-29 04:06:22 +01:00
Daniel Finneran
ba7a71bc5f Merge pull request #1368 from p-strusiewiczsurmacki-mobica/fix/svc-leaderelection-restart
Improved leaderelection context and ingress comparison
2025-12-24 17:00:16 +00:00
Patryk Strusiewicz-Surmacki
40d15fed9c Fixed ingress comparison
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
2025-12-23 17:47:57 +01:00
Patryk Strusiewicz-Surmacki
fad5176f6a Improved leaderelection context
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
2025-12-23 17:47:46 +01:00
Daniel Finneran
28bec598f5 Merge pull request #1360 from p-strusiewiczsurmacki-mobica/fix/redundant-delete-svcelection
Fixed service deletion when service leader election is enabled
2025-12-19 09:13:37 +00:00
Patryk Strusiewicz-Surmacki
200d0d960c Fixed service deletion when service leader election is enabled
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
2025-12-18 17:16:39 +01:00
Daniel Finneran
6e0f2132ca Merge pull request #1359 from kube-vip/repeat-of-prev-PR-to-move-error-to-warn 2025-12-17 19:55:31 +00:00
Daniel Finneran
19152ccd15 Merge pull request #1358 from kube-vip/bump-Makefile 2025-12-17 19:55:15 +00:00
Daniel Finneran
741d4a63e0 Move an Error to a warning 2025-12-17 18:04:56 +00:00
Daniel Finneran
badd66c4e8 Update Makefile 2025-12-17 18:02:56 +00:00
Daniel Finneran
fbb0717cb4 Merge pull request #1357 from p-strusiewiczsurmacki-mobica/fix/service-port-security
Fixed service port security rules for iptables
2025-12-17 18:02:29 +00:00
Marcel Fest
414ba0c6a6 Merge branch 'main' into fix/service-port-security 2025-12-17 18:09:11 +01:00
Daniel Finneran
c4054fa86d Merge pull request #1356 from p-strusiewiczsurmacki-mobica/fix/service-dns
Fixed service DNS resolve
2025-12-17 16:06:39 +00:00
Patryk Strusiewicz-Surmacki
5bfec6e426 Fixed service port security rules
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
2025-12-17 12:49:06 +01:00
Daniel Finneran
075639996e Merge pull request #1354 from kube-vip/dependabot/github_actions/anchore/sbom-action-0.20.11
Bump anchore/sbom-action from 0.20.10 to 0.20.11
2025-12-16 14:16:50 +00:00
Daniel Finneran
d90b7ae20e Merge pull request #1353 from kube-vip/dependabot/github_actions/actions/upload-artifact-6
Bump actions/upload-artifact from 5 to 6
2025-12-16 14:16:32 +00:00
Daniel Finneran
b200e9a3f7 Merge pull request #1352 from kube-vip/dependabot/go_modules/k8s.io/client-go-0.34.3
Bump k8s.io/client-go from 0.34.1 to 0.34.3
2025-12-16 14:16:17 +00:00
dependabot[bot]
e6c48839a7 Bump anchore/sbom-action from 0.20.10 to 0.20.11
Bumps [anchore/sbom-action](https://github.com/anchore/sbom-action) from 0.20.10 to 0.20.11.
- [Release notes](https://github.com/anchore/sbom-action/releases)
- [Changelog](https://github.com/anchore/sbom-action/blob/main/RELEASE.md)
- [Commits](https://github.com/anchore/sbom-action/compare/v0.20.10...v0.20.11)

---
updated-dependencies:
- dependency-name: anchore/sbom-action
  dependency-version: 0.20.11
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-16 12:58:25 +00:00
dependabot[bot]
53a86b6164 Bump actions/upload-artifact from 5 to 6
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 5 to 6.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-16 12:58:13 +00:00
dependabot[bot]
1988a69d1b Bump k8s.io/client-go from 0.34.1 to 0.34.3
Bumps [k8s.io/client-go](https://github.com/kubernetes/client-go) from 0.34.1 to 0.34.3.
- [Changelog](https://github.com/kubernetes/client-go/blob/master/CHANGELOG.md)
- [Commits](https://github.com/kubernetes/client-go/compare/v0.34.1...v0.34.3)

---
updated-dependencies:
- dependency-name: k8s.io/client-go
  dependency-version: 0.34.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-16 12:58:06 +00:00
Daniel Finneran
3b97bb7360 Merge pull request #1351 from kube-vip/dependabot/go_modules/k8s.io/api-0.34.3
Bump k8s.io/api from 0.34.2 to 0.34.3
2025-12-16 12:54:44 +00:00
Daniel Finneran
09800c9be6 Merge pull request #1346 from kube-vip/dependabot/go_modules/github.com/florianl/go-conntrack-0.5.0
Bump github.com/florianl/go-conntrack from 0.4.0 to 0.5.0
2025-12-16 12:54:32 +00:00
Patryk Strusiewicz-Surmacki
c8e0a72be6 Fixed service DNS resolve
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
2025-12-15 17:48:03 +01:00
Daniel Finneran
002a83fa65 Merge pull request #1347 from kube-vip/dependabot/docker/alpine-3.23.0
Bump alpine from 3.22.2 to 3.23.0
2025-12-15 16:42:42 +00:00
Daniel Finneran
9ad84e3ae6 Merge pull request #1345 from kube-vip/dependabot/go_modules/github.com/spf13/cobra-1.10.2
Bump github.com/spf13/cobra from 1.10.1 to 1.10.2
2025-12-15 16:10:36 +00:00
Daniel Finneran
ad50b9c3ef Merge pull request #1344 from kube-vip/dependabot/go_modules/testing/e2e/e2e/github.com/sirupsen/logrus-1.9.1
Bump github.com/sirupsen/logrus from 1.9.0 to 1.9.1 in /testing/e2e/e2e
2025-12-15 16:10:10 +00:00
dependabot[bot]
d98a6ef660 Bump k8s.io/api from 0.34.2 to 0.34.3
Bumps [k8s.io/api](https://github.com/kubernetes/api) from 0.34.2 to 0.34.3.
- [Commits](https://github.com/kubernetes/api/compare/v0.34.2...v0.34.3)

---
updated-dependencies:
- dependency-name: k8s.io/api
  dependency-version: 0.34.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-15 15:33:29 +00:00
dependabot[bot]
c83a8cea2f Bump github.com/florianl/go-conntrack from 0.4.0 to 0.5.0
Bumps [github.com/florianl/go-conntrack](https://github.com/florianl/go-conntrack) from 0.4.0 to 0.5.0.
- [Release notes](https://github.com/florianl/go-conntrack/releases)
- [Commits](https://github.com/florianl/go-conntrack/compare/v0.4.0...v0.5.0)

---
updated-dependencies:
- dependency-name: github.com/florianl/go-conntrack
  dependency-version: 0.5.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-15 15:32:50 +00:00
dependabot[bot]
08966e9bed Bump github.com/spf13/cobra from 1.10.1 to 1.10.2
Bumps [github.com/spf13/cobra](https://github.com/spf13/cobra) from 1.10.1 to 1.10.2.
- [Release notes](https://github.com/spf13/cobra/releases)
- [Commits](https://github.com/spf13/cobra/compare/v1.10.1...v1.10.2)

---
updated-dependencies:
- dependency-name: github.com/spf13/cobra
  dependency-version: 1.10.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-15 15:32:32 +00:00
dependabot[bot]
6bf0e37282 Bump github.com/sirupsen/logrus from 1.9.0 to 1.9.1 in /testing/e2e/e2e
Bumps [github.com/sirupsen/logrus](https://github.com/sirupsen/logrus) from 1.9.0 to 1.9.1.
- [Release notes](https://github.com/sirupsen/logrus/releases)
- [Changelog](https://github.com/sirupsen/logrus/blob/master/CHANGELOG.md)
- [Commits](https://github.com/sirupsen/logrus/compare/v1.9.0...v1.9.1)

---
updated-dependencies:
- dependency-name: github.com/sirupsen/logrus
  dependency-version: 1.9.1
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-15 15:32:00 +00:00
dependabot[bot]
ea1d6136be Bump alpine from 3.22.2 to 3.23.0
Bumps alpine from 3.22.2 to 3.23.0.

---
updated-dependencies:
- dependency-name: alpine
  dependency-version: 3.23.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-15 15:31:50 +00:00
Daniel Finneran
ff3e85c6a6 Merge pull request #1355 from kube-vip/golang_bump
Bump to golang to fix stdlib vuln
2025-12-15 15:30:49 +00:00
Dan Finneran
38a6fdb457 bump alpine release for build
Signed-off-by: Dan Finneran <dan@thebsdbox.co.uk>
2025-12-15 14:57:21 +00:00
Dan Finneran
dfd1b1da19 path up other ci complaints.
Signed-off-by: Dan Finneran <dan@thebsdbox.co.uk>
2025-12-15 14:53:21 +00:00
Dan Finneran
aecc0264b0 upgrade lint config
Signed-off-by: Dan Finneran <dan@thebsdbox.co.uk>
2025-12-15 12:02:41 +00:00
Dan Finneran
a35849d4f8 bump ci workflow
Signed-off-by: Dan Finneran <dan@thebsdbox.co.uk>
2025-12-15 11:57:46 +00:00
Dan Finneran
4c3a2d57ee Bump to golang to fix stdlib vuln
Signed-off-by: Dan Finneran <dan@thebsdbox.co.uk>
2025-12-15 11:53:23 +00:00
Daniel Finneran
48c99ca320 Merge pull request #1342 from kube-vip/dependabot/github_actions/docker/metadata-action-5.10.0
Bump docker/metadata-action from 5.9.0 to 5.10.0
2025-12-15 11:50:31 +00:00
Daniel Finneran
83d1a9e455 Merge pull request #1341 from kube-vip/dependabot/go_modules/github.com/google/go-containerregistry-0.20.7
Bump github.com/google/go-containerregistry from 0.20.6 to 0.20.7
2025-12-15 11:50:18 +00:00
Daniel Finneran
11649c9e79 Merge pull request #1350 from ivucica/ivucica-upnp-lease-duration
Support specifying UPNP lease duration as annotation on a service.
2025-12-15 11:50:06 +00:00
Ivan Vučica
b31de5ca61 Support specifying UPNP lease duration as annotation on a service.
The annotation `kube-vip.io/upnp-lease-duration` takes in a duration where the string is parseable by `time.ParseDuration`.

There is no new configuration option that would allow setting this globally, since this new feature is most helpful in limited cases (such as incorrect implementations that have trouble with certain values).

There is a minimal test added for the value returned by the new private helper `upnpLeaseDurationForService`. Due to a lack of dependency injection in `service.Processor`'s `upnpMap`, it is infeasible to add a more complete test at this time, to check what would be passed, exactly, into `AddPinholeCtx` and `AddPortMapping`.

Signed-off-by: Ivan Vučica <ivan@vucica.net>
Signed-off-by: Ivan Vučica <ivucica@google.com>
Fixes: #1349
2025-12-12 12:22:37 +00:00
Daniel Finneran
18544a5d54 Merge pull request #1343 from kube-vip/error_warn
Move this error to a warning
2025-12-01 15:56:14 +00:00
Dan Finneran
83d2092fec Move this error to a warning
Signed-off-by: Dan Finneran <dan@thebsdbox.co.uk>
2025-12-01 14:53:29 +00:00
dependabot[bot]
099d8f759b Bump docker/metadata-action from 5.9.0 to 5.10.0
Bumps [docker/metadata-action](https://github.com/docker/metadata-action) from 5.9.0 to 5.10.0.
- [Release notes](https://github.com/docker/metadata-action/releases)
- [Commits](https://github.com/docker/metadata-action/compare/v5.9.0...v5.10.0)

---
updated-dependencies:
- dependency-name: docker/metadata-action
  dependency-version: 5.10.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-01 02:14:54 +00:00
dependabot[bot]
e99fa71ed6 Bump github.com/google/go-containerregistry from 0.20.6 to 0.20.7
Bumps [github.com/google/go-containerregistry](https://github.com/google/go-containerregistry) from 0.20.6 to 0.20.7.
- [Release notes](https://github.com/google/go-containerregistry/releases)
- [Commits](https://github.com/google/go-containerregistry/compare/v0.20.6...v0.20.7)

---
updated-dependencies:
- dependency-name: github.com/google/go-containerregistry
  dependency-version: 0.20.7
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-01 02:03:39 +00:00
Daniel Finneran
6c9c5af373 Merge pull request #1334 from kube-vip/dependabot/github_actions/anchore/sbom-action-0.20.10
Bump anchore/sbom-action from 0.20.9 to 0.20.10
2025-11-27 09:02:30 +00:00
Daniel Finneran
509eeea1d4 Merge pull request #1339 from tbjorklund78/bgp_annotation
Add annotation to service when using BGP and not just ARP
2025-11-26 18:15:29 +00:00
Daniel Finneran
c00a61f45e Merge pull request #1338 from mkhpalm/patch-upnp
Do not run UPnP refresher if UPnP is disabled
2025-11-26 18:14:47 +00:00
Daniel Finneran
0ea24655eb Merge pull request #1336 from ivucica/patch-1
Avoid access inside WANIPv6FirewallControlClient when it might be nil
2025-11-26 18:14:28 +00:00
Ivan Vučica
288cd9a8b0 Avoid access inside WANIPv6FirewallControlClient when it might be nil
This moves the `log.Info` call inside the check for nil-ness of the
`gw.WANIPv6FirewallControlClient`. A UPnP portmap device that
has no IPv6 support crashes without this check.

To compensate, this adds logging statements for the `PortForward`
case.

Signed-off-by: Ivan Vučica <ivan@vucica.net>
Signed-off-by: Ivan Vučica <ivucica@google.com>
Fixes: #1335
2025-11-26 15:51:10 +00:00
Thomas Björklund
2c00d2bc05 Also add annotation to the service when using BGP and not just ARP to faciliate
using kube-vip to allow for high availability ciliumegressgatewaypolicies.cilium.io
using for example https://github.com/angeloxx/cilium-haegress-operator

Signed-off-by: Thomas Björklund <thomas@netnod.se>
2025-11-26 00:26:45 +01:00
Mike Palmer
5cf899c88c Do not run UPnP refresher if UPnP is disabled
Signed-off-by: Mike Palmer <mkhpalm@gmail.com>
2025-11-25 10:38:56 -07:00
dependabot[bot]
16fa1bcc26 Bump google.golang.org/grpc from 1.76.0 to 1.77.0 (#1330)
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.76.0 to 1.77.0.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.76.0...v1.77.0)

---
updated-dependencies:
- dependency-name: google.golang.org/grpc
  dependency-version: 1.77.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-24 13:29:34 +01:00
dependabot[bot]
a67ef25c15 Bump go.uber.org/zap from 1.27.0 to 1.27.1 (#1329)
Bumps [go.uber.org/zap](https://github.com/uber-go/zap) from 1.27.0 to 1.27.1.
- [Release notes](https://github.com/uber-go/zap/releases)
- [Changelog](https://github.com/uber-go/zap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/uber-go/zap/compare/v1.27.0...v1.27.1)

---
updated-dependencies:
- dependency-name: go.uber.org/zap
  dependency-version: 1.27.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-24 13:29:16 +01:00
dependabot[bot]
c82738633c Bump actions/checkout from 5 to 6 (#1333)
Bumps [actions/checkout](https://github.com/actions/checkout) from 5 to 6.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-24 07:52:48 +01:00
dependabot[bot]
11e419595b Bump k8s.io/api from 0.34.1 to 0.34.2 (#1331)
Bumps [k8s.io/api](https://github.com/kubernetes/api) from 0.34.1 to 0.34.2.
- [Commits](https://github.com/kubernetes/api/compare/v0.34.1...v0.34.2)

---
updated-dependencies:
- dependency-name: k8s.io/api
  dependency-version: 0.34.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-24 07:35:17 +01:00
dependabot[bot]
1db99a10dc Bump go.etcd.io/etcd/client/v3 from 3.6.5 to 3.6.6 (#1332)
Bumps [go.etcd.io/etcd/client/v3](https://github.com/etcd-io/etcd) from 3.6.5 to 3.6.6.
- [Release notes](https://github.com/etcd-io/etcd/releases)
- [Commits](https://github.com/etcd-io/etcd/compare/v3.6.5...v3.6.6)

---
updated-dependencies:
- dependency-name: go.etcd.io/etcd/client/v3
  dependency-version: 3.6.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-24 07:34:42 +01:00
dependabot[bot]
f51f3276b5 Bump anchore/sbom-action from 0.20.9 to 0.20.10
Bumps [anchore/sbom-action](https://github.com/anchore/sbom-action) from 0.20.9 to 0.20.10.
- [Release notes](https://github.com/anchore/sbom-action/releases)
- [Changelog](https://github.com/anchore/sbom-action/blob/main/RELEASE.md)
- [Commits](https://github.com/anchore/sbom-action/compare/v0.20.9...v0.20.10)

---
updated-dependencies:
- dependency-name: anchore/sbom-action
  dependency-version: 0.20.10
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-24 02:06:26 +00:00
Daniel Finneran
199bc43c5c Merge pull request #1327 from kube-vip/dependabot/go_modules/golang.org/x/crypto-0.45.0
Bump golang.org/x/crypto from 0.41.0 to 0.45.0
2025-11-21 09:13:31 +00:00
dependabot[bot]
16afc9c1d4 Bump golang.org/x/crypto from 0.41.0 to 0.45.0
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.41.0 to 0.45.0.
- [Commits](https://github.com/golang/crypto/compare/v0.41.0...v0.45.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-version: 0.45.0
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-20 02:49:20 +00:00
Daniel Finneran
76156b3f3b Update Makefile
Ready for new release
2025-11-19 20:03:29 +00:00
Daniel Finneran
5a1e8c1a3f Merge pull request #1323 from kube-vip/dependabot/github_actions/docker/metadata-action-5.9.0
Bump docker/metadata-action from 5.8.0 to 5.9.0
2025-11-19 19:59:50 +00:00
Daniel Finneran
2d0f0734c4 Merge pull request #1326 from kube-vip/k8s_dump 2025-11-19 19:05:09 +00:00
Dan Finneran
42b97175e3 adds UUID to output
Signed-off-by: Dan Finneran <dan@thebsdbox.co.uk>
2025-11-19 18:34:36 +00:00
Dan Finneran
eec091af23 Now returns the internal kubernetes configuration of services and endpoints
Signed-off-by: Dan Finneran <dan@thebsdbox.co.uk>
2025-11-19 18:32:01 +00:00
Daniel Finneran
6f4f870800 Merge pull request #1322 from kube-vip/dependabot/docker/golang-1.25.4-alpine3.22
Bump golang from 1.25.3-alpine3.22 to 1.25.4-alpine3.22
2025-11-19 17:22:07 +00:00
Daniel Finneran
3a5a59ae64 Merge pull request #1319 from kube-vip/dependabot/go_modules/golang.org/x/sync-0.18.0
Bump golang.org/x/sync from 0.17.0 to 0.18.0
2025-11-19 17:21:51 +00:00
dependabot[bot]
e8484fa1f3 Bump golang.org/x/sync from 0.17.0 to 0.18.0
Bumps [golang.org/x/sync](https://github.com/golang/sync) from 0.17.0 to 0.18.0.
- [Commits](https://github.com/golang/sync/compare/v0.17.0...v0.18.0)

---
updated-dependencies:
- dependency-name: golang.org/x/sync
  dependency-version: 0.18.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-19 16:13:52 +00:00
Daniel Finneran
55ccb8cd87 Merge pull request #1321 from kube-vip/dependabot/go_modules/golang.org/x/sys-0.38.0
Bump golang.org/x/sys from 0.37.0 to 0.38.0
2025-11-19 16:12:42 +00:00
Daniel Finneran
09edf341ab Merge pull request #1320 from kube-vip/dependabot/go_modules/github.com/docker/docker-28.5.2incompatible
Bump github.com/docker/docker from 28.5.1+incompatible to 28.5.2+incompatible
2025-11-19 16:12:25 +00:00
Daniel Finneran
8380e4f07e Merge pull request #1309 from kube-vip/dependabot/github_actions/actions/upload-artifact-5
Bump actions/upload-artifact from 4 to 5
2025-11-19 16:11:33 +00:00
Daniel Finneran
4a07466467 Merge pull request #1308 from kube-vip/dependabot/github_actions/anchore/sbom-action-0.20.9
Bump anchore/sbom-action from 0.20.6 to 0.20.9
2025-11-19 16:11:14 +00:00
Daniel Finneran
cbdc86ac8f Merge pull request #1298 from kube-vip/dependabot/github_actions/github/codeql-action-4
Bump github/codeql-action from 3 to 4
2025-11-19 16:11:00 +00:00
Daniel Finneran
7ea39fa7b5 Merge pull request #1325 from kube-vip/nft_fump
Adds the capability to dump the nftables config
2025-11-19 16:10:33 +00:00
Daniel Finneran
7eed2a33dc Merge pull request #1306 from slimm609/preserve_vip_leadership
Feat: preserve vip on leadership loss
2025-11-19 16:09:51 +00:00
Brian Davis
95bb7b9a85 fix dns.go formatting
Signed-off-by: Brian Davis <dbrian@vmware.com>
2025-11-19 08:59:19 -05:00
Brian Davis
2762fb624c fix go formatting
Signed-off-by: Brian Davis <dbrian@vmware.com>
2025-11-19 08:35:19 -05:00
Dan Finneran
3924a57168 lint fixesm
Signed-off-by: Dan Finneran <dan@thebsdbox.co.uk>
2025-11-17 20:22:31 +00:00
Dan Finneran
8750b3331c Adds the capability to dump the nftables config
Signed-off-by: Dan Finneran <dan@thebsdbox.co.uk>
2025-11-17 20:10:43 +00:00
Daniel Finneran
be9415fef1 Merge pull request #1324 from kube-vip/modules_warn
Moves the kernel modules to a warning as they can be loaded during th…
2025-11-17 16:54:16 +00:00
Dan Finneran
df13a69e26 Moves the kernel modules to a warning as they can be loaded during the rule creation.
Signed-off-by: Dan Finneran <dan@thebsdbox.co.uk>
2025-11-17 16:06:01 +00:00
Brian Davis
6b60780d6c handle ipv6 indepedently
- ipv6 has duplicate address dectection which prevents perserving the VIP on the old node

Signed-off-by: Brian Davis <slimm609@gmail.com>
Signed-off-by: Brian Davis <dbrian@vmware.com>
2025-11-13 10:21:26 -05:00
Brian Davis
9786aa9446 feat: preserve vip on leadership loss
When in arp mode, when preserveVipOnLeadershipLoss is true, when a node loses leadership (or can't keep it),
this will stop performing ARPs but will wait until a new leader is elected before deleting the arp.

when the flag is set to false (default) it continue to function like normal.

Signed-off-by: Brian Davis <slimm609@gmail.com>
Signed-off-by: Brian Davis <dbrian@vmware.com>
2025-11-13 10:21:26 -05:00
dependabot[bot]
71ca2614d2 Bump docker/metadata-action from 5.8.0 to 5.9.0
Bumps [docker/metadata-action](https://github.com/docker/metadata-action) from 5.8.0 to 5.9.0.
- [Release notes](https://github.com/docker/metadata-action/releases)
- [Commits](https://github.com/docker/metadata-action/compare/v5.8.0...v5.9.0)

---
updated-dependencies:
- dependency-name: docker/metadata-action
  dependency-version: 5.9.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-10 02:06:25 +00:00
dependabot[bot]
3d171a937e Bump golang from 1.25.3-alpine3.22 to 1.25.4-alpine3.22
Bumps golang from 1.25.3-alpine3.22 to 1.25.4-alpine3.22.

---
updated-dependencies:
- dependency-name: golang
  dependency-version: 1.25.4-alpine3.22
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-10 02:06:06 +00:00
dependabot[bot]
2663a1b222 Bump golang.org/x/sys from 0.37.0 to 0.38.0
Bumps [golang.org/x/sys](https://github.com/golang/sys) from 0.37.0 to 0.38.0.
- [Commits](https://github.com/golang/sys/compare/v0.37.0...v0.38.0)

---
updated-dependencies:
- dependency-name: golang.org/x/sys
  dependency-version: 0.38.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-10 02:03:23 +00:00
dependabot[bot]
51ebcc40f0 Bump github.com/docker/docker
Bumps [github.com/docker/docker](https://github.com/docker/docker) from 28.5.1+incompatible to 28.5.2+incompatible.
- [Release notes](https://github.com/docker/docker/releases)
- [Commits](https://github.com/docker/docker/compare/v28.5.1...v28.5.2)

---
updated-dependencies:
- dependency-name: github.com/docker/docker
  dependency-version: 28.5.2+incompatible
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-10 02:03:20 +00:00
dependabot[bot]
95c45b0b32 Bump github.com/onsi/ginkgo/v2 from 2.26.0 to 2.27.2 (#1314)
Bumps [github.com/onsi/ginkgo/v2](https://github.com/onsi/ginkgo) from 2.26.0 to 2.27.2.
- [Release notes](https://github.com/onsi/ginkgo/releases)
- [Changelog](https://github.com/onsi/ginkgo/blob/master/CHANGELOG.md)
- [Commits](https://github.com/onsi/ginkgo/compare/v2.26.0...v2.27.2)

---
updated-dependencies:
- dependency-name: github.com/onsi/ginkgo/v2
  dependency-version: 2.27.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-07 01:00:01 +01:00
dependabot[bot]
a3c5be3242 Bump golang.org/x/sys from 0.36.0 to 0.37.0 (#1296)
Bumps [golang.org/x/sys](https://github.com/golang/sys) from 0.36.0 to 0.37.0.
- [Commits](https://github.com/golang/sys/compare/v0.36.0...v0.37.0)

---
updated-dependencies:
- dependency-name: golang.org/x/sys
  dependency-version: 0.37.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-07 00:59:41 +01:00
Daniel Finneran
c5c920f341 Merge pull request #1315 from thc1006/feature/sigusr1-config-dump
Add SIGUSR1 signal handler for runtime configuration dumps
2025-11-04 22:13:24 +04:00
Patryk Strusiewicz-Surmacki
2e2951b35b Fixed DDNS nil pointer dereference (1305) (#1310)
* Fixed DDNS nil pointer dereference (1305)

Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>

* Using constants instead of values

Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>

---------

Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
Co-authored-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
2025-11-04 19:09:55 +01:00
Seungtae Moon
4b741e767a fix: normalize IPv6 to 32-hex (fixes #1302) (#1313)
Signed-off-by: seungtae62 <seungtae.moon62@gmail.com>
2025-11-04 19:08:12 +01:00
thc1006
66adbd4abb Add SIGUSR1 signal handler for runtime configuration dumps
Implements Issue #1301 - Adds support for dumping current configuration
when SIGUSR1 signal is received by the kube-vip process.

Changes:
- Add SIGUSR1 signal handling in all manager start methods
- Implement configuration dump functionality in pkg/manager/manager_dump.go:
  * dumpConfiguration() - Main dump coordinator
  * 7 helper methods for different configuration sections
- Update signal handlers to use switch statement pattern
- Add comprehensive unit tests (5 tests, all passing)
- Add E2E test for signal handling

Implementation details:
- Thread-safe with mutex protection
- Non-disruptive: process continues after dump
- Output format: human-readable plaintext via stdout
- File organization follows project convention (manager_*.go pattern)

Co-authored-by: SteveYi <steveyiyo@steveyi.net>
Signed-off-by: thc1006 <84045975+thc1006@users.noreply.github.com>
2025-11-04 11:24:59 +08:00
dependabot[bot]
c9e4e7aea1 Bump github.com/docker/docker
Bumps [github.com/docker/docker](https://github.com/docker/docker) from 28.5.0+incompatible to 28.5.1+incompatible.
- [Release notes](https://github.com/docker/docker/releases)
- [Commits](https://github.com/docker/docker/compare/v28.5.0...v28.5.1)

---
updated-dependencies:
- dependency-name: github.com/docker/docker
  dependency-version: 28.5.1+incompatible
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-04 02:16:11 +01:00
dependabot[bot]
56a441f700 Bump google.golang.org/grpc from 1.75.1 to 1.76.0
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.75.1 to 1.76.0.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.75.1...v1.76.0)

---
updated-dependencies:
- dependency-name: google.golang.org/grpc
  dependency-version: 1.76.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-04 02:15:56 +01:00
dependabot[bot]
f9951bac77 Bump alpine from 3.22.1 to 3.22.2
Bumps alpine from 3.22.1 to 3.22.2.

---
updated-dependencies:
- dependency-name: alpine
  dependency-version: 3.22.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-04 02:15:42 +01:00
dependabot[bot]
d7a66ce20f Bump golang from 1.25.1-alpine3.22 to 1.25.3-alpine3.22
Bumps golang from 1.25.1-alpine3.22 to 1.25.3-alpine3.22.

---
updated-dependencies:
- dependency-name: golang
  dependency-version: 1.25.3-alpine3.22
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-04 02:15:21 +01:00
dependabot[bot]
73d9ce7f44 Bump actions/upload-artifact from 4 to 5
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4 to 5.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-27 02:09:23 +00:00
dependabot[bot]
14ff1b9fec Bump anchore/sbom-action from 0.20.6 to 0.20.9
Bumps [anchore/sbom-action](https://github.com/anchore/sbom-action) from 0.20.6 to 0.20.9.
- [Release notes](https://github.com/anchore/sbom-action/releases)
- [Changelog](https://github.com/anchore/sbom-action/blob/main/RELEASE.md)
- [Commits](https://github.com/anchore/sbom-action/compare/v0.20.6...v0.20.9)

---
updated-dependencies:
- dependency-name: anchore/sbom-action
  dependency-version: 0.20.9
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-27 02:07:05 +00:00
dependabot[bot]
9a9c5998d8 Bump github/codeql-action from 3 to 4
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3 to 4.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/v3...v4)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-13 02:07:05 +00:00
dependabot[bot]
edb9dcb626 Bump github.com/onsi/ginkgo/v2 from 2.25.3 to 2.26.0
Bumps [github.com/onsi/ginkgo/v2](https://github.com/onsi/ginkgo) from 2.25.3 to 2.26.0.
- [Release notes](https://github.com/onsi/ginkgo/releases)
- [Changelog](https://github.com/onsi/ginkgo/blob/master/CHANGELOG.md)
- [Commits](https://github.com/onsi/ginkgo/compare/v2.25.3...v2.26.0)

---
updated-dependencies:
- dependency-name: github.com/onsi/ginkgo/v2
  dependency-version: 2.26.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-08 12:45:35 +02:00
dependabot[bot]
89559b97af Bump sigs.k8s.io/kind from 0.29.0 to 0.30.0
Bumps [sigs.k8s.io/kind](https://github.com/kubernetes-sigs/kind) from 0.29.0 to 0.30.0.
- [Release notes](https://github.com/kubernetes-sigs/kind/releases)
- [Commits](https://github.com/kubernetes-sigs/kind/compare/v0.29.0...v0.30.0)

---
updated-dependencies:
- dependency-name: sigs.k8s.io/kind
  dependency-version: 0.30.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-06 07:43:26 +02:00
dependabot[bot]
cc1d9ac16d Bump github.com/docker/docker
Bumps [github.com/docker/docker](https://github.com/docker/docker) from 28.4.0+incompatible to 28.5.0+incompatible.
- [Release notes](https://github.com/docker/docker/releases)
- [Commits](https://github.com/docker/docker/compare/v28.4.0...v28.5.0)

---
updated-dependencies:
- dependency-name: github.com/docker/docker
  dependency-version: 28.5.0+incompatible
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-06 07:43:07 +02:00
dependabot[bot]
1d9454c61b Bump google.golang.org/protobuf from 1.36.8 to 1.36.9
Bumps google.golang.org/protobuf from 1.36.8 to 1.36.9.

---
updated-dependencies:
- dependency-name: google.golang.org/protobuf
  dependency-version: 1.36.9
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-05 23:16:31 +02:00
Cellebyte
8409073e7a Release v1.0.1 2025-10-05 22:56:55 +02:00
dependabot[bot]
6d419f32bc Bump anchore/sbom-action from 0.20.5 to 0.20.6
Bumps [anchore/sbom-action](https://github.com/anchore/sbom-action) from 0.20.5 to 0.20.6.
- [Release notes](https://github.com/anchore/sbom-action/releases)
- [Changelog](https://github.com/anchore/sbom-action/blob/main/RELEASE.md)
- [Commits](https://github.com/anchore/sbom-action/compare/v0.20.5...v0.20.6)

---
updated-dependencies:
- dependency-name: anchore/sbom-action
  dependency-version: 0.20.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-05 22:50:14 +02:00
dependabot[bot]
9d68054e9a Bump github.com/spf13/cobra from 1.9.1 to 1.10.1
Bumps [github.com/spf13/cobra](https://github.com/spf13/cobra) from 1.9.1 to 1.10.1.
- [Release notes](https://github.com/spf13/cobra/releases)
- [Commits](https://github.com/spf13/cobra/compare/v1.9.1...v1.10.1)

---
updated-dependencies:
- dependency-name: github.com/spf13/cobra
  dependency-version: 1.10.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-05 22:49:53 +02:00
dependabot[bot]
5dcfb8742f Bump go.etcd.io/etcd/client/v3 from 3.6.4 to 3.6.5
Bumps [go.etcd.io/etcd/client/v3](https://github.com/etcd-io/etcd) from 3.6.4 to 3.6.5.
- [Release notes](https://github.com/etcd-io/etcd/releases)
- [Commits](https://github.com/etcd-io/etcd/compare/v3.6.4...v3.6.5)

---
updated-dependencies:
- dependency-name: go.etcd.io/etcd/client/v3
  dependency-version: 3.6.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-05 22:49:00 +02:00
dependabot[bot]
7e6f70b027 Bump github.com/gookit/slog from 0.5.8 to 0.6.0
Bumps [github.com/gookit/slog](https://github.com/gookit/slog) from 0.5.8 to 0.6.0.
- [Release notes](https://github.com/gookit/slog/releases)
- [Commits](https://github.com/gookit/slog/compare/v0.5.8...v0.6.0)

---
updated-dependencies:
- dependency-name: github.com/gookit/slog
  dependency-version: 0.6.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-05 22:48:47 +02:00
dependabot[bot]
3e10aa85d0 Bump google.golang.org/grpc from 1.75.0 to 1.75.1
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.75.0 to 1.75.1.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.75.0...v1.75.1)

---
updated-dependencies:
- dependency-name: google.golang.org/grpc
  dependency-version: 1.75.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-05 22:48:25 +02:00
Marcel Fest
16b9f6767e refactored BGP configs, kubevip pkg and more.
* Moved functions from mod pkg vip to pkg utils
* remove the dependency of the kubevip config pkg on the bgp pkg
* introduce BGPConfig and BGPPeer to kubevip package and migrate label from node labeler
* Use the new BGPConfig and BGPPeer type of the kubevip pkg
* Removed utils functions from vip pkg and refactor to call utils instead
* migrate from pkg vip to utils for generic IP funcs
* migrate common annotations and labels into a central place + support for hostnames
* if any change happens we want to reconcile it here
* fix e2e tests which relied also on the vip package instead of utils
* Better debug logging
* Added info if it is egress
* added missing condition to dhcp specific actions
* Disable the service before cancelling the context
* lets try auto,auto instead of /32 and nothing
* Let's reset svcCtx to be nil to ensure a new context when the previous was garbage collected
* Added a space for project wide constants
---------

Signed-off-by: Cellebyte <marcel.fest@live.de>
2025-10-05 22:47:21 +02:00
Alex Krasnov
d8a9727ff5 extend existing e2e tests with node labeling switch (disabled as is)
Signed-off-by: Alex Krasnov <askrasnov@gmail.com>
2025-09-19 12:20:08 +02:00
Alex Krasnov
016a899e60 refactor to interface and separate NoOP node labeler implementation
Signed-off-by: Alex Krasnov <askrasnov@gmail.com>
2025-09-19 12:20:08 +02:00
Alex Krasnov
68b39a83e0 skip node labeling when control-plane mode enabled
Signed-off-by: Alex Krasnov <askrasnov@gmail.com>
2025-09-19 12:20:08 +02:00
Alex Krasnov
93dabff000 fix case with nil clientset (eg, with etcd leader election)
Signed-off-by: Alex Krasnov <askrasnov@gmail.com>
2025-09-19 12:20:08 +02:00
Alex Krasnov
630be48010 add node labels for services
Signed-off-by: Alex Krasnov <askrasnov@gmail.com>
2025-09-19 12:20:08 +02:00
Cellebyte
ea78d291ce use slices.Compact correctly
Signed-off-by: Cellebyte <marcel.fest@live.de>
2025-09-18 17:41:57 +02:00
Cellebyte
2074be2939 use the new vip.LookupHost for manifest creation
Signed-off-by: Cellebyte <marcel.fest@live.de>
2025-09-18 17:41:57 +02:00
dependabot[bot]
7946c17c00 Bump github.com/docker/docker
Bumps [github.com/docker/docker](https://github.com/docker/docker) from 28.3.3+incompatible to 28.4.0+incompatible.
- [Release notes](https://github.com/docker/docker/releases)
- [Commits](https://github.com/docker/docker/compare/v28.3.3...v28.4.0)

---
updated-dependencies:
- dependency-name: github.com/docker/docker
  dependency-version: 28.4.0+incompatible
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-15 18:21:12 +02:00
dependabot[bot]
a0295d6a2f Bump golang.org/x/sync from 0.16.0 to 0.17.0
Bumps [golang.org/x/sync](https://github.com/golang/sync) from 0.16.0 to 0.17.0.
- [Commits](https://github.com/golang/sync/compare/v0.16.0...v0.17.0)

---
updated-dependencies:
- dependency-name: golang.org/x/sync
  dependency-version: 0.17.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-15 18:20:47 +02:00
dependabot[bot]
d70068b1a0 Bump github.com/onsi/ginkgo/v2 from 2.23.4 to 2.25.3
Bumps [github.com/onsi/ginkgo/v2](https://github.com/onsi/ginkgo) from 2.23.4 to 2.25.3.
- [Release notes](https://github.com/onsi/ginkgo/releases)
- [Changelog](https://github.com/onsi/ginkgo/blob/master/CHANGELOG.md)
- [Commits](https://github.com/onsi/ginkgo/compare/v2.23.4...v2.25.3)

---
updated-dependencies:
- dependency-name: github.com/onsi/ginkgo/v2
  dependency-version: 2.25.3
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-15 18:20:30 +02:00
dependabot[bot]
89baba07f5 Bump k8s.io/client-go from 0.33.3 to 0.34.1
Bumps [k8s.io/client-go](https://github.com/kubernetes/client-go) from 0.33.3 to 0.34.1.
- [Changelog](https://github.com/kubernetes/client-go/blob/master/CHANGELOG.md)
- [Commits](https://github.com/kubernetes/client-go/compare/v0.33.3...v0.34.1)

---
updated-dependencies:
- dependency-name: k8s.io/client-go
  dependency-version: 0.34.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-15 18:20:14 +02:00
Patryk Strusiewicz-Surmacki
95995500bc Added common lease for multiple services for all modes and service election for BGP
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
2025-09-15 18:19:50 +02:00
Thorsten Bonhagen
b1183e8a93 fix unit test error
Signed-off-by: Thorsten Bonhagen <Thorsten.Bonhagen@tbon.de>
2025-09-15 15:16:03 +02:00
Thorsten Bonhagen
101f722110 rebase
Signed-off-by: Thorsten Bonhagen <Thorsten.Bonhagen@tbon.de>
2025-09-15 15:16:03 +02:00
Thorsten Bonhagen
3f390120c1 remove condition for adding IP in service
orig was not working and inverse condition might not work for all

Signed-off-by: Thorsten Bonhagen <Thorsten.Bonhagen@tbon.de>
2025-09-15 15:16:03 +02:00
Thorsten Bonhagen
7baa8a3141 reformat with go fmt
Signed-off-by: Thorsten Bonhagen <Thorsten.Bonhagen@tbon.de>
2025-09-15 15:16:03 +02:00
Thorsten Bonhagen
6435581674 fix cp and svc not running on same instance
fix table addIP missing
add more debug lines
start service listener before content plane because content plane is blocking main thread

Signed-off-by: Thorsten Bonhagen <Thorsten.Bonhagen@tbon.de>
2025-09-15 15:16:03 +02:00
dependabot[bot]
7eb730c0ef Bump github.com/prometheus/client_golang from 1.22.0 to 1.23.2
Bumps [github.com/prometheus/client_golang](https://github.com/prometheus/client_golang) from 1.22.0 to 1.23.2.
- [Release notes](https://github.com/prometheus/client_golang/releases)
- [Changelog](https://github.com/prometheus/client_golang/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prometheus/client_golang/compare/v1.22.0...v1.23.2)

---
updated-dependencies:
- dependency-name: github.com/prometheus/client_golang
  dependency-version: 1.23.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-11 23:25:41 +02:00
dependabot[bot]
f6a7aeb130 Bump docker/metadata-action from 5.7.0 to 5.8.0
Bumps [docker/metadata-action](https://github.com/docker/metadata-action) from 5.7.0 to 5.8.0.
- [Release notes](https://github.com/docker/metadata-action/releases)
- [Commits](https://github.com/docker/metadata-action/compare/v5.7.0...v5.8.0)

---
updated-dependencies:
- dependency-name: docker/metadata-action
  dependency-version: 5.8.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-11 23:25:32 +02:00
dependabot[bot]
29296a9dc2 Bump actions/setup-go from 5 to 6
Bumps [actions/setup-go](https://github.com/actions/setup-go) from 5 to 6.
- [Release notes](https://github.com/actions/setup-go/releases)
- [Commits](https://github.com/actions/setup-go/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/setup-go
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-11 22:56:33 +02:00
dependabot[bot]
4d4a2f0ee1 Bump golang.org/x/sys from 0.33.0 to 0.36.0
Bumps [golang.org/x/sys](https://github.com/golang/sys) from 0.33.0 to 0.36.0.
- [Commits](https://github.com/golang/sys/compare/v0.33.0...v0.36.0)

---
updated-dependencies:
- dependency-name: golang.org/x/sys
  dependency-version: 0.36.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-11 22:56:08 +02:00
dependabot[bot]
e4e398bfcf Bump golang from 1.24.6-alpine3.22 to 1.25.1-alpine3.22
Bumps golang from 1.24.6-alpine3.22 to 1.25.1-alpine3.22.

---
updated-dependencies:
- dependency-name: golang
  dependency-version: 1.25.1-alpine3.22
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-11 22:55:33 +02:00
dependabot[bot]
8bd2c26a8f Bump actions/checkout from 4 to 5
Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 5.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-11 22:54:59 +02:00
dependabot[bot]
bd8f30d67d Bump google.golang.org/grpc from 1.73.0 to 1.75.0
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.73.0 to 1.75.0.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.73.0...v1.75.0)

---
updated-dependencies:
- dependency-name: google.golang.org/grpc
  dependency-version: 1.75.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-11 22:54:30 +02:00
dependabot[bot]
a3a429b2b9 Bump anchore/sbom-action from 0.20.4 to 0.20.5
Bumps [anchore/sbom-action](https://github.com/anchore/sbom-action) from 0.20.4 to 0.20.5.
- [Release notes](https://github.com/anchore/sbom-action/releases)
- [Changelog](https://github.com/anchore/sbom-action/blob/main/RELEASE.md)
- [Commits](https://github.com/anchore/sbom-action/compare/v0.20.4...v0.20.5)

---
updated-dependencies:
- dependency-name: anchore/sbom-action
  dependency-version: 0.20.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-11 22:54:16 +02:00
dependabot[bot]
4f7ce8a1c8 Bump go.etcd.io/etcd/client/v3 from 3.6.1 to 3.6.4
Bumps [go.etcd.io/etcd/client/v3](https://github.com/etcd-io/etcd) from 3.6.1 to 3.6.4.
- [Release notes](https://github.com/etcd-io/etcd/releases)
- [Commits](https://github.com/etcd-io/etcd/compare/v3.6.1...v3.6.4)

---
updated-dependencies:
- dependency-name: go.etcd.io/etcd/client/v3
  dependency-version: 3.6.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-11 22:54:01 +02:00
Cellebyte
d2ecf22edd fix images in the kind clusters when manifest is used
Signed-off-by: Cellebyte <marcel.fest@live.de>
2025-09-04 18:54:57 +02:00
Abhishek Pareek
3963172e49 rename var to conform to standards
Signed-off-by: Abhishek Pareek <makeittotop@users.noreply.github.com>
Signed-off-by: Cellebyte <marcel.fest@live.de>
2025-09-04 18:54:57 +02:00
Abhishek Pareek
80c6b0bde4 substitute local image into the ds
Signed-off-by: Abhishek Pareek <makeittotop@users.noreply.github.com>
Signed-off-by: Cellebyte <marcel.fest@live.de>
2025-09-04 18:54:57 +02:00
Abhishek Pareek
4f59df38f3 use a lease Identifier to uniquely identify a svc lease
Signed-off-by: Abhishek Pareek <makeittotop@users.noreply.github.com>
Signed-off-by: Cellebyte <marcel.fest@live.de>
2025-09-04 18:54:57 +02:00
Abhishek Pareek
1a3e6c9d5f uniquely identify a service lease combining namespace + service name
Signed-off-by: Abhishek Pareek <makeittotop@users.noreply.github.com>
Signed-off-by: Cellebyte <marcel.fest@live.de>
2025-09-04 18:54:57 +02:00
Cellebyte
0635ec9e01 Fix linting issues 2025-09-03 22:03:51 +02:00
Yuval Weisz
3fff60a64a fix: Update file permissions in tests to 0600 for security compliance
- Change os.WriteFile permissions from 0644 to 0600 in config_file_test.go
- Addresses GoSec G306 linter requirement for secure file permissions
- Ensures test files are readable/writable by owner only

Signed-off-by: Yuval Weisz <yuval.weisz@vastdata.com>
2025-09-03 15:54:17 +02:00
Yuval Weisz
f05f0469cc test: Add comprehensive tests for configuration file functionality
This commit adds extensive unit tests for the new configuration file features:

Test Coverage:
- LoadConfigFromFile() function with YAML and JSON parsing
- MergeConfigFromFile() function with priority logic testing
- Configuration merging with complex nested structures (BGP, leader election)
- Error handling for invalid files, unsupported formats, and missing files
- Environment variable integration for config_file
- Priority validation: CLI flags > env vars > config file
- Boolean flag merging behavior
- BGP configuration merging
- Leader election configuration merging

Files:
- pkg/kubevip/config_file_test.go: New comprehensive test suite (550+ lines)
- pkg/kubevip/config_generator_test.go: Enhanced with config_file env var tests

Test Structure:
- TestLoadConfigFromFile: Tests JSON/YAML parsing and error cases
- TestMergeConfigFromFile: Tests configuration priority and merging
- TestMergeConfigValues: Tests detailed field-by-field merging logic
- TestParseEnvironmentConfigFile: Tests config_file environment variable

The tests validate all aspects of the configuration file implementation
including edge cases, error scenarios, and complex configuration structures.
All tests follow Go testing best practices with table-driven test patterns.

Signed-off-by: Yuval Weisz <yuval.weisz@vastdata.com>
2025-09-03 15:54:17 +02:00
Yuval Weisz
00337a756b feat: Add --config-file flag and config_file environment variable
This commit implements configuration file support for kube-vip, allowing
users to specify configuration through JSON or YAML files.

Features:
- Added --config-file command line flag that accepts JSON/YAML file paths
- Added config_file environment variable support
- Implemented proper configuration priority: CLI flags > env vars > config file
- Added comprehensive configuration merging for all fields including BGP,
  leader election, routing table, and load balancer settings
- Supports both JSON and YAML file formats with automatic detection
- Maintains full backward compatibility with existing deployments

Changes:
- pkg/kubevip/config_envvar.go: Added configFile constant
- pkg/kubevip/config_types.go: Added ConfigFile field to Config struct
- pkg/kubevip/config_environment.go: Added LoadConfigFromFile() and
  MergeConfigFromFile() functions with comprehensive merging logic
- cmd/kube-vip.go: Integrated config file loading into service and manager commands

Usage:
  kube-vip manager --config-file /etc/kube-vip/config.yaml
  export config_file=/etc/kube-vip/config.json && kube-vip manager

This enhancement significantly improves configuration management for complex
kube-vip deployments while maintaining the existing behavior and patterns.

Signed-off-by: Yuval Weisz <yuval.weisz@vastdata.com>
2025-09-03 15:54:17 +02:00
Thorsten Bonhagen
d3473b5d68 change startup order of ControlPlane and Services
Fix: ControlPlane was blocking main thread so Services could not start in parallel
Signed-off-by: Thorsten Bonhagen <thbo@uhurutec.com>
2025-09-03 15:53:58 +02:00
Patryk Strusiewicz-Surmacki
889d442288 Fixed nil pointer reference when endpoints serving condition is not set
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
2025-09-03 15:53:30 +02:00
Daniel Finneran
b2c04c9058 Merge pull request #1240 from hensur/check-snat-error
check conn.Flush error in nftables SNAT
2025-09-01 15:20:38 +01:00
Mark Riedel
0889ebed7d Fix deletion of ConfiguredNetworks entry after deleting BGP host
Signed-off-by: Mark Riedel <5668435+rmarkdev@users.noreply.github.com>
2025-08-25 17:04:10 +02:00
Henning Surmeier
d1430e79e2 check conn.Flush error in nftables SNAT
Signed-off-by: Henning Surmeier <h.surmeier@mittwald.de>
2025-08-18 14:28:03 +02:00
Patryk Strusiewicz-Surmacki
31eca367ab Added logs as CI artifact
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
2025-08-15 07:50:51 +02:00
Dan Finneran
bdd353d0fd Unintentionally created duplicate functions that can't be used
Signed-off-by: Dan Finneran <dan@thebsdbox.co.uk>
2025-08-14 09:55:16 +02:00
dependabot[bot]
4deb0592f6 Bump golang from 1.24.5-alpine3.22 to 1.24.6-alpine3.22
Bumps golang from 1.24.5-alpine3.22 to 1.24.6-alpine3.22.

---
updated-dependencies:
- dependency-name: golang
  dependency-version: 1.24.6-alpine3.22
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-14 09:54:24 +02:00
Daniel Finneran
d8877072d4 Merge pull request #1219 from kube-vip/v1-release
Version ONE DOT ZERO
2025-07-31 16:42:23 +01:00
Dan Finneran
89a8dc7de1 default setting to 0
Signed-off-by: Dan Finneran <dan@thebsdbox.co.uk>
2025-07-31 16:09:10 +02:00
Dan Finneran
704c346f5e naming convention lint fix
Signed-off-by: Dan Finneran <dan@thebsdbox.co.uk>
2025-07-31 16:09:10 +02:00
Dan Finneran
65061c5cd9 Adds an annotation to set the return path filter for a macvlan nic
Signed-off-by: Dan Finneran <dan@thebsdbox.co.uk>
2025-07-31 16:09:10 +02:00
Daniel Finneran
32233918b4 Version ONE DOT ZERO 2025-07-31 12:34:37 +01:00
Daniel Finneran
76169da60f Merge pull request #1216 from kube-vip/dependabot/go_modules/github.com/docker/docker-28.3.3incompatible
Bump github.com/docker/docker from 28.3.0+incompatible to 28.3.3+incompatible
2025-07-31 12:33:44 +01:00
Daniel Finneran
9bcf1413f0 Merge pull request #1211 from kube-vip/dependabot/github_actions/anchore/sbom-action-0.20.4
Bump anchore/sbom-action from 0.20.1 to 0.20.4
2025-07-31 12:33:28 +01:00
Daniel Finneran
8e428e875f Merge pull request #1203 from kube-vip/dependabot/docker/alpine-3.22.1
Bump alpine from 3.22.0 to 3.22.1
2025-07-31 12:33:14 +01:00
dependabot[bot]
2fbecc25e5 Bump alpine from 3.22.0 to 3.22.1
Bumps alpine from 3.22.0 to 3.22.1.

---
updated-dependencies:
- dependency-name: alpine
  dependency-version: 3.22.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-30 15:17:21 +00:00
Daniel Finneran
02e77271d0 Merge pull request #1202 from kube-vip/dependabot/docker/golang-1.24.5-alpine3.22 2025-07-30 16:16:18 +01:00
Daniel Finneran
3d61888e58 Merge pull request #1192 from kube-vip/dependabot/go_modules/sigs.k8s.io/kind-0.29.0 2025-07-30 16:15:52 +01:00
dependabot[bot]
efe75f491b Bump sigs.k8s.io/kind from 0.27.0 to 0.29.0
Bumps [sigs.k8s.io/kind](https://github.com/kubernetes-sigs/kind) from 0.27.0 to 0.29.0.
- [Release notes](https://github.com/kubernetes-sigs/kind/releases)
- [Commits](https://github.com/kubernetes-sigs/kind/compare/v0.27.0...v0.29.0)

---
updated-dependencies:
- dependency-name: sigs.k8s.io/kind
  dependency-version: 0.29.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-30 13:55:46 +00:00
Daniel Finneran
000c139004 Merge pull request #1194 from kube-vip/dependabot/go_modules/github.com/vishvananda/netlink-1.3.1 2025-07-30 14:50:38 +01:00
Daniel Finneran
c39b84f0a9 Merge pull request #1193 from kube-vip/dependabot/go_modules/github.com/osrg/gobgp/v3-3.37.0 2025-07-30 14:50:25 +01:00
dependabot[bot]
ee958addaa Bump github.com/docker/docker
Bumps [github.com/docker/docker](https://github.com/docker/docker) from 28.3.0+incompatible to 28.3.3+incompatible.
- [Release notes](https://github.com/docker/docker/releases)
- [Commits](https://github.com/docker/docker/compare/v28.3.0...v28.3.3)

---
updated-dependencies:
- dependency-name: github.com/docker/docker
  dependency-version: 28.3.3+incompatible
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-30 13:48:44 +00:00
Daniel Finneran
8fe53351f8 Merge pull request #1215 from kube-vip/endpointslice 2025-07-30 14:47:26 +01:00
Daniel Finneran
bc9d860d83 Merge pull request #1213 from kube-vip/egress_internal 2025-07-30 14:47:07 +01:00
Dan Finneran
332a23e543 Bump k8s api and endpointslices as default
Signed-off-by: Dan Finneran <dan@thebsdbox.co.uk>
2025-07-29 13:36:32 +00:00
Dan Finneran
b20713b50f linting issue with port out of bounds.
Signed-off-by: Dan Finneran <dan@thebsdbox.co.uk>
2025-07-28 16:18:47 +00:00
Dan Finneran
94e96581ef typo and add SCTP
Signed-off-by: Dan Finneran <dan@thebsdbox.co.uk>
2025-07-28 16:13:20 +00:00
Dan Finneran
61be6d0b6a fighting with merge conflicts
Signed-off-by: Dan Finneran <dan@thebsdbox.co.uk>
2025-07-28 16:08:53 +00:00
Dan Finneran
be22805a7d sigh
Signed-off-by: Dan Finneran <dan@thebsdbox.co.uk>
2025-07-28 16:08:22 +00:00
Dan Finneran
25f6253286 Adds the internal egress functionality
Signed-off-by: Dan Finneran <dan@thebsdbox.co.uk>
2025-07-28 16:01:00 +00:00
dependabot[bot]
f3e9fb6ea9 Bump github.com/osrg/gobgp/v3 from 3.36.0 to 3.37.0
Bumps [github.com/osrg/gobgp/v3](https://github.com/osrg/gobgp) from 3.36.0 to 3.37.0.
- [Release notes](https://github.com/osrg/gobgp/releases)
- [Changelog](https://github.com/osrg/gobgp/blob/master/.goreleaser.yml)
- [Commits](https://github.com/osrg/gobgp/compare/v3.36.0...v3.37.0)

---
updated-dependencies:
- dependency-name: github.com/osrg/gobgp/v3
  dependency-version: 3.37.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-28 15:17:29 +00:00
Patryk Strusiewicz-Surmacki
0f3dda02c4 Refactoring services-watcher code
Co-authored-by: Cellebyte <marcel.fest@live.de>
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk-pawel.strusiewicz-surmacki@external.telekom.de>
2025-07-28 17:14:09 +02:00
Dan Finneran
a2873b5465 Adds the internal egress functionality
Signed-off-by: Dan Finneran <dan@thebsdbox.co.uk>
2025-07-28 13:57:50 +00:00
dependabot[bot]
202d45e5ab Bump anchore/sbom-action from 0.20.1 to 0.20.4
Bumps [anchore/sbom-action](https://github.com/anchore/sbom-action) from 0.20.1 to 0.20.4.
- [Release notes](https://github.com/anchore/sbom-action/releases)
- [Changelog](https://github.com/anchore/sbom-action/blob/main/RELEASE.md)
- [Commits](https://github.com/anchore/sbom-action/compare/v0.20.1...v0.20.4)

---
updated-dependencies:
- dependency-name: anchore/sbom-action
  dependency-version: 0.20.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-28 03:11:16 +00:00
Daniel Finneran
f5e4612c03 Merge pull request #1210 from kube-vip/fix/ci 2025-07-27 22:14:39 +01:00
Cellebyte
de888c501c split ci into two files
Signed-off-by: Cellebyte <marcel.fest@live.de>
2025-07-27 23:02:09 +02:00
Cellebyte
47bc83c248 Don't execute the e2e-tests in parallel
Signed-off-by: Cellebyte <marcel.fest@live.de>
2025-07-27 23:02:09 +02:00
Patryk Strusiewicz-Surmacki
1cf637c569 Moved endpoint-related code from pkg/manager to pkg/endpoints
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk-pawel.strusiewicz-surmacki@external.telekom.de>
2025-07-24 08:07:23 +02:00
Patryk Strusiewicz-Surmacki
ae2571e241 Refactoring endpoint-watcher code
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk-pawel.strusiewicz-surmacki@external.telekom.de>
2025-07-24 08:07:23 +02:00
Patryk Strusiewicz-Surmacki
86f5e9b8b2 Removed insecure client use in E2E tests
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
2025-07-24 08:07:00 +02:00
Patryk Strusiewicz-Surmacki
ce61ff085a Use insecure client only in E2E tests
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
2025-07-21 17:54:12 +02:00
dependabot[bot]
b816e154cf Bump golang from 1.24.4-alpine3.22 to 1.24.5-alpine3.22
Bumps golang from 1.24.4-alpine3.22 to 1.24.5-alpine3.22.

---
updated-dependencies:
- dependency-name: golang
  dependency-version: 1.24.5-alpine3.22
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-14 03:15:14 +00:00
Patryk Strusiewicz-Surmacki
ac1238c337 Rebase
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
2025-07-10 17:50:15 +02:00
Patryk Strusiewicz-Surmacki
10dbf2c0ef Refactoring endpoint-watcher code
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk-pawel.strusiewicz-surmacki@external.telekom.de>
2025-07-10 17:50:15 +02:00
Jan-Philipp Litza
cf68f8639c Add VIPs as deprecated
This causes IPv6 source address selection according to RFC 3484 to
ignore VIPs when choosing which address the host should use for egress
communication.

Signed-off-by: Jan-Philipp Litza <janphilipp@litza.de>
2025-07-09 10:54:28 +02:00
Daniel Finneran
b114c11b0f Merge pull request #1191 from kube-vip/thebsdbox-patch-1
Update README.md
2025-07-03 09:59:49 +01:00
Patryk Strusiewicz-Surmacki
42b7a8152b Basic e2e tests for BGP mode
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
2025-07-01 12:36:33 +02:00
mushrushu
f7821c7fb3 fixed vars formatting & log statement
Signed-off-by: mushrushu <mushrushu@outlook.com>
2025-07-01 12:34:43 +02:00
mushrushu
42478905d0 added zebra integration and its configuration
Signed-off-by: mushrushu <mushrushu@outlook.com>
2025-07-01 12:34:43 +02:00
dependabot[bot]
8d55bd3b63 Bump github.com/vishvananda/netlink from 1.3.0 to 1.3.1
Bumps [github.com/vishvananda/netlink](https://github.com/vishvananda/netlink) from 1.3.0 to 1.3.1.
- [Release notes](https://github.com/vishvananda/netlink/releases)
- [Commits](https://github.com/vishvananda/netlink/compare/v1.3.0...v1.3.1)

---
updated-dependencies:
- dependency-name: github.com/vishvananda/netlink
  dependency-version: 1.3.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-30 03:20:14 +00:00
Daniel Finneran
16247fc3a3 Update README.md
Adds health of project badges! (looking healthy) 😄
2025-06-27 14:20:14 +01:00
Marcel Fest
b56b80cd30 Bump version to v0.9.2
Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
2025-06-24 19:02:31 +02:00
dependabot[bot]
ba25e0e583 Bump github.com/prometheus/client_golang from 1.21.0 to 1.22.0
Bumps [github.com/prometheus/client_golang](https://github.com/prometheus/client_golang) from 1.21.0 to 1.22.0.
- [Release notes](https://github.com/prometheus/client_golang/releases)
- [Changelog](https://github.com/prometheus/client_golang/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prometheus/client_golang/compare/v1.21.0...v1.22.0)

---
updated-dependencies:
- dependency-name: github.com/prometheus/client_golang
  dependency-version: 1.22.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-24 18:59:16 +02:00
dependabot[bot]
8f1fe355fc Bump github.com/onsi/gomega from 1.36.2 to 1.37.0
Bumps [github.com/onsi/gomega](https://github.com/onsi/gomega) from 1.36.2 to 1.37.0.
- [Release notes](https://github.com/onsi/gomega/releases)
- [Changelog](https://github.com/onsi/gomega/blob/master/CHANGELOG.md)
- [Commits](https://github.com/onsi/gomega/compare/v1.36.2...v1.37.0)

---
updated-dependencies:
- dependency-name: github.com/onsi/gomega
  dependency-version: 1.37.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-24 16:29:41 +02:00
dependabot[bot]
649d9bf0ef Bump golang.org/x/sys from 0.32.0 to 0.33.0
Bumps [golang.org/x/sys](https://github.com/golang/sys) from 0.32.0 to 0.33.0.
- [Commits](https://github.com/golang/sys/compare/v0.32.0...v0.33.0)

---
updated-dependencies:
- dependency-name: golang.org/x/sys
  dependency-version: 0.33.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-23 09:20:35 +02:00
dependabot[bot]
a5108a69aa Bump anchore/sbom-action from 0.19.0 to 0.20.1
Bumps [anchore/sbom-action](https://github.com/anchore/sbom-action) from 0.19.0 to 0.20.1.
- [Release notes](https://github.com/anchore/sbom-action/releases)
- [Changelog](https://github.com/anchore/sbom-action/blob/main/RELEASE.md)
- [Commits](https://github.com/anchore/sbom-action/compare/v0.19.0...v0.20.1)

---
updated-dependencies:
- dependency-name: anchore/sbom-action
  dependency-version: 0.20.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-20 17:53:00 +02:00
dependabot[bot]
c74a496299 Bump go.etcd.io/etcd/client/v3 from 3.5.18 to 3.6.1
Bumps [go.etcd.io/etcd/client/v3](https://github.com/etcd-io/etcd) from 3.5.18 to 3.6.1.
- [Release notes](https://github.com/etcd-io/etcd/releases)
- [Commits](https://github.com/etcd-io/etcd/compare/v3.5.18...v3.6.1)

---
updated-dependencies:
- dependency-name: go.etcd.io/etcd/client/v3
  dependency-version: 3.6.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-17 12:06:43 +02:00
dependabot[bot]
b74c274466 Bump alpine from 3.21.3 to 3.22.0
Bumps alpine from 3.21.3 to 3.22.0.

---
updated-dependencies:
- dependency-name: alpine
  dependency-version: 3.22.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-17 11:57:04 +02:00
Dan Finneran
56b3867e57 typo fix 2025-06-17 11:56:43 +02:00
Dan Finneran
66d237bfbc adds kernel module check for nftables 2025-06-17 11:56:43 +02:00
Patryk Strusiewicz-Surmacki
68071b214e Fixed BGP clear deadlock
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
2025-06-17 11:55:49 +02:00
Patryk Strusiewicz-Surmacki
a82ca5576b Updated go version to 1.24.4
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
2025-06-17 09:53:57 +02:00
Patryk Strusiewicz-Surmacki
81dd386b4e Fixed service-tests
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
Co-authored-by: Marcel Fest <marcel@fest4.eu>
2025-06-10 22:26:02 +02:00
Patryk Strusiewicz-Surmacki
b61a74396d Moved configuredRoutes map to serviceContext struct
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
2025-06-10 22:26:02 +02:00
Daniel Finneran
105fbc522a Merge pull request #1163 from p-strusiewiczsurmacki-mobica/rt-tests
Added ARP/NDP services tests and Routing Table services tests
2025-06-10 11:34:15 -07:00
Dan Finneran
2b52c39242 Small change to reduce pointless errors 2025-06-10 13:31:06 +02:00
Patryk Strusiewicz-Surmacki
25d39bca09 Added TODO for insecure discovery client
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
2025-06-06 16:18:38 +02:00
Marcel Fest
644226321e fix typo
Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
2025-06-05 17:26:55 +02:00
Marcel Fest
3928dda541 move lock for cleanRoutes feature at start of kube-vip
Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
2025-06-05 17:26:55 +02:00
Patryk Strusiewicz-Surmacki
d9a7f413a6 Moved code to use sync.Maps
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
2025-06-05 17:26:55 +02:00
Patryk Strusiewicz-Surmacki
eb300bb634 Fixed deadlock
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
2025-06-05 17:26:55 +02:00
Marcel Fest
c30fd9e7be fix tests + refactor func
Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
2025-06-05 17:26:55 +02:00
Marcel Fest
2fc969b848 Move the check into the function
Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
2025-06-05 17:26:55 +02:00
Marcel Fest
47884088ec remove AI code
Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
2025-06-05 17:26:55 +02:00
Marcel Fest
70e1212396 remove redundant condition
Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
2025-06-05 17:26:55 +02:00
Marcel Fest
d947c2abcc refactor syncServices to be lockable at all
Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
2025-06-05 17:26:55 +02:00
Marcel Fest
e2efb64aea Use the mutext in callbacks as well
Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
2025-06-05 17:26:55 +02:00
Marcel Fest
01279d45e3 Added function to create ip array from statu LB ingress field
Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
2025-06-05 17:26:55 +02:00
Patryk Strusiewicz-Surmacki
f2a7cad218 Added ARP/NDP services tests and Routing Table services tests
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
2025-05-23 11:59:14 +02:00
Nathan Przybyszewski
98163341d3 Replace invalid verb "endpoints" with "update"
Signed-off-by: Nathan Przybyszewski <172687074+nprzy@users.noreply.github.com>
2025-05-01 10:28:43 +02:00
Marcel Fest
a71d361d15 Bump version
Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
2025-04-28 16:33:49 +02:00
dependabot[bot]
cf24ad835d Bump github.com/onsi/ginkgo/v2 from 2.22.2 to 2.23.4
Bumps [github.com/onsi/ginkgo/v2](https://github.com/onsi/ginkgo) from 2.22.2 to 2.23.4.
- [Release notes](https://github.com/onsi/ginkgo/releases)
- [Changelog](https://github.com/onsi/ginkgo/blob/master/CHANGELOG.md)
- [Commits](https://github.com/onsi/ginkgo/compare/v2.22.2...v2.23.4)

---
updated-dependencies:
- dependency-name: github.com/onsi/ginkgo/v2
  dependency-version: 2.23.4
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-28 14:21:36 +02:00
dependabot[bot]
0c04088b16 Bump github.com/cloudflare/ipvs from 0.10.3 to 0.11.0
Bumps [github.com/cloudflare/ipvs](https://github.com/cloudflare/ipvs) from 0.10.3 to 0.11.0.
- [Release notes](https://github.com/cloudflare/ipvs/releases)
- [Commits](https://github.com/cloudflare/ipvs/compare/v0.10.3...v0.11.0)

---
updated-dependencies:
- dependency-name: github.com/cloudflare/ipvs
  dependency-version: 0.11.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-28 14:07:42 +02:00
dependabot[bot]
22489ad095 Bump golang.org/x/sys from 0.31.0 to 0.32.0
Bumps [golang.org/x/sys](https://github.com/golang/sys) from 0.31.0 to 0.32.0.
- [Commits](https://github.com/golang/sys/compare/v0.31.0...v0.32.0)

---
updated-dependencies:
- dependency-name: golang.org/x/sys
  dependency-version: 0.32.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-28 14:07:29 +02:00
dependabot[bot]
1fa3da45fa Bump github.com/gookit/slog from 0.5.7 to 0.5.8
Bumps [github.com/gookit/slog](https://github.com/gookit/slog) from 0.5.7 to 0.5.8.
- [Release notes](https://github.com/gookit/slog/releases)
- [Commits](https://github.com/gookit/slog/compare/v0.5.7...v0.5.8)

---
updated-dependencies:
- dependency-name: github.com/gookit/slog
  dependency-version: 0.5.8
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-28 14:07:18 +02:00
Patryk Strusiewicz-Surmacki
d497df3767 Fixed instance finding and route deletion in RT mode
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
2025-04-28 14:06:20 +02:00
dependabot[bot]
bdd3c5c191 Bump anchore/sbom-action from 0.18.0 to 0.19.0
Bumps [anchore/sbom-action](https://github.com/anchore/sbom-action) from 0.18.0 to 0.19.0.
- [Release notes](https://github.com/anchore/sbom-action/releases)
- [Changelog](https://github.com/anchore/sbom-action/blob/main/RELEASE.md)
- [Commits](https://github.com/anchore/sbom-action/compare/v0.18.0...v0.19.0)

---
updated-dependencies:
- dependency-name: anchore/sbom-action
  dependency-version: 0.19.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-28 07:17:13 +02:00
Shawn Wilsher
5b41db2246 feat: Add opencontainers annotations during release
This change relies on `docker/metadata-action` to generate the
appropriate labels.

Fixes #1044

Signed-off-by: Shawn Wilsher <656602+sdwilsh@users.noreply.github.com>
2025-04-27 21:52:29 +02:00
Shawn Wilsher
1eb35774a5 fix: s/endoints/endpoints/ in RBAC manifest generation code
While moving over to using the RBAC manifest generator, this stood out as a clear typo.

Signed-off-by: Shawn Wilsher <me@shawnwilsher.com>
2025-04-27 09:27:12 +02:00
Daniel Finneran
7d7036fae9 Merge pull request #1130 from kube-vip/fix/upnp
fix #1127 as we have a nil deref if router does not support IPv6
2025-04-15 17:15:23 +01:00
Marcel Fest
1a4bf13819 fix #1127 as we have a nil deref if router does not support IPv6
Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
2025-04-14 23:20:29 +02:00
dependabot[bot]
3e225bf51f Bump go.etcd.io/etcd/api/v3 from 3.5.18 to 3.5.21
Bumps [go.etcd.io/etcd/api/v3](https://github.com/etcd-io/etcd) from 3.5.18 to 3.5.21.
- [Release notes](https://github.com/etcd-io/etcd/releases)
- [Commits](https://github.com/etcd-io/etcd/compare/v3.5.18...v3.5.21)

---
updated-dependencies:
- dependency-name: go.etcd.io/etcd/api/v3
  dependency-version: 3.5.21
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-14 23:16:09 +02:00
dependabot[bot]
d6837cbe7d Bump github.com/osrg/gobgp/v3 from 3.35.0 to 3.36.0
Bumps [github.com/osrg/gobgp/v3](https://github.com/osrg/gobgp) from 3.35.0 to 3.36.0.
- [Release notes](https://github.com/osrg/gobgp/releases)
- [Changelog](https://github.com/osrg/gobgp/blob/master/.goreleaser.yml)
- [Commits](https://github.com/osrg/gobgp/compare/v3.35.0...v3.36.0)

---
updated-dependencies:
- dependency-name: github.com/osrg/gobgp/v3
  dependency-version: 3.36.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-14 22:56:35 +02:00
dependabot[bot]
40994e0464 Bump go.etcd.io/etcd/client/pkg/v3 from 3.5.18 to 3.5.21
Bumps [go.etcd.io/etcd/client/pkg/v3](https://github.com/etcd-io/etcd) from 3.5.18 to 3.5.21.
- [Release notes](https://github.com/etcd-io/etcd/releases)
- [Commits](https://github.com/etcd-io/etcd/compare/v3.5.18...v3.5.21)

---
updated-dependencies:
- dependency-name: go.etcd.io/etcd/client/pkg/v3
  dependency-version: 3.5.21
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-14 22:54:20 +02:00
dependabot[bot]
4e18ad189d Bump google.golang.org/protobuf from 1.36.5 to 1.36.6
Bumps google.golang.org/protobuf from 1.36.5 to 1.36.6.

---
updated-dependencies:
- dependency-name: google.golang.org/protobuf
  dependency-version: 1.36.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-14 22:39:06 +02:00
dependabot[bot]
a0ed07913e Bump golang.org/x/sync from 0.11.0 to 0.13.0
Bumps [golang.org/x/sync](https://github.com/golang/sync) from 0.11.0 to 0.13.0.
- [Commits](https://github.com/golang/sync/compare/v0.11.0...v0.13.0)

---
updated-dependencies:
- dependency-name: golang.org/x/sync
  dependency-version: 0.13.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-14 22:20:57 +02:00
Patryk Strusiewicz-Surmacki
3d9ca62031 Removed dependancy for endpoint counter in ARP mode
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
2025-04-14 21:41:34 +02:00
Patryk Strusiewicz-Surmacki
e0f4520437 Fixed ARP multiple references issues
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
2025-04-14 21:41:34 +02:00
Marcel Fest
3a5ebd184d Setup ipv4 and ipv6 subnet mask in template
Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
2025-04-14 21:41:34 +02:00
Marcel Fest
a7d19c15f1 rename forgotten envvar
Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
2025-04-14 21:41:34 +02:00
Marcel Fest
9822d92bed remove wrong if condition
Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
2025-04-14 21:41:34 +02:00
Marcel Fest
4d8b7750ae fix error wrap
Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
2025-04-14 21:41:34 +02:00
Patryk Strusiewicz-Surmacki
3bcf783020 Fixed E2E tests
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk-pawel.strusiewicz-surmacki@external.telekom.de>
Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
2025-04-14 21:41:34 +02:00
Marcel Fest
1b3a7bb5de improved log messages
Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
2025-04-14 21:41:34 +02:00
Marcel Fest
0d5ac98209 Simplify validation check and remove unused code
Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
2025-04-14 21:41:34 +02:00
Marcel Fest
e2472e509b fix tests?
Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
2025-04-14 21:41:34 +02:00
Marcel Fest
08388496bc Updated logic to not be as redundant
Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
2025-04-14 21:41:34 +02:00
Marcel Fest
f4eab023e8 Refactor and condense code, we always want to set SubnetMask
Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
2025-04-14 21:41:34 +02:00
Marcel Fest
c5e854f323 Breaking: Remove vip_cidr in favor of vip_subnet from config interface
Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
2025-04-14 21:41:34 +02:00
Marcel Fest
e7b9439161 Breaking Change do to retirement of vip_cidr
Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
2025-04-14 21:41:34 +02:00
Marcel Fest
555ca2b830 fix ci
Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
2025-04-14 21:41:34 +02:00
Marcel Fest
271f21f203 Try to add dual-stack support for BGP mode
Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
2025-04-14 21:41:34 +02:00
Daniel Finneran
de54fcbd11 Merge pull request #1126 from kube-vip/add/rbac-manifest-generation
Added support for RBAC manifest generation
2025-04-10 15:50:40 +01:00
Patryk Strusiewicz-Surmacki
46cad395e1 Fixed service IP address deletion on service modification bug
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk-pawel.strusiewicz-surmacki@external.telekom.de>
2025-04-09 23:15:43 +02:00
Marcel Fest
3466947f69 Added doc string for RBAC manifest generation
Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
2025-04-09 23:06:22 +02:00
Marcel Fest
8696f80525 added missing inCluster flag back
Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
2025-04-09 23:06:22 +02:00
Marcel Fest
51527d3e6c Added support for RBAC manifest generation
Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
2025-04-09 23:06:20 +02:00
Marcel Fest
c8a9189bf6 Remove the packet env var constants
Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
2025-04-09 21:11:39 +02:00
Deveshi Dwivedi
896b0983e4 remove remaining providerConfig references
Signed-off-by: Deveshi Dwivedi <deveshigurgaon@gmail.com>
Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
2025-04-09 21:11:39 +02:00
Deveshi Dwivedi
d55b124251 change annotations format back
Signed-off-by: Deveshi Dwivedi <deveshigurgaon@gmail.com>
Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
2025-04-09 21:11:39 +02:00
Deveshi Dwivedi
72b6e22d90 remove equinix-metal code
Signed-off-by: Deveshi Dwivedi <deveshigurgaon@gmail.com>
Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
2025-04-09 21:11:39 +02:00
Marcel Fest
3272bc1f8b Update golang-ci-lint to use kubernetes 1.24.x 2025-04-04 16:54:39 +02:00
dependabot[bot]
1e754703e8 Bump k8s.io/client-go from 0.32.1 to 0.32.3
Bumps [k8s.io/client-go](https://github.com/kubernetes/client-go) from 0.32.1 to 0.32.3.
- [Changelog](https://github.com/kubernetes/client-go/blob/master/CHANGELOG.md)
- [Commits](https://github.com/kubernetes/client-go/compare/v0.32.1...v0.32.3)

---
updated-dependencies:
- dependency-name: k8s.io/client-go
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-04 16:54:39 +02:00
dependabot[bot]
119424bb9b Bump k8s.io/api from 0.32.1 to 0.32.3
Bumps [k8s.io/api](https://github.com/kubernetes/api) from 0.32.1 to 0.32.3.
- [Commits](https://github.com/kubernetes/api/compare/v0.32.1...v0.32.3)

---
updated-dependencies:
- dependency-name: k8s.io/api
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-04 16:54:39 +02:00
Marcel Fest
d8926ebea5 bump golang 2025-04-04 16:54:39 +02:00
dependabot[bot]
6b1a0a7ea8 Bump github.com/osrg/gobgp/v3 from 3.34.0 to 3.35.0
Bumps [github.com/osrg/gobgp/v3](https://github.com/osrg/gobgp) from 3.34.0 to 3.35.0.
- [Release notes](https://github.com/osrg/gobgp/releases)
- [Changelog](https://github.com/osrg/gobgp/blob/master/.goreleaser.yml)
- [Commits](https://github.com/osrg/gobgp/compare/v3.34.0...v3.35.0)

---
updated-dependencies:
- dependency-name: github.com/osrg/gobgp/v3
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-03 16:52:27 +02:00
dependabot[bot]
c92d01b957 Bump golang.org/x/net from 0.34.0 to 0.36.0
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.34.0 to 0.36.0.
- [Commits](https://github.com/golang/net/compare/v0.34.0...v0.36.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-03 16:51:26 +02:00
dependabot[bot]
d6c6d8e529 Bump sigs.k8s.io/kind from 0.26.0 to 0.27.0
Bumps [sigs.k8s.io/kind](https://github.com/kubernetes-sigs/kind) from 0.26.0 to 0.27.0.
- [Release notes](https://github.com/kubernetes-sigs/kind/releases)
- [Commits](https://github.com/kubernetes-sigs/kind/compare/v0.26.0...v0.27.0)

---
updated-dependencies:
- dependency-name: sigs.k8s.io/kind
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-03 16:50:41 +02:00
dependabot[bot]
1d086b2d5c Bump golang from 1.24.0-alpine3.20 to 1.24.1-alpine3.20
Bumps golang from 1.24.0-alpine3.20 to 1.24.1-alpine3.20.

---
updated-dependencies:
- dependency-name: golang
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-03 16:49:48 +02:00
dependabot[bot]
e5d967dcf4 Bump github.com/spf13/cobra from 1.8.1 to 1.9.1
Bumps [github.com/spf13/cobra](https://github.com/spf13/cobra) from 1.8.1 to 1.9.1.
- [Release notes](https://github.com/spf13/cobra/releases)
- [Commits](https://github.com/spf13/cobra/compare/v1.8.1...v1.9.1)

---
updated-dependencies:
- dependency-name: github.com/spf13/cobra
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-03 16:49:15 +02:00
Patryk Strusiewicz-Surmacki
21a5533936 Fixes for IPv6 and dualstack clusters
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk-pawel.strusiewicz-surmacki@external.telekom.de>
2025-04-03 16:19:06 +02:00
Patryk Strusiewicz-Surmacki
d21fec6c7d Cancel leaderelection if forwarding mode is local and no local endpoints are present
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk-pawel.strusiewicz-surmacki@external.telekom.de>
2025-04-03 16:19:06 +02:00
Patryk Strusiewicz-Surmacki
9c4ae86937 Added IPv6 related configuration for IPVS
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk-pawel.strusiewicz-surmacki@external.telekom.de>
2025-04-03 16:19:06 +02:00
Patryk Strusiewicz-Surmacki
9c67660b94 Added permission check for IPVS info
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk-pawel.strusiewicz-surmacki@external.telekom.de>
2025-04-03 16:19:06 +02:00
Patryk Strusiewicz-Surmacki
96d020b6ad Disable IPVS related iptables rules if LB is not enabled
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk-pawel.strusiewicz-surmacki@external.telekom.de>
2025-04-03 16:19:06 +02:00
Patryk Strusiewicz-Surmacki
bc42c3e2c3 Added sysctl check
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk-pawel.strusiewicz-surmacki@external.telekom.de>
2025-04-03 16:19:06 +02:00
Patryk Strusiewicz-Surmacki
ea45dafcf3 Fixed IPVS deletion issues
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk-pawel.strusiewicz-surmacki@external.telekom.de>
2025-04-03 16:19:06 +02:00
Patryk Strusiewicz-Surmacki
3e3fd21c16 Fixed route deletion issue when 2 services referenced same endpoint
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk-pawel.strusiewicz-surmacki@external.telekom.de>
2025-04-03 16:04:11 +02:00
Patryk Strusiewicz-Surmacki
70b83664a9 Less strict service status update error handling
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk-pawel.strusiewicz-surmacki@external.telekom.de>
2025-03-27 15:27:26 +01:00
Patryk Strusiewicz-Surmacki
9650a00157 Fixed service/endpoints discovery concurrent issue
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk-pawel.strusiewicz-surmacki@external.telekom.de>
2025-03-10 12:12:23 +01:00
Patryk Strusiewicz-Surmacki
f851ddbcaf Fixed service update in BGP and ARP mode
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk-pawel.strusiewicz-surmacki@external.telekom.de>
2025-03-08 08:43:00 +01:00
Daniel Finneran
a5ee4d969b Merge pull request #1091 from p-strusiewiczsurmacki-mobica/ipvs-re-add-cp
Fixed IPVS backend re-add
2025-03-06 17:15:24 +01:00
Patryk Strusiewicz-Surmacki
2dfd46decb Fixed IPVS backend re-add
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk-pawel.strusiewicz-surmacki@external.telekom.de>
2025-03-04 15:42:45 +01:00
Daniel Finneran
6752dc0fdd Merge pull request #1084 from kube-vip/dependabot/go_modules/github.com/prometheus/client_golang-1.21.0
Bump github.com/prometheus/client_golang from 1.20.5 to 1.21.0
2025-02-26 15:45:38 +01:00
Daniel Finneran
c7174d3c94 Merge pull request #1083 from kube-vip/dependabot/go_modules/github.com/google/go-cmp-0.7.0
Bump github.com/google/go-cmp from 0.6.0 to 0.7.0
2025-02-26 15:45:25 +01:00
Daniel Finneran
d33ba7e22e Merge pull request #1079 from kube-vip/health
This adds a health check
2025-02-26 15:44:29 +01:00
dependabot[bot]
9b552a4d29 Bump github.com/prometheus/client_golang from 1.20.5 to 1.21.0
Bumps [github.com/prometheus/client_golang](https://github.com/prometheus/client_golang) from 1.20.5 to 1.21.0.
- [Release notes](https://github.com/prometheus/client_golang/releases)
- [Changelog](https://github.com/prometheus/client_golang/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prometheus/client_golang/compare/v1.20.5...v1.21.0)

---
updated-dependencies:
- dependency-name: github.com/prometheus/client_golang
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-24 02:57:33 +00:00
dependabot[bot]
5fc04a24f8 Bump github.com/google/go-cmp from 0.6.0 to 0.7.0
Bumps [github.com/google/go-cmp](https://github.com/google/go-cmp) from 0.6.0 to 0.7.0.
- [Release notes](https://github.com/google/go-cmp/releases)
- [Commits](https://github.com/google/go-cmp/compare/v0.6.0...v0.7.0)

---
updated-dependencies:
- dependency-name: github.com/google/go-cmp
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-24 02:57:30 +00:00
Daniel Finneran
122b18a81d Merge pull request #1070 from kube-vip/dependabot/go_modules/google.golang.org/protobuf-1.36.5
Bump google.golang.org/protobuf from 1.36.1 to 1.36.5
2025-02-20 12:42:39 +01:00
Daniel Finneran
c9bc005abe Merge pull request #1075 from kube-vip/dependabot/go_modules/github.com/cloudflare/ipvs-0.10.3
Bump github.com/cloudflare/ipvs from 0.10.2 to 0.10.3
2025-02-20 12:42:26 +01:00
Daniel Finneran
ee0f0668ab Merge pull request #1076 from kube-vip/dependabot/docker/alpine-3.21.3
Bump alpine from 3.21.2 to 3.21.3
2025-02-20 12:42:09 +01:00
Daniel Finneran
826bb6fc8a Merge pull request #1077 from kube-vip/dependabot/docker/golang-1.24.0-alpine3.20
Bump golang from 1.23.5-alpine3.20 to 1.24.0-alpine3.20
2025-02-20 12:41:57 +01:00
Dan Finneran
b9aa99a208 more lint goodness 2025-02-17 17:23:01 +00:00
Dan Finneran
2b0aa825b5 lint fix 2025-02-17 17:21:20 +00:00
dependabot[bot]
24b1524aee Bump google.golang.org/protobuf from 1.36.1 to 1.36.5
Bumps google.golang.org/protobuf from 1.36.1 to 1.36.5.

---
updated-dependencies:
- dependency-name: google.golang.org/protobuf
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-17 17:18:22 +00:00
Daniel Finneran
cf7c7f2f25 Merge pull request #1069 from kube-vip/dependabot/go_modules/golang.org/x/sync-0.11.0
Bump golang.org/x/sync from 0.10.0 to 0.11.0
2025-02-17 18:17:01 +01:00
Dan Finneran
c082688e67 This adds a health check 2025-02-17 17:16:29 +00:00
dependabot[bot]
18bfe6a8d2 Bump golang.org/x/sync from 0.10.0 to 0.11.0
Bumps [golang.org/x/sync](https://github.com/golang/sync) from 0.10.0 to 0.11.0.
- [Commits](https://github.com/golang/sync/compare/v0.10.0...v0.11.0)

---
updated-dependencies:
- dependency-name: golang.org/x/sync
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-17 15:16:50 +00:00
Daniel Finneran
c367434798 Merge pull request #1068 from kube-vip/dependabot/go_modules/github.com/osrg/gobgp/v3-3.34.0
Bump github.com/osrg/gobgp/v3 from 3.33.0 to 3.34.0
2025-02-17 16:15:09 +01:00
Daniel Finneran
f1ca914e92 Merge pull request #1067 from kube-vip/dependabot/go_modules/golang.org/x/sys-0.30.0
Bump golang.org/x/sys from 0.29.0 to 0.30.0
2025-02-17 16:14:57 +01:00
Daniel Finneran
2763c7e417 Merge pull request #1072 from p-strusiewiczsurmacki-mobica/mask-fix
Fixed network mask setting function
2025-02-17 16:14:43 +01:00
Daniel Finneran
f9f0004d3f Merge pull request #1064 from kube-vip/resolver
Resolver, this will ensure that an address that is not an IP address is resolved first to determine the CIDR
2025-02-17 16:14:22 +01:00
Daniel Finneran
958eaefb40 Merge pull request #1062 from kube-vip/bgp_port
You can now specify the port as the fifth argument to peer config
2025-02-17 16:14:05 +01:00
Daniel Finneran
3752695000 Merge pull request #1060 from kube-vip/waitgroup
remove the waitgroups as we never wait
2025-02-17 16:13:38 +01:00
Daniel Finneran
d6eb7c4f26 Merge pull request #1059 from kube-vip/drop_all
drop all other capabilities
2025-02-17 16:13:21 +01:00
dependabot[bot]
b88769e109 Bump golang from 1.23.5-alpine3.20 to 1.24.0-alpine3.20
Bumps golang from 1.23.5-alpine3.20 to 1.24.0-alpine3.20.

---
updated-dependencies:
- dependency-name: golang
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-17 02:38:59 +00:00
dependabot[bot]
eddbcf0801 Bump alpine from 3.21.2 to 3.21.3
Bumps alpine from 3.21.2 to 3.21.3.

---
updated-dependencies:
- dependency-name: alpine
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-17 02:38:56 +00:00
dependabot[bot]
886f183108 Bump github.com/cloudflare/ipvs from 0.10.2 to 0.10.3
Bumps [github.com/cloudflare/ipvs](https://github.com/cloudflare/ipvs) from 0.10.2 to 0.10.3.
- [Release notes](https://github.com/cloudflare/ipvs/releases)
- [Commits](https://github.com/cloudflare/ipvs/compare/v0.10.2...v0.10.3)

---
updated-dependencies:
- dependency-name: github.com/cloudflare/ipvs
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-17 02:15:06 +00:00
Patryk Strusiewicz-Surmacki
aba1d53699 Changed initConfig.Logging to be int32
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk-pawel.strusiewicz-surmacki@external.telekom.de>
2025-02-13 19:36:39 +01:00
Patryk Strusiewicz-Surmacki
d05530e030 Fixed logging level configuration with command line argument
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk-pawel.strusiewicz-surmacki@external.telekom.de>
2025-02-13 19:36:39 +01:00
Patryk Strusiewicz-Surmacki
7d52dbbbd5 Return error instead of logging warning
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk-pawel.strusiewicz-surmacki@external.telekom.de>
2025-02-12 11:51:07 +01:00
Patryk Strusiewicz-Surmacki
53185bd58d Fixed ENV log level setting
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk-pawel.strusiewicz-surmacki@external.telekom.de>
2025-02-10 21:24:48 +01:00
Patryk Strusiewicz-Surmacki
8997c4b1a8 Fixed network mask setting function
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk-pawel.strusiewicz-surmacki@external.telekom.de>
2025-02-10 15:46:55 +01:00
dependabot[bot]
ce4665bbec Bump github.com/osrg/gobgp/v3 from 3.33.0 to 3.34.0
Bumps [github.com/osrg/gobgp/v3](https://github.com/osrg/gobgp) from 3.33.0 to 3.34.0.
- [Release notes](https://github.com/osrg/gobgp/releases)
- [Changelog](https://github.com/osrg/gobgp/blob/master/.goreleaser.yml)
- [Commits](https://github.com/osrg/gobgp/compare/v3.33.0...v3.34.0)

---
updated-dependencies:
- dependency-name: github.com/osrg/gobgp/v3
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-10 02:10:52 +00:00
dependabot[bot]
e1ecca42c5 Bump golang.org/x/sys from 0.29.0 to 0.30.0
Bumps [golang.org/x/sys](https://github.com/golang/sys) from 0.29.0 to 0.30.0.
- [Commits](https://github.com/golang/sys/compare/v0.29.0...v0.30.0)

---
updated-dependencies:
- dependency-name: golang.org/x/sys
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-10 02:10:48 +00:00
Dan Finneran
c6cb548763 This ensures a hostname is resolved if passed as the api address 2025-02-05 14:51:22 +00:00
Dan Finneran
b52c90f865 You can now specify the port as the fifth argument to peer config 2025-02-05 13:37:41 +00:00
Daniel Finneran
2ceba7f5ad Update ci.yaml
Remove the original control plane tests as everything is 1.29+ at this point
2025-02-05 12:32:22 +00:00
Daniel Finneran
c3121a97f1 Update README.md 2025-02-05 12:29:53 +00:00
Daniel Finneran
b7cc63bfd6 Merge pull request #1048 from kube-vip/dependabot/go_modules/k8s.io/api-0.32.1
Bump k8s.io/api from 0.32.0 to 0.32.1
2025-02-05 12:41:22 +01:00
Daniel Finneran
3a4d859457 Merge pull request #1047 from kube-vip/dependabot/go_modules/k8s.io/client-go-0.32.1
Bump k8s.io/client-go from 0.32.0 to 0.32.1
2025-02-05 12:41:02 +01:00
Dan Finneran
964b248108 remove the waitgroups as we never wait 2025-02-05 11:37:48 +00:00
Daniel Finneran
b6e87418a2 Merge pull request #1055 from kube-vip/dependabot/go_modules/go.etcd.io/etcd/client/v3-3.5.18
Bump go.etcd.io/etcd/client/v3 from 3.5.17 to 3.5.18
2025-02-05 12:01:27 +01:00
Dan Finneran
473fd6f4f8 drop all other capabilities 2025-02-05 09:58:14 +00:00
Daniel Finneran
c49afdb44d Merge branch 'main' into dependabot/go_modules/go.etcd.io/etcd/client/v3-3.5.18 2025-02-05 10:56:55 +01:00
dependabot[bot]
f0182fcb0c Bump k8s.io/api from 0.32.0 to 0.32.1
Bumps [k8s.io/api](https://github.com/kubernetes/api) from 0.32.0 to 0.32.1.
- [Commits](https://github.com/kubernetes/api/compare/v0.32.0...v0.32.1)

---
updated-dependencies:
- dependency-name: k8s.io/api
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-05 09:55:47 +00:00
Daniel Finneran
7424df98a5 Merge pull request #1054 from kube-vip/dependabot/go_modules/go.etcd.io/etcd/client/pkg/v3-3.5.18
Bump go.etcd.io/etcd/client/pkg/v3 from 3.5.17 to 3.5.18
2025-02-05 10:55:39 +01:00
Daniel Finneran
b4c4cfd365 Merge pull request #1053 from kube-vip/dependabot/github_actions/anchore/sbom-action-0.18.0
Bump anchore/sbom-action from 0.17.9 to 0.18.0
2025-02-05 10:55:27 +01:00
Daniel Finneran
7878be3847 Merge branch 'main' into dependabot/go_modules/k8s.io/client-go-0.32.1 2025-02-05 10:54:25 +01:00
Daniel Finneran
1dc75f9f21 Merge pull request #1046 from kube-vip/dependabot/go_modules/k8s.io/apimachinery-0.32.1
Bump k8s.io/apimachinery from 0.32.0 to 0.32.1
2025-02-05 10:53:34 +01:00
Daniel Finneran
cbe4cd150e Merge pull request #1043 from kube-vip/slog
Refactor to slog
2025-02-05 10:53:12 +01:00
Dan Finneran
99e1fb3fc6 linting 2025-02-05 09:38:20 +00:00
Dan Finneran
e1481db95c cleanup of messages 2025-02-05 09:24:39 +00:00
Daniel Finneran
efc7ba5646 Merge pull request #1045 from kube-vip/dependabot/docker/golang-1.23.5-alpine3.20
Bump golang from 1.23.4-alpine3.20 to 1.23.5-alpine3.20
2025-02-04 11:50:23 +00:00
Daniel Finneran
90552b73dc Merge pull request #1003 from p-strusiewiczsurmacki-mobica/feature/mp-bgp
Support for MP-BGP
2025-02-04 11:42:17 +00:00
Dan Finneran
81c0b4faf5 lint fix 2025-02-04 08:42:42 +00:00
Dan Finneran
95be514b8f fixes to slog formatting 2025-02-01 14:01:27 +00:00
Daniel Finneran
d289efc862 Merge branch 'main' into slog 2025-02-01 12:18:26 +00:00
Daniel Finneran
e388b2d1c9 Merge pull request #1056 from kube-vip/ndp_error
Ndp error
2025-02-01 12:12:52 +00:00
Dan Finneran
7ca0d79250 superflous error return 2025-02-01 11:49:09 +00:00
Dan Finneran
20b375770c reduced duplicated code and cleaned messages 2025-02-01 11:44:28 +00:00
Dan Finneran
6b3ada8402 NDP link-local messages 2025-02-01 11:07:48 +00:00
Dan Finneran
c12bb65b4b adds some testing for Cilium, not for CI 2025-01-29 14:27:05 +00:00
dependabot[bot]
2e0dddba60 Bump go.etcd.io/etcd/client/v3 from 3.5.17 to 3.5.18
Bumps [go.etcd.io/etcd/client/v3](https://github.com/etcd-io/etcd) from 3.5.17 to 3.5.18.
- [Release notes](https://github.com/etcd-io/etcd/releases)
- [Commits](https://github.com/etcd-io/etcd/compare/v3.5.17...v3.5.18)

---
updated-dependencies:
- dependency-name: go.etcd.io/etcd/client/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-27 02:24:49 +00:00
dependabot[bot]
8e6767c606 Bump go.etcd.io/etcd/client/pkg/v3 from 3.5.17 to 3.5.18
Bumps [go.etcd.io/etcd/client/pkg/v3](https://github.com/etcd-io/etcd) from 3.5.17 to 3.5.18.
- [Release notes](https://github.com/etcd-io/etcd/releases)
- [Commits](https://github.com/etcd-io/etcd/compare/v3.5.17...v3.5.18)

---
updated-dependencies:
- dependency-name: go.etcd.io/etcd/client/pkg/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-27 02:24:45 +00:00
dependabot[bot]
419051c762 Bump anchore/sbom-action from 0.17.9 to 0.18.0
Bumps [anchore/sbom-action](https://github.com/anchore/sbom-action) from 0.17.9 to 0.18.0.
- [Release notes](https://github.com/anchore/sbom-action/releases)
- [Changelog](https://github.com/anchore/sbom-action/blob/main/RELEASE.md)
- [Commits](https://github.com/anchore/sbom-action/compare/v0.17.9...v0.18.0)

---
updated-dependencies:
- dependency-name: anchore/sbom-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-27 02:09:46 +00:00
Dan Finneran
9e432d1178 Fixes to swallowed errors 2025-01-24 09:20:55 +00:00
Patryk Strusiewicz-Surmacki
0832a7227c Added MP-BGP for IPv4 over IPv6 session and config flags
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk-pawel.strusiewicz-surmacki@external.telekom.de>
2025-01-22 17:36:39 +01:00
Christopher Dziomba
3b16caa38c Messy prototype of MP-BGP with kube-vip 2025-01-21 12:10:07 +01:00
dependabot[bot]
1d4e57a754 Bump k8s.io/client-go from 0.32.0 to 0.32.1
Bumps [k8s.io/client-go](https://github.com/kubernetes/client-go) from 0.32.0 to 0.32.1.
- [Changelog](https://github.com/kubernetes/client-go/blob/master/CHANGELOG.md)
- [Commits](https://github.com/kubernetes/client-go/compare/v0.32.0...v0.32.1)

---
updated-dependencies:
- dependency-name: k8s.io/client-go
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-20 02:36:19 +00:00
dependabot[bot]
c36585ce98 Bump k8s.io/apimachinery from 0.32.0 to 0.32.1
Bumps [k8s.io/apimachinery](https://github.com/kubernetes/apimachinery) from 0.32.0 to 0.32.1.
- [Commits](https://github.com/kubernetes/apimachinery/compare/v0.32.0...v0.32.1)

---
updated-dependencies:
- dependency-name: k8s.io/apimachinery
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-20 02:36:11 +00:00
dependabot[bot]
af1280be1a Bump golang from 1.23.4-alpine3.20 to 1.23.5-alpine3.20
Bumps golang from 1.23.4-alpine3.20 to 1.23.5-alpine3.20.

---
updated-dependencies:
- dependency-name: golang
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-20 02:32:12 +00:00
Dan Finneran
c01fb8fca7 fix_spelling 2025-01-16 18:39:02 +00:00
Dan Finneran
1d6d860153 set default loglevel 2025-01-16 17:46:11 +00:00
Dan Finneran
2136e69a82 Big refactor to log/slog 2025-01-16 17:45:09 +00:00
Daniel Finneran
cb438d289b Merge pull request #1040 from kube-vip/restart_on_modification
Restart on modification
2025-01-16 12:50:20 +00:00
Dan Finneran
ded08ddf5c Fixing nits 2025-01-16 10:45:36 +00:00
Dan Finneran
79b24875ec le sigh 2025-01-16 09:46:18 +00:00
Daniel Finneran
b423cbdb89 Merge branch 'main' into restart_on_modification 2025-01-16 09:26:52 +00:00
Daniel Finneran
600c1db24b Merge pull request #1036 from kube-vip/logic_clean
This removes some weird pointless code
2025-01-16 09:25:56 +00:00
Dan Finneran
b2979be25c Linting fixes 2025-01-15 11:19:09 +00:00
Dan Finneran
462b511b9f This change means that a modification to an existing LB results in updating the settings. 2025-01-15 11:10:19 +00:00
Daniel Finneran
19e660d4a6 Update Makefile 2025-01-14 13:29:35 +00:00
Daniel Finneran
cfa11d1a88 Merge pull request #1037 from kube-vip/dependabot/go_modules/github.com/onsi/ginkgo/v2-2.22.2
Bump github.com/onsi/ginkgo/v2 from 2.22.1 to 2.22.2
2025-01-14 13:29:16 +00:00
Daniel Finneran
bf283f1252 Merge pull request #1038 from kube-vip/dependabot/docker/alpine-3.21.2
Bump alpine from 3.21.0 to 3.21.2
2025-01-14 13:29:00 +00:00
dependabot[bot]
839b860eee Bump alpine from 3.21.0 to 3.21.2
Bumps alpine from 3.21.0 to 3.21.2.

---
updated-dependencies:
- dependency-name: alpine
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-13 02:54:42 +00:00
dependabot[bot]
e134e5682e Bump github.com/onsi/ginkgo/v2 from 2.22.1 to 2.22.2
Bumps [github.com/onsi/ginkgo/v2](https://github.com/onsi/ginkgo) from 2.22.1 to 2.22.2.
- [Release notes](https://github.com/onsi/ginkgo/releases)
- [Changelog](https://github.com/onsi/ginkgo/blob/master/CHANGELOG.md)
- [Commits](https://github.com/onsi/ginkgo/compare/v2.22.1...v2.22.2)

---
updated-dependencies:
- dependency-name: github.com/onsi/ginkgo/v2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-13 02:26:18 +00:00
Dan Finneran
ebc4cdccb9 more_lint 2025-01-12 13:02:08 +00:00
Dan Finneran
baed70dbfc fix_linting 2025-01-12 12:53:05 +00:00
Dan Finneran
b8aff1d348 fix_lint 2025-01-12 12:52:58 +00:00
Dan Finneran
aa5f0cc267 This removes some weird pointless code 2025-01-12 11:36:30 +00:00
Daniel Finneran
316c3bbdd4 Merge pull request #1034 from murphp15/feature/release_the_lock_if_you_cant_advertise_service
release lock if unable to sync service correctly.
2025-01-10 16:17:37 +00:00
paul.murphy
dbc02485d9 release lock if unable to sync service correctly. 2025-01-10 15:54:08 +00:00
paul.murphy
6442ce26fc release lock if unable to sync service correctly. 2025-01-10 15:37:41 +00:00
Paul Murphy
ccd1137606 Merge branch 'kube-vip:main' into feature/release_the_lock_if_you_cant_advertise_service 2025-01-10 14:47:32 +00:00
Daniel Finneran
96d79774b5 Merge pull request #1035 from kube-vip/print_build_info
by default print build
2025-01-10 14:22:12 +00:00
Dan Finneran
829a1fced6 by default print build 2025-01-10 14:20:35 +00:00
paul.murphy
0c5dd3c890 release lock if unable to sync service correctly. 2025-01-10 10:49:51 +00:00
paul.murphy
51aad755c3 release lock if unable to sync service correctly. 2025-01-10 10:49:34 +00:00
paul.murphy
635950e329 release lock if unable to sync service correctly. 2025-01-10 10:45:33 +00:00
paul.murphy
7eb93bec0b Merge branch 'main' into feature/release_the_lock_if_you_cant_advertise_service 2025-01-10 10:39:19 +00:00
paul.murphy
cf8384fb1f release lock if unable to sync service correctly. 2025-01-10 10:36:45 +00:00
Daniel Finneran
6da951056c Merge pull request #1030 from kube-vip/services_fix
Ensure watcher is restarted as expected
2025-01-09 11:35:41 +00:00
Daniel Finneran
a50e476d7e Merge pull request #1029 from kube-vip/watcher-fix
Fixes an issue with watchers having an old reference
2025-01-09 11:21:37 +00:00
Dan Finneran
329e0940da Ensure watcher is restarted as expected 2025-01-09 11:05:03 +00:00
Dan Finneran
7a43646e62 Fixes an issue with watchers having an old reference 2025-01-08 18:27:30 +00:00
Daniel Finneran
dd8f2d13d2 Update Makefile 2025-01-06 13:47:49 +00:00
Daniel Finneran
f119c890a1 Merge pull request #1024 from kube-vip/small_fix
Fix linting issue
2025-01-06 13:46:49 +00:00
Dan Finneran
714b80225f Fix linting issue 2025-01-06 10:52:48 +00:00
Daniel Finneran
49297980b0 Merge pull request #923 from cdtzabra/main
Ensuring nodelabel will be always present
2025-01-06 10:51:31 +00:00
Daniel Finneran
e7beb9c9c3 Merge pull request #1012 from kube-vip/dependabot/github_actions/anchore/sbom-action-0.17.9
Bump anchore/sbom-action from 0.17.5 to 0.17.9
2025-01-06 10:23:02 +00:00
dependabot[bot]
5e66a62c32 Bump anchore/sbom-action from 0.17.5 to 0.17.9
Bumps [anchore/sbom-action](https://github.com/anchore/sbom-action) from 0.17.5 to 0.17.9.
- [Release notes](https://github.com/anchore/sbom-action/releases)
- [Changelog](https://github.com/anchore/sbom-action/blob/main/RELEASE.md)
- [Commits](https://github.com/anchore/sbom-action/compare/v0.17.5...v0.17.9)

---
updated-dependencies:
- dependency-name: anchore/sbom-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-06 09:54:08 +00:00
Daniel Finneran
fbbf83d9d0 Merge pull request #1008 from kube-vip/dependabot/docker/golang-1.23.4-alpine3.20
Bump golang from 1.23.2-alpine3.20 to 1.23.4-alpine3.20
2025-01-06 09:51:24 +00:00
Daniel Finneran
7e244084e1 Merge pull request #1022 from kube-vip/deps
update deps
2025-01-06 09:50:40 +00:00
Dan Finneran
089ad123b6 losing hope 2025-01-05 17:12:35 +00:00
Dan Finneran
fdc50efc86 clutching at straws now 2025-01-05 17:10:24 +00:00
Dan Finneran
7644cb720e attempt 2 2025-01-05 17:05:48 +00:00
Dan Finneran
299c9e1ebb updatae go.mod 2025-01-05 16:02:06 +00:00
Dan Finneran
b82b733dde CI fix 2025-01-05 15:58:58 +00:00
Dan Finneran
e339d12b40 update deps 2025-01-05 15:53:34 +00:00
dependabot[bot]
3ea17b134d Bump golang from 1.23.2-alpine3.20 to 1.23.4-alpine3.20
Bumps golang from 1.23.2-alpine3.20 to 1.23.4-alpine3.20.

---
updated-dependencies:
- dependency-name: golang
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-05 15:30:03 +00:00
Daniel Finneran
ea410e7490 Merge pull request #1007 from kube-vip/dependabot/docker/alpine-3.21.0
Bump alpine from 3.20.3 to 3.21.0
2025-01-05 15:29:04 +00:00
Daniel Finneran
430efae598 Merge pull request #1019 from kube-vip/egress_annotations
Adds a bunch of flexability around egress
2025-01-05 15:27:29 +00:00
Dan Finneran
c96cdb6cd2 test fix 2025-01-05 15:03:53 +00:00
Dan Finneran
ffe2e9c808 Various fixes to CI 2025-01-05 14:59:51 +00:00
Dan Finneran
545f9a4a47 fix to modules and workflow 2024-12-20 16:38:56 +00:00
Dan Finneran
2555dd8101 Adds a bunch of flexability around egress 2024-12-20 16:25:06 +00:00
dependabot[bot]
f7b4ab5b42 Bump alpine from 3.20.3 to 3.21.0
Bumps alpine from 3.20.3 to 3.21.0.

---
updated-dependencies:
- dependency-name: alpine
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-12-09 02:39:44 +00:00
Daniel Finneran
4c70d87381 Update Makefile 2024-11-20 09:08:47 +00:00
Dan Finneran
894e56458f remove commented out code 2024-11-15 17:07:51 +01:00
Dan Finneran
de5659e7b2 Services aren't removed when there are no endpoints. 2024-11-15 17:07:51 +01:00
Marcel Fest
e4b0b2a71f Use the new release version in Makefile
Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
2024-11-11 08:56:48 +01:00
Daniel Finneran
dd06c3fb82 Merge pull request #987 from p-strusiewiczsurmacki-mobica/rwclient-ipvs-fix
Fixed null pointer exception when IPVS loadbalancer is used
2024-11-04 11:31:28 +00:00
Patryk Strusiewicz-Surmacki
8ee952cf3e Fixed null pointer exception when IPVS loadbalancer is used
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk-pawel.strusiewicz-surmacki@external.telekom.de>
2024-11-04 11:50:34 +01:00
Daniel Finneran
57bcea9646 Merge pull request #984 from kube-vip/fix/retry-watch
initialize the config for the rwclient separately
2024-11-01 11:33:00 +00:00
Cellebyte
907696a4a3 initialize the config for the rwclient separately
Signed-off-by: Cellebyte <marcel.fest@live.de>
2024-11-01 10:50:09 +01:00
Daniel Finneran
78cdf8d5b6 Merge pull request #981 from kube-vip/New-release-0.8.5 2024-10-31 12:59:10 +00:00
Daniel Finneran
5a7edbe825 Merge pull request #976 from l0wl3vel/upnp-gateway-ip 2024-10-31 12:47:35 +00:00
Daniel Finneran
de8300a40a Merge pull request #961 from p-strusiewiczsurmacki-mobica/auto-svc-subnet 2024-10-31 12:46:10 +00:00
Patryk Strusiewicz-Surmacki
73e6ade0ea Added auto subnet discovery for services in ARP mode
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk-pawel.strusiewicz-surmacki@external.telekom.de>
2024-10-31 10:31:39 +01:00
Benjamin Ritter
4def2c784e Update Gateway IPs on UPNP refresh
Signed-off-by: Benjamin Ritter <Benjamin.Ritter@protonmail.com>
2024-10-30 17:51:00 +01:00
Benjamin Ritter
1c8ce223d7 Reduce UPNP refresh interval to 5 minutes
Reduces impact on availibility when the
gateway external IP changes

Signed-off-by: Benjamin Ritter <Benjamin.Ritter@protonmail.com>
2024-10-30 17:51:00 +01:00
Benjamin Ritter
02d00bf99c Annotate UPNP Gateway IPs on the service
Signed-off-by: Benjamin Ritter <Benjamin.Ritter@protonmail.com>
2024-10-30 17:51:00 +01:00
Daniel Finneran
4433243fa6 Update Makefile
This PR should be the last merged PR for the 0.8.5 release, which should also be the last of the `0.8.x` releases.
2024-10-30 15:21:43 +00:00
Daniel Finneran
a8ae976bb2 Merge pull request #968 from kube-vip/dependabot/go_modules/github.com/cloudflare/ipvs-0.10.2
Bump github.com/cloudflare/ipvs from 0.10.1 to 0.10.2
2024-10-30 14:38:40 +00:00
Daniel Finneran
1559b21cfb Merge pull request #954 from l0wl3vel/upnp-igd2
Use IGD:2 and Pinhole Port Forwarding
2024-10-30 14:37:34 +00:00
Daniel Finneran
f55aed4382 Merge pull request #979 from kube-vip/dependabot/github_actions/anchore/sbom-action-0.17.5
Bump anchore/sbom-action from 0.17.3 to 0.17.5
2024-10-30 14:36:21 +00:00
Daniel Finneran
cc12fcb0f6 Merge pull request #970 from p-strusiewiczsurmacki-mobica/egress-rules-fix
Egress rules deletion fix
2024-10-30 14:36:00 +00:00
Patryk Strusiewicz-Surmacki
95dfc47e47 Added info on egress protocol
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk-pawel.strusiewicz-surmacki@external.telekom.de>
2024-10-30 14:31:41 +01:00
Patryk Strusiewicz-Surmacki
0bf38f57f7 Fixed logging issues
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk-pawel.strusiewicz-surmacki@external.telekom.de>
2024-10-29 11:46:24 +01:00
Patryk Strusiewicz-Surmacki
7f4116417c Fixed typo
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk-pawel.strusiewicz-surmacki@external.telekom.de>
2024-10-29 11:46:24 +01:00
Patryk Strusiewicz-Surmacki
5763400c15 Added safeguards for IP family
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk-pawel.strusiewicz-surmacki@external.telekom.de>
2024-10-29 11:46:24 +01:00
Patryk Strusiewicz-Surmacki
6b136efff3 Added changes to CIDR discovery from auto-svc-subnet branch
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk-pawel.strusiewicz-surmacki@external.telekom.de>
2024-10-29 11:46:24 +01:00
Patryk Strusiewicz-Surmacki
1f089fe71c Added routing table ID fix
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk-pawel.strusiewicz-surmacki@external.telekom.de>
2024-10-29 11:46:24 +01:00
Patryk Strusiewicz-Surmacki
1bc26b5827 Fixed e2e
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk-pawel.strusiewicz-surmacki@external.telekom.de>
2024-10-29 11:46:24 +01:00
Patryk Strusiewicz-Surmacki
40674a12b6 Fixed route deleting issue in table mode
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk-pawel.strusiewicz-surmacki@external.telekom.de>
2024-10-29 11:46:24 +01:00
Patryk Strusiewicz-Surmacki
ef2f6ebaa0 Fixed auto CIDR discovery priority
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk-pawel.strusiewicz-surmacki@external.telekom.de>
2024-10-29 11:46:24 +01:00
Patryk Strusiewicz-Surmacki
625030dfb6 Fixed retry-watcher timeout issue (#974)
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk-pawel.strusiewicz-surmacki@external.telekom.de>
2024-10-28 20:14:05 +01:00
Benjamin Ritter
779fc5641f Add context to UPNP logging
Signed-off-by: Benjamin Ritter <Benjamin.Ritter@protonmail.com>
2024-10-28 15:24:18 +01:00
dependabot[bot]
971e794639 Bump anchore/sbom-action from 0.17.3 to 0.17.5
Bumps [anchore/sbom-action](https://github.com/anchore/sbom-action) from 0.17.3 to 0.17.5.
- [Release notes](https://github.com/anchore/sbom-action/releases)
- [Changelog](https://github.com/anchore/sbom-action/blob/main/RELEASE.md)
- [Commits](https://github.com/anchore/sbom-action/compare/v0.17.3...v0.17.5)

---
updated-dependencies:
- dependency-name: anchore/sbom-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-28 02:36:00 +00:00
Patryk Strusiewicz-Surmacki
89c6002f92 Fixed NDP responder (#973)
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk-pawel.strusiewicz-surmacki@external.telekom.de>
2024-10-27 22:27:55 +01:00
Benjamin Ritter
6b0e45da96 Clean up UPNP client handling
Signed-off-by: Benjamin Ritter <Benjamin.Ritter@protonmail.com>
2024-10-27 20:50:32 +01:00
Benjamin Ritter
7bde7a4845 feat: Add perpetual UPNP Forward refreshing
Signed-off-by: Benjamin Ritter <Benjamin.Ritter@protonmail.com>
2024-10-24 21:54:44 +02:00
Benjamin Ritter
eda0bd69b3 Use IGD:2 and Pinhole Port Forwarding
Signed-off-by: Benjamin Ritter <Benjamin.Ritter@protonmail.com>
2024-10-24 21:54:30 +02:00
dependabot[bot]
2a56bdb0c8 Bump github.com/cloudflare/ipvs from 0.10.1 to 0.10.2
Bumps [github.com/cloudflare/ipvs](https://github.com/cloudflare/ipvs) from 0.10.1 to 0.10.2.
- [Release notes](https://github.com/cloudflare/ipvs/releases)
- [Commits](https://github.com/cloudflare/ipvs/compare/v0.10.1...v0.10.2)

---
updated-dependencies:
- dependency-name: github.com/cloudflare/ipvs
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-21 02:20:18 +00:00
Daniel Finneran
de0375610d Merge pull request #965 from kube-vip/dependabot/github_actions/anchore/sbom-action-0.17.3
Bump anchore/sbom-action from 0.17.2 to 0.17.3
2024-10-18 11:18:27 +02:00
Daniel Finneran
382024104a Merge pull request #964 from kube-vip/dependabot/go_modules/github.com/spf13/cobra-1.8.1
Bump github.com/spf13/cobra from 1.8.0 to 1.8.1
2024-10-18 11:18:08 +02:00
dependabot[bot]
e896b55c25 Bump anchore/sbom-action from 0.17.2 to 0.17.3
Bumps [anchore/sbom-action](https://github.com/anchore/sbom-action) from 0.17.2 to 0.17.3.
- [Release notes](https://github.com/anchore/sbom-action/releases)
- [Changelog](https://github.com/anchore/sbom-action/blob/main/RELEASE.md)
- [Commits](https://github.com/anchore/sbom-action/compare/v0.17.2...v0.17.3)

---
updated-dependencies:
- dependency-name: anchore/sbom-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-14 02:50:27 +00:00
dependabot[bot]
53ce87755a Bump github.com/spf13/cobra from 1.8.0 to 1.8.1
Bumps [github.com/spf13/cobra](https://github.com/spf13/cobra) from 1.8.0 to 1.8.1.
- [Release notes](https://github.com/spf13/cobra/releases)
- [Commits](https://github.com/spf13/cobra/compare/v1.8.0...v1.8.1)

---
updated-dependencies:
- dependency-name: github.com/spf13/cobra
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-14 02:31:14 +00:00
Daniel Finneran
750f78164f Merge pull request #918 from kube-vip/dependabot/go_modules/k8s.io/klog/v2-2.130.1
Bump k8s.io/klog/v2 from 2.120.1 to 2.130.1
2024-10-10 09:41:30 +01:00
Daniel Finneran
bf6cb8e39e Merge pull request #887 from kube-vip/dependabot/github_actions/docker/build-push-action-6
Bump docker/build-push-action from 5 to 6
2024-10-10 09:39:55 +01:00
Daniel Finneran
f58e110057 Update Makefile 2024-10-10 09:39:28 +01:00
dependabot[bot]
98db46c817 Bump k8s.io/klog/v2 from 2.120.1 to 2.130.1
Bumps [k8s.io/klog/v2](https://github.com/kubernetes/klog) from 2.120.1 to 2.130.1.
- [Release notes](https://github.com/kubernetes/klog/releases)
- [Changelog](https://github.com/kubernetes/klog/blob/main/RELEASE.md)
- [Commits](https://github.com/kubernetes/klog/compare/v2.120.1...v2.130.1)

---
updated-dependencies:
- dependency-name: k8s.io/klog/v2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-10 08:28:26 +00:00
Daniel Finneran
da9b440f1e Merge pull request #939 from kube-vip/dependabot/docker/alpine-3.20.3
Bump alpine from 3.20.0 to 3.20.3
2024-10-10 09:27:48 +01:00
dependabot[bot]
a18039373d Bump docker/build-push-action from 5 to 6
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 5 to 6.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/v5...v6)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-10 08:27:05 +00:00
Daniel Finneran
a9753fafd2 Merge pull request #960 from kube-vip/dependabot/docker/golang-1.23.2-alpine3.20
Bump golang from 1.23.1-alpine3.20 to 1.23.2-alpine3.20
2024-10-10 09:26:45 +01:00
Daniel Finneran
8aa0a6b9e0 Merge pull request #958 from p-strusiewiczsurmacki-mobica/control-plane-table-e2e
Added e2e tests for control-plane in routing table mode, fixed IPv6 issue
2024-10-07 17:00:48 +01:00
dependabot[bot]
8f16021e4c Bump golang from 1.23.1-alpine3.20 to 1.23.2-alpine3.20
Bumps golang from 1.23.1-alpine3.20 to 1.23.2-alpine3.20.

---
updated-dependencies:
- dependency-name: golang
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-07 02:27:00 +00:00
Patryk Strusiewicz-Surmacki
456d52d507 Added e2e tests for control-plane in routing table mode and fixed IPv6 issue
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk-pawel.strusiewicz-surmacki@external.telekom.de>
2024-10-03 17:11:57 +02:00
Daniel Finneran
4da24fb64f Merge pull request #957 from p-strusiewiczsurmacki-mobica/control-plane-table-mode
Routing Table mode for Control Plane
2024-10-03 11:27:15 +02:00
Daniel Finneran
c27044b521 Merge pull request #952 from l0wl3vel/upnp-forward-multiple-ports
UPNP: Assume that multiple ports can exist on a service
2024-10-02 13:23:20 +02:00
Patryk Strusiewicz-Surmacki
810cf89f97 Routing Table mode for Control Plane
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk-pawel.strusiewicz-surmacki@external.telekom.de>
2024-10-01 18:00:59 +02:00
Patryk Strusiewicz-Surmacki
d65af2c84f Fixed lastKnownGoodEndpoint not being set when in non-leader-election mode (#955)
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk-pawel.strusiewicz-surmacki@external.telekom.de>
2024-10-01 14:29:42 +02:00
Daniel Finneran
d30fda1d9d Merge pull request #956 from tenyo/lo-iface-scope
Add loInterfaceGlobalScope flag for enabling global scope for vip lo interface
2024-09-30 14:24:42 +02:00
tenyo
b6d4aa1632 add loInterfaceGlobalScope flag for enabling global scope for vip lo interface
Signed-off-by: tenyo <tgrozev@equinix.com>
2024-09-27 20:21:51 +00:00
Benjamin Ritter
b024d04d91 Assume that multiple ports can exist on a service
Fixes UPNP exposing only the port with the lowest numeric value. #951

Signed-off-by: Benjamin Ritter <Benjamin.Ritter@protonmail.com>
2024-09-24 16:06:43 +02:00
Daniel Finneran
6cdc7a86c4 Merge pull request #950 from l0wl3vel/upnp-per-service
Enable UPNP Port forwarding per service
2024-09-24 08:47:26 +01:00
Benjamin Ritter
c6f1c740fd feat: Gate UPNP port forwarding behind kube-vip.io/forwardUPNP annotation
Signed-off-by: Benjamin Ritter <Benjamin.Ritter@protonmail.com>
2024-09-22 10:31:32 +02:00
Daniel Finneran
95c43472e9 Update Makefile 2024-09-09 13:34:45 +01:00
dependabot[bot]
c8a222e244 Bump alpine from 3.20.0 to 3.20.3
Bumps alpine from 3.20.0 to 3.20.3.

---
updated-dependencies:
- dependency-name: alpine
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-09 08:30:04 +00:00
Daniel Finneran
37abb44a64 Merge pull request #940 from kube-vip/dependabot/docker/golang-1.23.1-alpine3.20
Bump golang from 1.22.6-alpine3.20 to 1.23.1-alpine3.20
2024-09-09 09:25:34 +01:00
dependabot[bot]
b4e6725a1a Bump golang from 1.22.6-alpine3.20 to 1.23.1-alpine3.20
Bumps golang from 1.22.6-alpine3.20 to 1.23.1-alpine3.20.

---
updated-dependencies:
- dependency-name: golang
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-09 02:29:55 +00:00
Daniel Finneran
b6410d9b4d Merge pull request #927 from kube-vip/dependabot/github_actions/anchore/sbom-action-0.17.2
Bump anchore/sbom-action from 0.17.0 to 0.17.2
2024-09-06 16:11:49 +03:00
Daniel Finneran
4bdfeffc96 Merge pull request #937 from thebsdbox/ipv6_egress
This adds ipv6 egress & test
2024-09-06 16:11:35 +03:00
Daniel Finneran
a32804dfee Update pkg/vip/util.go
I like it

Co-authored-by: Patryk Strusiewicz-Surmacki <137421299+p-strusiewiczsurmacki-mobica@users.noreply.github.com>
2024-09-06 12:31:03 +01:00
Dan Finneran
b24ce18d55 Fix test
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2024-09-05 12:40:24 +00:00
Dan Finneran
5512a08aac restored the exact behaviour for IPv4
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2024-09-05 12:22:41 +00:00
Dan Finneran
f438367d6e This adds ipv6 egress & test
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2024-09-05 12:08:39 +00:00
cdtzabra
62a724122c Update node_labeling.go 2024-09-03 12:19:51 +02:00
Daniel Finneran
fb86cb8687 Merge pull request #929 from linsite/cleanup-makefile
clean up Makefile
2024-09-02 15:59:31 +03:00
linmaolin
29a0dc6c07 clean up Makefile
fmt target is stale, just removing it, also simplify target is not working under 1.21 toolchain,
update it as well.

Signed-off-by: Lin Lin <linlin152@foxmail.com>
2024-08-28 11:57:40 +08:00
dependabot[bot]
82f3c6a491 Bump anchore/sbom-action from 0.17.0 to 0.17.2
Bumps [anchore/sbom-action](https://github.com/anchore/sbom-action) from 0.17.0 to 0.17.2.
- [Release notes](https://github.com/anchore/sbom-action/releases)
- [Commits](https://github.com/anchore/sbom-action/compare/v0.17.0...v0.17.2)

---
updated-dependencies:
- dependency-name: anchore/sbom-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-08-26 02:53:48 +00:00
Daniel Finneran
fbb2746d07 Merge pull request #926 from p-strusiewiczsurmacki-mobica/svc-auto-interface
Auto network interface discovery for services
2024-08-23 17:55:26 +01:00
Patryk Strusiewicz-Surmacki
185d8bc484 Auto network interface discovery for services
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk-pawel.strusiewicz-surmacki@external.telekom.de>
2024-08-23 15:15:11 +02:00
cdtzabra
db88185c40 Merge pull request #1 from cdtzabra/cdtzabra-patch-1
Ensuring nodelabel will be always present
2024-08-21 18:24:01 +02:00
cdtzabra
611cb0288f Ensuring nodelabel will be always present 2024-08-21 18:22:57 +02:00
Daniel Finneran
b18bdd0fb9 Merge pull request #872 from kube-vip/dependabot/go_modules/github.com/stretchr/testify-1.9.0
Bump github.com/stretchr/testify from 1.8.4 to 1.9.0
2024-08-15 12:46:28 +01:00
Daniel Finneran
8ef0d459c0 Merge pull request #902 from kube-vip/dependabot/github_actions/anchore/sbom-action-0.17.0
Bump anchore/sbom-action from 0.16.0 to 0.17.0
2024-08-12 15:16:44 +02:00
Daniel Finneran
41bc78bc8f Merge pull request #915 from kube-vip/dependabot/docker/golang-1.22.6-alpine3.20
Bump golang from 1.22.4-alpine3.20 to 1.22.6-alpine3.20
2024-08-12 15:16:30 +02:00
Daniel Finneran
05984b9860 Merge pull request #910 from M0NsTeRRR/fix/ipv6-port-join
fix: ipv6 host and port join
2024-08-12 15:16:13 +02:00
dependabot[bot]
82b1e8536b Bump golang from 1.22.4-alpine3.20 to 1.22.6-alpine3.20
Bumps golang from 1.22.4-alpine3.20 to 1.22.6-alpine3.20.

---
updated-dependencies:
- dependency-name: golang
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-08-12 02:26:32 +00:00
Daniel Finneran
425cb92dee Merge pull request #904 from M0NsTeRRR/main
fix: set vip_cidr default value
2024-08-07 10:37:53 +02:00
Ludovic Ortega
9470edbea9 fix: ipv6 host and port join
Signed-off-by: Ludovic Ortega <ludovic.ortega@adminafk.fr>
2024-08-07 00:48:59 +02:00
Ludovic Ortega
a5d6846608 fix: set vip_cidr default value
Signed-off-by: Ludovic Ortega <ludovic.ortega@adminafk.fr>
2024-07-23 21:15:12 +02:00
Daniel Finneran
04ce471366 Update Makefile 2024-07-23 09:27:46 +01:00
Daniel Finneran
6c090701ea Merge pull request #897 from TilBlechschmidt/bug/dhcp-renew-failure
Change service interface to `macvlan` when using DHCP
2024-07-23 09:25:41 +01:00
dependabot[bot]
87fd49ac98 Bump anchore/sbom-action from 0.16.0 to 0.17.0
Bumps [anchore/sbom-action](https://github.com/anchore/sbom-action) from 0.16.0 to 0.17.0.
- [Release notes](https://github.com/anchore/sbom-action/releases)
- [Commits](https://github.com/anchore/sbom-action/compare/v0.16.0...v0.17.0)

---
updated-dependencies:
- dependency-name: anchore/sbom-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-07-22 02:47:10 +00:00
Til Blechschmidt
a0a19ea3fa Change service interface to macvlan when using DHCP
When using DHCP for LB services, the resulting IP was assigned to the
`serviceInterface` while most (not all) DHCP communication was done
through a per-service `macvlan` interface that is created on demand.

This has been the cause of DHCP lease renewal failures for some users,
as the response packets from the server never reached kube-vip. For more
details, see issue #871.

To remedy this, the primary interface used for a service is now being
set to the `macvlan`. Consequently, the IP address is also assigned to
it.

As a result, all traffic related to an LB service (DHCP or not) is now
originating from and sent to the per-service `macvlan` interface that
is tied to the user-configured `serviceInterface`.

Fixes #871

Signed-off-by: Til Blechschmidt <me@tibl.dev>
2024-07-19 12:26:43 +02:00
Daniel Finneran
a571d0a9c2 Merge pull request #894 from thebsdbox/manifest_fix
Manifest fix
2024-07-11 09:14:40 +01:00
Dan Finneran
6f267462bb linting fixes
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2024-07-11 08:03:51 +00:00
Dan Finneran
a52e9a1818 adds CI test
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2024-07-10 15:24:32 +00:00
Dan Finneran
e883c1ea5d fixes manifest generation
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2024-07-10 15:15:24 +00:00
Marcel Fest
59951cbd4b [Bugfix] Parse the routingTableID correctly (#889)
* Parse the routingTableID correctly [rtnetlink.h](55027e6899/include/uapi/linux/rtnetlink.h\#L354C15-L354C25) says RT_TABLE_MAX=0xFFFFFFFF

Signed-off-by: Marcel Fest <marcel.fest@telekom.de>

* Better error handling for int check

Signed-off-by: Marcel Fest <marcel.fest@telekom.de>

* Better error message + typo fix

Signed-off-by: Marcel Fest <marcel.fest@telekom.de>

* Use MaxInt instead of MaxUint

Signed-off-by: Marcel Fest <marcel.fest@telekom.de>

---------

Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
2024-06-26 12:29:07 +02:00
Daniel Finneran
9abce4a215 Update Makefile 2024-06-21 15:31:03 +01:00
Daniel Finneran
0b33aa64fc Merge pull request #884 from thebsdbox/go_security
bump golang for security fix
2024-06-21 15:30:47 +01:00
Dan Finneran
57980bd23f bump golang for security fix
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2024-06-21 14:18:58 +00:00
Daniel Finneran
69f4c389c5 Merge pull request #883 from thebsdbox/prometheus_fix
This allows prometheus configuration to be specified in the cli
2024-06-21 15:18:28 +01:00
Dan Finneran
f56c9b7480 This allows prometheus configuration to be specified in the cli
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2024-06-21 13:47:14 +00:00
dependabot[bot]
f8af9c37af Bump github.com/stretchr/testify from 1.8.4 to 1.9.0
Bumps [github.com/stretchr/testify](https://github.com/stretchr/testify) from 1.8.4 to 1.9.0.
- [Release notes](https://github.com/stretchr/testify/releases)
- [Commits](https://github.com/stretchr/testify/compare/v1.8.4...v1.9.0)

---
updated-dependencies:
- dependency-name: github.com/stretchr/testify
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-06-10 02:59:36 +00:00
Daniel Finneran
c16f634cf7 Merge pull request #869 from kube-vip/dependabot/go_modules/github.com/osrg/gobgp/v3-3.27.0
Bump github.com/osrg/gobgp/v3 from 3.25.0 to 3.27.0
2024-06-05 11:06:15 +01:00
dependabot[bot]
5df534a1e7 Bump github.com/osrg/gobgp/v3 from 3.25.0 to 3.27.0
Bumps [github.com/osrg/gobgp/v3](https://github.com/osrg/gobgp) from 3.25.0 to 3.27.0.
- [Release notes](https://github.com/osrg/gobgp/releases)
- [Changelog](https://github.com/osrg/gobgp/blob/master/.goreleaser.yml)
- [Commits](https://github.com/osrg/gobgp/compare/v3.25.0...v3.27.0)

---
updated-dependencies:
- dependency-name: github.com/osrg/gobgp/v3
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-06-04 13:20:19 +00:00
Daniel Finneran
ee535938b4 Merge pull request #861 from kube-vip/dependabot/go_modules/github.com/onsi/ginkgo/v2-2.19.0
Bump github.com/onsi/ginkgo/v2 from 2.17.2 to 2.19.0
2024-06-04 14:19:14 +01:00
Daniel Finneran
0df8a0dff4 Merge pull request #862 from kube-vip/dependabot/docker/alpine-3.20.0
Bump alpine from 3.19.1 to 3.20.0
2024-06-04 14:17:22 +01:00
Daniel Finneran
0e2a10535b Merge pull request #860 from kube-vip/dependabot/github_actions/anchore/sbom-action-0.16.0
Bump anchore/sbom-action from 0.15.11 to 0.16.0
2024-06-04 14:17:08 +01:00
Daniel Finneran
b5d9ede6f8 Merge pull request #855 from p-strusiewiczsurmacki-mobica/lbclass-filtering
New service class filtering behavior
2024-06-04 14:16:51 +01:00
Daniel Finneran
94bad6d53b Merge pull request #868 from murphp15/main
Small correction to docs on retryPeriod property
2024-06-04 14:16:38 +01:00
Paul Murphy
927bb95ead Update kube-vip.go 2024-06-04 13:33:20 +01:00
Paul Murphy
7b96ebc7d4 Update config_types.go 2024-06-04 12:34:41 +01:00
Paul Murphy
5b05f365f1 Update kube-vip.go 2024-06-04 12:33:19 +01:00
dependabot[bot]
cd3d8a592c Bump alpine from 3.19.1 to 3.20.0
Bumps alpine from 3.19.1 to 3.20.0.

---
updated-dependencies:
- dependency-name: alpine
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-05-27 02:42:31 +00:00
dependabot[bot]
e69fadf19b Bump github.com/onsi/ginkgo/v2 from 2.17.2 to 2.19.0
Bumps [github.com/onsi/ginkgo/v2](https://github.com/onsi/ginkgo) from 2.17.2 to 2.19.0.
- [Release notes](https://github.com/onsi/ginkgo/releases)
- [Changelog](https://github.com/onsi/ginkgo/blob/master/CHANGELOG.md)
- [Commits](https://github.com/onsi/ginkgo/compare/v2.17.2...v2.19.0)

---
updated-dependencies:
- dependency-name: github.com/onsi/ginkgo/v2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-05-27 02:35:13 +00:00
dependabot[bot]
5ded2d7574 Bump anchore/sbom-action from 0.15.11 to 0.16.0
Bumps [anchore/sbom-action](https://github.com/anchore/sbom-action) from 0.15.11 to 0.16.0.
- [Release notes](https://github.com/anchore/sbom-action/releases)
- [Commits](https://github.com/anchore/sbom-action/compare/v0.15.11...v0.16.0)

---
updated-dependencies:
- dependency-name: anchore/sbom-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-05-27 02:12:43 +00:00
Marcel Fest
c683bb879e Merge pull request #854 from kube-vip/hotfix/route-deletion
[Hotfix] Routes get not deleted when kube-vip is running without LeaderElection/ServiceElection in Table Mode
2024-05-17 15:53:57 +02:00
Daniel Finneran
392583d460 Merge pull request #853 from M0NsTeRRR/main
feat: generate VIPCIDR if not value is set
2024-05-17 14:15:23 +01:00
Patryk Strusiewicz-Surmacki
abf49f2fa6 New service class filtering behavior
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk-pawel.strusiewicz-surmacki@external.telekom.de>
2024-05-17 14:45:30 +02:00
Marcel Fest
25c2532e74 when in table mode we always want to clean routes
Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
2024-05-17 12:30:53 +02:00
Ludovic Ortega
28918e839f feat: generate VIPCIDR if not value is set
Signed-off-by: Ludovic Ortega <ludovic.ortega@adminafk.fr>
2024-05-16 22:42:53 +02:00
Daniel Finneran
1620e4c890 Merge pull request #846 from testwill/close_file
fix: close file
2024-05-16 09:19:24 +01:00
guoguangwu
c8bdf61a87 fix: close file
Signed-off-by: guoguangwu <guoguangwug@gmail.com>
2024-05-15 19:13:41 +08:00
Daniel Finneran
e9835aa981 Merge pull request #847 from kube-vip/dependabot/docker/golang-1.22.3-alpine3.18
Bump golang from 1.22.2-alpine3.18 to 1.22.3-alpine3.18
2024-05-15 11:59:21 +01:00
dependabot[bot]
ca3dad817d Bump golang from 1.22.2-alpine3.18 to 1.22.3-alpine3.18
Bumps golang from 1.22.2-alpine3.18 to 1.22.3-alpine3.18.

---
updated-dependencies:
- dependency-name: golang
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-05-13 02:39:51 +00:00
Daniel Finneran
cb29d7cb17 Merge pull request #840 from kube-vip/dependabot/go_modules/github.com/onsi/gomega-1.33.1
Bump github.com/onsi/gomega from 1.32.0 to 1.33.1
2024-05-09 08:49:20 +01:00
Daniel Finneran
0fa7cbdab8 Merge pull request #834 from kube-vip/dependabot/github_actions/anchore/sbom-action-0.15.11
Bump anchore/sbom-action from 0.15.10 to 0.15.11
2024-05-09 08:49:08 +01:00
dependabot[bot]
0038c27fec Bump github.com/onsi/gomega from 1.32.0 to 1.33.1
Bumps [github.com/onsi/gomega](https://github.com/onsi/gomega) from 1.32.0 to 1.33.1.
- [Release notes](https://github.com/onsi/gomega/releases)
- [Changelog](https://github.com/onsi/gomega/blob/master/CHANGELOG.md)
- [Commits](https://github.com/onsi/gomega/compare/v1.32.0...v1.33.1)

---
updated-dependencies:
- dependency-name: github.com/onsi/gomega
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-05-08 14:01:32 +00:00
Daniel Finneran
4c19a3370c Merge pull request #826 from kube-vip/dependabot/go_modules/github.com/prometheus/client_golang-1.19.0
Bump github.com/prometheus/client_golang from 1.18.0 to 1.19.0
2024-05-08 14:59:30 +01:00
Daniel Finneran
25abee70cd Merge pull request #833 from kube-vip/dependabot/go_modules/github.com/onsi/ginkgo/v2-2.17.2
Bump github.com/onsi/ginkgo/v2 from 2.15.0 to 2.17.2
2024-05-08 14:58:37 +01:00
Daniel Finneran
057a32d191 Merge pull request #838 from p-strusiewiczsurmacki-mobica/route-deletion-fix
Fixed route deletion when route is used by more than one service
2024-05-08 14:58:21 +01:00
Daniel Finneran
b33a7b6d32 Merge pull request #837 from starbops/fix-835
fix: set service's uid in activeService map for inactive services
2024-05-08 14:57:58 +01:00
Patryk Strusiewicz-Surmacki
ba0c9282e7 Fixed route deletion when route is used by more than one service
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk-pawel.strusiewicz-surmacki@external.telekom.de>
2024-04-30 14:44:26 +02:00
Zespre Schmidt
a431daab42 fix: set service's uid in activeService map for inactive services
Signed-off-by: Zespre Schmidt <starbops@zespre.com>
2024-04-30 16:31:10 +08:00
dependabot[bot]
54e4334b9f Bump anchore/sbom-action from 0.15.10 to 0.15.11
Bumps [anchore/sbom-action](https://github.com/anchore/sbom-action) from 0.15.10 to 0.15.11.
- [Release notes](https://github.com/anchore/sbom-action/releases)
- [Commits](https://github.com/anchore/sbom-action/compare/v0.15.10...v0.15.11)

---
updated-dependencies:
- dependency-name: anchore/sbom-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-04-29 02:55:01 +00:00
dependabot[bot]
6545a5aaab Bump github.com/onsi/ginkgo/v2 from 2.15.0 to 2.17.2
Bumps [github.com/onsi/ginkgo/v2](https://github.com/onsi/ginkgo) from 2.15.0 to 2.17.2.
- [Release notes](https://github.com/onsi/ginkgo/releases)
- [Changelog](https://github.com/onsi/ginkgo/blob/master/CHANGELOG.md)
- [Commits](https://github.com/onsi/ginkgo/compare/v2.15.0...v2.17.2)

---
updated-dependencies:
- dependency-name: github.com/onsi/ginkgo/v2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-04-29 02:13:32 +00:00
Daniel Finneran
2872256a89 Merge pull request #832 from ShivanshVij/main
fix: unecessary string modification
2024-04-25 08:26:35 +01:00
Shivansh Vij
a1ae304d07 fix: unecessary string modification
Signed-off-by: Shivansh Vij <shivanshvij@loopholelabs.io>
2024-04-24 12:32:27 -07:00
dependabot[bot]
c90d2043f0 Bump github.com/prometheus/client_golang from 1.18.0 to 1.19.0
Bumps [github.com/prometheus/client_golang](https://github.com/prometheus/client_golang) from 1.18.0 to 1.19.0.
- [Release notes](https://github.com/prometheus/client_golang/releases)
- [Changelog](https://github.com/prometheus/client_golang/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prometheus/client_golang/compare/v1.18.0...v1.19.0)

---
updated-dependencies:
- dependency-name: github.com/prometheus/client_golang
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-04-22 02:47:11 +00:00
Daniel Finneran
722c47fc08 Update Makefile 2024-04-18 18:11:51 +01:00
Daniel Finneran
27fae664fe Merge pull request #821 from kube-vip/dependabot/go_modules/go.etcd.io/etcd/client/v3-3.5.13
Bump go.etcd.io/etcd/client/v3 from 3.5.11 to 3.5.13
2024-04-18 15:12:18 +01:00
Daniel Finneran
7349576e5b Merge pull request #820 from thebsdbox/bgp_err
Errors are being ignored
2024-04-18 14:59:08 +01:00
dependabot[bot]
1ab5047941 Bump go.etcd.io/etcd/client/v3 from 3.5.11 to 3.5.13
Bumps [go.etcd.io/etcd/client/v3](https://github.com/etcd-io/etcd) from 3.5.11 to 3.5.13.
- [Release notes](https://github.com/etcd-io/etcd/releases)
- [Commits](https://github.com/etcd-io/etcd/compare/v3.5.11...v3.5.13)

---
updated-dependencies:
- dependency-name: go.etcd.io/etcd/client/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-04-18 13:52:10 +00:00
Dan Finneran
950264e403 lint fixes
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2024-04-18 13:44:08 +00:00
Dan Finneran
0686b92376 Errors are being ignored
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2024-04-18 13:38:38 +00:00
Daniel Finneran
b7ebb21dc0 Merge pull request #796 from kube-vip/dependabot/go_modules/github.com/onsi/gomega-1.32.0
Bump github.com/onsi/gomega from 1.30.0 to 1.32.0
2024-04-18 14:22:50 +01:00
Daniel Finneran
ab904e2e18 Merge pull request #819 from thebsdbox/example
Examples and fixes to annotation interface
2024-04-18 14:22:37 +01:00
Dan Finneran
a5d4d0ca98 Examples and fixes to annotation interface
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2024-04-18 13:02:21 +00:00
dependabot[bot]
7fb301d3b3 Bump github.com/onsi/gomega from 1.30.0 to 1.32.0
Bumps [github.com/onsi/gomega](https://github.com/onsi/gomega) from 1.30.0 to 1.32.0.
- [Release notes](https://github.com/onsi/gomega/releases)
- [Changelog](https://github.com/onsi/gomega/blob/master/CHANGELOG.md)
- [Commits](https://github.com/onsi/gomega/compare/v1.30.0...v1.32.0)

---
updated-dependencies:
- dependency-name: github.com/onsi/gomega
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-04-18 10:01:12 +00:00
Daniel Finneran
aa4da2f72a Merge pull request #816 from thebsdbox/interface_annotation
Adds annotation support for service interfaces.
2024-04-18 11:00:33 +01:00
Daniel Finneran
5dc91e6b3b Merge pull request #806 from kube-vip/dependabot/go_modules/github.com/osrg/gobgp/v3-3.25.0
Bump github.com/osrg/gobgp/v3 from 3.22.0 to 3.25.0
2024-04-18 10:58:29 +01:00
dependabot[bot]
658ca8697e Bump github.com/osrg/gobgp/v3 from 3.22.0 to 3.25.0
Bumps [github.com/osrg/gobgp/v3](https://github.com/osrg/gobgp) from 3.22.0 to 3.25.0.
- [Release notes](https://github.com/osrg/gobgp/releases)
- [Changelog](https://github.com/osrg/gobgp/blob/master/.goreleaser.yml)
- [Commits](https://github.com/osrg/gobgp/compare/v3.22.0...v3.25.0)

---
updated-dependencies:
- dependency-name: github.com/osrg/gobgp/v3
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-04-18 09:47:41 +00:00
Daniel Finneran
979c016d98 Merge pull request #817 from thebsdbox/linting
fixes to linting
2024-04-18 10:45:32 +01:00
Dan Finneran
8e4abea78e fixes to linting
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2024-04-18 09:35:04 +00:00
Daniel Finneran
3caedde7fe Merge pull request #801 from kube-vip/dependabot/github_actions/anchore/sbom-action-0.15.10
Bump anchore/sbom-action from 0.15.8 to 0.15.10
2024-04-18 10:24:13 +01:00
Daniel Finneran
fb43a48a87 Merge pull request #792 from kube-vip/dependabot/go_modules/k8s.io/apimachinery-0.29.3
Bump k8s.io/apimachinery from 0.29.1 to 0.29.3
2024-04-18 10:23:50 +01:00
Daniel Finneran
12e298bb22 Merge pull request #807 from kube-vip/dependabot/docker/golang-1.22.2-alpine3.18
Bump golang from 1.22.0-alpine3.18 to 1.22.2-alpine3.18
2024-04-18 10:23:32 +01:00
Daniel Finneran
f514269408 Merge pull request #778 from thebsdbox/remove_start
Removal of deprecated start command
2024-04-18 10:22:55 +01:00
Daniel Finneran
2c5d366487 Merge pull request #770 from lubronzhan/topic/lubron/fix-589
Mirror traffic of service interface to a dest interface
2024-04-18 10:22:32 +01:00
Daniel Finneran
fea05fa3ad Merge branch 'main' into topic/lubron/fix-589 2024-04-18 10:10:23 +01:00
Dan Finneran
5c515f0c0d Adds annotation support for service interfaces.
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2024-04-18 08:56:36 +00:00
Daniel Finneran
b0acf844ca Merge pull request #812 from wyike/fix_masquerade_issues
Fixes on masquerade forwarding mode
2024-04-18 09:54:11 +01:00
Daniel Finneran
bd3df6b616 Merge pull request #811 from d-uzlov/fix-nodename
Use node name for service election and lease holder name instead of hostname
2024-04-17 15:32:16 +01:00
Yike Wang
5100cd0e9a Fixes on masquerade forwarding mode
Signed-off-by: Yike Wang <yikew@vmware.com>
2024-04-17 08:59:44 +08:00
Danil Uzlov
04d863310b improve readability
Signed-off-by: Danil Uzlov <36223296+d-uzlov@users.noreply.github.com>
2024-04-11 03:35:02 +07:00
Danil Uzlov
29713acfeb fix golangci-lint better
Signed-off-by: Danil Uzlov <36223296+d-uzlov@users.noreply.github.com>
2024-04-11 03:32:49 +07:00
Danil Uzlov
8d607b89be fix golangci-lint
Signed-off-by: Danil Uzlov <36223296+d-uzlov@users.noreply.github.com>
2024-04-11 03:27:33 +07:00
Danil Uzlov
877ee75e75 go fmt
Signed-off-by: Danil Uzlov <36223296+d-uzlov@users.noreply.github.com>
2024-04-11 03:20:54 +07:00
Danil Uzlov
d3da4d934a check node names in services test
Signed-off-by: Danil Uzlov <36223296+d-uzlov@users.noreply.github.com>
2024-04-11 02:04:41 +07:00
Debian
c3e9a13f1c add hostname e2e test
Signed-off-by: Danil Uzlov <36223296+d-uzlov@users.noreply.github.com>
2024-04-11 02:04:36 +07:00
Danil Uzlov
59ad5ec9a2 fix e2e tests
Signed-off-by: Danil Uzlov <36223296+d-uzlov@users.noreply.github.com>
2024-04-10 21:28:09 +07:00
Danil Uzlov
8a80a72d94 fix golangci-lint
Signed-off-by: Danil Uzlov <36223296+d-uzlov@users.noreply.github.com>
2024-04-10 18:21:15 +07:00
Danil Uzlov
cb1e63c302 fix unit tests
Signed-off-by: Danil Uzlov <36223296+d-uzlov@users.noreply.github.com>
2024-04-10 17:58:20 +07:00
Danil Uzlov
e87ef6b3b8 go fmt
Signed-off-by: Danil Uzlov <36223296+d-uzlov@users.noreply.github.com>
2024-04-10 17:44:58 +07:00
Danil Uzlov
f87665c67f add fallback for hostname when node name is not available
Signed-off-by: Danil Uzlov <36223296+d-uzlov@users.noreply.github.com>
2024-04-10 17:43:53 +07:00
Daniel Finneran
c9d11e7123 Merge pull request #795 from adavis10006/fix-ddns
fix: add ddns address as a network
2024-04-10 09:59:55 +01:00
Daniel Finneran
51512201ea Merge pull request #809 from starbops/iptables-legacy
fix: add iptables-legacy package
2024-04-10 09:59:25 +01:00
Danil Uzlov
e37091c900 use node name instead of hostname
Signed-off-by: Danil Uzlov <36223296+d-uzlov@users.noreply.github.com>
2024-04-09 18:37:11 +07:00
Zespre Schmidt
b484be799e fix: add iptables-legacy package
Signed-off-by: Zespre Schmidt <starbops@zespre.com>
2024-04-08 15:21:56 +08:00
Shang-Kuei, Chen
2134c6b1fe fix: add ddns address as a network
Signed-off-by: Shang-Kuei, Chen <adavis10006@gmail.com>
2024-04-08 14:37:16 +08:00
dependabot[bot]
fbc6904fa0 Bump golang from 1.22.0-alpine3.18 to 1.22.2-alpine3.18
Bumps golang from 1.22.0-alpine3.18 to 1.22.2-alpine3.18.

---
updated-dependencies:
- dependency-name: golang
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-04-08 02:41:21 +00:00
Marcel Fest
0cedf6a97d Merge pull request #805 from Bao0ne/offline
fix: Modify the ImagePullPolicy used by cli manifest
2024-04-07 11:50:42 +02:00
wang
932fe09870 fix: Modify the ImagePullPolicy used by cli manifest
Signed-off-by: wang <wanglei@tdology.com>
2024-04-06 17:11:01 +08:00
Daniel Finneran
f1cf044eae Merge pull request #782 from lou-lan/fix/masquerade
Add masquerade mode
2024-04-02 11:06:22 +01:00
dependabot[bot]
a10a478f24 Bump anchore/sbom-action from 0.15.8 to 0.15.10
Bumps [anchore/sbom-action](https://github.com/anchore/sbom-action) from 0.15.8 to 0.15.10.
- [Release notes](https://github.com/anchore/sbom-action/releases)
- [Commits](https://github.com/anchore/sbom-action/compare/v0.15.8...v0.15.10)

---
updated-dependencies:
- dependency-name: anchore/sbom-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-04-01 02:11:42 +00:00
lou-lan
d1541c3464 Add masquerade mode
Signed-off-by: lou-lan <loulan@loulan.me>
2024-03-20 19:23:05 +08:00
dependabot[bot]
4e3717f089 Bump k8s.io/apimachinery from 0.29.1 to 0.29.3
Bumps [k8s.io/apimachinery](https://github.com/kubernetes/apimachinery) from 0.29.1 to 0.29.3.
- [Commits](https://github.com/kubernetes/apimachinery/compare/v0.29.1...v0.29.3)

---
updated-dependencies:
- dependency-name: k8s.io/apimachinery
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-18 02:47:29 +00:00
Daniel Finneran
2aa799c9d0 Merge pull request #773 from kube-vip/dependabot/go_modules/go.uber.org/zap-1.27.0
Bump go.uber.org/zap from 1.26.0 to 1.27.0
2024-03-10 16:31:49 +00:00
Daniel Finneran
bb08489898 Merge pull request #783 from lubronzhan/topic/lubron/fix-781
Fix netmask of ipvs to consider ipv6 case
2024-03-10 16:30:49 +00:00
Daniel Finneran
1ea277f43e Merge pull request #777 from thebsdbox/egress_fix
Fixes conntrack deleting wrong connections and cleaning old SNAT rules
2024-03-10 16:23:45 +00:00
Daniel Finneran
2c4ff6949a Update Makefile for next release 2024-03-10 17:23:30 +01:00
lubronzhan
1a4bd01332 Refactor
Signed-off-by: lubronzhan <lubronzhan@gmail.com>
2024-03-10 09:13:16 -07:00
lubronzhan
9e2a13c133 Fix netmask of ipvs to consider ipv6 case
Signed-off-by: lubronzhan <lubronzhan@gmail.com>
2024-03-09 22:38:07 -08:00
Dan Finneran
39fbbc57ac linting fixes
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2024-03-01 14:14:56 +00:00
Dan Finneran
b9f8c3b0f5 Removal of deprecated start command
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2024-03-01 12:29:05 +00:00
Daniel Finneran
ac5895a311 Merge pull request #775 from lubronzhan/topic/lubron/change_fatal
Exit(1) if service's leaderelection.onStartedLeading error out instead of silently continue
2024-03-01 11:05:44 +00:00
Daniel Finneran
e7eaa70fd4 Merge pull request #776 from lubronzhan/topic/lubron/fix-771
Fix flaky e2e test
2024-03-01 11:05:23 +00:00
Dan Finneran
76cf59c7a7 Fixes issues around conntrack deleting wrong connections and cleaning up old vip SNAT entries
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2024-03-01 10:54:50 +00:00
lubronzhan
a05ecbccb7 Consider 500 status code as a positive result of reaching control plane VIP
Signed-off-by: lubronzhan <lubronzhan@gmail.com>
2024-02-29 22:25:22 -08:00
lubronzhan
c531414542 Exit 1 if service's leaderelection onStartedLeading error out instead of silently continue
Signed-off-by: lubronzhan <lubronzhan@gmail.com>
2024-02-29 21:58:29 -08:00
lubronzhan
70b4728492 Resolve comments
Signed-off-by: lubronzhan <lubronzhan@gmail.com>
2024-02-29 21:48:20 -08:00
Lubron Zhan
835007b07a Refactor
Signed-off-by: Lubron Zhan <lubronzhan@gmail.com>
2024-02-29 21:48:20 -08:00
Lubron Zhan
6d0c132519 Try clean up before deleting
Signed-off-by: Lubron Zhan <lubronzhan@gmail.com>
2024-02-29 21:48:20 -08:00
Lubron Zhan
485cf6a0dd Fix the variable
Signed-off-by: Lubron Zhan <lubronzhan@gmail.com>
2024-02-29 21:48:20 -08:00
Lubron Zhan
1338e4fcd3 Move mirroring traffic code to servicesWatcher
Signed-off-by: Lubron Zhan <lubronzhan@gmail.com>
2024-02-29 21:48:20 -08:00
lubronzhan
981355d910 Mirror traffic of service interface to a dest interface
Signed-off-by: lubronzhan <lubronzhan@gmail.com>
2024-02-29 21:48:20 -08:00
Daniel Finneran
3d5f1a6fa3 Update Makefile for new release 2024-02-26 09:45:58 +00:00
dependabot[bot]
e89d6f9f00 Bump go.uber.org/zap from 1.26.0 to 1.27.0
Bumps [go.uber.org/zap](https://github.com/uber-go/zap) from 1.26.0 to 1.27.0.
- [Release notes](https://github.com/uber-go/zap/releases)
- [Changelog](https://github.com/uber-go/zap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/uber-go/zap/compare/v1.26.0...v1.27.0)

---
updated-dependencies:
- dependency-name: go.uber.org/zap
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-26 02:56:34 +00:00
Daniel Finneran
a5ec16e1e8 Merge pull request #768 from thebsdbox/egress_fix
fixes a bug that wouldn't return CIDRs for egress
2024-02-21 16:11:42 +00:00
Dan Finneran
8de44b9253 fixes a bug that wouldn't return CIDRs for egress
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2024-02-21 15:25:40 +00:00
Daniel Finneran
911d4c0796 Merge pull request #757 from kube-vip/dependabot/go_modules/go.etcd.io/etcd/api/v3-3.5.12
Bump go.etcd.io/etcd/api/v3 from 3.5.11 to 3.5.12
2024-02-21 14:35:19 +00:00
Daniel Finneran
b370681de4 Merge pull request #759 from kube-vip/dependabot/go_modules/golang.org/x/sys-0.17.0
Bump golang.org/x/sys from 0.16.0 to 0.17.0
2024-02-21 14:34:48 +00:00
Daniel Finneran
9b63a6e77a Merge pull request #764 from kube-vip/dependabot/go_modules/sigs.k8s.io/kind-0.22.0
Bump sigs.k8s.io/kind from 0.20.0 to 0.22.0
2024-02-21 14:34:33 +00:00
Daniel Finneran
56d57e7fae Merge pull request #763 from p-strusiewiczsurmacki-mobica/clean-routes
Added possibility to remove redundant routes
2024-02-21 14:31:13 +00:00
Patryk Strusiewicz-Surmacki
ba061e4475 Add protocol to legacy routes
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk-pawel.strusiewicz-surmacki@external.telekom.de>
2024-02-21 11:41:51 +01:00
Daniel Finneran
6ddd053bce Merge pull request #765 from lou-lan/fix/ipvs
Fix IPVS service error: netlink receive invalid argument
2024-02-20 09:13:52 +00:00
Patryk Strusiewicz-Surmacki
f12d340134 Fixed concurrent map writes issue
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk-pawel.strusiewicz-surmacki@external.telekom.de>
2024-02-20 10:08:29 +01:00
Patryk Strusiewicz-Surmacki
262ce70310 Changed default port, fixed typo, added route clean enable flag
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk-pawel.strusiewicz-surmacki@external.telekom.de>
2024-02-19 14:41:17 +01:00
Patryk Strusiewicz-Surmacki
cce895e071 Added possibility to remove redundant routes
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk-pawel.strusiewicz-surmacki@external.telekom.de>
2024-02-19 14:41:17 +01:00
lou-lan
388b6ca27f Fix IPVS service error: netlink receive invalid argument
Signed-off-by: lou-lan <loulan@loulan.me>
2024-02-19 16:39:14 +08:00
dependabot[bot]
0d27273ded Bump sigs.k8s.io/kind from 0.20.0 to 0.22.0
Bumps [sigs.k8s.io/kind](https://github.com/kubernetes-sigs/kind) from 0.20.0 to 0.22.0.
- [Release notes](https://github.com/kubernetes-sigs/kind/releases)
- [Commits](https://github.com/kubernetes-sigs/kind/compare/v0.20.0...v0.22.0)

---
updated-dependencies:
- dependency-name: sigs.k8s.io/kind
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-19 02:07:51 +00:00
Daniel Finneran
7b7746b55f Merge pull request #760 from kube-vip/dependabot/docker/golang-1.22.0-alpine3.18
Bump golang from 1.21.6-alpine3.18 to 1.22.0-alpine3.18
2024-02-15 17:13:28 +00:00
Daniel Finneran
b666a95961 Merge pull request #761 from p-strusiewiczsurmacki-mobica/endpoints-common
Added common endpoint provider interface and fixed route deletion iss…
2024-02-15 17:13:11 +00:00
Patryk Strusiewicz-Surmacki
3534116d70 Fixed BGP issues
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk-pawel.strusiewicz-surmacki@external.telekom.de>
2024-02-14 17:30:37 +01:00
Patryk Strusiewicz-Surmacki
107464fa1a Changed exist error chack from syscall to os
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk-pawel.strusiewicz-surmacki@external.telekom.de>
2024-02-13 16:32:51 +01:00
Patryk Strusiewicz-Surmacki
814bf3d18f Added common endpoint provider interface and fixed route deletion issues in routing table mode
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk-pawel.strusiewicz-surmacki@external.telekom.de>
2024-02-13 16:14:13 +01:00
dependabot[bot]
6503d7bec5 Bump golang from 1.21.6-alpine3.18 to 1.22.0-alpine3.18
Bumps golang from 1.21.6-alpine3.18 to 1.22.0-alpine3.18.

---
updated-dependencies:
- dependency-name: golang
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-12 03:03:12 +00:00
dependabot[bot]
c5e00d8660 Bump golang.org/x/sys from 0.16.0 to 0.17.0
Bumps [golang.org/x/sys](https://github.com/golang/sys) from 0.16.0 to 0.17.0.
- [Commits](https://github.com/golang/sys/compare/v0.16.0...v0.17.0)

---
updated-dependencies:
- dependency-name: golang.org/x/sys
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-12 02:54:17 +00:00
dependabot[bot]
409e188469 Bump go.etcd.io/etcd/api/v3 from 3.5.11 to 3.5.12
Bumps [go.etcd.io/etcd/api/v3](https://github.com/etcd-io/etcd) from 3.5.11 to 3.5.12.
- [Release notes](https://github.com/etcd-io/etcd/releases)
- [Commits](https://github.com/etcd-io/etcd/compare/v3.5.11...v3.5.12)

---
updated-dependencies:
- dependency-name: go.etcd.io/etcd/api/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-12 02:54:07 +00:00
Daniel Finneran
8ccfdeca05 Merge pull request #750 from Wielewout/gen-manifests
fix: print manifests to stdout
2024-02-06 19:53:41 +01:00
Wout Van De Wiel
f933079da0 fix: print manifests to stdout
Signed-off-by: Wout Van De Wiel <wout.vandewiel@accelleran.com>
2024-02-06 18:42:01 +01:00
Daniel Finneran
b64243a3da Update ci.yaml
fixes issue with file descriptors
2024-02-06 11:01:44 +01:00
Daniel Finneran
d277c0ff23 Merge pull request #737 from kube-vip/dependabot/go_modules/k8s.io/client-go-0.29.1
Bump k8s.io/client-go from 0.29.0 to 0.29.1
2024-02-06 09:45:27 +01:00
dependabot[bot]
e9d2542c46 Bump k8s.io/client-go from 0.29.0 to 0.29.1
Bumps [k8s.io/client-go](https://github.com/kubernetes/client-go) from 0.29.0 to 0.29.1.
- [Changelog](https://github.com/kubernetes/client-go/blob/master/CHANGELOG.md)
- [Commits](https://github.com/kubernetes/client-go/compare/v0.29.0...v0.29.1)

---
updated-dependencies:
- dependency-name: k8s.io/client-go
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-06 08:36:33 +00:00
Daniel Finneran
57445329f1 Merge pull request #747 from kube-vip/dependabot/github_actions/anchore/sbom-action-0.15.8
Bump anchore/sbom-action from 0.15.3 to 0.15.8
2024-02-06 09:36:00 +01:00
Daniel Finneran
66b224ed79 Merge pull request #736 from kube-vip/dependabot/go_modules/k8s.io/apimachinery-0.29.1
Bump k8s.io/apimachinery from 0.29.0 to 0.29.1
2024-02-06 09:35:42 +01:00
Daniel Finneran
67fbfe8973 Merge pull request #727 from kube-vip/dependabot/docker/golang-1.21.6-alpine3.18
Bump golang from 1.21.5-alpine3.18 to 1.21.6-alpine3.18
2024-02-06 09:31:37 +01:00
dependabot[bot]
55c6e6418f Bump k8s.io/apimachinery from 0.29.0 to 0.29.1
Bumps [k8s.io/apimachinery](https://github.com/kubernetes/apimachinery) from 0.29.0 to 0.29.1.
- [Commits](https://github.com/kubernetes/apimachinery/compare/v0.29.0...v0.29.1)

---
updated-dependencies:
- dependency-name: k8s.io/apimachinery
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-06 08:24:47 +00:00
Daniel Finneran
d1ef0f443f Merge pull request #742 from kube-vip/dependabot/docker/alpine-3.19.1
Bump alpine from 3.19.0 to 3.19.1
2024-02-06 09:23:41 +01:00
Daniel Finneran
495bde2668 Merge pull request #735 from kube-vip/dependabot/go_modules/github.com/onsi/ginkgo/v2-2.15.0
Bump github.com/onsi/ginkgo/v2 from 2.13.2 to 2.15.0
2024-02-06 09:23:26 +01:00
Daniel Finneran
01b889bfce Merge pull request #734 from kube-vip/dependabot/go_modules/k8s.io/klog/v2-2.120.1
Bump k8s.io/klog/v2 from 2.120.0 to 2.120.1
2024-02-06 09:23:04 +01:00
Daniel Finneran
a337127fc4 Merge pull request #746 from ii2day/pr/ii2day/format-log
fix: Using log instead of fmt.print
2024-02-06 09:22:00 +01:00
dependabot[bot]
c994b09f27 Bump anchore/sbom-action from 0.15.3 to 0.15.8
Bumps [anchore/sbom-action](https://github.com/anchore/sbom-action) from 0.15.3 to 0.15.8.
- [Release notes](https://github.com/anchore/sbom-action/releases)
- [Commits](https://github.com/anchore/sbom-action/compare/v0.15.3...v0.15.8)

---
updated-dependencies:
- dependency-name: anchore/sbom-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-05 02:55:11 +00:00
ii2day
7a93f6fd04 fix: Using log instead of fmt.print
Signed-off-by: ii2day <ii2day.zoro@gmail.com>
2024-02-05 09:58:32 +08:00
Daniel Finneran
34a4352fae Merge pull request #740 from p-strusiewiczsurmacki-mobica/no-leader-election-bgp
No-leader-election mode for BGP and fixes for routing table mode
2024-02-02 12:39:42 +01:00
Patryk Strusiewicz-Surmacki
e6e2e2b0a0 Fixed typo
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk-pawel.strusiewicz-surmacki@external.telekom.de>
2024-01-31 11:40:09 +01:00
dependabot[bot]
fe9b669fc3 Bump alpine from 3.19.0 to 3.19.1
Bumps alpine from 3.19.0 to 3.19.1.

---
updated-dependencies:
- dependency-name: alpine
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-29 02:19:46 +00:00
Patryk Strusiewicz-Surmacki
947c7bc8c0 Increased http test timeout
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk-pawel.strusiewicz-surmacki@external.telekom.de>
2024-01-25 18:41:14 +01:00
Patryk Strusiewicz-Surmacki
fa1b2c965a No-leader-election mode for BGP and fixes for routing table mode
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk-pawel.strusiewicz-surmacki@external.telekom.de>
2024-01-24 18:25:36 +01:00
dependabot[bot]
e85d8cd6c7 Bump github.com/onsi/ginkgo/v2 from 2.13.2 to 2.15.0
Bumps [github.com/onsi/ginkgo/v2](https://github.com/onsi/ginkgo) from 2.13.2 to 2.15.0.
- [Release notes](https://github.com/onsi/ginkgo/releases)
- [Changelog](https://github.com/onsi/ginkgo/blob/master/CHANGELOG.md)
- [Commits](https://github.com/onsi/ginkgo/compare/v2.13.2...v2.15.0)

---
updated-dependencies:
- dependency-name: github.com/onsi/ginkgo/v2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-22 02:09:10 +00:00
dependabot[bot]
deb0afb3a3 Bump k8s.io/klog/v2 from 2.120.0 to 2.120.1
Bumps [k8s.io/klog/v2](https://github.com/kubernetes/klog) from 2.120.0 to 2.120.1.
- [Release notes](https://github.com/kubernetes/klog/releases)
- [Changelog](https://github.com/kubernetes/klog/blob/main/RELEASE.md)
- [Commits](https://github.com/kubernetes/klog/compare/v2.120.0...v2.120.1)

---
updated-dependencies:
- dependency-name: k8s.io/klog/v2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-22 02:09:00 +00:00
Daniel Finneran
cb2ae0a2b6 Merge pull request #725 from kube-vip/dependabot/go_modules/k8s.io/klog/v2-2.120.0
Bump k8s.io/klog/v2 from 2.110.1 to 2.120.0
2024-01-18 13:47:58 +00:00
Daniel Finneran
9bc4489ebc Merge pull request #718 from kube-vip/dependabot/go_modules/github.com/prometheus/client_golang-1.18.0
Bump github.com/prometheus/client_golang from 1.17.0 to 1.18.0
2024-01-18 13:47:39 +00:00
Daniel Finneran
6329cd0536 Merge pull request #717 from kube-vip/dependabot/go_modules/github.com/osrg/gobgp/v3-3.22.0
Bump github.com/osrg/gobgp/v3 from 3.19.0 to 3.22.0
2024-01-18 13:47:20 +00:00
Daniel Finneran
fe41b06277 Merge pull request #733 from thebsdbox/bgp_log_fix
Consistent logging
2024-01-18 13:46:54 +00:00
Dan Finneran
2e39d510e4 Consistent logging
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2024-01-18 12:47:08 +00:00
dependabot[bot]
1c4c11098e Bump github.com/osrg/gobgp/v3 from 3.19.0 to 3.22.0
Bumps [github.com/osrg/gobgp/v3](https://github.com/osrg/gobgp) from 3.19.0 to 3.22.0.
- [Release notes](https://github.com/osrg/gobgp/releases)
- [Changelog](https://github.com/osrg/gobgp/blob/master/.goreleaser.yml)
- [Commits](https://github.com/osrg/gobgp/compare/v3.19.0...v3.22.0)

---
updated-dependencies:
- dependency-name: github.com/osrg/gobgp/v3
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-18 12:44:21 +00:00
dependabot[bot]
bbb0c86812 Bump github.com/prometheus/client_golang from 1.17.0 to 1.18.0
Bumps [github.com/prometheus/client_golang](https://github.com/prometheus/client_golang) from 1.17.0 to 1.18.0.
- [Release notes](https://github.com/prometheus/client_golang/releases)
- [Changelog](https://github.com/prometheus/client_golang/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prometheus/client_golang/compare/v1.17.0...v1.18.0)

---
updated-dependencies:
- dependency-name: github.com/prometheus/client_golang
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-18 12:43:50 +00:00
Daniel Finneran
3d100662d5 Merge pull request #716 from kube-vip/dependabot/go_modules/golang.org/x/sys-0.16.0
Bump golang.org/x/sys from 0.15.0 to 0.16.0
2024-01-18 12:43:21 +00:00
Daniel Finneran
6b6ebdcafa Merge pull request #726 from kube-vip/dependabot/github_actions/anchore/sbom-action-0.15.3
Bump anchore/sbom-action from 0.15.1 to 0.15.3
2024-01-18 12:42:55 +00:00
Daniel Finneran
2b8d62279c Merge pull request #715 from kube-vip/dependabot/go_modules/github.com/packethost/packngo-0.31.0
Bump github.com/packethost/packngo from 0.30.0 to 0.31.0
2024-01-18 12:42:40 +00:00
Daniel Finneran
81f94fac36 Merge pull request #722 from p-strusiewiczsurmacki-mobica/dualstack-support
Minimal implementation of DualStack Services support
2024-01-18 09:37:56 +00:00
Daniel Finneran
dae044a2ab Merge pull request #730 from Cellebyte/fix/bgp
Added cli-options for bgp holdtime and keepalive
2024-01-16 13:22:02 +00:00
Marcel Fest
bb2c03335f Added cli-options for the bgp holdtime and keepalive
Signed-off-by: Marcel Fest <marcel.fest@telekom.de>
2024-01-16 14:05:42 +01:00
Patryk Strusiewicz-Surmacki
eff0d21820 Fixed typo
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk-pawel.strusiewicz-surmacki@external.telekom.de>
2024-01-16 13:31:39 +01:00
Patryk Strusiewicz-Surmacki
8ced01382f Reintroduced e2e test changes
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk-pawel.strusiewicz-surmacki@external.telekom.de>
2024-01-15 21:41:17 +01:00
Patryk Strusiewicz-Surmacki
3d559ba0ce Minimal implementation of DualStack Services support
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk-pawel.strusiewicz-surmacki@external.telekom.de>
2024-01-15 21:27:58 +01:00
Daniel Finneran
a2129b04df Merge pull request #720 from p-strusiewiczsurmacki-mobica/endpointslices-support
Non-leader-election for routing table mode
2024-01-15 15:16:54 +00:00
dependabot[bot]
c3209d5c17 Bump golang from 1.21.5-alpine3.18 to 1.21.6-alpine3.18
Bumps golang from 1.21.5-alpine3.18 to 1.21.6-alpine3.18.

---
updated-dependencies:
- dependency-name: golang
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-15 03:01:12 +00:00
dependabot[bot]
7f67c71582 Bump anchore/sbom-action from 0.15.1 to 0.15.3
Bumps [anchore/sbom-action](https://github.com/anchore/sbom-action) from 0.15.1 to 0.15.3.
- [Release notes](https://github.com/anchore/sbom-action/releases)
- [Commits](https://github.com/anchore/sbom-action/compare/v0.15.1...v0.15.3)

---
updated-dependencies:
- dependency-name: anchore/sbom-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-15 02:47:32 +00:00
dependabot[bot]
40508a4c6d Bump k8s.io/klog/v2 from 2.110.1 to 2.120.0
Bumps [k8s.io/klog/v2](https://github.com/kubernetes/klog) from 2.110.1 to 2.120.0.
- [Release notes](https://github.com/kubernetes/klog/releases)
- [Changelog](https://github.com/kubernetes/klog/blob/main/RELEASE.md)
- [Commits](https://github.com/kubernetes/klog/compare/v2.110.1...v2.120.0)

---
updated-dependencies:
- dependency-name: k8s.io/klog/v2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-15 02:35:34 +00:00
Daniel Finneran
1dc52ed0d4 Merge pull request #724 from Cellebyte/fix/723
fix #723 and allow short hostnames as well
2024-01-13 19:10:30 +00:00
Cellebyte
29f7536083 fix #723 and allow short hostnames as well 2024-01-13 12:22:57 +01:00
Patryk Strusiewicz-Surmacki
d9fc6a5848 Fixed typos and removed error check after route deletion
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk-pawel.strusiewicz-surmacki@external.telekom.de>
2024-01-12 13:27:00 +01:00
Patryk Strusiewicz-Surmacki
70a436ddf3 Improved logging. Fixed issue with endpointslices deletion event.
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk-pawel.strusiewicz-surmacki@external.telekom.de>
2024-01-12 11:09:19 +01:00
Patryk Strusiewicz-Surmacki
9d640c5c44 Fixed linter issue
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk-pawel.strusiewicz-surmacki@external.telekom.de>
2024-01-11 11:37:29 +01:00
Marcel Fest
7dda7b42c1 Added non-leader-election mode for routing table mode and preliminary support for endpointslices.
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk-pawel.strusiewicz-surmacki@external.telekom.de>
2024-01-10 18:32:23 +01:00
dependabot[bot]
7dec367960 Bump golang.org/x/sys from 0.15.0 to 0.16.0
Bumps [golang.org/x/sys](https://github.com/golang/sys) from 0.15.0 to 0.16.0.
- [Commits](https://github.com/golang/sys/compare/v0.15.0...v0.16.0)

---
updated-dependencies:
- dependency-name: golang.org/x/sys
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-08 02:07:48 +00:00
dependabot[bot]
444b4a9c0d Bump github.com/packethost/packngo from 0.30.0 to 0.31.0
Bumps [github.com/packethost/packngo](https://github.com/packethost/packngo) from 0.30.0 to 0.31.0.
- [Release notes](https://github.com/packethost/packngo/releases)
- [Changelog](https://github.com/packethost/packngo/blob/master/CHANGELOG.md)
- [Commits](https://github.com/packethost/packngo/compare/v0.30.0...v0.31.0)

---
updated-dependencies:
- dependency-name: github.com/packethost/packngo
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-08 02:07:44 +00:00
Daniel Finneran
3c0e5e327e Update ci.yaml 2024-01-07 16:15:27 +00:00
Daniel Finneran
61d3d7ab45 Merge pull request #713 from thebsdbox/conf_path
Allows a configurable path to the kubernetes config
2024-01-07 15:45:59 +00:00
Dan Finneran
6ef860da52 Last fix
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2024-01-07 15:28:17 +00:00
Dan Finneran
748d60147d rage
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2024-01-07 15:13:15 +00:00
Dan Finneran
879b5337dc extensive fudging of the CI tests
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2024-01-07 15:04:13 +00:00
Dan Finneran
1aba51c70f v129 fixes
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2024-01-07 14:38:08 +00:00
Dan Finneran
c60660d4d9 fix for IPv6
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2024-01-07 11:39:37 +00:00
Dan Finneran
6a7c198df0 remove lb step
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2024-01-07 11:24:43 +00:00
Dan Finneran
e0f9b195af grasping at straws
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2024-01-06 17:43:34 +00:00
Dan Finneran
80241ecc74 align timeouts
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2024-01-06 16:29:55 +00:00
Dan Finneran
047fe8f444 Additional tests
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2024-01-06 16:16:21 +00:00
Dan Finneran
d29b8d1bd8 Allows a configurable path to the kubernetes config
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2024-01-05 16:00:40 +00:00
Daniel Finneran
8fb2a7dc07 Merge pull request #712 from thebsdbox/build_nudge
Bumps the Makefile for a new release
2024-01-05 15:15:05 +00:00
Daniel Finneran
f5810f028f Merge pull request #700 from AHB102/master
Removed docs as described in Remove /docs #549
2024-01-05 14:02:10 +00:00
Dan Finneran
7901b8d50c Bumps the Makefile for a new release
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2024-01-05 14:00:49 +00:00
Daniel Finneran
c7b0a55718 Merge pull request #710 from thebsdbox/ipvs
fixes to the new ipvs import
2024-01-03 18:03:37 +00:00
Dan Finneran
98d6579d9d fixes to the new ipvs import
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2024-01-03 17:53:38 +00:00
Daniel Finneran
7dad075682 Merge pull request #660 from kube-vip/dependabot/go_modules/github.com/cloudflare/ipvs-0.10.1
Bump github.com/cloudflare/ipvs from 0.9.1 to 0.10.1
2024-01-03 17:48:07 +00:00
Daniel Finneran
eac6f6f75a Merge branch 'main' into dependabot/go_modules/github.com/cloudflare/ipvs-0.10.1 2024-01-03 17:48:01 +00:00
Daniel Finneran
0c98c1e28a Merge pull request #648 from amragaey/patch-1
#647 Update Dependencies for Security Patch
2024-01-03 15:13:16 +00:00
Daniel Finneran
5b00d30966 Merge branch 'main' into patch-1 2024-01-03 15:12:58 +00:00
Daniel Finneran
29ddbbbe04 Merge pull request #709 from thebsdbox/linter_actions_fix
More fixes
2024-01-03 15:12:18 +00:00
Dan Finneran
03467dd085 More fixes
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2024-01-03 14:26:47 +00:00
Daniel Finneran
fc00d19271 Merge pull request #704 from kube-vip/dependabot/go_modules/go.etcd.io/etcd/client/v3-3.5.11
Bump go.etcd.io/etcd/client/v3 from 3.5.10 to 3.5.11
2024-01-03 14:15:40 +00:00
Daniel Finneran
3500d84fed Merge branch 'main' into dependabot/go_modules/go.etcd.io/etcd/client/v3-3.5.11 2024-01-03 14:15:29 +00:00
Daniel Finneran
09ab08b0ae Merge pull request #702 from kube-vip/dependabot/go_modules/go.etcd.io/etcd/api/v3-3.5.11
Bump go.etcd.io/etcd/api/v3 from 3.5.10 to 3.5.11
2024-01-03 14:14:43 +00:00
Daniel Finneran
0fa5e96037 Merge pull request #703 from kube-vip/dependabot/go_modules/k8s.io/client-go-0.29.0
Bump k8s.io/client-go from 0.28.3 to 0.29.0
2024-01-03 14:12:05 +00:00
Daniel Finneran
e6d56f7eb0 Update codeql-analysis.yml 2024-01-03 14:07:53 +00:00
Daniel Finneran
9b73b3c87b Merge pull request #708 from thebsdbox/workflow_fix
Workflow update for go 1.21
2024-01-03 13:57:03 +00:00
Dan Finneran
a342c75a65 Workflow update for go 1.21
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2024-01-03 13:56:43 +00:00
Daniel Finneran
377545e835 Merge pull request #707 from thebsdbox/apiserver_depbot_fix
fixes go modules
2024-01-03 13:52:41 +00:00
Dan Finneran
66c86e995b fixes go modules
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2024-01-03 13:52:13 +00:00
dependabot[bot]
52776f4a75 Bump k8s.io/client-go from 0.28.3 to 0.29.0
Bumps [k8s.io/client-go](https://github.com/kubernetes/client-go) from 0.28.3 to 0.29.0.
- [Changelog](https://github.com/kubernetes/client-go/blob/master/CHANGELOG.md)
- [Commits](https://github.com/kubernetes/client-go/compare/v0.28.3...v0.29.0)

---
updated-dependencies:
- dependency-name: k8s.io/client-go
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-03 13:51:16 +00:00
dependabot[bot]
f82b4a08b4 Bump go.etcd.io/etcd/client/v3 from 3.5.10 to 3.5.11
Bumps [go.etcd.io/etcd/client/v3](https://github.com/etcd-io/etcd) from 3.5.10 to 3.5.11.
- [Release notes](https://github.com/etcd-io/etcd/releases)
- [Commits](https://github.com/etcd-io/etcd/compare/v3.5.10...v3.5.11)

---
updated-dependencies:
- dependency-name: go.etcd.io/etcd/client/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-03 13:50:51 +00:00
dependabot[bot]
ec1288074e Bump go.etcd.io/etcd/api/v3 from 3.5.10 to 3.5.11
Bumps [go.etcd.io/etcd/api/v3](https://github.com/etcd-io/etcd) from 3.5.10 to 3.5.11.
- [Release notes](https://github.com/etcd-io/etcd/releases)
- [Commits](https://github.com/etcd-io/etcd/compare/v3.5.10...v3.5.11)

---
updated-dependencies:
- dependency-name: go.etcd.io/etcd/api/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-03 13:50:18 +00:00
Daniel Finneran
a388fdf156 Merge pull request #688 from kube-vip/dependabot/go_modules/k8s.io/apimachinery-0.29.0
Bump k8s.io/apimachinery from 0.28.3 to 0.29.0
2024-01-03 13:49:16 +00:00
dependabot[bot]
0212e78dc6 Bump k8s.io/apimachinery from 0.28.3 to 0.29.0
Bumps [k8s.io/apimachinery](https://github.com/kubernetes/apimachinery) from 0.28.3 to 0.29.0.
- [Commits](https://github.com/kubernetes/apimachinery/compare/v0.28.3...v0.29.0)

---
updated-dependencies:
- dependency-name: k8s.io/apimachinery
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-03 13:45:25 +00:00
Archit H Barve
12638aee85 Removed docs 2023-12-29 15:46:54 +05:30
Daniel Finneran
55a40bf771 Merge pull request #696 from zifeo/main
docs: fix directroute forwarding method
2023-12-28 16:31:01 +00:00
Daniel Finneran
3a7c331061 Merge pull request #673 from kube-vip/dependabot/go_modules/k8s.io/api-0.28.4
Bump k8s.io/api from 0.28.3 to 0.28.4
2023-12-28 16:28:45 +00:00
Daniel Finneran
35077570ff Merge branch 'main' into dependabot/go_modules/k8s.io/api-0.28.4 2023-12-28 16:28:34 +00:00
Daniel Finneran
24e3780792 Merge pull request #690 from kube-vip/dependabot/go_modules/golang.org/x/crypto-0.17.0
Bump golang.org/x/crypto from 0.14.0 to 0.17.0
2023-12-28 16:27:35 +00:00
Daniel Finneran
c7c772e40d Merge pull request #697 from kube-vip/dependabot/go_modules/github.com/spf13/cobra-1.8.0
Bump github.com/spf13/cobra from 1.7.0 to 1.8.0
2023-12-28 16:27:20 +00:00
Daniel Finneran
2d498d9161 Merge pull request #699 from thebsdbox/k8s_client
Updates to the client to auto-detect
2023-12-28 15:29:12 +00:00
Dan Finneran
52ad35d462 disable local tests
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2023-12-28 14:24:44 +00:00
Dan Finneran
2cfe326b9c Updates to the client to auto-detect
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2023-12-28 14:19:35 +00:00
dependabot[bot]
5308dfc055 Bump github.com/spf13/cobra from 1.7.0 to 1.8.0
Bumps [github.com/spf13/cobra](https://github.com/spf13/cobra) from 1.7.0 to 1.8.0.
- [Release notes](https://github.com/spf13/cobra/releases)
- [Commits](https://github.com/spf13/cobra/compare/v1.7.0...v1.8.0)

---
updated-dependencies:
- dependency-name: github.com/spf13/cobra
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-25 02:22:51 +00:00
Teo Stocco
4438fcb6d3 docs: fix directroute forwarding method 2023-12-24 15:33:39 +01:00
dependabot[bot]
88dbd0f45d Bump golang.org/x/crypto from 0.14.0 to 0.17.0
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.14.0 to 0.17.0.
- [Commits](https://github.com/golang/crypto/compare/v0.14.0...v0.17.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-22 12:25:40 +00:00
Daniel Finneran
69306d471c Merge pull request #672 from kube-vip/dependabot/go_modules/github.com/onsi/ginkgo/v2-2.13.2
Bump github.com/onsi/ginkgo/v2 from 2.13.0 to 2.13.2
2023-12-22 12:24:29 +00:00
Daniel Finneran
82e7399f60 Merge pull request #680 from kube-vip/dependabot/docker/golang-1.21.5-alpine3.18
Bump golang from 1.21.4-alpine3.18 to 1.21.5-alpine3.18
2023-12-22 12:23:13 +00:00
Daniel Finneran
0215a0e39e Merge pull request #678 from kube-vip/dependabot/github_actions/anchore/sbom-action-0.15.1
Bump anchore/sbom-action from 0.15.0 to 0.15.1
2023-12-22 12:22:56 +00:00
Daniel Finneran
2190a91df7 Merge pull request #689 from kube-vip/dependabot/github_actions/github/codeql-action-3
Bump github/codeql-action from 2 to 3
2023-12-22 12:22:40 +00:00
Daniel Finneran
17a07e6e4c Merge pull request #679 from kube-vip/dependabot/github_actions/actions/setup-go-5
Bump actions/setup-go from 4 to 5
2023-12-22 12:22:28 +00:00
Daniel Finneran
93fe008cc6 Merge pull request #674 from kube-vip/dependabot/go_modules/github.com/prometheus/client_golang-1.17.0
Bump github.com/prometheus/client_golang from 1.16.0 to 1.17.0
2023-12-22 12:22:05 +00:00
Daniel Finneran
eb880a2885 Merge pull request #681 from kube-vip/dependabot/docker/alpine-3.19.0
Bump alpine from 3.18.4 to 3.19.0
2023-12-22 08:03:48 +00:00
Daniel Finneran
dbf3233250 Merge pull request #695 from marc-cerebras/marc-cerebras/bgp-timer-cfg
Add config options for BGP timers
2023-12-22 08:03:24 +00:00
Daniel Finneran
2123ecf9c0 Merge pull request #687 from flawedmatrix/handle-dualstack-lb-ips
Dualstack support for Loadbalancer Services
2023-12-22 08:02:33 +00:00
marc-cerebras
06285210d0 update tests 2023-12-21 14:58:37 -08:00
marc-cerebras
fb062f7a55 add overlay for annotation driven cfg 2023-12-21 14:36:07 -08:00
marc-cerebras
5b63e4a181 add cfg opts for bgp timers 2023-12-21 12:56:01 -08:00
Daniel Finneran
0ae3ff840c Merge pull request #693 from thebsdbox/k8s_e2e
Adds capability to use your own images for e2e
2023-12-20 16:18:31 +00:00
Dan Finneran
20b3a3c00b Adds capability to use your own images for e2e
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2023-12-20 16:07:53 +00:00
Edwin Xie
e22ee4de74 Add service test for dualstack LB services
Signed-off-by: Edwin Xie <exie@vmware.com>
2023-12-19 18:55:04 +00:00
Edwin Xie
d21ce886a2 Preliminary support for dualstack loadbalancer services
Signed-off-by: Edwin Xie <exie@vmware.com>
2023-12-19 18:54:56 +00:00
dependabot[bot]
9c79e88ccb Bump github/codeql-action from 2 to 3
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 2 to 3.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/v2...v3)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-18 02:19:34 +00:00
dependabot[bot]
079423f218 Bump k8s.io/api from 0.28.3 to 0.28.4
Bumps [k8s.io/api](https://github.com/kubernetes/api) from 0.28.3 to 0.28.4.
- [Commits](https://github.com/kubernetes/api/compare/v0.28.3...v0.28.4)

---
updated-dependencies:
- dependency-name: k8s.io/api
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-12 16:09:01 +00:00
dependabot[bot]
dfd8b38268 Bump github.com/onsi/ginkgo/v2 from 2.13.0 to 2.13.2
Bumps [github.com/onsi/ginkgo/v2](https://github.com/onsi/ginkgo) from 2.13.0 to 2.13.2.
- [Release notes](https://github.com/onsi/ginkgo/releases)
- [Changelog](https://github.com/onsi/ginkgo/blob/master/CHANGELOG.md)
- [Commits](https://github.com/onsi/ginkgo/compare/v2.13.0...v2.13.2)

---
updated-dependencies:
- dependency-name: github.com/onsi/ginkgo/v2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-12 16:07:59 +00:00
Daniel Finneran
c03b7edb5f Merge pull request #671 from kube-vip/dependabot/go_modules/golang.org/x/sys-0.15.0
Bump golang.org/x/sys from 0.13.0 to 0.15.0
2023-12-12 16:06:51 +00:00
dependabot[bot]
be404237bd Bump alpine from 3.18.4 to 3.19.0
Bumps alpine from 3.18.4 to 3.19.0.

---
updated-dependencies:
- dependency-name: alpine
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-11 02:36:33 +00:00
dependabot[bot]
5b48797f8a Bump golang from 1.21.4-alpine3.18 to 1.21.5-alpine3.18
Bumps golang from 1.21.4-alpine3.18 to 1.21.5-alpine3.18.

---
updated-dependencies:
- dependency-name: golang
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-11 02:36:30 +00:00
dependabot[bot]
b0c344298c Bump actions/setup-go from 4 to 5
Bumps [actions/setup-go](https://github.com/actions/setup-go) from 4 to 5.
- [Release notes](https://github.com/actions/setup-go/releases)
- [Commits](https://github.com/actions/setup-go/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/setup-go
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-11 02:31:01 +00:00
dependabot[bot]
c79fff8d86 Bump anchore/sbom-action from 0.15.0 to 0.15.1
Bumps [anchore/sbom-action](https://github.com/anchore/sbom-action) from 0.15.0 to 0.15.1.
- [Release notes](https://github.com/anchore/sbom-action/releases)
- [Commits](https://github.com/anchore/sbom-action/compare/v0.15.0...v0.15.1)

---
updated-dependencies:
- dependency-name: anchore/sbom-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-11 02:30:58 +00:00
dependabot[bot]
b72ae63060 Bump github.com/prometheus/client_golang from 1.16.0 to 1.17.0
Bumps [github.com/prometheus/client_golang](https://github.com/prometheus/client_golang) from 1.16.0 to 1.17.0.
- [Release notes](https://github.com/prometheus/client_golang/releases)
- [Changelog](https://github.com/prometheus/client_golang/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prometheus/client_golang/compare/v1.16.0...v1.17.0)

---
updated-dependencies:
- dependency-name: github.com/prometheus/client_golang
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-04 02:35:08 +00:00
dependabot[bot]
9835fd4410 Bump golang.org/x/sys from 0.13.0 to 0.15.0
Bumps [golang.org/x/sys](https://github.com/golang/sys) from 0.13.0 to 0.15.0.
- [Commits](https://github.com/golang/sys/compare/v0.13.0...v0.15.0)

---
updated-dependencies:
- dependency-name: golang.org/x/sys
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-04 02:34:43 +00:00
Daniel Finneran
6a642c788a Merge pull request #670 from thebsdbox/lint_fix_routing
Fixes to linting for routing table
2023-12-03 10:38:40 +00:00
Daniel Finneran
47924247c4 Merge pull request #607 from hellt/patch-1
Added create rbac settings section for kind deployment
2023-12-03 10:36:40 +00:00
dependabot[bot]
100da0a3a5 Bump github.com/cloudflare/ipvs from 0.9.1 to 0.10.1
Bumps [github.com/cloudflare/ipvs](https://github.com/cloudflare/ipvs) from 0.9.1 to 0.10.1.
- [Release notes](https://github.com/cloudflare/ipvs/releases)
- [Commits](https://github.com/cloudflare/ipvs/compare/v0.9.1...v0.10.1)

---
updated-dependencies:
- dependency-name: github.com/cloudflare/ipvs
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-03 10:35:14 +00:00
Daniel Finneran
945167cab4 Merge branch 'main' into patch-1 2023-12-03 10:33:53 +00:00
Dan Finneran
b0f7aa1698 Fixes to linting for routing table
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2023-12-03 10:32:51 +00:00
Daniel Finneran
2cee4723d4 Merge pull request #606 from CopernicaMarketingSoftware/main
Add environment variable for routing table type
2023-12-03 10:27:37 +00:00
Daniel Finneran
f33a0b7481 Merge branch 'main' into main 2023-12-03 10:26:03 +00:00
Daniel Finneran
f54595d8f7 Merge pull request #669 from thebsdbox/cleanup
Cleanup
2023-12-02 17:56:24 +00:00
Dan Finneran
68c9e49480 linting fixes.
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2023-12-02 16:38:56 +00:00
Dan Finneran
cfa2e93c76 Further cleaning
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2023-12-02 16:32:30 +00:00
Dan Finneran
1f1c7fe819 Tidies up logging messages and redundant logic
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2023-12-02 16:32:12 +00:00
Daniel Finneran
c7abf75c17 Merge pull request #655 from kube-vip/dependabot/go_modules/go.etcd.io/etcd/client/v3-3.5.10
Bump go.etcd.io/etcd/client/v3 from 3.5.9 to 3.5.10
2023-12-02 16:10:09 +00:00
Daniel Finneran
befe2b92aa Merge branch 'main' into dependabot/go_modules/go.etcd.io/etcd/client/v3-3.5.10 2023-12-02 16:09:58 +00:00
Daniel Finneran
cd86f70a20 Merge pull request #661 from kube-vip/dependabot/go_modules/github.com/onsi/gomega-1.30.0
Bump github.com/onsi/gomega from 1.27.10 to 1.30.0
2023-12-02 16:08:55 +00:00
Daniel Finneran
0a4a1dc12d Merge pull request #659 from kube-vip/dependabot/docker/golang-1.21.4-alpine3.18
Bump golang from 1.21.3-alpine3.18 to 1.21.4-alpine3.18
2023-12-02 16:08:39 +00:00
Daniel Finneran
99dcf88cb2 Merge pull request #657 from kube-vip/dependabot/github_actions/docker/setup-buildx-action-3
Bump docker/setup-buildx-action from 1 to 3
2023-12-02 16:08:09 +00:00
Daniel Finneran
b53b340649 Merge pull request #668 from kube-vip/dependabot/github_actions/anchore/sbom-action-0.15.0
Bump anchore/sbom-action from 0.14.3 to 0.15.0
2023-12-02 16:07:45 +00:00
Daniel Finneran
8d90a805b4 Merge pull request #656 from kube-vip/dependabot/github_actions/docker/login-action-3
Bump docker/login-action from 1 to 3
2023-12-02 16:07:08 +00:00
Daniel Finneran
0626053eb5 Merge pull request #654 from kube-vip/dependabot/go_modules/go.etcd.io/etcd/client/pkg/v3-3.5.10
Bump go.etcd.io/etcd/client/pkg/v3 from 3.5.9 to 3.5.10
2023-12-02 16:06:47 +00:00
Daniel Finneran
de7a454462 Merge pull request #653 from kube-vip/dependabot/go_modules/sigs.k8s.io/yaml-1.4.0
Bump sigs.k8s.io/yaml from 1.3.0 to 1.4.0
2023-12-02 16:06:31 +00:00
Daniel Finneran
247cffb006 Merge pull request #664 from shkuviak/feature/service-dhcp-hostname
Add annotation to specify DHCP lease hostname
2023-12-02 16:06:10 +00:00
dependabot[bot]
0f29b97dd4 Bump anchore/sbom-action from 0.14.3 to 0.15.0
Bumps [anchore/sbom-action](https://github.com/anchore/sbom-action) from 0.14.3 to 0.15.0.
- [Release notes](https://github.com/anchore/sbom-action/releases)
- [Commits](https://github.com/anchore/sbom-action/compare/v0.14.3...v0.15.0)

---
updated-dependencies:
- dependency-name: anchore/sbom-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-27 02:25:46 +00:00
Nicolas JENDROWIAK
e7b68cfd3a Add upgrade command in Dockerfile_iptables
Fix trivy warning on vulnerable libcrypto package
-> No newer alpine image on dockerhub

Signed-off-by: Nicolas JENDROWIAK <75165555+shkuviak@users.noreply.github.com>
2023-11-25 18:22:14 +01:00
Nicolas JENDROWIAK
08abd3812a Added trivy command in makefile
Signed-off-by: Nicolas JENDROWIAK <75165555+shkuviak@users.noreply.github.com>
2023-11-25 18:22:14 +01:00
Nicolas JENDROWIAK
f0de6767a3 lint
Signed-off-by: Nicolas JENDROWIAK <nico.jendrowiak@gmail.com>
2023-11-24 17:13:03 +01:00
Daniel Finneran
b42b78283c Merge pull request #650 from aarnaud/doc/k0sctl
Add doc for static pods on k0s using k0sctl
2023-11-21 17:06:11 -01:00
Daniel Finneran
a0fed6b166 Merge branch 'main' into patch-1 2023-11-19 08:24:45 +00:00
Nicolas JENDROWIAK
a295b44d83 [svc] Add annotation to specify DHCP lease host
Signed-off-by: Nicolas JENDROWIAK <nico.jendrowiak@gmail.com>
2023-11-16 12:16:09 +01:00
dependabot[bot]
259b31cef2 Bump github.com/onsi/gomega from 1.27.10 to 1.30.0
Bumps [github.com/onsi/gomega](https://github.com/onsi/gomega) from 1.27.10 to 1.30.0.
- [Release notes](https://github.com/onsi/gomega/releases)
- [Changelog](https://github.com/onsi/gomega/blob/master/CHANGELOG.md)
- [Commits](https://github.com/onsi/gomega/compare/v1.27.10...v1.30.0)

---
updated-dependencies:
- dependency-name: github.com/onsi/gomega
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-13 02:36:55 +00:00
dependabot[bot]
16c8deb0fe Bump golang from 1.21.3-alpine3.18 to 1.21.4-alpine3.18
Bumps golang from 1.21.3-alpine3.18 to 1.21.4-alpine3.18.

---
updated-dependencies:
- dependency-name: golang
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-13 02:25:42 +00:00
dependabot[bot]
cf9fa5b30b Bump docker/setup-buildx-action from 1 to 3
Bumps [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) from 1 to 3.
- [Release notes](https://github.com/docker/setup-buildx-action/releases)
- [Commits](https://github.com/docker/setup-buildx-action/compare/v1...v3)

---
updated-dependencies:
- dependency-name: docker/setup-buildx-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-30 02:59:03 +00:00
dependabot[bot]
334590b88c Bump docker/login-action from 1 to 3
Bumps [docker/login-action](https://github.com/docker/login-action) from 1 to 3.
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](https://github.com/docker/login-action/compare/v1...v3)

---
updated-dependencies:
- dependency-name: docker/login-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-30 02:58:58 +00:00
dependabot[bot]
f0987424ef Bump go.etcd.io/etcd/client/v3 from 3.5.9 to 3.5.10
Bumps [go.etcd.io/etcd/client/v3](https://github.com/etcd-io/etcd) from 3.5.9 to 3.5.10.
- [Release notes](https://github.com/etcd-io/etcd/releases)
- [Commits](https://github.com/etcd-io/etcd/compare/v3.5.9...v3.5.10)

---
updated-dependencies:
- dependency-name: go.etcd.io/etcd/client/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-30 02:58:36 +00:00
dependabot[bot]
864bacfb13 Bump go.etcd.io/etcd/client/pkg/v3 from 3.5.9 to 3.5.10
Bumps [go.etcd.io/etcd/client/pkg/v3](https://github.com/etcd-io/etcd) from 3.5.9 to 3.5.10.
- [Release notes](https://github.com/etcd-io/etcd/releases)
- [Commits](https://github.com/etcd-io/etcd/compare/v3.5.9...v3.5.10)

---
updated-dependencies:
- dependency-name: go.etcd.io/etcd/client/pkg/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-30 02:58:25 +00:00
dependabot[bot]
6e528fef90 Bump sigs.k8s.io/yaml from 1.3.0 to 1.4.0
Bumps [sigs.k8s.io/yaml](https://github.com/kubernetes-sigs/yaml) from 1.3.0 to 1.4.0.
- [Release notes](https://github.com/kubernetes-sigs/yaml/releases)
- [Changelog](https://github.com/kubernetes-sigs/yaml/blob/master/RELEASE.md)
- [Commits](https://github.com/kubernetes-sigs/yaml/compare/v1.3.0...v1.4.0)

---
updated-dependencies:
- dependency-name: sigs.k8s.io/yaml
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-30 02:58:13 +00:00
Anthony ARNAUD
14c27ff839 Add doc for static pods on k0s using k0sctl
Signed-off-by: Anthony ARNAUD <github@anthony-arnaud.fr>
2023-10-26 12:11:35 -04:00
Daniel Finneran
063cc2fb8d Merge pull request #643 from kube-vip/dependabot/go_modules/k8s.io/client-go-0.28.3
Bump k8s.io/client-go from 0.27.4 to 0.28.3
2023-10-26 12:06:20 +02:00
Daniel Finneran
f5091a4650 Merge pull request #640 from kube-vip/dependabot/github_actions/actions/checkout-4
Bump actions/checkout from 2 to 4
2023-10-26 12:06:07 +02:00
Daniel Finneran
7ea481b904 Merge pull request #637 from kube-vip/dependabot/docker/alpine-3.18.4
Bump alpine from 3.18.3 to 3.18.4
2023-10-26 12:05:51 +02:00
Daniel Finneran
9b7ef5db31 Merge pull request #649 from kube-vip/dependabot/go_modules/google.golang.org/grpc-1.57.1
Bump google.golang.org/grpc from 1.57.0 to 1.57.1
2023-10-26 12:05:09 +02:00
dependabot[bot]
a25cc92daa Bump k8s.io/client-go from 0.27.4 to 0.28.3
Bumps [k8s.io/client-go](https://github.com/kubernetes/client-go) from 0.27.4 to 0.28.3.
- [Changelog](https://github.com/kubernetes/client-go/blob/master/CHANGELOG.md)
- [Commits](https://github.com/kubernetes/client-go/compare/v0.27.4...v0.28.3)

---
updated-dependencies:
- dependency-name: k8s.io/client-go
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-26 09:51:15 +00:00
dependabot[bot]
08d71536e9 Bump google.golang.org/grpc from 1.57.0 to 1.57.1
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.57.0 to 1.57.1.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.57.0...v1.57.1)

---
updated-dependencies:
- dependency-name: google.golang.org/grpc
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-26 09:51:00 +00:00
Daniel Finneran
256743758b Merge pull request #644 from kube-vip/dependabot/go_modules/github.com/osrg/gobgp/v3-3.19.0
Bump github.com/osrg/gobgp/v3 from 3.17.0 to 3.19.0
2023-10-26 11:49:10 +02:00
Daniel Finneran
b4593b2c9e Merge pull request #641 from kube-vip/dependabot/go_modules/github.com/onsi/ginkgo/v2-2.13.0
Bump github.com/onsi/ginkgo/v2 from 2.12.1 to 2.13.0
2023-10-26 11:48:49 +02:00
Daniel Finneran
f024f5ebbc Merge pull request #645 from kube-vip/dependabot/go_modules/go.uber.org/zap-1.26.0
Bump go.uber.org/zap from 1.21.0 to 1.26.0
2023-10-26 11:48:27 +02:00
Daniel Finneran
b643453816 Merge pull request #639 from kube-vip/dependabot/github_actions/docker/build-push-action-5
Bump docker/build-push-action from 2 to 5
2023-10-26 11:48:09 +02:00
dependabot[bot]
1eb9bddb9c Bump alpine from 3.18.3 to 3.18.4
Bumps alpine from 3.18.3 to 3.18.4.

---
updated-dependencies:
- dependency-name: alpine
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-26 09:47:13 +00:00
Daniel Finneran
ace7001e91 Merge pull request #638 from kube-vip/dependabot/github_actions/anchore/sbom-action-0.14.3
Bump anchore/sbom-action from 0.12.0 to 0.14.3
2023-10-26 11:47:09 +02:00
dependabot[bot]
3ea0b629ac Bump actions/checkout from 2 to 4
Bumps [actions/checkout](https://github.com/actions/checkout) from 2 to 4.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v2...v4)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-26 09:46:42 +00:00
Daniel Finneran
fb9d80aaaa Merge pull request #636 from kube-vip/dependabot/github_actions/github/codeql-action-2
Bump github/codeql-action from 1 to 2
2023-10-26 11:45:56 +02:00
Daniel Finneran
ed0281b243 Merge pull request #635 from kube-vip/dependabot/github_actions/docker/setup-qemu-action-3
Bump docker/setup-qemu-action from 1 to 3
2023-10-26 11:45:45 +02:00
Daniel Finneran
4d7409f18f Merge pull request #634 from kube-vip/dependabot/docker/golang-1.21.3-alpine3.18
Bump golang from 1.20.8-alpine3.18 to 1.21.3-alpine3.18
2023-10-26 11:45:18 +02:00
Amr Ragaey
305572359d update go-restful version 2023-10-26 11:57:20 +03:00
Amr Ragaey
12ab991048 update Go version 2023-10-26 11:52:37 +03:00
dependabot[bot]
2a8e981b49 Bump go.uber.org/zap from 1.21.0 to 1.26.0
Bumps [go.uber.org/zap](https://github.com/uber-go/zap) from 1.21.0 to 1.26.0.
- [Release notes](https://github.com/uber-go/zap/releases)
- [Changelog](https://github.com/uber-go/zap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/uber-go/zap/compare/v1.21.0...v1.26.0)

---
updated-dependencies:
- dependency-name: go.uber.org/zap
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-23 20:34:02 +00:00
dependabot[bot]
1cde04e8a1 Bump github.com/osrg/gobgp/v3 from 3.17.0 to 3.19.0
Bumps [github.com/osrg/gobgp/v3](https://github.com/osrg/gobgp) from 3.17.0 to 3.19.0.
- [Release notes](https://github.com/osrg/gobgp/releases)
- [Changelog](https://github.com/osrg/gobgp/blob/master/.goreleaser.yml)
- [Commits](https://github.com/osrg/gobgp/compare/v3.17.0...v3.19.0)

---
updated-dependencies:
- dependency-name: github.com/osrg/gobgp/v3
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-23 20:33:46 +00:00
dependabot[bot]
52bacaa03c Bump github.com/onsi/ginkgo/v2 from 2.12.1 to 2.13.0
Bumps [github.com/onsi/ginkgo/v2](https://github.com/onsi/ginkgo) from 2.12.1 to 2.13.0.
- [Release notes](https://github.com/onsi/ginkgo/releases)
- [Changelog](https://github.com/onsi/ginkgo/blob/master/CHANGELOG.md)
- [Commits](https://github.com/onsi/ginkgo/compare/v2.12.1...v2.13.0)

---
updated-dependencies:
- dependency-name: github.com/onsi/ginkgo/v2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-23 20:31:39 +00:00
dependabot[bot]
4e88e32e56 Bump docker/build-push-action from 2 to 5
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 2 to 5.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/v2...v5)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-23 20:29:36 +00:00
dependabot[bot]
202274d4f1 Bump anchore/sbom-action from 0.12.0 to 0.14.3
Bumps [anchore/sbom-action](https://github.com/anchore/sbom-action) from 0.12.0 to 0.14.3.
- [Release notes](https://github.com/anchore/sbom-action/releases)
- [Commits](https://github.com/anchore/sbom-action/compare/v0.12.0...v0.14.3)

---
updated-dependencies:
- dependency-name: anchore/sbom-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-23 20:29:32 +00:00
dependabot[bot]
f20fa9df3e Bump github/codeql-action from 1 to 2
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 1 to 2.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/v1...v2)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-23 20:29:29 +00:00
dependabot[bot]
70e94d24f4 Bump docker/setup-qemu-action from 1 to 3
Bumps [docker/setup-qemu-action](https://github.com/docker/setup-qemu-action) from 1 to 3.
- [Release notes](https://github.com/docker/setup-qemu-action/releases)
- [Commits](https://github.com/docker/setup-qemu-action/compare/v1...v3)

---
updated-dependencies:
- dependency-name: docker/setup-qemu-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-23 20:29:24 +00:00
dependabot[bot]
a8914af861 Bump golang from 1.20.8-alpine3.18 to 1.21.3-alpine3.18
Bumps golang from 1.20.8-alpine3.18 to 1.21.3-alpine3.18.

---
updated-dependencies:
- dependency-name: golang
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-23 20:29:23 +00:00
Daniel Finneran
5a0715dc50 Merge pull request #633 from mrueg/dependabot 2023-10-23 22:29:03 +02:00
Manuel Rüger
31955fedf7 .github: Add a dependabot config
Signed-off-by: Manuel Rüger <manuel@rueg.eu>
2023-10-23 19:24:45 +02:00
Daniel Finneran
888eff1317 Merge pull request #628 from kube-vip/dependabot/go_modules/golang.org/x/net-0.17.0
Bump golang.org/x/net from 0.12.0 to 0.17.0
2023-10-17 11:28:44 +02:00
Daniel Finneran
29d7773064 Merge pull request #629 from g-gaston/fix-etcd-e2e-test-action
Fix etcd e2e tests in GitHub actions
2023-10-17 11:21:45 +02:00
Guillermo Gaston
b5bf507546 Fix etcd e2e tests in GitHub actions
In order to run the kubelet in kind containers on the vms provided by
github, the kubelet needed some extra configuration.

Signed-off-by: Guillermo Gaston <gaslor@amazon.com>
2023-10-17 00:23:49 +00:00
dependabot[bot]
04bdc57434 Bump golang.org/x/net from 0.12.0 to 0.17.0
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.12.0 to 0.17.0.
- [Commits](https://github.com/golang/net/compare/v0.12.0...v0.17.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-14 11:20:58 +00:00
Daniel Finneran
fa26d779a0 Merge pull request #626 from g-gaston/etcd-vip
Add leader election using etcd as a backend
2023-10-14 13:19:56 +02:00
Guillermo Gaston
ae307f8cad Add leader election using etcd as a backend
This adds a new leader election mode that instead of using the kube api
server to obtain a lease, it relies solely on etcd.

By removing the dependency on the api server, we can use it even before
the api server is up, before cluster creation.

In an external etcd topology, this way we can make the api server point
to the VIPs instead of to the etcd machines IPs. This configuration
isolates the CP configuration from the etcd machine IPS. It's is super
convenient to avoid having to roll new control plane nodes when the etcd
nodes change.

Signed-off-by: Guillermo Gaston <gaslor@amazon.com>
2023-10-06 17:03:03 +00:00
Daniel Finneran
cbcc68e69d Update Makefile
Bump for new release
2023-10-04 09:37:41 +01:00
Daniel Finneran
a09a1db44c Merge pull request #623 from thebsdbox/fatal_interface
Call fatal when interface fails
2023-10-04 10:36:46 +02:00
Daniel Finneran
8d362d9d67 Merge pull request #624 from g-gaston/unit-tests
Enable unit and e2e tests in CI
2023-10-04 10:36:31 +02:00
Guillermo Gaston
72410cc6f7 Enable unit and e2e tests in CI
* Fix 2 broken tests
* Fix e2e ARP tests: killing one node in a 2 CP node cluster makes etcd
  lose quorum. So it can't elect a new leader if the node we happen to
  kill was the etcd leader.
* Separate unit tests, e2e tests, linter and scans in different jobs so
  they run concurrently.

Signed-off-by: Guillermo Gaston <gaslor@amazon.com>
2023-10-03 22:00:09 +00:00
Dan Finneran
36bccb723e Call fatal when interface fails
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2023-10-03 14:47:44 +00:00
Daniel Finneran
bfa6a9a9ac Merge pull request #622 from Willena/feat/svc-lock-configurable-in-arp-mode
Allow svc lock name to be configurable in arp mode.
2023-10-03 16:38:07 +02:00
Guillaume Villena
e41abf0f88 Allow svc lock name to be configurable in arp mode.
Signed-off-by: Guillaume Villena <guillaume@villena.me>
2023-10-01 01:12:37 +02:00
Daniel Finneran
0def3c0346 Merge pull request #621 from thebsdbox/endpoint_fqdn
Adds logic and debugging around fqdn endpoints
2023-09-29 17:02:56 +02:00
Dan Finneran
0ad1ccbf2f Adds logic and debugging around fqdn endpoints
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2023-09-28 12:38:54 +00:00
Daniel Finneran
219bc19bc2 Update ci.yaml
Adds Trivy scanning
2023-09-28 11:39:46 +01:00
Daniel Finneran
565e6dc550 Merge pull request #619 from thebsdbox/alpine_bump
This bumps the base images for vulnerabilities
2023-09-27 11:33:05 +02:00
Dan Finneran
d69a92f312 This bumps the base images for vulnerabilities
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2023-09-27 09:20:31 +00:00
Daniel Finneran
cc96d65b14 Merge pull request #612 from mjtrangoni/chore 2023-09-22 22:45:00 +02:00
Daniel Finneran
bad938105f Merge pull request #613 from mjtrangoni/handle-prom-root 2023-09-22 22:44:41 +02:00
Daniel Finneran
a826649886 Merge pull request #617 from mjtrangoni/add-node-labeling 2023-09-22 22:44:09 +02:00
Mario Trangoni
5ac633f319 ARP: Add node labeling for ARP mode DaemonSet deployment.
This feature is related to #611, to configure the
`CiliumEgressGatewayPolicy` EgressIP correctly.

As this is not a very common usage for this project, there is a default
disabled configuration flag added, `enable_node_labeling`.

Signed-off-by: Mario Trangoni <mjtrangoni@gmail.com>
2023-09-19 13:47:44 +02:00
Mario Trangoni
d8ed0e5296 prometheus: Handle root path
Signed-off-by: Mario Trangoni <mjtrangoni@gmail.com>
2023-09-14 14:26:01 +02:00
Mario Trangoni
06e41bae50 chore: Fix some misspellings found by codespell
Signed-off-by: Mario Trangoni <mjtrangoni@gmail.com>
2023-09-14 11:11:44 +02:00
Mario Trangoni
99e9579de5 Ignore kube-vip binary
Signed-off-by: Mario Trangoni <mjtrangoni@gmail.com>
2023-09-14 11:07:47 +02:00
Timo Sluis
31b7aad6c0 revert go.mod and go.sum
Signed-off-by: Timo Sluis <timo.sluis@live.nl>
2023-09-11 13:14:04 +02:00
Timo Sluis
991587c294 fix formatting + add route to link + remove route on shutdown
Signed-off-by: Timo Sluis <timo.sluis@live.nl>
2023-09-11 11:06:48 +02:00
Timo Sluis
89d883d0ec add routing table id as envvar
Signed-off-by: Timo Sluis <timo.sluis@live.nl>
2023-09-08 15:50:24 +02:00
Timo Sluis
724ec2ab10 specify different scope for local routes
Signed-off-by: Timo Sluis <timo.sluis@live.nl>
2023-09-08 15:28:45 +02:00
Timo Sluis
8afe5ca155 add comment about valid values
Signed-off-by: Timo Sluis <timo.sluis@live.nl>
2023-09-07 13:34:51 +02:00
Roman Dodin
6d47329f7c added create rbac settings section for kind 2023-09-04 20:47:56 +02:00
Timo Sluis
9fbe98c5d9 gofmt
Signed-off-by: Timo Sluis <timo.sluis@live.nl>
2023-09-04 16:45:47 +02:00
Timo Sluis
55398e6cfc add routing table type environment variable
Signed-off-by: Timo Sluis <timo.sluis@live.nl>
2023-09-04 16:35:09 +02:00
Daniel Finneran
f7666067a4 Update Makefile for new release 2023-08-24 09:01:16 +01:00
Daniel Finneran
a47e46ce84 Merge pull request #601 from usiegl00/main
Fix dos through checking for remaining services before releasing ip. …
2023-08-18 09:37:15 +01:00
usiegl00
9c84c56959 Fix formatting to pass lint.
Signed-off-by: usiegl00 <50933431+usiegl00@users.noreply.github.com>
2023-08-18 03:42:46 +09:00
usiegl00
b4f5554670 Fix dos through checking for remaining services before releasing ip. Fixes #600
Signed-off-by: usiegl00 <50933431+usiegl00@users.noreply.github.com>
2023-08-17 05:03:36 +09:00
Daniel Finneran
96541380b5 Merge pull request #599 from thebsdbox/codeql
action fix
2023-08-15 19:41:15 +01:00
Dan Finneran
92338ae74f action fix
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2023-08-15 18:40:47 +00:00
Daniel Finneran
4e69ada00c Merge pull request #598 from thebsdbox/fix_main
Fix to main
2023-08-15 19:26:20 +01:00
Dan Finneran
baba79e6ad Fix to main
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2023-08-15 18:16:58 +00:00
Daniel Finneran
cfdd5d1c42 Merge pull request #575 from megakid/patch-1
Increase client QPS to reduce clientside k8api throttling
2023-08-15 19:14:41 +01:00
Daniel Finneran
57c008b6da Merge pull request #595 from jkossis/update-makefile-0.6.1
Updating version in makefile
2023-08-15 18:01:56 +01:00
Daniel Finneran
778886e426 Merge pull request #597 from thebsdbox/watch_fix
This makes sure we check if a services is active
2023-08-15 18:01:17 +01:00
Daniel Finneran
203de87a85 Merge pull request #596 from thebsdbox/e2e-2-death
Some BIG OLDE e2e tests!
2023-08-15 18:00:31 +01:00
Dan Finneran
a18e26dbc3 more_lint
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2023-08-15 16:46:19 +00:00
Dan Finneran
bc63ed2ee5 lint fixes
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2023-08-15 15:32:25 +00:00
Dan Finneran
6a71e264da This makes sure we check if a services is active
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2023-08-15 15:25:30 +00:00
Dan Finneran
aa9cb9a49b Some BIG OLDE e2e tests!
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2023-08-15 15:21:32 +00:00
James Connor
74f6785f34 Compilation fixes again 2023-08-15 15:24:20 +01:00
James Connor
7a5d80bf35 Merge branch 'kube-vip:main' into patch-1 2023-08-15 15:21:49 +01:00
Jason Kossis
5f9dc0a997 initial commit
Signed-off-by: Jason Kossis <jason.kossis@aexp.com>
2023-08-14 08:17:47 -04:00
Daniel Finneran
18fadf25a2 Merge pull request #593 from thebsdbox/ginko_bump
Fixes to ginko
2023-08-14 08:25:46 +01:00
Dan Finneran
92e13761e4 MORE AND MORE FIXES
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2023-08-13 15:04:39 +00:00
Dan Finneran
ab7ceb8933 more fixes
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2023-08-13 14:45:16 +00:00
Dan Finneran
bac763e3f4 more tidying
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2023-08-13 14:04:33 +00:00
Dan Finneran
c2215e5d98 Fixes to ginko
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2023-08-13 13:57:12 +00:00
Daniel Finneran
c54994e9b7 Merge pull request #592 from thebsdbox/e2e_fixes
Fixes to e2e tests and re-enabling
2023-08-13 14:28:12 +01:00
Dan Finneran
1da54e6d8e lint fixes.
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2023-08-13 13:13:18 +00:00
Dan Finneran
9bfbb295dd Fixes to e2e tests and re-enabling
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2023-08-13 13:09:41 +00:00
Daniel Finneran
5a06a8888d Merge pull request #576 from mrueg/update-deps-0623
Update go dependencies
2023-08-12 10:27:30 +01:00
Manuel Rüger
7b64893703 Update golangci-lint
Signed-off-by: Manuel Rüger <manuel@rueg.eu>
2023-08-01 14:06:21 +02:00
Manuel Rüger
f36b433093 Update go dependencies
Signed-off-by: Manuel Rüger <manuel@rueg.eu>
2023-08-01 14:06:21 +02:00
Daniel Finneran
ec5a5139c8 Merge pull request #587 from rikatz/fix-dhcp-workflow-part1 2023-07-27 22:21:26 +01:00
Ricardo Katz
3d357a452b Fix linter error
Signed-off-by: Ricardo Katz <ricardo.katz@gmail.com>
2023-07-27 16:41:41 -03:00
Ricardo Katz
702a27bb1e Add proper backoff and max errors on dhcp client
Signed-off-by: Ricardo Katz <ricardo.katz@gmail.com>
2023-07-24 12:15:07 -03:00
Ricardo Katz
0060d36694 Update the DHCP workflows
Signed-off-by: Ricardo Katz <ricardo.katz@gmail.com>
2023-07-24 12:15:07 -03:00
Daniel Finneran
bdb9b0ef91 Merge pull request #585 from timosluis/lease_annotations
Allow specifying annotations for created Lease resources
2023-07-18 09:35:44 +01:00
Daniel Finneran
1ad0ae7740 Merge pull request #583 from kube-vip/dependabot/go_modules/google.golang.org/grpc-1.53.0
Bump google.golang.org/grpc from 1.51.0 to 1.53.0
2023-07-18 09:35:27 +01:00
Daniel Finneran
8c0791db19 Merge pull request #579 from runsisi/wip-fix-target
Fix makefile default target
2023-07-18 09:35:04 +01:00
Daniel Finneran
ec80533f81 Merge pull request #578 from marc-cerebras/marc-cerebras/bgp-cp-leaderelect
enable leaderelection for bgp in CP mode
2023-07-18 09:34:51 +01:00
Timo Sluis
64f8ebd865 fix formatting
Signed-off-by: Timo Sluis <timo.sluis@live.nl>
2023-07-12 11:27:49 +02:00
Timo Sluis
9667c7766f add lease annotations
Signed-off-by: Timo Sluis <timo.sluis@live.nl>
2023-07-12 11:14:14 +02:00
dependabot[bot]
23492519ed Bump google.golang.org/grpc from 1.51.0 to 1.53.0
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.51.0 to 1.53.0.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.51.0...v1.53.0)

---
updated-dependencies:
- dependency-name: google.golang.org/grpc
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-05 21:37:26 +00:00
runsisi
f2f7d362c7 Fix makefile default target
Signed-off-by: runsisi <runsisi@hust.edu.cn>
2023-06-21 07:53:43 +08:00
marc-cerebras
2dcd9e50c9 enable leaderelection for bgp in CP mode
Signed-off-by: marc-cerebras <marc.spehlmann@cerebras.net>
2023-06-19 11:25:13 -07:00
James Connor
c3ab677ad1 PR Fixes 2023-06-02 17:22:21 +01:00
James Connor
09daa0c57f Merge branch 'kube-vip:main' into patch-1 2023-06-02 17:20:04 +01:00
Daniel Finneran
c3a700ba3f Merge pull request #573 from timosluis/main
Use configurable LeaseName instead of hardcoded
2023-06-02 08:45:49 +01:00
James Connor
6f2acf0198 Increase client QPS to reduce clientside k8api throttling 2023-05-30 12:54:46 +01:00
Daniel Finneran
af86209d63 Merge pull request #571 from lubronzhan/topic/lubron/check_lb_cancel_func
Check activeServiceLoadBalancerCancel is nil or not before calling it
2023-05-25 16:19:18 +01:00
Timo Sluis
313c4c04f8 use config leasename instead of hardcoded
Signed-off-by: Timo Sluis <timo.sluis@live.nl>
2023-05-25 16:37:21 +02:00
lubronzhan
cd29e3d70a Check activeServiceLoadBalancerCancel is nil or not before calling it
Signed-off-by: lubronzhan <lzhan@vmware.com>
2023-05-22 14:36:15 -07:00
Daniel Finneran
6e8b3a9747 Merge pull request #569 from kube-vip/revert-502-iptables-nft
Revert "adding iptables-wrappers script to entrypoint"
2023-05-19 22:53:47 +01:00
Daniel Finneran
ef4995841a Revert "adding iptables-wrappers script to entrypoint" 2023-05-19 22:52:48 +01:00
Chris Privitere
0efed56a2a Merge pull request #502 from dockerpac/iptables-nft
adding iptables-wrappers script to entrypoint
2023-05-19 16:25:21 -05:00
Chris Privitere
fa248cca13 Merge pull request #567 from enkelprifti98/main
Add support for multiple BGP peers when using Equinix Metal annotations
2023-05-19 16:23:47 -05:00
Chris Privitere
24588d006a fix: formatting spaces on 217 2023-05-19 16:16:32 -05:00
Enkel Prifti
d7f4abafb8 Add support for multiple BGP peers when using Equinix Metal annotations
Using Equinix Metal annotations was limited to only the first BGP peer. This PR adds support for multiple BGP peer by looking at all bgp peer node annotations.

Signed-off-by: Enkel Prifti <enkelprifti@live.com>
2023-05-19 16:56:37 -04:00
Daniel Finneran
731545c666 Merge pull request #565 from enkelprifti98/main
Add BGP password support for Equinix Metal
2023-05-19 15:52:22 +01:00
Enkel Prifti
2a21b87b77 Add BGP password support for Equinix Metal
The Equinix Metal API integration was missing support for BGP session passwords so this PR adds the BGP password parameter.

Signed-off-by: Enkel Prifti <enkelprifti@live.com>
2023-05-18 20:09:26 -04:00
Daniel Finneran
b594d459fc Update Makefile 2023-05-15 12:29:34 +01:00
Daniel Finneran
8ea53f2b54 Merge pull request #562 from yaocw2020/ignoreServiceSecurity
Add annotation kube-vip.io/ignore-service-security
2023-05-15 09:49:05 +01:00
Canwu Yao
9ec6b3e8f5 Add annotation kube-vip.io/ignore-service-security
Skip service security configuration for the service whose annotation kube-vip.io/ignore-service-security is true

Signed-off-by: Canwu Yao <yaocanwu@gmail.com>
2023-05-15 11:24:50 +08:00
Daniel Finneran
2796185267 Merge pull request #557 from sykesm/kill-pkg-service 2023-05-11 19:29:35 +01:00
Matthew Sykes
cc362f7774 checks - fix things flagged by linting
Signed-off-by: Matthew Sykes <matthew.sykes@gmail.com>
2023-05-11 11:39:23 -04:00
Matthew Sykes
cfbf9b0458 Move helper from pkg/service and remove package
The pkg/service package is no longer used.

Signed-off-by: Matthew Sykes <matthew.sykes@gmail.com>
2023-05-11 11:38:45 -04:00
Daniel Finneran
ed59a13f10 Merge pull request #560 from yaocw2020/0502
Set iptables rules to restrict user access to ports other than the load balancer service port through the VIP
2023-05-11 08:49:43 +01:00
Canwu Yao
f2f73c00d0 Set iptables rules to limit traffic ports
Signed-off-by: Canwu Yao <yaocanwu@gmail.com>
2023-05-10 23:32:04 +08:00
Daniel Finneran
f03917e63f Merge pull request #561 from DrBu7cher/add_bgp_metrics_v1 2023-05-10 09:54:24 +01:00
Daniel Finneran
17eee86f2c Update main.yaml
Allow on-request builds.
2023-05-08 15:15:40 +01:00
Daniel Finneran
834aa94f75 Merge pull request #558 from thebsdbox/egress_namespace_isolation
This ensures rule cleaning only happens in a NS
2023-05-08 13:33:59 +01:00
Jonas Badstübner
4a2e72e811 refactor(metrics): better memory efficiency
Signed-off-by: Jonas Badstübner <jonas.badstuebner@hetzner-cloud.de>
2023-05-08 10:17:51 +02:00
Jonas Badstübner
68e6a940a2 feat(metrics): implement bgp_session_info
Signed-off-by: Jonas Badstübner <jonas.badstuebner@hetzner-cloud.de>
2023-05-08 10:17:51 +02:00
Jonas Badstübner
386d1514c2 feat(metrics): add bgp_session_info
Signed-off-by: Jonas Badstübner <jonas.badstuebner@hetzner-cloud.de>
2023-05-08 10:17:51 +02:00
Jonas Badstübner
640743a2de feat(bgp-server): add peer state change callback
Signed-off-by: Jonas Badstübner <jonas.badstuebner@hetzner-cloud.de>
2023-05-08 10:17:51 +02:00
Canwu Yao
1474fcf369 Support changing load balancer IP
Signed-off-by: Canwu Yao <yaocanwu@gmail.com>
2023-05-07 12:00:44 +08:00
Dan Finneran
e6e4d1cf08 This ensures rule cleaning only happens in a NS
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2023-05-05 16:51:03 +00:00
Daniel Finneran
60957d64aa Merge pull request #555 from sykesm/ipvs-ipv6
Ignore different family on IPVS delete
2023-05-03 16:08:08 +02:00
Matthew Sykes
37364882fd Ignore different family on IPVS delete
Signed-off-by: Matthew Sykes <matthew.sykes@gmail.com>
2023-05-03 08:31:29 -04:00
Daniel Finneran
e0a9e70664 Merge pull request #553 from tuxtof/fix-lb-annotation
fix LB annotations
2023-05-03 10:48:52 +02:00
Daniel Finneran
839011c29d Merge pull request #554 from sykesm/ipvs-ipv6
Use correct address family for ipvs destinations
2023-05-03 10:48:29 +02:00
Matthew Sykes
7fcf0f1b65 Use correct address family for ipvs destinations
When IPv6 addresses are present in node.Status.Addresses, the
IPVSLoadBalancer parses the addresses and attempts to add them as an
IPv4 destinations. This results in useless entries in the service table
that only hold the last 32 bits of address.

This change does two things:
- uses the appropriate address family when creating the service
- ignores backend addresses that use a different address family than the
  service

This avoids the immediate problem of using the wrong address family for
IPv6 destinations and the useless entries in the service table.

Signed-off-by: Matthew Sykes <matthew.sykes@gmail.com>
2023-04-30 17:38:14 -04:00
Christophe Jauffret
b33da242e8 fix LB annotations
Signed-off-by: Christophe Jauffret <reg-github@geo6.net>
2023-04-29 08:11:05 +02:00
Daniel Finneran
27444b31ee Merge pull request #546 from W1zzardTPU/main
Add support for lbClassName
2023-04-26 16:08:03 +02:00
W1zzardTPU
f1eef8f07d Add support for lbClassName 2023-04-23 20:36:59 +02:00
Daniel Finneran
e4f42a3a44 Merge pull request #540 from thebsdbox/iptables
Adds nftables as an option, and fixes a panic
2023-04-14 09:35:07 +01:00
Dan Finneran
6c5b39b02a Merge branch 'iptables' of github.com:thebsdbox/kube-vip into iptables 2023-04-14 08:30:01 +00:00
Dan Finneran
e8319a6464 dont lint old files
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2023-04-14 08:29:51 +00:00
Daniel Finneran
7e4f596b5d Merge branch 'main' into iptables 2023-04-14 09:14:42 +01:00
Dan Finneran
eac9d2b8be Adds nftables as an option, and fixes a panic
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2023-04-14 08:13:27 +00:00
Chris Privitere
2b7c02c614 Merge pull request #538 from lubronzhan/topic/lubron/kube-vip_update_version_variable
Update makefile to accept variable to update version
2023-04-05 08:57:01 -05:00
lubronzhan
aa7eabd4fb Update makefile to accept variable to update version
Signed-off-by: lubronzhan <lzhan@vmware.com>
2023-04-04 22:48:59 -07:00
Daniel Finneran
aeabe547ff Merge pull request #536 from thebsdbox/iptables
Adds ability to specifc iptables or nftables
2023-04-04 15:11:25 +01:00
Daniel Finneran
8febca00ee Update ci.yaml 2023-04-04 15:02:33 +01:00
Daniel Finneran
6037cc7a6e Merge pull request #531 from lubronzhan/topic/lubron/fix_doc_link
Fix the doc link
2023-04-04 14:53:35 +01:00
Dan Finneran
9119597b94 final fixes
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2023-04-04 13:52:45 +00:00
Dan Finneran
9e88b0003f Further linting fixes
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2023-04-04 13:44:03 +00:00
Dan Finneran
f4d193f7fb Merge branch 'iptables' of github.com:thebsdbox/kube-vip into iptables 2023-04-04 08:46:58 +00:00
Dan Finneran
e604e4fe26 lint fixes
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2023-04-04 08:45:56 +00:00
Daniel Finneran
8590fefa05 Merge branch 'main' into iptables 2023-04-03 18:19:30 +01:00
Dan Finneran
ae25e6bcf3 Adds ability to specifc iptables or nftables
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2023-04-03 17:18:00 +00:00
Daniel Finneran
8af0391bc9 Merge pull request #528 from lubronzhan/topic/lubron/deprecate_loadbalancerip
Deprecate loadbalancerIP, use annotation to fetch service loadbalancerIP
2023-03-16 16:23:32 +00:00
Pierre-Antoine Couaillier
e1bafbe699 Merge branch 'kube-vip:main' into iptables-nft 2023-03-09 14:22:36 +01:00
lubronzhan
cc63a13303 Fix the doc link
Signed-off-by: lubronzhan <lubronzhan@gmail.com>
2023-03-09 00:15:26 -08:00
Daniel Finneran
fb66fe0708 Merge pull request #529 from lubronzhan/topic/lubron/update_readme 2023-03-07 07:00:00 +00:00
lubronzhan
332546dd13 Update readme
Signed-off-by: lubronzhan <lzhan@vmware.com>
2023-03-06 16:01:31 -08:00
lubronzhan
a9932ec148 Deprecate loadbalancerIP
Add new annotation kube-vip.io/loadbalancerIPs to specify the loadbalancer ip for service
Now ip address fetched from loadbalancer service are first fetched from annotation, then fallback to service spec
Unit test

Signed-off-by: lubronzhan <lzhan@vmware.com>
2023-03-06 15:53:38 -08:00
Daniel Finneran
a422d246bb Merge pull request #526 from mrueg/bump-deps 2023-03-06 18:21:44 +00:00
Manuel Rüger
798b9c4b8f go.mod: Bump dependencies
Also replace github.com/ghodss/yaml with sigs.k8s.io/yaml (maintained
fork).

Signed-off-by: Manuel Rüger <manuel@rueg.eu>
2023-03-05 12:40:54 +01:00
Daniel Finneran
c7536f180e Merge pull request #524 from tylerschultz/recreate-vip-on-dadfailed
Readd VIP if address has dadfailed flag
2023-03-02 17:48:52 +01:00
Tyler Schultz
61d5deb0b9 Readd VIP if address has dadfailed flag
Remove the address from in the interface case that a duplicate address is detected.
Without this change, kube-vip will take no corrective action, and the
address will remain in dadfailed state. Removing and re adding the
address causes duplicate address detection to happen again, hopefully
successfully the next time.

We suspect dadfailed happens when a new leader is elected and the old
leader is too slow or fails to delete the IP address.

Co-authored-by: Aidan Obley <aobley@vmware.com>
Co-authored-by: Christian Ang <angc@vmware.com>
Signed-off-by: Tyler Schultz <tschultz@vmware.com>
2023-03-01 22:41:10 +00:00
Daniel Finneran
49c871bd93 Merge pull request #521 from ocobleseqx/support_new_equinix_ccm_annotations
check for new equinix ccm annotations
2023-02-27 11:58:56 +01:00
Daniel Finneran
9c6b87c43c Update README.md 2023-02-27 09:44:42 +00:00
ocobleseqx
0320d256f3 replace packet with equinix metal in comments and logs
Signed-off-by: ocobleseqx <oscar.cobles@eu.equinix.com>
2023-02-24 13:33:16 +01:00
ocobleseqx
a691b3f128 check for new equinix ccm annotations
Signed-off-by: ocobleseqx <oscar.cobles@eu.equinix.com>
2023-02-23 19:41:20 +01:00
Daniel Finneran
a92c536de2 Update main.yaml 2023-02-21 08:56:40 +00:00
Daniel Finneran
323f054ca5 Merge pull request #519 from kube-vip/final-0.5.x-release
Update Makefile
2023-02-20 18:44:38 +01:00
Daniel Finneran
53d33d79f4 Update Makefile 2023-02-20 17:36:39 +00:00
Daniel Finneran
a31d9a65f2 Merge pull request #515 from kube-vip/dependabot/go_modules/golang.org/x/net-0.7.0
Bump golang.org/x/net from 0.2.0 to 0.7.0
2023-02-20 17:00:31 +01:00
Daniel Finneran
bcaa8bede6 Merge pull request #518 from thebsdbox/actions_fixes
Actions fixes
2023-02-20 16:53:38 +01:00
Dan Finneran
18d11ea252 Set correct labels.
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2023-02-20 15:53:10 +00:00
Dan Finneran
3971c7de0b Tidies actions.
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2023-02-20 15:51:33 +00:00
Daniel Finneran
0c14497985 Update anchore-syft.yml 2023-02-20 09:33:36 +00:00
Daniel Finneran
3caa8fdec2 Merge pull request #517 from thebsdbox/2e2eLint
lint fixes
2023-02-20 10:04:14 +01:00
Daniel Finneran
23fda78b45 Update ci.yaml
removes random manifest generate
2023-02-20 08:41:38 +00:00
Dan Finneran
aed43b2def final fix to makefile
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2023-02-19 16:39:08 +00:00
Dan Finneran
790d0b5291 lint fix
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2023-02-19 16:27:27 +00:00
Dan Finneran
7802027f67 lint fixes
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2023-02-19 16:09:25 +00:00
Daniel Finneran
606f3e30d5 Update ci.yaml 2023-02-19 16:02:42 +00:00
Daniel Finneran
90f6234d71 Merge pull request #516 from thebsdbox/e2eServices
Adds e2e testing of services
2023-02-19 16:59:13 +01:00
Dan Finneran
98c885dff5 Adds e2e testing of services
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2023-02-19 15:58:03 +00:00
dependabot[bot]
acea12d09a Bump golang.org/x/net from 0.2.0 to 0.7.0
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.2.0 to 0.7.0.
- [Release notes](https://github.com/golang/net/releases)
- [Commits](https://github.com/golang/net/compare/v0.2.0...v0.7.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-17 14:14:28 +00:00
Daniel Finneran
9d15cbe8ca Merge pull request #494 from fimmicon/patch-1
Fix broken link in docs
2023-02-17 15:11:51 +01:00
Daniel Finneran
a3644baa7d Merge pull request #513 from thebsdbox/endpoint_fixes
Fixes and testing for endpoints
2023-02-15 15:09:22 +01:00
Dan Finneran
c10b4105b9 Fixes and testing for endpoints
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2023-02-15 13:52:25 +00:00
Daniel Finneran
62d826fbe5 Merge pull request #512 from thebsdbox/endpoint_leadership
Ensures a leadership will be restarted
2023-02-10 19:30:25 +00:00
Dan Finneran
285f4e514c this should be it
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2023-02-10 18:14:17 +00:00
Dan Finneran
71b490d735 stupid linter
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2023-02-10 18:09:55 +00:00
Dan Finneran
b62b331be8 more linting
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2023-02-10 18:02:46 +00:00
Dan Finneran
9ab8b909bf linter fix
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2023-02-10 16:41:48 +00:00
Dan Finneran
d93e0cdf9c Ensures a leadership will be restarted
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2023-02-10 16:36:20 +00:00
Daniel Finneran
4f0c163b89 Merge pull request #510 from spideyfusion/fix-service-delete
Fix service deletion not registering
2023-02-10 16:35:41 +00:00
Daniel Finneran
a66b84a77e Update Makefile 2023-02-08 14:05:37 +00:00
Daniel Finneran
b446a80d9b Merge pull request #511 from thebsdbox/context_fix
Adds services testing and fixes missing context
2023-02-08 14:05:13 +00:00
Dan Finneran
aa296d8211 Fixes to linting
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2023-02-08 13:57:01 +00:00
Dan Finneran
3a8a94fcc9 Adds services testing and fixes missing context
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2023-02-08 12:58:44 +00:00
Daniel Finneran
3ff1eb2f99 Merge pull request #509 from thebsdbox/main
Fixes to negative waitgroup
2023-02-07 08:59:43 +00:00
Petar Obradović
9f728278fd Fix service deletion not registering
Signed-off-by: Petar Obradović <petar.obradovic@sofascore.com>
2023-02-02 11:58:41 +01:00
Dan Finneran
7ad4e27084 Fixes to negative waitgroup
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2023-02-02 10:30:35 +00:00
Daniel Finneran
1b4bba0800 New Release 2023-01-19 15:10:21 +00:00
Daniel Finneran
1d1a8bbd55 Merge pull request #503 from thebsdbox/api_failure
Keep watching services after losing leadership
2023-01-19 15:09:59 +00:00
Dan Finneran
631960fb0c Keep watching services after losing leadership
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2023-01-16 20:57:34 +00:00
Pierre-Antoine Couaillier
af5860633b adding iptables-wrappers script to entrypoint
Signed-off-by: Pierre-Antoine Couaillier <pa.couaillier@gmail.com>
2023-01-16 16:47:56 +00:00
Daniel Finneran
c9ce2cf779 Merge pull request #498 from kriansa/patch-1
Fix watching for endpoints RBAC rule
2023-01-09 16:38:34 +00:00
Daniel Finneran
f28a448d0b Merge pull request #500 from imzyxwvu/fix/ipv6-path
Enable IPv6 peering and VIP advertisement and improve BGP support.
2023-01-09 16:36:52 +00:00
zyxwvu Shi
d01903194b doc: Update bgp_peers description
Signed-off-by: zyxwvu Shi <i@shiyc.cn>
2023-01-08 16:51:17 +08:00
zyxwvu Shi
1dfda79af8 bgp: Make password and multiHop params optional
Also fix a CodeQL alert.

Signed-off-by: zyxwvu Shi <i@shiyc.cn>
2023-01-08 16:51:17 +08:00
zyxwvu Shi
b83a993805 bgp: Allow IPv6 BGP peer to be specified with brackets
Ability to specify BGP port is removed, for two reasons:
1. IPv6 peer addresses contain colons, and the SpiltN func breaks IPv6 addresses.
2. Typical network devices do not allow changing BGP port, so this is rarely used.

Signed-off-by: zyxwvu Shi <i@shiyc.cn>
2023-01-08 16:51:17 +08:00
zyxwvu Shi
95ae62e9eb bgp: Remove unused Config fields
Signed-off-by: zyxwvu Shi <i@shiyc.cn>
2023-01-08 16:51:17 +08:00
zyxwvu Shi
35a93d8275 bgp: Advertise IPv6 host prefix using MpReachNLRIAttribute
MP-BGP protocol requires IPv6 prefixes to be advertised in a path attribute called MP_REACH_NLRI. Without the attribute non-IPv4 prefixes can not be advertised. This prevents IPv6 loadBalancerIps and control plane addresses from being advertised to the network.

Signed-off-by: zyxwvu Shi <i@shiyc.cn>
2023-01-08 16:51:17 +08:00
zyxwvu Shi
1dc74c4249 bgp: Let gobgp figure out NEXT_HOP path attribute
According to UpdatePathAttrs in gobgp internal/pkg/table/path.go, gobgp will fill NEXT_HOP with BGP session local address if given NEXT_HOP is an unspecified address, such as 0.0.0.0 and ::. It is better to use that address as NEXT_HOP, since the BGP TCP connection ensures the address reaches the node.

See: https://github.com/osrg/gobgp/blob/v3.10.0/internal/pkg/table/path.go#L223

Signed-off-by: zyxwvu Shi <i@shiyc.cn>
2023-01-06 22:51:41 +08:00
Daniel Finneran
c69edfe1e6 Merge pull request #493 from GeorgeGedox/patch-1
Update broken links in k3s docs
2022-12-30 16:03:33 +00:00
Daniel Pereira
9c7a1e60be fix: endpoints watcher
Without this specific ClusterRole rule, kube-vip would not be able to listen for `endpoints` changes when deployed as a DaemonSet, thus causing the IP addresses not being announced and the following error message every second:

```
E1227 20:37:20.290479       1 retrywatcher.go:130] "Watch failed" err="unknown (get endpoints)"
```
2022-12-27 17:46:44 -03:00
Efim
9c60351867 Fix broken link in docs 2022-12-06 14:27:18 +02:00
George V
45aae3ee7c Update broken links in k3s docs
Fix broken documentation links
2022-12-04 00:01:44 +02:00
Daniel Finneran
f830b389da Update Makefile 2022-12-01 11:23:21 +00:00
Daniel Finneran
3026769caf Merge pull request #490 from thebsdbox/goroutine_gc
garbage collection for goroutines
2022-12-01 11:19:20 +00:00
Dan Finneran
1e4ef9f2b1 garbage collection for goroutines
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2022-12-01 11:09:54 +00:00
Daniel Finneran
26f1b9ae67 Merge pull request #489 from lubronzhan/cve_2022_nov_28
Fix CVE
2022-11-29 20:16:24 +00:00
lubronzhan
f4a9e1b65b Fix several CVEs
Signed-off-by: lubronzhan <lzhan@vmware.com>
2022-11-28 18:11:51 -08:00
Daniel Finneran
96134ccbe5 Merge pull request #487 from stevesloka/linter-errors
linter: Clean up some linter errors
2022-11-28 13:44:12 +00:00
Steve Sloka
6d5533ca58 linter: Clean up some linter errors
Cleans up errors found when running `make` that golangci-lint
found.

Signed-off-by: Steve Sloka <steve@stevesloka.com>
2022-11-26 11:57:17 -05:00
Daniel Finneran
99b261a685 Merge pull request #485 from thebsdbox/reconcilliation_testing
added testing
2022-11-17 16:18:15 +00:00
Dan Finneran
f84c4aaa8b added testing
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2022-11-17 16:17:18 +00:00
Daniel Finneran
0aa339ec00 Merge pull request #484 from thebsdbox/flush_conntrack
Adds an annotation for flushing conntrack rules
2022-11-16 14:54:42 +00:00
Dan Finneran
139add9d51 Adds an annotation for flushing conntrack rules
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2022-11-16 13:20:17 +00:00
Daniel Finneran
06c5f784b8 Merge pull request #483 from thebsdbox/address_annotation
Tidies the annotations
2022-11-16 13:04:12 +00:00
Dan Finneran
dc40c4dc0b Tidies the annotations
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2022-11-16 13:03:27 +00:00
Daniel Finneran
76c5711129 Merge pull request #482 from thebsdbox/egress_clean_fix
Fix to egress rules
2022-11-10 11:28:42 +00:00
Daniel Finneran
7ebb54961b Update release.yaml
Allows manual trigger
2022-11-10 10:58:33 +00:00
Dan Finneran
47a8832d89 Fix to egress rules
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2022-11-10 10:52:53 +00:00
Daniel Finneran
1dc035f606 Update Makefile
Bumping for a new release!
2022-11-09 17:10:02 +00:00
Daniel Finneran
63e513ee34 Merge pull request #480 from thebsdbox/further_fixes
logging and fixed an issue with multiple elections
2022-11-09 17:09:32 +00:00
Dan Finneran
e599a33330 logging and fixed an issue with multiple elections
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2022-11-09 16:49:33 +00:00
Daniel Finneran
46d662ac14 Merge pull request #478 from thebsdbox/dangling_rules
Fixes to where iptables are gc
2022-11-07 13:41:26 -05:00
Dan Finneran
ccaf8119da Fixes to where iptables are gc
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2022-11-07 18:40:48 +00:00
Daniel Finneran
d8654781a9 Merge pull request #477 from thebsdbox/subnet
Adds capability to specify a subnet for the VIP
2022-11-07 12:46:09 -05:00
Dan Finneran
5e38c81290 Adds capability to specify a subnet for the VIP
Signed-off-by: Dan Finneran <daniel.finneran@gmail.com>
2022-11-07 17:43:55 +00:00
Daniel Finneran
f052777b6b Merge pull request #476 from thebsdbox/rule_cleaning
Adds tags to rules so that we can garbage collect.
2022-11-07 10:41:46 -05:00
Dan Finneran
af1a1e51c8 Adds tags to rules so that we can garbage collect. 2022-11-07 15:25:34 +00:00
Daniel Finneran
315fa695f4 Merge pull request #474 from thebsdbox/cached_services
This fixes an issue with the cache being wiped
2022-11-02 13:28:29 -04:00
thebsdbox
ccaef3d750 This fixes an issue with the cache being wiped
Signed-off-by: thebsdbox <dan@thebsdbox.co.uk>
2022-11-02 16:18:17 +00:00
Daniel Finneran
3d7c1229e5 Merge pull request #473 from thebsdbox/cidr
Adds the capability to exclude egress traffic
2022-10-31 12:16:47 -04:00
thebsdbox
f173c5f979 Adds the capability to exclude egress traffic
Signed-off-by: thebsdbox <dan@thebsdbox.co.uk>
2022-10-31 16:07:35 +00:00
Daniel Finneran
28eb301d32 Merge pull request #472 from thebsdbox/leaderElection
Fixes all leaderElection code to use config
2022-10-31 11:53:03 -04:00
thebsdbox
a4b11e6854 Fixes all leaderElection code to use config
Signed-off-by: thebsdbox <dan@thebsdbox.co.uk>
2022-10-31 15:52:29 +00:00
Daniel Finneran
4073cc3a8b Merge pull request #470 from thebsdbox/logging
Fixes to logging
2022-10-31 10:29:54 -04:00
thebsdbox
8687d28eb4 Fixes to logging
Signed-off-by: thebsdbox <dan@thebsdbox.co.uk>
2022-10-31 13:22:17 +00:00
Daniel Finneran
5330992f9b Merge pull request #469 from thebsdbox/testing_adds
Adds some additional checking scripts
2022-10-31 08:55:59 -04:00
thebsdbox
6c52800bd4 Adds some additional checking scripts 2022-10-31 12:54:53 +00:00
Daniel Finneran
76d5ad8a49 Merge pull request #467 from abhay-krishna/fix-typo
Fix typo in EnableControlPlane config option
2022-10-19 09:26:00 +01:00
Abhay Krishna Arunachalam
7321a06dae Fix typo in EnableControlPlane config option
Signed-off-by: Abhay Krishna Arunachalam <arnchlm@amazon.com>
2022-10-18 22:22:58 -07:00
Daniel Finneran
34b05aa525 Merge pull request #460 from mrueg/update-deps
Update deps / build with go 1.19
2022-10-12 09:22:32 +01:00
Manuel Rüger
6004892920 go.mod: Update dependencies
Signed-off-by: Manuel Rüger <manuel@rueg.eu>
2022-10-11 20:08:13 +02:00
Manuel Rüger
ea7ab1e4d6 Update to go 1.19
Signed-off-by: Manuel Rüger <manuel@rueg.eu>
2022-10-11 20:08:11 +02:00
Daniel Finneran
c9a4d584b4 Delete release_iptables.yaml 2022-10-11 13:13:45 +01:00
Daniel Finneran
bc260ce03a Update release.yaml 2022-10-11 13:13:31 +01:00
Daniel Finneran
28b58dc013 Create release_iptables.yaml 2022-10-11 09:45:07 +01:00
Daniel Finneran
256f866d43 Update release.yaml 2022-10-11 09:44:23 +01:00
Daniel Finneran
56362fb47e Update release.yaml 2022-10-10 20:27:10 +01:00
Daniel Finneran
5c859f42f5 Update Makefile 2022-10-10 16:25:16 +01:00
Daniel Finneran
834b5aae54 Merge pull request #459 from thebsdbox/egress_ports
Adds ports and namespaces
2022-10-10 16:24:10 +01:00
thebsdbox
daa7d852ab linting fixes 2022-10-10 14:12:36 +01:00
thebsdbox
651038ada2 Adds ports and namespaces 2022-10-10 13:48:54 +01:00
Daniel Finneran
97eae7c528 Merge pull request #456 from thebsdbox/egress_stability
Adds stability and warnings to egress
2022-09-28 12:06:16 +01:00
Daniel Finneran
c41df19a36 Update mainiptables.yaml 2022-09-28 12:01:22 +01:00
Daniel Finneran
88af581958 Update mainiptables.yaml 2022-09-28 11:56:39 +01:00
Daniel Finneran
00cd131e2e Update mainiptables.yaml 2022-09-28 11:55:16 +01:00
Daniel Finneran
e6ae07f404 Create mainiptables.yaml 2022-09-28 11:54:38 +01:00
Daniel Finneran
2a1152f4d0 Merge pull request #449 from daper/main
Add random MAC address generation for DHCP
2022-09-28 11:44:55 +01:00
thebsdbox
36f42300c4 Adds stability and warnings to egress 2022-09-28 11:44:02 +01:00
Daniel Finneran
65c175d185 Merge pull request #445 from thebsdbox/egress
This adds the initial code for egress (SNAT).
2022-09-15 15:45:28 +03:00
thebsdbox
6620440c95 Final first push at Egress 2022-09-15 13:41:42 +01:00
daper
023ddbafd1 Add random MAC address generation for DHCP
Signed-off-by: David Peralta <david@daper.email>
2022-09-13 16:37:01 +02:00
thebsdbox
98f5c73919 Fixes to iptables and endpoint watcher 2022-09-13 09:09:20 +01:00
Daniel Finneran
de206eb46a Merge pull request #440 from cprivitere/Build-fixes
Build-fixes
2022-09-11 08:52:06 +01:00
Daniel Finneran
0b82de9dcf Merge pull request #446 from alexandrevilain/fix/wrong-env-var 2022-09-07 20:29:33 +01:00
Alexandre Vilain
db1ed82510 fix --table flag should add vip_routingtable env var not vip_wireguard
Signed-off-by: Alexandre Vilain <alexandre.vilain@me.com>
2022-09-07 21:03:17 +02:00
thebsdbox
ba20ae1725 This adds the initial code for egress (SNAT). 2022-09-06 15:18:48 +01:00
Daniel Finneran
bb4c815c5c Update anchore-syft.yml 2022-08-30 14:28:10 +01:00
Daniel Finneran
8a0eb9a661 Update anchore-syft.yml 2022-08-30 14:26:29 +01:00
Chris Privitere
8eaafee0f5 Add ReadHeaderTimeout
Resolves golanglint-ci complaint

Signed-off-by: Chris Privitere <23177737+cprivitere@users.noreply.github.com>
2022-08-29 15:30:10 -05:00
Chris Privitere
7e97ef0eef go fmt
Signed-off-by: Chris Privitere <23177737+cprivitere@users.noreply.github.com>
2022-08-29 15:29:42 -05:00
Daniel Finneran
85cb26d305 Update anchore-syft.yml 2022-08-26 12:52:07 +01:00
Daniel Finneran
6b12d18ab2 Update anchore-syft.yml 2022-08-26 09:39:04 +01:00
Daniel Finneran
a29cf4ea80 Update anchore-syft.yml
Fixes buildkit dependency
2022-08-26 09:36:29 +01:00
Daniel Finneran
494283d511 Add Anchore SBOM creation 2022-08-26 09:31:34 +01:00
Daniel Finneran
bb0d1a3db0 Merge pull request #435 from abhinavmpandey08/exclusive-lb-class 2022-08-15 19:05:38 +01:00
Abhinav Pandey
c50465c09c Enable kube-vip to only respond to svc with kube-vip's lb class
Signed-off-by: Abhinav Pandey <abhinavmpandey08@gmail.com>
2022-08-15 11:00:25 -07:00
Daniel Finneran
ff040f2def Merge pull request #434 from valtzu/main
Allow fixed virtual MAC for DHCP VIPs
2022-08-10 11:25:30 +01:00
valtzu
14100f0aec Allow fixed virtual MAC for VIPs via DHCP
Closes #354

Signed-off-by: valtzu <valtzu@gmail.com>
2022-08-08 00:13:27 +03:00
Daniel Finneran
708f4b3ebf Update FUNDING.yml 2022-08-07 12:24:32 +01:00
Daniel Finneran
1ef3592305 Update Makefile 2022-07-22 09:27:24 +01:00
Daniel Finneran
a00040dd40 Merge pull request #427 from thebsdbox/add-route-on-lead
Adds a route if leader
2022-07-21 14:32:02 +01:00
thebsdbox
31786074a8 Adds a route if leader 2022-07-21 14:30:54 +01:00
Daniel Finneran
a70b965b52 Update FUNDING.yml 2022-07-15 22:34:04 +01:00
Daniel Finneran
579d9dd89f Merge pull request #423 from kube-vip/thebsdbox-sponsor
Create FUNDING.yml
2022-07-15 09:03:02 +01:00
Daniel Finneran
ef78dcc5e5 Create FUNDING.yml 2022-07-15 08:53:50 +01:00
Daniel Finneran
49f4516209 Merge pull request #422 from scuzhanglei/fix-close-nil-chanel-panic
Fixes close nil channel panic
2022-07-14 13:10:59 +01:00
zhanglei
e6048c3eab Fixes close nil channel panic
Signed-off-by: zhanglei <zhanglei@smartx.com>
2022-07-14 19:40:16 +08:00
Daniel Finneran
d533e40796 Merge pull request #417 from thebsdbox/prometheus
prometheus changes
2022-07-05 14:15:38 +01:00
thebsdbox
93dfe4d372 prometheus changes 2022-07-01 17:01:59 +01:00
Daniel Finneran
c7c4f8d31a Merge pull request #416 from thebsdbox/table_mode
Table mode is now added to kube-vip
2022-06-30 14:17:34 +01:00
thebsdbox
9d15e0ac8b fixes to missing env 2022-06-30 11:25:40 +01:00
thebsdbox
1bcd101b53 Table mode is now added to kube-vip 2022-06-29 16:08:02 +01:00
Daniel Finneran
c6f37f433a Merge pull request #414 from thebsdbox/loadBalancerClass
Adds loadBalancerClass
2022-06-27 19:07:02 +01:00
thebsdbox
46b4325187 linting fix 2022-06-27 18:59:25 +01:00
thebsdbox
169eb0c7aa Adds loadBalancerClass 2022-06-27 18:08:09 +01:00
Daniel Finneran
b8d3ec8087 Merge pull request #412 from thebsdbox/wireguard
Wireguard support (basic)
2022-06-27 18:06:14 +01:00
thebsdbox
fcb24e7eab Fixes to the design 2022-06-27 17:41:33 +01:00
thebsdbox
8d0db81225 linter fixes 2022-06-25 16:57:10 +01:00
thebsdbox
ccee5ab7bd Wireguard support (basic) 2022-06-25 16:42:26 +01:00
Daniel Finneran
3c2eac15d4 Merge pull request #410 from thebsdbox/traffic_policy
This enables local traffic policy
2022-06-21 19:21:36 +01:00
thebsdbox
5485bbdcab This enables local traffic policy 2022-06-21 15:53:41 +01:00
Daniel Finneran
d815d3cb79 Merge pull request #407 from thebsdbox/leader_per_service
Initial design of leaderElection per service
2022-06-21 15:52:58 +01:00
thebsdbox
f51aa1f60f formatting fixes 2022-06-21 15:19:59 +01:00
thebsdbox
efea371edc Security fixes 2022-06-21 15:14:47 +01:00
thebsdbox
7d9062fd0e linting 2022-06-21 13:59:27 +01:00
thebsdbox
8d4f0e5206 annotations and working leaderElection 2022-06-21 13:57:13 +01:00
thebsdbox
b2df1cba3d Fixes to function signature 2022-06-08 13:14:38 +01:00
thebsdbox
840a2ba2b1 Initial design of leaderElection per service 2022-06-08 12:57:56 +01:00
Daniel Finneran
f22f6d4e93 Merge pull request #405 from thebsdbox/e2e
e2e test
2022-06-01 17:15:38 +02:00
thebsdbox
7c22c78a75 e2e test 2022-06-01 16:14:55 +01:00
Daniel Finneran
0487080505 Merge pull request #404 from thebsdbox/ignore_wrong_services
Ignore services that aren't LoadBalancers
2022-06-01 13:04:24 +02:00
thebsdbox
cef1852099 Ignore services that aren't LoadBalancers 2022-06-01 11:52:19 +01:00
Daniel Finneran
ac53446f33 Merge pull request #396 from AxiomSamarth/get-lease
set kubernetes:6443 as default hostname
2022-05-30 17:54:19 +02:00
Daniel Finneran
ca61bfdbe3 Merge pull request #401 from thebsdbox/em_annotations
Packet to equinixmetal
2022-05-30 17:54:05 +02:00
thebsdbox
f8d3152e93 disable new annotations 2022-05-30 13:30:20 +01:00
thebsdbox
f1841f70ef Packet to equinixmetal 2022-05-30 11:15:07 +01:00
AxiomSamarth
da7ba0b9a6 set kubernetes:6443 as default hostname
Signed-off-by: AxiomSamarth <sdeyagond@microsoft.com>
2022-05-14 13:00:19 +05:30
Daniel Finneran
b9014ae32a Update README.md 2022-05-13 15:32:47 +01:00
Daniel Finneran
51a1a0bb61 Merge pull request #395 from AxiomSamarth/get-lease
Set api-endpoint to host for incluster deployment
2022-05-13 14:20:38 +01:00
AxiomSamarth
75a2323448 set api-endpoint to host for incluster deployment
Signed-off-by: AxiomSamarth <sdeyagond@microsoft.com>
2022-05-13 18:28:09 +05:30
Daniel Finneran
7a7425efdf Update Makefile 2022-04-21 09:24:11 +01:00
Daniel Finneran
d4683401b6 Merge pull request #351 from yaocw2020/release-bug
Fix DHCP release bug
2022-04-21 09:12:07 +01:00
yaocw2020
e6edf3a3de Fix DHCP release bug
The macvlan interface could not be deleted until the DHCP client has
released the IP.

If the network manager in the operating system uses DHCP to obtain an IP
for the network card, it will occupy the DHCP client port. In this case
the release function will fail because the unicast connection with UDP
socket need the same port. Update dhcp package and use a raw socket.

Signed-off-by: yaocw2020 <yaocanwu@gmail.com>
2022-04-21 12:38:01 +08:00
Daniel Finneran
40cff6bc50 Merge pull request #389 from claudio4/main
Treat interfaces with unknown state as valid
2022-04-18 10:00:16 +01:00
Claudio Yanes
428d306030 Fix missing interface name in warning message
Signed-off-by: Claudio Yanes <me@claudio4.com>
2022-04-14 13:34:09 +01:00
Claudio Yanes
5fbb11fa06 Treat interfaces with unknown state as valid
Previous commits addressed the issue of interface being incorrectly marked as
down for loopback (1a4465e) and point-to-point (051bb1f) interfaces by directly
passing the test when the interface is identified a any of those types. Both
commits failed to address the core issue, those interfaces (and many others) do
not publish their operational state resulting in the state UNKOWN. With this
commit, now interfaces with unknown status are accepted but the user is warned as
he needs to manually ensure that the interface is ready to handle traffic.
Fix #385

Signed-off-by: Claudio Yanes <me@claudio4.com>
2022-04-14 13:34:09 +01:00
Daniel Finneran
8185df46b9 Merge pull request #388 from mrueg/ignore-p2p 2022-04-09 14:08:20 +01:00
Manuel Rüger
051bb1f414 Don't check status on Point-To-Point interfaces
Signed-off-by: Manuel Rüger <manuel@rueg.eu>
2022-04-09 00:20:16 +02:00
Daniel Finneran
b883939f6e Merge pull request #387 from mrueg/gobgpv
Update to gobgp/v3, ndp/v0.10.0 / go 1.18
2022-04-05 14:07:06 +01:00
Manuel Rüger
88c9075116 Update golangci-lint
Signed-off-by: Manuel Rüger <manuel@rueg.eu>
2022-04-05 00:31:42 +02:00
Manuel Rüger
fae208e459 Update to gobgp/v3, ndp/v0.10.0 / go 1.18
Signed-off-by: Manuel Rüger <manuel@rueg.eu>
2022-04-05 00:31:42 +02:00
Daniel Finneran
1279570f11 Merge pull request #386 from thebsdbox/testing_n_logs
Update to automated testing and clear msg
2022-04-04 20:54:45 +01:00
thebsdbox
d7b49a0f0f Update to automated testing and clear msg 2022-04-04 14:49:38 +01:00
Daniel Finneran
7b0bd4061f Update Makefile 2022-04-01 15:59:54 +01:00
Daniel Finneran
342161068a Merge pull request #384 from yaocw2020/supportChangingVIP
support changing the VIP of services
2022-04-01 15:57:58 +01:00
yaocw2020
c81c8c1865 support changing the VIP of services
- Support changing the VIP of services
- Refactory the manager.syncServices to improve code readability

Signed-off-by: yaocw2020 <yaocanwu@gmail.com>
2022-03-29 00:23:13 +08:00
Daniel Finneran
344cb491eb Merge pull request #383 from yaocw2020/gratuitous-arp 2022-03-24 15:35:52 +00:00
yaocw2020
9bd837f0c6 The gratuitous arp should be sent periodically
Related issue: https://github.com/kube-vip/kube-vip/issues/382

Signed-off-by: yaocw2020 <yaocanwu@gmail.com>
2022-03-24 12:24:55 +08:00
Daniel Finneran
b609330c48 Merge pull request #370 from rohitsakala/main
Add s390x arch support
2022-02-28 17:19:54 +00:00
Venkata Krishna Rohit Sakala
8afd9487ff Add s390x arch support
Signed-off-by: Venkata Krishna Rohit Sakala <rohitsakala@gmail.com>
2022-02-28 14:35:20 +01:00
Daniel Finneran
48add4ddeb Merge pull request #366 from mrueg/go-1.17
Build with go-1.17, bump dependencies
2022-02-28 10:02:31 +00:00
Daniel Finneran
ac83920e2c Merge pull request #365 from thebsdbox/retry_update
Adds retry to status update
2022-02-28 10:02:09 +00:00
Manuel Rüger
3f91c045d4 Build with go-1.17, bump dependencies
Signed-off-by: Manuel Rüger <manuel@rueg.eu>
2022-02-18 13:23:08 +01:00
Daniel Finneran
027703ec0f Merge pull request #364 from rawkode/fix/correctly-spell-prometheus
fix: spell prometheus correctly
2022-02-17 14:43:39 +00:00
thebsdbox
58da24127e Adds retry to status update 2022-02-17 14:42:56 +00:00
David Flanagan
1fb1de9990 fix: spell prometheus correctly 2022-02-14 18:50:46 +00:00
Daniel Finneran
7038960a24 Merge pull request #362 from thebsdbox/new_release
New release
2022-02-09 07:52:01 -05:00
thebsdbox
ff3a010a8d Security fix for unit 2022-02-09 11:37:47 +00:00
thebsdbox
e9ea905693 Fix environment variable and tidy 2022-02-09 11:16:42 +00:00
thebsdbox
8448c1224e Bump new release to 4.2 2022-02-09 11:10:37 +00:00
Chris Privitere
c5049407c7 Merge pull request #350 from kube-vip:cprivite/issue349
Merge pull request #348 from cprivite/cprivite/issue342
2022-01-11 16:14:34 -06:00
Chris Privitere
1e0523fa8a Use same formatting for main and release.
Signed-off-by: Chris Privitere <cprivite@users.noreply.github.com>
2022-01-11 15:28:56 -06:00
Chris Privitere
d1aa8bcb6f Switch to doing the tags with a github context.
Signed-off-by: Chris Privitere <cprivite@users.noreply.github.com>
2022-01-11 15:09:22 -06:00
Chris Privitere
ae22483f08 Add id as per docker-build-push pattern.
Signed-off-by: Chris Privitere <cprivite@users.noreply.github.com>
2022-01-11 15:08:50 -06:00
Chris Privitere
ad355fb6f6 Add login for github packages.
Signed-off-by: Chris Privitere <cprivite@users.noreply.github.com>
2022-01-11 15:08:30 -06:00
Chris Privitere
777eddafd8 Move from env vars to github contexts.
Signed-off-by: Chris Privitere <cprivite@users.noreply.github.com>
2022-01-11 15:08:05 -06:00
Chris Privitere
0d5a140f0d Rename to docker since it's also building.
Signed-off-by: Chris Privitere <cprivite@users.noreply.github.com>
2022-01-11 15:07:19 -06:00
Daniel Finneran
4b269dcdfd Merge pull request #348 from cprivite/cprivite/issue342
Don't check interface is up if it's loopback.
2022-01-10 17:51:47 +00:00
Chris Privitere
1a4465ebcc Don't check interface is up if it's loopback.
Signed-off-by: Chris Privitere <cprivite@users.noreply.github.com>
2022-01-10 11:22:54 -06:00
Daniel Finneran
41dc5e9914 Merge pull request #347 from yaocw2020/main
Build and publish the main image every day
2022-01-07 09:57:29 +00:00
yaocw2020
c037ac3561 Build and publish the main image every day
Signed-off-by: yaocw2020 <yaocanwu@gmail.com>
2022-01-07 00:52:47 +08:00
Daniel Finneran
056a6c5c16 Update readme with correct URL for logo 2021-12-23 10:23:56 +00:00
Daniel Finneran
ec0014d9ea Add logo 2021-12-23 10:23:05 +00:00
Daniel Finneran
ce37958c39 Merge pull request #341 from yaocw2020/debugLog
set route event log as debug level
2021-12-22 15:49:39 +00:00
yaocw2020
98f0a9505b set route event log as debug level
Signed-off-by: yaocw2020 <yaocanwu@gmail.com>
2021-12-22 22:46:26 +08:00
Daniel Finneran
36f1b33e94 Merge pull request #338 from mrueg/manifests-0.4.1
docs: Generate manifests for 0.4.1
2021-12-22 13:31:55 +00:00
Daniel Finneran
bad7b5f92c Merge pull request #339 from yaocw2020/checkDefaultIF
Monitor default VIP interface
2021-12-22 13:31:31 +00:00
Daniel Finneran
ac6cbad0eb Merge pull request #340 from mrueg/common-labels
config: Use recommended labels in manifests
2021-12-22 13:20:46 +00:00
Manuel Rüger
afd9029474 config: Use recommended labels in manifests
https://kubernetes.io/docs/concepts/overview/working-with-objects/common-labels/

Fixes: https://github.com/kube-vip/kube-vip/issues/315

Signed-off-by: Manuel Rüger <manuel@rueg.eu>
2021-12-22 13:52:32 +01:00
yaocw2020
306ce2440e Monitor default VIP interface
The kube-vip chooses the default interface based on the default
route. Once the default route changes, the default interface may be
invalid. In this case, it would be better to crash the process. The pod
will restart immediately if the kube-vip is deployed as a daemonset.

Signed-off-by: yaocw2020 <yaocanwu@gmail.com>
2021-12-22 20:37:58 +08:00
Manuel Rüger
0f391a0032 docs: Generate manifests for 0.4.1
Signed-off-by: Manuel Rüger <manuel@rueg.eu>
2021-12-22 13:32:38 +01:00
Daniel Finneran
94ab16575f Merge pull request #337 from thebsdbox/new_release
New 0.4.1 release
2021-12-22 11:35:16 +00:00
thebsdbox
179cfef6e2 New 0.4.1 release 2021-12-22 11:06:55 +00:00
Daniel Finneran
fdf7773d29 Merge pull request #334 from mrueg/update
Update golang to 1.16.12 and golang dependencies
2021-12-22 10:44:32 +00:00
Daniel Finneran
2e554c9d49 Merge pull request #336 from thebsdbox/SYS_TIME
removes an incorrect CAP
2021-12-22 10:44:16 +00:00
thebsdbox
3507c46a51 Removes redundant config generation and e2e fix 2021-12-22 10:25:19 +00:00
thebsdbox
7f58bf4012 removes an incorrect CAP 2021-12-22 10:14:20 +00:00
Manuel Rüger
cd5fa620d5 pkg/vip/ndp.go: Rename Dial to Listen
Function was renamed.
See: 9dc889e435

Signed-off-by: Manuel Rüger <manuel@rueg.eu>
2021-12-22 00:37:28 +01:00
Manuel Rüger
19d84bb50b go.mod: Update dependencies
github.com/cloudflare/ipvs v0.0.0-20210114211356-96b2597859b3 -> v0.8.0
github.com/insomniacslk/dhcp v0.0.0-20210621130208-1cac67f12b1e -> v0.0.0-20211214070828-5297eed8f489
github.com/mdlayher/ndp v0.0.0-20200602162440-17ab9e3e5567 -> v0.0.0-20210831201139-f982b8766fb5
github.com/mdlayher/raw v0.0.0-20210412142147-51b895745faf -> v0.0.0-20211126142749-4eae47f3d54b
github.com/onsi/ginkgo v1.14.0 -> v1.14.2
github.com/packethost/packngo v0.13.0 -> v0.20.0
github.com/prometheus/client_golang v0.10.0 -> v0.11.0
github.com/spf13/cobra v1.1.3 -> v1.3.0
github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f -> v0.0.0-20211101163701-50045581ed74
golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d -> v0.0.0-20211216030914-fe4d6282115f
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22 -> v0.0.0-20211216021012-1d35b9e2eb4e
golang.org/x/term v0.0.0-20210503060354-a79de5458b56 -> v0.0.0-20210927222741-03fcf44c2211
k8s.io/api v0.22.2 -> v0.22.5
k8s.io/apimachinery v0.22.2 -> v0.22.5
k8s.io/client-go v0.22.2 -> v0.22.5
k8s.io/klog/v2 v2.9.0 -> v2.40.1
sigs.k8s.io/kind v0.10.0 -> v0.11.1

Signed-off-by: Manuel Rüger <manuel@rueg.eu>
2021-12-22 00:37:28 +01:00
Manuel Rüger
09088a9c17 Dockerfile: Update to go 1.16.12 and alpine 3.15 base
Signed-off-by: Manuel Rüger <manuel@rueg.eu>
2021-12-21 23:22:03 +01:00
Daniel Finneran
a5b0eab318 Adding static analysis as part of CNCF onboarding 2021-12-21 09:33:52 +00:00
Daniel Finneran
1deb91a93d Merge pull request #332 from thebsdbox/vip_services_doc
Adds missing flag/env for services interface
2021-12-20 13:21:55 +00:00
thebsdbox
dd621131c6 Adds missing flag/env for services interface 2021-12-20 13:11:35 +00:00
Daniel Finneran
f442e61fd3 Merge pull request #329 from yaocw2020/validateInterface
Check interface
2021-12-19 11:22:33 +00:00
yaocw2020
df539cbc6e Check interface
In some cases, kube-vip will start to serve before the interface is not
existed or not up. We should make sure the interface is valid.

Signed-off-by: yaocw2020 <yaocanwu@gmail.com>
2021-12-17 00:02:18 +08:00
Daniel Finneran
1d39a5b34a Merge pull request #326 from spectrocloud/ddns-fix
fix ddns support
2021-12-13 11:52:39 +00:00
Deepak Sharma
a642f32414 add client id to request
Signed-off-by: Deepak Sharma <deepak@spectrocloud.com>
2021-12-13 16:18:00 +05:30
Daniel Finneran
ccc97b9bc5 Merge pull request #327 from jbguerraz/lbforwardingtype
allow to configure the ipvs forwarding method
2021-12-13 09:11:20 +00:00
Jean-Baptiste Guerraz
0649fb01eb allow to configure the ipvs forwarding method 2021-12-11 23:21:13 +00:00
Deepak Sharma
3855ed4553 ddns fix
gofmt file

Signed-off-by: Deepak Sharma <deepak@spectrocloud.com>
2021-12-10 17:03:47 +05:30
Daniel Finneran
3979c1fcce Merge pull request #320 from lewisdiamond/patch-3
Fix typo in log (s/addded/added/)
2021-12-06 12:42:55 +00:00
Daniel Finneran
af52f4f9fd Merge pull request #323 from sykesm/address-no-vip-panic
Pass resolved VIP from Network.IP() to NewIPVSLB
2021-12-06 12:42:05 +00:00
Daniel Finneran
4e1bb7f77a Merge pull request #321 from sykesm/control-plane-label
Update label selector for control-plane nodes
2021-12-02 11:19:22 +00:00
Lewis Diamond
92f6ad4395 Fix typo in log (s/addded/added/)
Signed-off-by: Lewis Diamond <git@lewisdiamond.com>
2021-11-29 11:27:31 -05:00
Matthew Sykes
2d14d63ef2 Pass resolved VIP from Network.IP() to NewIPVSLB
When the manager process is started without the `--vip` flag, it will
panic during initialization. This is because the `nil` result from
`net.ParseIP("")` is passed to `ipvs.NewIP()`.

This change passes the resolved address from `cluster.Network.IP()`
instead of the possibly-empty VIP from the configuration.

Signed-off-by: Matthew Sykes <matthew.sykes@gmail.com>
2021-11-27 21:16:38 -05:00
Matthew Sykes
022b62caca Update label selector for control-plane nodes
The current node watcher uses a label selector of the form
`node-role.kubernetes.io/control-plane=`; this does not work correctly.

The label selector should be `node-role.kubernetes.io/control-plane" or
`node-role.kubernetes.io/control-plane=true` to select the control-plane
nodes.

Without these changes, the IPVS tables are never updated with the
control plane nodes and clients making requests to the VIP will fail
with a "connection refused" error.

```
$ kubectl get nodes -l node-role.kubernetes.io/control-plane=
No resources found

$ kubectl get nodes -l node-role.kubernetes.io/control-plane=true
NAME     STATUS   ROLES                       AGE   VERSION
pi4-00   Ready    control-plane,etcd,master   21h   v1.22.3+k3s1
pi4-01   Ready    control-plane,etcd,master   20h   v1.22.3+k3s1
pi4-02   Ready    control-plane,etcd,master   20h   v1.22.3+k3s1

$ kubectl get nodes -l node-role.kubernetes.io/control-plane
NAME     STATUS   ROLES                       AGE   VERSION
pi4-00   Ready    control-plane,etcd,master   21h   v1.22.3+k3s1
pi4-01   Ready    control-plane,etcd,master   20h   v1.22.3+k3s1
pi4-02   Ready    control-plane,etcd,master   20h   v1.22.3+k3s1
```

Signed-off-by: Matthew Sykes <matthew.sykes@gmail.com>
2021-11-27 14:00:01 -05:00
Daniel Finneran
2a2cb7b5fa Update index.md 2021-11-25 09:45:27 +00:00
Daniel Finneran
0783c006b8 Update index.md
Fixes header
2021-11-25 09:44:43 +00:00
Daniel Finneran
147ae7ae5f Merge pull request #316 from thebsdbox/ipvs_race_condition
IPVS fixes
2021-11-23 19:19:31 +00:00
Daniel Finneran
0a3f963578 Merge pull request #313 from chipzoller/main
Extensive linting, corrections, expansions
2021-11-23 19:19:19 +00:00
Chip Zoller
48fc7bd4a1 Merge branch 'main' into main 2021-11-23 10:22:11 -05:00
Chip Zoller
8ad1620844 fix conflicts
Signed-off-by: Chip Zoller <chipzoller@gmail.com>
2021-11-23 10:20:29 -05:00
Chip Zoller
a36d33e4e5 further edits; revamp K3s docs
Signed-off-by: Chip Zoller <chipzoller@gmail.com>
2021-11-23 10:17:26 -05:00
thebsdbox
135a6b55e2 Final fixes to IPVS 2021-11-23 15:17:24 +00:00
Daniel Finneran
17fd21aeda Merge pull request #317 from lewisdiamond/patch-2
Various KIND documentation fixes
2021-11-23 15:02:24 +00:00
Lewis Diamond
0b6d0be44b Various KIND documentation fixes
KVVERSION needs to be preceeded with `$` for shell expansion of the variable.
`kubectl` is unlikely to be a binary in the current directory and is likely to be in `$PATH`
2021-11-22 16:55:09 -05:00
thebsdbox
82db862a1a IPVS fixes 2021-11-22 20:00:05 +00:00
Chip Zoller
6f18708ec2 address PR comments
Signed-off-by: Chip Zoller <chipzoller@gmail.com>
2021-11-22 12:25:27 -05:00
Chip Zoller
c1c9635bf4 updates
Signed-off-by: Chip Zoller <chipzoller@gmail.com>
2021-11-22 10:06:25 -05:00
Chip Zoller
f5e8e05271 more work
Signed-off-by: Chip Zoller <chipzoller@gmail.com>
2021-11-22 09:17:17 -05:00
Chip Zoller
2ec0510a37 more linting
Signed-off-by: Chip Zoller <chipzoller@gmail.com>
2021-11-21 20:01:31 -05:00
Chip Zoller
31e4958c99 linting
Signed-off-by: Chip Zoller <chipzoller@gmail.com>
2021-11-21 19:39:17 -05:00
Chip Zoller
a377b6e2a8 linting, typos
Signed-off-by: Chip Zoller <chipzoller@gmail.com>
2021-11-21 19:32:04 -05:00
Chip Zoller
f5a2bd8e59 Extensive linting, corrections, expansions
Signed-off-by: Chip Zoller <chipzoller@gmail.com>
2021-11-21 19:23:00 -05:00
Daniel Finneran
88d6df058b Merge pull request #308 from thebsdbox/custom_ipvs_port
Allows setting an API server port
2021-11-10 16:37:29 +00:00
thebsdbox
b11b9ba396 Allows setting an API server port 2021-11-10 15:59:35 +00:00
Daniel Finneran
4585812e0e Merge pull request #306 from thebsdbox/0.4-release
New release v0.4.0
2021-11-09 13:26:52 +00:00
thebsdbox
7b79084ae2 New release v0.4.0 2021-11-09 13:01:23 +00:00
Daniel Finneran
fd61ee4d49 Merge pull request #305 from thebsdbox/more_docs
Fix manifests and old generator
2021-11-09 12:56:18 +00:00
Daniel Finneran
e190256f92 Merge pull request #303 from thebsdbox/code_dedupe
Removes duplicated code and tidies function names
2021-11-09 12:56:02 +00:00
thebsdbox
4c1fd117d5 Fix manifests and old generator 2021-11-09 12:53:41 +00:00
Daniel Finneran
6ffa87e42b Merge pull request #304 from thebsdbox/0.4docs
Docs for upcoming 0.4 release
2021-11-09 11:44:06 +00:00
Daniel Finneran
1c73f15bef Merge branch 'main' into 0.4docs 2021-11-09 11:43:42 +00:00
thebsdbox
27e889e8a6 Docs for upcoming 0.4 release 2021-11-09 11:42:07 +00:00
thebsdbox
a75a53c47e lint fix ! 2021-11-08 12:21:31 +00:00
thebsdbox
c0a5c7a762 Removal of more duplicate code 2021-11-08 12:17:53 +00:00
thebsdbox
35f7d816f4 Removes duplicated code and tidies function names 2021-11-07 14:56:48 +00:00
Daniel Finneran
cfc6aa04ba Merge pull request #302 from RZRCDR/main
Add hostAliases to kube-vip-arp-ds.yaml on v0.3.9
2021-11-06 14:26:57 +00:00
Daniel Finneran
259091d019 Merge pull request #301 from shibumi/shibumi/update-image
update images
2021-11-02 09:18:48 +00:00
Dirkco du Plessis
0cef76ff4a Add hostAliases to kube-vip-arp-ds.yaml on v0.3.9
Signed-off-by: Dirkco du Plessis <dduplessis@credogroup.com>
2021-10-30 12:02:41 +01:00
Christian Rebischke
a79d5e61e9 update images
Signed-off-by: Christian Rebischke <chris@shibumi.dev>
2021-10-30 03:29:32 +02:00
Daniel Finneran
066c046cf5 Merge pull request #296 from thebsdbox/ipvs
Replace IPVS as the API server LoadBalancer
2021-10-28 15:54:51 +01:00
thebsdbox
08d38f5520 Final fixes to the IPVS work 2021-10-26 15:03:00 +01:00
thebsdbox
81975220c6 Fixed missing import 2021-10-26 13:52:25 +01:00
Daniel Finneran
93cca8e938 Merge branch 'main' into ipvs 2021-10-26 13:48:26 +01:00
thebsdbox
e1bfcb1aa6 Tidying up of redundant code, fixes to fwdtype lb 2021-10-26 13:47:13 +01:00
Daniel Finneran
8a05989122 Merge pull request #298 from stevesloka/refactork8sClient
Refactor the Kubernetes client generation into a single package
2021-10-26 13:32:10 +01:00
Steve Sloka
9b65c1e63c Refactor the Kubernetes client generation into a single place inside a new k8s package.
Signed-off-by: Steve Sloka <slokas@vmware.com>
2021-10-25 15:30:23 -04:00
Daniel Finneran
e4ab718bc9 Merge pull request #297 from mikenabhan/patch-1
Fix spelling in documentation
2021-10-25 08:56:32 +01:00
Mike Nabhan
cf122a3239 Fix spelling in documentation 2021-10-24 18:03:38 -06:00
thebsdbox
6c759fcd74 Lint fixes 2021-10-22 15:53:59 +01:00
thebsdbox
7a759e41f7 Replace IPVS as the API server LoadBalancer 2021-10-22 09:28:41 +01:00
Daniel Finneran
a35df41b46 Merge pull request #294 from thebsdbox/leaderElection
Removes local leaderElection fix
2021-10-20 17:30:23 +01:00
thebsdbox
843c3ebf94 Removes local leaderElection fix 2021-10-20 17:21:12 +01:00
Daniel Finneran
638c521d36 Merge pull request #295 from kube-vip/thebsdbox-patch-1
Update ci.yaml
2021-10-20 17:18:25 +01:00
Daniel Finneran
e2e2183e57 Update ci.yaml
Moves from Go 1.15 to 1.16
2021-10-20 17:09:41 +01:00
Daniel Finneran
65363c21ec Merge pull request #291 from thebsdbox/ignore_service
Ability for Kube-Vip to ignore a service
2021-10-20 15:55:18 +01:00
Daniel Finneran
903a341873 Merge branch 'main' into ignore_service 2021-10-20 15:46:54 +01:00
Daniel Finneran
b544e5b729 Merge pull request #290 from stevesloka/fixupLintErrors
Adds golangci-lint to check for code errors + clean up resulting findings
2021-10-20 15:46:10 +01:00
Daniel Finneran
c140e6afa5 Merge pull request #292 from kube-vip/Adds-golangci-lint
Update ci.yaml
2021-10-20 15:17:38 +01:00
Daniel Finneran
2cd9b36fac Update ci.yaml 2021-10-20 15:08:09 +01:00
Steve Sloka
2e9c2244c1 Adds golangci-lint to check for code errors + clean up resulting findings after running.
Signed-off-by: Steve Sloka <slokas@vmware.com>
2021-10-20 13:55:34 +00:00
thebsdbox
ec6fbfd162 Fixes order for reading env vars, and ignore svc 2021-10-20 14:53:19 +01:00
Daniel Finneran
70f14a5bfd Merge pull request #289 from thebsdbox/main
Auto detect default interface for VIP
2021-10-19 16:04:58 +01:00
thebsdbox
821a488e15 Removed autoInterface option 2021-10-19 14:34:54 +01:00
thebsdbox
0d492faaf0 Auto detect default interface for VIP 2021-10-19 11:17:33 +01:00
Daniel Finneran
c94c15a6b9 Merge pull request #285 from thebsdbox/localhost
Use localhost to connect to manager
2021-10-13 11:10:37 +01:00
thebsdbox
e2c8e4d724 Automates the changes required for callback to API server 2021-10-13 10:48:17 +01:00
thebsdbox
1f7ff01bec Use localhost to connect to manager 2021-10-12 11:41:44 +01:00
Daniel Finneran
53ac3868e8 Merge pull request #284 from thebsdbox/testing_fix
Adds easier moving between Kubernetes versions
2021-10-12 10:50:01 +01:00
thebsdbox
74fa77735b Adds easier moving between Kubernetes versions 2021-10-12 10:49:08 +01:00
Daniel Finneran
9f244e4d7d Merge pull request #278 from larrymapacket/larry-kubevip
update Metal's doc
2021-10-08 14:23:36 +01:00
larrymapacket
a46042e548 update the Equinix Metal kube-vip doc.
Signed-off-by: larrymapacket <larry@packet.com>
2021-10-04 17:09:57 -05:00
larrymapacket
0c82f3e00b Changing EquiniMetal usage document to add a few missing information and links.
Signed-off-by: larrymapacket <larry@packet.com>
2021-09-28 17:09:54 -05:00
Daniel Finneran
c333e2a1eb Merge pull request #274 from elmariofredo/patch-1
Add link to Equinix Metal  metal-gateway guide
2021-09-18 09:51:36 +01:00
Mario Vejlupek
96c7dc5f15 Add link to Equinix Metal metal-gateway guide
Signed-off-by: Mario Vejlupek <mario@vejlupek.cz>
2021-09-16 09:47:10 +02:00
Daniel Finneran
6bfed9c454 Merge pull request #272 from detiber/bumpgobgp 2021-09-10 21:39:00 +02:00
Jason DeTiberus
975b892e6d Bump gobgp dependency to the latest v2.31.0
Signed-off-by: Jason DeTiberus <detiber@users.noreply.github.com>
2021-09-10 14:07:03 -04:00
Daniel Finneran
ab19d4a4a4 Merge pull request #266 from thebsdbox/nic_seperation 2021-09-04 15:03:24 +02:00
thebsdbox
5f751cc321 Fixes from feedback 2021-09-03 13:37:43 +01:00
Daniel Finneran
59ce702b5e Merge pull request #268 from detiber/creds 2021-09-02 22:37:27 +02:00
Jason DeTiberus
7bfa79750d Support use Equinix Metal credentials from config
Use Equinix Metal credentials when available with EIP configuration
not just BGP configuration.

Signed-off-by: Jason DeTiberus <detiber@users.noreply.github.com>
2021-09-02 16:21:19 -04:00
Daniel Finneran
2ec44596b3 Merge pull request #267 from detiber/nodeAffinity
Update DaemonSet generation to improve scheduling
2021-09-02 21:28:10 +02:00
Jason DeTiberus
9addea6149 Update DaemonSet generation to improve scheduling
- Tolerate more than just the node-role.kubernetes.io/master taint, this allows
  the daemonset to schedule prior to CNI being deployed.

- Switch from using a nodeSelector to using nodeAffinity
  - Allows scheduling even if the node label does not match the value (for the node-role label, the value is generally ignored).
  - Add support for the control-plane node role rather than just master.

Signed-off-by: Jason DeTiberus <detiber@users.noreply.github.com>
2021-09-02 14:09:23 -04:00
thebsdbox
d06176a56b Implements a secondary interface just for services 2021-09-02 10:07:17 +01:00
Daniel Finneran
cc0fe1e870 Merge pull request #265 from thebsdbox/src_annotation
This will set source IP for BGP from annotations
2021-09-01 16:41:15 +02:00
thebsdbox
306a75ff84 This will set source IP for BGP from annotations 2021-09-01 14:53:55 +01:00
Daniel Finneran
3e565851e8 Merge pull request #264 from thebsdbox/docs_fix
Fixes Docs
2021-09-01 10:52:13 +02:00
thebsdbox
0a57816567 Fixes Docs 2021-09-01 09:51:00 +01:00
Daniel Finneran
8021ef7bf6 Updates Makefile to correct version 2021-09-01 09:42:11 +01:00
Daniel Finneran
3cc6b17916 Merge pull request #263 from detiber/useProjectID
[metal] Use provided provider id in config if defined
2021-09-01 10:13:22 +02:00
Jason DeTiberus
925b3bdc20 [packet] Support Address config in addition to VIP
Signed-off-by: Jason DeTiberus <detiber@users.noreply.github.com>
2021-08-31 18:20:57 -04:00
Jason DeTiberus
4a814f2427 [metal] Use provided provider id in config if defined
Signed-off-by: Jason DeTiberus <detiber@users.noreply.github.com>
2021-08-31 17:34:15 -04:00
Daniel Finneran
b72c984d5c Merge pull request #262 from thebsdbox/password_bug
Fixes the broken logic in password parsing
2021-08-31 18:34:34 +02:00
thebsdbox
fab9be29f0 Fixes the broken logic in password parsing 2021-08-31 17:18:16 +01:00
Daniel Finneran
a93b8382ac Merge pull request #261 from thebsdbox/BGP_Source
This change allows to specify either an adapter on an address to peer from
2021-08-26 13:14:55 +02:00
thebsdbox
54615fa750 Remove duplicate flag 2021-08-25 16:00:51 +01:00
thebsdbox
2b0345cc86 Adds BGP Source 2021-08-25 15:58:11 +01:00
Daniel Finneran
165b2ebb40 Merge pull request #255 from kplimack/advertise 2021-08-17 06:49:23 +01:00
Jake Plimack
9188f554ab spelling
Signed-off-by: Jake Plimack <jplimack@tesla.com>
2021-08-16 18:05:44 -06:00
Daniel Finneran
c92bec91b7 Merge pull request #253 from panpan0000/fix_ServiceType
fix typo of ServiceType. There's no svc.spec.type = ServiceTypeLoadBalancer
2021-08-05 08:30:47 +01:00
panpan0000
a42a5e7493 fix typo of ServiceType 2021-08-05 02:19:14 -04:00
Daniel Finneran
c46887c0bc Merge pull request #249 from rawkode/fix/annotations-first-pass
fix: ensure node annotations are checked before watch
2021-07-26 11:45:27 +01:00
David McKay
76dbce050c chore: add tests for parseBgpAnnotations 2021-07-26 11:33:02 +01:00
David McKay
7c644d680d chore: use node ResourceVersion 2021-07-26 11:01:40 +01:00
David McKay
fc24064e2a fix: ensure node annotations are checked before watch 2021-07-26 09:40:25 +01:00
Daniel Finneran
092eb5423a Merge pull request #248 from rawkode/chore/use-ghcr-default 2021-07-24 21:45:32 +01:00
David McKay
a26288a1d0 chore: encourage useage of GHCR instead of rate limited Docker Hub 2021-07-24 16:53:57 +01:00
David McKay
39043ce0f8 fix: backticks are deprecated and not POSIX compat, replace with $() 2021-07-24 16:35:11 +01:00
David McKay
31448255e8 chore: use git to fetch latest tag 2021-07-24 16:34:37 +01:00
331 changed files with 51258 additions and 13093 deletions

4
.github/FUNDING.yml vendored Normal file
View File

@@ -0,0 +1,4 @@
# Enable GitHub funding
github: [kube-vip]

14
.github/dependabot.yml vendored Normal file
View File

@@ -0,0 +1,14 @@
version: 2
updates:
- package-ecosystem: github-actions
directory: /
schedule:
interval: weekly
- package-ecosystem: gomod
directory: /
schedule:
interval: weekly
- package-ecosystem: docker
directory: /
schedule:
interval: weekly

13
.github/suggestion-comment.md vendored Normal file
View File

@@ -0,0 +1,13 @@
I'll help you add a suggestion. Unfortunately, I can't directly add a suggestion to an existing comment through the API. However, here's what I recommend:
**Option 1: Reply with a suggestion**
Create a new comment with a suggested fix:
```suggestion
failed to get an IPv6 address after %d attempt(s), giving up, error: %s
```
**Option 2: Edit your existing comment**
Update your comment to include the suggestion details pointing out that line 284 in the error message says "IPv4" but should say "IPv6" since this is the DHCPv6Client.
Would you like me to create a new reply comment with the suggestion instead?

31
.github/workflows/anchore-syft.yml vendored Normal file
View File

@@ -0,0 +1,31 @@
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
# This workflow checks out code, builds an image, performs a container image
# scan with Anchore's Syft tool, and uploads the results to the GitHub Dependency
# submission API.
# For more information on the Anchore sbom-action usage
# and parameters, see https://github.com/anchore/sbom-action. For more
# information about the Anchore SBOM tool, Syft, see
# https://github.com/anchore/syft
name: Anchore Syft SBOM scan
on:
release:
types: [published]
jobs:
sbom:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v7
with:
ref: ${{ github.ref_name }}
- name: Anchore SBOM Action
uses: anchore/sbom-action@v0.24.2
with:
format: cyclonedx-json

88
.github/workflows/ci-pull-request.yaml vendored Normal file
View File

@@ -0,0 +1,88 @@
name: For each PR
on:
pull_request:
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
e2e-tests:
runs-on: ubuntu-latest
name: E2E tests
timeout-minutes: 120
env:
GINKGO_PROCS: ${{ matrix.ginkgo-procs }}
strategy:
fail-fast: false
max-parallel: 3
matrix:
include:
- mode: arp
ginkgo-procs: 4
- mode: rt
ginkgo-procs: 4
- mode: bgp
ginkgo-procs: 4
steps:
- name: Get current date
id: date
run: echo "date=$(date +'%Y-%m-%d-%H-%M')" >> "$GITHUB_OUTPUT"
- name: Ensure fs wont cause issues
run: sudo sysctl fs.inotify.max_user_instances=8192 && sudo sysctl fs.inotify.max_user_watches=524288
- name: Checkout code
uses: actions/checkout@v7
- name: Install Go
uses: actions/setup-go@v7
with:
go-version-file: go.mod
- name: Build image locally
run: make dockerx86Local
- name: Run Manifest generation tests
run: make manifest-test
if: matrix.mode == 'arp'
- name: Run ARP mode tests
run: DOCKER_API_VERSION=1.48 E2E_KEEP_LOGS=true GINKGO_ARGS="--output-dir=/tmp --json-report=kube-vip-test-report-arp.json" make e2e-tests-arp
if: matrix.mode == 'arp'
- name: Run RT mode tests
run: DOCKER_API_VERSION=1.48 E2E_KEEP_LOGS=true GINKGO_ARGS="--output-dir=/tmp --json-report=kube-vip-test-report-rt.json" make e2e-tests-rt
if: matrix.mode == 'rt'
- name: Get GoBGP binaries
run: make get-gobgp
if: matrix.mode == 'bgp'
- name: Run BGP mode tests
run: sudo -E PATH=$PATH DOCKER_API_VERSION=1.48 E2E_KEEP_LOGS=true GINKGO_ARGS="--output-dir=/tmp --json-report=kube-vip-test-report-bgp.json" make e2e-tests-bgp
if: matrix.mode == 'bgp'
- name: Change log directory permissions
run: sudo chmod -R 755 /tmp/kube-vip-test*
if: matrix.mode == 'bgp' && always()
- name: Save logs
uses: actions/upload-artifact@v7
with:
name: e2e-test-logs-${{ matrix.mode }}-${{ steps.date.outputs.date }}
path: /tmp/kube-vip-test*
if: always()
service-e2e-tests:
runs-on: ubuntu-latest
name: E2E service tests
timeout-minutes: 60
steps:
- name: Get current date
id: date
run: echo "date=$(date +'%Y-%m-%d-%H-%M')" >> "$GITHUB_OUTPUT"
- name: Checkout code
uses: actions/checkout@v7
- name: Install Go
uses: actions/setup-go@v7
with:
go-version-file: go.mod
- name: Build image with iptables
run: make dockerx86ActionIPTables
- name: Run tests
run: DOCKER_API_VERSION=1.48 DOCKERTAG=action E2E_KEEP_LOGS=true make service-tests
- name: Save logs
uses: actions/upload-artifact@v7
with:
name: services-test-logs-${{ steps.date.outputs.date }}
path: /tmp/kube-vip-services*
if: always()

View File

@@ -1,27 +1,88 @@
name: For each commit and PR
name: For each commit
on:
push:
branches: [main]
tags: ['v*']
pull_request:
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
validation:
runs-on: ubuntu-latest
env:
CGO_ENABLED: 0
name: Checks and linters
timeout-minutes: 30
steps:
- name: Init
run: sudo apt-get update && sudo apt-get install -y build-essential golint
- name: Checkout code
uses: actions/checkout@v2
- name: Install Go
uses: actions/setup-go@v2
with:
go-version: '1.15'
- name: checks
run: make check
- name: test docker build
run: make dockerx86Action
- name: Manifest generate
run: ./testing/testing.sh
- name: e2e tests
run: DOCKERTAG=action make e2e-tests
- name: Init
run: sudo apt-get update && sudo apt-get install -y build-essential && sudo sysctl fs.inotify.max_user_instances=8192 && sudo sysctl fs.inotify.max_user_watches=524288
- name: Install golangci-lint
uses: golangci/golangci-lint-action@v9
with:
version: v2.12
install-only: true
- name: Checkout code
uses: actions/checkout@v7
- name: Install Go
uses: actions/setup-go@v7
with:
go-version-file: go.mod
- name: Verify gofmt
run: |
unformatted=$(gofmt -l .)
if [ -n "$unformatted" ]; then
echo "The following files are not gofmt-formatted:"
echo "$unformatted"
exit 1
fi
- name: All checks
run: make check
unit-tests:
runs-on: ubuntu-latest
name: Unit tests
timeout-minutes: 30
steps:
- name: Checkout code
uses: actions/checkout@v7
- name: Install Go
uses: actions/setup-go@v7
with:
go-version-file: go.mod
- name: Run tests
run: make unit-tests
- name: Run privileged network tests
run: |
sudo -E env PATH="$PATH" KUBE_VIP_REQUIRE_NETNS=1 go test -race ./pkg/services ./pkg/vip ./pkg/instance \
-run 'TestRecover|TestServiceAddressRetained|TestRetainControlPlaneVIPs|TestAddressProtocol|TestKubeVIPAddressProtocol|TestCleanupKubeVIPAddresses|TestMonitorDefaultInterfaceReturnsErrorWhenTestLinkIsSetDown|TestCleanupLinkAttachmentsOnlyDeletesOwnedVLAN'
integration-tests:
name: Integration tests
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- name: Checkout code
uses: actions/checkout@v7
- name: Install Go
uses: actions/setup-go@v7
with:
go-version-file: go.mod
- name: Run tests
run: make integration-tests
image-vul-check:
runs-on: ubuntu-latest
name: Image vulnerability scan
timeout-minutes: 30
steps:
- name: Checkout code
uses: actions/checkout@v7
- name: Build image
run: make dockerx86Action
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@master
with:
image-ref: "plndr/kube-vip:action"
format: "table"
exit-code: "1"
ignore-unfixed: true
vuln-type: "os,library"
severity: "CRITICAL,HIGH"

75
.github/workflows/codeql-analysis.yml vendored Normal file
View File

@@ -0,0 +1,75 @@
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL"
on:
push:
branches: [ main ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ main ]
schedule:
- cron: '17 10 * * 6'
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
language: [ 'go' ]
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
# Learn more about CodeQL language support at https://git.io/codeql-language-support
steps:
- name: Checkout repository
uses: actions/checkout@v7
- name: Install Go
uses: actions/setup-go@v7
with:
go-version-file: go.mod
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v4
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# queries: ./path/to/local/query, your-org/your-repo/queries@main
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v4
# Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
# and modify them (or add more) to build your code if your project
# uses a compiled language
#- run: |
# make bootstrap
# make release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v4

View File

@@ -1,43 +1,52 @@
name: Publish the latest dev image
name: Build and publish main image regularly
on:
push:
branches:
- 'master'
schedule:
- cron: '25 0 * * *'
workflow_dispatch:
jobs:
docker:
nightly_build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Prepare Names
id: prep
run: |
DOCKER_IMAGE=plndr/kube-vip
VERSION=$(echo ${GITHUB_SHA} | cut -c1-8)
TAGS="${DOCKER_IMAGE}:${VERSION}"
TAGS="$TAGS,${DOCKER_IMAGE}:nightly"
echo ::set-output name=tags::${TAGS}
uses: actions/checkout@v7
- name: Set up QEMU
uses: docker/setup-qemu-action@v1
uses: docker/setup-qemu-action@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
uses: docker/setup-buildx-action@v4
- name: Login to DockerHub
uses: docker/login-action@v1
uses: docker/login-action@v4
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push main branch
uses: docker/build-push-action@v2
- name: Login to Github Packages
uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build standard version
id: docker_build
uses: docker/build-push-action@v7
with:
context: .
platforms: linux/amd64,linux/arm/v7,linux/arm64,linux/ppc64le
platforms: linux/amd64,linux/arm/v7,linux/arm64,linux/ppc64le,linux/s390x
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.prep.outputs.tags }}
tags: >-
plndr/kube-vip:${{ github.ref_name }},
ghcr.io/kube-vip/kube-vip:${{ github.ref_name }}
- name: Build iptables version
id: docker_build_iptables
uses: docker/build-push-action@v7
with:
context: .
file: Dockerfile_iptables
platforms: linux/amd64,linux/arm/v7,linux/arm64,linux/ppc64le,linux/s390x
push: ${{ github.event_name != 'pull_request' }}
tags: >-
plndr/kube-vip-iptables:${{ github.ref_name }},
ghcr.io/kube-vip/kube-vip-iptables:${{ github.ref_name }}
- name: Image digest
run: echo ${{ steps.docker_build.outputs.digest }}
run: echo ${{ steps.docker_build.outputs.digest }}

111
.github/workflows/nightly-e2e.yaml vendored Normal file
View File

@@ -0,0 +1,111 @@
name: Nightly e2e
on:
schedule:
- cron: '30 2 * * *'
workflow_dispatch:
permissions:
contents: read
jobs:
unit-coverage:
runs-on: ubuntu-latest
name: Unit tests with coverage
timeout-minutes: 30
steps:
- name: Checkout code
uses: actions/checkout@v7
- name: Install Go
uses: actions/setup-go@v7
with:
go-version-file: go.mod
- name: Run tests
run: make unit-tests
- name: Summarize coverage
if: always()
run: |
if test -f coverage.out; then
echo "### Unit coverage" >> "$GITHUB_STEP_SUMMARY"
go tool cover -func=coverage.out | tail -1 >> "$GITHUB_STEP_SUMMARY"
else
echo "### Unit coverage: report missing" >> "$GITHUB_STEP_SUMMARY"
fi
- name: Upload coverage
uses: actions/upload-artifact@v7
with:
name: unit-coverage
path: coverage.out
if-no-files-found: error
if: always()
etcd-e2e:
runs-on: ubuntu-latest
name: Etcd E2E tests
timeout-minutes: 60
steps:
- name: Ensure fs wont cause issues
run: sudo sysctl fs.inotify.max_user_instances=8192 && sudo sysctl fs.inotify.max_user_watches=524288
- name: Checkout code
uses: actions/checkout@v7
- name: Install Go
uses: actions/setup-go@v7
with:
go-version-file: go.mod
- name: Build image locally
run: make dockerx86Local
- name: Prepare Etcd artifacts
if: always()
run: |
mkdir -p /tmp/kube-vip-etcd-artifacts
: > /tmp/kube-vip-etcd-artifacts/suite.log
printf '[]\n' > /tmp/kube-vip-etcd-artifacts/report.json
- name: Run Etcd tests
id: etcd
# Scheduled failures are tolerated only during the initial stabilization window.
# The enforcement step below makes manual runs and later schedules blocking.
continue-on-error: true
shell: bash
run: |
set +e
set -o pipefail
DOCKER_API_VERSION=1.48 E2E_KEEP_LOGS=true \
GINKGO_ARGS="--json-report=report.json --output-dir=/tmp/kube-vip-etcd-artifacts" \
make e2e-tests-etcd 2>&1 | tee /tmp/kube-vip-etcd-artifacts/suite.log
exit_code=${PIPESTATUS[0]}
echo "exit_code=$exit_code" >> "$GITHUB_OUTPUT"
exit "$exit_code"
- name: Summarize Etcd suite
if: always()
env:
OUTCOME: ${{ steps.etcd.outcome }}
EXIT_CODE: ${{ steps.etcd.outputs.exit_code }}
run: |
echo "### Etcd E2E result: ${OUTCOME}" >> "$GITHUB_STEP_SUMMARY"
printf '{"outcome":"%s","exit_code":%s,"event":"%s","cutoff":"2026-10-01"}\n' \
"${OUTCOME:-skipped}" "${EXIT_CODE:-null}" "$GITHUB_EVENT_NAME" \
> /tmp/kube-vip-etcd-artifacts/result.json
- name: Save logs
uses: actions/upload-artifact@v7
continue-on-error: true
with:
name: etcd-e2e-logs
path: |
/tmp/kube-vip-etcd-artifacts
/tmp/kube-vip-test*
if-no-files-found: warn
if: always()
- name: Enforce Etcd result
if: always()
env:
EVENT_NAME: ${{ github.event_name }}
OUTCOME: ${{ steps.etcd.outcome }}
run: |
if test "$OUTCOME" = success; then
exit 0
fi
if test "$EVENT_NAME" = schedule && test "$(date -u +%Y-%m-%d)" \< 2026-10-01; then
echo "::warning::etcd e2e suite outcome was ${OUTCOME:-skipped} during stabilization through 2026-09-30"
exit 0
fi
echo "::error::etcd e2e suite outcome was ${OUTCOME:-skipped}; see the etcd-e2e-logs artifact"
exit 1

View File

@@ -1,48 +1,64 @@
name: Publish Releases to Docker Hub
name: Publish Releases to Docker Hub and GitHub Container Registry
on:
push:
tags:
- '*'
workflow_dispatch:
jobs:
docker:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Prepare Names
id: prep
run: |
DOCKER_IMAGE=plndr/kube-vip
VERSION=${GITHUB_REF#refs/tags/}
TAGS="${DOCKER_IMAGE}:${VERSION},ghcr.io/kube-vip/kube-vip:${VERSION}"
TAGS="$TAGS,${DOCKER_IMAGE}:latest,ghcr.io/kube-vip/kube-vip:latest"
echo ::set-output name=tags::${TAGS}
uses: actions/checkout@v7
- name: Set up QEMU
uses: docker/setup-qemu-action@v1
uses: docker/setup-qemu-action@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
uses: docker/setup-buildx-action@v4
- name: Login to DockerHub
uses: docker/login-action@v1
uses: docker/login-action@v4
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Login to Github Packages
uses: docker/login-action@v1
uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push main branch
uses: docker/build-push-action@v2
- name: Generate Metadata
uses: docker/metadata-action@v6.2.0
id: metadata
with:
labels: |
org.opencontainers.image.documentation=https://kube-vip.io/docs/
- name: Build and push main branch
id: docker_build
uses: docker/build-push-action@v7
with:
context: .
platforms: linux/amd64,linux/arm/v7,linux/arm64,linux/ppc64le
platforms: linux/amd64,linux/arm/v7,linux/arm64,linux/ppc64le,linux/s390x
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.prep.outputs.tags }}
labels: ${{ steps.metadata.outputs.labels }}
tags: >-
plndr/kube-vip:${{ github.ref_name }},
plndr/kube-vip:latest,
ghcr.io/kube-vip/kube-vip:${{ github.ref_name }},
ghcr.io/kube-vip/kube-vip:latest
- name: Build iptables version and push main branch
id: docker_build_iptables
uses: docker/build-push-action@v7
with:
context: .
file: Dockerfile_iptables
platforms: linux/amd64,linux/arm/v7,linux/arm64,linux/ppc64le,linux/s390x
push: ${{ github.event_name != 'pull_request' }}
labels: ${{ steps.metadata.outputs.labels }}
tags: >-
plndr/kube-vip-iptables:${{ github.ref_name }},
plndr/kube-vip-iptables:latest,
ghcr.io/kube-vip/kube-vip-iptables:${{ github.ref_name }},
ghcr.io/kube-vip/kube-vip-iptables:latest
- name: Image digest
run: echo ${{ steps.docker_build.outputs.digest }}

9
.gitignore vendored Normal file
View File

@@ -0,0 +1,9 @@
.idea
kube-vip
.vscode
bin
testing/e2e/etcd/certs
coverage.out
pkg/etcd/etcd.pid
pkg/etcd/etcd-data
testing/e2e/e2e.test

38
.golangci.yml Normal file
View File

@@ -0,0 +1,38 @@
version: "2"
linters:
enable:
- bodyclose
- gosec
- misspell
- unconvert
- unparam
settings:
misspell:
ignore-rules:
- creater
staticcheck:
checks:
- all
# Disable QF1008 to retain embedded fields for better readability.
- "-QF1008"
exclusions:
generated: lax
presets:
- comments
- common-false-positives
- legacy
- std-error-handling
paths:
- third_party$
- builtin$
- examples$
formatters:
enable:
- gofmt
- goimports
exclusions:
generated: lax
paths:
- third_party$
- builtin$
- examples$

62
CHANGELOG.md Normal file
View File

@@ -0,0 +1,62 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
### Fixed
- Propagate `bgp_attach_ip_to_interface` into per-service config so it attaches BGP-mode Service VIPs to the interface as configured.
- Add a configurable kube-vip instance name and use it to isolate internal nftables egress tables, persist table ownership on Services, and migrate per-Service chains without affecting other deployments. Fixes #1634.
- Retry on 403 Forbidden and 401 Unauthorized in `ServicesWatcher` at startup with exponential backoff. Fixes #1464.
- Reintroduce BGP config via node annotations. Fixes #1488.
- Fail fast in runtime `manager` and `service` paths when legacy `vip_address` is used without `vip_subnet` in control-plane ARP, BGP, or Routing Table mode.
- Cancel the mode context on init or configuration failure before waiting on goroutines during shutdown.
### Added
- Configurable control-plane health check for BGP mode without leader election
- Polls a configurable HTTP(S) endpoint (e.g. `https://localhost:6443/livez`) to verify the exposed service is healthy (usually the local kube-apiserver)
- Withdraws the BGP route after a configurable number of consecutive failures, removing the unhealthy node from the ECMP set
- Re-announces the route automatically once the endpoint recovers
- Gracefully withdraws the route on shutdown (SIGTERM)
- Supports custom CA certificates for TLS verification
- Configuration via environment variables or CLI flags:
- `control_plane_health_check_address` / `--controlPlaneHealthCheckAddress`: URL to poll
- `control_plane_health_check_period_seconds` / `--controlPlaneHealthCheckPeriodSeconds`: interval between checks (default: 5)
- `control_plane_health_check_timeout_seconds` / `--controlPlaneHealthCheckTimeoutSeconds`: per-request timeout (default: 3)
- `control_plane_health_check_failure_threshold` / `--controlPlaneHealthCheckFailureThreshold`: consecutive failures before withdrawal (default: 3)
- `control_plane_health_check_ca_path` / `--controlPlaneHealthCheckCAPath`: CA cert for HTTPS verification
- SIGUSR1 signal handler for runtime configuration dumps (#1301)
- Send SIGUSR1 to kube-vip process to dump current configuration to stdout
- Configuration dump includes:
- Basic configuration (VIP, interface, port, namespace settings)
- BGP configuration (enabled status, AS number, router ID, peers)
- ARP/NDP configuration (enabled status, broadcast rate)
- Services configuration (enabled status, load balancer settings)
- Network interfaces status
- Leader election configuration (type, lease details)
- Runtime statistics (load balancer, Prometheus, health check settings)
- Output format: Human-readable plaintext via fmt.Printf()
- Thread-safe implementation using mutex protection
- Non-disruptive: Process continues running after configuration dump
- Added comprehensive unit tests for all dump methods
- Added E2E tests for signal handling
- Opt-in support for endpointless `LoadBalancer` services with `externalTrafficPolicy: Cluster`
- Annotation: `kube-vip.io/allow-reconcile-without-endpoints: "true"`
- Starts service handling path for opted-in endpointless Cluster services while preserving default endpoint-gated behavior for non-opt-in services and `Local` policy
- Added endpoint behavior tests and README usage documentation
- Added support in ipoib interfaces in ARP mode. Fixes #694
### Changed
- BGP mode now honours `enable_leader_election` for services: a single global services leader advertises the service VIPs instead of every node advertising them. Deployments that enabled `enable_leader_election` for the control plane and relied on ECMP/multipath for services must unset it (or switch to `enable_service_election`) to keep the previous datapath. kube-vip logs a warning on startup when this path is taken.
- Updated signal handlers in manager_arp.go, manager_bgp.go, manager_wireguard.go, and manager_table.go to use switch statement pattern for handling multiple signals (SIGUSR1, SIGINT, SIGTERM)
- wireguard.go now manages a complete wireguard interface on the current network namespace
- manager_wireguard.go uses the new wireguard.go implementation
## [v1.0.1] - Previous Release
### Previous changes
- See git history for changes prior to CHANGELOG.md introduction

View File

@@ -113,8 +113,8 @@ and *merged* sorts of commits.
To make it easier for reviewers to review your PR, consider the following:
1. Follow the golang [coding conventions](https://github.com/golang/go/wiki/CodeReviewComments).
2. Format your code with `make golangci-fix`; if the [linters](ci/README.md) flag an issue that
cannot be fixed automatically, an error message will be displayed so you can address the issue.
2. Format your code with `make simplify` to automatically fix formatting issues.
2. Lint your code with `make check`; if the linters flag an issue that cannot be fixed automatically, an error message will be displayed so you can address the issue.
3. Follow [git commit](https://chris.beams.io/posts/git-commit/) guidelines.
4. Follow [logging](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-instrumentation/logging.md) guidelines.
@@ -154,7 +154,7 @@ the `$GOPATH`.
To develop locally, you can follow these steps:
1. [Install Go 1.15](https://golang.org/doc/install)
1. [Install Go 1.19](https://golang.org/doc/install)
2. Checkout your feature branch and `cd` into it.
3. To build all Go files and install them under `bin`, run `make bin`
4. To run all Go unit tests, run `make test-unit`

View File

@@ -1,6 +1,6 @@
# syntax=docker/dockerfile:experimental
FROM golang:1.16.5-alpine3.13 as dev
FROM golang:1.27.1-alpine3.23 as dev
RUN apk add --no-cache git ca-certificates make
RUN adduser -D appuser
COPY . /src/
@@ -16,4 +16,4 @@ FROM scratch
COPY --from=dev /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
# Add kube-vip binary
COPY --from=dev /src/kube-vip /
ENTRYPOINT ["/kube-vip"]
ENTRYPOINT ["/kube-vip"]

21
Dockerfile_iptables Normal file
View File

@@ -0,0 +1,21 @@
# syntax=docker/dockerfile:experimental
FROM golang:1.27.1-alpine3.23 as dev
RUN apk add --no-cache git make
RUN adduser -D appuser
COPY . /src/
WORKDIR /src
ENV GO111MODULE=on
RUN --mount=type=cache,sharing=locked,id=gomod,target=/go/pkg/mod/cache \
--mount=type=cache,sharing=locked,id=goroot,target=/root/.cache/go-build \
CGO_ENABLED=0 GOOS=linux make build
FROM alpine:3.24.1
# Update pkgs and add iptables
RUN apk upgrade && \
apk add --no-cache iptables iptables-legacy
# Add kube-vip binary
COPY --from=dev /src/kube-vip /
ENTRYPOINT ["/kube-vip"]

136
Makefile
View File

@@ -2,10 +2,11 @@ SHELL := /bin/sh
# The name of the executable (default is current directory name)
TARGET := kube-vip
.DEFAULT_GOAL: $(TARGET)
.DEFAULT_GOAL := $(TARGET)
# These will be provided to the target
VERSION := v0.3.7
VERSION := v1.2.3
BUILD := `git rev-parse HEAD`
# Operating System Default (LINUX)
@@ -14,9 +15,15 @@ TARGETOS=linux
# Use linker flags to provide version/build settings to the target
LDFLAGS=-ldflags "-s -w -X=main.Version=$(VERSION) -X=main.Build=$(BUILD) -extldflags -static"
DOCKERTAG ?= $(VERSION)
REPOSITORY = plndr
REPOSITORY ?= docker.io/plndr
GO_VERSION := $(word 2,$(shell grep '^go ' go.mod))
K8S_VERSION ?= v1.35.0
GINKGO_ARGS ?=
GINKGO_PROCS ?=
GINKGO_PARALLEL := $(if $(GINKGO_PROCS),--procs=$(GINKGO_PROCS),-p)
BUILDX_CACHE_FLAGS ?=
.PHONY: all build clean install uninstall fmt simplify check run e2e-tests
.PHONY: all build clean install uninstall simplify check run e2e-tests unit-tests integration-tests unit-tests-docker integration-tests-docker e2e-tests-etcd
all: check install
@@ -36,17 +43,30 @@ install:
uninstall: clean
@rm -f $$(which ${TARGET})
fmt:
@gofmt -l -w ./...
demo:
@cd demo
@docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v7,linux/ppc64le --push -t $(REPOSITORY)/$(TARGET):$(DOCKERTAG) .
@docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v7,linux/ppc64le,linux/s390x --push -t $(REPOSITORY)/$(TARGET):$(DOCKERTAG) .
@echo New Multi Architecture Docker image created
@cd ..
## Remote (push of images)
# This build a local docker image (x86 only) for quick testing
dockerx86Dev:
@-rm ./kube-vip
@docker buildx build --platform linux/amd64 --push -t $(REPOSITORY)/$(TARGET):dev .
@echo New single x86 Architecture Docker image created
dockerx86Iptables:
@-rm ./kube-vip
@docker buildx build --platform linux/amd64 -f ./Dockerfile_iptables --push -t $(REPOSITORY)/$(TARGET):dev .
@echo New single x86 Architecture Docker image created
dockerx86IptablesLocal:
@-rm ./kube-vip
@docker buildx build --platform linux/amd64 -f ./Dockerfile_iptables -t $(REPOSITORY)/$(TARGET):$(DOCKERTAG) .
@echo New single x86 Architecture Docker image created
dockerx86:
@-rm ./kube-vip
@docker buildx build --platform linux/amd64 --push -t $(REPOSITORY)/$(TARGET):$(DOCKERTAG) .
@@ -54,48 +74,118 @@ dockerx86:
docker:
@-rm ./kube-vip
@docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v7,linux/ppc64le --push -t $(REPOSITORY)/$(TARGET):$(DOCKERTAG) .
@docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v7,linux/ppc64le,linux/s390x --push -t $(REPOSITORY)/$(TARGET):$(DOCKERTAG) .
@echo New Multi Architecture Docker image created
## Local (docker load of images)
# This will build a local docker image (x86 only), use make dockerLocal for all architectures
dockerx86Local:
@-rm ./kube-vip
@docker buildx build --platform linux/amd64 --load -t $(REPOSITORY)/$(TARGET):$(DOCKERTAG) .
@docker buildx build --platform linux/amd64 --load -t $(REPOSITORY)/$(TARGET):$(DOCKERTAG) $(BUILDX_CACHE_FLAGS) .
@echo New Multi Architecture Docker image created
dockerx86Action:
@-rm ./kube-vip
@docker buildx build --platform linux/amd64 --load -t $(REPOSITORY)/$(TARGET):action .
@docker buildx build --platform linux/amd64 --load -t $(REPOSITORY)/$(TARGET):action $(BUILDX_CACHE_FLAGS) .
@echo New Multi Architecture Docker image created
dockerx86ActionIPTables:
@-rm ./kube-vip
@docker buildx build --platform linux/amd64 -f ./Dockerfile_iptables --load -t $(REPOSITORY)/$(TARGET):action $(BUILDX_CACHE_FLAGS) .
@echo New Multi Architecture Docker image created
dockerLocal:
@-rm ./kube-vip
@docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v7,linux/ppc64le --load -t $(REPOSITORY)/$(TARGET):$(DOCKERTAG) .
@docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v7,linux/ppc64le,linux/s390x --load -t $(REPOSITORY)/$(TARGET):$(DOCKERTAG) .
@echo New Multi Architecture Docker image created
simplify:
@gofmt -s -l -w ./...
@gofmt -s -l -w *.go pkg cmd
check:
go mod tidy
test -z "$(git status --porcelain)"
test -z $(shell gofmt -l main.go | tee /dev/stderr) || echo "[WARN] Fix formatting issues with 'make fmt'"
golint ./...
test -z $(shell gofmt -l *.go pkg cmd) || echo "[WARN] Fix formatting issues with 'make simplify'"
golangci-lint run
go vet ./...
run: install
@$(TARGET)
manifests:
@make build
@mkdir -p ./docs/manifests/$(VERSION)/
@./kube-vip manifest pod --interface eth0 --vip 192.168.0.1 --arp --leaderElection --controlplane --services > ./docs/manifests/$(VERSION)/kube-vip-arp.yaml
@./kube-vip manifest pod --interface eth0 --vip 192.168.0.1 --bgp --controlplane --services > ./docs/manifests/$(VERSION)/kube-vip-bgp.yaml
@./kube-vip manifest daemonset --interface eth0 --vip 192.168.0.1 --arp --leaderElection --controlplane --services --inCluster > ./docs/manifests/$(VERSION)/kube-vip-arp-ds.yaml
@./kube-vip manifest daemonset --interface eth0 --vip 192.168.0.1 --bgp --leaderElection --controlplane --services --inCluster > ./docs/manifests/$(VERSION)/kube-vip-bgp-ds.yaml
@./kube-vip manifest daemonset --interface eth0 --vip 192.168.0.1 --bgp --leaderElection --controlplane --services --inCluster --provider-config /etc/cloud-sa/cloud-sa.json > ./docs/manifests/$(VERSION)/kube-vip-bgp-em-ds.yaml
@./kube-vip manifest pod --interface eth0 --vip 192.168.0.1 --image "$(REPOSITORY)/$(TARGET):$(DOCKERTAG)" --arp --leaderElection --controlplane --services > ./docs/manifests/$(VERSION)/kube-vip-arp.yaml
@./kube-vip manifest pod --interface eth0 --vip 192.168.0.1 --image "$(REPOSITORY)/$(TARGET):$(DOCKERTAG)" --arp --leaderElection --controlplane --services --enableLoadBalancer > ./docs/manifests/$(VERSION)/kube-vip-arp-lb.yaml
@./kube-vip manifest pod --interface eth0 --vip 192.168.0.1 --image "$(REPOSITORY)/$(TARGET):$(DOCKERTAG)" --bgp --controlplane --services > ./docs/manifests/$(VERSION)/kube-vip-bgp.yaml
@./kube-vip manifest daemonset --interface eth0 --vip 192.168.0.1 --image "$(REPOSITORY)/$(TARGET):$(DOCKERTAG)" --arp --leaderElection --controlplane --services --inCluster > ./docs/manifests/$(VERSION)/kube-vip-arp-ds.yaml
@./kube-vip manifest daemonset --interface eth0 --vip 192.168.0.1 --image "$(REPOSITORY)/$(TARGET):$(DOCKERTAG)" --arp --leaderElection --controlplane --services --inCluster --enableLoadBalancer > ./docs/manifests/$(VERSION)/kube-vip-arp-ds-lb.yaml
@./kube-vip manifest daemonset --interface eth0 --vip 192.168.0.1 --image "$(REPOSITORY)/$(TARGET):$(DOCKERTAG)" --bgp --leaderElection --controlplane --services --inCluster > ./docs/manifests/$(VERSION)/kube-vip-bgp-ds.yaml
@./kube-vip manifest daemonset --interface eth0 --vip 192.168.0.1 --image "$(REPOSITORY)/$(TARGET):$(DOCKERTAG)" --bgp --leaderElection --controlplane --services --inCluster > ./docs/manifests/$(VERSION)/kube-vip-bgp-em-ds.yaml
@-rm ./kube-vip
e2e-tests:
E2E_IMAGE_PATH=$(REPOSITORY)/$(TARGET):$(DOCKERTAG) go run github.com/onsi/ginkgo/ginkgo -v -p testing/e2e
manifest-test:
docker run $(REPOSITORY)/$(TARGET):$(DOCKERTAG) manifest pod --interface eth0 --vip 192.168.0.1 --image "$(REPOSITORY)/$(TARGET):$(DOCKERTAG)" --arp --leaderElection --controlplane --services
docker run $(REPOSITORY)/$(TARGET):$(DOCKERTAG) manifest pod --interface eth0 --vip 192.168.0.1 --image "$(REPOSITORY)/$(TARGET):$(DOCKERTAG)" --arp --leaderElection --controlplane --services --enableLoadBalancer
docker run $(REPOSITORY)/$(TARGET):$(DOCKERTAG) manifest pod --interface eth0 --vip 192.168.0.1 --image "$(REPOSITORY)/$(TARGET):$(DOCKERTAG)" --bgp --controlplane --services
docker run $(REPOSITORY)/$(TARGET):$(DOCKERTAG) manifest daemonset --interface eth0 --vip 192.168.0.1 --image "$(REPOSITORY)/$(TARGET):$(DOCKERTAG)" --arp --leaderElection --controlplane --services --inCluster
docker run $(REPOSITORY)/$(TARGET):$(DOCKERTAG) manifest daemonset --interface eth0 --vip 192.168.0.1 --image "$(REPOSITORY)/$(TARGET):$(DOCKERTAG)" --arp --leaderElection --controlplane --services --inCluster --enableLoadBalancer
docker run $(REPOSITORY)/$(TARGET):$(DOCKERTAG) manifest daemonset --interface eth0 --vip 192.168.0.1 --image "$(REPOSITORY)/$(TARGET):$(DOCKERTAG)" --bgp --leaderElection --controlplane --services --inCluster
unit-tests:
go test -race -coverprofile=coverage.out -covermode=atomic ./...
unit-tests-docker:
docker run --rm -w /kube-vip -v $$(pwd):/kube-vip -v kube-vip-gomod-cache:/go/pkg/mod -v kube-vip-gobuild-cache:/root/.cache/go-build golang:$(GO_VERSION) sh -c "make unit-tests; status=$$?; chmod 666 coverage.out 2>/dev/null || true; exit $$status"
integration-tests:
go test -tags=integration,e2e -v ./pkg/etcd
e2e-tests-arp: get-whoami
GOMAXPROCS=4 TEST_MODE=arp K8S_IMAGE_PATH=kindest/node:$(K8S_VERSION) E2E_IMAGE_PATH=$(REPOSITORY)/$(TARGET):$(DOCKERTAG) go run github.com/onsi/ginkgo/v2/ginkgo --tags=e2e -v $(GINKGO_PARALLEL) $(GINKGO_ARGS) ./testing/e2e
e2e-tests-rt: get-whoami
GOMAXPROCS=4 TEST_MODE=rt K8S_IMAGE_PATH=kindest/node:$(K8S_VERSION) E2E_IMAGE_PATH=$(REPOSITORY)/$(TARGET):$(DOCKERTAG) go run github.com/onsi/ginkgo/v2/ginkgo --tags=e2e -v $(GINKGO_PARALLEL) $(GINKGO_ARGS) ./testing/e2e
e2e-tests-bgp: get-whoami get-gobgp
GOMAXPROCS=4 TEST_MODE=bgp K8S_IMAGE_PATH=kindest/node:$(K8S_VERSION) E2E_IMAGE_PATH=$(REPOSITORY)/$(TARGET):$(DOCKERTAG) go run github.com/onsi/ginkgo/v2/ginkgo --tags=e2e -v $(GINKGO_PARALLEL) $(GINKGO_ARGS) ./testing/e2e
e2e-tests-etcd: get-whoami
GOMAXPROCS=4 K8S_IMAGE_PATH=kindest/node:$(K8S_VERSION) E2E_IMAGE_PATH=$(REPOSITORY)/$(TARGET):$(DOCKERTAG) go run github.com/onsi/ginkgo/v2/ginkgo --tags=e2e -v $(GINKGO_PARALLEL) $(GINKGO_ARGS) ./testing/e2e/etcd
e2e-tests: e2e-tests-arp e2e-tests-rt e2e-tests-bgp
service-tests:
$(MAKE) -C testing/e2e/e2e dockerLocal
E2E_IMAGE_PATH=$(REPOSITORY)/$(TARGET):$(DOCKERTAG) go run ./testing/services -Services -simple -deployments -leaderActive -leaderFailover -localDeploy -electionFaults -egress -egressIPv6 -dualStack -egressInternal
trivy: dockerx86ActionIPTables
docker run -v /var/run/docker.sock:/var/run/docker.sock aquasec/trivy:0.47.0 \
image \
--format table \
--exit-code 1 \
--ignore-unfixed \
--vuln-type 'os,library' \
--severity 'CRITICAL,HIGH' \
$(REPOSITORY)/$(TARGET):action
kind-quick:
echo "Standing up your cluster"
kind create cluster --config ./testing/kind/kind.yaml --name kube-vip
kubectl apply -f https://kube-vip.io/manifests/rbac.yaml
kubectl create configmap --namespace kube-system kubevip --from-literal range-global=172.18.100.10-172.18.100.30
kubectl apply -f https://raw.githubusercontent.com/kube-vip/kube-vip-cloud-provider/main/manifest/kube-vip-cloud-controller.yaml
kind load docker-image --name kube-vip $(REPOSITORY)/$(TARGET):$(DOCKERTAG)
docker run --network host --rm $(REPOSITORY)/$(TARGET):$(DOCKERTAG) manifest daemonset --services --inCluster --image "$(REPOSITORY)/$(TARGET):$(DOCKERTAG)" --arp --servicesElection --interface eth0 | kubectl apply -f -
kind-reload:
kind load docker-image $(REPOSITORY)/$(TARGET):$(DOCKERTAG) --name services
kubectl rollout restart -n kube-system daemonset/kube-vip-ds
get-gobgp:
mkdir -p bin
wget -nc --directory-prefix=bin https://github.com/osrg/gobgp/releases/download/v4.6.0/gobgp_4.6.0_linux_amd64.tar.gz
tar -xvzf bin/gobgp_4.6.0_linux_amd64.tar.gz -C bin
get-whoami:
docker pull ghcr.io/traefik/whoami:v1.11

View File

@@ -1,8 +1,10 @@
# kube-vip
High Availability and Load-Balancing
High Availability and Load-Balancing
![](https://kube-vip.io/kube-vip.png)
![](https://github.com/kube-vip/kube-vip/raw/main/kube-vip.png)
[![Build and publish main image regularly](https://github.com/kube-vip/kube-vip/actions/workflows/main.yaml/badge.svg)](https://github.com/kube-vip/kube-vip/actions/workflows/main.yaml) [![LFX Health Score](https://img.shields.io/static/v1?label=Health%20Score&message=Healthy&color=A7F3D0&logo=linuxfoundation&logoColor=white&style=flat)](https://insights.linuxfoundation.org/project/kube-vip) [![LFX Active Contributors](https://img.shields.io/static/v1?label=Active%20contributors%20(1Y)&message=212&color=0094FF&logo=linuxfoundation&logoColor=white&style=flat)](https://insights.linuxfoundation.org/project/kube-vip)
## Overview
Kubernetes Virtual IP and Load-Balancer for both control plane and Kubernetes services
@@ -16,6 +18,8 @@ The idea behind `kube-vip` is a small self-contained Highly-Available option for
**NOTE:** All documentation of both usage and architecture are now available at [https://kube-vip.io](https://kube-vip.io).
For upgrading an existing install in place (static Pod or DaemonSet), see the [upgrade guide](https://kube-vip.io/docs/upgrade/).
## Features
Kube-Vip was originally created to provide a HA solution for the Kubernetes control plane, over time it has evolved to incorporate that same functionality into Kubernetes service type [load-balancers](https://kubernetes.io/docs/concepts/services-networking/service/#loadbalancer).
@@ -30,7 +34,8 @@ Kube-Vip was originally created to provide a HA solution for the Kubernetes cont
- Service LoadBalancer address pools per namespace or global
- Service LoadBalancer address via (existing network DHCP)
- Service LoadBalancer address exposure to gateway via UPNP
- ... manifest generation, vendor API integrations and many nore...
- Egress! Kube-vip will utilise a service loadbalancer as both the ingress and **egress** for a pod.
- ... manifest generation, vendor API integrations and many more...
## Why?
@@ -55,4 +60,81 @@ All of these would require a separate level of configuration and in some infrast
## Troubleshooting and Feedback
### SELinux and IPVS kernel modules
When using IPVS load balancing on nodes with SELinux enforcing, kube-vip may be
blocked from requesting kernel modules from inside the container. Symptoms can
include the kube-vip pod entering `Error` or `CrashLoopBackOff`, logs that show
`ensure IPVS kernel modules are loaded`, or audit denials for `module_request`
from `container_t`.
Load the required IPVS modules on every node that can run kube-vip before
deploying it:
```shell
sudo modprobe ip_vs
sudo modprobe ip_vs_rr
```
To persist this across reboots, add the modules to a file such as
`/etc/modules-load.d/kube-vip-ipvs.conf`:
```text
ip_vs
ip_vs_rr
```
Preloading only the required modules is preferred to enabling the SELinux
`domain_kernel_load_modules` boolean for containers.
### Gateway API `LoadBalancer` services with no endpoints
Some Gateway API controllers create `LoadBalancer` services that intentionally have no Endpoints/EndpointSlices backends.
If you want kube-vip to reconcile such a service, opt in with:
```yaml
metadata:
annotations:
kube-vip.io/allow-reconcile-without-endpoints: "true"
spec:
type: LoadBalancer
externalTrafficPolicy: Cluster
```
Scope:
- Works only with `externalTrafficPolicy: Cluster`
- No effect for `Local`
- Default endpoint-gated behavior remains unchanged for services without this annotation
Please raise issues on the GitHub repository and as mentioned check the documentation at [https://kube-vip.io](https://kube-vip.io/).
## Community Tools
- **[KubeStellar Console — Guided kube-vip Install](https://console.kubestellar.io/missions/install-kube-vip)** — A step-by-step guided installation experience for kube-vip with pre-flight checks, validation, troubleshooting, and rollback support.
## Contributing
Thanks for taking the time to join our community and start contributing! We welcome pull requests. Feel free to dig through the [issues](https://github.com/kube-vip/kube-vip/issues) and jump in.
:warning: This project has issue compiling on MacOS, please compile it on linux distribution
Additionally it is now relatively easy and quick to develop with [skaffold](https://skaffold.dev/), and the `skaffold.yaml` exists within the root folder of the gir repository.
### Set up a kind development environment
1. `kind create cluster --config ./testing/kind.yaml`
2. `kubectl apply -f https://kube-vip.io/manifests/rbac.yaml`
3. Create a load balancer range `configMap` from the kind cluster
4. Apply the CCM manifest
5. Start skaffold with `skaffold dev`
6. Start developing and see changes applied in real-time.
## Star History
[![Star History Chart](https://star-history.dera.page/svg?repos=kube-vip/kube-vip&type=Date)](https://star-history.dera.page/#kube-vip/kube-vip&type=date)
[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fkube-vip%2Fkube-vip.svg?type=shield)](https://app.fossa.com/projects/git%2Bgithub.com%2Fkube-vip%2Fkube-vip?ref=badge_shield)
## License
[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fkube-vip%2Fkube-vip.svg?type=large)](https://app.fossa.com/projects/git%2Bgithub.com%2Fkube-vip%2Fkube-vip?ref=badge_large)

View File

@@ -1,10 +1,10 @@
# Kube-Vip Roadmap
This document outlines the roadmap for the **kube-vip** project and only covers the technologies within this particular project, other projects that augment or provide additional functionality (such as cloud-providers) may have their own roadmaps in future. The functionality for **kube-vip** has grown either been developed organically or through real-world needs, and this is the first attempt to put into words a plan for the future of **kube-vip** and will additional evolve over time. This means that items listed or detailed here are not neccessarily set in stone and the roadmap can grow/shrink as the project matures. We definitely welcome suggestions and ideas from everyone about the roadmap and **kube-vip** features. Reach us through Issues, Slack or email <catch-all>@kube-vip.io.
This document outlines the roadmap for the **kube-vip** project and only covers the technologies within this particular project, other projects that augment or provide additional functionality (such as cloud-providers) may have their own roadmaps in future. The functionality for **kube-vip** has grown either been developed organically or through real-world needs, and this is the first attempt to put into words a plan for the future of **kube-vip** and will additional evolve over time. This means that items listed or detailed here are not necessarily set in stone and the roadmap can grow/shrink as the project matures. We definitely welcome suggestions and ideas from everyone about the roadmap and **kube-vip** features. Reach us through Issues, Slack or email <catch-all>@kube-vip.io.
## Release methodology
The **kube-vip** project attempts to follow a tick-tock release cycle, this typically means that one release will come **packed** with new features where the following release will come with fixes, code sanitation and performane enhancements.
The **kube-vip** project attempts to follow a tick-tock release cycle, this typically means that one release will come **packed** with new features where the following release will come with fixes, code sanitation and performance enhancements.
## Roadmap
@@ -13,12 +13,12 @@ The **kube-vip** project offers two main areas of functionality:
- HA Kubernetes clusters through a control-plane VIP
- Kubernetes `service type:LoadBalancer`
Whilst both of these functions share underlying technologies and code they will have slightly differening roadmaps.
Whilst both of these functions share underlying technologies and code they will have slightly differing roadmaps.
### HA Kubernetes Control Plane
- **Re-implememt LoadBalancing** - due to a previous request the HTTP loadbalancing was removed leaving just HA for the control plane. This functionality will be re-implemented either through the original round-robin HTTP requests or utilising IPVS.
- **Utilise the Kubernetes API to determine additional Control Plane members** - Once a single node cluster is running **kube-vip** could use the API to determine the additional members, at this time a Cluster-API provider needs to drop a static manifest per CP node.
- **Re-implement LoadBalancing** - due to a previous request the HTTP loadbalancing was removed leaving just HA for the control plane. This functionality will be re-implemented either through the original round-robin HTTP requests or utilising IPVS.
- **Utilise the Kubernetes API to determine additional Control Plane members** - Once a single node cluster is running **kube-vip** could use the API to determine the additional members, at this time a Cluster-API provider needs to drop a static manifest per CP node.
- **Re-evaluate raft** - **kube-vip** is mainly designed to run within a Kubernetes cluster, however it's original design was a raft cluster external to Kubernetes. Unfortunately given some of the upgrade paths identified in things like CAPV moving to leaderElection within Kubernetes became a better idea.
## Kubernetes `service type:LoadBalancer`
@@ -29,7 +29,7 @@ Whilst both of these functions share underlying technologies and code they will
## Global **Kube-Vip** items
- **Improved metrics** - At this time the scaffolding for monitoring exists, however this needs drastically extending to provide greater observability to what is happening within **kube-vip**
- **Windows support** - The Go SDK didn't support the capability for low-levels sockets for ARP originally, this should be revisted.
- **Windows support** - The Go SDK didn't support the capability for low-levels sockets for ARP originally, this should be revisited.
- **Additional BGP features** :
- Communities
- BFD

View File

@@ -1,146 +0,0 @@
package cmd
import (
"fmt"
"github.com/ghodss/yaml"
"github.com/kube-vip/kube-vip/pkg/kubevip"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
appv1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// [sample configuration] - flags
var cliConfig kubevip.Config
var cliConfigLB kubevip.LoadBalancer
var cliLocalPeer string
var cliRemotePeers, cliBackends []string
func init() {
kubeVipSampleConfig.Flags().StringVar(&cliConfig.Interface, "interface", "eth0", "Name of the interface to bind to")
kubeVipSampleConfig.Flags().StringVar(&cliConfig.VIP, "vip", "192.168.0.1", "The Virtual IP address")
kubeVipSampleConfig.Flags().BoolVar(&cliConfig.SingleNode, "singleNode", false, "Start this instance as a single node")
kubeVipSampleConfig.Flags().BoolVar(&cliConfig.StartAsLeader, "startAsLeader", false, "Start this instance as the cluster leader")
kubeVipSampleConfig.Flags().BoolVar(&cliConfig.EnableARP, "arp", true, "Use ARP broadcasts to improve VIP re-allocations")
kubeVipSampleConfig.Flags().StringVar(&cliLocalPeer, "localPeer", "server1:192.168.0.1:10000", "Settings for this peer, format: id:address:port")
kubeVipSampleConfig.Flags().StringSliceVar(&cliRemotePeers, "remotePeers", []string{"server2:192.168.0.2:10000", "server3:192.168.0.3:10000"}, "Comma seperated remotePeers, format: id:address:port")
// Load Balancer flags
kubeVipSampleConfig.Flags().BoolVar(&cliConfigLB.BindToVip, "lbBindToVip", false, "Bind example load balancer to VIP")
kubeVipSampleConfig.Flags().StringVar(&cliConfigLB.Type, "lbType", "tcp", "Type of load balancer instance (TCP/HTTP)")
kubeVipSampleConfig.Flags().StringVar(&cliConfigLB.Name, "lbName", "Example Load Balancer", "The name of a load balancer instance")
kubeVipSampleConfig.Flags().IntVar(&cliConfigLB.Port, "lbPort", 8080, "Port that load balancer will expose on")
kubeVipSampleConfig.Flags().StringSliceVar(&cliBackends, "lbBackends", []string{"192.168.0.1:8080", "192.168.0.2:8080"}, "Comma seperated backends, format: address:port")
}
var kubeVipSampleConfig = &cobra.Command{
Use: "config",
Short: "Generate a Sample configuration",
Run: func(cmd *cobra.Command, args []string) {
// // Parse localPeer
// p, err := kubevip.ParsePeerConfig(cliLocalPeer)
// if err != nil {
// cmd.Help()
// log.Fatalln(err)
// }
// cliConfig.LocalPeer = *p
// // Parse remotePeers
// //Iterate backends
// for i := range cliRemotePeers {
// p, err := kubevip.ParsePeerConfig(cliRemotePeers[i])
// if err != nil {
// cmd.Help()
// log.Fatalln(err)
// }
// cliConfig.RemotePeers = append(cliConfig.RemotePeers, *p)
// }
// //Iterate backends
// for i := range cliBackends {
// b, err := kubevip.ParseBackendConfig(cliBackends[i])
// if err != nil {
// cmd.Help()
// log.Fatalln(err)
// }
// cliConfigLB.Backends = append(cliConfigLB.Backends, *b)
// }
// Add the basic Load-Balancer to the configuration
cliConfig.LoadBalancers = append(cliConfig.LoadBalancers, cliConfigLB)
err := cliConfig.ParseFlags(cliLocalPeer, cliRemotePeers, cliBackends)
if err != nil {
cmd.Help()
log.Fatalln(err)
}
err = kubevip.ParseEnvironment(&cliConfig)
if err != nil {
cmd.Help()
log.Fatalln(err)
}
cliConfig.PrintConfig()
},
}
var kubeVipSampleManifest = &cobra.Command{
Use: "manifest",
Short: "Generate a Sample kubernetes manifest",
Run: func(cmd *cobra.Command, args []string) {
// Generate the sample manifest specification
p := &appv1.Pod{
TypeMeta: metav1.TypeMeta{
Kind: "Pod",
APIVersion: "v1",
},
ObjectMeta: metav1.ObjectMeta{
Name: "kube-vip",
Namespace: "kube-system",
},
Spec: appv1.PodSpec{
Containers: []appv1.Container{
{
Name: "kube-vip",
Image: fmt.Sprintf("docker.io/plndr/kube-vip:%s", Release.Version),
SecurityContext: &appv1.SecurityContext{
Capabilities: &appv1.Capabilities{
Add: []appv1.Capability{
"NET_ADMIN",
"SYS_TIME",
},
},
},
Args: []string{
"start",
"-c",
"/etc/kube-vip/config.yaml",
},
VolumeMounts: []appv1.VolumeMount{
{
Name: "config",
MountPath: "/etc/kube-vip/",
},
},
},
},
Volumes: []appv1.Volume{
{
Name: "config",
VolumeSource: appv1.VolumeSource{
HostPath: &appv1.HostPathVolumeSource{
Path: "/etc/kube-vip/",
},
},
},
},
HostNetwork: true,
},
}
b, _ := yaml.Marshal(p)
fmt.Printf(string(b))
},
}

View File

@@ -1,18 +1,13 @@
package cmd
import (
"context"
"fmt"
"net"
"os"
log "log/slog"
"github.com/kube-vip/kube-vip/pkg/kubevip"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/clientcmd"
)
// kubeadm adds two subcommands for managing a vip during a kubeadm init/join
@@ -28,134 +23,137 @@ func init() {
var kubeKubeadm = &cobra.Command{
Use: "kubeadm",
Short: "Kubeadm functions",
Run: func(cmd *cobra.Command, args []string) {
cmd.Help()
// TODO - A load of text detailing what's actually happening
Long: `This command group provides utilities for generating static Pod manifests specifically tailored for the kubeadm bootstrapping process.
It contains two subcommands:
- init: Generates a manifest to be used during 'kubeadm init' on the first control-plane node.
- join: Generates a manifest to be used during 'kubeadm join' for additional control-plane nodes.
The generated YAML manifest should be saved to the kubeadm static Pod directory (typically /etc/kubernetes/manifests/) so that kubeadm launches the kube-vip static Pod automatically.`,
Run: func(cmd *cobra.Command, _ []string) {
_ = cmd.Help()
},
}
var kubeKubeadmInit = &cobra.Command{
Use: "init",
Short: "kube-vip init",
Long: "The \"init\" subcommand will generate the Kubernetes manifest that will be started by kubeadm through the kubeadm init process",
Run: func(cmd *cobra.Command, args []string) {
// Set the logging level for all subsequent functions
log.SetLevel(log.Level(logLevel))
Long: `The 'init' subcommand generates a Kubernetes Pod manifest that kubeadm will start as a static Pod during the cluster initialisation phase.
This manifest runs kube-vip on the first control-plane node to advertise the Virtual IP (VIP) for the API server. The VIP is typically configured using ARP (Layer 2) or BGP (dynamic routing).
Required flags for this command:
--interface : The network interface to bind the VIP to (e.g., eth0).
--vip or --address : The Virtual IP address or DNS name to use.
Example:
kube-vip kubeadm init --interface eth0 --vip 192.168.1.100 --controlplane
The output YAML should be written to the kubeadm manifests directory, e.g.:
kube-vip kubeadm init ... > /etc/kubernetes/manifests/kube-vip.yaml`,
Run: func(cmd *cobra.Command, _ []string) {
initConfig.LoadBalancers = append(initConfig.LoadBalancers, initLoadBalancer)
// TODO - A load of text detailing what's actually happening
kubevip.ParseEnvironment(&initConfig)
err := kubevip.ParseEnvironment(&initConfig)
if err != nil {
log.Error("parsing environment", "err", err)
return
}
if err := initConfig.Validate(); err != nil {
log.Error("validating configuration", "err", err)
return
}
// TODO - check for certain things VIP/interfaces
if initConfig.Interface == "" {
cmd.Help()
log.Fatalln("No interface is specified for kube-vip to bind to")
_ = cmd.Help()
log.Error("No interface is specified for kube-vip to bind to")
return
}
if initConfig.VIP == "" && initConfig.Address == "" {
cmd.Help()
log.Fatalln("No address is specified for kube-vip to expose services on")
_ = cmd.Help()
log.Error("No address is specified for kube-vip to expose services on")
return
}
cfg := kubevip.GeneratePodManifestFromConfig(&initConfig, Release.Version, inCluster)
fmt.Println(cfg)
// Ensure there is an address to generate the CIDR from
if initConfig.VIPSubnet == "" && initConfig.Address != "" {
initConfig.VIPSubnet, err = GenerateCidrRange(initConfig.Address, initConfig.DNSMode)
if err != nil {
log.Error("generating VIPSubnet", "err", err)
return
}
}
cfg, err := kubevip.GeneratePodManifestFromConfig(&initConfig, image, Release.Version, inCluster)
if err != nil {
log.Error("unable to create manifest", "err", err)
return
}
fmt.Println(cfg) // output manifest to stdout
},
}
var kubeKubeadmJoin = &cobra.Command{
Use: "join",
Short: "kube-vip join",
Run: func(cmd *cobra.Command, args []string) {
// Set the logging level for all subsequent functions
log.SetLevel(log.Level(logLevel))
Long: `The 'join' subcommand generates a Kubernetes Pod manifest for additional control-plane nodes joining an existing cluster via 'kubeadm join'.
It functions identically to the 'init' subcommand, but is intended for secondary control-plane nodes. It validates that the kubeconfig file (specified by --config, defaulting to /etc/kubernetes/admin.conf) exists on the node to ensure the node can authenticate with the cluster.
Required flags for this command:
--interface : The network interface to bind the VIP to.
--vip or --address : The Virtual IP address or DNS name (must match the VIP used during 'init').
Example:
kube-vip kubeadm join --interface eth0 --vip 192.168.1.100
The output YAML should be saved to the kubeadm manifests directory on the joining node.`,
Run: func(cmd *cobra.Command, _ []string) {
initConfig.LoadBalancers = append(initConfig.LoadBalancers, initLoadBalancer)
// TODO - A load of text detailing what's actually happening
kubevip.ParseEnvironment(&initConfig)
err := kubevip.ParseEnvironment(&initConfig)
if err != nil {
log.Error("parsing environment", "err", err)
return
}
if err := initConfig.Validate(); err != nil {
log.Error("validating configuration", "err", err)
return
}
// TODO - check for certain things VIP/interfaces
if initConfig.Interface == "" {
cmd.Help()
log.Fatalln("No interface is specified for kube-vip to bind to")
_ = cmd.Help()
log.Error("No interface is specified for kube-vip to bind to")
return
}
if initConfig.VIP == "" && initConfig.Address == "" {
cmd.Help()
log.Fatalln("No address is specified for kube-vip to expose services on")
_ = cmd.Help()
log.Error("No address is specified for kube-vip to expose services on")
return
}
if _, err := os.Stat(kubeConfigPath); os.IsNotExist(err) {
log.Fatalf("Unable to find file [%s]", kubeConfigPath)
log.Error("kubeConfig not found", "Path", kubeConfigPath)
return
}
// We will use kubeconfig in order to find all the master nodes
// use the current context in kubeconfig
config, err := clientcmd.BuildConfigFromFlags("", kubeConfigPath)
if err != nil {
log.Fatal(err.Error())
}
// create the clientset
clientset, err := kubernetes.NewForConfig(config)
if err != nil {
log.Fatal(err.Error())
}
opts := metav1.ListOptions{}
opts.LabelSelector = "node-role.kubernetes.io/master"
nodes, err := clientset.CoreV1().Nodes().List(context.TODO(), opts)
// Iterate over all nodes that are masters and find the details to build a peer list
for x := range nodes.Items {
// Get hostname and address
var nodeAddress, nodeHostname string
for y := range nodes.Items[x].Status.Addresses {
switch nodes.Items[x].Status.Addresses[y].Type {
case corev1.NodeHostName:
nodeHostname = nodes.Items[x].Status.Addresses[y].Address
case corev1.NodeInternalIP:
nodeAddress = nodes.Items[x].Status.Addresses[y].Address
}
}
newPeer, err := kubevip.ParsePeerConfig(fmt.Sprintf("%s:%s:%d", nodeHostname, nodeAddress, 10000))
// Ensure there is an address to generate the CIDR from
if initConfig.VIPSubnet == "" && initConfig.Address != "" {
initConfig.VIPSubnet, err = GenerateCidrRange(initConfig.Address, initConfig.DNSMode)
if err != nil {
panic(err.Error())
log.Error("generating VIPSubnet", "err", err)
return
}
initConfig.RemotePeers = append(initConfig.RemotePeers, *newPeer)
}
// Generate manifest and print
cfg := kubevip.GeneratePodManifestFromConfig(&initConfig, Release.Version, inCluster)
fmt.Println(cfg)
cfg, err := kubevip.GeneratePodManifestFromConfig(&initConfig, image, Release.Version, inCluster)
if err != nil {
log.Error("unable to create manifest", "err", err)
return
}
fmt.Println(cfg) // output manifest to stdout
},
}
func autoGenLocalPeer() (*kubevip.RaftPeer, error) {
// hostname // address // defaultport
h, err := os.Hostname()
if err != nil {
return nil, err
}
var a string
addrs, err := net.InterfaceAddrs()
if err != nil {
return nil, err
}
for _, address := range addrs {
// check the address type and if it is not a loopback the display it
if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
if ipnet.IP.To16() != nil {
a = ipnet.IP.String()
break
}
}
}
if a == "" {
return nil, fmt.Errorf("Unable to find local address")
}
return &kubevip.RaftPeer{
ID: h,
Address: a,
Port: 10000,
}, nil
}

View File

@@ -3,8 +3,9 @@ package cmd
import (
"fmt"
log "log/slog"
"github.com/kube-vip/kube-vip/pkg/kubevip"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
)
@@ -12,75 +13,200 @@ import (
// manifests will be used to generate:
// - Pod spec manifest, mainly used for a static pod (kubeadm)
// - Daemonset manifest, mainly used to run kube-vip as a deamonset within Kubernetes (k3s/rke)
// - RBAC manifest, used to generate the RBAC permissions for kube-vip
//var inCluster bool
var taint bool
var taint, role, rolebinding bool
func init() {
kubeManifest.PersistentFlags().BoolVar(&inCluster, "inCluster", false, "Use the incluster token to authenticate to Kubernetes")
kubeManifest.PersistentFlags().StringVar(&image, "image", "ghcr.io/kube-vip/kube-vip", "Define a hardcoded image with or without tag for the manifest")
kubeManifestDaemon.PersistentFlags().BoolVar(&taint, "taint", false, "Taint the manifest for only running on control planes")
kubeManifestRbac.PersistentFlags().BoolVar(&role, "role", false, "Generate only a Role inside the serviceNamespace access")
kubeManifestRbac.PersistentFlags().BoolVar(&rolebinding, "rolebinding", false, "Generate only a RoleBinding for namespaced access")
kubeManifest.AddCommand(kubeManifestPod)
kubeManifest.AddCommand(kubeManifestDaemon)
kubeManifest.AddCommand(kubeManifestRbac)
}
var kubeManifest = &cobra.Command{
Use: "manifest",
Short: "Manifest functions",
Run: func(cmd *cobra.Command, args []string) {
cmd.Help()
// TODO - A load of text detailing what's actually happening
Long: `This command group provides flexible manifest generation for deploying kube-vip in various Kubernetes environments.
Unlike the 'kubeadm' subcommands, which are tightly coupled to kubeadm's static Pod requirements, these generators produce standard Kubernetes manifests (Pod, DaemonSet, RBAC) that can be used with any Kubernetes distribution (e.g., k3s, RKE, or vanilla Kubernetes).
Subcommands:
pod : Generates a standalone Pod manifest (similar to a static pod).
daemonset : Generates a DaemonSet manifest to run kube-vip on selected nodes.
rbac : Generates the necessary ServiceAccount, Role/ClusterRole, and Binding manifests.
All output is written to stdout as YAML, typically piped to 'kubectl apply -f -' or saved to a file.`,
Run: func(cmd *cobra.Command, _ []string) {
_ = cmd.Help()
},
}
var kubeManifestPod = &cobra.Command{
Use: "pod",
Short: "Generate a Pod Manifest",
Run: func(cmd *cobra.Command, args []string) {
// Set the logging level for all subsequent functions
log.SetLevel(log.Level(logLevel))
Long: `Generate a standalone Pod manifest for kube-vip.
This is ideal for environments that do not use DaemonSets or where you want to run kube-vip as a static Pod (similar to the 'kubeadm' subcommand, but without kubeadm-specific assumptions). It includes all the necessary container specifications, volumes, and environment variables derived from the provided flags.
Key flags:
--interface : Network interface for the VIP.
--vip or --address : The Virtual IP address or DNS name.
--image : Override the container image (default: ghcr.io/kube-vip/kube-vip).
The manifest is generated based on the current configuration flags set on the root command.
Example:
kube-vip manifest pod --interface eth0 --vip 10.0.0.100 --controlplane | kubectl apply -f -`,
Run: func(cmd *cobra.Command, _ []string) {
var err error
initConfig.LoadBalancers = append(initConfig.LoadBalancers, initLoadBalancer)
// TODO - A load of text detailing what's actually happening
kubevip.ParseEnvironment(&initConfig)
// TODO - check for certain things VIP/interfaces
if initConfig.Interface == "" {
cmd.Help()
log.Fatalln("No interface is specified for kube-vip to bind to")
if err := kubevip.ParseEnvironment(&initConfig); err != nil {
log.Error("parsing environment", "err", err)
return
}
if err := initConfig.Validate(); err != nil {
log.Error("validating configuration", "err", err)
return
}
// The control plane has a requirement for a VIP being specified
if initConfig.EnableControlPane && (initConfig.VIP == "" && initConfig.Address == "" && initConfig.DDNS == false) {
cmd.Help()
log.Fatalln("No address is specified for kube-vip to expose services on")
if initConfig.EnableControlPlane && (initConfig.VIP == "" && initConfig.Address == "" && !initConfig.DDNS) {
_ = cmd.Help()
log.Error("no address is specified for kube-vip to expose services on")
return
}
cfg := kubevip.GeneratePodManifestFromConfig(&initConfig, Release.Version, inCluster)
fmt.Println(cfg)
// Ensure there is an address to generate the CIDR from
if initConfig.VIPSubnet == "" && initConfig.Address != "" {
initConfig.VIPSubnet, err = GenerateCidrRange(initConfig.Address, initConfig.DNSMode)
if err != nil {
log.Error("config parse", "err", err)
return
}
}
cfg, err := kubevip.GeneratePodManifestFromConfig(&initConfig, image, Release.Version, inCluster)
if err != nil {
log.Error("unable to create manifest", "err", err)
return
}
fmt.Println(cfg) // output manifest to stdout
},
}
var kubeManifestDaemon = &cobra.Command{
Use: "daemonset",
Short: "Generate a Daemonset Manifest",
Run: func(cmd *cobra.Command, args []string) {
// Set the logging level for all subsequent functions
log.SetLevel(log.Level(logLevel))
Long: `Generate a DaemonSet manifest to run kube-vip across multiple nodes.
This is the recommended deployment method for production clusters running kube-vip as a service. It ensures that kube-vip runs on all control-plane nodes (or selected nodes via tolerations) and can handle both control-plane HA and service load-balancing.
Flags specific to this subcommand:
--taint : Adds a toleration to the DaemonSet so that pods are scheduled only on nodes with the control-plane taint (node-role.kubernetes.io/control-plane:NoSchedule). This is essential for control-plane-only deployments.
All other standard kube-vip flags (--interface, --vip, --enableARP, --enableBGP, etc.) are respected and embedded into the DaemonSet pod template.
Example:
kube-vip manifest daemonset --interface eth0 --vip 192.168.1.100 --controlplane --taint | kubectl apply -f -`,
Run: func(cmd *cobra.Command, _ []string) {
var err error
initConfig.LoadBalancers = append(initConfig.LoadBalancers, initLoadBalancer)
// TODO - A load of text detailing what's actually happening
kubevip.ParseEnvironment(&initConfig)
// TODO - check for certain things VIP/interfaces
if initConfig.Interface == "" {
cmd.Help()
log.Fatalln("No interface is specified for kube-vip to bind to")
if err := kubevip.ParseEnvironment(&initConfig); err != nil {
log.Error("parsing environment", "err", err)
return
}
if err := initConfig.Validate(); err != nil {
log.Error("validating configuration", "err", err)
return
}
// The control plane has a requirement for a VIP being specified
if initConfig.EnableControlPlane && (initConfig.VIP == "" && initConfig.Address == "" && !initConfig.DDNS) {
_ = cmd.Help()
log.Error("no address is specified for kube-vip to expose services on")
return
}
// Ensure there is an address to generate the CIDR from
if initConfig.VIPSubnet == "" && initConfig.Address != "" {
initConfig.VIPSubnet, err = GenerateCidrRange(initConfig.Address, initConfig.DNSMode)
if err != nil {
log.Error("config parse", "err", err)
return
}
}
cfg, err := kubevip.GenerateDaemonsetManifestFromConfig(&initConfig, image, Release.Version, inCluster, taint)
if err != nil {
log.Error("unable to create manifest", "err", err)
return
}
fmt.Println(cfg) // output manifest to stdout
},
}
var kubeManifestRbac = &cobra.Command{
Use: "rbac",
Short: "Generate an RBAC Manifest",
Long: `Generate the RBAC (Role-Based Access Control) manifests required for kube-vip to interact with the Kubernetes API.
kube-vip needs permissions to watch services, endpoints, configmaps, and manage leader election leases. This command outputs the minimum required ServiceAccount, Role (or ClusterRole), and the corresponding binding.
Flags:
--role : If true, generates a namespaced Role instead of a ClusterRole. The namespace is taken from the root --namespace flag (default: kube-system).
--rolebinding : If true, generates a RoleBinding (if --role is also true). If --role is false, a ClusterRoleBinding is generated automatically.
The output is a multi-document YAML (separated by '---'). It is safe to apply directly:
kube-vip manifest rbac --role --rolebinding | kubectl apply -f -
Without --role, it generates a ClusterRole and ClusterRoleBinding, which is the default behaviour and suitable for most cluster-wide deployments.`,
Run: func(cmd *cobra.Command, _ []string) {
initConfig.LoadBalancers = append(initConfig.LoadBalancers, initLoadBalancer)
if err := kubevip.ParseEnvironment(&initConfig); err != nil {
log.Error("parsing environment", "err", err)
return
}
if err := initConfig.Validate(); err != nil {
log.Error("validating configuration", "err", err)
return
}
// The control plane has a requirement for a VIP being specified
if initConfig.EnableControlPane && (initConfig.VIP == "" && initConfig.Address == "" && initConfig.DDNS == false) {
cmd.Help()
log.Fatalln("No address is specified for kube-vip to expose services on")
if initConfig.EnableControlPlane && (initConfig.VIP == "" && initConfig.Address == "" && !initConfig.DDNS) {
_ = cmd.Help()
log.Error("no address is specified for kube-vip to expose services on")
return
}
cfg := kubevip.GenerateDeamonsetManifestFromConfig(&initConfig, Release.Version, inCluster, taint)
fmt.Println(cfg)
// Ensure there is an address to generate the CIDR from
if initConfig.VIPSubnet == "" && initConfig.Address != "" {
var err error
initConfig.VIPSubnet, err = GenerateCidrRange(initConfig.Address, initConfig.DNSMode)
if err != nil {
log.Error("generating VIPSubnet", "err", err)
return
}
}
saCfg := kubevip.GenerateSA(&initConfig)
roleCfg := kubevip.GenerateRole(&initConfig, role)
if role {
rolebinding = true
}
roleBindingCfg := kubevip.GenerateRoleBinding(rolebinding, saCfg, roleCfg)
// Output the YAML manifests to stdout
fmt.Println("---") // Separator for YAML documents
fmt.Println(kubevip.TransformApplyObjectToManifest(saCfg))
fmt.Println("---") // Separator for YAML documents
fmt.Println(kubevip.TransformApplyObjectToManifest(roleCfg))
fmt.Println("---") // Separator for YAML documents
fmt.Println(kubevip.TransformApplyObjectToManifest(roleBindingCfg))
},
}

View File

@@ -1,136 +0,0 @@
package cmd
import (
"os"
"os/signal"
"github.com/kube-vip/kube-vip/pkg/bgp"
"github.com/kube-vip/kube-vip/pkg/cluster"
"github.com/kube-vip/kube-vip/pkg/kubevip"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
)
// Start as a single node (no cluster), start as a leader in the cluster
var startConfig kubevip.Config
var startConfigLB kubevip.LoadBalancer
var startLocalPeer, startKubeConfigPath string
var startRemotePeers, startBackends []string
var inCluster bool
func init() {
// Get the configuration file
kubeVipStart.Flags().StringVarP(&configPath, "config", "c", "", "Path to a kube-vip configuration")
kubeVipStart.Flags().BoolVarP(&disableVIP, "disableVIP", "d", false, "Disable the VIP functionality")
// Pointers so we can see if they're nil (and not called)
kubeVipStart.Flags().StringVar(&startConfig.Interface, "interface", "eth0", "Name of the interface to bind to")
kubeVipStart.Flags().StringVar(&startConfig.VIP, "vip", "192.168.0.1", "The Virtual IP address")
kubeVipStart.Flags().StringVar(&startConfig.Address, "address", "", "an address (IP or DNS name) to use as a VIP")
kubeVipStart.Flags().IntVar(&startConfig.Port, "port", 6443, "listen port for the VIP")
kubeVipStart.Flags().BoolVar(&startConfig.DDNS, "ddns", false, "use Dynamic DNS + DHCP to allocate VIP for address")
kubeVipStart.Flags().BoolVar(&startConfig.SingleNode, "singleNode", false, "Start this instance as a single node")
kubeVipStart.Flags().BoolVar(&startConfig.StartAsLeader, "startAsLeader", false, "Start this instance as the cluster leader")
kubeVipStart.Flags().BoolVar(&startConfig.EnableARP, "arp", false, "Use ARP broadcasts to improve VIP re-allocations")
kubeVipStart.Flags().StringVar(&startLocalPeer, "localPeer", "server1:192.168.0.1:10000", "Settings for this peer, format: id:address:port")
kubeVipStart.Flags().StringSliceVar(&startRemotePeers, "remotePeers", []string{"server2:192.168.0.2:10000", "server3:192.168.0.3:10000"}, "Comma seperated remotePeers, format: id:address:port")
// Load Balancer flags
kubeVipStart.Flags().BoolVar(&startConfigLB.BindToVip, "lbBindToVip", false, "Bind example load balancer to VIP")
kubeVipStart.Flags().StringVar(&startConfigLB.Type, "lbType", "tcp", "Type of load balancer instance (TCP/HTTP)")
kubeVipStart.Flags().StringVar(&startConfigLB.Name, "lbName", "Example Load Balancer", "The name of a load balancer instance")
kubeVipStart.Flags().IntVar(&startConfigLB.Port, "lbPort", 8080, "Port that load balancer will expose on")
kubeVipStart.Flags().IntVar(&startConfigLB.BackendPort, "lbBackEndPort", 6443, "A port that all backends may be using (optional)")
kubeVipStart.Flags().StringSliceVar(&startBackends, "lbBackends", []string{"192.168.0.1:8080", "192.168.0.2:8080"}, "Comma seperated backends, format: address:port")
// Cluster configuration
kubeVipStart.Flags().StringVar(&startKubeConfigPath, "kubeConfig", "/etc/kubernetes/admin.conf", "The path of a kubernetes configuration file")
kubeVipStart.Flags().BoolVar(&inCluster, "inCluster", false, "Use the incluster token to authenticate to Kubernetes")
kubeVipStart.Flags().BoolVar(&startConfig.EnableLeaderElection, "leaderElection", false, "Use the Kubernetes leader election mechanism for clustering")
// This sets the namespace that the lock should exist in
kubeVipStart.Flags().StringVarP(&startConfig.Namespace, "namespace", "n", "kube-system", "The configuration map defined within the cluster")
}
var kubeVipStart = &cobra.Command{
Use: "start",
Short: "Start the Virtual IP / Load balancer",
Run: func(cmd *cobra.Command, args []string) {
// Set the logging level for all subsequent functions
log.SetLevel(log.Level(logLevel))
var err error
// If a configuration file is loaded, then it will overwrite flags
if configPath != "" {
c, err := kubevip.OpenConfig(configPath)
if err != nil {
log.Fatalf("%v", err)
}
startConfig = *c
}
// parse environment variables, these will overwrite anything loaded or flags
err = kubevip.ParseEnvironment(&startConfig)
if err != nil {
log.Fatalln(err)
}
newCluster, err := cluster.InitCluster(&startConfig, disableVIP)
if err != nil {
log.Fatalf("%v", err)
}
var bgpServer *bgp.Server
if startConfig.SingleNode {
// If the Virtual IP isn't disabled then create the netlink configuration
// Start a single node cluster
newCluster.StartSingleNode(&startConfig, disableVIP)
} else {
if disableVIP {
log.Fatalln("Cluster mode requires the Virtual IP to be enabled, use single node with no VIP")
}
if startConfig.EnableLeaderElection {
cm, err := cluster.NewManager(startKubeConfigPath, inCluster, startConfig.Port)
if err != nil {
log.Fatalf("%v", err)
}
if startConfig.EnableBGP {
log.Info("Starting the BGP server to adverise VIP routes to VGP peers")
bgpServer, err = bgp.NewBGPServer(&startConfig.BGPConfig)
if err != nil {
log.Fatalf("%v", err)
}
// Defer a function to check if the bgpServer has been created and if so attempt to close it
defer func() {
if bgpServer != nil {
bgpServer.Close()
}
}()
}
// Leader Cluster will block
err = newCluster.StartLeaderCluster(&startConfig, cm, bgpServer)
if err != nil {
log.Fatalf("%v", err)
}
} else {
// // Start a multi-node (raft) cluster, this doesn't block so will wait on signal
err = newCluster.StartRaftCluster(&startConfig)
if err != nil {
log.Fatalf("%v", err)
}
signalChan := make(chan os.Signal, 1)
signal.Notify(signalChan, os.Interrupt)
<-signalChan
newCluster.Stop()
}
}
},
}

View File

@@ -3,42 +3,41 @@ package cmd
import (
"context"
"fmt"
"net"
"net/http"
"os"
"slices"
"strconv"
"strings"
"sync"
"time"
log "log/slog"
"github.com/prometheus/client_golang/prometheus/promhttp"
"github.com/spf13/cobra"
"github.com/vishvananda/netlink"
"golang.org/x/sys/unix"
"github.com/kube-vip/kube-vip/pkg/debouncer"
"github.com/kube-vip/kube-vip/pkg/kubevip"
"github.com/kube-vip/kube-vip/pkg/manager"
"github.com/kube-vip/kube-vip/pkg/packet"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/kube-vip/kube-vip/pkg/metrics"
"github.com/kube-vip/kube-vip/pkg/utils"
"github.com/kube-vip/kube-vip/pkg/vip"
)
// Path to the configuration file
var configPath string
// Is an option to set the image
var image string
// Path to the configuration file
var namespace string
// Disable the Virtual IP (bind to the existing network stack)
var disableVIP bool
// Disable the Virtual IP (bind to the existing network stack)
var controlPlane bool
// Run as a load balancer service (within a pod / kubernetes)
var serviceArp bool
// Is kube-vip running within cluster
var inCluster bool
// ConfigMap name within a Kubernetes cluster
var configMap string
// Configure the level of loggin
var logLevel uint32
// Provider Config
var providerConfig string
// Points to a kubernetes configuration file
var kubeConfigPath string
// Release - this struct contains the release information populated when building kube-vip
var Release struct {
@@ -47,110 +46,164 @@ var Release struct {
}
// Structs used via the various subcommands
var initConfig kubevip.Config
var initLoadBalancer kubevip.LoadBalancer
// Points to a kubernetes configuration file
var kubeConfigPath string
var (
initConfig kubevip.Config
initLoadBalancer kubevip.LoadBalancer
)
var kubeVipCmd = &cobra.Command{
Use: "kube-vip",
Short: "This is a server for providing a Virtual IP and load-balancer for the Kubernetes control-plane",
Use: "kube-vip",
Short: "This is a server for providing a Virtual IP and load-balancer for the Kubernetes control-plane",
SilenceErrors: true,
}
func init() {
localpeer, err := autoGenLocalPeer()
if err != nil {
log.Fatalln(err)
}
initConfig.LocalPeer = *localpeer
//initConfig.Peers = append(initConfig.Peers, *localpeer)
// Basic flags
kubeVipCmd.PersistentFlags().StringVar(&initConfig.Interface, "interface", "", "Name of the interface to bind to")
kubeVipCmd.PersistentFlags().StringVar(&initConfig.ServicesInterface, "serviceInterface", "", "Name of the interface to bind to (for services)")
kubeVipCmd.PersistentFlags().BoolVar(&initConfig.AllowInterfaceNotUp, "allowInterfaceNotUp", false, "Allow kube-vip to start even if the interface is not up")
kubeVipCmd.PersistentFlags().StringVar(&initConfig.VIP, "vip", "", "The Virtual IP address")
kubeVipCmd.PersistentFlags().StringVar(&initConfig.VIPSubnet, "vipSubnet", "", "The Virtual IP address subnet e.g. /32 /24 /8 etc.. (Default to 32 for IPv4 and 128 for IPv6)")
kubeVipCmd.PersistentFlags().StringVar(&initConfig.NodeName, "nodeName", "", "Name to be used for lease holder. Must be unique for each node/instance")
// VIP flags
kubeVipCmd.PersistentFlags().StringVar(&initConfig.Address, "address", "", "an address (IP or DNS name) to use as a VIP")
kubeVipCmd.PersistentFlags().IntVar(&initConfig.Port, "port", 6443, "listen port for the VIP")
kubeVipCmd.PersistentFlags().StringVar(&initConfig.VIPCIDR, "cidr", "32", "The CIDR range for the virtual IP address")
kubeVipCmd.PersistentFlags().BoolVar(&initConfig.EnableARP, "arp", false, "Enable Arp for Vip changes")
kubeVipCmd.PersistentFlags().StringVar(&initConfig.Annotations, "annotations", "", "Set Node annotations prefix for parsing")
kubeVipCmd.PersistentFlags().Uint16Var(&initConfig.Port, "port", 6443, "Port for the VIP")
kubeVipCmd.PersistentFlags().BoolVar(&initConfig.EnableARP, "arp", false, "Enable Arp for VIP changes")
kubeVipCmd.PersistentFlags().BoolVar(&initConfig.EnableWireguard, "wireguard", false, "Enable Wireguard for services VIPs")
kubeVipCmd.PersistentFlags().BoolVar(&initConfig.EnableRoutingTable, "table", false, "Enable Routing Table for services VIPs")
kubeVipCmd.PersistentFlags().BoolVar(&initConfig.PreserveVIPOnLeadershipLoss, "preserveVipOnLeadershipLoss", false, "Preserve ARP VIP addresses on interface when leadership is lost (default: false for backward compatibility)")
kubeVipCmd.PersistentFlags().BoolVar(&initConfig.LoseLeadership, "loseLeadership", false, "Lose leadership when VIP interface goes down")
kubeVipCmd.PersistentFlags().IntVar(&initConfig.LoseLeadershipTimeoutSeconds, "loseLeadershiptTimeoutSeconds", 30, "Timeout before re-electing a leader when the VIP interface is down")
// LoadBalancer flags
kubeVipCmd.PersistentFlags().BoolVar(&initConfig.EnableLoadBalancer, "enableLoadBalancer", false, "enable loadbalancing on the VIP with IPVS")
kubeVipCmd.PersistentFlags().Uint16Var(&initConfig.LoadBalancerPort, "lbPort", 6443, "loadbalancer port for the VIP")
kubeVipCmd.PersistentFlags().StringVar(&initConfig.LoadBalancerForwardingMethod, "lbForwardingMethod", "local", "loadbalancer forwarding method")
kubeVipCmd.PersistentFlags().BoolVar(&initConfig.DDNS, "ddns", false, "use Dynamic DNS + DHCP to allocate VIP for address")
kubeVipCmd.PersistentFlags().StringVar(&initConfig.MirrorDestInterface, "mirrorDestInterface", "", "network interface where all traffic that traverses the service interface will be mirrored to. Source interface will use default interface is servicesInterface is not set.")
// Clustering type (leaderElection)
kubeVipCmd.PersistentFlags().BoolVar(&initConfig.EnableLeaderElection, "leaderElection", false, "Use the Kubernetes leader election mechanism for clustering")
kubeVipCmd.PersistentFlags().IntVar(&initConfig.LeaseDuration, "leaseDuration", 5, "Length of time a Kubernetes leader lease can be held for")
kubeVipCmd.PersistentFlags().IntVar(&initConfig.RenewDeadline, "leaseRenewDuration", 3, "Length of time a Kubernetes leader can attempt to renew its lease")
kubeVipCmd.PersistentFlags().IntVar(&initConfig.RetryPeriod, "leaseRetry", 1, "Number of times the host will retry to hold a lease")
// Clustering type (raft)
kubeVipCmd.PersistentFlags().BoolVar(&initConfig.StartAsLeader, "startAsLeader", false, "Start this instance as the cluster leader")
kubeVipCmd.PersistentFlags().BoolVar(&initConfig.AddPeersAsBackends, "addPeersToLB", true, "Add raft peers to the load-balancer")
// Packet flags
kubeVipCmd.PersistentFlags().BoolVar(&initConfig.EnableMetal, "metal", false, "This will use the Equinix Metal API (requires the token ENV) to update the EIP <-> VIP")
kubeVipCmd.PersistentFlags().StringVar(&initConfig.MetalAPIKey, "metalKey", "", "The API token for authenticating with the Equinix Metal API")
kubeVipCmd.PersistentFlags().StringVar(&initConfig.MetalProject, "metalProject", "", "The name of project already created within Equinix Metal")
kubeVipCmd.PersistentFlags().StringVar(&initConfig.MetalProjectID, "metalProjectID", "", "The ID of project already created within Equinix Metal")
kubeVipCmd.PersistentFlags().StringVar(&initConfig.ProviderConfig, "provider-config", "", "The path to a provider configuration")
// Load Balancer flags
kubeVipCmd.PersistentFlags().BoolVar(&initConfig.EnableLoadBalancer, "lbEnable", false, "Enable a load-balancer on the VIP")
kubeVipCmd.PersistentFlags().BoolVar(&initLoadBalancer.BindToVip, "lbBindToVip", true, "Bind example load balancer to VIP")
kubeVipCmd.PersistentFlags().StringVar(&initLoadBalancer.Type, "lbType", "tcp", "Type of load balancer instance (TCP/HTTP)")
kubeVipCmd.PersistentFlags().StringVar(&initLoadBalancer.Name, "lbName", "Kubeadm Load Balancer", "The name of a load balancer instance")
kubeVipCmd.PersistentFlags().IntVar(&initLoadBalancer.Port, "lbPort", 6443, "Port that load balancer will expose on")
kubeVipCmd.PersistentFlags().IntVar(&initLoadBalancer.BackendPort, "lbBackEndPort", 6444, "A port that all backends may be using (optional)")
kubeVipCmd.PersistentFlags().StringVar(&initConfig.LeaderElectionType, "leaderElectionType", "kubernetes", "Defines the backend to run the leader election: kubernetes or etcd. Defaults to kubernetes.")
kubeVipCmd.PersistentFlags().StringVar(&initConfig.LeaseName, "leaseName", "plndr-cp-lock", "Name of the lease that is used for leader election")
kubeVipCmd.PersistentFlags().IntVar(&initConfig.LeaseDuration, "leaseDuration", 15, "Length of time (in seconds) a Kubernetes leader lease can be held for")
kubeVipCmd.PersistentFlags().IntVar(&initConfig.RenewDeadline, "leaseRenewDuration", 10, "Length of time (in seconds) a Kubernetes leader can attempt to renew its lease")
kubeVipCmd.PersistentFlags().IntVar(&initConfig.RetryPeriod, "leaseRetry", 2, "Length of time (in seconds) the LeaderElector clients should wait between tries of actions")
// BGP flags
kubeVipCmd.PersistentFlags().BoolVar(&initConfig.EnableBGP, "bgp", false, "This will enable BGP support within kube-vip")
kubeVipCmd.PersistentFlags().BoolVar(&initConfig.BGPAttachIPToInterface, "bgpAttachIPToInterface", false, "Assign BGP service VIPs to the configured interface")
kubeVipCmd.PersistentFlags().StringVar(&initConfig.BGPConfig.RouterID, "bgpRouterID", "", "The routerID for the bgp server")
kubeVipCmd.PersistentFlags().StringVar(&initConfig.BGPConfig.SourceIF, "sourceIF", "", "The source interface for bgp peering (not to be used with sourceIP)")
kubeVipCmd.PersistentFlags().StringVar(&initConfig.BGPConfig.SourceIP, "sourceIP", "", "The source address for bgp peering (not to be used with sourceIF)")
kubeVipCmd.PersistentFlags().Uint32Var(&initConfig.BGPConfig.AS, "localAS", 65000, "The local AS number for the bgp server")
kubeVipCmd.PersistentFlags().Uint64Var(&initConfig.BGPConfig.HoldTime, "bgpHoldTimer", 30, "The hold timer for all bgp peers (it defines the time a session is held)")
kubeVipCmd.PersistentFlags().Uint64Var(&initConfig.BGPConfig.KeepaliveInterval, "bgpKeepAliveInterval", 10, "The keepalive interval for all bgp peers (it defines the heartbeat of keepalive messages)")
kubeVipCmd.PersistentFlags().StringVar(&initConfig.BGPPeerConfig.Address, "peerAddress", "", "The address of a BGP peer")
kubeVipCmd.PersistentFlags().Uint32Var(&initConfig.BGPPeerConfig.AS, "peerAS", 65000, "The AS number for a BGP peer")
kubeVipCmd.PersistentFlags().StringVar(&initConfig.BGPPeerConfig.Password, "peerPass", "", "The md5 password for a BGP peer")
kubeVipCmd.PersistentFlags().BoolVar(&initConfig.BGPPeerConfig.MultiHop, "multihop", false, "This will enable BGP multihop support")
kubeVipCmd.PersistentFlags().StringSliceVar(&initConfig.BGPPeers, "bgppeers", []string{}, "Comma seperated BGP Peer, format: address:as:password:multihop")
kubeVipCmd.PersistentFlags().StringSliceVar(&initConfig.BGPPeers, "bgppeers", []string{}, "Comma separated BGP Peer, format: address:as:password:multihop")
kubeVipCmd.PersistentFlags().StringVar(&initConfig.Annotations, "annotations", "", "Set Node annotations prefix for parsing")
// Control plane specific flags
kubeVipCmd.PersistentFlags().StringVarP(&initConfig.Namespace, "namespace", "n", "kube-system", "The configuration map defined within the cluster")
kubeVipCmd.PersistentFlags().BoolVar(&initConfig.BGPConfig.Zebra.Enabled, "zebra", false, "This will enable Zebra support within kube-vip")
kubeVipCmd.PersistentFlags().StringVar(&initConfig.BGPConfig.Zebra.URL, "zebraUrl", "unix:/var/run/frr/zserv.api", "Path to the unix domain socket for connecting to Zebra daemon")
kubeVipCmd.PersistentFlags().Uint32Var(&initConfig.BGPConfig.Zebra.Version, "zebraVersion", 6, "Zebra API Version")
kubeVipCmd.PersistentFlags().StringVar(&initConfig.BGPConfig.Zebra.SoftwareName, "zebraSoftwareName", "frr8.3", "Software Name for Zebra")
kubeVipCmd.PersistentFlags().StringVar(&initConfig.ControlPlaneHealthCheck.Address, "controlPlaneHealthCheckAddress", "", "URL to poll for the control-plane health check when using BGP without leader election")
kubeVipCmd.PersistentFlags().IntVar(&initConfig.ControlPlaneHealthCheck.PeriodSeconds, "controlPlaneHealthCheckPeriodSeconds", 5, "Seconds between control-plane health checks")
kubeVipCmd.PersistentFlags().IntVar(&initConfig.ControlPlaneHealthCheck.TimeoutSeconds, "controlPlaneHealthCheckTimeoutSeconds", 3, "Timeout for each control-plane health check request")
kubeVipCmd.PersistentFlags().IntVar(&initConfig.ControlPlaneHealthCheck.FailureThreshold, "controlPlaneHealthCheckFailureThreshold", 3, "Consecutive control-plane health check failures before withdrawing the BGP route")
kubeVipCmd.PersistentFlags().StringVar(&initConfig.ControlPlaneHealthCheck.CAPath, "controlPlaneHealthCheckCAPath", "", "Path to CA certificate for TLS verification when the control-plane health check URL is HTTPS")
// Namespace for kube-vip
kubeVipCmd.PersistentFlags().StringVarP(&initConfig.Namespace, "namespace", "n", "kube-system", "The namespace for the configmap defined within the cluster")
// Manage logging
kubeVipCmd.PersistentFlags().Uint32Var(&logLevel, "log", 4, "Set the level of logging")
kubeVipCmd.PersistentFlags().Int32Var(&initConfig.Logging, "log", 0, "Set the level of logging")
// Service flags
kubeVipService.Flags().StringVarP(&configMap, "configMap", "c", "plndr", "The configuration map defined within the cluster")
kubeVipCmd.PersistentFlags().BoolVar(&initConfig.EnableControlPane, "controlplane", false, "Enable HA for control plane, hybrid mode")
kubeVipCmd.PersistentFlags().BoolVar(&initConfig.EnableServices, "services", false, "Enable Kubernetes services, hybrid mode")
// Routing Table flags
kubeVipCmd.PersistentFlags().IntVar(&initConfig.RoutingTableID, "tableID", 198, "The routing table used for all table entries")
kubeVipCmd.PersistentFlags().IntVar(&initConfig.RoutingTableType, "tableType", unix.RTN_UNICAST, "The type of route that will be added to the routing table")
kubeVipCmd.PersistentFlags().IntVar(&initConfig.RoutingProtocol, "routingProtocol", 248, "The routing protocol value used to create routes")
kubeVipCmd.PersistentFlags().BoolVar(&initConfig.CleanRoutingTable, "cleanRoutingTable", false, "Clean routing table of redundant routes on start")
// Behaviour flags
kubeVipCmd.PersistentFlags().BoolVar(&initConfig.EnableControlPlane, "controlplane", false, "Enable HA for control plane")
kubeVipCmd.PersistentFlags().BoolVar(&initConfig.DetectControlPlane, "autodetectcp", false, "Determine working address for control plane (from loopback)")
kubeVipCmd.PersistentFlags().BoolVar(&initConfig.EnableServices, "services", false, "Enable Kubernetes services")
// Extended behaviour flags
kubeVipCmd.PersistentFlags().BoolVar(&initConfig.EnableServicesElection, "servicesElection", false, "Enable leader election per kubernetes service")
kubeVipCmd.PersistentFlags().BoolVar(&initConfig.LoadBalancerClassOnly, "lbClassOnly", false, fmt.Sprintf("Enable load balancing only for services with LoadBalancerClass %q", kubevip.LBClassName))
kubeVipCmd.PersistentFlags().StringVar(&initConfig.LoadBalancerClassName, "lbClassName", kubevip.LBClassName, fmt.Sprintf("Name of load balancer class for kube-VIP, defaults to %q", kubevip.LBClassName))
kubeVipCmd.PersistentFlags().BoolVar(&initConfig.LoadBalancerClassLegacyHandling, "lbClassNameLegacyHandling", true, "Use legacy LoadBalancer class name handling (e.g. accepting services both with empty and non-empty class)")
kubeVipCmd.PersistentFlags().BoolVar(&initConfig.EnableServiceSecurity, "onlyAllowTrafficServicePorts", false, "Only allow traffic to service ports, others will be dropped, defaults to false")
kubeVipCmd.PersistentFlags().BoolVar(&initConfig.EnableNodeLabeling, "enableNodeLabeling", false, fmt.Sprintf("Enable leader node labeling with %q, defaults to false", kubevip.HasIP))
kubeVipCmd.PersistentFlags().StringVar(&initConfig.ServicesLeaseName, "servicesLeaseName", "plndr-svcs-lock", "Name of the lease that is used for leader election for services (in arp mode)")
kubeVipCmd.PersistentFlags().StringVar(&initConfig.DNSMode, "dnsMode", "first", "Name of the mode that DNS lookup will be performed (first, ipv4, ipv6, dual)")
kubeVipCmd.PersistentFlags().StringVar(&initConfig.DHCPMode, "dhcpMode", "", "Mode DHCP resolving will use to obtain IP addresses (ipv4, ipv6, dual)")
kubeVipCmd.PersistentFlags().UintVar(&initConfig.DHCPBackoffAttempts, "dhcpBackoffAttempts", kubevip.DefaultDHCPBackoffAttempts,
fmt.Sprintf("number of times DHCP client will try to obtain an IP address (defaults to: %d, 0 for unlimited retries)", kubevip.DefaultDHCPBackoffAttempts))
kubeVipCmd.PersistentFlags().BoolVar(&initConfig.DisableServiceUpdates, "disableServiceUpdates", false, "If true, kube-vip will process services as usual, but will not update service's Status.LoadBalancer.Ingress slice")
kubeVipCmd.PersistentFlags().BoolVar(&initConfig.EnableEndpoints, "enableEndpoints", false, "If enabled, kube-vip will only advertise services, but will use the (deprecated since v1.33) endpoints for IP addresses")
kubeVipCmd.PersistentFlags().BoolVar(&initConfig.LoInterfaceGlobalScope, "loInterfaceGlobalScope", false, "If true, kube-vip will set global scope when using the lo interface, otherwise a host scope will be used by default")
kubeVipCmd.PersistentFlags().IntVar(&initConfig.HealthCheckPort, "healthCheckPort", 0, "If set to non-zero (> 1024), then this is the port that the healthcheck will listen on")
kubeVipCmd.PersistentFlags().StringVar(&initConfig.DebounceTime, "debounceTime", debouncer.DefaultTime,
"Configures the time that the event debouncer will wait for the events arrival (default 0s - debouncer disabled, enable with min. 200ms)")
// Prometheus HTTP Server
kubeVipCmd.PersistentFlags().StringVar(&initConfig.PrometheusHTTPServer, "promethuesHTTPServer", ":2112", "Host and port used to expose Promethues metrics via an HTTP server")
kubeVipCmd.PersistentFlags().StringVar(&initConfig.PrometheusHTTPServer, "prometheusHTTPServer", ":2112", "Host and port used to expose Prometheus metrics via an HTTP server")
// Etcd
kubeVipCmd.PersistentFlags().StringVar(&initConfig.Etcd.CAFile, "etcdCACert", "", "Verify certificates of TLS-enabled secure servers using this CA bundle file")
kubeVipCmd.PersistentFlags().StringVar(&initConfig.Etcd.ClientCertFile, "etcdCert", "", "Identify secure client using this TLS certificate file")
kubeVipCmd.PersistentFlags().StringVar(&initConfig.Etcd.ClientKeyFile, "etcdKey", "", "Identify secure client using this TLS key file")
kubeVipCmd.PersistentFlags().StringSliceVar(&initConfig.Etcd.Endpoints, "etcdEndpoints", nil, "Etcd member endpoints")
// Kubernetes client specific flags
kubeVipCmd.PersistentFlags().StringVar(&initConfig.K8sConfigFile, "k8sConfigPath", "/etc/kubernetes/admin.conf", "Path to the configuration file used with the Kubernetes client")
// Configuration file flag
kubeVipCmd.PersistentFlags().StringVar(&initConfig.ConfigFile, "config-file", "", "Path to a JSON/YAML configuration file to load settings from")
kubeVipCmd.PersistentFlags().StringVar(&initConfig.InstanceName, "instanceName", "", "Unique name for this kube-vip instance (currently used to isolate nftables egress tables)")
kubeVipCmd.PersistentFlags().BoolVar(&initConfig.EgressWithNftables, "egressWithNftables", true, "Use nftables-based egress implementation")
kubeVipCmd.PersistentFlags().BoolVar(&initConfig.PerServiceElectionOnDemand, "perServiceElectionOnDemand", false, "Allow kube-vip to use per-service election for annotated services")
kubeVipCmd.AddCommand(kubeKubeadm)
kubeVipCmd.AddCommand(kubeManifest)
kubeVipCmd.AddCommand(kubeVipManager)
kubeVipCmd.AddCommand(kubeVipSample)
kubeVipCmd.AddCommand(kubeVipService)
kubeVipCmd.AddCommand(kubeVipStart)
kubeVipCmd.AddCommand(kubeVipVersion)
// Sample commands
kubeVipSample.AddCommand(kubeVipSampleConfig)
kubeVipSample.AddCommand(kubeVipSampleManifest)
// Set the logging level for all subsequent functions
log.SetLogLoggerLevel(log.Level(initConfig.Logging))
}
// Execute - starts the command parsing process
func Execute() {
if err := kubeVipCmd.Execute(); err != nil {
fmt.Println(err)
os.Exit(1)
func Execute() int {
cmd, err := kubeVipCmd.ExecuteC()
if err != nil {
log.Error("command failed", "err", err)
if cmd == kubeVipCmd {
_ = cmd.Usage()
}
return 1
}
return 0
}
var kubeVipVersion = &cobra.Command{
Use: "version",
Short: "Version and Release information about the Kubernetes Virtual IP Server",
Run: func(cmd *cobra.Command, args []string) {
Run: func(cmd *cobra.Command, args []string) { //nolint TODO
fmt.Printf("Kube-VIP Release Information\n")
fmt.Printf("Version: %s\n", Release.Version)
fmt.Printf("Build: %s\n", Release.Build)
@@ -160,22 +213,44 @@ var kubeVipVersion = &cobra.Command{
var kubeVipSample = &cobra.Command{
Use: "sample",
Short: "Generate a Sample configuration",
Run: func(cmd *cobra.Command, args []string) {
cmd.Help()
Run: func(cmd *cobra.Command, args []string) { //nolint TODO
_ = cmd.Help()
},
}
var kubeVipService = &cobra.Command{
Use: "service",
Short: "Start the Virtual IP / Load balancer as a service within a Kubernetes cluster",
Run: func(cmd *cobra.Command, args []string) {
// Set the logging level for all subsequent functions
log.SetLevel(log.Level(logLevel))
RunE: func(cmd *cobra.Command, args []string) error { //nolint TODO
cmd.SilenceUsage = true
// parse environment variables, these will overwrite anything loaded or flags
// Load configuration from file if specified (lowest priority)
if initConfig.ConfigFile != "" {
err := kubevip.MergeConfigFromFile(&initConfig, initConfig.ConfigFile)
if err != nil {
return fmt.Errorf("loading config file: %w", err)
}
}
// parse environment variables, these will overwrite anything loaded from config file
err := kubevip.ParseEnvironment(&initConfig)
if err != nil {
log.Fatalln(err)
return fmt.Errorf("parsing environment: %w", err)
}
if err := initConfig.Validate(); err != nil {
return fmt.Errorf("validating configuration: %w", err)
}
// Change RTN_UNSPEC to default type
if initConfig.RoutingProtocol == unix.RTN_UNSPEC {
initConfig.RoutingProtocol = unix.RTN_UNICAST
}
// Set the logging level for all subsequent functions
log.SetLogLoggerLevel(log.Level(initConfig.Logging))
if err := initConfig.CheckInterface(); err != nil {
return fmt.Errorf("checking interface: %w", err)
}
// User Environment variables as an option to make manifest clearer
@@ -184,35 +259,205 @@ var kubeVipService = &cobra.Command{
configMap = envConfigMap
}
// Legacy vip_address requires vip_subnet for control-plane ARP, BGP, and Routing Table modes.
if initConfig.EnableControlPlane &&
(initConfig.EnableARP || initConfig.EnableBGP || initConfig.EnableRoutingTable) {
if err := initConfig.CheckSubnetExists(); err != nil {
return fmt.Errorf("checking subnet exists if vip_address defined: %w", err)
}
}
// Ensure there is an address to generate the CIDR from
if initConfig.VIPSubnet == "" && initConfig.Address != "" {
initConfig.VIPSubnet, err = GenerateCidrRange(initConfig.Address, initConfig.DNSMode)
if err != nil {
return fmt.Errorf("generating CIDR: %w", err)
}
}
ctx, cancel := context.WithCancel(cmd.Context())
defer cancel()
// Define the new service manager
mgr, err := manager.New(configMap, &initConfig)
mgr, err := manager.New(ctx, configMap, &initConfig)
if err != nil {
log.Fatalf("%v", err)
return fmt.Errorf("new manager: %w", err)
}
// Start the service manager, this will watch the config Map and construct kube-vip services for it
err = mgr.Start()
err = mgr.Start(ctx)
if err != nil {
log.Fatalf("%v", err)
return fmt.Errorf("manager start: %w", err)
}
return nil
},
}
var kubeVipManager = &cobra.Command{
Use: "manager",
Short: "Start the kube-vip manager",
Run: func(cmd *cobra.Command, args []string) {
// Set the logging level for all subsequent functions
log.SetLevel(log.Level(logLevel))
RunE: func(cmd *cobra.Command, args []string) error { //nolint TODO
cmd.SilenceUsage = true
go servePrometheusHTTPServer(cmd.Context(), PrometheusHTTPServerConfig{
Addr: initConfig.PrometheusHTTPServer,
})
// Load configuration from file if specified (lowest priority)
if initConfig.ConfigFile != "" {
err := kubevip.MergeConfigFromFile(&initConfig, initConfig.ConfigFile)
if err != nil {
return fmt.Errorf("loading config file: %w", err)
}
}
// parse environment variables, these will overwrite anything loaded or flags
// parse environment variables, these will overwrite anything loaded from config file
err := kubevip.ParseEnvironment(&initConfig)
if err != nil {
log.Fatalln(err)
return fmt.Errorf("parsing environment: %w", err)
}
if err := initConfig.Validate(); err != nil {
return fmt.Errorf("validating configuration: %w", err)
}
// Change RTN_UNSPEC to default type
if initConfig.RoutingProtocol == unix.RTN_UNSPEC {
initConfig.RoutingProtocol = unix.RTN_UNICAST
}
// Set the logging level for all subsequent functions
log.SetLogLoggerLevel(log.Level(initConfig.Logging))
// Legacy vip_address requires vip_subnet for control-plane ARP, BGP, and Routing Table modes.
if initConfig.EnableControlPlane &&
(initConfig.EnableARP || initConfig.EnableBGP || initConfig.EnableRoutingTable) {
if err := initConfig.CheckSubnetExists(); err != nil {
return fmt.Errorf("checking subnet exists if vip_address defined: %w", err)
}
}
// Ensure there is an address to generate the CIDR from
if initConfig.VIPSubnet == "" && initConfig.Address != "" {
initConfig.VIPSubnet, err = GenerateCidrRange(initConfig.Address, initConfig.DNSMode)
if err != nil {
return fmt.Errorf("generating CIDR: %w", err)
}
}
// Welome messages
log.Info("kube-vip.io", "version", Release.Version, "build", Release.Build)
wg := sync.WaitGroup{}
defer wg.Wait()
// create main manager context
ctx, cancel := context.WithCancelCause(cmd.Context())
defer cancel(nil)
// start prometheus server
if initConfig.PrometheusHTTPServer != "" {
wg.Go(func() {
servePrometheusHTTPServer(ctx, PrometheusHTTPServerConfig{
Addr: initConfig.PrometheusHTTPServer,
})
})
}
// Determine the kube-vip mode
var (
mode string
modesEnabled int
)
if initConfig.EnableARP {
mode = "ARP"
modesEnabled++
}
if initConfig.EnableBGP {
mode = "BGP"
modesEnabled++
}
if initConfig.EnableWireguard {
mode = "Wireguard"
modesEnabled++
}
if initConfig.EnableRoutingTable {
mode = "Routing Table"
modesEnabled++
}
if mode == "" {
return fmt.Errorf("no valid kube-vip mode detected, ensure a supported mode is configured")
}
if modesEnabled > 1 {
return fmt.Errorf("multiple kube-vip modes detected, ensure only one mode is configured")
}
// Provide configuration to output/logging
log.Info("starting", "namespace", initConfig.Namespace, "Mode", mode, "Control Plane", initConfig.EnableControlPlane, "Services", initConfig.EnableServices)
// End if nothing is enabled
if !initConfig.EnableServices && !initConfig.EnableControlPlane {
return fmt.Errorf("no features are enabled")
}
if !initConfig.EnableARP && strings.Contains(initConfig.VIPSubnet, kubevip.Auto) {
return fmt.Errorf("auto subnet discovery cannot be used outside ARP mode")
}
if strings.Contains(initConfig.VIPSubnet, kubevip.Auto) && initConfig.Address != "" {
return fmt.Errorf("auto subnet discovery cannot be used if VIP address was provided")
}
// If we're using wireguard then all traffic goes through the wg0 interface
if initConfig.EnableWireguard {
if initConfig.Interface == "" {
// Set the vip interface to the wireguard interface
initConfig.Interface = "wg0"
}
log.Info("configuring Wireguard networking")
l, err := netlink.LinkByName(initConfig.Interface)
if err != nil {
if strings.Contains(err.Error(), "Link not found") {
log.Warn("attempting to create wireguard interface", "interface not found", initConfig.Interface)
err = netlink.LinkAdd(&netlink.Wireguard{LinkAttrs: netlink.LinkAttrs{Name: initConfig.Interface}})
if err != nil {
return fmt.Errorf("adding link: %w", err)
}
l, err = netlink.LinkByName(initConfig.Interface)
if err != nil {
return fmt.Errorf("finding link: %w", err)
}
}
}
err = netlink.LinkSetUp(l)
if err != nil {
return fmt.Errorf("setting link UP: %w", err)
}
} else { // if we're not using Wireguard then we'll need to use an actual interface
// Check if the interface needs auto-detecting
if initConfig.Interface == "" {
log.Info("No interface is specified for VIP in config, auto-detecting default Interface")
defaultIF, err := vip.GetDefaultGatewayInterface()
if err != nil {
_ = cmd.Help()
return fmt.Errorf("detecting interface: %w", err)
}
initConfig.Interface = defaultIF.Name
log.Info("kube-vip bind", "interface", initConfig.Interface)
wg.Go(func() {
if err := vip.MonitorDefaultInterface(ctx, defaultIF); err != nil {
log.Error("interface monitor", "err", err)
cancel(err)
}
})
}
}
// Perform a check on the state of the interface
if err := initConfig.CheckInterface(); err != nil {
return fmt.Errorf("checking interface: %w", err)
}
// User Environment variables as an option to make manifest clearer
@@ -221,34 +466,25 @@ var kubeVipManager = &cobra.Command{
configMap = envConfigMap
}
// If Packet is enabled and there is a provider configuration passed
if initConfig.EnableMetal {
if providerConfig != "" {
providerAPI, providerProject, err := packet.GetPacketConfig(providerConfig)
if err != nil {
log.Fatalf("%v", err)
}
initConfig.MetalAPIKey = providerAPI
initConfig.MetalProject = providerProject
}
}
// Define the new service manager
mgr, err := manager.New(configMap, &initConfig)
mgr, err := manager.New(ctx, configMap, &initConfig)
if err != nil {
log.Fatalf("%v", err)
return fmt.Errorf("new manager: %w", err)
}
prometheus.MustRegister(mgr.PrometheusCollector()...)
metrics.RegisterPrometheusMetrics()
metrics.BuildInfo.WithLabelValues(Release.Version, Release.Build, initConfig.NodeName)
// Start the service manager, this will watch the config Map and construct kube-vip services for it
err = mgr.Start()
err = mgr.Start(ctx)
if err != nil {
log.Fatalf("%v", err)
return fmt.Errorf("start manager: %w", err)
}
return nil
},
}
// PrometheusHTTPServerConfig defines the Prometheus server configuration.
type PrometheusHTTPServerConfig struct {
// Addr sets the http server address used to expose the metric endpoint
Addr string
@@ -258,35 +494,86 @@ func servePrometheusHTTPServer(ctx context.Context, config PrometheusHTTPServerC
var err error
mux := http.NewServeMux()
mux.Handle("/metrics", promhttp.Handler())
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { //nolint TODO
_, _ = w.Write([]byte(`<html>
<head><title>kube-vip</title></head>
<body>
<h1>kube-vip Metrics</h1>
<p><a href="` + "/metrics" + `">Metrics</a></p>
</body>
</html>`))
})
srv := &http.Server{
Addr: config.Addr,
Handler: mux,
Addr: config.Addr,
Handler: mux,
ReadHeaderTimeout: 2 * time.Second,
}
go func() {
if err = srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
log.Fatalf("listen:%+s\n", err)
}
}()
wg := sync.WaitGroup{}
log.Printf("server started")
wg.Go(func() {
if err = srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
log.Error("prometheus HTTP server", "err", err)
return
}
})
log.Info("prometheus HTTP server started")
<-ctx.Done()
log.Printf("server stopped")
// create prometheus shutdown context (independent of other contexts)
ctxShutDown, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer func() {
cancel()
}()
if err = srv.Shutdown(ctxShutDown); err != nil {
log.Fatalf("server Shutdown Failed:%+s", err)
log.Error("shutting down prometheus HTTP server", "err", err)
return
}
if err == http.ErrServerClosed {
err = nil
}
log.Info("prometheus HTTP server stopped")
wg.Wait()
}
func GenerateCidrRange(address string, dnsMode string) (string, error) {
var cidrs []string
addresses := strings.Split(address, ",")
for _, a := range addresses {
ip := net.ParseIP(a)
if ip == nil {
// we probably are a DNS name
ips, err := utils.LookupHost(a, dnsMode, true)
if len(ips) == 0 || err != nil {
return "", fmt.Errorf("invalid IP address: %s from [%s], %v", a, address, err)
}
for _, addr := range ips {
ip = net.ParseIP(addr)
if ip.To4() != nil {
cidrs = append(cidrs, strconv.Itoa(vip.DefaultMaskIPv4))
} else {
cidrs = append(cidrs, strconv.Itoa(vip.DefaultMaskIPv6))
}
}
} else {
if ip.To4() != nil {
cidrs = append(cidrs, strconv.Itoa(vip.DefaultMaskIPv4))
} else {
cidrs = append(cidrs, strconv.Itoa(vip.DefaultMaskIPv6))
}
}
}
// compact as DNS could have a lot of addresses
slices.Sort(cidrs)
cidrs = slices.Compact(cidrs)
slices.Reverse(cidrs)
return strings.Join(cidrs, ","), nil
}

46
demo/README.md Normal file
View File

@@ -0,0 +1,46 @@
# Demo client-server
This contains some example code to determine how long "failovers" are taking within kube-vip, the server component should live within the cluster and the client should be externally.
## Deploy the server
Simply apply the manifest to a working cluster that has kube-vip deployed:
```
kubectl apply -f ./demo/server/deploy.yaml
```
Retrieve the loadBalancer IP that is fronting the service:
```
kubectl get svc demo-service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
demo-service LoadBalancer 10.104.18.147 192.168.0.217 10002:32529/UDP 117m
```
## Connect the client
From elsewhere, clone the kube-vip repository and connect the client to the server endpoint (loadBalancer IP) with the following command:
```
go run ./demo/client/main.go -address=<vip>
```
You will only see output when the client has reconcilled the connection to a pod beneath the service, where it will print the timestamp to reconnection along with the time in milliseconds it took:
```
15:58:35.916952 3008
15:58:45.947506 2005
15:58:57.983151 3007
15:59:08.013450 2005
15:59:20.046491 3008
15:59:30.076341 2507
15:59:42.110747 3008
```
## Kill some pods to test
On a machine or control plane that has `kubectl` and has the credentials to speak to the cluster we will run a command to find the demo pod and kill it every 10 seconds:
`while true ; do kubectl delete pod $(kubectl get pods | grep -v NAME | grep vip| awk '{ print $1 }'); sleep 10; done`

71
demo/client/main.go Normal file
View File

@@ -0,0 +1,71 @@
package main
import (
"bufio"
"flag"
"fmt"
"net"
"time"
)
const udpdata = "a3ViZS12aXAK=kube-vip"
func main() {
address := flag.String("address", "127.0.0.1", "The address of the server")
port := flag.Int("port", 10002, "the port of the server")
interval := flag.Float64("interval", 1000, "Interval in milliseconds")
flag.Parse()
var errorTime time.Time
var errorOccurred bool
for {
p := make([]byte, 2048)
conn, err := net.Dial("udp", net.JoinHostPort(*address, fmt.Sprint(port)))
if err != nil {
if !errorOccurred {
errorTime = time.Now()
errorOccurred = true
}
continue
}
err = conn.SetDeadline(time.Now().Add(time.Duration(*interval) * time.Millisecond))
if err != nil {
//fmt.Printf("Connectivity error [%v]", err)
if !errorOccurred {
errorTime = time.Now()
errorOccurred = true
}
if err = conn.Close(); err != nil {
fmt.Printf("Error closing connection [%v]", err)
}
continue
}
_, err = fmt.Fprint(conn, udpdata)
if err != nil {
fmt.Printf("Error writing data [%v]", err)
}
_, err = bufio.NewReader(conn).Read(p)
if err != nil {
//fmt.Printf("read error %v\n", err)
if !errorOccurred {
errorTime = time.Now()
errorOccurred = true
}
if err = conn.Close(); err != nil {
fmt.Printf("Error closing connection [%v]", err)
}
continue
}
time.Sleep(time.Duration(*interval) * time.Millisecond)
if errorOccurred {
finishTime := time.Since(errorTime)
//fmt.Printf("connectivity reconciled in %dms\n", finishTime.Milliseconds())
//t :=time.Now().Format("15:04:05.000000")
fmt.Printf("%s %d\n", time.Now().Format("15:04:05.000000"), finishTime.Milliseconds())
errorOccurred = false
}
}
}

View File

@@ -1,6 +1,6 @@
# syntax=docker/dockerfile:experimental
FROM golang:1.13-alpine as dev
FROM golang:1.19-alpine as dev
RUN apk add --no-cache git ca-certificates
RUN adduser -D appuser
COPY main.go /src/
@@ -13,4 +13,4 @@ RUN --mount=type=cache,sharing=locked,id=gomod,target=/go/pkg/mod/cache \
FROM scratch
COPY --from=dev /src/demo /
CMD ["/demo"]
CMD ["/demo"]

View File

@@ -45,7 +45,7 @@ fmt:
@gofmt -l -w $(SRC)
docker:
@docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v7,linux/ppc64le --push -t $(REPOSITORY)/$(TARGET):$(DOCKERTAG) .
@docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v7,linux/ppc64le,linux/s390x --push -t $(REPOSITORY)/$(TARGET):$(DOCKERTAG) .
@echo New Multi Architecture Docker image created
simplify:

View File

@@ -6,7 +6,7 @@ metadata:
app: kube-vip-demo
name: kube-vip-demo
spec:
replicas: 3
replicas: 1
selector:
matchLabels:
app: kube-vip-demo
@@ -30,4 +30,25 @@ spec:
ports:
- containerPort: 10001
- containerPort: 10002
status: {}
status: {}
---
apiVersion: v1
kind: Service
metadata:
name: demo-service
namespace: default
labels:
app: demo-service
annotations:
kube-vip.io/egress: "true"
spec:
type: LoadBalancer
# "Local" preserves the client source IP and avoids a second hop for
# LoadBalancer and NodePort
externalTrafficPolicy: Local
ports:
- name: demo-udp
port: 10002
protocol: UDP
selector:
app: kube-vip-demo

View File

@@ -32,7 +32,7 @@ func main() {
}
}
if serverType == strings.ToLower("udp") {
if serverType == "udp" {
// Start the UDP echo server
ServerAddr, err := net.ResolveUDPAddr("udp", ":10002")

View File

@@ -1,5 +0,0 @@
FROM nginx:latest
RUN apt-get update; apt-get install -y nodejs npm; npm install -g markdown-styles;
COPY . /docs
WORKDIR /docs
RUN generate-md --layout github --input ./ --output /usr/share/nginx/html/

View File

@@ -1,135 +0,0 @@
# **kube-vip** architecture
This section covers two parts of the architecture:
1. The technical capabilities of `kube-vip`
2. The components to build a load-balancing service within [Kubernetes](https://kubernetes.io)
The `kube-vip` project is designed to provide both a highly available networking endpoint and load-balancing functionality for underlying networking services. The project was originally designed for the purpose of providing a resilient control-plane for Kubernetes, it has since expanded to provide the same functionality for applications within a Kubernetes cluster.
Additionally `kube-vip` is designed to be lightweight and **multi-architecture**, all of the components are built for Linux but are also built for both `x86` and `armv7`,`armhvf`,`ppc64le`. This means that `kube-vip` will run fine in **bare-metal**, **virtual** and **edge** (raspberry pi or small arm SoC devices).
## Technologies
There are a number of technologies or functional design choices that provide high-availability or networking functions as part of a VIP/Load-balancing solution.
### Cluster
The `kube-vip` service builds a multi-node or multi-pod cluster to provide High-Availability. In ARP mode a leader is elected, this node will inherit the Virtual IP and become the leader of the load-balancing within the cluster, whereas with BGP all nodes will advertise the VIP address.
When using ARP or layer2 it will use [leader election](https://godoc.org/k8s.io/client-go/tools/leaderelection)
It is also possible to use [raft](https://en.wikipedia.org/wiki/Raft_(computer_science) clustering technology, but this approach has largely been superseded by leader election especially when running in cluster.
### Virtual IP
The leader within the cluster will assume the **vip** and will have it bound to the selected interface that is declared within the configuration. When the leader changes it will evacuate the **vip** first or in failure scenarios the **vip** will be directly assumed by the next elected leader.
When the **vip** moves from one host to another any host that has been using the **vip** will retain the previous `vip <-> MAC address` mapping until the ARP (Address resolution protocol) expires the old entry (typically 30 seconds) and retrieves a new `vip <-> MAC` mapping. This can be improved using Gratuitous ARP broadcasts (when enabled), this is detailed below.
### ARP
(Optional) The `kube-vip` can be configured to broadcast a [gratuitous arp](https://wiki.wireshark.org/Gratuitous_ARP) that will typically immediately notify all local hosts that the `vip <-> MAC` has changed.
**Below** we can see that the failover is typically done within a few seconds as the ARP broadcast is recieved.
```
64 bytes from 192.168.0.75: icmp_seq=146 ttl=64 time=0.258 ms
64 bytes from 192.168.0.75: icmp_seq=147 ttl=64 time=0.240 ms
92 bytes from 192.168.0.70: Redirect Host(New addr: 192.168.0.75)
Vr HL TOS Len ID Flg off TTL Pro cks Src Dst
4 5 00 0054 bc98 0 0000 3f 01 3d16 192.168.0.95 192.168.0.75
Request timeout for icmp_seq 148
92 bytes from 192.168.0.70: Redirect Host(New addr: 192.168.0.75)
Vr HL TOS Len ID Flg off TTL Pro cks Src Dst
4 5 00 0054 75ff 0 0000 3f 01 83af 192.168.0.95 192.168.0.75
Request timeout for icmp_seq 149
92 bytes from 192.168.0.70: Redirect Host(New addr: 192.168.0.75)
Vr HL TOS Len ID Flg off TTL Pro cks Src Dst
4 5 00 0054 2890 0 0000 3f 01 d11e 192.168.0.95 192.168.0.75
Request timeout for icmp_seq 150
64 bytes from 192.168.0.75: icmp_seq=151 ttl=64 time=0.245 ms
```
### Load Balancing
Within a Kubernetes cluster, the load-balancing is managed by the `plndr-cloud-provider` which watches all service that are created, and for those of `type=LoadBalancer` will create the configuration for `kube-vip` to consume.
#### Load Balancing (Inside a cluster)
When using `type=LoadBalancer` within a Kubernetes cluster `kube-vip` will assign the VIP to the leader (when using ARP) or to all running Pods (when using BGP). When traffic is directed to a node with the VIP then the rules configured by `kube-proxy` will redirect the traffic to one of the pods running in the service.
#### Load Balancing (Outside a cluster)
Within the configuration of `kube-vip` multiple load-balancers can be created, below is the example load-balancer for a Kubernetes Control-plane:
```
loadBalancers:
- name: Kubernetes Control Plane
type: tcp
port: 6443
bindToVip: true
backends:
- port: 6444
address: 192.168.0.70
- port: 6444
address: 192.168.0.71
- port: 6444
address: 192.168.0.72
```
The above load balancer will create an instance that listens on port `6443` and will forward traffic to the array of backend addresses. If the load-balancer type is `tcp` then the backends will be IP addresses, however if the backend is set to `http` then the backends should be URLs:
```
type: http
port: 6443
bindToVip: true
backends:
- port: 6444
address: https://192.168.0.70
```
Additionally the load-balancing within `kibe-vip` has two modes of operation:
`bindToVip: false` - will result in every node in the cluster binding all load-balancer port(s) to all interfaces on the host itself
`bindToVip: true` - The load-balancer will only **bind** to the VIP address.
## Components within a Kubernetes Cluster
The `kube-vip` kubernetes load-balancer requires a number of components in order to function:
- The Plunder Cloud Provider -> [https://github.com/kube-vip/plndr-cloud-provider](https://github.com/kube-vip/plndr-cloud-provider)
- The Kube-Vip Deployment -> [https://github.com/kube-vip/kube-vip](https://github.com/kube-vip/kube-vip)
### Architecture overview
![kubernetes-vip-architecture.png](kubernetes-vip-architecture.png)
### Plunder Cloud Provider
The cloud provider works like all Kubernetes cloud providers and is built using the Kubernetes cloud-provider SDK. It's role is to provide the same cloud "like" services one would expect from services such as AWS / Azure / GCP etc.. in that when a user requests functionality then the cloud provider can speak natively to the underlying vendor and provision the required service
e.g. _In AWS when requesting a Kubernetes LoadBalancer, the cloud provider will provision an **ELB**_
The `Plunder cloud Provider` is *currently* only designed to intercept the creation of LoadBalancers and translate that into a `kube-vip` load balancer.
It is configured by a `configMap` within the `kube-system` namespace that contains the ranges of addresses that the other `kube-vip` load-balancers can use, it will also manage the allocation of addresses and then build the configMap configurations in these namespaces for consumption by `kube-vip`. The IP addresses for each namespace should be in the structure `cidr-<namespace>` followed by the cidr range for the address pool.
**Example `ConfigMap`**
```
apiVersion: v1
kind: ConfigMap
metadata:
name: plndr
namespace: kube-system
data:
cidr-default: 192.168.0.200/29
cidr-plunder: 192.168.0.210/29
cidr-testing: 192.168.0.220/29
```

Binary file not shown.

Before

Width:  |  Height:  |  Size: 67 KiB

View File

@@ -1,147 +0,0 @@
# Load Balancing a Kubernetes Cluster (Control-Plane) (pre 0.1.5)
This document covers all of the details for using `kube-vip` to build a HA Kubernetes cluster
`tl;dr version`
- Generate/modify first node `kube-vip` config/manifest
- `init` first node
- `join` remaining nodes
- Add remaining config/manifests
## Infrastructure architecture
The infrastructure for our example HA Kubernetes cluster is as follows:
| Node | Address |
|----------------|------------|
| VIP | 10.0.0.75 |
| controlPlane01 | 10.0.0.70 |
| controlPlane02 | 10.0.0.71 |
| controlPlane03 | 10.0.0.72 |
All nodes are running Ubuntu 18.04, Docker CE and will use Kubernetes 1.17.0.
### Generate the `kube-vip` configuration
Make sure that the config directory exists: `sudo mkdir -p /etc/kube-vip/`, this directory can be any directory however the `hostPath` in the manifest will need modifying to point to the correct path.
```
sudo docker run -it --rm plndr/kube-vip:0.1 /kube-vip sample config | sudo tee /etc/kube-vip/config.yaml
```
### Modify the configuration
**Cluster Configuration**
Modify the `remotePeers` to point to the correct addresses of the other two nodes, ensure that their `id` is unique otherwise this will confuse the raft algorithm. The `localPeer` should be the configuration of the current node (`controlPlane01`), which is where this instance of the cluster will run.
As this node will be the first node, it will need to elect itself leader as until this occurs the VIP wont be activated!
`startAsLeader: true`
**VIP Config**
We will need to set our VIP address to `192.168.0.75` and to ensure all hosts are updated when the VIP moves we will enable ARP broadcasts `gratuitousARP: true`
**Load Balancer**
We will configure the load balancer to sit on the standard API-Server port `6443` and we will configure the backends to point to the API-servers that will be configured to run on port `6444`. Also for the Kubernetes Control Plane we will configure the load balancer to be of `type: tcp`.
We can also use `6443` for both the VIP and the API-Servers, in order to do this we need to specify that the api-server is bound to it's local IP. To do this we use the `--apiserver-advertise-address` flag as part of the `init`, this means that we can then bind the same port to the VIP and we wont have a port conflict.
**config.yaml**
`user@controlPlane01:/etc/kube-vip$ cat config.yaml`
...
```
remotePeers:
- id: server2
address: 192.168.0.71
port: 10000
- id: server3
address: 192.168.0.72
port: 10000
localPeer:
id: server1
address: 192.168.0.70
port: 10000
vip: 192.168.0.75
gratuitousARP: true
singleNode: false
startAsLeader: true
interface: ens192
loadBalancers:
- name: Kubernetes Control Plane
type: tcp
port: 6443
bindToVip: true
backends:
- port: 6444
address: 192.168.0.70
- port: 6444
address: 192.168.0.71
- port: 6444
address: 192.168.0.72
```
### First Node
To generate the basic Kubernetes static pod `yaml` configuration:
Make sure that the manifest directory exists: `sudo mkdir -p /etc/kubernetes/manifests/`
```
sudo docker run -it --rm plndr/kube-vip:0.1 /kube-vip sample manifest | sudo tee /etc/kubernetes/manifests/kube-vip.yaml
```
Ensure that `image: plndr/kube-vip:<x>` is modified to point to a specific version (`0.1` at the time of writing), refer to [docker hub](https://hub.docker.com/r/plndr/kube-vip/tags) for details. Also ensure that the `hostPath` points to the correct `kube-vip` configuration, if it isnt the above path.
The **vip** is set to `192.168.0.75` and this first node will elect itself as leader, and as part of the `kubeadm init` it will use the VIP in order to speak back to the initialising api-server.
`sudo kubeadm init --control-plane-endpoint “192.168.0.75:6443” --apiserver-bind-port 6444 --upload-certs --kubernetes-version “v1.17.0”`
Once this node is up and running we will be able to see the control-plane pods, including the `kube-vip` pod:
```
$ kubectl get pods -A
NAMESPACE NAME READY STATUS RESTARTS AGE
<...>
kube-system kube-vip-controlplane01 1/1 Running 0 10m
```
### Remaining Nodes
We first will need to create the `kube-vip` configuration that resides in `/etc/kube-vip/config.yaml` or we can regenerate it from scratch using the above example. Ensure that the configuration is almost identical with the `localPeer` and `remotePeers` sections are updated for each node. Finally, ensure that the remaining nodes will behave as standard cluster nodes by setting `startAsLeader: false`.
At this point **DONT** generate the manifests, this is due to some bizarre `kubeadm/kubelet` behaviour.
```
kubeadm join 192.168.0.75:6443 --token <tkn> \
--discovery-token-ca-cert-hash sha256:<hash> \
--control-plane --certificate-key <key>
```
**After** this node has been added to the cluster, we can add the manifest to also add this node as a `kube-vip` member. (Adding the manifest afterwards doesnt interfere with `kubeadm`).
```
sudo docker run -it --rm plndr/kube-vip:0.1 /kube-vip sample manifest | sudo tee /etc/kubernetes/manifests/kube-vip.yaml
```
Once this node is added we will be able to see that the `kube-vip` pod is up and running as expected:
```
user@controlPlane01:~$ kubectl get pods -A | grep vip
kube-system kube-vip-controlplane01 1/1 Running 1 16m
kube-system kube-vip-controlplane02 1/1 Running 0 18m
kube-system kube-vip-controlplane03 1/1 Running 0 20m
```
If we look at the logs, we can see that the VIP is running on the second node and were waiting for our third node to join the cluster:
```
$ kubectl logs kube-vip-controlplane02 -n kube-system
time=“2020-02-12T15:33:09Z” level=info msg=“The Node [192.168.0.70:10000] is leading”
time=“2020-02-12T15:33:09Z” level=info msg=“The Node [192.168.0.70:10000] is leading”
```

View File

@@ -1,195 +0,0 @@
# Load Balancing a Kubernetes Cluster (Control-Plane)
This document covers the newer (post `0.1.5`) method for using `kube-vip` to provide HA for a Kubernetes Cluster. The documentation for older releases can be found [here](./0.1.4/)
This document covers all of the details for using `kube-vip` to build a HA Kubernetes cluster
`tl;dr version`
- Generate/modify first node `kube-vip` config/manifest
- `init` first node
- `join` remaining nodes
- Add remaining config/manifests
Below are examples of the steps required:
```
# First Node
sudo docker run --network host --rm plndr/kube-vip:0.1.5 kubeadm init --interface ens192 --vip 192.168.0.81 --startAsLeader=true | sudo tee /etc/kubernetes/manifests/vip.yaml
sudo kubeadm init --kubernetes-version 1.17.0 --control-plane-endpoint 192.168.0.81 --upload-certs
# Additional Node(s)
sudo kubeadm join 192.168.0.81:6443 --token w5atsr.blahblahblah --control-plane --certificate-key abc123
sudo docker run -v /etc/kubernetes/admin.conf:/etc/kubernetes/admin.conf --network host --rm plndr/kube-vip:0.1.5 kubeadm join --interface ens192 --vip 192.168.0.81 --startAsLeader=false | sudo tee /etc/kubernetes/manifests/vip.yaml
```
## Infrastructure architecture
The infrastructure for our example HA Kubernetes cluster is as follows:
| Node | Address |
|----------------|------------|
| VIP | 10.0.0.75 |
| controlPlane01 | 10.0.0.70 |
| controlPlane02 | 10.0.0.71 |
| controlPlane03 | 10.0.0.72 |
All nodes are running Ubuntu 18.04, Docker CE and will use Kubernetes 1.17.0.
### Generate the `kube-vip` configuration
Kube-Vip no longer requires storing it's configuration in a seperate directory and will now store its configuration in the actual manifest that defines the static pods.
```
sudo docker run --network host \
--rm plndr/kube-vip:0.1.5 \
kubeadm init \
--interface ens192 \
--vip 192.168.0.75 \
--startAsLeader=true | sudo tee /etc/kubernetes/manifests/vip.yaml
```
The above command will "initialise" the manifest within the `/etc/kubernetes/manifests` directory, that will be started when we actually initialise our Kubernetes cluster with `kubeadm init`
### Modify the configuration
**Cluster Configuration**
As this node will be the first node, it will need to elect itself leader as until this occurs the VIP wont be activated!
`--startAsLeader=true`
**VIP Config**
We will need to set our VIP address to `192.168.0.75` with `--vip 192.168.0.75` and to ensure all hosts are updated when the VIP moves we will enable ARP broadcasts `--arp` (defaults to `true`)
**Load Balancer**
We will configure the load balancer to sit on the standard API-Server port `6443` and we will configure the backends to point to the API-servers that will be configured to run on port `6444`. Also for the Kubernetes Control Plane we will configure the load balancer to be of `type: tcp`.
We can also use `6443` for both the VIP and the API-Servers, in order to do this we need to specify that the api-server is bound to it's local IP. To do this we use the `--apiserver-advertise-address` flag as part of the `init`, this means that we can then bind the same port to the VIP and we wont have a port conflict.
**vip.yaml** Static-pod Manifest
`$ sudo cat /etc/kubernetes/manifests/vip.yaml`
```
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
name: kube-vip
namespace: kube-system
spec:
containers:
- args:
- start
env:
- name: vip_arp
value: "true"
- name: vip_interface
value: ens192
- name: vip_address
value: 192.168.0.81
- name: vip_startleader
value: "true"
- name: vip_addpeerstolb
value: "true"
- name: vip_localpeer
value: controlPlane01:192.168.0.70:10000
- name: lb_backendport
value: "6443"
- name: lb_name
value: Kubeadm Load Balancer
- name: lb_type
value: tcp
- name: lb_bindtovip
value: "true"
image: plndr/kube-vip:0.1.5
imagePullPolicy: Always
name: kube-vip
resources: {}
securityContext:
capabilities:
add:
- NET_ADMIN
- SYS_TIME
hostNetwork: true
status: {}
```
### First Node
To generate the basic Kubernetes static pod `yaml` configuration:
Make sure that the manifest directory exists: `sudo mkdir -p /etc/kubernetes/manifests/`
```
sudo docker run --network host \
--rm plndr/kube-vip:0.1.5 \
kubeadm init \
--interface ens192 \
--vip 192.168.0.75 \
--startAsLeader=true | sudo tee /etc/kubernetes/manifests/vip.yaml
```
Ensure that `image: plndr/kube-vip:<x>` is modified to point to a specific version (`0.1.5` at the time of writing), refer to [docker hub](https://hub.docker.com/r/plndr/kube-vip/tags) for details.
The **vip** is set to `192.168.0.75` and this first node will elect itself as leader, and as part of the `kubeadm init` it will use the VIP in order to speak back to the initialising api-server.
`sudo kubeadm init --control-plane-endpoint “192.168.0.75:6443” --apiserver-bind-port 6444 --upload-certs --kubernetes-version “v1.17.0”`
Once this node is up and running we will be able to see the control-plane pods, including the `kube-vip` pod:
```
$ kubectl get pods -A
NAMESPACE NAME READY STATUS RESTARTS AGE
<...>
kube-system kube-vip-controlplane01 1/1 Running 0 10m
```
### Remaining Nodes
At this point **DONT** generate the manifests, this is due to some bizarre `kubeadm/kubelet` behaviour.
```
kubeadm join 192.168.0.75:6443 --token <tkn> \
--discovery-token-ca-cert-hash sha256:<hash> \
--control-plane --certificate-key <key>
```
**After** this node has been added to the cluster, we can add the manifest to also add this node as a `kube-vip` member. (Adding the manifest afterwards doesnt interfere with `kubeadm`).
```
sudo docker run \
-v /etc/kubernetes/admin.conf:/etc/kubernetes/admin.conf \
--network host \
--rm plndr/kube-vip:0.1.5 \
kubeadm join \
--interface ens192 \
--vip 192.168.0.81 \
--startAsLeader=false | sudo tee /etc/kubernetes/manifests/vip.yaml
```
Once this node is added we will be able to see that the `kube-vip` pod is up and running as expected:
```
user@controlPlane01:~$ kubectl get pods -A | grep vip
kube-system kube-vip-controlplane01 1/1 Running 1 16m
kube-system kube-vip-controlplane02 1/1 Running 0 18m
kube-system kube-vip-controlplane03 1/1 Running 0 20m
```
If we look at the logs, we can see that the VIP is running on the second node and were waiting for our third node to join the cluster:
```
$ kubectl logs kube-vip-controlplane02 -n kube-system
time=“2020-02-12T15:33:09Z” level=info msg=“The Node [192.168.0.70:10000] is leading”
time=“2020-02-12T15:33:09Z” level=info msg=“The Node [192.168.0.70:10000] is leading”
```

View File

@@ -1,421 +0,0 @@
# Load Balancing a Kubernetes Cluster (Control-Plane)
**Note**: The most common deployment currently for HA Kubernetes clusters w/`kube-vip` involved `kubeadm`, however recently we've worked to bring a method of bringing `kube-vip` to other types of Kubernetes cluster. Typically this deployment method makes use of a daemonset that is usually brought up during the cluster instantiation.. So for those wanting to deploy [k3s](https://k3s.io), we now have installation steps available [here](https://kube-vip.io/control-plane/#k3s),
This document covers the newer (post `0.1.6`) method for using `kube-vip` to provide HA for a Kubernetes Cluster. The documentation for older releases can be found [here](./0.1.5/)
From version `0.1.6` we've moved `kube-vip` from raft to leaderElection within the Kubernetes cluster. After a lot of testing it became clear that the leaderElection gave quicker reconciliation when removing nodes etc.. during upgrades and failures.
For **more** configuration around LeaderElection click [here](https://kube-vip.io/control-plane/#leaderelection-configuration).
This document covers all of the details for using `kube-vip` to build a HA Kubernetes cluster
`tl;dr version`
- Generate/modify first node `kube-vip` config/manifest
- `init` first node
- `join` remaining nodes
- Add remaining config/manifests
Below are examples of the steps required:
```
# First Node
sudo docker run --network host --rm plndr/kube-vip:0.2.1 manifest pod \
--interface ens192 \
--vip 192.168.0.75 \
--arp \
--leaderElection | sudo tee /etc/kubernetes/manifests/vip.yaml
sudo kubeadm init --kubernetes-version 1.17.0 --control-plane-endpoint 192.168.0.75 --upload-certs
# Additional Node(s)
sudo kubeadm join 192.168.0.75:6443 --token w5atsr.blahblahblah --control-plane --certificate-key abc123
sudo docker run --network host --rm plndr/kube-vip:0.2.1 manifest pod \
--interface ens192 \
--vip 192.168.0.75 \
--arp \
--leaderElection | sudo tee /etc/kubernetes/manifests/vip.yaml
```
## Infrastructure architecture
The infrastructure for our example HA Kubernetes cluster is as follows:
| Node | Address |
|----------------|------------|
| VIP | 10.0.0.75 |
| controlPlane01 | 10.0.0.70 |
| controlPlane02 | 10.0.0.71 |
| controlPlane03 | 10.0.0.72 |
All nodes are running Ubuntu 18.04, Docker CE and will use Kubernetes 1.17.0.
### Generate the `kube-vip` configuration
`kube-vip` no longer requires storing its configuration in a separate directory and will now store its configuration in the actual manifest that defines the static pods.
```
sudo docker run --network host \
--rm plndr/kube-vip:0.2.1 \
manifest pod \
--interface ens192 \
--vip 192.168.0.75 \
--arp \
--leaderElection | sudo tee /etc/kubernetes/manifests/vip.yaml
```
The above command will "initialise" the manifest within the `/etc/kubernetes/manifests` directory, that will be started when we actually initialise our Kubernetes cluster with `kubeadm init`
### Modify the configuration
**Cluster Configuration**
To enable Kubernetes leader Election passing the `--leaderElection` flag will enable `kube-vip` to use the Kubernetes leaderElection functionality to work out which member is the leader.
**VIP Config**
We will need to set our VIP address to `192.168.0.75` with `--vip 192.168.0.75` and to ensure all hosts are updated when the VIP moves we will enable ARP broadcasts `--arp` (defaults to `true`)
**vip.yaml** Static-pod Manifest
`$ sudo cat /etc/kubernetes/manifests/vip.yaml`
```
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
name: kube-vip
namespace: kube-system
spec:
containers:
- args:
- start
env:
- name: vip_arp
value: "true"
- name: vip_interface
value: ens160
- name: vip_leaderelection
value: "true"
- name: vip_leaseduration
value: "5"
- name: vip_renewdeadline
value: "3"
- name: vip_retryperiod
value: "1"
- name: vip_address
value: 192.168.0.75
image: plndr/kube-vip:0.2.1
imagePullPolicy: Always
name: kube-vip
resources: {}
securityContext:
capabilities:
add:
- NET_ADMIN
- SYS_TIME
hostNetwork: true
status: {}
```
### First Node
To generate the basic Kubernetes static pod `yaml` configuration:
Make sure that the manifest directory exists: `sudo mkdir -p /etc/kubernetes/manifests/`
```
sudo docker run --network host \
--rm plndr/kube-vip:0.2.1 \
manifest pod \
--interface ens192 \
--vip 192.168.0.75 \
--arp \
--leaderElection | sudo tee /etc/kubernetes/manifests/vip.yaml
```
Ensure that `image: plndr/kube-vip:<x>` is modified to point to a specific version (`0.1.8` at the time of writing), refer to [docker hub](https://hub.docker.com/r/plndr/kube-vip/tags) for details.
The **vip** is set to `192.168.0.75` and this first node will elect itself as leader, and as part of the `kubeadm init` it will use the VIP in order to speak back to the initialising api-server.
`sudo kubeadm init --control-plane-endpoint “192.168.0.75:6443” --upload-certs --kubernetes-version “v1.17.0”`
Once this node is up and running we will be able to see the control-plane pods, including the `kube-vip` pod:
```
$ kubectl get pods -A
NAMESPACE NAME READY STATUS RESTARTS AGE
<...>
kube-system kube-vip-controlplane01 1/1 Running 0 10m
```
### Remaining Nodes
At this point **DONT** generate the manifests, this is due to some bizarre `kubeadm/kubelet` behaviour.
```
kubeadm join 192.168.0.75:6443 --token <tkn> \
--discovery-token-ca-cert-hash sha256:<hash> \
--control-plane --certificate-key <key>
```
**After** this node has been added to the cluster, we can add the manifest to also add this node as a `kube-vip` member. (Adding the manifest afterwards doesnt interfere with `kubeadm`).
```
sudo docker run --network host \
--rm plndr/kube-vip:0.2.1 \
manifest pod \
--interface ens192 \
--vip 192.168.0.75 \
--arp \
--leaderElection | sudo tee /etc/kubernetes/manifests/vip.yaml
```
Once this node is added we will be able to see that the `kube-vip` pod is up and running as expected:
```
user@controlPlane01:~$ kubectl get pods -A | grep vip
kube-system kube-vip-controlplane01 1/1 Running 1 16m
kube-system kube-vip-controlplane02 1/1 Running 0 18m
kube-system kube-vip-controlplane03 1/1 Running 0 20m
```
## DNS Support
### Static DNS Support (added in 0.2.0)
A new flag `--address` is introduced to support using a DNS record as the control plane endpoint. `kube-vip` will do a dns lookup to retrieve the IP for the DNS record, and use that IP as the VIP. An `dnsUpdater` periodically checks and updates the system if IP changes for the DNS record.
### Dynamic DNS Support (added in 0.2.1)
`kube-vip` was also updated to support DHCP + [Dynamic DNS](https://en.wikipedia.org/wiki/Dynamic_DNS), for the use case where it's not able to reserve a static IP for the control plane endpoint.
A new flag `--ddns` is introduced. Once enabled, `kube-vip` expects the input `--address` will be a FQDN without binding to an IP. Then `kube-vip` will start a dhcp client to allocate an IP for the hostname of FQDN, and maintain the lease for it.
Once DHCP returns an IP for the FQDN, the same `dnsUpdater` runs to periodically checks and updates if IP got changed.
## BGP Support (added in 0.1.8)
In version `0.1.8`+ `kube-vip` was updated to support [BGP](https://en.wikipedia.org/wiki/Border_Gateway_Protocol) as a VIP failover mechanism. When a node is elected as a leader then it will update it's peers so that they are aware to route traffic to that node in order to access the VIP.
The following new flags are used:
- `--bgp` This will enable BGP support within kube-vip
- `--localAS` The local AS number
- `--bgpRouterID` The local router address
- `--peerAS` The AS number for a BGP peer
- `--peerAddress` The address of a BGP peer
### BGP Packet support
If the `--bgp` flag is passed alone with the Packet flags `packet, packetKey and packetProject`, then the Packet API will be used in order to determine the BGP configuration for the nodes being used in the cluster. This automates a lot of the process and makes using BGP within Packet much simpler.
## Packet Support (added in 0.1.7)
Recently in version `0.1.7` of `kube-vip` we added the functionality to use a Packet Elastic IP as the virtual IP fronting the Kubernetes Control plane cluster. In order to first get out virtual IP we will need to use our Packet account and create a EIP (either public (eek) or private). We will only need a single address so a `/32` will suffice, once this is created as part of a Packet project we can now apply this address to the servers that live in the same project.
In this example we've logged into the UI can created a new EIP of `147.75.1.2`, and we've deployed three small server instances with Ubuntu.
The following new flags are used:
- `--packet` which enables the use of the Packet API
- `--packetKey` which is our API key
- `--packetProject`which is the name of our Packet project where our servers and EIP are located.
*Also* the `--arp` flag should NOT be used as it wont work within the Packet network.
### Variables
```
export EIP=1.1.1.1
export PACKET_AUTH_TOKEN=XYZ
```
### First node
```
# Generate the manifest
sudo docker run --network host --rm plndr/kube-vip:0.2.1 manifest pod \
--arp=false \
--interface lo \
--vip $EIP \
--leaderElection \
--packet \
--packetKey $PACKET_AUTH_TOKEN \
--packetProject vipTest | sudo tee /etc/kubernetes/manifests/vip.yaml\
# Init Kubernetes
sudo kubeadm init --kubernetes-version 1.18.5 --control-plane-endpoint $EIP --upload-certs
```
### Other nodes
```
# Join
kubeadm join $EIP:6443 --token BLAH --control-plane --certificate-key BLAH --discovery-token-ca-cert-hash sha:blah
# Generate Manifest
sudo docker run --network host --rm plndr/kube-vip:0.2.1 manifest pod \
--arp=false \
--interface lo \
--vip $EIP \
--leaderElection \
--packet \
--packetKey $PACKET_AUTH_TOKEN \
--packetProject vipTest | sudo tee /etc/kubernetes/manifests/vip.yaml\
```
The Elastic IP failover takes some time (30+ seconds) to move from a failed host to a new leader, so in this release it is mainly for testing.
## Upgrades
From above we have a 3 node cluster and the controlPlane01 is leader:
```
$ kubectl logs -n kube-system kube-vip-controlplane01 -f
time="2020-07-04T15:12:52Z" level=info msg="Beginning cluster membership, namespace [kube-system], lock name [plunder-lock], id [controlPlane01]"
I0704 15:12:52.290420 1 leaderelection.go:242] attempting to acquire leader lease kube-system/plunder-lock...
I0704 15:12:56.373113 1 leaderelection.go:252] successfully acquired lease kube-system/plunder-lock
time="2020-07-04T15:12:56Z" level=info msg="This node is assuming leadership of the cluster"
time="2020-07-04T15:12:56Z" level=error msg="This node is leader and is adopting the virtual IP"
time="2020-07-04T15:12:56Z" level=info msg="Starting TCP Load Balancer for service [192.168.0.81:0]"
time="2020-07-04T15:12:56Z" level=info msg="Load Balancer [Kubeadm Load Balancer] started"
time="2020-07-04T15:12:56Z" level=info msg="Broadcasting ARP update for 192.168.0.81 (00:50:56:a5:69:a1) via ens192"
time="2020-07-04T15:12:56Z" level=info msg="Starting TCP Load Balancer for service [192.168.0.81:0]"
time="2020-07-04T15:12:56Z" level=info msg="Load Balancer [Kubeadm Load Balancer] started"
time="2020-07-04T15:12:56Z" level=info msg="Broadcasting ARP update for 192.168.0.81 (00:50:56:a5:69:a1) via ens192"
time="2020-07-04T15:12:56Z" level=info msg="new leader elected: controlPlane01"
```
We will kill this node and watch `kube-vip` logs from another node:
#### Pinging VIP
```
64 bytes from 192.168.0.81: icmp_seq=667 ttl=64 time=0.387 ms
Request timeout for icmp_seq 668
Request timeout for icmp_seq 669
Request timeout for icmp_seq 670
Request timeout for icmp_seq 671
Request timeout for icmp_seq 672
64 bytes from 192.168.0.81: icmp_seq=673 ttl=64 time=0.453 ms
```
#### Logs
```
$ kubectl logs -n kube-system kube-vip-controlplane03 -f
time="2020-07-04T15:17:53Z" level=info msg="Beginning cluster membership, namespace [kube-system], lock name [plunder-lock], id [controlPlane03]"
I0704 15:17:53.484698 1 leaderelection.go:242] attempting to acquire leader lease kube-system/plunder-lock...
time="2020-07-04T15:17:53Z" level=info msg="new leader elected: controlPlane01"
E0704 15:20:18.864141 1 leaderelection.go:331] error retrieving resource lock kube-system/plunder-lock: etcdserver: request timed out
time="2020-07-04T15:20:20Z" level=info msg="new leader elected: controlPlane02"
```
#### Adding `controlPlane04`
A kubeadm join will fail as the `controlPlane01` still exists as an endpoint, so we have two options (manual steps and configmap edit to remove all mention of this node, or we can bring this node up and `kubeadm reset` the node (which we will do)).
```
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
controlplane01 NotReady master 14m v1.17.0
controlplane02 Ready master 13m v1.17.2
controlplane03 Ready master 13m v1.17.0
controlplane04 NotReady master 9s v1.17.0
```
After this we can add this node into `kube-vip` with the same manifest created by `docker run`.
## LeaderElection configuration
The Kubernetes LeaderElection that is used to manage the election of a new leader now supports having it's settings managed through flags.
- `--leaseDuration` Length of time a Kubernetes leader lease can be held for
- `--leaseRenewDuration` Length of time a Kubernetes leader can attempt to renew its lease
- `--leaseRetry` Number of times the host will retry to hold a lease
For larger clusters the `--leaseDuration` and `--leaseRenewDuration` may need extending due to slower `etcd` performance. (Tested with 2000 nodes)
## k3s
This section details the steps required to deploye `k3s` in a Highly available manner, using kube-vip deployed within k3s as a daemonset on the control plane nodes. As of `k3s` v1 the persistent datastore is back to etcd, however this guide will also include the steps for using `mysql`.
### Example MySQL deployment (optional)
To quickly validate this we can use docker on a host to quickly spin up a mysql database to store the persistent Kubernetes data.
#### Create local directory for BD storage
`mkdir mysql`
#### Start Docker MySQL container
`sudo docker run --cap-add SYS_NICE -p 3306:3306 --name k3s-mysql -v /home/dan/mysql:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=k3s-password -d mysql:8`
### Create `kube-vip` manifest
The `kube-vip` manifest contains all the configuration for starting up `kube-vip` within the `k3s` cluster, it runs as a daemonset with affinity/taints for the control-plane nodes. As `k3s` starts it will parse all manifests in the manifests folder and start the highly available VIP across all control plane nodes in the cluster.
#### Create the `k3` manifests directory
Create the manifests directory, this directory is used by `k3s` for all of it's other deployments once it's up and running.
`sudo mkdir -p /var/lib/rancher/k3s/server/manifests/`
#### Generate the manifest
Modify the `vipAddress` and `vipInterface` to match the floating IP address you'd like to use and the interface it should bind to.
`curl -sL kube-vip.io/k3s | vipAddress=192.168.0.10 vipInterface=ens192 sh | sudo tee /var/lib/rancher/k3s/server/manifests/vip.yaml`
### Start `k3s`
Set the VIP **first**
`export VIP=192.168.0.10`
From online `-->`
```
curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="--write-kubeconfig-mode 644 \
-t agent-secret --tls-san $VIP" sh -
```
From local `-->`
```
sudo ./k3s server --tls-san $VIP
```
#### With MySQL
From online `-->`
```
curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="--write-kubeconfig-mode 644 \
--datastore-endpoint mysql://root:k3s-password@tcp(192.168.0.43:3306)/kubernetes \
-t agent-secret --tls-san $VIP" sh -
```
From local `-->`
```
sudo ./k3s server --tls-san $VIP \
--datastore-endpoint="mysql://root:k3s-password@tcp(192.168.0.43:3306)/kubernetes"
```
### Get a `kubeconfig` that uses the vip
````
mkdir -p $HOME/.kube
sudo cat /etc/rancher/k3s/k3s.yaml | sed 's/127.0.0.1/'$VIP'/g' > $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
```

View File

@@ -1,84 +0,0 @@
# Kube-Vip Flag / Environment Variable reference
## Flags
These flags are typically used in manifest generation.
| Category | Flag | Usage | Notes |
|--------------|------|-------|-------|
|**Mode** ||||
| |`--controlPlane`|Enables `kube-vip` control-plane functionality||
| |`--services`|Enables `kube-vip` to watch services of type:LoadBalancer||
|**Vip Config** ||||
| |`--arp`|Enables ARP brodcasts from Leader||
| |`--bgp`|Enables BGP peering from `kube-vip`||
| |`--vip`|`<IP Address>`|(deprecated)|
| |`--address`|`<IP Address>` or `<DNS name>`||
| |`--interface`|`<linux interface>`||
| |`--leaderElection`|Enables Kubernetes LeaderElection|Used by ARP, as only the leader can broadcast|
|**Services**||||
| |`--cidr`|Defaults "32"|Used when advertising BGP addresses (typically as `x.x.x.x/32`)|
|**Kubernetes**||||
| |`--inCluster`|Defaults to looking inside the Pod for the token||
| |`--taint`|Enables a taint, stopping control plane daemonset being on workers||
|**LeaderElection**||||
| |`--leaseDuration`|default 5|Seconds a lease is held for|
| |`--leaseRenewDuration`|default 3|Seconds a leader can attempt to renew the lease|
| |`--leaseRetry`|default 1|Number of times the leader will hold the lease for|
| |`--namespace`|"kube-vip"|The namespace where the lease will reside|
|**BGP**||||
| |`--bgpRouterID`|`<IP Address>`|Typically the address of the local node|
| |`--localAS`|default 65000|The AS we peer from|
| |`--bgppeers`|`<address:AS:password:mutlihop>`|Comma seperate list of BGP peers|
| |`--peerAddress`|`<IP Address>`|Address of a single BGP Peer|
| |`--peerAS`|default 65000|AS of a single BGP Peer|
| |`--peerPass`|""| Password to work with a single BGP Peer|
| |`--multiHop`|Enables eBGP MultiHop| Enable multiHop with a single BGP Peer|
| |`--annotaions`|`<provider string>`|Startup will be paused until the node annotaions contain the BGP configuration|
|**Equinix Metal**|||(May be deprecated)|
| |`--metal`|Enables Equinix Metal API calls||
| |`--metalKey`|Equinix Metal API token||
| |`--metalProject`|Equinix Metal Project (Name)||
| |`--metalProjectID`|Equinix Metal Project (UUID)||
| |`--provider-config`|Path to the Equinix Metal provider configuration|Requires the Equinix Metal CCM|
## Environment Variables
These environment variables are usually part of a kube-vip manifest.
More environment variables can be read through the `pkg/kubevip/config_envvar.go` file.
| Category | Environment Variable | Usage | Notes |
|--------------|------|-------|-------|
|**Mode** ||||
| |`cp_enable`|Enables `kube-vip` control-plane functionality||
| |`svc_enable`|Enables `kube-vip` to watch services of `type:LoadBalancer`||
|**Vip Config** ||||
| |`vip_arp`|Enables ARP brodcasts from Leader||
| |`bgp_enable`|Enables BGP peering from `kube-vip`||
| |`vip_address`|`<IP Address>`|(deprecated)|
| |`address`|`<IP Address>` or `<DNS name>`||
| |`vip_interface`|`<linux interface>`||
| |`vip_leaderelection`|Enables Kubernetes LeaderElection|Used by ARP, as only the leader can broadcast|
|**Services**||||
| |`vip_cidr`|Defaults "32"|Used when advertising BGP addresses (typically as `x.x.x.x/32`)|
|**LeaderElection**||||
| |`vip_leaseduration`|default 5|Seconds a lease is held for|
| |`vip_renewdeadline`|default 3|Seconds a leader can attempt to renew the lease|
| |`vip_retryperiod`|default 1|Number of times the leader will hold the lease for|
| |`cp_namespace`|"kube-vip"|The namespace where the lease will reside|
|**BGP**||||
| |`bgp_routerid`|`<IP Address>`|Typically the address of the local node|
| |`bgp_as`|default 65000|The AS we peer from|
| |`bgp_peers`|`<address:AS:password:mutlihop>`|Comma seperate list of BGP peers|
| |`bgp_peeraddress`|`<IP Address>`|Address of a single BGP Peer|
| |`bgp_peeras`|default 65000|AS of a single BGP Peer|
| |`bgp_peerpass`|""| Password to work with a single BGP Peer|
| |`bgp_multihop`|Enables eBGP MultiHop| Enable multiHop with a single BGP Peer|
| |`annotaions`|`<provider string>`|Startup will be paused until the node annotaions contain the BGP configuration|
|**Equinix Metal**|||(May be deprecated)|
| |`vip_packet`|Enables Equinix Metal API calls||
| |`PACKET_AUTH_TOKEN`|Equinix Metal API token||
| |`vip_packetproject`|Equinix Metal Project (Name)||
| |`vip_packetprojectid`|Equinix Metal Project (UUID)||
| |`provider_config`|Path to the Equinix Metal provider configuration|Requires the Equinix Metal CCM|

View File

@@ -1,226 +0,0 @@
# Kube-Vip as a daemonset
In Hybrid mode `kube-vip` will manage a virtual IP address that is passed through it's configuration for a Highly Available Kubernetes cluster, it will also "watch" services of `type:LoadBalancer` and once their `spec.LoadBalancerIP` is updated (typically by a cloud controller) it will advertise this address using BGP/ARP.
**Note about Daemonsets**
The "hybrid" mode is now the default mode in `kube-vip` from `0.2.3` onwards, and allows both modes to be enabled at the same time.
If the Kubernetes installer allows for adding a Virtual IP as an additional [SAN](https://en.wikipedia.org/wiki/Subject_Alternative_Name) to the API server certificate then we can apply `kube-vip` to the cluster once the first node has been brought up.
Unlike generating the static manifest there are a few more things that may need configuring, this page will cover most scenarios.
## Create the RBAC settings
As a daemonSet runs within the Kubernetes cluster it needs the correct access to be able to watch Kubernetes services and other objects. In order to do this we create a User, Role, and a binding.. we can apply this with the command:
```
kubectl apply -f https://kube-vip.io/manifests/rbac.yaml
```
## Generating a Manifest
This section only covers generating a simple *BGP* configuration, as the main focus is will be on additional changes to the manifest. For more examples we can look at [here](/hybrid/static/).
**Note:** Pay attention if using the "static" examples, as the `manifest` subcommand should use `daemonset` and NOT `pod`.
### Set configuration details
`export VIP=192.168.0.40`
`export INTERFACE=<interface>`
### Configure to use a container runtime
The easiest method to generate a manifest is using the container itself, below will create an alias for different container runtimes.
#### containerd
`alias kube-vip="ctr run --rm --net-host docker.io/plndr/kube-vip:0.3.1 vip"`
#### Docker
`alias kube-vip="docker run --network host --rm plndr/kube-vip:0.3.1"`
### BGP Example
This configuration will create a manifest that will start `kube-vip` providing **controlplane** and **services** management. **Unlike** ARP, all nodes in the BGP configuration will advertise virtual IP addresses.
**Note** we bind the address to `lo` as we don't want multiple devices that have the same address on public interfaces. We can specify all the peers in a comma seperate list in the format of `address:AS:password:multihop`.
**Note 2** we pass the `--inCluster` flag as this is running as a daemonSet within the Kubernetes cluster and therefore will have access to the token inside the running pod.
**Note 2** we pass the `--taint` flag as we're deploying `kube-vip` as both a daemonset and as advertising controlplane, we want to taint this daemonset to only run on the worker nodes.
`export INTERFACE=lo`
```
kube-vip manifest daemonset \
--interface $INTERFACE \
--vip $VIP \
--controlplane \
--services \
--inCluster \
--taint \
--bgp \
--bgppeers 192.168.0.10:65000::false,192.168.0.11:65000::false
```
### Generated Manifest
```
apiVersion: apps/v1
kind: DaemonSet
metadata:
creationTimestamp: null
name: kube-vip-ds
namespace: kube-system
spec:
selector:
matchLabels:
name: kube-vip-ds
template:
metadata:
creationTimestamp: null
labels:
name: kube-vip-ds
spec:
containers:
- args:
- manager
env:
- name: vip_arp
value: "false"
- name: vip_interface
value: lo
- name: port
value: "6443"
- name: vip_cidr
value: "32"
- name: cp_enable
value: "true"
- name: cp_namespace
value: kube-system
- name: svc_enable
value: "true"
- name: bgp_enable
value: "true"
- name: bgp_peers
value: "192.168.0.10:65000::false,192.168.0.11:65000::false"
- name: vip_address
value: 192.168.0.40
image: plndr/kube-vip:0.2.3
imagePullPolicy: Always
name: kube-vip
resources: {}
securityContext:
capabilities:
add:
- NET_ADMIN
- SYS_TIME
hostNetwork: true
serviceAccountName: kube-vip
nodeSelector:
node-role.kubernetes.io/master: "true"
tolerations:
- effect: NoSchedule
key: node-role.kubernetes.io/master
updateStrategy: {}
```
### Manifest Overview
- `nodeSelector` - Ensures that this particular daemonset only runs on control plane nodes
- `serviceAccountName: kube-vip` - this specifies the user in the `rbac` that will give us the permissions to get/update services.
- `hostNetwork: true` - This pod will need to modify interfaces (for VIPs)
- `env {...}` - We pass the configuration into the kube-vip pod through environment variables.
## Equinix Metal Overview (using the [Equinix Metal CCM](https://github.com/packethost/packet-ccm))
The below example is for running `type:LoadBalancer` services on worker nodes only and will create a daemonset that will run `kube-vip`.
**NOTE** This use-case requires the [Equinix Metal CCM](https://github.com/packethost/packet-ccm) to be installed and that the cluster/kubelet is configured to use an "external" cloud provider.
This is important as the CCM will apply the BGP configuration to the [node annotations](https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/) making it easy for `kube-vip` to find the networking configuration it needs to expose load balancer addresses. The `--annotations metal.equinix.com` will cause kube-vip to "watch" the annotations of the worker node that it is running on, once all of the configuarion has been applied by the CCM then the `kube-vip` pod is ready to advertise BGP addresses for the service.
```
kube-vip manifest daemonset \
--interface $INTERFACE \
--services \
--bgp \
--annotations metal.equinix.com \
--inCluster | k apply -f -
```
### Troubleshooting
If `kube-vip` has been sat waiting for a long time then you may need to investigate that the annotations have been applied correctly by doing running the `describe` on the node:
```
kubectl describe node k8s.bgp02
...
Annotations: kubeadm.alpha.kubernetes.io/cri-socket: /var/run/dockershim.sock
node.alpha.kubernetes.io/ttl: 0
metal.equinix.com/node-asn: 65000
metal.equinix.com/peer-asn: 65530
metal.equinix.com/peer-ip: x.x.x.x
metal.equinix.com/src-ip: x.x.x.x
```
If there are errors regarding `169.254.255.1` or `169.254.255.2` in the `kube-vip` logs then the routes to the ToR switches that provide BGP peering may by missing from the nodes. They can be replaced with the below command:
```
GATEWAY_IP=$(curl https://metadata.platformequinix.com/metadata | jq -r ".network.addresses[] | select(.public == false) | .gateway")
ip route add 169.254.255.1 via $GATEWAY_IP
ip route add 169.254.255.2 via $GATEWAY_IP
```
Additionally examining the logs of the Packet CCM may reveal why the node is not yet ready.
## K3s overview (on Equinix Metal)
### Step 1: TIDY (best if something was running before)
`rm -rf /var/lib/rancher /etc/rancher ~/.kube/*; ip addr flush dev lo; ip addr add 127.0.0.1/8 dev lo; mkdir -p /var/lib/rancher/k3s/server/manifests/`
### Step 2: Get rbac
`curl https://kube-vip.io/manifests/rbac.yaml > /var/lib/rancher/k3s/server/manifests/rbac.yaml`
### Step 3: Generate kube-vip (get EIP from CLI or UI)
```
export EIP=x.x.x.x
export INTERFACE=lo
```
```
kube-vip manifest daemonset \
--interface $INTERFACE \
--vip $EIP \
--controlplane \
--services \
--inCluster \
--taint \
--bgp \
--metal \
--provider-config /etc/cloud-sa/cloud-sa.json | tee /var/lib/rancher/k3s/server/manifests/vip.yaml
```
NOTE: the `—provider-config` actually comes from the secret we apply in step 5 (this will leave kube-vip waiting to start)
### Step 4: Up Cluster
`K3S_TOKEN=SECRET k3s server --cluster-init --tls-san $EIP --no-deploy servicelb --disable-cloud-controller`
### Step 5: Add CCM
`alias k="k3s kubectl"`
`k apply -f ./secret.yaml`
(^ https://github.com/packethost/packet-ccm/blob/master/deploy/template/secret.yaml)
`k apply -f https://gist.githubusercontent.com/thebsdbox/c86dd970549638105af8d96439175a59/raw/4abf90fb7929ded3f7a201818efbb6164b7081f0/ccm.yaml`
### Step 6: Demo !
`k apply -f https://k8s.io/examples/application/deployment.yaml`
`k expose deployment nginx-deployment --port=80 --type=LoadBalancer --name=nginx`
### Step 7 watch and test:
`k get svc --watch`

View File

@@ -1,141 +0,0 @@
# Using `kube-vip` in Hybrid Mode
We can deploy kube-vip in two different methods, which completely depends on your use-case and method for installing Kubernetes:
- Static Pods (hybrid)
- Daemonset (hybrid, requires taint)
## **Prerequisites**
In order for `kube-vip` to be able to speak with the Kubernetes API server, we need to be able to resolve the hostname within the pod. In order to ensure this will work as expected the `/etc/hosts` file should have the `hostname` of the server within it. The `/etc/hosts` file is passed into the running container and will ensure that the pod isn't "confused" by any Kubernetes networking.
## Kubernetes Services (`type:LoadBalancer`)
To learn more about how `kube-vip` in hybrid works with the LoadBalancer services within a kubernetes cluster the documentation is [here](./services/). To get `kube-vip` deployed read on !
## Static Pods
Static pods are a Kubernetes pod that is ran by the `kubelet` on a single node, and is **not** managed by the Kubernetes cluster itself. This means that whilst the pod can appear within Kubernetes it can't make use of a variety of kubernetes functionality (such as the kubernetes token or `configMaps`). The static pod approach is primarily required for [kubeadm](https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/), this is due to the sequence of actions performed by `kubeadm`. Ideally we want `kube-vip` to be part of the kubernetes cluster, for various bits of functionality we also need `kube-vip` to provide a HA virtual IP as part of the installation.
The sequence of events for this to work follows:
1. Generate a `kube-vip` manifest in the static pods manifest folder
2. Run `kubeadm init`, this generates the manifests for the control plane and wait to connect to the VIP
3. The `kubelet` will parse and execute all manifest, including the `kube-vip` manifest
4. `kube-vip` starts and advertises our VIP
5. The `kubeadm init` finishes succesfully.
## Daemonset
Other Kubernetes distributions can bring up a Kubernetes cluster, without depending on a VIP (BUT they are configured to support one). A prime example of this would be k3s, that can be configured to start and also sign the certificates to allow incoming traffic to a virtual IP. Given we don't need the VIP to exist **before** the cluster, we can bring up the k3s node(s) and then add `kube-vip` as a daemonset for all control plane nodes.
# Deploying `kube-vip`
The simplest method for generating the Kubernetes manifests is with `kube-vip` itself.. The subcommand `manifest pod|daemonset` can be used to generate specific types of Kubernetes manifests for use in a cluster. These subcommands can be configured with additional flags to enable/disable BGP/ARP/LeaderElection and a host of other options.
Both Examples will use the same Architecture:
#### Infrastructure architecture
The infrastructure for our example HA Kubernetes cluster is as follows:
| Node | Address |
|----------------|------------|
| VIP | 10.0.0.40 |
| controlPlane01 | 10.0.0.41 |
| controlPlane02 | 10.0.0.42 |
| controlPlane03 | 10.0.0.43 |
| worker01 | 10.0.0.44 |
All nodes are running Ubuntu 18.04, Docker CE and will use Kubernetes 1.19.0, we only have one worker as we're going to use our controlPlanes in "hybrid" mode.
## As a static Pod (for kubeadm)
The details for creating a static pod are available [here](./static/)
## As a daemonset
When using `kube-vip` as a daemonset the details are available [here](./daemonset/)
# Kube-Vip flag reference
| Category | Flag | Usage | Notes |
|--------------|------|-------|-------|
|**Mode** ||||
| |`--controlPlane`|Enables `kube-vip` control-plane functionality||
| |`--services`|Enables `kube-vip` to watch services of type:LoadBalancer||
|**Vip Config** ||||
| |`--arp`|Enables ARP brodcasts from Leader||
| |`--bgp`|Enables BGP peering from `kube-vip`||
| |`--vip`|`<IP Address>`|(deprecated)|
| |`--address`|`<IP Address>` or `<DNS name>`||
| |`--interface`|`<linux interface>`||
| |`--leaderElection`|Enables Kubernetes LeaderElection|Used by ARP, as only the leader can broadcast|
|**Services**||||
| |`--cidr`|Defaults "32"|Used when advertising BGP addresses (typically as `x.x.x.x/32`)|
|**Kubernetes**||||
| |`--inCluster`|Defaults to looking inside the Pod for the token||
| |`--taint`|Enables a taint, stopping control plane daemonset being on workers||
|**LeaderElection**||||
| |`--leaseDuration`|default 5|Seconds a lease is held for|
| |`--leaseRenewDuration`|default 3|Seconds a leader can attempt to renew the lease|
| |`--leaseRetry`|default 1|Number of times the leader will hold the lease for|
| |`--namespace`|"kube-vip"|The namespace where the lease will reside|
|**BGP**||||
| |`--bgpRouterID`|`<IP Address>`|Typically the address of the local node|
| |`--localAS`|default 65000|The AS we peer from|
| |`--bgppeers`|`<address:AS:password:mutlihop>`|Comma seperate list of BGP peers|
| |`--peerAddress`|`<IP Address>`|Address of a single BGP Peer|
| |`--peerAS`|default 65000|AS of a single BGP Peer|
| |`--peerPass`|""| Password to work with a single BGP Peer|
| |`--multiHop`|Enables eBGP MultiHop| Enable multiHop with a single BGP Peer|
| |`--annotaions`|`<provider string>`|Startup will be paused until the node annotaions contain the BGP configuration|
|**Equinix Metal**|||(May be deprecated)|
| |`--metal`|Enables Equinix Metal API calls||
| |`--metalKey`|Equinix Metal API token||
| |`--metalProject`|Equinix Metal Project (Name)||
| |`--metalProjectID`|Equinix Metal Project (UUID)||
| |`--provider-config`|Path to the Equinix Metal provider configuration|Requires the Equinix Metal CCM|
## Changelog
### Static DNS Support (added in 0.2.0)
A new flag `--address` is introduced to support using a DNS record as the control plane endpoint. `kube-vip` will do a dns lookup to retrieve the IP for the DNS record, and use that IP as the VIP. An `dnsUpdater` periodically checks and updates the system if IP changes for the DNS record.
### Dynamic DNS Support (added in 0.2.1)
`kube-vip` was also updated to support DHCP + [Dynamic DNS](https://en.wikipedia.org/wiki/Dynamic_DNS), for the use case where it's not able to reserve a static IP for the control plane endpoint.
A new flag `--ddns` is introduced. Once enabled, `kube-vip` expects the input `--address` will be a FQDN without binding to an IP. Then `kube-vip` will start a dhcp client to allocate an IP for the hostname of FQDN, and maintain the lease for it.
Once DHCP returns an IP for the FQDN, the same `dnsUpdater` runs to periodically checks and updates if IP got changed.
## BGP Support (added in 0.1.8)
In version `0.1.8` `kube-vip` was updated to support [BGP](https://en.wikipedia.org/wiki/Border_Gateway_Protocol) as a VIP failover mechanism. When a node is elected as a leader then it will update it's peers so that they are aware to route traffic to that node in order to access the VIP.
The following new flags are used:
- `--bgp` This will enable BGP support within kube-vip
- `--localAS` The local AS number
- `--bgpRouterID` The local router address
- `--peerAS` The AS number for a BGP peer
- `--peerAddress` The address of a BGP peer
### Equinix Metal BGP support
If the `--bgp` flag is passed along with the Equinix Metal flags `metal, metalKey and metalProject`, then Equinix Metal API will be used in order to determine the BGP configuration for the nodes being used in the cluster. This automates a lot of the process and makes using BGP within Equinix Metal much simpler.
## Equinix Metal Control Plane Support (added in 0.1.8)
Recently in version `0.1.7` of `kube-vip` we added the functionality to use a Equinix Metal Elastic IP as the virtual IP fronting the Kubernetes Control plane cluster. In order to first get out virtual IP we will need to use our Equinix Metal account and create a EIP (either public or private). We will only need a single address so a `/32` will suffice, once this is created as part of a Equinix Metal project we can now apply this address to the servers that live in the same project.
In this example we've logged into the UI can created a new EIP of `147.75.1.2`, and we've deployed three small server instances with Ubuntu.
The following new flags are used:
- `--metal` which enables the use of the Equinix Metal API
- `--metalKey` which is our API key
- `--metalProject`which is the name of our Equinix Metal project where our servers and EIP are located.
*Also* the `--arp` flag should NOT be used as it wont work within the Equinix Metal network.

View File

@@ -1,269 +0,0 @@
# Kube-vip services
We've designed `kube-vip` to be as de-coupled or agnostic from other components that may exist within a Kubernetes cluster as possible. This has lead to `kube-vip` having a very simplistic but robust approach to advertising Kubernetes services to the outside world and marking these services as ready to use.
## Flow
This section details the flow of events in order for `kube-vip` to advertise a Kubernetes service:
1. An end user exposes a application through Kubernetes as a LoadBalancer => `kubectl expose deployment nginx-deployment --port=80 --type=LoadBalancer --name=nginx`
2. Within the Kubernetes cluster a service object is created with the `svc.Spec.Type = ServiceTypeLoadBalancer`
3. A controller (typically a Cloud Controller) has a loop that "watches" for services of the type `LoadBalancer`.
4. The controller now has the responsibility of providing an IP address for this service along with doing anything that is network specific for the environment where the cluster is running.
5. Once the controller has an IP address it will update the service `svc.Spec.LoadBalancerIP` with it's new IP address.
6. The `kube-vip` pods also implement a "watcher" for services that have a `svc.Spec.LoadBalancerIP` address attached.
7. When a new service appears `kube-vip` will start advertising this address to the wider network (through BGP/ARP) which will allow traffic to come into the cluster and hit the service network.
8. Finally `kube-vip` will update the service status so that the API reflects that this LoadBalancer is ready. This is done by updating the `svc.Status.LoadBalancer.Ingress` with the VIP address.
## CCM
We can see from the [flow](#Flow) above that `kube-vip` isn't coupled to anything other than the Kubernetes API, and will only act upon an existing Kubernetes primative (in this case the object of type `Service`). This makes it easy for existing CCMs to simply apply their logic to services of type LoadBalancer and leave `kube-vip` to take the next steps to advertise these load-balancers to the outside world.
## Using the Kube-vip Cloud Provider
The below instructions *should just work* on Kubernetes regardless of architecture (Linux Operating System is the only requirement) - you can quickly install the "latest" components:
**Install the `kube-vip-cloud-provider`**
```
$ kubectl apply -f https://raw.githubusercontent.com/kube-vip/kube-vip-cloud-provider/main/manifest/kube-vip-cloud-controller.yaml
```
It uses a `statefulSet` and can always be viewed with the following command:
```
kubectl describe pods -n kube-system kube-vip-cloud-provider-0
```
**Create a global CIDR or IP Range**
Any `service` in any `namespace` can use an address from the global CIDR `cidr-global` or range `range-global`
```
kubectl create configmap --namespace kube-system kubevip --from-literal cidr-global=192.168.0.220/29
```
or
```
kubectl create configmap --namespace kube-system kubevip --from-literal range-global=192.168.1.220-192.168.1.230
```
Creating services of `type: LoadBalancer` in *any namespace* will now take addresses from the **global** cidr defined in the `configmap` unless a specific
## The Detailed guide
### Deploy the Kube-vip Cloud Provider
**Install the `kube-vip-cloud-provider`**
```
$ kubectl apply -f https://raw.githubusercontent.com/kube-vip/kube-vip-cloud-provider/main/manifest/kube-vip-cloud-controller.yaml
```
The following output should appear when the manifest is applied:
```
serviceaccount/kube-vip-cloud-controller created
clusterrole.rbac.authorization.k8s.io/system:kube-vip-cloud-controller-role created
clusterrolebinding.rbac.authorization.k8s.io/system:kube-vip-cloud-controller-binding created
statefulset.apps/kube-vip-cloud-provider created
```
We can validate the cloud provider by examining the pods and following the logs:
```
kubectl describe pods -n kube-system kube-vip-cloud-provider-0
kubectl logs -n kube-system kube-vip-cloud-provider-0 -f
```
### The Kube-vip Cloud Provider `configmap`
To manage the IP address ranges for the load balancer instances the `kube-vip-cloud-provider` uses a `configmap` held in the `kube-system` namespace. IP address ranges can be configured using:
- IP address pools by CIDR
- IP ranges [start address - end address]
- Multiple pools by CIDR per namespace
- Multiple IP ranges per namespace (handles overlapping ranges)
- Setting of static addresses through --load-balancer-ip=x.x.x.x
To control which IP address range is used for which service the following rules are applied:
- Global address pools (`cidr-global` or `range-global`) are available for use by *any* `service` in *any* `namespace`
- Namespace specific address pools (`cidr-<namespace>` or `range-<namespace>`) are *only* available for use by `service` in the *specific* `namespace`
- Static IP addresses can be applied to a load balancer `service` using the `loadbalancerIP` setting, even outside of the assigned ranges
Example Configmap:
```
$ kubectl get configmap -n kube-system kubevip -o yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: kubevip
namespace: kube-system
data:
cidr-default: 192.168.0.200/29 # CIDR-based IP range for use in the default namespace
range-development: 192.168.0.210-192.168.0.219 # Range-based IP range for use in the development namespace
cidr-finance: 192.168.0.220/29,192.168.0.230/29 # Multiple CIDR-based ranges for use in the finance namespace
cidr-global: 192.168.0.240/29 # CIDR-based range which can be used in any namespace
```
### Expose a service
We can now expose a service and once the cloud provider has provided an address `kube-vip` will start to advertise that address to the outside world as shown below!
```
kubectl expose deployment nginx-deployment --port=80 --type=LoadBalancer --name=nginx
```
or via a `service` YAML definition
```
apiVersion: v1
kind: Service
metadata:
name: nginx
spec:
ports:
- name: http
port: 80
protocol: TCP
selector:
app: nginx
type: LoadBalancer
```
We can also expose a specific address by specifying it on the command line:
```
kubectl expose deployment nginx-deployment --port=80 --type=LoadBalancer --name=nginx --load-balancer-ip=1.1.1.1
```
or including it in the `service` definition:
```
apiVersion: v1
kind: Service
metadata:
name: nginx
spec:
ports:
- name: http
port: 80
protocol: TCP
selector:
app: nginx
type: LoadBalancer
loadBalancerIP: "1.1.1.1"
```
### Using DHCP for Load Balancers (experimental)
With the latest release of `kube-vip` > 0.2.1, it is possible to use the local network DHCP server to provide `kube-vip` with a load-balancer address that can be used to access a
Kubernetes service on the network.
In order to do this we need to signify to `kube-vip` and the cloud-provider that we don't need one of their managed addresses. We do this by explicitly exposing a service on the
address `0.0.0.0`. When `kube-vip` sees a service on this address it will create a `macvlan` interface on the host and request a DHCP address, once this address is provided it will assign it as the VIP and update the Kubernetes service!
```
$ k expose deployment nginx-deployment --port=80 --type=LoadBalancer --name=nginx-dhcp --load-balancer-ip=0.0.0.0; k get svc
service/nginx-dhcp exposed
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 17m
nginx-dhcp LoadBalancer 10.97.150.208 0.0.0.0 80:31184/TCP 0s
{ ... a second or so later ... }
$ k get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 17m
nginx-dhcp LoadBalancer 10.97.150.208 192.168.0.155 80:31184/TCP 3s
```
### Using UPNP to expose a service to the outside world
With the latest release of `kube-vip` > 0.2.1, it is possible to expose a load-balancer on a specific port and using UPNP (on a supported gateway) expose this service to the inte
rnet.
Most simple networks look something like the following:
`<----- <internal network 192.168.0.0/24> <Gateway / router> <external network address> ----> Internet`
Using UPNP we can create a matching port on the `<external network address>` allowing your service to be exposed to the internet.
#### Enable UPNP
Add the following to the `kube-vip` `env:` section, and the rest should be completely automated.
**Note** some environments may require (Unifi) will require `Secure mode` being `disabled` (this allows a host with a different address to register a port)
```
- name: enableUPNP
value: "true"
```
#### Exposing a service
To expose a port successfully we'll need to change the command slightly:
`--target-port=80` the port of the application in the pods (HTT/NGINX)
`--port=32380` the port the service will be exposed on (and what you should connect to in order to receive traffic from the service)
`kubectl expose deployment plunder-nginx --port=32380 --target-port=80 --type=LoadBalancer --namespace plunder`
The above example should expose a port on your external (internet facing address), that can be tested externally with:
```
$ curl externalIP:32380
<!DOCTYPE html>
<html>
...
```
### Expose with Equinix Metal (using the `kube-vip-cloud-provider`)
Either through the CLI or through the UI, create a public IPv4 EIP address.. and this is the address you can expose through BGP!
```
# packet ip request -p xxx-bbb-ccc -f ams1 -q 1 -t public_ipv4
+-------+---------------+--------+----------------------+
| ID | ADDRESS | PUBLIC | CREATED |
+-------+---------------+--------+----------------------+
| xxxxx | 1.1.1.1 | true | 2020-11-10T15:57:39Z |
+-------+---------------+--------+----------------------+
kubectl expose deployment nginx-deployment --port=80 --type=LoadBalancer --name=nginx --load-balancer-ip=1.1.1.1
```
## Equinix Metal Overview (using the [Equinix Metal CCM](https://github.com/packethost/packet-ccm))
Below are two examples for running `type:LoadBalancer` services on worker nodes only and will create a daemonset that will run `kube-vip`.
**NOTE** This use-case requires the [Equinix Metal CCM](https://github.com/packethost/packet-ccm) to be installed and that the cluster/kubelet is configured to use an "external" cloud provider.
### Using Annotations
This is important as the CCM will apply the BGP configuration to the [node annotations](https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/) making it easy for `kube-vip` to find the networking configuration it needs to expose load balancer addresses. The `--annotations metal.equinix.com` will cause kube-vip to "watch" the annotations of the worker node that it is running on, once all of the configuarion has been applied by the CCM then the `kube-vip` pod is ready to advertise BGP addresses for the service.
```
kube-vip manifest daemonset \
--interface $INTERFACE \
--services \
--bgp \
--annotations metal.equinix.com \
--inCluster | k apply -f -
```
### Using the existing CCM secret
Alternatively it is possible to create a daemonset that will use the existing CCM secret to do an API lookup, this will allow for discovering the networking configuration needed to advertise loadbalancer addresses through BGP.
```
kube-vip manifest daemonset --interface $INTERFACE \
--services \
--inCluster \
--bgp \
--metal \
--provider-config /etc/cloud-sa/cloud-sa.json | kubectl apply -f -
```

View File

@@ -1,129 +0,0 @@
# Kube-vip as a Static Pod
In Hybrid mode `kube-vip` will manage a virtual IP address that is passed through it's configuration for a Highly Available Kubernetes cluster, it will also "watch" services of `type:LoadBalancer` and once their `spec.LoadBalancerIP` is updated (typically by a cloud controller) it will advertise this address using BGP/ARP.
The "hybrid" mode is now the default mode in `kube-vip` from `0.2.3` onwards, and allows both modes to be enabled at the same time.
## Generating a Manifest
This section details creating a number of manifests for various use cases
### Set configuration details
`export VIP=192.168.0.40`
`export INTERFACE=<interface>`
### Configure to use a container runtime
The easiest method to generate a manifest is using the container itself, below will create an alias for different container runtimes.
#### containerd
`alias kube-vip="ctr run --rm --net-host docker.io/plndr/kube-vip:0.3.1 vip /kube-vip"`
#### Docker
`alias kube-vip="docker run --network host --rm plndr/kube-vip:0.3.1"`
### ARP
This configuration will create a manifest that starts `kube-vip` providing **controlplane** and **services** management, using **leaderElection**. When this instance is elected as the leader it will bind the `vip` to the specified `interface`, this is also the same for services of `type:LoadBalancer`.
`export INTERFACE=eth0`
```
kube-vip manifest pod \
--interface $INTERFACE \
--vip $VIP \
--controlplane \
--services \
--arp \
--leaderElection | tee /etc/kubernetes/manifests/kube-vip.yaml
```
### BGP
This configuration will create a manifest that will start `kube-vip` providing **controlplane** and **services** management. **Unlike** ARP, all nodes in the BGP configuration will advertise virtual IP addresses.
**Note** we bind the address to `lo` as we don't want multiple devices that have the same address on public interfaces. We can specify all the peers in a comma seperate list in the format of `address:AS:password:multihop`.
`export INTERFACE=lo`
```
kube-vip manifest pod \
--interface $INTERFACE \
--vip $VIP \
--controlplane \
--services \
--bgp \
--localAS 65000 \
--bgpRouterID 192.168.0.2 \
--bgppeers 192.168.0.10:65000::false,192.168.0.11:65000::false | tee /etc/kubernetes/manifests/kube-vip.yaml
```
### BGP with Equinix Metal
When deploying Kubernetes with Equinix Metal with the `--controlplane` functionality we need to pre-populate the BGP configuration in order for the control plane to be advertised and work in a HA scenario. Luckily Equinix Metal provides the capability to "look up" the configuration details (for BGP) that we need in order to advertise our virtual IP for HA functionality. We can either make use of the [Equinix Metal API](https://metal.equinix.com/developers/api/) or we can parse the [Equinix Metal Metadata service](https://metal.equinix.com/developers/docs/servers/metadata/).
**Note** If this cluster will be making use of Equinix Metal for `type:LoadBalancer` (by using the [Equinix Metal CCM](https://github.com/packethost/packet-ccm)) then we will need to ensure that nodes are set to use an external cloud-provider. Before doing a `kubeadm init|join` ensure the kubelet has the correct flags by using the following command `echo KUBELET_EXTRA_ARGS=\"--cloud-provider=external\" > /etc/default/kubelet`.
#### Creating a manifest using the API
We can enable `kube-vip` with the capability to discover the required configuration for BGP by passing the `--metal` flag and the API Key and our project ID.
```
kube-vip manifest pod \
--interface $INTERFACE\
--vip $VIP \
--controlplane \
--services \
--bgp \
--metal \
--metalKey xxxxxxx \
--metalProjectID xxxxx | tee /etc/kubernetes/manifests/kube-vip.yaml
```
#### Creating a manifest using the metadata
We can parse the metadata, *however* it requires that the tools `curl` and `jq` are installed.
```
kube-vip manifest pod \
--interface $INTERFACE\
--vip $VIP \
--controlplane \
--services \
--bgp \
--peerAS $(curl https://metadata.platformequinix.com/metadata | jq '.bgp_neighbors[0].peer_as') \
--peerAddress $(curl https://metadata.platformequinix.com/metadata | jq -r '.bgp_neighbors[0].peer_ips[0]') \
--localAS $(curl https://metadata.platformequinix.com/metadata | jq '.bgp_neighbors[0].customer_as') \
--bgpRouterID $(curl https://metadata.platformequinix.com/metadata | jq -r '.bgp_neighbors[0].customer_ip') | sudo tee /etc/kubernetes/manifests/vip.yaml
```
## Deploy your Kubernetes Cluster
### First node
```
sudo kubeadm init \
--kubernetes-version 1.19.0 \
--control-plane-endpoint $VIP \
--upload-certs
```
### Additional Node(s)
Due to an oddity with `kubeadm` we can't have our `kube-vip` manifest present **before** joining our additional nodes. So on these control plane nodes we will add them first to the cluster.
```
sudo kubeadm join $VIP:6443 \
--token w5atsr.blahblahblah
--control-plane \
--certificate-key abc123
```
**Once**, joined these nodes can have the same command that we ran on the first node to populate the `/etc/kubernetes/manifests/` folder with the `kube-vip` manifest.
## Services
At this point your `kube-vip` static pods will be up and running and where used with the `--services` flag will also be watching for Kubernetes services that they can advertise. In order for `kube-vip` to advertise a service it needs a CCM or other controller to apply an IP address to the `spec.LoadBalancerIP`, which marks the loadbalancer as defined.

View File

@@ -1,80 +0,0 @@
![kube-vip.png](kube-vip.png)
## Overview
Kubernetes Virtual IP and Load-Balancer for both control plane and Kubernetes services
The idea behind `kube-vip` is a small self-contained Highly-Available option for all environments, especially:
- Bare-Metal
- On-Prem
- Edge (ARM / Raspberry PI)
- Virtualisation
- Pretty much anywhere else :)
## Features
Kube-Vip was originally created to provide a HA solution for the Kubernetes control plane, over time it has evolved to incorporate that same functionality into Kubernetes service type [load-balancers](https://kubernetes.io/docs/concepts/services-networking/service/#loadbalancer).
- VIP addresses can be both IPv4 or IPv6
- Control Plane with ARP (Layer 2) or BGP (Layer 3)
- Control Plane using either [leader election](https://godoc.org/k8s.io/client-go/tools/leaderelection) or [raft](https://en.wikipedia.org/wiki/Raft_(computer_science))
- Control Plane HA with kubeadm (static Pods)
- Control Plane HA with K3s/and others (daemonsets)
- Service LoadBalancer using [leader election](https://godoc.org/k8s.io/client-go/tools/leaderelection) for ARP (Layer 2)
- Service LoadBalancer using multiple nodes with BGP
- Service LoadBalancer address pools per namespace or global
- Service LoadBalancer address via (existing network DHCP)
- Service LoadBalancer address exposure to gateway via UPNP
- ... manifest generation, vendor API integrations and many nore...
## Why?
The "original" purpose of `kube-vip` was to simplify the building of HA Kubernetes clusters, which at this time can involve a few components and configurations that all need to be managed. This was blogged about in detail by [thebsdbox](https://twitter.com/thebsdbox/) here -> [https://thebsdbox.co.uk/2020/01/02/Designing-Building-HA-bare-metal-Kubernetes-cluster/#Networking-load-balancing](https://thebsdbox.co.uk/2020/01/02/Designing-Building-HA-bare-metal-Kubernetes-cluster/#Networking-load-balancing). As the project evolved it now can use those same technologies to provide load-balancing capabilities within a Kubernetes Cluster.
## Architecture
The architecture for `kube-vip` (and associated kubernetes components) is covered in detail [here](/architecture/)
## Installation
There are two main routes for deploying `kube-vip`, either through a [static pod](https://kubernetes.io/docs/tasks/configure-pod-container/static-pod/) when bringing up a Kubernetes cluster with [kubeadm](https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/) or as a [daemon set](https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/) (typically with distributions like [k3s](https://k3s.io)).
The infrastructure for our example HA Kubernetes cluster is as follows:
| Node | Address |
|----------------|------------|
| VIP | 10.0.0.40 |
| controlPlane01 | 10.0.0.41 |
| controlPlane02 | 10.0.0.42 |
| controlPlane03 | 10.0.0.43 |
| worker01 | 10.0.0.44 |
All nodes are running Ubuntu 20.04, Docker CE and will use Kubernetes 1.21.0, we only have one worker as we're going to use our controlPlanes in "hybrid" mode.
- [Static Pod](/install_static)
- [Daemon Set](/install_daemonset)
## Usage
- [On-Prem with the kube-vip cloud controller](/usage/on-prem)
- [KIND](/usage/kind)
- [Equinix Metal](/usage/EquinixMetal)
- [k3s](/usage/k3s)
## Flags/Environment Variables
- [Flags and Environment variables](/flags/)
## Links
- The Kube-Vip Cloud Provider Repository -> [https://github.com/kube-vip/kube-vip-cloud-provider](https://github.com/kube-vip/kube-vip-cloud-provider)
- The Kube-Vip Repository -> [https://github.com/kube-vip/kube-vip](https://github.com/kube-vip/kube-vip)
## Copyright
© 2021 [The Linux Foundation](https://www.linuxfoundation.org/). All right reserved
The Linux Foundation has registered trademarks and uses trademarks.
For a list trademarks of The Linux Foundation, please see our [Trademark Usage page](https://www.linuxfoundation.org/en/trademark-usage).

View File

@@ -1,167 +0,0 @@
# Kube-Vip as a daemonset
## Daemonset
Other Kubernetes distributions can bring up a Kubernetes cluster, without depending on a VIP (BUT they are configured to support one). A prime example of this would be k3s, that can be configured to start and also sign the certificates to allow incoming traffic to a virtual IP. Given we don't need the VIP to exist **before** the cluster, we can bring up the k3s node(s) and then add `kube-vip` as a daemonset for all control plane nodes.
If the Kubernetes installer allows for adding a Virtual IP as an additional [SAN](https://en.wikipedia.org/wiki/Subject_Alternative_Name) to the API server certificate then we can apply `kube-vip` to the cluster once the first node has been brought up.
## Kube-Vip as **HA**, **Load-Balancer** or both ` ¯\_(ツ)_/¯`
When generating a manifest for `kube-vip` we will pass in the flags `--controlplane` / `--services` these will enable the various types of functionality within `kube-vip`.
With both enabled `kube-vip` will manage a virtual IP address that is passed through it's configuration for a Highly Available Kubernetes cluster, it will also "watch" services of `type:LoadBalancer` and once their `spec.LoadBalancerIP` is updated (typically by a cloud controller) it will advertise this address using BGP/ARP.
**Note about Daemonsets**
Unlike generating the static manifest there are a few more things that may need configuring, this page will cover most scenarios.
## Create the RBAC settings
As a daemonSet runs within the Kubernetes cluster it needs the correct access to be able to watch Kubernetes services and other objects. In order to do this we create a User, Role, and a binding.. we can apply this with the command:
```
kubectl apply -f https://kube-vip.io/manifests/rbac.yaml
```
## Generating a Manifest
This section only covers generating a simple *BGP* configuration, as the main focus is will be on additional changes to the manifest. For more examples we can look at [here](/hybrid/static/).
**Note:** Pay attention if using the "static" examples, as the `manifest` subcommand should use `daemonset` and NOT `pod`.
### Set configuration details
`export VIP=192.168.0.40`
`export INTERFACE=<interface>`
### Configure to use a container runtime
The easiest method to generate a manifest is using the container itself, below will create an alias for different container runtimes.
#### containerd
`alias kube-vip="ctr run --rm --net-host docker.io/plndr/kube-vip:0.3.1 vip"`
#### Docker
`alias kube-vip="docker run --network host --rm plndr/kube-vip:0.3.1"`
### BGP Example
This configuration will create a manifest that will start `kube-vip` providing **controlplane** and **services** management. **Unlike** ARP, all nodes in the BGP configuration will advertise virtual IP addresses.
**Note** we bind the address to `lo` as we don't want multiple devices that have the same address on public interfaces. We can specify all the peers in a comma seperate list in the format of `address:AS:password:multihop`.
**Note 2** we pass the `--inCluster` flag as this is running as a daemonSet within the Kubernetes cluster and therefore will have access to the token inside the running pod.
**Note 2** we pass the `--taint` flag as we're deploying `kube-vip` as both a daemonset and as advertising controlplane, we want to taint this daemonset to only run on the worker nodes.
`export INTERFACE=lo`
```
kube-vip manifest daemonset \
--interface $INTERFACE \
--vip $VIP \
--controlplane \
--services \
--inCluster \
--taint \
--bgp \
--bgppeers 192.168.0.10:65000::false,192.168.0.11:65000::false
```
### Generated Manifest
```
apiVersion: apps/v1
kind: DaemonSet
metadata:
creationTimestamp: null
name: kube-vip-ds
namespace: kube-system
spec:
selector:
matchLabels:
name: kube-vip-ds
template:
metadata:
creationTimestamp: null
labels:
name: kube-vip-ds
spec:
containers:
- args:
- manager
env:
- name: vip_arp
value: "false"
- name: vip_interface
value: lo
- name: port
value: "6443"
- name: vip_cidr
value: "32"
- name: cp_enable
value: "true"
- name: cp_namespace
value: kube-system
- name: vip_ddns
value: "false"
- name: svc_enable
value: "true"
- name: bgp_enable
value: "true"
- name: bgp_routerid
- name: bgp_as
value: "65000"
- name: bgp_peeraddress
- name: bgp_peerpass
- name: bgp_peeras
value: "65000"
- name: bgp_peers
value: 192.168.0.10:65000::false,192.168.0.11:65000::false
- name: vip_address
value: 192.168.0.40
image: 'plndr/kube-vip:'
imagePullPolicy: Always
name: kube-vip
resources: {}
securityContext:
capabilities:
add:
- NET_ADMIN
- NET_RAW
- SYS_TIME
hostNetwork: true
nodeSelector:
node-role.kubernetes.io/master: "true"
serviceAccountName: kube-vip
tolerations:
- effect: NoSchedule
key: node-role.kubernetes.io/master
operator: Exists
updateStrategy: {}
status:
currentNumberScheduled: 0
desiredNumberScheduled: 0
numberMisscheduled: 0
numberReady: 0
```
### Managing a `routerID` as a daemonset
The routerID needs to be unique on each node that participates in BGP advertisements. In order to do this we can modify the manifest so that when `kube-vip` starts it will look up its local address and use that as the routerID.
```
- name: bgp_routerinterface
value: "ens160"
```
This will instruct each instance of `kube-vip` as part of the daemonset to look up the IP address on that interface and use it as the routerID.
### Manifest Overview
- `nodeSelector` - Ensures that this particular daemonset only runs on control plane nodes
- `serviceAccountName: kube-vip` - this specifies the user in the `rbac` that will give us the permissions to get/update services.
- `hostNetwork: true` - This pod will need to modify interfaces (for VIPs)
- `env {...}` - We pass the configuration into the kube-vip pod through environment variables.

View File

@@ -1,75 +0,0 @@
# Kube-vip as a Static Pod
## Static Pods
Static pods are a Kubernetes pod that is ran by the `kubelet` on a single node, and is **not** managed by the Kubernetes cluster itself. This means that whilst the pod can appear within Kubernetes it can't make use of a variety of kubernetes functionality (such as the kubernetes token or `configMaps`). The static pod approach is primarily required for [kubeadm](https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/), this is due to the sequence of actions performed by `kubeadm`. Ideally we want `kube-vip` to be part of the kubernetes cluster, for various bits of functionality we also need `kube-vip` to provide a HA virtual IP as part of the installation.
The sequence of events for this to work follows:
1. Generate a `kube-vip` manifest in the static pods manifest folder
2. Run `kubeadm init`, this generates the manifests for the control plane and wait to connect to the VIP
3. The `kubelet` will parse and execute all manifest, including the `kube-vip` manifest
4. `kube-vip` starts and advertises our VIP
5. The `kubeadm init` finishes succesfully.
## Kube-Vip as **HA**, **Load-Balancer** or both ` ¯\_(ツ)_/¯`
When generating a manifest for `kube-vip` we will pass in the flags `--controlplane` / `--services` these will enable the various types of functionality within `kube-vip`.
With both enabled `kube-vip` will manage a virtual IP address that is passed through it's configuration for a Highly Available Kubernetes cluster, it will also "watch" services of `type:LoadBalancer` and once their `spec.LoadBalancerIP` is updated (typically by a cloud controller) it will advertise this address using BGP/ARP.
## Generating a Manifest
This section details creating a number of manifests for various use cases
### Set configuration details
`export VIP=192.168.0.40`
`export INTERFACE=<interface>`
## Configure to use a container runtime
The easiest method to generate a manifest is using the container itself, below will create an alias for different container runtimes.
### containerd
`alias kube-vip="ctr run --rm --net-host docker.io/plndr/kube-vip:0.3.1 vip /kube-vip"`
### Docker
`alias kube-vip="docker run --network host --rm plndr/kube-vip:0.3.1"`
## ARP
This configuration will create a manifest that starts `kube-vip` providing **controlplane** and **services** management, using **leaderElection**. When this instance is elected as the leader it will bind the `vip` to the specified `interface`, this is also the same for services of `type:LoadBalancer`.
`export INTERFACE=eth0`
```
kube-vip manifest pod \
--interface $INTERFACE \
--vip $VIP \
--controlplane \
--services \
--arp \
--leaderElection | tee /etc/kubernetes/manifests/kube-vip.yaml
```
## BGP
This configuration will create a manifest that will start `kube-vip` providing **controlplane** and **services** management. **Unlike** ARP, all nodes in the BGP configuration will advertise virtual IP addresses.
**Note** we bind the address to `lo` as we don't want multiple devices that have the same address on public interfaces. We can specify all the peers in a comma seperate list in the format of `address:AS:password:multihop`.
`export INTERFACE=lo`
```
kube-vip manifest pod \
--interface $INTERFACE \
--vip $VIP \
--controlplane \
--services \
--bgp \
--localAS 65000 \
--bgpRouterID 192.168.0.2 \
--bgppeers 192.168.0.10:65000::false,192.168.0.11:65000::false | tee /etc/kubernetes/manifests/kube-vip.yaml
```

View File

@@ -1,61 +0,0 @@
#!/bin/bash
echo "apiVersion: apps/v1
kind: DaemonSet
metadata:
creationTimestamp: null
name: kube-vip-ds
namespace: kube-system
spec:
selector:
matchLabels:
name: kube-vip-ds
template:
metadata:
creationTimestamp: null
labels:
name: kube-vip-ds
spec:
containers:
- args:
- manager
env:
- name: vip_arp
value: \"true\"
- name: vip_interface
value: $vipInterface
- name: port
value: \"6443\"
- name: vip_cidr
value: \"32\"
- name: cp_enable
value: \"true\"
- name: cp_namespace
value: kube-system
- name: svc_enable
value: \"false\"
- name: vip_address
value: $vipAddress
image: plndr/kube-vip:v0.3.5
imagePullPolicy: Always
name: kube-vip
resources: {}
securityContext:
capabilities:
add:
- NET_ADMIN
- NET_RAW
- SYS_TIME
hostNetwork: true
nodeSelector:
node-role.kubernetes.io/master: \"true\"
serviceAccountName: kube-vip
tolerations:
- effect: NoSchedule
key: node-role.kubernetes.io/master
updateStrategy: {}
status:
currentNumberScheduled: 0
desiredNumberScheduled: 0
numberMisscheduled: 0
numberReady: 0"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 61 KiB

View File

@@ -1,181 +0,0 @@
# Kube-vip (Layer 2 / ARP)
**BEFORE** we begin we should ensure that ipvs has `strict` ARP enabled:
```
$ kubectl describe configmap -n kube-system kube-proxy | grep ARP
strictARP: false
```
If this is false we can enable it with the command:
```
$ kubectl get configmap kube-proxy -n kube-system -o yaml | \
sed -e "s/strictARP: false/strictARP: true/" | \
kubectl apply -f - -n kube-system
```
and confirm with:
```
$ kubectl describe configmap -n kube-system kube-proxy | grep ARP
strictARP: true
```
## Deploy `kube-vip`
To deploy the [latest] then `kubectl apply -f https://kube-vip.io/manifests/kube-vip.yaml`, specific versions should be found in the repository as detailed below:
From the GitHub repository [https://github.com/kube-vip/kube-vip/tree/master/example/deploy](https://github.com/kube-vip/kube-vip/tree/master/example/deploy) find the version of the `kube-vip` to deploy (although typically the highest version number will provider more functionality/stability). The [raw] option in Github will provide the url that can be applied directly with a `kubectl apply -f <url>`.
The following output should appear when the manifest is applied:
```
serviceaccount/vip created
role.rbac.authorization.k8s.io/vip-role created
rolebinding.rbac.authorization.k8s.io/vip-role-bind created
deployment.apps/kube-vip-cluster created
```
*NOTE* The manifest for the `kube-vip` deployment has rules to ensure affinity (pods are always distributed to different nodes for HA). By default the replicas are set to `3` in the event you have less than `3` worker nodes then those replicas will sit as `pending`. This in itself isn't an issue, it means when new workers are added then they will be scheduled. *However*, tooling such as `kapps` will inspect the manifest before it's applied an error because of issues such as this.
### Editing `kube-vip` configuration
Either download and edit the manifest locally or apply as above and edit the deployment with `kubectl edit deploy/kube-vip-cluster` (change namespace where appropriate `-n`)
```
- name: vip_interface
value: ens192
- name: vip_configmap
value: plndr
- name: vip_arp
value: "true"
- name: vip_loglevel
value: "5"
```
- `vip_interface` - defines the interface that the VIP will bind to
- `vip_configmap` - defines the `configmap` that `kube-vip` will watch for service configuration
- `vip_arp` - determines if ARP broadcasts are enabled
- `vip_loglevel` - determines the verbosity of logging
## Using other namespaces
In this example we'll deploy and load-balance within the namespace `plunder`
### Create the namespace
`kubectl create namespace plunder`
### Add a network range/cidr for this namespace
`kubectl edit -n kube-system configmap/plndr`
We will add the range 192.168.0.210/29 for the namespace plunder underneath the existing range for the namespace default:
```
apiVersion: v1
data:
cidr-default: 192.168.0.200/29
cidr-global: 192.168.0.210/29
cidr-plunder: 192.168.0.220/29
<...>
```
### Deploy `kube-vip` in the namespace **plunder**
In the same way we deployed `kube-vip` into the default namespace we can deploy the same manifest into a different namespace using `-n namespace` e.g.
**Note** change the version of manifest when actually deploying!
```
kubectl apply -f https://kube-vip.io/manifests/kube-vip.yaml -n plunder
```
## Usage
This example will deploy into the namespace `plunder` as mention in the [Using other namespaces](Using other namespaces) example. Remove the `-n plunder` to deploy within the `default` namespace.
### Deploy nginx
```
kubectl create deployment --image nginx plunder-nginx --namespace plunder
```
### Create a load balancer
```
kubectl expose deployment plunder-nginx --port=80 --type=LoadBalancer --namespace plunder
```
## Using DHCP for Load Balancers (experimental)
With the latest release of `kube-vip` > 0.2.1, it is possible to use the local network DHCP server to provide `kube-vip` with a load-balancer address that can be used to access a Kubernetes service on the network.
In order to do this we need to signify to `kube-vip` and the cloud-provider that we don't need one of their managed addresses. We do this by explicitly exposing a service on the address `0.0.0.0`. When `kube-vip` sees a service on this address it will create a `macvlan` interface on the host and request a DHCP address, once this address is provided it will assign it as the VIP and update the Kubernetes service!
```
$ k expose deployment nginx-deployment --port=80 --type=LoadBalancer --name=nginx-dhcp --load-balancer-ip=0.0.0.0; k get svc
service/nginx-dhcp exposed
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 17m
nginx-dhcp LoadBalancer 10.97.150.208 0.0.0.0 80:31184/TCP 0s
{ ... a second or so later ... }
$ k get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 17m
nginx-dhcp LoadBalancer 10.97.150.208 192.168.0.155 80:31184/TCP 3s
```
## Using UPNP to expose a service to the outside world
With the latest release of `kube-vip` > 0.2.1, it is possible to expose a load-balancer on a specific port and using UPNP (on a supported gateway) expose this service to the internet.
Most simple networks look something like the following:
`<----- <internal network 192.168.0.0/24> <Gateway / router> <external network address> ----> Internet`
Using UPNP we can create a matching port on the `<external network address>` allowing your service to be exposed to the internet.
### Enable UPNP
Add the following to the `kube-vip` `env:` section, and the rest should be completely automated.
**Note** some environments may require (Unifi) will require `Secure mode` being `disabled` (this allows a host with a different address to register a port)
```
- name: enableUPNP
value: "true"
```
### Exposing a service
To expose a port successfully we'll need to change the command slightly:
`--target-port=80` the port of the application in the pods (HTT/NGINX)
`--port=32380` the port the service will be exposed on (and what you should connect to in order to receive traffic from the service)
`kubectl expose deployment plunder-nginx --port=32380 --target-port=80 --type=LoadBalancer --namespace plunder`
The above example should expose a port on your external (internet facing address), that can be tested externally with:
```
$ curl externalIP:32380
<!DOCTYPE html>
<html>
...
```
## Troubleshooting
Typically the logs from the `kube-vip` controller will reveal the most clues as to where a problem may lie.
The `ClusterRoleBinding` is missing will result in the following:
```
E0229 17:36:38.014351 1 retrywatcher.go:129] Watch failed: unknown (get endpoints)
E0229 17:36:38.014352 1 retrywatcher.go:129] Watch failed: unknown (get endpoints)
```
Additionally ensure that the vip_interface matches the correct interface from `ip addr`

View File

@@ -1,87 +0,0 @@
# Kube-vip (Layer 3 / BGP)
## Deploy `kube-vip`
To deploy the [latest] then `kubectl apply -f https://kube-vip.io/manifests/kube-vip.yaml`, specific versions should be found in the repository as detailed below:
From the GitHub repository [https://github.com/kube-vip/kube-vip/tree/master/example/deploy](https://github.com/kube-vip/kube-vip/tree/master/example/deploy) find the version of the `kube-vip` to deploy (although typically the highest version number will provider more functionality/stability). The [raw] option in Github will provide the url that can be applied directly with a `kubectl apply -f <url>`.
The following output should appear when the manifest is applied:
```
serviceaccount/vip created
role.rbac.authorization.k8s.io/vip-role created
rolebinding.rbac.authorization.k8s.io/vip-role-bind created
deployment.apps/kube-vip-cluster created
```
*NOTE* The manifest for the `kube-vip` deployment has rules to ensure affinity (pods are always distributed to different nodes for HA). By default the replicas are set to `3` in the event you have less than `3` worker nodes then those replicas will sit as `pending`. This in itself isn't an issue, it means when new workers are added then they will be scheduled. *However*, tooling such as `kapps` will inspect the manifest before it's applied an error because of issues such as this.
### Editing `kube-vip` configuration
Either download and edit the manifest locally or apply as above and edit the deployment with `kubectl edit deploy/kube-vip-cluster` (change namespace where appropriate `-n`)
Ensure the `vip_arp` isn't enabled as ARP and BGP can't be used at the same time (today), also that the `vip_interface` is set to localhost (`lo`).
```
- name: vip_interface
value: "lo"
- name: vip_configmap
value: "plndr"
- name: bgp_enable
value: "true"
- name: vip_loglevel
value: "5"
```
### BGP Specific configuration
Additionally for BGP we'll need some configuration details, your local friendly network admin should be able to help here:
```
- name: bgp_routerid
value: "192.168.0.45"
- name: bgp_as
value: "65000"
- name: bgp_peeraddress
value: "10.0.0.1"
- name: bgp_peeras
value: "65522"
```
### BGP on Packet
If you're lucky enough to be running services on Packet then The above BGP information can be found from the API, instead of specifying the above we need to use the following:
```
- name: vip_packet
value: "true"
- name: vip_packetproject
value: "My Project"
- name: PACKET_AUTH_TOKEN
value: "XXYZZYVVY"
```
With the above configuration in place, all `kube-vip` pods will start in active mode and when a service is exposed then all nodes will advertise the VIP to the routers.
## Expose a service
Given that `kube-vip` doesn't know your network (at this point) ask your local friendly network OPs for an address you can advertise. That is the address you can expose to the outside world as shown below!
```
kubectl expose deployment nginx-deployment --port=80 --type=LoadBalancer --name=nginx --load-balancer-ip=1.1.1.1
```
## Expose with packet
Either through the CLI or through the UI, create a public IPv4 EIP address.. and this is the address you can expose through BGP!
```
# packet ip request -p xxx-bbb-ccc -f ams1 -q 1 -t public_ipv4
+-------+---------------+--------+----------------------+
| ID | ADDRESS | PUBLIC | CREATED |
+-------+---------------+--------+----------------------+
| xxxxx | 1.1.1.1 | true | 2020-11-10T15:57:39Z |
+-------+---------------+--------+----------------------+
kubectl expose deployment nginx-deployment --port=80 --type=LoadBalancer --name=nginx --load-balancer-ip=1.1.1.1
```

View File

@@ -1,75 +0,0 @@
# Usage
The below instructions *should just work* on Kubernetes regardless of architecture, Linux as the Operating System is the only requirement.
## The `tl;dr` guide
If you just want things to "work", then you can quickly install the "latest" components:
**NOTE** the `kube-vip.yaml` may need customising to set ARP/BGP OR to configure which interface to bind VIPs too.
**Install the `plndr-cloud-provider`, and `kube-vip`**
```
kubectl apply -f https://kube-vip.io/manifests/controller.yaml
kubectl apply -f https://kube-vip.io/manifests/kube-vip.yaml
```
**Create the `cidr` for the `global` namespace**
```
kubectl create configmap --namespace kube-system plndr --from-literal cidr-global=192.168.0.200/29
```
Creating services of `type: LoadBalancer` in the default namespace will now take addresses from the **global** cidr defined in the `configmap`.
**Additional namespaces**
Edit the `configmap` and add in the cidr ranges for those namespaces, the key in the cidr should be `cidr-<namespace>`, then ensure that `kube-vip` is deployed into that namespace with the above `apply` command with the `-n namespace` flag.
## The Detailed guide
### Deploy the `plndr-cloud-provider`
To deploy the [latest] then `kubectl apply -f https://kube-vip.io/manifests/controller.yaml`, specific versions should be found in the repository as detailed below:
From the GitHub repository [https://github.com/kube-vip/plndr-cloud-provider/tree/master/example/pod](https://github.com/kube-vip/plndr-cloud-provider/tree/master/example/pod), find the version of the plunder cloud provider manifest (although typically the highest version number will provider more functionality/stability). The [raw] option in Github will provide the url that can be applied directly with a `kubectl apply -f <url>`.
The following output should appear when the manifest is applied:
```
serviceaccount/plunder-cloud-controller created
clusterrole.rbac.authorization.k8s.io/system:plunder-cloud-controller-role created
clusterrolebinding.rbac.authorization.k8s.io/system:plunder-cloud-controller-binding created
pod/plndr-cloud-provider created
```
We can validate the cloud-provider by examining the pods:
`kubectl logs -n kube-system plndr-cloud-provider-0 -f`
#### The `plndr-cloud-provider` `configmap`
The `configmap` details a CIDR range *per* namespace, however as of (`kube-vip 0.2.1` and `plnder-cloud-provider 0.1.4`), there is now the option of having a **global** CIDR range (`cidr-global)`.
To manage the ranges for the load-balancer instances, the `plndr-cloud-provider` has a `configmap` held in the `kube-system` namespace. The structure for the key/values within the `configmap` should be that the key is in the format `cidr-<namespace>` and the value should be the cidr range.
Example Configmap:
```
apiVersion: v1
kind: ConfigMap
metadata:
name: plndr
namespace: kube-system
data:
cidr-default: 192.168.0.200/29
cidr-global: 192.168.0.210/29
```
### Deploying `kube-vip`
To use `kube-vip` in Layer2/ARP the follow this [guide](/kubernetes/arp/)
To use `kube-vip` in Layer3/BGP the follow this [guide](/kubernetes/bgp/)

View File

@@ -1,63 +0,0 @@
apiVersion: apps/v1
kind: DaemonSet
metadata:
creationTimestamp: null
name: kube-vip-ds
namespace: kube-system
spec:
selector:
matchLabels:
name: kube-vip-ds
template:
metadata:
creationTimestamp: null
labels:
name: kube-vip-ds
spec:
containers:
- args:
- manager
env:
- name: vip_arp
value: "true"
- name: vip_interface
value: eth0
- name: port
value: "6443"
- name: vip_cidr
value: "32"
- name: cp_enable
value: "true"
- name: cp_namespace
value: kube-system
- name: svc_enable
value: "true"
- name: vip_leaderelection
value: "true"
- name: vip_leaseduration
value: "5"
- name: vip_renewdeadline
value: "3"
- name: vip_retryperiod
value: "1"
- name: vip_address
value: 192.168.0.1
image: plndr/kube-vip:0.3.1
imagePullPolicy: Always
name: kube-vip
resources: {}
securityContext:
capabilities:
add:
- NET_ADMIN
- NET_RAW
- SYS_TIME
hostNetwork: true
serviceAccountName: kube-vip
updateStrategy: {}
status:
currentNumberScheduled: 0
desiredNumberScheduled: 0
numberMisscheduled: 0
numberReady: 0

View File

@@ -1,72 +0,0 @@
apiVersion: apps/v1
kind: DaemonSet
metadata:
creationTimestamp: null
name: kube-vip-ds
namespace: kube-system
spec:
selector:
matchLabels:
name: kube-vip-ds
template:
metadata:
creationTimestamp: null
labels:
name: kube-vip-ds
spec:
containers:
- args:
- manager
env:
- name: vip_arp
value: "false"
- name: vip_interface
value: eth0
- name: port
value: "6443"
- name: vip_cidr
value: "32"
- name: cp_enable
value: "true"
- name: cp_namespace
value: kube-system
- name: svc_enable
value: "true"
- name: vip_leaderelection
value: "true"
- name: vip_leaseduration
value: "5"
- name: vip_renewdeadline
value: "3"
- name: vip_retryperiod
value: "1"
- name: bgp_enable
value: "true"
- name: bgp_routerid
- name: bgp_as
value: "65000"
- name: bgp_peeraddress
- name: bgp_peerpass
- name: bgp_peeras
value: "65000"
- name: vip_address
value: 192.168.0.1
image: plndr/kube-vip:0.3.1
imagePullPolicy: Always
name: kube-vip
resources: {}
securityContext:
capabilities:
add:
- NET_ADMIN
- NET_RAW
- SYS_TIME
hostNetwork: true
serviceAccountName: kube-vip
updateStrategy: {}
status:
currentNumberScheduled: 0
desiredNumberScheduled: 0
numberMisscheduled: 0
numberReady: 0

View File

@@ -1,82 +0,0 @@
apiVersion: apps/v1
kind: DaemonSet
metadata:
creationTimestamp: null
name: kube-vip-ds
namespace: kube-system
spec:
selector:
matchLabels:
name: kube-vip-ds
template:
metadata:
creationTimestamp: null
labels:
name: kube-vip-ds
spec:
containers:
- args:
- manager
env:
- name: vip_arp
value: "false"
- name: vip_interface
value: lo
- name: port
value: "6443"
- name: vip_cidr
value: "32"
- name: cp_enable
value: "false"
- name: cp_namespace
value: kube-system
- name: svc_enable
value: "true"
- name: vip_leaderelection
value: "true"
- name: vip_leaseduration
value: "5"
- name: vip_renewdeadline
value: "3"
- name: vip_retryperiod
value: "1"
- name: provider_config
value: /etc/cloud-sa/cloud-sa.json
- name: bgp_enable
value: "true"
- name: bgp_routerid
- name: bgp_as
value: "65000"
- name: bgp_peeraddress
- name: bgp_peerpass
- name: bgp_peeras
value: "65000"
- name: vip_address
value: 192.168.0.1
image: plndr/kube-vip:0.3.1
imagePullPolicy: Always
name: kube-vip
resources: {}
securityContext:
capabilities:
add:
- NET_ADMIN
- NET_RAW
- SYS_TIME
volumeMounts:
- mountPath: /etc/cloud-sa
name: cloud-sa-volume
readOnly: true
hostNetwork: true
serviceAccountName: kube-vip
volumes:
- name: cloud-sa-volume
secret:
secretName: packet-cloud-config
updateStrategy: {}
status:
currentNumberScheduled: 0
desiredNumberScheduled: 0
numberMisscheduled: 0
numberReady: 0

View File

@@ -1,62 +0,0 @@
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
name: kube-vip
namespace: kube-system
spec:
containers:
- args:
- manager
env:
- name: vip_arp
value: "false"
- name: vip_interface
value: eth0
- name: port
value: "6443"
- name: vip_cidr
value: "32"
- name: cp_enable
value: "true"
- name: cp_namespace
value: kube-system
- name: svc_enable
value: "true"
- name: vip_startleader
value: "false"
- name: vip_addpeerstolb
value: "true"
- name: vip_localpeer
value: code:192.168.0.22:10000
- name: bgp_enable
value: "true"
- name: bgp_routerid
- name: bgp_as
value: "65000"
- name: bgp_peeraddress
- name: bgp_peerpass
- name: bgp_peeras
value: "65000"
- name: vip_address
value: 192.168.0.1
image: plndr/kube-vip:0.3.1
imagePullPolicy: Always
name: kube-vip
resources: {}
securityContext:
capabilities:
add:
- NET_ADMIN
- NET_RAW
- SYS_TIME
volumeMounts:
- mountPath: /etc/kubernetes/admin.conf
name: kubeconfig
hostNetwork: true
volumes:
- hostPath:
path: /etc/kubernetes/admin.conf
name: kubeconfig
status: {}

View File

@@ -1,70 +0,0 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: kube-vip-cloud-controller
namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
annotations:
rbac.authorization.kubernetes.io/autoupdate: "true"
name: system:kube-vip-cloud-controller-role
rules:
- apiGroups: ["coordination.k8s.io"]
resources: ["leases"]
verbs: ["get", "create", "update", "list", "put"]
- apiGroups: [""]
resources: ["configmaps", "endpoints","events","services/status", "leases"]
verbs: ["*"]
- apiGroups: [""]
resources: ["nodes", "services"]
verbs: ["list","get","watch","update"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: system:kube-vip-cloud-controller-binding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:kube-vip-cloud-controller-role
subjects:
- kind: ServiceAccount
name: kube-vip-cloud-controller
namespace: kube-system
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: kube-vip-cloud-provider
namespace: kube-system
spec:
serviceName: kube-vip-cloud-provider
podManagementPolicy: OrderedReady
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
app: kube-vip
component: kube-vip-cloud-provider
template:
metadata:
labels:
app: kube-vip
component: kube-vip-cloud-provider
spec:
containers:
- command:
- /kube-vip-cloud-provider
- --leader-elect-resource-name=kube-vip-cloud-controller
image: kubevip/kube-vip-cloud-provider:latest
name: kube-vip-cloud-provider
imagePullPolicy: Always
resources: {}
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30
serviceAccountName: kube-vip-cloud-controller

View File

@@ -1,85 +0,0 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: kube-vip
namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
annotations:
rbac.authorization.kubernetes.io/autoupdate: "true"
name: system:kube-vip-role
rules:
- apiGroups: ["coordination.k8s.io"]
resources: ["leases"]
verbs: ["get", "create", "update", "list", "put"]
- apiGroups: [""]
resources: ["services"]
verbs: ["list","get","watch", "update"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: system:kube-vip-binding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:kube-vip-role
subjects:
- kind: ServiceAccount
name: kube-vip
namespace: kube-system
---
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: kube-vip-workers
name: kube-vip-workers
namespace: kube-system
spec:
replicas: 3
selector:
matchLabels:
app: kube-vip-workers
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: kube-vip-workers
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: "app"
operator: In
values:
- kube-vip-workers
topologyKey: "kubernetes.io/hostname"
containers:
- image: plndr/kube-vip:0.2.2
imagePullPolicy: Always
name: kube-vip
command:
- /kube-vip
- service
env:
- name: vip_interface
value: "ens160"
- name: vip_arp
value: "true"
- name: vip_loglevel
value: "5"
resources: {}
securityContext:
capabilities:
add:
- NET_ADMIN
hostNetwork: true
serviceAccountName: kube-vip
status: {}

View File

@@ -1,90 +0,0 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: kube-vip
namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
annotations:
rbac.authorization.kubernetes.io/autoupdate: "true"
name: system:kube-vip-role
rules:
- apiGroups: [""]
resources: ["services"]
verbs: ["list","get","watch", "update"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: system:kube-vip-binding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:kube-vip-role
subjects:
- kind: ServiceAccount
name: kube-vip
namespace: kube-system
---
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: kube-vip-workers
name: kube-vip-workers
namespace: kube-system
spec:
replicas: 3
selector:
matchLabels:
app: kube-vip-workers
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: kube-vip-workers
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: "app"
operator: In
values:
- kube-vip-workers
topologyKey: "kubernetes.io/hostname"
containers:
- image: plndr/kube-vip:0.2.2
imagePullPolicy: Always
name: kube-vip
command:
- /kube-vip
- service
env:
- name: vip_interface
value: "lo"
- name: bgp_enable
value: "true"
- name: vip_loglevel
value: "5"
- name: bgp_routerinterface
value: "ens160"
- name: bgp_as
value: "64512"
- name: bgp_peeraddress
value: "192.168.0.1"
- name: bgp_peeras
value: "64512"
resources: {}
securityContext:
capabilities:
add:
- NET_ADMIN
hostNetwork: true
serviceAccountName: kube-vip
status: {}

View File

@@ -1,91 +0,0 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: kube-vip
namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
annotations:
rbac.authorization.kubernetes.io/autoupdate: "true"
name: system:kube-vip-role
rules:
- apiGroups: [""]
resources: ["services", "services/status"]
verbs: ["list","get","watch", "update"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: system:kube-vip-binding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:kube-vip-role
subjects:
- kind: ServiceAccount
name: kube-vip
namespace: kube-system
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
creationTimestamp: null
name: kube-vip-ds
namespace: kube-system
spec:
selector:
matchLabels:
name: kube-vip-ds
template:
metadata:
creationTimestamp: null
labels:
name: kube-vip-ds
spec:
containers:
- args:
- manager
env:
- name: vip_arp
value: "false"
- name: vip_interface
value: lo
- name: port
value: "6443"
- name: vip_cidr
value: "32"
- name: svc_enable
value: "true"
- name: provider_config
value: /etc/cloud-sa/cloud-sa.json
- name: vip_packet
value: "true"
- name: bgp_enable
value: "true"
image: plndr/kube-vip:0.2.3
imagePullPolicy: Always
name: kube-vip
resources: {}
securityContext:
capabilities:
add:
- NET_ADMIN
- SYS_TIME
volumeMounts:
- mountPath: /etc/cloud-sa
name: cloud-sa-volume
readOnly: true
hostNetwork: true
serviceAccountName: kube-vip
volumes:
- name: cloud-sa-volume
secret:
secretName: packet-cloud-config
updateStrategy: {}
status:
currentNumberScheduled: 0
desiredNumberScheduled: 0
numberMisscheduled: 0
numberReady: 0

View File

@@ -1,83 +0,0 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: vip
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: vip-role
rules:
- apiGroups: ["coordination.k8s.io"]
resources: ["leases"]
verbs: ["get", "create", "update", "list", "put"]
- apiGroups: [""]
resources: ["configmaps", "endpoints"]
verbs: ["watch", "get"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: vip-role-bind
subjects:
- kind: ServiceAccount
name: vip
apiGroup: ""
roleRef:
kind: Role
name: vip-role
apiGroup: ""
---
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: kube-vip-cluster
name: kube-vip-cluster
spec:
replicas: 3
selector:
matchLabels:
app: kube-vip-cluster
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: kube-vip-cluster
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: "app"
operator: In
values:
- kube-vip-cluster
topologyKey: "kubernetes.io/hostname"
containers:
- image: plndr/kube-vip:0.1.3
imagePullPolicy: Always
name: kube-vip
command:
- /kube-vip
- service
env:
- name: vip_interface
value: "ens192"
- name: vip_configmap
value: "plndr"
- name: vip_arp
value: "true"
- name: vip_loglevel
value: "5"
resources: {}
securityContext:
capabilities:
add:
- NET_ADMIN
hostNetwork: true
serviceAccountName: vip
status: {}

View File

@@ -1,32 +0,0 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: kube-vip
namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
annotations:
rbac.authorization.kubernetes.io/autoupdate: "true"
name: system:kube-vip-role
rules:
- apiGroups: [""]
resources: ["services", "services/status", "nodes"]
verbs: ["list","get","watch", "update"]
- apiGroups: ["coordination.k8s.io"]
resources: ["leases"]
verbs: ["list", "get", "watch", "update", "create"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: system:kube-vip-binding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:kube-vip-role
subjects:
- kind: ServiceAccount
name: kube-vip
namespace: kube-system

View File

@@ -1,9 +0,0 @@
#!/bin/bash
echo Deploying updated documentation
# Sleep for dramatic purposes!
sleep 5
generate-md --layout github --input ./ --output /var/www/kube-vip/

View File

@@ -1,114 +0,0 @@
# Equinix Metal Overview (using the [Equinix Metal CCM](https://github.com/packethost/packet-ccm))
## BGP with Equinix Metal
When deploying Kubernetes with Equinix Metal with the `--controlplane` functionality we need to pre-populate the BGP configuration in order for the control plane to be advertised and work in a HA scenario. Luckily Equinix Metal provides the capability to "look up" the configuration details (for BGP) that we need in order to advertise our virtual IP for HA functionality. We can either make use of the [Equinix Metal API](https://metal.equinix.com/developers/api/) or we can parse the [Equinix Metal Metadata service](https://metal.equinix.com/developers/docs/servers/metadata/).
**Note** If this cluster will be making use of Equinix Metal for `type:LoadBalancer` (by using the [Equinix Metal CCM](https://github.com/packethost/packet-ccm)) then we will need to ensure that nodes are set to use an external cloud-provider. Before doing a `kubeadm init|join` ensure the kubelet has the correct flags by using the following command `echo KUBELET_EXTRA_ARGS=\"--cloud-provider=external\" > /etc/default/kubelet`.
## Creating HA clusters in Equinix Metal
### Creating a manifest using the API
We can enable `kube-vip` with the capability to discover the required configuration for BGP by passing the `--metal` flag and the API Key and our project ID.
```
kube-vip manifest pod \
--interface $INTERFACE\
--vip $VIP \
--controlplane \
--services \
--bgp \
--metal \
--metalKey xxxxxxx \
--metalProjectID xxxxx | tee /etc/kubernetes/manifests/kube-vip.yaml
```
### Creating a manifest using the metadata
We can parse the metadata, *however* it requires that the tools `curl` and `jq` are installed.
```
kube-vip manifest pod \
--interface $INTERFACE\
--vip $VIP \
--controlplane \
--services \
--bgp \
--peerAS $(curl https://metadata.platformequinix.com/metadata | jq '.bgp_neighbors[0].peer_as') \
--peerAddress $(curl https://metadata.platformequinix.com/metadata | jq -r '.bgp_neighbors[0].peer_ips[0]') \
--localAS $(curl https://metadata.platformequinix.com/metadata | jq '.bgp_neighbors[0].customer_as') \
--bgpRouterID $(curl https://metadata.platformequinix.com/metadata | jq -r '.bgp_neighbors[0].customer_ip') | sudo tee /etc/kubernetes/manifests/vip.yaml
```
## Load Balancing servies on Equinix Metal
Below are two examples for running `type:LoadBalancer` services on worker nodes only and will create a daemonset that will run `kube-vip`.
**NOTE** This use-case requires the [Equinix Metal CCM](https://github.com/packethost/packet-ccm) to be installed and that the cluster/kubelet is configured to use an "external" cloud provider.
### Using Annotations
This is important as the CCM will apply the BGP configuration to the [node annotations](https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/) making it easy for `kube-vip` to find the networking configuration it needs to expose load balancer addresses. The `--annotations metal.equinix.com` will cause kube-vip to "watch" the annotations of the worker node that it is running on, once all of the configuarion has been applied by the CCM then the `kube-vip` pod is ready to advertise BGP addresses for the service.
```
kube-vip manifest daemonset \
--interface $INTERFACE \
--services \
--bgp \
--annotations metal.equinix.com \
--inCluster | k apply -f -
```
### Using the existing CCM secret
Alternatively it is possible to create a daemonset that will use the existing CCM secret to do an API lookup, this will allow for discovering the networking configuration needed to advertise loadbalancer addresses through BGP.
```
kube-vip manifest daemonset --interface $INTERFACE \
--services \
--inCluster \
--bgp \
--metal \
--provider-config /etc/cloud-sa/cloud-sa.json | kubectl apply -f -
```
### Expose with Equinix Metal (using the `kube-vip-cloud-provider`)
Either through the CLI or through the UI, create a public IPv4 EIP address.. and this is the address you can expose through BGP!
```
# packet ip request -p xxx-bbb-ccc -f ams1 -q 1 -t public_ipv4
+-------+---------------+--------+----------------------+
| ID | ADDRESS | PUBLIC | CREATED |
+-------+---------------+--------+----------------------+
| xxxxx | 1.1.1.1 | true | 2020-11-10T15:57:39Z |
+-------+---------------+--------+----------------------+
kubectl expose deployment nginx-deployment --port=80 --type=LoadBalancer --name=nginx --load-balancer-ip=1.1.1.1
```
## Troubleshooting
If `kube-vip` has been sat waiting for a long time then you may need to investigate that the annotations have been applied correctly by doing running the `describe` on the node:
```
kubectl describe node k8s.bgp02
...
Annotations: kubeadm.alpha.kubernetes.io/cri-socket: /var/run/dockershim.sock
node.alpha.kubernetes.io/ttl: 0
metal.equinix.com/node-asn: 65000
metal.equinix.com/peer-asn: 65530
metal.equinix.com/peer-ip: x.x.x.x
metal.equinix.com/src-ip: x.x.x.x
```
If there are errors regarding `169.254.255.1` or `169.254.255.2` in the `kube-vip` logs then the routes to the ToR switches that provide BGP peering may by missing from the nodes. They can be replaced with the below command:
```
GATEWAY_IP=$(curl https://metadata.platformequinix.com/metadata | jq -r ".network.addresses[] | select(.public == false) | .gateway")
ip route add 169.254.255.1 via $GATEWAY_IP
ip route add 169.254.255.2 via $GATEWAY_IP
```
Additionally examining the logs of the Packet CCM may reveal why the node is not yet ready.

View File

@@ -1,82 +0,0 @@
# K3s overview (on Equinix Metal)
## Optional Tidy environment (best if something was running before)
```
rm -rf /var/lib/rancher /etc/rancher ~/.kube/*; \
ip addr flush dev lo; \
ip addr add 127.0.0.1/8 dev lo;
```
## Step 1: Create Manifests folder
This is required, this folder will contain all of the generated manifests that `k3s` will execute as it starts. We will create it before `k3s` and place our `kube-vip` manifests within it.
```
mkdir -p /var/lib/rancher/k3s/server/manifests/
```
## Step 2: Get rbac for `Kube-Vip`
As `kube-vip` runs inside of the Kubernetes cluster, we will need to ensure that the required permissions exist.
```
curl https://kube-vip.io/manifests/rbac.yaml > /var/lib/rancher/k3s/server/manifests/rbac.yaml
```
## Step 3: Generate kube-vip (A VIP address for the network will be required)
Configure your virtual IP (for the control plane) and interface that will expose this VIP first.
```
export VIP=x.x.x.x
export INTERFACE=ethx
```
Modify the `VIP` and `INTERFACE` to match the floating IP address you'd like to use and the interface it should bind to.
To generate the manifest we have two options! We can generate the manifest from [kube-vip.io](kube-vip.io) or use a kube-vip image to generate the manifest!
## Step 3.1: Generate from kube-vip.io
```
curl -sL kube-vip.io/k3s | vipAddress=$VIP vipInterface=$INTERFACE sh | sudo tee /var/lib/rancher/k3s/server/manifests/vip.yaml
```
## Step 3.2 Genereate from container image
### containerd
`alias kube-vip="ctr run --rm --net-host docker.io/plndr/kube-vip:0.3.1 vip /kube-vip"`
### Docker
`alias kube-vip="docker run --network host --rm plndr/kube-vip:0.3.1"`
```
kube-vip manifest daemonset \
--interface $INTERFACE \
--vip $VIP \
--controlplane \
--services \
--inCluster \
--taint \
--arp
```
## Step 4: Up Cluster
From online `-->`
```
curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="--write-kubeconfig-mode 644 \
-t agent-secret --tls-san $VIP" sh -
```
From local `-->`
```
sudo ./k3s server --tls-san $VIP
```
## Step 5: Service Load-Balancing
For this refer to the [on-prem](../on-prem) documentation

View File

@@ -1,57 +0,0 @@
# Kube-vip on KIND
## Deploying KIND
The documentation for KIND is fantastic and it's quickstart guide will have you up and running in no time -> [https://kind.sigs.k8s.io/docs/user/quick-start/](https://kind.sigs.k8s.io/docs/user/quick-start/)
## Find Address Pool for Kube-Vip
We will need to find addresses that can be used by Kube-Vip:
```
docker network inspect kind -f '{{ range $i, $a := .IPAM.Config }}{{ println .Subnet }}{{ end }}'
```
This will return a cidr range such as `172.18.0.0/16` and from here we can select a range.
## Deploy the Kube-Vip Cloud Controller
```
$ kubectl apply -f https://raw.githubusercontent.com/kube-vip/kube-vip-cloud-provider/main/manifest/kube-vip-cloud-controller.yaml
```
## Add our Address range
```
kubectl create configmap --namespace kube-system kubevip --from-literal range-global=172.18.100.10-172.18.100.30
```
## Install kube-vip
Set the correct `alias` for `kube-vip`
```
alias kube-vip="docker run --network host --rm plndr/kube-vip:v0.3.5"
```
Install Kube-vip deamonset inside of KIND
```
kube-vip manifest daemonset --services --inCluster --arp --interface eth0 | ./kubectl apply -f -
```
## Test
```
kubectl apply -f https://k8s.io/examples/application/deployment.yaml
```
```
kubectl expose deployment nginx-deployment --port=80 --type=LoadBalancer --name=nginx
```
```
kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 74m
nginx LoadBalancer 10.96.196.235 172.18.100.11 80:31236/TCP 6s
```

View File

@@ -1,222 +0,0 @@
# Kube-vip on-prem
We've designed `kube-vip` to be as de-coupled or agnostic from other components that may exist within a Kubernetes cluster as possible. This has lead to `kube-vip` having a very simplistic but robust approach to advertising Kubernetes services to the outside world and marking these services as ready to use.
## Flow
This section details the flow of events in order for `kube-vip` to advertise a Kubernetes service:
1. An end user exposes a application through Kubernetes as a LoadBalancer => `kubectl expose deployment nginx-deployment --port=80 --type=LoadBalancer --name=nginx`
2. Within the Kubernetes cluster a service object is created with the `svc.Spec.Type = ServiceTypeLoadBalancer`
3. A controller (typically a Cloud Controller) has a loop that "watches" for services of the type `LoadBalancer`.
4. The controller now has the responsibility of providing an IP address for this service along with doing anything that is network specific for the environment where the cluster is running.
5. Once the controller has an IP address it will update the service `svc.Spec.LoadBalancerIP` with it's new IP address.
6. The `kube-vip` pods also implement a "watcher" for services that have a `svc.Spec.LoadBalancerIP` address attached.
7. When a new service appears `kube-vip` will start advertising this address to the wider network (through BGP/ARP) which will allow traffic to come into the cluster and hit the service network.
8. Finally `kube-vip` will update the service status so that the API reflects that this LoadBalancer is ready. This is done by updating the `svc.Status.LoadBalancer.Ingress` with the VIP address.
## CCM
We can see from the [flow](#Flow) above that `kube-vip` isn't coupled to anything other than the Kubernetes API, and will only act upon an existing Kubernetes primative (in this case the object of type `Service`). This makes it easy for existing CCMs to simply apply their logic to services of type LoadBalancer and leave `kube-vip` to take the next steps to advertise these load-balancers to the outside world.
## Using the Kube-vip Cloud Provider
The below instructions *should just work* on Kubernetes regardless of architecture (Linux Operating System is the only requirement) - you can quickly install the "latest" components:
**Install the `kube-vip-cloud-provider`**
```
$ kubectl apply -f https://raw.githubusercontent.com/kube-vip/kube-vip-cloud-provider/main/manifest/kube-vip-cloud-controller.yaml
```
It uses a `statefulSet` and can always be viewed with the following command:
```
kubectl describe pods -n kube-system kube-vip-cloud-provider-0
```
**Create a global CIDR or IP Range**
Any `service` in any `namespace` can use an address from the global CIDR `cidr-global` or range `range-global`
```
kubectl create configmap --namespace kube-system kubevip --from-literal cidr-global=192.168.0.220/29
```
or
```
kubectl create configmap --namespace kube-system kubevip --from-literal range-global=192.168.1.220-192.168.1.230
```
Creating services of `type: LoadBalancer` in *any namespace* will now take addresses from the **global** cidr defined in the `configmap` unless a specific
## The Detailed guide
### Deploy the Kube-vip Cloud Provider
**Install the `kube-vip-cloud-provider`**
```
$ kubectl apply -f https://raw.githubusercontent.com/kube-vip/kube-vip-cloud-provider/main/manifest/kube-vip-cloud-controller.yaml
```
The following output should appear when the manifest is applied:
```
serviceaccount/kube-vip-cloud-controller created
clusterrole.rbac.authorization.k8s.io/system:kube-vip-cloud-controller-role created
clusterrolebinding.rbac.authorization.k8s.io/system:kube-vip-cloud-controller-binding created
statefulset.apps/kube-vip-cloud-provider created
```
We can validate the cloud provider by examining the pods and following the logs:
```
kubectl describe pods -n kube-system kube-vip-cloud-provider-0
kubectl logs -n kube-system kube-vip-cloud-provider-0 -f
```
### The Kube-vip Cloud Provider `configmap`
To manage the IP address ranges for the load balancer instances the `kube-vip-cloud-provider` uses a `configmap` held in the `kube-system` namespace. IP address ranges can be configured using:
- IP address pools by CIDR
- IP ranges [start address - end address]
- Multiple pools by CIDR per namespace
- Multiple IP ranges per namespace (handles overlapping ranges)
- Setting of static addresses through --load-balancer-ip=x.x.x.x
To control which IP address range is used for which service the following rules are applied:
- Global address pools (`cidr-global` or `range-global`) are available for use by *any* `service` in *any* `namespace`
- Namespace specific address pools (`cidr-<namespace>` or `range-<namespace>`) are *only* available for use by `service` in the *specific* `namespace`
- Static IP addresses can be applied to a load balancer `service` using the `loadbalancerIP` setting, even outside of the assigned ranges
Example Configmap:
```
$ kubectl get configmap -n kube-system kubevip -o yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: kubevip
namespace: kube-system
data:
cidr-default: 192.168.0.200/29 # CIDR-based IP range for use in the default namespace
range-development: 192.168.0.210-192.168.0.219 # Range-based IP range for use in the development namespace
cidr-finance: 192.168.0.220/29,192.168.0.230/29 # Multiple CIDR-based ranges for use in the finance namespace
cidr-global: 192.168.0.240/29 # CIDR-based range which can be used in any namespace
```
### Expose a service
We can now expose a service and once the cloud provider has provided an address `kube-vip` will start to advertise that address to the outside world as shown below!
```
kubectl expose deployment nginx-deployment --port=80 --type=LoadBalancer --name=nginx
```
or via a `service` YAML definition
```
apiVersion: v1
kind: Service
metadata:
name: nginx
spec:
ports:
- name: http
port: 80
protocol: TCP
selector:
app: nginx
type: LoadBalancer
```
We can also expose a specific address by specifying it on the command line:
```
kubectl expose deployment nginx-deployment --port=80 --type=LoadBalancer --name=nginx --load-balancer-ip=1.1.1.1
```
or including it in the `service` definition:
```
apiVersion: v1
kind: Service
metadata:
name: nginx
spec:
ports:
- name: http
port: 80
protocol: TCP
selector:
app: nginx
type: LoadBalancer
loadBalancerIP: "1.1.1.1"
```
### Using DHCP for Load Balancers (experimental)
With the latest release of `kube-vip` > 0.2.1, it is possible to use the local network DHCP server to provide `kube-vip` with a load-balancer address that can be used to access a
Kubernetes service on the network.
In order to do this we need to signify to `kube-vip` and the cloud-provider that we don't need one of their managed addresses. We do this by explicitly exposing a service on the
address `0.0.0.0`. When `kube-vip` sees a service on this address it will create a `macvlan` interface on the host and request a DHCP address, once this address is provided it will assign it as the VIP and update the Kubernetes service!
```
$ k expose deployment nginx-deployment --port=80 --type=LoadBalancer --name=nginx-dhcp --load-balancer-ip=0.0.0.0; k get svc
service/nginx-dhcp exposed
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 17m
nginx-dhcp LoadBalancer 10.97.150.208 0.0.0.0 80:31184/TCP 0s
{ ... a second or so later ... }
$ k get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 17m
nginx-dhcp LoadBalancer 10.97.150.208 192.168.0.155 80:31184/TCP 3s
```
### Using UPNP to expose a service to the outside world
With the latest release of `kube-vip` > 0.2.1, it is possible to expose a load-balancer on a specific port and using UPNP (on a supported gateway) expose this service to the inte
rnet.
Most simple networks look something like the following:
`<----- <internal network 192.168.0.0/24> <Gateway / router> <external network address> ----> Internet`
Using UPNP we can create a matching port on the `<external network address>` allowing your service to be exposed to the internet.
#### Enable UPNP
Add the following to the `kube-vip` `env:` section, and the rest should be completely automated.
**Note** some environments may require (Unifi) will require `Secure mode` being `disabled` (this allows a host with a different address to register a port)
```
- name: enableUPNP
value: "true"
```
#### Exposing a service
To expose a port successfully we'll need to change the command slightly:
`--target-port=80` the port of the application in the pods (HTT/NGINX)
`--port=32380` the port the service will be exposed on (and what you should connect to in order to receive traffic from the service)
`kubectl expose deployment plunder-nginx --port=32380 --target-port=80 --type=LoadBalancer --namespace plunder`
The above example should expose a port on your external (internet facing address), that can be tested externally with:
```
$ curl externalIP:32380
<!DOCTYPE html>
<html>
...
```

View File

@@ -1,74 +0,0 @@
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: kube-vip-cluster
name: kube-vip-cluster
spec:
replicas: 3
selector:
matchLabels:
app: kube-vip-cluster
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: kube-vip-cluster
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: "app"
operator: In
values:
- kube-vip-cluster
topologyKey: "kubernetes.io/hostname"
containers:
- image: plndr/kube-vip:0.1.2
imagePullPolicy: Always
name: kube-vip
command:
- /kube-vip
- service
- --configMap
- plndr-configmap
- --arp
- --interface
- ens192
- --log
- "5"
resources: {}
securityContext:
capabilities:
add:
- NET_ADMIN
hostNetwork: true
status: {}
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: lease-access
rules:
- apiGroups: ["coordination.k8s.io"]
resources: ["leases"]
verbs: ["get", "create", "update", "list", "put"]
- apiGroups: [""]
resources: ["configMap"]
verbs: ["get"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: lease-access
subjects:
- kind: User
name: system:serviceaccount:default:default
roleRef:
kind: Role
name: lease-access
apiGroup: rbac.authorization.k8s.io

View File

@@ -1,83 +0,0 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: vip
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: vip-role
rules:
- apiGroups: ["coordination.k8s.io"]
resources: ["leases"]
verbs: ["get", "create", "update", "list", "put"]
- apiGroups: [""]
resources: ["configmaps", "endpoints"]
verbs: ["watch", "get"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: vip-role-bind
subjects:
- kind: ServiceAccount
name: vip
apiGroup: ""
roleRef:
kind: Role
name: vip-role
apiGroup: ""
---
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: kube-vip-cluster
name: kube-vip-cluster
spec:
replicas: 3
selector:
matchLabels:
app: kube-vip-cluster
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: kube-vip-cluster
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: "app"
operator: In
values:
- kube-vip-cluster
topologyKey: "kubernetes.io/hostname"
containers:
- image: plndr/kube-vip:0.1.3
imagePullPolicy: Always
name: kube-vip
command:
- /kube-vip
- service
env:
- name: vip_interface
value: "ens192"
- name: vip_configmap
value: "plndr"
- name: vip_arp
value: "true"
- name: vip_loglevel
value: "5"
resources: {}
securityContext:
capabilities:
add:
- NET_ADMIN
hostNetwork: true
serviceAccountName: vip
status: {}

View File

@@ -1,83 +0,0 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: vip
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: vip-role
rules:
- apiGroups: ["coordination.k8s.io"]
resources: ["leases"]
verbs: ["get", "create", "update", "list", "put"]
- apiGroups: [""]
resources: ["configmaps", "endpoints"]
verbs: ["watch", "get"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: vip-role-bind
subjects:
- kind: ServiceAccount
name: vip
apiGroup: ""
roleRef:
kind: Role
name: vip-role
apiGroup: ""
---
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: kube-vip-cluster
name: kube-vip-cluster
spec:
replicas: 3
selector:
matchLabels:
app: kube-vip-cluster
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: kube-vip-cluster
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: "app"
operator: In
values:
- kube-vip-cluster
topologyKey: "kubernetes.io/hostname"
containers:
- image: plndr/kube-vip:0.1.4
imagePullPolicy: Always
name: kube-vip
command:
- /kube-vip
- service
env:
- name: vip_interface
value: "ens192"
- name: vip_configmap
value: "plndr"
- name: vip_arp
value: "true"
- name: vip_loglevel
value: "5"
resources: {}
securityContext:
capabilities:
add:
- NET_ADMIN
hostNetwork: true
serviceAccountName: vip
status: {}

View File

@@ -1,55 +0,0 @@
apiVersion: apps/v1
kind: DaemonSet
metadata:
creationTimestamp: null
name: kube-vip-ds
namespace: kube-system
spec:
selector:
matchLabels:
name: kube-vip-ds
template:
metadata:
creationTimestamp: null
labels:
name: kube-vip-ds
spec:
containers:
- args:
- manager
env:
- name: vip_arp
value: "true"
- name: vip_interface
value: eth0
- name: port
value: "6443"
- name: vip_cidr
value: "32"
- name: svc_enable
value: "true"
- name: vip_startleader
value: "false"
- name: vip_addpeerstolb
value: "true"
- name: vip_localpeer
value: ip-172-20-40-207:172.20.40.207:10000
- name: vip_address
image: plndr/kube-vip:v0.3.5
imagePullPolicy: Always
name: kube-vip
resources: {}
securityContext:
capabilities:
add:
- NET_ADMIN
- NET_RAW
- SYS_TIME
hostNetwork: true
serviceAccountName: kube-vip
updateStrategy: {}
status:
currentNumberScheduled: 0
desiredNumberScheduled: 0
numberMisscheduled: 0
numberReady: 0

19
example/deployment.yaml Normal file
View File

@@ -0,0 +1,19 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80

View File

@@ -0,0 +1,15 @@
apiVersion: v1
kind: Service
metadata:
name: nginx-interface-ens192-service
annotations:
kube-vip.io/serviceInterface: ens192
spec:
selector:
app: nginx
type: LoadBalancer
ports:
- name: http
port: 80
targetPort: 80
protocol: TCP

13
example/service.yaml Normal file
View File

@@ -0,0 +1,13 @@
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx
type: LoadBalancer
ports:
- name: http
port: 80
targetPort: 80
protocol: TCP

204
go.mod
View File

@@ -1,66 +1,154 @@
module github.com/kube-vip/kube-vip
go 1.14
go 1.26.4
require (
github.com/armon/go-metrics v0.3.8 // indirect
github.com/davecgh/go-spew v1.1.1
github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect
github.com/fatih/color v1.10.0 // indirect
github.com/ghodss/yaml v1.0.0
github.com/golang/protobuf v1.5.2
github.com/google/gofuzz v1.2.0 // indirect
github.com/google/uuid v1.2.0 // indirect
github.com/googleapis/gnostic v0.5.5 // indirect
github.com/hashicorp/go-hclog v0.16.0 // indirect
github.com/hashicorp/go-immutable-radix v1.3.0 // indirect
github.com/hashicorp/go-msgpack v1.1.5 // indirect
github.com/hashicorp/golang-lru v0.5.4 // indirect
github.com/hashicorp/raft v1.3.1
github.com/imdario/mergo v0.3.12 // indirect
github.com/insomniacslk/dhcp v0.0.0-20210621130208-1cac67f12b1e
github.com/cloudflare/ipvs v0.12.0
github.com/containernetworking/plugins v1.9.1
github.com/docker/docker v28.5.2+incompatible
github.com/florianl/go-conntrack v0.7.0
github.com/google/go-cmp v0.7.0
github.com/google/go-containerregistry v0.22.1
github.com/google/nftables v0.3.0
github.com/gookit/slog v0.7.1
github.com/huin/goupnp v1.3.0
github.com/insomniacslk/dhcp v0.0.0-20260719225207-c76316d4aa82
github.com/jpillora/backoff v1.0.0
github.com/json-iterator/go v1.1.11 // indirect
github.com/k-sone/critbitgo v1.4.0 // indirect
github.com/kamhlos/upnp v0.0.0-20210324072331-5661950dff08
github.com/magiconair/properties v1.8.5 // indirect
github.com/mdlayher/ndp v0.0.0-20200602162440-17ab9e3e5567
github.com/mdlayher/raw v0.0.0-20210412142147-51b895745faf // indirect
github.com/mitchellh/mapstructure v1.4.1 // indirect
github.com/onsi/ginkgo v1.11.0
github.com/onsi/gomega v1.7.0
github.com/osrg/gobgp v2.0.0+incompatible
github.com/packethost/packngo v0.13.0
github.com/pelletier/go-toml v1.9.0 // indirect
github.com/mdlayher/ndp v1.1.0
github.com/onsi/ginkgo/v2 v2.32.2
github.com/onsi/gomega v1.43.0
github.com/osrg/gobgp/v4 v4.9.0
github.com/pkg/errors v0.9.1
github.com/prometheus/client_golang v1.10.0
github.com/prometheus/common v0.23.0 // indirect
github.com/sirupsen/logrus v1.8.1
github.com/spf13/afero v1.6.0 // indirect
github.com/spf13/cast v1.3.1 // indirect
github.com/spf13/cobra v1.1.3
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/viper v1.7.1 // indirect
github.com/vishvananda/netlink v1.1.1-0.20200221165523-c79a4b7b4066
github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f // indirect
golang.org/x/crypto v0.0.0-20210503195802-e9a32991a82e // indirect
golang.org/x/net v0.0.0-20210505024714-0287a6fb4125
golang.org/x/oauth2 v0.0.0-20210427180440-81ed05c6b58c // indirect
golang.org/x/sys v0.0.0-20210525143221-35b2ab0089ea
golang.org/x/term v0.0.0-20210503060354-a79de5458b56 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto v0.0.0-20210505142820-a42aa055cf76 // indirect
google.golang.org/grpc v1.37.0 // indirect
gopkg.in/ini.v1 v1.62.0 // indirect
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
k8s.io/api v0.21.0
k8s.io/apimachinery v0.21.0
k8s.io/client-go v0.21.0
k8s.io/klog v1.0.0
k8s.io/klog/v2 v2.8.0
k8s.io/utils v0.0.0-20210305010621-2afb4311ab10 // indirect
sigs.k8s.io/kind v0.10.0
sigs.k8s.io/structured-merge-diff/v4 v4.1.1 // indirect
github.com/prometheus/client_golang v1.24.1
github.com/spf13/cobra v1.10.2
github.com/stretchr/testify v1.12.1
github.com/vishvananda/netlink v1.3.2-0.20260830232854-cf01b55a4a4b
github.com/vishvananda/netns v0.0.5
go.etcd.io/etcd/api/v3 v3.7.1
go.etcd.io/etcd/client/pkg/v3 v3.7.1
go.etcd.io/etcd/client/v3 v3.7.1
go.uber.org/zap v1.28.0
golang.org/x/exp v0.0.0-20250103183323-7d7fa50e5329
golang.org/x/sync v0.23.0
golang.org/x/sys v0.48.0
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20241231184526-a9ab2273dd10
google.golang.org/grpc v1.83.2
gopkg.in/yaml.v3 v3.0.1
k8s.io/api v0.36.4
k8s.io/apimachinery v0.36.4
k8s.io/client-go v0.36.4
k8s.io/klog/v2 v2.140.0
sigs.k8s.io/kind v0.33.0
sigs.k8s.io/yaml v1.6.0
)
replace github.com/osrg/gobgp v2.0.0+incompatible => github.com/osrg/gobgp v0.0.0-20191101114856-a42a1a5f6bf0
require (
al.essio.dev/pkg/shellescape v1.5.1 // indirect
github.com/BurntSushi/toml v1.5.0 // indirect
github.com/Masterminds/semver/v3 v3.4.0 // indirect
github.com/Microsoft/go-winio v0.6.2 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/containerd/errdefs v1.0.0 // indirect
github.com/containerd/errdefs/pkg v0.3.0 // indirect
github.com/containerd/log v0.1.0 // indirect
github.com/coreos/go-semver v0.3.1 // indirect
github.com/coreos/go-systemd/v22 v22.7.0 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/dgryski/go-farm v0.0.0-20240924180020-3414d57e47da // indirect
github.com/distribution/reference v0.6.0 // indirect
github.com/docker/go-connections v0.7.0 // indirect
github.com/docker/go-units v0.5.0 // indirect
github.com/eapache/channels v1.1.0 // indirect
github.com/eapache/queue v1.1.0 // indirect
github.com/emicklei/go-restful/v3 v3.13.0 // indirect
github.com/evanphx/json-patch/v5 v5.9.0 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/fsnotify/fsnotify v1.9.0 // indirect
github.com/fxamacker/cbor/v2 v2.9.0 // indirect
github.com/gaissmai/bart v0.26.1 // indirect
github.com/go-logr/logr v1.4.3 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-openapi/jsonpointer v0.21.0 // indirect
github.com/go-openapi/jsonreference v0.21.0 // indirect
github.com/go-openapi/swag v0.23.0 // indirect
github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
github.com/go-viper/mapstructure/v2 v2.4.0 // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/google/gnostic-models v0.7.0 // indirect
github.com/google/pprof v0.0.0-20260402051712-545e8a4df936 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/gookit/color v1.6.1 // indirect
github.com/gookit/goutil v0.7.6 // indirect
github.com/gookit/gsr v0.1.1 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.29.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/josharian/native v1.1.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/k-sone/critbitgo v1.4.0 // indirect
github.com/kylelemons/godebug v1.1.0 // indirect
github.com/mailru/easyjson v0.9.0 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mdlayher/genetlink v1.3.2 // indirect
github.com/mdlayher/netlink v1.8.0 // indirect
github.com/mdlayher/packet v1.1.2 // indirect
github.com/mdlayher/socket v0.5.1 // indirect
github.com/moby/docker-image-spec v1.3.1 // indirect
github.com/moby/sys/atomicwriter v0.1.0 // indirect
github.com/moby/term v0.5.2 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect
github.com/morikuni/aec v1.1.0 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.1.1 // indirect
github.com/orcaman/concurrent-map/v2 v2.0.1 // indirect
github.com/pelletier/go-toml v1.9.5 // indirect
github.com/pelletier/go-toml/v2 v2.2.3 // indirect
github.com/pierrec/lz4/v4 v4.1.22 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/prometheus/client_model v0.6.2 // indirect
github.com/prometheus/common v0.70.1 // indirect
github.com/prometheus/procfs v0.21.1 // indirect
github.com/sagikazarmark/locafero v0.7.0 // indirect
github.com/segmentio/fasthash v1.0.3 // indirect
github.com/sourcegraph/conc v0.3.0 // indirect
github.com/spf13/afero v1.12.0 // indirect
github.com/spf13/cast v1.7.1 // indirect
github.com/spf13/pflag v1.0.10 // indirect
github.com/spf13/viper v1.20.1 // indirect
github.com/subosito/gotenv v1.6.0 // indirect
github.com/u-root/uio v0.0.0-20240224005618-d2acac8f3701 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/x448/float16 v0.8.4 // indirect
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect
go.opentelemetry.io/otel v1.44.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.43.0 // indirect
go.opentelemetry.io/otel/metric v1.44.0 // indirect
go.opentelemetry.io/otel/trace v1.44.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.yaml.in/yaml/v2 v2.4.4 // indirect
go.yaml.in/yaml/v3 v3.0.5 // indirect
golang.org/x/crypto v0.55.0 // indirect
golang.org/x/mod v0.39.0 // indirect
golang.org/x/net v0.58.0 // indirect
golang.org/x/oauth2 v0.36.0 // indirect
golang.org/x/term v0.45.0 // indirect
golang.org/x/text v0.41.0 // indirect
golang.org/x/time v0.14.0 // indirect
golang.org/x/tools v0.49.0 // indirect
golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa // indirect
google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af // indirect
gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
k8s.io/kube-openapi v0.0.0-20260317180543-43fb72c5454a // indirect
k8s.io/utils v0.0.0-20260210185600-b8788abfbbc2 // indirect
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect
sigs.k8s.io/randfill v1.0.0 // indirect
sigs.k8s.io/structured-merge-diff/v6 v6.3.3 // indirect
)

1398
go.sum

File diff suppressed because it is too large Load Diff

BIN
kube-vip.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

View File

@@ -1,147 +0,0 @@
# Load Balancing a Kubernetes Cluster (Control-Plane)
This document covers all of the details for using `kube-vip` to build a HA Kubernetes cluster
`tl;dr version`
- Generate/modify first node `kube-vip` config/manifest
- `init` first node
- `join` remaining nodes
- Add remaining config/manifests
## Infrastructure architecture
The infrastructure for our example HA Kubernetes cluster is as follows:
| Node | Address |
|----------------|------------|
| VIP | 10.0.0.75 |
| controlPlane01 | 10.0.0.70 |
| controlPlane02 | 10.0.0.71 |
| controlPlane03 | 10.0.0.72 |
All nodes are running Ubuntu 18.04, Docker CE and will use Kubernetes 1.17.0.
### Generate the `kube-vip` configuration
Make sure that the config directory exists: `sudo mkdir -p /etc/kube-vip/`, this directory can be any directory however the `hostPath` in the manifest will need modifying to point to the correct path.
```
sudo docker run -it --rm plndr/kube-vip:0.1.5 sample config | sudo tee /etc/kube-vip/config.yaml
```
### Modify the configuration
**Cluster Configuration**
Modify the `remotePeers` to point to the correct addresses of the other two nodes, ensure that their `id` is unique otherwise this will confuse the raft algorithm. The `localPeer` should be the configuration of the current node (`controlPlane01`), which is where this instance of the cluster will run.
As this node will be the first node, it will need to elect itself leader as until this occurs the VIP wont be activated!
`startAsLeader: true`
**VIP Config**
We will need to set our VIP address to `192.168.0.75` and to ensure all hosts are updated when the VIP moves we will enable ARP broadcasts `gratuitousARP: true`
**Load Balancer**
We will configure the load balancer to sit on the standard API-Server port `6443` and we will configure the backends to point to the API-servers that will be configured to run on port `6444`. Also for the Kubernetes Control Plane we will configure the load balancer to be of `type: tcp`.
We can also use `6443` for both the VIP and the API-Servers, in order to do this we need to specify that the api-server is bound to it's local IP. To do this we use the `--apiserver-advertise-address` flag as part of the `init`, this means that we can then bind the same port to the VIP and we wont have a port conflict.
**config.yaml**
`user@controlPlane01:/etc/kube-vip$ cat config.yaml`
...
```
remotePeers:
- id: server2
address: 192.168.0.71
port: 10000
- id: server3
address: 192.168.0.72
port: 10000
localPeer:
id: server1
address: 192.168.0.70
port: 10000
vip: 192.168.0.75
gratuitousARP: true
singleNode: false
startAsLeader: true
interface: ens192
loadBalancers:
- name: Kubernetes Control Plane
type: tcp
port: 6443
bindToVip: true
backends:
- port: 6444
address: 192.168.0.70
- port: 6444
address: 192.168.0.71
- port: 6444
address: 192.168.0.72
```
### First Node
To generate the basic Kubernetes static pod `yaml` configuration:
Make sure that the manifest directory exists: `sudo mkdir -p /etc/kubernetes/manifests/`
```
sudo docker run -it --rm plndr/kube-vip:0.1.5 sample manifest | sudo tee /etc/kubernetes/manifests/kube-vip.yaml
```
Ensure that `image: plndr/kube-vip:<x>` is modified to point to a specific version (`0.1.5` at the time of writing), refer to [docker hub](https://hub.docker.com/r/plndr/kube-vip/tags) for details. Also ensure that the `hostPath` points to the correct `kube-vip` configuration, if it isnt the above path.
The **vip** is set to `192.168.0.75` and this first node will elect itself as leader, and as part of the `kubeadm init` it will use the VIP in order to speak back to the initialising api-server.
`sudo kubeadm init --control-plane-endpoint “192.168.0.75:6443” --apiserver-bind-port 6444 --upload-certs --kubernetes-version “v1.17.0”`
Once this node is up and running we will be able to see the control-plane pods, including the `kube-vip` pod:
```
$ kubectl get pods -A
NAMESPACE NAME READY STATUS RESTARTS AGE
<...>
kube-system kube-vip-controlplane01 1/1 Running 0 10m
```
### Remaining Nodes
We first will need to create the `kube-vip` configuration that resides in `/etc/kube-vip/config.yaml` or we can regenerate it from scratch using the above example. Ensure that the configuration is almost identical with the `localPeer` and `remotePeers` sections are updated for each node. Finally, ensure that the remaining nodes will behave as standard cluster nodes by setting `startAsLeader: false`.
At this point **DONT** generate the manifests, this is due to some bizarre `kubeadm/kubelet` behaviour.
```
kubeadm join 192.168.0.75:6443 --token <tkn> \
--discovery-token-ca-cert-hash sha256:<hash> \
--control-plane --certificate-key <key>
```
**After** this node has been added to the cluster, we can add the manifest to also add this node as a `kube-vip` member. (Adding the manifest afterwards doesnt interfere with `kubeadm`).
```
sudo docker run -it --rm plndr/kube-vip:0.1.5 sample manifest | sudo tee /etc/kubernetes/manifests/kube-vip.yaml
```
Once this node is added we will be able to see that the `kube-vip` pod is up and running as expected:
```
user@controlPlane01:~$ kubectl get pods -A | grep vip
kube-system kube-vip-controlplane01 1/1 Running 1 16m
kube-system kube-vip-controlplane02 1/1 Running 0 18m
kube-system kube-vip-controlplane03 1/1 Running 0 20m
```
If we look at the logs, we can see that the VIP is running on the second node and were waiting for our third node to join the cluster:
```
$ kubectl logs kube-vip-controlplane02 -n kube-system
time=“2020-02-12T15:33:09Z” level=info msg=“The Node [192.168.0.70:10000] is leading”
time=“2020-02-12T15:33:09Z” level=info msg=“The Node [192.168.0.70:10000] is leading”
```

View File

@@ -1,6 +1,10 @@
package main
import "github.com/kube-vip/kube-vip/cmd"
import (
"os"
"github.com/kube-vip/kube-vip/cmd"
)
// Version is populated from the Makefile and is tied to the release TAG
var Version string
@@ -9,7 +13,8 @@ var Version string
var Build string
func main() {
cmd.Release.Version = Version
cmd.Release.Build = Build
cmd.Execute()
os.Exit(cmd.Execute())
}

296
pkg/arp/arp.go Normal file
View File

@@ -0,0 +1,296 @@
package arp
import (
"context"
"fmt"
log "log/slog"
"sync"
"time"
"github.com/kube-vip/kube-vip/pkg/kubevip"
"github.com/kube-vip/kube-vip/pkg/utils"
"github.com/kube-vip/kube-vip/pkg/vip"
"github.com/vishvananda/netlink"
)
const linkSubscriptionBuffer = 64
type Manager struct {
mu sync.Mutex
instances map[string]*Instance
config *kubevip.Config
}
type Instance struct {
network vip.Network
ndp *vip.NdpResponder
counter int
}
func NewManager(config *kubevip.Config) *Manager {
if config.ArpBroadcastRate < 500 {
log.Warn("[ARP manager] arp broadcast rate is too low", "rate (ms)", config.ArpBroadcastRate, "setting to (ms)", "3000")
config.ArpBroadcastRate = 3000
}
return &Manager{
instances: make(map[string]*Instance),
config: config,
}
}
func NewInstance(network vip.Network, ndp *vip.NdpResponder) *Instance {
return &Instance{
ndp: ndp,
network: network,
counter: 1,
}
}
func (i *Instance) Name() string {
return i.network.ARPName()
}
func (m *Manager) Insert(instance *Instance) {
m.mu.Lock()
defer m.mu.Unlock()
existing := m.instances[instance.Name()]
if existing == nil {
m.instances[instance.Name()] = instance
log.Info("[ARP manager] inserting ARP/NDP instance", "name", instance.Name())
return
}
existing.counter++
}
func (m *Manager) Remove(instance *Instance) {
m.RemoveWithIPDelete(instance, true)
}
// RemoveOnLeadershipLoss removes an ARP instance when leadership is lost
func (m *Manager) RemoveOnLeadershipLoss(instance *Instance) {
// Use the inverse of PreserveVIPOnLeadershipLoss to decide whether to delete the IP
// If preserve is true, don't delete IP (deleteIP = false)
// If preserve is false, delete IP (deleteIP = true), This is the legacy behavior
deleteIP := !m.config.PreserveVIPOnLeadershipLoss
m.RemoveWithIPDelete(instance, deleteIP)
}
func (m *Manager) RemoveWithIPDelete(instance *Instance, deleteIP bool) {
m.mu.Lock()
defer m.mu.Unlock()
i := m.instances[instance.Name()]
if i != nil {
i.counter--
if i.counter == 0 {
log.Info("[ARP manager] removing ARP/NDP instance", "name", instance.Name())
if deleteIP {
if _, err := instance.network.DeleteIP(); err != nil {
log.Error("failed to delete IP", "address", instance.network.IP(), "err", err)
}
}
delete(m.instances, instance.Name())
}
} else {
log.Warn("[ARP manager] unable to remove the instance - instance not found", "name", instance.Name())
}
}
func (m *Manager) Count(name string) int {
m.mu.Lock()
defer m.mu.Unlock()
i := m.instances[name]
if i != nil {
return i.counter
}
return 0
}
func (m *Manager) StartAdvertisement(ctx context.Context, killFunc func()) {
if m.config.LoseLeadership {
var wg sync.WaitGroup
defer wg.Wait()
log.Info("[ARP manager] starting watching network device", "interface", m.config.Interface)
duration := time.Duration(m.config.LoseLeadershipTimeoutSeconds) * time.Second
timeout := time.NewTimer(duration)
timeout.Stop()
wg.Go(func() {
select {
case <-timeout.C:
killFunc()
case <-ctx.Done():
return
}
})
wg.Go(func() {
if err := watch(ctx, m.config.Interface, func(s netlink.LinkOperState) {
if isUp(s) {
timeout.Stop()
return
}
timeout.Reset(duration)
}); err != nil {
log.Error("[ARP manager] stopped watching interface", "err", err)
killFunc()
}
})
}
log.Info("[ARP manager] starting ARP/NDP advertisement")
ticker := time.NewTicker(time.Duration(m.config.ArpBroadcastRate) * time.Millisecond)
defer ticker.Stop()
for {
select {
case <-ctx.Done(): // if cancel() execute
return
case <-ticker.C: // send gratuitous ARP/NDP on each tick
m.advertiseAll()
}
}
}
func (m *Manager) advertiseAll() {
m.mu.Lock()
defer m.mu.Unlock()
for _, instance := range m.instances {
if instance.counter > 0 {
ensureIPAndSendGratuitous(instance)
} else if _, err := instance.network.DeleteIP(); err != nil {
log.Error("[ARP manager] failed to delete IP", "address", instance.network.IP(), "err", err)
}
}
}
// ensureIPAndSendGratuitous - adds IP to the interface if missing, and send
// either a gratuitous ARP or gratuitous NDP. Re-adds the interface if it is IPv6
// and in a dadfailed state.
func ensureIPAndSendGratuitous(instance *Instance) {
iface := instance.network.Interface()
ipString := instance.network.IP()
// Check if IP is dadfailed
if instance.network.IsDADFAIL() {
log.Warn("IP address is in dadfailed state, removing config", "ip", ipString, "interface", iface)
deleted, err := instance.network.DeleteIP()
if err != nil {
log.Warn(err.Error())
}
if deleted {
log.Info("deleted and recreating address with NODAD flag to skip DAD", "IP", ipString, "interface", iface)
// Re-add immediately without DAD check since we're recovering from DADFAILED
// The AddIP function will set IFA_F_NODAD flag for IPv6 addresses when skipDAD=true
if _, err := instance.network.AddIP(false, true); err != nil {
log.Error("failed to recreate address after DADFAILED", "IP", ipString, "interface", iface, "err", err)
} else {
log.Info("successfully recreated address after DADFAILED recovery", "IP", ipString, "interface", iface)
}
}
// Return early after DADFAILED recovery to avoid double IP addition
return
}
// Normal case: add IP with precheck and normal DAD process
if added, err := instance.network.AddIP(true, false); err != nil {
log.Warn(err.Error())
} else if added {
log.Warn("Re-applied the VIP configuration", "ip", ipString, "interface", iface)
}
if utils.IsIPv6(ipString) {
// Gratuitous NDP, will broadcast new MAC <-> IPv6 address
if instance.ndp == nil {
log.Error("NDP responder was not created")
} else {
err := instance.ndp.SendGratuitous(ipString)
if err != nil {
log.Warn(err.Error())
}
}
} else {
// Gratuitous ARP, will broadcast to new MAC <-> IPv4 address
err := vip.ARPSendGratuitous(ipString, iface)
if err != nil {
log.Warn(err.Error())
}
}
}
// watch subscribing to the network interface events and calls handler
func watch(ctx context.Context, interfaceName string, operStateHandler func(netlink.LinkOperState)) error {
ifname, err := netlink.LinkByName(interfaceName)
if err != nil {
return fmt.Errorf("failed to watch interface %q: %w", interfaceName, err)
}
// verify if this interface is physical device
if _, ok := ifname.(*netlink.Device); !ok {
return fmt.Errorf("interface %s is not physical, ignoring", interfaceName)
}
// The subscription is buffered and drained on exit: netlink parks its reader
// goroutine on an unread send, which closing done alone does not release.
events := make(chan netlink.LinkUpdate, linkSubscriptionBuffer)
done := make(chan struct{})
if err := netlink.LinkSubscribe(events, done); err != nil {
return fmt.Errorf("failed to subscribe to the interface events: %w", err)
}
defer func() {
close(done)
drainLinkUpdates(events)
}()
// handle initial state
operStateHandler(ifname.Attrs().OperState)
for {
select {
case <-ctx.Done():
return ctx.Err()
case event, ok := <-events:
if !ok {
return fmt.Errorf("interface events channel closed")
}
attrs := event.Attrs()
// LinkSubscribe captures events for all network devices found
// so we only care about vip interface
if ifname.Attrs().Name != attrs.Name {
continue
}
log.Debug("handling device change", "state", attrs.OperState)
operStateHandler(attrs.OperState)
}
}
}
func isUp(operState netlink.LinkOperState) bool {
return operState == netlink.OperUp
}
// drainLinkUpdates releases a netlink sender that is parked on an unread update
// so its goroutine can observe the closed subscription and exit.
func drainLinkUpdates(events <-chan netlink.LinkUpdate) {
timer := time.NewTimer(100 * time.Millisecond)
defer timer.Stop()
for {
select {
case _, ok := <-events:
if !ok {
return
}
case <-timer.C:
return
}
}
}

119
pkg/arp/arp_test.go Normal file
View File

@@ -0,0 +1,119 @@
package arp
import (
"sync"
"testing"
"time"
"github.com/kube-vip/kube-vip/pkg/kubevip"
"github.com/vishvananda/netlink"
v1 "k8s.io/api/core/v1"
)
func TestDrainLinkUpdatesReleasesParkedSender(t *testing.T) {
events := make(chan netlink.LinkUpdate)
sent := make(chan struct{})
go func() {
events <- netlink.LinkUpdate{}
close(sent)
}()
drainLinkUpdates(events)
select {
case <-sent:
case <-time.After(time.Second):
t.Fatal("netlink sender is still parked on an unread link update")
}
}
// stubNetwork is a minimal vip.Network implementation; only ARPName matters here.
type stubNetwork struct {
name string
deleteStarted chan struct{}
releaseDelete chan struct{}
}
func (s *stubNetwork) AddIP(bool, bool, ...int) (bool, error) { return false, nil }
func (s *stubNetwork) AddRoute(bool) (bool, error) { return false, nil }
func (s *stubNetwork) ReplaceRoute() error { return nil }
func (s *stubNetwork) DeleteIP() (bool, error) {
if s.deleteStarted != nil {
close(s.deleteStarted)
<-s.releaseDelete
}
return true, nil
}
func (s *stubNetwork) DeleteRoute() error { return nil }
func (s *stubNetwork) UpdateRoutes() (bool, error) { return false, nil }
func (s *stubNetwork) IsSet() (*netlink.Addr, error) { return nil, nil }
func (s *stubNetwork) IP() string { return "" }
func (s *stubNetwork) CIDR() string { return "" }
func (s *stubNetwork) IPisLinkLocal() bool { return false }
func (s *stubNetwork) PrepareRoute() *netlink.Route { return nil }
func (s *stubNetwork) RouteHash() string { return "" }
func (s *stubNetwork) SetIP(string) error { return nil }
func (s *stubNetwork) SetServicePorts(*v1.Service) {}
func (s *stubNetwork) Interface() string { return "eth0" }
func (s *stubNetwork) IsDADFAIL() bool { return false }
func (s *stubNetwork) IsDNS() bool { return false }
func (s *stubNetwork) IsDDNS() bool { return false }
func (s *stubNetwork) DDNSHostName() string { return "" }
func (s *stubNetwork) DNSName() string { return "" }
func (s *stubNetwork) SetMask(string) error { return nil }
func (s *stubNetwork) SetHasEndpoints(bool) {}
func (s *stubNetwork) HasEndpoints() bool { return false }
func (s *stubNetwork) ARPName() string { return s.name }
func (s *stubNetwork) GetPossibleSubnets() string { return "" }
func (s *stubNetwork) DHCPFamily() string { return "" }
func (s *stubNetwork) IPVSMark() uint32 { return 0 }
// TestManagerInsertConcurrentFirstRegistrationsDoNotLoseClaims guards the
// get-then-store race: two never-before-seen instances for the same ARP name
// registering concurrently must both be counted, not just the last writer.
func TestManagerInsertConcurrentFirstRegistrationsDoNotLoseClaims(t *testing.T) {
m := NewManager(&kubevip.Config{ArpBroadcastRate: 3000})
const concurrent = 8
var wg sync.WaitGroup
for range concurrent {
wg.Add(1)
go func() {
defer wg.Done()
m.Insert(NewInstance(&stubNetwork{name: "shared"}, nil))
}()
}
wg.Wait()
if got := m.Count("shared"); got != concurrent {
t.Fatalf("Count() = %d, want %d claims registered", got, concurrent)
}
}
func TestManagerInsertDoesNotJoinEntryBeingRemoved(t *testing.T) {
m := NewManager(&kubevip.Config{ArpBroadcastRate: 3000})
deleteStarted := make(chan struct{})
releaseDelete := make(chan struct{})
first := NewInstance(&stubNetwork{name: "shared", deleteStarted: deleteStarted, releaseDelete: releaseDelete}, nil)
m.Insert(first)
removeDone := make(chan struct{})
go func() {
m.Remove(first)
close(removeDone)
}()
<-deleteStarted
insertDone := make(chan struct{})
go func() {
m.Insert(NewInstance(&stubNetwork{name: "shared"}, nil))
close(insertDone)
}()
close(releaseDelete)
<-removeDone
<-insertDone
if got := m.Count("shared"); got != 1 {
t.Fatalf("Count() = %d, want replacement claim registered", got)
}
}

107
pkg/backend/backend.go Normal file
View File

@@ -0,0 +1,107 @@
package backend
import (
"context"
"fmt"
"sync"
"time"
log "log/slog"
"github.com/kube-vip/kube-vip/pkg/k8s"
"github.com/kube-vip/kube-vip/pkg/utils"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
)
type Entry struct {
Addr string
Port uint16
IsLocal bool
}
type Map map[Entry]bool
// kubeConfigPath is an explicitly configured kubeconfig used by Check when
// set; static pod deployments configure it since neither admin.conf nor
// in-cluster config are available there.
var (
kubeConfigPath string
pathMtx sync.Mutex
)
// SetKubeConfigPath configures the kubeconfig used by backend health checks.
func SetKubeConfigPath(path string) {
pathMtx.Lock()
defer pathMtx.Unlock()
kubeConfigPath = path
}
func (e *Entry) Check() bool {
var client *kubernetes.Clientset
var err error
var config *rest.Config
adminConfigPath := "/etc/kubernetes/admin.conf"
// TODO: add one more switch case of homeConfigPath if there is such scenario in future
// homeConfigPath := filepath.Join(os.Getenv("HOME"), ".kube", "config")
var k8sAddr string
if utils.IsIPv6(e.Addr) {
k8sAddr = fmt.Sprintf("[%s]:%v", e.Addr, e.Port)
} else {
k8sAddr = fmt.Sprintf("%s:%v", e.Addr, e.Port)
}
switch {
case kubeConfigPath != "" && utils.FileExists(kubeConfigPath):
config, err = k8s.NewRestConfig(kubeConfigPath, false, k8sAddr)
if err != nil {
log.Error("create k8s REST config", "path", kubeConfigPath, "err", err)
return false
}
case utils.FileExists(adminConfigPath):
config, err = k8s.NewRestConfig(adminConfigPath, false, k8sAddr)
if err != nil {
log.Error("create k8s REST config", "path", adminConfigPath, "err", err)
return false
}
default:
config, err = k8s.NewRestConfig("", true, k8sAddr)
if err != nil {
log.Error("create k8s REST config", "err", err)
return false
}
}
client, err = k8s.NewClientset(config)
if err != nil {
log.Error("create k8s client", "err", err)
return false
}
_, err = client.DiscoveryClient.ServerVersion()
if err != nil {
log.Error("discover k8s version", "err", err)
return false
}
return true
}
func Watch(ctx context.Context, interval int, tickAction func()) {
if interval <= 0 {
interval = 5
}
ticker := time.NewTicker(time.Second * time.Duration(interval))
defer ticker.Stop()
for {
select {
case <-ctx.Done():
return
case <-ticker.C:
tickAction()
}
}
}

View File

@@ -3,46 +3,80 @@ package bgp
import (
"context"
"fmt"
log "log/slog"
"net"
api "github.com/osrg/gobgp/api"
"github.com/osrg/gobgp/v4/pkg/apiutil"
)
// AddHost will update peers of a host
func (b *Server) AddHost(addr string) (err error) {
ip, _, err := net.ParseCIDR(addr)
if err != nil {
return err
func (b *Server) AddHost(ctx context.Context, addr string, object string) error {
b.mtx.Lock()
defer b.mtx.Unlock()
objects, exists := b.tracker[addr]
if !exists {
b.tracker[addr] = make(map[string]bool)
objects = b.tracker[addr]
ip, _, err := net.ParseCIDR(addr)
if err != nil {
return err
}
p := b.getPath(ip)
if p == nil {
return fmt.Errorf("failed to get path for %v", ip)
}
if _, err := b.s.AddPath(apiutil.AddPathRequest{
Paths: []*apiutil.Path{p},
}); err != nil {
return err
}
log.Debug("[BGP] added host", "addr", addr, "cnt", len(objects)+1, "object", object)
}
p := b.getPath(ip)
if p == nil {
return fmt.Errorf("failed to get path for %v", ip)
}
objects[object] = true
_, err = b.s.AddPath(context.Background(), &api.AddPathRequest{
Path: p,
})
if err != nil {
return err
}
return
return nil
}
// DelHost will inform peers to remove a host
func (b *Server) DelHost(addr string) (err error) {
func (b *Server) DelHost(ctx context.Context, addr string, object string) error {
b.mtx.Lock()
defer b.mtx.Unlock()
objects, exists := b.tracker[addr]
if !exists {
log.Debug("[BGP] deleting host - nothing to delete", "addr", addr, "object", object)
return nil
}
ip, _, err := net.ParseCIDR(addr)
if err != nil {
return err
}
p := b.getPath(ip)
if p == nil {
return
delete(objects, object)
if len(objects) == 0 {
p := b.getPath(ip)
if p == nil {
return nil
}
if err := b.s.DeletePath(apiutil.DeletePathRequest{
Paths: []*apiutil.Path{p},
}); err != nil {
return err
}
delete(b.tracker, addr)
log.Debug("[BGP] deleted host", "addr", addr, "cnt", len(objects), "object", object)
} else {
log.Debug("[BGP] deleting from tracker only", "addr", addr, "object", object)
}
return b.s.DeletePath(context.Background(), &api.DeletePathRequest{
Path: p,
})
return nil
}

View File

@@ -3,37 +3,46 @@ package bgp
import (
"context"
"fmt"
log "log/slog"
"net"
"net/netip"
"strconv"
"strings"
"time"
"github.com/golang/protobuf/ptypes"
"github.com/golang/protobuf/ptypes/any"
api "github.com/osrg/gobgp/api"
"github.com/jpillora/backoff"
"github.com/kube-vip/kube-vip/pkg/kubevip"
"github.com/kube-vip/kube-vip/pkg/vip"
api "github.com/osrg/gobgp/v4/api"
"github.com/kube-vip/kube-vip/pkg/utils"
"github.com/osrg/gobgp/v4/pkg/apiutil"
"github.com/osrg/gobgp/v4/pkg/config/oc"
bgp "github.com/osrg/gobgp/v4/pkg/packet/bgp"
"github.com/osrg/gobgp/v4/pkg/server"
)
//AddPeer will add peers to the BGP configuration
func (b *Server) AddPeer(peer Peer) (err error) {
port := 179
const defaultBGPPort uint32 = 179
if t := strings.SplitN(peer.Address, ":", 2); len(t) == 2 {
peer.Address = t[0]
if port, err = strconv.Atoi(t[1]); err != nil {
return fmt.Errorf("Unable to parse port '%s' as int: %s", t[1], err)
}
// AddPeer will add peers to the BGP configuration
func (b *Server) AddPeer(ctx context.Context, peer kubevip.BGPPeer) (err error) {
remotePort := defaultBGPPort
if peer.Port != 0 {
remotePort = uint32(peer.Port)
}
p := &api.Peer{
Conf: &api.PeerConf{
NeighborAddress: peer.Address,
PeerAs: peer.AS,
AuthPassword: peer.Password,
NeighborAddress: peer.Address,
PeerAsn: peer.AS,
NeighborInterface: peer.Interface,
AuthPassword: peer.Password,
},
Timers: &api.Timers{
Config: &api.TimersConfig{
ConnectRetry: 10,
ConnectRetry: 10,
HoldTime: b.c.HoldTime,
KeepaliveInterval: b.c.KeepaliveInterval,
},
},
@@ -46,95 +55,273 @@ func (b *Server) AddPeer(peer Peer) (err error) {
Transport: &api.Transport{
MtuDiscovery: true,
RemoteAddress: peer.Address,
RemotePort: uint32(port),
RemotePort: remotePort,
},
}
// if b.c.SourceIP != "" {
// p.Transport.LocalAddress = b.c.SourceIP
// }
if peer.BFDEnabled {
p.Bfd = &api.BfdPeerConfig{
Enabled: true,
DesiredMinimumTxInterval: peer.BFDTransmitInterval,
RequiredMinimumReceive: peer.BFDReceiveInterval,
DetectionMultiplier: peer.BFDDetectMultiplier,
Port: 3784, // TODO: Should this be configurable??
}
}
// if b.c.SourceIF != "" {
// p.Transport.BindInterface = b.c.SourceIF
// }
if peer.Interface != "" {
neighborAddress, err := getIPv6LinkLocalNeighborAddress(ctx, peer.Interface)
if err != nil {
return fmt.Errorf("failed to get link-local address of interface %s: %w", peer.Interface, err)
}
return b.s.AddPeer(context.Background(), &api.AddPeerRequest{
Peer: p,
})
p.State = &api.PeerState{
NeighborAddress: neighborAddress,
}
}
mpBGP := b.c.MpbgpNexthop
if peer.MpbgpNexthop != "" {
mpBGP = peer.MpbgpNexthop
}
if mpBGP != "" {
ipv4Address, ipv6Address, err := peer.FindMpbgpAddresses(p, b.c)
if err != nil {
log.Error("failed to get MP-BGP addresses, will not us MP-BGP for this host", "error", err)
b.setPeerSource(p)
} else {
p.AfiSafis = []*api.AfiSafi{
{
Config: &api.AfiSafiConfig{
Family: &api.Family{
Afi: api.Family_AFI_IP,
Safi: api.Family_SAFI_UNICAST,
},
Enabled: true,
},
},
{
Config: &api.AfiSafiConfig{
Family: &api.Family{
Afi: api.Family_AFI_IP6,
Safi: api.Family_SAFI_UNICAST,
},
Enabled: true,
},
},
}
peer.SetMpbgpOptions(b.c)
mask := strconv.Itoa(vip.DefaultMaskIPv6)
address := ipv4Address
family := api.Family_AFI_IP
if utils.IsIPv4(p.Conf.NeighborAddress) {
mask = strconv.Itoa(vip.DefaultMaskIPv4)
address = ipv6Address
family = api.Family_AFI_IP6
}
err = b.s.AddDefinedSet(ctx, &api.AddDefinedSetRequest{
DefinedSet: &api.DefinedSet{
DefinedType: api.DefinedType_DEFINED_TYPE_NEIGHBOR,
Name: fmt.Sprintf("peer-%s", p.Conf.NeighborAddress),
List: []string{fmt.Sprintf("%s/%s", p.Conf.NeighborAddress, mask)},
},
})
if err != nil {
return fmt.Errorf("failed to add defined set: %v", err)
}
if address != "" {
if err := insertPolicy(ctx, b.s, address, p, family); err != nil {
return fmt.Errorf("failed to add policy: %w", err)
}
}
}
} else {
b.setPeerSource(p)
}
if err := b.s.AddPeer(ctx, &api.AddPeerRequest{Peer: p}); err != nil {
return fmt.Errorf("failed to add peer: %v", err)
}
log.Info("[BGP]", "peer", p.Conf.NeighborAddress, "AS", p.Conf.PeerAsn, "BFD", p.Bfd)
return nil
}
func (b *Server) getPath(ip net.IP) *api.Path {
var pfxLen uint32 = 32
if ip.To4() == nil {
if !b.c.IPv6 {
func (b *Server) setPeerSource(p *api.Peer) {
if b.c.SourceIP != "" {
p.Transport.LocalAddress = b.c.SourceIP
}
if b.c.SourceIF != "" {
p.Transport.BindInterface = b.c.SourceIF
}
}
func (b *Server) getPath(ip net.IP) *apiutil.Path {
isV6 := ip.To4() == nil
if !isV6 {
prefix, err := bgp.NewIPAddrPrefix(netip.MustParsePrefix(
fmt.Sprintf("%s/%d", ip.String(), vip.DefaultMaskIPv4),
))
if err != nil {
return nil
}
pfxLen = 128
nh, err := bgp.NewPathAttributeNextHop(netip.MustParseAddr("0.0.0.0"))
if err != nil {
return nil
}
return &apiutil.Path{
Family: bgp.RF_IPv4_UC,
Nlri: prefix,
Attrs: []bgp.PathAttributeInterface{
bgp.NewPathAttributeOrigin(0),
nh,
},
}
}
nlri, _ := ptypes.MarshalAny(&api.IPAddressPrefix{
Prefix: ip.String(),
PrefixLen: pfxLen,
})
a1, _ := ptypes.MarshalAny(&api.OriginAttribute{
Origin: 0,
})
var nh string
if b.c.NextHop != "" {
nh = b.c.NextHop
} else if b.c.SourceIP != "" {
nh = b.c.SourceIP
} else {
nh = b.c.RouterID
prefix, err := bgp.NewIPAddrPrefix(netip.MustParsePrefix(
fmt.Sprintf("%s/%d", ip.String(), vip.DefaultMaskIPv6),
))
if err != nil {
return nil
}
a2, _ := ptypes.MarshalAny(&api.NextHopAttribute{
NextHop: nh,
})
mpReach, err := bgp.NewPathAttributeMpReachNLRI(
bgp.RF_IPv6_UC,
[]bgp.PathNLRI{{NLRI: prefix}},
netip.MustParseAddr("::"),
)
if err != nil {
return nil
}
return &api.Path{
Family: &api.Family{
Afi: api.Family_AFI_IP,
Safi: api.Family_SAFI_UNICAST,
return &apiutil.Path{
Family: bgp.RF_IPv6_UC,
Nlri: prefix,
Attrs: []bgp.PathAttributeInterface{
bgp.NewPathAttributeOrigin(0),
mpReach,
},
Nlri: nlri,
Pattrs: []*any.Any{a1, a2},
}
}
// ParseBGPPeerConfig - take a string and parses it into an array of peers
func ParseBGPPeerConfig(config string) (bgpPeers []Peer, err error) {
peers := strings.Split(config, ",")
if len(peers) == 0 {
return nil, fmt.Errorf("No BGP Peer configurations found")
func insertPolicy(ctx context.Context, s *server.BgpServer, address string, p *api.Peer, family api.Family_Afi) error {
familyType := "v4"
if family == api.Family_AFI_IP6 {
familyType = "v6"
}
for x := range peers {
peer := strings.Split(peers[x], ":")
if len(peer) != 4 {
return nil, fmt.Errorf("BGP Peer configuration format error <host>:<AS>:<password>:<multihop>")
}
ASNumber, err := strconv.Atoi(peer[1])
if err != nil {
return nil, fmt.Errorf("BGP Peer AS format error [%s]", peer[1])
setName := fmt.Sprintf("peer-%s", p.Conf.NeighborAddress)
policyName := fmt.Sprintf("%s-%s", setName, familyType)
policy := &api.Policy{
Name: policyName,
Statements: []*api.Statement{
{
Conditions: &api.Conditions{
AfiSafiIn: []*api.Family{
{
Afi: family,
Safi: api.Family_SAFI_UNICAST,
},
},
NeighborSet: &api.MatchSet{
Type: api.MatchSet_TYPE_ANY,
Name: setName,
},
},
Actions: &api.Actions{
RouteAction: api.RouteAction_ROUTE_ACTION_ACCEPT,
Nexthop: &api.NexthopAction{
Address: address,
},
},
},
{
Conditions: &api.Conditions{
NeighborSet: &api.MatchSet{
Type: api.MatchSet_TYPE_ANY,
Name: setName,
},
},
Actions: &api.Actions{
RouteAction: api.RouteAction_ROUTE_ACTION_ACCEPT,
},
},
},
}
err := s.AddPolicy(ctx, &api.AddPolicyRequest{
Policy: policy,
})
if err != nil {
return fmt.Errorf("failed to add policy: %w", err)
}
err = s.AddPolicyAssignment(ctx, &api.AddPolicyAssignmentRequest{
Assignment: &api.PolicyAssignment{
Name: "global",
Direction: api.PolicyDirection_POLICY_DIRECTION_EXPORT,
Policies: []*api.Policy{
{
Name: policy.Name,
},
},
},
})
if err != nil {
return fmt.Errorf("failed to add policy assignment: %v", err)
}
return nil
}
func getIPv6LinkLocalNeighborAddress(ctx context.Context, peerInterface string) (string, error) {
neighCtx, neighCancel := context.WithTimeout(ctx, time.Minute)
defer neighCancel()
bo := backoff.Backoff{
Factor: 2,
Jitter: true,
Min: 1 * time.Second,
Max: 5 * time.Second,
}
maxAttempts := 20.0
var err error
for {
select {
case <-neighCtx.Done():
if err != nil {
return "", fmt.Errorf("failed to get link-local address of interface %s: %w", peerInterface, err)
}
return "", fmt.Errorf("failed to get link-local address of interface %s: %w", peerInterface, neighCtx.Err())
default:
dur := bo.Duration()
var neighborAddress string
neighborAddress, err = oc.GetIPv6LinkLocalNeighborAddress(peerInterface)
if err != nil && bo.Attempt() >= maxAttempts {
return "", fmt.Errorf("failed to get link-local address of interface %s: %w", peerInterface, err)
}
if neighborAddress != "" {
return neighborAddress, nil
}
t := time.NewTimer(dur)
select {
case <-neighCtx.Done():
t.Stop()
case <-t.C:
}
}
}
multiHop, err := strconv.ParseBool(peer[3])
if err != nil {
return nil, fmt.Errorf("BGP MultiHop format error (true/false) [%s]", peer[1])
}
peerConfig := Peer{
Address: peer[0],
AS: uint32(ASNumber),
Password: peer[2],
MultiHop: multiHop,
}
bgpPeers = append(bgpPeers, peerConfig)
}
return
}

View File

@@ -0,0 +1,146 @@
package bgp
import (
"context"
"sync"
"testing"
log "log/slog"
"github.com/kube-vip/kube-vip/pkg/kubevip"
api "github.com/osrg/gobgp/v4/api"
gobgp "github.com/osrg/gobgp/v4/pkg/server"
)
func TestAddPeerConfiguresTransportOptions(t *testing.T) {
tests := []struct {
name string
newServer func(*testing.T) *Server
peer kubevip.BGPPeer
wantPort uint32
wantLocalAddr string
wantInterface string
}{
{
name: "configured remote port",
newServer: func(t *testing.T) *Server {
return newStartedTestBGPServer(t, kubevip.BGPConfig{
AS: 65000,
RouterID: "192.0.2.1",
Peers: []kubevip.BGPPeer{{Address: "192.0.2.10", AS: 65001}},
})
},
peer: kubevip.BGPPeer{Address: "192.0.2.10", AS: 65001, Port: 180},
wantPort: 180,
},
{
name: "configured source interface after MP-BGP fallback",
newServer: func(t *testing.T) *Server {
return newPeerTestServer(t, kubevip.BGPConfig{
AS: 65000,
RouterID: "192.0.2.1",
SourceIF: "lo",
MpbgpNexthop: "fixed",
Peers: []kubevip.BGPPeer{{Address: "192.0.2.20", AS: 65001}},
MpbgpIPv4: "",
MpbgpIPv6: "",
})
},
peer: kubevip.BGPPeer{Address: "192.0.2.20", AS: 65001},
wantInterface: "lo",
},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
server := tt.newServer(t)
if err := server.AddPeer(context.Background(), tt.peer); err != nil {
t.Fatalf("AddPeer() error = %v", err)
}
peer := listTestPeer(t, server, tt.peer.Address)
if peer.GetTransport() == nil {
t.Fatal("configured peer has no transport")
}
if tt.wantPort != 0 && peer.GetTransport().GetRemotePort() != tt.wantPort {
t.Fatalf("remote port = %d, want %d", peer.GetTransport().GetRemotePort(), tt.wantPort)
}
if tt.wantLocalAddr != "" && peer.GetTransport().GetLocalAddress() != tt.wantLocalAddr {
t.Fatalf("local address = %q, want %q", peer.GetTransport().GetLocalAddress(), tt.wantLocalAddr)
}
if tt.wantInterface != "" && peer.GetTransport().GetBindInterface() != tt.wantInterface {
t.Fatalf("bind interface = %q, want %q", peer.GetTransport().GetBindInterface(), tt.wantInterface)
}
})
}
}
func newStartedTestBGPServer(t *testing.T, config kubevip.BGPConfig) *Server {
t.Helper()
server, err := NewBGPServer(config, log.LevelError)
if err != nil {
t.Fatalf("NewBGPServer() error = %v", err)
}
go server.s.Serve()
if err := server.s.StartBgp(context.Background(), &api.StartBgpRequest{
Global: &api.Global{
Asn: config.AS,
RouterId: config.RouterID,
ListenPort: -1,
},
}); err != nil {
server.s.Stop()
t.Fatalf("StartBgp() error = %v", err)
}
t.Cleanup(server.s.Stop)
return server
}
func listTestPeer(t *testing.T, server *Server, address string) *api.Peer {
t.Helper()
var got *api.Peer
if err := server.s.ListPeer(context.Background(), &api.ListPeerRequest{Address: address}, func(peer *api.Peer) {
got = peer
}); err != nil {
t.Fatalf("ListPeer() error = %v", err)
}
if got == nil {
t.Fatalf("ListPeer() returned no peer for %s", address)
}
return got
}
func newPeerTestServer(t *testing.T, cfg kubevip.BGPConfig) *Server {
t.Helper()
raw := startEmbeddedRawBGP(t)
return &Server{s: raw, c: &cfg, tracker: make(map[string]map[string]bool)}
}
func startEmbeddedRawBGP(t *testing.T) *gobgp.BgpServer {
t.Helper()
raw := gobgp.NewBgpServer()
go raw.Serve()
if err := raw.StartBgp(context.Background(), &api.StartBgpRequest{
Global: &api.Global{
Asn: 65000,
RouterId: "192.0.2.1",
ListenPort: -1,
},
}); err != nil {
t.Fatalf("starting embedded BGP server: %v", err)
}
var stopOnce sync.Once
t.Cleanup(func() {
stopOnce.Do(func() {
if err := raw.StopBgp(context.Background(), &api.StopBgpRequest{}); err != nil {
t.Logf("stopping embedded BGP server: %v", err)
}
})
})
return raw
}

View File

@@ -3,49 +3,94 @@ package bgp
import (
"context"
"fmt"
"log"
"sync"
"time"
api "github.com/osrg/gobgp/api"
gobgp "github.com/osrg/gobgp/pkg/server"
log "log/slog"
"github.com/kube-vip/kube-vip/pkg/kubevip"
api "github.com/osrg/gobgp/v4/api"
"github.com/osrg/gobgp/v4/pkg/apiutil"
bgp "github.com/osrg/gobgp/v4/pkg/packet/bgp"
gobgp "github.com/osrg/gobgp/v4/pkg/server"
)
type BGPManager interface {
AddHost(ctx context.Context, addr string, object string) error
DelHost(ctx context.Context, addr string, object string) error
}
// Server manages a server object
type Server struct {
s *gobgp.BgpServer
c *kubevip.BGPConfig
mtx sync.Mutex
tracker map[string]map[string]bool
}
// NewBGPServer takes a configuration and returns a running BGP server instance
func NewBGPServer(c *Config) (b *Server, err error) {
func NewBGPServer(c kubevip.BGPConfig, logLevel log.Level) (b *Server, err error) {
if c.AS == 0 {
return nil, fmt.Errorf("You need to provide AS")
return nil, fmt.Errorf("you need to provide AS")
}
// if c.SourceIP != "" && c.SourceIF != "" {
// return nil, fmt.Errorf("SourceIP and SourceIF are mutually exclusive")
// }
if c.SourceIP != "" && c.SourceIF != "" {
return nil, fmt.Errorf("sourceIP and SourceIF are mutually exclusive")
}
if len(c.Peers) == 0 {
return nil, fmt.Errorf("You need to provide at least one peer")
return nil, fmt.Errorf("you need to provide at least one peer")
}
bgpLogger := log.Default()
lvl := &log.LevelVar{}
lvl.Set(logLevel)
b = &Server{
s: gobgp.NewBgpServer(),
c: c,
s: gobgp.NewBgpServer(gobgp.LoggerOption(bgpLogger, lvl)),
c: &c,
tracker: make(map[string]map[string]bool),
}
return
}
// Start starts the BGP server
func (b *Server) Start(ctx context.Context, peerStateChangeCallback func(*apiutil.WatchEventMessage_PeerEvent)) (err error) {
go b.s.Serve()
if err = b.s.StartBgp(context.Background(), &api.StartBgpRequest{
if err = b.s.StartBgp(ctx, &api.StartBgpRequest{
Global: &api.Global{
As: c.AS,
RouterId: c.RouterID,
Asn: b.c.AS,
RouterId: b.c.RouterID,
ListenPort: -1,
},
}); err != nil {
return
}
if err = b.s.MonitorPeer(context.Background(), &api.MonitorPeerRequest{}, func(p *api.Peer) { log.Println(p) }); err != nil {
if err = b.s.WatchEvent(ctx, gobgp.WatchEventMessageCallbacks{
OnPeerUpdate: func(p *apiutil.WatchEventMessage_PeerEvent, _ time.Time) {
log.Info("[BGP]", "peer", fmt.Sprintf("%+v", p))
if peerStateChangeCallback != nil {
peerStateChangeCallback(p)
}
},
}, gobgp.WatchPeer()); err != nil {
return
}
for _, p := range c.Peers {
if err = b.AddPeer(p); err != nil {
for _, p := range b.c.Peers {
if err = b.AddPeer(ctx, p); err != nil {
return
}
}
if b.c.Zebra.Enabled {
if err = b.s.EnableZebra(ctx, &api.EnableZebraRequest{
Url: b.c.Zebra.URL,
Version: b.c.Zebra.Version,
SoftwareName: b.c.Zebra.SoftwareName,
}); err != nil {
log.Error(err.Error())
return
}
}
@@ -55,7 +100,51 @@ func NewBGPServer(c *Config) (b *Server, err error) {
// Close will stop a running BGP Server
func (b *Server) Close() error {
ctx, cf := context.WithTimeout(context.Background(), 5*time.Second)
defer cf()
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
return b.s.StopBgp(ctx, &api.StopBgpRequest{})
}
// ListAdvertisedRoutes retrieves all active routes inside GoBGP's local RIB.
// It queries the GLOBAL table type to find routes that kube-vip has requested GoBGP to advertise.
func (b *Server) ListAdvertisedRoutes(ctx context.Context, isIPv6 bool) ([]*api.Destination, error) {
afi := bgp.AFI_IP
if isIPv6 {
afi = bgp.AFI_IP6
}
family := bgp.NewFamily(uint16(afi), bgp.SAFI_UNICAST)
var destinations []*api.Destination
req := apiutil.ListPathRequest{
TableType: api.TableType_TABLE_TYPE_GLOBAL,
Family: family,
}
// GoBGP's embedded server API uses a callback function to stream results
// locally without requiring a gRPC client stream setup.
err := b.s.ListPath(req, func(prefix bgp.NLRI, paths []*apiutil.Path) {
var newPaths []*api.Path
for _, p := range paths {
np, err := apiutil.NewPath(p.Family, p.Nlri, p.Withdrawal, p.Attrs, time.Unix(p.Age, 0))
if err != nil {
log.Error("failed to create BGP path details", "err", err)
continue
}
newPaths = append(newPaths, np)
}
d := &api.Destination{
Prefix: prefix.String(),
Paths: newPaths,
}
destinations = append(destinations, d)
})
if err != nil {
return nil, fmt.Errorf("failed to extract local RIB: %w", err)
}
return destinations, nil
}

View File

@@ -1,29 +0,0 @@
package bgp
import gobgp "github.com/osrg/gobgp/pkg/server"
// Peer defines a BGP Peer
type Peer struct {
Address string
AS uint32
Password string
MultiHop bool
}
// Config defines the BGP server configuration
type Config struct {
AS uint32
RouterID string
NextHop string
SourceIP string
SourceIF string
Peers []Peer
IPv6 bool
}
// Server manages a server object
type Server struct {
s *gobgp.BgpServer
c *Config
}

View File

@@ -1,52 +1,288 @@
package cluster
import (
"crypto/tls"
"crypto/x509"
"fmt"
"net/http"
"os"
"sync"
"time"
log "log/slog"
"github.com/kube-vip/kube-vip/pkg/arp"
"github.com/kube-vip/kube-vip/pkg/kubevip"
"github.com/kube-vip/kube-vip/pkg/networkinterface"
"github.com/kube-vip/kube-vip/pkg/node"
"github.com/kube-vip/kube-vip/pkg/route"
"github.com/kube-vip/kube-vip/pkg/vip"
)
const leaderLogcount = 5
// Cluster - The Cluster object manages the state of the cluster for a particular node
type Cluster struct {
stateMachine FSM
stop chan bool
completed chan bool
Network vip.Network
stop chan struct{}
stopMu sync.Mutex
service *servicesWorker
Network []vip.Network
arpMgr *arp.Manager
routeMgr *route.Manager
nodeLabelMgr node.Labeler
labelAdded bool
healthCheckHTTPClient *http.Client
}
type servicesWorker struct {
stop chan struct{}
done chan struct{}
stopping bool
preserveVIPs map[string]struct{}
}
// InitCluster - Will attempt to initialise all of the required settings for the cluster
func InitCluster(c *kubevip.Config, disableVIP bool) (*Cluster, error) {
// TODO - Check for root (needed to netlink)
var network vip.Network
func InitCluster(c *kubevip.Config, disableVIP bool, intfMgr *networkinterface.Manager, arpMgr *arp.Manager,
routeMgr *route.Manager, nodeLabelMgr node.Labeler) (*Cluster, error) {
var networks []vip.Network
var healthCheckHTTPClient *http.Client
var err error
if !disableVIP {
// Start the Virtual IP Networking configuration
network, err = startNetworking(c)
networks, err = startNetworking(c, intfMgr)
if err != nil {
return nil, err
}
}
if c.ControlPlaneHealthCheck.Address != "" {
healthCheckHTTPClient, err = newHealthCheckHTTPClient(c)
if err != nil {
return nil, fmt.Errorf("initializing BGP health check client: %w", err)
}
}
// Initialise the Cluster structure
newCluster := &Cluster{
Network: network,
Network: networks,
arpMgr: arpMgr,
stop: make(chan struct{}),
routeMgr: routeMgr,
nodeLabelMgr: nodeLabelMgr,
healthCheckHTTPClient: healthCheckHTTPClient,
}
log.Debug("service security", "enabled", c.EnableServiceSecurity)
return newCluster, nil
}
func startNetworking(c *kubevip.Config) (vip.Network, error) {
func startNetworking(c *kubevip.Config, intfMgr *networkinterface.Manager) ([]vip.Network, error) {
address := c.VIP
if c.Address != "" {
address = c.Address
}
network, err := vip.NewConfig(address, c.Interface, c.DDNS)
if err != nil {
return nil, err
addresses := vip.Split(address)
networks := []vip.Network{}
for _, addr := range addresses {
network, err := vip.NewConfig(addr, c.Interface, c.LoInterfaceGlobalScope, c.VIPSubnet, c.DDNS, c.DHCPMode,
c.RequireDualStack, c.IsDualStack, c.RoutingTableID, c.RoutingTableType, c.RoutingProtocol, c.DNSMode,
c.LoadBalancerForwardingMethod, c.IptablesBackend, c.EnableLoadBalancer, c.LoadBalancerPort,
c.EnableServiceSecurity, intfMgr, c.EgressWithNftables, c.SkipDAD)
if err != nil {
return nil, err
}
networks = append(networks, network...)
}
return networks, nil
}
// Stop - Will stop the Cluster and release VIP if needed
func (cluster *Cluster) Stop() {
cluster.stopMu.Lock()
defer cluster.stopMu.Unlock()
if cluster.service != nil {
workers := cluster.service
if workers.stopping {
return
}
workers.stopping = true
cluster.stop = make(chan struct{})
close(workers.stop)
return
}
stop := cluster.stop
cluster.stop = make(chan struct{})
close(stop)
}
// StopAndWait signals the current Service worker generation and waits until it
// has finished its datapath cleanup.
func (cluster *Cluster) StopAndWait() {
cluster.stopAndWait(nil)
}
// StopAndWaitPreserving stops the current Service worker generation while
// preserving the supplied VIPs for another Service that shares the same lease.
func (cluster *Cluster) StopAndWaitPreserving(addresses ...string) {
preserve := make(map[string]struct{}, len(addresses))
for _, address := range addresses {
preserve[address] = struct{}{}
}
cluster.stopAndWait(preserve)
}
func (cluster *Cluster) stopAndWait(preserveVIPs map[string]struct{}) {
workers, signal := cluster.prepareServiceStop(preserveVIPs)
if workers == nil {
return
}
if signal {
close(workers.stop)
}
<-workers.done
}
func (cluster *Cluster) prepareServiceStop(preserveVIPs map[string]struct{}) (*servicesWorker, bool) {
cluster.stopMu.Lock()
defer cluster.stopMu.Unlock()
workers := cluster.service
if workers == nil {
return nil, false
}
if workers.stopping {
workers.preserveVIPs = mergeVIPs(workers.preserveVIPs, preserveVIPs)
return workers, false
}
workers.stopping = true
workers.preserveVIPs = preserveVIPs
cluster.stop = make(chan struct{})
return workers, true
}
func (cluster *Cluster) startServicesWorker() (<-chan struct{}, chan struct{}, error) {
cluster.stopMu.Lock()
defer cluster.stopMu.Unlock()
if cluster.service != nil {
return nil, nil, fmt.Errorf("load balancer workers already running")
}
workers := &servicesWorker{stop: cluster.stop, done: make(chan struct{})}
cluster.service = workers
return workers.stop, workers.done, nil
}
func (cluster *Cluster) preserveServiceVIP(done chan struct{}, address string) bool {
cluster.stopMu.Lock()
defer cluster.stopMu.Unlock()
if cluster.service == nil || cluster.service.done != done {
return false
}
_, preserve := cluster.service.preserveVIPs[address]
return preserve
}
func mergeVIPs(existing, addresses map[string]struct{}) map[string]struct{} {
if len(addresses) == 0 {
return existing
}
if existing == nil {
existing = make(map[string]struct{}, len(addresses))
}
for address := range addresses {
existing[address] = struct{}{}
}
return existing
}
func (cluster *Cluster) finishServicesWorker(done chan struct{}) {
cluster.stopMu.Lock()
defer cluster.stopMu.Unlock()
if cluster.service == nil || cluster.service.done != done {
return
}
cluster.service = nil
close(done)
}
func (cluster *Cluster) StopChannel() <-chan struct{} {
cluster.stopMu.Lock()
defer cluster.stopMu.Unlock()
return cluster.stop
}
func newHealthCheckHTTPClient(c *kubevip.Config) (*http.Client, error) {
defaultTransport, ok := http.DefaultTransport.(*http.Transport)
if !ok {
return nil, fmt.Errorf("unexpected default HTTP transport type %T", http.DefaultTransport)
}
transport := defaultTransport.Clone()
if c.ControlPlaneHealthCheck.CAPath != "" {
caCert, err := os.ReadFile(c.ControlPlaneHealthCheck.CAPath)
if err != nil {
return nil, fmt.Errorf("reading health check CA cert %q: %w", c.ControlPlaneHealthCheck.CAPath, err)
}
rootCAs, err := x509.SystemCertPool()
if err != nil || rootCAs == nil {
rootCAs = x509.NewCertPool()
}
if !rootCAs.AppendCertsFromPEM(caCert) {
return nil, fmt.Errorf("health check CA cert %q contains no valid certificates", c.ControlPlaneHealthCheck.CAPath)
}
tlsConfig := &tls.Config{MinVersion: tls.VersionTLS12}
if transport.TLSClientConfig != nil {
tlsConfig = transport.TLSClientConfig.Clone()
}
tlsConfig.RootCAs = rootCAs
transport.TLSClientConfig = tlsConfig
}
return &http.Client{
Timeout: time.Duration(c.ControlPlaneHealthCheck.TimeoutSeconds) * time.Second,
Transport: transport,
}, nil
}
// cleanupVIPs releases the control plane VIPs after leadership was lost.
// Nothing waits for the control plane layer2Update goroutine to observe the
// cancelled context, so this caller usually still holds its own ARP claim and
// has to delete the address itself.
func (cluster *Cluster) cleanupVIPs(c *kubevip.Config) {
for i := range cluster.Network {
cluster.cleanupVIP(c, cluster.Network[i], 1)
}
}
// cleanupServiceVIPs releases the service VIPs once the services worker has
// drained. layer2Update already removed this instance's own claim by then, so
// any remaining claim belongs to another service sharing the VIP.
func (cluster *Cluster) cleanupServiceVIPs(c *kubevip.Config, done chan struct{}) {
for i := range cluster.Network {
if cluster.preserveServiceVIP(done, cluster.Network[i].IP()) {
continue
}
cluster.cleanupVIP(c, cluster.Network[i], 0)
}
}
// cleanupVIP deletes the VIP unless somebody else still advertises it.
// ownClaims is the number of ARP claims the caller may still hold itself.
func (cluster *Cluster) cleanupVIP(c *kubevip.Config, network vip.Network, ownClaims int) {
if c.EnableARP && cluster.arpMgr.Count(network.ARPName()) > ownClaims {
return
}
log.Info("[VIP] Deleting VIP", "ip", network.IP())
deleted, err := network.DeleteIP()
if err != nil {
log.Warn(err.Error())
}
if deleted {
log.Info("deleted address", "IP", network.IP(), "interface", network.Interface())
}
return network, nil
}

View File

@@ -2,6 +2,7 @@ package cluster
import (
"context"
"sync"
"github.com/kube-vip/kube-vip/pkg/vip"
)
@@ -12,14 +13,13 @@ import (
// during runtime if IP changes, startDDNS don't have to do reconfigure because
// dnsUpdater already have the functionality to keep trying resolve the IP
// and update the VIP configuration if it changes
func (cluster *Cluster) StartDDNS(ctx context.Context) error {
ddnsMgr := vip.NewDDNSManager(ctx, cluster.Network)
ip, err := ddnsMgr.Start()
func (cluster *Cluster) StartDDNS(ctx context.Context, network vip.Network, backoffAttempts uint, wg *sync.WaitGroup) error {
ddnsMgr := vip.NewDDNSManager(network, backoffAttempts)
ip, err := ddnsMgr.Start(ctx, wg)
if err != nil {
return err
}
if err = cluster.Network.SetIP(ip); err != nil {
if err = network.SetIP(ip); err != nil {
return err
}

View File

@@ -1,469 +0,0 @@
package cluster
import (
"context"
"fmt"
"os"
"os/signal"
"path/filepath"
"syscall"
"time"
"github.com/kube-vip/kube-vip/pkg/bgp"
"github.com/kube-vip/kube-vip/pkg/kubevip"
leaderelection "github.com/kube-vip/kube-vip/pkg/leaderElection"
"github.com/kube-vip/kube-vip/pkg/loadbalancer"
"github.com/kube-vip/kube-vip/pkg/packet"
"github.com/kube-vip/kube-vip/pkg/vip"
"github.com/packethost/packngo"
log "github.com/sirupsen/logrus"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
"k8s.io/client-go/tools/leaderelection/resourcelock"
)
const plunderLock = "plndr-cp-lock"
// Manager degines the manager of the load-balancing services
type Manager struct {
KubernetesClient *kubernetes.Clientset
}
// NewManager will create a new managing object
func NewManager(path string, inCluster bool, port int) (*Manager, error) {
var clientset *kubernetes.Clientset
if inCluster {
// This will attempt to load the configuration when running within a POD
cfg, err := rest.InClusterConfig()
if err != nil {
return nil, fmt.Errorf("error creating kubernetes client config: %s", err.Error())
}
clientset, err = kubernetes.NewForConfig(cfg)
if err != nil {
return nil, fmt.Errorf("error creating kubernetes client: %s", err.Error())
}
// use the current context in kubeconfig
} else {
if path == "" {
path = filepath.Join(os.Getenv("HOME"), ".kube", "config")
}
config, err := clientcmd.BuildConfigFromFlags("", path)
if err != nil {
panic(err.Error())
}
// We modify the config so that we can always speak to the correct host
id, err := os.Hostname()
if err != nil {
return nil, err
}
config.Host = fmt.Sprintf("%s:%v", id, port)
clientset, err = kubernetes.NewForConfig(config)
if err != nil {
return nil, fmt.Errorf("error creating kubernetes client: %s", err.Error())
}
}
return &Manager{
KubernetesClient: clientset,
}, nil
}
// StartLeaderCluster - Begins a running instance of the Raft cluster
func (cluster *Cluster) StartLeaderCluster(c *kubevip.Config, sm *Manager, bgpServer *bgp.Server) error {
id, err := os.Hostname()
if err != nil {
return err
}
log.Infof("Beginning cluster membership, namespace [%s], lock name [%s], id [%s]", c.Namespace, plunderLock, id)
// we use the Lease lock type since edits to Leases are less common
// and fewer objects in the cluster watch "all Leases".
lock := &resourcelock.LeaseLock{
LeaseMeta: metav1.ObjectMeta{
Name: plunderLock,
Namespace: c.Namespace,
},
Client: sm.KubernetesClient.CoordinationV1(),
LockConfig: resourcelock.ResourceLockConfig{
Identity: id,
},
}
// use a Go context so we can tell the leaderelection code when we
// want to step down
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
// use a Go context so we can tell the arp loop code when we
// want to step down
ctxArp, cancelArp := context.WithCancel(context.Background())
defer cancelArp()
// use a Go context so we can tell the dns loop code when we
// want to step down
ctxDNS, cancelDNS := context.WithCancel(context.Background())
defer cancelDNS()
// listen for interrupts or the Linux SIGTERM signal and cancel
// our context, which the leader election code will observe and
// step down
signalChan := make(chan os.Signal, 1)
// Add Notification for Userland interrupt
signal.Notify(signalChan, syscall.SIGINT)
// Add Notification for SIGTERM (sent from Kubernetes)
signal.Notify(signalChan, syscall.SIGTERM)
// Add Notification for SIGKILL (sent from Kubernetes)
signal.Notify(signalChan, syscall.SIGKILL)
go func() {
<-signalChan
log.Info("Received termination, signaling shutdown")
// Cancel the context, which will in turn cancel the leadership
cancel()
// Cancel the arp context, which will in turn stop any broadcasts
}()
// (attempt to) Remove the virtual IP, incase it already exists
cluster.Network.DeleteIP()
// Managers for Vip load balancers and none-vip loadbalancers
nonVipLB := loadbalancer.LBManager{}
VipLB := loadbalancer.LBManager{}
// Defer a function to check if the bgpServer has been created and if so attempt to close it
defer func() {
if bgpServer != nil {
bgpServer.Close()
}
}()
// If Packet is enabled then we can begin our preperation work
var packetClient *packngo.Client
if c.EnableMetal {
packetClient, err = packngo.NewClient()
if err != nil {
log.Error(err)
}
// We're using Packet with BGP, popuplate the Peer information from the API
if c.EnableBGP {
log.Infoln("Looking up the BGP configuration from packet")
err = packet.BGPLookup(packetClient, c)
if err != nil {
log.Error(err)
}
}
}
if c.EnableBGP {
// Lets start BGP
log.Info("Starting the BGP server to adverise VIP routes to VGP peers")
bgpServer, err = bgp.NewBGPServer(&c.BGPConfig)
if err != nil {
log.Error(err)
}
}
if c.EnableLoadBalancer {
// Iterate through all Configurations
if len(c.LoadBalancers) != 0 {
for x := range c.LoadBalancers {
// If the load balancer doesn't bind to the VIP
if c.LoadBalancers[x].BindToVip == false {
err = nonVipLB.Add("", &c.LoadBalancers[x])
if err != nil {
log.Warnf("Error creating loadbalancer [%s] type [%s] -> error [%s]", c.LoadBalancers[x].Name, c.LoadBalancers[x].Type, err)
}
}
}
}
}
// start the leader election code loop
leaderelection.RunOrDie(ctx, leaderelection.LeaderElectionConfig{
Lock: lock,
// IMPORTANT: you MUST ensure that any code you have that
// is protected by the lease must terminate **before**
// you call cancel. Otherwise, you could have a background
// loop still running and another process could
// get elected before your background loop finished, violating
// the stated goal of the lease.
ReleaseOnCancel: true,
LeaseDuration: time.Duration(c.LeaseDuration) * time.Second,
RenewDeadline: time.Duration(c.RenewDeadline) * time.Second,
RetryPeriod: time.Duration(c.RetryPeriod) * time.Second,
Callbacks: leaderelection.LeaderCallbacks{
OnStartedLeading: func(ctx context.Context) {
// we're notified when we start
log.Info("This node is starting with leadership of the cluster")
// setup ddns first
// for first time, need to wait until IP is allocated from DHCP
if cluster.Network.IsDDNS() {
if err := cluster.StartDDNS(ctxDNS); err != nil {
log.Error(err)
}
}
// start the dns updater if address is dns
if cluster.Network.IsDNS() {
log.Infof("starting the DNS updater for the address %s", cluster.Network.DNSName())
ipUpdater := vip.NewIPUpdater(cluster.Network)
ipUpdater.Run(ctxDNS)
}
err = cluster.Network.AddIP()
if err != nil {
log.Warnf("%v", err)
}
if c.EnableMetal {
// We're not using Packet with BGP
if !c.EnableBGP {
// Attempt to attach the EIP in the standard manner
log.Debugf("Attaching the Packet EIP through the API to this host")
err = packet.AttachEIP(packetClient, c, id)
if err != nil {
log.Error(err)
}
}
}
if c.EnableBGP {
// Lets advertise the VIP over BGP, the host needs to be passed using CIDR notation
cidrVip := fmt.Sprintf("%s/%s", cluster.Network.IP(), c.VIPCIDR)
log.Debugf("Attempting to advertise the address [%s] over BGP", cidrVip)
err = bgpServer.AddHost(cidrVip)
if err != nil {
log.Error(err)
}
}
if c.EnableLoadBalancer {
// Once we have the VIP running, start the load balancer(s) that bind to the VIP
for x := range c.LoadBalancers {
if c.LoadBalancers[x].BindToVip == true {
err = VipLB.Add(cluster.Network.IP(), &c.LoadBalancers[x])
if err != nil {
log.Warnf("Error creating loadbalancer [%s] type [%s] -> error [%s]", c.LoadBalancers[x].Name, c.LoadBalancers[x].Type, err)
// Stop all load balancers associated with the VIP
err = VipLB.StopAll()
if err != nil {
log.Warnf("%v", err)
}
err = cluster.Network.DeleteIP()
if err != nil {
log.Warnf("%v", err)
}
}
}
}
}
if c.EnableARP == true {
ctxArp, cancelArp = context.WithCancel(context.Background())
ipString := cluster.Network.IP()
var ndp *vip.NdpResponder
if vip.IsIPv6(ipString) {
ndp, err = vip.NewNDPResponder(c.Interface)
if err != nil {
log.Fatalf("failed to create new NDP Responder")
}
}
go func(ctx context.Context) {
if ndp != nil {
defer ndp.Close()
}
for {
select {
case <-ctx.Done(): // if cancel() execute
return
default:
// Ensure the address exists on the interface before attempting to ARP
set, err := cluster.Network.IsSet()
if err != nil {
log.Warnf("%v", err)
}
if !set {
log.Warnf("Re-applying the VIP configuration [%s] to the interface [%s]", ipString, c.Interface)
err = cluster.Network.AddIP()
if err != nil {
log.Warnf("%v", err)
}
}
if vip.IsIPv4(ipString) {
// Gratuitous ARP, will broadcast to new MAC <-> IPv4 address
err := vip.ARPSendGratuitous(ipString, c.Interface)
if err != nil {
log.Warnf("%v", err)
}
} else {
// Gratuitous NDP, will broadcast new MAC <-> IPv6 address
err := ndp.SendGratuitous(ipString)
if err != nil {
log.Warnf("%v", err)
}
}
}
time.Sleep(3 * time.Second)
}
}(ctxArp)
}
},
OnStoppedLeading: func() {
// we can do cleanup here
log.Info("This node is becoming a follower within the cluster")
// Stop the dns context
cancelDNS()
// Stop the Arp context if it is running
cancelArp()
// Stop the BGP server
if bgpServer != nil {
err = bgpServer.Close()
if err != nil {
log.Warnf("%v", err)
}
}
// Stop all load balancers associated with the VIP
err = VipLB.StopAll()
if err != nil {
log.Warnf("%v", err)
}
err = cluster.Network.DeleteIP()
if err != nil {
log.Warnf("%v", err)
}
log.Fatal("lost leadership, restarting kube-vip")
},
OnNewLeader: func(identity string) {
// we're notified when new leader elected
log.Infof("Node [%s] is assuming leadership of the cluster", identity)
if identity == id {
// We have the lock
}
},
},
})
return nil
}
// TODO - refactor an active machine func(), this will replace the singleNode code and have a single code block
// func (cluster *Cluster) active(c *kubevip.Config) error {
// // we're notified when we start
// log.Info("This node is starting with leadership of the cluster")
// // setup ddns first
// // for first time, need to wait until IP is allocated from DHCP
// if cluster.Network.IsDDNS() {
// if err := cluster.StartDDNS(ctxDns); err != nil {
// log.Error(err)
// }
// }
// // start the dns updater if address is dns
// if cluster.Network.IsDNS() {
// log.Infof("starting the DNS updater for the address %s", cluster.Network.DNSName())
// ipUpdater := vip.NewIPUpdater(cluster.Network)
// ipUpdater.Run(ctxDns)
// }
// err := cluster.Network.AddIP()
// if err != nil {
// log.Warnf("%v", err)
// }
// if c.EnablePacket {
// // We're not using Packet with BGP
// if !c.EnableBGP {
// // Attempt to attach the EIP in the standard manner
// log.Debugf("Attaching the Packet EIP through the API to this host")
// err = packet.AttachEIP(packetClient, c, id)
// if err != nil {
// log.Error(err)
// }
// }
// }
// if c.EnableBGP {
// // Lets advertise the VIP over BGP, the host needs to be passed using CIDR notation
// cidrVip := fmt.Sprintf("%s/%s", cluster.Network.IP(), c.VIPCIDR)
// log.Debugf("Attempting to advertise the address [%s] over BGP", cidrVip)
// err = bgpServer.AddHost(cidrVip)
// if err != nil {
// log.Error(err)
// }
// }
// if c.EnableLoadBalancer {
// // Once we have the VIP running, start the load balancer(s) that bind to the VIP
// for x := range c.LoadBalancers {
// if c.LoadBalancers[x].BindToVip == true {
// err = VipLB.Add(cluster.Network.IP(), &c.LoadBalancers[x])
// if err != nil {
// log.Warnf("Error creating loadbalancer [%s] type [%s] -> error [%s]", c.LoadBalancers[x].Name, c.LoadBalancers[x].Type, err)
// // Stop all load balancers associated with the VIP
// err = VipLB.StopAll()
// if err != nil {
// log.Warnf("%v", err)
// }
// err = cluster.Network.DeleteIP()
// if err != nil {
// log.Warnf("%v", err)
// }
// }
// }
// }
// }
// if c.EnableARP == true {
// ctxArp, cancelArp = context.WithCancel(context.Background())
// go func(ctx context.Context) {
// for {
// select {
// case <-ctx.Done(): // if cancel() execute
// return
// default:
// // Gratuitous ARP, will broadcast to new MAC <-> IP
// err = vip.ARPSendGratuitous(cluster.Network.IP(), c.Interface)
// if err != nil {
// log.Warnf("%v", err)
// }
// }
// time.Sleep(3 * time.Second)
// }
// }(ctxArp)
// }
// }

View File

@@ -0,0 +1,169 @@
package cluster
import (
"context"
"fmt"
"sync"
"github.com/kube-vip/kube-vip/pkg/bgp"
"github.com/kube-vip/kube-vip/pkg/election"
"github.com/kube-vip/kube-vip/pkg/kubevip"
"github.com/kube-vip/kube-vip/pkg/lease"
"github.com/kube-vip/kube-vip/pkg/utils"
"github.com/kube-vip/kube-vip/pkg/vip"
log "log/slog"
)
// StartCluster - Begins a running instance of the Leader Election cluster
func (cluster *Cluster) StartCluster(ctx context.Context, c *kubevip.Config,
em *election.Manager, bgpServer *bgp.Server, leaseMgr *lease.Manager, killFunc func()) error {
ns, leaseName := lease.NamespaceName(c.LeaseName, c)
leaseID := lease.NewID(c.LeaderElectionType, ns, leaseName)
log.Info("cluster membership", "namespace", leaseID.Namespace(), "lock", leaseID.Name(), "id", c.NodeName)
objectName := lease.ObjectName(leaseID, "cp")
objLease, _ := leaseMgr.Acquire(context.Background(), leaseID, objectName)
defer leaseMgr.Delete(leaseID, objectName, objLease)
wg := sync.WaitGroup{}
defer wg.Wait()
electionCtx, cancelElection := objLease.NewElectionContext(ctx)
defer cancelElection()
stop := cluster.StopChannel()
wg.Go(func() {
select {
case <-stop:
cancelElection()
case <-electionCtx.Done():
}
})
// (attempt to) Remove the virtual IP, in case it already exists
for i := range cluster.Network {
deleted, err := cluster.Network[i].DeleteIP()
if err != nil {
log.Error("could not delete virtualIP", "err", err)
}
if deleted {
log.Info("deleted address", "IP", cluster.Network[i].IP(), "interface", cluster.Network[i].Interface())
}
}
for {
if !objLease.BeginElection() {
log.Debug("this election was already done, shared lease", "lease", leaseName)
leaderGeneration, elected := objLease.WaitForLeaderGeneration(electionCtx)
if !elected {
if electionCtx.Err() != nil {
return nil
}
// The runner that owned this shared lease's election ended it
// without ever being elected; take over the campaign ourselves
// instead of leaving the lease without an active runner.
continue
}
leaderCtx, cancelLeader := context.WithCancel(electionCtx)
leaderWG := sync.WaitGroup{}
leaderWG.Go(func() {
cluster.OnStartedLeading(leaderCtx, c, em, bgpServer, killFunc, true)
})
log.Debug("cluster waiting for shared election to finish", "lease", leaseName)
objLease.WaitForElectionEndAfter(electionCtx, leaderGeneration)
cancelLeader()
leaderWG.Wait()
cluster.OnStoppedLeading(c, bgpServer)
return nil
}
break
}
defer objLease.ElectionStopped()
run := &election.RunConfig{
Config: c,
LeaseID: leaseID,
LeaseAnnotations: c.LeaseAnnotations,
VIPs: controlPlaneElectionVIPs(c),
Mgr: em,
OnStartedLeading: func(ctx context.Context) {
objLease.ElectionStarted()
cluster.OnStartedLeading(ctx, c, em, bgpServer, killFunc, false)
},
OnStoppedLeading: func() {
objLease.ElectionStopped()
cluster.OnStoppedLeading(c, bgpServer)
},
OnNewLeader: func(identity string) {
cluster.OnNewLeader(identity, c)
},
}
if err := election.RunOrDie(electionCtx, run, c); err != nil {
cluster.Stop()
return fmt.Errorf("leaderelection failed: %w", err)
}
return nil
}
func controlPlaneElectionVIPs(config *kubevip.Config) []string {
configured := config.VIP
if config.Address != "" {
configured = config.Address
}
return vip.Split(configured)
}
func (cluster *Cluster) OnStartedLeading(ctx context.Context, c *kubevip.Config,
em *election.Manager, bgpServer *bgp.Server, killFunc func(), _ bool) {
labels := generateLabelsFromConfig(c.Address, kubevip.HasIP)
if err := cluster.nodeLabelMgr.AddLabel(labels); err != nil {
log.Error("error adding label to node", "err", err)
}
cluster.labelAdded = true
// As we're leading lets start the vip service
err := cluster.StartVipService(ctx, c, em, bgpServer, killFunc)
if err != nil {
log.Error("starting VIP service on leader", "err", err)
killFunc()
}
}
func (cluster *Cluster) OnStoppedLeading(c *kubevip.Config, bgpServer *bgp.Server) {
// we can do cleanup here
log.Info("This node is becoming a follower within the cluster")
if cluster.labelAdded {
labels := generateLabelsFromConfig(c.Address, kubevip.HasIP)
if err := cluster.nodeLabelMgr.RemoveLabel(labels); err != nil {
log.Error("error removing label from node", "err", err)
}
cluster.labelAdded = false
}
cluster.cleanupVIPs(c)
log.Error("lost leadership, restarting kube-vip")
}
func (cluster *Cluster) OnNewLeader(identity string, c *kubevip.Config) {
// we're notified when new leader elected
log.Info("New leader", "leader", identity)
}
func generateLabelsFromConfig(addr, labelKey string) map[string]string {
return map[string]string{
labelKey: utils.SanitizeIPForLabel(addr),
}
}

View File

@@ -1,296 +0,0 @@
package cluster
import (
"fmt"
"net"
"time"
"github.com/hashicorp/raft"
"github.com/kube-vip/kube-vip/pkg/kubevip"
"github.com/kube-vip/kube-vip/pkg/loadbalancer"
"github.com/kube-vip/kube-vip/pkg/vip"
log "github.com/sirupsen/logrus"
)
// StartRaftCluster - Begins a running instance of the Raft cluster
func (cluster *Cluster) StartRaftCluster(c *kubevip.Config) error {
// Create local configuration address
localAddress := fmt.Sprintf("%s:%d", c.LocalPeer.Address, c.LocalPeer.Port)
// Begin the Raft configuration
config := raft.DefaultConfig()
config.LocalID = raft.ServerID(c.LocalPeer.ID)
logger := log.StandardLogger().Writer()
config.LogOutput = logger
// Initialize communication
address, err := net.ResolveTCPAddr("tcp", localAddress)
if err != nil {
return err
}
// Create transport
transport, err := raft.NewTCPTransport(localAddress, address, 3, 10*time.Second, logger)
if err != nil {
return err
}
// Create Raft structures
snapshots := raft.NewInmemSnapshotStore()
logStore := raft.NewInmemStore()
stableStore := raft.NewInmemStore()
// Cluster configuration
configuration := raft.Configuration{}
// Add Local Peer
configuration.Servers = append(configuration.Servers, raft.Server{
ID: raft.ServerID(c.LocalPeer.ID),
Address: raft.ServerAddress(fmt.Sprintf("%s:%d", c.LocalPeer.Address, c.LocalPeer.Port))})
// If we want to start a node as leader then we will not add any remote peers, this will leave this as a cluster of one
// The remotePeers will add themselves to the cluster as they're added
if c.StartAsLeader != true {
for x := range c.RemotePeers {
// Make sure that we don't add in this server twice
if c.LocalPeer.Address != c.RemotePeers[x].Address {
// Build the address from the peer configuration
peerAddress := fmt.Sprintf("%s:%d", c.RemotePeers[x].Address, c.RemotePeers[x].Port)
// Set this peer into the raft configuration
configuration.Servers = append(configuration.Servers, raft.Server{
ID: raft.ServerID(c.RemotePeers[x].ID),
Address: raft.ServerAddress(peerAddress)})
}
}
log.Info("This node will attempt to start as Follower")
} else {
log.Info("This node will attempt to start as Leader")
}
// Bootstrap cluster
if err := raft.BootstrapCluster(config, logStore, stableStore, snapshots, transport, configuration); err != nil {
return err
}
// Create RAFT instance
raftServer, err := raft.NewRaft(config, cluster.stateMachine, logStore, stableStore, snapshots, transport)
if err != nil {
return err
}
cluster.stop = make(chan bool, 1)
cluster.completed = make(chan bool, 1)
ticker := time.NewTicker(time.Second)
isLeader := c.StartAsLeader
// (attempt to) Remove the virtual IP, incase it already exists
cluster.Network.DeleteIP()
// leader log broadcast - this counter is used to stop flooding STDOUT with leader log entries
var leaderbroadcast int
// Managers for Vip load balancers and none-vip loadbalancers
nonVipLB := loadbalancer.LBManager{}
VipLB := loadbalancer.LBManager{}
// Iterate through all Configurations
for x := range c.LoadBalancers {
// If the load balancer doesn't bind to the VIP
if c.LoadBalancers[x].BindToVip == false {
err = nonVipLB.Add("", &c.LoadBalancers[x])
if err != nil {
log.Warnf("Error creating loadbalancer [%s] type [%s] -> error [%s]", c.LoadBalancers[x].Name, c.LoadBalancers[x].Type, err)
}
}
}
// On a cold start the node will sleep for 5 seconds to ensure that leader elections are complete
log.Infoln("This instance will wait approximately 5 seconds, from cold start to ensure cluster elections are complete")
time.Sleep(time.Second * 5)
go func() {
for {
if c.AddPeersAsBackends == true {
// Get addresses and change backends
// c.LoadBalancers[0].Backends
// for x := range raftServer.GetConfiguration().Configuration().Servers {
// raftServer.GetConfiguration().Configuration().Servers[x].Address
// }
}
// Broadcast the current leader on this node if it's the correct time (every leaderLogcount * time.Second)
if leaderbroadcast == leaderLogcount {
log.Infof("The Node [%s] is leading", raftServer.Leader())
// Reset the timer
leaderbroadcast = 0
// ensure that if this node is the leader, it is set as the leader
if localAddress == string(raftServer.Leader()) {
// Re-broadcast arp to ensure network stays up to date
if c.EnableARP == true {
// Gratuitous ARP, will broadcast to new MAC <-> IP
err = vip.ARPSendGratuitous(cluster.Network.IP(), c.Interface)
if err != nil {
log.Warnf("%v", err)
}
}
if !isLeader {
log.Infoln("This node is leading, but isnt the leader (correcting)")
isLeader = true
}
} else {
// (attempt to) Remove the virtual IP, incase it already exists to keep nodes clean
cluster.Network.DeleteIP()
isLeader = false
}
}
leaderbroadcast++
select {
case leader := <-raftServer.LeaderCh():
log.Infoln("New Election event")
if leader {
isLeader = true
log.Info("This node is assuming leadership of the cluster")
err = cluster.Network.AddIP()
if err != nil {
log.Warnf("%v", err)
}
// Once we have the VIP running, start the load balancer(s) that bind to the VIP
for x := range c.LoadBalancers {
if c.LoadBalancers[x].BindToVip == true {
err = VipLB.Add(cluster.Network.IP(), &c.LoadBalancers[x])
if err != nil {
log.Warnf("Error creating loadbalancer [%s] type [%s] -> error [%s]", c.LoadBalancers[x].Name, c.LoadBalancers[x].Type, err)
log.Errorf("Dropping Leadership to another node in the cluster")
raftServer.LeadershipTransfer()
// Stop all load balancers associated with the VIP
err = VipLB.StopAll()
if err != nil {
log.Warnf("%v", err)
}
err = cluster.Network.DeleteIP()
if err != nil {
log.Warnf("%v", err)
}
}
}
}
if c.EnableARP == true {
// Gratuitous ARP, will broadcast to new MAC <-> IP
err = vip.ARPSendGratuitous(cluster.Network.IP(), c.Interface)
if err != nil {
log.Warnf("%v", err)
}
}
} else {
isLeader = false
log.Info("This node is becoming a follower within the cluster")
// Stop all load balancers associated with the VIP
err = VipLB.StopAll()
if err != nil {
log.Warnf("%v", err)
}
err = cluster.Network.DeleteIP()
if err != nil {
log.Warnf("%v", err)
}
}
case <-ticker.C:
if isLeader {
result, err := cluster.Network.IsSet()
if err != nil {
log.WithFields(log.Fields{"error": err, "ip": cluster.Network.IP(), "interface": cluster.Network.Interface()}).Error("Could not check ip")
}
if result == false {
log.Error("This node is leader and is adopting the virtual IP")
err = cluster.Network.AddIP()
if err != nil {
log.Warnf("%v", err)
}
// Once we have the VIP running, start the load balancer(s) that bind to the VIP
for x := range c.LoadBalancers {
if c.LoadBalancers[x].BindToVip == true {
err = VipLB.Add(cluster.Network.IP(), &c.LoadBalancers[x])
if err != nil {
log.Warnf("Error creating loadbalancer [%s] type [%s] -> error [%s]", c.LoadBalancers[x].Name, c.LoadBalancers[x].Type, err)
}
}
}
if c.EnableARP == true {
// Gratuitous ARP, will broadcast to new MAC <-> IP
err = vip.ARPSendGratuitous(cluster.Network.IP(), c.Interface)
if err != nil {
log.Warnf("%v", err)
}
}
}
}
case <-cluster.stop:
log.Info("[RAFT] Stopping this node")
log.Info("[LOADBALANCER] Stopping load balancers")
// Stop all load balancers associated with the VIP
err = VipLB.StopAll()
if err != nil {
log.Warnf("%v", err)
}
// Stop all load balancers associated with the Host
err = nonVipLB.StopAll()
if err != nil {
log.Warnf("%v", err)
}
if isLeader {
log.Info("[VIP] Releasing the Virtual IP")
err = cluster.Network.DeleteIP()
if err != nil {
log.Warnf("%v", err)
}
}
close(cluster.completed)
return
}
}
}()
log.Info("Started")
return nil
}
// Stop - Will stop the Cluster and release VIP if needed
func (cluster *Cluster) Stop() {
// Close the stop chanel, which will shut down the VIP (if needed)
close(cluster.stop)
// Wait until the completed channel is closed, signallign all shutdown tasks completed
<-cluster.completed
log.Info("Stopped")
}

View File

@@ -0,0 +1,196 @@
package cluster
import (
"context"
"slices"
"testing"
"time"
"github.com/kube-vip/kube-vip/pkg/arp"
"github.com/kube-vip/kube-vip/pkg/kubevip"
"github.com/kube-vip/kube-vip/pkg/lease"
"github.com/kube-vip/kube-vip/pkg/vip"
"github.com/vishvananda/netlink"
v1 "k8s.io/api/core/v1"
)
func TestControlPlaneElectionVIPsPreservesConfigOrder(t *testing.T) {
config := &kubevip.Config{Address: "2001:db8::10,192.0.2.10"}
want := []string{"2001:db8::10", "192.0.2.10"}
if got := controlPlaneElectionVIPs(config); !slices.Equal(got, want) {
t.Fatalf("controlPlaneElectionVIPs() = %v, want %v", got, want)
}
}
type recordingLabeler struct {
added chan struct{}
removed chan struct{}
}
func (l *recordingLabeler) AddLabel(map[string]string) error {
l.added <- struct{}{}
return nil
}
func (l *recordingLabeler) RemoveLabel(map[string]string) error {
l.removed <- struct{}{}
return nil
}
// stubNetwork is a minimal vip.Network implementation for exercising
// cleanupVIP without a real interface.
type stubNetwork struct {
ip string
deleteIPCalls int
}
func (s *stubNetwork) AddIP(bool, bool, ...int) (bool, error) { return false, nil }
func (s *stubNetwork) AddRoute(bool) (bool, error) { return false, nil }
func (s *stubNetwork) ReplaceRoute() error { return nil }
func (s *stubNetwork) DeleteIP() (bool, error) { s.deleteIPCalls++; return true, nil }
func (s *stubNetwork) DeleteRoute() error { return nil }
func (s *stubNetwork) UpdateRoutes() (bool, error) { return false, nil }
func (s *stubNetwork) IsSet() (*netlink.Addr, error) { return nil, nil }
func (s *stubNetwork) IP() string { return s.ip }
func (s *stubNetwork) CIDR() string { return s.ip + "/32" }
func (s *stubNetwork) IPisLinkLocal() bool { return false }
func (s *stubNetwork) PrepareRoute() *netlink.Route { return nil }
func (s *stubNetwork) RouteHash() string { return "" }
func (s *stubNetwork) SetIP(string) error { return nil }
func (s *stubNetwork) SetServicePorts(*v1.Service) {}
func (s *stubNetwork) Interface() string { return "eth0" }
func (s *stubNetwork) IsDADFAIL() bool { return false }
func (s *stubNetwork) IsDNS() bool { return false }
func (s *stubNetwork) IsDDNS() bool { return false }
func (s *stubNetwork) DDNSHostName() string { return "" }
func (s *stubNetwork) DNSName() string { return "" }
func (s *stubNetwork) SetMask(string) error { return nil }
func (s *stubNetwork) SetHasEndpoints(bool) {}
func (s *stubNetwork) HasEndpoints() bool { return false }
func (s *stubNetwork) ARPName() string { return "shared-vip" }
func (s *stubNetwork) GetPossibleSubnets() string { return "" }
func (s *stubNetwork) DHCPFamily() string { return "" }
func (s *stubNetwork) IPVSMark() uint32 { return 0 }
// TestCleanupVIPRetainsSharedVIPWithOneSiblingLeft reproduces the off-by-one:
// layer2Update already removes its own ARP claim before cleanupVIP runs, so a
// single remaining sibling must still block deletion.
func TestCleanupVIPRetainsSharedVIPWithOneSiblingLeft(t *testing.T) {
arpMgr := arp.NewManager(&kubevip.Config{ArpBroadcastRate: 3000})
netA := &stubNetwork{ip: "192.0.2.10"}
netB := &stubNetwork{ip: "192.0.2.10"}
instA := arp.NewInstance(netA, nil)
instB := arp.NewInstance(netB, nil)
arpMgr.Insert(instA)
arpMgr.Insert(instB)
// Cluster A's layer2Update goroutine ends first and drops its own claim,
// leaving only sibling B registered.
arpMgr.Remove(instA)
c := &Cluster{arpMgr: arpMgr}
c.cleanupVIP(&kubevip.Config{EnableARP: true}, netA, 0)
if netA.deleteIPCalls != 0 {
t.Fatalf("cleanupVIP deleted the shared VIP while a sibling was still registered")
}
}
// TestCleanupVIPsDeletesControlPlaneVIPHoldingItsOwnARPClaim covers the
// leadership loss path: OnStoppedLeading runs concurrently with the control
// plane layer2Update goroutine, so the VIP's only ARP claim is still the
// caller's own and the address must still be removed before the process exits.
func TestCleanupVIPsDeletesControlPlaneVIPHoldingItsOwnARPClaim(t *testing.T) {
arpMgr := arp.NewManager(&kubevip.Config{ArpBroadcastRate: 3000})
network := &stubNetwork{ip: "2001:db8::10"}
arpMgr.Insert(arp.NewInstance(network, nil))
c := &Cluster{arpMgr: arpMgr, Network: []vip.Network{network}}
c.cleanupVIPs(&kubevip.Config{EnableARP: true})
if network.deleteIPCalls != 1 {
t.Fatalf("cleanupVIPs made %d DeleteIP calls, want 1", network.deleteIPCalls)
}
}
func TestControlPlaneFollowsSharedServiceElection(t *testing.T) {
config := &kubevip.Config{KubernetesLeaderElection: kubevip.KubernetesLeaderElection{LeaseName: "default/shared"}}
leaseID := lease.NewID(config.LeaderElectionType, "default", "shared")
leaseMgr := lease.NewManager()
sharedLease, _ := leaseMgr.Acquire(context.Background(), leaseID, "service")
if !sharedLease.BeginElection() {
t.Fatal("Service election did not start")
}
sharedLease.ElectionStarted()
labels := &recordingLabeler{added: make(chan struct{}, 1), removed: make(chan struct{}, 1)}
cluster := &Cluster{stop: make(chan struct{}), nodeLabelMgr: labels}
done := make(chan error, 1)
go func() {
done <- cluster.StartCluster(context.Background(), config, nil, nil, leaseMgr, func() {})
}()
select {
case <-labels.added:
case <-time.After(time.Second):
t.Fatal("control plane did not activate under the shared Service election")
}
sharedLease.ElectionStopped()
select {
case err := <-done:
if err != nil {
t.Fatalf("shared control-plane follower returned an error: %v", err)
}
case <-time.After(time.Second):
t.Fatal("control plane did not stop after shared Service leadership ended")
}
select {
case <-labels.removed:
default:
t.Fatal("control-plane label was not removed after shared leadership ended")
}
if sharedLease.Ctx.Err() != nil || leaseMgr.Get(leaseID) != sharedLease {
t.Fatal("control-plane cleanup cancelled the surviving Service lease")
}
leaseMgr.Delete(leaseID, "service", sharedLease)
}
func TestStopAndWaitPreservingUpgradesInProgressStop(t *testing.T) {
done := make(chan struct{})
service := &Cluster{
stop: make(chan struct{}),
service: &servicesWorker{
stop: make(chan struct{}),
done: done,
stopping: true,
},
}
returned := make(chan struct{})
go func() {
service.StopAndWaitPreserving("192.0.2.10")
close(returned)
}()
deadline := time.Now().Add(time.Second)
for {
service.stopMu.Lock()
_, preserving := service.service.preserveVIPs["192.0.2.10"]
service.stopMu.Unlock()
if preserving {
break
}
if time.Now().After(deadline) {
t.Fatal("preserving stop did not update the in-progress worker shutdown")
}
time.Sleep(time.Millisecond)
}
service.finishServicesWorker(done)
select {
case <-returned:
case <-time.After(time.Second):
t.Fatal("preserving stop did not return after worker cleanup completed")
}
}

View File

@@ -0,0 +1,32 @@
package cluster
import (
"sync"
"sync/atomic"
"testing"
)
func TestStopConcurrentDoesNotRaceOrPanic(t *testing.T) {
c := &Cluster{stop: make(chan struct{})}
start := make(chan struct{})
var wg sync.WaitGroup
var panics atomic.Int64
for range 128 {
wg.Go(func() {
<-start
defer func() {
if recover() != nil {
panics.Add(1)
}
}()
c.Stop()
})
}
close(start)
wg.Wait()
if got := panics.Load(); got != 0 {
t.Fatalf("concurrent Stop panicked %d time(s)", got)
}
}

125
pkg/cluster/cluster_test.go Normal file
View File

@@ -0,0 +1,125 @@
package cluster_test
import (
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"crypto/x509"
"encoding/pem"
"math/big"
"os"
"path/filepath"
"strings"
"testing"
"time"
"github.com/kube-vip/kube-vip/pkg/cluster"
"github.com/kube-vip/kube-vip/pkg/kubevip"
)
func TestInitCluster_HealthCheckClientNoCA(t *testing.T) {
t.Parallel()
cfg := &kubevip.Config{
EnableBGP: true,
ControlPlaneHealthCheck: kubevip.HealthCheck{
Address: "http://localhost:6443/livez",
TimeoutSeconds: 5,
},
}
_, err := cluster.InitCluster(cfg, true, nil, nil, nil, nil)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
}
func TestInitCluster_HealthCheckClientValidCA(t *testing.T) {
t.Parallel()
caPEM := generateTestCACert(t)
caFile := filepath.Join(t.TempDir(), "ca.crt")
if err := os.WriteFile(caFile, caPEM, 0o600); err != nil {
t.Fatal(err)
}
cfg := &kubevip.Config{
EnableBGP: true,
ControlPlaneHealthCheck: kubevip.HealthCheck{
Address: "https://localhost:6443/livez",
TimeoutSeconds: 3,
CAPath: caFile,
},
}
_, err := cluster.InitCluster(cfg, true, nil, nil, nil, nil)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
}
func TestInitCluster_HealthCheckClientInvalidCAPath(t *testing.T) {
t.Parallel()
cfg := &kubevip.Config{
EnableBGP: true,
ControlPlaneHealthCheck: kubevip.HealthCheck{
Address: "https://localhost:6443/livez",
CAPath: "/nonexistent/ca.crt",
},
}
_, err := cluster.InitCluster(cfg, true, nil, nil, nil, nil)
if err == nil {
t.Fatal("expected error for invalid CA path")
}
if !strings.Contains(err.Error(), "reading health check CA cert") {
t.Errorf("expected error about reading CA cert, got: %v", err)
}
}
func TestInitCluster_HealthCheckClientInvalidCAContent(t *testing.T) {
t.Parallel()
caFile := filepath.Join(t.TempDir(), "bad-ca.crt")
if err := os.WriteFile(caFile, []byte("not a certificate"), 0o600); err != nil {
t.Fatal(err)
}
cfg := &kubevip.Config{
EnableBGP: true,
ControlPlaneHealthCheck: kubevip.HealthCheck{
Address: "https://localhost:6443/livez",
CAPath: caFile,
},
}
_, err := cluster.InitCluster(cfg, true, nil, nil, nil, nil)
if err == nil {
t.Fatal("expected error for invalid CA content")
}
if !strings.Contains(err.Error(), "contains no valid certificates") {
t.Errorf("expected error about invalid certificates, got: %v", err)
}
}
// generateTestCACert creates a self-signed CA certificate in PEM format for testing.
func generateTestCACert(t *testing.T) []byte {
t.Helper()
key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
if err != nil {
t.Fatal(err)
}
template := &x509.Certificate{
SerialNumber: big.NewInt(1),
NotBefore: time.Now(),
NotAfter: time.Now().Add(time.Hour),
IsCA: true,
BasicConstraintsValid: true,
}
certDER, err := x509.CreateCertificate(rand.Reader, template, template, &key.PublicKey, key)
if err != nil {
t.Fatal(err)
}
return pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: certDER})
}

626
pkg/cluster/service.go Normal file
View File

@@ -0,0 +1,626 @@
package cluster
import (
"context"
"errors"
"fmt"
"io/fs"
"net/http"
"net/url"
"strconv"
"strings"
"sync"
"syscall"
"time"
log "log/slog"
"github.com/kube-vip/kube-vip/pkg/arp"
"github.com/kube-vip/kube-vip/pkg/backend"
"github.com/kube-vip/kube-vip/pkg/bgp"
"github.com/kube-vip/kube-vip/pkg/election"
"github.com/kube-vip/kube-vip/pkg/kubevip"
"github.com/kube-vip/kube-vip/pkg/loadbalancer"
"github.com/kube-vip/kube-vip/pkg/utils"
"github.com/kube-vip/kube-vip/pkg/vip"
corev1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
)
func (cluster *Cluster) StartVipService(ctx context.Context, c *kubevip.Config, em *election.Manager, bgpServer bgp.BGPManager, killFunc func()) error {
var err error
var wg sync.WaitGroup
defer wg.Wait()
wg.Go(func() {
<-ctx.Done()
killFunc()
})
loadbalancers := []*loadbalancer.IPVSLoadBalancer{}
for i := range cluster.Network {
if err := ctx.Err(); err != nil {
return err
}
network := cluster.Network[i]
if network.IsDDNS() {
if err := cluster.StartDDNS(ctx, cluster.Network[i], c.DHCPBackoffAttempts, &wg); err != nil {
log.Error("failed to start DDNS", "err", err)
}
}
if err := network.SetMask(c.VIPSubnet); err != nil {
killFunc()
return fmt.Errorf("failed to set mask for subnet %q: %w", c.VIPSubnet, err)
}
// start the dns updater if address is dns
if network.IsDNS() {
log.Info("starting the DNS updater", "address", network.DNSName())
ipUpdater := vip.NewIPUpdater(network)
wg.Go(func() {
ipUpdater.Run(ctx)
})
}
if !c.EnableRoutingTable {
// Normal VIP addition, use skipDAD=false for normal DAD process
if _, err = network.AddIP(false, false); err != nil {
log.Error("failed to add IP", "address", network.IP(), "error", err)
}
}
if c.EnableBGP {
if c.ControlPlaneHealthCheck.Address != "" {
// The health check loop owns route advertisement/withdrawal when configured.
wg.Go(func() {
cluster.bgpHealthCheckLoop(ctx, c, bgpServer, network.CIDR())
})
} else {
// Lets advertise the VIP over BGP, the host needs to be passed using CIDR notation.
log.Debug("Attempting to advertise over BGP", "address", network.CIDR())
err = bgpServer.AddHost(ctx, network.CIDR(), c.NodeName)
if err != nil {
log.Error(err.Error())
}
}
}
if c.EnableLoadBalancer {
lb, err := loadbalancer.NewIPVSLB(ctx, network, c.LoadBalancerPort, c.LoadBalancerForwardingMethod,
c.BackendHealthCheckInterval, c.EgressWithNftables, killFunc, &wg)
if err != nil {
killFunc()
return fmt.Errorf("creating IPVS LoadBalancer: %w", err)
}
wg.Go(func() {
for {
select {
case <-ctx.Done():
return
default:
err = em.NodeWatcher(ctx, lb, c.Port)
if err != nil {
log.Error("Error watching node labels", "err", err)
if utils.IsPanicError(err) {
killFunc()
return
}
}
}
}
})
loadbalancers = append(loadbalancers, lb)
}
if c.EnableARP {
wg.Go(func() {
cluster.layer2Update(ctx, network, c)
})
}
}
if c.EnableLoadBalancer {
// Shutdown function that will wait on this signal, unless we call it ourselves
<-ctx.Done()
for _, lb := range loadbalancers {
err = lb.RemoveIPVSLB()
if err != nil {
log.Error("Error stopping IPVS LoadBalancer", "err", err)
}
}
}
if c.EnableRoutingTable {
backendMapV4 := backend.Map{}
backendMapV6 := backend.Map{}
// only check localhost
// An explicitly configured Kubernetes API address (static-pod
// deployments point it at the local API server, whose loopback
// listener is often the only certificate-valid local endpoint)
// takes precedence over the Node object's addresses: the check
// answers "is the local API server healthy" for every VIP family,
// regardless of the transport family of the override itself.
if entry := kubernetesAddrBackendEntry(c.KubernetesAddr, c.Port); entry != nil {
log.Info("using configured Kubernetes address for backend health checks", "address", c.KubernetesAddr)
backendMapV4[*entry] = false
backendMapV6[*entry] = false
} else {
ips := []string{}
if c.NodeName != "" {
if ips, err = getNodeIPs(ctx, c.NodeName, em.KubernetesClient); err != nil && !apierrors.IsNotFound(err) {
log.Error("failed to get IP of control-plane node", "err", err)
}
}
if len(ips) == 0 {
if !utils.IsIPv6(cluster.Network[0].IP()) {
ips = append(ips, "127.0.0.1")
} else {
ips = append(ips, "::1")
}
log.Info("no IP address found for node - will fallback to use localhost address", "addresses", ips)
}
for _, ip := range ips {
entry := backend.Entry{Addr: ip, Port: c.Port}
if !utils.IsIPv6(ip) {
backendMapV4[entry] = false
} else {
backendMapV6[entry] = false
}
}
}
backend.SetKubeConfigPath(c.K8sConfigFile)
backend.Watch(ctx, c.BackendHealthCheckInterval, func() {
for i := range cluster.Network {
network := cluster.Network[i]
networkIP := network.IP()
isNetworkV6 := utils.IsIPv6(networkIP)
log.Debug("current ip to process", "ip", networkIP)
backendMap := &backendMapV4
if isNetworkV6 {
backendMap = &backendMapV6
}
for entry := range *backendMap {
log.Debug("entry.Check() for entry", "entry", entry)
var healthy bool
if c.ControlPlaneHealthCheck.Address != "" {
req, reqErr := http.NewRequestWithContext(ctx, http.MethodGet, c.ControlPlaneHealthCheck.Address, nil)
if reqErr != nil {
log.Error("create health check request", "err", reqErr)
} else if resp, doErr := cluster.healthCheckHTTPClient.Do(req); doErr != nil {
log.Error("health check request failed", "url", c.ControlPlaneHealthCheck.Address, "err", doErr)
} else {
resp.Body.Close()
healthy = resp.StatusCode == http.StatusOK
if !healthy {
log.Warn("health check returned non-200 status", "url", c.ControlPlaneHealthCheck.Address, "status", resp.StatusCode)
}
}
} else {
healthy = entry.Check()
}
if healthy {
log.Debug("entry.Check() true")
// Normal VIP addition with precheck, use skipDAD=false for normal DAD process
_, err = network.AddIP(true, false)
if err != nil {
log.Error("error adding address", "err", err)
}
if !(*backendMap)[entry] {
log.Info("added backend", "ip", network.IP())
}
err = cluster.routeMgr.Add(c.NodeName, network, true, false)
if err != nil && !errors.Is(err, fs.ErrExist) && !errors.Is(err, syscall.ESRCH) {
log.Warn(err.Error())
} else if err == nil && !(*backendMap)[entry] {
log.Info("added route", "route", network.PrepareRoute())
} else if err == nil || errors.Is(err, fs.ErrExist) {
// Re-assert the route on every healthy cycle: routing daemons
// (e.g. zebra) can miss the single netlink event for the route,
// leaving it unadvertised even though it exists in the kernel.
// RouteReplace is idempotent and regenerates that event.
if replaceErr := network.ReplaceRoute(); replaceErr != nil {
log.Warn("re-asserting route", "err", replaceErr)
} else {
log.Debug("re-asserted route", "route", network.PrepareRoute())
}
}
(*backendMap)[entry] = true
break
}
(*backendMap)[entry] = false
}
deleteAddress := true
for entry := range *backendMap {
if (*backendMap)[entry] {
deleteAddress = false
break
}
}
if deleteAddress {
err = cluster.routeMgr.Delete(c.NodeName, network)
if err != nil {
log.Warn("deleting route", "err", err)
}
deleted, err := network.DeleteIP()
if err != nil {
log.Error("error deleting IP", "err", err)
killFunc()
return
}
if deleted {
log.Info("deleted address", "IP", network.IP(), "interface", network.Interface())
}
}
}
})
}
if c.EnableBGP {
<-ctx.Done()
}
return nil
}
func (cluster *Cluster) bgpHealthCheck(ctx context.Context, c *kubevip.Config) (bool, error) {
statusCode := 0
req, err := http.NewRequestWithContext(ctx, http.MethodGet, c.ControlPlaneHealthCheck.Address, nil)
if err != nil {
return false, fmt.Errorf("building request %v: %w", req, err)
} else {
resp, err := cluster.healthCheckHTTPClient.Do(req)
if err != nil {
return false, fmt.Errorf("checking control-plane: %w", err)
}
defer resp.Body.Close()
statusCode = resp.StatusCode
}
healthy := statusCode == http.StatusOK
if !healthy {
return healthy, fmt.Errorf("wrong status code: %d", statusCode)
}
return healthy, nil
}
func (cluster *Cluster) bgpHealthCheckLoop(ctx context.Context, c *kubevip.Config, bgpServer bgp.BGPManager, vipCIDR string) {
period := time.Duration(c.ControlPlaneHealthCheck.PeriodSeconds) * time.Second
consecutiveFailures := 0
routeAnnounced := false
ticker := time.NewTicker(period)
defer ticker.Stop()
log.Info("Starting BGP health check",
"address", c.ControlPlaneHealthCheck.Address,
"cidr", vipCIDR,
"period", period,
"timeout", cluster.healthCheckHTTPClient.Timeout,
"threshold", c.ControlPlaneHealthCheck.FailureThreshold,
)
for {
healthy, healthErr := cluster.bgpHealthCheck(ctx, c)
if healthy {
consecutiveFailures = 0
if !routeAnnounced {
log.Info("BGP health check passed, announcing route", "cidr", vipCIDR)
if err := bgpServer.AddHost(ctx, vipCIDR, c.NodeName); err != nil {
log.Error("BGP health check: failed to announce route", "cidr", vipCIDR, "err", err)
} else {
routeAnnounced = true
}
}
} else {
consecutiveFailures++
if healthErr != nil {
log.Warn("BGP health check failed", "address", c.ControlPlaneHealthCheck.Address, "consecutive", consecutiveFailures, "err", healthErr)
}
if consecutiveFailures >= c.ControlPlaneHealthCheck.FailureThreshold && routeAnnounced {
log.Warn("BGP health check threshold reached, withdrawing route", "failureThreshold", c.ControlPlaneHealthCheck.FailureThreshold, "cidr", vipCIDR)
if err := bgpServer.DelHost(ctx, vipCIDR, c.NodeName); err != nil {
log.Error("BGP health check: failed to withdraw route", "cidr", vipCIDR, "err", err)
} else {
routeAnnounced = false
}
}
}
select {
case <-ctx.Done():
if routeAnnounced {
if err := bgpServer.DelHost(ctx, vipCIDR, c.NodeName); err != nil {
log.Error("BGP health check: failed to withdraw route", "cidr", vipCIDR, "err", err)
}
}
return
case <-ticker.C:
}
}
}
// kubernetesAddrBackendEntry converts an explicitly configured Kubernetes
// API address override (config.KubernetesAddr, e.g. "https://127.0.0.1:6443"
// on static-pod deployments) into a backend health-check entry. Returns nil
// when no usable override is configured.
func kubernetesAddrBackendEntry(kubernetesAddr string, defaultPort uint16) *backend.Entry {
if kubernetesAddr == "" {
return nil
}
u, err := url.Parse(kubernetesAddr)
if err != nil || u.Hostname() == "" {
return nil
}
port := defaultPort
if p := u.Port(); p != "" {
if parsed, err := strconv.ParseUint(p, 10, 16); err == nil {
port = uint16(parsed)
}
}
return &backend.Entry{Addr: u.Hostname(), Port: port}
}
func getNodeIPs(ctx context.Context, nodename string, client *kubernetes.Clientset) ([]string, error) {
node, err := client.CoreV1().Nodes().Get(ctx, nodename, metav1.GetOptions{})
if err != nil && !apierrors.IsNotFound(err) {
return []string{}, fmt.Errorf("failed to get data about '%s' node: %w", nodename, err)
}
ips := []string{}
for _, addr := range node.Status.Addresses {
if addr.Type == corev1.NodeInternalIP {
ips = append(ips, addr.Address)
}
}
return ips, nil
}
// StartLoadBalancerService will start a VIP instance and leave it for kube-proxy to handle
func (cluster *Cluster) StartLoadBalancerService(ctx context.Context, c *kubevip.Config, bgp bgp.BGPManager, name string, wg *sync.WaitGroup) error {
// use a Go context so we can tell the arp loop code when we
// want to step down
//nolint
lbCtx, lbCancel := context.WithCancel(ctx)
var lbWg sync.WaitGroup
stop, done, err := cluster.startServicesWorker()
if err != nil {
lbCancel()
return err
}
type startedNetwork struct {
network vip.Network
routeAdded bool
ipAdded bool
bgpAdded bool
}
startedNetworks := make([]startedNetwork, 0, len(cluster.Network))
servicesWorkerStarted := false
defer func() {
if !servicesWorkerStarted {
lbCancel()
lbWg.Wait()
cleanupCtx := context.WithoutCancel(ctx)
for index := len(startedNetworks) - 1; index >= 0; index-- {
started := startedNetworks[index]
if started.bgpAdded && bgp != nil {
if err := bgp.DelHost(cleanupCtx, started.network.CIDR(), name); err != nil {
log.Warn("failed to withdraw BGP host after startup failure", "address", started.network.CIDR(), "err", err)
}
}
if started.routeAdded && cluster.routeMgr != nil {
if err := cluster.routeMgr.Delete(name, started.network); err != nil {
log.Warn("failed to delete route after startup failure", "address", started.network.CIDR(), "err", err)
}
}
if started.ipAdded {
if _, err := started.network.DeleteIP(); err != nil {
log.Warn("failed to delete VIP after startup failure", "address", started.network.IP(), "err", err)
}
}
}
cluster.finishServicesWorker(done)
}
}()
for i := range cluster.Network {
if err := ctx.Err(); err != nil {
return err
}
network := cluster.Network[i]
startedNetworks = append(startedNetworks, startedNetwork{network: network})
started := &startedNetworks[len(startedNetworks)-1]
if network.IsDDNS() {
ddnsReady := make(chan struct{})
lbWg.Go(func() {
// start the DDNS if requested
log.Debug("(svcs) start DDNS", "name", network.DNSName())
if err := cluster.StartDDNS(lbCtx, cluster.Network[i], c.DHCPBackoffAttempts, &lbWg); err != nil {
log.Error("failed to start DDNS", "err", err)
}
close(ddnsReady)
<-lbCtx.Done()
})
<-ddnsReady
}
log.Debug("current ip to process", "ip", network.IP(), "mask", c.VIPSubnet)
if err := network.SetMask(c.VIPSubnet); err != nil {
log.Error("failed to set mask", "subnet", c.VIPSubnet, "err", err)
lbCancel()
return utils.WrapPanicError(err, "failed to set mask for subnet %q", c.VIPSubnet)
}
existing, err := network.IsSet()
if err != nil {
lbCancel()
return fmt.Errorf("check existing VIP %q: %w", network.IP(), err)
}
log.Debug("config flags", "enable_routing_table", c.EnableRoutingTable, "enable_leader_election", c.EnableLeaderElection, "enable_services_election", c.EnableServicesElection)
if c.EnableRoutingTable && (c.EnableLeaderElection || c.EnableServicesElection) {
err = cluster.routeMgr.Add(name, network, false, false)
if err != nil {
log.Warn(err.Error())
} else {
started.routeAdded = true
log.Info("successful add Route")
}
}
if shouldAddServiceIP(c) {
// Normal VIP addition, use skipDAD=false for normal DAD process
// Note: When WireGuard is enabled, the VIP is added to the tunnel interface
// instead of lo, so we skip adding it here.
added, addErr := network.AddIP(false, false)
started.ipAdded = existing == nil && added
if addErr != nil {
log.Warn(addErr.Error())
} else {
log.Info("successful add IP", "address", network.IP())
}
}
if c.EnableARP {
lbWg.Go(func() {
cluster.layer2Update(lbCtx, network, c)
})
}
if c.EnableBGP && (c.EnableLeaderElection || c.EnableServicesElection) {
// Lets advertise the VIP over BGP, the host needs to be passed using CIDR notation
log.Debug("(svcs) attempting to advertise over BGP", "address", network.CIDR())
err = bgp.AddHost(lbCtx, network.CIDR(), name)
if err != nil {
log.Error(err.Error())
} else {
started.bgpAdded = true
}
}
}
wg.Go(func() {
defer cluster.finishServicesWorker(done)
for i := range cluster.Network {
network := cluster.Network[i]
// start the dns updater if address is dns
if network.IsDNS() {
log.Info("(svcs) starting the DNS updater", "address", network.DNSName(), "ip", network.IP())
ipUpdater := vip.NewIPUpdater(network)
wg.Go(func() {
ipUpdater.Run(lbCtx)
})
}
}
select {
case <-stop:
case <-ctx.Done():
}
// Stop the loadbalancer context if it is running
lbCancel()
lbWg.Wait() // wait for all cluster ARP/NDP to be finished
log.Info("[LOADBALANCER] Stopping load balancers", "name", name)
if c.EnableRoutingTable {
for i := range cluster.Network {
if err := cluster.routeMgr.Delete(name, cluster.Network[i]); err != nil {
log.Warn(err.Error())
}
}
return
}
cluster.cleanupServiceVIPs(c, done)
})
servicesWorkerStarted = true
return nil
}
func shouldAddServiceIP(c *kubevip.Config) bool {
return !c.EnableRoutingTable && (!c.EnableBGP || c.BGPAttachIPToInterface) && !c.EnableWireguard
}
// Layer2Update, handles the creation of the
func (cluster *Cluster) layer2Update(ctx context.Context, network vip.Network, c *kubevip.Config) {
var ndp *vip.NdpResponder
var err error
ipString := network.IP()
if utils.IsIPv6(ipString) {
if network.IPisLinkLocal() {
log.Error("layer2 is link-local can't use NDP", "address", ipString)
} else {
ndp, err = waitNDPResponder(ctx, network.Interface())
if err != nil {
log.Error("failed to create new NDP Responder", "error", err)
} else {
if ndp != nil {
defer ndp.Close()
}
}
}
}
log.Info("layer 2 broadcaster starting", "IP", network.IP(), "device", network.Interface())
log.Debug("layer 2 update", "ip", ipString, "interface", network.Interface(), "ms", c.ArpBroadcastRate)
arpInstance := arp.NewInstance(network, ndp)
cluster.arpMgr.Insert(arpInstance)
<-ctx.Done() // if cancel() execute
log.Debug("ending layer 2 update", "ip", ipString, "interface", network.Interface(), "ms", c.ArpBroadcastRate)
cluster.arpMgr.RemoveOnLeadershipLoss(arpInstance)
}
func waitNDPResponder(ctx context.Context, ifaceName string) (*vip.NdpResponder, error) {
ndp, err := vip.NewNDPResponder(ifaceName)
if err != nil && strings.Contains(err.Error(), "no such device") {
log.Warn("unable to create NDP responder at first try", "interface", ifaceName, "err", err)
ndpCreateCtx, cancel := context.WithTimeout(ctx, 2*time.Minute)
defer cancel()
ticker := time.NewTicker(time.Second)
for {
select {
case <-ndpCreateCtx.Done():
return nil, fmt.Errorf("failed to create NDP responder for interface %q: %w", ifaceName, ndpCreateCtx.Err())
case <-ticker.C:
ndp, err = vip.NewNDPResponder(ifaceName)
if err != nil {
log.Warn("unable to create NDP responder on retry", "interface", ifaceName, "err", err)
} else {
return ndp, nil
}
}
}
} else if err != nil {
return nil, fmt.Errorf("unable to create NDP responder for interface %q: %w", ifaceName, err)
}
return ndp, nil
}

View File

@@ -0,0 +1,55 @@
package cluster
import (
"testing"
"github.com/kube-vip/kube-vip/pkg/kubevip"
)
func TestShouldAddServiceIP(t *testing.T) {
tests := []struct {
name string
config *kubevip.Config
want bool
}{
{
name: "BGP default does not attach IP",
config: &kubevip.Config{EnableBGP: true},
want: false,
},
{
name: "BGP opt-in attaches IP",
config: &kubevip.Config{
EnableBGP: true,
BGPAttachIPToInterface: true,
},
want: true,
},
{
name: "routing table takes precedence",
config: &kubevip.Config{
EnableBGP: true,
BGPAttachIPToInterface: true,
EnableRoutingTable: true,
},
want: false,
},
{
name: "WireGuard takes precedence",
config: &kubevip.Config{
EnableBGP: true,
BGPAttachIPToInterface: true,
EnableWireguard: true,
},
want: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := shouldAddServiceIP(tt.config); got != tt.want {
t.Fatalf("shouldAddServiceIP() = %t, want %t", got, tt.want)
}
})
}
}

View File

@@ -0,0 +1,61 @@
package cluster
import (
"testing"
)
func TestKubernetesAddrBackendEntry(t *testing.T) {
cases := []struct {
name string
addr string
port uint16
wantAddr string
wantPort uint16
wantNil bool
}{
{
name: "explicit v4 loopback with port",
addr: "https://127.0.0.1:6443",
port: 9999,
wantAddr: "127.0.0.1",
wantPort: 6443,
},
{
name: "hostname without port falls back to config port",
addr: "https://localhost",
port: 6443,
wantAddr: "localhost",
wantPort: 6443,
},
{
name: "empty override",
addr: "",
port: 6443,
wantNil: true,
},
{
name: "garbage override",
addr: "://not-a-url",
port: 6443,
wantNil: true,
},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
entry := kubernetesAddrBackendEntry(tc.addr, tc.port)
if tc.wantNil {
if entry != nil {
t.Fatalf("expected nil entry, got %+v", entry)
}
return
}
if entry == nil {
t.Fatal("expected an entry, got nil")
}
if entry.Addr != tc.wantAddr || entry.Port != tc.wantPort {
t.Fatalf("got %+v, want addr %q port %d", entry, tc.wantAddr, tc.wantPort)
}
})
}
}

548
pkg/cluster/service_test.go Normal file
View File

@@ -0,0 +1,548 @@
package cluster_test
import (
"context"
"encoding/pem"
"errors"
"net/http"
"net/http/httptest"
"os"
"path/filepath"
"sync"
"sync/atomic"
"testing"
"time"
"github.com/kube-vip/kube-vip/pkg/bgp"
"github.com/kube-vip/kube-vip/pkg/cluster"
"github.com/kube-vip/kube-vip/pkg/kubevip"
"github.com/kube-vip/kube-vip/pkg/route"
"github.com/kube-vip/kube-vip/pkg/vip"
"github.com/vishvananda/netlink"
corev1 "k8s.io/api/core/v1"
)
const testCIDR = "10.0.0.34/32"
func TestBGPHealthCheckLoop_AnnouncesOnHealthy(t *testing.T) {
t.Parallel()
healthcheck := newTestHealthServer(t, http.StatusOK)
t.Cleanup(healthcheck.server.Close)
bgpManager := newMockBGPRouteManager()
startVipService(t, newBGPConfig(healthcheck.server.URL, healthcheck.caPath), bgpManager)
expectEventually(t, func() bool { return bgpManager.isAnnounced() },
"route should be announced")
}
func TestServicesWorkerStopAndWaitDrainsBeforeRestart(t *testing.T) {
config := &kubevip.Config{}
serviceCluster, err := cluster.InitCluster(config, true, nil, nil, nil, nil)
if err != nil {
t.Fatalf("InitCluster() error = %v", err)
}
var workers sync.WaitGroup
if err := serviceCluster.StartLoadBalancerService(context.Background(), config, nil, "service", &workers); err != nil {
t.Fatalf("first StartLoadBalancerService() error = %v", err)
}
if err := serviceCluster.StartLoadBalancerService(context.Background(), config, nil, "service", &workers); err == nil {
t.Fatal("second StartLoadBalancerService() started while the first workers were active")
}
serviceCluster.StopAndWait()
if err := serviceCluster.StartLoadBalancerService(context.Background(), config, nil, "service", &workers); err != nil {
t.Fatalf("StartLoadBalancerService() after StopAndWait error = %v", err)
}
serviceCluster.StopAndWait()
workers.Wait()
}
func TestServicesWorkerStopAndWaitPreservingDrainsBeforeRestart(t *testing.T) {
config := &kubevip.Config{}
serviceCluster, err := cluster.InitCluster(config, true, nil, nil, nil, nil)
if err != nil {
t.Fatalf("InitCluster() error = %v", err)
}
var workers sync.WaitGroup
if err := serviceCluster.StartLoadBalancerService(context.Background(), config, nil, "service", &workers); err != nil {
t.Fatalf("StartLoadBalancerService() error = %v", err)
}
serviceCluster.StopAndWait()
if err := serviceCluster.StartLoadBalancerService(context.Background(), config, nil, "service", &workers); err != nil {
t.Fatalf("StartLoadBalancerService() after preserving stop error = %v", err)
}
serviceCluster.StopAndWait()
workers.Wait()
}
func TestStartLoadBalancerServiceRollsBackEarlierNetwork(t *testing.T) {
first := &mockNetwork{ip: "192.0.2.10", cidr: "192.0.2.10/32"}
second := &mockNetwork{ip: "192.0.2.11", cidr: "192.0.2.11/32", setMaskErr: errors.New("set mask")}
serviceCluster, err := cluster.InitCluster(&kubevip.Config{}, true, nil, nil, nil, nil)
if err != nil {
t.Fatalf("InitCluster() error = %v", err)
}
serviceCluster.Network = []vip.Network{first, second}
if err := serviceCluster.StartLoadBalancerService(context.Background(), &kubevip.Config{VIPSubnet: "32"}, nil, "service", &sync.WaitGroup{}); err == nil {
t.Fatal("StartLoadBalancerService() error = nil, want second-network failure")
}
first.mu.Lock()
addCalls, deleteCalls, present := first.addIPCalls, first.deleteIPCalls, first.present
first.mu.Unlock()
if addCalls != 1 || deleteCalls != 1 || present {
t.Fatalf("first network rollback = add %d, delete %d, present %t; want 1, 1, false", addCalls, deleteCalls, present)
}
serviceCluster.StopAndWait()
}
func TestStartLoadBalancerServiceRollbackPreservesExistingVIP(t *testing.T) {
first := &mockNetwork{ip: "192.0.2.10", cidr: "192.0.2.10/32", present: true}
second := &mockNetwork{ip: "192.0.2.11", cidr: "192.0.2.11/32", setMaskErr: errors.New("set mask")}
serviceCluster, err := cluster.InitCluster(&kubevip.Config{}, true, nil, nil, nil, nil)
if err != nil {
t.Fatalf("InitCluster() error = %v", err)
}
serviceCluster.Network = []vip.Network{first, second}
if err := serviceCluster.StartLoadBalancerService(context.Background(), &kubevip.Config{VIPSubnet: "32"}, nil, "service", &sync.WaitGroup{}); err == nil {
t.Fatal("StartLoadBalancerService() error = nil, want second-network failure")
}
first.mu.Lock()
addCalls, deleteCalls, present := first.addIPCalls, first.deleteIPCalls, first.present
first.mu.Unlock()
if addCalls != 1 || deleteCalls != 0 || !present {
t.Fatalf("existing VIP rollback = add %d, delete %d, present %t; want 1, 0, true", addCalls, deleteCalls, present)
}
serviceCluster.StopAndWait()
}
func TestStartLoadBalancerServiceCancelledContextDoesNotConfigureVIP(t *testing.T) {
network := &mockNetwork{ip: "192.0.2.10", cidr: "192.0.2.10/32"}
serviceCluster, err := cluster.InitCluster(&kubevip.Config{}, true, nil, nil, nil, nil)
if err != nil {
t.Fatalf("InitCluster() error = %v", err)
}
serviceCluster.Network = []vip.Network{network}
ctx, cancel := context.WithCancel(context.Background())
cancel()
err = serviceCluster.StartLoadBalancerService(ctx, &kubevip.Config{VIPSubnet: "32"}, nil, "service", &sync.WaitGroup{})
if !errors.Is(err, context.Canceled) {
t.Fatalf("StartLoadBalancerService() error = %v, want context.Canceled", err)
}
network.mu.Lock()
addCalls := network.addIPCalls
network.mu.Unlock()
if addCalls != 0 {
t.Fatalf("AddIP calls = %d, want 0 after context cancellation", addCalls)
}
}
func TestBGPHealthCheckLoop_NoAnnouncementUntilHealthy(t *testing.T) {
t.Parallel()
healthcheck := newTestHealthServer(t, http.StatusInternalServerError)
t.Cleanup(healthcheck.server.Close)
bgpManager := newMockBGPRouteManager()
startVipService(t, newBGPConfig(healthcheck.server.URL, healthcheck.caPath), bgpManager)
expectConsistently(t, func() bool { return !bgpManager.isAnnounced() },
2*time.Second, "route should not be announced while unhealthy")
healthcheck.setStatus(http.StatusOK)
expectEventually(t, func() bool { return bgpManager.isAnnounced() },
"route should be announced after recovery")
}
func TestBGPHealthCheckLoop_WithdrawsAfterThreshold(t *testing.T) {
t.Parallel()
healthcheck := newTestHealthServer(t, http.StatusOK)
t.Cleanup(healthcheck.server.Close)
bgpManager := newMockBGPRouteManager()
cfg := newBGPConfig(healthcheck.server.URL, healthcheck.caPath)
cfg.ControlPlaneHealthCheck.FailureThreshold = 3
startVipService(t, cfg, bgpManager)
expectEventually(t, func() bool { return bgpManager.isAnnounced() },
"route should be announced")
healthcheck.setStatus(http.StatusServiceUnavailable)
expectConsistently(t, func() bool { return bgpManager.isAnnounced() },
1500*time.Millisecond, "route should stay announced before threshold is reached")
expectEventually(t, func() bool { return !bgpManager.isAnnounced() },
"route should be withdrawn after threshold")
}
func TestBGPHealthCheckLoop_ReAnnouncesOnRecovery(t *testing.T) {
t.Parallel()
healthcheck := newTestHealthServer(t, http.StatusOK)
t.Cleanup(healthcheck.server.Close)
bgpManager := newMockBGPRouteManager()
cfg := newBGPConfig(healthcheck.server.URL, healthcheck.caPath)
cfg.ControlPlaneHealthCheck.FailureThreshold = 1
startVipService(t, cfg, bgpManager)
expectEventually(t, func() bool { return bgpManager.isAnnounced() },
"route should be announced")
healthcheck.setStatus(http.StatusServiceUnavailable)
expectEventually(t, func() bool { return !bgpManager.isAnnounced() },
"route should be withdrawn")
healthcheck.setStatus(http.StatusOK)
expectEventually(t, func() bool { return bgpManager.isAnnounced() },
"route should be re-announced")
}
func TestBGPHealthCheckLoop_StopsOnContextCancel(t *testing.T) {
t.Parallel()
healthcheck := newTestHealthServer(t, http.StatusOK)
t.Cleanup(healthcheck.server.Close)
bgpManager := newMockBGPRouteManager()
cancelContext, vipServiceDone := startVipService(t, newBGPConfig(healthcheck.server.URL, healthcheck.caPath), bgpManager)
expectEventually(t, func() bool { return bgpManager.isAnnounced() },
"route should be announced")
cancelContext()
select {
case <-vipServiceDone:
case <-time.After(5 * time.Second):
t.Fatal("vipService did not stop after context cancellation")
}
}
func TestBGPHealthCheckLoop_RetriesAddHostOnFailure(t *testing.T) {
t.Parallel()
healthcheck := newTestHealthServer(t, http.StatusOK)
t.Cleanup(healthcheck.server.Close)
bgpManager := newMockBGPRouteManager()
bgpManager.setAddErr(errTestAddHost)
startVipService(t, newBGPConfig(healthcheck.server.URL, healthcheck.caPath), bgpManager)
expectConsistently(t, func() bool { return !bgpManager.isAnnounced() },
2*time.Second, "route should not be announced while AddHost errors")
bgpManager.setAddErr(nil)
expectEventually(t, func() bool { return bgpManager.isAnnounced() },
"route should be announced after clearing AddHost error")
}
func TestBGPHealthCheckLoop_RetriesDelHostOnFailure(t *testing.T) {
t.Parallel()
healthcheck := newTestHealthServer(t, http.StatusOK)
t.Cleanup(healthcheck.server.Close)
bgpManager := newMockBGPRouteManager()
cfg := newBGPConfig(healthcheck.server.URL, healthcheck.caPath)
cfg.ControlPlaneHealthCheck.FailureThreshold = 1
startVipService(t, cfg, bgpManager)
expectEventually(t, func() bool { return bgpManager.isAnnounced() },
"route should be announced")
bgpManager.setDelErr(errTestDelHost)
healthcheck.setStatus(http.StatusServiceUnavailable)
expectConsistently(t, func() bool { return bgpManager.isAnnounced() },
1500*time.Millisecond, "route should stay announced while DelHost errors")
bgpManager.setDelErr(nil)
expectEventually(t, func() bool { return !bgpManager.isAnnounced() },
"route should be withdrawn after clearing DelHost error")
}
func TestRoutingTableHealthCheck_AddsVIPWhenHealthy(t *testing.T) {
t.Parallel()
healthcheck := newTestHealthServer(t, http.StatusOK)
t.Cleanup(healthcheck.server.Close)
network := &mockNetwork{ip: "10.0.0.1", cidr: testCIDR}
startRoutingTableVipService(t, newRoutingTableConfig(healthcheck.server.URL, healthcheck.caPath), network)
expectEventually(t, network.isPresent,
"VIP should be added while health check is healthy")
}
func TestRoutingTableHealthCheck_RemovesVIPWhenUnhealthy(t *testing.T) {
t.Parallel()
healthcheck := newTestHealthServer(t, http.StatusOK)
t.Cleanup(healthcheck.server.Close)
network := &mockNetwork{ip: "10.0.0.1", cidr: testCIDR}
startRoutingTableVipService(t, newRoutingTableConfig(healthcheck.server.URL, healthcheck.caPath), network)
expectEventually(t, network.isPresent,
"VIP should be added while health check is healthy")
healthcheck.setStatus(http.StatusServiceUnavailable)
expectEventually(t, func() bool { return !network.isPresent() },
"VIP should be removed once health check becomes unhealthy")
}
var (
errTestAddHost = &testError{msg: "mock AddHost error"}
errTestDelHost = &testError{msg: "mock DelHost error"}
)
type testError struct{ msg string }
func (e *testError) Error() string { return e.msg }
// startVipService launches vipService in a goroutine with a mock network and
// registers a cleanup to cancel the context and wait for it to finish.
// Uses InitCluster so the real code parses certs for the BGP health check client.
func startVipService(t *testing.T, cfg *kubevip.Config, bgpServer bgp.BGPManager) (context.CancelFunc, <-chan struct{}) {
t.Helper()
c, err := cluster.InitCluster(cfg, true, nil, nil, nil, nil)
if err != nil {
t.Fatalf("InitCluster: %v", err)
}
c.Network = []vip.Network{&mockNetwork{ip: "10.0.0.1", cidr: testCIDR}}
ctx, cancel := context.WithCancel(context.Background())
done := make(chan struct{})
go func() {
_ = c.StartVipService(ctx, cfg, nil, bgpServer, func() {})
close(done)
}()
t.Cleanup(func() {
cancel()
<-done
})
return cancel, done
}
// startRoutingTableVipService launches vipService in routing-table mode with a
// mock network and a real route.Manager (which only drives the mock network's
// route methods, so no netlink calls happen). Registers cleanup to stop it.
func startRoutingTableVipService(t *testing.T, cfg *kubevip.Config, network *mockNetwork) {
t.Helper()
c, err := cluster.InitCluster(cfg, true, nil, nil, route.NewManager(), nil)
if err != nil {
t.Fatalf("InitCluster: %v", err)
}
c.Network = []vip.Network{network}
ctx, cancel := context.WithCancel(context.Background())
done := make(chan struct{})
go func() {
_ = c.StartVipService(ctx, cfg, nil, nil, func() {})
close(done)
}()
t.Cleanup(func() {
cancel()
<-done
})
}
func newRoutingTableConfig(url, caPath string) *kubevip.Config {
cfg := newBGPConfig(url, caPath)
cfg.EnableBGP = false
cfg.EnableRoutingTable = true
cfg.BackendHealthCheckInterval = 1
return cfg
}
func newBGPConfig(url, caPath string) *kubevip.Config {
return &kubevip.Config{
EnableBGP: true,
ControlPlaneHealthCheck: kubevip.HealthCheck{
Address: url,
CAPath: caPath,
PeriodSeconds: 1,
TimeoutSeconds: 2,
FailureThreshold: 1,
},
}
}
// mockBGPRouteManager tracks announced addresses as a set.
// AddHost adds, DelHost removes. Errors prevent state changes.
type mockBGPRouteManager struct {
mu sync.Mutex
announced map[string]bool
addErr error
delErr error
}
func newMockBGPRouteManager() *mockBGPRouteManager {
return &mockBGPRouteManager{announced: make(map[string]bool)}
}
func (m *mockBGPRouteManager) AddHost(_ context.Context, addr string, _ string) error {
m.mu.Lock()
defer m.mu.Unlock()
if m.addErr != nil {
return m.addErr
}
m.announced[addr] = true
return nil
}
func (m *mockBGPRouteManager) DelHost(_ context.Context, addr string, _ string) error {
m.mu.Lock()
defer m.mu.Unlock()
if m.delErr != nil {
return m.delErr
}
delete(m.announced, addr)
return nil
}
func (m *mockBGPRouteManager) isAnnounced() bool {
m.mu.Lock()
defer m.mu.Unlock()
return m.announced[testCIDR]
}
func (m *mockBGPRouteManager) setAddErr(err error) {
m.mu.Lock()
m.addErr = err
m.mu.Unlock()
}
func (m *mockBGPRouteManager) setDelErr(err error) {
m.mu.Lock()
m.delErr = err
m.mu.Unlock()
}
// mockNetwork implements vip.Network with no-op operations.
type mockNetwork struct {
ip string
cidr string
mu sync.Mutex
present bool
setMaskErr error
addIPCalls int
deleteIPCalls int
}
func (m *mockNetwork) AddIP(bool, bool, ...int) (bool, error) {
m.mu.Lock()
defer m.mu.Unlock()
m.addIPCalls++
m.present = true
return true, nil
}
func (m *mockNetwork) DeleteIP() (bool, error) {
m.mu.Lock()
defer m.mu.Unlock()
m.deleteIPCalls++
deleted := m.present
m.present = false
return deleted, nil
}
func (m *mockNetwork) isPresent() bool {
m.mu.Lock()
defer m.mu.Unlock()
return m.present
}
func (m *mockNetwork) AddRoute(bool) (bool, error) { return false, nil }
func (m *mockNetwork) ReplaceRoute() error { return nil }
func (m *mockNetwork) DeleteRoute() error { return nil }
func (m *mockNetwork) UpdateRoutes() (bool, error) { return false, nil }
func (m *mockNetwork) IsSet() (*netlink.Addr, error) {
m.mu.Lock()
defer m.mu.Unlock()
if m.present {
return &netlink.Addr{}, nil
}
return nil, nil
}
func (m *mockNetwork) IP() string { return m.ip }
func (m *mockNetwork) CIDR() string { return m.cidr }
func (m *mockNetwork) IPisLinkLocal() bool { return false }
func (m *mockNetwork) PrepareRoute() *netlink.Route { return nil }
func (m *mockNetwork) RouteHash() string { return "" }
func (m *mockNetwork) SetIP(string) error { return nil }
func (m *mockNetwork) SetServicePorts(*corev1.Service) {}
func (m *mockNetwork) Interface() string { return "eth0" }
func (m *mockNetwork) IsDADFAIL() bool { return false }
func (m *mockNetwork) IsDNS() bool { return false }
func (m *mockNetwork) IsDDNS() bool { return false }
func (m *mockNetwork) DDNSHostName() string { return "" }
func (m *mockNetwork) DNSName() string { return "" }
func (m *mockNetwork) SetMask(string) error { return m.setMaskErr }
func (m *mockNetwork) SetHasEndpoints(bool) {}
func (m *mockNetwork) HasEndpoints() bool { return false }
func (m *mockNetwork) ARPName() string { return "" }
func (m *mockNetwork) GetPossibleSubnets() string { return "" }
func (m *mockNetwork) DHCPFamily() string { return "" }
func (m *mockNetwork) IPVSMark() uint32 { return 0 }
// testHealthServer wraps an HTTPS httptest.Server with an atomic status code.
// caPath is the path to the server's CA cert for client verification.
type testHealthServer struct {
server *httptest.Server
statusCode atomic.Int64
caPath string
}
func newTestHealthServer(t *testing.T, status int) *testHealthServer {
t.Helper()
healthcheck := &testHealthServer{}
healthcheck.statusCode.Store(int64(status))
healthcheck.server = httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
w.WriteHeader(int(healthcheck.statusCode.Load()))
}))
cert := healthcheck.server.Certificate()
if cert == nil {
t.Fatal("TLS server has no certificate")
}
caPEM := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: cert.Raw})
caFile := filepath.Join(t.TempDir(), "ca.crt")
if err := os.WriteFile(caFile, caPEM, 0o600); err != nil {
t.Fatal(err)
}
healthcheck.caPath = caFile
return healthcheck
}
func (ths *testHealthServer) setStatus(code int) {
ths.statusCode.Store(int64(code))
}
// expectConsistently continuously checks that condition remains true for the given duration.
// Fails immediately if the condition becomes false at any point.
func expectConsistently(t *testing.T, condition func() bool, duration time.Duration, msg string) {
t.Helper()
deadline := time.Now().Add(duration)
for time.Now().Before(deadline) {
if !condition() {
t.Fatalf("condition violated: %s", msg)
}
time.Sleep(50 * time.Millisecond)
}
}
// expectEventually polls condition until it returns true or 5s timeout is reached.
func expectEventually(t *testing.T, condition func() bool, msg string) {
t.Helper()
deadline := time.Now().Add(5 * time.Second)
for time.Now().Before(deadline) {
if condition() {
return
}
time.Sleep(50 * time.Millisecond)
}
t.Fatalf("timeout: %s", msg)
}

View File

@@ -1,219 +0,0 @@
package cluster
import (
"context"
"fmt"
"time"
log "github.com/sirupsen/logrus"
"github.com/kube-vip/kube-vip/pkg/bgp"
"github.com/kube-vip/kube-vip/pkg/kubevip"
"github.com/kube-vip/kube-vip/pkg/loadbalancer"
"github.com/kube-vip/kube-vip/pkg/vip"
)
// StartSingleNode will start a single node cluster
func (cluster *Cluster) StartSingleNode(c *kubevip.Config, disableVIP bool) error {
// Start kube-vip as a single node server
// TODO - Split all this code out as a seperate function
log.Infoln("Starting kube-vip as a single node cluster")
log.Info("This node is assuming leadership of the cluster")
cluster.stop = make(chan bool, 1)
cluster.completed = make(chan bool, 1)
// Managers for Vip load balancers and none-vip loadbalancers
nonVipLB := loadbalancer.LBManager{}
VipLB := loadbalancer.LBManager{}
// Iterate through all Configurations
for x := range c.LoadBalancers {
// If the load balancer doesn't bind to the VIP
if c.LoadBalancers[x].BindToVip == false {
err := nonVipLB.Add("", &c.LoadBalancers[x])
if err != nil {
log.Warnf("Error creating loadbalancer [%s] type [%s] -> error [%s]", c.LoadBalancers[x].Name, c.LoadBalancers[x].Type, err)
}
}
}
if !disableVIP {
err := cluster.Network.DeleteIP()
if err != nil {
log.Warnf("Attempted to clean existing VIP => %v", err)
}
err = cluster.Network.AddIP()
if err != nil {
log.Warnf("%v", err)
}
// Once we have the VIP running, start the load balancer(s) that bind to the VIP
for x := range c.LoadBalancers {
if c.LoadBalancers[x].BindToVip == true {
err = VipLB.Add(cluster.Network.IP(), &c.LoadBalancers[x])
if err != nil {
log.Warnf("Error creating loadbalancer [%s] type [%s] -> error [%s]", c.LoadBalancers[x].Name, c.LoadBalancers[x].Type, err)
}
}
}
}
if c.EnableARP == true {
// Gratuitous ARP, will broadcast to new MAC <-> IP
err := vip.ARPSendGratuitous(cluster.Network.IP(), c.Interface)
if err != nil {
log.Warnf("%v", err)
}
}
go func() {
for {
select {
case <-cluster.stop:
log.Info("[LOADBALANCER] Stopping load balancers")
// Stop all load balancers associated with the VIP
err := VipLB.StopAll()
if err != nil {
log.Warnf("%v", err)
}
// Stop all load balancers associated with the Host
err = nonVipLB.StopAll()
if err != nil {
log.Warnf("%v", err)
}
if !disableVIP {
log.Info("[VIP] Releasing the Virtual IP")
err = cluster.Network.DeleteIP()
if err != nil {
log.Warnf("%v", err)
}
}
close(cluster.completed)
return
}
}
}()
log.Infoln("Started Load Balancer and Virtual IP")
return nil
}
// StartLoadBalancerService will start a VIP instance and leave it for kube-proxy to handle
func (cluster *Cluster) StartLoadBalancerService(c *kubevip.Config, bgp *bgp.Server) error {
// Start a kube-vip loadbalancer service
log.Infof("Starting advertising address [%s] with kube-vip", c.VIP)
// use a Go context so we can tell the arp loop code when we
// want to step down
ctxArp, cancelArp := context.WithCancel(context.Background())
defer cancelArp()
cluster.stop = make(chan bool, 1)
cluster.completed = make(chan bool, 1)
err := cluster.Network.DeleteIP()
if err != nil {
log.Warnf("Attempted to clean existing VIP => %v", err)
}
err = cluster.Network.AddIP()
if err != nil {
log.Warnf("%v", err)
}
if c.EnableARP == true {
ctxArp, cancelArp = context.WithCancel(context.Background())
ipString := cluster.Network.IP()
var ndp *vip.NdpResponder
if vip.IsIPv6(ipString) {
ndp, err = vip.NewNDPResponder(c.Interface)
if err != nil {
log.Fatalf("failed to create new NDP Responder")
}
}
go func(ctx context.Context) {
if ndp != nil {
defer ndp.Close()
}
for {
select {
case <-ctx.Done(): // if cancel() execute
return
default:
// Ensure the address exists on the interface before attempting to ARP
set, err := cluster.Network.IsSet()
if err != nil {
log.Warnf("%v", err)
}
if !set {
log.Warnf("Re-applying the VIP configuration [%s] to the interface [%s]", ipString, c.Interface)
err = cluster.Network.AddIP()
if err != nil {
log.Warnf("%v", err)
}
}
if vip.IsIPv4(ipString) {
// Gratuitous ARP, will broadcast to new MAC <-> IPv4 address
err := vip.ARPSendGratuitous(ipString, c.Interface)
if err != nil {
log.Warnf("%v", err)
}
} else {
// Gratuitous NDP, will broadcast new MAC <-> IPv6 address
err := ndp.SendGratuitous(ipString)
if err != nil {
log.Warnf("%v", err)
}
}
}
time.Sleep(3 * time.Second)
}
}(ctxArp)
}
if c.EnableBGP {
// Lets advertise the VIP over BGP, the host needs to be passed using CIDR notation
cidrVip := fmt.Sprintf("%s/%s", cluster.Network.IP(), c.VIPCIDR)
log.Debugf("Attempting to advertise the address [%s] over BGP", cidrVip)
err = bgp.AddHost(cidrVip)
if err != nil {
log.Error(err)
}
}
go func() {
for {
select {
case <-cluster.stop:
// Stop the Arp context if it is running
cancelArp()
log.Info("[LOADBALANCER] Stopping load balancers")
log.Infof("[VIP] Releasing the Virtual IP [%s]", c.VIP)
err = cluster.Network.DeleteIP()
if err != nil {
log.Warnf("%v", err)
}
close(cluster.completed)
return
}
}
}()
log.Infoln("Started Load Balancer and Virtual IP")
return nil
}

View File

@@ -1,39 +0,0 @@
package cluster
import (
"io"
"github.com/hashicorp/raft"
)
// FSM - Finite State Machine for Raft
type FSM struct {
}
// Apply - TODO
func (fsm FSM) Apply(log *raft.Log) interface{} {
return nil
}
// Restore - TODO
func (fsm FSM) Restore(snap io.ReadCloser) error {
return nil
}
// Snapshot - TODO, returns an empty snapshot
func (fsm FSM) Snapshot() (raft.FSMSnapshot, error) {
return Snapshot{}, nil
}
// Snapshot -
type Snapshot struct {
}
// Persist -
func (snapshot Snapshot) Persist(sink raft.SnapshotSink) error {
return nil
}
// Release -
func (snapshot Snapshot) Release() {
}

277
pkg/debouncer/debouncer.go Normal file
View File

@@ -0,0 +1,277 @@
package debouncer
import (
"context"
"fmt"
log "log/slog"
"sync"
"sync/atomic"
"time"
v1 "k8s.io/api/core/v1"
discoveryv1 "k8s.io/api/discovery/v1"
"k8s.io/apimachinery/pkg/watch"
)
const (
DefaultTime = "0s"
minimalTime = time.Millisecond * 200
)
type debouncer struct {
input <-chan watch.Event
output chan watch.Event
stopChan chan any
stopOnce sync.Once
// events holds event per namespace
namespaces sync.Map
debounceTime time.Duration
}
type ns struct {
sync.Map
cnt atomic.Int64
}
func (n *ns) get(name string) (*object, bool) {
value, exists := n.Load(name)
if !exists {
return nil, false
}
i, ok := value.(*object)
if !ok {
return nil, false
}
return i, true
}
func (n *ns) add(name string, output chan<- watch.Event) *object {
i := newObject(output)
n.Store(name, i)
n.cnt.Add(1)
return i
}
func (n *ns) del(name string, object *object) {
if n.CompareAndDelete(name, object) {
n.cnt.Add(-1)
}
}
func New(input <-chan watch.Event, debounceTime string) (*debouncer, error) {
dt, err := time.ParseDuration(debounceTime)
if err != nil {
// debouncer was configured with invalid unparsable value, return error
return nil, fmt.Errorf("failed to parse debounce time configuration: %w", err)
}
if dt < minimalTime {
if dt > 0 {
log.Warn("configured debounce time is less than the minimal threshold of 200ms, debouncer will remain disabled", "config value", dt.String())
}
return nil, nil
}
return &debouncer{
input: input,
output: make(chan watch.Event),
stopChan: make(chan any),
debounceTime: dt,
}, nil
}
func (d *debouncer) Start(ctx context.Context) error {
wg := sync.WaitGroup{}
debouncerCtx, cancel := context.WithCancel(ctx)
defer func() {
cancel()
wg.Wait()
close(d.output)
}()
for {
select {
case <-debouncerCtx.Done():
// return if debouncer context was cancelled
return nil
case <-d.stopChan:
// return if Stop() was called
return nil
case tmp := <-d.input:
// event has no type, probably error
if tmp.Type == "" {
return fmt.Errorf("get undefined object (input channel probably closed)")
}
var namespace, name string
// type switch event object
switch v := tmp.Object.(type) {
case *discoveryv1.EndpointSlice:
namespace = v.Namespace
name = v.Name
case *v1.Endpoints: //nolint:staticcheck
namespace = v.Namespace
name = v.Name
case *v1.Service:
namespace = v.Namespace
name = v.Name
default:
return fmt.Errorf("objects of type %T are not supported", v)
}
processEvent:
for {
eventNs, exists := d.getNs(namespace)
if !exists {
// if not, create new map for the namespace
eventNs = d.addNs(namespace)
}
// check if the object was previously reconciled
eventObject, exists := eventNs.get(name)
// if not and the event is not of type 'Deleted', create new object
if !exists && tmp.Type != watch.Deleted {
eventObject = eventNs.add(name, d.output)
workerObject := eventObject
workerNs := eventNs
workerName := name
workerNamespace := namespace
workerObject.onStop = func() {
// Remove the object before its worker can become receiver-less.
workerNs.del(workerName, workerObject)
}
wg.Go(func() {
// start deboucing events for this object
workerObject.start(debouncerCtx, d.debounceTime)
// if debouncer for the object ended - e.g. object was deleted - clean the map of objects
workerNs.del(workerName, workerObject)
// if namespace is empty, delete the namespace map
if workerNs.cnt.Load() == 0 {
d.delNs(workerNamespace, workerNs)
}
})
}
if eventObject == nil {
break processEvent
}
// pass the watch event to the debouncer object
select {
case eventObject.input <- tmp:
break processEvent
case <-eventObject.stopChan:
// The object stopped after the map lookup. Retry the event
// against the newly-created object instead of dropping it.
continue processEvent
case <-debouncerCtx.Done():
return nil
}
}
}
}
}
func (d *debouncer) Stop() {
d.stopOnce.Do(func() {
close(d.stopChan)
})
}
func (d *debouncer) Output() chan watch.Event {
return d.output
}
func (d *debouncer) getNs(namespace string) (*ns, bool) {
value, exists := d.namespaces.Load(namespace)
if !exists {
return nil, false
}
n, ok := value.(*ns)
if !ok {
return nil, false
}
return n, true
}
func (d *debouncer) addNs(namespace string) *ns {
n := ns{}
d.namespaces.Store(namespace, &n)
return &n
}
func (d *debouncer) delNs(namespace string, ns *ns) {
d.namespaces.CompareAndDelete(namespace, ns)
}
type object struct {
input chan watch.Event
output chan<- watch.Event
stopChan chan any
stopOnce sync.Once
onStop func()
}
func newObject(output chan<- watch.Event) *object {
return &object{
input: make(chan watch.Event),
output: output,
stopChan: make(chan any),
}
}
func (o *object) start(ctx context.Context, debounceTime time.Duration) {
t := time.NewTicker(debounceTime)
var last *watch.Event
defer func() {
if last != nil {
o.output <- *last
last = nil
}
}()
for {
select {
case <-ctx.Done():
// if context is done, return
return
case <-o.stopChan:
// return if Stop() was called
return
case tmp := <-o.input:
// if last event is known, but an event of another type arrived,
// send out the previous event
if last != nil && last.Type != tmp.Type {
o.output <- *last
}
// save current event as the last event
last = &tmp
// reset the ticker to wait for more events
t.Reset(debounceTime)
case <-t.C:
if last != nil {
// on tick, if we have an event, send it out
o.output <- *last
// if the event is of type 'Deleted', stop the debouncer for the object
if last.Type == watch.Deleted {
o.stop()
}
// reset last known event, so it won't be send out twice
last = nil
}
}
}
}
func (o *object) stop() {
o.stopOnce.Do(func() {
if o.onStop != nil {
o.onStop()
}
close(o.stopChan)
})
}

Some files were not shown because too many files have changed in this diff Show More