zoukankan      html  css  js  c++  java
  • 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基础-鉴权框架与用户权限分配,整理详细

  • 相关阅读:
    双机信任关系
    VCS双机原理
    VCS常用指令
    TCL数组
    TCL数据类型
    TCL列表
    TCL基本语法
    CentOS防火墙中端口的开启和关闭
    会话保持技术及原理技术
    ESN
  • 原文地址:https://www.cnblogs.com/zjz20/p/14392333.html
Copyright © 2011-2022 走看看