如何在OpenShift集群中不使用--privileged标志部署FN Server?
在OpenShift非特权模式下部署FN Server的可行方案
我们尝试在OpenShift集群中部署FN Server,不使用特权安全上下文,仅以非特权root模式运行,但遇到以下错误:
/usr/local/bin/preentry.sh: set: line 14: can't access tty; job control turned off mount: permission denied (are you root?) Could not mount /sys/kernel/security. AppArmor detection and --privileged mode might break. mount: permission denied (are you root?) time="2022-12-09T12:03:59Z" level=info msg="Setting log level to" fields.level=DEBUG time="2022-12-09T12:03:59Z" level=info msg="Registering data store provider 'sql'" time="2022-12-09T12:03:59Z" level=debug msg="creating new datastore" db=sqlite3 time="2022-12-09T12:03:59Z" level=debug msg="mysql does not support sqlite3" time="2022-12-09T12:03:59Z" level=debug msg="postgres does not support sqlite3" time="2022-12-09T12:03:59Z" level=debug msg="mysql does not support sqlite3" time="2022-12-09T12:03:59Z" level=debug msg="postgres does not support sqlite3" time="2022-12-09T12:03:59Z" level=info msg="Connecting to DB" url="sqlite3:///app/data/fn.db" time="2022-12-09T12:03:59Z" level=info msg="datastore dialed" datastore=sqlite3 max_idle_connections=256 url="sqlite3:///app/data/fn.db" time="2022-12-09T12:03:59Z" level=debug msg="mysql does not support sqlite3" time="2022-12-09T12:03:59Z" level=debug msg="postgres does not support sqlite3" time="2022-12-09T12:03:59Z" level=info msg="agent starting cfg={MinDockerVersion:17.10.0-ce ContainerLabelTag: DockerNetworks: DockerLoadFile: DisableUnprivilegedContainers:false FreezeIdle:50ms HotPoll:200ms HotLauncherTimeout:1h0m0s HotPullTimeout:10m0s HotStartTimeout:5s DetachedHeadRoom:6m0s MaxResponseSize:0 MaxHdrResponseSize:0 MaxLogSize:1048576 MaxTotalCPU:0 MaxTotalMemory:0 MaxFsSize:0 MaxPIDs:50 MaxOpenFiles:0xc4201b5bf8 MaxLockedMemory:0xc4201b5c10 MaxPendingSignals:0xc4201b5c18 MaxMessageQueue:0xc4201b5c20 PreForkPoolSize:0 PreForkImage:busybox PreForkCmd:tail -f /dev/null PreForkUseOnce:0 PreForkNetworks: EnableNBResourceTracker:false MaxTmpFsInodes:0 DisableReadOnlyRootFs:false DisableDebugUserLogs:false IOFSEnableTmpfs:false EnableFDKDebugInfo:false IOFSAgentPath: IOFSMountRoot: IOFSOpts: ImageCleanMaxSize:0 ImageCleanExemptTags: ImageEnableVolume:false}" time="2022-12-09T12:03:59Z" level=info msg="no docker auths from config files found (this is fine)" error="open /root/.dockercfg: no such file or directory" time="2022-12-09T12:03:59Z" level=fatal msg="couldn't connect to docker daemon" error="Get http://unix.sock/_ping: dial unix /var/run/docker.sock: connect: no such file or directory"
请问是否存在无需特权模式即可部署FN Server的方法?
可行方案:切换Kubernetes执行器模式
错误核心是FN Server默认依赖Docker daemon调度函数容器,但OpenShift使用CRI-O作为容器运行时,且非特权容器无法访问Docker套接字。通过切换到Kubernetes执行器,可绕过Docker依赖,实现非特权部署。
1. 配置FN Server使用Kubernetes执行器
设置环境变量指定执行器类型,让FN直接调用Kubernetes API管理函数Pod:
FN_EXECUTOR_TYPE=k8s
可补充Kubernetes相关配置:
FN_K8S_NAMESPACE=your-fn-namespace FN_K8S_SERVICE_ACCOUNT=fn-server-sa
2. 赋予FN Server服务账号必要权限
FN需要创建、管理Pod/Deployment等资源,需配置RBAC规则:
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: fn-server-cluster-role rules: - apiGroups: [""] resources: ["pods", "services", "secrets", "configmaps"] verbs: ["create", "get", "list", "watch", "delete", "update", "patch"] - apiGroups: ["apps"] resources: ["deployments", "replicasets"] verbs: ["create", "get", "list", "watch", "delete", "update", "patch"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: fn-server-cluster-binding subjects: - kind: ServiceAccount name: fn-server-sa namespace: your-fn-namespace roleRef: kind: ClusterRole name: fn-server-cluster-role apiGroup: rbac.authorization.k8s.io
3. 调整容器安全上下文
保持非特权root模式,配置符合OpenShift要求的安全上下文:
securityContext: runAsUser: 0 allowPrivilegeEscalation: false privileged: false capabilities: drop: ["ALL"]
4. 处理镜像挂载错误
初始错误中的挂载失败来自镜像preentry.sh脚本尝试挂载/sys/kernel/security(用于AppArmor检测),OpenShift中无需此操作:
- 自定义FN镜像,注释或删除
preentry.sh中挂载相关代码; - 若镜像支持,通过环境变量禁用AppArmor检测。
5. 替换SQLite为持久化数据库
SQLite为单节点临时存储,容器重启后数据丢失,建议改用MySQL或PostgreSQL:
FN_DB_TYPE=mysql FN_DB_URL=mysql://db-user:db-password@mysql-service:3306/fn_database
总结
无需特权模式即可成功部署FN Server,核心是切换到Kubernetes执行器,通过RBAC赋予必要权限,调整容器配置并替换持久化存储。
内容的提问来源于stack exchange,提问作者Javier Gómez - Cornejo Gil
相关产品推荐
相关产品推荐

