Showing posts with label configmap. Show all posts
Showing posts with label configmap. Show all posts

Friday, May 10, 2019

Error: cannot use "k8s.io/api/core/v1".ConfigMapVolumeSource literal (type "k8s.io/api/core/v1".ConfigMapVolumeSource) as type *"k8s.io/api/core/v1".ConfigMapVolumeSource in field value

Symptom:

Related code:
o.pgreplicamaster.Spec.Template.Spec.Volumes = []corev1.Volume{
{Name: "pgreplica-config",
VolumeSource: corev1.VolumeSource{ 
   ConfigMap: corev1.ConfigMapVolumeSource{
    LocalObjectReference: corev1.LocalObjectReference{Name: o.UserSpecifiedCM},
   },
   },
    
},
}
 Compile Error
cannot use "k8s.io/api/core/v1".ConfigMapVolumeSource literal (type "k8s.io/api/core/v1".ConfigMapVolumeSource) as type *"k8s.io/api/core/v1".ConfigMapVolumeSource in field value

Solution:

    Refer VolumeSource k8s doc. ConfigMap suppose to have pointer  *ConfigMapVolumeSource, not value of  ConfigMapVolumeSource , We need to add &.
Meanwhile we can't mix field value and value , refer stackflow link
Correct code is:
o.pgreplicamaster.Spec.Template.Spec.Volumes = []corev1.Volume{
{Name: "pgreplica-config",
 VolumeSource: corev1.VolumeSource{ 
   ConfigMap: &corev1.ConfigMapVolumeSource{
    LocalObjectReference: corev1.LocalObjectReference{Name: o.UserSpecifiedCM},
   },
   },
 
},
}

Error: spec.volumes[1].configMap.name: Required value, spec.containers[0].volumeMounts[1].name: Not found

Symptom:

  We use partial yaml below to create a statefulset with mount a volume for configmap.It is successful
apiVersion: apps/v1
kind: StatefulSet
......  
    spec:
      volumes:
        - name: pgreplica-config
          configMap:
            name: pgconfigmap
........
When we try to use client-go to do the same thing.
Related codes
o.pgreplicamaster.Spec.Template.Spec.Volumes = []corev1.Volume{
{Name: "pgreplica-config",
 VolumeSource: corev1.VolumeSource{ 
   ConfigMap: &corev1.ConfigMapVolumeSource{
    Items: corev1.KeyToPath{{Key: "name",Path: pgconfigmap}},
   },
   },
    
},
}
We hit error
Error: spec.volumes[1].configMap.name: Required value, spec.containers[0].volumeMounts[1].name: Not found

Solution

Refer k8s doc of ConfigMapVolumeSource
There is LocalObjectReference which we should use, instead of using Items
Update code as below to make it work
o.pgreplicamaster.Spec.Template.Spec.Volumes = []corev1.Volume{
{Name: "pgreplica-config",
VolumeSource: corev1.VolumeSource{
   ConfigMap: &corev1.ConfigMapVolumeSource{
    LocalObjectReference: corev1.LocalObjectReference{Name: "pgconfigmap"},
   },
   },
   
},
}

Monday, April 15, 2019

Use ConfigMap To Store Http.conf For Http Service Pod

Requirement:

    Lots of applications would have http service ie apache or nginx as the frontend. We often deploy pods of apache or nginx for it.  Take apache httpd as example, we often need to update httpd.conf for rewrite, redirect.....etc. It is ok to build a new docker image to achieve that ,but not efficient .  ConfigMap of K8S can store text and binary files in K8S, can be mounted in the pod. So we can leverage that to update httpd.conf without rebuilding the docker images. We can use same concept for all other config files of different apps ie nginx, ords...etc

Solution:

  • Prepare for Dockerfile and your customized httpd.conf file . Example can be found on github repo
  • Once new docker image is built , we need to store httpd.conf into configmap via kubectl 
kubectl create configmap httpdconfig --from-file=httpd.conf 
  • Prepare for deployment yaml to mount configmap in the pod. Partial yaml file is like
         volumes:
            - name: httpd-config
              configMap:
                 name: httpdconfig
         containers:
           - name: httpd
             image: httpd-configmap:v3
             imagePullPolicy: IfNotPresent
             volumeMounts:
                - name: httpd-config
                  mountPath: /mnt/k8s
             ports:
                - containerPort: 80

  • Kubectl command of updating httpd.conf  after we have new version of httpd.conf
kubectl create configmap httpdconfig --from-file=httpd.conf  -o yaml --dry-run | kubectl replace -f -
  • Bounce the http pod to let new pod  read the new configmap
  • It is the same concept and process for any other apps which have config files ie ORDS, Nginx.....etc
  • Configmap supports binary file as well ie wallets  see other note

Thursday, February 14, 2019

How To Put Binary or Text Config Files into K8s ConfigMap

Requirement:

  We often have all kind of config files for our Apps.  From binary wallet files to simple text config files, we need to store them somewhere where apps can access.  It is not a good idea to put these config files inside docker images or PV(persistent volume) as it would make the pod less portable and hard to scale and migrate. Fortunately from K8S v1.10 , Configmap would support both binary and text config files .  Here are some examples how we utilize configmap to achieve that. Mounted configmap are updated automatically. More details please refer kubernetes configmap doc

Solution:

We plan to create 2 configmaps . One for binary files like ewallet and one for text config files  like sysctl.conf, init.ora....

  • Use kubectl create configmap walletconfigmap --from-file=ewallet1 --from-file=ewallet2
  • Use kubectl create configmap textconfigmap --from-file=sysctl.conf  --from-file=jdbc.xml  --from-file=init.ora  
  • Use kubectl get configmap walletconfigmap -o yaml . You would see ewallet would be stored as binaryData

apiVersion: v1
items:
- apiVersion: v1
  binaryData:
    ewallet: sdfsweffewg.....
........
  • Mount wallet configmap as a volume in the pod with correct config file path . ie wallet file is on /etc/oracle/tde
  • Mount text configmap as a volume in the pod with correct config file path . ie text file is on /opt/oracle/dbs
volumes:
- name: wallet-volume
  configMap:
          name: walletconfigmap 
- name: textconfig-volume
   configMap:
          name: textconfigmap 

Under container section of yaml file
volumeMounts:
- name: wallet-volume
  mountPath: /etc/oracle/tde
- name: textconfig-volume
  mountPath: /opt/oracle/dbs

  • In this way, when we into the pod via kubectl exec -it  <pod name> /bin/bash , we would see ewallet1 ewallet2 in /etc/oracle/tde  and  sysctl.conf jdbc.xml and init.ora are in /opt/oracle/dbs.
  • If we do some updates on configmap , K8S will sync them periodically.

Sunday, February 10, 2019

Error: Couldn't find key username in Secret default/test-stg-secret

Symptom:

  We create test-stg-secret via yaml file below
apiVersion: v1
kind: Secret
metadata:
  name: 
 test-stg-secret
type: Opaque
stringData:
  config.yaml: |-
    username: test
    password:  test

 However we got "Error: Couldn't find key username in Secret default/test-stg-secret" when we create statefulset. Part of secret usages are:
env:
            - name: TEST_USER
              valueFrom:
                  secretKeyRef:
                     name: test-stg-secret
                     key: username
            - name: TEST_PASSWORD
              valueFrom:
                  secretKeyRef:
                     name: test-stg-secret
                     key: password

Solution:

The reason is due to when we create secret it regards the whole text as one single string as config.yaml
It does not take username or password as key
To workaround it, we need to get decoded string via base64
echo -n 'test' | base64  --->  dGVzdA==

-n will take new line at the end

Then correct yaml file is :
apiVersion: v1kind: Secretmetadata:  name:  test-stg-secret
type: Opaque
data:
    username: dGVzdA==
    password:  dGVzdA==