CONTENTS
Set the context environment variable:
export CLUSTER1=cluster1
Run the following commands to deploy a multi node Kubernetes cluster using KinD:
data/steps/deploy-kind-cluster/deploy-multi.sh 1 cluster1
Creating cluster "kind1" ...
β Ensuring node image (kindest/node:v1.24.0) πΌ
β Preparing nodes π¦ π¦ π¦ π¦
β Writing configuration π
β Starting control-plane πΉοΈ
β Installing CNI π
β Installing StorageClass πΎ
β Joining worker nodes π
Set kubectl context to "kind-kind1"
You can now use your cluster with:
kubectl cluster-info --context kind-kind1
Thanks for using kind! π
Cluster "kind-kind1" set.
namespace/metallb-system created
Warning: policy/v1beta1 PodSecurityPolicy is deprecated in v1.21+, unavailable in v1.25+
podsecuritypolicy.policy/controller created
podsecuritypolicy.policy/speaker created
serviceaccount/controller created
serviceaccount/speaker created
clusterrole.rbac.authorization.k8s.io/metallb-system:controller created
clusterrole.rbac.authorization.k8s.io/metallb-system:speaker created
role.rbac.authorization.k8s.io/config-watcher created
role.rbac.authorization.k8s.io/pod-lister created
clusterrolebinding.rbac.authorization.k8s.io/metallb-system:controller created
clusterrolebinding.rbac.authorization.k8s.io/metallb-system:speaker created
rolebinding.rbac.authorization.k8s.io/config-watcher created
rolebinding.rbac.authorization.k8s.io/pod-lister created
Warning: spec.template.spec.nodeSelector[beta.kubernetes.io/os]: deprecated since v1.14; use "kubernetes.io/os" instead
daemonset.apps/speaker created
deployment.apps/controller created
secret/memberlist created
configmap/config created
configmap/local-registry-hosting created
Context "kind-kind1" renamed to "cluster1".
Then run the following commands to wait for all the Pods to be ready:
data/steps/deploy-kind-cluster/check.sh cluster1
Waiting for all the kube-system pods to become ready in context cluster1
Waiting for all the metallb-system pods to become ready in context cluster1
Note: If you run the check.sh
script immediately after the deploy.sh
script, you may see a jsonpath error. If that happens, simply wait a few seconds and try again.
Download istioctl
for ambient:
wget https://storage.googleapis.com/istio-build/dev/0.0.0-ambient.191fe680b52c1754ee72a06b3e0d3f9d116f2e82/istioctl-0.0.0-ambient.191fe680b52c1754ee72a06b3e0d3f9d116f2e82-linux-amd64.tar.gz
Uncompress the archive:tar zxvf istioctl*.tar.gz
The Ambient profile is designed to help you get started with Ambient easily.
Install Istio with the ambient profile on your Kubernetes cluster.
./istioctl install -y --set profile=ambient
After running the above command, youβll get the following output that indicates these four components are installed successfully!
β Istio core installed
- Processing resources for Istiod. Waiting for DaemonSet/istio-system/ztunnel, Deployment/istio-system/istiod
- Processing resources for Istiod. Waiting for DaemonSet/istio-system/ztunnel
β Istiod installed
β Ingress gateways installed
β CNI installed
β Installation complete Making this installation the default for injection and validation.
By default, the Ambient profile has the Istio core, Istiod, ingress gateway, ztunnel and CNI plugin enabled. The Istio CNI plugin is responsible for detecting which application pods are part of ambient and configuring the traffic redirection between them and the ztunnel.
Run the following command to check the Pods deployed in the istio-system
namespace:
kubectl -n istio-system get pods
Here is the expected output:
NAME READY STATUS RESTARTS AGE
istio-cni-node-96lnb 1/1 Running 0 4m58s
istio-cni-node-n9wgw 1/1 Running 0 4m58s
istio-cni-node-vchk9 1/1 Running 0 4m58s
istio-cni-node-z7rsg 1/1 Running 0 4m58s
istio-ingressgateway-65fb89f688-55njk 1/1 Running 0 4m58s
istiod-67ff7f98c7-9z69c 1/1 Running 0 5m30s
ztunnel-2xtrx 1/1 Running 0 5m30s
ztunnel-9njpt 1/1 Running 0 5m30s
ztunnel-fjt99 1/1 Running 0 5m30s
ztunnel-l59cf 1/1 Running 0 5m30s
Youβll notice the following pods are deployed in the istio-system
namespace with the default Ambient profile.
We're going to deploy the web-api
, recommendation
, and purchase-history
services built using the fake service.
The web-api
service calls the recommendation
service via HTTP, and the recommendation
service calls the purchase-history
service, also via HTTP. Youβll use curl as your client, either outside of the cluster or in the cluster from the sleep
pod. Pod anti-affinity rules are specified in the sleep
, web-api
, recommendation
and purchase-history
deployment descriptors to avoid them deployed on the same node whenever possible.
Deploy the sample application:
kubectl apply -f data/steps/deploy-fake-services
Note that you can use the Files
tab to see the content of the different files we use in this workshop.
Run the following command to check the Pods deployed in the default
namespace:
kubectl get pods
Youβll notice the following pods are deployed in the default
namespace:
NAME READY STATUS RESTARTS AGE
notsleep-5564c6dd94-x7zfs 1/1 Running 0 107s
purchase-history-v1-fc9446597-scbzh 1/1 Running 0 107s
recommendation-bb5cbdc9d-v6j8s 1/1 Running 0 107s
sleep-84585fd6cc-whb6m 1/1 Running 0 107s
web-api-7c9755c6d-g5wbq 1/1 Running 0 107s
Test the sample application using the following command:
kubectl exec deploy/sleep -- curl http://web-api:8080/
You should get something like this:
{
"name": "web-api",
"uri": "/",
"type": "HTTP",
"ip_addresses": [
"10.101.2.5"
],
"start_time": "2022-08-31T08:37:40.958489",
"end_time": "2022-08-31T08:37:40.961207",
"duration": "2.718015ms",
"body": "Hello From Web API",
"upstream_calls": [
{
"name": "recommendation",
"uri": "http://recommendation:8080",
"type": "HTTP",
"ip_addresses": [
"10.101.2.4"
],
"start_time": "2022-08-31T08:37:40.959451",
"end_time": "2022-08-31T08:37:40.961007",
"duration": "1.555879ms",
"body": "Hello From Recommendations!",
"upstream_calls": [
{
"name": "purchase-history-v1",
"uri": "http://purchase-history:8080",
"type": "HTTP",
"ip_addresses": [
"10.101.1.4"
],
"start_time": "2022-08-31T08:37:40.960476",
"end_time": "2022-08-31T08:37:40.960658",
"duration": "182.631Β΅s",
"body": "Hello From Purchase History (v1)!",
"code": 200
}
],
"code": 200
}
],
"code": 200
}
Inbound traffic for the mesh is controlled with Istio ingress gateways, which can be configured with the Istio Gateway
and VirtualService
resources.
Create these resources to expose the web-api
service through the Istio ingress gateway:
kubectl apply -f data/steps/expose-web-api-service
virtualservice.networking.istio.io/web-api-gw-vs created
gateway.networking.istio.io/web-api-gateway created
Get the external IP address of the Kubernetes Load Balancer service corresponding to the Istio ingress gateway:
export GATEWAY_IP=$(kubectl -n istio-system get svc istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].*}')
You should now be able to access the web-api
service via Istio ingress gateway using the host header specified in the gateway resource.
curl -H "Host: istioexplained.io" "http://${GATEWAY_IP}/"
{
"name": "web-api",
"uri": "/",
"type": "HTTP",
"ip_addresses": [
"10.101.2.5"
],
"start_time": "2022-08-31T08:37:40.958489",
"end_time": "2022-08-31T08:37:40.961207",
"duration": "2.718015ms",
"body": "Hello From Web API",
"upstream_calls": [
{
"name": "recommendation",
"uri": "http://recommendation:8080",
"type": "HTTP",
"ip_addresses": [
"10.101.2.4"
],
"start_time": "2022-08-31T08:37:40.959451",
"end_time": "2022-08-31T08:37:40.961007",
"duration": "1.555879ms",
"body": "Hello From Recommendations!",
"upstream_calls": [
{
"name": "purchase-history-v1",
"uri": "http://purchase-history:8080",
"type": "HTTP",
"ip_addresses": [
"10.101.1.4"
],
"start_time": "2022-08-31T08:37:40.960476",
"end_time": "2022-08-31T08:37:40.960658",
"duration": "182.631Β΅s",
"body": "Hello From Purchase History (v1)!",
"code": 200
}
],
"code": 200
}
],
"code": 200
}
Join the newsletter to receive the latest updates in your inbox.