k8s 新建用户远程连接集群和context切换

一、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 authclient 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 将 Group system:masters 与 ClusterRole cluster-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>

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基础-鉴权框架与用户权限分配,整理详细

原文地址:https://www.cnblogs.com/zjz20/p/14392333.html