Kubernetes(10) Configmap and Secret

Some additioanl knowledge...

How to configure a docker image:

  • Customized command line arguments -> args: []
  • Copy configuration file into docker image
  • By parsing enviorment parameter

1) Cloud Native application are usually configurable with enviorment parameter

2) Using entrypoint script to configure/overwirte existing configuration file in docker image

  • Using configuration file within Volumes as mount point in Docker

1 Configmap

Configmap provide configuration parameters as plaintext from outside of the container to container image.
There are two ways to injects configuration parameters in a docker instance:

  • Mounting configuration file in docker by using volume
  • Reading infos from Configmap and add them to enviorment parameters

1.1 Creating a Configmap by using command line

With kubectl create configmap --help command we can see, there are many ways to parse parameters to Configmap. In this section I will take the one with "--from-literal" as example.

[root@k8smaster pod_storage]# kubectl create configmap --help
Create a configmap based on a file, directory, or specified literal value. 
...
Examples:
  # Create a new configmap named my-config based on folder bar
  kubectl create configmap my-config --from-file=path/to/bar
  
  # Create a new configmap named my-config with specified keys instead of file basenames on disk
  kubectl create configmap my-config --from-file=key1=/path/to/bar/file1.txt --from-file=key2=/path/to/bar/file2.txt
  
  # Create a new configmap named my-config with key1=config1 and key2=config2
  kubectl create configmap my-config --from-literal=key1=config1 --from-literal=key2=config2
  
  # Create a new configmap named my-config from the key=value pairs in the file
  kubectl create configmap my-config --from-file=path/to/bar
  
  # Create a new configmap named my-config from an env file
  kubectl create configmap my-config --from-env-file=path/to/bar.env
...

Example -> setting nginx port and servername:

[root@k8smaster pod_storage]# kubectl create configmap myconfig --from-literal=nginx_port=80 --from-literal=server_name=k8smaster
configmap/myconfig created

[root@k8smaster pod_storage]# kubectl get cm -o yaml ...

[root@k8smaster pod_storage]# kubectl describe cm myconfig Name: myconfig Namespace: default Labels:
<none> Annotations: <none> Data ==== nginx_port: ---- 80 server_name: ---- k8smaster Events: <none>

As result above nginx_port is 80 and servername is setted to k8smaster.

1.2 Deploy a new Pod with Configmap

Pod template:

apiVersion: v1
kind: Pod
metadata:
  name: pod-configmap-demo
  namespace: default
  labels:
    app: myapp
    tier: frontend
  annotations:
    crazy-chinese.com/created-by: "cluster-admin"
spec:
  containers:
    - name: mypp
      image: ikubernetes/myapp:v1
      imagePullPolicy: IfNotPresent
      ports:
      - name: http
        containerPort: 80
      env:
        - name: NGINX_SERVER_PORT
          valueFrom:
            configMapKeyRef:
              name: myconfig # pre configured configmap name: kubectl create configmap myconfig --from-literal=nginx_port=80 --from-literal=server_name=k8smaster
              key: nginx_port
        - name: NGINX_SERVER_NAME
          valueFrom:
            configMapKeyRef:
              name: myconfig
              key: server_name

With env we can define enviorment parameters for docker image. env.name is the name of defined parameter, valueFrom.configMapKeyRef will search key in configmap and return value back and assign it to env.name.

Invesgating configuration in docker container:

[root@k8smaster pod_configmap_secret]# kubectl exec -it pod-configmap-demo -- /bin/sh
/ # env
MYAPP_SVC_PORT_80_TCP_ADDR=10.98.57.156
KUBERNETES_PORT=tcp://10.96.0.1:443
KUBERNETES_SERVICE_PORT=443
MYAPP_SVC_PORT_80_TCP_PORT=80
HOSTNAME=pod-configmap-demo
SHLVL=1
MYAPP_SVC_PORT_80_TCP_PROTO=tcp
HOME=/root
NGINX_SERVER_PORT=80
NGINX_SERVER_NAME=k8smaster
MYAPP_SVC_PORT_80_TCP=tcp://10.98.57.156:80
TERM=xterm
NGINX_VERSION=1.12.2
KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
KUBERNETES_PORT_443_TCP_PORT=443
KUBERNETES_PORT_443_TCP_PROTO=tcp
MYAPP_SVC_SERVICE_HOST=10.98.57.156
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
PWD=/
KUBERNETES_SERVICE_HOST=10.96.0.1
MYAPP_SVC_SERVICE_PORT=80
MYAPP_SVC_PORT=tcp://10.98.57.156:80

We have seen in the output of  command env are NGINX_SERVER_PORT and NGINX_SERVER_NAME configured.

* you can update Configmap with kubectl edit cm name_configmap. The new Update will deployed in Pod after you restart this pod.

1.3 Deploy a Pod with Configmap as Volumes

We have seen in the last section, our update for Configmap was not activ before we restart the Pod. But if you mount Configmap as Volumes on the Pod, the configuration of configmap will be automatically updated by changes!

a new template for deployment:

apiVersion: v1
kind: Pod
metadata:
  name: pod-configmap-demo
  namespace: default
  labels:
    app: myapp
    tier: frontend
  annotations:
    crazy-chinese.com/created-by: "cluster-admin"
spec:
  containers:
    - name: mypp
      image: ikubernetes/myapp:v1
      imagePullPolicy: IfNotPresent
      ports:
      - name: http
        containerPort: 80
      volumeMounts:
        - mountPath: /etc/nginx/conf.d
          name: configmap-myconfig
          readOnly: true
  volumes:
    - name: configmap-myconfig
      configMap:
        name: myconfig

In this template we defined, that Configmap myconfig is mounted as volumes with mount path /etc/nginx/conf.d

[root@k8smaster pod_configmap_secret]# kubectl apply -f configmap-volumes-demo.yaml 
pod/pod-configmap-demo created
[root@k8smaster pod_configmap_secret]# kubectl exec
-it pod/pod-configmap-demo -- /bin/sh [root@k8smaster pod_configmap_secret]# kubectl exec -it pod-configmap-demo -- /bin/sh / # cd /etc/nginx/conf.d/ /etc/nginx/conf.d # ls nginx_port server_name /etc/nginx/conf.d # cat server_name k8smaster

With this configuration Configmap create two new files in /etc/nginx/conf.d with Configmap key as filename and value as Content of the file.

Now, if we change the value of Configmap, it will update the configuration immediatlly (with several seconds delay)

If we reload nginx pod now, the new changes will be activ! (the reload should be done by scripting)

2 Secret

In the section above we learned that Configmap could be used for setting configuration file or enviorment parameter of pod (container). They are present as plaintext, which means, everyone can read the content... If we want pass a critical information to the container like password of a database, this must be encrypted. Therefore we have Secret!

[root@k8smaster pod_configmap_secret]# kubectl create secret --help
Available Commands:
  docker-registry Create a secret for use with a Docker registry
  generic         Create a secret from a local file, directory or literal value
  tls             Create a TLS secret
...
  • docker-registry is used to store authentication information to able kubelet pull image from docker-registry
  • tls stores tls certificates
  • generic stores common secret like username and password etc.

 

2.1 Create a Secret

Now we will create a secret for mysql database manually:

[root@k8smaster pod_configmap_secret]# kubectl create secret generic mysql-credentials --from-literal=username=db_user1 --from-literal=password=myp@ssword123
secret/mysql-credentials created

[root@k8smaster pod_configmap_secret]# kubectl get secret NAME TYPE DATA AGE default
-token-rxs5t kubernetes.io/service-account-token 3 25d mysql-credentials Opaque 2 21s [root@k8smaster pod_configmap_secret]# kubectl describe secret mysql-credentials Name: mysql-credentials Namespace: default Labels: <none> Annotations: <none> Type: Opaque Data ==== password: 13 bytes username: 8 bytes

The funny thing is, that the k8s secret is not that secure as we think...

[root@k8smaster pod_configmap_secret]# kubectl get secret mysql-credentials -o yaml
apiVersion: v1
data:
  password: bXlwQHNzd29yZDEyMw==
  username: ZGJfdXNlcjE=
kind: Secret
metadata:
  creationTimestamp: "2019-01-27T21:58:18Z"
  name: mysql-credentials
  namespace: default
  resourceVersion: "399813"
  selfLink: /api/v1/namespaces/default/secrets/mysql-credentials
  uid: a753efe4-227e-11e9-84e6-000c297191df
type: Opaque

[root@k8smaster pod_configmap_secret]#
echo bXlwQHNzd29yZDEyMw== | base64 -d myp@ssword123

See command above, we can decode this password by using base64

PS: the best way might be using Secret, but set permission to 600, so that only the people who create the container can read the credentials.

2.2 Deploy a Pod with Secret

Assume that you have followed this artical and already created a secret (see above), now deploy a pod with following template.

apiVersion: v1
kind: Pod
metadata:
  name: pod-configmap-demo
  namespace: default
  labels:
    app: myapp
    tier: frontend
  annotations:
    crazy-chinese.com/created-by: "cluster-admin"
spec:
  containers:
    - name: mypp
      image: ikubernetes/myapp:v1
      imagePullPolicy: IfNotPresent
      ports:
      - name: http
        containerPort: 80
      env:
        - name: MYSQL_ROOT_PASSWORD
          valueFrom:
            secretKeyRef:
              key: password
              name: mysql-credentials

Invesgating in the Container:

[root@k8smaster pod_configmap_secret]# kubectl apply -f secret-demo.yaml 
pod/pod-secret-demo created

[root@k8smaster pod_configmap_secret]# kubectl get pods NAME READY STATUS RESTARTS AGE pod
-secret-demo 1/1 Running 0 7s
[root@k8smaster pod_configmap_secret]# kubectl exec
-it pod-secret-demo -- /bin/sh / # env MYAPP_SVC_PORT_80_TCP_ADDR=10.98.57.156 KUBERNETES_PORT=tcp://10.96.0.1:443 KUBERNETES_SERVICE_PORT=443 MYAPP_SVC_PORT_80_TCP_PORT=80 HOSTNAME=pod-secret-demo SHLVL=1 MYAPP_SVC_PORT_80_TCP_PROTO=tcp HOME=/root MYSQL_ROOT_PASSWORD=myp@ssword123 ...

Again... this is not a secure way, to store the secret!

2.3 Deploy a Pod with Secret as Volumes Mounts

Use template below

apiVersion: v1
kind: Pod
metadata:
  name: pod-secret-volumes-demo
  namespace: default
  labels:
    app: myapp
    tier: frontend
  annotations:
    crazy-chinese.com/created-by: "cluster-admin"
spec:
  containers:
    - name: mypp
      image: ikubernetes/myapp:v1
      imagePullPolicy: IfNotPresent
      ports:
      - name: http
        containerPort: 80
      volumeMounts:
        - mountPath: /home/credentials
          name: secret-mysql-credentials
          readOnly: true
  volumes:
    - name: secret-mysql-credentials
      secret:
        secretName: mysql-credentials
        defaultMode: 600

Invesgating in Container

[root@k8smaster pod_configmap_secret]# kubectl get pods
No resources found.
[root@k8smaster pod_configmap_secret]# kubectl apply -f secret-
secret-demo.yaml          secret-volumes-demo.yaml  
[root@k8smaster pod_configmap_secret]# kubectl apply -f secret-volumes-demo.yaml 
pod/pod-secret-volumes-demo created
[root@k8smaster pod_configmap_secret]# kubectl get pods
NAME                      READY   STATUS    RESTARTS   AGE
pod-secret-volumes-demo   1/1     Running   0          10s
[root@k8smaster pod_configmap_secret]# kubectl exec -it pod-secret-volumes-demo -- /bin/sh
/ # cd /home/credentials/
/home/credentials # ls
password  username/home/credentials # cat username 
db_user1 

 

转载于:https://www.cnblogs.com/crazy-chinese/p/10438978.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值