这是一种向kube-dns添加任意记录的方法吗?

时间:2016-05-11 15:14:17

标签: kubernetes google-kubernetes-engine

我将使用非常具体的方式来解释问题,但我认为这比抽象问题更具体...

比如说,在kubernetes集群之外但在网络中有一个mongo db副本集。副本集的所有成员的IP地址由应用服务器和数据库服务器中的/ etc / hosts解析。

在实验/过渡阶段,我需要从kubernetes pod访问那些mongo db服务器。 但是,kubernetes似乎不允许在pods /容器中向/ etc / hosts添加自定义条目。

mongo db副本集已经在处理大型数据集,因此无法在群集中创建新的副本集。

Becaseu我使用GKE,我想应该避免更改kube-dns命名空间中的任何资源。配置或替换kube-dns以适合我的需要是最后一件事。

是否可以解析kubernetes集群中自定义主机名的IP地址?

这只是一个想法,但如果kube2sky可以读取一些configmap的条目并将它们用作dns记录,那么它就会很棒。 例如repl1.mongo.local: 192.168.10.100

编辑:我从https://github.com/kubernetes/kubernetes/issues/12337

引用了这个问题

5 个答案:

答案 0 :(得分:10)

访问kubernetes之外的主机或ips需要一种外部名称。

以下对我有用。

{
    "kind": "Service",
    "apiVersion": "v1",
    "metadata": {
        "name": "tiny-server-5",
        "namespace": "default"
    },
    "spec": {
        "type": "ExternalName",
        "externalName": "192.168.1.15",
        "ports": [{ "port": 80 }]
    }
}

答案 1 :(得分:4)

对于记录,是那些未检查引用的github issue的人的替代解决方案。

您可以定义"外部"通过不指定任何选择器或ClusterIP在Kubernetes中提供服务。您还必须定义指向外部IP的相应端点。

来自Kubernetes documentation

{
    "kind": "Service",
    "apiVersion": "v1",
    "metadata": {
        "name": "my-service"
    },
    "spec": {
        "ports": [
            {
                "protocol": "TCP",
                "port": 80,
                "targetPort": 9376
            }
        ]
    }
}
{
    "kind": "Endpoints",
    "apiVersion": "v1",
    "metadata": {
        "name": "my-service"
    },
    "subsets": [
        {
            "addresses": [
                { "ip": "1.2.3.4" }
            ],
            "ports": [
                { "port": 9376 }
            ]
        }
    ]
}

有了这个,您可以将容器中的应用指向my-service:9376,并将流量转发到1.2.3.4:9376

限制:

  • 使用的DNS名称必须仅字母,数字或短划线。您无法使用多级名称(something.like.this)。这意味着您可能需要将应用修改为仅指向your-service,而不是yourservice.domain.tld
  • 您只能指向特定的IP,而不是DNS名称。为此,您可以使用ExternalName类型服务定义一种DNS别名。

答案 2 :(得分:3)

更新时间:2017-07-03 Kunbernetes 1.7现在支持caniuse.com

解决方案不是关于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
        ...

答案 3 :(得分:1)

使用configMap似乎是更好的设置DNS的方法,但是在添加一些记录时(在我看来)它有点重。所以我通过docker /etc/hosts执行的shell脚本将记录添加到CMD

例如:

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可能会被另一个容器覆盖(从以后开始。)

答案 4 :(得分:1)

现在可以使用/etc/hosts将条目添加到Pod的.spec.hostAliases

例如:要将foo.localbar.local解析为127.0.0.1foo.remotebar.remote10.1.2.3,您可以在以下位置为Pod配置HostAliases .spec.hostAliases

apiVersion: v1
kind: Pod
metadata:
  name: hostaliases-pod
spec:
  restartPolicy: Never
  hostAliases:
  - ip: "127.0.0.1"
    hostnames:
    - "foo.local"
    - "bar.local"
  - ip: "10.1.2.3"
    hostnames:
    - "foo.remote"
    - "bar.remote"
  containers:
  - name: cat-hosts
    image: busybox
    command:
    - cat
    args:
    - "/etc/hosts"