如何用Frabic client以serviceAccount方式訪問k8s叢集
阿新 • • 發佈:2020-09-18
一. 以ServiceAccount的方式訪問k8s叢集
k8s支援客戶端通過serviceAccount與RBAC結合的方式訪問kube-apiserver,這種方式便於靈活控制賬戶許可權
1)建立serviceAccount與對應的secret
建立serviceAccount
使用指令碼:kubernetes_add_service_account.sh在qa-k8s-2-master叢集建立serviceAccount: test-sa1
#!/bin/bash set -e set -o pipefail # Add user to k8s using service account, no RBAC (must create RBAC after this script) if [[ -z "$1" ]] || [[ -z "$2" ]]; then echo "usage: $0 <service_account_name> <namespace>" exit 1 fi SERVICE_ACCOUNT_NAME=$1 NAMESPACE="$2" KUBECFG_FILE_NAME="/tmp/kube/k8s-${SERVICE_ACCOUNT_NAME}-${NAMESPACE}-conf" TARGET_FOLDER="/tmp/kube" create_target_folder() { echo -n "Creating target directory to hold files in ${TARGET_FOLDER}..." mkdir -p "${TARGET_FOLDER}" printf "done" } create_service_account() { echo -e "\\nCreating a service account in ${NAMESPACE} namespace: ${SERVICE_ACCOUNT_NAME}" kubectl create sa "${SERVICE_ACCOUNT_NAME}" --namespace "${NAMESPACE}" } get_secret_name_from_service_account() { echo -e "\\nGetting secret of service account ${SERVICE_ACCOUNT_NAME} on ${NAMESPACE}" SECRET_NAME=$(kubectl get sa "${SERVICE_ACCOUNT_NAME}" --namespace="${NAMESPACE}" -o json | jq -r .secrets[].name) echo "Secret name: ${SECRET_NAME}" } extract_ca_crt_from_secret() { echo -e -n "\\nExtracting ca.crt from secret..." kubectl get secret --namespace "${NAMESPACE}" "${SECRET_NAME}" -o json | jq \ -r '.data["ca.crt"]' | base64 -d > "${TARGET_FOLDER}/ca.crt" printf "done" } get_user_token_from_secret() { echo -e -n "\\nGetting user token from secret..." USER_TOKEN=$(kubectl get secret --namespace "${NAMESPACE}" "${SECRET_NAME}" -o json | jq -r '.data["token"]' | base64 -d) printf "done" } set_kube_config_values() { context=$(kubectl config current-context) echo -e "\\nSetting current context to: $context" CLUSTER_NAME=$(kubectl config get-contexts "$context" | awk '{print $3}' | tail -n 1) echo "Cluster name: ${CLUSTER_NAME}" ENDPOINT=$(kubectl config view \ -o jsonpath="{.clusters[?(@.name == \"${CLUSTER_NAME}\")].cluster.server}") echo "Endpoint: ${ENDPOINT}" # Set up the config echo -e "\\nPreparing k8s-${SERVICE_ACCOUNT_NAME}-${NAMESPACE}-conf" echo -n "Setting a cluster entry in kubeconfig..." kubectl config set-cluster "${CLUSTER_NAME}" \ --kubeconfig="${KUBECFG_FILE_NAME}" \ --server="${ENDPOINT}" \ --certificate-authority="${TARGET_FOLDER}/ca.crt" \ --embed-certs=true echo -n "Setting token credentials entry in kubeconfig..." kubectl config set-credentials \ "${SERVICE_ACCOUNT_NAME}-${NAMESPACE}-${CLUSTER_NAME}" \ --kubeconfig="${KUBECFG_FILE_NAME}" \ --token="${USER_TOKEN}" echo -n "Setting a context entry in kubeconfig..." kubectl config set-context \ "${SERVICE_ACCOUNT_NAME}-${NAMESPACE}-${CLUSTER_NAME}" \ --kubeconfig="${KUBECFG_FILE_NAME}" \ --cluster="${CLUSTER_NAME}" \ --user="${SERVICE_ACCOUNT_NAME}-${NAMESPACE}-${CLUSTER_NAME}" \ --namespace="${NAMESPACE}" echo -n "Setting the current-context in the kubeconfig file..." kubectl config use-context "${SERVICE_ACCOUNT_NAME}-${NAMESPACE}-${CLUSTER_NAME}" \ --kubeconfig="${KUBECFG_FILE_NAME}" } create_target_folder create_service_account get_secret_name_from_service_account extract_ca_crt_from_secret get_user_token_from_secret set_kube_config_values echo -e "\\nAll done! Test with:" echo "KUBECONFIG=${KUBECFG_FILE_NAME} kubectl get pods" echo "you should not have any permissions by default - you have just created the authentication part" echo "You will need to create RBAC permissions" KUBECONFIG=${KUBECFG_FILE_NAME} kubectl get pods
得到serviceAccount與對應secre
[root@qa-k8s-2-master ~]# bash /tmp/kubernetes_add_service_account.sh test-sa1 default ... [root@qa-k8s-2-master ~]# kubectl get serviceaccount test-sa1 -o yaml apiVersion: v1 kind: ServiceAccount metadata: creationTimestamp: 2019-06-10T09:20:55Z name: test-sa1 namespace: default resourceVersion: "19622333" selfLink: /api/v1/namespaces/default/serviceaccounts/test-sa1 uid: 0ced12b2-8b61-11e9-8839-fa163e432469 secrets: - name: test-sa1-token-zp6vt ... [root@qa-k8s-2-master ~]# kubectl get secret test-sa1-token-zp6vt -o yaml apiVersion: v1 data: ca.crt: LS0tLS1C......EUtLS0tLQo= namespace: ZGVmYXVsdA== token: ZXlKaGJ........R1JMdw== kind: Secret metadata: annotations: kubernetes.io/service-account.name: test-sa1 kubernetes.io/service-account.uid: 0ced12b2-8b61-11e9-8839-fa163e432469 creationTimestamp: 2019-06-10T09:20:55Z name: test-sa1-token-zp6vt namespace: default resourceVersion: "19622332" selfLink: /api/v1/namespaces/default/secrets/test-sa1-token-zp6vt uid: 0cefd45a-8b61-11e9-8839-fa163e432469 type: kubernetes.io/service-account-token
同時也會生成對應的kubeconfig檔案:
[root@qa-k8s-2-master ~]# cat /tmp/kube/k8s-test-sa1-default-conf apiVersion: v1 clusters: - cluster: certificate-authority-data: LS0tLS1CRUdJ.........LS0tLQo= server: https://qa-k8s-2-master:6443 name: qa-k8s-2-master contexts: - context: cluster: qa-k8s-2-master namespace: default user: test-sa1-default-qa-k8s-2-master name: test-sa1-default-qa-k8s-2-master current-context: test-sa1-default-qa-k8s-2-master kind: Config preferences: {} users: - name: test-sa1-default-qa-k8s-2-master user: as-user-extra: {} token: eyJhbGciOiJ....hGRLw
2)繫結clusterRole
clusterRole cluster-admin擁有k8s叢集中所有資源的讀寫許可權,將test-sa1加入clusterRoleBinding cluster-admin的subjects中
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
annotations:
rbac.authorization.kubernetes.io/autoupdate: "true"
creationTimestamp: 2019-01-30T10:32:45Z
labels:
kubernetes.io/bootstrapping: rbac-defaults
name: cluster-admin
resourceVersion: "19622865"
selfLink: /apis/rbac.authorization.k8s.io/v1/clusterrolebindings/cluster-admin
uid: 619bdffa-247a-11e9-9ccb-fa163e432469
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: Group
name: system:masters
- kind: ServiceAccount
name: test-sa1
namespace: default
3) kubectl使用test-sa1訪問k8s叢集
指定KUBECONFIG為k8s-test-sa1-default-conf,則可以在任意機器上訪問qa-k8s-2-master叢集
[root@qa-k8s-1-master ~]# scp qa-k8s-2-master:/tmp/kube/k8s-test-sa1-default-conf /tmp/
...
[root@qa-k8s-1-master ~]# KUBECONFIG=/tmp/k8s-test-sa1-default-conf kubectl get node
NAME STATUS ROLES AGE VERSION
10.189.108.144 Ready <none> 105d 1.9.8.4
10.189.108.145 Ready <none> 130d 1.9.8.4
10.189.108.146 Ready <none> 130d 1.9.8.4
4)Java客戶端訪問示例
String k8sEntryPoint = "https://10.199.175.66:6443";
ConfigBuilder configBuilder = new ConfigBuilder().withMasterUrl(k8sEntryPoint)
.withRequestTimeout(REQUEST_TIMEOUT).withConnectionTimeout(CONNECTION_TIMEOUT);
Config config = configBuilder.build();
config.setCaCertData("LS0tLS1CRUdJTiB....BVEUtLS0tLQo=");
config.setOauthToken("eyJhb......V0TGd_hGRLw");
OkHttpClient httpClient = HttpClientUtils.createHttpClient(config);
httpClient.dispatcher().setMaxRequests(MAX_REQUEST);
httpClient.dispatcher().setMaxRequestsPerHost(MAX_REQUEST);
KubernetesClient client = new DefaultKubernetesClient(httpClient, config);
NodeList nodeList = client.nodes().list();
for (Node node : nodeList.getItems()) {
System.out.println(node.getMetadata().getName())
}