首页 > 解决方案 > dnsConfig 在 GKE 中被跳过

问题描述

面临以下问题:我需要在某些 pod 上添加搜索域才能与无头服务通信。Kubernetes 文档建议设置一个 dnsConfig 并在其中设置所有内容。这就是我所做的。还有一个限制,只能设置 6 个搜索域。清单的一部分:

    spec:
  hostname: search
  dnsPolicy: ClusterFirst
  dnsConfig:
    searches:
      - indexer.splunk.svc.cluster.local
  containers:
  - name: search

不幸的是,它没有效果,并且目标 pod 上的 resolv.conf 文件不包含此搜索域:

search splunk.svc.cluster.local svc.cluster.local cluster.local us-east4-c.c.'project-id'.internal c.'project-id'.internal google.internal
nameserver 10.39.240.10
options ndots:5

快速查看此配置后,我发现当前指定了 6 个搜索域,这可能是未添加新搜索域的原因。您可以手动添加,一切都会正常工作,但这不是我想要实现的。

您有任何想法如何绕过此限制吗?

PS 将 dnsPolicy 设置为 None 也不是设置预启动挂钩以添加我的搜索区域的选项。

---
# Search-head deployment
apiVersion: apps/v1
kind: Deployment
metadata:
  name: search
  namespace: splunk
  labels:
    app: splunk
spec:
  replicas: 1
  selector:
    matchLabels:
      app: splunk
  template:
    metadata:
      labels:
        app: splunk
    spec:
      hostname: search
      dnsPolicy: ClusterFirst
      dnsConfig:
        searches:
          - indexer.splunk.svc.cluster.local
      containers:
      - name: search
        image: splunk/splunk
        env:
          - name: SPLUNK_START_ARGS
            value: "--accept-license"
          - name: SPLUNK_PASSWORD
            valueFrom:
              secretKeyRef:
                name: splunk-password
                key: password
          - name: SPLUNK_ROLE
            value: splunk_search_head
          - name: SPLUNK_SEARCH_HEAD_URL
            value: search
          - name: SPLUNK_INDEXER_URL # TODO: make this part dynamic.
            value: indexer-0,indexer-1
        ports:
          - name: web
            containerPort: 8000
          - name: mgmt
            containerPort: 8089
          - name: kv
            containerPort: 8191
        volumeMounts:
        - mountPath: /opt/splunk/var
          name: sh-volume
      volumes:
      - name: sh-volume
        persistentVolumeClaim:
          claimName: sh-volume

标签: kubernetesgoogle-cloud-platformgoogle-kubernetes-enginekubernetes-pod

解决方案


根据Pods DnsConfig 文档

searches:用于在 Pod 中查找主机名的 DNS 搜索域列表。该属性是可选的。指定后,提供的列表将合并到从所选 DNS 策略生成的基本搜索域名中。重复的域名被删除。Kubernetes 最多允许 6 个搜索域。

  • 尽管resolv.conf 文档提到它在最新版本中接受超过 6 个搜索域,但通过 kubernetes 部署还不可能超过这个数量的搜索域。

  • 我创建了一个解决方法,在该方法上InitContainer创建一个新的 Pod 并将其挂载到 Pod上resolv.conf,并且在容器启动后它会替换自动生成的 Pod。这样,如果容器崩溃或重新启动,resolv.conf它将始终得到加强。

nginx-emulating-your-splunk-deploy.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: search
  namespace: default
  labels:
    app: splunk
spec:
  replicas: 1
  selector:
    matchLabels:
      app: splunk
  template:
    metadata:
      labels:
        app: splunk
    spec:
      hostname: search
      initContainers:
        - name: initdns
          image: nginx
          imagePullPolicy: IfNotPresent
          command: ["/bin/bash","-c"] 
          args: ["echo -e \"nameserver 10.39.240.10\nsearch indexer.splunk.svc.cluster.local splunk.svc.cluster.local svc.cluster.local cluster.local us-east4-c.c.'project-id'.internal c.'project-id'.internal google.internal\noptions ndots:5\n \" > /mnt/resolv.conf"]
          volumeMounts:
          - mountPath: /mnt
            name: volmnt      
      containers:
        - name: search
          image: nginx
          env:
          - name: SPLUNK_START_ARGS
            value: "--accept-license"
          - name: SPLUNK_PASSWORD
            value: password
          - name: SPLUNK_ROLE
            value: splunk_search_head
          - name: SPLUNK_SEARCH_HEAD_URL
            value: search
          ports:
          - name: web
            containerPort: 8000
          - name: mgmt
            containerPort: 8089
          - name: kv
            containerPort: 8191
          volumeMounts:
          - mountPath: /mnt
            name: volmnt
          command: ["/bin/bash","-c"] 
          args: ["cp /mnt/resolv.conf /etc/resolv.conf ; nginx -g \"daemon off;\""]
      volumes:
      - name: volmnt
        emptyDir: {}
  • 请记住检查以下字段并根据您的环境进行设置:
    • namespace, nameserver, container.image, container.args

  • 再生产:
$ kubectl apply -f search-head-splunk.yaml 
deployment.apps/search created

$ kubectl get pods
NAME                      READY   STATUS    RESTARTS   AGE
search-64b6fb5854-shm2x   1/1     Running   0          5m14sa

$ kubectl exec -it search-64b6fb5854-shm2x -- cat /etc/resolv.conf 
nameserver 10.39.240.10
search indexer.splunk.svc.cluster.local splunk.svc.cluster.local svc.cluster.local cluster.local us-east4-c.c.'project-id'.internal c.'project-id'.internal google.internal
options ndots:5

您可以看到 resolv.conf 保持配置不变,请在您的环境中重现,如果您发现任何问题,请告诉我。


编辑1:

  • 上述方案专为需要 6 个以上搜索域的环境而设计。
  • 我们必须对 DNS 服务器进行硬编码,但kube-dns服务在集群生命周期内使用相同的 IP,有时甚至在集群重新创建之后,这取决于网络配置。

  • 如果您需要 6 个或更少的域,您可以更改dnsPolicyNone跳过InitContainer

apiVersion: apps/v1
kind: Deployment
metadata:
  name: search
  namespace: splunk
  labels:
    app: splunk
spec:
  replicas: 1
  selector:
    matchLabels:
      app: splunk
  template:
    metadata:
      labels:
        app: splunk
    spec:
      hostname: search
      dnsPolicy: "None"
      dnsConfig:
        nameservers:
          - 10.39.240.10
        searches:
          - indexer.splunk.svc.cluster.local
          - splunk.svc.cluster.local
          - us-east4-c.c.'project-id'.internal
          - c.'project-id'.internal
          - svc.cluster.local
          - cluster.local
        options:
          - name: ndots
          - value: "5"
      containers:
      - name: search
        image: splunk/splunk
...
{{{the rest of your config}}}

推荐阅读