Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Fixed readme. #5

Merged
merged 2 commits into from
Nov 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
110 changes: 93 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,58 +1,134 @@
# Hetzner LoadBalancer for bare-metal robot clusters

This project can be used when you have deployed a bare-metal kubernetes cluster on
hetzner robot and want to use hetzner's cloud load-balaner.
This project is useful when you've deployed a bare-metal Kubernetes cluster on Hetzner Robot and want to use Hetzner's cloud load balancer.

This small operator will integrate them together and you will be able to use the `LoadBalancer` type of service.
This small operator integrates them together, allowing you to use the `LoadBalancer` service type.

## Prerequisites

Before you can use this operator, please make sure:
Before using this operator, make sure:

1. You have a cluster deployed on [Hetzner robot](https://robot.hetzner.com/) (at least agent nodes);
2. You created a [vSwitch](https://docs.hetzner.com/robot/dedicated-server/network/vswitch/) for these servers;
3. You have a cloud network with subnet that points to the vSwitch ([Tutorial](https://docs.hetzner.com/cloud/networks/connect-dedi-vswitch/));
2. You've created a [vSwitch](https://docs.hetzner.com/robot/dedicated-server/network/vswitch/) for these servers;
3. You've assigned IPs to your dedicated servers within the vSwitch network.
4. You have a cloud network with subnet that points to the vSwitch ([Tutorial](https://docs.hetzner.com/cloud/networks/connect-dedi-vswitch/));
5. You’ve specified node IPs using the `--node-ip` argument with the private IP.

If you have all the requirements met, you can deploy robotlb.
If you meet all the requirements, you can deploy `robotlb`.

## Deploying

The recommended way of deploying this operator is by using helm chart.

The recommended way to deploy this operator is using the Helm chart.

```bash
helm show values oci://ghcr.io/intreecom/charts/robotlb > values.yaml
# Edit values.yaml to suit your needs
# Set `envs.ROBOTLB_HCLOUD_TOKEN`.
helm install robotlb oci://ghcr.io/intreecom/charts/robotlb -f values.yaml
```

After the chart is installed, you should be able to create `LoadBalancer` services.

## How it works

The operator listens to the Kubernetes API for services of type `LoadBalancer` and creates Hetzner load balancers that point to nodes based on `node-ip`.

Nodes are selected based on where the service's target pods are deployed, which is determined by searching for pods with the service's selector. This behavior can be configured.


## Configuration

This project has two places for configuration: environment variables and service annotations.

### Envs

Environment variables are mainly used to override default arguments and provide sensitive information.

Here’s a complete list of parameters for the operator's binary:

```
Usage: robotlb [OPTIONS] --hcloud-token <HCLOUD_TOKEN>

Options:
-t, --hcloud-token <HCLOUD_TOKEN>
`HCloud` API token [env: ROBOTLB_HCLOUD_TOKEN=nY1eU1iMeAd63eRhHRmubQCsRqhGGJoVNK7JmqfxG33SbJZkfdIw5xvf4vfdbQHu]
--dynamic-node-selector
If enabled, the operator will try to find target nodes based on where the target pods are actually deployed. If disabled, the operator will try to find target nodes based on the node selector [env: ROBOTLB_DYNAMIC_NODE_SELECTOR=]
--default-lb-retries <DEFAULT_LB_RETRIES>
Default load balancer healthcheck retries cound [env: ROBOTLB_DEFAULT_LB_RETRIES=] [default: 3]
--default-lb-timeout <DEFAULT_LB_TIMEOUT>
Default load balancer healthcheck timeout [env: ROBOTLB_DEFAULT_LB_TIMEOUT=] [default: 10]
--default-lb-interval <DEFAULT_LB_INTERVAL>
Default load balancer healhcheck interval [env: ROBOTLB_DEFAULT_LB_INTERVAL=] [default: 15]
--default-lb-location <DEFAULT_LB_LOCATION>
Default location of a load balancer. https://docs.hetzner.com/cloud/general/locations/ [env: ROBOTLB_DEFAULT_LB_LOCATION=] [default: hel1]
--default-balancer-type <DEFAULT_BALANCER_TYPE>
Type of a load balancer. It differs in price, number of connections, target servers, etc. The default value is the smallest balancer. https://docs.hetzner.com/cloud/load-balancers/overview#pricing [env: ROBOTLB_DEFAULT_LB_TYPE=] [default: lb11]
--default-lb-algorithm <DEFAULT_LB_ALGORITHM>
Default load balancer algorithm. Possible values: * `least-connections` * `round-robin` https://docs.hetzner.com/cloud/load-balancers/overview#load-balancers [env: ROBOTLB_DEFAULT_LB_ALGORITHM=] [default: least-connections]
--default-lb-proxy-mode-enabled
Default load balancer proxy mode. If enabled, the load balancer will act as a proxy for the target servers. The default value is `false`. https://docs.hetzner.com/cloud/load-balancers/faq/#what-does-proxy-protocol-mean-and-should-i-enable-it [env: ROBOTLB_DEFAULT_LB_PROXY_MODE_ENABLED=]
--ipv6-ingress
Whether to enable IPv6 ingress for the load balancer. If enabled, the load balancer's IPv6 will be attached to the service as an external IP along with IPv4 [env: ROBOTLB_IPV6_INGRESS=]
--log-level <LOG_LEVEL>
[env: ROBOTLB_LOG_LEVEL=] [default: INFO]
-h, --help
Print help
```


### Service annotations


```yaml
apiVersion: v1
kind: Service
metadata:
name: target
annotations:
# Node selector for NodePort type of service.
# This selector will select ips of nodes to which loadbalancer traffic will be routed.
# All nodes included if label is not present.
# Custom name of the balancer to create on Hetzner. Defaults to service name.
robotlb/balancer: "custom name"
# Hetzner cloud network. If this annotation is missing, the operator will try to
# assign external IPs to the load balancer if available. Otherwise, the update won't happen.
robotlb/lb-network: "my-net"
# Node selector for the loadbalancer. This is only required if ROBOTLB_DYNAMIC_NODE_SELECTOR
# is set to false. If not specified then, all nodes will be selected as LB targets by default.
# This property helps you filter out nodes.
# Filters are separated by commas and should have one of the following formats:
# * key=value -- checks that the node has a label `key` with value `value`;
# * key!=value -- verifies that key either doesn't exist or isn't equal to `value`;
# * !key -- verifies that the node doesn't have a label `key`;
# * key -- verifies that the node has a label `key`.
robotlb/node-selector: "node-role.kubernetes.io/control-plane!=true,beta.kubernetes.io/arch=amd64"
# Load balancer healthcheck options
robotlb/lb-check-interval: "1"
robotlb/lb-timeout: "10"
### Load balancer healthcheck options. ###
# How often to run health probes.
robotlb/lb-check-interval: "5"
# Timeout for a single probe.
robotlb/lb-timeout: "3"
# How many failed probes before marking the node as unhealthy.
robotlb/lb-retries: "3"
# Wether to use proxymode for this target.

### Load balancer options ###
# Whether to use proxy mode for this target.
# https://docs.hetzner.com/cloud/load-balancers/faq/#what-does-proxy-protocol-mean-and-should-i-enable-it
robotlb/lb-proxy-mode: "false"
# Location of the load balancer. This expects the code of one of Hetzner's available locations.
robotlb/lb-location: "hel1"
# Balancing algorithm. Can be either
# * least-connection
# * round-robin
robotlb/lb-algorithm: "least-connection"
# Type of balancer.
robotlb/balancer-type: "lb11"
spec:
type: LoadBalancer
# If dynamic node selector is enabled, nodes will be found
# using this property.
selector:
app: target
ports:
# Currently only TCP protocol is supported. UDP will be ignored.
- protocol: TCP
port: 80 # This will be listening_port on the LB
port: 80 # This will become the listening port on the LB
targetPort: 80
```
13 changes: 6 additions & 7 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ pub struct OperatorConfig {
#[arg(short = 't', long, env = "ROBOTLB_HCLOUD_TOKEN")]
pub hcloud_token: String,

/// If this flag is enabled, the operator will try to find target nodes
/// based on where target pods are actually deployed.
/// If enabled, the operator will try to find target nodes based on where the target pods are actually deployed.
/// If disabled, the operator will try to find target nodes based on the node selector.
#[arg(long, env = "ROBOTLB_DYNAMIC_NODE_SELECTOR", default_value = "true")]
pub dynamic_node_selector: bool,

Expand All @@ -24,7 +24,7 @@ pub struct OperatorConfig {
#[arg(long, env = "ROBOTLB_DEFAULT_LB_INTERVAL", default_value = "15")]
pub default_lb_interval: i32,

/// Default loadction of a load balancer.
/// Default location of a load balancer.
/// https://docs.hetzner.com/cloud/general/locations/
#[arg(long, env = "ROBOTLB_DEFAULT_LB_LOCATION", default_value = "hel1")]
pub default_lb_location: String,
Expand Down Expand Up @@ -57,13 +57,12 @@ pub struct OperatorConfig {
)]
pub default_lb_proxy_mode_enabled: bool,

/// Whether to enable IPv6 ingress for the load balancer. The default value
/// is `false`. If enabled, the load balancer's IPv6 will be attached to a
/// service as external IP along with IPv4.
/// Whether to enable IPv6 ingress for the load balancer.
/// If enabled, the load balancer's IPv6 will be attached to the service as an external IP along with IPv4.
#[arg(long, env = "ROBOTLB_IPV6_INGRESS", default_value = "false")]
pub ipv6_ingress: bool,

// Log level for the operator.
// Log level of the operator.
#[arg(long, env = "ROBOTLB_LOG_LEVEL", default_value = "INFO")]
pub log_level: LevelFilter,
}
2 changes: 0 additions & 2 deletions src/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ pub const LB_LOCATION_LABEL_NAME: &str = "robotlb/lb-location";
pub const LB_ALGORITHM_LABEL_NAME: &str = "robotlb/lb-algorithm";
pub const LB_BALANCER_TYPE_LABEL_NAME: &str = "robotlb/balancer-type";

pub const DEFAULT_NODE_IP: &str = "InternalIP";

pub const DEFAULT_LB_RETRIES: i32 = 3;
pub const DEFAULT_LB_TIMEOUT: i32 = 10;
pub const DEFAULT_LB_INTERVAL: i32 = 15;
Expand Down
Loading