How to set dynamic values with Kubernetes yaml file

前端 未结 13 1935
旧巷少年郎
旧巷少年郎 2020-12-04 16:22

For example, a deployment yaml file:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: guestbook
spec:
  replicas: 2
  template:
    metadata         


        
相关标签:
13条回答
  • 2020-12-04 16:42

    One line:

    cat app-deployment.yaml | sed "s/{{BITBUCKET_COMMIT}}/$BITBUCKET_COMMIT/g" | kubectl apply -f -
    

    In yaml:

      ...
      containers:
      - name: ulisses
        image: niceuser/niceimage:{{BITBUCKET_COMMIT}}
      ...
    
    0 讨论(0)
  • 2020-12-04 16:42

    yaml does not read values from another yaml file. As an alternative approach you could try this.

    kind: Pod
    metadata:
      creationTimestamp: null
      annotations:
        namespace: &namespaceId dev
        imageId: &imgageId nginx
        podName: &podName nginx-pod
        containerName: &containerName nginx-container
      name: *podName
      namespace: *namespaceId
    spec:
      containers:
      - image: *imgageId
        name: *containerName
        resources: {}
      dnsPolicy: ClusterFirst
      restartPolicy: Always
    status: {}
    
    0 讨论(0)
  • 2020-12-04 16:45

    My approach:

    tools/jinja2-cli.py:

    #!/usr/bin/env python3
    import os
    import sys
    from jinja2 import Environment, FileSystemLoader
    
    sys.stdout.write(Environment(loader=FileSystemLoader('templates/')).from_string(sys.stdin.read()).render(env=os.environ) + "\n")
    

    Make rule:

    _GENFILES = $(basename $(TEMPLATES))
    GENFILES = $(_GENFILES:templates/%=%)
    
    $(GENFILES): %: templates/%.j2 $(MKFILES) tools/jinja2-cli.py .env
            env $$(cat .env | xargs) tools/jinja2-cli.py < $< > $@ || (rm -f $@; false)
    

    Inside the .j2 template file you can use any jinja syntax construct, e.g. {{env.GUEST}} will be replaced by the value of GUEST defined in .env

    So your templates/deploy.yaml.j2 would look like:

    apiVersion: extensions/v1beta1
    kind: Deployment
    metadata:
      name: guestbook
    spec:
      replicas: 2
      template:
        metadata:
          labels:
            app: guestbook
          spec:
            container:
              - name: guestbook
                image: {{env.GUEST}}
    

    Another approach (using just bash builtins and xargs) might be

    env $(cat .env | xargs) cat <<EOF | kubectl create -f -
    apiVersion: extensions/v1beta1
    kind: Deployment
    metadata:
      name: guestbook
    spec:
      replicas: 2
      template:
        metadata:
          labels:
            app: guestbook
          spec:
            container:
              - name: guestbook
                image: ${GUEST}
    EOF
    
    0 讨论(0)
  • 2020-12-04 16:45

    This kind of thing is painfully easy with ytt:

    deployment.yml

    #@ load("@ytt:data", "data")
    ---
    apiVersion: extensions/v1beta1
    kind: Deployment
    metadata:
      name: guestbook
    spec:
      replicas: 2
      template:
        metadata:
          labels:
            app: guestbook
          spec:
            container:
              - name: guestbook
                image: #@ data.values.image
    

    values.yml

    #@data/values
    image: nginx@sha256:fe2fa7bb1ceb86c6d9c935bc25c3dd8cbd64f2e95ed5b894f93ae7ffbd1e92bb
    

    Then...

    $ ytt -f deployment.yml -f values.yml | kubectl apply -f -
    

    or even better, use ytt's cousin, kapp for a high-control deployment experience:

    $ ytt -f deployment.yml -f values.yml | kapp deploy -a guestbook -f -
    
    0 讨论(0)
  • 2020-12-04 16:49

    Helm is exactly meant for such things and a lot more. It handle complex set of resource deployment as a group etc.

    But if we are still looking for some simple alternative then how about using ant?

    If you want to modify the file as part of build process or test process then you can go with ant task as well.

    Using ant you can load all environment values as property or you can simply load properties file like:

    <property environment="env" />
    <property file="build.properties" />
    

    Then you can have a target which converts template files into your desired yaml file.

    <target name="generate_from_template">
    
        <!-- Copy task to replaces values and create new file -->
        <copy todir="${dest.dir}" verbose="true" overwrite="true" failonerror="true">
    
            <!-- List of files to be processed -->
            <fileset file="${source.dir}/xyz.template.yml" />
    
            <!-- Mapper to transform filename. Removes '.template' from the file
                name when copying the file to output directory -->
            <mapper type="regexp" from="(.*).template(.*)" to="\1\2" />
    
            <!-- Filter chain that replaces the template values with actual values 
                fetched from properties file -->
            <filterchain>
                <expandproperties />
            </filterchain>
        </copy>
    </target>
    

    Of course you can use a fileset instead of file in case you want to change values dynamically for multiple files (nested or whatever)

    Your template file xyz.template.yml should look like:

    apiVersion: v1
    kind: Service
    metadata:
      name: ${XYZ_RES_NAME}-ser
      labels:
        app: ${XYZ_RES_NAME}
        version: v1
    spec:
      type: NodePort
      ports:
        - port: ${env.XYZ_RES_PORT}
          protocol: TCP
      selector:
        app: ${XYZ_RES_NAME}
        version: v1
    

    env. property being loaded from environment variables and other from property file

    Hope it helped :)

    0 讨论(0)
  • 2020-12-04 16:52

    I don't think it is possible to set image through variable or Config Map in Kubernetes. But you can use for example Helm to make your deployments much more flexible and configurable.

    0 讨论(0)
提交回复
热议问题