标签归档:Kubernetes

Kubernetes中的RBAC

  Kubernetes中,授权有ABAC(基于属性的访问控制)、RBAC(基于角色的访问控制)、Webhook、Node、AlwaysDeny(一直拒绝)和AlwaysAllow(一直允许)这6种模式。需要在kube-apiserver设置–authorization-mode=RBAC参数,启用RABC模式,下面的操作版本为v1.10.1;
  当应用没有指定serviceAccountName,它将使用default服务帐户。

  在RABC API中,通过如下的步骤进行授权:
  1)定义角色:定义角色时会指定此角色对于资源的访问控制的规则;
  2)定义主体:用户、组和服务帐户
  3)绑定角色:将主体与角色进行绑定,对主体进行访问授权。

        enter image description here
                    RBAC API中的对象关系图

  Kubernetes中角色包含代表权限集合的规则,权限只有被授予,没有被拒绝的设置。
  在Kubernetes中有两类角色:普通角色和集群角色。
可以通过Role定义在一个命名空间中的角色,或是使用ClusterRole定义集群范围的角色。

普通角色只能被授予访问单一命令空间中的资源。
集群角色(ClusterRole)能够被授予资源权限有:集群范围资源(Node、NameSpace)、非资源端点(/healthz)、集群所有命名空间资源(跨名称空间);

角色绑定和集群角色绑定
  角色绑定用于将角色与一个主体进行绑定,从而实现将对主体授权的目的,主体分为用户、组和服务帐户。
角色绑定分为:普通角色绑定和集群角色绑定

角色绑定中不同主体定义有:
名称为 demo 用户:

 subjects:
 - kind:User
   name:"demo"
   apiGroup:rbac.authorization.k8s.io

名称为 demo 组:

 subjects:
 - kind:Group
   name:"demo-group"
   apiGroup:rbac.authorization.k8s.io

kube-system命名空间中,名称为default的服务帐户

 subjects:
 - kind:ServiceAccount
   name:default
   namespace:kube-system

so命名空间中,所有的服务帐户:

 subjects:
 - kind:Group
   name:system:serviceaccounts:so
   apiGroup:rbac.authorization.k8s.io

所有的服务帐户:

 subjects:
 - kind:Group
   name:system:serviceaccounts
   apiGroup:rbac.authorization.k8s.io

所有用户:

 subjects:
 - kind:Group
   name:system:authenticated    #授权用户
   apiGroup:rbac.authorization.k8s.io
 - kind:Group
   name:system:unauthenticated  #未授权用户
   apiGroup:rbac.authorization.k8s.io

授予cluster-admin集群角色给admin用户:

 kubectl create clusterrolebinding admin-cluster-admin-binding --clusterrole=cluster-admin --user=admin  

授予cluster-admin集群角色给so名称空间中的app服务帐户:

 kubectl create clusterrolebinding app-admin-binding --clusterrole=cluster-admin --serviceaccount=so:app  

  RBAC实例demo下面创建solinx-service-account.yml文件包含以下内容:

 # 服务账号
 apiVersion: v1
 kind: ServiceAccount   
 metadata:
   name: solinx
 # 角色
 ---
 kind: Role
 apiVersion: rbac.authorization.k8s.io/v1beta1
 metadata:
   name: solinx
 rules:                #规则
 - apiGroups: [""]       # 所有核心api
   resources: ["pods"]   # 资源
   verbs: ["create","delete","get","list","patch","update","watch"]  #操作
 - apiGroups: [""]
   resources: ["namespaces"]
   verbs: ["create","delete","get","list","patch","update","watch"]
 # 角色绑定
 ---
 apiVersion: rbac.authorization.k8s.io/v1beta1
 kind: RoleBinding
 metadata:
   name: solinx
 roleRef:     # 上面定义的角色
   apiGroup: rbac.authorization.k8s.io
   kind: Role
   name: solinx
 subjects:   # 上面定义的服务账户
 - kind: ServiceAccount
   name: solinx
   namespace: default

  上面定义了一个服务账户solinx、普通角色solinx,并将该服务账户与角色进行绑定,该角色定义了对了pod的增删查改等操作,所以该服务账户也具备了该权限;
  这里使用solinx服务账户对资源进行操作:

 kubectl get po --as system:serviceaccount:default:solinx

enter image description here

由于只授予了pod的操作权限,当访问service资源时被拒绝:

 kubectl get svc --as system:serviceaccount:default:solinx

 Error from server (Forbidden): services is forbidden: User "system:serviceaccount:default:solinx" cannot list services in the namespace "default"

enter image description here

该角色为普通角色Role,当访问集群资源NameSpace时同样被拒绝:

 kubectl get ns --as system:serviceaccount:default:solinx

 Error from server (Forbidden): namespaces is forbidden: User "system:serviceaccount:default:solinx" cannot list namespaces at the cluster scope

enter image description here

  此时把角色改为集群角色:ClusterRole,并重新绑定服务账户:
enter image description here

  此时该服务账户已经具备集群角色权限,访问集群资源:NameSpace

 kubectl get ns --as system:serviceaccount:default:solinx

enter image description here

参考资料: https://kubernetes.io/docs/reference/access-authn-authz/rbac/

使用Skaffold一键将项目发布到Kubernetes

  当前skaffold版本为v0.4,还未发布正式版本,不建议在生产环境中使用;
  skaffold用于开发人员快速部署程序到Kubernetes中;skaffold提供了dev、run两种模式;使用skaffold需先编写skaffold配置文件,该文件为定义skaffold的工作流;
  Skaffold工作流定义了三个主要阶段Build、Push、Deploy

enter image description here

一、Build
  在构建阶段,Skaffold通过Dockerfile使用源码生成Artifacts,Skaffold中目前Docker镜像、bazel这两种Artifacts,这里使用的是Docker镜像所以也可以成称为Docker镜像,该镜像用于应用程序的运行,Build阶段的输出就是Artifacts;
二、Push
  在推送阶段,Skaffold将把构建阶段生成的Docker镜像推送到Docker镜像仓库中,并使用所配置的镜像名称;在运行Skaffold时需确保镜像能够推送到镜像仓库中;
  但如果使用的是Minikube或 Docker for Desktop本地Kubernetes集群时默认是不推送到镜像仓库的,跳过推送阶段,因为本地已经存在了该镜像所以是可以正常运行的;
三、Deploy
  部署阶段,将最新的Docker镜像部署到k8s中,该阶段可以使用不同的部署工具如kubectl或helm,每个工具都有不一样的参数用于定义如何安装与更新应用程序;

概念介绍

Artifacts
  在Build阶段通过运行一系列步骤来创建Artifacts,在Skaffold中Artifacts分为bazel与Docker镜像,可以定义Skaffold生成多个Docker镜像,Skaffold在开发模式运行时,Skaffold只会重新生成源码已经更改的Docker镜像,通过在Skaffold配置中指定Dockerfile来生成Docker镜像,并指定其名称;

标签策略
  标签策略在Build阶段进行配置,用于配置Skaffold在推送Docker镜像时如果对镜像进行打标签,目前Skaffold支持三种标签策略:sha256标签生成器、git标签生成器、自定义标签生成器策略
  在开发过程中,推荐使用基于内容的标签策略sha256,方便在源代码变更时Skaffold会使Kubernetes重新部署新Docker镜像;

运行模式

  Skaffold有dev、run两种运行模式,也就是开发模式与发布模式,在dev模式下Skaffold会监控项目的源码随着代码的变更会实时的重新生产镜像并将变更更新部署到Kubernetes中;还可在CI/CD管道中运行Skaffold;

  dev模式默认使用sha256标签生成器
  run模式默认使用git标签生成器

  所以注意如果使用run模式又没配置git则Skaffold是无法跑下去的,需配置标签策略(TagPolicy),或配置git即可;

使用流程:

  开发环境使用skaffold部署项目到远程k8s中;
  1、下载skaffold
https://github.com/GoogleCloudPlatform/skaffold/releases/download/v0.4.0/skaffold-windows-amd64.exe
  2、下载kubectl、服务端开放Docker远程连接
在服务端Docker配置中加上: -H tcp://0.0.0.0:2375
  在开发端在创建C:\Users\xin.docker\config.json文件,内容如下:

 {
    "auths" : {
    }
 }

  3、开发端kubectl 配置
  创建C:\Users\xin.kube\config.json文件,配置k8s的连接与密钥,文件内容如下:

 apiVersion: v1
 clusters:
 - cluster:
     server: http://182.61.xx.xxx:8001
   name: minikube
 contexts:
 - context:
     cluster: minikube
     user: minikube
   name: minikube
 current-context: minikube
 kind: Config
 preferences: {}
 users:
 - name: minikube
   user:
 as-user-extra: {}

  4、服务端kubectl使用开启代理
  kubectl proxy –address 0.0.0.0 –accept-hosts ‘.*’
  5、环境变量配置
  需要在环境变量中配置Docker的链接信息:

 DOCKER_HOST = tcp://xxx.xxx.xxx.xxx:2375
 DOCKER_TLS_VERIFY = 0

  下载Demo并使用Skaffold将其部署到Kubernetes中;

  git clone https://github.com/GoogleCloudPlatform/skaffold
  cd examples/getting-started

运行:skaffold dev

enter image description here
enter image description here

  可以看到由于使用的是Minikube所以只有Build、Deploy两个阶段跳过了Push阶段,与我们上面的说法是一致的;
修改main.go的内容即可看到Skaffold检测到了变化,并重新把项目更新到Kubernetes中;

enter image description here
enter image description here

  常见异常信息:

 WARN[0005] run: build: build step: running build: read auth configs: docker config: opening docker config: 
 open C:\Users\xin\.docker\config.json: no such file or directory   

不存在.docker\confog.json文件,在用户目录下添加上即可;

 open //./pipe/docker_engine: The system cannot find the file specified. In the default daemon configuration on 
 Windows, the docker client must be run elevated to connect. This error may also indicate that the docker 
 daemon is not running.  

  未配置Docker环境变量,加上DOCKER_HOST、DOCKER_TLS_VERIFY环境变量即可;

本文使用的环境为:minikube、skaffold v0.4、windows

参考资料: https://github.com/GoogleCloudPlatform/skaffold/blob/master/docs/concepts.md