istio-setup-on-kubernetes

set up istio from scratch

istio-setup-on-kubernetes

Introduction

In this guide, we will walk you through the process of setting up Istio on a Kubernetes cluster. Istio is a powerful service mesh that provides a uniform way to secure, connect, and observe microservices. By the end of this tutorial, you will have a fully functional Istio setup on your Kubernetes cluster.

Prerequisites

Before you begin, ensure you have the following:

  • A running Kubernetes cluster
  • kubectl command-line tool installed
  • helm package manager installed

Step-by-Step Guide

1. Verify Kubernetes Cluster

First, verify that your Kubernetes cluster is up and running:

kubectl cluster-info

2. Add Istio Helm Repository

Add the Istio Helm repository to your Helm configuration:

helm repo add istio https://istio-release.storage.googleapis.com/charts
helm repo list

3. Install Istio Control Plane

Install the Istio control plane using Helm:

helm install istiod istio/istiod -n istio-system --create-namespace --version 1.22.1

4. Deploy Istio Gateway

Create a namespace for Istio ingress gateways and install the Istio gateway:

kubectl create namespace istio-ingress
helm install istio-ingressgateway istio/gateway -n istio-ingress

5. Deploy Sample Application

Deploy the sample httpbin application:

kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.22/samples/httpbin/httpbin.yaml

6. Configure Gateway and Routes

Create and configure a Gateway resource and HTTPRoute for the httpbin service:

kubectl apply -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: httpbin-gateway
spec:
  gatewayClassName: istio
  listeners:
  - name: http
    hostname: "httpbin.example.com"
    port: 80
    protocol: HTTP
    allowedRoutes:
      namespaces:
        from: Same
EOF

kubectl apply -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: httpbin
spec:
  parentRefs:
  - name: httpbin-gateway
  hostnames: ["httpbin.example.com"]
  rules:
  - matches:
    - path:
        type: PathPrefix
        value: /status
    - path:
        type: PathPrefix
        value: /delay
    backendRefs:
    - name: httpbin
      port: 8000
EOF

7. Access the Application

Determine the ingress IP and ports, then access the httpbin service using curl:

export INGRESS_HOST=$(kubectl get gtw httpbin-gateway -o jsonpath='{.status.addresses[0].value}')
export INGRESS_PORT=$(kubectl get gtw httpbin-gateway -o jsonpath='{.spec.listeners[?(@.name=="http")].port}')

curl -s -I -HHost:httpbin.example.com "http://$INGRESS_HOST:$INGRESS_PORT/status/200"

8. Cleanup

To clean up the resources created in this tutorial:

helm delete istiod -n istio-system
helm delete istio-ingressgateway -n istio-ingress
kubectl delete httproute httpbin
kubectl delete gateway httpbin-gateway

Conclusion

Congratulations! You have successfully set up Istio on your Kubernetes cluster and deployed a sample application. For more information and advanced configurations, visit the Istio documentation.

kubectl cluster-info
Kubernetes control plane is running at https://******.technotipstoday.dev
CoreDNS is running at https://******.technotipstoday.dev/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.

helm repo add istio https://istio-release.storage.googleapis.com/charts
helm repo list

helm install istiod istio/istiod -n istio-system --create-namespace --version 1.22.1
NAME: istiod
LAST DEPLOYED: Sun Jun 16 01:23:44 2024
NAMESPACE: istio-system
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
"istiod" successfully installed!

To learn more about the release, try:
  $ helm status istiod -n istio-system
  $ helm get all istiod -n istio-system

Next steps:
  * Deploy a Gateway: https://istio.io/latest/docs/setup/additional-setup/gateway/
  * Try out our tasks to get started on common configurations:
    * https://istio.io/latest/docs/tasks/traffic-management
    * https://istio.io/latest/docs/tasks/security/
    * https://istio.io/latest/docs/tasks/policy-enforcement/
  * Review the list of actively supported releases, CVE publications and our hardening guide:
    * https://istio.io/latest/docs/releases/supported-releases/
    * https://istio.io/latest/news/security/
    * https://istio.io/latest/docs/ops/best-practices/security/

For further documentation see https://istio.io website

# create namespace for istio-ingressgateways
kubectl create namespace istio-ingress
# Install istio-gateway
helm install istio-ingressgateway istio/gateway -n istio-ingress

namespace/istio-ingress created
NAME: istio-ingressgateway
LAST DEPLOYED: Sun Jun 16 01:28:34 2024
NAMESPACE: istio-ingress
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
"istio-ingressgateway" successfully installed!

To learn more about the release, try:
  $ helm status istio-ingressgateway -n istio-ingress
  $ helm get all istio-ingressgateway -n istio-ingress

Next steps:
  * Deploy an HTTP Gateway: https://istio.io/latest/docs/tasks/traffic-management/ingress/ingress-control/
  * Deploy an HTTPS Gateway: https://istio.io/latest/docs/tasks/traffic-management/ingress/secure-ingress/

# kubectl apply -f samples/httpbin/httpbin.yaml
kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.22/samples/httpbin/httpbin.yaml

# https://istio.io/latest/docs/tasks/traffic-management/ingress/ingress-control/

kubectl get crd gateways.gateway.networking.k8s.io &> /dev/null || \
  { kubectl kustomize "github.com/kubernetes-sigs/gateway-api/config/crd?ref=v1.1.0" | kubectl apply -f -; }

customresourcedefinition.apiextensions.k8s.io/gatewayclasses.gateway.networking.k8s.io created
customresourcedefinition.apiextensions.k8s.io/gateways.gateway.networking.k8s.io created
customresourcedefinition.apiextensions.k8s.io/grpcroutes.gateway.networking.k8s.io created
customresourcedefinition.apiextensions.k8s.io/httproutes.gateway.networking.k8s.io created
customresourcedefinition.apiextensions.k8s.io/referencegrants.gateway.networking.k8s.io created


kubectl apply -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1 # Specifies the API version for the Gateway resource
kind: Gateway # Specifies the type of resource
metadata: # Contains metadata about the Gateway resource. Here, it defines the name of the Gateway
  name: httpbin-gateway
spec:
  gatewayClassName: istio # Specifies the name of the GatewayClass resource that this Gateway should use, which is `istio` in this case.
  listeners: # Defines the listener configurations for this Gateway
  - name: http # A unique name for the listener
    hostname: "httpbin.example.com" # Specifies the hostname for which this Gateway will handle traffic
    port: 80 # Specifies the port number, 80, which is commonly used for HTTP traffic
    protocol: HTTP # Specifies the protocol to be used
    allowedRoutes: # Specifies the namespaces from which routes are allowed.
      namespaces:
        from: Same # Specifies that routes are allowed from the same namespace as the Gateway
EOF

gateway.gateway.networking.k8s.io/httpbin-gateway created

kubectl get gateways -A

NAMESPACE   NAME              CLASS   ADDRESS          PROGRAMMED   AGE
default     httpbin-gateway   istio   10.237.150.217   True         9h

# Because creating a Kubernetes Gateway resource will also deploy an associated proxy service, run the following command to wait for the gateway to be ready:

kubectl wait --for=condition=programmed gtw httpbin-gateway

# Configure routes for traffic entering via the Gateway:

kubectl apply -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1  # Specifies the API version for the HTTPRoute resource.
kind: HTTPRoute  # Defines the type of resource, which is HTTPRoute.
metadata:
  name: httpbin  # The name of the HTTPRoute resource.
spec:
  parentRefs:
  - name: httpbin-gateway  # References the Gateway resource that this route is associated with.
  hostnames: ["httpbin.example.com"]  # Specifies the hostname that this route will match.
  rules:
  - matches:
    - path:
        type: PathPrefix  # Specifies that the match type is a prefix match.
        value: /status  # Matches paths that start with /status.
    - path:
        type: PathPrefix  # Specifies that the match type is a prefix match.
        value: /delay  # Matches paths that start with /delay.
    backendRefs:
    - name: httpbin  # References the backend service to which traffic should be routed.
      port: 8000  # Specifies the port on the backend service to which traffic should be routed.
EOF


httproute.gateway.networking.k8s.io/httpbin created

# You have now created an HTTP Route configuration for the httpbin service containing two route rules that allow traffic for paths /status and /delay.

# Determining the ingress IP and ports

# Every Gateway is backed by a service of type LoadBalancer. The external load balancer IP and ports for this service are used to access the gateway. Kubernetes services of type LoadBalancer are supported by default in clusters running on most cloud platforms but in some environments (e.g., test) you may need to do the following:

    # minikube - start an external load balancer by running the following command in a different terminal:

    # $ minikube tunnel


# For convenience, we will store the ingress IP and ports in environment variables which will be used in later instructions. Set the INGRESS_HOST and INGRESS_PORT environment variables according to the following instructions:
export INGRESS_HOST=$(kubectl get gtw httpbin-gateway -o jsonpath='{.status.addresses[0].value}')
export INGRESS_PORT=$(kubectl get gtw httpbin-gateway -o jsonpath='{.spec.listeners[?(@.name=="http")].port}')
export SECURE_INGRESS_PORT=$(kubectl get gtw httpbin-gateway -o jsonpath='{.spec.listeners[?(@.name=="https")].port}')

echo "host: $INGRESS_HOST - port: $INGRESS_PORT securePort: $SECURE_INGRESS_PORT"
# Accessing ingress services
## Access the httpbin service using curl:
curl -s -I -HHost:httpbin.example.com "http://$INGRESS_HOST:$INGRESS_PORT/status/200"

HTTP/1.1 200 OK
server: istio-envoy
date: Sat, 15 Jun 2024 23:54:34 GMT
content-type: text/html; charset=utf-8
access-control-allow-origin: *
access-control-allow-credentials: true
content-length: 0
x-envoy-upstream-service-time: 2

# yayy. success.

# Note that you use the -H flag to set the Host HTTP header to `httpbin.example.com`. This is needed because your ingress Gateway is configured to handle `httpbin.example.com`, but in your test environment you have no DNS binding for that host and are simply sending your request to the ingress IP.

# Access any other URL that has not been explicitly exposed. You should see an HTTP 404 error:
curl -s -I -HHost:httpbin.example.com "http://$INGRESS_HOST:$INGRESS_PORT/headers"

HTTP/1.1 404 Not Found
date: Sat, 15 Jun 2024 23:57:25 GMT
server: istio-envoy
transfer-encoding: chunked

# Continue from here
# https://istio.io/latest/docs/tasks/traffic-management/ingress/ingress-control/#accessing-ingress-services-using-a-browser

# Cleanup:
helm delete istiod -n istio-system
# release "istiod" uninstalled
helm delete istio-ingressgateway -n istio-ingress
# release "istio-ingressgateway" uninstalled
kubectl delete httproute httpbin
# httproute.gateway.networking.k8s.io "httpbin" deleted
kubectl delete --ignore-not-found=true gateway httpbin-gateway
# gateway.gateway.networking.k8s.io "httpbin-gateway" deleted

# create again..
TODO:
# Reinstall istio and install sample application.

–>