一些特殊的工作负载,需要提前在集群母机上部署一些软件,比如一些特殊的存储或者是网络插件等,如果不考虑 k8s 的方式,一般的操作可能是通过 ssh
命令,对远程主机执行 yum install
之类的操作。
在测试 Longhorn 的时候,看到 Longhorn 的文档 有提供一个 DaemonSet 来完成 iSCSI 的配置。但是 DaemonSet 有个问题就是容器会不断重启,所以个人更期望是通过一个 Job 来完成这样的操作,所以大概改造成下面的例子的样子。
原理其实也不是太复杂,在特权容器内,通过设置 hostPID
参数,使用 nscenter
挂载母机的 /proc
文件系统,然后执行 yum install
之类的命令,可以执行一些在母机上安装软件的工作。然后通过一些 affinity
的配置,让 Job 生产的 Pod 可以部署到想要做变更的节点上即可,并且可以通过 restartPolicy
来控制任务失败之后的策略,如果成功就直接到达 complete
的状态。
apiVersion: batch/v1
kind: Job
metadata:
name: longhorn-iscsi-installation
annotations:
command: &cmd OS=$(grep -E "^ID_LIKE=" /etc/os-release | cut -d '=' -f 2); if [[ -z "${OS}" ]]; then OS=$(grep -E "^ID=" /etc/os-release | cut -d '=' -f 2); fi; if [[ "${OS}" == *"debian"* ]]; then sudo apt-get update -q -y && sudo apt-get install -q -y open-iscsi && sudo systemctl -q enable iscsid && sudo systemctl start iscsid; elif [[ "${OS}" == *"suse"* ]]; then sudo zypper --gpg-auto-import-keys -q refresh && sudo zypper --gpg-auto-import-keys -q install -y open-iscsi && sudo systemctl -q enable iscsid && sudo systemctl start iscsid; else sudo yum makecache -q -y && sudo yum --setopt=tsflags=noscripts install -q -y iscsi-initiator-utils && echo "InitiatorName=$(/sbin/iscsi-iname)" > /etc/iscsi/initiatorname.iscsi && sudo systemctl -q enable iscsid && sudo systemctl start iscsid; fi && if [ $? -eq 0 ]; then echo "iscsi install successfully"; else echo "iscsi install failed error code $?"; fi
spec:
template:
spec:
restartPolicy: OnFailure
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/os
operator: In
values:
- linux
hostNetwork: true
hostPID: true
containers:
- name: iscsi-installation
command:
- nsenter
- --mount=/proc/1/ns/mnt
- --
- bash
- -c
- *cmd
image: alpine:3.12
securityContext:
privileged: true