Je vais utiliser un moyen très spécifique pour expliquer le problème, mais je pense qu'il vaut mieux être spécifique que le problème abstrait ...
Supposons qu’un jeu de répliques mongo db se trouve en dehors d’un cluster kubernetes mais dans un réseau. Les adresses IP de tous les membres du jeu de réplicas ont été résolues par/etc/hosts dans les serveurs d'applications et les serveurs de base de données.
Dans une phase d’expérience/transition, je dois accéder à ces serveurs mongo db à partir de pods kubernetes. Cependant, kubernetes ne semble pas autoriser l'ajout d'une entrée personnalisée à/etc/hosts dans les pods/conteneurs.
Les jeux de répliques mongo db fonctionnent déjà avec un ensemble de données volumineux, la création d’un nouveau jeu de réplicas dans le cluster n’est pas une option.
Comme j'utilise GKE, il est préférable d'éviter de modifier les ressources de l'espace de noms kube-dns. Configurer ou remplacer kube-dns pour qu’il soit adapté à mes besoins est la dernière chose à faire.
Est-ce un moyen de résoudre l'adresse IP de noms d'hôtes personnalisés dans un cluster Kubernetes?
C’est juste une idée, mais si kube2sky peut lire certaines entrées de configmap et les utiliser comme enregistrements DNS, c’est génial. par exemple. repl1.mongo.local: 192.168.10.100
.
EDIT: J'ai référencé cette question de https://github.com/kubernetes/kubernetes/issues/12337
MISE À JOUR: 2017-07-03 Kunbernetes 1.7 prend désormais en charge Ajout d'entrées dans Pod/etc/hosts avec HostAliases .
La solution ne concerne pas kube-dns, mais /etc/hosts.Anyway, le truc suivant semble fonctionner jusqu’à présent ...
EDIT: La modification de/etc/hosts peut avoir une condition de concurrence avec le système kubernetes. Laissez-le réessayer.
1) créer un configMap
apiVersion: v1
kind: ConfigMap
metadata:
name: db-hosts
data:
hosts: |
10.0.0.1 db1
10.0.0.2 db2
2) Ajoutez un script nommé ensure_hosts.sh
.
#!/bin/sh
while true
do
grep db1 /etc/hosts > /dev/null || cat /mnt/hosts.append/hosts >> /etc/hosts
sleep 5
done
N'oubliez pas chmod a+x ensure_hosts.sh
.
3) Ajoutez un script wrapper start.sh
votre image
#!/bin/sh
$(dirname "$(realpath "$0")")/ensure_hosts.sh &
exec your-app args...
N'oubliez pas chmod a+x start.sh
4) Utilisez la configmap en tant que volume et lancez start.sh
apiVersion: extensions/v1beta1
kind: Deployment
...
spec:
template:
...
spec:
volumes:
- name: hosts-volume
configMap:
name: db-hosts
...
containers:
command:
- ./start.sh
...
volumeMounts:
- name: hosts-volume
mountPath: /mnt/hosts.append
...
Un type de nom externe est requis pour accéder aux hôtes ou ips en dehors des kubernetes.
Ce qui suit a fonctionné pour moi.
{
"kind": "Service",
"apiVersion": "v1",
"metadata": {
"name": "tiny-server-5",
"namespace": "default"
},
"spec": {
"type": "ExternalName",
"externalName": "192.168.1.15",
"ports": [{ "port": 80 }]
}
}
Pour mémoire, une solution alternative pour ceux qui ne vérifient pas le problème référencé github .
Vous pouvez définir un service "externe" dans Kubernetes, en ne spécifiant aucun sélecteur ou ClusterIP. Vous devez également définir un noeud final correspondant à votre adresse IP externe.
Dans la documentation Kubernetes :
{ "kind": "Service", "apiVersion": "v1", "métadonnées": { "nom" : "mon-service" }, "spec": { "ports": [ { "protocole": "TCP ", " port ": 80, " targetPort ": 9376 } ] } } { "kind": "Points de terminaison", "apiVersion": "v1", "métadonnées": { "name": "my -service " }, " sous-ensembles ": [ { " adresses ": [ {" ip ":" 1.2.3.4 "} ], " ports ": [ {" port ": 9376} ] ]. ] }
Avec cela, vous pouvez diriger votre application à l'intérieur des conteneurs vers my-service:9376
et le trafic devrait être transféré vers 1.2.3.4:9376
Limites:
something.like.this
). Cela signifie que vous devez probablement modifier votre application pour pointer uniquement vers your-service
et non pas yourservice.domain.tld
.ExternalName
.Utiliser configMap semble être un meilleur moyen de configurer le DNS, mais c’est un peu lourd lorsque vous ajoutez quelques enregistrements (à mon avis). J'ajoute donc des enregistrements à /etc/hosts
par le script shell exécuté par le docker CMD
.
par exemple:
Dockerfile
...(ignore)
COPY run.sh /tmp/run.sh
CMD bash /tmp/run.sh
run.sh
#!/bin/bash
echo repl1.mongo.local 192.168.10.100 >> /etc/hosts
# some else command...
Notez que si vous exécutez PLUS D'UN conteneur dans un pod, vous devez ajouter un script dans chaque conteneur , car kubernetes démarre le conteneur de manière aléatoire, /etc/hosts
peut être remplacé par un autre conteneur (qui commence plus tard).