私は自分の問題を説明するために非常に具体的な方法を使用しますが、これは抽象的な方法で説明するよりも具体的にする方が良いと思います...
たとえば、Kubernetesクラスタの外部であるがネットワーク内にMongoDBレプリカが設定されているとします。レプリカセットのすべてのメンバーのIPアドレスは、アプリサーバーとデータベースサーバーの/ etc/hostsによって解決されました。
実験/移行フェーズでは、kubernetesポッドからこれらのmongodbサーバーにアクセスする必要があります。ただし、kubernetesでは、pods/containersの/ etc/hostsにカスタムエントリを追加できないようです。
MongoDBレプリカセットはすでに大きなデータセットで動作しているため、クラスターに新しいレプリカセットを作成することはできません。
私はGKEを使用しているので、kube-dns名前空間のリソースを変更することは避けるべきだと思います。私のニーズに適するようにkube-dnを構成または置換することは、最後に試すことです。
Kubernetesクラスター内のカスタムホスト名のIPアドレスを解決する方法はありますか?
これは単なるアイデアですが、kube2skyがconfigmapのいくつかのエントリを読み取り、それらをdnsレコードとして使用できる場合、それは素晴らしいことです。例えばrepl1.mongo.local: 192.168.10.100
。
編集:私はこの質問を https://github.com/kubernetes/kubernetes/issues/12337 から参照しました
更新:2017-07-03 Kunbernetes 1.7がサポートするようになりました HostAliasesを使用してポッド/ etc/hostsにエントリを追加する 。
解決策はkube-dnsではなく、/ etc/hostsについてです。とにかく、次のトリックは今のところうまくいくようです...
編集:/ etc/hostsを変更すると、kubernetesシステムとの競合状態になる可能性があります。再試行します。
1)configMapを作成する
apiVersion: v1
kind: ConfigMap
metadata:
name: db-hosts
data:
hosts: |
10.0.0.1 db1
10.0.0.2 db2
2)ensure_hosts.sh
という名前のスクリプトを追加します。
#!/bin/sh
while true
do
grep db1 /etc/hosts > /dev/null || cat /mnt/hosts.append/hosts >> /etc/hosts
sleep 5
done
chmod a+x ensure_hosts.sh
を忘れないでください。
3)ラッパースクリプトstart.sh
画像を追加します
#!/bin/sh
$(dirname "$(realpath "$0")")/ensure_hosts.sh &
exec your-app args...
chmod a+x start.sh
を忘れないでください
4)configmapをボリュームとして使用し、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
...
Kubernetesの外部のホストまたはIPにアクセスするには、一種の外部名が必要です。
以下は私のために働いた。
{
"kind": "Service",
"apiVersion": "v1",
"metadata": {
"name": "tiny-server-5",
"namespace": "default"
},
"spec": {
"type": "ExternalName",
"externalName": "192.168.1.15",
"ports": [{ "port": 80 }]
}
}
参考までに、参照されている githubの問題をチェックしない人のための代替ソリューション 。
セレクターやClusterIPを指定しないことで、Kubernetesで「外部」サービスを定義できます。外部IPを指す対応するエンドポイントも定義する必要があります。
Kubernetesドキュメント から:
{ "種類": "サービス"、 "apiVersion": "v1"、 "メタデータ":{ "名前" : "my-service" }、 "spec":{ "ports": { "protocol": "TCP "、 " port ":80、 " targetPort ":9376 } } } { "kind": "Endpoints"、 "apiVersion": "v1"、 "metadata":{ "name": "my -service " }、 "サブセット ": { "アドレス ": {" ip ":" 1.2.3.4 "} 、 "ポート ": {"ポート ":9376} } }
これにより、コンテナー内のアプリをmy-service:9376
にポイントでき、トラフィックは1.2.3.4:9376
に転送されます
制限:
something.like.this
)は使用できません。これは、おそらくyour-service
ではなくyourservice.domain.tld
だけを指すようにアプリを変更する必要があることを意味します。ExternalName
タイプのサービスを使用して一種のDNSエイリアスを定義できます。ConfigMapを使用することはDNSを設定するためのより良い方法のようですが、(私の意見では)いくつかのレコードを追加するだけでは少し重いです。そこで、Docker CMD
によって実行されるシェルスクリプトによって/etc/hosts
にレコードを追加します。
例えば:
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...
ポッドで複数のコンテナを実行する場合は、各コンテナにスクリプトを追加する必要があることに注意してください。kubernetesはコンテナをランダムに開始するため、/etc/hosts
は別のコンテナ(後で開始する)によってオーバーライドされる可能性があります)。