在 Kubernetes 中,安全认证是非常重要和必要的。令牌是 Kubernetes 中的主要认证方式之一,可以用于用户身份验证和 API 访问控制。在本文中,我们将深入探讨 Kubernetes 中基于令牌的认证,并提供配置指南和示例代码。
令牌的作用
在 Kubernetes 中,令牌是用于用户身份验证和 API 访问控制的主要方式。令牌是一种用于身份验证的凭证,它由 Kubernetes API Server 颁发,并用于用户访问 Kubernetes API Server 的安全令牌。
Kubernetes 中有两种令牌类型,分别是:
- 用户令牌
- 服务账户令牌
用户令牌是由 Kubernetes API Server 在 Kubernetes 集群中使用的,用于用户身份验证和 API 访问控制。它们是在 Kubernetes 环境中的用户使用的。
服务账户令牌用于 Kubernetes 服务中,用于在 Kubernetes 集群中对服务进行身份验证和 API 访问控制。它们是在 Kubernetes 部件中使用的。
Kubernetes 中的基于令牌的认证
在 Kubernetes 中,基于令牌的认证需要进行以下步骤:
- 通过 API Server 请求令牌
- 认证 API Server 颁发的令牌
- 对 API Server 进行 API 调用
通过 API Server 请求令牌
在 Kubernetes 中,用户需要通过 kubectl
命令请求一个令牌,并将其用于身份验证和 API 访问控制。
例如,通过下面的命令来请求一个用户令牌:
kubectl -n kube-system describe secret $(kubectl -n kube-system get secret | grep service-controller-token | awk '{print $1}')
在上面的命令中,使用 kubectl -n kube-system get secret
命令来列出所有的 secrets,并通过 grep
命令过滤出 service-controller-token,最后使用 awk
命令来获取 secret 名称。
认证 API Server 颁发的令牌
在 Kubernetes 中,令牌是由 API Server 颁发的,因此需要进行认证,防止攻击者获取令牌并访问 Kubernetes API。
通常情况下,Kubernetes 使用 TLS for authentication(TLS 验证)来保证令牌的安全性。认证过程如下:
- 客户端通过 HTTPS 连接到 API Server。
- API Server 返回证书。
- 客户端从本地信任的 CA 中验证证书。
- 客户端将要发出的 API 调用中包含的令牌。
- API Server 验证令牌是否有效。
对 API Server 进行 API 调用
在 Kubernetes 中,进行 API 访问需要先进行身份验证,并获取有效的令牌。然后,通过使用 Authorization: Bearer <token>
头部来将令牌包含在 API 调用中。
例如,使用 curl
工具执行以下操作即可在 Kubernetes 中进行 API 访问:
curl -H "Authorization: Bearer <token>" https://<kubernetes-master>/apis/
配置指南
在 Kubernetes 中,需要配置 API Server 以启用令牌身份验证。以下是一些配置指南:
- 创建并分发令牌
- 配置 API Server 以使用令牌认证
创建并分发令牌
在 Kubernetes 中,可以使用 kube-admin
工具创建、查看和分发用户和服务账户令牌。
例如,使用以下命令创建新用户令牌并将其写入文件:
kubectl create sa my-user kubectl get secret $(kubectl get sa my-user -o jsonpath='{.secrets[0].name}') -o jsonpath="{.data.token}" | base64 --decode > /path/to/token.txt
在上面的示例中,使用 kubectl create sa
命令创建了一个名为 my-user
的用户,然后使用 kubectl get secret
命令以 JSON 格式显示 secret 并使用 grep
命令获取 secret 名称,最后使用 base64
命令解码 token 并将其写入文件。
配置 API Server 以使用令牌认证
在 Kubernetes 中,需要通过以下方式配置 API Server 以使用令牌认证:
- 启用令牌认证
- 配置 API Server 颁发的令牌
- 配置用户和服务账户访问策略
启用令牌认证
在 Kubernetes 中,需要在 API Server 的配置文件中启用令牌认证。Kubernetes 首先使用 TLS 来建立安全连接,然后接受身份验证令牌。
例如,如下是 APIServer 的配置文件:
apiVersion: v1 kind: Config clusters: - name: my-cluster cluster: certificate-authority: /path/to/server/ca.crt server: https://<kubernetes-master>:6443 contexts: - name: my-context context: cluster: my-cluster user: my-user namespace: default users: - name: my-user user: token-file: /path/to/token.txt
在上面的示例中,users
列表中指定了令牌文件。
配置 API Server 颁发的令牌
在 Kubernetes 中,需要配置 API Server 颁发哪些令牌。例如,可以使用以下命令创建一个新的服务账户,并为其颁发一个令牌:
kubectl create serviceaccount my-svc-acct kubectl -n default get secret $(kubectl -n default get sa my-svc-acct -o jsonpath='{.secrets[0].name}') -o jsonpath="{.data.token}" | base64 --decode > /path/to/token.txt
在上面的示例中,使用 kubectl create serviceaccount
命令创建了一个名为 my-svc-acct
的服务账户,并使用 kubectl get secret
命令以 JSON 格式显示 secret 和 grep
以获取 secret 名称,最后使用 base64
命令解码 token 并将其写入文件。
配置用户和服务账户访问策略
在 Kubernetes 中,可以使用 kubectl
工具以 YAML 或 JSON 格式为用户和服务账户定义访问策略。例如,以下是一个 Kubernetes 集群中的示例:
kind: Role apiVersion: rbac.authorization.k8s.io/v1 metadata: namespace: default name: deployment-manager rules: - apiGroups: ["", "extensions", "apps"] resources: ["deployments", "replicasets"] verbs: ["create", "get", "list", "update", "delete", "patch"]
在上面的示例中,使用 kind
为 Role,为 deployments
和 replicasets
定义了一系列 verbs
。
示例代码
下面是一个 Go 代码示例,用于在 Kubernetes 中使用基于令牌的认证:
import ( "flag" "fmt" "io/ioutil" "net/http" "os" "path/filepath" "time" ) var ( kubeConfig *string apiServer *string tokenFile *string token []byte bearerToken string transport *http.Transport httpClient *http.Client ) func init() { kubeConfigPath := filepath.Join(os.Getenv("HOME"), ".kube", "config") kubeConfig = flag.String("kubeconfig", kubeConfigPath, "location of kubectl config file") apiServer = flag.String("apiServer", "", "location of the Kubernetes API server, takes precedence over kubeconfig") tokenFile = flag.String("tokenFile", "", "token file to use for authentication") bearerToken = "Bearer " + string(token) transport = &http.Transport{} httpClient.Transport = transport httpClient = &http.Client{ Timeout: time.Second * 10, } } func main() { flag.Parse() if *apiServer == "" { // Get the API server from the Kubeconfig apiServer = getAPIServer(kubeConfig) } if *tokenFile != "" { // Read the token from the token file bs, err := ioutil.ReadFile(*tokenFile) if err != nil { fmt.Errorf("failed to read token file %v: %v", *tokenFile, err) os.Exit(1) } token = bs } url := fmt.Sprintf("%s/api/v1/namespaces?limit=500", *apiServer) req, err := http.NewRequest("GET", url, nil) if err != nil { fmt.Errorf("failed to create new request: %v", err) os.Exit(1) } req.Header.Set("Authorization", bearerToken) resp, err := httpClient.Do(req) if err != nil { fmt.Errorf("failed to fetch response: %v", err) os.Exit(1) } defer resp.Body.Close() bs, err := ioutil.ReadAll(resp.Body) if err != nil { fmt.Errorf("failed to read response: %v", err) os.Exit(1) } fmt.Println(string(bs)) } func getAPIServer(configFile *string) *string { f, err := os.Open(*configFile) if err != nil { panic("Could not open kubeconfig file") } defer f.Close() var data interface{} decoder := yaml.NewYAMLDecoder(f) err = decoder.Decode(&data) if err != nil { panic("Could not decode kubeconfig file") } // Get the API server if currentContext, ok := data.(map[interface{}]interface{})["current-context"].(string); ok { contexts := data.(map[interface{}]interface{})["contexts"].([]interface{}) for i := range contexts { c := contexts[i].(map[interface{}]interface{}) if c["name"] == currentContext { return c["context"].(map[interface{}]interface{})["cluster"].(string) } } } return nil }
总结
Kubernetes 中的基于令牌的认证是保护 Kubernetes 环境安全的重要组成部分。在本文中,我们深入了解了 Kubernetes 中的令牌认证,并提供了配置指南和示例代码。我们希望这篇文章可以为你提供足够的深度和指导意义,以帮助你更好地理解 Kubernetes 中的基于令牌的认证方式。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/658fc306eb4cecbf2d557b7a