diff --git a/.gitignore b/.gitignore index dc1bf5d6..7e95a9be 100644 --- a/.gitignore +++ b/.gitignore @@ -47,3 +47,7 @@ junit.xml # Local dev setup .envrc + +# Jekyll local preview +_site/ +.sass-cache/ diff --git a/Makefile b/Makefile index 52ea3d43..37044bc9 100644 --- a/Makefile +++ b/Makefile @@ -44,6 +44,15 @@ SUBNET_KUBECONFIG_PATH ?= $(CURDIR)/subnet-testing-kubeconfig.yaml MGMT_KUBECONFIG_PATH ?= $(CURDIR)/mgmt-cluster-kubeconfig.yaml IPV6_KUBECONFIG_PATH ?= $(CURDIR)/ipv6-kubeconfig.yaml +##################################################################### +# Local Docs Preview Setup +##################################################################### + +DOCS_IMAGE := jekyll/jekyll:pages +DOCS_CONTAINER := lccm-docs +DOCS_PORT := 4000 +DOCS_LIVERELOAD_PORT := 35729 + export GO111MODULE=on .PHONY: all @@ -260,3 +269,19 @@ helm-template: @helm template foo deploy/chart --set apiToken="apiToken",region="us-east" > /dev/null @helm template foo deploy/chart --set secretRef.apiTokenRef="apiToken",secretRef.name="api",secretRef.regionRef="us-east" > /dev/null +.PHONY: serve-docs +serve-docs: +# Serve the documentation site locally with live reload + echo "Serving the docs on http://localhost:$(DOCS_PORT), press ctrl-c to stop" + docker run --rm --interactive --tty --name $(DOCS_CONTAINER) \ + --publish $(DOCS_PORT):4000 \ + --publish $(DOCS_LIVERELOAD_PORT):35729 \ + --volume "$(shell pwd):/srv/jekyll" \ + $(DOCS_IMAGE) \ + jekyll serve --host 0.0.0.0 --livereload --force-polling + +.PHONY: build-docs +build-docs: +# Build the documentation site the way GitHub Pages does + docker run --rm --volume "$(shell pwd):/srv/jekyll" $(DOCS_IMAGE) jekyll build + diff --git a/_config.yaml b/_config.yaml deleted file mode 100644 index 88b63ad6..00000000 --- a/_config.yaml +++ /dev/null @@ -1 +0,0 @@ -markdown: GFM diff --git a/_config.yml b/_config.yml new file mode 100644 index 00000000..4c0435d5 --- /dev/null +++ b/_config.yml @@ -0,0 +1,39 @@ +remote_theme: just-the-docs/just-the-docs + +# GitHub Pages turns the plugins below on by default; a local `jekyll build` +# does not, which is why pages that rely on them (markdown without front +# matter, titles taken from the first heading) are missing from the local nav +# unless they are listed here. Listing them changes nothing in production. +plugins: + - jekyll-remote-theme + - jekyll-default-layout + - jekyll-optional-front-matter + - jekyll-readme-index + - jekyll-relative-links + - jekyll-titles-from-headings + +title: Kubernetes Cloud Controller Manager for Linode +search_enabled: true +heading_anchors: true +color_scheme: dark + + +# Everything that is not documentation. Without this the site carries the whole +# Go tree, and CHANGELOG.md is published as a stray page nothing links to. +exclude: + - bin/ + - CHANGELOG.md + - cloud/ + - codecov.yml + - coverage.out + - deploy/ + - e2e/ + - examples/ + - go.mod + - go.sum + - hack/ + - main.go + - Makefile + - mise.toml + - renovate.json5 + - sentry/ diff --git a/_includes/head_custom.html b/_includes/head_custom.html new file mode 100644 index 00000000..76f1dd00 --- /dev/null +++ b/_includes/head_custom.html @@ -0,0 +1,100 @@ +{%- comment -%} + Color scheme preference: light, dark, or follow the OS ("system"). The script + runs in the document head so the stored choice is applied before the page + paints. The toggle button itself is in header_custom.html. + + Two constraints on the script below: + + 1. Block comments only. The theme renders pages through + _layouts/vendor/compress.html, which strips newlines, so a `//` comment + would swallow the rest of the script. + 2. Never write a literal `head` element tag in it. Jekyll's `--livereload` + server injects its reload snippet at that string, and the snippet's closing + script tag would end the script early, dumping the rest of the code onto + the page as text. + + Long notes like this one belong in a Liquid comment: Jekyll strips it at build + time, so it never ships to the browser with every page. +{%- endcomment -%} + diff --git a/_includes/header_custom.html b/_includes/header_custom.html new file mode 100644 index 00000000..625120e2 --- /dev/null +++ b/_includes/header_custom.html @@ -0,0 +1,66 @@ +
+ + +
+ +{%- comment -%} + Cycles the color scheme preference (System, Light, Dark) and shows the matching + icon. Block comments only in the script below, and no literal element tags: see + the notes in head_custom.html. +{%- endcomment -%} + diff --git a/_sass/custom/custom.scss b/_sass/custom/custom.scss new file mode 100644 index 00000000..18015f3c --- /dev/null +++ b/_sass/custom/custom.scss @@ -0,0 +1,62 @@ +// Overrides just-the-docs' (empty) custom stylesheet. Imported last by the +// theme, so these rules win over the theme's own and are compiled into every +// color scheme. + +// The theme pins the sidebar header to a fixed height and centers the title in +// it, so a site title long enough to wrap (this one takes three lines) is +// clipped and spills out of the sidebar. Let the header grow to fit instead: +// .site-nav below it is `flex: 1 1 auto` with its own scrollbar, so it simply +// starts lower. The theme's own min-height still applies. +.site-header { + height: auto; + max-height: none; +} + +// Color scheme toggle, rendered by _includes/header_custom.html. An icon-only +// button styled from the theme's color variables, so it follows whichever +// scheme is active. +.theme-switcher { + display: flex; + align-items: center; + padding: $sp-2 $sp-4; +} + +.theme-switcher-btn { + display: flex; + align-items: center; + justify-content: center; + width: 2rem; + height: 2rem; + padding: 0; + color: $body-text-color; + cursor: pointer; + border-radius: $border-radius; + transition: color 150ms ease, background-color 150ms ease; + + &:hover { + // $feedback-color is what the theme uses for its own hover surfaces. + color: $link-color; + background-color: $feedback-color; + } + + &:focus-visible { + outline: 2px solid $link-color; + outline-offset: 1px; + } +} + +.theme-switcher-icon { + width: 1.125rem; + height: 1.125rem; + fill: none; + stroke: currentcolor; + stroke-width: 2; + stroke-linecap: round; + stroke-linejoin: round; + + // SVG elements are not HTML elements, so spell out what `hidden` means here + // rather than relying on the browser's rule for it. + &[hidden] { + display: none; + } +} diff --git a/docs/configuration/README.md b/docs/configuration/README.md index 3300d113..1ba869b8 100644 --- a/docs/configuration/README.md +++ b/docs/configuration/README.md @@ -1,3 +1,9 @@ +--- +layout: default +title: Configuration Guide +nav_order: 3 +--- + # 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. diff --git a/docs/configuration/annotations.md b/docs/configuration/annotations.md index bc07809d..14295601 100644 --- a/docs/configuration/annotations.md +++ b/docs/configuration/annotations.md @@ -1,3 +1,10 @@ +--- +layout: default +title: Service Annotations +parent: Configuration Guide +nav_order: 2 +--- + # Service Annotations ## Overview @@ -18,7 +25,7 @@ The keys and the values in [annotations must be strings](https://kubernetes.io/d ### 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`, `udp`, `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 | diff --git a/docs/configuration/environment.md b/docs/configuration/environment.md index 91056871..625e8110 100644 --- a/docs/configuration/environment.md +++ b/docs/configuration/environment.md @@ -1,3 +1,10 @@ +--- +layout: default +title: Environment Variables and Flags +parent: Configuration Guide +nav_order: 4 +--- + # Environment Variables and Flags ## Overview @@ -96,7 +103,7 @@ spec: - Adjust cache TTL based on cluster size and update frequency - Monitor memory usage when modifying cache settings -- Consider API rate limits when decreasing TTL (see [Linode API Rate Limits](@https://techdocs.akamai.com/linode-api/reference/rate-limits)) +- Consider API rate limits when decreasing TTL (see [Linode API Rate Limits](https://techdocs.akamai.com/linode-api/reference/rate-limits)) ### API Settings diff --git a/docs/configuration/firewall.md b/docs/configuration/firewall.md index c5d011d4..01ca85c6 100644 --- a/docs/configuration/firewall.md +++ b/docs/configuration/firewall.md @@ -1,8 +1,16 @@ +--- +layout: default +title: Firewall Setup +parent: Configuration Guide +nav_order: 5 +--- + # 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) @@ -13,6 +21,7 @@ The CCM provides two methods for securing NodeBalancers with firewalls: 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 @@ -29,6 +38,7 @@ metadata: ``` #### Deny List Configuration + ```yaml metadata: annotations: @@ -42,6 +52,7 @@ metadata: ``` ### 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 @@ -61,6 +72,7 @@ metadata: ``` ### Management + - User maintains full control over firewall rules - Firewall persists after service deletion - Manual updates required for rule changes @@ -78,6 +90,7 @@ metadata: - 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/configuration/loadbalancer.md b/docs/configuration/loadbalancer.md index 7a166f02..6df2a1f0 100644 --- a/docs/configuration/loadbalancer.md +++ b/docs/configuration/loadbalancer.md @@ -1,3 +1,10 @@ +--- +layout: default +title: LoadBalancer Services +parent: Configuration Guide +nav_order: 1 +--- + # LoadBalancer Services Configuration ## Overview diff --git a/docs/configuration/nodeipam.md b/docs/configuration/nodeipam.md index 5b0e3920..1ae09a78 100644 --- a/docs/configuration/nodeipam.md +++ b/docs/configuration/nodeipam.md @@ -1,3 +1,10 @@ +--- +layout: default +title: Node IPAM using CCM +parent: Configuration Guide +nav_order: 8 +--- + # Node IPAM using CCM ## Overview @@ -21,6 +28,7 @@ Note: Make sure node IPAM allocation is disabled in kube-controller-manager to avoid both controllers competing to assign CIDRs to nodes. To make sure its disabled, check and make sure kube-controller-manager is not started with `--allocate-node-cidrs` flag. ## Allocated subnet size + By default, CCM allocates /24 subnet for IPv4 addresses and /112 for IPv6 addresses to nodes. For IPv6, CCM derives /112 PodCIDRs from the node's /64 IPv6 range using the stable mnemonic subprefix `:0:c::/112`. For IPv6 CIDR allocation using CCM, Linodes should have IPv6 ranges configured on their interfaces. If one wants different subnet range, it can be configured by using `--node-cidr-mask-size-ipv4` and `--node-cidr-mask-size-ipv6` flags. ```yaml @@ -37,4 +45,5 @@ spec: ``` ## Disabling ipv6 ipam allocation + If one wants to just use ipv4 node ipam allocation for their nodes, they can start CCM with `--disable-ipv6-node-cidr-allocation=true` which disables ipv6 range allocation to nodes. diff --git a/docs/configuration/nodes.md b/docs/configuration/nodes.md index 62e308ef..1253c72c 100644 --- a/docs/configuration/nodes.md +++ b/docs/configuration/nodes.md @@ -1,3 +1,10 @@ +--- +layout: default +title: Node Configuration +parent: Configuration Guide +nav_order: 3 +--- + # Node Configuration ## Overview @@ -9,15 +16,19 @@ The Node Controller in CCM manages node-specific configurations and lifecycle op 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 @@ -33,6 +44,7 @@ All node annotations must be prefixed with: `node.k8s.linode.com/` ### Use Cases #### Private Network Configuration + ```yaml apiVersion: v1 kind: Node @@ -43,7 +55,9 @@ metadata: ``` #### VPC Configuration + 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 @@ -56,12 +70,15 @@ metadata: ## Node Networking ### Private Network Requirements + - 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 ### 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 @@ -72,23 +89,27 @@ 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/) diff --git a/docs/configuration/routes.md b/docs/configuration/routes.md index 0f8b8a26..9d37b574 100644 --- a/docs/configuration/routes.md +++ b/docs/configuration/routes.md @@ -1,3 +1,10 @@ +--- +layout: default +title: Route Configuration +parent: Configuration Guide +nav_order: 6 +--- + # Route Configuration ## Overview @@ -15,6 +22,7 @@ The Route Controller manages network routes for pod communication in VPC environ ### 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 @@ -23,6 +31,7 @@ routeController: ``` 2. Via command line flags in CCM deployment: + ```yaml spec: template: @@ -46,6 +55,7 @@ spec: ### 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 @@ -67,11 +77,13 @@ The Route Controller: ## Best Practices ### CIDR Planning + - Ensure pod CIDR range doesn't overlap with node's VPC ip-address - Plan for future cluster growth - Document CIDR allocations ### VPC Configuration + - Use clear, descriptive VPC names - Configure proper VPC security settings - Ensure proper API permissions diff --git a/docs/configuration/session-affinity.md b/docs/configuration/session-affinity.md index 78683c90..9f209bdd 100644 --- a/docs/configuration/session-affinity.md +++ b/docs/configuration/session-affinity.md @@ -1,3 +1,9 @@ +--- +layout: default +title: Session Affinity +parent: Configuration Guide +nav_order: 7 +--- # Session Affinity ## Overview @@ -9,6 +15,7 @@ Session affinity (also known as sticky sessions) ensures that requests from the ### Basic Setup Enable session affinity by setting `service.spec.sessionAffinity` to `ClientIP`: + ```yaml apiVersion: v1 kind: Service @@ -27,6 +34,7 @@ spec: ### Setting Timeout Configure the maximum session sticky time using `sessionAffinityConfig`: + ```yaml apiVersion: v1 kind: Service @@ -43,10 +51,12 @@ spec: ## 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) diff --git a/docs/development/README.md b/docs/development/README.md index 73814c92..51ea30e4 100644 --- a/docs/development/README.md +++ b/docs/development/README.md @@ -1,3 +1,9 @@ +--- +layout: default +title: Development Guide +nav_order: 5 +--- + # Development Guide ## Prerequisites diff --git a/docs/examples/README.md b/docs/examples/README.md index 1372afa8..d59e5579 100644 --- a/docs/examples/README.md +++ b/docs/examples/README.md @@ -1,3 +1,8 @@ +--- +layout: default +title: Examples +nav_order: 4 +--- # Examples This section provides working examples of common CCM configurations. Each example includes a complete service and deployment configuration. diff --git a/docs/examples/advanced.md b/docs/examples/advanced.md index 101acbc2..288ab6e7 100644 --- a/docs/examples/advanced.md +++ b/docs/examples/advanced.md @@ -1,3 +1,9 @@ +--- +layout: default +title: Advanced Configuration +parent: Examples +nav_order: 2 +--- # Advanced Configuration ## Custom Health Checks diff --git a/docs/examples/basic.md b/docs/examples/basic.md index 84c8b3cb..3b262abe 100644 --- a/docs/examples/basic.md +++ b/docs/examples/basic.md @@ -1,3 +1,9 @@ +--- +layout: default +title: Basic Services +parent: Examples +nav_order: 1 +--- # Basic Services ## HTTP LoadBalancer @@ -144,5 +150,6 @@ spec: ``` For more configuration options, see: + - [Service Annotations](../configuration/annotations.md) - [LoadBalancer Configuration](../configuration/loadbalancer.md) diff --git a/docs/getting-started/README.md b/docs/getting-started/README.md index 9850e6d3..65394ab1 100644 --- a/docs/getting-started/README.md +++ b/docs/getting-started/README.md @@ -1,12 +1,20 @@ +--- +layout: default +title: Getting Started +nav_order: 2 +--- + # 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 diff --git a/docs/getting-started/helm-installation.md b/docs/getting-started/helm-installation.md index 2ac94e72..3d829ee3 100644 --- a/docs/getting-started/helm-installation.md +++ b/docs/getting-started/helm-installation.md @@ -1,3 +1,10 @@ +--- +layout: default +title: Helm Installation +parent: Installation +nav_order: 1 +--- + # Helm Installation ## Prerequisites diff --git a/docs/getting-started/installation.md b/docs/getting-started/installation.md index ea47f6df..cd187df7 100644 --- a/docs/getting-started/installation.md +++ b/docs/getting-started/installation.md @@ -1,3 +1,10 @@ +--- +layout: default +title: Installation +parent: Getting Started +nav_order: 3 +--- + # Installation The CCM can be installed using either Helm (recommended) or by manually applying manifests. Choose the method that best suits your needs: @@ -5,16 +12,19 @@ The CCM can be installed using either Helm (recommended) or by manually applying ## 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/getting-started/manual-installation.md b/docs/getting-started/manual-installation.md index 7c4af09e..fb5ee722 100644 --- a/docs/getting-started/manual-installation.md +++ b/docs/getting-started/manual-installation.md @@ -1,6 +1,14 @@ +--- +layout: default +title: Manual Installation +parent: Installation +nav_order: 2 +--- + # Manual Installation ## Prerequisites + - kubectl configured to access your cluster - Linode API token - Target region identified @@ -8,18 +16,22 @@ ## Installation Steps 1. Generate the manifest: + ```bash ./deploy/generate-manifest.sh $LINODE_API_TOKEN $REGION ``` 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 ``` @@ -27,7 +39,9 @@ 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 @@ -37,7 +51,9 @@ env: ``` ### Resource Limits + Adjust compute resources as needed: + ```yaml resources: requests: @@ -61,6 +77,7 @@ Linode API calls can be monitored using `ccm_linode_client_requests_total` metri ## Uninstalling To remove the CCM: + ```bash kubectl delete -f ccm-linode.yaml ``` diff --git a/docs/getting-started/overview.md b/docs/getting-started/overview.md index eeb805ca..37069369 100644 --- a/docs/getting-started/overview.md +++ b/docs/getting-started/overview.md @@ -1,3 +1,10 @@ +--- +layout: default +title: Overview +parent: Getting Started +nav_order: 1 +--- + # Overview The Linode Cloud Controller Manager provides several key features that enable a fully supported Kubernetes experience on Linode infrastructure. diff --git a/docs/getting-started/requirements.md b/docs/getting-started/requirements.md index 463d4bc3..b9fe2f8c 100644 --- a/docs/getting-started/requirements.md +++ b/docs/getting-started/requirements.md @@ -1,3 +1,10 @@ +--- +layout: default +title: Requirements +parent: Getting Started +nav_order: 2 +--- + # Requirements Before installing the Linode Cloud Controller Manager, ensure your environment meets the following requirements. @@ -5,11 +12,14 @@ Before installing the Linode Cloud Controller Manager, ensure your environment m ## Kubernetes Cluster Requirements ### Version Compatibility + - Kubernetes version 1.22 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 @@ -17,7 +27,9 @@ The following Kubernetes components must be started with the `--cloud-provider=e ## 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 @@ -27,6 +39,7 @@ You need a Linode APIv4 Personal Access Token with the following scopes: - VLANs - Read/Write (if using VLAN 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 @@ -35,20 +48,25 @@ To create a token: 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/getting-started/troubleshooting.md b/docs/getting-started/troubleshooting.md index 5e613f8d..30389210 100644 --- a/docs/getting-started/troubleshooting.md +++ b/docs/getting-started/troubleshooting.md @@ -1,3 +1,10 @@ +--- +layout: default +title: Troubleshooting +parent: Getting Started +nav_order: 5 +--- + # Troubleshooting ## Common Issues and Solutions @@ -5,23 +12,28 @@ ### 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 @@ -29,17 +41,21 @@ Common causes: ### 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 @@ -47,17 +63,21 @@ Verify: ### 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 @@ -65,6 +85,7 @@ Check: ## 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}' @@ -77,7 +98,9 @@ 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 @@ -87,6 +110,7 @@ env: ## 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: diff --git a/docs/getting-started/verification.md b/docs/getting-started/verification.md index 22e7c046..0692c54a 100644 --- a/docs/getting-started/verification.md +++ b/docs/getting-started/verification.md @@ -1,3 +1,10 @@ +--- +layout: default +title: Verification +parent: Getting Started +nav_order: 4 +--- + # Verification After installing the CCM, follow these steps to verify it's working correctly. @@ -5,17 +12,20 @@ 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: -``` + +```text 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 ``` @@ -25,11 +35,13 @@ 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 @@ -37,6 +49,7 @@ Look for: ## Test LoadBalancer Service 1. Create a test service: + ```yaml apiVersion: v1 kind: Service @@ -51,6 +64,7 @@ spec: ``` 2. Verify NodeBalancer creation: + ```bash kubectl get svc test-lb ``` @@ -58,6 +72,7 @@ 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/index.md b/index.md new file mode 100644 index 00000000..7b5b2c1d --- /dev/null +++ b/index.md @@ -0,0 +1,15 @@ +--- +layout: default +title: Kubernetes Cloud Controller Manager for Linode +nav_order: 1 +--- + +{%- capture readme -%} +{%- include_relative README.md -%} +{%- endcapture -%} + +{{ readme + | replace: ".md)", ".html)" + | replace: ".md#", ".html#" + | replace: "](.github/CONTRIBUTING.html)", "]()" +}} diff --git a/mise.toml b/mise.toml index cbda06d8..8b9b2a66 100644 --- a/mise.toml +++ b/mise.toml @@ -117,3 +117,11 @@ run = "make run-debug" [tasks.test] description = "Run unit tests" run = "make test" + +[tasks.serve-docs] +description = "Serve the documentation site locally with live reload" +run = "make serve-docs" + +[tasks.build-docs] +description = "Build the documentation site the way GitHub Pages does" +run = "make build-docs"