一、kubectl 遠程連接cluster
1、kubectl是k8s的客戶端程序,也是k8s的命令行工具,kubectl提供了大量的子命令可以讓用戶和集群進行交互。kubectl不一定部署在master上,也可以在內網的私人筆記本上,開發或者運維人員只有config文件和kubectl工具就可操作k8s集群。
2、默認情況下是默認連接本地的apiserver,也可以使用https連接集群。
一般情況下,在k8s 的 master節點上kubectl是連接的本地http 8080端口和apiserver進行通訊的,當然也可以通過https端口進行通訊前提是要生成證書。所以說
kubectl -s 127.0.0.1:8080 get node ###二進制老版本
配置kubectl使用apiserver安全的https端口(6443)連接集群
3、 使用cfssl簽發證書
生成pem和key.pem文件
###集群之前已經有了ca證書那就不需要在生成了,只需要利用該ca證書生成用戶證書即可。 cat > ca-config.json <<EOF { "signing": { "default": { "expiry": "87600h" }, "profiles": { "kubernetes": { "usages": [ "signing", "key encipherment", "server auth", "client auth" ], "expiry": "87600h" } } } } EOF
signing
:表示該證書可用於簽名其它證書;生成的 ca.pem 證書中 CA=TRUE
;
server auth
:表示可以用該 CA 對 server 提供的證書進行驗證;
client auth
:表示可以用該 CA 對 client 提供的證書進行驗證;
profile kubernetes
包含了server auth
和client auth
,所以可以簽發三種不同類型證書;
expiry 證書有效期,默認50年
cat > zjz-csr.json <<EOF { "CN": "zjz", "hosts": [], "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "CN", "ST": "BeiJing", "L": "BeiJing", "O": "system:masters", "OU": "System" } ] } EOF
注:
- CN就是要創建的用戶名
- profile= 對應的是ca-config.json中的profiles字段
- 證書請求中
O
指定該證書的 Group 為system:masters
,而RBAC
預定義的ClusterRoleBinding
將 Groupsystem:masters
與 ClusterRolecluster-admin
綁定,這就賦予了用戶所有集群權限
$ kubectl describe clusterrolebinding cluster-admin Name: cluster-admin Labels: kubernetes.io/bootstrapping=rbac-defaults Annotations: rbac.authorization.kubernetes.io/autoupdate=true Role: Kind: ClusterRole Name: cluster-admin Subjects: Kind Name Namespace ---- ---- --------- Group system:masters
生成zjz用戶的證書
cfssl gencert -ca=/etc/kubernetes/pki/ca.crt -ca-key=/etc/kubernetes/pki/ca.key -config=ca-config.json -profile=kubernetes zjz-csr.json | cfssljson -bare zjz
查看證書
# ls admin* zjz.csr zjz-csr.json zjz-key.pem zjz.pem
5、配置config
拷貝證書以及相關kubectl到目標機器
scp /opt/kubernetes/bin/kubectl 10.1.210.32:/usr/bin #拷貝kubectl二進制可執行文件 scp zjz* ca.pem 10.1.210.32:/opt/kubernetes/kubectl/ssl # 拷貝證書
配置config和kubectl
#進入證書目錄 cd /opt/kubernetes/kubectl/ssl #配置訪問的集群 kubectl config set-cluster k8s-cluster1 --server=https://10.25.72.62:6443 --certificate-authority=ca.pem --embed-certs=true Cluster "k8s-cluster1" set. #配置訪問特定的集群、特定的context、特定的namespace kubectl config set-context kube-system-ctx --cluster=k8s-cluster1 --user=kubectl --namespace=kube-system Context "kube-system-ctx" modified. #設置用戶項中cluster-admin用戶證書認證字段 kubectl config set-credentials cluster-admin --certificate-authority=ca.pem --client-key=admin-key.pem --client-certificate=admin.pem #設置默認上下文 kubectl config set-context default --cluster=kubernetes --user=cluster-admin #切換上下文context kubectl config use-context kube-system-ctx Switched to context "kube-system-ctx".
查看config文件
cat /root/.kube/config apiVersion: v1 clusters: - cluster: certificate-authority: /opt/kubernetes/kubectl/ssl/ca.pem server: https://10.1.210.33:6443 name: kubernetes contexts: - context: cluster: kubernetes user: cluster-admin name: default current-context: default kind: Config preferences: {} users: - name: cluster-admin user: client-certificate: /opt/kubernetes/kubectl/ssl/admin.pem client-key: /opt/kubernetes/kubectl/ssl/admin-key.pem
將kubeconfig和kubelet可執行文件拷貝到遠程主機或者筆記本上即可
cp zjz.kubeconfig ~/.kube/config
二、context的理解
context:背景,環境,上下文
對上下文(context)的理解:集群包含context,一個k8s集群中可以有多個context,比如ops、dev、lead。在不同的上下文中,資源是相互隔離的,互不干擾。
k8s集群可以通過namespace和context的設置來對不同的工作組進行區分,同一集群,不同的namespace下,不同context,資源隔離,互不干擾。而同一集群,同一namespace,不同context,資源做不到隔離。
另外,如果用一台機器管理多個k8s集群,集群切換操作也可以用context實現。
用途:配置對多集群的訪問時,context字段定義用戶訪問憑證
每個上下文包含三部分(集群、用戶和名字空間),
例如config配置如下:
apiVersion: v1 clusters: - cluster: certificate-authority: fake-ca-file server: https://1.2.3.4 name: development - cluster: insecure-skip-tls-verify: true server: https://5.6.7.8 name: scratch contexts: - context: cluster: development namespace: frontend user: developer name: dev-frontend - context: cluster: development namespace: storage user: developer name: dev-storage - context: cluster: scratch namespace: default user: experimenter name: exp-scratch current-context: "" kind: Config preferences: {} users: - name: developer user: client-certificate: fake-cert-file client-key: fake-key-file - name: experimenter user: password: some-password username: exp
dev-frontend
上下文表明:使用 developer
用戶的憑證來訪問 development
集群的 frontend
名字空間。
查看當前的context(是一個合並后的結果)
$ kubectl config view apiVersion: v1 clusters: - cluster: certificate-authority-data: DATA+OMITTED server: https://xx.xx.xx.xx:6443 name: Kubernetes contexts: - context: cluster: Kubernetes namespace: ops user: ops name: Kubernetes current-context: Kubernetes kind: Config preferences: {} users: - name: ops user: client-certificate-data: REDACTED client-key-data: REDACTED
切換context
kubectl config use-context k8s-cluster-name
驗證是否已經切換到了新的context
kubectl config current-context Kubernetes
刪除context,不影響其下的資源
kubectl config delete-context context1 deleted context context1 from /Users/zhangjingzhi/.kube/config
新增一個context
kubectl config set-context zjz --namespace=zjz-ops --cluster=Kubernetes --user=ops Context "zjz" created.
查看所有的contexts
$ kubectl config get-contexts CURRENT NAME CLUSTER AUTHINFO NAMESPACE * Kubernetes Kubernetes ops ops context3 Kubernetes ops kube-system zjz Kubernetes ops zjz-ops
設置工作上下文,前提是該命名空間已經存在
kubectl config set-context xxx --namespace=xxxx --cluster=xxxx --user=xxxx
在kubeconfig配置文件中設置一個context。 如果指定了一個已存在的名字,將合並新字段並覆蓋舊字段。
kubectl config set-context NAME --cluster=cluster_nickname --user=user_nickname --namespace=namespace
示例
# 設置gce環境項中的user字段,不影響其他字段。 $ kubectl config set-context gce --user=cluster-admin
選項
--cluster="": 設置kuebconfig配置文件中環境選項中的集群。 --namespace="": 設置kuebconfig配置文件中環境選項中的命名空間。 --user="": 設置kuebconfig配置文件中環境選項中的用戶。
繼承自父命令的選項
--alsologtostderr[=false]: 同時輸出日志到標准錯誤控制台和文件。 --api-version="": 和服務端交互使用的API版本。 --certificate-authority="": 用以進行認證授權的.cert文件路徑。 --client-certificate="": TLS使用的客戶端證書路徑。 --client-key="": TLS使用的客戶端密鑰路徑。 --cluster="": 指定使用的kubeconfig配置文件中的集群名。 --context="": 指定使用的kubeconfig配置文件中的環境名。 --insecure-skip-tls-verify[=false]: 如果為true,將不會檢查服務器憑證的有效性,這會導致你的HTTPS鏈接變得不安全。 --kubeconfig="": 命令行請求使用的配置文件路徑。 --log-backtrace-at=:0: 當日志長度超過定義的行數時,忽略堆棧信息。 --log-dir="": 如果不為空,將日志文件寫入此目錄。 --log-flush-frequency=5s: 刷新日志的最大時間間隔。 --logtostderr[=true]: 輸出日志到標准錯誤控制台,不輸出到文件。 --match-server-version[=false]: 要求服務端和客戶端版本匹配。 --namespace="": 如果不為空,命令將使用此namespace。 --password="": API Server進行簡單認證使用的密碼。 -s, --server="": Kubernetes API Server的地址和端口號。 --stderrthreshold=2: 高於此級別的日志將被輸出到錯誤控制台。 --token="": 認證到API Server使用的令牌。 --user="": 指定使用的kubeconfig配置文件中的用戶名。 --username="": API Server進行簡單認證使用的用戶名。 --v=0: 指定輸出日志的級別。 --vmodule=: 指定輸出日志的模塊,格式如下:pattern=N,使用逗號分隔。
測試同一集群中,不同namespace下,不同的context,二者之間的關系
#當前的context如下 kubectl config current-context Kubernetes #在Kubernetes中創建rc資源 kubectl apply -f redis.yaml replicationcontroller/redis-slave created $ kubectl get rc NAME DESIRED CURRENT READY AGE redis-slave 2 2 0 11s #切換到zjz-ops這個context下 $ kubectl config use-context zjz-ops Switched to context "zjz-ops". 查看資源,正常輸出是 No resources found in zjz-ops namespace. $ kubectl get rc The connection to the server localhost:8080 was refused - did you specify the right host or port
測試同一個集群,同一個namespace下,不同的context,二者關系
#查看現有的context,zjz1和Kubernetes屬於同一集群同一namespace下: kubectl config get-contexts CURRENT NAME CLUSTER AUTHINFO NAMESPACE * Kubernetes Kubernetes ops ops context3 Kubernetes ops kube-system zjz Kubernetes ops zjz-ops zjz1 Kubernetes ops ops #切換到zjz1 kubectl config use-context zjz1 Switched to context "zjz1". #創建資源、查看 $ kubectl create deployment web --image=nginx -n ops deployment.apps/web created $ kubectl get deployment -n ops NAME READY UP-TO-DATE AVAILABLE AGE postgresql 1/1 1 1 41d web 1/1 1 1 21s #切換到Kubernetes kubectl config use-context Kubernetes Switched to context "Kubernetes". $ kubectl config current-context Kubernetes #可以查看zjz1創建的資源,也可以刪除 $ kubectl get deployment -n ops NAME READY UP-TO-DATE AVAILABLE AGE postgresql 1/1 1 1 41d web 1/1 1 1 4m13s kubectl delete deployment web -n ops deployment.apps "web" deleted
三、創建用戶的shell腳本(cfssl工具生成證書)
#!/usr/bin/env bash # 注意修改KUBE_APISERVER為你的API Server的地址 KUBE_APISERVER=$1 USER=$2 USER_SA=system:serviceaccount:default:${USER} Authorization=$3 USAGE="USAGE: create-user.sh <api_server> <username> <clusterrole authorization>\n Example: https://192.168.1.2:6443 brand" CSR=`pwd`/user-csr.json SSL_PATH="/opt/kubernetes/ssl" USER_SSL_PATH="/opt/kubernetes/create-user" SSL_FILES=(ca-key.pem ca.pem ca-config.json) CERT_FILES=(${USER}.csr $USER-key.pem ${USER}.pem) if [[ $KUBE_APISERVER == "" ]]; then echo -e $USAGE exit 1 fi if [[ $USER == "" ]];then echo -e $USAGE exit 1 fi if [[ $Authorization == "" ]];then echo -e $USAGE exit 1 fi # 創建用戶的csr文件 function createCSR(){ cat>$CSR<<EOF { "CN": "USER", "hosts": [], "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "CN", "ST": "BeiJing", "L": "BeiJing", "O": "k8s", "OU": "System" } ] } EOF # 替換csr文件中的用戶名 sed -i "s/USER/$USER_SA/g" $CSR } function ifExist(){ if [ ! -f "$SSL_PATH/$1" ]; then echo "$SSL_PATH/$1 not found." exit 1 fi } function ifClusterrole(){ kubectl get clusterrole ${Authorization} &> /dev/null if (( $? !=0 ));then echo "${Authorization} clusterrole there is no" exit 1 fi } # 判斷clusterrole授權是否存在 ifClusterrole # 判斷證書文件是否存在 for f in ${SSL_FILES[@]}; do echo "Check if ssl file $f exist..." ifExist $f echo "OK" done echo "Create CSR file..." createCSR echo "$CSR created" echo "Create user's certificates and keys..." cd $USER_SSL_PATH cfssl gencert -ca=${SSL_PATH}/ca.pem -ca-key=${SSL_PATH}/ca-key.pem -config=${SSL_PATH}/ca-config.json -profile=kubernetes $CSR| cfssljson -bare $USER_SA # 創建 sa kubectl create sa ${USER} -n default # 設置集群參數 kubectl config set-cluster kubernetes \ --certificate-authority=${SSL_PATH}/ca.pem \ --embed-certs=true \ --server=${KUBE_APISERVER} \ --kubeconfig=${USER}.kubeconfig # 設置客戶端認證參數 kubectl config set-credentials ${USER_SA} \ --client-certificate=${USER_SSL_PATH}/${USER_SA}.pem \ --client-key=${USER_SSL_PATH}/${USER_SA}-key.pem \ --embed-certs=true \ --kubeconfig=${USER}.kubeconfig # 設置上下文參數 kubectl config set-context kubernetes \ --cluster=kubernetes \ --user=${USER_SA} \ --namespace=development \ --kubeconfig=${USER}.kubeconfig # 設置默認上下文 kubectl config use-context kubernetes --kubeconfig=${USER}.kubeconfig # 創建 namespace # kubectl create ns $USER # 綁定角色 # kubectl create rolebinding ${USER}-admin-binding --clusterrole=admin --user=$USER --namespace=$USER --serviceaccount=$USER:default kubectl create clusterrolebinding ${USER}-binding --clusterrole=${Authorization} --user=${USER_SA} # kubectl config get-contexts echo "Congratulations!" echo "Your kubeconfig file is ${USER}.kubeconfig"
context和kubeconfig的詳細信息可參考官網:
https://kubernetes.io/zh/docs/concepts/configuration/organize-cluster-access-kubeconfig/#%E4%B8%8A%E4%B8%8B%E6%96%87-context https://kubernetes.io/zh/docs/tasks/access-application-cluster/configure-access-multiple-clusters/#set-the-kubeconfig-environment-variable
https://blog.csdn.net/zhangxiangui40542/article/details/81672578/ kubectl config配置示例
https://blog.csdn.net/ywq935/article/details/84840935 K8S基礎-鑒權框架與用戶權限分配,整理詳細