Open Service Mesh (OSM)
--
O OSM (Open Service Mesh) é uma malha de serviço de código aberto que fornece recursos para gerenciamento de tráfego e observabilidade para aplicativos em contêineres em um cluster Kubernetes. Ele permite que os usuários definam políticas de tráfego de rede, coletar métricas e rastreamento de logs para aplicativos em um ambiente de contêiner orquestrado pelo Kubernetes.
Suporte e Funcionalidades do OSM
- Criptografar todo o tráfego no cluster
- Distribuições em fases e do tipo canário
- Gerenciamento e manipulação de tráfego
- Observabilidade
O Serviço de Kubernetes do Azure (AKS) oferece complementos com suporte oficial para Istio e Open Service Mesh:
Saiba mais em Sobre as malhas de serviço — Azure Kubernetes Service | Microsoft Learn
O que o OSM faz
- Distribuição de tráfego.
- Comunicação de serviço a serviço segura de ponta a ponta, habilitando mTLS. Defina e execute políticas de controle de acesso detalhadas para serviços.
- Observabilidade e insights sobre métricas de aplicativos para depuração e monitoramento de serviços.
- Integre-se a serviços/soluções externas de gerenciamento de certificados com uma interface plugável.
- Incorpore aplicativos à malha, habilitando a injeção automática de sidecar do proxy Envoy.
- Suficientemente flexível para lidar tanto com cenários simples quanto complexos por meio das APIs SMI e Envoy XDS.
Como habilitar no AKS
Para habilitar via CLI (Esse comando não funcionou para mim)
az aks enable-addons --addons open-service-mesh -g aks_hpa -n aks_hpa_01
Para habilitar pelo Portal do Azure basta acessar suas instancia no menu Open Service Mesh e clicar em enable, depois disso podemos observar que vários deploys vão ser criados com o prefixo OSM .
Depois de instalar podemos verificar se esta tudo ok com esse comando
kubectl get pods -n kube-system --selector app=osm-controller
Basicamente eu usei dois exemplos, um mais simples seguindo o video Open Service Mesh | Azure Kubernetes Services ele usa apenas três deploys para demostrar um Split, e um mais completo chamado AKS Open Service Mesh Demo que usa além das do objeto de split (TrafficSplit), também usa configuração de rotas com os objetos TrafficTarget e HTTPRouteGroup Na documentação do OSM temos um exemplo muito parecido também How to run the OSM manual demo.
Open Service Mesh | Azure Kubernetes Services (Exemplo 1)
O objetivo final e criar um split entre book buyer e Bookstore V1 e V2 mais ou menos como no desenho
Não consegui chegar até o final desse exemplo pois não encontrei o arquivo com as políticas que o video usou, mas vou tentar completar o que faltou.
bookbuyer
- Cria uma Namespace
- Criar um ServiceAccount
- Cria um Deployment
- Imagem openservicemesh/bookbuyer:v0.8.4
- Variases de Ambiente (BOOKSTORE_NAMESPACE,BOOKSTORE_SVC)
bookstore
- Cria uma Namespace
- Cria um Service na porta 14001 (Cluster IP)
- Criar um ServiceAccount
- Cria um Deployment
- Imagem openservicemesh/bookstore:v0.8.4
- Variases de Ambiente (BOOKWAREHOUSE_NAMESPACE,IDENTITY)
bookstore V2
- Cria um Service na porta 14001 (Cluster IP)
- Criar um ServiceAccount
- Cria um Deployment
- Imagem openservicemesh/bookstore:v0.8.4
- Variases de Ambiente (BOOKWAREHOUSE_NAMESPACE,IDENTITY)
- Cria um TrafficTarget
kind: TrafficTarget
apiVersion: access.smi-spec.io/v1alpha3
metadata:
name: bookstore-v2
namespace: bookstore
spec:
destination:
kind: ServiceAccount
name: bookstore-v2
namespace: bookstore
rules:
- kind: HTTPRouteGroup
name: bookstore-service-routes
matches:
- buy-a-book
- books-bought
sources:
- kind: ServiceAccount
name: bookbuyer
namespace: bookbuyer
bookwarehouse
- Cria uma Namespace
- Cria um Service na porta 14001 (Cluster IP)
- Criar um ServiceAccount
- Cria um Deployment
- Imagem openservicemesh/bookwarehouse:v0.8.4
Como rodar os deploy
kubectl create -f https://raw.githubusercontent.com/openservicemesh/osm/release-v0.8/docs/example/manifests/apps/bookbuyer.yaml
kubectl create -f https://raw.githubusercontent.com/openservicemesh/osm/release-v0.8/docs/example/manifests/apps/bookstore.yaml
kubectl create -f https://raw.githubusercontent.com/openservicemesh/osm/release-v0.8/docs/example/manifests/apps/bookstore-v2.yaml
kubectl create -f https://raw.githubusercontent.com/openservicemesh/osm/release-v0.8/docs/example/manifests/apps/bookwarehouse.yaml
Depois de Rodar esses deploys precisamos usar a CLI do OSM para monitorar as namespaces criadas, para isso usamos esse comando
osm namespace add bookstore bookbuyer bookwarehouse
Para instalar essa CLI use o ps abaixo
# Specify the OSM version that will be leveraged throughout these instructions
$OSM_VERSION="v1.0.0"
[Net.ServicePointManager]::SecurityProtocol = "tls12"
$ProgressPreference = 'SilentlyContinue'; Invoke-WebRequest -URI "https://github.com/openservicemesh/osm/releases/download/$OSM_VERSION/osm-$OSM_VERSION-windows-amd64.zip" -OutFile "osm-$OSM_VERSION.zip"
Expand-Archive -Path "osm-$OSM_VERSION.zip" -DestinationPath .
Para baixar https://release-v1-0.docs.openservicemesh.io/docs/guides/cli/
Cria uma pasta no C: algo como isso “c:\osm” copia o arquivo osm.exe e coloca na variável de ambiente path.
Esse exemplo me chamou atenção pois falou do parâmetro addonProfiles.openServiceMesh.enabled.O modo de política de tráfego permissivo é ativado para evitar a necessidade de criar políticas de controle de acesso explícitas para saber mais clique Permissive Mode | Open Service Mesh
Podemos verificar assim
az aks show --resource-group AKS_PRV --name aksprv01 --query 'addonProfiles.openServiceMesh.enabled'
e desabilitar assim (Esse comando não funionou para mim)
kubectl patch meshconfig osm-mesh-config -n osm-system -p '{"spec":{"traffic":{"enablePermissiveTrafficPolicyMode":false}}}' --type=merge
Alem dos arquivos de depoy que mostrei acima será necessário criar um HTTPRouteGroup chamado bookstore-service-routes
apiVersion: specs.smi-spec.io/v1alpha4
kind: HTTPRouteGroup
metadata:
name: bookstore-service-routes
namespace: bookstore
spec:
matches:
- name: books-bought
pathRegex: /books-bought
methods:
- GET
headers:
- "user-agent": ".*-http-client/*.*"
- "client-app": "bookbuyer"
- name: buy-a-book
pathRegex: ".*a-book.*new"
methods:
- GET
e um TrafficSplit
apiVersion: split.smi-spec.io/v1alpha2
kind: TrafficSplit
metadata:
name: bookstore-split
namespace: bookstore
spec:
service: bookstore.bookstore # <root-service>.<namespace>
backends:
- service: bookstore
weight: 0
- service: bookstore-v2
weight: 100
AKS Open Service Mesh Demo
Aqui temos mais deploys como ele não usou os manifestos oficiais do openservicemesh vou colocar todo o conteúdo aqui.
bookbuyer.yaml
# Create bookbuyer Service Account
apiVersion: v1
kind: ServiceAccount
metadata:
name: bookbuyer
namespace: bookbuyer
---
# Create bookbuyer Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: bookbuyer
namespace: bookbuyer
spec:
replicas: 1
selector:
matchLabels:
app: bookbuyer
version: v1
template:
metadata:
labels:
app: bookbuyer
version: v1
spec:
serviceAccountName: bookbuyer
nodeSelector:
kubernetes.io/arch: amd64
kubernetes.io/os: linux
containers:
- name: bookbuyer
image: openservicemesh/bookbuyer:v1.0.0
imagePullPolicy: Always
command: ["/bookbuyer"]
env:
- name: "BOOKSTORE_NAMESPACE"
value: bookstore
- name: "BOOKSTORE_SVC"
value: bookstore
bookwarehouse.yaml
# Create bookwarehouse Service Account
apiVersion: v1
kind: ServiceAccount
metadata:
name: bookwarehouse
namespace: bookwarehouse
---
# Create bookwarehouse Service
apiVersion: v1
kind: Service
metadata:
name: bookwarehouse
namespace: bookwarehouse
labels:
app: bookwarehouse
spec:
ports:
- port: 14001
name: bookwarehouse-port
selector:
app: bookwarehouse
---
# Create bookwarehouse Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: bookwarehouse
namespace: bookwarehouse
spec:
replicas: 1
selector:
matchLabels:
app: bookwarehouse
template:
metadata:
labels:
app: bookwarehouse
version: v1
spec:
serviceAccountName: bookwarehouse
nodeSelector:
kubernetes.io/arch: amd64
kubernetes.io/os: linux
containers:
- name: bookwarehouse
image: openservicemesh/bookwarehouse:v1.0.0
imagePullPolicy: Always
command: ["/bookwarehouse"]
mysql.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: mysql
namespace: bookwarehouse
---
apiVersion: v1
kind: Service
metadata:
name: mysql
namespace: bookwarehouse
spec:
ports:
- port: 3306
targetPort: 3306
name: client
appProtocol: tcp
selector:
app: mysql
clusterIP: None
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql
namespace: bookwarehouse
spec:
serviceName: mysql
replicas: 1
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
serviceAccountName: mysql
nodeSelector:
kubernetes.io/os: linux
containers:
- image: mysql:5.6
name: mysql
env:
- name: MYSQL_ROOT_PASSWORD
value: mypassword
- name: MYSQL_DATABASE
value: booksdemo
ports:
- containerPort: 3306
name: mysql
volumeMounts:
- mountPath: /mysql-data
name: data
readinessProbe:
tcpSocket:
port: 3306
initialDelaySeconds: 15
periodSeconds: 10
volumes:
- name: data
emptyDir: {}
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 250M
bookstore-v1.yaml
# Create bookstore Service
apiVersion: v1
kind: Service
metadata:
name: bookstore
namespace: bookstore
labels:
app: bookstore-v1
spec:
ports:
- port: 14001
name: bookstore-port
selector:
app: bookstore-v1
---
# Create bookstore Service Account
apiVersion: v1
kind: ServiceAccount
metadata:
name: bookstore-v1
namespace: bookstore
---
# Create bookstore Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: bookstore
namespace: bookstore
spec:
replicas: 1
selector:
matchLabels:
app: bookstore-v1
template:
metadata:
labels:
app: bookstore-v1
spec:
serviceAccountName: bookstore-v1
nodeSelector:
kubernetes.io/arch: amd64
kubernetes.io/os: linux
containers:
- name: bookstore
image: openservicemesh/bookstore:v1.0.0
imagePullPolicy: Always
ports:
- containerPort: 14001
name: web
command: ["/bookstore"]
args: ["--port", "14001"]
env:
- name: BOOKWAREHOUSE_NAMESPACE
value: bookwarehouse
- name: IDENTITY
value: bookstore-v1
bookthief.yaml
# Create bookthief ServiceAccount
apiVersion: v1
kind: ServiceAccount
metadata:
name: bookthief
namespace: bookthief
---
# Create bookthief Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: bookthief
namespace: bookthief
spec:
replicas: 1
selector:
matchLabels:
app: bookthief
template:
metadata:
labels:
app: bookthief
version: v1
spec:
serviceAccountName: bookthief
nodeSelector:
kubernetes.io/arch: amd64
kubernetes.io/os: linux
containers:
- name: bookthief
image: openservicemesh/bookthief:v1.0.0
imagePullPolicy: Always
command: ["/bookthief"]
env:
- name: "BOOKSTORE_NAMESPACE"
value: bookstore
- name: "BOOKSTORE_SVC"
value: bookstore
- name: "BOOKTHIEF_EXPECTED_RESPONSE_CODE"
value: "503"
traffic-v1.yaml
apiVersion: specs.smi-spec.io/v1alpha4
kind: HTTPRouteGroup
metadata:
name: bookstore-service-routes
namespace: bookstore
spec:
matches:
- name: books-bought
pathRegex: /books-bought
methods:
- GET
headers:
- "user-agent": ".*-http-client/*.*"
- "client-app": "bookbuyer"
- name: buy-a-book
pathRegex: ".*a-book.*new"
methods:
- GET
---
kind: TrafficTarget
apiVersion: access.smi-spec.io/v1alpha3
metadata:
name: bookstore-v1
namespace: bookstore
spec:
destination:
kind: ServiceAccount
name: bookstore-v1
namespace: bookstore
rules:
- kind: HTTPRouteGroup
name: bookstore-service-routes
matches:
- buy-a-book
- books-bought
sources:
- kind: ServiceAccount
name: bookbuyer
namespace: bookbuyer
bookstore-v2.yaml
# Create bookstore-v2 Service
apiVersion: v1
kind: Service
metadata:
name: bookstore-v2
namespace: bookstore
labels:
app: bookstore-v2
spec:
ports:
- port: 14001
name: bookstore-port
selector:
app: bookstore-v2
---
# Create bookstore-v2 Service Account
apiVersion: v1
kind: ServiceAccount
metadata:
name: bookstore-v2
namespace: bookstore
---
# Create bookstore-v2 Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: bookstore-v2
namespace: bookstore
spec:
replicas: 1
selector:
matchLabels:
app: bookstore-v2
template:
metadata:
labels:
app: bookstore-v2
spec:
serviceAccountName: bookstore-v2
nodeSelector:
kubernetes.io/arch: amd64
kubernetes.io/os: linux
containers:
- name: bookstore
image: openservicemesh/bookstore:v1.0.0
imagePullPolicy: Always
ports:
- containerPort: 14001
name: web
command: ["/bookstore"]
args: ["--port", "14001"]
env:
- name: BOOKWAREHOUSE_NAMESPACE
value: bookwarehouse
- name: IDENTITY
value: bookstore-v2
---
kind: TrafficTarget
apiVersion: access.smi-spec.io/v1alpha3
metadata:
name: bookstore-v2
namespace: bookstore
spec:
destination:
kind: ServiceAccount
name: bookstore-v2
namespace: bookstore
rules:
- kind: HTTPRouteGroup
name: bookstore-service-routes
matches:
- buy-a-book
- books-bought
sources:
- kind: ServiceAccount
name: bookbuyer
namespace: bookbuyer
traffic-split-v2.yaml
apiVersion: split.smi-spec.io/v1alpha2
kind: TrafficSplit
metadata:
name: bookstore-split
namespace: bookstore
spec:
service: bookstore.bookstore # <root-service>.<namespace>
backends:
- service: bookstore
weight: 0
- service: bookstore-v2
weight: 100
No fundo é a mesma coisa do primeiro, mas achei os deployments mas bem organizados.
- Criar as namespaces
kubectl create ns bookstore
kubectl create ns bookbuyer
kubectl create ns bookthief
kubectl create ns bookwarehouse
Adicionar as ns no OSM
osm namespace add bookstore bookbuyer bookwarehouse bookthief
faz os deployments (conteúdos acima)
kubectl create -f https://raw.githubusercontent.com/nitinkansal1984/aks/main/bookbuyer.yaml
kubectl create -f https://raw.githubusercontent.com/nitinkansal1984/aks/main/bookwarehouse.yaml
kubectl create -f https://raw.githubusercontent.com/nitinkansal1984/aks/main/mysql.yaml
kubectl create -f https://raw.githubusercontent.com/nitinkansal1984/aks/main/bookstore-v1.yaml
kubectl create -f https://raw.githubusercontent.com/nitinkansal1984/aks/main/bookstore-v2.yaml
kubectl create -f https://raw.githubusercontent.com/nitinkansal1984/aks/main/bookthief.yaml
Para verificar usa o port-forward aqui tem um script bem elaborado que pega as variaveis dos pods etc eu montei na mão mesmo pegando os nomes dos pods com kubectl get pods
kubectl port-forward bookbuyer-85b76d4b84-hpd88 -n bookbuyer 8080:14001
kubectl port-forward bookstore-856c5bfcf-5sdmd -n bookstore 8081:14001
kubectl port-forward bookstore-v2-86767775ff-7ltv4 -n bookstore-v2 8082:14001
kubectl port-forward bookthief-6656b97479-l5kd8 -n bookthief 8083:14001
Faz os dois deploys finais
kubectl create -f https://raw.githubusercontent.com/nitinkansal1984/aks/main/traffic-v1.yaml
kubectl create -f https://raw.githubusercontent.com/nitinkansal1984/aks/main/traffic-split-v2.yaml
Expondo o serviço para fora do Cluster
Tentei expor um LoadBalancer com IP publico, mas não acessou !!!!!
# Expor a APP
kubectl expose deploy bookstore --name=bookstoresvc --type=LoadBalancer --port=80 --target-port=14001
Habilitei um ingress_k8s_nginx
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.7.0/deploy/static/provider/cloud/deploy.yaml
disable-sidecar-injection
osm namespace add ingress-nginx --mesh-name osm --disable-sidecar-injection
http-ingress-bookstore.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: bookstore
namespace: bookstore
spec:
ingressClassName: nginx
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: bookstore
port:
number: 14001
---
kind: IngressBackend
apiVersion: policy.openservicemesh.io/v1alpha1
metadata:
name: bookstore
namespace: bookstore
spec:
backends:
- name: bookstore
port:
number: 14001
protocol: http
sources:
- kind: Service
namespace: ingress-nginx
name: ingress-nginx-controller
fiz isso com o bookthief também, primeiro expus o serviço que não existia
kubectl expose deploy bookthief --name=bookthiefsvc2 --type=LoadBalancer --port=80 --target-port=14001 -n bookthief
e depois rodei o deploy http-ingress-bookthief.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: bookthief
namespace: bookthief
spec:
ingressClassName: nginx
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: bookthief
port:
number: 14001
---
kind: IngressBackend
apiVersion: policy.openservicemesh.io/v1alpha1
metadata:
name: bookthief
namespace: bookthief
spec:
backends:
- name: bookthief
port:
number: 14001
protocol: http
sources:
- kind: Service
namespace: ingress-nginx
name: ingress-nginx-controller
Testei com AGIC (Azure Gateway Ingress Controller)
Você não pode configurar o Azure Gateway Ingress Controller (AGIC) para entrada HTTPS.
ou pela CLI
az aks enable-addons -n myCluster -g myResourceGroup -a ingress-appgw --appgw-id $appgwId
http-ingress-agic.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: httpbin
namespace: httpbin
annotations:
kubernetes.io/ingress.class: azure/application-gateway
appgw.ingress.kubernetes.io/use-private-ip: "true"
spec:
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: httpbin
port:
number: 14001
---
kind: IngressBackend
apiVersion: policy.openservicemesh.io/v1alpha1
metadata:
na
namespace: httpbin
spec:
backends:
- name: httpbin
port:
number: 14001 # targetPort of httpbin service
protocol: http
sources:
- kind: IPRange
name: 10.0.0.0/8
httpbin é uma aplicação de exemplo da documentação do Integrations with Open Service Mesh on Azure Kubernetes Service (AKS)
Usando o bookthief com o AGIC
kubectl get ingress -n bookthief
NAME CLASS HOSTS ADDRESS PORTS AGE
bookthief nginx * 20.121.148.149 80 25h
vou deletar
kubectl delete ingress bookthief -n bookthief
http-ingress-bookthief-agic.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: bookthief
namespace: bookthief
annotations:
kubernetes.io/ingress.class: azure/application-gateway
appgw.ingress.kubernetes.io/use-private-ip: "true"
spec:
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: bookthief
port:
number: 14001
---
kind: IngressBackend
apiVersion: policy.openservicemesh.io/v1alpha1
metadata:
name: bookthief
namespace: bookthief
spec:
backends:
- name: bookthief
port:
number: 14001 # targetPort of httpbin service
protocol: http
sources:
- kind: IPRange
name: 10.0.0.0/8
Verificando
kubectl get ingress -n bookthief
NAME CLASS HOSTS ADDRESS PORTS AGE
bookthief <none> * 10.225.0.4 80 7s
Teste com duas aplicações e um AGIC
Criei dois manifestos um para o httpbin, observe o path
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: httpbin
namespace: httpbin
annotations:
kubernetes.io/ingress.class: azure/application-gateway
appgw.ingress.kubernetes.io/use-private-ip: "true"
appgw.ingress.kubernetes.io/backend-path-prefix: "/"
spec:
rules:
- http:
paths:
- path: /httpbin
pathType: Prefix
backend:
service:
name: httpbin
port:
number: 14001
---
kind: IngressBackend
apiVersion: policy.openservicemesh.io/v1alpha1
metadata:
name: httpbin
namespace: httpbin
spec:
backends:
- name: httpbin
port:
number: 14001 # targetPort of httpbin service
protocol: http
sources:
- kind: IPRange
name: 10.0.0.0/8
e outro para bookthief na raiz do gateway
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: bookthief
namespace: bookthief
annotations:
kubernetes.io/ingress.class: azure/application-gateway
appgw.ingress.kubernetes.io/use-private-ip: "true"
appgw.ingress.kubernetes.io/backend-path-prefix: "/"
spec:
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: bookthief
port:
number: 14001
---
kind: IngressBackend
apiVersion: policy.openservicemesh.io/v1alpha1
metadata:
name: bookthief
namespace: bookthief
spec:
backends:
- name: bookthief
port:
number: 14001 # targetPort of httpbin service
protocol: http
sources:
- kind: IPRange
name: 10.0.0.0/8
o segredo esta nessa anotação appgw.ingress.kubernetes.io/backend-path-prefix: “/”
Alem disso usei o /* no path assim foi possível acessar diversas controllers da mesma API.
Annotations — Application Gateway Ingress Controller (azure.github.io)
Teste com acesso externo e Canary
Comecei com esse exemplo Canary Rollouts using SMI Traffic Split | Open Service Mesh
O deploy que precisam ser analisados são:
- https://raw.githubusercontent.com/openservicemesh/osm-docs/release-v1.0/manifests/samples/canary/httpbin.yaml
- https://raw.githubusercontent.com/openservicemesh/osm-docs/release-v1.0/manifests/samples/canary/httpbin-v1.yaml
- https://raw.githubusercontent.com/openservicemesh/osm-docs/release-v1.0/manifests/samples/canary/httpbin-v2.yaml
Podemos notar o uso de app: httpbin e version: v1
depois de rodar os depploys precisa rodar esse é o split
apiVersion: split.smi-spec.io/v1alpha2
kind: TrafficSplit
metadata:
name: http-split
namespace: httpbin
spec:
service: httpbin.httpbin.svc.cluster.local
backends:
- service: httpbin-v1
weight: 50
- service: httpbin-v2
weight: 50
e ai podemos notar uma diferença nos serviços
kubectl get services -n httpbin
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
httpbin ClusterIP 10.0.247.250 <none> 14001/TCP 30m
httpbin-v1 ClusterIP 10.0.103.76 <none> 14001/TCP 30m
httpbin-v2 ClusterIP 10.0.124.183 <none> 14001/TCP 28m
services httpbin
kubectl describe services httpbin -n httpbin
Name: httpbin
Namespace: httpbin
Labels: app=httpbin
Annotations: <none>
Selector: app=httpbin
Type: ClusterIP
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.0.247.250
IPs: 10.0.247.250
Port: http 14001/TCP
TargetPort: 14001/TCP
Endpoints: 10.244.1.12:14001,10.244.1.14:14001
Session Affinity: None
Events: <none>
services httpbin-v1 usa Labels: app=httpbin e version=v1
kubectl describe services httpbin-v1 -n httpbin
Name: httpbin-v1
Namespace: httpbin
Labels: app=httpbin
version=v1
Annotations: <none>
Selector: app=httpbin,version=v1
Type: ClusterIP
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.0.103.76
IPs: 10.0.103.76
Port: http 14001/TCP
TargetPort: 14001/TCP
Endpoints: 10.244.1.14:14001
Session Affinity: None
Events: <none>
services httpbin-v2 usa Labels: app=httpbin version=v2
kubectl describe services httpbin-v2 -n httpbin
Name: httpbin-v2
Namespace: httpbin
Labels: app=httpbin
version=v2
Annotations: <none>
Selector: app=httpbin,version=v2
Type: ClusterIP
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.0.124.183
IPs: 10.0.124.183
Port: http 14001/TCP
TargetPort: 14001/TCP
Endpoints: 10.244.1.12:14001
Session Affinity: None
Events: <none>
pods httpbin
kubectl get pods -n httpbin
NAME READY STATUS RESTARTS AGE
httpbin-v1-94df54b75-xkxfx 2/2 Running 0 7m15s
httpbin-v2-68dffc446b-clsx4 2/2 Running 0 7m16s
describe pod httpbin-v1–94df54b75-xkxfx
kubectl describe pod httpbin-v1-94df54b75-xkxfx -n httpbin
Name: httpbin-v1-94df54b75-xkxfx
Namespace: httpbin
Priority: 0
Service Account: httpbin
Node: aks-agentpool-51082989-vmss000001/10.224.0.5
Start Time: Wed, 05 Apr 2023 13:19:36 -0300
Labels: app=httpbin
osm-proxy-uuid=d9c27af4-e5a8-4490-86df-b809f9edf7ff
pod-template-hash=94df54b75
version=v1
describe pod httpbin-v2–68dffc446b-clsx
kubectl describe pod httpbin-v2-68dffc446b-clsx -n httpbin
Name: httpbin-v2-68dffc446b-clsx4
Namespace: httpbin
Priority: 0
Service Account: httpbin
Node: aks-agentpool-51082989-vmss000001/10.224.0.5
Start Time: Wed, 05 Apr 2023 13:19:35 -0300
Labels: app=httpbin
osm-proxy-uuid=e2c18940-caf6-4771-a285-b197fe63d877
pod-template-hash=68dffc446b
version=v2
Depois usei esse manifesto do AGIC (já habilitamos no cluster)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: httpbin
namespace: httpbin
annotations:
kubernetes.io/ingress.class: azure/application-gateway
spec:
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: httpbin
port:
number: 14001
---
kind: IngressBackend
apiVersion: policy.openservicemesh.io/v1alpha1
metadata:
name: httpbin
namespace: httpbin
spec:
backends:
- name: httpbin
port:
number: 14001 # targetPort of httpbin service
protocol: http
sources:
- kind: IPRange
name: 10.0.0.0/8
apliquei
kubectl apply -f .\HTTPIngress-agic.yaml
Podemos ver o Canary funcionando pelo response header poc
Alem dos nonos metadados vemos que o APPGW aponta para o serviço httpbin raiz assim como o split de trafico usando essa nomenclatura httpbin.httpbin.svc.cluster.local
Visualmente é algo assim:
Referências
- https://release-v1-0.docs.openservicemesh.io/
- https://release-v1-2.docs.openservicemesh.io/docs/demos/ingress_k8s_nginx/
- Integrations with Open Service Mesh on Azure Kubernetes Service (AKS) — Azure Kubernetes Service | Microsoft Learn
- Create an ingress controller in Azure Kubernetes Service (AKS) — Azure Kubernetes Service | Microsoft Learn
- https://learn.microsoft.com/pt-br/azure/application-gateway/ingress-controller-annotations
- AKS Comandos de CLI. todos os comandos que já usei | by Wilson Santos | Mar, 2023 | Medium