除了依托容器镜像来定义运行的Container,Pod还需要解决如下问题
1、不可变基础设施(容器)的可变配置
2、敏感信息的存储和使用(如:密码,token等)
3、集群中Pod自我的身份认证
4、容器运行资源的配置管理
5、容器的运行安全管控
6、容器启动前置条件校验
主要管理容器运行所需的配置文件,环境变量,命令行参数等可变配置。用于解耦容器镜像和可变配置,从而保障工作负载(Pod)的可移植性。

创建命令: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主要被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
Secret是在集群中用于存储密码,token等敏感信息用的资源对象。其中的敏感数据采用base-64编码保存,相比存储在明文的ConfigMap中更规范,更安全。
- apiVersion: v1
- kind: Secret
- metadata:
- name: mysecret
- namespace: kube-system
- type: Opaque
- data:
- username: xxx
- password: xxxx
Secret主要有如下类型:
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主要被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

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主要用于解决Pod在集群中的身份认证问题。其中认证使用的授权信息,则利用前面讲到Secret(type=kubernetes.io/service-account-token)进行管理。
命令
- kubectl get serviceaccount -o yaml
- kubectl get secret/default-token-c9kc7 -o yaml

实现原理:
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"
依据容器对CPU,Memory资源的request/limit需求,Pod服务质量分类:
Guaranteed定义:
Burstable定义:
BestEffort定义
当节点上Memory资源不足时,将依据BestEffort,Burstable, Buaranteed的优先顺序驱逐Pod
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
1、InitContainer会先于普通Container启动执行,直到所有InitContainer执行成功后,普通Container才会被启动
2、Pod中多个InitContainer之间是按次序以此启动执行,而Pod中多个普通Container是并行启动
3、InitContainer执行成功后就结束退出了,而普通容器可能会一直执行或者重启(restartPolicy!=Never)
基于InitContainer和普通Container的区别,一般InitContainer用于普通Container启动前的初始化(如配置文件准备)或者普通Container启动的前置条件检查(如网络联通检验)。
