From 8125c46bbd6660572d7757c50fc4ddfe2374aff9 Mon Sep 17 00:00:00 2001 From: Khaja Omer Date: Fri, 17 Jan 2025 13:04:48 -0600 Subject: [PATCH 01/19] Refactor docs into a mdbook --- README.md | 464 ++---------------- devbox.json | 4 +- devbox.lock | 96 ++++ docs/book.toml | 23 + docs/src/SUMMARY.md | 33 ++ docs/src/configuration/README.md | 57 +++ docs/src/configuration/annotations.md | 116 +++++ docs/src/configuration/environment.md | 87 ++++ docs/src/configuration/firewall.md | 83 ++++ docs/src/configuration/loadbalancer.md | 206 ++++++++ docs/src/configuration/nodes.md | 96 ++++ docs/src/configuration/routes.md | 100 ++++ docs/src/configuration/session-affinity.md | 60 +++ docs/src/development/README.md | 127 +++++ docs/src/examples/README.md | 23 + docs/src/examples/advanced.md | 140 ++++++ docs/src/examples/basic.md | 107 ++++ docs/src/getting-started/README.md | 13 + docs/src/getting-started/helm-installation.md | 58 +++ docs/src/getting-started/installation.md | 20 + .../getting-started/manual-installation.md | 56 +++ docs/src/getting-started/overview.md | 34 ++ docs/src/getting-started/requirements.md | 50 ++ docs/src/getting-started/troubleshooting.md | 96 ++++ docs/src/getting-started/verification.md | 63 +++ docs/src/help.md | 23 + docs/src/introduction.md | 61 +++ 27 files changed, 1865 insertions(+), 431 deletions(-) create mode 100644 docs/book.toml create mode 100644 docs/src/SUMMARY.md create mode 100644 docs/src/configuration/README.md create mode 100644 docs/src/configuration/annotations.md create mode 100644 docs/src/configuration/environment.md create mode 100644 docs/src/configuration/firewall.md create mode 100644 docs/src/configuration/loadbalancer.md create mode 100644 docs/src/configuration/nodes.md create mode 100644 docs/src/configuration/routes.md create mode 100644 docs/src/configuration/session-affinity.md create mode 100644 docs/src/development/README.md create mode 100644 docs/src/examples/README.md create mode 100644 docs/src/examples/advanced.md create mode 100644 docs/src/examples/basic.md create mode 100644 docs/src/getting-started/README.md create mode 100644 docs/src/getting-started/helm-installation.md create mode 100644 docs/src/getting-started/installation.md create mode 100644 docs/src/getting-started/manual-installation.md create mode 100644 docs/src/getting-started/overview.md create mode 100644 docs/src/getting-started/requirements.md create mode 100644 docs/src/getting-started/troubleshooting.md create mode 100644 docs/src/getting-started/verification.md create mode 100644 docs/src/help.md create mode 100644 docs/src/introduction.md diff --git a/README.md b/README.md index acfdd737..f1f897f3 100644 --- a/README.md +++ b/README.md @@ -4,451 +4,55 @@ [![Continuous Integration](https://github.com/linode/linode-cloud-controller-manager/actions/workflows/ci.yml/badge.svg)](https://github.com/linode/linode-cloud-controller-manager/actions/workflows/ci.yml) [![codecov](https://codecov.io/gh/linode/linode-cloud-controller-manager/graph/badge.svg?token=GSRnqHUmCk)](https://codecov.io/gh/linode/linode-cloud-controller-manager) [![Docker Pulls](https://img.shields.io/docker/pulls/linode/linode-cloud-controller-manager.svg)](https://hub.docker.com/r/linode/linode-cloud-controller-manager/) - [![Twitter](https://img.shields.io/twitter/follow/linode.svg?style=social&logo=twitter&label=Follow)](https://twitter.com/intent/follow?screen_name=linode) -## The purpose of the CCM -The Linode Cloud Controller Manager (CCM) creates a fully supported -Kubernetes experience on Linode. +## Overview -* Load balancers, Linode NodeBalancers, are automatically deployed when a -[Kubernetes Service of type "LoadBalancer"](https://kubernetes.io/docs/concepts/services-networking/service/#loadbalancer) is deployed. This is the most -reliable way to allow services running in your cluster to be reachable from -the Internet. -* Linode hostnames and network addresses (private/public IPs) are automatically -associated with their corresponding Kubernetes resources, forming the basis for -a variety of Kubernetes features. -* Nodes resources are put into the correct state when Linodes are shut down, -allowing pods to be appropriately rescheduled. -* Nodes are annotated with the Linode region, which is the basis for scheduling based on -failure domains. +The Linode Cloud Controller Manager (CCM) integrates Kubernetes with Linode's infrastructure services. It implements cloud-specific control loops essential for cluster operation. For detailed documentation, see the [docs](docs/src/introduction.md). -## Kubernetes Supported Versions -Kubernetes 1.9+ +### Core Components -## Usage +- **Node Controller**: Manages node lifecycle and configuration +- **Service Controller**: Handles LoadBalancer implementations using NodeBalancers +- **Route Controller**: Configures network routes for pod communication -### LoadBalancer Services -Kubernetes Services of type `LoadBalancer` will be served through a [Linode NodeBalancer](https://www.linode.com/nodebalancers) by default which the Cloud Controller Manager will provision on demand. -For general feature and usage notes, refer to the [Getting Started with Linode NodeBalancers](https://www.linode.com/docs/platform/nodebalancer/getting-started-with-nodebalancers/) guide. +### Key Features -#### Using IP Sharing instead of NodeBalancers -Alternatively, the Linode CCM can integrate with [Cilium's BGP Control Plane](https://docs.cilium.io/en/stable/network/bgp-control-plane/) -to perform load-balancing via IP sharing on labeled Nodes. This option does not create a backing NodeBalancer and instead -provisions a new IP on an ip-holder Nanode to share for the desired region. See [Shared IP LoadBalancing](#shared-ip-load-balancing). +- Automatic LoadBalancer provisioning using Linode NodeBalancers +- Node management and lifecycle operations +- Network route configuration for VPC environments +- Firewall management for services -#### Annotations -The Linode CCM accepts several annotations which affect the properties of the underlying NodeBalancer deployment. +## Requirements -All the Service annotation names listed below have been shortened for readability. The values, such as `http`, are case-sensitive. +- Kubernetes 1.9+ +- Kubelets, controller-manager, and apiserver with `--cloud-provider=external` +- Linode APIv4 Token +- Supported Linode region -Each *Service* annotation **MUST** be prefixed with:
-**`service.beta.kubernetes.io/linode-loadbalancer-`** +## Quick Links -| Annotation (Suffix) | Values | Default | Description | -|--------------------------|-------------------------------------------------------------------------------------------------|---------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `throttle` | `0`-`20` (`0` to disable) | `0` | Client Connection Throttle, which limits the number of subsequent new connections per second from the same client IP | -| `default-protocol` | `tcp`, `http`, `https` | `tcp` | This annotation is used to specify the default protocol for Linode NodeBalancer. | -| `default-proxy-protocol` | `none`, `v1`, `v2` | `none` | Specifies whether to use a version of Proxy Protocol on the underlying NodeBalancer. | -| `port-*` | json (e.g. `{ "tls-secret-name": "prod-app-tls", "protocol": "https", "proxy-protocol": "v2"}`) | | Specifies port specific NodeBalancer configuration. See [Port Specific Configuration](#port-specific-configuration). `*` is the port being configured, e.g. `linode-loadbalancer-port-443` | -| `check-type` | `none`, `connection`, `http`, `http_body` | | The type of health check to perform against back-ends to ensure they are serving requests | -| `check-path` | string | | The URL path to check on each back-end during health checks | -| `check-body` | string | | Text which must be present in the response body to pass the NodeBalancer health check | -| `check-interval` | int | | Duration, in seconds, to wait between health checks | -| `check-timeout` | int (1-30) | | Duration, in seconds, to wait for a health check to succeed before considering it a failure | -| `check-attempts` | int (1-30) | | Number of health check failures necessary to remove a back-end from the service | -| `check-passive` | [bool](#annotation-bool-values) | `false` | When `true`, `5xx` status codes will cause the health check to fail | -| `preserve` | [bool](#annotation-bool-values) | `false` | When `true`, deleting a `LoadBalancer` service does not delete the underlying NodeBalancer. This will also prevent deletion of the former LoadBalancer when another one is specified with the `nodebalancer-id` annotation. | -| `nodebalancer-id` | string | | The ID of the NodeBalancer to front the service. When not specified, a new NodeBalancer will be created. This can be configured on service creation or patching | -| `hostname-only-ingress` | [bool](#annotation-bool-values) | `false` | When `true`, the LoadBalancerStatus for the service will only contain the Hostname. This is useful for bypassing kube-proxy's rerouting of in-cluster requests originally intended for the external LoadBalancer to the service's constituent pod IPs. | -| `tags` | string | | A comma seperated list of tags to be applied to the createad NodeBalancer instance | -| `firewall-id` | string | | An existing Cloud Firewall ID to be attached to the NodeBalancer instance. See [Firewalls](#firewalls). | -| `firewall-acl` | string | | The Firewall rules to be applied to the NodeBalancer. Adding this annotation creates a new CCM managed Linode CloudFirewall instance. See [Firewalls](#firewalls). | +- [Getting Started](docs/src/getting-started/README.md) + - [Requirements](docs/src/getting-started/requirements.md) + - [Installation](docs/src/getting-started/installation.md) + - [Verification](docs/src/getting-started/verification.md) + - [Troubleshooting](docs/src/getting-started/troubleshooting.md) -#### Deprecated Annotations -These annotations are deprecated, and will be removed in a future release. +- [Configuration Guide](docs/src/configuration/README.md) + - [LoadBalancer Services](docs/src/configuration/loadbalancer.md) + - [Service Annotations](docs/src/configuration/annotations.md) + - [Node Configuration](docs/src/configuration/nodes.md) -| Annotation (Suffix) | Values | Default | Description | Scheduled Removal | -|---------------------|--------------------|---------|-------------------------------------------------------------------------------------|-------------------| -| `proxy-protcol` | `none`, `v1`, `v2` | `none` | Specifies whether to use a version of Proxy Protocol on the underlying NodeBalancer | Q4 2021 | +- [Examples](docs/src/examples/README.md) + - [Basic Services](docs/src/examples/basic.md) + - [Advanced Configuration](docs/src/examples/advanced.md) -#### Annotation bool values -For annotations with bool value types, `"1"`, `"t"`, `"T"`, `"True"`, `"true"` and `"True"` are valid string representations of `true`. Any other values will be interpreted as false. For more details, see [strconv.ParseBool](https://golang.org/pkg/strconv/#ParseBool). +- [Development Guide](docs/src/development/README.md) -#### Port Specific Configuration -These configuration options can be specified via the `port-*` annotation, encoded in JSON. +## Getting Help -| Key | Values | Default | Description | -|-------------------|------------------------|---------|---------------------------------------------------------------------------------------------------------------------------| -| `protocol` | `tcp`, `http`, `https` | `tcp` | Specifies protocol of the NodeBalancer port. Overwrites `default-protocol`. | -| `proxy-protocol` | `none`, `v1`, `v2` | `none` | Specifies whether to use a version of Proxy Protocol on the underlying NodeBalancer. Overwrites `default-proxy-protocol`. | -| `tls-secret-name` | string | | Specifies a secret to use for TLS. The secret type should be `kubernetes.io/tls`. | +For support and development discussions, join us in #linode on the [Kubernetes Slack](https://kubernetes.slack.com/messages/CD4B15LUR/details/). To sign up, use the [Kubernetes Slack inviter](http://slack.kubernetes.io/). -#### Shared IP Load-Balancing -**NOTE:** This feature requires contacting [Customer Support](https://www.linode.com/support/contact/) to enable provisioning additional IPs. +## Contributing -Services of `type: LoadBalancer` can receive an external IP not backed by a NodeBalancer if `--bgp-node-selector` is set on the Linode CCM and `--load-balancer-type` is set to `cilium-bgp`. - -If you plan to run multiple clusters within a single API Region, setting `--ip-holder-suffix` on the Linode CCM to a unique value per cluster will create an ip-holder nanode for each cluster that is created within that API Region (ex. `linode-ccm-ip-holder--`). - -If you do not set `--ip-holder-suffix` on the Linode CCM, it will use the following naming convention for the ip-holder nanode (ex. `linode-ccm-ip-holder-`). - -This feature requires the Kubernetes cluster to be using [Cilium](https://cilium.io/) as the CNI with the `bgp-control-plane` feature enabled. - -##### Example Daemonset configuration: - -``` -apiVersion: apps/v1 -kind: DaemonSet -metadata: - name: ccm-linode - namespace: kube-system -spec: - template: - spec: - containers: - - image: linode/linode-cloud-controller-manager:latest - name: ccm-linode - env: - - name: LINODE_URL - value: https://api.linode.com/v4 - args: - - --bgp-node-selector=cilium-bgp-peering=true - - --load-balancer-type=cilium-bgp - - --ip-holder-suffix=myclustername1 -... -``` - -##### Example Helm chart configuration: - -``` -sharedIPLoadBalancing: - loadBalancerType: cilium-bgp - bgpNodeSelector: cilium-bgp-peering=true - ipHolderSuffix: myclustername1 -``` - -#### Firewalls -Firewall rules can be applied to the CCM Managed NodeBalancers in two distinct ways. - -##### CCM Managed Firewall -To use this feature, ensure that the linode api token used with the ccm has the `add_firewalls` grant. - -The CCM accepts firewall ACLs in json form. The ACL can either be an `allowList` or a `denyList`. Supplying both is not supported. Supplying neither is not supported. The `allowList` sets up a CloudFirewall that `ACCEPT`s traffic only from the specified IPs/CIDRs and `DROP`s everything else. The `denyList` sets up a CloudFirewall that `DROP`s traffic only from the specified IPs/CIDRs and `ACCEPT`s everything else. Ports are automatically inferred from the service configuration. - -See [Firewall rules](https://www.linode.com/docs/api/networking/#firewall-create__request-body-schema) for more details on how to specify the IPs/CIDRs - -Example usage of an ACL to allow traffic from a specific set of addresses - -```yaml -kind: Service -apiVersion: v1 -metadata: - name: https-lb - annotations: - service.beta.kubernetes.io/linode-loadbalancer-firewall-acl: | - { - "allowList": { - "ipv4": ["192.166.0.0/16", "172.23.41.0/24"], - "ipv6": ["2001:DB8::/128"] - } - } -spec: - type: LoadBalancer - selector: - app: nginx-https-example - ports: - - name: http - protocol: TCP - port: 80 - targetPort: http - - name: https - protocol: TCP - port: 443 - targetPort: https -``` - - -##### User Managed Firewall -Users can create CloudFirewall instances, supply their own rules and attach them to the NodeBalancer. To do so, set the -`service.beta.kubernetes.io/linode-loadbalancer-firewall-id` annotation to the ID of the cloud firewall. The CCM does not manage the lifecycle of the CloudFirewall Instance in this case. Users are responsible for ensuring the policies are correct. - -**Note**
-If the user supplies a firewall-id, and later switches to using an ACL, the CCM will take over the CloudFirewall Instance. To avoid this, delete the service, and re-create it so the original CloudFirewall is left undisturbed. - -#### Routes -When running k8s clusters within VPC, node specific podCIDRs need to be allowed on the VPC interface. Linode CCM comes with route-controller functionality which can be enabled for automatically adding/deleting routes on VPC interfaces. When installing CCM with helm, make sure to specify routeController settings. - -##### Example usage in values.yaml -```yaml -routeController: - vpcNames: - clusterCIDR: 10.0.0.0/8 - configureCloudRoutes: true -``` - -### Nodes -Kubernetes Nodes can be configured with the following annotations. - -Each *Node* annotation **MUST** be prefixed with:
-**`node.k8s.linode.com/`** - -| Key | Values | Default | Description | -|--------------|--------|---------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `private-ip` | `IPv4` | `none` | Specifies the Linode Private IP overriding default detection of the Node InternalIP.
When using a [VLAN] or [VPC], the Node InternalIP may not be a Linode Private IP as [required for NodeBalancers] and should be specified. | - -[required for NodeBalancers]: https://www.linode.com/docs/api/nodebalancers/#nodebalancer-create__request-body-schema -[VLAN]: https://www.linode.com/products/vlan/ -[VPC]: https://www.linode.com/blog/linode/new-betas-coming-to-green-light/ - -### Example usage -```yaml -kind: Service -apiVersion: v1 -metadata: - name: https-lb - annotations: - service.beta.kubernetes.io/linode-loadbalancer-throttle: "4" - service.beta.kubernetes.io/linode-loadbalancer-default-protocol: "http" - service.beta.kubernetes.io/linode-loadbalancer-port-443: | - { - "tls-secret-name": "example-secret", - "protocol": "https" - } -spec: - type: LoadBalancer - selector: - app: nginx-https-example - ports: - - name: http - protocol: TCP - port: 80 - targetPort: http - - name: https - protocol: TCP - port: 443 - targetPort: https - ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-https-deployment -spec: - replicas: 2 - selector: - matchLabels: - app: nginx-https-example - template: - metadata: - labels: - app: nginx-https-example - spec: - containers: - - name: nginx - image: nginx - ports: - - name: http - containerPort: 80 - protocol: TCP - - name: https - containerPort: 80 - protocol: TCP - -``` - -See more in the [examples directory](examples) - -## Why `stickiness` and `algorithm` annotations don't exist -As kube-proxy will simply double-hop the traffic to a random backend Pod anyway, it doesn't matter which backend Node traffic is forwarded-to for the sake of session stickiness. -These annotations are not necessary to implement session stickiness, as kube-proxy will simply double-hop the packets to a random backend Pod. It would not make a difference to set a backend Node that would receive the network traffic in an attempt to set session stickiness. - -## How to use sessionAffinity -In Kubernetes, sessionAffinity refers to a mechanism that allows a client always to be redirected to the same pod when the client hits a service. - -To enable sessionAffinity `service.spec.sessionAffinity` field must be set to `ClientIP` as the following service yaml: - -```yaml -apiVersion: v1 -kind: Service -metadata: - name: wordpress-lsmnl-wordpress - namespace: wordpress-lsmnl - labels: - app: wordpress-lsmnl-wordpress -spec: - type: LoadBalancer - selector: - app: wordpress-lsmnl-wordpress - sessionAffinity: ClientIP -``` - -The max session sticky time can be set by setting the field `service.spec.sessionAffinityConfig.clientIP.timeoutSeconds` as below: - -```yaml -sessionAffinityConfig: - clientIP: - timeoutSeconds: 100 -``` - -## Additional environment variables -To tweak CCM based on needs, one can overwrite the default values set for caches and requests by setting appropriate environment variables when applying the manifest or helm chart. - -| Environment Variable | Default | Description | -|-----------------------------------|-------------|-------------------------------------------------------------| -| `LINODE_INSTANCE_CACHE_TTL` | `15` | Default timeout of instance cache in seconds | -| `LINODE_ROUTES_CACHE_TTL_SECONDS` | `60` | Default timeout of route cache in seconds | -| `LINODE_REQUEST_TIMEOUT_SECONDS` | `120` | Default timeout in seconds for http requests to linode API | -| `LINODE_EXTERNAL_SUBNET` | | Mark private network as external. Example - `172.24.0.0/16` | -| `BGP_CUSTOM_ID_MAP` | | Use your own map instead of default region map for BGP | -| `BGP_PEER_PREFIX` | `2600:3c0f` | Use your own BGP peer prefix instead of default one | - -## Generating a Manifest for Deployment -Use the script located at `./deploy/generate-manifest.sh` to generate a self-contained deployment manifest for the Linode CCM. Two arguments are required. - -The first argument must be a Linode APIv4 Personal Access Token with all permissions. -(https://cloud.linode.com/profile/tokens) - -The second argument must be a Linode region. -(https://api.linode.com/v4/regions) - -Example: - -```sh -./deploy/generate-manifest.sh $LINODE_API_TOKEN us-east -``` - -This will create a file `ccm-linode.yaml` which you can use to deploy the CCM. - -`kubectl apply -f ccm-linode.yaml` - -Note: Your kubelets, controller-manager, and apiserver must be started with `--cloud-provider=external` as noted in the following documentation. - -## Deployment Through Helm Chart -LINODE_API_TOKEN must be a Linode APIv4 [Personal Access Token](https://cloud.linode.com/profile/tokens) with all permissions. - -REGION must be a Linode [region](https://api.linode.com/v4/regions). -### Install the ccm-linode repo -```shell -helm repo add ccm-linode https://linode.github.io/linode-cloud-controller-manager/ -helm repo update ccm-linode -``` - -### To deploy ccm-linode. Run the following command: - -```sh -export VERSION=v0.4.8 -export LINODE_API_TOKEN= -export REGION= -helm install ccm-linode --set apiToken=$LINODE_API_TOKEN,region=$REGION ccm-linode/ccm-linode -``` -_See [helm install](https://helm.sh/docs/helm/helm_install/) for command documentation._ - -### To uninstall ccm-linode from kubernetes cluster. Run the following command: -```sh -helm uninstall ccm-linode -``` -_See [helm uninstall](https://helm.sh/docs/helm/helm_uninstall/) for command documentation._ - -### To upgrade when new changes are made to the helm chart. Run the following command: -```sh -export VERSION=v0.4.8 -export LINODE_API_TOKEN= -export REGION= - -helm upgrade ccm-linode --install --set apiToken=$LINODE_API_TOKEN,region=$REGION ccm-linode/ccm-linode -``` -_See [helm upgrade](https://helm.sh/docs/helm/helm_upgrade/) for command documentation._ - -### Configurations -There are other variables that can be set to a different value. For list of all the modifiable variables/values, take a look at './deploy/chart/values.yaml'. - -Values can be set/overrided by using the '--set var=value,...' flag or by passing in a custom-values.yaml using '-f custom-values.yaml'. - -Recommendation: Use custom-values.yaml to override the variables to avoid any errors with template rendering - -### Upstream Documentation Including Deployment Instructions - -[Kubernetes Cloud Controller Manager](https://kubernetes.io/docs/tasks/administer-cluster/running-cloud-controller/). - -## Upstream Developer Documentation - -[Developing a Cloud Controller Manager](https://kubernetes.io/docs/tasks/administer-cluster/developing-cloud-controller-manager/). - -## Development Guide - -### Building the Linode Cloud Controller Manager - -Some of the Linode Cloud Controller Manager development helper scripts rely -on a fairly up-to-date GNU tools environment, so most recent Linux distros -should work just fine out-of-the-box. - -#### Setup Go - -The Linode Cloud Controller Manager is written in Google's Go programming -language. Currently, the Linode Cloud Controller Manager is developed and -tested on **Go 1.8.3**. If you haven't set up a Go development environment, -please follow [these instructions](https://golang.org/doc/install) to -install Go. - -On macOS, Homebrew has a nice package - -```bash -brew install golang -``` - -#### Download Source - -```bash -go get github.com/linode/linode-cloud-controller-manager -cd $(go env GOPATH)/src/github.com/linode/linode-cloud-controller-manager -``` - -#### Install Dev tools -To install various dev tools for Pharm Controller Manager, run the following command: - -```bash -./hack/builddeps.sh -``` - -#### Build Binary -Use the following Make targets to build and run a local binary - -```bash -$ make build -$ make run -# You can also run the binary directly to pass additional args -$ dist/linode-cloud-controller-manager -``` - -#### Dependency management -Linode Cloud Controller Manager uses [Go Modules](https://blog.golang.org/using-go-modules) to manage dependencies. -If you want to update/add dependencies, run: - -```bash -go mod tidy -``` - -#### Building Docker images -To build and push a Docker image, use the following make targets. - -```bash -# Set the repo/image:tag with the TAG environment variable -# Then run the docker-build make target -$ IMG=linode/linode-cloud-controller-manager:canary make docker-build - -# Push Image -$ IMG=linode/linode-cloud-controller-manager:canary make docker-push -``` - -Then, to run the image - -```bash -docker run -ti linode/linode-cloud-controller-manager:canary -``` - -## Contribution Guidelines -Want to improve the linode-cloud-controller-manager? Please start [here](.github/CONTRIBUTING.md). - -## Join the Kubernetes Community -For general help or discussion, join us in #linode on the [Kubernetes Slack](https://kubernetes.slack.com/messages/CD4B15LUR/details/). To sign up, use the [Kubernetes Slack inviter](http://slack.kubernetes.io/). +Want to improve the Linode Cloud Controller Manager? Please see our [contributing guidelines](.github/CONTRIBUTING.md). diff --git a/devbox.json b/devbox.json index ff3d96fa..da13e240 100644 --- a/devbox.json +++ b/devbox.json @@ -12,7 +12,9 @@ "kustomize@latest", "kyverno-chainsaw@latest", "mockgen@latest", - "yq-go@latest" + "yq-go@latest", + "mdbook@latest", + "mdbook-admonish@latest" ], "shell": { "init_hook": [ diff --git a/devbox.lock b/devbox.lock index cb767c68..2e32398e 100644 --- a/devbox.lock +++ b/devbox.lock @@ -633,6 +633,102 @@ } } }, + "mdbook-admonish@latest": { + "last_modified": "2024-12-23T21:10:33Z", + "resolved": "github:NixOS/nixpkgs/de1864217bfa9b5845f465e771e0ecb48b30e02d#mdbook-admonish", + "source": "devbox-search", + "version": "1.18.0", + "systems": { + "aarch64-darwin": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/hrmry6gcyxq576yyvvv2vsl05sycmi1y-mdbook-admonish-1.18.0", + "default": true + } + ], + "store_path": "/nix/store/hrmry6gcyxq576yyvvv2vsl05sycmi1y-mdbook-admonish-1.18.0" + }, + "aarch64-linux": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/fg3pqy6459lx562bq6gdf8hdhf2wh0h5-mdbook-admonish-1.18.0", + "default": true + } + ], + "store_path": "/nix/store/fg3pqy6459lx562bq6gdf8hdhf2wh0h5-mdbook-admonish-1.18.0" + }, + "x86_64-darwin": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/0vddbww043c8w1d4sfk2wpb5ljyq45x7-mdbook-admonish-1.18.0", + "default": true + } + ], + "store_path": "/nix/store/0vddbww043c8w1d4sfk2wpb5ljyq45x7-mdbook-admonish-1.18.0" + }, + "x86_64-linux": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/hs7z4g4v6acd9km5kaw7gibxdpcdijbj-mdbook-admonish-1.18.0", + "default": true + } + ], + "store_path": "/nix/store/hs7z4g4v6acd9km5kaw7gibxdpcdijbj-mdbook-admonish-1.18.0" + } + } + }, + "mdbook@latest": { + "last_modified": "2024-12-23T21:10:33Z", + "resolved": "github:NixOS/nixpkgs/de1864217bfa9b5845f465e771e0ecb48b30e02d#mdbook", + "source": "devbox-search", + "version": "0.4.43", + "systems": { + "aarch64-darwin": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/5yibli76rfaq70cv0lyasndswbf3hjw8-mdbook-0.4.43", + "default": true + } + ], + "store_path": "/nix/store/5yibli76rfaq70cv0lyasndswbf3hjw8-mdbook-0.4.43" + }, + "aarch64-linux": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/130z9032izdwxdishjkvjrdfacyd1fkq-mdbook-0.4.43", + "default": true + } + ], + "store_path": "/nix/store/130z9032izdwxdishjkvjrdfacyd1fkq-mdbook-0.4.43" + }, + "x86_64-darwin": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/4lcz6mj30f40k08q2s2phdfnydmkk8w2-mdbook-0.4.43", + "default": true + } + ], + "store_path": "/nix/store/4lcz6mj30f40k08q2s2phdfnydmkk8w2-mdbook-0.4.43" + }, + "x86_64-linux": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/izq6ww5isq00l6l02i4yhad2ykn45djm-mdbook-0.4.43", + "default": true + } + ], + "store_path": "/nix/store/izq6ww5isq00l6l02i4yhad2ykn45djm-mdbook-0.4.43" + } + } + }, "mockgen@latest": { "last_modified": "2024-11-03T14:18:04Z", "resolved": "github:NixOS/nixpkgs/4ae2e647537bcdbb82265469442713d066675275#mockgen", diff --git a/docs/book.toml b/docs/book.toml new file mode 100644 index 00000000..7e23cb80 --- /dev/null +++ b/docs/book.toml @@ -0,0 +1,23 @@ +[book] +authors = ["Linode"] +language = "en" +multilingual = false +src = "src" +title = "Linode Cloud Controller Manager" +description = "Documentation for the Kubernetes Cloud Controller Manager for Linode" + +[output.html] +git-repository-url = "https://github.com/linode/linode-cloud-controller-manager" + +[output.html.playground] +editable = true +line-numbers = true + +[output.html.search] +limit-results = 20 +use-boolean-and = true +boost-title = 2 +boost-hierarchy = 2 +boost-paragraph = 1 +expand = true +heading-split-level = 2 diff --git a/docs/src/SUMMARY.md b/docs/src/SUMMARY.md new file mode 100644 index 00000000..e654c593 --- /dev/null +++ b/docs/src/SUMMARY.md @@ -0,0 +1,33 @@ +# Summary + +[Introduction](./introduction.md) + +# User Guide + +- [Getting Started](./getting-started/README.md) + - [Overview](./getting-started/overview.md) + - [Requirements](./getting-started/requirements.md) + - [Installation](./getting-started/installation.md) + - [Helm Installation](./getting-started/helm-installation.md) + - [Manual Installation](./getting-started/manual-installation.md) + - [Verification](./getting-started/verification.md) + - [Troubleshooting](./getting-started/troubleshooting.md) + +- [Configuration](./configuration/README.md) + - [LoadBalancer Services](./configuration/loadbalancer.md) + - [Service Annotations](./configuration/annotations.md) + - [Node Configuration](./configuration/nodes.md) + - [Environment Variables](./configuration/environment.md) + - [Firewall Setup](./configuration/firewall.md) + - [Route Configuration](./configuration/routes.md) + - [Session Affinity](./configuration/session-affinity.md) + +- [Examples](./examples/README.md) + - [Basic Services](./examples/basic.md) + - [Advanced Configuration](./examples/advanced.md) + +- [Development Guide](./development/README.md) + +--- + +[Getting Help](./help.md) diff --git a/docs/src/configuration/README.md b/docs/src/configuration/README.md new file mode 100644 index 00000000..9d8f2531 --- /dev/null +++ b/docs/src/configuration/README.md @@ -0,0 +1,57 @@ +# Configuration Guide + +The Linode Cloud Controller Manager (CCM) offers extensive configuration options to customize its behavior. This section covers all available configuration methods and options. + +## Configuration Areas + +1. **[LoadBalancer Services](loadbalancer.md)** + - NodeBalancer implementation + - BGP-based IP sharing + - Protocol configuration + - Health checks + - SSL/TLS setup + - Connection throttling + - [See examples](../examples/basic.md#loadbalancer-services) + +2. **[Service Annotations](annotations.md)** + - NodeBalancer configuration + - Protocol settings + - Health check options + - Port configuration + - Firewall settings + - [See annotation reference](annotations.md#available-annotations) + +3. **[Node Configuration](nodes.md)** + - Node labels and topology + - Private networking setup + - VPC configuration + - Node controller behavior + - [See node management](nodes.md#node-controller-behavior) + +4. **[Environment Variables](environment.md)** + - Cache settings + - API configuration + - Network settings + - BGP configuration + - [See environment reference](environment.md#available-variables) + +5. **[Firewall Setup](firewall.md)** + - CCM-managed firewalls + - User-managed firewalls + - Allow/deny lists + - [See firewall options](firewall.md#ccm-managed-firewalls) + +6. **[Route Configuration](routes.md)** + - VPC routing + - Pod CIDR management + - Route controller setup + - [See route management](routes.md#route-management) + +7. **[Session Affinity](session-affinity.md)** + - Client IP affinity + - Timeout configuration + - Service configuration + - [See affinity setup](session-affinity.md#configuration) + +For installation instructions, see the [Installation Guide](../getting-started/installation.md). +For troubleshooting help, see the [Troubleshooting Guide](../getting-started/troubleshooting.md). diff --git a/docs/src/configuration/annotations.md b/docs/src/configuration/annotations.md new file mode 100644 index 00000000..2739c472 --- /dev/null +++ b/docs/src/configuration/annotations.md @@ -0,0 +1,116 @@ +# Service Annotations + +## Overview + +Service annotations allow you to customize the behavior of your LoadBalancer services. All Service annotations must be prefixed with: `service.beta.kubernetes.io/linode-loadbalancer-` + +For implementation details, see: +- [LoadBalancer Configuration](loadbalancer.md) +- [Basic Service Examples](../examples/basic.md) +- [Advanced Configuration Examples](../examples/advanced.md) + +## Available Annotations + +### Basic Configuration + +| Annotation (Suffix) | Values | Default | Description | +|--------------------|--------|---------|-------------| +| `throttle` | `0`-`20` (`0` to disable) | `0` | Client Connection Throttle, which limits the number of subsequent new connections per second from the same client IP | +| `default-protocol` | `tcp`, `http`, `https` | `tcp` | This annotation is used to specify the default protocol for Linode NodeBalancer | +| `default-proxy-protocol` | `none`, `v1`, `v2` | `none` | Specifies whether to use a version of Proxy Protocol on the underlying NodeBalancer | +| `port-*` | json object | | Specifies port specific NodeBalancer configuration. See [Port Configuration](#port-specific-configuration) | +| `check-type` | `none`, `connection`, `http`, `http_body` | | The type of health check to perform against back-ends. See [Health Checks](loadbalancer.md#health-checks) | +| `check-path` | string | | The URL path to check on each back-end during health checks | +| `check-body` | string | | Text which must be present in the response body to pass the health check | +| `check-interval` | int | | Duration, in seconds, to wait between health checks | +| `check-timeout` | int (1-30) | | Duration, in seconds, to wait for a health check to succeed | +| `check-attempts` | int (1-30) | | Number of health check failures necessary to remove a back-end | +| `check-passive` | bool | `false` | When `true`, `5xx` status codes will cause the health check to fail | +| `preserve` | bool | `false` | When `true`, deleting a `LoadBalancer` service does not delete the underlying NodeBalancer | +| `nodebalancer-id` | string | | The ID of the NodeBalancer to front the service | +| `hostname-only-ingress` | bool | `false` | When `true`, the LoadBalancerStatus will only contain the Hostname | +| `tags` | string | | A comma separated list of tags to be applied to the NodeBalancer instance | +| `firewall-id` | string | | An existing Cloud Firewall ID to be attached to the NodeBalancer instance. See [Firewall Setup](firewall.md) | +| `firewall-acl` | string | | The Firewall rules to be applied to the NodeBalancer. See [Firewall Configuration](#firewall-configuration) | + +### Port Specific Configuration + +The `port-*` annotation allows per-port configuration, encoded in JSON. For detailed examples, see [LoadBalancer SSL/TLS Setup](loadbalancer.md#ssltls-configuration). + +```yaml +service.beta.kubernetes.io/linode-loadbalancer-port-443: | + { + "protocol": "https", + "tls-secret-name": "my-tls-secret", + "proxy-protocol": "v2" + } +``` + +Available port options: +- `protocol`: Protocol for this port (tcp, http, https) +- `tls-secret-name`: Name of TLS secret for HTTPS. The secret type should be `kubernetes.io/tls` +- `proxy-protocol`: Proxy protocol version for this port + +### Deprecated Annotations + +| Annotation (Suffix) | Values | Default | Description | Scheduled Removal | +|--------------------|--------|---------|-------------|-------------------| +| `proxy-protocol` | `none`, `v1`, `v2` | `none` | Specifies whether to use a version of Proxy Protocol on the underlying NodeBalancer | Q4 2021 | + +### Annotation Boolean Values +For annotations with bool value types, the following string values are interpreted as `true`: +- `"1"` +- `"t"` +- `"T"` +- `"true"` +- `"True"` +- `"TRUE"` + +Any other values will be interpreted as `false`. For more details, see [strconv.ParseBool](https://golang.org/pkg/strconv/#ParseBool). + +## Examples + +### Basic HTTP Service +```yaml +metadata: + annotations: + service.beta.kubernetes.io/linode-loadbalancer-default-protocol: "http" + service.beta.kubernetes.io/linode-loadbalancer-check-type: "http" + service.beta.kubernetes.io/linode-loadbalancer-check-path: "/healthz" +``` + +### HTTPS Service with TLS +```yaml +metadata: + annotations: + service.beta.kubernetes.io/linode-loadbalancer-port-443: | + { + "protocol": "https", + "tls-secret-name": "my-tls-secret" + } +``` + +### Firewall Configuration +```yaml +metadata: + annotations: + service.beta.kubernetes.io/linode-loadbalancer-firewall-acl: | + { + "allowList": { + "ipv4": ["192.168.0.0/16"], + "ipv6": ["2001:db8::/32"] + } + } +``` + +For more examples and detailed configuration options, see: +- [LoadBalancer Configuration](loadbalancer.md) +- [Firewall Configuration](firewall.md) +- [Basic Service Examples](../examples/basic.md) +- [Advanced Configuration Examples](../examples/advanced.md) +- [Complete Stack Example](../examples/complete-stack.md) + +See also: +- [Environment Variables](environment.md) +- [Route Configuration](routes.md) +- [Session Affinity](session-affinity.md) diff --git a/docs/src/configuration/environment.md b/docs/src/configuration/environment.md new file mode 100644 index 00000000..6622bb76 --- /dev/null +++ b/docs/src/configuration/environment.md @@ -0,0 +1,87 @@ +# Environment Variables + +## Overview + +Environment variables provide global configuration options for the CCM. These settings affect caching, API behavior, and networking configurations. + +## Available Variables + +### Cache Configuration + +| Variable | Default | Description | +|----------|---------|-------------| +| `LINODE_INSTANCE_CACHE_TTL` | `15` | Default timeout of instance cache in seconds | +| `LINODE_ROUTES_CACHE_TTL_SECONDS` | `60` | Default timeout of route cache in seconds | + +### API Configuration + +| Variable | Default | Description | +|----------|---------|-------------| +| `LINODE_REQUEST_TIMEOUT_SECONDS` | `120` | Default timeout in seconds for http requests to linode API | +| `LINODE_URL` | `https://api.linode.com/v4` | Linode API endpoint | + +### Network Configuration + +| Variable | Default | Description | +|----------|---------|-------------| +| `LINODE_EXTERNAL_SUBNET` | "" | Mark private network as external. Example - `172.24.0.0/16` | +| `BGP_CUSTOM_ID_MAP` | "" | Use your own map instead of default region map for BGP | +| `BGP_PEER_PREFIX` | `2600:3c0f` | Use your own BGP peer prefix instead of default one | + +## Configuration Methods + +### Helm Chart +Configure via `values.yaml`: +```yaml +env: + - name: LINODE_INSTANCE_CACHE_TTL + value: "30" +``` + +### Manual Deployment +Add to the CCM DaemonSet: +```yaml +spec: + template: + spec: + containers: + - name: ccm-linode + env: + - name: LINODE_INSTANCE_CACHE_TTL + value: "30" +``` + +## Usage Guidelines + +### Cache Settings +- Adjust cache TTL based on cluster size and update frequency +- Monitor memory usage when modifying cache settings +- Consider API rate limits when decreasing TTL + +### API Settings +- Increase timeout for slower network conditions +- Use default API URL unless testing/development required +- Consider regional latency when adjusting timeouts + +### Network Settings +- Configure external subnet for custom networking needs +- Use BGP settings only when implementing IP sharing +- Document any custom network configurations + +## Troubleshooting + +### Common Issues + +1. **API Timeouts** + - Check network connectivity + - Verify API endpoint accessibility + - Consider increasing timeout value + +2. **Cache Issues** + - Monitor memory usage + - Verify cache TTL settings + - Check for stale data + +For more details, see: +- [Installation Guide](../getting-started/installation.md) +- [Troubleshooting Guide](../getting-started/troubleshooting.md) diff --git a/docs/src/configuration/firewall.md b/docs/src/configuration/firewall.md new file mode 100644 index 00000000..c5d011d4 --- /dev/null +++ b/docs/src/configuration/firewall.md @@ -0,0 +1,83 @@ +# Firewall Setup + +## Overview + +The CCM provides two methods for securing NodeBalancers with firewalls: +1. CCM-managed Cloud Firewalls (using `firewall-acl` annotation) +2. User-managed Cloud Firewalls (using `firewall-id` annotation) + +## CCM-Managed Firewalls + +### Configuration + +Use the `firewall-acl` annotation to specify firewall rules. The rules should be provided as a JSON object with either an `allowList` or `denyList` (but not both). + +#### Allow List Configuration +```yaml +apiVersion: v1 +kind: Service +metadata: + name: restricted-service + annotations: + service.beta.kubernetes.io/linode-loadbalancer-firewall-acl: | + { + "allowList": { + "ipv4": ["192.168.0.0/16", "10.0.0.0/8"], + "ipv6": ["2001:db8::/32"] + } + } +``` + +#### Deny List Configuration +```yaml +metadata: + annotations: + service.beta.kubernetes.io/linode-loadbalancer-firewall-acl: | + { + "denyList": { + "ipv4": ["203.0.113.0/24"], + "ipv6": ["2001:db8:1234::/48"] + } + } +``` + +### Behavior +- Only one type of list (allow or deny) can be used per service +- Rules are automatically created and managed by the CCM +- Rules are updated when the annotation changes +- Firewall is deleted when the service is deleted (unless preserved) + +## User-Managed Firewalls + +### Configuration + +1. Create a Cloud Firewall in Linode Cloud Manager +2. Attach it to the service using the `firewall-id` annotation: + +```yaml +metadata: + annotations: + service.beta.kubernetes.io/linode-loadbalancer-firewall-id: "12345" +``` + +### Management +- User maintains full control over firewall rules +- Firewall persists after service deletion +- Manual updates required for rule changes + +## Best Practices + +1. **Rule Management** + - Use descriptive rule labels + - Document rule changes + - Regular security audits + +2. **IP Range Planning** + - Plan CIDR ranges carefully + - Document allowed/denied ranges + - Consider future expansion + +For more information: +- [Service Annotations](annotations.md#firewall-configuration) +- [LoadBalancer Configuration](loadbalancer.md) +- [Linode Cloud Firewall Documentation](https://www.linode.com/docs/products/networking/cloud-firewall/) diff --git a/docs/src/configuration/loadbalancer.md b/docs/src/configuration/loadbalancer.md new file mode 100644 index 00000000..c0781fe2 --- /dev/null +++ b/docs/src/configuration/loadbalancer.md @@ -0,0 +1,206 @@ +# LoadBalancer Services Configuration + +## Overview + +The CCM supports two types of LoadBalancer implementations: +1. Linode NodeBalancers (default) +2. BGP-based IP sharing + +For implementation examples, see [Basic Service Examples](../examples/basic.md#loadbalancer-services). + +## NodeBalancer Implementation + +When using NodeBalancers, the CCM automatically: +1. Creates and configures a NodeBalancer +2. Sets up backend nodes +3. Manages health checks +4. Handles SSL/TLS configuration + +For more details, see [Linode NodeBalancer Documentation](https://www.linode.com/docs/products/networking/nodebalancers/). + +### Basic Configuration + +Create a LoadBalancer service: +```yaml +apiVersion: v1 +kind: Service +metadata: + name: my-service +spec: + type: LoadBalancer + ports: + - port: 80 + targetPort: 8080 + selector: + app: my-app +``` + +See [Advanced Configuration Examples](../examples/advanced.md#loadbalancer-services) for more complex setups. + +### NodeBalancer Settings + +#### Protocol Configuration +Available protocols: +- `tcp` (default) +- `http` +- `https` + +Set the default protocol: +```yaml +metadata: + annotations: + service.beta.kubernetes.io/linode-loadbalancer-default-protocol: "http" +``` + +See [Service Annotations](annotations.md#basic-configuration) for all protocol options. + +### Health Checks + +Configure health checks using annotations: +```yaml +metadata: + annotations: + service.beta.kubernetes.io/linode-loadbalancer-check-type: "http" + service.beta.kubernetes.io/linode-loadbalancer-check-path: "/healthz" + service.beta.kubernetes.io/linode-loadbalancer-check-interval: "5" + service.beta.kubernetes.io/linode-loadbalancer-check-timeout: "3" + service.beta.kubernetes.io/linode-loadbalancer-check-attempts: "2" +``` + +Available check types: +- `none`: No health check +- `connection`: TCP connection check +- `http`: HTTP status check +- `http_body`: HTTP response body check + +For more details, see [Health Check Configuration](annotations.md#health-check-configuration). + +### SSL/TLS Configuration + +1. Create a TLS secret: +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: my-tls-secret +type: kubernetes.io/tls +data: + tls.crt: + tls.key: +``` + +2. Reference in service annotation: +```yaml +metadata: + annotations: + service.beta.kubernetes.io/linode-loadbalancer-port-443: | + { + "protocol": "https", + "tls-secret-name": "my-tls-secret" + } +``` + +### Connection Throttling + +Limit connections from the same client IP: +```yaml +metadata: + annotations: + service.beta.kubernetes.io/linode-loadbalancer-throttle: "5" +``` + +### Proxy Protocol + +Enable proxy protocol for client IP preservation: +```yaml +metadata: + annotations: + service.beta.kubernetes.io/linode-loadbalancer-default-proxy-protocol: "v2" +``` + +## BGP-based IP Sharing Implementation + +BGP-based IP sharing provides a more cost-effective solution for multiple LoadBalancer services. For detailed setup instructions, see [Cilium BGP Documentation](https://docs.cilium.io/en/stable/network/bgp-control-plane/). + +### Prerequisites +- [Cilium CNI](https://docs.cilium.io/en/stable/network/bgp-control-plane/) with BGP control plane enabled +- Additional IP provisioning enabled on your account (contact [Linode Support](https://www.linode.com/support/)) +- Nodes labeled for BGP peering + +### Configuration + +1. Enable BGP in CCM deployment: +```yaml +args: + - --load-balancer-type=cilium-bgp + - --bgp-node-selector=cilium-bgp-peering=true + - --ip-holder-suffix=mycluster +``` + +2. Label nodes that should participate in BGP peering: +```bash +kubectl label node my-node cilium-bgp-peering=true +``` + +3. Create LoadBalancer services as normal - the CCM will automatically use BGP-based IP sharing instead of creating NodeBalancers. + +### Environment Variables +- `BGP_CUSTOM_ID_MAP`: Use your own map instead of default region map for BGP +- `BGP_PEER_PREFIX`: Use your own BGP peer prefix instead of default one + +For more details, see [Environment Variables](environment.md#network-configuration). + +## Advanced Configuration + +### Using Existing NodeBalancers + +Specify an existing NodeBalancer: +```yaml +metadata: + annotations: + service.beta.kubernetes.io/linode-loadbalancer-nodebalancer-id: "12345" +``` + +### NodeBalancer Preservation + +Prevent NodeBalancer deletion when service is deleted: +```yaml +metadata: + annotations: + service.beta.kubernetes.io/linode-loadbalancer-preserve: "true" +``` + +### Port Configuration + +Configure individual ports: +```yaml +metadata: + annotations: + service.beta.kubernetes.io/linode-loadbalancer-port-443: | + { + "protocol": "https", + "tls-secret-name": "my-tls-secret", + "proxy-protocol": "v2" + } +``` + +### Tags + +Add tags to NodeBalancer: +```yaml +metadata: + annotations: + service.beta.kubernetes.io/linode-loadbalancer-tags: "production,web-tier" +``` + +## Related Documentation + +- [Service Annotations](annotations.md) +- [Firewall Configuration](firewall.md) +- [Session Affinity](session-affinity.md) +- [Environment Variables](environment.md) +- [Route Configuration](routes.md) +- [Linode NodeBalancer Documentation](https://www.linode.com/docs/products/networking/nodebalancers/) +- [Cilium BGP Documentation](https://docs.cilium.io/en/stable/network/bgp-control-plane/) +- [Basic Service Examples](../examples/basic.md) +- [Advanced Configuration Examples](../examples/advanced.md) diff --git a/docs/src/configuration/nodes.md b/docs/src/configuration/nodes.md new file mode 100644 index 00000000..6d8ed298 --- /dev/null +++ b/docs/src/configuration/nodes.md @@ -0,0 +1,96 @@ +# Node Configuration + +## Overview + +The Node Controller in CCM manages node-specific configurations and lifecycle operations for Kubernetes nodes running on Linode instances. + +## Node Labels + +The CCM automatically adds the following labels to nodes: + +### Topology Labels +Current: +- `topology.kubernetes.io/region`: Linode region (e.g., "us-east") +- `topology.kubernetes.io/zone`: Linode availability zone + +Legacy (deprecated): +- `failure-domain.beta.kubernetes.io/region`: Linode region +- `failure-domain.beta.kubernetes.io/zone`: Linode availability zone + +### Provider Labels +- `node.kubernetes.io/instance-type`: Linode instance type (e.g., "g6-standard-4") + +## Node Annotations + +All node annotations must be prefixed with: `node.k8s.linode.com/` + +### Available Annotations + +| Annotation | Type | Default | Description | +|------------|------|---------|-------------| +| `private-ip` | IPv4 | none | Overrides default detection of Node InternalIP | + +### Use Cases + +#### Private Network Configuration +```yaml +apiVersion: v1 +kind: Node +metadata: + name: my-node + annotations: + node.k8s.linode.com/private-ip: "192.168.1.100" +``` + +#### VPC Configuration +When using [Linode VPC](https://www.linode.com/docs/products/networking/vpc/), you may need to manually configure the node's InternalIP: +```yaml +apiVersion: v1 +kind: Node +metadata: + name: vpc-node + annotations: + node.k8s.linode.com/private-ip: "10.0.0.5" +``` + +## Node Networking + +### Private Network Requirements +- NodeBalancers require nodes to have private IP addresses +- Private IPs must be configured in the Linode Cloud Manager or via the API +- The CCM will use private IPs for inter-node communication + +### VPC Configuration +When using VPC: +1. Configure network interfaces in Linode Cloud Manager +2. Add appropriate node annotations for private IPs +3. Ensure proper routing configuration +4. Configure security groups if needed + +For VPC routing setup, see [Route Configuration](routes.md). + +## Node Controller Behavior + +### Node Initialization +- Configures node with Linode-specific information +- Sets node addresses (public/private IPs) +- Applies region/zone labels +- Configures node hostnames + +### Node Lifecycle Management +- Monitors node health +- Updates node status +- Handles node termination +- Manages node cleanup + +### Node Updates +- Updates node labels when region/zone changes +- Updates node addresses when IP configuration changes +- Maintains node conditions based on Linode instance status + +For more information: +- [Linode Instance Types](https://www.linode.com/docs/products/compute/compute-instances/plans/) +- [Private Networking](https://www.linode.com/docs/products/networking/private-networking/) +- [VPC Documentation](https://www.linode.com/docs/products/networking/vpc/) +- [Route Configuration](routes.md) +- [Environment Variables](environment.md) diff --git a/docs/src/configuration/routes.md b/docs/src/configuration/routes.md new file mode 100644 index 00000000..29dfbbc7 --- /dev/null +++ b/docs/src/configuration/routes.md @@ -0,0 +1,100 @@ +# Route Configuration + +## Overview + +The Route Controller manages network routes for pod communication in VPC environments. It ensures proper connectivity between nodes and pods across the cluster by configuring routes in Linode VPC. + +## Prerequisites + +- Kubernetes cluster running in Linode VPC +- CCM with route controller enabled +- Proper API permissions + +## Configuration + +### Enable Route Controller + +1. Via Helm chart in `values.yaml`: +```yaml +routeController: + vpcNames: "vpc-prod,vpc-staging" # Comma separated names of VPCs managed by CCM + clusterCIDR: "10.0.0.0/8" # Pod CIDR range + configureCloudRoutes: true # Enable route controller +``` + +2. Via command line flags in CCM deployment: +```yaml +spec: + template: + spec: + containers: + - name: ccm-linode + args: + - --configure-cloud-routes=true + - --vpc-names=vpc-prod,vpc-staging + - --cluster-cidr=10.0.0.0/8 +``` + +### Environment Variables + +| Variable | Default | Description | +|----------|---------|-------------| +| `LINODE_ROUTES_CACHE_TTL_SECONDS` | `60` | Default timeout of route cache in seconds | + +## Route Management + +### Automatic Operations + +The Route Controller: +- Creates routes for pod CIDR ranges assigned to nodes +- Updates routes when nodes are added/removed +- Manages route tables in specified VPCs +- Handles route cleanup during node removal +- Maintains route cache for performance + +### Route Types + +1. **Pod CIDR Routes** + - Created for each node's pod CIDR allocation + - Target is node's private IP address + - Automatically managed based on node lifecycle + +2. **VPC Routes** + - Managed within specified VPCs + - Enables cross-node pod communication + - Automatically updated with topology changes + +## Best Practices + +### CIDR Planning +- Ensure pod CIDR range doesn't overlap with VPC ranges +- Plan for future cluster growth +- Document CIDR allocations + +### VPC Configuration +- Use clear, descriptive VPC names +- Configure proper VPC security settings +- Ensure proper API permissions + +## Troubleshooting + +### Common Issues + +1. **Route Creation Failures** + - Verify API permissions + - Check for CIDR conflicts + - Validate VPC configuration + - Ensure node private IPs are configured + +2. **Pod Communication Issues** + - Verify route table entries + - Check VPC network ACLs + - Validate node networking + - Confirm pod CIDR assignments + +## Related Documentation + +- [VPC Configuration](https://www.linode.com/docs/products/networking/vpc/) +- [Node Configuration](nodes.md) +- [Environment Variables](environment.md) +- [Kubernetes Network Policies](https://kubernetes.io/docs/concepts/services-networking/network-policies/) diff --git a/docs/src/configuration/session-affinity.md b/docs/src/configuration/session-affinity.md new file mode 100644 index 00000000..78683c90 --- /dev/null +++ b/docs/src/configuration/session-affinity.md @@ -0,0 +1,60 @@ +# Session Affinity + +## Overview + +Session affinity (also known as sticky sessions) ensures that requests from the same client are consistently routed to the same backend pod. In Kubernetes, sessionAffinity refers to a mechanism that allows a client to always be redirected to the same pod when the client hits a service. + +## Configuration + +### Basic Setup + +Enable session affinity by setting `service.spec.sessionAffinity` to `ClientIP`: +```yaml +apiVersion: v1 +kind: Service +metadata: + name: wordpress-lsmnl-wordpress + namespace: wordpress-lsmnl + labels: + app: wordpress-lsmnl-wordpress +spec: + type: LoadBalancer + selector: + app: wordpress-lsmnl-wordpress + sessionAffinity: ClientIP +``` + +### Setting Timeout + +Configure the maximum session sticky time using `sessionAffinityConfig`: +```yaml +apiVersion: v1 +kind: Service +metadata: + name: my-service +spec: + type: LoadBalancer + sessionAffinity: ClientIP + sessionAffinityConfig: + clientIP: + timeoutSeconds: 10800 # 3 hours +``` + +## Configuration Options + +### Session Affinity Types +- `None`: No session affinity (default) +- `ClientIP`: Route based on client's IP address. All requests from the same client IP will be directed to the same pod. + +### Timeout Configuration +- `timeoutSeconds`: Duration to maintain affinity +- Default: 10800 seconds (3 hours) +- Valid range: 1 to 86400 seconds (24 hours) +- After the timeout period, client requests may be routed to a different pod + +## Related Documentation + +- [Service Configuration](annotations.md) +- [LoadBalancer Configuration](loadbalancer.md) +- [Kubernetes Services Documentation](https://kubernetes.io/docs/concepts/services-networking/service/#session-affinity) +- [Service Selectors](https://kubernetes.io/docs/concepts/services-networking/service/#defining-a-service) diff --git a/docs/src/development/README.md b/docs/src/development/README.md new file mode 100644 index 00000000..33b977a9 --- /dev/null +++ b/docs/src/development/README.md @@ -0,0 +1,127 @@ +# Development Guide + +## Prerequisites + +The Linode Cloud Controller Manager development requires: +- A fairly up-to-date GNU tools environment +- Go 1.8.3 or higher + +### Setting Up Development Environment + +#### Option 1: Using Devbox (Recommended) +The simplest way to set up your development environment is using [Devbox](https://www.jetpack.io/devbox/): + +1. Install Devbox by following the instructions at [jetpack.io/devbox/docs/installing_devbox/](https://www.jetpack.io/devbox/docs/installing_devbox/) + +2. Start the development environment: +```bash +devbox shell +``` + +This will automatically set up all required dependencies and tools for development. + +#### Option 2: Manual Setup + +1. If you haven't set up a Go development environment, follow [these instructions](https://golang.org/doc/install) to install Go. + +On macOS, you can use Homebrew: +```bash +brew install golang +``` + +## Getting Started + +### Download Source +```bash +go get github.com/linode/linode-cloud-controller-manager +cd $(go env GOPATH)/src/github.com/linode/linode-cloud-controller-manager +``` + +### Install Development Tools +To install various dev tools for the Cloud Controller Manager: +```bash +./hack/builddeps.sh +``` + +### Building the Project + +#### Build Binary +Use the following Make targets to build and run a local binary: + +```bash +# Build the binary +make build + +# Run the binary +make run + +# You can also run the binary directly to pass additional args +dist/linode-cloud-controller-manager +``` + +#### Building Docker Images +To build and push a Docker image: + +```bash +# Set the repo/image:tag with the TAG environment variable +# Then run the docker-build make target +IMG=linode/linode-cloud-controller-manager:canary make docker-build + +# Push Image +IMG=linode/linode-cloud-controller-manager:canary make docker-push +``` + +To run the Docker image: +```bash +docker run -ti linode/linode-cloud-controller-manager:canary +``` + +### Managing Dependencies +The Linode Cloud Controller Manager uses [Go Modules](https://blog.golang.org/using-go-modules) to manage dependencies. + +To update or add dependencies: +```bash +go mod tidy +``` + +## Development Guidelines + +### Code Quality Standards +- Write correct, up-to-date, bug-free, fully functional, secure, and efficient code +- Use the latest stable version of Go +- Follow Go idioms and best practices +- Implement proper error handling with custom error types when beneficial +- Include comprehensive input validation +- Utilize built-in language features for performance optimization +- Follow relevant design patterns and principles +- Leave NO todos, placeholders, or incomplete implementations + +### Code Structure +- Include necessary imports and declarations +- Implement proper logging using appropriate logging mechanisms +- Consider implementing middleware or interceptors for cross-cutting concerns +- Structure code in a modular and maintainable way +- Use appropriate naming conventions and code organization + +### Security & Performance +- Implement security best practices +- Consider rate limiting when appropriate +- Include authentication/authorization where needed +- Optimize for performance while maintaining readability +- Consider scalability in design decisions + +### Documentation & Testing +- Provide brief comments for complex logic or language-specific idioms +- Include clear documentation for public interfaces +- Write tests using appropriate testing frameworks +- Document any assumptions or limitations + +### Pull Request Process +1. Ensure your code follows the project's coding standards +2. Update documentation as needed +3. Add or update tests as appropriate +4. Make sure all tests pass locally +5. Submit the PR with a clear description of the changes + +## Getting Help +For development related questions or discussions, join us in #linode on the [Kubernetes Slack](https://kubernetes.slack.com/messages/CD4B15LUR/details/). \ No newline at end of file diff --git a/docs/src/examples/README.md b/docs/src/examples/README.md new file mode 100644 index 00000000..606e1589 --- /dev/null +++ b/docs/src/examples/README.md @@ -0,0 +1,23 @@ +# Examples + +This section provides working examples of common CCM configurations. Each example includes a complete service and deployment configuration. + +## Available Examples + +1. **[Basic Services](basic.md)** + - HTTP LoadBalancer + - HTTPS LoadBalancer with TLS termination + +2. **[Advanced Configuration](advanced.md)** + - Custom Health Checks + - Firewalled Services + - Session Affinity + - Shared IP Load-Balancing + - Custom Node Selection + +For testing these examples, see the [test script](https://github.com/linode/linode-cloud-controller-manager/blob/master/examples/test.sh). + +For more configuration options, see: +- [Service Annotations](../configuration/annotations.md) +- [LoadBalancer Configuration](../configuration/loadbalancer.md) +- [Firewall Configuration](../configuration/firewall.md) diff --git a/docs/src/examples/advanced.md b/docs/src/examples/advanced.md new file mode 100644 index 00000000..42fd8e64 --- /dev/null +++ b/docs/src/examples/advanced.md @@ -0,0 +1,140 @@ +# Advanced Configuration + +## Custom Health Checks + +Service with custom health check configuration: + +```yaml +apiVersion: v1 +kind: Service +metadata: + name: web-healthcheck + annotations: + service.beta.kubernetes.io/linode-loadbalancer-check-type: "http" + service.beta.kubernetes.io/linode-loadbalancer-check-path: "/healthz" + service.beta.kubernetes.io/linode-loadbalancer-check-interval: "5" + service.beta.kubernetes.io/linode-loadbalancer-check-timeout: "3" + service.beta.kubernetes.io/linode-loadbalancer-check-attempts: "2" + service.beta.kubernetes.io/linode-loadbalancer-check-passive: "true" +spec: + type: LoadBalancer + ports: + - port: 80 + selector: + app: web +``` + +## Firewalled Services + +Service with firewall rules: + +```yaml +kind: Service +apiVersion: v1 +metadata: + name: restricted-access + annotations: + service.beta.kubernetes.io/linode-loadbalancer-firewall-acl: | + { + "allowList": { + "ipv4": ["192.166.0.0/16", "172.23.41.0/24"], + "ipv6": ["2001:DB8::/128"] + } + } +spec: + type: LoadBalancer + selector: + app: restricted-app + ports: + - name: http + port: 80 + targetPort: 8080 +``` + +## Session Affinity + +Service with sticky sessions: + +```yaml +apiVersion: v1 +kind: Service +metadata: + name: sticky-service +spec: + type: LoadBalancer + sessionAffinity: ClientIP + sessionAffinityConfig: + clientIP: + timeoutSeconds: 100 + selector: + app: sticky-app + ports: + - port: 80 + targetPort: 8080 +``` + +## Shared IP Load-Balancing + +```yaml +apiVersion: v1 +kind: Service +metadata: + name: shared-ip-service +spec: + type: LoadBalancer + selector: + app: web + ports: + - port: 80 + targetPort: 8080 +--- +# Required DaemonSet configuration for shared IP +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: ccm-linode + namespace: kube-system +spec: + template: + spec: + containers: + - image: linode/linode-cloud-controller-manager:latest + name: ccm-linode + env: + - name: LINODE_URL + value: https://api.linode.com/v4 + args: + - --bgp-node-selector=cilium-bgp-peering=true + - --load-balancer-type=cilium-bgp + - --ip-holder-suffix=myclustername1 +``` + +## Custom Node Selection + +```yaml +apiVersion: v1 +kind: Service +metadata: + name: custom-nodes +spec: + type: LoadBalancer + selector: + app: custom-app + ports: + - port: 80 + # Only use nodes with specific labels + externalTrafficPolicy: Local +--- +# Example node with custom annotation +apiVersion: v1 +kind: Node +metadata: + name: custom-node + annotations: + node.k8s.linode.com/private-ip: "192.168.1.100" +``` + +For more examples, see: +- [Service Annotations](../configuration/annotations.md) +- [Firewall Configuration](../configuration/firewall.md) +- [LoadBalancer Configuration](../configuration/loadbalancer.md) diff --git a/docs/src/examples/basic.md b/docs/src/examples/basic.md new file mode 100644 index 00000000..c4da3a09 --- /dev/null +++ b/docs/src/examples/basic.md @@ -0,0 +1,107 @@ +# Basic Services + +## HTTP LoadBalancer + +Basic HTTP LoadBalancer service with nginx: + +```yaml +kind: Service +apiVersion: v1 +metadata: + name: http-lb + annotations: + service.beta.kubernetes.io/linode-loadbalancer-default-protocol: "http" +spec: + type: LoadBalancer + selector: + app: nginx-http-example + ports: + - name: http + protocol: TCP + port: 80 + targetPort: 80 + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: nginx-http-deployment +spec: + replicas: 2 + selector: + matchLabels: + app: nginx-http-example + template: + metadata: + labels: + app: nginx-http-example + spec: + containers: + - name: nginx + image: nginx + ports: + - containerPort: 80 + protocol: TCP +``` + +## HTTPS LoadBalancer + +HTTPS LoadBalancer with TLS termination: + +```yaml +kind: Service +apiVersion: v1 +metadata: + name: https-lb + annotations: + service.beta.kubernetes.io/linode-loadbalancer-throttle: "4" + service.beta.kubernetes.io/linode-loadbalancer-default-protocol: "http" + service.beta.kubernetes.io/linode-loadbalancer-port-443: | + { + "tls-secret-name": "example-secret", + "protocol": "https" + } +spec: + type: LoadBalancer + selector: + app: nginx-https-example + ports: + - name: http + protocol: TCP + port: 80 + targetPort: http + - name: https + protocol: TCP + port: 443 + targetPort: https + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: nginx-https-deployment +spec: + replicas: 2 + selector: + matchLabels: + app: nginx-https-example + template: + metadata: + labels: + app: nginx-https-example + spec: + containers: + - name: nginx + image: nginx + ports: + - name: http + containerPort: 80 + protocol: TCP + - name: https + containerPort: 80 + protocol: TCP +``` + +For more configuration options, see: +- [Service Annotations](../configuration/annotations.md) +- [LoadBalancer Configuration](../configuration/loadbalancer.md) diff --git a/docs/src/getting-started/README.md b/docs/src/getting-started/README.md new file mode 100644 index 00000000..9850e6d3 --- /dev/null +++ b/docs/src/getting-started/README.md @@ -0,0 +1,13 @@ +# Getting Started + +This section will guide you through: +- Understanding the CCM's requirements +- Installing the CCM using either Helm or manual installation +- Verifying your installation +- Troubleshooting common issues + +Choose the installation method that best suits your needs: +- **Helm Installation**: Recommended for most users, provides easier upgrades and configuration +- **Manual Installation**: Offers more control over the deployment process + +Before proceeding with installation, make sure to review the requirements section to ensure your environment is properly configured. diff --git a/docs/src/getting-started/helm-installation.md b/docs/src/getting-started/helm-installation.md new file mode 100644 index 00000000..96debd58 --- /dev/null +++ b/docs/src/getting-started/helm-installation.md @@ -0,0 +1,58 @@ +# Helm Installation + +## Prerequisites +- Helm 3.x installed +- kubectl configured to access your cluster +- Linode API token +- Target region identified + +## Installation Steps + +1. Add the CCM Helm repository: +```bash +helm repo add ccm-linode https://linode.github.io/linode-cloud-controller-manager/ +helm repo update ccm-linode +``` + +2. Create a values file (values.yaml): +```yaml +apiToken: "your-api-token" +region: "us-east" + +# Optional: Configure route controller +routeController: + vpcNames: "" # Comma separated VPC names + clusterCIDR: "10.0.0.0/8" + configureCloudRoutes: true + +# Optional: Configure shared IP load balancing +sharedIPLoadBalancing: + loadBalancerType: cilium-bgp + bgpNodeSelector: cilium-bgp-peering=true + ipHolderSuffix: "" +``` + +3. Install the CCM: +```bash +helm install ccm-linode \ + --namespace kube-system \ + -f values.yaml \ + ccm-linode/ccm-linode +``` + +## Upgrading + +To upgrade an existing installation: +```bash +helm upgrade ccm-linode \ + --namespace kube-system \ + -f values.yaml \ + ccm-linode/ccm-linode +``` + +## Uninstalling + +To remove the CCM: +```bash +helm uninstall ccm-linode -n kube-system +``` diff --git a/docs/src/getting-started/installation.md b/docs/src/getting-started/installation.md new file mode 100644 index 00000000..ea47f6df --- /dev/null +++ b/docs/src/getting-started/installation.md @@ -0,0 +1,20 @@ +# Installation + +The CCM can be installed using either Helm (recommended) or by manually applying manifests. Choose the method that best suits your needs: + +## Installation Methods + +### [Helm Installation](helm-installation.md) +- Easier to manage and upgrade +- Configurable through values.yaml +- Supports templating for different environments + +### [Manual Installation](manual-installation.md) +- More control over the deployment +- Better for customized setups +- Useful for understanding the components + +## Post-Installation +After installing the CCM, proceed to the [Verification](verification.md) section to ensure everything is working correctly. + +If you encounter any issues, check the [Troubleshooting](troubleshooting.md) guide. diff --git a/docs/src/getting-started/manual-installation.md b/docs/src/getting-started/manual-installation.md new file mode 100644 index 00000000..79954f53 --- /dev/null +++ b/docs/src/getting-started/manual-installation.md @@ -0,0 +1,56 @@ +# Manual Installation + +## Prerequisites +- kubectl configured to access your cluster +- Linode API token +- Target region identified + +## Installation Steps + +1. Generate the manifest: +```bash +./deploy/generate-manifest.sh $LINODE_API_TOKEN us-east +``` + +2. Review the generated manifest: +The script creates `ccm-linode.yaml` containing: +- ServiceAccount +- ClusterRole and ClusterRoleBinding +- Secret with API token +- DaemonSet for the CCM + +3. Apply the manifest: +```bash +kubectl apply -f ccm-linode.yaml +``` + +## Customization + +### Environment Variables +You can modify the DaemonSet to include custom environment variables: +```yaml +env: + - name: LINODE_INSTANCE_CACHE_TTL + value: "15" + - name: LINODE_ROUTES_CACHE_TTL_SECONDS + value: "60" +``` + +### Resource Limits +Adjust compute resources as needed: +```yaml +resources: + requests: + cpu: 100m + memory: 128Mi + limits: + cpu: 200m + memory: 256Mi +``` + +## Uninstalling + +To remove the CCM: +```bash +kubectl delete -f ccm-linode.yaml +``` diff --git a/docs/src/getting-started/overview.md b/docs/src/getting-started/overview.md new file mode 100644 index 00000000..39fe3f0e --- /dev/null +++ b/docs/src/getting-started/overview.md @@ -0,0 +1,34 @@ +# Overview + +The Linode Cloud Controller Manager provides several key features that enable a fully supported Kubernetes experience on Linode infrastructure. + +## Features + +### LoadBalancer Services +- Automatic deployment and configuration of Linode NodeBalancers +- Support for HTTP, HTTPS, and TCP traffic +- SSL/TLS termination +- Custom health checks and session affinity + +### Node Management +- Automatic configuration of node hostnames and network addresses +- Proper node state management for Linode shutdowns +- Region-based node annotation for failure domain scheduling + +### Network Integration +- Support for private networking +- VPC and VLAN compatibility +- BGP-based IP sharing capabilities + +### Security +- Integrated firewall management +- Support for TLS termination +- Custom security rules and ACLs + +## When to Use CCM + +The Linode CCM is essential when: +- Running Kubernetes clusters on Linode infrastructure +- Requiring automated load balancer provisioning +- Needing integrated cloud provider features +- Managing multi-node clusters with complex networking requirements \ No newline at end of file diff --git a/docs/src/getting-started/requirements.md b/docs/src/getting-started/requirements.md new file mode 100644 index 00000000..4458d777 --- /dev/null +++ b/docs/src/getting-started/requirements.md @@ -0,0 +1,50 @@ +# Requirements + +## Kubernetes Cluster Requirements + +### Version Compatibility +- Kubernetes version 1.9 or higher +- Kubernetes cluster running on Linode infrastructure + +### Kubernetes Components Configuration +The following Kubernetes components must be started with the `--cloud-provider=external` flag: +- Kubelet +- Kube Controller Manager +- Kube API Server + +## Linode Requirements + +### API Token +You need a Linode APIv4 Personal Access Token with the following scopes: +- Linodes - Read/Write +- NodeBalancers - Read/Write +- IPs - Read/Write +- Volumes - Read/Write +- Firewalls - Read/Write (if using firewall features) + +To create a token: +1. Log into the [Linode Cloud Manager](https://cloud.linode.com) +2. Go to your profile +3. Select the "API Tokens" tab +4. Click "Create a Personal Access Token" +5. Select the required scopes +6. Set an expiry (optional) + +### Region Support +Your cluster must be in a [supported Linode region](https://api.linode.com/v4/regions). + +## Network Requirements + +### Private Networking +- If using NodeBalancers, nodes must have private IP addresses +- VPC or VLAN configurations require additional network configuration + +### Firewall Considerations +- Ensure required ports are open for Kubernetes components +- If using Cloud Firewalls, ensure the API token has firewall management permissions + +## Resource Quotas +Ensure your Linode account has sufficient quota for: +- NodeBalancers (if using LoadBalancer services) +- Additional IP addresses (if using shared IP features) +- Cloud Firewalls (if using firewall features) diff --git a/docs/src/getting-started/troubleshooting.md b/docs/src/getting-started/troubleshooting.md new file mode 100644 index 00000000..5e613f8d --- /dev/null +++ b/docs/src/getting-started/troubleshooting.md @@ -0,0 +1,96 @@ +# Troubleshooting + +## Common Issues and Solutions + +### CCM Pod Issues + +#### Pod Won't Start +```bash +kubectl get pods -n kube-system -l app=ccm-linode +kubectl describe pod -n kube-system -l app=ccm-linode +``` + +Common causes: +- Invalid API token +- Missing RBAC permissions +- Resource constraints + +#### Pod Crashes +Check the logs: +```bash +kubectl logs -n kube-system -l app=ccm-linode +``` + +Common causes: +- API rate limiting +- Network connectivity issues +- Configuration errors + +### LoadBalancer Service Issues + +#### Service Stuck in Pending +```bash +kubectl describe service +``` + +Check for: +- API token permissions +- NodeBalancer quota limits +- Network configuration + +#### Health Checks Failing +Verify: +- Backend pod health +- Service port configuration +- Health check path configuration + +### Node Issues + +#### Missing Node Labels +```bash +kubectl get nodes --show-labels +``` + +Verify: +- CCM node controller logs +- Node annotations +- API permissions + +#### Network Problems +Check: +- Private IP configuration +- VPC/VLAN setup +- Firewall rules + +## Gathering Information + +### Useful Commands +```bash +# Get CCM version +kubectl get pods -n kube-system -l app=ccm-linode -o jsonpath='{.items[0].spec.containers[0].image}' + +# Check events +kubectl get events -n kube-system + +# Get CCM logs with timestamps +kubectl logs -n kube-system -l app=ccm-linode --timestamps +``` + +### Debug Mode +Set the following environment variable in the CCM deployment: +```yaml +env: + - name: LINODE_DEBUG + value: "1" +``` + +## Getting Help + +If issues persist: +1. Join #linode on [Kubernetes Slack](https://kubernetes.slack.com) +2. Check [GitHub Issues](https://github.com/linode/linode-cloud-controller-manager/issues) +3. Submit a new issue with: + - CCM version + - Kubernetes version + - Relevant logs + - Steps to reproduce diff --git a/docs/src/getting-started/verification.md b/docs/src/getting-started/verification.md new file mode 100644 index 00000000..22e7c046 --- /dev/null +++ b/docs/src/getting-started/verification.md @@ -0,0 +1,63 @@ +# Verification + +After installing the CCM, follow these steps to verify it's working correctly. + +## Check CCM Pod Status + +1. Verify the CCM pods are running: +```bash +kubectl get pods -n kube-system -l app=ccm-linode +``` + +Expected output: +``` +NAME READY STATUS RESTARTS AGE +ccm-linode-xxxxx 1/1 Running 0 2m +``` + +2. Check CCM logs: +```bash +kubectl logs -n kube-system -l app=ccm-linode +``` + +Look for successful initialization messages and no errors. + +## Verify Node Configuration + +1. Check node annotations: +```bash +kubectl get nodes -o yaml +``` + +Look for: +- Proper region labels +- Node addresses +- Provider ID + +## Test LoadBalancer Service + +1. Create a test service: +```yaml +apiVersion: v1 +kind: Service +metadata: + name: test-lb +spec: + type: LoadBalancer + ports: + - port: 80 + selector: + app: test +``` + +2. Verify NodeBalancer creation: +```bash +kubectl get svc test-lb +``` + +The service should receive an external IP address. + +## Common Issues +- Pods in CrashLoopBackOff: Check logs for API token or permissions issues +- Service stuck in 'Pending': Verify API token has NodeBalancer permissions +- Missing node annotations: Check CCM logs for node controller issues diff --git a/docs/src/help.md b/docs/src/help.md new file mode 100644 index 00000000..2ced1b39 --- /dev/null +++ b/docs/src/help.md @@ -0,0 +1,23 @@ +# Getting Help + +## Community Support + +For general help or discussion, join us in #linode on the [Kubernetes Slack](https://kubernetes.slack.com/messages/CD4B15LUR/details/). + +To sign up for Kubernetes Slack, use the [Kubernetes Slack inviter](http://slack.kubernetes.io/). + +## Issue Tracking + +If you've found a bug or want to request a feature: +- Check the [GitHub Issues](https://github.com/linode/linode-cloud-controller-manager/issues) +- Submit a [Pull Request](https://github.com/linode/linode-cloud-controller-manager/pulls) + +## Documentation + +- [Official Linode Documentation](https://www.linode.com/docs/) +- [Kubernetes Cloud Controller Manager Documentation](https://kubernetes.io/docs/tasks/administer-cluster/running-cloud-controller/) +- [API Documentation](https://www.linode.com/docs/api) + +## Social Media + +Follow [@linode](https://twitter.com/linode) on Twitter for updates and announcements. diff --git a/docs/src/introduction.md b/docs/src/introduction.md new file mode 100644 index 00000000..20c7c00c --- /dev/null +++ b/docs/src/introduction.md @@ -0,0 +1,61 @@ +# Introduction + +The Linode Cloud Controller Manager (CCM) is a crucial component that integrates Kubernetes with Linode's infrastructure services. It implements the cloud-controller-manager binary, running cloud-specific control loops that are essential for cluster operation. + +## What is a Cloud Controller Manager? + +A Cloud Controller Manager (CCM) is a Kubernetes control plane component that embeds cloud-specific control logic. It lets you link your cluster to your cloud provider's API, separating out the components that interact with that cloud platform from components that only interact with your cluster. + +## Core Functions + +### Node Controller +The Node Controller is responsible for: +- Initializing node configuration with Linode-specific information + - Setting node addresses (public/private IPs) + - Labeling nodes with region/zone information + - Configuring node hostnames +- Monitoring node health and lifecycle + - Detecting node termination + - Updating node status + - Managing node cleanup + +### Service Controller +The Service Controller manages the lifecycle of cloud load balancers: +- Manages LoadBalancer service implementations using Linode NodeBalancers + - Creates and configures NodeBalancers + - Updates backend pools + - Manages SSL/TLS certificates +- Handles automatic provisioning and configuration + - Health checks + - Session affinity + - Protocol configuration +- Supports multiple load balancing approaches + - Traditional NodeBalancer deployment + - BGP-based IP sharing for cost optimization + - Custom firewall rules and security configurations + +### Route Controller +The Route Controller configures networking for pod communication: +- Manages VPC and private network integration + - Configures routes for pod CIDR ranges + - Handles cross-node pod communication +- Ensures proper network connectivity + - Sets up pod-to-pod networking + - Manages network policies + - Configures network routes for optimal communication + +## Architecture + +### Component Integration +The CCM runs as a Kubernetes deployment in your cluster and: +- Watches for changes to Service and Node resources +- Interacts with Linode's API to manage infrastructure +- Maintains state synchronization between Kubernetes and Linode resources +- Operates independently of core Kubernetes controllers + +## Next Steps + +- Review the [Requirements](getting-started/requirements.md) for using the CCM +- Follow the [Installation Guide](getting-started/installation.md) to set up the CCM +- Learn about [Configuration Options](configuration/README.md) +- See [Examples](examples/README.md) of common use cases \ No newline at end of file From 02f3c8dad87faac3696e22d7cfcb581abfca54a8 Mon Sep 17 00:00:00 2001 From: Khaja Omer Date: Fri, 17 Jan 2025 13:06:45 -0600 Subject: [PATCH 02/19] Add missing links in the Readme --- README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README.md b/README.md index f1f897f3..ef57e2a6 100644 --- a/README.md +++ b/README.md @@ -33,8 +33,11 @@ The Linode Cloud Controller Manager (CCM) integrates Kubernetes with Linode's in ## Quick Links - [Getting Started](docs/src/getting-started/README.md) + - [Overview](docs/src/getting-started/overview.md) - [Requirements](docs/src/getting-started/requirements.md) - [Installation](docs/src/getting-started/installation.md) + - [Helm Installation](docs/src/getting-started/helm-installation.md) + - [Manual Installation](docs/src/getting-started/manual-installation.md) - [Verification](docs/src/getting-started/verification.md) - [Troubleshooting](docs/src/getting-started/troubleshooting.md) @@ -42,6 +45,10 @@ The Linode Cloud Controller Manager (CCM) integrates Kubernetes with Linode's in - [LoadBalancer Services](docs/src/configuration/loadbalancer.md) - [Service Annotations](docs/src/configuration/annotations.md) - [Node Configuration](docs/src/configuration/nodes.md) + - [Environment Variables](docs/src/configuration/environment.md) + - [Firewall Setup](docs/src/configuration/firewall.md) + - [Route Configuration](docs/src/configuration/routes.md) + - [Session Affinity](docs/src/configuration/session-affinity.md) - [Examples](docs/src/examples/README.md) - [Basic Services](docs/src/examples/basic.md) @@ -49,6 +56,8 @@ The Linode Cloud Controller Manager (CCM) integrates Kubernetes with Linode's in - [Development Guide](docs/src/development/README.md) +- [Getting Help](docs/src/help.md) + ## Getting Help For support and development discussions, join us in #linode on the [Kubernetes Slack](https://kubernetes.slack.com/messages/CD4B15LUR/details/). To sign up, use the [Kubernetes Slack inviter](http://slack.kubernetes.io/). From 748ae3397ccafc730b5812f272048cb7d3e3c147 Mon Sep 17 00:00:00 2001 From: Khaja Omer Date: Fri, 17 Jan 2025 13:11:33 -0600 Subject: [PATCH 03/19] Add GHA for publishing mdbook --- .github/workflows/docs.yml | 62 ++++++++++++++++++++++++++++++++++++++ docs/book.toml | 8 +++++ 2 files changed, 70 insertions(+) create mode 100644 .github/workflows/docs.yml diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml new file mode 100644 index 00000000..3615ef26 --- /dev/null +++ b/.github/workflows/docs.yml @@ -0,0 +1,62 @@ +name: Deploy Documentation + +on: + push: + branches: + - master + paths: + - 'README.md' + - 'docs/**' + - '.github/workflows/docs.yml' + pull_request: + paths: + - 'docs/**' + - '.github/workflows/docs.yml' + +permissions: + contents: read + pages: write # to deploy to Pages + id-token: write # to verify the deployment originates from an appropriate source + +jobs: + generate-docs: + runs-on: ubuntu-latest + container: docker.io/node:20-bullseye-slim + timeout-minutes: 2 + steps: + - uses: actions/checkout@v4 + + - name: Setup mdBook + run: | + apt-get update + apt-get install curl -y + mkdir mdbook + curl -sSL https://github.com/rust-lang/mdbook/releases/download/v0.4.37/mdbook-v0.4.37-x86_64-unknown-linux-gnu.tar.gz | tar -xz --directory=./mdbook + curl -sSL https://github.com/tommilligan/mdbook-admonish/releases/download/v1.15.0/mdbook-admonish-v1.15.0-x86_64-unknown-linux-gnu.tar.gz | tar -xz --directory=./mdbook + echo `pwd`/mdbook >> $GITHUB_PATH + + - name: Build with mdBook + run: | + cd docs + mdbook build + + - name: Setup Pages + uses: actions/configure-pages@v5 + + - name: Upload artifact + uses: actions/upload-pages-artifact@v3 + with: + path: 'docs/book' + + deploy-page: + needs: generate-docs + if: github.event_name == 'push' + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + timeout-minutes: 2 + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 \ No newline at end of file diff --git a/docs/book.toml b/docs/book.toml index 7e23cb80..74d9798b 100644 --- a/docs/book.toml +++ b/docs/book.toml @@ -8,6 +8,14 @@ description = "Documentation for the Kubernetes Cloud Controller Manager for Lin [output.html] git-repository-url = "https://github.com/linode/linode-cloud-controller-manager" +site-url = "/linode-cloud-controller-manager/" +edit-url-template = "https://github.com/linode/linode-cloud-controller-manager/edit/master/docs/{path}" + +[preprocessor] + +[preprocessor.admonish] +command = "mdbook-admonish" +assets_version = "3.0.2" # do not edit: managed by `mdbook-admonish install` [output.html.playground] editable = true From 9054e122de014bfb1db29e04f08f4faa328e36db Mon Sep 17 00:00:00 2001 From: Khaja Omer Date: Fri, 17 Jan 2025 13:14:13 -0600 Subject: [PATCH 04/19] testing the mdbook deploy --- .github/workflows/docs.yml | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 3615ef26..9e7bdeed 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -48,7 +48,20 @@ jobs: with: path: 'docs/book' - deploy-page: + deploy-preview: + needs: generate-docs + if: github.event_name == 'pull_request' + environment: + name: pr-preview + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + timeout-minutes: 2 + steps: + - name: Deploy PR Preview + id: deployment + uses: actions/deploy-pages@v4 + + deploy-production: needs: generate-docs if: github.event_name == 'push' environment: From 41a6cd001c47ecd11153dd5efd960df292131a38 Mon Sep 17 00:00:00 2001 From: Khaja Omer Date: Fri, 17 Jan 2025 13:33:59 -0600 Subject: [PATCH 05/19] Update Makefile --- .gitignore | 2 ++ Makefile | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/.gitignore b/.gitignore index d23661ad..0e911385 100644 --- a/.gitignore +++ b/.gitignore @@ -39,3 +39,5 @@ coverage.txt junit.xml .DS_Store + +docs/book \ No newline at end of file diff --git a/Makefile b/Makefile index 42a96e2a..339eddcb 100644 --- a/Makefile +++ b/Makefile @@ -25,6 +25,8 @@ LINODE_REGION ?= us-lax LINODE_OS ?= linode/ubuntu22.04 KUBECONFIG_PATH ?= $(CURDIR)/test-cluster-kubeconfig.yaml MGMT_KUBECONFIG_PATH ?= $(CURDIR)/mgmt-cluster-kubeconfig.yaml +MDBOOK_DEV_HOST ?= 0.0.0.0 +MDBOOK_DEV_PORT ?= 3000 # if the $DEVBOX_PACKAGES_DIR env variable exists that means we are within a devbox shell and can safely # use devbox's bin for our tools @@ -131,6 +133,10 @@ run-debug: build --kubeconfig=${KUBECONFIG} \ --linodego-debug +.PHONY: docs +docs: + @cd docs && mdbook serve -n $(MDBOOK_DEV_HOST) -p $(MDBOOK_DEV_PORT) + ##################################################################### # E2E Test Setup ##################################################################### From ddd2049f67db7c347a1a31d370765884edac6404 Mon Sep 17 00:00:00 2001 From: Khaja Omer Date: Fri, 17 Jan 2025 13:44:37 -0600 Subject: [PATCH 06/19] GHA: do not run CI flow if we are just updating docs. Its unneccessary --- .github/filters.yml | 8 +++++++- .github/workflows/ci.yml | 18 +++++++++++++++++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/.github/filters.yml b/.github/filters.yml index e307b278..b09d8360 100644 --- a/.github/filters.yml +++ b/.github/filters.yml @@ -1,3 +1,9 @@ # Any file that is not a doc *.md file src: - - "!**/**.md" + - "!docs/**" + - "!**/*.md" + - "!*.md" + - "!.github/CONTRIBUTING.md" + - "!.github/PULL_REQUEST_TEMPLATE.md" + - "!**/README.md" + - "!**/CHANGELOG.md" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 78394bd1..114dc568 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -4,7 +4,23 @@ on: push: branches: - main - pull_request: null + paths-ignore: + - 'docs/**' + - '**/*.md' + - '*.md' + - '.github/CONTRIBUTING.md' + - '.github/PULL_REQUEST_TEMPLATE.md' + - '**/README.md' + - '**/CHANGELOG.md' + pull_request: + paths-ignore: + - 'docs/**' + - '**/*.md' + - '*.md' + - '.github/CONTRIBUTING.md' + - '.github/PULL_REQUEST_TEMPLATE.md' + - '**/README.md' + - '**/CHANGELOG.md' permissions: contents: read From bce787eac8da597ecb411304247ba56bca143abf Mon Sep 17 00:00:00 2001 From: Khaja Omer Date: Fri, 17 Jan 2025 13:46:09 -0600 Subject: [PATCH 07/19] address comments --- README.md | 2 +- docs/src/getting-started/requirements.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ef57e2a6..fe7417c0 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ The Linode Cloud Controller Manager (CCM) integrates Kubernetes with Linode's in ## Requirements -- Kubernetes 1.9+ +- Kubernetes 1.22+ - Kubelets, controller-manager, and apiserver with `--cloud-provider=external` - Linode APIv4 Token - Supported Linode region diff --git a/docs/src/getting-started/requirements.md b/docs/src/getting-started/requirements.md index 4458d777..e72f305f 100644 --- a/docs/src/getting-started/requirements.md +++ b/docs/src/getting-started/requirements.md @@ -3,7 +3,7 @@ ## Kubernetes Cluster Requirements ### Version Compatibility -- Kubernetes version 1.9 or higher +- Kubernetes version 1.22 or higher - Kubernetes cluster running on Linode infrastructure ### Kubernetes Components Configuration From 37267165eb2cd0b88fa6db770c2648d67a7205fc Mon Sep 17 00:00:00 2001 From: Khaja Omer Date: Fri, 17 Jan 2025 13:53:09 -0600 Subject: [PATCH 08/19] fix typo --- docs/src/examples/basic.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/examples/basic.md b/docs/src/examples/basic.md index c4da3a09..d15ff070 100644 --- a/docs/src/examples/basic.md +++ b/docs/src/examples/basic.md @@ -98,7 +98,7 @@ spec: containerPort: 80 protocol: TCP - name: https - containerPort: 80 + containerPort: 443 protocol: TCP ``` From b12952db4da6e35ff8b4ac88a281375145a226b5 Mon Sep 17 00:00:00 2001 From: Khaja Omer Date: Fri, 17 Jan 2025 14:15:47 -0600 Subject: [PATCH 09/19] Removing the temp PR gh-pages push --- .github/workflows/docs.yml | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 9e7bdeed..72ae2b87 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -48,19 +48,6 @@ jobs: with: path: 'docs/book' - deploy-preview: - needs: generate-docs - if: github.event_name == 'pull_request' - environment: - name: pr-preview - url: ${{ steps.deployment.outputs.page_url }} - runs-on: ubuntu-latest - timeout-minutes: 2 - steps: - - name: Deploy PR Preview - id: deployment - uses: actions/deploy-pages@v4 - deploy-production: needs: generate-docs if: github.event_name == 'push' From f25bc66ffb0c805a98535d40b494b7173c1792ae Mon Sep 17 00:00:00 2001 From: Khaja Omer Date: Fri, 17 Jan 2025 14:18:42 -0600 Subject: [PATCH 10/19] Add rate limits link --- docs/src/configuration/environment.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/configuration/environment.md b/docs/src/configuration/environment.md index 6622bb76..15ad47f0 100644 --- a/docs/src/configuration/environment.md +++ b/docs/src/configuration/environment.md @@ -56,7 +56,7 @@ spec: ### Cache Settings - Adjust cache TTL based on cluster size and update frequency - Monitor memory usage when modifying cache settings -- Consider API rate limits when decreasing TTL +- Consider API rate limits when decreasing TTL (see [Linode API Rate Limits](@https://techdocs.akamai.com/linode-api/reference/rate-limits)) ### API Settings - Increase timeout for slower network conditions From 855b4079956285d641feba450313c29f879bc77d Mon Sep 17 00:00:00 2001 From: Khaja Omer Date: Fri, 17 Jan 2025 14:20:34 -0600 Subject: [PATCH 11/19] Update based on PR comment --- docs/src/configuration/nodes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/configuration/nodes.md b/docs/src/configuration/nodes.md index 6d8ed298..b69ec395 100644 --- a/docs/src/configuration/nodes.md +++ b/docs/src/configuration/nodes.md @@ -43,7 +43,7 @@ metadata: ``` #### VPC Configuration -When using [Linode VPC](https://www.linode.com/docs/products/networking/vpc/), you may need to manually configure the node's InternalIP: +When using CCM with [Linode VPC](https://www.linode.com/docs/products/networking/vpc/), internal ip will be set to VPC ip. To use a different ip-address as internal ip, you may need to manually configure the node's InternalIP: ```yaml apiVersion: v1 kind: Node From 4eb0f62ad81b465a2739f7935d67ff67c366b4e0 Mon Sep 17 00:00:00 2001 From: Khaja Omer Date: Tue, 21 Jan 2025 14:09:35 -0600 Subject: [PATCH 12/19] Address a commet --- docs/src/configuration/nodes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/configuration/nodes.md b/docs/src/configuration/nodes.md index b69ec395..62e308ef 100644 --- a/docs/src/configuration/nodes.md +++ b/docs/src/configuration/nodes.md @@ -56,7 +56,7 @@ metadata: ## Node Networking ### Private Network Requirements -- NodeBalancers require nodes to have private IP addresses +- NodeBalancers require nodes to have linode specific [private IP addresses](https://techdocs.akamai.com/cloud-computing/docs/managing-ip-addresses-on-a-compute-instance#types-of-ip-addresses) - Private IPs must be configured in the Linode Cloud Manager or via the API - The CCM will use private IPs for inter-node communication From 5e1fe994f04ee080a7297538030c7ef0f2e4cec4 Mon Sep 17 00:00:00 2001 From: Khaja Omer Date: Wed, 22 Jan 2025 09:45:29 -0600 Subject: [PATCH 13/19] Remove mdbook implementation --- .github/workflows/docs.yml | 62 ---------- Makefile | 4 - README.md | 110 ++++++++++++------ docs/book.toml | 31 ----- docs/{src => }/configuration/README.md | 0 docs/{src => }/configuration/annotations.md | 0 docs/{src => }/configuration/environment.md | 0 docs/{src => }/configuration/firewall.md | 0 docs/{src => }/configuration/loadbalancer.md | 0 docs/{src => }/configuration/nodes.md | 0 docs/{src => }/configuration/routes.md | 0 .../configuration/session-affinity.md | 0 docs/{src => }/development/README.md | 0 docs/{src => }/examples/README.md | 0 docs/{src => }/examples/advanced.md | 0 docs/{src => }/examples/basic.md | 0 docs/{src => }/getting-started/README.md | 0 .../getting-started/helm-installation.md | 0 .../{src => }/getting-started/installation.md | 0 .../getting-started/manual-installation.md | 0 docs/{src => }/getting-started/overview.md | 0 .../{src => }/getting-started/requirements.md | 2 + .../getting-started/troubleshooting.md | 0 .../{src => }/getting-started/verification.md | 0 docs/src/SUMMARY.md | 33 ------ docs/src/help.md | 23 ---- docs/src/introduction.md | 61 ---------- 27 files changed, 77 insertions(+), 249 deletions(-) delete mode 100644 .github/workflows/docs.yml delete mode 100644 docs/book.toml rename docs/{src => }/configuration/README.md (100%) rename docs/{src => }/configuration/annotations.md (100%) rename docs/{src => }/configuration/environment.md (100%) rename docs/{src => }/configuration/firewall.md (100%) rename docs/{src => }/configuration/loadbalancer.md (100%) rename docs/{src => }/configuration/nodes.md (100%) rename docs/{src => }/configuration/routes.md (100%) rename docs/{src => }/configuration/session-affinity.md (100%) rename docs/{src => }/development/README.md (100%) rename docs/{src => }/examples/README.md (100%) rename docs/{src => }/examples/advanced.md (100%) rename docs/{src => }/examples/basic.md (100%) rename docs/{src => }/getting-started/README.md (100%) rename docs/{src => }/getting-started/helm-installation.md (100%) rename docs/{src => }/getting-started/installation.md (100%) rename docs/{src => }/getting-started/manual-installation.md (100%) rename docs/{src => }/getting-started/overview.md (100%) rename docs/{src => }/getting-started/requirements.md (93%) rename docs/{src => }/getting-started/troubleshooting.md (100%) rename docs/{src => }/getting-started/verification.md (100%) delete mode 100644 docs/src/SUMMARY.md delete mode 100644 docs/src/help.md delete mode 100644 docs/src/introduction.md diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml deleted file mode 100644 index 72ae2b87..00000000 --- a/.github/workflows/docs.yml +++ /dev/null @@ -1,62 +0,0 @@ -name: Deploy Documentation - -on: - push: - branches: - - master - paths: - - 'README.md' - - 'docs/**' - - '.github/workflows/docs.yml' - pull_request: - paths: - - 'docs/**' - - '.github/workflows/docs.yml' - -permissions: - contents: read - pages: write # to deploy to Pages - id-token: write # to verify the deployment originates from an appropriate source - -jobs: - generate-docs: - runs-on: ubuntu-latest - container: docker.io/node:20-bullseye-slim - timeout-minutes: 2 - steps: - - uses: actions/checkout@v4 - - - name: Setup mdBook - run: | - apt-get update - apt-get install curl -y - mkdir mdbook - curl -sSL https://github.com/rust-lang/mdbook/releases/download/v0.4.37/mdbook-v0.4.37-x86_64-unknown-linux-gnu.tar.gz | tar -xz --directory=./mdbook - curl -sSL https://github.com/tommilligan/mdbook-admonish/releases/download/v1.15.0/mdbook-admonish-v1.15.0-x86_64-unknown-linux-gnu.tar.gz | tar -xz --directory=./mdbook - echo `pwd`/mdbook >> $GITHUB_PATH - - - name: Build with mdBook - run: | - cd docs - mdbook build - - - name: Setup Pages - uses: actions/configure-pages@v5 - - - name: Upload artifact - uses: actions/upload-pages-artifact@v3 - with: - path: 'docs/book' - - deploy-production: - needs: generate-docs - if: github.event_name == 'push' - environment: - name: github-pages - url: ${{ steps.deployment.outputs.page_url }} - runs-on: ubuntu-latest - timeout-minutes: 2 - steps: - - name: Deploy to GitHub Pages - id: deployment - uses: actions/deploy-pages@v4 \ No newline at end of file diff --git a/Makefile b/Makefile index 339eddcb..7c806748 100644 --- a/Makefile +++ b/Makefile @@ -133,10 +133,6 @@ run-debug: build --kubeconfig=${KUBECONFIG} \ --linodego-debug -.PHONY: docs -docs: - @cd docs && mdbook serve -n $(MDBOOK_DEV_HOST) -p $(MDBOOK_DEV_PORT) - ##################################################################### # E2E Test Setup ##################################################################### diff --git a/README.md b/README.md index fe7417c0..9d8a521a 100644 --- a/README.md +++ b/README.md @@ -8,20 +8,44 @@ ## Overview -The Linode Cloud Controller Manager (CCM) integrates Kubernetes with Linode's infrastructure services. It implements cloud-specific control loops essential for cluster operation. For detailed documentation, see the [docs](docs/src/introduction.md). +The Linode Cloud Controller Manager (CCM) is a crucial component that integrates Kubernetes with Linode's infrastructure services. It implements the cloud-controller-manager binary, running cloud-specific control loops that are essential for cluster operation. -### Core Components - -- **Node Controller**: Manages node lifecycle and configuration -- **Service Controller**: Handles LoadBalancer implementations using NodeBalancers -- **Route Controller**: Configures network routes for pod communication +A Cloud Controller Manager (CCM) is a Kubernetes control plane component that embeds cloud-specific control logic. It lets you link your cluster to your cloud provider's API, separating out the components that interact with that cloud platform from components that only interact with your cluster. -### Key Features +### Core Components -- Automatic LoadBalancer provisioning using Linode NodeBalancers -- Node management and lifecycle operations -- Network route configuration for VPC environments -- Firewall management for services +#### Node Controller +- Initializes node configuration with Linode-specific information + - Sets node addresses (public/private IPs) + - Labels nodes with region/zone information + - Configures node hostnames +- Monitors node health and lifecycle + - Detects node termination + - Updates node status + - Manages node cleanup + +#### Service Controller +- Manages LoadBalancer service implementations using Linode NodeBalancers + - Creates and configures NodeBalancers + - Updates backend pools + - Manages SSL/TLS certificates +- Handles automatic provisioning and configuration + - Health checks + - Session affinity + - Protocol configuration +- Supports multiple load balancing approaches + - Traditional NodeBalancer deployment + - BGP-based IP sharing for cost optimization + - Custom firewall rules and security configurations + +#### Route Controller +- Manages VPC and private network integration + - Configures routes for pod CIDR ranges + - Handles cross-node pod communication +- Ensures proper network connectivity + - Sets up pod-to-pod networking + - Manages network policies + - Configures network routes for optimal communication ## Requirements @@ -30,37 +54,53 @@ The Linode Cloud Controller Manager (CCM) integrates Kubernetes with Linode's in - Linode APIv4 Token - Supported Linode region -## Quick Links +## Documentation + +### Quick Start +- [Getting Started Guide](docs/getting-started/README.md) - Start here for installation and setup + - [Overview](docs/getting-started/overview.md) - Learn about CCM basics + - [Requirements](docs/getting-started/requirements.md) - Check prerequisites + - [Installation](docs/getting-started/installation.md) - Install the CCM + - [Helm Installation](docs/getting-started/helm-installation.md) - Install using Helm + - [Manual Installation](docs/getting-started/manual-installation.md) - Manual setup instructions + - [Verification](docs/getting-started/verification.md) - Verify your installation + - [Troubleshooting](docs/getting-started/troubleshooting.md) - Common issues and solutions + +### Configuration +- [Configuration Guide](docs/configuration/README.md) - Detailed configuration options + - [LoadBalancer Services](docs/configuration/loadbalancer.md) + - [Service Annotations](docs/configuration/annotations.md) + - [Node Configuration](docs/configuration/nodes.md) + - [Environment Variables](docs/configuration/environment.md) + - [Firewall Setup](docs/configuration/firewall.md) + - [Route Configuration](docs/configuration/routes.md) + - [Session Affinity](docs/configuration/session-affinity.md) + +### Examples and Development +- [Examples](docs/examples/README.md) - Real-world usage examples + - [Basic Services](docs/examples/basic.md) + - [Advanced Configuration](docs/examples/advanced.md) +- [Development Guide](docs/development/README.md) - Contributing to CCM -- [Getting Started](docs/src/getting-started/README.md) - - [Overview](docs/src/getting-started/overview.md) - - [Requirements](docs/src/getting-started/requirements.md) - - [Installation](docs/src/getting-started/installation.md) - - [Helm Installation](docs/src/getting-started/helm-installation.md) - - [Manual Installation](docs/src/getting-started/manual-installation.md) - - [Verification](docs/src/getting-started/verification.md) - - [Troubleshooting](docs/src/getting-started/troubleshooting.md) +## Getting Help -- [Configuration Guide](docs/src/configuration/README.md) - - [LoadBalancer Services](docs/src/configuration/loadbalancer.md) - - [Service Annotations](docs/src/configuration/annotations.md) - - [Node Configuration](docs/src/configuration/nodes.md) - - [Environment Variables](docs/src/configuration/environment.md) - - [Firewall Setup](docs/src/configuration/firewall.md) - - [Route Configuration](docs/src/configuration/routes.md) - - [Session Affinity](docs/src/configuration/session-affinity.md) +### Community Support -- [Examples](docs/src/examples/README.md) - - [Basic Services](docs/src/examples/basic.md) - - [Advanced Configuration](docs/src/examples/advanced.md) +For general help or discussion, join us in #linode on the [Kubernetes Slack](https://kubernetes.slack.com/messages/CD4B15LUR/details/). -- [Development Guide](docs/src/development/README.md) +To sign up for Kubernetes Slack, use the [Kubernetes Slack inviter](http://slack.kubernetes.io/). -- [Getting Help](docs/src/help.md) +### Issue Tracking -## Getting Help +If you've found a bug or want to request a feature: +- Check the [GitHub Issues](https://github.com/linode/linode-cloud-controller-manager/issues) +- Submit a [Pull Request](https://github.com/linode/linode-cloud-controller-manager/pulls) + +### Additional Resources -For support and development discussions, join us in #linode on the [Kubernetes Slack](https://kubernetes.slack.com/messages/CD4B15LUR/details/). To sign up, use the [Kubernetes Slack inviter](http://slack.kubernetes.io/). +- [Official Linode Documentation](https://www.linode.com/docs/) +- [Kubernetes Cloud Controller Manager Documentation](https://kubernetes.io/docs/tasks/administer-cluster/running-cloud-controller/) +- [API Documentation](https://www.linode.com/docs/api) ## Contributing diff --git a/docs/book.toml b/docs/book.toml deleted file mode 100644 index 74d9798b..00000000 --- a/docs/book.toml +++ /dev/null @@ -1,31 +0,0 @@ -[book] -authors = ["Linode"] -language = "en" -multilingual = false -src = "src" -title = "Linode Cloud Controller Manager" -description = "Documentation for the Kubernetes Cloud Controller Manager for Linode" - -[output.html] -git-repository-url = "https://github.com/linode/linode-cloud-controller-manager" -site-url = "/linode-cloud-controller-manager/" -edit-url-template = "https://github.com/linode/linode-cloud-controller-manager/edit/master/docs/{path}" - -[preprocessor] - -[preprocessor.admonish] -command = "mdbook-admonish" -assets_version = "3.0.2" # do not edit: managed by `mdbook-admonish install` - -[output.html.playground] -editable = true -line-numbers = true - -[output.html.search] -limit-results = 20 -use-boolean-and = true -boost-title = 2 -boost-hierarchy = 2 -boost-paragraph = 1 -expand = true -heading-split-level = 2 diff --git a/docs/src/configuration/README.md b/docs/configuration/README.md similarity index 100% rename from docs/src/configuration/README.md rename to docs/configuration/README.md diff --git a/docs/src/configuration/annotations.md b/docs/configuration/annotations.md similarity index 100% rename from docs/src/configuration/annotations.md rename to docs/configuration/annotations.md diff --git a/docs/src/configuration/environment.md b/docs/configuration/environment.md similarity index 100% rename from docs/src/configuration/environment.md rename to docs/configuration/environment.md diff --git a/docs/src/configuration/firewall.md b/docs/configuration/firewall.md similarity index 100% rename from docs/src/configuration/firewall.md rename to docs/configuration/firewall.md diff --git a/docs/src/configuration/loadbalancer.md b/docs/configuration/loadbalancer.md similarity index 100% rename from docs/src/configuration/loadbalancer.md rename to docs/configuration/loadbalancer.md diff --git a/docs/src/configuration/nodes.md b/docs/configuration/nodes.md similarity index 100% rename from docs/src/configuration/nodes.md rename to docs/configuration/nodes.md diff --git a/docs/src/configuration/routes.md b/docs/configuration/routes.md similarity index 100% rename from docs/src/configuration/routes.md rename to docs/configuration/routes.md diff --git a/docs/src/configuration/session-affinity.md b/docs/configuration/session-affinity.md similarity index 100% rename from docs/src/configuration/session-affinity.md rename to docs/configuration/session-affinity.md diff --git a/docs/src/development/README.md b/docs/development/README.md similarity index 100% rename from docs/src/development/README.md rename to docs/development/README.md diff --git a/docs/src/examples/README.md b/docs/examples/README.md similarity index 100% rename from docs/src/examples/README.md rename to docs/examples/README.md diff --git a/docs/src/examples/advanced.md b/docs/examples/advanced.md similarity index 100% rename from docs/src/examples/advanced.md rename to docs/examples/advanced.md diff --git a/docs/src/examples/basic.md b/docs/examples/basic.md similarity index 100% rename from docs/src/examples/basic.md rename to docs/examples/basic.md diff --git a/docs/src/getting-started/README.md b/docs/getting-started/README.md similarity index 100% rename from docs/src/getting-started/README.md rename to docs/getting-started/README.md diff --git a/docs/src/getting-started/helm-installation.md b/docs/getting-started/helm-installation.md similarity index 100% rename from docs/src/getting-started/helm-installation.md rename to docs/getting-started/helm-installation.md diff --git a/docs/src/getting-started/installation.md b/docs/getting-started/installation.md similarity index 100% rename from docs/src/getting-started/installation.md rename to docs/getting-started/installation.md diff --git a/docs/src/getting-started/manual-installation.md b/docs/getting-started/manual-installation.md similarity index 100% rename from docs/src/getting-started/manual-installation.md rename to docs/getting-started/manual-installation.md diff --git a/docs/src/getting-started/overview.md b/docs/getting-started/overview.md similarity index 100% rename from docs/src/getting-started/overview.md rename to docs/getting-started/overview.md diff --git a/docs/src/getting-started/requirements.md b/docs/getting-started/requirements.md similarity index 93% rename from docs/src/getting-started/requirements.md rename to docs/getting-started/requirements.md index e72f305f..c9a4e396 100644 --- a/docs/src/getting-started/requirements.md +++ b/docs/getting-started/requirements.md @@ -1,5 +1,7 @@ # Requirements +Before installing the Linode Cloud Controller Manager, ensure your environment meets the following requirements. + ## Kubernetes Cluster Requirements ### Version Compatibility diff --git a/docs/src/getting-started/troubleshooting.md b/docs/getting-started/troubleshooting.md similarity index 100% rename from docs/src/getting-started/troubleshooting.md rename to docs/getting-started/troubleshooting.md diff --git a/docs/src/getting-started/verification.md b/docs/getting-started/verification.md similarity index 100% rename from docs/src/getting-started/verification.md rename to docs/getting-started/verification.md diff --git a/docs/src/SUMMARY.md b/docs/src/SUMMARY.md deleted file mode 100644 index e654c593..00000000 --- a/docs/src/SUMMARY.md +++ /dev/null @@ -1,33 +0,0 @@ -# Summary - -[Introduction](./introduction.md) - -# User Guide - -- [Getting Started](./getting-started/README.md) - - [Overview](./getting-started/overview.md) - - [Requirements](./getting-started/requirements.md) - - [Installation](./getting-started/installation.md) - - [Helm Installation](./getting-started/helm-installation.md) - - [Manual Installation](./getting-started/manual-installation.md) - - [Verification](./getting-started/verification.md) - - [Troubleshooting](./getting-started/troubleshooting.md) - -- [Configuration](./configuration/README.md) - - [LoadBalancer Services](./configuration/loadbalancer.md) - - [Service Annotations](./configuration/annotations.md) - - [Node Configuration](./configuration/nodes.md) - - [Environment Variables](./configuration/environment.md) - - [Firewall Setup](./configuration/firewall.md) - - [Route Configuration](./configuration/routes.md) - - [Session Affinity](./configuration/session-affinity.md) - -- [Examples](./examples/README.md) - - [Basic Services](./examples/basic.md) - - [Advanced Configuration](./examples/advanced.md) - -- [Development Guide](./development/README.md) - ---- - -[Getting Help](./help.md) diff --git a/docs/src/help.md b/docs/src/help.md deleted file mode 100644 index 2ced1b39..00000000 --- a/docs/src/help.md +++ /dev/null @@ -1,23 +0,0 @@ -# Getting Help - -## Community Support - -For general help or discussion, join us in #linode on the [Kubernetes Slack](https://kubernetes.slack.com/messages/CD4B15LUR/details/). - -To sign up for Kubernetes Slack, use the [Kubernetes Slack inviter](http://slack.kubernetes.io/). - -## Issue Tracking - -If you've found a bug or want to request a feature: -- Check the [GitHub Issues](https://github.com/linode/linode-cloud-controller-manager/issues) -- Submit a [Pull Request](https://github.com/linode/linode-cloud-controller-manager/pulls) - -## Documentation - -- [Official Linode Documentation](https://www.linode.com/docs/) -- [Kubernetes Cloud Controller Manager Documentation](https://kubernetes.io/docs/tasks/administer-cluster/running-cloud-controller/) -- [API Documentation](https://www.linode.com/docs/api) - -## Social Media - -Follow [@linode](https://twitter.com/linode) on Twitter for updates and announcements. diff --git a/docs/src/introduction.md b/docs/src/introduction.md deleted file mode 100644 index 20c7c00c..00000000 --- a/docs/src/introduction.md +++ /dev/null @@ -1,61 +0,0 @@ -# Introduction - -The Linode Cloud Controller Manager (CCM) is a crucial component that integrates Kubernetes with Linode's infrastructure services. It implements the cloud-controller-manager binary, running cloud-specific control loops that are essential for cluster operation. - -## What is a Cloud Controller Manager? - -A Cloud Controller Manager (CCM) is a Kubernetes control plane component that embeds cloud-specific control logic. It lets you link your cluster to your cloud provider's API, separating out the components that interact with that cloud platform from components that only interact with your cluster. - -## Core Functions - -### Node Controller -The Node Controller is responsible for: -- Initializing node configuration with Linode-specific information - - Setting node addresses (public/private IPs) - - Labeling nodes with region/zone information - - Configuring node hostnames -- Monitoring node health and lifecycle - - Detecting node termination - - Updating node status - - Managing node cleanup - -### Service Controller -The Service Controller manages the lifecycle of cloud load balancers: -- Manages LoadBalancer service implementations using Linode NodeBalancers - - Creates and configures NodeBalancers - - Updates backend pools - - Manages SSL/TLS certificates -- Handles automatic provisioning and configuration - - Health checks - - Session affinity - - Protocol configuration -- Supports multiple load balancing approaches - - Traditional NodeBalancer deployment - - BGP-based IP sharing for cost optimization - - Custom firewall rules and security configurations - -### Route Controller -The Route Controller configures networking for pod communication: -- Manages VPC and private network integration - - Configures routes for pod CIDR ranges - - Handles cross-node pod communication -- Ensures proper network connectivity - - Sets up pod-to-pod networking - - Manages network policies - - Configures network routes for optimal communication - -## Architecture - -### Component Integration -The CCM runs as a Kubernetes deployment in your cluster and: -- Watches for changes to Service and Node resources -- Interacts with Linode's API to manage infrastructure -- Maintains state synchronization between Kubernetes and Linode resources -- Operates independently of core Kubernetes controllers - -## Next Steps - -- Review the [Requirements](getting-started/requirements.md) for using the CCM -- Follow the [Installation Guide](getting-started/installation.md) to set up the CCM -- Learn about [Configuration Options](configuration/README.md) -- See [Examples](examples/README.md) of common use cases \ No newline at end of file From 71e7de270da11d646072096887c2adeaab8cb248 Mon Sep 17 00:00:00 2001 From: Khaja Omer Date: Wed, 22 Jan 2025 10:16:18 -0600 Subject: [PATCH 14/19] clean up --- .github/filters.yml | 6 ------ .github/workflows/ci.yml | 18 +----------------- Makefile | 2 -- devbox.json | 4 +--- 4 files changed, 2 insertions(+), 28 deletions(-) diff --git a/.github/filters.yml b/.github/filters.yml index b09d8360..a790d19d 100644 --- a/.github/filters.yml +++ b/.github/filters.yml @@ -1,9 +1,3 @@ # Any file that is not a doc *.md file src: - - "!docs/**" - "!**/*.md" - - "!*.md" - - "!.github/CONTRIBUTING.md" - - "!.github/PULL_REQUEST_TEMPLATE.md" - - "!**/README.md" - - "!**/CHANGELOG.md" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 114dc568..8b13ae12 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -4,23 +4,7 @@ on: push: branches: - main - paths-ignore: - - 'docs/**' - - '**/*.md' - - '*.md' - - '.github/CONTRIBUTING.md' - - '.github/PULL_REQUEST_TEMPLATE.md' - - '**/README.md' - - '**/CHANGELOG.md' - pull_request: - paths-ignore: - - 'docs/**' - - '**/*.md' - - '*.md' - - '.github/CONTRIBUTING.md' - - '.github/PULL_REQUEST_TEMPLATE.md' - - '**/README.md' - - '**/CHANGELOG.md' + pull_request: null permissions: contents: read diff --git a/Makefile b/Makefile index 7c806748..42a96e2a 100644 --- a/Makefile +++ b/Makefile @@ -25,8 +25,6 @@ LINODE_REGION ?= us-lax LINODE_OS ?= linode/ubuntu22.04 KUBECONFIG_PATH ?= $(CURDIR)/test-cluster-kubeconfig.yaml MGMT_KUBECONFIG_PATH ?= $(CURDIR)/mgmt-cluster-kubeconfig.yaml -MDBOOK_DEV_HOST ?= 0.0.0.0 -MDBOOK_DEV_PORT ?= 3000 # if the $DEVBOX_PACKAGES_DIR env variable exists that means we are within a devbox shell and can safely # use devbox's bin for our tools diff --git a/devbox.json b/devbox.json index da13e240..ff3d96fa 100644 --- a/devbox.json +++ b/devbox.json @@ -12,9 +12,7 @@ "kustomize@latest", "kyverno-chainsaw@latest", "mockgen@latest", - "yq-go@latest", - "mdbook@latest", - "mdbook-admonish@latest" + "yq-go@latest" ], "shell": { "init_hook": [ From 41c8727c152dd5f9fa0de3c5874244d075b6778a Mon Sep 17 00:00:00 2001 From: Khaja Omer Date: Wed, 22 Jan 2025 10:29:20 -0600 Subject: [PATCH 15/19] address comments --- .github/workflows/ci.yml | 2 +- devbox.lock | 96 ---------------------------------------- 2 files changed, 1 insertion(+), 97 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8b13ae12..78394bd1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -4,7 +4,7 @@ on: push: branches: - main - pull_request: null + pull_request: null permissions: contents: read diff --git a/devbox.lock b/devbox.lock index 2e32398e..cb767c68 100644 --- a/devbox.lock +++ b/devbox.lock @@ -633,102 +633,6 @@ } } }, - "mdbook-admonish@latest": { - "last_modified": "2024-12-23T21:10:33Z", - "resolved": "github:NixOS/nixpkgs/de1864217bfa9b5845f465e771e0ecb48b30e02d#mdbook-admonish", - "source": "devbox-search", - "version": "1.18.0", - "systems": { - "aarch64-darwin": { - "outputs": [ - { - "name": "out", - "path": "/nix/store/hrmry6gcyxq576yyvvv2vsl05sycmi1y-mdbook-admonish-1.18.0", - "default": true - } - ], - "store_path": "/nix/store/hrmry6gcyxq576yyvvv2vsl05sycmi1y-mdbook-admonish-1.18.0" - }, - "aarch64-linux": { - "outputs": [ - { - "name": "out", - "path": "/nix/store/fg3pqy6459lx562bq6gdf8hdhf2wh0h5-mdbook-admonish-1.18.0", - "default": true - } - ], - "store_path": "/nix/store/fg3pqy6459lx562bq6gdf8hdhf2wh0h5-mdbook-admonish-1.18.0" - }, - "x86_64-darwin": { - "outputs": [ - { - "name": "out", - "path": "/nix/store/0vddbww043c8w1d4sfk2wpb5ljyq45x7-mdbook-admonish-1.18.0", - "default": true - } - ], - "store_path": "/nix/store/0vddbww043c8w1d4sfk2wpb5ljyq45x7-mdbook-admonish-1.18.0" - }, - "x86_64-linux": { - "outputs": [ - { - "name": "out", - "path": "/nix/store/hs7z4g4v6acd9km5kaw7gibxdpcdijbj-mdbook-admonish-1.18.0", - "default": true - } - ], - "store_path": "/nix/store/hs7z4g4v6acd9km5kaw7gibxdpcdijbj-mdbook-admonish-1.18.0" - } - } - }, - "mdbook@latest": { - "last_modified": "2024-12-23T21:10:33Z", - "resolved": "github:NixOS/nixpkgs/de1864217bfa9b5845f465e771e0ecb48b30e02d#mdbook", - "source": "devbox-search", - "version": "0.4.43", - "systems": { - "aarch64-darwin": { - "outputs": [ - { - "name": "out", - "path": "/nix/store/5yibli76rfaq70cv0lyasndswbf3hjw8-mdbook-0.4.43", - "default": true - } - ], - "store_path": "/nix/store/5yibli76rfaq70cv0lyasndswbf3hjw8-mdbook-0.4.43" - }, - "aarch64-linux": { - "outputs": [ - { - "name": "out", - "path": "/nix/store/130z9032izdwxdishjkvjrdfacyd1fkq-mdbook-0.4.43", - "default": true - } - ], - "store_path": "/nix/store/130z9032izdwxdishjkvjrdfacyd1fkq-mdbook-0.4.43" - }, - "x86_64-darwin": { - "outputs": [ - { - "name": "out", - "path": "/nix/store/4lcz6mj30f40k08q2s2phdfnydmkk8w2-mdbook-0.4.43", - "default": true - } - ], - "store_path": "/nix/store/4lcz6mj30f40k08q2s2phdfnydmkk8w2-mdbook-0.4.43" - }, - "x86_64-linux": { - "outputs": [ - { - "name": "out", - "path": "/nix/store/izq6ww5isq00l6l02i4yhad2ykn45djm-mdbook-0.4.43", - "default": true - } - ], - "store_path": "/nix/store/izq6ww5isq00l6l02i4yhad2ykn45djm-mdbook-0.4.43" - } - } - }, "mockgen@latest": { "last_modified": "2024-11-03T14:18:04Z", "resolved": "github:NixOS/nixpkgs/4ae2e647537bcdbb82265469442713d066675275#mockgen", From a1ff9601781178354b9f9a5e4d967032a2454159 Mon Sep 17 00:00:00 2001 From: Khaja Omer Date: Wed, 22 Jan 2025 10:30:06 -0600 Subject: [PATCH 16/19] clean up --- .gitignore | 2 -- 1 file changed, 2 deletions(-) diff --git a/.gitignore b/.gitignore index 0e911385..d23661ad 100644 --- a/.gitignore +++ b/.gitignore @@ -39,5 +39,3 @@ coverage.txt junit.xml .DS_Store - -docs/book \ No newline at end of file From 0db7edb73e08dc12c3302d619644beca530df370 Mon Sep 17 00:00:00 2001 From: Khaja Omer Date: Wed, 22 Jan 2025 10:44:30 -0600 Subject: [PATCH 17/19] Switch the pages rendered to GFM --- _config.yaml | 1 + 1 file changed, 1 insertion(+) create mode 100644 _config.yaml diff --git a/_config.yaml b/_config.yaml new file mode 100644 index 00000000..88b63ad6 --- /dev/null +++ b/_config.yaml @@ -0,0 +1 @@ +markdown: GFM From 98a84942ed3e2588c523f38e33ade0041bf0d023 Mon Sep 17 00:00:00 2001 From: Khaja Omer Date: Wed, 22 Jan 2025 12:59:19 -0600 Subject: [PATCH 18/19] Address comments --- docs/configuration/routes.md | 2 +- docs/development/README.md | 8 +------- docs/getting-started/manual-installation.md | 2 +- docs/getting-started/requirements.md | 2 ++ 4 files changed, 5 insertions(+), 9 deletions(-) diff --git a/docs/configuration/routes.md b/docs/configuration/routes.md index 29dfbbc7..0f8b8a26 100644 --- a/docs/configuration/routes.md +++ b/docs/configuration/routes.md @@ -67,7 +67,7 @@ The Route Controller: ## Best Practices ### CIDR Planning -- Ensure pod CIDR range doesn't overlap with VPC ranges +- Ensure pod CIDR range doesn't overlap with node's VPC ip-address - Plan for future cluster growth - Document CIDR allocations diff --git a/docs/development/README.md b/docs/development/README.md index 33b977a9..552c1fb6 100644 --- a/docs/development/README.md +++ b/docs/development/README.md @@ -4,7 +4,7 @@ The Linode Cloud Controller Manager development requires: - A fairly up-to-date GNU tools environment -- Go 1.8.3 or higher +- Go 1.23 or higher ### Setting Up Development Environment @@ -37,12 +37,6 @@ go get github.com/linode/linode-cloud-controller-manager cd $(go env GOPATH)/src/github.com/linode/linode-cloud-controller-manager ``` -### Install Development Tools -To install various dev tools for the Cloud Controller Manager: -```bash -./hack/builddeps.sh -``` - ### Building the Project #### Build Binary diff --git a/docs/getting-started/manual-installation.md b/docs/getting-started/manual-installation.md index 79954f53..d8f8ef9a 100644 --- a/docs/getting-started/manual-installation.md +++ b/docs/getting-started/manual-installation.md @@ -9,7 +9,7 @@ 1. Generate the manifest: ```bash -./deploy/generate-manifest.sh $LINODE_API_TOKEN us-east +./deploy/generate-manifest.sh $LINODE_API_TOKEN $REGION ``` 2. Review the generated manifest: diff --git a/docs/getting-started/requirements.md b/docs/getting-started/requirements.md index c9a4e396..463d4bc3 100644 --- a/docs/getting-started/requirements.md +++ b/docs/getting-started/requirements.md @@ -23,6 +23,8 @@ You need a Linode APIv4 Personal Access Token with the following scopes: - IPs - Read/Write - Volumes - Read/Write - Firewalls - Read/Write (if using firewall features) +- VPCs - Read/Write (if using VPC features) +- VLANs - Read/Write (if using VLAN features) To create a token: 1. Log into the [Linode Cloud Manager](https://cloud.linode.com) From 2870b71b6f13e29dd4f8882b58635aa254c1422b Mon Sep 17 00:00:00 2001 From: Khaja Omer Date: Wed, 22 Jan 2025 13:23:34 -0600 Subject: [PATCH 19/19] address comments --- docs/configuration/annotations.md | 13 +++++++------ docs/getting-started/helm-installation.md | 2 +- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/docs/configuration/annotations.md b/docs/configuration/annotations.md index 2739c472..185627a3 100644 --- a/docs/configuration/annotations.md +++ b/docs/configuration/annotations.md @@ -38,12 +38,13 @@ For implementation details, see: The `port-*` annotation allows per-port configuration, encoded in JSON. For detailed examples, see [LoadBalancer SSL/TLS Setup](loadbalancer.md#ssltls-configuration). ```yaml -service.beta.kubernetes.io/linode-loadbalancer-port-443: | - { - "protocol": "https", - "tls-secret-name": "my-tls-secret", - "proxy-protocol": "v2" - } +metadata: + annotations: + service.beta.kubernetes.io/linode-loadbalancer-port-443: | + "protocol": "https", + "tls-secret-name": "my-tls-secret", + "proxy-protocol": "v2" + } ``` Available port options: diff --git a/docs/getting-started/helm-installation.md b/docs/getting-started/helm-installation.md index 96debd58..979bd868 100644 --- a/docs/getting-started/helm-installation.md +++ b/docs/getting-started/helm-installation.md @@ -25,7 +25,7 @@ routeController: clusterCIDR: "10.0.0.0/8" configureCloudRoutes: true -# Optional: Configure shared IP load balancing +# Optional: Configure shared IP load balancing instead of NodeBalancers (requires Cilium CNI and BGP Control Plane enabled) sharedIPLoadBalancing: loadBalancerType: cilium-bgp bgpNodeSelector: cilium-bgp-peering=true