ConfigMap

ConfigMap 并不提供保密或者加密功能。 如果你想存储的数据是机密的,请使用 Secret, 或者使用其他第三方工具来保证你的数据的私密性,而不是用 ConfigMap。

apiVersion: v1
kind: ConfigMap
metadata:
  name: game-demo
data:
  # 类属性键;每一个键都映射到一个简单的值
  player_initial_lives: "6"
  ui_properties_file_name: "user-interface.properties"

  # 类文件键
  game.properties: | # 竖线保留换行符
    enemy.types=aliens,monsters
    player.maximum-lives=5    
  user-interface.properties: |
    color.good=purple
    color.bad=yellow
    allow.textmode=true

监听configMap的变化

// 此处演示的是在容器外
package main

import (
	"context"
	"fmt"
	"k8s.io/client-go/tools/clientcmd"
	"os"
	"os/user"
	"strings"

	v1 "k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

	"k8s.io/client-go/kubernetes"
	"time"
)

func main() {
	// outside cluster
	u, err := user.Current()
	if err != nil {
		fmt.Println(err)
	}

	fmt.Println("Home dir:", u.HomeDir)
	cmdapi, err := clientcmd.LoadFromFile(u.HomeDir + "/.kube/config")
	if err != nil {
		fmt.Println("LoadFromFile err:", err)
		return
	}
	// 当前集群名称
	fmt.Printf("current cluster: [%s]\n", cmdapi.CurrentContext)

	// uses the current context in kubeconfig
	// path-to-kubeconfig -- for example, /root/.kube/config
	// 需要传入url,否则容器内有可能会访问失败
	masterUrl := strings.Replace(os.Getenv("KUBERNETES_PORT"), "tcp", "https", -1)
	config, err := clientcmd.BuildConfigFromFlags(masterUrl, u.HomeDir + "/.kube/config")
	if err != nil {
		fmt.Printf("build config fail: %s", err)
		return
	}

	// in cluster
	/*
		config, err := rest.InClusterConfig()
		if err != nil {
			fmt.Printf("get in cluster config error: %s\n", err)
			return
		}*/

	// creates the clientset
	clientset, err := kubernetes.NewForConfig(config)
	if err != nil {
		fmt.Println("NewForConfig err is ", err)
	}

	// 实时监听ConfigMap
	w, _ := clientset.CoreV1().ConfigMaps("default").Watch(context.Background(), metav1.ListOptions{})
	for {
		select {
		case e, _ := <-w.ResultChan():
			obj := e.Object
			// 转成config对象
			cf := obj.(*v1.ConfigMap)
			fmt.Printf("*********************** %s %s start ***********************\n", e.Type, cf.Name)
			fmt.Println(e.Type, e.Object)
			fmt.Printf("*********************** %s %s end   ***********************\n", e.Type, cf.Name)
			if cf.Name == "game-demo" {
				fmt.Printf("player_initial_lives: %s\n", cf.Data["player_initial_lives"])
			}
		default:
			time.Sleep(1 * time.Second)
			fmt.Printf("time sleep %s\n", time.Now())
		}
	}
}

Pod使用ConfigMap

你可以使用四种方式来使用 ConfigMap 配置 Pod 中的容器:

  • 在容器命令和参数内
  • 容器的环境变量
  • 在只读卷里面添加一个文件,让应用来读取
  • 编写代码在 Pod 中运行,使用 Kubernetes API 来读取 ConfigMap

这些不同的方法适用于不同的数据使用方式。 对前三个方法,kubelet 使用 ConfigMap 中的数据在 Pod 中启动容器。

第四种方法意味着你必须编写代码才能读取 ConfigMap 和它的数据。然而, 由于你是直接使用 Kubernetes API,因此只要 ConfigMap 发生更改, 你的应用就能够通过订阅来获取更新,并且在这样的情况发生的时候做出反应。 通过直接进入 Kubernetes API,这个技术也可以让你能够获取到不同的名字空间里的 ConfigMap。

apiVersion: v1
kind: Pod
metadata:
  name: configmap-demo-pod
spec:
  containers:
    - name: demo
      image: alpine
      command: ["sleep", "3600"]
      env:
        # 定义环境变量
        - name: PLAYER_INITIAL_LIVES # 请注意这里和 ConfigMap 中的键名是不一样的
          valueFrom:
            configMapKeyRef:
              name: game-demo           # 这个值来自 ConfigMap
              key: player_initial_lives # 需要取值的键
        - name: UI_PROPERTIES_FILE_NAME
          valueFrom:
            configMapKeyRef:
              name: game-demo
              key: ui_properties_file_name
      volumeMounts:
      - name: config
        mountPath: "/config"
        readOnly: true
  volumes:
    # 你可以在 Pod 级别设置卷,然后将其挂载到 Pod 内的容器中
    - name: config
      configMap:
        # 提供你想要挂载的 ConfigMap 的名字
        name: game-demo
        # 来自 ConfigMap 的一组键,将被创建为文件
        items:
        - key: "game.properties"
          path: "game.properties"
        - key: "user-interface.properties"
          path: "user-interface.properties"

Secret

secret和configMap的使用类似

apiVersion: v1
kind: Secret
metadata:
  name: test-secret
  namespace: test
type: kubernetes.io/tls
data:
  tls.crt: “crt内容”
  tls.key: “key内容”

参考

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐