需求来源
背景问题
除了依托容器镜像来定义运行的Container,Pod还需解决如下问题
- 不可变的基础设施(容器)的可变配置
- 敏感信息的存储和使用(密码,token等)
- 集群中Pod自我的身份认证
- 容器运行资源的配置管理
- 容器的运行安全管控
- 容器启动前置条件检验
pod的配置管理
ConfigMap
ConfigMap介绍
主要管理容器运行所需的配置文件,环境变量,命令行参数等可变配置。用于解耦容器镜像和可变配置,从而保障Pod的可移植性。
ConfigMap创建
- 创建命令:kubectl create configmap [name] [data]
- 其中data:
- 指定文件或者目录
- 指定键值对
ConfigMap使用
ConfigMap主要被Pod使用,一般用于挂在Pod用的配置文件,环境变量,命令行参数等。
ConfigMap使用注意点
- ConfigMap文件大小限制:1MB(ETCD的要求)
- Pod只能引用相同Namespace中的ConfigMap
- Pod引用的ConfigMap不存在时,Pod无法创建成功。即Pod创建前需要先创建好ConfigMap。
- 使用envFrom从ConfigMap来配置环境变量时,如果ConfigMap中的某些key被认为无效(比如key名称中带有数字),该环境变量将不会注入容器,但是Pod可以正常创建。
- 只有通过k8s api创建的pod才能使用ConfigMap,其他方式创建的pod(如manifest创建的static)不能使用ConfigMap
Secret
Secret介绍
secret实在集群中用于存储密码,token等敏感信息用的资源对象。其中的敏感数据采用base-64编码保存,相比存储在明文的ConfigMap中更规范,更安全。
- Opaque:普通的secret类型
- service-account-token:用于service-account身份认证
- dockerconfigjson:用于拉取私有仓库镜像
- token:用于节点接入集群校验
Secret创建
- Secret创建可以是用户自己创建,也有Secret是系统自动创建
- 比如:k8s为每个namespace的默认用户(default ServiceAccount)创建的Secret
- 手动创建命令:kubectl create secret generic [NAME] [DATA] [TYPE]
- DATA:可以指定文件/键值对
- TYPE:默认为Opaque
Secret使用
Secret主要被Pod使用,一般通过volume挂载到指定容器目录,供容器中业务使用。另外在需要访问私有镜像仓库时,也可以引用Secret来实现。
使用私有镜像库
私有镜像仓库的信息可以通过Secret(kubernetes.io/dockerconfigjson)存储在集群中,Pod如果需要使用私有镜像仓库,可以通过如下两种方式来配置:
- Pod.spec.imagePullSecrets来指定secret
- ServiceAccount中设置imagePullSecrets,然后自动为使用该SA的Pod注入imagePullSecrets信息
Secret使用的注意点
- Secret文件大小限制:1MB
- Secret虽然采用,但是可以简单解码查看原始信息。因此机密信息采用Secret存储仍需要谨慎考虑或者对secret访问者进行控制。对Secret加密由较强需求。可以考虑结合Kubernetes+Valut来解决敏感信息的加密和权限管理。
- Secret最佳实践:因为list/watch的一半处理将获取到namespace下所有secret,因此不建议采取list/watch方式获取Secret信息。而推荐使用GET来获取需要的Secret,从而减少更多Secret暴露的可能性。
ServiceAccount
ServiceAccount介绍
ServiceAccount主要用于解决Pod在集群中的身份认证问题。其中认证使用的授权信息利用前面讲到的Secret(type=kubernetes.io/service-account-token)进行管理。
举例:Pod中的应用访问它所属的k8s集群
实现原理:
- Pod创建时Admission Controller会根据指定的ServiceAccount(默认为default)把对应的Secret挂在到容器中固定目录下(/var/run/secrets/kubernetes.io/serviceaccount)。(k8s自动实现)
- 当Pod访问集群时,可以默认利用Secret中的token文件来认证Pod的身份。(ca.crt用于校验服务端)
- 默认token的认证信息为:
- Group:system:serviceaccounts:[namespace-name]
- User:System:serviceaccount:[namespace-name]:[pod-name]
- *Pod身份被认证合法后,其权限需要通过RBAC功能来配置。默认具备资源的GET权限。
Resource
容器资源配置管理
- 支持资源类型:
- CPU:单位:millicore(1Core=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.limits.request.ephemeral-storage
Pod服务质量(QoS)配置
- 依据容器对CPU,Memory资源的request/limit需求,Pod服务质量分为:
- Guaranteed
- Pod里的每个容器都必须有内存、CPU限制和请求,而且必须是一样的
- Bursrable
- Pod里至少由一个容器由内存或者CPU请求
- BestEffort
- 当节点上的Memory资源不足时,将依据BestEffort,Burstable,Guranteed的优先顺序驱逐Pod
SecurityContext
- Security Context主要用于限制容器的行为,从而保障系统和其他容器的安全。通过内核机制。
- 容器级别的Security Context:仅对指定容器生效
- Pod级别的Security Context:对指定Pod中的所有容器生效
- Pod Security Policies(PSP):对集群内所有Pod生效
- 权限和访问控制设置项:
- Discretionary Access Control:根据用户id和组id来控制文件访问权限
- SELinux:通过SELinux的策略配置控制用户,进程等对文件的访问控制
- privileged:容器是否为特权模式
- Linux Capabilities:给特定进程配置privileged能力
- AppArmor:控制可执行文件的访问控制权限(读写文件/目录,网络端口读写等)
- Seccomp:控制进程可以操作的系统调用
- AllowPrivilegeEscalation:控制一个进程是否能比其父进程获取更多的权限
InitContainer
InitContainer介绍
InitContainer和普通Container的区别:
- InitContainer会先于普通Container启动执行,直到所有InitContainer执行成功后,普通Container才会被启动
- Pod中多个InitContainer之间是按次序依次启动执行,而Pod中多个普通Container是并行启动
- InitContainer执行成功后就结束退出了,而普通容器可能会一直执行或者重启(restartPolicy != Never)
InitContainer用途:
- 基于InitContainer和普通Container的区别,一般InitContainer用于普通Container启动前的初始化(如配置文件准备)或者普通Container启动的前置条件检验(如网络连通检验)