diff --git a/kubernetes-addons/istio/README.md b/kubernetes-addons/istio/README.md new file mode 100644 index 000000000..b3c583550 --- /dev/null +++ b/kubernetes-addons/istio/README.md @@ -0,0 +1,81 @@ +# OPEA with Istio + +## Introduction + +Istio service mesh provides many features including 1) [mTLS between Kubernetes pods](#enforce-mtls-between-opea-pods) and 2) [TLS connection to Kubernetes ingress](#create-istio-gateway-with-tls-and-virtual-service). + +This document describes how to enable the above two Istio features with OPEA applications. We will use the new Istio ambient mode (a.k.a. sidecar-less mode) + +## Deployment + +In this document we use the following components: + +- OPEA ChatQnA as an example application +- Istio (in ambient mode) with ingress gateway using TLS and strict mTLS for ChatQnA application +- Cert-Manager for issuing TLS certificate to Istio ingress gateway + +### Deploy Istio, ChatQnA and Cert-Manager + +In this document we use [helmfile](https://helmfile.readthedocs.io/en/latest/) to do the deployment: + +```bash +helmfile apply +``` + +> [!NOTE] +> The above deployment uses `model-volume` Persistent Volume Claim (PVC) for storing the ChatQnA models so ensure such PVC and corresponding PV are available in your cluster. + +### Install Kubernetes Gateway CRDs + +Note that the Kubernetes Gateway API CRDs do not come installed by default on most Kubernetes clusters, so make sure they are installed before using the Gateway API: + +```bash +kubectl get crd gateways.gateway.networking.k8s.io &> /dev/null || \ + { kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.2.0/standard-install.yaml; } +``` + +## Create Istio gateway with TLS and virtual service + +Istio gateway terminates the external TLS connections. Istio virtual service routes the traffic to services. In this example, all the traffic that matches host '\*.intel.com' and path prefix '/' is routed to 'chatqna-nginx.chatqna' service. The Istio gateway needs certificate which is created via 'cert-manager' Issuer and Certificate. + +Create Istio gateway and virtual service: + +```bash +kubectl apply -f istio-gateway-and-virtual-service.yaml +``` + +Create cert-manager Issuer and Certificate: + +```bash +kubectl apply -f istio-gateway-ca-and-cert.yaml +``` + +Now you are able to connect to OPEA engine services via TLS. You can test the connection with the command: + +```bash +# Get Istio ingress loadbalancer (LB) address. If you don't use LB, you can set use `kubectl port-forward` command. +IP=$(kubectl get svc -n istio-ingress -ojsonpath="{.items[0].status.loadBalancer.ingress[0].ip}") +# Resolve IP to DNS. DNS needs to match the dnsNames in istio-gateway certificate. +curl -ks https://${DNS}/v1/chatqna -H "Content-Type: application/json" -d '{"messages": "What is the TLS?"}' +``` + +> [!NOTE] > `https` scheme (TLS) is used and in curl we ignore the server's self signed certificate with `-k` option. + +## Enforce mTLS between OPEA pods + +This task ensures the OPEA workloads only communicate using mutual TLS. + +```bash +kubectl apply -f istio-mtls-strict.yaml -n chatqna +``` + +## Cleanup + +Once you are done with the example you can cleanup your environment with the following commands: + +```bash +kubectl delete -f istio-gateway-and-virtual-service.yaml +kubectl delete -f istio-gateway-ca-and-cert.yaml +kubectl apply -f istio-mtls-strict.yaml -n chatqna +helmfile delete +``` diff --git a/kubernetes-addons/istio/helmfile.yaml b/kubernetes-addons/istio/helmfile.yaml new file mode 100644 index 000000000..9fb3f8ab7 --- /dev/null +++ b/kubernetes-addons/istio/helmfile.yaml @@ -0,0 +1,65 @@ +# Copyright (C) 2025 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +repositories: +- name: opea + url: ghcr.io/opea-project/charts + oci: true +- name: jetstack + url: https://charts.jetstack.io +- name: istio + url: https://istio-release.storage.googleapis.com/charts + oci: false + +releases: +- name: chatqna + chart: opea/chatqna + namespace: chatqna + version: 1.1.0 + values: + - global: + HUGGINGFACEHUB_API_TOKEN: {{ env "HF_TOKEN" }} + modelUsePVC: model-volume + https_proxy: {{ env "https_proxy" }} + +- name: cert-manager + chart: jetstack/cert-manager + namespace: cert-manager + version: "v1.16.1" + set: + - name: crds.enabled + value: true + +- name: istio-base + chart: istio/base + namespace: istio-system + set: + - name: defaultRevision + value: default + +- name: istiod + chart: istio/istiod + namespace: istio-system + wait: true + set: + - name: profile + value: ambient + +- name: istio-cni + chart: istio/cni + namespace: istio-system + wait: true + set: + - name: profile + value: ambient + +- name: ztunnel + chart: istio/ztunnel + namespace: istio-system + wait: true + +- name: istio-ingress + chart: istio/gateway + namespace: istio-ingress + needs: + - istio-system/istiod diff --git a/kubernetes-addons/istio/istio-gateway-and-virtual-service.yaml b/kubernetes-addons/istio/istio-gateway-and-virtual-service.yaml new file mode 100644 index 000000000..08bd49aaf --- /dev/null +++ b/kubernetes-addons/istio/istio-gateway-and-virtual-service.yaml @@ -0,0 +1,45 @@ +# Copyright (C) 2025 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +apiVersion: networking.istio.io/v1 +kind: Gateway +metadata: + name: opea-gateway +spec: + selector: + app: istio-ingress + servers: + - port: + number: 80 + name: http + protocol: HTTP + hosts: + - "*" + tls: + httpsRedirect: true # sends 301 redirect for http requests + - port: + number: 443 + name: https + protocol: HTTPS + hosts: + - "*.intel.com" + tls: + mode: SIMPLE + credentialName: istio-gateway +--- +apiVersion: networking.istio.io/v1 +kind: VirtualService +metadata: + name: opea +spec: + gateways: + - opea-gateway + hosts: + - "*" + http: + - match: + - uri: + prefix: / + route: + - destination: + host: chatqna-nginx.chatqna.svc.cluster.local diff --git a/kubernetes-addons/istio/istio-gateway-ca-and-cert.yaml b/kubernetes-addons/istio/istio-gateway-ca-and-cert.yaml new file mode 100644 index 000000000..0d8050870 --- /dev/null +++ b/kubernetes-addons/istio/istio-gateway-ca-and-cert.yaml @@ -0,0 +1,25 @@ +# Copyright (C) 2025 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: ca-issuer + namespace: istio-ingress +spec: + selfSigned: {} +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: istio-gateway + namespace: istio-ingress # ceritificate must be in the same namespace as istio ingress gw +spec: + commonName: "Istio ingress for OPEA services" + dnsNames: + - "*.intel.com" # adjust to your environment + issuerRef: + group: cert-manager.io + kind: Issuer + name: ca-issuer + secretName: istio-gateway diff --git a/kubernetes-addons/istio/istio-mtls-strict.yaml b/kubernetes-addons/istio/istio-mtls-strict.yaml new file mode 100644 index 000000000..27cfc8064 --- /dev/null +++ b/kubernetes-addons/istio/istio-mtls-strict.yaml @@ -0,0 +1,10 @@ +# Copyright (C) 2025 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +apiVersion: security.istio.io/v1 +kind: PeerAuthentication +metadata: + name: default +spec: + mtls: + mode: STRICT