我可以看到 2 种方法来满足您的需求:
1 - 使用 configMap: 您需要授予 initContainer 运行 kubectl 的权限,以创建具有所需值的 configmap 或 secret,并使您的主容器读取 configmap 和配置为环境变量。
2 - 使用persistentVolume:在initContainer中写入文件,并在pod上挂载相同的卷,读取文件并根据需要使用。
first 方法更加优雅 IMO,因为您可以配置权限级别并隔离 configMap 对象以使用 Role 权限。
第二种方法比第二种方法更简单,所需步骤更少,但是这取决于你需要存储什么样的数据,如果它是一个明智的数据,我建议使用第二种方法。
方法一
这种方式包括使用您希望的变量创建一个 kubernetes configMap,并使用此 configMap 中的值在主容器中配置环境变量。
这需要一些额外的步骤:
- 创建服务帐户
- 创建一个允许在 configmap 中执行 serviceAccount 操作的角色
- 创建一个 RoleBinding 以将 serviceAccount 与 Role 连接起来
在这种情况下,initContainer 将负责创建/更新configmap,您的主容器将读取此配置映射并将值配置为环境变量。
注意:在这个例子中,我使用了 myns 命名空间中的所有资源。
您应该进行适当的更改以最适合您的环境,例如:角色/集群角色权限,您可以使用 resourceNames 使 ir 更具限制性。看这里
envFrom:这将负责从 Kubernetes 读取 configMap 并设置环境变量。更多信息here.
RBAC
以下规范将创建serviceAccount、Role and RoleBinding:
创建一个名为rbac-sa-myuser.yaml的文件,内容如下
apiVersion: v1
kind: ServiceAccount
metadata:
name: sa-myuser
namespace: myns
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: myns
name: role-configmap
rules:
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["create", "update", "get", "patch", "delete"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: rolebinding-configmap
namespace: myns
roleRef:
kind: Role
name: role-configmap
apiGroup: rbac.authorization.k8s.io
subjects:
- kind: ServiceAccount
name: sa-myuser
namespace: myns
通过kubectl apply -f rbac-sa-myuser.yaml申请
现在,您需要在部署模板中进行适当的更改,添加额外的参数:
serviceAccountName:
spec:
serviceAccountName: sa-myuser
envFrom:
envFrom:
- configMapRef:
name: my-var
initContainer:这里只是一个运行命令来创建 configMap 的 initContainer 示例,您需要根据您的用例进行调整:
initContainers:
- name: my-init
image: bitnami/kubectl
command: ['sh', '-c', 'kubectl delete cm my-var ; kubectl create cm my-var --from-literal MYVAR=UPVOTEIT']
最后,您的部署规范必须如下所示:
apiVersion: apps/v1
kind: Deployment
metadata:
name: var-example
namespace: myns
spec:
selector:
matchLabels:
app: var-example
template:
metadata:
labels:
app: var-example
spec:
serviceAccountName: sa-myuser
containers:
- name: var-example
image: nginx
envFrom:
- configMapRef:
name: my-var
ports:
- name: http
containerPort: 80
initContainers:
- name: my-init
image: bitnami/kubectl
command: ['sh', '-c', 'kubectl delete cm my-var ; kubectl create cm my-var --from-literal MYVAR=UPVOTEIT']
方法二:持久化卷
您需要在两个 pod 中创建一个 persistVolume 并挂载,例如,我将使用 hostPath 来演示它是如何工作的,但是您需要为您的工作负载找到最佳的持久卷类型。查看here 各种列表。
关注yaml 将在您的节点上创建一个 2Gi 的 persistentVolume 和一个 1Gi 的 persistentVolumeClaim。
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-volume
labels:
type: local
spec:
storageClassName: manual
capacity:
storage: 2Gi
accessModes:
- ReadWriteOnce
hostPath:
path: "/mnt/data"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pv-claim
spec:
storageClassName: manual
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
然后只需在 initContainer 和主 pod 中创建安装卷的部署,例如:
apiVersion: apps/v1
kind: Deployment
metadata:
name: var-example
spec:
selector:
matchLabels:
app: var-example
template:
metadata:
labels:
app: var-example
spec:
volumes:
- name: pv-storage
persistentVolumeClaim:
claimName: pv-claim
containers:
- name: var-example
image: nginx
ports:
- name: http
containerPort: 80
volumeMounts:
- mountPath: "/mnt/data"
name: pv-storage
command: ["sh", "-c", "echo MYVAR=$(cat /mnt/data/myfile.txt) >> /etc/environment ; sleep 3600"]
initContainers:
- name: my-init
image: busybox:1.28
volumeMounts:
- mountPath: "/mnt/data"
name: pv-storage
command: ['sh', '-c', 'echo "UPVOTE_IT" > /mnt/data/myfile.txt']