namespace设计解读

namespace是k8s进行多租户资源隔离主要手段,那么它在系统中的表现形式是什么?实现原理和使用方法又是什么呢?

什么是namespace

namespace是一个将k8s的资源对象进行细分的类似于DNS子域名的概念。namespace能够帮助不同的租户共享一个k8s集群。k8s引入namespace的目的包括以下几点:

  • 建立一种简单易用的,能够在逻辑上对k8s资源对象进行隔离的机制。
  • 将资源对象与实际的物理节点解耦,用户只需要关注namespace而非工作节点上的资源情况。
  • 随着k8s访问控制代码开发的深入,与k8s认证和授权机制相结合。
  • 通过namespace对资源进行归类,使得APIserver能够建立一套有效的过滤k8s资源请求的机制。

与namespace相关的命令比如:

  • kubectl namespace <new_space>:将当前namespace切换为new_space。
  • kubectl get namespace:取得系统当前可用的namespace。

大多数的Kubernetes中的集群默认会有一个叫default的namespace:

NAME              STATUS   AGE
default           Active   2d15h
kube-node-lease   Active   2d15h
kube-public       Active   2d15h
kube-system       Active   2d15h
  • default:你的service和app默认被创建于此(系统默认的namespace是default)。
  • kube-system:kubernetes系统组件使用。
  • kube-public:公共资源使用。但实际上现在并不常用。

多namespace使用案例

利用之前写的redis-controller.json,我们在default namespace中创建一个replication controller:

[root@master controller]# kubectl create -f redis-controller.json --namespace=default
replicationcontroller/redis-controller created

接着用同样的方法在myspace namespace中创建一个replication controller:

[root@master controller]# kubectl create namespace myspace
namespace/myspace created
[root@master controller]# kubectl create -f redis-controller.json --namespace=myspace
replicationcontroller/redis-controller created

查看系统中的controller信息:

[root@master controller]# kubectl get replicationcontroller
NAME               DESIRED   CURRENT   READY   AGE
redis-controller   1         1         1       2m20s

这显然实在default namespace下查询得到的,如果要看到另一个可以切换到myspace namespace或者使用下面的命令:

[root@master controller]# kubectl get replicationcontroller --namespace=myspace
NAME               DESIRED   CURRENT   READY   AGE
redis-controller   1         1         0       88s

利用namespace来切换应用上下文

[root@master controller]# kubectl create namespace development
namespace/development created
[root@master controller]# kubectl create namespace production
namespace/production created
[root@master controller]# kubectl config set-context prod --namespace=production
Context "prod" created.
[root@master controller]# kubectl config set-context  dev --namespace=development
Context "dev" created.

切换到你希望进行操作的namespace:

[root@master controller]# kubectl config use-context dev
Switched to context "dev".

接下来的所有kubectl刻画段操作都被限定在development namespace中,如果需要查看当前所处的上下文,可以参考以下的做法:

[root@master controller]# kubectl config view
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: DATA+OMITTED
    server: https://192.168.0.11:6443
  name: kubernetes
contexts:
- context:
    cluster: ""
    namespace: development
    user: ""
  name: dev
- context:
    cluster: kubernetes
    user: kubernetes-admin
  name: kubernetes-admin@kubernetes
- context:
    cluster: ""
    namespace: production
    user: ""
  name: prod
current-context: dev
kind: Config
preferences: {}
users:
- name: kubernetes-admin
  user:
    client-certificate-data: REDACTED
    client-key-data: REDACTED

可以发现,我们处于current-context: dev中,也就是development namespace中。上面的输出也说明,namespace可以与用户的认证授权机制结合在一起使用。

Kubernetes用户认证机制

暂时不表。

应用健康检查

在k8s中系统和应用程序的健康检查是由kubelet来完成的。

进程级健康检查
最简单的健康检查是进程级的健康检查,即验证容器进程是否存活。这类健康检查的健康粒度是在k8s集群中运行的单一容器。kubelet会定期通过Docker daemon获取所有Docker进程的运行情况,如果发现某个Dokcer容器没有正常运行,则才会重新启动该容器进程。

业务级健康检查
比如“死锁”的例子,当发生死锁的时候,容器仍然在正常运行,但是从应用程序来看,无法响应用户的业务请求。
为了解决以上问题,k8s引入了一个在容器内执行的活性探针(liveness probe)的概念,以支持用户自己实现应用业务级的健康检查。

  • HttpGet:kubelet将调用容器内的Web应用的web hook,如果返回的HTTP状态码在200和399之间,则认为容器运转正常,否则认为容器运转不正常。
  • Container Exec:kubelet将在用户容器内执行一次命令,如果命令执行的退出码为0,则认为容器运转正常。其中执行命令的默认目录是容器的根目录,要执行的命令在pod配置文件中定义。
  • TCP Socket:理论上kubelet将会尝试打开一个到用户容器的socker连接。如果能够建立这条连接,则可以认为容器运转正常。

使用HttpGet的健康检查的pod配置文件如下所示:
在这里插入图片描述
一个使用Container Exec健康检查的pod配置文件如下所示:
在这里插入图片描述

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐