k8s 容器内存渲染逻辑

210 阅读2分钟
  • 背景:为限制k8s集群容器内存资源,为每个业务定制不同的内存分配需求。由于把逻辑写在ansible tasks里显得有点臃肿,因此尝试把这块剖离出来写到template里。

需求说明

  • 用户输出两个参数jvm 的最小需要内存和最大内存参数。脚本逻辑会根据服务名和namespace条件去找服务的内存,如果没找到服务名,给默认值。给出的四个参数,其中两个是jvm的最小和最大内存,另外两个是pod的request_memory和limit_memory(其中limit_memory根据jvm最大内存*1.2得出内存量)

数据结构

workMemoryConfig:
    javaOptMinMemory:
       test-memory: 1024
       serviceb: 1500
    javaOptMaxMemory:
       test-memory: 2048
       serviceb: 4096
    
defaultPodRequestMemory: 1024
defaultJavaMaxMemory: 2048

namespaceList: 
 - test1
 - test2
 - test3

namespace: test3
service: servicec

脚本逻辑

{% if namespace in namespaceList   %}
  {% set k = namespace() %}
  {% for t,v in workMemoryConfig.items() %}
     {% if t == 'javaOptMinMemory' %}
         enter javaoptminmemory
         {% for key,value in v.items() %}
             {% if key == service %}
                  {% set podRequestMemoryValue = value|string + 'Mi' %}
                  {% set javaMinMemoryValue = '-Xms' + (value*1.2)|string + 'm' %}
                    {{ podRequestMemoryValue }}    
                    {{  javaMinMemoryValue }}
                    {% set ns.podrmv = podRequestMemoryValue %}
             {% else %}
                  enter default pod request
                  {% set podRequestMemoryValue = defaultPodRequestMemory|string + 'Mi' %}
                  {% set javaMinMemoryValue = '-Xms' + defaultPodRequestMemory|string + 'm' %}          
                    {{ podRequestMemoryValue  }}
                    {{ javaMinMemoryValue }}
             {% endif %}        
         {% endfor %}
     {% elif t == 'javaOptMaxMemory' %}
         enter javaoptmaxmemroy
         {% for key,value in v.items() %}
             {% if key == service %}
                  {% set podLimitMemoryValue = (value*1.2)|string + 'Mi' %}
                  {% set javaMaxMemoryValue = '-Xmx' + value|string + 'm' %}
                           {{ podLimitMemoryValue  }}
                           {{ javaMaxMemoryValue }}
             {% else %}
                  enter limit default
                  {% set podLimitMemoryValue = (defaultJavaMaxMemory*1.2)|string + 'Mi' %}
                  {% set javaMaxMemoryValue = '-Xms' + defaultJavaMaxMemory|string + 'm' %}   
                           {{ podLimitMemoryValue  }}
                           {{ javaMaxMemoryValue }}
             {% endif %}        
         {% endfor %}
                   
     {% else %}
         another key
     {% endif %}
  {% endfor %}    
{% else %}
      could not found namespace
{% endif %}

存在的问题:

  jinja2如果用到for循环变量的作用域就只能在循环内,查了一系统文章。有个解决办法就是升级jinja2到2.10以上,可以用set ns =namespaces()来支持全局变量。全局变量虽然支持,但是同样的模板和逻辑,组织方式不一样,一跑ansible数据类型还是报错,于是我只能寻求其它方法来解。接下来,我打算自已开发一个ansible module来解决这个问题。