Ошибка запуска приложения Kubernetes при использовании env из ConfigMaps - PullRequest
0 голосов
/ 07 мая 2020

У меня есть приложение, написанное на Go, которое считывает переменные среды из файла config.toml. Файл config.toml содержит значение ключа как

Server="mongodb://mongo-0.mongo,mongo-1.mongo,mongo-2.mongo"
Database="nrfdb"
NRFAddrPort = ":9090"

В моем приложении я читаю все varialbes из файла .toml в свое приложение как

// Represents database and server credentials
type Config struct {
    Server      string
    Database    string
    NRFAddrPort string
}

var NRFAddrPort string

// Read and parse the configuration file
func (c *Config) Read() {
    if _, err := toml.DecodeFile("config.toml", &c); err != nil {
        log.Print("Cannot parse .toml configuration file ")
    }
    NRFAddrPort = c.NRFAddrPort
}

Я хотел бы развернуть мое приложение в моем кластере Kubernetes (3 виртуальных машины, главный и 2 рабочих узла). После создания docker и нажатия на хаб docker при развертывании моего приложения с использованием configMaps для анализа переменных мое приложение запускается в течение нескольких секунд, а затем выдает ошибку. Кажется, приложение не может прочитать переменную env из configMap. Ниже мой configMap и deployemnt.

apiVersion: v1
kind: ConfigMap
metadata:
  name: nrf-config
  namespace: default
data:
  config-toml: |
    Server="mongodb://mongo-0.mongo,mongo-1.mongo,mongo-2.mongo"
    Database="nrfdb"
    NRFAddrPort = ":9090"
apiVersion: apps/v1 
kind: Deployment
metadata:
  name: nrf-instance
spec:
  selector:
    matchLabels:
      app: nrf-instance
  replicas: 1 
  template:
    metadata:
      labels:
        app: nrf-instance
        version: "1.0"
    spec:
      nodeName: k8s-worker-node2
      containers:
      - name: nrf-instance
        image: grego/appapi:1.0.0
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 9090
        volumeMounts:
        - name: config-volume
          mountPath: /home/ubuntu/appapi    
      volumes:
        - name: config-volume
          configMap:
            name: nrf-config

Также я не понимаю, что путь монтирования в volumeMounts. Нужно ли мне копировать config.toml в этот mountPath? Когда я жестко кодирую эту переменную в своем приложении и развертываю образ docker в кубернетах, он запускается без ошибок. Моя проблема теперь заключается в том, как проанализировать эту переменную окружения в моем приложении с помощью kubernetes configMap или любого другого метода, чтобы он мог работать в моем кластере Kubernetes вместо жесткого кодирования их в моем приложении. Любая помощь.

Также прилагается мой контент Dockerfile

# Dockerfile References: https://docs.docker.com/engine/reference/builder/

# Start from the latest golang base image
FROM golang:latest as builder

# Set the Current Working Directory inside the container
WORKDIR /app

# Copy go mod and sum files
COPY go.mod go.sum ./

# Download all dependencies. Dependencies will be cached if the go.mod and go.sum files are not changed
RUN go mod download

# Copy the source from the current directory to the Working Directory inside the container
COPY . .

# Build the Go app
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main .

######## Start a new stage from scratch #######
FROM alpine:latest

RUN apk --no-cache add ca-certificates

WORKDIR /root/

# Copy the Pre-built binary file from the previous stage
COPY --from=builder /app/main .

# Expose port 9090 to the outside world
EXPOSE 9090

# Command to run the executable
CMD ["./main"]

Возникли проблемы с содержимым?

Передача значений в виде значений env как

apiVersion: apps/v1 
kind: Deployment
metadata:
  name: nrf-instance
spec:
  selector:
    matchLabels:
      app: nrf-instance
  replicas: 1 
  template:
    metadata:
      labels:
        app: nrf-instance
        version: "1.0"
    spec:
      nodeName: k8s-worker-node2
      containers:
      - name: nrf-instance
        image: grego/appapi:1.0.0
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 9090
        env:
          - name: Server
            valueFrom:
              configMapKeyRef:
                name: nrf-config
                key: config-toml
          - name: Database
            valueFrom:
              configMapKeyRef:
                name: nrf-config
                key: config-toml
          - name: NRFAddrPort
            valueFrom:
              configMapKeyRef:
                name: nrf-config
                key: config-toml

Ответы [ 2 ]

0 голосов
/ 08 мая 2020

Вы не можете передавать эти значения как отдельные переменные среды, поскольку они читаются как один текстовый BLOB-объект, а не как отдельные key:values. Текущая конфигурационная карта выглядит так:

Data
====
config.toml:
----
Server="mongodb://mongo-0.mongo,mongo-1.mongo,mongo-2.mongo"
Database="nrfdb"
NRFAddrPort = ":9090"

Чтобы передать ее в качестве переменных среды, вам необходимо изменить configmap, чтобы эти значения считывались как key: value pair:

kind: ConfigMap 
apiVersion: v1 
metadata:
  name: example-configmap
data:
  Server: mongodb://mongo-0.mongo,mongo-1.mongo,mongo-2.mongo
  Database: nrfdb
  NRFAddrPort: :9090

Таким образом, те значения будут разделены и могут быть переданы как переменные env:

Data
====
Database:
----
nrfdb
NRFAddrPort:
----
:9090
Server:
----
mongodb://mongo-0.mongo,mongo-1.mongo,mongo-2.mongo

Когда вы передаете его в pod:

[...]   
 spec:    
      containers:
      - name: nrf-instance
        image: nginx
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 9090
        envFrom:
        - configMapRef:
            name: example-configmap

Вы можете видеть, что он был передан правильно, например, выполнив env команда внутри модуля:

kubectl exec -it env-6fb4b557d7-zw84w -- env
NRFAddrPort=:9090
Server=mongodb://mongo-0.mongo,mongo-1.mongo,mongo-2.mongo
Database=nrfdb

Значения читаются как отдельные переменные env, например Server значение:

kubectl exec -it env-6fb4b557d7-zw84w -- printenv Server
mongodb://mongo-0.mongo,mongo-1.mongo,mongo-2.mongo
0 голосов
/ 07 мая 2020

То, что у вас есть в настоящее время, создаст файл в точке монтирования для каждого ключа в вашей карте конфигурации. Ваш код ищет "config.toml", но ключ - "config-toml", поэтому он не находит его.

Если вы хотите сохранить ключ как есть, вы можете контролировать, какие ключи написано где (внутри крепления) вот так:

volumes:
  - name: config-volume
    configMap:
       name: nrf-config
       items:
          - key: config-toml
            path: config.toml
...