K8S之应用配置管理

背景问题

除了依托容器镜像来定义运行的Container,Pod还需要解决如下问题

1、不可变基础设施(容器)的可变配置

2、敏感信息的存储和使用(如:密码,token等)

3、集群中Pod自我的身份认证

4、容器运行资源的配置管理

5、容器的运行安全管控

6、容器启动前置条件校验

容器

  • 可变配置:ConfigMap
  • 敏感信息:Secret
  • 身份认证:ServiceAccount
  • 资源配置:Spec.Containers[].Resources.limits/requests
  • 安全管控:Spec.Containers[].SecurityContext
  • 前置校验:Spec.InitContainers

ConfigMap介绍

主要管理容器运行所需的配置文件,环境变量,命令行参数等可变配置。用于解耦容器镜像和可变配置,从而保障工作负载(Pod)的可移植性。

ConfigMAp创建

创建命令:kubectl create configmap [NAME] [DATA]

其中DATA:

  • 指定文件或者目录
  • 指定键值对

示例:

1、指定文件:

kubectl create configmap kube-flannel-cfg --from-file=configure-pod-container/configmap/cni-conf.json -n kube-system

2、指定键值对:

kubectl create configmap special-config --from-literal=special.how=very --from-literal=special.type=charm

ConfigMap使用

ConfigMap主要被Pod使用,一般用于挂载Pod用的配置文件,环境变量,命令行参数等。

具体配置文件:

# 用ConfigMap配置环境变量
apiVersion: v1
kind: Pod
metadata:
  name: cm-env-test
spec:
  containers:
    - name: test-container
        image: busybox
        command: ["/bin/sh", "-c", "env"]
        env:
        # 用special-config中special.how定义环境变量
        - name: SPECIAL_LEVEL_KEY
          valueFrom:
            configMapKeyRef:
              name: special-config
              key: specal.how
  restartPolicy: Never

  
# 用ConfigMap配置管控命令行参数
apiVersion: v1
kind: Pod
metadata:
  name: cm-test-test
spec:
  containers:
    - name: test-container
      image: busybox
      command: ["/bin/sh", "-c", "echo $(SPECIAL_LEVEL_KEY)"]
      env:
      # 在命令行参数中使用ConfigMap定义的环境变量
      - name: SPECIAL_LEVEL_KEY
        valueFrom:
          configMapKeyRef:
            name: special-config
            key: special.how
  restartPolicy: Never

  
# 用ConfigMap挂载配置文件
apiVersion: v1
kind: Pod
metadata:
  name: cm-volume-test
spec:
  containers:
    - name: test-container
      image: busybox
      # # ConfigMap中指定的内容以文件形式挂载在容器中的/etc/config目录下
      command: ["/bin/sh", "-c", "ls /etc/config/"]
      volumeMounts:
      - name: config-volume
        mountPath: /etc/config
  volumes:
    - name: config-volume
      configMap:
        name: special-config
  restartPolicy: Never

ConfigMap使用注意点

  1. ConfigMap文件大小限制:1MB (.ETCD的要求)
  2. Pod只能引用相同Namespace中的ConfigMap
  3. Pod引用的ConfigMap不存在时,Pod无法创建成功。即Pod创建前需要先创建好Config Map。
  4. 使用envFrom从ConfigMap来配置环境变量时,如果CongfigMap中的某些key被认为无效(比如key名称中带有数字),该环境变量将不会注入容器,但是Pod可以正常创建。
  5. 只有通过k8s api创建的pod才能使用ConfigMap,其他方式创建的pod(如manifest创建的static pod)不能使用ConfigMap

Secret介绍

Secret是在集群中用于存储密码,token等敏感信息用的资源对象。其中的敏感数据采用base-64编码保存,相比存储在明文的ConfigMap中更规范,更安全。

apiVersion: v1
kind: Secret
metadata:
  name: mysecret
  namespace: kube-system
type: Opaque
data:
  username: xxx
  password: xxxx

Secret主要有如下类型:

  • type=Opaque
  • type=kubernetes.io/service-account-token
  • type=kubernetes.io/dockerconfigjson
  • type=bootstrap.kubernetes.io/token

1、指定文件:

kubectl create secret generic myregistrykey --from-file=.dockerconfigjson=/root/.docker/config.json --type=kubernetes.io/dockerconfigjson

命令:

kubectl create secret generic myregistrykey --from-file=.dockerconfigjson=/root/.docker/config.json --type=kubernetes.io/dockerconfigjson

kubectl get secret

kubectl describe secret/myregistrykey

kubectl get secret/myregistrykey -o yaml

2、指定键值对:

kubectl create secret generic prod-db-secret --from-literal=username=produser --from-literal=password=Y4nys7f11

命令:

kubectl create secret generic prod-db-secret --from-literal=username=produser --from-literal=password=Y4nys7f11

kubectl get secret/prod-db-secret -o yaml

Secret使用

Secret主要被Pod使用,一般通过volume挂载到指定容器目录,供容器中业务使用。另外在需要访问私有镜像仓库时,也可以引用Secret来实现。

[root@master pod]# cat secret-3.yaml
apiVersion: v1
kind: Pod
metadata:
  name: mypod-3
spec:
  containers:
  - name: mypod
    image: busybox
    command: ["/bin/sh", "-c", "sleep 120"]
    volumeMounts:
    - name: chaitc
      mountPath: "/etc/chaitc/"
      readOnly: true
  volumes:
  - name: chaitc
    secret:
      secretName: myregistrykey

apiVersion: v1
kind: Pod
metadata:
  name: mypod-123
  namespace: default
spec:
  containers:
  - name: mypod
    image: busybox
    command: ["/bin/sh", "-c", "sleep 180"]
    volumeMounts:
    - name: chaitc
      mountPath: /var/run/secrets/kubernetes.io/serviceaccount
      readOnly: true
  serviceAccount: default
  serviceAccountName: default
  volumes:
  - name: chaitc
    secret:
      defaultMode: 420
      secretName: default-token-c9kc7

Secret使用的注意点

1、Secret文件大小限制:1MB

2、Secret虽然采用base-64编码,但是可以简单解码查看原始信息。因此机密信息才用Secret存储仍需要慎重考虑或者Secret访问者进行控制。对Secret加密有较强需求,可以考虑结合Kubernetes + Vault来解决敏感信息的加密和权限管理。

3、Secret最佳实践:因为list/watch的一般处理将获取到的namespace下所有secret,因此不建议采取list/watch方式获取Secret信息。而推荐使用GET来获取需要的Secret,从而减少更多Secret暴露的可能性。

ServiceAccount介绍

ServiceAccount主要用于解决Pod在集群中的身份认证问题。其中认证使用的授权信息,则利用前面讲到Secret(type=kubernetes.io/service-account-token)进行管理。

命令

kubectl get serviceaccount -o yaml
kubectl get secret/default-token-c9kc7 -o yaml

举例: Pod里的应用访问它所属的K8S集群

实现原理:

1、Pod创建时Admission Controller会根据指定的ServiceAccount(默认为default)把对应的Secret挂载到容器的目录下(/var/run/secrets/kubernetes.io/serviceaccount).(*k8s自动实现)

2、当Pod访问集群时,可以默认利用Secret其中的token文件来认证Pod的身份。(ca.crt用于校验服务端)(*参考右边代码)

3、默认token的认证信息为:

        - Group: system:serviceaccounts:[namespace-name]

        - User: system:serviceaccount:[namespace-name]:[pod-name]

* 同时Pod身份被认证合法后,其权限需要通过RBAC功能来配置。默认具备资源的GET权限。

kubernetes/config.go at 76277917b9b98bfac79d0e25fe8f45dfc5bec145 · kubernetes/kubernetes · GitHub

// InClusterConfig returns a config object which uses the service account
// kubernetes gives to pods. It's intended for clients that expect to be
// running inside a pod running on kubernetes. It will return ErrNotInCluster
// if called from a process not running in a kubernetes environment.
func InClusterConfig() (*Config, error) {
	const (
		tokenFile  = "/var/run/secrets/kubernetes.io/serviceaccount/token"
		rootCAFile = "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt"
	)
	host, port := os.Getenv("KUBERNETES_SERVICE_HOST"), os.Getenv("KUBERNETES_SERVICE_PORT")
	if len(host) == 0 || len(port) == 0 {
		return nil, ErrNotInCluster
	}

	token, err := os.ReadFile(tokenFile)
	if err != nil {
		return nil, err
	}

	tlsClientConfig := TLSClientConfig{}

	if _, err := certutil.NewPool(rootCAFile); err != nil {
		klog.Errorf("Expected to load root CA config from %s, but got err: %v", rootCAFile, err)
	} else {
		tlsClientConfig.CAFile = rootCAFile
	}

	return &Config{
		// TODO: switch to using cluster DNS.
		Host:            "https://" + net.JoinHostPort(host, port),
		TLSClientConfig: tlsClientConfig,
		BearerToken:     string(token),
		BearerTokenFile: tokenFile,
	}, nil
}

容器资源配置管理

支持资源类型:

- CPU:单位:millicore (1 Core=1000millicore)

- Memory: 单位:Byte

- ephemeral storage(临时存储):单位:Byte

- 自定义资源:配置时必须为整数

配置方法:

资源配置分为request/limit两种类型

- CPU:

spec.containers[].resources.limits.cpu

spec.containers[].resources.requests.cpu

- Memory:

spec.containers[].resources.limits.memory

spec.containers[].resources.requests.memory

- ephemeral.storage(临时存储):

spec.containers[].resources.limits.ephemeral-storage

spec.containers[].resources.requests.ephemeral-storage

apiVersion: v1
kind: Pod
metadata:
  name: frontend
spec:
  containers:
  - name: wp
    image: wordpress
	resources:
	  # 申明需要的资源
	  requests:
	    memory: "64Mi"
		cpu: "250m"
		ephemeral-storage: "2Gi"
	  # 申明需要资源的边界
	  limits:
	    memory: "128Mi"
		cpu: "500m"
		ephemeral-storage: "4Gi"

Pod服务质量(QoS)配置

依据容器对CPU,Memory资源的request/limit需求,Pod服务质量分类:

  • Guaranteed
  • Burstable
  • BestEffort

Guaranteed定义:

  • Pod里的每个容器都必须有内存限制和请求,而且必须是一样的
  • Pod里的每个容器都必须有CPU限制和请求,而且必须是一样的

Burstable定义:

  • 非Guaranteed
  • Pod里至少有一个容器有内存或者CPU请求

BestEffort定义

  • 非Guaranteed
  • 非Burstable

当节点上Memory资源不足时,将依据BestEffort,Burstable, Buaranteed的优先顺序驱逐Pod

Security Context介绍

Security Context主要用于限制容器的行为,从而保障系统和其他容器的安全。

1、容器级别的Security Context: 仅对指定容器生效

2、Pod级别的Security Context: 对指定Pod中的所有容器生效

3、Pod Security Policies(PSP):对集群内所有Pod生效

权限和访问控制设置项:

1、Discretionary Access Control:根据用户id和组id来控制文件访问权限

2、SElinux: 通过SElinux的策略配置控制用户,进程等对文件等访问控制

3、privileged:容器是否为特权模式

4、Linux Capabilities:给特定进程配置privileged能力

5、AppArmor:控制可执行文件的访问控制权限(读写文件/目录,网络端口读写等)

6、Seccomp:控制进程可以操作的系统调用

7、AllowPrivilegeEscalation:控制一个进程是否能比其父进程获取更多的权限

apiVersion: v1
kind: Pod
metadata:
  name: security-context-demo
spec:
  # Pod级别Security Context定义
  securityContext:
    runAsUser: 1000
	runAsGroup: 3000
	fsGroup: 2000
  volumes:
  - name: sec-ctx-vol
    emptyDir: {}
  containers:
  - name: sec-ctx-demo
    image: busybox
	command: [ "sh", "-c", "sleep 1h" ]
	volumeMounts:
	- name: sec-ctx-vol
	  mountPath: /data/demo
	# 容器级别定义
	securityContext:
	  allowPrivilegeEscalation: false

InitContainer介绍

InitContainer和普通Container的区别:

1、InitContainer会先于普通Container启动执行,直到所有InitContainer执行成功后,普通Container才会被启动

2、Pod中多个InitContainer之间是按次序以此启动执行,而Pod中多个普通Container是并行启动

3、InitContainer执行成功后就结束退出了,而普通容器可能会一直执行或者重启(restartPolicy!=Never)

InitContainer用途:

基于InitContainer和普通Container的区别,一般InitContainer用于普通Container启动前的初始化(如配置文件准备)或者普通Container启动的前置条件检查(如网络联通检验)。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Helm是一个开源的Kubernetes应用包管理工具,用于简化Kubernetes应用的部署和管理。通过Helm,我们可以将应用打包为一个可重复使用的Chart,然后在Kubernetes集群中进行部署。 首先,我们需要安装Helm客户端工具。可以从Helm官方网站上下载适合自己操作系统的版本,并根据安装说明进行安装。 安装完成后,我们可以使用Helm命令行工具来创建一个新的Chart。一个Chart包含了应用的全部资源定义,包括Deployment、Service、Ingress等。我们可以使用helm create命令创建一个新的Chart,并根据需求修改Chart文件夹下的各个模板文件。 在Chart文件夹下,最重要的文件是values.yaml。该文件定义了Chart的默认值,我们可以在部署时通过传入自定义的values文件来覆盖这些默认值。这样,我们可以根据不同环境和需求来定制化应用的部署配置。 在部署之前,我们可以使用helm lint命令来检查Chart是否符合Helm的规范。一旦通过了lint检查,我们就可以使用helm install命令来将应用部署到Kubernetes集群中。 在部署完成后,我们可以使用helm list命令来查看已部署的应用,以及相关的版本信息和状态。如果需要升级应用或回滚到之前的版本,我们可以使用helm upgrade和helm rollback命令。 除了部署应用,Helm还提供了一些其他功能,如搜索和安装Chart仓库中的应用、打包和分享自己的Chart等。通过Helm,我们可以更方便地管理和扩展Kubernetes应用,提高开发和部署的效率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值