Kubernetes Service Account

Service Account 概念的引用是以這樣為基礎的使用場景:執行在Pod裡的處理程序需要呼叫Kubernetes API 以及非Kubernetes API的其他服務. 我們使用Service Account 來為Pod 提供認證.

Service Account 和 User Account 可能會帶來某種程度上的混淆, 它們的區別如下:

User Account 通常是為人類設計的,而Service Account 則是為執行在Pod中的應用設計的
User Account是全域的,即可跨Namespace使用:而Service Account 是限定Namespace的, 即僅在所屬的Namespace下使用
建立一個新的User Account 通常需要較高的特權並且需要經過比較複雜的,而Service Account則不然

Kubernetes API Server 目前支援Authentication和 Authorization機制進行安全存取控制

Authentication:
  1. Basic Authentication
              vim  basic_auth.csv
                  admin_passwd,admin,1
                  test_passwd,test,2

          然後設定Kubernetes API Server 的啟動參數
           --basic-auth-file=/path/to/basic_auth.csv

  1. Token Authentication 
              vim token_auth.csv
                  kefjeeojjojepfeof3jojo2oj,admin,1
                  kmckemkekcekmekcmk,test,2

          其中 Token 是任意字串,可以用以下指令產生
           $ echo $(cat /dev/urandom | base64 | tr -d "=+/" | dd bs=32 count=12>/dev/null
          然後設定Kubernetes API Server 的啟動參數
            —token-auth-file=/path/to/token_auth.csv

  1. Client Certificate Authentication     
                 --client-ca-file=/path/to/ca.crt

  1. OpenID Authentication     
               --oidc-issuer-url=<url>
               --oidc-client-id=<id_token>

      5.  Keystone Authentication
                --experimental-keystone-url=<AuthURL>



Service Account 在API Server啟動參數
--service-account-key-file=" "

Service Account 在Controller Manager啟動參數
--service-account-private-key-file=" "
--root-ca-file=" "

使用預設 Service Account
Kubernetes Controller Manager 會為每個Namespace 預設建立一個Service Account 我們稱為預設Service Account

$ kubectl get serviceaccount

預設Service Account 包含一個Secret:

$ kubectl describe serviceaccount default

查詢該Secret:

$ kubectl describe secret default-token-lm2tq
查詢顯示這是一個Kubernetes.io/service-account-token 類型的secret, 稱為 Service Account Secret , 包含兩個資料token 和 ca.crt 這也是由kubernetes controller manager 產生的. 其中token是由 --service-account-private-key-file指定的金鑰簽發產生的,而ca.crt是由--root-ca-file指定的CA憑證.

這樣一來, 新增的Pod如果沒有指定Service Account, 就會使用預設Service Account, 掛載Service Account 到容器目錄中 /var/run/secrets/kubernetes.io/serviceaccount
$ kubectl exec my-pod -- ls /var/run/secrets/kubernetes.io/serviceaccount/
$ kubectl exec my-pod -- cat  /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
$ kubectl exec my-pod -- cat  /var/run/secrets/kubernetes.io/serviceaccount/token

Pod中的應用透過token和ca.crt 存取kubernetes API Server, 同時kubernetes 提供非常方便的方式讓Pod取得kubernetes API Server 的位址.

Kubernetes 在初始化的時候會建立一個Kubernetes Service , 叫作kubernetes, 它代表的就是kubernetes API Server

$ kubectl describe service kubernetes

kubernetes service的虛擬IP是10.254.0.1, 這是kubernetes API Server設定的Service 網段的第一個IP (--service-cluster-ip-range=10.254.0.0/16) 然後將轉發HTTPS的443通訊埠到192.168.3.146:6443, 即Kubernetes API Server的地址和HTTPS安全通訊埠, 並且Kubernetes Service 是最早建立的,新增的Pod中可以透過環境變數取得來存取Kubernetes API Server(也可以透過DNS方式),Pod中的處理程序就可以存取Kubernetes API Server, 我們現在簡單實現一個指令搞 curl-k8s-api.sh 來呼叫 Kubernetes API;

#!/bin/sh

Endpoint=$1
ServiceAccountToken=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)
ServiceAccountRootCA=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
KubernetesserverURL="http://$KUBERNETES_SERVICE_HOST:$KUBERNETES_SERVICE_POST"

curl -XGET -H "Authorization: Bearer $ServiceAccountToken" \
--caret $ServiceAccountRootCA \
${KubernetesserverURL}${Endpoint}

我們需要將指令稿curl-k8s.api.sh 放入Pod 容器中, 然後存取/api 版本資訊
$ kubectl exec -it my-pod /bin/bash
    vim curl-k8s.api.sh

$ kubectl exec my-pod -- cat curl-k8s.api.sh
$ kubectl exec my-pod -- curl-k8s.api.sh /api
  {
     "version":{
       "v1"
    }
 }


建立自訂Service Account
使用者可以建立自訂的Service Account
vim serviceaccount.yaml
 
apiVersion: v1
kind: ServiceAccount
metadata:
     name: my-serviceaccount


$ kubectl create -f serviceaccount.yaml
$ kubectl describe serviceaccount my-serviceaccount

透過定義檔案建立Service Account Secret:
vim serviceaccountSecret.yaml

apiVersion: v1
kind: secret
metadata:
     name: my-serviceaccount-secret
     annotations:
         kubernetes.io/service-account.name: my-serviceaccount
type: kubernetes.io/service-account-token

$ kubectl create -f serviceaccountSecret.yaml

$ kubectl path serviceaccount my-serviceaccount -p '{"secrets": [{"name": "my-serviceaccount-secret"}]}’

然後刪除自動建立的Service Account Secret
$ kubectl delete secret my-serviceaccount-token-ivsml

在Pod 的定義中可以透過.spec.serviceAccountName 指定Service Account 

apiVersion: v1
kind: Pod
metadata:
     name: busy box
     namespace: default
spec:
   containers:
   -name: busybox
    image:busybox
    command:
      -"sleep"
      -"3600"
   restartPolicy: Always
   serviceAccountName: my-serviceaccount


留言

這個網誌中的熱門文章

Json概述以及python對json的相關操作

遠程控制管理工具ipmitool

從Kubernetes到Cloud Native——雲原生應用之路