diff --git a/blog/2026-02-19-typesense30docscraper.md b/blog/2026-02-19-typesense30docscraper.md index 5c318c3..a79ddb1 100644 --- a/blog/2026-02-19-typesense30docscraper.md +++ b/blog/2026-02-19-typesense30docscraper.md @@ -27,3 +27,5 @@ TyKO `0.3.7` is the first version tested with Typesense 30.x+, therefore is the **Any earlier versions combinations might lead to undefined behavior and/or potential index corruption.** ::: + + diff --git a/blog/2026-02-27-release-0-4-0-rc.1.md b/blog/2026-02-27-release-0-4-0-rc.1.md new file mode 100644 index 0000000..b4a7dcf --- /dev/null +++ b/blog/2026-02-27-release-0-4-0-rc.1.md @@ -0,0 +1,17 @@ +--- +slug: release-0-4-0-rc-1 +title: 0.4.0-rc.1 +authors: [tykobot] +tags: [release] +--- + +## What's Changed + +### 0.4.0-rc.1 + +* 219 upgrade operator sdk by @akyriako in https://github.com/akyriako/typesense-operator/pull/240 +* 183 add support for gateway api by @akyriako in https://github.com/akyriako/typesense-operator/pull/244 + +**Full Changelog**: https://github.com/akyriako/typesense-operator/compare/typesense-operator-0.3.8...typesense-operator-0.4.0-rc.1 + + diff --git a/docs/crds/examples.md b/docs/crds/examples.md index 2b00e33..0e53365 100644 --- a/docs/crds/examples.md +++ b/docs/crds/examples.md @@ -473,6 +473,52 @@ To expose your Typesense cluster via an `Ingress`, certain prerequisites must al ::: +## Gateway HttpRoutes + +```yaml +apiVersion: ts.opentelekomcloud.com/v1alpha1 +kind: TypesenseCluster +metadata: + name: tsc +spec: + image: typesense/typesense:30.1 + replicas: 3 + storage: + storageClassName: standard + enableCors: true + corsDomains: "https://docs.example.com" + httpRoutes: + - name: public + parentRef: + name: traefik-gateway + namespace: kube-system + hostnames: + - typesense.docs.example.com + - search.docs.example.com + enabled: true + - name: private + parentRef: + name: traefik-gateway + namespace: kube-system + section: web + hostnames: + - typesense-int.docs.example.com + enabled: true + referenceGrant: true +``` + +:::warning + +**The operator does not configure or manage Gateways. Gateway setup is intentionally left out of scope because it is highly platform-specific and tightly coupled to cluster networking, security, and organizational policies. All required Gateway resources must be provisioned and maintained in advance by your platform or cluster engineering team.** + +To expose your Typesense cluster via a `Gateway`, certain prerequisites must already be present in your Kubernetes cluster: + +☑️ You will need a gateway controller present (example is using [Traefik Gateway Controller](https://doc.traefik.io/traefik/reference/routing-configuration/kubernetes/gateway-api/)).
+☑️ You will need a `GatewayClass` and a `Gateway` configured.
+☑️ You will need [cert-manager](https://cert-manager.io/) present that takes care of the TLS certiicates.
+ +::: + ## Metrics ```yaml diff --git a/docs/crds/index.mdx b/docs/crds/index.mdx index b83318c..2e349db 100644 --- a/docs/crds/index.mdx +++ b/docs/crds/index.mdx @@ -40,7 +40,8 @@ Typesense Kubernetes Operator is controlling the lifecycle of multiple Typesense | podsInheritStatefulSetAnnotations | propagate all `StatefulSet` annotations to `Pods` | X | false | | serviceAnnotations | user-defined annotations | X | | | storage | check `StorageSpec` [below](#storagespec-optional) | | | -| ingress | check `IngressSpec` [below](#ingressspec-optional) | X | | +| ingress | check `IngressSpec` [below](#ingressspec-deprecated) | X | | +| httpRoutes | array of `HttpRouteSpec`; check [below](#httproutespec-optional) | X | | | scrapers | array of `DocSearchScraperSpec`; check [below](#docsearchscraperspec-optional) | X | | | metrics | check `MetricsSpec` [below](#metricsspec-optional) | X | | | healthcheck | check `HealthCheckSpec` [below](#healthcheckspec-optional) | X | | @@ -89,7 +90,28 @@ For more information about installing and configuring **JuiceFS** and **JuiceFS ::: -### IngressSpec (optional) +### IngressSpec (deprecated) + +:::warning + +As of **v0.4.0-rc.1**, following the events triggered by the Ingress NGINX retirement in March 2026 (see [here](https://www.kubernetes.dev/blog/2025/11/12/ingress-nginx-retirement/) the announcement of the Kubernetes SIG Network and the Security Response Committee), +Ingress API support is deprecated in favor of the more flexible and powerful Gateway API. + +Although the operator will continue to support `Ingress` resources for the foreseeable future without any breaking changes, +**no new features or maintainance updates will be made to the `Ingress` implementation**. + +For that reason, it is recommended to transition to use `HttpRoute` for new deployments or when updating existing ones. + +Additionally, bear in mind that the Kubernetes project itself recommends the following regarding Ingress API (exerpt from the [Kubernetes documentation/Ingress](https://kubernetes.io/docs/concepts/services-networking/ingress/)): + +"_The Kubernetes project recommends using Gateway instead of Ingress. The Ingress API has been frozen._ + +_This means that:_ + +_-The Ingress API is generally available, and is subject to the stability guarantees for generally available APIs. The Kubernetes project has no plans to remove Ingress from Kubernetes._ +_-The Ingress API is no longer being developed, and will have no further changes or updates made to it._" + +::: | Name | Description | Optional | Default | | ---------------------- | -------------------------------------------------------------------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | @@ -118,19 +140,57 @@ For more information about installing and configuring **JuiceFS** and **JuiceFS | volumeMounts | additional mounts in the container | X | | :::note -This feature makes use of the existence of [cert-manager](https://cert-manager.io/) in the cluster, but **does not** actively enforce it with an error. If no clusterIssuer is specified a valid certificate must be stored in a secret and the secret name must be provided in the tlsSecretName config. +1️⃣ This feature makes use of the existence of [cert-manager](https://cert-manager.io/) in the cluster, but **does not** actively enforce it with an error. If no clusterIssuer is specified a valid certificate must be stored in a secret and the secret name must be provided in the tlsSecretName config. If you are targeting [Open Telekom Cloud](https://www.open-telekom-cloud.com/en), you might be interested in provisioning additionally the designated DNS solver webhook for Open Telekom Cloud. You can find it [here](https://github.com/akyriako/cert-manager-webhook-opentelekomcloud). -::: -:::caution -Although in official Typesense documentation under _Production Best Practices_ -> _Configuration_ is stated: +2️⃣ Although in official Typesense documentation under _Production Best Practices_ -> _Configuration_ is stated: "_Typesense comes built-in with a high performance HTTP server that is used by likes of Fastly in their edge servers at scale. So Typesense can be directly exposed to incoming public-facing internet traffic, without the need to place it behind another web server like Nginx/Apache or your backend API._" It is highly recommended, from this operator's perspective, to always expose Typesense behind a reverse proxy (using the `referer` option). ::: +### HttpRouteSpec (optional) + +| Name | Description | Optional | Default | +| -------------- | -------------------------------------------------------------------------------------- | -------- | ------------------------ | +| name | name of the route | | | +| enabled | enable this route | X | true | +| parentRef | reference to the parent `Gateway`; check `GatewayParentRef` [below](#gatewayparentref) | | | +| hostnames | array of hostnames to match for this route | | | +| path | path to match for this route | X | / | +| pathType | interpretation of the path matching | X | `ImplementationSpecific` | +| labels | user-defined labels | X | | +| annotations | user-defined annotations | X | | +| referenceGrant | enable cross-namespace reference to the parent `Gateway` | X | false | + +:::warning + +1️⃣ **The operator does not configure or manage Gateway(s). A `Gateway` setup is intentionally left out of scope because it is highly platform-specific and tightly coupled to cluster networking, security, +and organizational policies. All required `Gateway` resources must be provisioned and maintained in advance by your platform or cluster engineering team.** + +To expose your Typesense cluster via a `Gateway`, certain prerequisites must already be present in your Kubernetes cluster: + +🚧 You will need: + +- a gateway controller present (example is using [Traefik Gateway Controller](https://doc.traefik.io/traefik/reference/routing-configuration/kubernetes/gateway-api/)).
+- a `GatewayClass` and a `Gateway` configured.
+- [cert-manager](https://cert-manager.io/) to be present that takes care of the TLS certiicates.
+ +2️⃣ Activating the `HttpRoute` confiruration will automatically deactivate/ignore the `Ingress` one if it exists, but the `Ingress` resource which might be present in the cluster +will not be automatically deleted. It can be safely deleted manually, if not needed anymore. + +::: + +#### GatewayParentRef + +| Name | Description | Optional | Default | +| ----------- | -------------------------------------------------------------- | -------- | ------- | +| name | name of the parent `Gateway` | | | +| namespace | namespace of the parent `Gateway` | | | +| sectionName | section of the parent `Gateway` to route to (e.g. "websecure") | X | | + ### DocSearchScraperSpec (optional) | Name | Description | Optional | Default | diff --git a/docusaurus.config.ts b/docusaurus.config.ts index 662c5dd..442e53b 100644 --- a/docusaurus.config.ts +++ b/docusaurus.config.ts @@ -1,5 +1,5 @@ -import {themes as prismThemes} from 'prism-react-renderer'; -import type {Config} from '@docusaurus/types'; +import { themes as prismThemes } from 'prism-react-renderer'; +import type { Config } from '@docusaurus/types'; import type * as Preset from '@docusaurus/preset-classic'; import type { Options as UmamiOptions } from '@dipakparmar/docusaurus-plugin-umami'; @@ -61,6 +61,8 @@ const config: Config = { onInlineTags: 'warn', onInlineAuthors: 'warn', onUntruncatedBlogPosts: 'warn', + blogSidebarTitle: 'All posts', + blogSidebarCount: 'ALL', }, theme: { customCss: './src/css/custom.css', @@ -85,13 +87,13 @@ const config: Config = { position: 'left', label: 'Docs', }, - {to: '/blog', label: 'Releases', position: 'left'}, + { to: '/blog', label: 'Releases', position: 'left' }, // { // type: 'docsVersionDropdown', // position: 'right' // }, - { - href: 'https://github.com/akyriako/typesense-operator', + { + href: 'https://github.com/akyriako/typesense-operator', position: 'right', className: 'navbar--github-link', "aria-label": 'GitHub', diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 77b42e0..a638a9d 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -3,7 +3,7 @@ import Layout from "@theme/Layout"; import Link from "@docusaurus/Link"; import useBaseUrl from '@docusaurus/useBaseUrl'; import useDocusaurusContext from "@docusaurus/useDocusaurusContext"; -import { BarChart3, Lock, HeartPulse, Rocket, CircleFadingArrowUp, Ship, Cable } from "lucide-react"; +import { BarChart3, Lock, HeartPulse, Rocket, CircleFadingArrowUp, Ship, Cable, HandPlatter, Archive } from "lucide-react"; export default function Home(): JSX.Element { const { siteConfig } = useDocusaurusContext(); @@ -33,7 +33,7 @@ export default function Home(): JSX.Element {

- Get Started -> + Get Started -{">"} GitHub @@ -112,7 +112,7 @@ export default function Home(): JSX.Element {

{s.desc}

- Learn more -> + Learn more -{">"} @@ -151,24 +151,24 @@ export default function Home(): JSX.Element { const features = [ { - title: "Self‑healing clusters", + title: "Self-healing clusters", desc: "Automated failover, quorum recovery, and raft re-evaluation keep your Typesense clusters healthy without any manual intervention.", icon: , }, { - title: "Zero‑downtime updates", - desc: "Rolling updates with safe orchestration ensure your clusters stay online while you upgrade or downgrade their Typesense version.", + title: "Zero-downtime updates", + desc: "Rolling updates with safe orchestration ensure you are always stay operational while you upgrade, downgrade or resize your Typesense clusters.", icon: , }, { - title: "Kubernetes‑native", - desc: "Built with Go & Operator SDK, following Kubernetes best‑practices. Extend TyKO to your needs if you wish.", - icon: , + title: "Batteries-included", + desc: "StatefulSets, ConfigMaps, Secrets, Services, PodMetrics, HttpRoutes and many more, all managed for you.", + icon: , }, { - title: "Batteries‑included", - desc: "Ingress, Services, StatefulSets, ConfigMaps, Secrets, PodMetrics and many more, all managed for you.", - icon: , + title: "Ingress & Gateway APIs support", + desc: "Expose Typesense securely using Kubernetes Ingress or the Gateway API. Integrates with Shared Gateways & TLS termination.", + icon: , }, { title: "Observability", @@ -177,8 +177,18 @@ const features = [ }, { title: "Production-ready", - desc: "Opinionated defaults for secure production‑ready clusters and sane resource limits.", - icon: , + desc: "Opinionated defaults for secure production-ready clusters and sane resource limits.", + icon: , + }, + { + title: "S3-compatible storage support", + desc: "Persist data on any S3-compatible object storage. Works with OBS, AWS S3, RustFS and many more for vendor-neutral storage.", + icon: , + }, + { + title: "Kubernetes-native", + desc: "Built with Go & Operator SDK, following Kubernetes best-practices. Extend TyKO to your needs if you wish.", + icon: , }, ] as const; @@ -190,7 +200,7 @@ const steps = [ }, { title: "Define your Cluster", - desc: "Apply a TypesenseCluster YAML with the version, sizing and storage type you need.", + desc: "Apply a single manifest with the version, size and storage you need.", href: "/docs/crds/crds-examples", }, {