我正在运行一个代码,它在一个docker容器中打开一个原始套接字,kubernetes作为编排器。
下面是我的示例代码:#include <stdio.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <errno.h>
#include <netinet/tcp.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <unistd.h>
int main (void)
{
//Create a raw socket
int s = socket (AF_INET, SOCK_RAW, IPPROTO_SCTP);
if(s == -1)
{
perror("Failed to create socket");
exit(1);
}
}
在我的容器/pod中以非root用户运行代码时,我得到了这个错误。
./rawSocTest
Failed to create socket: Operation not permitted
这是很明显的,因为它需要root级别的特权才能打开原始套接字。我通过设置能力cap_net_raw来纠正这个问题。
getcap rawSocTest
rawSocTest = cap_net_raw+eip
现在,当我再次运行它。我得到一个不同的错误。
./rawSocTest
bash: ./rawSocTest: Permission denied
根据我的理解,设置能力应该已经解决了我的问题。我遗漏了什么吗?或者这是已知的容器限制吗?
提前感谢。
我解决了。我需要在kubernetes部署的容器安全上下文部分设置功能。我添加了NET_RAW功能以允许原始套接字创建。我的印象是,只要在构建过程中添加cap_net_raw功能就足够了。但我的理解原来是错误的。
我做了一些研究并清理了部署解决方案。我在pod安全策略的允许功能部分添加了NET_RAW。然后创建角色和角色绑定。通过角色绑定将其链接到我的pod将要部署的名称空间中的服务帐户。然后在pod部署中使用这个serviceAccount。我不确定这是不是一个好的解决方案。
我使用用户kubernetes-admin运行它
将容器定义的示例部署文件添加到前面所述的
apiVersion: apps/v1
kind: Deployment
metadata:
name: httpd-deployment
labels:
app: httpd
spec:
replicas: 1
selector:
matchLabels:
app: httpd
template:
metadata:
labels:
app: httpd
spec:
containers:
- name: my-apache2
image: docker.io/arunsippy12/my-apache2:latest
securityContext:
allowPrivilegeEscalation: true
capabilities:
add: ["NET_RAW"]
ports:
- containerPort: 80
你也可以参考k8s文档:https://kubernetes.io/docs/tasks/configure-pod-container/security-context/