kubernetes: Cannot use dash in environment variable names in a pod definition

It’s not possible to define a container with an environment variable containing dash. For example:

...
containers:
        - name: my-name
          image: gcr.io/id/name:v1
          ports:
            - containerPort: 8080
          env:
            - name: SOMETHING_WITH-DASH
              value: Something
...

yields the following error:

The ReplicationController "rc-name" is invalid:spec.template.spec.containers[0].env[0].name: invalid value 'SOMETHING_WITH-DASH': must be a C identifier (matching regex [A-Za-z_][A-Za-z0-9_]*): e.g. "my_name" or "MyName"

So why is this needed?

I’m trying to deploy an existing Spring Boot Java application running inside a Docker container. Spring boot allows you to inject configuration using this approach:

@Value("${something.with-dash}")
private String mySomething;

Spring Boot allows you to externalize the configuration in various different ways. For example it maps environment variables like this:

If you use environment variables rather than system properties, most operating systems disallow period-separated key names, but you can use underscores instead (e.g. SPRING_CONFIG_NAME instead of spring.config.name).

So in this case I need to use an environment variable called SOMETHING_WITH-DASH in order for spring to pick it up and map it to something.with-dash.

This works when using tools like Docker Compose. In bash it works when you do like this:

env 'SOMETHING_WITH-DASH=Something' myprogram

It’s even more common when using Clojure and the popular environ library that deals with properties. Since Clojure uses Lisp syntax it’s very common to name keys using dashes.

Without support for this it’ll be harder for me (and presumably others) to sell Kubernetes to my company since we have to make code changes in several projects/services.

I’m using Kubernetes 1.0.6 on Google Container Engine.

About this issue

  • Original URL
  • State: closed
  • Created 9 years ago
  • Reactions: 5
  • Comments: 24 (6 by maintainers)

Most upvoted comments

The following use case might be relatively common -

The official documentation for setting up Elastic Search via docker provides a docker-compose.yml file with an environment parameter bootstrap.memory_lock=true. This causes the following error:

Error from server (Invalid): error when creating "kubernetes/elasticsearch1-deployment.yaml": Deployment.apps "elasticsearch1" is invalid: [spec.template.spec.containers[0].env[0].name: Invalid value: "cluster.name": a valid C identifier must start with alphabetic character or '_', followed by a string of alphanumeric characters or '_' (e.g. 'my_name',  or 'MY_NAME',  or 'MyName', regex used for validation is '[A-Za-z_][A-Za-z0-9_]*'), spec.template.spec.containers[0].env[1].name: Invalid value: "bootstrap.memory_lock": a valid C identifier must start with alphabetic character or '_', followed by a string of alphanumeric characters or '_' (e.g. 'my_name',  or 'MY_NAME',  or 'MyName', regex used for validation is '[A-Za-z_][A-Za-z0-9_]*')]

The docker-compose.yml file for the lazy:

version: '2'
services:
  elasticsearch1:
    image: docker.elastic.co/elasticsearch/elasticsearch:5.4.2
    container_name: elasticsearch1
    environment:
      - cluster.name=docker-cluster
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
    ulimits:
      memlock:
        soft: -1
        hard: -1
    mem_limit: 1g
    volumes:
      - esdata1:/usr/share/elasticsearch/data
    ports:
      - 9200:9200
    networks:
      - esnet
  elasticsearch2:
    image: docker.elastic.co/elasticsearch/elasticsearch:5.4.2
    environment:
      - cluster.name=docker-cluster
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
      - "discovery.zen.ping.unicast.hosts=elasticsearch1"
    ulimits:
      memlock:
        soft: -1
        hard: -1
    mem_limit: 1g
    volumes:
      - esdata2:/usr/share/elasticsearch/data
    networks:
      - esnet

volumes:
  esdata1:
    driver: local
  esdata2:
    driver: local

networks:
  esnet:

I was able to sidestep this issue in .Net Core by replacing colons with double underscores.

env:
- name: "Logging__LogLevel__Default"
  value: "Debug"

I’d rather see this get fixed, as weird as it is.

I managed to solve this for Spring by replacing dots with underscores. I’m running the PetClinic example in Kubernetes like with these env params:

env:
        - name: "spring_profiles_active"
          value: "mysql"
        - name: "spring_datasource_url"
          value: "jdbc:mysql://mysql/petclinic"
        - name: "spring_datasource_username"
          value: root
        - name: "spring_datasource_password"
          value: "password"
        - name: "spring_datasource_initialize"
          value: "true"