设置RBAC规则来实现多用户权限隔离访问
1 AAA和BBB产品线容器的环境准备
1.1 两个产品线的权限隔离说明
假如我们公司有productline-aaa和productline-bbb两个产品线,每个产品线都有各自相应的负责人。要求每个产品线的负责人只能管理自己产品线的容器,实现效果如下:
为了方便演示,我这里建productline-aaa和productline-bbb两个不同的命名空间,并分别在每个命名空间中创建几个容器和service。
1.2 创建两个产品线的容器环境
创建productline-aaa命名空间,并在productline-aaa命名空间中创建2个productline-aaa-testweb容器和productline-aaa-testweb服务,productline-aaa同理。
编写yaml代码 aaa产线
apiVersion: v1
kind: Namespace
metadata:
name: productline-aaa
---
apiVersion: v1
kind: ReplicationController
metadata:
name: productline-aaa-testweb
namespace: productline-aaa
labels:
name: productline-aaa-testweb
spec:
replicas: 2
selector:
name: productline-aaa-testweb
template:
metadata:
labels:
name: productline-aaa-testweb
spec:
containers:
- name: productline-aaa-testweb
image: 10.57.26.15:4000/guestbook-php-frontend
env:
- name: GET_HOSTS_FROM
value: env
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: productline-aaa-testweb
namespace: productline-aaa
labels:
name: productline-aaa-testweb
spec:
ports:
- port: 80
selector:
name: productline-aaa-testweb
bbb产线
apiVersion: v1
kind: Namespace
metadata:
name: productline-bbb
---
apiVersion: v1
kind: ReplicationController
metadata:
name: productline-bbb-testweb
namespace: productline-bbb
labels:
name: productline-bbb-testweb
spec:
replicas: 2
selector:
name: productline-bbb-testweb
template:
metadata:
labels:
name: productline-bbb-testweb
spec:
containers:
- name: productline-bbb-testweb
image: 10.57.26.15:4000/guestbook-php-frontend
env:
- name: GET_HOSTS_FROM
value: env
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: productline-bbb-testweb
namespace: productline-bbb
labels:
name: productline-bbb-testweb
spec:
ports:
- port: 80
selector:
name: productline-bbb-testweb
使用kubectl apply -f productline-aaa-testweb.yaml 和 kubectl apply -f productline-bbb-testweb.yaml 创建ns,rc和service
使用kubectl get ns
查看刚创建的ns
输入kubectl get pod,svc -n productline-aaa && kubectl get pod,svc -n productline-bbb
查看两个ns(部门)对应的pods和service,如下图所示:
tips:在测试的时候副本数不能大于node数,若大于多出来的pod将创建失败,通过更改yaml配置文件的副本数,然后再执行kubectl apply -f <yaml>
即可更新状态,kubectl edit rc productline-aaa-testweb -nproductline-aaa
类似这样修改rc也可以达到一样的效果。
2 准备环境
2.1 下载cfssl工具
wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64
chmod +x cfssl_linux-amd64
mv cfssl_linux-amd64 /usr/local/bin/cfssl
wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64
chmod +x cfssljson_linux-amd64
mv cfssljson_linux-amd64 /usr/local/bin/cfssljson
wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64
chmod +x cfssl-certinfo_linux-amd64
mv cfssl-certinfo_linux-amd64 /usr/local/bin/cfssl-certinfo
2.2 生成默认的配置文件和证书签名请求文件
生成配置文件后可以基于这些配置文件进行修改
cfssl print-defaults config > ca-config.json
cfssl print-defaults csr > ca-csr.json
3 创建devuser用户访问productline-aaa产品线
3.1 创建用于kubectl使用的devuser
3.1.1 cfssl下载
3.1.2 生成证书
cfssl gencert --ca /etc/kubernetes/pki/ca.crt --ca-key /etc/kubernetes/pki/ca.key --config k8s-gencert.json --profile kubernetes devuser-csr.json | cfssljson -bare devuser
就会生成下面的文件:
3.1.3 校验证书
cfssl-certinfo -cert devuser.pem
3.1.4 生成config文件
在部署k8s平台的时候已经生成了kubeconfig,我们可以直接利用这个文件,省的自己再去配置集群参数
cp /etc/kubernetes/admin.conf devuser.kubeconfig
3.1.5 设置客户端认证参数
kubectl config set-credentials devuser \
--client-certificate=devuser.pem \
--client-key=devuser-key.pem \
--embed-certs=true \
--kubeconfig=devuser.kubeconfig
3.1.6 设置上下文参数:
kubectl config set-context kubernetes \
--cluster=kubernetes \
--user=devuser \
--namespace=productline-aaa \
--kubeconfig=devuser.kubeconfig
3.1.7 设置默认上下文:
kubectl config use-context kubernetes --kubeconfig=devuser.kubeconfig
以上执行一个步骤就可以看一下 devuser.kubeconfig的变化。里面最主要的三个东西
cluster: 集群信息,包含集群地址与公钥 user: 用户信息,客户端证书与私钥,真正的信息是从证书里读取出来的,人能看到的只是给人看的。 context: 维护一个三元组,namespace cluster 与 user
3.2 创建AAA产品线管理员角色
创建一个叫pod-reader的角色 输入以下yaml,并保存为productline-aaa-pod-reader.yaml
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: productline-aaa
name: aaa-pod-admin
rules:
- apiGroups: ["*"]
resources: ["*"]
verbs: ["*"]
输入kubectl apply -f productline-aaa-pod-reader.yaml
创建role。
通过输入kubectl get role --all-namespaces
查看创建的role
3.3、将devuser绑定到AAA产品线管理员角色
创建一个角色绑定,把pod-reader角色绑定到 devuser上
输入以下yaml,并保存为productline-aaa-devuser-role-bind.yaml
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: admin-aaa
namespace: productline-aaa
subjects:
- kind: User
name: devuser
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: aaa-pod-admin
apiGroup: rbac.authorization.k8s.io
输入kubectl apply -f productline-aaa-devuser-role-bind.yaml
创建role-binding。
通过输入kubectl get role --all-namespaces
查看创建的rolebinding
3.4、测试devuser.kubeconfig的访问效果
使用新的config文件替换原有的config来访问试试:
先将原有的kubeconfig备份一下。
我们用kubectl get pod
查看到的只是productline-aaa产品线下的所有容器:
来登录productline-aaa产品线下的其中一个容器试试:
使用kubectl get pod -n default
等各种命令试图进入其他命名空间,显然失效。因为devuser没有别的namespace的权限了。
4 创建opsuser用户访问productline-bbb产品线
4.1 创建用于kubectl使用的opsuser
流程和第二步一致,提供一个脚本简化执行
证书和上下文相关
# 生成证书请求文件
cat > opsuser-csr.json << EOF
{
"CN": "opsuser",
"hosts": [],
"key": {
"algo": "ecdsa",
"size": 256
},
"names": [
{
"C": "CN",
"L": "Hangzhou",
"ST": "Hangzhou",
"O": "k8s",
"OU": "System"
}
]
}
EOF
# 生成证书
cfssl gencert --ca /etc/kubernetes/pki/ca.crt --ca-key /etc/kubernetes/pki/ca.key --config k8s-gencert.json --profile kubernetes opsuser-csr.json | cfssljson -bare opsuser
# 生成config文件
cp /etc/kubernetes/admin.conf opsuser.kubeconfig
# 客户端认证参数
kubectl config set-credentials opsuser \
--client-certificate=opsuser.pem \
--client-key=opsuser-key.pem \
--embed-certs=true \
--kubeconfig=opsuser.kubeconfig
# 上下文参数
kubectl config set-context kubernetes \
--cluster=kubernetes \
--user=opsuser \
--namespace=productline-bbb \
--kubeconfig=opsuser.kubeconfig
# 设置默认上下文
kubectl config use-context kubernetes --kubeconfig=opsuser.kubeconfig
4.2 创建BBB产品线管理员角色
cat > productline-bbb-pod-reader.yaml<<EOF
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: productline-bbb
name: bbb-pod-admin
rules:
- apiGroups: ["*"]
resources: ["*"]
verbs: ["*"]
EOF
kubectl create -f productline-bbb-pod-reader.yaml
cat>productline-bbb-devuser-role-bind.yaml<<EOF
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: admin-bbb
namespace: productline-bbb
subjects:
- kind: User
name: opsuser
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: bbb-pod-admin
apiGroup: rbac.authorization.k8s.io
EOF
kubectl create -f productline-bbb-devuser-role-bind.yaml
4.3 测试opsuser.kubeconfig的访问效果
5 配置跳板机实现多用户隔离远程访问
对于跳板机的要求其实很简单,只要一个普通的Linux服务器就行了。
5.1 给跳板机安装kubectl工具
翻墙下载相关软件包
wget https://dl.k8s.io/v1.8.5/kubernetes-node-linux-amd64.tar.gz
解压后将kubectl复制到/usr/bin目录并附权
cp kubernetes/node/bin/kubectl /usr/bin/
chmod 755 /usr/bin/kubectl
5.2 给跳板机创建devuser和opsuser
给跳板机分别创建devuser和opsuser,分别给productline-aaa和productline-bbb两个产品线的负责人。
useradd devuser
useradd opsuser
ls /home
切换到devuser和opsuser下面,分别创建“.kube”目录,并验证
mkdir -p /home/devuser/.kube
mkdir -p /home/opsuser/.kube
ls -a /home/devuser/
ls -a /home/opsuser/
5.3 分发config到跳板机
把我们在第三章和第四章生成好的devuser.kubeconfig和opsuser.kubeconfig文件分别对应分发到跳板机的/home/devuser/.kube目录和/home/opsuser/.kube目录
scp devuser.kubeconfig opsuser.kubeconfig admin@10.57.30.217:/tmp
然后在跳板机上分别拷贝
mv /tmp/devuser.kubeconfig /home/devuser/.kube/config
mv /tmp/opsuser.kubeconfig /home/opsuser/.kube/config
并把config的own赋给相对应的用户
chown -R devuser:devuser /home/devuser/.kube/config
chown -R opsuser:opsuser /home/opsuser/.kube/config
ls -l /home/devuser/.kube/config
ls -l /home/opsuser/.kube/config
5.4 使用不同用户登录访问各自产品线的容器
测试两个不同用户访问的pod
测试两个不同用户跨namespace访问
测试两个不同用户进入pod
可以看到如下图所示,不能进入其他namespace的pod。
最后达到了如下图所示的效果