k8s学习笔记
管理集群
安装网络插件
如果要让pod可以相互通信,必须安装网络插件
网络必须在所有应用程序之前部署。并且,在安装网络之前CoreDNS不会启动。kubeadm仅支持基于容器网络接口(CNI)的网络(不支持kubenet)。
一些项目使用CNI提供Kubernetes Pod网络,其中一些还支持网络策略(Network Policy)。
附件页面里有所有可用的网络插件,如果要快速安装可以看这里
例:使用Calico作为网络插件
Calico默认使用 192.168.0.0/16
作为CIDR(Classless Inter-Domain Routing,无类域间路由选择),需要在执行 kubeadm init
命令时配置Calico的CIDR:
kubeadm init --apiserver-advertise-address master的IP --pod-network-cidr 192.168.0.0/16
然后应用网络插件(插件中的CIDR必须与上面配置的一致)
kubectl apply -f https://docs.projectcalico.org/v3.11/manifests/calico.yaml
安装完之后,可以看看下面命令的输出中的CoreDNS Pod是否正在运行来确认其是否正常工作
kubectl get pods --all-namespaces
使用k8s API访问集群
要访问集群,需要知道集群位置并拥有凭证,使用下面的命令检查kubectl已知的位置和凭证
kubectl config view
直接访问REST API
kubectl 处理对 API 服务器的定位和身份验证。如果想通过 http 客户端(如 curl
或 wget
,或浏览器)直接访问 REST API,可以通过多种方式对 API 服务器进行定位和身份验证:
- 以代理模式运行 kubectl(推荐)。 使用存储的 apiserver 位置并使用自签名证书验证 API 服务器的标识。可以防止中间人(MITM)攻击。
- 另外,也可以直接为 http 客户端提供位置和身份认证。这适用于被代理混淆的客户端代码。为防止中间人攻击,您需要将根证书导入浏览器。
使用kubectl代理
运行kubectl的反向代理来处理API请求
kubectl proxy --port=8080 &
然后就可以通过 curl,wget,或浏览器访问 API:
curl http://localhost:8080/api/
输出类似如下:
{
"versions": [
"v1"
],
"serverAddressByClientCIDRs": [
{
"clientCIDR": "0.0.0.0/0",
"serverAddress": "10.0.1.149:443"
}
]
}
不使用 kubectl 代理
将身份认证令牌直接传给 API 服务器,可以避免使用 kubectl 代理:
使用 grep/cut
方式:
# 检查所有可用的集群,因为 .KUBECONFIG 可能有多个上下文:
kubectl config view -o jsonpath='{"Cluster name\tServer\n"}{range .clusters[*]}{.name}{"\t"}{.cluster.server}{"\n"}{end}'
# 从上面的输出中选择你要进行交互的集群名:
export CLUSTER_NAME="some_server_name"
# 选择指定集群的API服务器
APISERVER=$(kubectl config view -o jsonpath="{ .clusters[?(@.name==\"$CLUSTER_NAME\")].cluster.server}") # 获取令牌的值 TOKEN=$(kubectl get secrets -o jsonpath="{ .items[?(@.metadata.annotations['kubernetes\.io/service-account\.name']=='default')].data.token}"|base64 -d)
# 持令牌访问API
curl -X GET $APISERVER/api --header "Authorization: Bearer $TOKEN" --insecure
输出类似如下:
{
"kind": "APIVersions",
"versions": [
"v1"
],
"serverAddressByClientCIDRs": [
{
"clientCIDR": "0.0.0.0/0",
"serverAddress": "10.0.1.149:443"
}
]
}
使用 jsonpath
方式:
$ 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 )
$ curl $APISERVER/api --header "Authorization: Bearer $TOKEN" --insecure
{
"kind": "APIVersions",
"versions": [
"v1"
],
"serverAddressByClientCIDRs": [
{
"clientCIDR": "0.0.0.0/0",
"serverAddress": "10.0.1.149:443"
}
]
}
使用 --insecure
标志位会导致易受到 MITM 攻击。当 kubectl 访问集群时,会使用存储的根证书和客户端证书访问服务器(已安装在 ~/.kube
目录下)。由于集群认证通常是自签名的,因此可能需要特殊设置才能使 http 客户端使用根证书。
在一些集群中,API 服务器不需要身份认证;它运行在本地,或由防火墙保护着。配置对 API 的访问 里会说集群管理员如何对此进行配置。这种方法可能与未来的高可用性支持发生冲突。
编程方式访问 API
Kubernetes 官方支持 Go 和 Python 的客户端库.
例:python客户端
安装:pip install kubernetes
(详见 Python 客户端库主页 )。
Python 客户端可以使用与 kubectl 命令行工具相同的 kubeconfig 文件 进行验证:
from kubernetes import client, config
config.load_kube_config()
v1=client.CoreV1Api()
print("Listing pods with their IPs:")
ret = v1.list_pod_for_all_namespaces(watch=False)
for i in ret.items:
print("%s\t%s\t%s" % (i.status.pod_ip, i.metadata.namespace, i.metadata.name))
其他语言
详见 客户端库 。
从 Pod 中访问 API
最简单的方法就是使用一个官方的 客户端库。这些库可以自动发现 API 服务器并进行身份验证。
客户端在运行在 Pod 中时,可以通过 default
命名空间中的名为 kubernetes
的服务访问 Kubernetes apiserver。也就是说,Pods 可以使用 kubernetes.default.svc
主机名来查询 API 服务器。官方客户端库自动完成这个工作。
从 Pod 中向 API 服务器进行身份认证的推荐做法是使用 服务账号 凭证。一个 Pod 默认与一个服务账号关联,该服务账号的凭证放置在此 Pod 中每个容器的文件系统树中的 /var/run/secrets/kubernetes.io/serviceaccount/token
处。
如果可用,凭证包被放入每个容器的文件系统树中的 /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
处,并且将被用于验证 API 服务器的服务证书。
最后,用于命名空间 API 操作的默认的命名空间放置在每个容器中的 /var/run/secrets/kubernetes.io/serviceaccount/namespace
文件中。
从一个 Pod 内,连接 Kubernetes API 的推荐方法是:
- 使用官方的 客户端库 因为他们会自动地完成 API 主机发现和身份认证。以 Go 客户端来说,
rest.InClusterConfig()
可以帮助解决这个问题。参见 这里的一个例子。 - 如果您想要在没有官方客户端库的情况下查询 API,可以在 Pod 里以一个新容器的 命令的方式运行
kubectl proxy
。此方式下,kubectl proxy
将对 API 进行身份验证并将其公开在 Pod 的localhost
接口上,以便 Pod 中的其他容器可以直接使用它。
所有情况下,Pod 的服务账号凭证都可以用于与 API 服务器的安全通信。
访问集群中运行的服务
从集群外连接nodes、pods、services
nodes、pods 和 services 都有它们自己的 IP。一般情况下,集群上的 node IP、pod IP 和某些 service IP 路由不可达,所以不能从集群外的节点访问它们(比如自己电脑)。开发者一般不需要通过节点 IP 直接访问 nodes。
从集群外连接nodes、pods、services有以下方式:
通过公共 IP 访问 services。
- 具有
NodePort
或LoadBalancer
类型的 service 可以从外部访问。参考 services 和 kubectl expose 文档。 - 取决于你的集群环境,可以仅把 service 暴露在你的企业网络中,也可以将其暴露在公共网络上。需要考虑暴露的 service 是否安全,它是否有自己的用户认证?
- 将 pods 放在 services 中。可以给一些 pod 指定特殊的标签并创建一个新 service 选择这个标签。
- 具有
通过 Proxy Verb 访问 services、nodes 或者 pods。
- 应用场景:服务暴露在公有网络中不安全时,或需要获取 node IP 之上的端口,或者处于调试目的。
- Proxies 可能给某些应用带来麻烦。
- 仅适用于 HTTP/HTTPS。
- 详见这里
从集群中的 node 或者 pod 访问。
- 运行一个 pod,然后使用 kubectl exec 连接到它的shell。从 shell 连接其他的 nodes、pods 和 services。
- 某些集群可能允许你 ssh 到集群中的节点。你或许可以从那里访问集群服务。非标准方式,是否工作取决于环境。
访问内置服务
一般 kube-system 会启动集群中的几个服务。
取得 service 的代理 URL:
kubectl cluster-info
会显示访问每个服务的 proxy-verb URL。提供凭据即可访问。
手动构建 apiserver 代理 URLs
要创建包含 service endpoints、suffixes 和 parameters 的代理 URLs,可以在 service 的代理 URL中 添加: http://kubernetes_master_address/api/v1/namespaces/namespace_name/services/service_name[:port_name]/proxy
如果没有为端口指定名称,可以不用在 URL 中指定 port_name。
示例
- 通过
http://104.197.5.247/api/v1/namespaces/kube-system/services/elasticsearch-logging/proxy/_search?q=user:kimchy
访问 Elasticsearch service endpoint_search?q=user:kimchy
。 通过
https://104.197.5.247/api/v1/namespaces/kube-system/services/elasticsearch-logging/proxy/_cluster/health?pretty=true
访问 Elasticsearch 集群健康信息 endpoint_cluster/health?pretty=true
。{
"cluster_name" : "kubernetes_logging",
"status" : "yellow",
"timed_out" : false,
"number_of_nodes" : 1,
"number_of_data_nodes" : 1,
"active_primary_shards" : 5,
"active_shards" : 5,
"relocating_shards" : 0,
"initializing_shards" : 0,
"unassigned_shards" : 5
}
通过 web 浏览器访问集群中运行的服务
可以用浏览器访问 apiserver 代理的 url ,不过:
- Web 服务器并非总是能够传递令牌,所以你可能需要使用密码认证。 Apiserver 可以配置为接受密码认证,但集群可能会没有这样配置。
- 某些 web 应用可能不能工作,特别是那些使用客户端侧 javascript 的应用,它们构造 url 的方式可能不能解析代理路径前缀。
在集群中自动缩放DNS服务
需要开启DNS功能,且节点使用的是AMD64或Intel 64 CPU架构
查看是否启用DNS水平自动缩放:
kubectl get deployment --namespace=kube-system
如果启用了,输出中会看到“dns-autoscaler”:
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
...
dns-autoscaler 1 1 1 1 ...
...
如果没有就进行开启。
先确定缩放目标,如果用DNS部署,那么缩放目标就是:
Deployment/DNS部署的名称
比如DNS部署名是coredns,那么缩放目标就是Deployment/coredns。
如果用DNS 副本控制器,那么你的缩放目标是:
ReplicationController/DNS副本控制器的名称
创建一个运行 cluster-proportional-autoscaler-amd64
镜像的部署:
dns-horizontal-autoscaler.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: dns-autoscaler
namespace: kube-system
labels:
k8s-app: dns-autoscaler
spec:
selector:
matchLabels:
k8s-app: dns-autoscaler
template:
metadata:
labels:
k8s-app: dns-autoscaler
spec:
containers:
- name: autoscaler
image: k8s.gcr.io/cluster-proportional-autoscaler-amd64:1.6.0
resources:
requests:
cpu: 20m
memory: 10Mi
command:
- /cluster-proportional-autoscaler
- --namespace=kube-system
- --configmap=dns-autoscaler
- --target=<SCALE_TARGET>
# 当集群使用大节点(核数较多)时应该以"coresPerReplica"为主导
# 使用小节点应该以 "nodesPerReplica" 为主导
- --default-params={ "linear":{ "coresPerReplica":256,"nodesPerReplica":16,"min":1}}
- --logtostderr=true
- --v=2
将 <SCALE_TARGET>
替换为缩放目标。
然后创建部署:
kubectl apply -f dns-horizontal-autoscaler.yaml
DNS水平缩放就启用了。
优化自动缩放参数
验证是否存在 dns-autoscaler ConfigMap :
kubectl get configmap --namespace=kube-system
NAME DATA AGE
...
dns-autoscaler 1 ...
...
编辑ConfigMap:
kubectl edit configmap dns-autoscaler --namespace=kube-system
这一行:
linear: '{"coresPerReplica":256,"min":1,"nodesPerReplica":16}'
“min”字段表示DNS后端数量的最小值。后端数量的实际值计算公式如下:
replicas = max( ceil( cores * 1/coresPerReplica ) , ceil( nodes * 1/nodesPerReplica ) )
注意 coresPerReplica
和 nodesPerReplica
的值都是整数。
其思想是,当集群使用具有多个核的节点时,coresPerReplica
占主导地位。当一个集群使用的节点的核比较少时,nodesPerReplica
占主导地位。 (应该是说单个节点好几个核时就一个部署占节点的几个核,核少就一个部署多用几个节点)
其他缩放模式见集群比例自动伸缩器。
禁用DNS水平自动缩放
有几个选项可以优化DNS水平自动缩放。使用哪个选项取决于不同的条件。
选项1:将dns-autoscaler部署缩减到0个副本
这个选项适用于所有情况。输入这个命令:
kubectl scale deployment --replicas=0 dns-autoscaler --namespace=kube-system
输出:
deployment.extensions/dns-autoscaler scaled
验证副本数是否为0:
kubectl get deployment --namespace=kube-system
输出显示列DESIRED 和CURRENT 为0:
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
...
dns-autoscaler 0 0 0 0 ...
...
选项2:删除dns-autoscaler部署
dns-autoscaler处于你的控制下时有效。这意味着没有人会重新创建它:
kubectl delete deployment dns-autoscaler --namespace=kube-system
输出:
deployment.extensions "dns-autoscaler" deleted
选项3:从master节点删除dns-autoscaler清单文件
dns-autoscaler处于(已废弃) 插件管理器(Addon Manager) 的控制下并且你有对master的写入权限时有效。
登录到主节点并删除对应的清单(manifest)文件。这个dns-autoscaler的常见路径是:
/etc/kubernetes/addons/dns-horizontal-autoscaler/dns-horizontal-autoscaler.yaml
清单文件删除之后,插件管理器会删除dns-autoscaler 部署。
理解DNS水平自动扩展如何工作
- 集群比例自动缩放(cluster-proportional-autoscaler)应用程序与DNS服务分开部署。
- 自动缩放器Pod运行一个客户端,该客户端轮询Kubernetes API服务器,以确定集群中的节点和核心的数量。
- 根据当前可调度节点和核心以及给定的缩放参数,计算所需的副本数并将其应用于DNS后端。
- 缩放参数和数据点通过ConfigMap提供给autoscaler,它会在每个轮询间隔刷新它的参数表,以获得最新的缩放参数需求。
- 不需要重新构建或重新启动自动缩放器Pod就可以更改缩放参数。
- 自动调度器提供了一个控制接口来支持两种控制模式:线性和梯形。
未来开发
正在考虑未来开发除了线性和梯形之外的自定义度量的控制模式。
基于DNS指定的缩放度量的DNS后端缩放是未来的发展方向。当前使用集群中的节点和内核的数量来实现是有限制的。
正在考虑未来支持自定义度量,类似于水平Pod自动缩放(Horizontal Pod Autoscaling) 提供的指标)。
配置Pod和容器
配置pod
为pod指定内存请求与限制
LimitRange 为命名空间设定的约束只有在 Pod 创建和更新时才会对要创建/更新的Pod强制执行。所以更新 LimitRange时不会影响之前创建的 Pod。
LimitRange也可以对单个Pod进行约束。
定义一个范围约束
apiVersion: v1
kind: LimitRange
metadata:
name: mem-limit-range
spec:
limits:
- default:
memory: 512Mi
defaultRequest:
memory: 256Mi
type: Container
将约束应用到命名空间default-mem-example
kubectl create -f https://k8s.io/examples/admin/resource/memory-defaults.yaml --namespace=default-mem-example
如果在这个命名空间中创建容器且容器没有声明内存请求和限制,就会使用约束中定义的请求256Mi和限制512Mi,指定了则使用指定的。
- 如果指定了内存限制没有指定内存请求,则内存请求被设置为内存限制相同的值
- 如果指定了请求没有指定限制,默认使用命名空间的内存限制
定义pod:
apiVersion: v1
kind: Pod
metadata:
name: default-mem-demo
spec:
containers:
- name: default-mem-demo-ctr
image: nginx
# resources:
# requests:
# memory: "128Mi"
# limits:
# memory: "512Mi"
创建 Pod
kubectl create -f https://k8s.io/examples/admin/resource/memory-defaults-pod.yaml --namespace=default-mem-example
查看 Pod 的详情:
kubectl get pod default-mem-demo --output=yaml --namespace=default-mem-example
containers:
- image: nginx
imagePullPolicy: Always
name: default-mem-demo-ctr
resources:
limits:
memory: 512Mi
requests:
memory: 256Mi
删除 Pod:
kubectl delete pod default-mem-demo --namespace=default-mem-example
为命名空间指定容器运行的内存范围
即容器最小要多少请求,最大不超过多少限制,才能在命名空间里运行
定义约束
apiVersion: v1
kind: LimitRange
metadata:
name: 约束名
spec:
limits:
- max:
memory: 1Gi
min:
memory: 500Mi
type: Container
创建 LimitRange:
kubectl create -f https://k8s.io/examples/admin/resource/memory-constraints.yaml --namespace=要应用的命名空间
查看 LimitRange 的详情:
kubectl get limitrange 约束名 --namespace=命名空间 --output=yaml
如果没有 LimitRange 的配置文件中为pod指定默认内存大小,则会将最大内存限制设置为默认大小,pod没有指定内存时就会读取这个默认大小。
limits:
- default:
memory: 1Gi
defaultRequest:
memory: 1Gi
max:
memory: 1Gi
min:
memory: 500Mi
type: Container
现在,在命名空间中创建容器,Kubernetes 会执行下面的步骤:
- 如果 Container 未指定自己的内存请求和限制,将为它指定默认的内存请求和限制。
- 验证 Container 的内存请求是否大于或等于最小限制。
- 验证 Container 的内存限制是否小于或等于最大限制。
创建一个满足 LimitRange 的约束的pod:
apiVersion: v1
kind: Pod
metadata:
name: pod名
spec:
containers:
- name: 容器名
image: nginx
resources:
limits:
memory: "800Mi"
requests:
memory: "600Mi"
创建 Pod:
kubectl create -f https://k8s.io/examples/admin/resource/memory-constraints-pod.yaml --namespace=命名空间
确认下 Pod 中的容器在运行:
kubectl get pod Pod名 --namespace=命名空间
查看 Pod 详情:
kubectl get pod Pod名 --output=yaml --namespace=命名空间
resources:
limits:
memory: 800Mi
requests:
memory: 600Mi
如果不满足约束:
#太大了
Error from server (Forbidden): error when creating "examples/admin/resource/memory-constraints-pod-2.yaml":
pods "constraints-mem-demo-2" is forbidden: maximum memory usage per Container is 1Gi, but limit is 1536Mi.
#太小了
Error from server (Forbidden): error when creating "examples/admin/resource/memory-constraints-pod-3.yaml":
pods "constraints-mem-demo-3" is forbidden: minimum memory usage per Container is 500Mi, but request is 100Mi.
如果没有指定内存请求和限制,则会从LimitRange约束那里获取默认的内存请求和限制。
limits:
- default:
memory: 1Gi
defaultRequest:
memory: 1Gi
CPU限制
定义约束
apiVersion: v1
kind: LimitRange
metadata:
name: cpu-limit-range
spec:
limits:
- default:
cpu: 1
defaultRequest:
cpu: 0.5
type: Container
将约束应用到命名空间 default-cpu-example(需先创建命名空间):
kubectl create -f https://k8s.io/examples/admin/resource/cpu-defaults.yaml --namespace=default-cpu-example
创建pod:
apiVersion: v1
kind: Pod
metadata:
name: default-cpu-demo-3
spec:
containers:
- name: default-cpu-demo-3-ctr
image: nginx
# resources:
# requests:
# cpu: "0.75"
# limits:
# cpu: "1"
只指定请求和只指定限制时的规则与内存相同。
最大和最小可在命名空间运行的CPU值的定义、不指定默认cpu大小时自动生成、不满足约束时创建失败、LimitRange更新不影响之前Pod等特性与内存相同。
GPU和大页限制
也可以使用LimitRange对象对GPU和大页进行限制,当这些资源同时声明了 ‘default’ 和 ‘defaultRequest’ 参数时,两个参数的值必须相同。
命名空间配置
为命名空间设置内存总量、CPU总量、Pod配额
即命名空间中左右容器的内存请求/限制、CPU请求/限制等的总和不能超过多少。使用ResourceQuota对象进行配置。
创建ResourceQuota(资源配额)对象:
apiVersion: v1
kind: ResourceQuota
metadata:
name: mem-cpu-demo
spec:
hard:
requests.cpu: "1"
requests.memory: 1Gi
limits.cpu: "2"
limits.memory: 2Gi
pods: "2"
该配置文件设置了以下要求:
- 每个容器必须有内存请求和限制,以及 CPU 请求和限制。
- 所有容器的内存请求总和不能超过1 GiB。
- 所有容器的内存限制总和不能超过2 GiB。
- 所有容器的 CPU 请求总和不能超过1 cpu。
- 所有容器的 CPU 限制总和不能超过2 cpu。
- pod数量不能超过2个。
创建 ResourceQuota
kubectl create -f https://k8s.io/examples/admin/resource/quota-mem-cpu.yaml --namespace=quota-mem-cpu-example
查看 ResourceQuota 详情:
kubectl get resourcequota mem-cpu-demo --namespace=quota-mem-cpu-example --output=yaml
输出显示配额总量及使用量。
status:
hard:
limits.cpu: "2"
limits.memory: 2Gi
requests.cpu: "1"
requests.memory: 1Gi
pods: "2"
used:
limits.cpu: 800m
limits.memory: 800Mi
requests.cpu: 400m
requests.memory: 600Mi
pods: "1"
如果创建pod会导致超出配额会创建失败:
Error from server (Forbidden): error when creating "examples/admin/resource/quota-mem-cpu-pod-2.yaml":
pods "quota-mem-cpu-demo-2" is forbidden: exceeded quota: mem-cpu-demo,
requested: requests.memory=700Mi,used: requests.memory=600Mi, limited: requests.memory=1Gi
如果一次创建多个pod导致超出配额,则会创建配额数量的pod,超出的会创建失败。
例:使用部署一次创建3个pod
apiVersion: apps/v1
kind: Deployment
metadata:
name: pod-quota-demo
spec:
selector:
matchLabels:
purpose: quota-demo
replicas: 3
template:
metadata:
labels:
purpose: quota-demo
spec:
containers:
- name: pod-quota-demo
image: nginx
配置文件中,replicas: 3
使 Kubernetes 尝试创建3个 Pod,都运行相同的应用。
创建 Deployment:
kubectl create -f https://k8s.io/examples/admin/resource/quota-pod-deployment.yaml --namespace=quota-pod-example
查看 Deployment 详情:
kubectl get deployment pod-quota-demo --namespace=quota-pod-example --output=yaml
输出结果显示尽管 Deployment 声明了三个副本,但由于配额的限制只创建了两个 Pod。
spec:
...
replicas: 3
...
status:
availableReplicas: 2
...
lastUpdateTime: 2017-07-07T20:57:05Z
message: 'unable to create pods: pods "pod-quota-demo-1650323038-" is forbidden:
exceeded quota: pod-demo, requested: pods=1, used: pods=2, limited: pods=2'
定义和分配扩展资源
定义扩展资源
扩展资源是什么?它跟CPU和内存等资源相似,比如扩展一些磁盘资源,创建容器时可以请求内存和CPU,也可以请求扩展的磁盘资源。
kubectl get nodes
选择其中一个节点,在这个节点上附加扩展资源。扩展资源的附加数量只能是整数。
给API server发送 HTTP PATCH 请求来向节点附加4个叫做dongle的资源:
curl --header "Content-Type: application/json-patch+json" \
--request PATCH \
--data '[{"op": "add", "path": "/status/capacity/example.com~1dongle", "value": "4"}]' \
http://localhost:8001/api/v1/nodes/<your-node-name>/status
Note: patch路径中的
~1
代表/
k8s并不知道dongle是什么有什么用, PATCH请求只是告诉节点有4个叫dongle的东西。
查看节点信息可以看到资源:
kubectl describe node <your-node-name>
Capacity:
cpu: 2
memory: 2049008Ki
example.com/dongle: 4
例:
假如一个节点有800G的特殊磁盘空间,就可以将这个特殊空间命名为 example.com/special-storage,然后就可以以一定大小的块来附加了,比如100G。这样,你的节点就会附加8个 example.com/special-storage 类型的资源。
Capacity:
...
example.com/special-storage: 8
如果不想总是请求100G而是允许请求任意大小,可以使用大小为1byte的块来附加特殊存储。这样就会附加800G的类型为 example.com/special-storage 的资源。
Capacity:
...
example.com/special-storage: 800Gi
然后容器就可以申请任意字节的特殊存储了,最高800G。
请求扩展资源
现在创建节点时就可以向节点请求一定数量的dongle了。
apiVersion: v1
kind: Pod
metadata:
name: extended-resource-demo
spec:
containers:
- name: extended-resource-demo-ctr
image: nginx
resources:
requests:
example.com/dongle: 3
limits:
example.com/dongle: 3
扩展资源不够用时创建的pod不会被调度,处于挂起状态。
删除扩展资源
发送HTTP PATCH请求。把 <your-node-name>
换成你的节点名:
curl --header "Content-Type: application/json-patch+json" \
--request PATCH \
--data '[{"op": "remove", "path": "/status/capacity/example.com~1dongle"}]' \
http://localhost:8001/api/v1/nodes/<your-node-name>/status
验证dongle是否被移除:
kubectl describe node <your-node-name> | grep dongle
还没有评论,来说两句吧...