Istio
В данном практическом занятии познакомимся с работой istio service mesh в кластере kubernetes.
Vagrant
Для работы будем использовать следующий Vagrantfile
:
Vagrant.configure("2") do |config|
config.vm.define "otel" do |c|
c.vm.provider "virtualbox" do |v|
v.cpus = 2
v.memory = 4096
end
c.vm.box = "ubuntu/lunar64"
c.vm.hostname = "otel"
c.vm.network "forwarded_port", guest: 8080, host: 8888
c.vm.provision "shell", inline: <<-SHELL
apt-get update -q
apt-get install -yq docker.io docker-compose-v2
usermod -a -G docker vagrant
curl -LO https://dl.k8s.io/release/v1.30.0/bin/linux/amd64/kubectl
curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.22.0/kind-linux-amd64
curl -L https://github.com/istio/istio/releases/download/1.21.2/istioctl-1.21.2-linux-amd64.tar.gz \
| tar xzf - -C /usr/local/bin/
install -m 755 kubectl kind /usr/local/bin/
rm kubectl kind
SHELL
end
end
Данная конфигурация установит на виртуальную машину docker, kubectl и kind, с помощью которых будет производиться развертывание и управление кластером kubernetes, а также утилита istioctl для управления istio.
Install
Создадим новый кластер с помощью утилиты kind
передав конфигурацию, в которой
указаны дополнительные порты для доступа снаружи:
cat <<EOF | kind create cluster --config=-
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
kubeadmConfigPatches:
- |
kind: InitConfiguration
nodeRegistration:
kubeletExtraArgs:
node-labels: "ingress-ready=true"
extraPortMappings:
- containerPort: 8080
hostPort: 8080
protocol: TCP
- containerPort: 8443
hostPort: 8443
protocol: TCP
EOF
И убедимся что он функционирует:
Creating cluster "kind" ...
✓ Ensuring node image (kindest/node:v1.29.2) 🖼
✓ Preparing nodes 📦
✓ Writing configuration 📜
✓ Starting control-plane 🕹️
✓ Installing CNI 🔌
✓ Installing StorageClass 💾
Set kubectl context to "kind-kind"
You can now use your cluster with:
kubectl cluster-info --context kind-kind
Not sure what to do next? 😅 Check out https://kind.sigs.k8s.io/docs/user/quick-start/
$ kubectl cluster-info
Kubernetes control plane is running at https://127.0.0.1:34283
CoreDNS is running at https://127.0.0.1:34283/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
Установим istio с помощью istioctl, добавим метку на неймспейс, чтобы
istio мог инжектить сайдкары, а также внесем изменения в конфигурацию
istio-ingressgateway
для доступа снаружи:
$ istioctl install --set profile=demo -y
✔ Istio core installed
✔ Istiod installed
✔ Egress gateways installed
✔ Ingress gateways installed
✔ Installation complete
Made this installation the default for injection and validation.
$ kubectl label namespace default istio-injection=enabled
namespace/default labeled
$ kubectl patch deploy -n istio-system istio-ingressgateway -p '{"spec":{"template":{"spec":{"dnsPolicy":"ClusterFirstWithHostNet","hostNetwork":true}}}}'
deployment.apps/istio-ingressgateway patched
Deploy App
Развернем тестовое приложение для демонстрации работы service mesh:
$ kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.21/samples/bookinfo/platform/kube/bookinfo.yaml
service/details created
serviceaccount/bookinfo-details created
deployment.apps/details-v1 created
service/ratings created
serviceaccount/bookinfo-ratings created
deployment.apps/ratings-v1 created
service/reviews created
serviceaccount/bookinfo-reviews created
deployment.apps/reviews-v1 created
deployment.apps/reviews-v2 created
deployment.apps/reviews-v3 created
service/productpage created
serviceaccount/bookinfo-productpage created
deployment.apps/productpage-v1 created
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
details-v1-698d88b-5ctrm 2/2 Running 0 17m
productpage-v1-675fc69cf-qqnnr 2/2 Running 0 17m
ratings-v1-6484c4d9bb-kcj2d 2/2 Running 0 17m
reviews-v1-5b5d6494f4-42mf8 2/2 Running 0 17m
reviews-v2-5b667bcbf8-xsdvg 2/2 Running 0 17m
reviews-v3-5b9bd44f4-6njpm 2/2 Running 0 17m
После применения появится несколько связанных микросервисов. Входной точкой
является productpage
, который отображает информацию с других сервисов -
details
, rating
и reviews
.
Добавим конфигурацию, которая позволит направить трафик снаружи через
istio-ingressgateway
в сервис productpage
:
$ kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.21/samples/bookinfo/networking/bookinfo-gateway.yaml
gateway.networking.istio.io/bookinfo-gateway created
virtualservice.networking.istio.io/bookinfo created
После чего сможем попасть в него через адрес localhost:8888/productpage:
Как было видно в списке подов находится несколько версий сервиса reviews
, при
обновлениях страницы у нас будет меняться вывод блока Book Reviews
:
Version Routing
Добавим конфигурацию destinationrules
для разделения версий приложений с
помощью лейблов:
$ kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.21/samples/bookinfo/networking/destination-rule-all.yaml
destinationrule.networking.istio.io/productpage created
destinationrule.networking.istio.io/reviews created
destinationrule.networking.istio.io/ratings created
destinationrule.networking.istio.io/details created
$ kubectl get dr
NAME HOST AGE
details details 6m58s
productpage productpage 6m58s
ratings ratings 6m58s
reviews reviews 6m58s
$ kubectl get dr reviews -o yaml
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
creationTimestamp: "2024-05-12T21:22:11Z"
generation: 1
name: reviews
namespace: default
resourceVersion: "8361"
uid: d46d96ef-8605-426a-8d1c-4a09f48ba058
spec:
host: reviews
subsets:
- labels:
version: v1
name: v1
- labels:
version: v2
name: v2
- labels:
version: v3
name: v3
Теперь сконфигурируем virtualservice
для выбора версии v1
:
$ kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.21/samples/bookinfo/networking/virtual-service-all-v1.yaml
virtualservice.networking.istio.io/productpage created
virtualservice.networking.istio.io/reviews created
virtualservice.networking.istio.io/ratings created
virtualservice.networking.istio.io/details created
$ kubectl get vs reviews -o yaml
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
creationTimestamp: "2024-05-12T21:32:36Z"
generation: 1
name: reviews
namespace: default
resourceVersion: "9509"
uid: 81f13936-a823-434c-90ec-39987b12b90b
spec:
hosts:
- reviews
http:
- route:
- destination:
host: reviews
subset: v1
После чего при любых обновлениях страницы
/productpage блок Book Reviews
всегда
будет содержать первую версию:
С помощью команды kubectl edit
или kubectl patch
изменим версию на v3
:
$ kubectl patch vs reviews -p '{"spec":{"http":[{"route":[{"destination":{"host":"reviews","subset":"v3"}}]}]}}' --type merge
virtualservice.networking.istio.io/reviews patched
После чего всегда будет отображаться версия v3
сервиса reviews
:
User Routing
С помощью istio можно направить только часть трафика на определенную версию,
зададим конфигурацию virtualservice
, которая направит трафик только для
пользователя jason
на версию v2
:
$ kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.21/samples/bookinfo/networking/virtual-service-reviews-test-v2.yaml
virtualservice.networking.istio.io/reviews configured
$ kubectl get vs reviews -o yaml
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
creationTimestamp: "2024-05-12T21:32:36Z"
generation: 5
name: reviews
namespace: default
resourceVersion: "12531"
uid: 81f13936-a823-434c-90ec-39987b12b90b
spec:
hosts:
- reviews
http:
- match:
- headers:
end-user:
exact: jason
route:
- destination:
host: reviews
subset: v2
- route:
- destination:
host: reviews
subset: v1
Если зайти на страницу /productpage, то
блок Book Reviews
будет содержать первую версию:
Если же нажать на кнопку Sign In
и авторизоваться под пользователем jason
,
то блок Book Reviews
будет содержать вторую версию:
Таким образом с помощью istio service mesh можно настроить гибкую маршрутизацию трафика.