Open xuanyuanaosheng opened 1 month ago
在命令行下管理多个 Kubernetes 集群,通常使用 kubectl
工具结合 Kubernetes 的 kubeconfig
文件。以下是管理多个 Kubernetes 集群的基本步骤和技巧:
kubeconfig
Kubernetes 使用 kubeconfig
文件来存储集群的配置信息。您可以在一个 kubeconfig
文件中配置多个集群和用户。
kubeconfig
文件合并多个 kubeconfig
文件:
如果您已经有多个集群的 kubeconfig
文件,可以使用以下命令合并它们:
KUBECONFIG=~/.kube/config:~/.kube/other-config kubectl config view --merge --flatten > ~/.kube/merged-config
然后,您可以使用合并后的配置文件:
export KUBECONFIG=~/.kube/merged-config
手动添加集群配置:
您可以通过以下命令手动添加集群和上下文配置:
kubectl config set-cluster CLUSTER_NAME --server=https://your-cluster-api-server --certificate-authority=/path/to/ca.crt
kubectl config set-credentials USER_NAME --token=YOUR_TOKEN
kubectl config set-context CONTEXT_NAME --cluster=CLUSTER_NAME --user=USER_NAME
选择上下文:
在 kubeconfig
文件中,您可以定义多个上下文(contexts),每个上下文代表一个集群、用户和命名空间的组合。您可以使用以下命令查看当前上下文和所有上下文:
kubectl config current-context
kubectl config get-contexts
切换到另一个上下文:
kubectl config use-context CONTEXT_NAME
一旦配置好 kubeconfig
文件,您就可以使用 kubectl
命令管理不同的集群。以下是一些常见的命令示例:
查看所有集群信息:
kubectl config get-contexts
切换上下文:
kubectl config use-context CONTEXT_NAME
查看集群状态:
kubectl cluster-info
列出命名空间:
kubectl get namespaces
在特定上下文中执行命令:
您也可以直接在命令中指定上下文:
kubectl --context=CONTEXT_NAME get pods
KUBECONFIG
如果您经常需要在多个集群之间切换,可以通过设置 KUBECONFIG
环境变量来简化流程。例如:
export KUBECONFIG=~/.kube/config:~/.kube/other-config
这允许您一次性访问多个集群的配置。
还有一些工具可以帮助管理多个 Kubernetes 集群:
kubectx: 一个命令行工具,帮助快速切换 Kubernetes 上下文。
# 安装 kubectx
git clone https://github.com/ahmetb/kubectx.git ~/.kubectx
echo 'export PATH="$HOME/.kubectx:$PATH"' >> ~/.bashrc
source ~/.bashrc
# 切换上下文
kubectx CONTEXT_NAME
Rancher: 适合集中管理多个 Kubernetes 集群的可视化工具。
通过配置 kubeconfig
文件和使用 kubectl
命令,您可以方便地在命令行中管理多个 Kubernetes 集群。结合使用工具如 kubectx
可以进一步简化管理流程。
在 Kubernetes (K8S) 中,用户(User) 和 用户组(Group) 的管理不是通过 Kubernetes 自身来进行的,而是通过外部认证机制来管理的。Kubernetes 集群通常不会直接管理用户和组的创建、删除或管理,而是通过 认证(Authentication) 和 授权(Authorization) 来控制用户的权限和访问操作。
然而,我们可以通过以下方式实现用户和用户组的管理和权限控制:
在 Kubernetes (K8S) 中,RBAC(Role-Based Access Control,基于角色的访问控制)允许你通过角色和绑定来精确地控制用户和服务账户在集群中的权限。你可以通过定义不同的 Role 或 ClusterRole 来控制用户能够执行的操作,以及通过 RoleBinding 或 ClusterRoleBinding 来将这些角色分配给用户。
Role 适用于某个 Namespace 内的资源控制,而 ClusterRole 则适用于集群范围内的控制。我们先来看如何创建一个 Role。
dev-namespace
中管理 PodsapiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: dev-namespace
name: pod-manager
rules:
- apiGroups: [""] # "" 代表核心 API 组,用于控制像 Pod 这样的基本资源
resources: ["pods"]
verbs: ["create", "delete", "get", "list", "watch", "update"]
kubectl apply -f pod-manager-role.yaml
你需要创建一个 RoleBinding 或 ClusterRoleBinding,将刚刚创建的 Role 绑定到一个用户或组上。
pod-manager
Role 绑定到一个用户 user1
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: pod-manager-binding
namespace: dev-namespace
subjects:
- kind: User # 这里可以是 User, Group, 或 ServiceAccount
name: user1 # 绑定的用户名称
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role # 绑定的角色是 Role
name: pod-manager # Role 的名称
apiGroup: rbac.authorization.k8s.io
kubectl apply -f pod-manager-binding.yaml
如果你希望在集群范围内进行权限控制,可以使用 ClusterRole 和 ClusterRoleBinding。ClusterRole 还可以用来控制某些特定非命名空间资源(如节点、命名空间、持久卷等)。
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: view-pods
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch"]
kubectl apply -f view-pods-clusterrole.yaml
user2
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: view-pods-binding
subjects:
- kind: User
name: user2
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: view-pods
apiGroup: rbac.authorization.k8s.io
kubectl apply -f view-pods-binding.yaml
在绑定角色后,用户应该只能执行他们所被允许的操作。你可以使用 kubectl auth can-i
命令来验证某个用户是否有执行某些操作的权限。
kubectl auth can-i create pods --as=user1 --namespace=dev-namespace
kubectl auth can-i get pods --as=user2 --namespace=default
通过 RBAC,你可以灵活控制用户或组对 Kubernetes 资源的访问权限。以下是配置 RBAC 的主要步骤:
kubectl auth can-i
验证用户的权限。通过这种方式,你可以为不同角色和用户设置不同的权限,从而确保 Kubernetes 集群的安全性。
在 Kubernetes 中,您可以通过 kubectl auth can-i
命令查看某个账户在集群中的资源权限。该命令用于检查某个用户是否有权执行特定的操作。下面是一些具体的使用方式:
kubectl auth can-i <verb> <resource> --namespace=<namespace>
<verb>
:表示操作类型,如 get
、list
、create
、delete
等。<resource>
:表示资源类型,如 pods
、deployments
、services
等。--namespace=<namespace>
:指定命名空间(可选)。如果不指定,默认为 default
命名空间。示例:
# 查看当前用户是否可以获取 pods 资源
kubectl auth can-i get pods
# 查看当前用户是否可以删除 services 资源
kubectl auth can-i delete services --namespace=my-namespace
通过指定 --as
选项,您可以模拟某个用户来查看他们的权限。
kubectl auth can-i <verb> <resource> --namespace=<namespace> --as=<username>
示例:
# 查看名为 "user123" 的用户是否可以创建 deployments 资源
kubectl auth can-i create deployments --as=user123
# 查看 "user123" 是否可以在 "prod" 命名空间中删除 pods
kubectl auth can-i delete pods --namespace=prod --as=user123
如果您想查看用户在命名空间中的所有资源权限,可以使用以下命令列出用户可以进行的所有操作:
kubectl auth can-i --list --namespace=<namespace> --as=<username>
示例:
# 查看当前用户在 "default" 命名空间的所有权限
kubectl auth can-i --list
# 查看名为 "user123" 的用户在 "dev" 命名空间的所有权限
kubectl auth can-i --list --namespace=dev --as=user123
如果您想了解某个用户或者服务账户绑定了哪些角色,您可以查看相关的 RoleBinding
或 ClusterRoleBinding
。
kubectl get clusterrolebindings --field-selector subjects.kind=User,subjects.name=<username> -o yaml
kubectl get rolebindings --namespace=<namespace> --field-selector subjects.kind=User,subjects.name=<username> -o yaml
示例:
# 查看 user123 绑定的 ClusterRoleBinding
kubectl get clusterrolebindings --field-selector subjects.kind=User,subjects.name=user123 -o yaml
# 查看 user123 在 "dev" 命名空间中绑定的 RoleBinding
kubectl get rolebindings --namespace=dev --field-selector subjects.kind=User,subjects.name=user123 -o yaml
对于 ServiceAccount,您可以通过以下命令查看权限:
kubectl auth can-i --as=system:serviceaccount:<namespace>:<serviceaccount> <verb> <resource>
示例:
# 查看 default 命名空间中的 my-serviceaccount 是否可以创建 pods
kubectl auth can-i create pods --as=system:serviceaccount:default:my-serviceaccount
kubectl auth can-i
是检查权限的主要命令。--as
选项可以模拟特定用户或服务账户。--list
可以列出用户对资源的所有权限。RoleBinding
和 ClusterRoleBinding
来检查用户的角色和权限。在 Kubernetes (K8S) 中,调度和使用 GPU 资源需要做一些配置,涉及 GPU 驱动、设备插件以及指定资源请求等。以下是调度 GPU 资源的具体步骤:
要调度 GPU 资源,首先需要确保在 Kubernetes 集群中的节点具备 GPU,并安装了相应的驱动程序。
如果使用 NVIDIA GPU,首先需要在节点上安装 NVIDIA GPU 驱动程序。
在大多数情况下,你可以按照以下步骤安装 NVIDIA 驱动:
# 1. 添加 NVIDIA repository
distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add -
curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list
# 2. 安装 NVIDIA 驱动
sudo apt-get update
sudo apt-get install -y nvidia-driver-470
根据你的系统类型(例如 Ubuntu 或 CentOS),可能需要调整安装过程。如果在云平台(如 AWS、GCP 等)使用 GPU 节点,通常系统会预装必要的驱动。
接下来,你需要为 Docker 安装 nvidia-docker
来管理 GPU 资源。
# 安装 nvidia-container-toolkit
sudo apt-get install -y nvidia-container-toolkit
sudo systemctl restart docker
Kubernetes GPU 调度依赖于 NVIDIA 的 NVIDIA Kubernetes Device Plugin,用于暴露 GPU 设备给 Kubernetes。接下来我们来安装这个插件。
NVIDIA 提供了一个设备插件(device plugin)用于管理 GPU。通过这个插件,Kubernetes 可以自动发现并调度 GPU 资源。
使用 kubectl apply
来部署 NVIDIA 设备插件:
kubectl apply -f https://github.com/NVIDIA/k8s-device-plugin/raw/main/nvidia-device-plugin.yml
这个插件会在每个拥有 GPU 的节点上运行,并将 GPU 资源报告给 Kubernetes。部署完成后,你可以通过以下命令来验证设备插件是否正常运行:
## DaemonSet
kubectl get ds -n kube-system
查看 nvidia-device-plugin
的状态,确保设备插件已经正常部署到所有 GPU 节点上。
部署 NVIDIA 设备插件后,Kubernetes 将自动检测节点上的 GPU 并将其作为资源。你可以通过以下命令检查 GPU 资源是否可用:
kubectl describe nodes | grep -A 5 "Capacity"
在输出中,你应该能看到类似如下的 GPU 资源:
nvidia.com/gpu: 1
这表示该节点上有 1 个 NVIDIA GPU 可供调度。
在创建需要使用 GPU 的 Pod 时,可以在 spec
中指定 GPU 资源请求。下面是一个示例,演示如何请求使用 1 个 GPU 的 Pod:
apiVersion: v1
kind: Pod
metadata:
name: gpu-pod
spec:
containers:
- name: gpu-container
image: nvidia/cuda:10.0-base
resources:
limits:
nvidia.com/gpu: 1 # 请求 1 个 GPU
command: ["nvidia-smi"]
在这个 Pod 配置中,nvidia.com/gpu: 1
表示请求 1 个 GPU 资源。可以根据实际需要调整请求的 GPU 数量。
使用 kubectl apply
命令部署 Pod:
kubectl apply -f gpu-pod.yaml
你可以通过 kubectl logs
命令查看容器日志,确认 GPU 是否正常工作:
kubectl logs gpu-pod
例如,使用 nvidia/cuda
镜像并执行 nvidia-smi
命令可以查看 GPU 的工作状态。
在 K8S 集群中,GPU 是作为一种 可限制的资源 来管理的,类似于 CPU 和内存。当你定义工作负载(如 Pod、Deployment 等)时,可以在 resources
字段下设置对 GPU 资源的请求和限制。
resources:
limits:
nvidia.com/gpu: 1 # 限制容器最多使用 1 个 GPU
Kubernetes 通过设备插件自动发现并分配 GPU 资源,调度器根据这些资源请求为 Pod 安排 GPU 节点。如果节点上没有可用的 GPU,Pod 将处于 Pending 状态,直到有 GPU 可用。
你可以通过以下命令查看 Pod 是否成功调度到 GPU 节点上:
kubectl get pods -o wide
查看 Pod 所在节点,并确认该节点上是否有 GPU。
调度 GPU 资源的关键步骤包括:
nvidia/k8s-device-plugin
来将 GPU 资源暴露给 Kubernetes。通过以上步骤,您可以在 Kubernetes 集群中高效地调度和管理 GPU 资源,支持需要 GPU 加速的计算任务(如深度学习、图像处理等)。
Kubernetes(K8S)的网络插件用于管理和配置集群中的网络通信,确保Pod之间以及Pod与外部服务之间的连接。Kubernetes本身提供了基本的网络模型,但具体的网络实现是通过插件来完成的。网络插件一般遵循CNI(Container Network Interface)标准,并为集群提供了不同的功能和特性,如网络隔离、服务发现、负载均衡等。
Kubernetes中的网络插件非常多样,选择合适的插件取决于具体的需求,如性能、易用性、安全性、网络策略支持等。以下是常见场景下的推荐插件:
选择适合的网络插件可以帮助提高集群的性能、灵活性和安全性。
以下是常见的Kubernetes网络插件及其介绍:
Flannel 是最简单、最常见的Kubernetes网络插件之一,专注于为Kubernetes集群中的每个节点提供IP地址空间。
适用场景:适用于对网络要求不高的场景,尤其是开发或测试环境。
Calico 是一个功能强大的网络插件,提供IP数据包路由和网络策略控制,支持大规模Kubernetes集群。
适用场景:适用于对网络安全、性能和可扩展性要求较高的场景,尤其是生产环境。
Weave Net 是一个简单易用的Kubernetes网络插件,支持网络隔离和加密功能。
适用场景:适用于中小规模集群,尤其是对安全性和易用性有要求的环境。
Cilium 是一个基于eBPF(Extended Berkeley Packet Filter)的网络插件,专注于提供安全性和可观察性,尤其适用于微服务架构。
适用场景:适用于微服务架构、云原生应用以及对网络安全和监控有较高要求的场景。
Canal 是Calico和Flannel的结合体,兼具两者的优点,提供了网络策略支持和简化的配置。
适用场景:适合需要网络策略但又想要保持简单配置的场景。
Kube-Router 是一个Kubernetes网络插件,专注于提供高效的网络转发、网络策略和负载均衡功能。
适用场景:适合对网络性能要求较高的场景,尤其是需要复杂路由和负载均衡的场景。
Multus 是一个多网络插件,允许在Kubernetes中为Pod分配多个网络接口。
适用场景:适合需要多网络接口或多CNI插件的复杂网络环境。
OVS + OVN 是一个强大的网络解决方案,基于Open vSwitch的虚拟交换技术。
适用场景:适合需要复杂虚拟网络架构的场景,如企业数据中心或云计算环境。
在一个典型的Kubernetes (K8S) 集群中,网络插件(如Calico)为容器提供了跨节点的网络通信能力。将GitLab部署在K8S上时,不同组件之间的通信必须依赖于K8S的网络模型和插件来实现。
下面我将以Calico网络插件为例,详细讲解GitLab各个组件在K8S中如何进行网络通信。
Kubernetes中的每个Pod都通过网络插件(例如Calico)拥有一个独立的IP地址,这使得不同Pod之间的通信能够像同一个虚拟网络中设备的通信一样。
GitLab通常由多个独立的服务组件组成,常见的GitLab服务组件包括:
在K8S中,这些组件通常被分别部署为多个Pod,运行在不同的节点上。
在K8S集群中,GitLab的不同组件通过服务发现和网络层进行通信。这些组件之间的通信需求包括:
通过Calico网络插件,每个Pod都有一个唯一的IP地址,这意味着GitLab的各个Pod可以通过IP地址和K8S的DNS服务相互发现和通信。
Calico通过路由机制和BGP协议保证跨节点的Pod间通信。无论GitLab的不同组件运行在哪个节点,它们都可以通过Pod IP直接通信。通信的方式可以是:
通过Service:K8S中的Service为一组Pod提供了负载均衡和服务发现。GitLab的不同组件之间一般通过K8S Service来通信。例如:
gitlab-postgresql
Service连接到PostgreSQL。gitlab-redis
Service连接到Redis。通过直接Pod IP:在一些特殊情况下,一个组件可以直接通过另一个Pod的IP进行通信。Calico确保了即使跨节点,这些IP之间的通信也能够正常进行。
K8S的服务发现机制通过内部的CoreDNS服务,允许Pod使用服务名称来解析到其他服务的IP。例如,GitLab Web Service Pod可以通过名称gitlab-postgresql
找到PostgreSQL数据库Pod的IP地址。
Calico确保所有Pod都可以在整个集群内通过IP和DNS解析来找到彼此,从而实现GitLab各组件之间的通信。
Calico不仅提供了网络连接能力,还支持定义网络策略(NetworkPolicy)来控制哪些Pod或服务能够访问特定的GitLab组件。这可以用来加强GitLab部署的安全性。
例如,可以通过Calico的网络策略实现以下访问控制:
通过这些策略,Calico可以有效控制GitLab各个组件之间的通信,确保其在安全和性能上得到保证。
外部访问:GitLab的Web Service通常需要通过K8S的Ingress或LoadBalancer与外部用户通信。Calico支持与K8S Ingress结合使用,确保从外部访问GitLab服务的流量能够被正确路由到GitLab的Pod。
外部服务调用:GitLab的某些功能可能需要访问外部资源或服务(如API调用、第三方服务等)。通过Calico的网络策略,可以配置允许的外部通信范围,例如只允许GitLab Web Service访问某些API服务或限制外部访问权限。
GitLab Runner负责执行CI/CD任务,并需要与GitLab Web Service进行通信。这一过程通常涉及多种网络操作:
使用Calico,Runner Pod无论部署在哪个节点上,都可以通过DNS解析找到GitLab Web Service的地址,并通过Pod间通信机制访问该服务。
以下是一个GitLab各组件的网络通信示例:
gitlab-postgresql
连接到 PostgreSQL Pod,执行数据库查询。gitlab-redis
连接到 Redis Pod,读取任务队列并执行任务。在K8S中部署GitLab时,Calico网络插件通过为每个Pod提供唯一的IP地址和跨节点通信能力,确保GitLab的各个组件可以正常通信。同时,借助Calico的网络策略,用户还可以加强GitLab各个服务之间的网络访问控制,提升集群的安全性。
通过这种方式,GitLab的各个服务组件(Web Service、PostgreSQL、Redis、Sidekiq、Runner等)可以通过K8S的网络模型高效地互相通信,同时保证整个集群的安全和性能。
以Gitlab里面的组件为例 (下面的例子并未实际测试,默认通过Helm搭建的Gitlab也不知道有木有对应的网络策略控制,可以自己确认下),在 Kubernetes 中,Calico 是一个广泛使用的网络插件之一,它不仅提供容器间的网络通信功能,还支持网络策略(Network Policy),用于控制不同 Pod 之间的网络访问权限。通过 Calico 的网络策略,我们可以细粒度地定义哪些 Pod 或服务能够访问特定的 GitLab 组件。
网络策略(Network Policy)是 Kubernetes 提供的一种功能,允许管理员定义集群中不同 Pod 之间的网络通信规则。通过网络策略,你可以限制哪些 Pod 可以访问其他 Pod 或服务,或者限制 Pod 的出站访问权限。
Calico 作为一个强大的网络插件,扩展了 Kubernetes 的网络策略功能,支持更多的匹配选项和更复杂的规则。使用 Calico,你可以控制 Pod 的入站和出站流量。
在 GitLab 部署中,多个组件(如 GitLab Web Service、GitLab Redis、GitLab Runner 等)需要进行通信。为了确保安全性,你可能希望控制哪些 Pod 能够访问某些 GitLab 组件。
假设有以下 GitLab 组件:
gitlab-webservice
服务。gitlab-redis
服务。gitlab-runner
服务。需求可能包括:
为了实现这些访问控制,我们可以使用 Calico 定义的网络策略来限制哪些 Pod 或服务能够访问特定的 GitLab 组件。每个网络策略都是一个 Kubernetes 资源,用 YAML 文件进行定义。
一个网络策略通常包括以下几部分:
下面是一个网络策略的示例,用于允许 gitlab-webservice
Pod 访问 gitlab-redis
Pod,同时禁止其他 Pod 访问 Redis。
apiVersion: crd.projectcalico.org/v1
kind: NetworkPolicy
metadata:
name: allow-webservice-to-redis
namespace: default # 假设所有 GitLab 组件都在 'default' namespace
spec:
selector: app == 'gitlab-redis' # 选择 GitLab Redis Pod
ingress:
- action: Allow
source:
selector: app == 'gitlab-webservice' # 只允许 GitLab Web Service 访问 Redis
egress:
- action: Allow
destination:
selector: app == 'gitlab-webservice' # 允许 Redis 响应 Web Service 的请求
types:
- Ingress
- Egress
解释:
gitlab-redis
Pod。app=gitlab-webservice
的 Pod 向 Redis 发起请求。gitlab-webservice
的请求。接下来,我们定义一个策略,允许 GitLab Runner 访问 GitLab Web Service,但限制其他 Pod 的访问。
apiVersion: crd.projectcalico.org/v1
kind: NetworkPolicy
metadata:
name: allow-runner-to-webservice
namespace: default # 假设所有 GitLab 组件都在 'default' namespace
spec:
selector: app == 'gitlab-webservice' # 选择 GitLab Web Service Pod
ingress:
- action: Allow
source:
selector: app == 'gitlab-runner' # 只允许 GitLab Runner 访问 Web Service
egress:
- action: Allow
destination:
selector: app == 'gitlab-runner' # 允许 Web Service 响应 Runner 的请求
types:
- Ingress
- Egress
解释:
gitlab-webservice
Pod。app=gitlab-runner
的 Pod 向 Web Service 发起请求。gitlab-runner
的请求。如果你想限制所有外部流量,只允许内部组件互相通信,可以定义一条网络策略来阻止所有未授权的外部访问。比如,阻止对 GitLab Web Service 的任何外部访问:
apiVersion: crd.projectcalico.org/v1
kind: NetworkPolicy
metadata:
name: deny-external-to-webservice
namespace: default
spec:
selector: app == 'gitlab-webservice'
ingress:
- action: Deny # 拒绝所有没有明确允许的流量
source:
notSelector: app in ('gitlab-runner', 'gitlab-redis') # 不允许来自 Runner 和 Redis 以外的流量
types:
- Ingress
解释:
gitlab-runner
和 gitlab-redis
以外的所有 Pod 的访问。将上述策略定义好之后,可以通过 kubectl apply
命令将其应用到 Kubernetes 集群:
kubectl apply -f allow-webservice-to-redis.yaml
kubectl apply -f allow-runner-to-webservice.yaml
kubectl apply -f deny-external-to-webservice.yaml
这将生效并影响相应的网络流量。
你可以使用 kubectl exec
命令进入 Pod 并尝试访问其他 Pod 来验证网络策略是否生效。例如,尝试从 gitlab-runner
Pod 中访问 gitlab-webservice
:
kubectl exec -it <gitlab-runner-pod> -- curl gitlab-webservice.default.svc.cluster.local
如果策略生效,应该能够访问 Web Service。
如果你发现某些 Pod 无法访问预期的服务,可以通过以下方法进行调试:
app=gitlab-webservice
)与 Pod 的实际标签一致。kubectl describe networkpolicy <policy-name>
来查看已应用的网络策略的详细信息。通过 Calico 提供的网络策略功能,你可以精细化地控制 Kubernetes 集群中不同 Pod 之间的网络通信。这对于 GitLab 等多组件应用尤为重要,能够防止未经授权的 Pod 或服务访问敏感组件,如 GitLab Redis 或 Web Service。通过合理的网络策略配置,可以确保集群的安全性和可维护性。
NetworkPolicy
)。kubectl apply
应用策略。Calico 的网络策略功能非常灵活,适用于 Kubernetes 中的多种安全和隔离场景。
Kubernetes 调度器(Scheduler)是 Kubernetes 中负责将新创建的未指定节点的 Pod 分配到合适的节点上的组件。调度器是 Kubernetes 系统中非常关键的一部分,因为它决定了工作负载如何在集群内的节点上分布,从而影响资源利用率、应用程序的性能和集群的健壮性。
当一个新的 Pod 被创建时,它处于一个未调度(Pending)的状态,并且没有分配到任何节点上。此时,Kubernetes 调度器会负责以下操作:
过滤阶段(Filtering Phase):调度器首先会根据 Pod 的要求和节点的条件,对所有的节点进行筛选,过滤掉不符合要求的节点。这些条件可能包括:
优选阶段(Scoring Phase):在过滤完所有不适合的节点之后,调度器会对剩余的候选节点进行评分。评分的依据可以是多种因素,例如:
绑定阶段(Binding Phase):最后,调度器会将 Pod 绑定到得分最高的节点上。这个步骤完成后,Kubelet(节点上的代理)会开始在该节点上运行这个 Pod。
资源管理:调度器会根据节点的资源分配策略,为 Pod 分配最合适的节点。它需要确保节点的 CPU、内存、存储等资源不会被超分配。
亲和性与反亲和性:调度器可以根据用户定义的亲和性(Affinity)和反亲和性(Anti-affinity)规则,将 Pod 放在特定的节点上,或者避免将 Pod 放在特定节点或同一节点上。这在高可用性、容错性和拓扑分布策略上非常重要。
污点和容忍度(Taints and Tolerations):调度器能够根据节点的污点(Taints)过滤掉不合适的节点,除非 Pod 有相应的容忍度(Tolerations)。这种机制允许你将某些 Pod 避免调度到特定的节点上,或强制某些 Pod 只能调度到特定节点。
拓扑感知调度:在某些情况下,你可能希望 Pod 根据拓扑(如可用区、区域)进行调度。调度器可以通过拓扑感知规则,确保应用程序的高可用性和容灾能力。
Predicate 算法:在过滤阶段,调度器会使用多个 Predicate 函数来确定某个节点是否能够运行特定的 Pod。这些函数包括检查节点的可用性、资源、污点、Pod 的请求等。
Priority 算法:在优选阶段,调度器使用 Priority 函数对候选节点进行评分。这些评分由多个因素决定,例如节点的剩余资源、负载均衡情况、亲和性等。
调度周期:调度器定期执行调度循环,在这个过程中会检查所有的 Pending Pod,尝试将它们调度到合适的节点。
资源亲和性:根据 Pod 的资源需求,将它调度到有足够资源的节点上。这是最基本的调度策略,确保 CPU、内存等资源的充分利用。
Pod 亲和性/反亲和性:你可以指定某些 Pod 希望和某些其他 Pod 一起运行(或避免在同一节点上运行),这种策略可以通过 PodAffinity
和 PodAntiAffinity
实现。
节点亲和性:你可以定义 Pod 需要调度到特定节点上,或避免某些节点。这通常通过 NodeSelector
和 NodeAffinity
实现。
拓扑容忍性:通过将 Pod 分布在不同的可用区或区域,以提高高可用性。
Kubernetes 调度器是可扩展的,允许你根据集群的需求自定义调度逻辑:
自定义调度器:如果默认调度器不满足你的需求,你可以编写自定义调度器,并将其部署到 Kubernetes 中。自定义调度器可以使用不同的调度算法和策略来调度 Pod。
调度器扩展点:Kubernetes 还提供了调度器扩展点(Scheduler Extender),允许你在现有调度器的基础上添加额外的调度逻辑,比如增加过滤条件或对节点进行额外评分。
多调度器支持:Kubernetes 允许你运行多个调度器,不同的 Pod 可以通过 schedulerName
字段来指定使用哪个调度器。
为了提高集群效率,调度器需要经过调优,以下是一些常见的调优策略:
调度器的日志非常重要,它可以帮助你理解调度决策并排查问题。常见的调度器日志包括:
另外,你可以使用 Prometheus 等监控工具来监控调度器的行为,捕获调度延迟、调度成功率等关键指标。
Kubernetes 调度器在确保集群资源的高效利用、Pod 的可靠调度和应用程序的可用性方面起到了至关重要的作用。你可以通过调优、监控和扩展来更好地满足不同业务需求。如果你有更多的具体问题或场景,可以进一步讨论!
Kubernetes 的 HPA(Horizontal Pod Autoscaler,水平 Pod 自动伸缩)是 Kubernetes 中的一项核心功能,它允许基于集群的实时负载自动调整工作负载的副本数量,以保证应用的高可用性和弹性。HPA 能根据资源使用情况或自定义指标的变化,自动增加或减少 Pod 数量,从而优化资源利用和应用性能。
HPA 的核心功能是监控某个工作负载(如 Deployment、ReplicaSet 或 StatefulSet)的资源使用情况(例如 CPU、内存)或其他自定义指标,当负载达到某个预定义的阈值时,它会动态调整副本的数量,确保应用具有足够的资源来处理负载变化。
HPA 的主要工作流程如下:
监控指标:HPA 定期(默认 15 秒)通过 Kubernetes 的资源度量 API(Metrics API)或自定义指标 API 收集 Pod 的资源使用情况或自定义指标。
计算副本数:根据预定义的目标值和当前的资源使用情况,HPA 计算出应该增加或减少多少个 Pod。例如,如果 CPU 使用率超过目标值,它会增加 Pod 数量,反之则减少。
更新副本数:HPA 将新计算的副本数量更新到控制器(如 Deployment),以调整 Pod 副本的数量。
使用 HPA 需要定义一个 HPA 资源对象,这个对象指定了:
以下是一个简单的 HPA 配置示例,基于 CPU 使用率自动伸缩:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: myapp-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: myapp-deployment # 需要伸缩的对象
minReplicas: 2 # 最小副本数
maxReplicas: 10 # 最大副本数
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 50 # 目标 CPU 使用率
在上面的配置中:
scaleTargetRef
指定要扩展的资源(Deployment),HPA 会监控这个 Deployment 的 Pod。minReplicas
和 maxReplicas
定义了 Pod 的副本范围,HPA 只能在这个范围内调整副本数。metrics
部分定义了 HPA 监控 CPU 使用率,当使用率超过 50% 时,它会扩展副本数。你也可以基于自定义指标(如应用程序请求数、队列长度等)来定义 HPA。这需要借助外部监控工具如 Prometheus 和自定义指标 API。
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: myapp-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: myapp-deployment
minReplicas: 2
maxReplicas: 10
metrics:
- type: Pods
pods:
metric:
name: custom_requests_per_second # 自定义指标名称
target:
type: AverageValue
averageValue: 100 # 每秒请求数的目标值
在这个示例中,HPA 会基于 custom_requests_per_second
指标来调整副本数。
Metrics Server:HPA 默认通过 Metrics Server 来获取资源使用数据,特别是 CPU 和内存使用率。Metrics Server 是 Kubernetes 内置的资源监控工具,它定期从节点和 Pod 中收集指标。
Custom Metrics API:如果你想要基于自定义指标进行伸缩(例如业务指标、Prometheus 指标等),则需要配置 Custom Metrics API
,并与外部的监控系统(如 Prometheus)集成。
Control Loop:HPA 是一个控制回路(control loop)组件,它会定期评估当前的资源使用情况,并与目标值对比,然后做出决策。如果发现当前使用率超过或低于目标值,HPA 就会相应地增减 Pod 的数量。
HPA 的伸缩逻辑是基于资源使用率的目标值。伸缩算法可以总结为以下公式:
desiredReplicas = ceil(currentReplicas * (currentMetricValue / desiredMetricValue))
例如,如果当前有 5 个 Pod,每个 Pod 的 CPU 使用率为 80%,而目标 CPU 使用率是 50%,则 HPA 将计算出新的副本数量:
desiredReplicas = ceil(5 * (80 / 50)) = ceil(5 * 1.6) = 8
HPA 会将副本数从 5 个增加到 8 个。
Kubernetes 的 HPA 提供了多个高级选项,帮助你更好地管理自动伸缩行为:
冷却时间(Stabilization Window):你可以设置一个冷却时间,避免 HPA 频繁地扩展或缩减副本数。默认情况下,HPA 会在缩减 Pod 数时采用 5 分钟的冷却时间。
behavior:
scaleDown:
stabilizationWindowSeconds: 300 # 5 分钟冷却时间
伸缩速率:你可以限制每次伸缩操作的最大增长或减少幅度,避免过度伸缩导致系统不稳定。
behavior:
scaleUp:
policies:
- type: Percent
value: 50 # 每次最多扩展 50%
periodSeconds: 60
scaleDown:
policies:
- type: Pods
value: 4 # 每次最多缩减 4 个 Pod
periodSeconds: 60
最小副本数与最大副本数:你可以设置最小和最大副本数,防止自动伸缩时 Pod 数过低影响可用性,或过高造成资源浪费。
自定义指标:通过 Custom Metrics API
,你可以使用 Prometheus 等外部系统作为自定义指标数据源。例如,基于请求率或队列长度来调整副本数。
查看 HPA 状态:可以使用以下命令查看 HPA 的当前状态,包括当前副本数、目标值和实际的资源使用情况:
kubectl get hpa
kubectl describe hpa <hpa-name>
监控 HPA:可以使用 Prometheus 和 Grafana 来监控 HPA 的伸缩行为和 Pod 的资源使用情况。
调试问题:如果 HPA 没有按预期工作,常见的故障排查步骤包括:
自动伸缩 Web 服务:对于处理用户请求的 Web 应用,HPA 可以根据 CPU 使用率或请求率自动扩展或缩减副本,确保在高负载时有足够的资源应对流量。
批处理任务:HPA 可以根据任务队列长度或工作负载的数量自动增加 Pod 数量,以加快处理速度。当任务完成后,它会自动缩减副本数。
微服务架构:在微服务架构中,不同服务的负载可能差异较大,HPA 能够为每个服务动态调整副本数,从而优化资源利用率并提高服务的稳定性。
Kubernetes 的 HPA 是实现应用程序自动伸缩的强大工具,通过动态调整 Pod 数量来应对负载波动。它可以基于多种指标(如 CPU、内存、请求数等)来执行自动伸缩操作,帮助你更好地管理资源,提高系统的弹性和可用性。
在 Kubernetes 中,Deployment 和 StatefulSet 是用于管理应用程序的两种不同的控制器。它们都能用来部署和管理应用程序的副本,但它们的工作方式和适用场景不同,尤其是在管理有状态服务(例如 MySQL)时。
Pod 标识(唯一性):
mysql-0
、mysql-1
、mysql-2
)。如果某个 Pod 崩溃,StatefulSet 会重新创建一个同名的 Pod,且该 Pod 会重新绑定到原来的存储卷上。这对有状态应用非常重要,因为它需要持久化存储和固定的 Pod 身份。存储卷的持久化:
emptyDir
或者非持久化存储)。如果 Pod 重新创建,可能会分配到不同的节点,并且使用不同的存储卷,因此无法保证数据的持久性。启动和终止顺序:
mysql-0
启动后,才会启动 mysql-1
),同样,Pod 的删除和更新也遵循同样的顺序。这对有状态服务(如 MySQL 主从架构)非常重要,因为它们需要确保在数据复制、集群管理等方面的一致性和顺序性。网络标识(网络名):
mysql-0
会有一个 mysql-0.<service-name>
的 DNS 记录)。即使 Pod 重新创建,它的 DNS 名称和 IP 地址保持不变。这对有状态服务(如 MySQL 集群)非常有用,因为服务可以通过固定的 DNS 名称找到特定的 Pod。滚动更新(Rolling Updates):
使用 Deployment 部署 MySQL:
使用 StatefulSet 部署 MySQL:
Deployment 适合场景:
StatefulSet 适合场景:
如果要部署 MySQL 这样的有状态服务,应该选择 StatefulSet,这样可以保证 MySQL 的数据持久性、可靠性以及主从架构的一致性。
在 Kubernetes 集群中,CoreDNS 是默认的 DNS 服务,用于为集群内部的服务提供服务发现和名称解析。它通过为集群中的服务、Pod 提供 DNS 解析,帮助这些组件在网络中找到彼此,从而实现通信。
CoreDNS 是 K8S 中的关键组件,负责将集群中的服务名称(如 Service 和 Pod)解析为 IP 地址,允许不同的服务、Pod 通过名称互相通信,而不需要明确使用 IP 地址。
CoreDNS 是一个灵活的 DNS 服务器,通过其配置文件(通常是 Corefile
)定义不同的解析规则。对于 Kubernetes 集群,它的主要功能是解析服务名称并返回相应的服务 IP 地址。
在 K8S 集群中,每个服务创建时,K8S API 会为其生成一个 DNS 名称。这些服务的 DNS 名称通常为 service-name.namespace.svc.cluster.local
,可以通过该名称解析到服务的 ClusterIP(虚拟 IP 地址)。
CoreDNS 主要负责以下工作:
service-name.namespace.svc.cluster.local
。
8.8.8.8
(Google DNS)或者其他公共 DNS 服务器。CoreDNS 使用 Corefile
来配置其行为。在 Kubernetes 中,Corefile 通常会包含处理 cluster.local
域的配置,这是 Kubernetes 内部服务使用的默认域名。
一个典型的 Corefile 可能如下:
.:53 {
errors
health
kubernetes cluster.local in-addr.arpa ip6.arpa {
pods insecure
fallthrough in-addr.arpa ip6.arpa
}
prometheus :9153
forward . /etc/resolv.conf
cache 30
loop
reload
loadbalance
}
:53
:CoreDNS 监听的 DNS 端口,通常是 53 端口。kubernetes cluster.local in-addr.arpa ip6.arpa
:这部分是处理 K8S 内部 DNS 的配置。cluster.local
是 K8S 服务的默认域名。forward
:将无法在集群内部解析的 DNS 请求转发给外部 DNS 服务器,通常指 /etc/resolv.conf
中配置的 DNS。cache 30
:启用 DNS 缓存,缓存 30 秒,减少 DNS 查询负载。loadbalance
:在多个 DNS 响应时,均衡地选择 IP 地址,确保请求被分配到不同的 Pod 实例上。当集群内的一个 Pod 通过服务名称访问另一个服务时,会发起 DNS 请求。CoreDNS 会从 K8S API 获取与该服务对应的 IP 并返回,具体流程如下,以gitlab系统里面的组件通信为例:
CoreDNS
发起 DNS 查询请求。例如,它想访问 gitlab-redis.default.svc.cluster.local
。gitlab-redis
的 ClusterIP
。返回 IP:CoreDNS 将服务的 ClusterIP
返回给发起请求的 Pod,应用程序可以使用这个 IP 地址进行通信。
如果是 Headless Service(即服务没有 ClusterIP),CoreDNS 会返回与服务关联的 Pod 的 IP(即 Endpoints 的 IP)。
如果某个 Pod 发起的 DNS 请求不是针对集群内部的服务,比如查询 google.com
,CoreDNS 会根据 Corefile
中的 forward
配置,将查询请求转发到外部 DNS 服务器(如 /etc/resolv.conf
配置的 DNS 服务器),并将结果返回给 Pod。
Calico 提供了 Pod 间的网络通信,而 CoreDNS 则提供了服务发现和名称解析功能。它们协同工作,为集群内的 Pod 和服务之间提供无缝的通信能力。
例如,GitLab 部署在 K8S 上,GitLab Web Service 需要访问 GitLab Redis。这时,GitLab Web Service 通过服务名称(如 gitlab-redis.default.svc.cluster.local
)来访问 Redis。CoreDNS 解析该名称并返回 Redis 服务的 ClusterIP,Calico 则负责将数据包从 Web Service Pod 路由到 Redis Pod,完成整个通信过程。
CoreDNS 的一个重要特性是其插件化架构,它支持通过插件来扩展其功能。每个 DNS 请求通过 CoreDNS 时,插件会按照配置的顺序处理。
常用的插件包括:
/etc/resolv.conf
)。这些插件使得 CoreDNS 非常灵活,可以根据需要配置各种功能。
当 GitLab 各组件通过 Kubernetes 的 DNS 名称进行通信时,CoreDNS 会发挥作用。例如:
gitlab-redis.default.svc.cluster.local
访问 Redis。它发起 DNS 请求,CoreDNS 解析名称并返回 Redis 的 ClusterIP。gitlab-webservice.default.svc.cluster.local
进行访问。当在 K8S 中遇到 DNS 解析问题时,通常可以采取以下步骤进行排查:
查看 CoreDNS Pod 状态: 通过命令查看 CoreDNS 是否正常运行:
kubectl get pods -n kube-system -l k8s-app=kube-dns
检查 CoreDNS 日志: 查看 CoreDNS 的日志以排查是否有错误:
kubectl logs -n kube-system -l k8s-app=kube-dns
验证 DNS 配置:
使用 Pod 内的工具(如 nslookup
或 dig
)检查 DNS 解析是否正常:
kubectl exec -it <pod-name> -- nslookup gitlab-redis.default.svc.cluster.local
检查 Corefile 配置: 查看 Corefile 配置是否正确,是否存在配置错误:
kubectl get configmap coredns -n kube-system -o yaml
外部 DNS 解析: 如果集群内部的 Pod 无法解析外部域名,可以检查 CoreDNS 是否能够正确转发到外部 DNS 服务器。
CoreDNS 是 Kubernetes 中提供 DNS 服务和服务发现的关键组件,尤其是在像 GitLab 这种多服务、多组件的系统中,它的作用尤为重要。通过 CoreDNS,K8S 中的每个 Pod 和服务可以通过服务名称进行通信
桌面客户端:https://k8slens.dev/
Web 客户端:Rancher
Web 客户端:Kuboard
Web 客户端:Kubesphere
命令行客户端,Krew:https://github.com/kubernetes-sigs/krew
Ingress通过HostPost(80/443)
来对外进行暴露的,可以理解为一种特殊的Service
。
Docker 的实现原理主要基于以下几个关键技术:
Docker 使用 Linux 容器技术来隔离应用。容器与虚拟机不同,虚拟机提供完全的操作系统隔离,而容器共享宿主机操作系统的内核,只隔离应用和应用的运行环境。Linux 的命名空间 (Namespaces) 和控制组 (Control Groups, cgroups) 是实现容器的核心技术。
命名空间用于隔离系统资源,使得每个容器中的进程都认为自己是独立的。例如:
IPC Namespace:隔离进程间通信资源。
这些命名空间的隔离,使得容器看起来像一个独立的操作系统环境。
控制组用于限制和监控资源的使用(如 CPU、内存、磁盘 I/O 等)。每个容器可以分配特定的资源限制,以避免资源滥用和实现高效的资源利用。
Docker 使用联合文件系统(如 AUFS、OverlayFS、btrfs 等)来管理镜像和容器的文件系统。UnionFS 支持对文件系统的分层操作,将多个目录叠加在一起提供一个文件系统视图。镜像由一系列只读的层构成,容器启动时会在其上添加一个可写层。这种分层文件系统使得镜像可以复用,减少了存储空间占用并提高了部署速度。
Docker 使用虚拟网络技术为容器提供网络隔离和连接能力,支持多种网络模式,包括:
None:不分配网络,完全隔离。
Docker 内置了网络插件和 DNS 服务,以实现不同容器和主机之间的网络通信。
Docker 提供多种存储驱动(如 AUFS、OverlayFS、Device Mapper、btrfs 等),通过分层文件系统实现镜像和容器的文件隔离和共享。
Docker 守护进程(dockerd
)运行在宿主机上,负责管理容器的生命周期,包括构建、启动、停止和删除容器。Docker Daemon 通过 REST API 提供服务,客户端通过 Docker CLI 命令与守护进程通信。
在多节点环境中,Docker 使用编排工具(如 Docker Swarm、Kubernetes)管理集群中的容器。编排工具提供容器调度、自动扩缩容、服务发现和负载均衡等功能,提升了容器的可管理性和可扩展性。
Docker Hub 是 Docker 的公共镜像仓库,用于存储和分发容器镜像。开发者可以将构建好的镜像推送到 Docker Hub,用户则可以从 Docker Hub 拉取镜像。此外,也支持私有镜像仓库以满足安全需求。
Docker 利用 Linux 的容器技术、命名空间、控制组、联合文件系统、以及网络虚拟化技术,实现了轻量级的应用隔离和高效的资源利用。容器的镜像和分层文件系统使得应用可以便捷地进行分发和部署,从而加快了开发和运维的流程。Docker 的网络和存储插件体系为容器提供了灵活的网络拓扑和数据持久化解决方案。同时,通过编排工具,Docker 适合在大规模集群环境中管理容器应用。
这些技术相互配合,使 Docker 成为了现代云原生架构和 DevOps 工具链中不可或缺的一部分。
在 Kubernetes (K8S) 集群中,进行故障排查是确保集群稳定性和可用性的重要工作。K8S 提供了一系列工具和方法帮助管理员识别、诊断和解决问题。以下是常用的故障排查步骤和方法:
使用 kubectl get pods
命令查看 Pod 的状态。如果 Pod 处于 Pending
、CrashLoopBackOff
、Error
等状态,说明可能有问题。
kubectl get pods -n <namespace> -o wide
Pending
:表示 Pod 在等待资源的调度,可能是因为资源不足。CrashLoopBackOff
:表示容器不断崩溃和重启,可能是应用问题或环境变量配置错误。ImagePullBackOff
:表示镜像无法拉取,可能是镜像名错误或没有访问权限。使用 kubectl describe pod
查看 Pod 的详细信息,包括事件、容器状态、错误信息等,可以帮助定位问题。
kubectl describe pod <pod-name> -n <namespace>
使用 kubectl logs
查看 Pod 内部容器的日志,日志通常包含错误信息和诊断信息。
kubectl logs <pod-name> -n <namespace> --container <container-name>
--container
指定容器名称。-f
选项实时查看日志流动,以监控当前日志输出。使用 kubectl get services
和 kubectl describe service
检查服务配置和状态,以确认服务是否正确创建以及是否正确暴露了端口。
ClusterIP
或 NodePort
是否正确配置。确认服务的 Endpoints
是否指向了正确的 Pod。
kubectl get svc -n <namespace>
kubectl describe svc <service-name> -n <namespace>
使用 kubectl get deployment
、kubectl describe deployment
等命令检查 Deployment、ReplicaSet 的状态,确认副本数量、滚动更新状态等是否正常。
kubectl get deployment -n <namespace>
kubectl describe deployment <deployment-name> -n <namespace>
使用 kubectl get nodes
检查集群中节点的状态,确保节点处于 Ready
状态。如果节点不可用,会导致 Pod 无法调度。
kubectl get nodes
kubectl describe node <node-name>
Pod 和容器可以配置资源限制(如 CPU 和内存),如果配置不当会导致资源不足或频繁 OOM 重启。可以使用以下命令查看 Pod 配置的资源限制:
kubectl describe pod <pod-name> -n <namespace>
Limits
和 Requests
的配置,确保合理分配资源。网络问题会导致 Pod 之间、服务之间通信异常,可以使用以下方法检查网络:
kubectl exec
进入 Pod 中,检查 DNS 解析是否正常。Ping 检测:使用 kubectl exec
在 Pod 中尝试 ping 其他 Pod 或 Service 的 IP,检查连通性。
kubectl exec -it <pod-name> -n <namespace> -- nslookup <service-name>
Kubernetes 中的事件日志可以帮助定位问题,尤其是资源调度和 Pod 生命周期管理相关的问题。
kubectl get events -n <namespace>
kubectl describe pod
查看事件时,如果事件较多,可以通过事件日志筛选更详细的信息。Kubernetes 的控制组件(如 API Server、Scheduler、Controller Manager)运行在 Master 节点上,可以查看这些组件的日志以获取更多诊断信息。
Controller Manager:负责管理控制器状态(如 Deployment、ReplicaSet 等)。
示例:
journalctl -u kubelet -f # 查看 Kubelet 的日志
journalctl -u kube-apiserver # 查看 API Server 的日志
如果 Pod 挂载的存储(如 PVC)存在问题,可能会导致 Pod 卡在 ContainerCreating
或 Pending
状态。
Bound
。检查 PV 状态:确保 PV 已绑定到 PVC。
kubectl get pvc -n <namespace>
kubectl describe pvc <pvc-name> -n <namespace>
kubectl debug
命令启动调试容器,对有问题的 Pod 进行深入排查。在故障排查过程中,经常会遇到配置错误导致资源创建失败或状态异常。在 K8S 中,许多资源的创建都是通过 YAML 文件定义的。我们可以使用以下方法检查配置文件是否有误:
kubectl apply --dry-run=client -f <file.yaml>
来检查 YAML 文件格式是否正确。K8S 中的资源往往具有依赖关系。例如,Deployment 依赖于 Pod,Service 依赖于 Pod 和 Endpoints。如果一个资源出现问题,可能会影响其他相关资源:
Kubernetes 提供了 kubectl debug
功能,可以创建临时的调试容器。在需要深入排查应用环境或配置的场景下,可以使用 kubectl debug
进入 Pod 并执行特定调试操作。
kubectl debug -it <pod-name> --image=busybox --target=<container-name>
这种方式可以帮助你排查网络连接、权限问题、环境变量等。
网络故障是 K8S 中的常见问题之一,尤其是在使用不同的网络插件时。以下是几种网络排查的方法:
kubectl exec
进入 Pod,并执行 ping 和 nslookup 测试其他服务或外部网络的连接性。tcpdump
抓包,检查流量数据包,分析网络通信异常。如果集群中已经部署了 Prometheus 和 Grafana 之类的监控工具,可以通过它们来查看集群资源的运行情况,进一步分析系统的瓶颈和异常:
日志可以为故障排查提供丰富的线索。建议使用集中化的日志收集和分析工具(如 ELK 或 Loki)来管理 K8S 集群的日志数据:
kubectl logs
命令查看应用日志,排查特定应用的运行错误和异常信息。如果问题难以排查或偶发,尝试在开发环境或测试集群中复现问题,有助于精确诊断。可以通过以下方式进行测试:
故障排查不仅仅是处理问题,更重要的是预防问题。以下是一些常见的故障预防措施:
Limits
和 Requests
,防止单个 Pod 占用过多资源影响集群。Kubernetes 故障排查涉及多个方面,从基础的 Pod、Service 状态检查,到日志分析、网络排查,再到利用监控系统和自动化工具进行全面诊断。每个步骤都可以帮助我们深入了解系统的健康状态,定位故障的根源。
在 Kubernetes (K8S) 中,Pod 调度是指将 Pod 分配到合适的节点上运行的过程。K8S 的调度器负责决定每个 Pod 应该被分配到哪个节点,调度策略和规则有助于实现资源的有效分配、应用的高可用性等。以下是 K8S 中 Pod 的调度方法和策略:
nodeSelector
是一种简单的调度方法,用于将 Pod 限制到具有特定标签的节点上。可以在 Pod 的 YAML 配置中使用 nodeSelector
字段指定目标节点的标签。
示例:
apiVersion: v1
kind: Pod
metadata:
name: example-pod
spec:
nodeSelector:
disktype: ssd # 只有带有 "disktype=ssd" 标签的节点会被选择
containers:
- name: nginx
image: nginx
这种方法适合简单的场景,但不够灵活,主要用在标签匹配的静态调度场景。
nodeAffinity
是 nodeSelector
的增强版,提供了更多条件组合和灵活性。nodeAffinity
支持三种不同的条件:
requiredDuringSchedulingIgnoredDuringExecution
:调度时必须满足条件,不满足则 Pod 不会被调度到该节点上。preferredDuringSchedulingIgnoredDuringExecution
:调度时优先满足条件,但不是强制性的,调度器会尽量满足。requiredDuringSchedulingRequiredDuringExecution
(Alpha) :调度和运行时都强制要求满足条件。示例:
apiVersion: v1
kind: Pod
metadata:
name: example-pod
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: disktype
operator: In
values:
- ssd
containers:
- name: nginx
image: nginx
nodeAffinity
更加灵活,可以实现按需资源分配和分布策略控制。
Pod Affinity
和 Pod Anti-Affinity
用于控制 Pod 与其他 Pod 的分布。
示例:
apiVersion: v1
kind: Pod
metadata:
name: example-pod
spec:
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- web-server
topologyKey: "kubernetes.io/hostname" # 在同一主机上
containers:
- name: nginx
image: nginx
Pod Anti-Affinity
常用于确保关键应用实例分布在不同节点上,以防止单点故障。
Taints
和 Tolerations
是一种节点隔离策略,用于防止不符合条件的 Pod 被调度到指定节点上。管理员可以在节点上设置污点 (taint
),只有包含相应 tolerations
的 Pod 才能被调度到该节点上。
示例:
给节点添加污点:
kubectl taint nodes <node-name> key=value:NoSchedule
Pod 配置容忍度:
apiVersion: v1
kind: Pod
metadata:
name: example-pod
spec:
tolerations:
- key: "key"
operator: "Equal"
value: "value"
effect: "NoSchedule"
containers:
- name: nginx
image: nginx
Taints and Tolerations
非常适用于划分节点池和控制特定工作负载的调度。
Pod 在定义容器时,可以设置 requests
和 limits
,用于资源调度时的要求:
requests
表示最低资源需求,调度器会选择满足这些请求的节点。limits
表示资源上限,用于运行时限制资源。示例:
apiVersion: v1
kind: Pod
metadata:
name: example-pod
spec:
containers:
- name: nginx
image: nginx
resources:
requests:
cpu: "500m"
memory: "128Mi"
limits:
cpu: "1"
memory: "256Mi"
资源请求与限制可以帮助 K8S 在调度时选择符合资源要求的节点,避免资源不足或浪费。
K8S 支持基于优先级的调度,在资源紧张时,优先级高的 Pod 可以优先调度,甚至可以驱逐低优先级的 Pod。
示例:
创建一个高优先级的 PriorityClass:
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: high-priority
value: 1000
globalDefault: false
description: "This is a high priority class"
在 Pod 中指定优先级:
apiVersion: v1
kind: Pod
metadata:
name: example-pod
spec:
priorityClassName: high-priority
containers:
- name: nginx
image: nginx
优先级调度可以确保关键任务在资源紧张时优先运行。
Kubernetes 支持自定义调度器,管理员可以根据需求实现自定义的调度逻辑。例如,可以通过编写自定义调度器实现基于特定策略的调度行为。
schedulerName
,告知 K8S 使用特定调度器。示例:
apiVersion: v1
kind: Pod
metadata:
name: example-pod
spec:
schedulerName: my-custom-scheduler
containers:
- name: nginx
image: nginx
Topology Spread Constraints
是一种可以控制 Pod 在不同拓扑域(如区域或可用区)之间均匀分布的调度策略,适用于高可用性要求较高的场景。
示例:
apiVersion: v1
kind: Pod
metadata:
name: example-pod
spec:
topologySpreadConstraints:
- maxSkew: 1
topologyKey: "topology.kubernetes.io/zone"
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
app: web-server
containers:
- name: nginx
image: nginx
Topology Spread Constraints
可确保 Pod 在不同区域或节点均匀分布,从而提高容错性。
K8S 提供了多种调度方法来满足不同的调度需求,包括:
nodeSelector
标签选择nodeAffinity
和 podAffinity
Taints and Tolerations
实现节点隔离PriorityClass
实现优先级调度Topology Spread Constraints
控制跨区域的高可用性这些调度策略可以单独使用,也可以组合使用,以实现最佳的 Pod 调度
在 Kubernetes 和现代应用程序的交付过程中,有多种发布策略可以用来部署和更新应用程序。不同的发布策略适用于不同的场景和需求,选择合适的策略可以在确保稳定性的同时,提升用户体验。以下是常见的发布策略:
滚动更新是 Kubernetes 中默认的发布策略,通过逐步替换旧版本的 Pod 为新版本,从而实现无中断更新。在更新过程中,K8S 控制器会逐个地删除旧的 Pod,并创建新的 Pod。
配置示例:
在 Deployment 中指定 strategy
为 RollingUpdate
:
apiVersion: apps/v1
kind: Deployment
metadata:
name: example-deployment
spec:
replicas: 3
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 1
template:
spec:
containers:
- name: app
image: example-app:v2
重建发布策略是一种“替换式”的策略,即先终止所有旧版本的 Pod,然后再启动新版本的 Pod。这种策略适用于对中断不敏感的应用场景。
配置示例:
在 Deployment 中指定 strategy
为 Recreate
:
apiVersion: apps/v1
kind: Deployment
metadata:
name: example-deployment
spec:
strategy:
type: Recreate
template:
spec:
containers:
- name: app
image: example-app:v2
蓝绿部署通过创建两个完全独立的环境(通常称为蓝色环境和绿色环境)来进行发布,确保旧版本和新版本环境互相隔离。更新时先在绿色环境中部署新版本,然后在切换流量前进行验证,一旦验证通过,切换所有流量到新版本。
实现方法:
在 Kubernetes 中可以通过使用两个 Deployment(蓝色和绿色)结合服务切换来实现。
金丝雀发布是一种渐进式发布策略,通过将新版本发布给部分用户进行测试,逐步增加新版本的流量,直到所有流量都切换到新版本。这样可以在小范围内验证新版本的稳定性,逐步推广更新。
实现方法:
可以通过 Kubernetes 的 Deployment 配合 Service 或 Istio 等服务网格工具进行金丝雀流量的控制。
A/B 测试策略类似于金丝雀发布,但主要用于同时运行多个版本来测试不同功能或配置的效果。用户会被分配到不同版本上,以收集用户反馈或行为数据,从而确定最佳版本。
实现方法:
可以通过服务网格(如 Istio 或 Linkerd)来实现不同流量策略。
分阶段发布是一种分批发布的策略,将整个更新过程分为多个阶段,每个阶段逐步增加新版本的 Pod 数量。每一阶段结束后进行验证,确保没有问题再进入下一阶段。
实现方法:
可以在 Kubernetes 中通过配置 Deployment 的 RollingUpdate
策略,并结合流量控制工具来逐步增加更新的范围。
影子发布是在生产环境中将真实的用户流量“影射”到新版本上,但不对用户产生实际影响。影子发布的流量仅用于测试和验证新版本的稳定性,不会影响到现有的生产版本。
实现方法:
通常需要使用 API 网关或服务网格(如 Istio),将流量复制到新版本的 Pod。
无中断发布是一种确保发布过程对用户透明的策略,通过合理的调度策略、健康检查和负载均衡来实现发布过程中的服务不中断。滚动更新、金丝雀发布和蓝绿部署都是实现无中断发布的常见方式。
不同的发布策略在实际使用中各有优缺点,选择合适的发布策略应根据应用的特性、用户需求和资源成本来决定:
这些发布策略可以单独使用,也可以组合使用。比如,可以先进行影子发布测试新版本,然后使用金丝雀发布逐步引入流量,最后使用蓝绿部署进行全量切换。这些组合能够在确保服务稳定性的同时,灵活地满足不同的发布需求。
在 Kubernetes 中,pause 容器是一种特殊的容器,它通常作为 Pod 的“基础容器”存在。它有以下主要作用和意义:
网络命名空间:每个 Pod 在 Kubernetes 中共享一个网络命名空间。Pod 中的所有容器都可以通过 localhost
互相通信。
pause
容器负责初始化和持有网络命名空间,确保 Pod 中的其他容器可以共享网络配置。pause
容器,Pod 中的每个容器都需要自己管理网络命名空间,增加复杂性。其他命名空间:如 PID、IPC 等,pause
容器也负责持有这些命名空间。
pause
容器作为 Pod 的生命周期主控容器,确保 Pod 的网络、存储和其他资源在 Pod 的主容器重启时仍然保持有效。pause
容器的存在可以确保网络和命名空间不被破坏。pause
容器交互来配置网络,而不是直接与业务容器交互。pause
容器非常轻量化,通常使用一个小型镜像(如 pause:3.9
),几乎不消耗额外的资源。sleep infinity
或一个空循环),目的是维持命名空间的有效性。k8s.gcr.io/pause
# pause 容器运行的简单代码示例
int main() {
pause();
return 0;
}
pause
容器在 Kubernetes 中是 Pod 资源隔离的基础,它负责:
虽然它本身不起眼,但在 Kubernetes 的资源管理和调度中扮演了重要角色。
在 Kubernetes 中,静态 Pod 是一种特殊类型的 Pod,它由 Kubelet 直接管理,而不是通过 Kubernetes API Server 创建或管理。它适用于需要直接运行在某个节点上的关键组件或独立服务。
由 Kubelet 管理:
文件定义:
/etc/kubernetes/manifests
)。无 ReplicaSet 或 Deployment:
自动注册到 API Server:
status
)。运行关键组件:
etcd
、kube-apiserver
、kube-scheduler
等),尤其是在高可用集群中。节点专属任务:
不依赖控制平面:
确定静态 Pod 的存储路径:
--pod-manifest-path
,用于指定静态 Pod 文件的目录(例如 /etc/kubernetes/manifests
)。编写 Pod 配置文件:
apiVersion: v1
kind: Pod
metadata:
name: static-pod-example
namespace: default
spec:
containers:
- name: static-container
image: nginx:latest
ports:
- containerPort: 80
将配置文件放置到指定目录:
--pod-manifest-path
所指定的目录中。Kubelet 自动管理:
独立性强:
适合节点级别的关键任务:
简单性:
管理复杂性:
调试困难:
不支持高级功能:
静态 Pod 是 Kubernetes 中一种特殊的运行方式,主要用于关键组件和节点级别的任务。它由 Kubelet 直接管理,适合需要独立于控制平面运行的场景,但在管理能力和灵活性上不如常规 Pod。
在 Kubernetes 中,Pod 是由一个或多个容器组成的,容器在执行过程中可能会因为各种原因退出。Kubernetes 使用容器的退出码(exit code)来表示容器的执行状态和退出原因。退出码是操作系统提供的标准方式,用于指示程序的终止状态。
每个容器在运行过程中都可以退出,并且退出时会返回一个退出码。退出码是一个整数,用于标识容器是否成功执行,或者失败的具体原因。
退出码 0:
退出码 1:
退出码 137:
SIGKILL
信号发送给容器,可能是因为资源限制(如内存限制)超出了容器的资源请求。退出码 139:
退出码 143:
SIGTERM
信号,通常是 Kubernetes 或用户手动停止了容器时发生的。SIGTERM
信号,请求容器优雅地关闭。如果容器在一定时间内没有响应,Kubernetes 会发送 SIGKILL
强制终止容器。退出码 255:
Kubernetes 会将容器的退出码和其他信息记录在 Pod 的状态中。你可以通过 kubectl
命令查看容器的状态,包括退出码。
例如,查看 Pod 的详细状态:
kubectl describe pod <pod-name>
输出中会包括容器的状态,例如:
Containers:
<container-name>:
Container ID: docker://<container-id>
Image: <image-name>
Image ID: <image-id>
Port: <port>
State: Terminated
Reason: Completed
Exit Code: 0
Kubernetes 提供了通过 Pod 状态查看容器退出码的能力。利用这些退出码,你可以进行故障排除,快速确定容器退出的原因。
kubectl logs <pod-name> -c <container-name>
)来诊断问题。Kubernetes 允许为 Pod 设置重启策略,通常有以下三种:
通过合理的重启策略,可以确保容器根据退出状态适当地进行重启。
Kubernetes 中的 Pod 退出码是容器执行结果的一个重要指标,帮助开发者了解容器是否成功运行,或者在发生错误时追踪问题的根本原因。通过查看容器的退出码和日志,用户可以迅速定位并解决问题。
下面是一个实际生产可用的deployment.yml
和 service.yml
, CI/CD的过程就是生成对应的K8S
apiVersion: apps/v1 # 使用 apps/v1 API 版本来定义部署。
kind: Deployment # 定义资源类型为 Deployment。
metadata:
name: dcspp-mgmt--deployment--a # Deployment 的名称,唯一标识该部署对象。
namespace: channels-istio # 指定该 Deployment 属于的 Kubernetes 命名空间。
labels: # 用于标识和组织资源的标签。
app: dcspp-mgmt-a # 定义标签 app,其值为 dcspp-mgmt-a,用于选择 Pod。
spec:
minReadySeconds: 10 # Pod 准备好后的等待时间(秒),保证稳定性。
progressDeadlineSeconds: 600 # 最大等待时间(秒),若超出则标记为失败。
replicas: 6 # 指定创建的 Pod 副本数。
revisionHistoryLimit: 2 # 保留的旧版本数量,最多保留 2 个历史版本。
selector:
matchLabels:
app: dcspp-mgmt-a # Pod 选择器,根据标签 app=dcspp-mgmt-a 来匹配 Pods。
strategy:
type: RollingUpdate # 使用滚动更新策略,逐步替换旧版 Pod。
rollingUpdate:
maxSurge: 50% # 在更新期间允许的最大额外 Pod 数量(百分比)。
maxUnavailable: 0 # 更新期间不可用的最大 Pod 数量为 0,确保无停机。
template: # Pod 模板定义
metadata:
annotations:
prometheus.io/path: /metrics # 指定 Prometheus 的监控路径
prometheus.io/port: "5556" # Prometheus 的监控端口
prometheus.io/scrape: "true" # 启用 Prometheus 数据抓取
labels:
app: dcspp-mgmt-a # Pod 的标签,用于服务发现和选择
artifactId: dcspp-mgmt # 指定构件 ID
slot: a # 槽位标签,用于区分不同版本
version: 60009.0.0 # 应用版本
spec:
affinity: # 节点亲和性设置
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: type # 指定要调度的节点类型
operator: In # 要求节点标签 type 的值必须在下面的列表中
values:
- app # 匹配 type=app 的节点
containers: # 容器定义
- name: dcspp-mgmt--deployment--a # 容器名称
image: bruce.du.me/pre-releases/dcspp/dcspp-mgmt:60009.0.0-beta.9 # 容器镜像
imagePullPolicy: Always # 每次都拉取最新镜像
ports:
- containerPort: 8080 # 容器监听的第一个端口(8080),命名为 8080tcp2,协议为 TCP
name: 8080tcp2
protocol: TCP
- containerPort: 6300 # 容器监听的第二个端口(6300),协议为 TCP
name: 6300tcp2
protocol: TCP
- containerPort: 5556 # Prometheus 监控端口(5556)
name: 5556tcp2
protocol: TCP
env: # 环境变量定义
- name: POD_IP # Pod IP 地址
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: status.podIP
- name: POD_NAME # Pod 名称
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- name: VERSION # 应用版本
value: 60009.0.0-beta.9+1daac54
livenessProbe: # 活性探针配置,用于监控容器的健康状态
httpGet:
path: dcspp-mgmt/ping # 访问路径
port: 8080 # 访问端口
scheme: HTTP # 使用 HTTP 协议
initialDelaySeconds: 30 # 初始延迟时间(秒)
periodSeconds: 10 # 探测周期(秒)
timeoutSeconds: 10 # 探测超时时间(秒)
readinessProbe: # 就绪探针配置,确保容器可接收流量
httpGet:
path: dcspp-mgmt/ping
port: 8080
scheme: HTTP
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 10
resources: # 容器资源限制
limits:
cpu: "1" # 限制容器 CPU 使用量为 1 个核
memory: 1Gi # 内存限制为 1 GiB
requests:
cpu: 50m # 最小 CPU 请求量 50 毫核
memory: 512Mi # 最小内存请求量 512 MiB
volumeMounts: # 挂载卷定义
- mountPath: /opt/pod # 主机路径卷挂载到 /opt/pod
name: host-path
- mountPath: /opt/app-cert # 证书卷挂载到 /opt/app-cert
name: cacerts
- mountPath: /opt/dcspp # NFS 卷挂载到 /opt/dcspp
name: nfs-volume-1
volumes: # 卷定义
- name: host-path # 定义主机路径卷
hostPath:
path: /data/logs/dcspp/dcspp-mgmt # 主机上日志目录路径
type: DirectoryOrCreate # 若目录不存在则创建
- name: cacerts # 定义证书密钥卷
secret:
secretName: baidu-cert # 使用名为 baidu-cert 的 Secret
items:
- key: tls.crt # Secret 中的密钥条目
path: tls-uat.crt # 在容器中保存的路径
- name: nfs-volume-1 # 定义 NFS 卷
nfs:
path: /data/application/data/dcspp # NFS 路径
server: bjdck8snfs01.me # NFS 服务器地址
apiVersion: v1 # API 版本为 v1,表示使用 Kubernetes 核心 API 组中的 v1 版本
kind: Service # 定义资源类型为 Service,用于在 Kubernetes 集群中暴露服务
metadata:
name: dcspp-mgmt # 服务的名称,唯一标识该 Service
namespace: channels-istio # 命名空间(namespace),用于隔离资源
labels:
artifactId: dcspp-mgmt # 标签,用于标识和选择特定应用的资源
spec:
ports: # 定义服务的端口映射
- name: default # 端口的名称,用于在应用内部引用
port: 80 # 服务的端口号,客户端连接服务时使用此端口
protocol: TCP # 传输协议类型,TCP 是常见的默认选项
targetPort: 8080 # 后端容器的端口号,与应用容器中的端口对应
- name: jacoco # 另一个端口名称,提供其他服务(例如测试覆盖率服务)
port: 6300 # 服务的端口号,客户端连接服务时使用此端口
protocol: TCP # 传输协议为 TCP
targetPort: 6300 # 后端容器的端口号,与应用容器中的端口对应
selector:
artifactId: dcspp-mgmt # 选择标签,用于将该服务与相同标签的 Pod 关联,使服务流量导向符合条件的 Pod
sessionAffinity: None # 会话亲和性配置为 None,表示不绑定特定客户端到特定 Pod
type: ClusterIP # 服务类型为 ClusterIP,默认类型,服务只在集群内部可访问
1. Kubernetes 基础知识
Q1: 什么是Kubernetes?Kubernetes主要解决了哪些问题?
回答要点:
Q2: 描述一下Kubernetes中的主要组件及其作用?
回答要点:
Q3: 什么是Pod?为什么Pod是Kubernetes的基础单位?
回答要点:
Q4: 什么是ReplicaSet,Deployment与StatefulSet之间的区别?
回答要点:
Q5: ConfigMap和Secret有什么区别?
回答要点:
2. 集群管理
Q6: 描述一下Kubernetes的调度策略。
回答要点:
Q7: 什么是Taints和Tolerations?
回答要点:
Q8: 如何在Kubernetes中进行滚动更新和回滚?
回答要点:
kubectl apply
或kubectl set image
命令修改Deployment资源。kubectl rollout undo
命令可以回滚到之前的Deployment版本。Q9: Kubernetes中的Service有哪几种类型?分别有什么作用?
回答要点:
Q10: 如何对K8S集群进行自动伸缩(Horizontal Pod Autoscaling, HPA)?
回答要点:
kubectl autoscale deployment <deployment_name> --cpu-percent=80 --min=1 --max=10
设置。3. 高级主题
Q11: 在Kubernetes中,如何管理存储?PersistentVolume和PersistentVolumeClaim有什么作用?
回答要点:
Q12: 如何在Kubernetes中实现安全性?如何进行网络隔离?
回答要点:
Ingress
和Egress
规则限制特定的流量。Q13: 什么是Kubernetes的Ingress?如何配置HTTPS的Ingress?
回答要点:
kubectl create secret tls <secret_name> --cert=<cert_path> --key=<key_path>
创建TLS Secret。Q14: Helm是什么?它是如何工作的?
回答要点:
helm install
命令安装Chart。Q15: 如何备份和恢复Kubernetes集群中的etcd数据?
回答要点:
etcdctl snapshot save <backup_name>
命令备份etcd数据。etcdctl snapshot restore <backup_name>
命令恢复etcd。4. Kubernetes故障排查与优化
Q16: 当Pod状态为CrashLoopBackOff时,如何进行故障排查?
回答要点:
kubectl describe pod <pod_name>
和kubectl logs <pod_name>
查看详细的错误信息。Q17: 如何监控Kubernetes集群的运行状况?
回答要点:
kubectl top nodes
和kubectl top pods
命令查看实时资源使用情况。Q18: 如何管理多个Kubernetes集群?
回答要点:
kubeconfig
文件来管理多个集群。kubectl config use-context <context_name>
来切换不同集群的上下文。Q19: 你如何优化Kubernetes集群的性能?
回答要点:
Q20: 如何在Kubernetes中进行日志收集和集中管理?
回答要点: