命令记不住

登陆

k8s 资源配置 Secret 相关配置管理

k8s资源配置Secret相关配置管理

1.Secret 介绍

Secret 是一个主要用来存储密码 token 等一些敏感信息的资源对象。其中,敏感信息是采用 base-64 编码保存起来的

元数据的话,里面主要是 name、namespace 两个字段;接下来是 type,它是非常重要的一个字段,是指 Secret 的一个类型。Secret 类型种类比较多,下面列了常用的四种类型:

  • 第一种是 Opaque,它是普通的 Secret 文件;
  • 第二种是 service-account-token,是用于 service-account 身份认证用的 Secret;
  • 第三种是 dockerconfigjson,这是拉取私有仓库镜像的用的一种 Secret;
  • 第四种是 bootstrap.token,是用于节点接入集群校验用的 Secret。

再接下来是 data,是存储的 Secret 的数据,它也是 key-value 的形式存储的。

1.1 Secret的创建

两种创建方式:

  • 系统创建:比如 K8s 为每一个 namespace 的默认用户(default ServiceAccount)创建 Secret;
  • 用户手动创建:手动创建命令,推荐 kubectl 这个命令行工具,它相对 ConfigMap 会多一个 type 参数。其中 data 也是一样,它也是可以指定文件和键值对的。type 的话,要是你不指定的话,默认是 Opaque 类型。

指定文件:

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

指定键值对:

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

两个例子,第一个是通过指定文件,创建了一个拉取私有仓库镜像的 Secret,指定的文件是 /root/.docker/config.json。type 的话指定的是 dockerconfigjson,另外一个我们指定键值对,我们 type 没有指定,默认是 Opaque。键值对是 key:value 的形式,其中对 value 内容进行 base64 加密。创建 Secret 就是这么一个情况。

1.2 Secret的使用

主要是被 pod 来使用,一般是通过 volume 形式挂载到容器里指定的目录,然后容器里的业务进程再到目录下读取 Secret 来进行使用。另外在需要访问私有镜像仓库时,也是通过引用 Secret 来实现。

2

挂载到用户指定目录的方式:
  • 第一种方式:如上图左侧所示,用户直接指定,把 mysecret 挂载到容器 /etc/foo 目录下面;
  • 第二种方式:如上图右侧所示,系统自动生成,把 serviceaccount-secret 自动挂载到容器 /var/run/secrets/kubernetes.io/serviceaccount 目录下,它会生成两个文件,一个是 ca.crt,一个是 token。这是两个保存了认证信息的证书文件。
1.3 使用私有镜像库

用 Secret 来使用私有镜像仓库。首先,私有镜像仓库的信息是存储在 Secret 里面的(具体参照上述的Secret创建章节),然后拉取私有仓库镜像,那么通过下图中两种方法的配置就可以:

  • 第一种方式:如下图左侧所示,直接在 pod 里面,通过 imagePullSecrets 字段来配置;
  • 第二种方式是自动注入。用户提前在 pod 会使用的 serviceaccount 里配置 imagePullSecrets,Pod创建时系统自动注入这个 imagePullSecrets。

1

1.4 Secret 使用注意要点

第一个是 Secret 的文件大小限制。这个跟 ConfigMap 一样,也是 1MB;

第二个是 Secret 采用了 base-64 编码,但是它跟明文也没有太大区别。所以说,如果有一些机密信息要用 Secret 来存储的话,还是要很慎重考虑。也就是说谁会来访问你这个集群,谁会来用你这个 Secret,还是要慎重考虑,因为它如果能够访问这个集群,就能拿到这个 Secret。如果是对 Secret 敏感信息要求很高,对加密这块有很强的需求,推荐可以使用 Kubernetes 和开源的 vault做一个解决方案,来解决敏感信息的加密和权限管理。

第三个就是 Secret 读取的最佳实践,建议不要用 list/watch,如果用 list/watch 操作的话,会把 namespace 下的所有 Secret 全部拉取下来,这样其实暴露了更多的信息。推荐使用 GET 的方法,这样只获取你自己需要的那个 Secret。

2.ServiceAccount

ServiceAccount 首先是用于解决 pod 在集群里面的身份认证问题,身份认证信息是存在于 Secret 里面。

Secret 字段,它指定 ServiceAccount 用哪一个 Secret,这个是 K8s 自动为 ServiceAccount 加上的。然后再来看一下上图中的右侧截图,它对应的 Secret 的 data 里有两块数据,一个是 ca.crt,一个是 token。ca.crt 用于对服务端的校验,token 用于 Pod 的身份认证,它们都是用 base64 编码过的。然后可以看到 metadata 即元信息里,其实是有关联 ServiceAccount 信息的(这个 secret 被哪个 ServiceAccount 使用)。最后我们注意一下 type,这个就是 service-account-token 这种类型。

4

2.1 Pod 里的应用访问它所属的 K8s 集群

od 是怎么利用 ServiceAccount 或者说它是怎么利用 secret 来访问所属 K8s 集群的。

其实 pod 创建的时候,首先它会把这个 secret 挂载到容器固定的目录下,这是 K8s 功能上实现的。它要把这个 ca.crt 和 token 这两个文件挂载到固定目录下面。

Config 里面有两部分信息:

  • 一个是 tlsClientConfig,这个主要是用于 ca.crt 校验服务端;
  • 第二个是 Bearer Token,这个就是 pod 的身份认证。在服务端,会利用 token 对 pod 进行一个身份认证。

再次回到上图左侧。认证完之后 pod 的身份信息会有两部分:一个是 Group,一个是 User。身份认证是就是认证这两部分信息。接着可以使用 RBAC 功能,对 pod 进行一个授权管理。

假如 RBAC 没有配置的话,默认的 pod 具有资源 GET 权限,就是可以从所属的 K8s 集群里 get 数据。

3.SecurityContext限制容器行为

SecurityContext 主要是用于限制容器的一个行为,它能保证系统和其他容器的安全。这一块的能力不是 Kubernetes 或者容器 runtime 本身的能力,而是 Kubernetes 和 runtime 通过用户的配置,最后下传到内核里,再通过内核的机制让 SecurityContext 来生效。所以这里讲的内容,会比较简单或者说比较抽象一点。

3.1 SecurityContext 主要分为三个级别

SecurityContext 主要分为三个级别:

  • 第一个是容器级别,仅对容器生效;
  • 第二个是 pod 级别,对 pod 里所有容器生效;
  • 第三个是集群级别,就是 PSP,对集群内所有 pod 生效。
3.2 权限和访问控制设置项

现在一共7项

  1. 第一个就是通过用户 ID 和组 ID 来控制文件访问权限;
  2. 第二个是 SELinux,它是通过策略配置来控制用户或者进程对文件的访问控制;
  3. 第三个是特权容器;
  4. 第四个是 Capabilities,它也是给特定进程来配置一个 privileged 能力;
  5. 第五个是 AppArmor,它也是通过一些配置文件来控制可执行文件的一个访问控制权限,比如说一些端口的读写;
  6. 第六个是一个对系统调用的控制;
  7. 第七个是对子进程能否获取比父亲更多的权限的一个限制。

最后其实都是落到内核来控制它的一些权限。