Service Mesh mit Istio und
MicroProfile
-
eine harmonische Kombination?
Michael Hofmann
Hofmann IT-Consulting
info@hofmann-itconsulting.de
https://hofmann-itconsulting.de
Service Mesh
„The term service mesh is used to describe the network of
microservices that make up such application and the
interactions between them.“ (istio.io)
Anzahl der Services steigt ...
Ohne Werkzeug lässt sich
Service Mesh (Big Ball of Mud)
nicht beherrschen!
Quelle: https://twitter.com/Werner/status/741673514567143424
(Werner Vogels, CTO Amazon)
Service Mesh Funktionen
●
Service Discovery
●
Load Balancing
●
Resilienz
●
Dynamic Routing (Blue/Green Deployments, Canary Releasing, Traffic
Shadowing)
●
Observability (Metrics, Tracing)
●
End-to-End Authentication, Access Control
●
Rate Limiting
Service Mesh womit?
Vergleich Istio und Linkerd: https://abhishek-tiwari.com/a-sidecar-for-your-service-mesh/
Istio
IBM (Amalgam8)
content-based routing
(extended)
service discovery
resilience
load balancing
Google (Istio)
content-based routing
rate limiting
ACLs
telemetry
Kubernetes integration
Lyft (Envoy)
proxy (sidecar)
Istio Architektur
Quelle: istio.io
Data Plane
Control Plane
What is Eclipse MicroProfile?
● Eclipse MicroProfile is an open-source community specification for Enterprise Java
microservices
● A community of individuals, organizations, and vendors collaborating within an open
source (Eclipse) project to bring microservices to the Enterprise Java community
7
Quelle: microprofile.io
Community - individuals, organizations, vendors
8
Quelle: microprofile.io
Current MicroProfile implementations
9
Quelle: microprofile.io
Eclipse MicroProfile 2.2 (Feb 2019)
10
MicroProfile 2.2
JAX-RS 2.1JSON-P 1.1CDI 2.0
Config 1.3
Fault
Tolerance 2.0
JWT
Propagation
1.1
Health
Check 1.0
Metrics 1.1
Open Tracing
1.3
Open API 1.1
= Updated
= No change from last release (MicroProfile 2.1)
= New
Rest Client
1.2
JSON-B 1.0
Quelle: microprofile.io
MicroProfile vs. Istio (Kubernetes)
Funktionalität MicroProfile Istio
Anwendungs-
Konfiguration
Kubernetes ConfigMap
Resilienz Timeout, Retry, CircuitBreaker,
Bulkhead, Fallback
Timeout, Retry, CircuitBreaker
(Bulkhead)
Request-Tracing (MicroProfile Rest Client)
Metrics
Health Checks
JWT + RBAC
Konfiguration: MicroProfile Config
Ziel: mehrere Stage-abhängige Werte von aussen
überschreiben
●
System Properties (400)
●
Environment Variables (300)
●
microprofile-config.properties
im Classpath (100)
abc.key=valueABC
xyz.key=123
@Inject
@ConfigProperty(name=“abc.key“)
private String abc;
@Inject
@ConfigProperty(name=“xyz.key“)
private Long xyz;
Konfiguration: K8S ConfigMap
apiVersion: v1
kind: Pod
metadata:
name: servicea-pod
spec:
containers:
- name: ...
envFrom:
- configMapRef:
name: servicea-config
restartPolicy: Never
/bin/sh -c env
abc_key=valueABC
xyz_key=123
kubectl create configmap servicea-config 
--from-file=servicea/config.properties apiVersion: v1
kind: ConfigMap
metadata:
name: servicea-config
namespace: default
data:
abc_key: valueABC
xyz_key: „123“
Konfiguration: Stolperstein
Namenskonflikt der Variablen
K8S Environment Variables:
"must be a C identifier
(matching regex [A-Za-z_][A-Za-z0-9_]*)"
bei MicroProfile: entsprechend Package-Konvention mit .
Seit MicroProfile Config 1.3:
Mapping von non-alphanumeric auf .
(Mapping-Reihenfolge: abc.key, abc_key, ABC_KEY)
Konfiguration: Reload
Environment-
Variablen können nur
bei Start des Pods
gesetzt werden!
Ausweg: K8S
ConfigMap als
Volume mounten
@Inject
@ConfigProperty(name="xyz.key", defaultValue="100")
private javax.inject.Provider<Long> xyz;
public interface ConfigSource {
Map<String, String> getProperties();
default Set<String> getPropertyNames(){...}
default int getOrdinal(){...}
String getValue(String propertyName);
String getName();
...
}
Timeout
Retry
CircuitBreaker
Bulkhead
Fallback
Resilienz
●
CircuitBreaker / Bulkhead (MicroProfile)
– Semaphor (synchron)
– Threadpool (asynchron)
●
CircuitBreaker im Sidecar wirkt wie Bulkhead
●
Fallback: fachlich motiviert Sidecar
Timeout
Retry
CircuitBreaker
Resilienz
●
CircuitBreaker = Bulkhead
●
Vorsicht: doppelte Ausführung
●
Nur Fallback aktivieren
apiVersion: v1
kind: ConfigMap
metadata:
name: res_off
data: MP_Fault_Tolerance_NonFallback_Enabled: "false"
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: reviews
spec:
host: reviews
subsets:
- name: v1
labels:
version: v1
trafficPolicy:
connectionPool:
http:
http1MaxPendingRequests: 2
tcp:
maxConnections: 5
Resilienz: wer die Wahl hat...
●
Frameworks (Hystrix (eol!), Resilience4J, Failsafe, MicroProfile Fault Tolerance)
ABER:
●
richtiges Pattern und Werte: erst in Produktion erkannt (neues Deployment!)
●
Abhängigkeit Bibliothek zur Programmiersprache
●
Versionsmix der Bibliotheken über alle Services hinweg
●
Abhängigkeiten zu anderen Frameworks (Service-Call → LoadBalancing → Service Registry)
●
Service Registry für andere Services verwendbar? Doppelte Service Registry? (hohe
Kopplung der Services an Infrastruktur-Komponenten!)
●
Lernkurve bzgl. vieler Frameworks bei jedem Entwickler-Team
Resilienz Fazit
●
Probleme der Infrastruktur sollten auch dort behoben werden!
●
Fallback-Schalter
●
Healthchecks durch Sidecar
auf Loadbalancing Pool
●
Istio Fault Injection:
Resilienz einfach testen
●
Globale Wirkung
Resilienz im Service Mesh!
apiVersion:networking.istio.io/
v1alpha3
kind: VirtualService
metadata:
name: ratings
...
spec:
hosts:
- ratings
http:
- fault:
delay:
fixedDelay: 7s
percent: 100
Tracing
●
Vom Sidecar oder Istio-Gateway erzeugt
●
Service schickt Header mit (MP OpenTracing)
●
Istio: Jaeger (OpenZipkin, LightStep)
●
Trace-Anzeige über alle beteiligte Komponenten
●
Datenmenge
– Reduktion: PILOT_TRACE_SAMPLING = "0.1"
– Tracing trotzdem erzwingen: Header x-envoy-force-trace = „true“
x-request-id
x-b3-traceid
x-b3-spanid
x-b3-parentspanid
x-b3-sampled
x-b3-flags
x-ot-span-context
MicroProfile Rest Client
●
Trace-Header von Client
– JAX-RS Client
– MicroProfile Rest Client erst seit Spec 1.2 (02/2019)
●
Namensproblem bei Config (geht, … nicht beschrieben in der
Spec!)
MicroProfile Rest Client
@RegisterRestClient
public interface MyClient {
@GET
@Path("/hallo")
public String hallo();
...
@ApplicationScoped
public class MyService {
@Inject
@RestClient
private MyClient client;
...
String txt = client.hallo();
de.company.remote.MyClient/mp-rest/uri=...
apiVersion: v1
kind: ConfigMap
metadata:
name: servicea-config
namespace: default
data:
de_company_remote_myclient_mp_rest_uri: ...
Health und Metrics
●
Service: MicroProfile Health
●
Service: MicroProfile Metrics
●
App-Server: Openliberty
●
Sidecar
●
Sammlung und Query
●
Graphische Anzeige
http://host/health
<feature>monitor-1.0</feature>
http://host/metrics/...
JWT und RBAC
●
Istio übernimmt mTLS transparent für Service
●
Istio und MicroProfile:
– JWT Prüfung
– RBAC
●
Mögliche Kombination:
– Istio: JWT Prüfung
– MicroProfile: RBAC und programmatic security
mTLS und JWT Prüfung
apiVersion:
"authentication.istio.io/v1alpha1"
kind: "MeshPolicy"
metadata:
name: "default"
spec:
peers:
- mtls: {}
apiVersion: "authentication.istio.io/v1alpha1"
kind: "Policy"
metadata:
name: "jwt-example"
spec:
targets: {}
origins:
- jwt:
issuer: "https://mysecurity.mycompany.de"
jwksUri: "https://mysecurity.mycompany.de/jwtkey"
principalBinding: USE_ORIGIN
RBAC + programmatic Security
@LoginConfig(authMethod = "MP-JWT",
realmName = "MY-REALM")
@ApplicationPath("/")
public class MyApplication extends Application {
}
@Path("/myendpoint")
@DenyAll
public class MyEndpoint {
@Inject
private JsonWebToken jwt;
@Resource
Principal principal;
...
}
Zusatznutzen von Istio/K8S
●
Service Discovery and load balancing im Sidecar (client-side)
●
Traffic Managment: Canary (z.B. 5%), Content Based Routing,
A/B Deployment, URL rewrite, Rate Limiting
●
mTLS
●
Fault Injection, Traffic Shadowing
●
Steuerung Tracing Output
Fazit
Funktionale Ergänzung
• Zusatznutzen durch Istio
• Tracing (Jaeger), Metrics (Prometheus), zusätzliche HealthChecks
Funktionale Überlappung
• Resilienz mit Schalter
• JWT und RBAC
Inkompatibles (behoben)
• Namenskonflikt bei Config
• Rest Client Tracing

Service Mesh mit Istio und MicroProfile - eine harmonische Kombination?

  • 1.
    Service Mesh mitIstio und MicroProfile - eine harmonische Kombination? Michael Hofmann Hofmann IT-Consulting info@hofmann-itconsulting.de https://hofmann-itconsulting.de
  • 2.
    Service Mesh „The termservice mesh is used to describe the network of microservices that make up such application and the interactions between them.“ (istio.io) Anzahl der Services steigt ... Ohne Werkzeug lässt sich Service Mesh (Big Ball of Mud) nicht beherrschen! Quelle: https://twitter.com/Werner/status/741673514567143424 (Werner Vogels, CTO Amazon)
  • 3.
    Service Mesh Funktionen ● ServiceDiscovery ● Load Balancing ● Resilienz ● Dynamic Routing (Blue/Green Deployments, Canary Releasing, Traffic Shadowing) ● Observability (Metrics, Tracing) ● End-to-End Authentication, Access Control ● Rate Limiting
  • 4.
    Service Mesh womit? VergleichIstio und Linkerd: https://abhishek-tiwari.com/a-sidecar-for-your-service-mesh/
  • 5.
    Istio IBM (Amalgam8) content-based routing (extended) servicediscovery resilience load balancing Google (Istio) content-based routing rate limiting ACLs telemetry Kubernetes integration Lyft (Envoy) proxy (sidecar)
  • 6.
  • 7.
    What is EclipseMicroProfile? ● Eclipse MicroProfile is an open-source community specification for Enterprise Java microservices ● A community of individuals, organizations, and vendors collaborating within an open source (Eclipse) project to bring microservices to the Enterprise Java community 7 Quelle: microprofile.io
  • 8.
    Community - individuals,organizations, vendors 8 Quelle: microprofile.io
  • 9.
  • 10.
    Eclipse MicroProfile 2.2(Feb 2019) 10 MicroProfile 2.2 JAX-RS 2.1JSON-P 1.1CDI 2.0 Config 1.3 Fault Tolerance 2.0 JWT Propagation 1.1 Health Check 1.0 Metrics 1.1 Open Tracing 1.3 Open API 1.1 = Updated = No change from last release (MicroProfile 2.1) = New Rest Client 1.2 JSON-B 1.0 Quelle: microprofile.io
  • 11.
    MicroProfile vs. Istio(Kubernetes) Funktionalität MicroProfile Istio Anwendungs- Konfiguration Kubernetes ConfigMap Resilienz Timeout, Retry, CircuitBreaker, Bulkhead, Fallback Timeout, Retry, CircuitBreaker (Bulkhead) Request-Tracing (MicroProfile Rest Client) Metrics Health Checks JWT + RBAC
  • 12.
    Konfiguration: MicroProfile Config Ziel:mehrere Stage-abhängige Werte von aussen überschreiben ● System Properties (400) ● Environment Variables (300) ● microprofile-config.properties im Classpath (100) abc.key=valueABC xyz.key=123 @Inject @ConfigProperty(name=“abc.key“) private String abc; @Inject @ConfigProperty(name=“xyz.key“) private Long xyz;
  • 13.
    Konfiguration: K8S ConfigMap apiVersion:v1 kind: Pod metadata: name: servicea-pod spec: containers: - name: ... envFrom: - configMapRef: name: servicea-config restartPolicy: Never /bin/sh -c env abc_key=valueABC xyz_key=123 kubectl create configmap servicea-config --from-file=servicea/config.properties apiVersion: v1 kind: ConfigMap metadata: name: servicea-config namespace: default data: abc_key: valueABC xyz_key: „123“
  • 14.
    Konfiguration: Stolperstein Namenskonflikt derVariablen K8S Environment Variables: "must be a C identifier (matching regex [A-Za-z_][A-Za-z0-9_]*)" bei MicroProfile: entsprechend Package-Konvention mit . Seit MicroProfile Config 1.3: Mapping von non-alphanumeric auf . (Mapping-Reihenfolge: abc.key, abc_key, ABC_KEY)
  • 15.
    Konfiguration: Reload Environment- Variablen könnennur bei Start des Pods gesetzt werden! Ausweg: K8S ConfigMap als Volume mounten @Inject @ConfigProperty(name="xyz.key", defaultValue="100") private javax.inject.Provider<Long> xyz; public interface ConfigSource { Map<String, String> getProperties(); default Set<String> getPropertyNames(){...} default int getOrdinal(){...} String getValue(String propertyName); String getName(); ... }
  • 16.
    Timeout Retry CircuitBreaker Bulkhead Fallback Resilienz ● CircuitBreaker / Bulkhead(MicroProfile) – Semaphor (synchron) – Threadpool (asynchron) ● CircuitBreaker im Sidecar wirkt wie Bulkhead ● Fallback: fachlich motiviert Sidecar Timeout Retry CircuitBreaker
  • 17.
    Resilienz ● CircuitBreaker = Bulkhead ● Vorsicht:doppelte Ausführung ● Nur Fallback aktivieren apiVersion: v1 kind: ConfigMap metadata: name: res_off data: MP_Fault_Tolerance_NonFallback_Enabled: "false" apiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata: name: reviews spec: host: reviews subsets: - name: v1 labels: version: v1 trafficPolicy: connectionPool: http: http1MaxPendingRequests: 2 tcp: maxConnections: 5
  • 18.
    Resilienz: wer dieWahl hat... ● Frameworks (Hystrix (eol!), Resilience4J, Failsafe, MicroProfile Fault Tolerance) ABER: ● richtiges Pattern und Werte: erst in Produktion erkannt (neues Deployment!) ● Abhängigkeit Bibliothek zur Programmiersprache ● Versionsmix der Bibliotheken über alle Services hinweg ● Abhängigkeiten zu anderen Frameworks (Service-Call → LoadBalancing → Service Registry) ● Service Registry für andere Services verwendbar? Doppelte Service Registry? (hohe Kopplung der Services an Infrastruktur-Komponenten!) ● Lernkurve bzgl. vieler Frameworks bei jedem Entwickler-Team
  • 19.
    Resilienz Fazit ● Probleme derInfrastruktur sollten auch dort behoben werden! ● Fallback-Schalter ● Healthchecks durch Sidecar auf Loadbalancing Pool ● Istio Fault Injection: Resilienz einfach testen ● Globale Wirkung Resilienz im Service Mesh! apiVersion:networking.istio.io/ v1alpha3 kind: VirtualService metadata: name: ratings ... spec: hosts: - ratings http: - fault: delay: fixedDelay: 7s percent: 100
  • 20.
    Tracing ● Vom Sidecar oderIstio-Gateway erzeugt ● Service schickt Header mit (MP OpenTracing) ● Istio: Jaeger (OpenZipkin, LightStep) ● Trace-Anzeige über alle beteiligte Komponenten ● Datenmenge – Reduktion: PILOT_TRACE_SAMPLING = "0.1" – Tracing trotzdem erzwingen: Header x-envoy-force-trace = „true“ x-request-id x-b3-traceid x-b3-spanid x-b3-parentspanid x-b3-sampled x-b3-flags x-ot-span-context
  • 21.
    MicroProfile Rest Client ● Trace-Headervon Client – JAX-RS Client – MicroProfile Rest Client erst seit Spec 1.2 (02/2019) ● Namensproblem bei Config (geht, … nicht beschrieben in der Spec!)
  • 22.
    MicroProfile Rest Client @RegisterRestClient publicinterface MyClient { @GET @Path("/hallo") public String hallo(); ... @ApplicationScoped public class MyService { @Inject @RestClient private MyClient client; ... String txt = client.hallo(); de.company.remote.MyClient/mp-rest/uri=... apiVersion: v1 kind: ConfigMap metadata: name: servicea-config namespace: default data: de_company_remote_myclient_mp_rest_uri: ...
  • 23.
    Health und Metrics ● Service:MicroProfile Health ● Service: MicroProfile Metrics ● App-Server: Openliberty ● Sidecar ● Sammlung und Query ● Graphische Anzeige http://host/health <feature>monitor-1.0</feature> http://host/metrics/...
  • 24.
    JWT und RBAC ● Istioübernimmt mTLS transparent für Service ● Istio und MicroProfile: – JWT Prüfung – RBAC ● Mögliche Kombination: – Istio: JWT Prüfung – MicroProfile: RBAC und programmatic security
  • 25.
    mTLS und JWTPrüfung apiVersion: "authentication.istio.io/v1alpha1" kind: "MeshPolicy" metadata: name: "default" spec: peers: - mtls: {} apiVersion: "authentication.istio.io/v1alpha1" kind: "Policy" metadata: name: "jwt-example" spec: targets: {} origins: - jwt: issuer: "https://mysecurity.mycompany.de" jwksUri: "https://mysecurity.mycompany.de/jwtkey" principalBinding: USE_ORIGIN
  • 26.
    RBAC + programmaticSecurity @LoginConfig(authMethod = "MP-JWT", realmName = "MY-REALM") @ApplicationPath("/") public class MyApplication extends Application { } @Path("/myendpoint") @DenyAll public class MyEndpoint { @Inject private JsonWebToken jwt; @Resource Principal principal; ... }
  • 27.
    Zusatznutzen von Istio/K8S ● ServiceDiscovery and load balancing im Sidecar (client-side) ● Traffic Managment: Canary (z.B. 5%), Content Based Routing, A/B Deployment, URL rewrite, Rate Limiting ● mTLS ● Fault Injection, Traffic Shadowing ● Steuerung Tracing Output
  • 28.
    Fazit Funktionale Ergänzung • Zusatznutzendurch Istio • Tracing (Jaeger), Metrics (Prometheus), zusätzliche HealthChecks Funktionale Überlappung • Resilienz mit Schalter • JWT und RBAC Inkompatibles (behoben) • Namenskonflikt bei Config • Rest Client Tracing