Kubernetes Cookbook 编程指南 中文版教程
创建时间:2018-12-07  访问量:3665  7  0

Kubernetes Cookbook 编程指南 中文版教程

认证与授权

为了使用更高级的管理,我们可以为Kubernete系统添加许可规则。在我们的集群中,可以生成两种许可规则:一个是机器之间的许可。具有身份认证的节点可以与控制节点联系。例如,只有拥有etcd服务器证书的Master才可以往etcd中存储数据。其它许可都在Kubernetes Master中。用户需要经过授权才可以检查并创建资源。使用应用和授权是一个安全方案,它能阻止你的数据或状态被其它人访问。

开始

在你开始使用一些权限配置你的集群之前,请先安装集群。然而,停止系统中的每个服务。它们稍后将使用认证来启动。

如何去做...

本节,我们将讨论认证和授权。对于认证,etcd和Kubernetes服务器在响应请求之前都需要身份认证。另一方面,授权通过不同的资源访问许可规则限制用户。所有这些关系都是基于API连接的。后面的部人向你展示了如何完成配置并遵循身份认证。

为API调用启用身份认证

Kubernetes系统中有几种方法可以阻非认证的通信。我们将介绍基本认证机制。可以很容易的设置它,不仅仅在Kubernetes Master上,在etcd服务器上也一样。

etcd基本身份认证

首先,让我们尝试向etcd主机上发送API请求。你将发现,黙认任何人都可以访问这些数据:

// Create a key-value pair in etcd
# curl -X PUT -d value="Happy coding" http://localhost:4001/v2/keys/
message
{"action":"set","node":{"key":"/message","value":"Happy coding","modified
Index":4,"createdIndex":4}}
// Check the value you just push
# curl http://localhost:4001/v2/keys/message
{"action":"get","node":{"key":"/message","value":"Happy coding","modified
Index":4,"createdIndex":4}}

// Remove the value
# curl -X DELETE http://localhost:4001/v2/keys/message
{"action":"delete","node":{"key":"/message","modifiedIndex":5,"createdInd
ex":4},"prevNode":{"key":"/message","value":"Happy coding","modifiedIndex
":4,"createdIndex":4}}

没有认证的话,读和写都是被保护的。启用基本的etcd认证的方式是使用RESTful API。过程如下所示:

  • 为admin帐户root添加一个密码

  • 启用基本认证

  • 停止guest帐户的读写许可

保证etcd服务处于运行状态。我们将前面的逻辑转成如下命令:

// Send the API request for setup root account
# curl -X PUT -d "{\"user\":\"root\",\"password\":\"<YOUR_ETCD_PASSWD>\",
\"roles\":[\"root\"]}" http://localhost:4001/v2/auth/users/root
{"user":"root","roles":["root"]}
// Enable authentication
# curl -X PUT http://localhost:4001/v2/auth/enable
// Encode "USERACCOUNT:PASSWORD" string in base64 format, and record in a
value
# AUTHSTR=$(echo -n "root:<YOUR_ETCD_PASSWD>" | base64)
// Remove all permission of guest account. Since we already enable
authentication, use the authenticated root.
# curl -H "Authorization: Basic $AUTHSTR" -X PUT -d "{\"role\":\"guest
\",\"revoke\":{\"kv\":{\"read\":[\"*\"],\"write\":[\"*\"]}}}" http://
localhost:4001/v2/auth/roles/guest
{"role":"guest","permissions":{"kv":{"read":[],"write":[]}}}

现在,对于验证,尝试通过API检查etcd中的任何东西:

# curl http://localhost:4001/v2/keys
{"message":"Insufficient credentials"}

因为我们不为API调用指定任何身份,它就认为这是一个guest的请求。甚至没有查看数据的权限。

对长期的使用,我们将etcd的用户配置放到Kubernetes的配置中。检查Kubernetes API服务器中的配置文件。在RHEL服务器,它就是/etc/kubernetes/apiserver这个文件;或者在其它Linux服务器,仅仅对于服务,是 /etc/init.d/kubernetes-master这个文件。你可以为etcd服务器的调用找一个标记--etcd-servers。基于前面的设置,我们附加的值是一个简单的URL和端口。它可能是 http://ETCD_ELB_URL:80 。添加一个root帐户,并将密码指定为普通文本格式的值,这个为作为HTTP请求的授权请求头。--etcd-servers标记新的值将变成http://root:YOUR_ETCD_PASSWD@ETCD_ELB_URL:80。然后,你的Kubernetes API服务器的守护进程在etcd端点上启用身份认证后也工作得很好。

Kubernetes Master的基本身份认证

我们在Kubernetes Master中设置身证之前,让我们先检查一下Master的端点:

# curl https://K8S_MASTER_HOST_IP:SECURED_PORT --insecure
or
# curl http://K8S_MASTER_ELB_URL:80
{
    "paths": [
        "/api",
        "/api/v1",
        "/apis",
        "/apis/extensions",
        "/apis/extensions/v1beta1",
        "/healthz",
        "/healthz/ping",
        "/logs/",
        "/metrics",
        "/resetMetrics",
        "/swagger-ui/",
        "/swaggerapi/",
        "/ui/",
        "/version"
    ]
}

我们不想让前面的信息暴露给每一个人,是不是?与etcd主机类似,Kubernetes Master可以使用基本认证作为安全机制。本节,我们将限制API服务器的许可。然而,不同于etcd,认证的信息是定义在一个文件中的:

// Create a file for basic authentication with content:
PASSWORD,USERNAME,UID
# cat /root/k8s-bafile
<APISERVER_BA_PASSWORD>,<APISERVER_BA_USERACCOUNT>,1

然后,我们需要在配置文件中指定这个文件。根据你的守护进程管理工具,配置文件应该被放在/etc/inid.d/kubernetes-master或/etc/kubernetes/apiserver。配置文件中应该添加一个新的标记--basic-auth-file:

  • 对于kubernetes-master这个文件,在kube-apiserver命令或hyperkube apiserver命令后添加--basic-auth-file标记。这个标记的值应该是基本认证文件的完整路径例如,--basic-auth-file=/root/k8s-bafile。

  • 对于apiserver这个文件,向环境变量KUBE_API_ARGS中添加一个标记。例如,KUBE_API_ARGS=--basic-auth-file=/root/k8s-bafile。

最重要的是要保证启动Kubernetes服务的用户,不管是root还是kubelte,都要有访问你附加在标记后的这个文件权限。在你添加了这个新标记后,有必要重启服务,以使用认证有效。接下来,最好尝试一下本节开始处的curl命令。如果不提供用户名和密码,它将返回Unauthorized。

我们的节点通过不安全端口8080与API服务器通信。尽管我们不需要为授权许可指定任何角色,意识到配置Master的防火墙,它仅仅允许节点通过8080端口。在AWS上,一个安全组可以对此部分提供帮助。

对于Kubernetes的认证还有一些方法。为获得其它想法,请查看官方网站(http://kubernetes.io/docs/admin/authentication/ )。

利用用户授权

我们也可以为Kubernetes Master API服务器守护进程添加一个不同的用户许可。有两个标记可以设置用户授权。如下所示:

  • --authorization-mode=ABAC:这个值,ABAC,是Attribute-Based Access Controll的缩写。通过启用这个模式,我们可以设置自定义用户许可。

  • --token-auth-file=<FULL_PATH_OF_YOUR_TOKEN_FILE>:这是一个文件,我们使用它为API访问声明有资格的用户。可以提供更多的帐户和token对。

  • --authorization-policy-file=<FULL_PATH_OF_YOUR_POLICY_FILE>:我们将要使用这个策略文件来生成不同用户的独立规则。

这些特定的标记将被附加在kube-apiserver或hyperkube apiserver命令的后面。你可以参考以下示例:

// The daemon configuration file of Kubernetes master for init.d service
# cat /etc/init.d/kubernetes-master
(above lines are ignored)
:
# Start daemon.
echo $"Starting apiserver: "
    daemon $apiserver_prog \
    --service-cluster-ip-range=${CLUSTER_IP_RANGE} \
    --insecure-port=8080 \
    --secure-port=6443 \
    --authorization-mode=ABAC \
    --token-auth-file=/root/k8s-tokenfile \
    --authorization-policy-file=/root/k8s-policyfile \
    --address=0.0.0.0 \
    --etcd-servers=${ETCD_SERVERS} \
    --cluster-name=${CLUSTER_NAME} \
    > ${logfile}-apiserver.log 2>&1 &
:
(below lines are ignored)
or
// The kubernetes apiserver's configuration file for systemd service in
RHEL
# cat /etc/kubernetes/apiserver
(above lines are ignored)
:
KUBE_API_ARGS="--authorization-mode=ABAC --token-auth-file=/root/k8stokenfile --authorization-policy-file=/root/k8s-policyfile"

你仍然需要为帐户和策略配置这个文件。为了演示自定义用户许可的使用,下面的文件内容向你展示了如何创建一个admin帐户,并使这个帐户具有完全访问,再创建一个只读帐户:

# cat /root/k8s-tokenfile
k8s2016,admin,1
happy123,amy,2

用户定义格式与我们之前提到的基本认证的文件类似。这些项顺序列在每行中:token,username和UID。除了admin,我们创另一个叫amy的帐户,它只有读的许可:

# cat /root/k8s-policyfile
{"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind":
"Policy", "spec": {"user": "admin", "namespace": "*", "resource": "*",
"apiGroup": "*"}}
{"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind":
"Policy", "spec": {"user": "amy", "namespace": "*", "resource": "*",
"readonly": true}}

对于策略文件,JSON格式中的每行都是一个策略。每个策略都应该指明哪个用户需要遵循这个规则。对于admin第一个策略允许控制每个命名空间,资源和API组的许可。apiGroup这个Key指定了不同的API类别。例如,资源job是定义在extensions 的API组中。为了访问job,extensions类型应该包含在apiGroup中。第二个策略是定义只读许可的,意味着amy这个角色仅可以查看资源,但是不可以创建、删除和编辑资源。

稍后,在你准备好配置文件和服务之后重新启动Kubernetes Master的所有守护进程:

// For init.d service management
# service kubernetes-master restart
// Or, you can restart the individually with dependency
# systemctl stop kube-scheduler
# systemctl stop kube-controller-manager
# systemctl stop kube-apiserver
# systemctl start kube-apiserver
# systemctl start kube-controller-manager
# systemctl start kube-scheduler

还可以参考

建议阅读前面一些关于Kubernetes集群安装的章节:

  • 第1章构建你自己的Kubernetes,构建数据存储库,配置Master和Node这两节。

  • 第6章在AWS上构建Kubernetes,通过Chef Recipes自动部署Kubernetes这一节