Je rassemble une preuve de concept pour aider à identifier les pièges en utilisant Spring Boot/Netflix OSS et Kubernetes ensemble. Il s'agit également de prouver des technologies connexes telles que Prometheus et Graphana.
J'ai une configuration de service Eureka qui démarre sans problème dans mon clouster Kubernetes. Ceci est nommé découverte et a reçu le nom "discovery-1551420162-iyz2c" lorsqu'il est ajouté à K8 à l'aide
kubectl run discovery --image=xyz/discovery-microservice --replicas=1 --port=8761
Pour mon serveur de configuration, j'essaie d'utiliser Eureka sur la base d'une URL logique, donc dans mon bootstrap.yml, j'ai
server:
port: 8889
eureka:
instance:
hostname: configserver
client:
registerWithEureka: true
fetchRegistry: true
serviceUrl:
defaultZone: http://discovery:8761/eureka/
spring:
cloud:
config:
server:
git:
uri: https://github.com/xyz/microservice-config
et je commence cela en utilisant
kubectl run configserver --image=xyz/config-microservice --replicas=1 --port=8889
Ce service finit par s'exécuter sous le nom de configserver-3481062421-tmv4d. Je vois alors des exceptions dans les journaux du serveur de configuration alors qu'il essaie de localiser l'instance eureka et ne le peut pas.
J'ai la même configuration pour cela en utilisant docker-compose localement avec des liens et il démarre les différents conteneurs sans problème.
discovery:
image: xyz/discovery-microservice
ports:
- "8761:8761"
configserver:
image: xyz/config-microservice
ports:
- "8888:8888"
links:
- discovery
Comment dois-je configurer quelque chose comme eureka.client.serviceUri pour que mes microserices puissent localiser leurs homologues sans connaître les adresses IP fixes au sein du cluster K8?
Comment puis-je configurer quelque chose comme eureka.client.serviceUri?
Vous devez avoir un Kubernetes service au-dessus des pods/déploiements eureka qui vous fournira alors une adresse IP et un numéro de port référençables. Et puis utilisez cette adresse référentielle pour rechercher le service Eureka, au lieu de "8761".
Vous ne devriez pas avoir plus d'un pod/réplique d'Eureka par service k8s (rappelez-vous, les pods sont éphémères, vous avez besoin d'une adresse IP/nom de domaine référençable pour le registre de services eureka). Pour atteindre la haute disponibilité (HA), faites tourner plus de services k8s avec un pod dans chacun.
Donc, maintenant vous avez un IP/nom de domaine référençable (IP du service k8s) pour chacun de vos Eureka .. maintenant il peut s'enregistrer les uns les autres.
Vous vous sentez exagéré? Si tous vos services sont dans le même espace de noms kubernetes , vous pouvez réaliser tout (enfin, presque tout, sauf l'équilibrage de charge côté client) qu'eureka offre via le service k8s + Module complémentaire KubeDNS. Lisez ceci article par Christian Posta
Au lieu de Services avec un pod chacun, vous pouvez utiliser StatefulSets comme Stefan Ocke indiqué.
Comme un déploiement, un StatefulSet gère des pods basés sur une spécification de conteneur identique. Contrairement à un déploiement, un StatefulSet conserve une identité collante pour chacun de ses pods. Ces pods sont créés à partir de la même spécification, mais ne sont pas interchangeables: chacun a un identifiant persistant qu'il conserve à travers toute replanification.
Concernant la configuration HA d'Eureka dans Kubernetes: vous pouvez (pendant ce temps) utiliser un StatefulSet pour cela au lieu de créer un service pour chacun exemple. StatefulSet garantit une identité réseau stable pour chaque instance que vous créez. Par exemple, le déploiement pourrait ressembler au yaml suivant (StatefulSet + headless Service). Il existe deux instances d'Eureka ici, selon les règles de dénomination DNS pour StatefulSets (en supposant que l'espace de noms est "par défaut"):
eureka-0.eureka.default.svc.cluster.local et
eureka-1.eureka.default.svc.cluster.local
Tant que vos pods sont dans le même espace de noms, ils peuvent également atteindre Eureka:
Remarque: L'image de docker utilisée dans l'exemple provient de https://github.com/stefanocke/eureka . Vous voudrez peut-être choisir ou construire le vôtre.
---
apiVersion: v1
kind: Service
metadata:
name: eureka
labels:
app: eureka
spec:
ports:
- port: 8761
name: eureka
clusterIP: None
selector:
app: eureka
---
apiVersion: apps/v1beta2
kind: StatefulSet
metadata:
name: eureka
spec:
serviceName: "eureka"
replicas: 2
selector:
matchLabels:
app: eureka
template:
metadata:
labels:
app: eureka
spec:
containers:
- name: eureka
image: stoc/eureka
ports:
- containerPort: 8761
env:
- name: MY_POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
# Due to camelcase issues with "defaultZone" and "preferIpAddress", _Java_OPTIONS is used here
- name: _Java_OPTIONS
value: -Deureka.instance.preferIpAddress=false -Deureka.client.serviceUrl.defaultZone=http://eureka-0.eureka:8761/eureka/,http://eureka-1.eureka:8761/eureka/
- name: EUREKA_CLIENT_REGISTERWITHEUREKA
value: "true"
- name: EUREKA_CLIENT_FETCHREGISTRY
value: "true"
# The hostnames must match with the the eureka serviceUrls, otherwise the replicas are reported as unavailable in the eureka dashboard
- name: EUREKA_INSTANCE_HOSTNAME
value: ${MY_POD_NAME}.eureka
# No need to start the pods in order. We just need the stable network identity
podManagementPolicy: "Parallel"
Vous devez installer un serveur kubernetes kube-dns pour résoudre les noms avec leurs adresses IP, puis exposer vos pods eureka en tant que service. (voir kubernetes docs ) pour plus d'informations sur la création de DNS et de services. @random_dude, que sera-t-il le cas si j'avais l'habitude de créer 2 ou 3 répliques d'eureka? il s'est avéré que lorsque je monte un micro-service 'X' je serai enregistré dans toutes les répliques eureka, mais quand il sera en panne, une seule réplique recevra la mise à jour! les autres considèrent toujours l'instance de micro-service comme en cours d'exécution