From 6e2644ccdae4d2c211071c08190cac87c07bcb16 Mon Sep 17 00:00:00 2001 From: Pavel Kirilin Date: Wed, 20 Nov 2024 21:50:15 +0100 Subject: [PATCH 1/2] Fixed readme. --- README.md | 110 ++++++++++++++++++++++++++++++++++++++++++-------- src/config.rs | 13 +++--- src/consts.rs | 2 - 3 files changed, 99 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index d76a538..f98b893 100644 --- a/README.md +++ b/README.md @@ -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 + +Options: + -t, --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 load balancer healthcheck retries cound [env: ROBOTLB_DEFAULT_LB_RETRIES=] [default: 3] + --default-lb-timeout + Default load balancer healthcheck timeout [env: ROBOTLB_DEFAULT_LB_TIMEOUT=] [default: 10] + --default-lb-interval + Default load balancer healhcheck interval [env: ROBOTLB_DEFAULT_LB_INTERVAL=] [default: 15] + --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 + 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 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 + [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 ``` diff --git a/src/config.rs b/src/config.rs index e2e60e5..1d1a1a9 100644 --- a/src/config.rs +++ b/src/config.rs @@ -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, @@ -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, @@ -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, } diff --git a/src/consts.rs b/src/consts.rs index 3543381..f7eca82 100644 --- a/src/consts.rs +++ b/src/consts.rs @@ -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; From c88158d7e8cbd7af96d06afd9137b09f81035b17 Mon Sep 17 00:00:00 2001 From: Pavel Kirilin Date: Wed, 20 Nov 2024 21:52:40 +0100 Subject: [PATCH 2/2] Fixed pre-commit. --- src/config.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/config.rs b/src/config.rs index 1d1a1a9..5db834c 100644 --- a/src/config.rs +++ b/src/config.rs @@ -57,7 +57,7 @@ pub struct OperatorConfig { )] pub default_lb_proxy_mode_enabled: bool, - /// Whether to enable IPv6 ingress for the load balancer. + /// 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,