diff --git a/guide/example/import.md b/guide/example/import.md index cd00c30..189a696 100644 --- a/guide/example/import.md +++ b/guide/example/import.md @@ -12,6 +12,7 @@ description: 通过Kuboard将一个预先定义好的SpringCloud微服务样例 必须具备如下条件: * Kubernetes 集群 (安装在阿里云,本文将使用阿里云的 NFS 服务作为存储资源,Kuboard 也可以运行在其他云环境或者私有环境中。) +* 导入 example 微服务时,要求 Kubernetes 集群版本不低于 1.14.0 重要 * 已在集群中安装 Kuboard ## 创建存储资源 @@ -24,7 +25,7 @@ example中用到了存储卷声明,请在 Kuboard 中 [创建存储类](/guide ## 创建名称空间 -创建新的名称空间,用来导入 exmaple。可参考 [创建名称空间](/guide/cluster/namespace.html?id=创建名称空间) +创建新的名称空间,用来导入 example。可参考 [创建名称空间](/guide/cluster/namespace.html?id=创建名称空间) 假设您已经进入了 Kuboard 名称空间界面,如下图所示: diff --git a/learning/faq/metrics.md b/learning/faq/metrics.md new file mode 100644 index 0000000..caa3bef --- /dev/null +++ b/learning/faq/metrics.md @@ -0,0 +1,12 @@ +--- +vssueId: 174 +layout: LearningLayout +description: Kubernetes教程_本文解释了Kubernetes中为什么ping Service 不能成功的原因 +meta: + - name: keywords + content: Kubernetes教程,K8S教程,Kubernetes Service +--- + +# Metrics + +Kuboard 界面上显示 Metrics(性能指标)信息时,调用了 Kubernetes 的 [Metrics API](https://kubernetes.io/docs/tasks/debug-application-cluster/resource-metrics-pipeline/), diff --git a/learning/k8s-intermediate/service/dns.md b/learning/k8s-intermediate/service/dns.md index ee57d45..db75c93 100644 --- a/learning/k8s-intermediate/service/dns.md +++ b/learning/k8s-intermediate/service/dns.md @@ -33,13 +33,13 @@ Kubernetes 集群中运行了一组 DNS Pod,配置了对应的 Service,并 * Service(headless Service 除外)将被分配一个 DNS A 记录,格式为 `my-svc.my-namespace.svc.cluster-domain.example`。该 DNS 记录解析到 Service 的 ClusterIP。 -* Headless Service(没有 ClusterIP)也将被分配一个 DNS A 记录,格式为 `my-svc.my-namespace.svc.cluster-domain.exmaple`。该 DNS 记录解析到 Service 所选中的一组 Pod 的 IP 地址的集合。调用者应该使用该 IP 地址集合,或者按照轮询(round-robin)的方式从集合中选择一个 IP 地址使用。 +* Headless Service(没有 ClusterIP)也将被分配一个 DNS A 记录,格式为 `my-svc.my-namespace.svc.cluster-domain.example`。该 DNS 记录解析到 Service 所选中的一组 Pod 的 IP 地址的集合。调用者应该使用该 IP 地址集合,或者按照轮询(round-robin)的方式从集合中选择一个 IP 地址使用。 ### SRV 记录 Service(含 headless Service)的命名端口(有 name 的端口)将被分配一个 SRV 记录,其格式为 `_my-port-name._my-port-protocol.my-svc.my-namespace.svc.cluster-domain.example`: -* 对于一个普通 Service(非 headless Service),该 SRV 记录解析到其端口号和域名 `my-svc.my-namespace.svc.cluster-domain.exmaple` -* 对于一个 Headless Service,该 SRV 记录解析到多个结果:每一个结果都对应该 Service 的一个后端 Pod,包含其端口号和 Pod 的域名 `auto-generated-pod-name.my-svc.my-namespace.svc.cluster-domain.exmaple` +* 对于一个普通 Service(非 headless Service),该 SRV 记录解析到其端口号和域名 `my-svc.my-namespace.svc.cluster-domain.example` +* 对于一个 Headless Service,该 SRV 记录解析到多个结果:每一个结果都对应该 Service 的一个后端 Pod,包含其端口号和 Pod 的域名 `auto-generated-pod-name.my-svc.my-namespace.svc.cluster-domain.example` ## Pods diff --git a/support/change-log/change-log-on-the-way.md b/support/change-log/change-log-on-the-way.md index fc17d33..992548a 100644 --- a/support/change-log/change-log-on-the-way.md +++ b/support/change-log/change-log-on-the-way.md @@ -1,16 +1,11 @@ Kuboard v1.0.x 的更新说明 -**BUG 修复** - - - * EndPoint * 导入工作负载时,如果存储类没有 annotations,不应该报错 * 表单校验:数据卷名不能带小数点 * Prometheus 监控 -* 工作负载编辑器 --> 容器组 --> 容忍 -- 正在开发 * Limit Range diff --git a/support/change-log/v1.0.x.md b/support/change-log/v1.0.x.md index 4da818d..3afc116 100644 --- a/support/change-log/v1.0.x.md +++ b/support/change-log/v1.0.x.md @@ -11,8 +11,39 @@ description: 本文描述了Kuboard_v1.0.x的版本变更说明 Kuboard v1.0.x 的更新说明 +## v1.0.5-beta.5 + +**发布日期** + +2019年12月3日 + +**新特性** + +* 按CPU、内存使用情况对节点排序 +* 新增 top pods 界面 + + +## v1.0.5-beta.4 + +**发布日期** + +2019年12月2日 + +**新特性** + +* 安装 metrics-server +* 显示节点当前的 metrics 数据 + +**BUG 修复** + +* 预览YAML时,emptyDir为空的情况下,仍然应该显示在YAML中 + ## v1.0.5-beta.3 +**发布日期** + +2019年12月1日 + **新特性** * 工作负载编辑器 --> 容忍 diff --git a/t/cka/daily.md b/t/cka/daily.md index 3110394..fe0f075 100644 --- a/t/cka/daily.md +++ b/t/cka/daily.md @@ -53,4 +53,8 @@ CKA证书的含金量如何?考不考这个证完全取决于个人,因为 [CKA每日一题 - Day 8](./daily/008.html) +[CKA每日一题 - Day 9](./daily/009.html) + +[CKA每日一题 - Day 10](./daily/010.html) + diff --git a/t/cka/daily/008.md b/t/cka/daily/008.md index ef3766c..639bee0 100644 --- a/t/cka/daily/008.md +++ b/t/cka/daily/008.md @@ -20,7 +20,7 @@ meta: ::: -答案及解析 +答案及解析 diff --git a/t/cka/daily/009.assets/640-20191202195858696.png b/t/cka/daily/009.assets/640-20191202195858696.png new file mode 100644 index 0000000..f1fd817 Binary files /dev/null and b/t/cka/daily/009.assets/640-20191202195858696.png differ diff --git a/t/cka/daily/009.assets/640-20191202195858697.png b/t/cka/daily/009.assets/640-20191202195858697.png new file mode 100644 index 0000000..2c5999c Binary files /dev/null and b/t/cka/daily/009.assets/640-20191202195858697.png differ diff --git a/t/cka/daily/009.assets/640.jpeg b/t/cka/daily/009.assets/640.jpeg new file mode 100644 index 0000000..f351e31 Binary files /dev/null and b/t/cka/daily/009.assets/640.jpeg differ diff --git a/t/cka/daily/009.assets/640.png b/t/cka/daily/009.assets/640.png new file mode 100644 index 0000000..d1e84f8 Binary files /dev/null and b/t/cka/daily/009.assets/640.png differ diff --git a/t/cka/daily/009.md b/t/cka/daily/009.md new file mode 100644 index 0000000..d3a6c1d --- /dev/null +++ b/t/cka/daily/009.md @@ -0,0 +1,487 @@ +--- +vssueId: 170 +# layout: StepLayout +sharingTitle: CKA备考打卡 - 每日一题 - Day 9 +description: CKA备考打卡 - 每日一题 - Day 9 +meta: + - name: keywords + content: Kubernetes,K8S,CKA,Certified Kubernetes Administrator +--- + +# CKA每日一题 --- Day 9 + + + +::: tip 考题 + +创建 Secret 名为 cka1127-secret,内含有 password 字段,值为 cka1127,然后在名为 cka1127-01 的 Pod1 里使用ENV进行调用,名为cka1127-02的 Pod2 里使用 Volume 挂载在 `/data` 下; + +> **注意:提交评论:包含命令和yaml,以及注意点。可分多次评论。** + +::: + +答案及解析 + + + + + +## 答案 + +**创建secret方式一** +cka1127-secret.yaml可以是以下这样: + +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: cka1127-secret +type: Opaque +stringData: + cka1127-password: cka1127 +``` + +创建 + +```sh +[root@liabio test]# kubectl apply -f cka-1127-secret.yaml +secret/cka1127-secret created +``` + +**创建secret方式二** + +```sh +kubectl create secret generic cka1127-secret --from-literal=password=cka1127 +``` + +**名为cka1127-01的Pod yaml** + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: cka1127-01 +spec: + containers: + - name: nginx + image: nginx + volumeMounts: + - name: pwd + mountPath: /data/password + readOnly: true + volumes: + - name: pwd + secret: + secretName: cka1127-secret +``` + +**名为cka1127-02的Pod yaml** + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: cka1127-02 +spec: + containers: + - image: nginx + name: nginx + env: + - name: PASSWORD + valueFrom: + secretKeyRef: + name: cka1127-secret + key: password +``` + +volume形式验证,保证/data/password/下有password文件,文件内容为明文cka1127 + +```sh +[root@liabio ~]# kubectl exec -ti cka1127-01 sh +# +# ls -l /data/password +total 0 +lrwxrwxrwx 1 root root 15 Nov 28 00:40 password -> ..data/password +# cat /data/password/password +cka1127# +# +``` + +环境变量形式验证,保证env能查到name为PASSWORD的环境变量; + +```sh +[root@liabio test]# kubectl exec -ti cka1127-02 bash +root@cka1127-02:/# +root@cka1127-02:/# echo $PASSWORD +cka1127 +root@cka1127-02:/# +``` + +## 解析 + +**secret官方文档:** +https://kubernetes.io/docs/concepts/configuration/secret/ + +中文文档:[https://kuboard.cn/learning/k8s-intermediate/config/secrets/](https://kuboard.cn/learning/k8s-intermediate/config/secrets/) + +### secret简介 + +Kubernetes中的Secret资源可以用来存储密码、Token、秘钥等敏感数据, 将这些敏感信息保存在Secret中,相对于暴露到Pod、镜像中更加的安全和灵活。 + +你可能会觉得,secret一般不会用到,实际上在创建Pod时,Kubernetes会自动创建包含用于访问API的凭据的`secret`(由`kube-controller-manager`的`service account token controller`控制),并且它会自动修改Pod以使用这种类型的secret(这个由Admission Controller来控制)。 + +k8s每个namespace都会有一个Service Account,当我们创建namespace时,service account controller会监听namespace的创建,会在该namespace中创建一个名为default的Service Account,同时service account token controller会监听Service Account的创建,创建对应的secret,并将这个secret绑定到Service Account。 + +``` +[root@liabio test]# kubectl create ns cka +namespace/cka created +[root@liabio test]# +[root@liabio test]# kubectl get sa -n cka +NAME SECRETS AGE +default 1 11s +[root@liabio test]# kubectl get secrets -n cka +NAME TYPE DATA AGE +default-token-r77xn kubernetes.io/service-account-token 3 18s +[root@liabio test]# +``` + +![CKA每日一题_Day9](./009.assets/640.png) + + +当我们创建Pod时,如果未指定Service Account,则默认会在同一命令空间namespace中自动为其分配Service Account。则可以看到该spec.serviceAccountName字段已被自动设置。 + +![CKA每日一题_Day9](./009.assets/640.jpeg) + +您可以使用自动添加的Service Account凭据从Pod内部访问API,Service Account的API权限取决于所使用的授权插件和策略。 + +有关Service Account如何工作的更多信息,请参见文档: +https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/ + +### Secret的类型 + +--type指定创建的秘密类型,Kubernetes内置了三种类型的Secret + +##### kubernetes.io/service-account-token Secret + +上面我们已经讲到,为了能从Pod内部访问Kubernetes API,Kubernetes提供了Service Account资源。Service Account会自动创建和挂载访问Kubernetes API的Secret,会挂载到Pod的 /var/run/secrets/kubernetes.io/serviceaccount目录中。namespace创建时自动创建的Service Account用到的Secret就是这种类型的。 + +![CKA每日一题_Day9](./009.assets/640-20191202195858697.png)在这里插入图片描述 + +##### Opaque Secret + +Opaque类型的Secret是一个map结构(key-value),其中vlaue要求以base64格式编码,以下示例中基本都为Opaque类型的Secret。 + +##### kubernetes.io/dockerconfigjson Secret + +kubernetes.io/dockercfg类型的Secret用于存放私有Docker Registry的认证信息。当Kubernetes在创建Pod并且需要从私有Docker Registry pull镜像时,需要使用认证信息,就会用到kubernetes.io/dockercfg类型的Secret。 + +```sh +kubectl create secret docker-registry cka-regsecret \ +--docker-server=coderaction \ +--docker-username=admin \ +--docker-password=123456 \ +--docker-email=837448191@qq.com +``` + +![CKA每日一题_Day9](./009.assets/640-20191202195858696.png) + + +在创建Pod时需要在Pod的spec中按如下形式使用: + + + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: cka-private-reg +spec: + containers: + - name: cka-private-reg-container + image: nginx + imagePullSecrets: + - name: cka-regsecret +``` + +**可以参考官方文档:** +https://kubernetes.io/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-pod + +中文文档: [使用私有仓库中的镜像](https://kuboard.cn/learning/k8s-intermediate/private-registry.html) + +**给分区默认的ServiceAccount添加imagePullSecrets,以至于创建的所有Pod可以自动添加spec.imagePullSecrets,详情参考官方文档:** +https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/#add-imagepullsecrets-to-a-service-account + +### secret创建 + +#### kubectl创建secret + +**kubectl创建seccret官方文档:** +https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands#-em-secret-em- + +**格式:** + +``` +kubectl create secret generic NAME [--type=string] [--from-file=[key=]source] [--from-literal=key1=value1] [--dry-run] +``` + +--from-literal:指定要插入的键和文字值(即mykey = somevalue),value为明文值,创建后会被base64编码; +--from-file:可以使用密钥文件的文件路径指定密钥文件,在这种情况下,将为它们指定默认名称;或者可以选择使用指定目录,这样将迭代该目录中的每个有效文件密钥。 +--type:创建的秘密类型,上面已经介绍过三种类型; +--dry-run:如果为true,则仅打印将要向APIServer发送创建的对象,而不发送它。默认false; + +#### 使用--from-file创建 + +```sh +[root@liabio cka]# echo -n 'admin' > ./username +[root@liabio cka]# echo -n 'test123' > ./password +[root@liabio cka]# echo -n 'shanghai' > ./city +[root@liabio cka]# ll +total 12 +-rw-r--r-- 1 root root 9 Nov 28 20:44 city +-rw-r--r-- 1 root root 8 Nov 28 20:43 password +-rw-r--r-- 1 root root 6 Nov 28 20:43 username +[root@liabio cka]# kubectl create secret generic test-cka1127-01 --from-file=./username --from-file=./password +secret/test-cka1127-01 created +[root@liabio cka]# kubectl create secret generic test-cka1127-02 --from-file=./ +secret/test-cka1127-02 created +[root@liabio cka]# +``` + +以指定目录创建的secret,查看到目录下所有文件都被加到data下: + +```yaml +kubectl get secrets test-cka1127-02 -oyaml +apiVersion: v1 +data: + city: c2hhbmdoYWkK + password: dGVzdDEyMwo= + username: YWRtaW4K +kind: Secret +metadata: + creationTimestamp: "2019-11-28T12:44:57Z" + name: test-cka1127-02 + namespace: default + resourceVersion: "14636360" + selfLink: /api/v1/namespaces/default/secrets/test-cka1127-02 + uid: 4a3a1a5d-09e6-4bf9-bbe3-3300db1ddf7a +type: Opaque +``` + +指定username和password创建的secret: + +```yaml +kubectl get secrets test-cka1127-01 -oyaml +apiVersion: v1 +data: + password: dGVzdDEyMwo= + username: YWRtaW4K +kind: Secret +metadata: + creationTimestamp: "2019-11-28T12:44:47Z" + name: test-cka1127-01 + namespace: default + resourceVersion: "14636347" + selfLink: /api/v1/namespaces/default/secrets/test-cka1127-01 + uid: 766516a2-34be-4a18-b4e2-83751a6cd2b7 +type: Opaque +``` + +默认情况下,kubectl describe 命令能避免显示文件的内容。这可以防止将 secret 中的内容暴露给从终端日志记录中刻意寻找它们的人。 + +> 特殊字符,例如`不能识别此Latex公式: ,\,*,和!需要逃逸。在大多数常见的shell中,最简单的转义密码方法是用单引号(')引起来。例如,如果您的实际密码是S!B*d`zDsb,则应以这种方式执行命令: +> +> kubectl create secret generic dev-db-secret +> --from-literal=username=devuser --from-literal=password='S!B*d$zDsb' 您无需从文件(--from-file)中转义密码中的特殊字符。 + +#### 手动创建Secret + +还可以先在文件中以json或yaml格式创建一个Secret,然后创建该对象。该secret包含两种:`data`和是`stringData`是。data字段用于存储使用base64编码的任意数据。提供stringData字段是为了方便起见,它允许提供未编码的字符串。 + +例如,要使用data将两个字符串存储在Secret中,请按如下所示将它们转换为base64: + +```sh +echo -n 'admin' | base64 +YWRtaW4= +echo -n '1f2d1e2e67df' | base64 +MWYyZDFlMmU2N2Rm +``` + +**注意:在转base64编码时,一定记得加-n参数,否则可能会遇到坑。** + +然后创建以下yaml,最终`kubectl apply` + +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: mysecret +type: Opaque +data: + username: YWRtaW4= + password: MWYyZDFlMmU2N2Rm +``` + +如果用以下yaml创建,注意到用了stringData,user的值为coderaction明文。 + +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: cka1127-secret-02 +type: Opaque +stringData: + user: coderaction +``` + +执行 `kubectl apply` 后查看: + +```yaml +apiVersion: v1 +data: + user: Y29kZXJhY3Rpb24= +kind: Secret +metadata: + name: cka1127-secret-02 +type: Opaque +``` + +Y29kZXJhY3Rpb24=解码为coderaction + +```sh +[root@liabio cka]# echo Y29kZXJhY3Rpb24= | base64 -d +coderaction +``` + +data和stringData的键必须由字母数字字符“-”,“ _”或“。”组成。 + +> 编码注意:secret数据的序列化JSON和YAML值被编码为base64字符串。换行符在这些字符串中无效,因此必须省略。base64在Darwin/macOS上使用该实用程序时,用户应避免使用该-b选项来分隔长行。相反,如果选项不可用,Linux用户应将选项添加-w 0到base64命令或管道中。base64 | tr -d '\n'-w + +#### 从生成器创建Secret + +从1.14开始,Kubectl支持使用Kustomize管理对象。使用此新功能,您还可以从生成器创建一个Secret,然后将其应用于在Apiserver上创建对象。 + +#### 使用Kuboard界面创建Secret + +参考文档 [使用Kuboard界面创建Secret](/learning/k8s-intermediate/config/secrets/create-kuboard.html) + +### 使用Secret + +#### 将secret所有内容挂载为Pod里的文件 + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: mypod +spec: + containers: + - name: mypod + image: redis + volumeMounts: + - name: foo + mountPath: "/etc/foo" + readOnly: true + volumes: + - name: foo + secret: + secretName: mysecret +``` + +这样Pod中的/etc/foo目录下会生成mysecret中的所有映射文件。 + +#### 将密钥投影到特定路径 + +我们还可以控制secret映射到卷中的路径。您可以使用.spec.volumes[].secret.items更改每个键的目标路径: + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: mypod +spec: + containers: + - name: mypod + image: redis + volumeMounts: + - name: foo + mountPath: "/etc/foo" + readOnly: true + volumes: + - name: foo + secret: + secretName: mysecret + items: + - key: username + path: my-group/my-username +``` + +这样Pod中username存储在/etc/foo/my-group/my-username文件而非/etc/foo/username;而且没有password的映射文件。 + +#### secret文件权限 + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: mypod +spec: + containers: + - name: mypod + image: nginx + volumeMounts: + - name: foo + mountPath: "/etc/foo" + volumes: + - name: foo + secret: + secretName: cka1127-secret + defaultMode: 256 +``` + +然后,Secret将被挂载到/etc/foo并且由Secret卷挂载创建的所有文件权限为0400; + +请注意,JSON规范不支持八进制表示法,因此对于0400权限,请使用值256。如果您使用yaml而不是json描述Pod,则可以使用八进制表示法以更自然的方式指定权限。 + +也可以像前面的示例一样使用映射,并为不同的文件指定不同的权限,如下所示: + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: mypod-1 +spec: + containers: + - name: mypod + image: nginx + volumeMounts: + - name: foo + mountPath: "/etc/foo" + volumes: + - name: foo + secret: + secretName: cka1127-secret-02 + items: + - key: user + path: my-group/my-username + mode: 511 +``` + +mode值511为十进制,在这种情况下,生成的文件的/etc/foo/my-group/my-username许可权值为八进制0777。由于JSON的限制,您必须以十进制表示法指定mode。 + +**请注意,如果稍后阅读此权限值,则可能会以十进制表示法显示。** + +#### 环境变量 + +Pod中通过环境变量引用Secret和题目答案一样,不做累述; + +> 以上事例来自于官方文档。方便大家学习。 + + + + + + +> CKA 考试每日一题系列,全部内容由 [我的小碗汤](https://mp.weixin.qq.com/s/5tYgb_eSzHz_TMsi0U32gw) 创作,本站仅做转载 + + + diff --git a/t/cka/daily/010.md b/t/cka/daily/010.md new file mode 100644 index 0000000..4995d44 --- /dev/null +++ b/t/cka/daily/010.md @@ -0,0 +1,315 @@ +--- +vssueId: 170 +# layout: StepLayout +sharingTitle: CKA备考打卡 - 每日一题 - Day 10 +description: CKA备考打卡 - 每日一题 - Day 10 +meta: + - name: keywords + content: Kubernetes,K8S,CKA,Certified Kubernetes Administrator +--- + +# CKA每日一题 --- Day 10 + + + +::: tip 考题 + +创建一个Role(只有cka namespace下pods的所有操作权限)和RoleBinding(使用serviceaccount认证鉴权),使用对应serviceaccount作为认证信息对cka namespace下的pod进行操作以及对default namespace下的pods进行操作。 +– Role和RoleBinding的名称的名称为cka-1202-role、cka-1202-rb + +> **注意:请附所用命令、创建的Role、RoleBinding以及serviceaccount的完整yaml,可分多次评论。** + +::: + +答案及解析 + + + + + +## 答案 + +创建Service Account: + +```yaml +[root@liabio cka]# kubectl create serviceaccount cka-1202-sa -n cka -o yaml +apiVersion: v1 +kind: ServiceAccount +metadata: + creationTimestamp: "2019-12-02T23:37:42Z" + name: cka-1202-sa + namespace: cka + resourceVersion: "15159020" + selfLink: /api/v1/namespaces/cka/serviceaccounts/cka-1202-sa + uid: 6764e90c-cb28-4de1-9109-6e3d56941fcb +``` + +创建Role: + +```yaml +[root@liabio cka]# kubectl create role cka-1202-role -n cka --verb=* --resource=pods -oyaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + creationTimestamp: "2019-12-02T23:40:26Z" + name: cka-1202-role + namespace: cka + resourceVersion: "15159247" + selfLink: /apis/rbac.authorization.k8s.io/v1/namespaces/cka/roles/cka-1202-role + uid: fc2c5593-2fd9-46d7-a809-99bcee32249e +rules: +- apiGroups: + - "" + resources: + - pods + verbs: + - '*' +``` + +创建RoleBinding: + +```yaml +[root@liabio cka]# kubectl create rolebinding cka-1202-rb -n cka --role=cka-1202-role --serviceaccount=cka:cka-1202-sa -oyaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + creationTimestamp: "2019-12-02T23:46:50Z" + name: cka-1202-rb + namespace: cka + resourceVersion: "15159794" + selfLink: /apis/rbac.authorization.k8s.io/v1/namespaces/cka/rolebindings/cka-1202-rb + uid: c00d104e-a531-4781-90f4-2821651492bf +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: cka-1202-role +subjects: +- kind: ServiceAccount + name: cka-1202-sa + namespace: cka +``` + +验证: + +获取到`cka-1202-sa`这个`Service Account`绑定的`secret`并`base64 -d`解码`token`字段: + +```sh +[root@liabio ~]# kubectl get secret -n cka +NAME TYPE DATA AGE +cka-1202-sa-token-9rgp4 kubernetes.io/service-account-token 3 42m +default-token-r77xn kubernetes.io/service-account-token 3 4d14h +[root@liabio ~]# kubectl get secret -n cka cka-1202-sa-token-9rgp4 -ojson | jq .data.token +"ZXlKaGJHY2lPaUpTVXpJMU5pSXNJbXRwWkNJNklpSjkuZXlKcGMzTWlPaUpyZFdKbGNtNWxkR1Z6TDNObGNuWnBZMlZoWTJOdmRXNTBJaXdpYTNWaVpYSnVaWFJsY3k1cGJ5OXpaWEoyYVdObFlXTmpiM1Z1ZEM5dVlXMWxjM0JoWTJVaU9pSmphMkVpTENKcmRXSmxjbTVsZEdWekxtbHZMM05sY25acFkyVmhZMk52ZFc1MEwzTmxZM0psZEM1dVlXMWxJam9pWTJ0aExURXlNREl0YzJFdGRHOXJaVzR0T1hKbmNEUWlMQ0pyZFdKbGNtNWxkR1Z6TG1sdkwzTmxjblpwWTJWaFkyTnZkVzUwTDNObGNuWnBZMlV0WVdOamIzVnVkQzV1WVcxbElqb2lZMnRoTFRFeU1ESXRjMkVpTENKcmRXSmxjbTVsZEdWekxtbHZMM05sY25acFkyVmhZMk52ZFc1MEwzTmxjblpwWTJVdFlXTmpiM1Z1ZEM1MWFXUWlPaUkyTnpZMFpUa3dZeTFqWWpJNExUUmtaVEV0T1RFd09TMDJaVE5rTlRZNU5ERm1ZMklpTENKemRXSWlPaUp6ZVhOMFpXMDZjMlZ5ZG1salpXRmpZMjkxYm5RNlkydGhPbU5yWVMweE1qQXlMWE5oSW4wLnFXanJUcTdEbVZTU01TM0h4YzR0bFd4ODdUNGtvUkNvVmkxMjVzZXNWRWJ2QUtEaTJ6MFhvNjJaNzAza2htQ1dsWTU1TkxPYWVKS2taWXhYOWZMTEdYMnpPVWVFdzFvbUpmRkZpTm41NGxjOUhRTjlRXzVmTjRyYS1WNFZSaU5uQkFUeW43Yzc2aGk2Nks1aUh5WjB4bFRNcnBNQThXN1l2TmJnU1pIOXhnaFdSenpkSElKYWF1UXBTY0xtSk5MNmxGNGd5ZG9Xd0dDQy1QU0VjdGpKTkRtMF8zSTZoUkhEZkJzd3k2d0t4VGx4T3lIdE9yeUc0ckUzZzVqUWZOdV9BNTdTNVlocmEwWVM0emM0X0RvdXBmUC1zVjU3R0FQS1JxODZsRGdlOHo4cWFIaDRyb0k3RTNJbC1DRU9HS1JJeE52SWZVX3d0aHRrMG95aW5HR2wydw==" +[root@liabio ~]# echo ZXlKaGJHY2lPaUpTVXpJMU5pSXNJbXRwWkNJNklpSjkuZXlKcGMzTWlPaUpyZFdKbGNtNWxkR1Z6TDNObGNuWnBZMlZoWTJOdmRXNTBJaXdpYTNWaVpYSnVaWFJsY3k1cGJ5OXpaWEoyYVdObFlXTmpiM1Z1ZEM5dVlXMWxjM0JoWTJVaU9pSmphMkVpTENKcmRXSmxjbTVsZEdWekxtbHZMM05sY25acFkyVmhZMk52ZFc1MEwzTmxZM0psZEM1dVlXMWxJam9pWTJ0aExURXlNREl0YzJFdGRHOXJaVzR0T1hKbmNEUWlMQ0pyZFdKbGNtNWxkR1Z6TG1sdkwzTmxjblpwWTJWaFkyTnZkVzUwTDNObGNuWnBZMlV0WVdOamIzVnVkQzV1WVcxbElqb2lZMnRoTFRFeU1ESXRjMkVpTENKcmRXSmxjbTVsZEdWekxtbHZMM05sY25acFkyVmhZMk52ZFc1MEwzTmxjblpwWTJVdFlXTmpiM1Z1ZEM1MWFXUWlPaUkyTnpZMFpUa3dZeTFqWWpJNExUUmtaVEV0T1RFd09TMDJaVE5rTlRZNU5ERm1ZMklpTENKemRXSWlPaUp6ZVhOMFpXMDZjMlZ5ZG1salpXRmpZMjkxYm5RNlkydGhPbU5yWVMweE1qQXlMWE5oSW4wLnFXanJUcTdEbVZTU01TM0h4YzR0bFd4ODdUNGtvUkNvVmkxMjVzZXNWRWJ2QUtEaTJ6MFhvNjJaNzAza2htQ1dsWTU1TkxPYWVKS2taWXhYOWZMTEdYMnpPVWVFdzFvbUpmRkZpTm41NGxjOUhRTjlRXzVmTjRyYS1WNFZSaU5uQkFUeW43Yzc2aGk2Nks1aUh5WjB4bFRNcnBNQThXN1l2TmJnU1pIOXhnaFdSenpkSElKYWF1UXBTY0xtSk5MNmxGNGd5ZG9Xd0dDQy1QU0VjdGpKTkRtMF8zSTZoUkhEZkJzd3k2d0t4VGx4T3lIdE9yeUc0ckUzZzVqUWZOdV9BNTdTNVlocmEwWVM0emM0X0RvdXBmUC1zVjU3R0FQS1JxODZsRGdlOHo4cWFIaDRyb0k3RTNJbC1DRU9HS1JJeE52SWZVX3d0aHRrMG95aW5HR2wydw== | base64 -d +eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJja2EiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlY3JldC5uYW1lIjoiY2thLTEyMDItc2EtdG9rZW4tOXJncDQiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoiY2thLTEyMDItc2EiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiI2NzY0ZTkwYy1jYjI4LTRkZTEtOTEwOS02ZTNkNTY5NDFmY2IiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6Y2thOmNrYS0xMjAyLXNhIn0.qWjrTq7DmVSSMS3Hxc4tlWx87T4koRCoVi125sesVEbvAKDi2z0Xo62Z703khmCWlY55NLOaeJKkZYxX9fLLGX2zOUeEw1omJfFFiNn54lc9HQN9Q_5fN4ra-V4VRiNnBATyn7c76hi66K5iHyZ0xlTMrpMA8W7YvNbgSZH9xghWRzzdHIJaauQpScLmJNL6lF4gydoWwGCC-PSEctjJNDm0_3I6hRHDfBswy6wKxTlxOyHtOryG4rE3g5jQfNu_A57S5Yhra0YS4zc4_DoupfP-sV57GAPKRq86lDge8z8qaHh4roI7E3Il-CEOGKRIxNvIfU_wthtk0oyinGGl2w[root@liabio ~]# +``` + +把解码后的信息添加到将添加到`~/.kube/config`中,注意到下面加了`name为coderaction的context和name为coderaction的user` + +```yaml +apiVersion: v1 +clusters: +- cluster: + certificate-authority-data: LS0tLS1CRUdJTiBDLQo= + server: https://10.0.0.0:6443 + name: kubernetes +contexts: +- context: + cluster: kubernetes + user: coderaction + name: coderaction +- context: + cluster: kubernetes + user: kubernetes-admin + name: kubernetes-admin@kubernetes +current-context: kubernetes-admin@kubernetes +kind: Config +preferences: {} +users: +- name: coderaction + user: + token: eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJja2EiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlY3JldC5uYW1lIjoiY2thLTEyMDItc2EtdG9rZW4tOXJncDQiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoiY2thLTEyMDItc2EiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiI2NzY0ZTkwYy1jYjI4LTRkZTEtOTEwOS02ZTNkNTY5NDFmY2IiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6Y2thOmNrYS0xMjAyLXNhIn0.qWjrTq7DmVSSMS3Hxc4tlWx87T4koRCoVi125sesVEbvAKDi2z0Xo62Z703khmCWlY55NLOaeJKkZYxX9fLLGX2zOUeEw1omJfFFiNn54lc9HQN9Q_5fN4ra-V4VRiNnBATyn7c76hi66K5iHyZ0xlTMrpMA8W7YvNbgSZH9xghWRzzdHIJaauQpScLmJNL6lF4gydoWwGCC-PSEctjJNDm0_3I6hRHDfBswy6wKxTlxOyHtOryG4rE3g5jQfNu_A57S5Yhra0YS4zc4_DoupfP-sV57GAPKRq86lDge8z8qaHh4roI7E3Il-CEOGKRIxNvIfU_wthtk0oyinGGl2w +- name: kubernetes-admin + user: + client-certificate-data: LS0tLS1CRUdJTiB1M1Y2NDTnpPUT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo= + client-key-data: LS0tLS1CBS0NBUUVBdjNpTkx5eUEwaVdmOU1hUjA3cVFTOEtFWS0tLS0tCg== +``` + +通过切换到coderaction这个`use-context`可以发现,get默认分区下的Pod时提示`system:serviceaccount:cka:cka-1202-sa`没有权限,但可以正常获取cka namespace下的Pods + +```sh +[root@liabio cka]# kubectl config use-context kubernetes-admin@kubernetes +Switched to context "kubernetes-admin@kubernetes". +[root@liabio cka]# kubectl get pod +NAME READY STATUS RESTARTS AGE +cka-1128-01-7b8b8cb79-mll6d 1/1 Running 118 32h +[root@liabio cka]# +[root@liabio cka]# +[root@liabio cka]# kubectl get node +NAME STATUS ROLES AGE VERSION +liabio Ready master 141d v1.15.2 +[root@liabio cka]# kubectl config use-context coderaction +Switched to context "coderaction". +[root@liabio cka]# kubectl get pod +Error from server (Forbidden): pods is forbidden: User "system:serviceaccount:cka:cka-1202-sa" cannot list resource "pods" in API group "" in the namespace "default" +[root@liabio cka]# kubectl get pod -n cka +No resources found. +``` + +## 解析 + +k8s对于访问 API 来说提供了两个步骤的安全措施:认证和授权。认证解决用户是谁的问题,授权解决用户能做什么的问题。通过合理的权限管理,能够保证系统的安全可靠。 + +k8s集群的所有操作基本上都是通过kube-apiserver这个组件进行的,它提供HTTP RESTful形式的API供集群内外客户端调用。需要注意的是:认证授权过程只存在HTTPS形式的API中。也就是说,如果客户端使用HTTP连接到kube-apiserver,那么是不会进行认证授权的。所以说,可以这么设置,在集群内部组件间通信使用HTTP,集群外部就使用HTTPS,这样既增加了安全性,也不至于太复杂。 + +本题主要是考察授权:基于角色的访问控制(RBAC)的考题。 + +**RBAC官方文档:** +https://kubernetes.io/docs/reference/access-authn-authz/rbac/ + +**创建RoleBinding 、Role、Service Account官网命令指导:** +https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands#-em-rolebinding-em- + +**使用 kubeconfig 文件组织集群访问:** +https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/ + +**context相关操作官方命令指南:** +https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands#config + +基于角色的访问控制(RBAC)是一种基于企业内各个用户的角色来调节对计算机或网络资源的访问的方法。 + +RBAC使用`rbac.authorization.k8s.io` API组 驱动授权决策,使管理员可以通过Kubernetes API动态配置策略。 + +从1.8开始,RBAC模式是稳定的,并由rbac.authorization.k8s.io/v1 API提供支持。 + +要启用RBAC,请通过启动`apiserver --authorization-mode=RBAC` + +RBAC API声明了四个顶级类型: + +## Role和ClusterRole + +在RBAC API中,Role包含代表一组权限的规则。权限纯粹是累加的(没有“拒绝”规则)。可以在namespace中用Role或在集群范围内用ClusterRole。 + +Role只能用于授予对单个名称空间内资源的访问权限。 + +ClusterRole由于它们是集群范围的,因此它们还可以用于授予以下权限: + +- 集群范围内的资源(如节点) +- 非资源端点(例如“ /healthz”) +- 所有namespace中的命名空间资源(例如pod) + +## RoleBinding和ClusterRoleBinding + +`RoleBinding`向一个或一组用户授予在`Role`中定义的权限。它包含`subjects`(User,Group或Service Account),以及对所授予角色的引用。可以在namespace中使用RoleBinding或在集群范围内使用ClusterRoleBinding。 + +RoleBinding可以引用同一namespace下的Role。 + +roleRef是实际创建绑定的方式。该kind可以是Role或ClusterRole,并且name将引用具体名字的Role或ClusterRole + +ClusterRoleBinding可以在集群级别和所有namespace中授予权限。 + +### 创建Role命令: + +```sh +kubectl create role NAME --verb=verb --resource=resource.group/subresource [--resource-name=resourcename] [--dry-run] +``` + +--verb指定,对资源的操作动作集合,包括`get、delete、update、create、patch、watch、list`,所有操作动作为`*` +--resource指定可操作资源类型集合; +--resource-name指定可操作资源名称集合; +如: + +```yaml +[root@liabio ~]# kubectl create role pod-reader-cka -n cka --verb=get --verb=list --resource=pods --resource-name=readablepod --resource-name=anotherpod -oyaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + creationTimestamp: "2019-12-03T03:50:34Z" + name: pod-reader-cka + namespace: cka + resourceVersion: "15179947" + selfLink: /apis/rbac.authorization.k8s.io/v1/namespaces/cka/roles/pod-reader-cka + uid: 16742721-4890-43de-9725-d6c721c6e4cf +rules: +- apiGroups: + - "" + resourceNames: + - readablepod + - anotherpod + resources: + - pods + verbs: + - get + - list +``` + +### 创建RoleBinding + +```sh +kubectl create rolebinding NAME --clusterrole=NAME|--role=NAME [--user=username] [--group=groupname] [--serviceaccount=namespace:serviceaccountname] [--dry-run] +``` + +--role指定RoleBinding的roleRef中的Role名称; +--clusterrole指定RoleBinding的roleRef中的ClusterRole名称; +--serviceaccount指定RoleBinding的subjects集合; +--user指定RoleBinding的subjects下User的名称; +如: + +```yaml +[root@liabio ~]# kubectl create rolebinding admin-cka -n cka --clusterrole=admin --user=user1 --user=user2 --group=group1 -oyaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + creationTimestamp: "2019-12-03T03:47:55Z" + name: admin-cka + namespace: cka + resourceVersion: "15179732" + selfLink: /apis/rbac.authorization.k8s.io/v1/namespaces/cka/rolebindings/admin-cka + uid: 4d4eacfb-3ba0-4fa1-96c3-c624fbafb12c +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: admin +subjects: +- apiGroup: rbac.authorization.k8s.io + kind: User + name: user1 +- apiGroup: rbac.authorization.k8s.io + kind: User + name: user2 +- apiGroup: rbac.authorization.k8s.io + kind: Group + name: group1 +``` + +### 创建ServiceAccount + +```sh +kubectl create serviceaccount NAME [--dry-run] +``` + +如: + +```yaml +[root@liabio cka]# kubectl create serviceaccount cka-1202-sa -n cka -o yaml +apiVersion: v1 +kind: ServiceAccount +metadata: + creationTimestamp: "2019-12-02T23:37:42Z" + name: cka-1202-sa + namespace: cka + resourceVersion: "15159020" + selfLink: /api/v1/namespaces/cka/serviceaccounts/cka-1202-sa + uid: 6764e90c-cb28-4de1-9109-6e3d56941fcb +``` + + + + + + + +> CKA 考试每日一题系列,全部内容由 [我的小碗汤](https://mp.weixin.qq.com/s/5tYgb_eSzHz_TMsi0U32gw) 创作,本站仅做转载 + + +