• k8s学习笔记之九: Service Account


    第一章、前言

    每一个用户对API资源进行操作都需要通经过以下三个步骤:
    第一步:对客户端访问进行认证操作,确认是否具有访问k8s权限
        token(共享秘钥)
        SSL(双向SSL认证)
      ....
      通过任何一个认证即表示认证通过,进入下一步
    第二步:授权检查,确认是否对资源具有相关的权限 ABAC(基于属性的访问控制) RBAC(基于角色的访问控制) NODE(基于节点的访问控制) WEB HOOK(自定义HTTP回调方法的访问控制) 第三步:准入控制(对操作资源相关联的其他资源是否有权限操作)

    Kubernetes只对以下的API请求属性进行检查:

    user - username,uid
    group - user group 
    "extra"- 额外信息
    API - API资源的对象 
    Request path - 请求资源的路径(k8s使用resultful风格接口的API) 
     http://Node_IPaddr:6443/apis/apps/v1/namespaces/namespaces_name/resource_name/
    HTTP 请求动作 - HTTP verbs get,post,put,和delete用于非资源请求
    HTTP 请求动作映射到 API资源操作-  get,list,create,update,patch,watch,proxy,redirect,delete,和deletecollection用于请求resource
    Resource -被访问(仅用于resource 请求)的resource 的ID或名字- *对于使用resource 的请求get,update,patch,和delete,必须提供resource 名称。
    Subresource - 正在访问的subresource (仅用于请求resource )
    Namespace - 正在访问对象的命名空间(仅针对命名空间的请求资源)
    API group - 正在访问的API组(仅用于请求资源)。空字符串指定核心API组。

    什么是serviceaccount

    Service account是为了方便Pod里面的进程调用Kubernetes API或其他外部服务而设计的。它与User account不同
      1.User account是为人设计的,而service account则是为Pod中的进程调用Kubernetes API而设计;
      2.User account是跨namespace的,而service account则是仅局限它所在的namespace;
      3.每个namespace都会自动创建一个default service account
      4.Token controller检测service account的创建,并为它们创建secret
      5.开启ServiceAccount Admission Controller后
           1.每个Pod在创建后都会自动设置spec.serviceAccount为default(除非指定了其他ServiceAccout)
        2.验证Pod引用的service account已经存在,否则拒绝创建
        3.如果Pod没有指定ImagePullSecrets,则把service account的ImagePullSecrets加到Pod中
        4.每个container启动后都会挂载该service account的token和ca.crt到/var/run/secrets/kubernetes.io/serviceaccount/  

     验证:

    [root@k8s-master01 ~]# kubectl create namespace qiangungun  #创建一个名称空间
    namespace "qiangungun" created
    [root@k8s-master01 ~]# kubectl get sa -n qiangungun  #名称空间创建完成后会自动创建一个sa
    NAME      SECRETS   AGE
    default   1         11s
    [root@k8s-master01 ~]# kubectl get secret -n qiangungun  #同时也会自动创建一个secret
    NAME                  TYPE                                  DATA      AGE
    default-token-5jtz2   kubernetes.io/service-account-token   3         19s

    在创建的名称空间中新建一个pod

    [root@k8s-master01 pod-example]# cat pod_demo.yaml 
    kind: Pod
    apiVersion: v1
    metadata:
      name: task-pv-pod
      namespace: qiangungun
    spec:
      containers:
      - name: nginx
        image: ikubernetes/myapp:v1
        ports:
         - containerPort: 80
           name: www

    查看pod信息

    [root@k8s-master01 pod-example]# kubectl apply -f  pod_demo.yaml 
    pod "task-pv-pod" created
    [root@k8s-master01 pod-example]# kubectl get pod -n qiangungun 
    NAME          READY     STATUS    RESTARTS   AGE
    task-pv-pod   1/1       Running   0          13s
    [root@k8s-master01 pod-example]# kubectl get  pod task-pv-pod -o yaml   -n qiangungun 
    ......
    volumeMounts:
        - mountPath: /var/run/secrets/kubernetes.io/serviceaccount
          name: default-token-5jtz2
    ......
    volumes:  #挂载sa的secret
      - name: default-token-5jtz2
        secret:
          defaultMode: 420
          secretName: default-token-5jtz2 
    ......

    #名称空间新建的pod如果不指定sa,会自动挂载当前名称空间中默认的sa(default)

    第二章、创建serviceaccount(以下简称sa)

    [root@k8s-master01 ~]#  kubectl create  serviceaccount admin   #创建一个sa 名称为admin
    serviceaccount "admin" created
    [root@k8s-master01 ~]# kubectl get sa 
    NAME      SECRETS   AGE
    admin     1         6s
    default   1         28d
    [root@k8s-master01 ~]# kubectl describe sa admin   #查看名称为admin的sa的信息,系统会自动创建一个token信息
    Name:                admin
    Namespace:           default
    Labels:              <none>
    Annotations:         <none>
    Image pull secrets:  <none>
    Mountable secrets:   admin-token-rxtrc
    Tokens:              admin-token-rxtrc
    Events:              <none>
    [root@k8s-master01 ~]# kubectl get secret  #会自动创建一个secret(admin-token-rxtrc),用于当前sa连接至当前API server时使用的认证信息
    NAME                    TYPE                                  DATA      AGE
    admin-token-rxtrc       kubernetes.io/service-account-token   3         1m
    default-token-tcwjz     kubernetes.io/service-account-token   3         28d
    myapp-ingress-secret    kubernetes.io/tls                     2         6h
    mysql-passwd            Opaque                                1         17d
    tomcat-ingress-secret   kubernetes.io/tls                     2         7h

    创建一个pod应用刚刚创建的sa

    [root@k8s-master01 service_account]# cat deploy-demon.yaml 
    apiVersion: v1
    kind: Pod
    metadata:
      name: sa-demo
      labels:
        app: myapp
        release: canary
    spec:
      containers:
      - name: myapp
        image: ikubernetes/myapp:v2
        ports:
        - name: httpd
          containerPort: 80
      serviceAccountName: admin  #此处指令为指定sa的名称
    [root@k8s-master01 service_account]# kubectl apply -f deploy-demon.yaml 
    pod "sa-demo" created
    [root@k8s-master01 service_account]# kubectl describe pod sa-demo 
    ......
    Mounts:
          /var/run/secrets/kubernetes.io/serviceaccount from admin-token-rxtrc (ro) #pod会自动挂载自己sa的证书
    ......

      Volumes:
        admin-token-rxtrc:
          Type: Secret (a volume populated by a Secret)
          SecretName: admin-token-rxtrc

    ......

     

    集群交互的时候少不了的是身份认证,使用 kubeconfig(即证书) 和 token 两种认证方式是最简单也最通用的认证方式,下面我使用kubeconfing来进行认证

    使用kubeconfig文件来组织关于集群,用户,名称空间和身份验证机制的信息。使用 kubectl命令行工具对kubeconfig文件来查找选择群集并与群集的API服务器进行通信所需的信息。

    默认情况下 kubectl使用的配置文件名称是在$HOME/.kube目录下 config文件,可以通过设置环境变量KUBECONFIG或者--kubeconfig指定其他的配置文件

    查看系统的kubeconfig

    [root@k8s-master01 ~]# kubectl config view 
    apiVersion: v1
    clusters:   #集群列表 
    - cluster:
        certificate-authority-data: REDACTED  #认证集群的方式
        server: https://172.16.150.212:6443    #访问服务的APIserver的路径
      name: kubernetes #集群的名称
    contexts: #上下文列表
    - context:
        cluster: kubernetes  #访问kubernetes这个集群
        user: kubernetes-admin  #使用 kubernetes-admin账号
      name: kubernetes-admin@kubernetes #给定一个名称
    current-context: kubernetes-admin@kubernetes #当前上下文,表示使用哪个账号访问哪个集群
    kind: Config
    preferences: {}
    users:  #用户列表
    - name: kubernetes-admin #用户名称
      user:
        client-certificate-data: REDACTED #客户端证书,用于与apiserver进行认证
        client-key-data: REDACTED #客户端私钥

     

    [root@k8s-master01 ~]# kubectl get svc
    NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)             AGE
    kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP             29d
    my-nginx     NodePort    10.104.13.148    <none>        80:32008/TCP        18h
    myapp        ClusterIP   10.102.229.150   <none>        80/TCP              19h
    tomcat       ClusterIP   10.106.222.72    <none>        8080/TCP,8009/TCP   19h
    [root@k8s-master01 ~]# kubectl describe svc kubernetes 
    Name:              kubernetes
    Namespace:         default
    Labels:            component=apiserver
                       provider=kubernetes
    Annotations:       <none>
    Selector:          <none>
    Type:              ClusterIP
    IP:                10.96.0.1
    Port:              https  443/TCP
    TargetPort:        6443/TCP
    Endpoints:         172.16.150.212:6443  #可以看到此处svc后端的Endpoint是当前节点的IP地址,通过svc的IP地址进行映射,以确保cluster中的pod可以通过该sa与集群内api进行通讯,仅仅是身份认证
    Session Affinity:  ClientIP
    Events:            <none>

    查看kubeconfig命令行配置帮助

    [root@k8s-master01 ~]# kubectl config --help
    Modify kubeconfig files using subcommands like "kubectl config set current-context my-context" 
    
    The loading order follows these rules: 
    
      1. If the --kubeconfig flag is set, then only that file is loaded.  The flag may only be set once
    and no merging takes place.  
      2. If $KUBECONFIG environment variable is set, then it is used a list of paths (normal path
    delimitting rules for your system).  These paths are merged.  When a value is modified, it is
    modified in the file that defines the stanza.  When a value is created, it is created in the first
    file that exists.  If no files in the chain exist, then it creates the last file in the list.  
      3. Otherwise, ${HOME}/.kube/config is used and no merging takes place.
    
    Available Commands:
      current-context 显示 current_context
      delete-cluster  删除 kubeconfig 文件中指定的集群
      delete-context  删除 kubeconfig 文件中指定的 context
      get-clusters    显示 kubeconfig 文件中定义的集群
      get-contexts    描述一个或多个 contexts
      rename-context  Renames a context from the kubeconfig file.
      set             设置 kubeconfig 文件中的一个单个值
      set-cluster     设置 kubeconfig 文件中的一个集群条目
      set-context     设置 kubeconfig 文件中的一个 context 条目
      set-credentials 设置 kubeconfig 文件中的一个用户条目
      unset           取消设置 kubeconfig 文件中的一个单个值
      use-context     设置 kubeconfig 文件中的当前上下文
      view            显示合并的 kubeconfig 配置或一个指定的 kubeconfig 文件
    
    Usage:
      kubectl config SUBCOMMAND [options]
    
    Use "kubectl <command> --help" for more information about a given command.
    Use "kubectl options" for a list of global command-line options (applies to all commands).

    第三章、创建一个cluster用户及context

    使用当前系统的ca证书认证一个私有证书

    [root@k8s-master01 ~]# cd /etc/kubernetes/pki/
    [root@k8s-master01 pki]# (umask 077;openssl genrsa -out qiangungun.key 2048)
    Generating RSA private key, 2048 bit long modulus
    .........................+++
    ..........................................................+++
    e is 65537 (0x10001)
    [root@k8s-master01 pki]# openssl req -new -key qiangungun.key -out qiangungun.csr -subj "/CN=qiangungun"  #qiangungun是后面我们创建的用户名称,需要保持一致
    [root@k8s-master01 pki]# openssl x509 -req -in qiangungun.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out qiangungun.crt -days 3650
    Signature ok
    subject=/CN=qiangungun
    Getting CA Private Key

    查看证书内容

    [root@k8s-master01 pki]# openssl x509 -in qiangungun.crt -text -noout
    Certificate:
        Data:
            Version: 1 (0x0)
            Serial Number:
                b6:06:cb:30:86:e3:fe:84
        Signature Algorithm: sha256WithRSAEncryption
            Issuer: CN=kubernetes  #由谁签署的
            Validity  #证书的有效时间
                Not Before: Nov 27 15:09:41 2018 GMT
                Not After : Nov 24 15:09:41 2028 GMT
            Subject: CN=qiangungun  #证书使用的用户
            Subject Public Key Info:
                Public Key Algorithm: rsaEncryption
                    Public-Key: (2048
                     ......

    创建一个当前集群用户

    [root@k8s-master01 pki]#  kubectl config set-credentials qiangungun --client-certificate=./qiangungun.crt --client-key=./qiangungun.key --embed-certs=true  #--embed-certs表示是否隐藏证书路径及名称,默认不隐藏
    User "qiangungun" set.
    [root@k8s-master01 pki]# kubectl config view 
    apiVersion: v1
    clusters:
    - cluster:
        certificate-authority-data: REDACTED
        server: https://172.16.150.212:6443
      name: kubernetes
    contexts:
    - context:
        cluster: kubernetes
        user: kubernetes-admin
      name: kubernetes-admin@kubernetes
    current-context: kubernetes-admin@kubernetes
    kind: Config
    preferences: {}
    users:
    - name: kubernetes-admin
      user:
        client-certificate-data: REDACTED
        client-key-data: REDACTED
    - name: qiangungun #我们新建的用户 user: client-certificate-data: REDACTED client-key-data: REDACTED

    为qiangungun用户创建一个context

    [root@k8s-master01 pki]# kubectl config set-context  qiangungun@kubernetes --cluster=kubernetes --user=qiangungun 
    Context "qiangungun@kubernetes" created.
    [root@k8s-master01 pki]# kubectl config view 
    apiVersion: v1
    clusters:
    - cluster:
        certificate-authority-data: REDACTED
        server: https://172.16.150.212:6443
      name: kubernetes
    contexts:
    - context:
        cluster: kubernetes
        user: kubernetes-admin
      name: kubernetes-admin@kubernetes
    - context:  #新创建的context
        cluster: kubernetes
        user: qiangungun
      name: qiangungun@kubernetes
    current-context: kubernetes-admin@kubernetes
    kind: Config
    preferences: {}
    users:
    - name: kubernetes-admin
      user:
        client-certificate-data: REDACTED
        client-key-data: REDACTED- name: qiangungun
      user:
        client-certificate-data: REDACTED
        client-key-data: REDACTED

    切换serviceaccount

    [root@k8s-master01 pki]# kubectl config use-context qiangungun@kubernetes 
    Switched to context "qiangungun@kubernetes".
    [root@k8s-master01 pki]# kubectl get pod
    Error from server (Forbidden): pods is forbidden: User "qiangungun" cannot list pods in the namespace "default"

    自定义一个cluster

    [root@k8s-master01 pki]# kubectl config set-cluster  mycluster --kubeconfig=/tmp/test.conf --server="https://172.16.150.212:6443" --certificate-authority=/etc/kubernetes/pki/ca.crt --embed-certs=true
    Cluster "mycluster" set.
    [root@k8s-master01 pki]# kubectl config view --kubeconfig=/tmp/test.conf 
    apiVersion: v1
    clusters:
    - cluster:
        certificate-authority-data: REDACTED
        server: https://172.16.150.212:6443
      name: mycluster
    contexts: []
    current-context: ""
    kind: Config
    preferences: {}
    users: []

     

  • 相关阅读:
    nginx 禁止访问某个目录
    ssh 无法链接的解决思路
    linux 时间修改(同步到时间服务器)
    BitNami Gitlab的重启问题
    gitlab push时报错
    VirtualBox 安装centos后无法上网
    VirtualBox 创建64位系统的问题
    NOIP2010 题解
    NOIP2011 题解
    NOIP2012 题解
  • 原文地址:https://www.cnblogs.com/panwenbin-logs/p/10029834.html
Copyright © 2020-2023  润新知