K8S网络诊断之我的ingress咋不显示ip了

本文涉及的产品
实时计算 Flink 版,5000CU*H 3个月
简介: 某客户反馈,新建的ingress不显示ingress关联slb的公网ip了,与客户沟通后确认创建了两套ingress-controller后出现的问题,创建ingress后的显示效果如下:

背景信息:

     某客户反馈,新建的ingress不显示ingress关联slb的公网ip了,与客户沟通后确认创建了两套ingress-controller后出现的问题,创建ingress后的显示效果如下:



需求沟通:

      沟通客户部署两套ingress的需求原因,是因为默认ingress-controller的service关联公网slb,需要在内网再部署一套关联内网slb的ingress-controller,便于内部的其他应用走内网slb调用,

需求实现:

      这个需求无论是多套,或者多个slb都是有现成的文档可以参考进行设置的如:

《如何配置阿里云容器服务Kubernetes Ingress Controller使用私网SLB》

《如何在ACK集群中部署多个Ingress Controller》



问题排查:

我们知道多套ingress-controller区分ingress要关联的ingress-controller是要使用ingressClass关键字的,因此我们先看ingress的yaml里面的字段,而客户的yaml里面并没有写ingress.class相关字段

缺少下面的字段

annotations:

   kubernetes.io/ingress.class: "<YOUR_INGRESS_CLASS>"

添加了ingress.class的annotations后问题依然如故,将视线从配置本身转移到关联显示ip的角度上,将kubectl 的get日志级别调整到最大,未见明显异常

# kubectl get ing web -v 10(v10调整日志级别,后补日志)

I0904 14:05:39.618631   30866 loader.go:375] Config loaded from file:  /root/.kube/config

I0904 14:05:39.623263   30866 round_trippers.go:423] curl -k -v -XGET  -H "User-Agent: kubectl/v1.16.9 (linux/amd64) kubernetes/4f7ea78" -H "Accept: application/json, */*" 'https://192.168.0.128:6443/apis/external.metrics.k8s.io/v1beta1?timeout=32s'

I0904 14:05:39.654111   30866 round_trippers.go:443] GET https://192.168.0.128:6443/apis/external.metrics.k8s.io/v1beta1?timeout=32s 200 OK in 30 milliseconds

I0904 14:05:39.654133   30866 round_trippers.go:449] Response Headers:

I0904 14:05:39.654138   30866 round_trippers.go:452]     Cache-Control: no-cache, private

I0904 14:05:39.654143   30866 round_trippers.go:452]     Content-Type: application/json

I0904 14:05:39.654147   30866 round_trippers.go:452]     Date: Fri, 04 Sep 2020 06:05:39 GMT

I0904 14:05:39.654151   30866 round_trippers.go:452]     Content-Length: 109

I0904 14:05:39.654155   30866 round_trippers.go:452]     Audit-Id: e4e508e5-ac55-4c9b-becf-4e77a5114ef6

I0904 14:05:39.656979   30866 request.go:968] Response Body: {"kind":"APIResourceList","apiVersion":"v1","groupVersion":"external.metrics.k8s.io/v1beta1","resources":[]}

I0904 14:05:39.659221   30866 cached_discovery.go:82] skipped caching discovery info, no resources found

I0904 14:05:39.663461   30866 round_trippers.go:423] curl -k -v -XGET  -H "Accept: application/json, */*" -H "User-Agent: kubectl/v1.16.9 (linux/amd64) kubernetes/4f7ea78" 'https://192.168.0.128:6443/apis/external.metrics.k8s.io/v1beta1?timeout=32s'

I0904 14:05:39.671174   30866 round_trippers.go:449] Response Headers:

I0904 14:05:39.671179   30866 round_trippers.go:452]     Audit-Id: 4b8e7e46-3269-4c6e-9283-e95818954158

I0904 14:05:39.671184   30866 round_trippers.go:452]     Cache-Control: no-cache, private

I0904 14:05:39.671188   30866 round_trippers.go:452]     Content-Type: application/json

I0904 14:05:39.671192   30866 round_trippers.go:452]     Date: Fri, 04 Sep 2020 06:05:39 GMT

I0904 14:05:39.671196   30866 round_trippers.go:452]     Content-Length: 109

I0904 14:05:39.674712   30866 request.go:968] Response Body: {"kind":"APIResourceList","apiVersion":"v1","groupVersion":"external.metrics.k8s.io/v1beta1","resources":[]}

I0904 14:05:39.678065   30866 cached_discovery.go:82] skipped caching discovery info, no resources found

I0904 14:05:39.680165   30866 round_trippers.go:423] curl -k -v -XGET  -H "Accept: application/json, */*" -H "User-Agent: kubectl/v1.16.9 (linux/amd64) kubernetes/4f7ea78" 'https://192.168.0.128:6443/apis/external.metrics.k8s.io/v1beta1?timeout=32s'

I0904 14:05:39.686710   30866 round_trippers.go:443] GET https://192.168.0.128:6443/apis/external.metrics.k8s.io/v1beta1?timeout=32s 200 OK in 5 milliseconds

I0904 14:05:39.686725   30866 round_trippers.go:449] Response Headers:

I0904 14:05:39.686734   30866 round_trippers.go:452]     Audit-Id: 441b3b75-5376-409e-93f6-e1fd5e4f7798

I0904 14:05:39.686739   30866 round_trippers.go:452]     Cache-Control: no-cache, private

I0904 14:05:39.686744   30866 round_trippers.go:452]     Content-Type: application/json

I0904 14:05:39.686757   30866 round_trippers.go:452]     Date: Fri, 04 Sep 2020 06:05:39 GMT

I0904 14:05:39.686761   30866 round_trippers.go:452]     Content-Length: 109

I0904 14:05:39.689455   30866 request.go:968] Response Body: {"kind":"APIResourceList","apiVersion":"v1","groupVersion":"external.metrics.k8s.io/v1beta1","resources":[]}

I0904 14:05:39.691663   30866 cached_discovery.go:82] skipped caching discovery info, no resources found

I0904 14:05:39.693421   30866 round_trippers.go:423] curl -k -v -XGET  -H "Accept: application/json;as=Table;v=v1beta1;g=meta.k8s.io, application/json" -H "User-Agent: kubectl/v1.16.9 (linux/amd64) kubernetes/4f7ea78" 'https://192.168.0.128:6443/apis/extensions/v1beta1/namespaces/default/ingresses/web'

I0904 14:05:39.696346   30866 round_trippers.go:443] GET https://192.168.0.128:6443/apis/extensions/v1beta1/namespaces/default/ingresses/web 200 OK in 2 milliseconds

I0904 14:05:39.696359   30866 round_trippers.go:449] Response Headers:

I0904 14:05:39.696364   30866 round_trippers.go:452]     Audit-Id: 99bff432-cd2a-4692-b030-09e237b88731

I0904 14:05:39.696370   30866 round_trippers.go:452]     Cache-Control: no-cache, private

I0904 14:05:39.696393   30866 round_trippers.go:452]     Content-Type: application/json

I0904 14:05:39.696401   30866 round_trippers.go:452]     Content-Length: 1987

I0904 14:05:39.696406   30866 round_trippers.go:452]     Date: Fri, 04 Sep 2020 06:05:39 GMT

I0904 14:05:39.696458   30866 request.go:968] Response Body: {"kind":"Table","apiVersion":"meta.k8s.io/v1beta1","metadata":{"selfLink":"/apis/extensions/v1beta1/namespaces/default/ingresses/web","resourceVersion":"200490461"},"columnDefinitions":[{"name":"Name","type":"string","format":"name","description":"Name must be unique within a namespace. Is required when creating resources, although some resources may allow a client to request the generation of an appropriate name automatically. Name is primarily intended for creation idempotence and configuration definition. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/identifiers#names","priority":0},{"name":"Hosts","type":"string","format":"","description":"Hosts that incoming requests are matched against before the ingress rule","priority":0},{"name":"Address","type":"string","format":"","description":"Address is a list containing ingress points for the load-balancer","priority":0},{"name":"Ports","type":"string","format":"","description":"Ports of TLS configurations that open","priority":0},{"name":"Age","type":"string","format":"","description":"CreationTimestamp is a timestamp representing the server time when this object was created. It is not guaranteed to be set in happens-before order across separate operations. Clients may not set this value. It is represented in RFC3339 form and is in UTC.\n\nPopulated by the system. Read-only. Null for lists. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata","priority":0}],"rows":[{"cells":["web","m*****.w***b.com","","80","99d"],"object":{"kind":"PartialObjectMetadata","apiVersion":"meta.k8s.io/v1beta1","metadata":{"name":"web","namespace":"default","selfLink":"/apis/extensions/v1beta1/namespaces/default/ingresses/web","uid":"226ccb92-cd23-4af9-a899-06afc459d0f0","resourceVersion":"200490461","generation":8,"creationTimestamp":"2020-05-28T01:36:19Z","annotations":{"nginx.ingress.kubernetes.io/service-weight":""}}}}]}

NAME   HOSTS                                            ADDRESS   PORTS   AGE

web    m***.***8.com             80      99d


查看ingress-controller的日志,看看是否可以找到蛛丝马迹,果然发现了一些errorlog,如下

error updating ingress rule: ingresses.networking.k8s.io "wh03" is forbidden: User "system:serviceaccount:kube-system:nginx-ingress-controller" cannot update resource "ingresses/status" in API group "networking.k8s.io" in the namespace "default"

问题定位:

      上面的报错意思是ingress-controller使用的sa权限不足,导致更新ingresses/status缺少了权限,在k8s的RBAC权限配置里面,某个service account的权限取决于绑定的clusterrole,我们先看下ingress-controller使用的service account绑定的clusterrole是哪个?

# kubectl get clusterrolebindings.rbac.authorization.k8s.io nginx-ingress-controller -o yaml

apiVersion: rbac.authorization.k8s.io/v1

kind: ClusterRoleBinding

metadata:

 annotations:

   kubectl.kubernetes.io/last-applied-configuration: |

     {"apiVersion":"rbac.authorization.k8s.io/v1beta1","kind":"ClusterRoleBinding","metadata":{"annotations":{},"name":"nginx-ingress-controller"},"roleRef":{"apiGroup":"rbac.authorization.k8s.io","kind":"ClusterRole","name":"nginx-ingress-controller"},"subjects":[{"kind":"ServiceAccount","name":"nginx-ingress-controller","namespace":"kube-system"}]}

 creationTimestamp: 2019-05-15T02:21:45Z

 name: nginx-ingress-controller

 resourceVersion: "72216951"

 selfLink: /apis/rbac.authorization.k8s.io/v1/clusterrolebindings/nginx-ingress-controller

 uid: 2f43dbc8-76b8-11e9-864c-62cf21d8490a

roleRef:

 apiGroup: rbac.authorization.k8s.io

 kind: ClusterRole

 name: nginx-ingress-controller

subjects:

- kind: ServiceAccount

 name: nginx-ingress-controller

 namespace: kube-system

   可以看到 ingress-controller使用的service account绑定的clusterrole是nginx-ingress-controller,我们再看下nginx-ingress-controller clusterrole的具体权限是什么?是否缺少了报错中提到的 networking.k8s.io

# kubectl get clusterroles nginx-ingress-controller -o yaml

apiVersion: rbac.authorization.k8s.io/v1

kind: ClusterRole

metadata:

...

rules:

- apiGroups:

 - ""

 resources:

 - configmaps

 - endpoints

 - nodes

 - pods

 - secrets

 - namespaces

 - services

 verbs:

...

报错的是update  ingresses/status 的时候没有networking.k8s.io的授权,因此在apigroup里面添加即可

- apiGroups:

 - extensions  这里缺一条 - networking.k8s.io

 resources:

 - ingresses/status

 verbs:

 - update

 

 

- ...

- apiGroups:

 - ""

 resourceNames:

 - ingress-controller-leader-nginx

 resources:

 - configmaps

 verbs:

 - get

 - update

完整的demo如下:(不同集群版本在rbac的授权上可能有所不同,请根据实际报错去检查)

apiVersion: rbac.authorization.k8s.io/v1

kind: ClusterRole

metadata:

 annotations:

   kubectl.kubernetes.io/last-applied-configuration: |

     {"apiVersion":"rbac.authorization.k8s.io/v1beta1","kind":"ClusterRole","metadata":{"annotations":{},"name":"nginx-ingress-controller"},"rules":[{"apiGroups":[""],"resources":["configmaps","endpoints","nodes","pods","secrets","namespaces","services"],"verbs":["get","list","watch"]},{"apiGroups":["extensions","networking.k8s.io"],"resources":["ingresses"],"verbs":["get","list","watch"]},{"apiGroups":[""],"resources":["events"],"verbs":["create","patch"]},{"apiGroups":["extensions","networking.k8s.io"],"resources":["ingresses/status"],"verbs":["update"]},{"apiGroups":[""],"resources":["configmaps"],"verbs":["create"]},{"apiGroups":[""],"resourceNames":["ingress-controller-leader-nginx"],"resources":["configmaps"],"verbs":["get","update"]}]}

 creationTimestamp: "2019-05-13T06:08:48Z"

 name: nginx-ingress-controller

 resourceVersion: "128875243"

 selfLink: /apis/rbac.authorization.k8s.io/v1/clusterroles/nginx-ingress-controller

 uid: 92cc75b7-7545-11e9-b617-00163e06992d

rules:

- apiGroups:

 - ""

 resources:

 - configmaps

 - endpoints

 - nodes

 - pods

 - secrets

 - namespaces

 - services

 verbs:

 - get

 - list

 - watch

- apiGroups:

 - extensions

 - networking.k8s.io

 resources:

 - ingresses

 verbs:

 - get

 - list

 - watch

- apiGroups:

 - ""

 resources:

 - events

 verbs:

 - create

 - patch

- apiGroups:

 - extensions

 - networking.k8s.io

 resources:

 - ingresses/status

 verbs:

 - update

- apiGroups:

 - ""

 resources:

 - configmaps

 verbs:

 - create

- apiGroups:

 - ""

 resourceNames:

 - ingress-controller-leader-nginx

 resources:

 - configmaps

 verbs:

 - get

 - update


     注意:还有一个报错的版本是由于在配置私有Ingress Controller Pod时是引用集群默认的ServiceAccount,新生成的ingress-controller配置项没有更新到默认的ClusterRole所以导致发布ingress规则报没权限从而显示不了ip,此时需要在默认的ClusterRole中的resourceNames下添加ingress-controller


apiVersion: rbac.authorization.k8s.io/v1beta1

 kind: Role

 metadata:

   name: nginx-ingress-role

   namespace: ingress-nginx

  ...

     resourceNames:

       # Defaults to "<election-id>-<ingress-class>"

       # Here: "<ingress-controller-leader>-<nginx>"

       # This has to be adapted if you change either parameter

       # when launching the nginx-ingress-controller.

       - "ingress-controller-leader-nginx"

     verbs:

       - get

       - update

    ...


RBAC扩展:

    基于角色的访问控制(Role-Based Access Control, 即”RBAC”)使用”rbac.authorization.k8s.io” API Group实现授权决策,允许管理员通过Kubernetes API动态配置策略。


API概述

    RBAC API声明了四个最高级别的类型(本文介绍),RBAC 的授权策略可以利用 kubectl 或者 Kubernetes API 直接进行配置。RBAC 可以授权给用户,让用户有权进行授权管理,这样就无需接触节点,直接进行授权管理。RBAC 在 Kubernetes 中被映射为 API 资源和操作。相关资源的图示如下:


                               

Kubernetes 仅审查以下 API 请求属性:

  • user - 身份验证期间提供的 user 字符串。
  • group - 经过身份验证的用户所属的组名列表。
  • extra - 由身份验证层提供的任意字符串键到字符串值的映射。
  • API - 指示请求是否针对 API 资源。
  • Request path - 各种非资源端点的路径,如 /api/healthz
  • API request verb - API 动词 getlistcreateupdatepatchwatchproxyredirectdeletedeletecollection 用于资源请求。
  • HTTP request verb - HTTP 动词 getpostputdelete 用于非资源请求。
  • Resource - 正在访问的资源的 ID 或名称(仅限资源请求) - 对于使用 getupdatepatchdelete 动词的资源请求,您必须提供资源名称。
  • Subresource - 正在访问的子资源(仅限资源请求)。
  • Namespace - 正在访问的对象的名称空间(仅适用于命名空间资源请求)。
  • API group - 正在访问的 API 组(仅限资源请求)。空字符串表示核心 API 组。(可以理解为不限制具体哪个apigroup)


Role 和 ClusterRole

       在 RBAC API 中,一个角色包含一组相关权限的规则。权限是纯粹累加的(不存在拒绝某操作的规则)。 角色可以用 Role 来定义到某个命名空间上, 或者用 ClusterRole 来定义到整个集群作用域。

一个 Role 只可以用来对某一命名空间中的资源赋予访问权限。 下面的 Role 示例定义到名称为 "default" 的命名空间,可以用来授予对该命名空间中的 Pods 的读取权限:


apiVersion: rbac.authorization.k8s.io/v1

kind: Role

metadata:

 namespace: default

 name: pod-reader

rules:

- apiGroups: [""] # "" 指定核心 API 组

 resources: ["pods"]

 verbs: ["get", "watch", "list"]

ClusterRole 可以授予的权限和 Role 相同, 但是因为 ClusterRole 属于集群范围,所以它也可以授予以下访问权限:

  • 集群范围资源 (比如 nodes)
  • 非资源端点(比如 "/healthz")
  • 跨命名空间访问的有名字空间作用域的资源(如 Pods),比如运行命令kubectl get pods --all-namespaces 时需要此能力

下面的 ClusterRole 示例可用来对某特定命名空间下的 Secrets 的读取操作授权, 或者跨所有命名空间执行授权(取决于它是如何绑定的):

apiVersion: rbac.authorization.k8s.io/v1

kind: ClusterRole

metadata:

 # 此处的 "namespace" 被省略掉是因为 ClusterRoles 是没有命名空间的。集群级别的授权

 name: secret-reader

rules:

- apiGroups: [""]

 resources: ["secrets"]

 verbs: ["get", "watch", "list"]

RoleBinding 和 ClusterRoleBinding

        角色绑定(RoleBinding)是将角色中定义的权限赋予一个或者一组用户。 它包含若干主体(用户,组和服务账户)的列表和对这些主体所获得的角色的引用。 可以使用 RoleBinding 在指定的命名空间中执行授权, 或者在集群范围的命名空间使用 ClusterRoleBinding 来执行授权。

一个 RoleBinding 可以引用同一的命名空间中的 Role 。 下面的例子 RoleBinding 将 "pod-reader" 角色授予在 "default" 命名空间中的用户 "jane"; 这样,用户 "jane" 就具有了读取 "default" 命名空间中 pods 的权限。

roleRef 里的内容决定了实际创建绑定的方法。kind 可以是 RoleClusterRolename 将引用你要指定的 RoleClusterRole 的名称。在下面的例子中,角色绑定使用 roleRef 将用户 "jane" 绑定到前文创建的角色 Role,其名称是 pod-reader

apiVersion: rbac.authorization.k8s.io/v1

# 此角色绑定使得用户 "muyuan" 能够读取 "default" 命名空间中的 Pods

kind: RoleBinding

metadata:

 name: read-pods

 namespace: default

subjects:

- kind: User

 name: muyuan # 需要注意name字段的大小写是敏感的

 apiGroup: rbac.authorization.k8s.io

roleRef:

 kind: Role #this must be Role or ClusterRole

 name: pod-reader # 这里的名称必须与你想要绑定的 Role 或 ClusterRole 名称一致

 apiGroup: rbac.authorization.k8s.io

RoleBinding 也可以引用 ClusterRole,对 ClusterRole 所定义的、位于 RoleBinding 命名空间内的资源授权。 这可以允许管理者在 整个集群中定义一组通用的角色,然后在多个命名空间中重用它们。

例如下面的例子,RoleBinding 指定的是 ClusterRole, "dave" (主体,区分大小写)将只可以读取在"development" 命名空间( RoleBinding 的命名空间)中的"secrets"。

apiVersion: rbac.authorization.k8s.io/v1

# 这个角色绑定允许 "muyuan" 用户在 "myns" 命名空间中有读取 secrets 的权限。

kind: RoleBinding

metadata:

 name: read-secrets

 namespace: myns # 这里只授予 "myns" 命名空间的权限。

subjects:

- kind: User

 name: muyuan # 需要注意name字段的大小写是敏感的

 apiGroup: rbac.authorization.k8s.io

roleRef:

 kind: ClusterRole

 name: secret-reader

 apiGroup: rbac.authorization.k8s.io

最后,ClusterRoleBinding 可用来在集群级别或对所有命名空间执行授权。 下面的例子允许 "manager" 组中的任何用户读取任意命名空间中 "secrets"。


apiVersion: rbac.authorization.k8s.io/v1

# 这个集群角色绑定允许 "muyuangroup" 组中的任何用户读取任意命名空间中 "secrets"。

kind: ClusterRoleBinding

metadata:

 name: read-secrets-global

subjects:

- kind: Group

 name: muyuangroup # 名称区分大小写

 apiGroup: rbac.authorization.k8s.io

roleRef:

 kind: ClusterRole

 name: secret-reader

 apiGroup: rbac.authorization.k8s.io

你不能修改绑定对象所引用的 RoleClusterRole 。 试图改变绑定对象的 roleRef 将导致验证错误。想要 改变现有绑定对象中 roleRef 字段的内容,必须删除并 重新创建绑定对象。这种限制有两个主要原因:

1.关于不同角色的绑定是完全不一样的。更改 roleRef 需要删除/重建绑定,确保要赋予绑定的完整主体列表是新 的角色(而不是只是启用修改 roleRef 在不验证所有现有 主体的情况下的,应该授予新角色对应的权限)。

2.使得 roleRef 不可以改变现有绑定主体用户的 update 权限, 这样可以让它们能够管理主体列表,而不能更改授予这些主体相关 的角色。


对资源的引用

大多数资源都是使用名称的字符串表示,例如在相关的 API 端点的 URL 之中出现的 "pods" 。 然而有一些 Kubernetes API 涉及 "子资源(subresources)",例如 pod 的日志。Pod 日志相关的端点 URL 如下:

GET /api/v1/namespaces/{namespace}/pods/{name}/log


在这种情况下,"pods" 是有命名空间的资源,而 "log" 是 pods 的子资源。在 RBAC 角色中, 使用"/"分隔资源和子资源。允许一个主体要同时读取 pods 和 pod logs,你可以这么写:

apiVersion: rbac.authorization.k8s.io/v1

kind: Role

metadata:

 namespace: default

 name: pod-and-pod-logs-reader

rules:

- apiGroups: [""]

 resources: ["pods", "pods/log"]

 verbs: ["get", "list"]

对于某些请求,也可以通过 resourceNames 列表按名称引用资源。 在指定时,可以将请求类型限制资源的单个实例。限制只可以 "get" 和 "update" 的单一configmap,你可以这么写:

apiVersion: rbac.authorization.k8s.io/v1

kind: Role

metadata:

 namespace: default

 name: configmap-updater

rules:

- apiGroups: [""]

 resources: ["configmaps"]

 resourceNames: ["my-configmap"]

 verbs: ["update", "get"]

需要注意的是,create 请求不能被 resourceName 限制,因为在鉴权时还不知道对象名称。 另一个例外是 deletecollection


对主体的引用

RoleBinding 或者 ClusterRoleBinding 需要绑定角色到 主体。 主体可以是组,用户或者服务账户。

用户是由字符串表示,它们可以是普通的用户名,像 "alice",或者是 邮件格式 "bob@example.com",或者是数字ID。由 Kubernetes 管理员配置身份认证模块 需要的格式。RBAC 鉴权系统不对格式作任何要求,但是前缀 system: 是 Kubernetes 系统保留的, 所以管理员要确保配置的用户名不能出现上述前缀格式。

用户组信息是 Kubernetes 现在提供的一种身份验证模块,与用户一样,对组的字符串没有格式要求, 只是不能使用保留的前缀 system:

服务账号 的用户名前缀为system:serviceaccount:, 属于前缀为 system:serviceaccounts: 的用户组。

RoleBinding的示例

下面的示例只是展示 RoleBindingsubjects 的部分。

用户的名称为 "muyuanuser":

subjects:

- kind: User

 name: "muyuanuser"

 apiGroup: rbac.authorization.k8s.io

组的名称为 "muyuangroups":

subjects:

- kind: Group

 name: "muyuangroups"

 apiGroup: rbac.authorization.k8s.io

服务账号在 kube-system 命名空间中:

subjects:

- kind: ServiceAccount

 name: default

 namespace: kube-system



好的,看到这里我相信你已经大概明白了RBAC的授权方式了,我来大致总结一下


RBAC通过角色绑定将角色和主体相关联,角色负责授权相关资源,主体绑定角色后就对授权资源有了授权


话不多说,我们来做一个场景实验,新建muyuantest用户,并生成该用户所属的kubeconfig,具备操作muyuanns命名空间所有权限,测试环境为master节点,托管集群请走ram+rbac授权(请不要直接跟着动手做,看完本篇文章之后想要尝试的话,再在测试环境上尝试)


一,创建证书

1.1  创建user私钥

[root@iZwz99lmwvr1f2s76mrv6mZ pki]# pwd

/etc/kubernetes/pki

# umask 077;openssl genrsa -out muyuantest.key 2048

Generating RSA private key, 2048 bit long modulus

............+++

.....................................................+++

e is 65537 (0x10001)

1.2  创建证书签署请求

O=组织信息,CN=用户名

# openssl req -new -key muyuantest.key -out muyuantest.csr -subj "/O=k8s/CN=muyuantest"

1.3  签署证书

pki]# openssl  x509 -req -in muyuantest.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out muyuantest.crt -days 365

Signature ok

subject=/O=k8s/CN=muyuantest

Getting CA Private Key

二,创建配置文件

2.1 创建集群配置(注意里面的server写的是master的ip,不是api-server的slb的ip)

pki]# kubectl config set-cluster k8s --server=https://192.168.0.128:6443 --certificate-authority=ca.crt --embed-certs=true --kubeconfig=/root/muyuantest.conf

Cluster "k8s" set.

# kubectl config view --kubeconfig=/root/muyuantest.conf

apiVersion: v1

clusters:

- cluster:

   certificate-authority-data: DATA+OMITTED

   server: https://192.168.0.128:6443

 name: k8s

contexts: []

current-context: ""

kind: Config

preferences: {}

users: []

2.2 创建用户配置

# kubectl config set-credentials muyuantest --client-certificate=muyuantest.crt --client-key=muyuantest.key --embed-certs=true --kubeconfig=/root/muyuantest.conf

User "muyuantest" set.

# kubectl config view --kubeconfig=/root/muyuantest.conf

apiVersion: v1

clusters:

- cluster:

   certificate-authority-data: DATA+OMITTED

   server: https://192.168.0.128:6443

 name: k8s

contexts: []

current-context: ""

kind: Config

preferences: {}

users:

- name: muyuantest

 user:

   client-certificate-data: REDACTED

   client-key-data: REDACTED

2.3 创建context配置

# kubectl config set-context muyuantest@k8s --cluster=k8s --user=muyuantest --kubeconfig=/root/muyuantest.conf

Context "muyuantest@k8s" created.

# kubectl config view --kubeconfig=/root/muyuantest.conf

apiVersion: v1

clusters:

- cluster:

   certificate-authority-data: DATA+OMITTED

   server: https://192.168.0.128:6443

 name: k8s

contexts:

- context:

   cluster: k8s

   user: muyuantest

 name: muyuantest@k8s

current-context: ""

kind: Config

preferences: {}

users:

- name: muyuantest

 user:

   client-certificate-data: REDACTED

   client-key-data: REDACTED

2.4 切换context

# kubectl config use-context muyuantest@k8s --kubeconfig=/root/muyuantest.conf

2.5 创建系统用户

# mkdir -p /home/muyuantest/.kube

# cp /root/muyuantest.conf /home/muyuantest/.kube/config

# chown -R muyuantest:muyuantest /home/muyuantest/

# su - muyuantest

-bash-4.2$

2.6 未做role的绑定,验证权限

-bash-4.2$ kubectl get pods

Error from server (Forbidden): pods is forbidden: User "muyuantest" cannot list resource "pods" in API group "" in the namespace "default"

2.7,创建role

# cat muyuantest-role.yaml

apiVersion: rbac.authorization.k8s.io/v1

kind: Role

metadata:

 namespace: muyuanns

 name: muyuannsall

rules:

- apiGroups: ["*"]

 resources: ["*"]

 verbs: ["*"]


# kubectl apply -f muyuantest-role.yaml

role.rbac.authorization.k8s.io/muyuannsall created

2.8 创建rolebindings

# kubectl apply -f muyuan-rolebindings.yaml

rolebinding.rbac.authorization.k8s.io/muyuantestrolebindings created


# cat muyuan-rolebindings.yaml

apiVersion: rbac.authorization.k8s.io/v1

kind: RoleBinding

metadata:

 name: muyuantestrolebindings

 namespace: muyuanns

subjects:

- kind: User

 name: muyuantest

 apiGroup: rbac.authorization.k8s.io

roleRef:

 kind: Role

 name: muyuannsall

 apiGroup: rbac.authorization.k8s.io

2.9 验证授权,授权通过

# su - muyuantest

Last login: Mon Sep  7 13:02:02 CST 2020 on pts/0

-bash-4.2$ kubectl get pods -n muyuanns

NAME                                   READY   STATUS    RESTARTS   AGE

nginx-muyuanns-test-54f57cf6bf-8qkm7   1/1     Running   0          89s


注意:使用阿里云的子账号授权是没有这么复杂的,我们只需要关注,子账号授权的时候,默认权限的角色定义是否匹配我们的需求,不匹配的话就使用自定义规则去创建(控制台使用clusterrole进行授权,clusterrole需要提前创建)


=====命令扩展=====

下面这几个命令是api相关的资源

# kubectl get apiservices

# kubectl api-versions

# kubectl api-resources

=====RBAC 子资源list=====

# cat list_subresource.sh

#!/bin/bash

_list=($(kubectl get --raw / |grep "^    \"/api"|sed 's/[",]//g'));

for _api in ${_list[@]}; do

 _aruyo=$(kubectl get --raw ${_api} | jq .resources);

 if [ "x${_aruyo}" != "xnull" ]; then

   echo;

   echo "===${_api}===";

   kubectl get --raw ${_api} | jq -r ".resources[].name";

 fi;

done


# bash list_subresource.sh


===/api/v1===

bindings

componentstatuses

configmaps

endpoints

events

limitranges

namespaces

namespaces/finalize

namespaces/status

nodes

nodes/proxy

nodes/status

persistentvolumeclaims

persistentvolumeclaims/status

persistentvolumes

persistentvolumes/status

pods

pods/attach

pods/binding

pods/eviction

pods/exec

pods/log

pods/portforward

pods/proxy

pods/status

podtemplates

replicationcontrollers

replicationcontrollers/scale

replicationcontrollers/status

resourcequotas

resourcequotas/status

secrets

serviceaccounts

services

services/proxy

services/status


===/apis/admissionregistration.k8s.io/v1===

mutatingwebhookconfigurations

validatingwebhookconfigurations

...

                                                                                                                                                                                                                                 by 思葵 牧原

参考资料:

https://kubernetes.io/zh/docs/reference/access-authn-authz/rbac/

https://medium.com/@tannhauser.sphinx/bash-kubernetes-script-to-list-all-available-resources-subresources-c65a5c2c1173

相关实践学习
容器服务Serverless版ACK Serverless 快速入门:在线魔方应用部署和监控
通过本实验,您将了解到容器服务Serverless版ACK Serverless 的基本产品能力,即可以实现快速部署一个在线魔方应用,并借助阿里云容器服务成熟的产品生态,实现在线应用的企业级监控,提升应用稳定性。
云原生实践公开课
课程大纲 开篇:如何学习并实践云原生技术 基础篇: 5 步上手 Kubernetes 进阶篇:生产环境下的 K8s 实践 相关的阿里云产品:容器服务&nbsp;ACK 容器服务&nbsp;Kubernetes&nbsp;版(简称&nbsp;ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情:&nbsp;https://www.aliyun.com/product/kubernetes
目录
相关文章
|
1月前
|
缓存 Kubernetes Docker
容器服务ACK常见问题之容器服务ACK ingress websocket配置失败如何解决
容器服务ACK(阿里云容器服务 Kubernetes 版)是阿里云提供的一种托管式Kubernetes服务,帮助用户轻松使用Kubernetes进行应用部署、管理和扩展。本汇总收集了容器服务ACK使用中的常见问题及答案,包括集群管理、应用部署、服务访问、网络配置、存储使用、安全保障等方面,旨在帮助用户快速解决使用过程中遇到的难题,提升容器管理和运维效率。
|
1月前
|
移动开发 网络协议 安全
网络面试题:什么是 TCP/IP?
网络面试题:什么是 TCP/IP?
43 0
网络面试题:什么是 TCP/IP?
|
2月前
|
运维 网络协议 网络架构
网络技术基础(6)——IP路由基础
【2月更文挑战第10天】网络基础笔记(加班了几天,中途耽搁了,预计推迟6天)
|
23天前
|
运维 Kubernetes Cloud Native
探索Kubernetes的大二层网络:原理、优势与挑战🚀
在云原生领域,Kubernetes (K8s) 已经成为容器编排的事实标准☁️📦。为了支撑其灵活的服务发现和负载均衡🔍🔄,K8s采用了大二层网络的设计理念🕸️。本文将深入探讨大二层网络的工作原理、带来的好处✨,以及面临的挑战和解决方案❗🛠️。
探索Kubernetes的大二层网络:原理、优势与挑战🚀
|
2天前
|
监控 负载均衡 网络协议
|
2天前
|
网络协议 Linux iOS开发
|
2天前
|
存储 网络协议 网络安全
IP路由详解:网络互联的心脏
【4月更文挑战第22天】
24 7
IP路由详解:网络互联的心脏
|
11天前
|
安全 网络安全 网络虚拟化
如何保护IP在线隐私,提高网络安全?
如何保护IP在线隐私,提高网络安全?
|
12天前
|
缓存 安全 网络协议
代理ip会不会影响网络速度和稳定性
代理ip会不会影响网络速度和稳定性
|
17天前
|
JSON Kubernetes 网络架构
Kubernetes CNI 网络模型及常见开源组件
【4月更文挑战第13天】目前主流的容器网络模型是CoreOS 公司推出的 Container Network Interface(CNI)模型

推荐镜像

更多