Kubernetes JSONpath Support

JSONPath模板是由{}大括号括起来的JSONPath表达式组成。除了原始的JSONPath语法之外,我们还添加了三个函数:

  • 可选的$操作符,因为表达式总是默认从根对象开始。
  • 用""双引号来引用JSONPath表达式中的文本
  • 使用range操作符来迭代List。

result对象被打印成String()函数。

输出结果:

{
  "kind": "List",
  "items":[
    {
      "kind":"None",
      "metadata":{"name":"127.0.0.1"},
      "status":{
        "capacity":{"cpu":"4"},
        "addresses":[{"type": "LegacyHostIP", "address":"127.0.0.1"}]
      }
    },
    {
      "kind":"None",
      "metadata":{"name":"127.0.0.2"},
      "status":{
        "capacity":{"cpu":"8"},
        "addresses":[
          {"type": "LegacyHostIP", "address":"127.0.0.2"},
          {"type": "another", "address":"127.0.0.3"}
        ]
      }
    }
  ],
  "users":[
    {
      "name": "myself",
      "user": {}
    },
    {
      "name": "e2e",
      "user": {"username": "admin", "password": "secret"}
    }
  ]
}
Function Description Example Result
text the plain text kind is {.kind} kind is List
@ the current object {@} the same as input
. or [] child operator {.kind} or {[‘kind’]} List
.. recursive descent {..name} 127.0.0.1 127.0.0.2 myself e2e
* wildcard. Get all objects {.items[*].metadata.name} [127.0.0.1 127.0.0.2]
[start:end :step] subscript operator {.users[0].name} myself
[,] union operator {.items[*][‘metadata.name’, ‘status.capacity’]} 127.0.0.1 127.0.0.2 map[cpu:4] map[cpu:8]
?() filter {.users[?(@.name==”e2e”)].user.password} secret
range, end iterate list {range .items[*]}[{.metadata.name}, {.status.capacity}] {end} [127.0.0.1, map[cpu:4]] [127.0.0.2, map[cpu:8]]
”” quote interpreted string {range .items[*]}{.metadata.name}{“\t”}{end} 127.0.0.1 127.0.0.2

 

K8S中文社区微信公众号

Kubernetes kubectl 概述

kubectl用于运行Kubernetes集群命令的管理工具。本文概述涵盖了kubectl语法,对命令操作的描述,并列举的常见例子。有关每个命令的详细信息,包括支持的所有flags和子命令,请查阅kubectl命令参考文档。有关安装说明,请参阅安装kubectl

语法

在管理工具界面使用kubectl语法运行如下命令:

kubectl [command] [TYPE] [NAME] [flags]

其中command,TYPE,NAME,和flags都是:* command:指定要在一个或多个资源执行的操作,例如操作create,get,describe,delete。* TYPE:指定资源类型Resource types。Resource types会区分大小写,也可以指定单数,复数或缩写的形式。例如,以下命令将输出相同的结果:

shell $ kubectl get pod pod1 $ kubectl get pods pod1 $ kubectl get po pod1 * NAME:指定Resource的Name。Name区分大小写,如果省略Name,则显示所有资源的详细信息,例如:$ kubectl get pods。

当在多个资源上执行操作时,可以通过type和name 指定每个资源,或者指定一个或多个file:通过type和name指定的资源:如果它们都是相同的type,就可以对资源进行分组TYPE1 name1 name2 name<#>

  • 例:$ kubectl get pod example-pod1 example-pod2 *单独指定多种资源type:TYPE1/name1 TYPE1/name2 TYPE2/name3 TYPE<#>/name<#>
  • 例:$ kubectl get pod/example-pod1 replicationcontroller/example-rc1 *使用一个或多个file来指定资源:-f file1 -f file2 -f file<#> 使用YAML而不是JSON,因为YAML往往更容易掌握也对用户更友好,特别是对于配置文件。
  • 例:$ kubectl get pod -f ./pod.yaml * flags:指定可选flags。例如,你可以使用-s或--server flag来指定Kubernetes API Server的地址和端口。

提示:命令行指定的flags将覆盖默认值和任何相应的环境变量。

如果需要更多相关帮助,只需从终端命令窗口运行 kubectl help

Operations

下表包括了所有kubectl操作简短描述和通用语法:

Operation Syntax Description
annotate kubectl annotate (-f FILENAME | TYPE NAME | TYPE/NAME) KEY_1=VAL_1 ... KEY_N=VAL_N [--overwrite] [--all] [--resource-version=version] [flags] 为一个或多个资源添加注释
api-versions kubectl api-versions [flags] 列出支持的API版本。
apply kubectl apply -f FILENAME [flags] 对文件或stdin的资源进行配置更改。
attach kubectl attach POD -c CONTAINER [-i] [-t] [flags] 连接到一个运行的容器,既可以查看output stream,也可以与容器(stdin)进行交互。
autoscale kubectl autoscale (-f FILENAME | TYPE NAME | TYPE/NAME) [--min=MINPODS] --max=MAXPODS [--cpu-percent=CPU] [flags] 自动扩容/缩容由replication controller管理的一组pod。
cluster-info kubectl cluster-info [flags] 显示有关集群中master和services的终端信息。
config kubectl config SUBCOMMAND [flags] 修改kubeconfig文件。有关详细信息,请参阅各个子命令。
create kubectl create -f FILENAME [flags] 从file或stdin创建一个或多个资源。
delete kubectl delete (-f FILENAME | TYPE [NAME | /NAME | -l label | --all]) [flags] 从file,stdin或指定label 选择器,names,resource选择器或resources中删除resources。
describe kubectl describe (-f FILENAME | TYPE [NAME_PREFIX | /NAME | -l label]) [flags] 显示一个或多个resources的详细状态。
edit kubectl edit (-f FILENAME | TYPE NAME | TYPE/NAME) [flags] 使用默认编辑器编辑和更新服务器上一个或多个定义的资源。
exec kubectl exec POD [-c CONTAINER] [-i] [-t] [flags] [-- COMMAND [args...]] 对pod中的容器执行命令。
explain kubectl explain [--include-extended-apis=true] [--recursive=false] [flags] 获取各种资源的文档。例如pod,node,services等
expose kubectl expose (-f FILENAME | TYPE NAME | TYPE/NAME) [--port=port] [--protocol=TCP|UDP] [--target-port=number-or-name] [--name=name] [----external-ip=external-ip-of-service] [--type=type] [flags] 将 replication controller,service或pod作为一个新的Kubernetes service显示。
get kubectl get (-f FILENAME | TYPE [NAME | /NAME | -l label]) [--watch] [--sort-by=FIELD] [[-o | --output]=OUTPUT_FORMAT] [flags] 列出一个或多个资源。
label kubectl label (-f FILENAME | TYPE NAME | TYPE/NAME) KEY_1=VAL_1 ... KEY_N=VAL_N [--overwrite] [--all] [--resource-version=version] [flags] 添加或更新一个或多个资源的flags。
logs kubectl logs POD [-c CONTAINER] [--follow] [flags] 在pod中打印容器的日志。
patch kubectl patch (-f FILENAME | TYPE NAME | TYPE/NAME) --patch PATCH [flags] 使用strategic merge 补丁程序更新资源的一个或多个字段。
port-forward kubectl port-forward POD [LOCAL_PORT:]REMOTE_PORT [...[LOCAL_PORT_N:]REMOTE_PORT_N] [flags] 将一个或多个本地端口转发到pod。
proxy kubectl proxy [--port=PORT] [--www=static-dir] [--www-prefix=prefix] [--api-prefix=prefix] [flags] 在Kubernetes API服务器运行代理。
replace kubectl replace -f FILENAME 从file或stdin替换资源。
rolling-update kubectl rolling-update OLD_CONTROLLER_NAME ([NEW_CONTROLLER_NAME] --image=NEW_CONTAINER_IMAGE | -f NEW_CONTROLLER_SPEC) [flags] 通过逐步替换指定的replication controller及其pod来执行滚动更新。
run kubectl run NAME --image=image [--env="key=value"] [--port=port] [--replicas=replicas] [--dry-run=bool] [--overrides=inline-json] [flags] 在集群上运行指定的镜像。
scale kubectl scale (-f FILENAME | TYPE NAME | TYPE/NAME) --replicas=COUNT [--resource-version=version] [--current-replicas=count] [flags] 更新指定replication controller的大小。
stop kubectl stop 已弃用:请参阅kubectl delete
version kubectl version [--client] [flags] 显示客户端和服务器上运行的Kubernetes版本。

提示:有关更多命令信息,请参阅kubectl参考文档。

Resource types

下表列出了所有支持的资源类型及其缩写:

Resource type Abbreviated alias
apiservices
certificatesigningrequests csr
clusters
clusterrolebindings
clusterroles
componentstatuses cs
configmaps cm
controllerrevisions
cronjobs
customresourcedefinition crd
daemonsets ds
deployments deploy
endpoints ep
events ev
horizontalpodautoscalers hpa
ingresses ing
jobs
limitranges limits
namespaces ns
networkpolicies netpol
nodes no
persistentvolumeclaims pvc
persistentvolumes pv
poddisruptionbudget pdb
podpreset
pods po
podsecuritypolicies psp
podtemplates
replicasets rs
replicationcontrollers rc
resourcequotas quota
rolebindings
roles
secrets
serviceaccounts sa
services svc
statefulsets
storageclasses

输出选项 Output options

使用以下部分来了解如何格式化或对某些命令的输出进行排序。关于哪些命令支持什么输出选项,请查阅kubectl参考文档。

格式化输出 Formatting output

所有kubectl命令输出的默认格式是可读的纯文本格式。要以特定的格式向终端窗口输出详细信息,可以将-o或-output flags 添加到支持的kubectl命令中。

语法:

kubectl [command] [TYPE] [NAME] -o=<output_format>

根据kubectl操作,支持以下输出格式:

输出格式 描述
-o=custom-columns=<spec> 使用逗号分隔的custom columns列表打印一个表。
-o=custom-columns-file=<filename> 使用文件中的custom columns模板打印表<filename>。
-o=json 输出JSON格式的API对象。
-o=jsonpath=<template> 打印在jsonpath表达式中定义的字段。
-o=jsonpath-file=<filename> 打印由 file中的jsonpath表达式定义的字段<filename>。
-o=name 仅打印资源名称,而不打印其他内容。
-o=wide 以纯文本格式输出任何附加信息。对于pod,包括node名称。
-o=yaml 输出YAML格式的API对象。

例如:

在此示例中,以下命令将单个pod的详细信息作为YAML格式化对象输出:

$ kubectl get pod web-pod-13je7 -o=yaml

注意:有关每个命令支持哪种输出格式的详细信息,请参阅kubectl参考文档。

Custom columns

要定义custom columns并仅将所需的详细信息输出,可以使用该custom-columns选项,选择Inline定义custom columns或使用模板文件定义:-o=custom-columns=<spec>或-o=custom-columns-file=<filename>。

例如

Inline方式:

$ kubectl get pods <pod-name> -o=custom-columns=NAME:.metadata.name,RSRC:.metadata.resourceVersion

模板文件方式:

$ kubectl get pods <pod-name> -o=custom-columns-file=template.txt

其中,template.txt文件包含:

NAME                    RSRC

      metadata.name           metadata.resourceVersion

任何一个命令运行的结果将是:

NAME           RSRC

submit-queue   610995

Sorting list objects

要将对象输出到终端窗口中的排序列表,可以将--sort-by标志添加到kubectl支持的命令中,通过使用--sort-by标志指定任何数字或字符串字段来对对象进行排序,要指定字段,请使用jsonpath表达式。

命令:

kubectl [command] [TYPE] [NAME] --sort-by=<jsonpath_exp>

例如

要打印按名称排序的pod列表,请运行:

$ kubectl get pods --sort-by=.metadata.name

示例:常用操作

使用以下一组示例来帮助你熟悉运行kubectl常用操作:

kubectl create - 从file或stdin中创建资源。

// Create a service using the definition in example-service.yaml.
$ kubectl create -f example-service.yaml

// Create a replication controller using the definition in example-controller.yaml.
$ kubectl create -f example-controller.yaml

// Create the objects that are defined in any .yaml, .yml, or .json file within the <directory> directory.
$ kubectl create -f <directory>

kubectl get 列出一个或多个资源。

// List all pods in plain-text output format.
$ kubectl get pods

// List all pods in plain-text output format and includes additional information (such as node name).
$ kubectl get pods -o wide

// List the replication controller with the specified name in plain-text output format. Tip: You can shorten and replace the 'replicationcontroller' resource type with the alias 'rc'.
$ kubectl get replicationcontroller <rc-name>

// List all replication controllers and services together in plain-text output format.
$ kubectl get rc,services

kubectl describe - 显示一个或多个资源的详细状态。

// Display the details of the node with name <node-name>.
$ kubectl describe nodes <node-name>

// Display the details of the pod with name <pod-name>.
$ kubectl describe pods/<pod-name>

// Display the details of all the pods that are managed by the replication controller named <rc-name>.
// Remember: Any pods that are created by the replication controller get prefixed with the name of the replication controller.
$ kubectl describe pods <rc-name>

kubectl delete - 从file、stdin或指定label选择器,names,resource选择器或resources中删除resources资源。

// Delete a pod using the type and name specified in the pod.yaml file.
$ kubectl delete -f pod.yaml

// Delete all the pods and services that have the label name=<label-name>.
$ kubectl delete pods,services -l name=<label-name>

// Delete all pods.
$ kubectl delete pods --all

kubectl exec - 对pod中的容器执行命令。

// Get output from running 'date' from pod <pod-name>. By default, output is from the first container.
$ kubectl exec <pod-name> date

// Get output from running 'date' in container <container-name> of pod <pod-name>.
$ kubectl exec <pod-name> -c <container-name> date

// Get an interactive TTY and run /bin/bash from pod <pod-name>. By default, output is from the first container.
$ kubectl exec -ti <pod-name> /bin/bash

kubectl logs - 打印pod中的容器的日志。

// Return a snapshot of the logs from pod <pod-name>.
$ kubectl logs <pod-name>

// Start streaming the logs from pod <pod-name>. This is similar to the 'tail -f' Linux command.
$ kubectl logs -f <pod-name>

下一步

开始了解kubectl命令。

 

K8S中文社区微信公众号

Kubernetes 认证

Kubernetes 账户

所有Kubernetes集群有两类用户:由Kubernetes管理的Service Accounts (服务账户)和(Users Accounts) 普通账户。

普通账户是假定被外部或独立服务管理的,由管理员分配keys,用户像使用Keystone或google账号一样,被存储在包含usernames和passwords的list的文件里。

需要注意:在Kubernetes中不能通过API调用将普通用户添加到集群中

相比之下,Service Accounts是由Kubernetes API管理的帐户。它们被绑定到特定的命名空间,并由APIserver自动创建或通过API调用手动创建。Service Accounts与存储为Secrets的一组证书相关联,这些凭据被挂载到pod中,以便集群进程与Kubernetes API通信。

验证策略

Kubernetes用户可以使用client certificates、bearer tokens、authenticating proxy、HTTP basic auth等认证插件来验证API请求。比如HTTP请求到达API Server,插件会尝试将以下属性与请求关联:

  • UserName:普通用户的字符串。比如“kube-admin”或“xxxx@kubernetes.org.cn”。
  • UID:普通用户的字符串,比UserName更具有唯一性。
  • Groups:一组字符串,将常用的user分组的组合字符串。
  • Extra fields:将一些有用的字符串信息映射成的列表。

所有values值对于认证系统都是不透明的,只有当授权解释后才有意义。

可以同时启用多个认证方法。最少使用两种:

  • 为Service Accounts使用service account tokens方法。
  • 使用另外一种用户认证方法。

system:authenticated组被包括在所有已认证用户的组列表中。

X509 客户证书

使用API Server启动时配置–client-ca-file = SOMEFILE选项来启用客户端证书认证。引用的文件必须包含,提交给API Server的客户端证书的证书颁发机构。如果客户端提交的证书通过,通用名称(common name)将被用作请求的用户名。

例如,使用openssl命令管理工具生成证书签名请求:

openssl req -new -key jbeda.pem -out jbeda-csr.pem -subj "/CN=jbeda/O=app1/O=app2"

将为“jbeda”用户名创建一个CSR,所属组为”app1”和“app2”的签名请求。

Static Token File

启动静态Token文件需要API Server启动时配置- -token-auth-file=SOMEFILE选项时,目前,tokens状态可以持续存在,需要重新启用 API server,token last 才会重启。

token文件是至少包含3列的csv格式文件: token, user name, user uid,第四列为可选group 名项。注意:如果有多个group名,列必须用””双引号包含其中,例如

token,user,uid,"group1,group2,group3"

Putting a Bearer Token in a Request

当http客户端使用 bearer token 认证时,API Server需要一个值为Bearer THETOKEN的授权头。bearer token必须可以放在HTTP请求头中且值不需要转码和引用的一个字符串。例如:bearer token :31ada4fd-adec-460c-809a-9e56ceb75269,会在HTTP header中按下面的方式呈现:

Authorization: Bearer 31ada4fd-adec-460c-809a-9e56ceb75269

Bootstrap Tokens

功能目前为Alpha级别

Kubernetes包括一个dynamically-managed的Bearer token类型,称为Bootstrap Token。这些token作为Secret存储在kube-system namespace中,可以动态管理和创建。Controller Manager包含一个TokenCleaner Controller,如果到期时可以删除Bootstrap Tokens Controller。

Tokens的形式是[a-z0-9]{6}.[a-z0-9]{16}。第一个组件是Token ID,第二个组件是Token Secret。可以在HTTP header中指定Token,如下所示:

Authorization: Bearer 781292.db7bc3a58fc5f07e

如何使用Kubeadm来管理Token,以及想了解更多BootstrapToken文档,请参考Bootstrap Token

Static Password File

Basic Authentication是通过在API Server启动是配置-Basic-authfile=file选项实现,Basic认证凭证一直有效,并且如果没有重新启动API Server,密码将无法更改。

Basic Authentication文件csv也是格式文件,且必须包含:password, user, uid。在Kubernetes 1.6+版本中,可以指定一个可选的第四列,使用逗号来分隔group名,如果有多个组,必须使用双引号(“)。参考以下示例:

password,user,uid,"group1,group2,group3"

当从http客户端使用Basic Authentication时,API Server需要在请求头加入Basic BASE64ENCODED(USER:PASSWORD)

OpenID Connect Tokens

OpenID Connect 是由一些云提供商支持的OAuth2认证机制,特别是Azure Active Directory,Salesforce和Google。OAuth2协议的主要扩展是增加一个额外字段,返回ID Token的access token。这个token被服务器签名的JSON Web Token (JWT) ,常见的字段如user’s email。

为了鉴定user,认证器使用OAuth2 token响应的id_token 步骤如下:

Kubernetes OpenID Connect Flow

  1. 登录identity provider
  2. identity provider提供一个access_token,id_token和refresh_token
  3. 在使用kubectl时,使用id_token的—token flag或者直接添加到kubeconfig
  4. kubectl 在header通过Authorization字段将id_token发送到 API server
  5. API Server检查配置中证书来确保JWT签名的有效性
  6. 检查id_token是否过期
  7. 确保user被授权
  8. 当被授权API Server会返回对kubectl响应
  9. kubectl向user提供反馈

由于所有认证需要的数据在id_token中,所以Kubernetes不需要向身份提供者“phone home”,每个请求都是在无状态的模型中,它为认证提供可扩展的解决方案。 也带来了一些挑战:

  1. Kubernetes没有“web interface”来触发认证过程,没有任何浏览器或接口来收集凭据,这就是为什么需要首先向身份提供者进行认证的原因。
  2. id_token不能被撤销,它像一个certificate持续时间非常短(只有几分钟),所以每隔几分钟就得到一个新的token。
  3. 如果不使用kubectl -proxy命令或注入id_token的反向代理,将无法向Kubernetes dashboard 进行认证。

Configuring the API Server

启用插件,请在API Server上配置如下的选项:

Parameter Description Example Required
- -oidc-issuer-url URL of the provider which allows the API server to discover public signing keys. Only URLs which use the https:// scheme are accepted. This is typically the provider’s discovery URL without a path, for example “https://accounts.google.com” or “https://login.salesforce.com”. This URL should point to the level below .well-known/openid-configuration If the discovery URL is https://accounts.google.com/.well-known/openid-configuration the value should be https://accounts.google.com
- -oidc-client-id A client id that all tokens must be issued for. kubernetes
- -oidc-username-claim WT claim to use as the user name. By default sub, which is expected to be a unique identifier of the end user. Admins can choose other claims, such as email or name, depending on their provider. However, claims other than email will be prefixed with the issuer URL to prevent naming clashes with other plugins. sub
- -oidc-groups-claim JWT claim to use as the user’s group. If the claim is present it must be an array of strings. groups
- -oidc-ca-file The path to the certificate for the CA that signed your identity provider’s web certificate. Defaults to the host’s root CAs. /etc/kubernetes/ssl/kc-ca.pem

如果--oidc-username-claim选择除Email以外的声明,该值将以--oidc-issuer-url为前缀,以防止与现有Kubernetes名称(例如system:users)的冲突。 例如,如果提供商URL是https://accounts.google.com,username声明映射到jane,该插件对user进行认证为:

https://accounts.google.com#jane

Kubernetes不提供OpenID Connect Identity Provider。可以使用现有公开的OpenID Connect  Identity Provider(如Google或其他)。或者可以使用者些CoreOS dexKeycloak,CloudFoundry UAA或Tremolo Security的OpenUnison

For an identity provider to work with Kubernetes it must

  1. 支持OpenID connect discovery;(not all do)
  2. 在TLS中确保密码有效
  3. 一个CA签名的证书(商业或个人的)

其他安装设置说明:

使用kubectl

选项1-OIDC AUTHENTICATOR

第一个选择使用oidc authenticator。这个认证需要使用id_token,refresh_token和OIDC client_secret,并会自动更新你的token令牌。

kubectl config set-credentials USER_NAME \
   --auth-provider=oidc \
   --auth-provider-arg=idp-issuer-url=( issuer url ) \
   --auth-provider-arg=client-id=( your client id ) \
   --auth-provider-arg=client-secret=( your client secret ) \
   --auth-provider-arg=refresh-token=( your refresh token ) \
   --auth-provider-arg=idp-certificate-authority=( path to your ca certificate ) \
   --auth-provider-arg=id-token=( your id_token ) \
   --auth-provider-arg=extra-scopes=( comma separated list of scopes to add to "openid email profile", optional )

例如,在对身份提供商进行认证之后,运行下面的命令:

kubectl config set-credentials mmosley  \
        --auth-provider=oidc  \
        --auth-provider-arg=idp-issuer-url=https://oidcidp.tremolo.lan:8443/auth/idp/OidcIdP  \
        --auth-provider-arg=client-id=kubernetes  \
        --auth-provider-arg=client-secret=1db158f6-177d-4d9c-8a8b-d36869918ec5  \
        --auth-provider-arg=refresh-token=q1bKLFOyUiosTfawzA93TzZIDzH2TNa2SMm0zEiPKTUwME6BkEo6Sql5yUWVBSWpKUGphaWpxSVAfekBOZbBhaEW+VlFUeVRGcluyVF5JT4+haZmPsluFoFu5XkpXk5BXqHega4GAXlF+ma+vmYpFcHe5eZR+slBFpZKtQA= \
        --auth-provider-arg=idp-certificate-authority=/root/ca.pem \
        --auth-provider-arg=extra-scopes=groups \
        --auth-provider-arg=id-token=eyJraWQiOiJDTj1vaWRjaWRwLnRyZW1vbG8ubGFuLCBPVT1EZW1vLCBPPVRybWVvbG8gU2VjdXJpdHksIEw9QXJsaW5ndG9uLCBTVD1WaXJnaW5pYSwgQz1VUy1DTj1rdWJlLWNhLTEyMDIxNDc5MjEwMzYwNzMyMTUyIiwiYWxnIjoiUlMyNTYifQ.eyJpc3MiOiJodHRwczovL29pZGNpZHAudHJlbW9sby5sYW46ODQ0My9hdXRoL2lkcC9PaWRjSWRQIiwiYXVkIjoia3ViZXJuZXRlcyIsImV4cCI6MTQ4MzU0OTUxMSwianRpIjoiMm96US15TXdFcHV4WDlHZUhQdy1hZyIsImlhdCI6MTQ4MzU0OTQ1MSwibmJmIjoxNDgzNTQ5MzMxLCJzdWIiOiI0YWViMzdiYS1iNjQ1LTQ4ZmQtYWIzMC0xYTAxZWU0MWUyMTgifQ.w6p4J_6qQ1HzTG9nrEOrubxIMb9K5hzcMPxc9IxPx2K4xO9l-oFiUw93daH3m5pluP6K7eOE6txBuRVfEcpJSwlelsOsW8gb8VJcnzMS9EnZpeA0tW_p-mnkFc3VcfyXuhe5R3G7aa5d8uHv70yJ9Y3-UhjiN9EhpMdfPAoEB9fYKKkJRzF7utTTIPGrSaSU6d2pcpfYKaxIwePzEkT4DfcQthoZdy9ucNvvLoi1DIC-UocFD8HLs8LYKEqSxQvOcvnThbObJ9af71EwmuE21fO5KzMW20KtAeget1gnldOosPtz1G5EwvaQ401-RPQzPGMVBld0_zMCAwZttJ4knw

将产生如下配置:

users:
- name: mmosley
  user:
    auth-provider:
      config:
        client-id: kubernetes
        client-secret: 1db158f6-177d-4d9c-8a8b-d36869918ec5
        extra-scopes: groups
        id-token: eyJraWQiOiJDTj1vaWRjaWRwLnRyZW1vbG8ubGFuLCBPVT1EZW1vLCBPPVRybWVvbG8gU2VjdXJpdHksIEw9QXJsaW5ndG9uLCBTVD1WaXJnaW5pYSwgQz1VUy1DTj1rdWJlLWNhLTEyMDIxNDc5MjEwMzYwNzMyMTUyIiwiYWxnIjoiUlMyNTYifQ.eyJpc3MiOiJodHRwczovL29pZGNpZHAudHJlbW9sby5sYW46ODQ0My9hdXRoL2lkcC9PaWRjSWRQIiwiYXVkIjoia3ViZXJuZXRlcyIsImV4cCI6MTQ4MzU0OTUxMSwianRpIjoiMm96US15TXdFcHV4WDlHZUhQdy1hZyIsImlhdCI6MTQ4MzU0OTQ1MSwibmJmIjoxNDgzNTQ5MzMxLCJzdWIiOiI0YWViMzdiYS1iNjQ1LTQ4ZmQtYWIzMC0xYTAxZWU0MWUyMTgifQ.w6p4J_6qQ1HzTG9nrEOrubxIMb9K5hzcMPxc9IxPx2K4xO9l-oFiUw93daH3m5pluP6K7eOE6txBuRVfEcpJSwlelsOsW8gb8VJcnzMS9EnZpeA0tW_p-mnkFc3VcfyXuhe5R3G7aa5d8uHv70yJ9Y3-UhjiN9EhpMdfPAoEB9fYKKkJRzF7utTTIPGrSaSU6d2pcpfYKaxIwePzEkT4DfcQthoZdy9ucNvvLoi1DIC-UocFD8HLs8LYKEqSxQvOcvnThbObJ9af71EwmuE21fO5KzMW20KtAeget1gnldOosPtz1G5EwvaQ401-RPQzPGMVBld0_zMCAwZttJ4knw
        idp-certificate-authority: /root/ca.pem
        idp-issuer-url: https://oidcidp.tremolo.lan:8443/auth/idp/OidcIdP
        refresh-token: q1bKLFOyUiosTfawzA93TzZIDzH2TNa2SMm0zEiPKTUwME6BkEo6Sql5yUWVBSWpKUGphaWpxSVAfekBOZbBhaEW+VlFUeVRGcluyVF5JT4+haZmPsluFoFu5XkpXk5BXq
      name: oidc

如果id_token过期,kubectl将尝试使用refresh_token和client_secret来刷新id_token,在kube/.config中存储refresh_token和id_token新的值。

选项 2 - USE THE --TOKEN OPTION

kubectl命令允许你使用--token选项传入一个token。只需将idtoken粘贴到这个选项中:

kubectl --token=eyJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJodHRwczovL21sYi50cmVtb2xvLmxhbjo4MDQzL2F1dGgvaWRwL29pZGMiLCJhdWQiOiJrdWJlcm5ldGVzIiwiZXhwIjoxNDc0NTk2NjY5LCJqdGkiOiI2RDUzNXoxUEpFNjJOR3QxaWVyYm9RIiwiaWF0IjoxNDc0NTk2MzY5LCJuYmYiOjE0NzQ1OTYyNDksInN1YiI6Im13aW5kdSIsInVzZXJfcm9sZSI6WyJ1c2VycyIsIm5ldy1uYW1lc3BhY2Utdmlld2VyIl0sImVtYWlsIjoibXdpbmR1QG5vbW9yZWplZGkuY29tIn0.f2As579n9VNoaKzoF-dOQGmXkFKf1FMyNV0-va_B63jn-_n9LGSCca_6IVMP8pO-Zb4KvRqGyTP0r3HkHxYy5c81AnIh8ijarruczl-TK_yF5akjSTHFZD-0gRzlevBDiH8Q79NAr-ky0P4iIXS8lY9Vnjch5MF74Zx0c3alKJHJUnnpjIACByfF2SCaYzbWFMUNat-K1PaUk5-ujMBG7yYnr95xD-63n8CO8teGUAAEMx6zRjzfhnhbzX-ajwZLGwGUBT4WqjMs70-6a7_8gZmLZb2az1cZynkFRj2BaCkVT3A2RrjeEwZEtGXlMqKJ1_I2ulrOVsYx01_yD35-rw get nodes

Webhook Token Authentication

Webhook authentication is a hook for verifying bearer tokens

  • - -authentication-token-webhook-config-file 配置文件描述了如何访问远程webhook服务
  • - -authentication-token-webhook-cache-ttl 缓存认证时间。默认2分钟

配置文件使用kubeconfig file format。在文件中,“users”指的是API服务器的webhook,“clusters”指的是远程服务。示例如下:

# clusters refers to the remote service.
clusters:
  - name: name-of-remote-authn-service
    cluster:
      certificate-authority: /path/to/ca.pem         # CA for verifying the remote service.
      server: https://authn.example.com/authenticate # URL of remote service to query. Must use 'https'.

# users refers to the API server's webhook configuration.
users:
  - name: name-of-api-server
    user:
      client-certificate: /path/to/cert.pem # cert for the webhook plugin to use
      client-key: /path/to/key.pem          # key matching the cert

# kubeconfig files require a context. Provide one for the API server.
current-context: webhook
contexts:
- context:
    cluster: name-of-remote-authn-service
    user: name-of-api-sever
  name: webhook

当客户端使用如上所述的bearer token与API服务器进行认证时,认证webhook通过一个包含token的review 对象来查询远程服务。Kubernetes不会对缺少这样的头的请求提出质疑。( Kubernetes will not challenge a request that lacks such a header.)??

注意 webhook API对象与其他Kubernetes API对象一样受版本兼容性规则的约束,选择需谨慎。

请求主体采用的格式:

{
  "apiVersion": "authentication.k8s.io/v1beta1",
  "kind": "TokenReview",
  "spec": {
    "token": "(BEARERTOKEN)"
  }
}

远程服务预计将填写请求的TokenAccessReviewStatus字段,以示登录成功。 响应主体体的“spec”字段被忽略。 bearer token认证成功将返回:

{
  "apiVersion": "authentication.k8s.io/v1beta1",
  "kind": "TokenReview",
  "status": {
    "authenticated": true,
    "user": {
      "username": "janedoe@example.com",
      "uid": "42",
      "groups": [
        "developers",
        "qa"
      ],
      "extra": {
        "extrafield1": [
          "extravalue1",
          "extravalue2"
        ]
      }
    }
  }
}

不成功的请求将返回:

{
  "apiVersion": "authentication.k8s.io/v1beta1",
  "kind": "TokenReview",
  "status": {
    "authenticated": false
  }
}

HTTP status codes can be used to supply additional error context

Authenticating Proxy

API服务器可以根据header values配置来识别users ,如X-Remote-User。

  • –requestheader-username-headers 必选,不区分大小写。按顺序检查Header names用于识别用户身份,第一包含Value的Header用于username。
  • –requestheader-group-headers 1.6+以上,可选,不区分大小写。 建议使用“X-Remote-Group”。按顺序检查Header Names用于识别user’s groups。Header中指定的所有Value均用作Group Names。
  • –requestheader-extra-headers-prefix 1.6+以上,可选,不区分大小写。 建议使用“X-Remote-Extra-”。用于查找关于用户的额外信息(通常由配置的授权插件使用)。

例如,使用此配置:

--requestheader-username-headers=X-Remote-User--requestheader-group-headers=X-Remote-Group--requestheader-extra-headers-prefix=X-Remote-Extra-

请求:

GET / HTTP/1.1X-Remote-User: fidoX-Remote-Group: dogsX-Remote-Group: dachshundsX-Remote-Extra-Scopes: openidX-Remote-Extra-Scopes: profile

将会产生的用户信息:

name: fidogroups:- dogs- dachshundsextra:  scopes:  - openid  - profile

为了防止header欺骗,Authenticating Proxy需要在检查请求header之前,向API服务器提交有效的客户端证书,以针对指定的CA进行验证。

–requestheader-client-ca-file  必选, PEM-encoded的证书包。在为用户名检查请求header之前,必须根据指定文件中的证书颁发机构呈现和验证有效的客户端证书。

–requestheader-allowed-names 可选,(common names)通用名称(cn)List。如果设置,则在检查请求header用户名之前,必须提交List中指定(common names)通用名中有效的客户端证书。

Keystone Password

Keystone认证通过--experimental-keystone-url=<AuthURL> 在启动期间将选项传递给API服务器来启用。该插件已实现,plugin/pkg/auth/authenticator/password/keystone/keystone.go目前使用basic auth来验证用户名和密码。

如果为Keystone服务器配置了自签名证书,则需要--experimental-keystone-ca-file=SOMEFILE在启动Kubernetes API服务器时设置该选项。设置完成后Keystone服务器的证书将由其中一个authorities进行验证 experimental-keystone-ca-file。否则将由主机的根证书颁发机构验证。

有关如何使用keystone管理项目和users的详细信息,请参阅 Keystone文档。需要注意此插件目前处于测试开发阶段。

更多详细信息,请参阅 discussionblueprintproposed changes

K8S中文社区微信公众号

Kubernetes API 概述

REST API是Kubernetes系统的重要部分,组件之间的所有操作和通信均由API Server处理的REST API调用,大多数情况下,API定义和实现都符合标准的HTTP REST格式,可以通过 kubectl命令管理工具或其他命令行工具来执行。

API 版本

为了在兼容旧版本的同时不断升级新的API,Kubernetes支持多种API版本,每种API版本都有不同的API路径,例如/api/v1或 /apis/extensions/v1beta1

API版本规则是通过基于API level选择版本,而不是基于资源和域级别选择,是为了确保API能够描述一个清晰的连续的系统资源和行为的视图,能够控制访问的整个过程和控制实验性API的访问。

  • JSON和Protobuf序列化模式遵循相同的模式变化原则,以下所有描述都涵盖了这两种模式。

需要注意,API版本和软件的版本没有直接关系,不同API版本有不同程度稳定性,API文档中详细描述了每个级别的标准。

  • Alpha级别:

  • 包含alpha名称的版本(例如v1alpha1)。
  • 该软件可能包含错误。启用一个功能可能会导致bug。默认情况下,功能可能会被禁用。
  • 随时可能会丢弃对该功能的支持,恕不另行通知。
  • API可能在以后的软件版本中以不兼容的方式更改,恕不另行通知。
  • 该软件建议仅在短期测试集群中使用,因为错误的风险增加和缺乏长期支持。
  • Beta级别:

  • 包含beta名称的版本(例如v2beta3)。
  • 该软件经过很好的测试。启用功能被认为是安全的。默认情况下功能是开启的。
  • 细节可能会改变,但功能在后续版本不会被删除
  • 对象的模式或语义在随后的beta版本或Stable版本中可能以不兼容的方式发生变化。如果这种情况发生时,官方会提供迁移操作指南。这可能需要删除、编辑和重新创建API对象。
  • 该版本在后续可能会更改一些不兼容地方,所以建议用于非关键业务,如果你有多个可以独立升级的集群,你也可以放宽此限制。
  • 大家使用过的Beta版本后,可以多给社区反馈,如果此版本在后续更新后将不会有太大变化。
  • Stable级别:

  • 该版本名称命名方式:vX这里X是一个整数。
  • Stable版本的功能特性,将出现在后续发布的软件版本中。

API groups

API groups使得Kubernetes API的扩展更加方便。API groups是在REST路径和序列化对象的apiVersion字段中被指定。

目前,有几个API groups在使用:

  • 核心(also called legacy)组,REST路径在/api/v1,但此路径不是固定的,v1是当前的版本。与之相对应的代码里面的apiVersion字段的值为v1。
  • Named Groups,REST路径被指定在/apis/$GROUP_NAME/$VERSION中,并使用apiVersion: $GROUP_NAME/$VERSION(例如apiVersion: batch/v1)。在Kubernetes API参考引用中可以看到API Groups的完整列表。

使用自定义资源扩展API的两种方法:

  1. CustomResourceDefinition为有基本CRUD需求用户提供。
  2. 即将推出:需要有完整的Kubernetes API语义的用户,可以实现自定义的api server,并使用聚合器来无缝连接客户端。

启用API Groups

可以使用--runtime-config 在api server上设置来启用或禁用某些资源和API Groups。--runtime-config可以使用逗号分隔值。例如,要禁用batch / v1,set --runtime-config=batch/v1=false, to enable batch/v2alpha1, set --runtime-config=batch/v2alpha1。该标签接受逗号分隔的一组key = value对,描述了运行时的api server配置。

提示:启用和禁用Groups或资源需要重新启动apiserver和controller-manager确保--runtime-config更改生效。

启用组中的资源

DaemonSets,Deployments,Horizo​​ntalPodAutoscalers,Ingress,Jobs和ReplicaSets,都是默认启用的。可以通过--runtime-config在api server上设置来启用其他扩展资源。--runtime-config接受逗号来分隔值。例如,要禁用deployments和 jobs,请设置 --runtime-config=extensions/v1beta1/deployments=false,extensions/v1beta1/jobs=false

K8S中文社区微信公众号

Kubernetes客户端库

本章将描述各种编程语言类型的Kubernetes API客户端库。

要使用Kubernetes REST API编写应用程序,你不需要自己编写API来调用、请求/响应等类型,可以直接使用现成的客户端库来实现。

客户端库经常是处理一些常见的任务,例如进行身份验证。

官方支持的Kubernetes客户端库

以下客户端库由Kubernetes SIG API Machinery维护。

Language Client Library Sample Programs
Go github.com/kubernetes/client-go/ browse
Python github.com/kubernetes-incubator/client-python/ browse

社区维护的客户端库

以下Kubernetes API客户端库由社区创建者维护,Kubernetes团队不会提供支持和维护。

Language Client Library
Clojure github.com/yanatan16/clj-kubernetes-api
Go github.com/ericchiang/k8s
Java (OSGi) bitbucket.org/amdatulabs/amdatu-kubernetes
Java (Fabric8, OSGi) github.com/fabric8io/kubernetes-client
Node.js github.com/tenxcloud/node-kubernetes-client
Node.js github.com/godaddy/kubernetes-client
Perl metacpan.org/pod/Net::Kubernetes
PHP github.com/devstub/kubernetes-api-php-client
PHP github.com/maclof/kubernetes-client
Python github.com/eldarion-gondor/pykube
Ruby github.com/Ch00k/kuber
Ruby github.com/abonas/kubeclient
Scala github.com/doriordan/skuber
K8S中文社区微信公众号

Kubernetes API 访问控制

可以使用kubectl客户端库方式对REST API的访问,Kubernetes的普通账户和Service帐户都可以实现授权访问API。API的请求会经过多个阶段的访问控制才会被接受处理,其中包含认证、授权以及准入控制(Admission Control)等。如下图所示:

Kubernetes API请求的请求处理步骤图

需要注意:认证授权过程只存在HTTPS形式的API中。也就是说,如果客户端使用HTTP连接到kube-apiserver,是不会进行认证授权的。所以说,可以这么设置,在集群内部组件间通信使用HTTP,集群外部就使用HTTPS,这样既增加了安全性,也不至于太复杂。

认证

开启TLS时,所有的请求首先需要认证。Kubernetes支持多种认证机制,并支持同时开启多个认证插件(只要有一个认证通过即可)。如果认证成功,则用户的username会传入授权模块做进一步授权验证;对于认证失败的请求则返回HTTP 401。

当TLS建立时,HTTP请求会进行身份认证步骤,如图中步骤1,集群管理器将apiserver配置为运行一个或多个认证器模块。

认证模块包含客户端证书,密码、Plain Tokens、Bootstrap Tokens、JWT Tokens(used for service accounts)。

我们可以指定多个认证模块,每个认证模块都会按顺序进行,直到其中一个成功。

(在GCE上,客户端证书、密码、Plain Tokens和JWT Tokens都会启用。)

更多认证模块的使用方法可以参考 认证

授权

认证之后的请求是授权模块。如图中步骤2  。

请求必须包含请求者的用户名,请求的操作以及受该操作影响的对象,如果策略已经声明用户具有完成请求的权限,则该请求将被授权。

例如:设置如下Bob策略,那么会在namespace projectCaribou 中读取pods

{
    "apiVersion": "abac.authorization.kubernetes.io/v1beta1",
    "kind": "Policy",
    "spec": {
        "user": "bob",
        "namespace": "projectCaribou",
        "resource": "pods",
        "readonly": true
    }
}

如果Bob发出以下请求,被允许读取projectCaribou namespace中的对象,请求被授权

{
  "apiVersion": "authorization.k8s.io/v1beta1",
  "kind": "SubjectAccessReview",
  "spec": {
    "resourceAttributes": {
      "namespace": "projectCaribou",
      "verb": "get",
      "group": "unicorn.example.org",
      "resource": "pods"
    }
  }
}
  • 如果Bob向projectCaribou namespace中对象写入(create或update)请求,则会拒绝其授权。
  • 如果Bob请求在不同的namespace中读取(get)对象,比如projectFish,授权也将被拒绝。

Kubernetes授权要求使用公共常见得REST属性与云提供商的访问控制系统进行交互。为了避免访问控制系统与Kubernetes API与外部API的冲突,所以必须使用REST格式。

Kubernetes支持多种授权模块,如ABAC模式RBAC模式和Webhook模式。当管理员创建集群时,他们将会配置在API Server中使用的授权模块。如果配置了多个授权模块,Kubernetes会检查每个模块,当通过其中任何模块授权请求,则授权成功,如果所有模块都拒绝了该请求,则授权失败(HTTP 403)。

了解Kubernetes授权的更多信息,参靠授权概述

准入控制(Admission Control)

准入控制(Admission Control)用来对请求做进一步的验证或添加默认参数,除了授权模块可用的属性外,准入控制模块还可以访问正在创建或更新对象内容。

也可以可以配置多个准入控制器,每个都会按顺序调用。

如图中步骤3。

Kubernetes API请求的请求处理步骤图

与认证和授权模块不同,任何接入控制器模块被遭拒时,请求会立即失败。

当请求通过了所有准入控制(Admission Control),就会使用相应API对象的验证功能,然后写入对象存储(如步骤4所示)

API Server端口和IPs

之前讨论用于发送到API Server安全端口的请求(经典情况)。API Server实际上可以在两个端口上服务:

默认情况下,Kubernetes API Server在2个端口上提供HTTP:

  1. Localhost Port:
     - is intended for testing and bootstrap, and for other components of the master node
       (scheduler, controller-manager) to talk to the API
     - no TLS
     - default is port 8080, change with `--insecure-port` flag.
     - defaults IP is localhost, change with `--insecure-bind-address` flag.
     - request **bypasses** authentication and authorization modules.
     - request handled by admission control module(s).
     - protected by need to have host access
    
  2. Secure Port:
     - use whenever possible
     - uses TLS.  Set cert with `--tls-cert-file` and key with `--tls-private-key-file` flag.
     - default is port 6443, change with `--secure-port` flag.
     - default IP is first non-localhost network interface, change with `--bind-address` flag.
     - request handled by authentication and authorization modules.
     - request handled by admission control module(s).
     - authentication and authorisation modules run.

在Google Compute Engine(GCE)或其他云提供商使用kube-up.sh创建集群时

  • API Server提供 443端口
  • GCE项目配置防火墙
  • 允许API进行外部HTTPS访问
K8S中文社区微信公众号