Namespace
查看某一个Namespace下的pod
默认情况下,所有的pod都是运行在default
这个namespace下的。
1 | kubectl get pods -n default |
创建一个Namespace
namespace-dev.yaml
1
2
3
4apiVersion: v1
kind: Namespace
metadata:
name: dev
在Namespace下创建资源
web-dev.yaml
1 | #deploy |
1 | kubectl get all -n dev |
Namespace的隔离性
同一个Namespace下的资源访问
随便找一个pod,进入到其容器中。
比如要测试同一个namespace下的另一个pod上的服务是否可以解析,可以执行ping命令。
用curl, wget也可以验证。
不同Namespace下的资源访问
进入到dev这个namespace下(必须制定-n
参数,否则访问的还是default namespace)
通过DNS无法访问
通过ping访问服务,可以看到无法访问,说明通过DNS层是隔离的。
通过服务IP
可以访问
尝试通过服务IP访问另一个namespace下的服务,事实上是可以访问到的。
通过pod + port
可以访问
可以看到,通过pod + 端口的方式也是可以访问的。
由此可知,k8s的隔离是DNS解析的隔离,通过服务IP或pod + 端口的方式仍然可以互访。
对上下文限定Namespace
可以通过设置上下文,实现对namespace的限定。
创建kubeconfig
比如:创建一个名叫ctx-dev
的上下文,namespace限定为dev
。
1 | kubectl config set-context ctx-dev \ |
设置默认上下文
1 | kubectl config use-context ctx-dev --kubeconfig=/root/.kube/config |
此时运行kubectl get all
, 也只能看到dev
namespace下的所有资源。
Resources
Resources 主要包括:CPU, 内存, GPU, 持久化存储等。
查看k8s节点资源
1 | kubectl get nodes |
对k8s服务进行资源限制
- memory: 100Mi //限制100MB内存
- cpu: 100m //限制只能使用0.1核CPU
这里有两个地方都有CPU和内存的设置。requests设置的是必须的最小要求,如果超出硬件最大配置,则容器启动时会一直卡在
Pending
状态。
而limits限制的是最大的内存,即使设置成超出硬件配置,启动时还是可以起来。
可以通过以下命令查看pod详细失败原因。
1 | kubectl describe pod <pod名称> |
部署到k8s
1 | kubectl apply -f web-dev.yaml |
每次部署后,如果查看节点的状态,可以看到k8s会新启动一个服务,然后把旧服务停掉,因为k8s的资源隔离本质上是利用的docker的资源隔离机制。
1 | kubectl get pods -n dev |
可以切换到容器运行的那台节点上,看看对应的docker容器的情况。
1 | docker ps | grep web-demo |
查看该容器详细信息
1 | docker inspect <容器id> |
参数解读:
CpuShares
: 之前在yaml文件里配置的值是100m,docker会将该值转化为0.1核,之后再乘以1024,就得到这里的102了。这个值在docker里代表相对权重,但发生资源不足时,docker会尝试根据这个权重分配资源。Memory
: 这个值就是我们在yaml文件中指定的内存。CpuQuota
: yaml文件里设置的最大CPU核数。CpuPeriod
: docker默认值,默认值是100000ns。
修改yaml文件,测试k8s调度策略
将requests.memory
和limits.memory
都设置成100Mi。
如果docker实例里使用的内存超过了限定内存最大值,则k8s会自动将“有问题的进程”杀掉,但不会终止docker容器。
如果是CPU超过限定,则会限定在最大值,因为CPU是可压缩资源,而内存不是。
如果将实例数(replicas
)改成3, 每个内存改成10GB(服务器硬件一共24GB内存)。
部署服务后可以看到,k8s只允许两个实例启动,第三个一直处于Pending
状态。
实验说明,
requests
要求的配置是要“预留”的,即使实际上还没用到。
测试结论(最佳实践)
设置yaml配置时,
- 如果
requests
==limits
:此时是最可靠的,推荐使用; - 如果不设置:最不可靠,不推荐;
- 如果
requests
>limits
:超过时,k8s会根据优先级来分配资源;
使用LimitRange
限制资源请求
limits-test.yaml
对 pod
和 container
分别限定了资源。
1 | apiVersion: v1 |
新建一个命名空间,将limits-test.yaml
部署到k8s新的namespace下,观察其资源占用情况。
1 | # 新建一个test命名空间 |
在test命名空间下部署一个新的deployment (web-test.yaml),不限制资源。
web-test.yaml
1 | #deploy |
可以通过以下命令查看deploy的详细信息;
1 | kubectl get deploy -n test -o yaml |
多个团队间的资源配额限制
compute-resource.yaml
: 对CPU和内存的限制。
1 | apiVersion: v1 |
object-count.yaml
: 更多资源限制。
1 | apiVersion: v1 |
1 | # 对test命名空间限制资源配额 |
Pod驱逐策略 - Evition
soft策略
--eviction-soft=memory.available<1.5Gi
--eviction-soft-grace-period=memory.available=1m30s
soft策略配合使用,效果:当内存持续1分30秒小于1.5G时,执行驱逐。
hard策略
--eviction-hard=memory.available<100Mi,nodefs.avaiblable<1Gi,nodefs.inodesFree<5%
hard策略:当满足任意一个条件时,立刻执行;
磁盘紧缺
- 删掉死掉的pod、容器;
- 删除没用的镜像;
- 按优先级、资源占用情况驱逐pod;
内存紧缺
- 驱逐不可靠的pod;
- 驱逐基本可靠的pod(实际使用内存超过正常的);
- 驱逐可靠的pod;
Label
key-value值对,可以“贴”到任何资源上。
web-dev.yaml
: 在metadata里定义了label,之后就可以用selector/matchLabels
选择标签了。
1 | #deploy |
不同的deployment的同名label是不冲突的,因为分属不同的实例。
根据label过滤资源
1 | kubectl get pods -l app=web-demo,group=dev -n dev |
在node上指定label
比如,实现在node上打个标签
1 | kubectl label node <节点名> disktype=ssd |
在yaml文件里指定node label,disktype:ssd