2017-07-17 29 views
0

問題

我有一個監視應用程序,我想在一個DaemonSet中進行部署。在應用程序的配置中,指定一個唯一的用戶代理來將節點與其他節點分開。我爲應用程序創建了一個ConfigMap,但這隻適用於同步環境中的其他設置。如何在Kubernetes配置圖中使用唯一值

的理想解決方案?

我想指定一個唯一值,如節點的主機名或另一個本地推斷的值,以用作用戶代理字符串。有沒有一種方法,我可以調用從系統信息和Kubernetes將填充值(如主機名)所需的關鍵?

這是否有意義,還是有更好的方法來做到這一點?我正在瀏覽文檔,但我無法在這個特定問題的任何地方找到答案。

作爲一個例子,這裏是我現在擁有的應用程序配置中的字符串,而不是我想要使用的字符串。

user_agent = "app-k8s-test"

但我寧願......

user_agent = $HOSTNAME

是這樣的可能嗎?

回答

2

您可以使用起始容器預處理一個配置模板從配置圖。預處理步驟可以將局部變量注入配置文件。擴展的配置被寫入init容器和主應用程序容器之間共享的emptyDir。這是一個如何做到這一點的例子。

首先,使用佔位符爲您要擴展的任何字段創建配置圖。我用sed和和臨時名稱來代替。你也可以看中並使用jinja2或任何你喜歡的東西。只要將你想要的任何預處理器放入init容器映像即可。你可以使用任何你想要的配置文件的文件格式。我只是在這裏使用TOML來表明它不一定是YAML。我把它叫做「.tpl」,因爲它是不準備使用:它有一個字符串,_HOSTNAME_,需要進行擴展。

$ cat config.toml.tpl 
[blah] 
blah=_HOSTNAME_ 
otherkey=othervalue 
$ kubectl create configmap cm --from-file=config.toml.tpl 
configmap "cm" created 

現在寫與安裝在卷的配置圖,並將其擴展並寫入到另一個卷的起始容器吊艙,與主容器共享:

$ cat personalized-pod.yaml 
apiVersion: v1 
kind: Pod 
metadata: 
    name: myapp-pod-5 
    labels: 
    app: myapp 
    annotations: 
spec: 
    containers: 
    - name: myapp-container 
    image: busybox 
    command: ['sh', '-c', 'echo The app is running and my config-map is && cat /etc/config/config.toml && sleep 3600'] 
    volumeMounts: 
     - name: config-volume 
     mountPath: /etc/config 
    initContainers: 
    - name: expander 
    image: busybox 
    command: ['sh', '-c', 'cat /etc/config-templates/config.toml.tpl | sed "s/_HOSTNAME_/$MY_NODE_NAME/" > /etc/config/config.toml'] 
    volumeMounts: 
     - name: config-tpl-volume 
     mountPath: /etc/config-templates 
     - name: config-volume 
     mountPath: /etc/config 
    env: 
     - name: MY_NODE_NAME 
     valueFrom: 
      fieldRef: 
      fieldPath: spec.nodeName 
    volumes: 
    - name: config-tpl-volume 
     configMap: 
     name: cm 
    - name: config-volume 
     emptyDir: 
$ kubctl create -f personalized-pod.yaml 
$ sleep 10 
$ kubectl logs myapp-pod 
The app is running and my config-map is 
[blah] 
blah=gke-k0-default-pool-93916cec-p1p6 
otherkey=othervalue 

我在此一裸露的莢作爲例子。您可以將這種類型的窗格嵌入到DaemonSet的窗格模板中。

在這裏,Downward API is used to set the MY_NODE_NAME Environment Variable,因爲節點名稱不容易從容器內獲得。

請注意,由於某些原因,您無法將spec.nodeName轉換爲文件,只是一個env var。

如果您只需要Env Var中的主機名,那麼您可以跳過init容器。

由於Init Container只運行一次,所以您不應該更新configMap並期望它被重新擴展。如果你需要更新,你可以做兩件事情之一:

  • 相反的起始容器,運行手錶的配置圖卷,當它改變再膨脹(或只是它週期性的)邊車。這要求主容器也知道如何監視配置文件更新。

  • 每次配置模板更改時,您都可以創建一個新的配置映射,然後編輯daemonSet以將一行更改爲指向新的配置映射。 然後執行滾動更新以使用新配置。