访问集群
本文介绍了访问 Kubernetes 集群的各种方式,包括命令行工具、REST API、编程接口等多种方法。
使用 kubectl 访问集群
初次配置
如果你是第一次访问 Kubernetes API,推荐使用 Kubernetes 命令行工具 kubectl
。
访问集群需要知道:
- 集群的地址
- 访问凭证
这些信息通常在完成集群部署后自动配置,或由集群管理员提供。
使用以下命令检查 kubectl 的配置信息:
kubectl config view
验证连接
确认集群连接正常:
kubectl cluster-info
kubectl get nodes
直接访问 REST API
kubectl 会自动处理 API server 的定位和认证。如果需要直接访问 REST API,可以使用 HTTP 客户端(如 curl、wget 或浏览器),有以下几种方式:
使用 kubectl proxy(推荐)
这是最推荐的方法,具有以下优势:
- 使用已保存的 API server 位置信息
- 自动处理 TLS 证书验证
- 自动处理身份认证
- 支持客户端负载均衡和故障转移
启动代理:
kubectl proxy --port=8080
然后可以通过 HTTP 访问 API:
curl http://localhost:8080/api/v1
直接访问(需要手动处理认证)
获取必要的认证信息:
# 获取 API server 地址
APISERVER=$(kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}')
# 获取访问令牌
TOKEN=$(kubectl get secret $(kubectl get serviceaccount default -o jsonpath='{.secrets[0].name}') -o jsonpath='{.data.token}' | base64 --decode)
# 访问 API
curl $APISERVER/api/v1 --header "Authorization: Bearer $TOKEN" --insecure
注意:使用 --insecure
标志会跳过 TLS 证书验证,存在中间人攻击风险。生产环境应使用正确的证书配置。
编程访问 API
Kubernetes 提供多种语言的官方客户端库:
Go 客户端
安装客户端库:
go get k8s.io/client-go/kubernetes
基本使用示例:
package main
import (
"context"
"fmt"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/clientcmd"
)
func main() {
// 使用默认的 kubeconfig
config, err := clientcmd.BuildConfigFromFlags("", clientcmd.RecommendedHomeFile)
if err != nil {
panic(err)
}
// 创建客户端
clientset, err := kubernetes.NewForConfig(config)
if err != nil {
panic(err)
}
// 列出 Pod
pods, err := clientset.CoreV1().Pods("default").List(context.TODO(), metav1.ListOptions{})
if err != nil {
panic(err)
}
fmt.Printf("共有 %d 个 Pod\n", len(pods.Items))
}
Python 客户端
安装客户端库:
pip install kubernetes
基本使用示例:
from kubernetes import client, config
# 加载 kubeconfig
config.load_kube_config()
# 创建 API 客户端
v1 = client.CoreV1Api()
# 列出所有 Pod
pods = v1.list_pod_for_all_namespaces()
print(f"共有 {len(pods.items)} 个 Pod")
其他语言客户端
Kubernetes 社区还提供了以下语言的客户端库:
- Java
- JavaScript (Node.js)
- C#
- Ruby
- Rust
- PHP
详细信息请参考 Kubernetes 客户端库。
在 Pod 中访问 API
当应用运行在 Kubernetes Pod 中时,访问 API 的方式有所不同。
服务发现
在 Pod 中可以通过以下方式找到 API server:
- 使用 DNS 名称:
kubernetes.default.svc.cluster.local
- 使用环境变量:
KUBERNETES_SERVICE_HOST
和KUBERNETES_SERVICE_PORT
服务账户认证
每个 Pod 都会自动挂载默认服务账户的凭证:
- Token 文件:
/var/run/secrets/kubernetes.io/serviceaccount/token
- CA 证书:
/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
- Namespace:
/var/run/secrets/kubernetes.io/serviceaccount/namespace
在 Pod 中使用客户端库
Go 客户端示例:
config, err := rest.InClusterConfig()
if err != nil {
panic(err)
}
clientset, err := kubernetes.NewForConfig(config)
if err != nil {
panic(err)
}
Python 客户端示例:
from kubernetes import client, config
# 加载集群内配置
config.load_incluster_config()
v1 = client.CoreV1Api()
访问集群中的服务
服务类型和访问方式
根据服务类型选择合适的访问方式:
服务类型 | 访问方式 | 适用场景 |
---|---|---|
ClusterIP | 集群内访问 | 内部服务通信 |
NodePort | 节点端口访问 | 开发测试环境 |
LoadBalancer | 外部负载均衡器 | 生产环境对外服务 |
ExternalName | DNS 别名 | 访问外部服务 |
通过代理访问
使用 kubectl 代理访问集群内服务:
kubectl proxy
然后通过以下 URL 格式访问服务:
http://localhost:8080/api/v1/namespaces/{namespace}/services/{service-name}:{port}/proxy/
端口转发
将本地端口转发到 Pod 或服务:
# 转发到 Pod
kubectl port-forward pod/my-pod 8080:80
# 转发到服务
kubectl port-forward service/my-service 8080:80
内置服务访问
查看集群内置服务:
kubectl cluster-info
常见的内置服务包括:
- Kubernetes Dashboard
- DNS 服务
- 监控服务(如 Prometheus、Grafana)
- 日志服务(如 Elasticsearch、Kibana)
访问这些服务通常需要适当的 RBAC 权限配置。
安全最佳实践
认证和授权
使用强认证方式:
- 避免使用基本认证
- 优先使用 OIDC 或证书认证
- 定期轮换访问令牌
最小权限原则:
- 为应用创建专用服务账户
- 使用 RBAC 限制访问权限
- 定期审查权限配置
网络安全:
- 使用 TLS 加密通信
- 配置网络策略限制流量
- 避免在生产环境使用
--insecure
标志
访问控制
以下是相关的代码示例:
# 示例:创建只读权限的服务账户
apiVersion: v1
kind: ServiceAccount
metadata:
name: readonly-user
namespace: default
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: readonly
rules:
- apiGroups: [""]
resources: ["pods", "services"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: readonly-binding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: readonly
subjects:
- kind: ServiceAccount
name: readonly-user
namespace: default
故障排查
常见问题和解决方案
连接被拒绝:
- 检查集群状态:
kubectl cluster-info
- 验证网络连接
- 确认防火墙设置
- 检查集群状态:
认证失败:
- 检查 kubeconfig 配置
- 验证证书有效性
- 确认服务账户权限
TLS 证书错误:
- 更新 CA 证书
- 检查证书过期时间
- 验证主机名匹配
调试命令
以下是相关的代码示例:
# 检查集群状态
kubectl cluster-info dump
# 查看详细错误信息
kubectl get events --sort-by=.metadata.creationTimestamp
# 测试 API 连接
kubectl auth can-i '*' '*' --all-namespaces
代理类型总结
Kubernetes 环境中存在多种代理类型:
kubectl proxy:
- 运行在客户端
- HTTP 到 HTTPS 转换
- 自动处理认证
API server proxy:
- 内置在 API server 中
- 用于访问集群内资源
- 支持负载均衡
kube-proxy:
- 运行在每个节点
- 处理服务流量转发
- 支持多种代理模式
Ingress Controller:
- 七层负载均衡
- HTTP/HTTPS 路由
- SSL 终结
Cloud Load Balancer:
- 云提供商服务
- 外部流量入口
- 高可用性支持
每种代理都有其特定的使用场景和配置要求,选择合适的代理方式对于集群的性能和安全性都很重要。