web-dev-qa-db-fra.com

Est-ce un moyen d'ajouter des enregistrements arbitraires à kube-dns?

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

9
hiroshi

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
        ...
3
hiroshi

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 }]
    }
}
10
Gapmeister66

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:

  • Le nom DNS utilisé doit être uniquement des lettres, des chiffres ou des tirets . Vous ne pouvez pas utiliser de noms à plusieurs niveaux (something.like.this). Cela signifie que vous devez probablement modifier votre application pour pointer uniquement vers your-service et non pas yourservice.domain.tld.
  • Vous pouvez uniquement pointer sur une adresse IP spécifique, pas sur un nom DNS. Pour cela, vous pouvez définir un type d'alias DNS avec un service de type ExternalName.
4
morallo

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).

1
gaga5lala