美文网首页
etcd如何以non-root用户运行

etcd如何以non-root用户运行

作者: Lis_ | 来源:发表于2019-03-26 16:18 被阅读0次

背景

etcd作为kubernetes的基础组件之一,在kubernetes集群中是以static pod的方式部署的,社区中的经典部署方式kubeadm,etcd都是用root 用户启动的,使用root用户启动赋予了容器过高的权限,存在很大的安全问题,所以本文介绍如何使用普通用户以static pod的方式部署etcd.

问题

  • etcd的存储数据目录--data-dir=/var/lib/etcd的ownership
    etcd运行在container中,/var/lib/etcd目录作为存储etcd数据的目录是通过hostPath方式将主机目录挂载到对应的容器目录中。当etcd通过normal user的方式启动时,要保证volume的ownership在容器内部和外部是相同的,内外ownership不同,将会导致etcd 没有权限读写该目录同步数据。
  • 不同的user namespace是相互隔离的
    etcd部署在容器中,容器内部和主机分别在两个相互隔离的namespace中。

Kubernete 中pod的安全策略

kubernetes会对集群中的容器进行限制,限制不可信的容器,以免对系统或者其他容器造成影响。
按照作用的范围不同,分为以下三种规则对容器进行限制:

  • Pod Security Policy(PSP):应用到集群中所有的pod和volume
  • Security Context(Pod-level):应用到集群中的Pod
  • Security Context(Container-level):仅应用到单个container中

Pod Security Policy

Pod Security Policy 简称PSP,是集群级别的安全策略,是kubernetes中的一种resource。当集群中开启了此功能,会自动的为集群的pod和volume设置Security Context。此外在etcd作为非root用户运行时,应该检查集群中的PSP是否有限制。

如何开启Pod Security Policy

在API server中的配置项--enable-admission-plugins中增加PodSecurityPolicy 参数

--enable-admission-plugins=NodeRestriction,PodSecurityPolicy

创建一个简单的PSP

apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
  name: example
spec:
  privileged: false  # Don't allow privileged pods!
  # The rest fills in some required fields.
  seLinux:
    rule: RunAsAny
  supplementalGroups:
    rule: RunAsAny
  runAsUser:
    rule: RunAsAny
  fsGroup:
    rule: RunAsAny
  volumes:
  - '*'

重启API server服务,此时如果集群中没有创建出任何可用的policy,API server在阻止任何pod的创建。

Security Context(Pod-level)

Pod-level Security Context应用到Pod内所有容器,还会影响volume(包括fsGroup和selinuxOptions)。

apiVersion: v1
kind: Pod
metadata:
  name: hello-world
spec:
  containers:
  # specification of the pod's containers
  # ...
  securityContext:
    fsGroup: 1234
    supplementalGroups: [5678]
    seLinuxOptions:
      level: "s0:c123,c456"

Security Context(Container-level)

Container-level Security Context仅应用到指定的容器上,并且不会影响Volume。比如设置容器运行在特权模式:

apiVersion: v1
kind: Pod
metadata:
  name: hello-world
spec:
  containers:
    - name: hello-world-container
      # The container definition
      # ...
      securityContext:
        privileged: true

etcd是static pod,pod中只有一个container,所以我们选择在pod level配置Security Context。

如何通过normal user部署

  1. 在etcd image中添加normal user,使用normal user运行etcd.
    目前社区中的etcd还是默认运行在root用户下,所以我们需要自己build etcd的binary,修改etcd的Dockerfile,在Dockerfile中创建一个特定的normal user,user在创建的时候我们需要指定一个ID,只有指定ID,我们才能在host上也创建出一个ID相同的user。
FROM alpine:latest

ADD etcd /usr/local/bin/
ADD etcdctl /usr/local/bin/
RUN mkdir -p /var/etcd/
RUN mkdir -p /var/lib/etcd/

# RUN groupadd -r etcd
# RUN useradd -r -g etcd etcd -u 2375
RUN adduser  etcd -u 2375 -D
RUN chown -R etcd:etcd /var/etcd/ /var/lib/etcd/


# Alpine Linux doesn't use pam, which means that there is no /etc/nsswitch.conf,
# but Golang relies on /etc/nsswitch.conf to check the order of DNS resolving
# (see https://github.com/golang/go/commit/9dee7771f561cf6aee081c0af6658cc81fac3918)
# To fix this we just create /etc/nsswitch.conf and add the following line:
RUN echo 'hosts: files mdns4_minimal [NOTFOUND=return] dns mdns4' >> /etc/nsswitch.conf
USER etcd
EXPOSE 2379 2380

# Define default command.
CMD ["/usr/local/bin/etcd", "--data-dir=/var/lib/etcd" ]

etcd的base image是alpine,添加user的命令与普通的Linux不太相同,见Dockerfile中注释

  1. 在host上创建与1中相同ID的user,并且创建好/var/lib/etcd目录,将此目录的ownership修改为自己创建的normal user
useradd -U etcd -u 2375
chown -R etcd:etcd /var/lib/etcd/
  1. 在etcd的pod.json文件中添加Security Context配置
"securityContext": {
       "privileged": true,
       "runAsUser": 2375
 }

接下来就可以通过etcd user部署etcd啦。

相关文章

网友评论

      本文标题:etcd如何以non-root用户运行

      本文链接:https://www.haomeiwen.com/subject/bovgvqtx.html