K8S原來如此簡單(八)ServiceAccount+RBAC

chester·chen發表於2022-03-27

ServiceAccount

ServiceAccount是給執行在Pod的程式使用的身份認證,Pod容器的程式需要訪問API Server時用的就是ServiceAccount賬戶。

ServiceAccount僅侷限它所在的namespace,每個namespace建立時都會自動建立一個default service account。

建立Pod時,如果沒有指定Service Account,Pod則會使用default Service Account。

 

通過以下命令可以檢視我們前面建立chesterns這個namespace下的serviceaccount與對應的secret

kubectl describe pod -n chesterns
kubectl describe sa -n chesterns
kubectl describe secrets -n chesterns

通過以下命令檢視serviceaccount掛載進容器內部的檔案

kubectl exec -it chesterdeployment-cb855fb4b-5ksgd -n chesterns -- ls /var/run/secrets/kubernetes.io/serviceaccount/
  • ca.crt:根證書,用於Client端驗證API Server傳送的證書
  • namespace:標識這個service-account-token的作用域空間
  • token:使用API Server私鑰簽名的JWT,用於訪問API Server時,Server端的驗證

自定義ServiceAccount

kubectl create sa chestersa -n chesterns
kubectl describe sa chestersa -n chesterns

通過指定serviceAccountName,讓pod使用自定義的sa

apiVersion: apps/v1
kind: Deployment
metadata:
  name: chesterdeployment
  namespace: chesterns
  labels:
    app: chesterapi
spec:
  replicas: 1
  selector:
    matchLabels:
      app: chesterapi
  template:
    metadata:
      labels:
        app: chesterapi
    spec:
     serviceAccountName: chestersa
     containers:
     - name: oneapi
       image: registry.cn-beijing.aliyuncs.com/chester-k8s/oneapi:latest
       ports:
       - containerPort: 5000
       livenessProbe:
         httpGet:
           path: /test
           port: 5000
     - name: twoapi
       image: registry.cn-beijing.aliyuncs.com/chester-k8s/twoapi:latest
       ports:
       - containerPort: 5001
       livenessProbe:
         httpGet:
           path: /test/calloneapi
           port: 5001

 

我們可以配置serviceaccount中的ImagePullSecret,拉取私有映象。

建立secret

kubectl create secret docker-registry aliregistry --docker-server=registry.cn-beijing.aliyuncs.com --docker-username=陳xx --docker-password=xxxxx -n chesterns
kubectl edit sa chestersa -n chesterns

imagePullSecrets:   #新增此欄位
- name: aliregistry

通過我們自定義的sa拉取私有映象

apiVersion: apps/v1
kind: Deployment
metadata:
  name: chesterdeployment
  namespace: chesterns
  labels:
    app: chesterapi
spec:
  replicas: 1
  selector:
    matchLabels:
      app: chesterapi
  template:
    metadata:
      labels:
        app: chesterapi
    spec:
     serviceAccountName: chestersa
     containers:
     - name: oneapi
       image: registry.cn-beijing.aliyuncs.com/chester-k8s/privateoneapi:latest
       ports:
       - containerPort: 5000
       livenessProbe:
         httpGet:
           path: /test
           port: 5000

通過以下命令驗證私有映象拉取狀態

kubectl delete -f deployment.yaml
kubectl apply -f deployment.yaml
kubectl describe pod -n chesterns

RBAC

在Kubernetes中,所有資源物件都是通過API物件進行操作,他們儲存在etcd裡。

而對etcd的操作我們需要通過訪問 kube-apiserver 來實現,上面的Service Account其實就是APIServer的認證過程,而授權的機制是通過RBAC這個基於角色的訪問控制實現。

Role與ClusterRole

在RBAC中,Role表示一組規則許可權,許可權只會增加(累加許可權)。

  • Role 是定義在一個 namespace 中

  • ClusterRole 是叢集級別的 

 

定義Role

定義一個Role,限定在在名字為 chesterns namespace 中,對Pods有get,watch,list的許可權

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: chesterrole
  namespace: chesterns
rules:
- apiGroups: [""] 
  resources: ["pods"] 
  verbs: ["get","watch","list"]
kubectl create -f role.yaml 
kubectl get role -n chesterns

 

修改初始化叢集時,應用kubeconfig檔案的模式

vi /etc/profile
export KUBECONFIG=/etc/kubernetes/admin.conf  #刪除
source /etc/profile

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

建立使用者

useradd chester
su - chester
#嘗試訪問叢集
kubectl get pod

下載cfssl

cd /usr/bin

wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64
wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64
wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64

## 改名,給執行許可權
mv cfssl_linux-amd64 cfssl
mv cfssljson_linux-amd64 cfssljson
mv cfssl-certinfo_linux-amd64 cfssl-certinfo
chmod +x *
ll -h 

生成證書

mkdir /usr/local/chestercert
cd /usr/local/chestercert

vi chester-csr.json
{
  "CN": "chester",
  "hosts": [], 
  "key": {
    "algo": "rsa",
    "size": 2048
},
  "names": [
    {
       "C": "CN",
       "L": "BeiJing",
       "O": "Ctyun",
       "ST": "BeiJing",            
       "OU": "System"
    }
  ]
}
cd /etc/kubernetes/pki/
cfssl gencert -ca=ca.crt -ca-key=ca.key -profile=kubernetes /usr/local/chestercert/chester-csr.json | cfssljson -bare chesteruser
ls

 

為chester使用者生成叢集配置檔案

kubectl config set-cluster kubernetes --certificate-authority=/etc/kubernetes/pki/ca.crt --embed-certs=true --server=https://192.168.43.111:6443 --kubeconfig=chester.kubeconfig
ls

 

繫結使用者資訊至kubeconfig中

kubectl config set-credentials chesteruser \
 --client-certificate=/etc/kubernetes/pki/chesteruser.pem \
 --client-key=/etc/kubernetes/pki/chesteruser-key.pem \
 --embed-certs=true \
 --kubeconfig=chester.kubeconfig

 

設定上下文引數

kubectl config set-context kubernetes \
 --cluster=kubernetes \
 --user=chesteruser \
 --namespace=chesterns \
 --kubeconfig=chester.kubeconfig

 

把kubeconfig檔案複製到chester使用者的目錄的.kube下

mkdir -p /home/chester/.kube
cp chester.kubeconfig /home/chester/.kube/config
cd /home/chester/.kube/
ls
config

## 修改檔案所有者
cd /home/chester/
chown -R chester:chester .kube/

RoleBinding與ClusterRoleBinding

RoleBinding可以將角色中定義的許可權授予使用者或使用者組。

RoleBinding包含一組許可權列表(Subjects),許可權列表中包含有不同形式的待授予許可權資源型別(users,groups, or Service Account),Rolebinding 同樣包含對被 Bind的Role

  • RoleBinding 適用於某個名稱空間內授權

  • ClusterRoleBinding適用於叢集範圍內的授權。

定義RoleBinding

定義一個名稱為chesterrolebinding,將chesterrole許可權資源賦予名為chester的使用者,僅作用於chesterns namespace。

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: chesterrolebinding
  namespace: chesterns
subjects:
- kind: User
  name: chester
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: chesterrole
  apiGroup: rbac.authorization.k8s.io
kubectl apply -f rolebinding.yaml
kubectl describe rolebinding -n chesterns

 

驗證chester使用者能否正常訪問

su chester
cd /home/chester/.kube
kubectl config use-context kubernetes --kubeconfig=config
kubectl get pod -n chesterns

相關文章