需求来源
- 可变的配置不能放到容器里,否则配置改变,需要重新构建镜像
- ConfigMap —— 资源
- 敏感信息的存储和使用
- Secret —— 资源
- 认证相关,例如容器访问集群的 kube-apiserver
- ServiceAccount —— 资源
- 容器在节点上运行的资源要求
- Resources —— spec 字段
- 容器是共享内核的,统一 node 上如何安全管控
- SecurityContext —— spec 字段
- 容器启动前的前置校验
- InitContainers —— spec 字段
ConfigMap
定义
- 主要被 pod 使用
- 配置信息与镜像解耦
- 可以指定文件或者指定目录,以及直接指定键值对
- ConfigMap 文件的大小。虽然说 ConfigMap 文件没有大小限制,但是在 ETCD 里面,数据的写入是有大小限制的,限制在 1MB 以内;
- pod 引入 ConfigMap 的时候,必须是相同的 Namespace 中的 ConfigMap
- pod 引用的 ConfigMap。假如这个 ConfigMap 不存在,这个 pod 是无法创建成功的
- 使用 envFrom 的方式。把 ConfigMap 里面所有的信息导入成环境变量时,如果 ConfigMap 里有些 key 是无效的,比如 key 的名字里面带有数字,那么这个环境变量是不会注入容器的,它会被忽略。但是这个 pod 本身是可以创建的
- 通过 K8s api 创建的 pod 才能使用 ConfigMap,比如说通过用命令行 kubectl 来创建的 pod。通过 manifest 创建的 static pod,它是不能使用 ConfigMap
配置信息可以文件的形式挂载到容器里,kv键值对怎么用文件表示?实际运行看看
- 没想到如此简单粗暴,k作为文件名,v作为文件内容
使用方式
实操
创建configmap
apiVersion: v1
kind: ConfigMap
metadata:
name: my-configmap
data:
a.b.json: "server {\n listen 80;\n server_name localhost;\n\n location / {\n root html;\n index index.html index.htm;\n }\n}"
a.c: jkjkjkkj
a1: sdasg
使用configmap
apiVersion: v1
kind: Pod
metadata:
name: test-configmap
spec:
containers:
- name: centos
image: centos
command: ["/bin/sh"]
args: ["-c","env;sleep 3600"]
env:
- name: MY_ENV_KEY
valueFrom:
configMapKeyRef:
name: my-configmap
key: a.c
- name: MY_ENV_KEY_1
valueFrom:
configMapKeyRef:
name: my-configmap
key: a1
volumeMounts:
- name: configmap-volumes
mountPath: /etc/config
volumes:
- name: configmap-volumes
configMap:
name: my-configmap
-
valueFrom.configMapKeyRef.key
如果配置错误会导致创建容器失败,好严格啊,但也是提前暴露问题。不过日志里没有具体的提示信息,只能看到创建容器失败。。。通过请教大佬,学到了这个命令:
kubectl describe pod test-configmap
,能查看到 pod 创建时的事件,其中就能看到是获取配置时出错了 -
command: ["/bin/sh"] args: ["-c","env;sleep 3600"]
:容器启动时运行多个命令 -
k8s 里进入容器
-
如果 pod 只有一个容器,容器名称为 pod name
-
多个容器时,通过
--container
指定
kubectl exec -it my-pod --container main-app -- /bin/bash
-
-
kubectl delete
:删除通过编排文件创建出来的资源
Secret
Secret 介绍
Secret 是一个主要用来存储密码 token 等一些敏感信息的资源对象。敏感信息是采用 base-64 编码保存起来的,相比储存在ConfigMap中更规范,更安全。
为啥更安全?这个加密又没有使用复杂算法、秘钥之类的
Secret 有4个类型
- Opaque,它是普通的 Secret 文件,默认;
- service-account-token,是用于 service-account 身份认证用的 Secret;
- dockerconfigjson,这是拉取私有仓库镜像的用的一种 Secret;
- bootstrap.token,是用于节点接入集群校验用的 Secret。
Secret 创建
-
系统创建:比如 K8s 为每一个 namespace 的默认用户(default ServiceAccount)创建 Secret;
-
用户手动创建
Secret 使用
- 第一种方式:如上图左侧所示,用户直接指定,把 mysecret 挂载到容器 /etc/foo 目录下面;
- 第二种方式:如上图右侧所示,系统自动生成,把 serviceaccount-secret 自动挂载到容器 /var/run/secrets/kubernetes.io/serviceaccount 目录下,它会生成两个文件,一个是 ca.crt,一个是 token。这是两个保存了认证信息的证书文件。
使用私有镜像库
-
第一种方式:如下图左侧所示,直接在 pod 里面,通过 imagePullSecrets 字段来配置;
-
第二种方式是自动注入。用户提前在 pod 会使用的 serviceaccount 里配置 imagePullSecrets,Pod创建时系统自动注入这个 imagePullSecrets。
secrets.name是干啥的?和imagePullSecrets.name的区别?
Secret 使用注意要点
-
Secret 的文件大小限制。这个跟 ConfigMap 一样,也是 1MB;
-
Secret 采用了 base-64 编码,但是它跟明文也没有太大区别。所以说,如果有一些机密信息要用 Secret 来存储的话,还是要很慎重考虑。也就是说谁会来访问你这个集群,谁会来用你这个 Secret,还是要慎重考虑,因为它如果能够访问这个集群,就能拿到这个 Secret。
-
那这个base64加密是鸡肋吗?
查了下,没发现啥好处,我想到的只有防止被加密字符串里的特殊字符影响yaml文件的解析
-
如果是对 Secret 敏感信息要求很高,对加密这块有很强的需求,推荐可以使用 Kubernetes 和开源的 vault做一个解决方案,来解决敏感信息的加密和权限管理
-
-
Secret 读取的最佳实践,建议不要用 list/watch,如果用 list/watch 操作的话,会把 namespace 下的所有 Secret 全部拉取下来,这样其实暴露了更多的信息。推荐使用 GET 的方法,这样只获取你自己需要的那个 Secret。
-
这里不懂了,后面的课程学了回来看
-
ServiceAccount
ServiceAccount 介绍
ServiceAccount 用于解决 pod 在集群里面的身份认证问题,身份认证信息是存在于 Secret 里面。
- 系统默认创建了一个用于访问集群的 ServiceAccount
pod 认证流程
-
pod 创建时 Admission Controller 会根据指定的 ServiceAccount(默认 default)把对应的 Secret 挂载到容器里
-
访问集群时会用到 Secret 里的认证信息
- 一个是 tlsClientConfig,这个主要是用于 ca.crt 校验服务端;
- 第二个是 Bearer Token,这个就是 pod 的身份认证。在服务端,会利用 token 对 pod 进行一个身份认证
这里只讲了认证,鉴权还得 RBAC
Resource
resource 介绍
- 容器资源配置管理
- 目前内部支持类型有三种:CPU、内存,以及临时存储。可自定义其他配置项。
- 配置值必须为整数
resource 使用
- limits:最多使用多少
Pod 服务质量 (QoS) 配置
根据容器对 CPU、内存资源的需求,对 pod 的服务质量进行一个分类,分别是 Guaranteed、Burstable 和 BestEffort。
- Guaranteed :pod 里面每个容器都必须有内存和 CPU 的 request 以及 limit 的一个声明,且 request 和 limit 必须是一样的,这就是 Guaranteed;
- Burstable:Burstable 至少有一个容器存在内存和 CPU 的一个 request;
- BestEffort:只要不是 Guaranteed 和 Burstable,那就是 BestEffort。
当节点 memory 配额资源不足,kubelet会把一些低优先级的,或者说服务质量要求不高的pod 驱逐掉。按照先去除 BestEffort,再去除 Burstable 的顺序来驱逐 pod 的。
SecurityContext
SecurityContext 介绍
SecurityContext 主要是用于限制容器的一个行为,它能保证系统和其他容器的安全。这一块的能力不是 Kubernetes 或者容器 runtime 本身的能力,而是 Kubernetes 和 runtime 通过用户的配置,最后下传到内核里,再通过内核的机制让 SecurityContext 来生效。
SecurityContext 主要分为三个级别
- 第一个是容器级别,仅对容器生效;
- 第二个是 pod 级别,对 pod 里所有容器生效;
- 第三个是集群级别,就是 PSP,对集群内所有 pod 生效。
权限和访问控制设置项
-
第一个就是通过用户 ID 和组 ID 来控制文件访问权限;
-
第二个是 SELinux,它是通过策略配置来控制用户或者进程对文件的访问控制;
-
第三个是特权容器;
-
第四个是 Capabilities,它也是给特定进程来配置一个 privileged 能力;
-
第五个是 AppArmor,它也是通过一些配置文件来控制可执行文件的一个访问控制权限,比如说一些端口的读写;
-
第六个是一个对系统调用的控制;
-
第七个是对子进程能否获取比父亲更多的权限的一个限制。
主要是控制容器权限的,这里没有讲太多
InitContainer
InitContainer 介绍
-
InitContainer 首先会比普通 container 先启动,并且直到所有的 InitContainer 执行成功后,普通 container 才会被启动;
-
InitContainer 之间是按定义的次序去启动执行的,执行成功一个之后再执行第二个,而普通的 container 是并发启动的;
-
InitContainer 执行成功后就结束退出,而普通容器可能会一直在执行。它可能是一个 longtime 的,或者说失败了会重启。
用于前置条件检查,或者是完成前置工作
当你所有的事情都听从大多数人的意见时,你注定成为“大多数人”