kubernetes 通过 Namespace (命名空间)和 Context 的设置对不同的工作组进行区分,使得它们既可以共享一个 Kubernetes 集群的服务,也可以互不干扰。

创建Namespace

为了在 Kubernetes 集群中实现这两个分组,首先需要创建两个命名空间。

使用 namespace-development.yaml,创建 development 命名空间:

apiVersion: v1
kind: Namespace
metadata:
  name: development

使用 namespace-production.yaml,创建 production 命名空间:

apiVersion: v1
kind: Namespace
metadata:
  name: production

使用kubectl create命令完成命名空间的创建:

[root@master1 ~]# kubectl create -f namespace-development.yaml -f namespace-production.yaml 
namespace/development created
namespace/production created

查看系统中的命名空间

[root@master1 ~]# kubectl get namespaces | grep -v 'kube'
NAME              STATUS   AGE
default           Active   2d16h
development       Active   18s
production        Active   18s

定义Context

接下来,通过kubectl config set-context命令定义 Context,并将 Context 置于之前创建的命名空间中。为这两个工作组分别定义一个 Context,即运行环境。这个运行环境将属于某个特定的命名空间。
通过kubectl config set-context命令定义 Context,并将 Context 置于之前创建的命名空间中:

1. 设置集群参数

[root@master1 ~]# kubectl config set-cluster kubernetes-cluster --server=https://192.168.100.100:9443 --embed-certs=true --certificate-authority=/etc/kubernetes/pki/ca.crt --kubeconfig=/data/ctx/config
Cluster "kubernetes-cluster" set.

2. 设置上下文参数

[root@master1 ~]# kubectl config set-context ctx-dev --namespace=development --cluster=kubernetes-cluster --user=dev  --kubeconfig=/data/ctx/config
Context "ctx-dev" created.
[root@master1 ~]# kubectl config set-context ctx-prod --namespace=production --cluster=kubernetes-cluster --user=prod  --kubeconfig=/data/ctx/config
Context "ctx-prod" created.

3. 设置客户端认证参数

[root@master1 ~]# kubectl config set-credentials dev --embed-certs=true --client-key=/etc/kubernetes/pki/client.key   --client-certificate=/etc/kubernetes/pki/client.crt  --kubeconfig=/data/ctx/config
User "dev" set.
[root@master1 ~]# kubectl config set-credentials prod --embed-certs=true --client-key=/etc/kubernetes/pki/client.key   --client-certificate=/etc/kubernetes/pki/client.crt  --kubeconfig=/data/ctx/config
User "prod" set.

备注

  1. kubectl config命令默认在${HOME}/.kube目录下生成了一个名为 config 的文件,也可通过增加--kubeconfig参数指定生成的配置文件路径,那么后续要通过kubectl使用这个自定义文件,就需要使用--kubeconfig来指定这个自定义文件,因为kubectl默认读取的 config 文件也是读取${HOME}/.kube/config这个文件。本案例将两个普通用户的 config 文件指定到/data/ctx/config里。
  2. 本案例的 dev 和 prod 这两个用户是通过证书认证的方式进行用户身份校验。如果使用密码校验方式可以使用--password参数设定密码验证。如果设置的用户不对,就会提示输入用户名和密码:Please enter Username:,或者证书校验不通过:error: tls: failed to find any PEM data in key input

通过kubectl config view --kubeconfig=/data/ctx/config命令查看已定义的 Context:

apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: DATA+OMITTED
    server: https://192.168.100.100:9443
  name: kubernetes-cluster
contexts:
- context:
    cluster: kubernetes-cluster
    namespace: development
    user: dev
  name: ctx-dev
- context:
    cluster: kubernetes-cluster
    namespace: production
    user: prod
  name: ctx-prod
current-context: ""
kind: Config
preferences: {}
users:
- name: dev
  user:
    client-certificate-data: REDACTED
    client-key-data: REDACTED
- name: prod
  user:
    client-certificate-data: REDACTED
    client-key-data: REDACTED

通过kubectl config view命令显示的内容就是刚刚kubectl config等命令生成的信息。所以,也可以通过手工编辑该文件的方式来设置 Context。

设置工作组在特定Context中工作

可以通过kubectl config use-context <context_name>命令设置当前运行环境。通过下面的命令行将把当前运行环境设置为 ctx-dev:

[root@master1 ~]# kubectl config use-context ctx-dev  --kubeconfig=/data/ctx/config
Switched to context "ctx-dev".

运行这个命令后,当前运行环境被设置为开发组所需的环境(在${HOME}/.kube/config文件中 Key 为current-context设置一个ctx-dev的值)。之后的所有操作都将在名为 deployment 的命名空间中完成。

查看 ctx-dev 的上下文所在的命名空间里的 Pod:

[root@master1 ~]# kubectl config use-context ctx-dev --kubeconfig=/data/ctx/config
Switched to context "ctx-dev".
[root@master1 ~]# kubectl get pods --kubeconfig=/data/ctx/config
No resources found in development namespace.

查看 ctx-prod 的上下文所在的命名空间里的 Pod:

[root@master1 ~]# kubectl config use-context ctx-prod --kubeconfig=/data/ctx/config
Switched to context "ctx-prod".
[root@master1 ~]# kubectl get pods --kubeconfig=/data/ctx/config
No resources found in production namespace.

可以发现都有一个属于自己默认的 namespace。

创建一个 redis-slave-controller.yaml 文件,以 redis-slave RC 为例子创建两个 Pod:

apiVersion: v1
kind: ReplicationController
metadata:
  name: redis-slave
  labels:
    name: redis-slave
spec:
  replicas: 2
  selector:
    name: redis-slave
  template:
    metadata:
      labels:
        name: redis-slave
    spec:
      containers:
      - name: slave
        image: kubeguide/guestbook-redis-slave
        ports:
        - containerPort: 6379

在 development 环境创建 Pod

在 ctx-dev 上下文中创建:

[root@master1 ~]# kubectl config use-context ctx-dev --kubeconfig=/data/ctx/config
Switched to context "ctx-dev".
[root@master1 ~]# kubectl create -f redis-slave-controller.yaml --kubeconfig=/data/ctx/config
replicationcontroller/redis-slave created

查看创建好的 Pod 和 RC:

[root@master1 ~]# kubectl get pods -o wide --kubeconfig=/data/ctx/config
NAME                READY   STATUS    RESTARTS   AGE   IP             NODE    NOMINATED NODE   READINESS GATES
redis-slave-hb8m6   1/1     Running   0          5s    10.0.166.135   node1   <none>           <none>
redis-slave-m7zwg   1/1     Running   0          5s    10.0.104.7     node2   <none>           <none>
[root@master1 ~]# kubectl get rc -o wide --kubeconfig=/data/ctx/config
NAME          DESIRED   CURRENT   READY   AGE   CONTAINERS   IMAGES                            SELECTOR
redis-slave   2         2         2       13s   slave        kubeguide/guestbook-redis-slave   name=redis-slave

可以看到容器已经正常运行,而且当前的运行环境是 development,所以不会影响到 production。

在 production 环境中创建 Pod

切换到 ctx-prod 运行环境:

[root@master1 ~]# kubectl config use-context ctx-prod --kubeconfig=/data/ctx/config
Switched to context "ctx-prod".

查看RC 和 Pod

[root@master1 ~]# kubectl get pods -o wide --kubeconfig=/data/ctx/config
No resources found in production namespace.
[root@master1 ~]# kubectl get rc -o wide --kubeconfig=/data/ctx/config
No resources found in production namespace.

结果为空,说明看不到 ctx-dev 里的 RC 和 Pod。

现在也为 ctx-prod 创建两个 redis-slave 的Pod:

[root@master1 ~]# kubectl get pods -o wide --kubeconfig=/data/ctx/config
NAME                READY   STATUS    RESTARTS   AGE   IP             NODE    NOMINATED NODE   READINESS GATES
redis-slave-9mm4b   1/1     Running   0          6s    10.0.166.136   node1   <none>           <none>
redis-slave-cgcgl   1/1     Running   0          6s    10.0.104.8     node2   <none>           <none>
[root@master1 ~]# kubectl get rc -o wide --kubeconfig=/data/ctx/config
NAME          DESIRED   CURRENT   READY   AGE   CONTAINERS   IMAGES                            SELECTOR
redis-slave   2         2         2       13s   slave        kubeguide/guestbook-redis-slave   name=redis-slave

可以看到容器被正确创建并运行起来,并且当前运行的环境是 production,也不会影响到 development。

在管理员用户查看 Pod

在 Kubernetes 最高用户中查看所有命名空间的 redis-slave ,发现都是分别在 development 和 production 这两个 namespace 中。

[root@master1 ~]# kubectl get pod --all-namespaces -l name=redis-slave -o wide
NAMESPACE     NAME                READY   STATUS    RESTARTS   AGE     IP             NODE    NOMINATED NODE   READINESS GATES
development   redis-slave-hb8m6   1/1     Running   0          8m6s    10.0.166.135   node1   <none>           <none>
development   redis-slave-m7zwg   1/1     Running   0          8m6s    10.0.104.7     node2   <none>           <none>
production    redis-slave-9mm4b   1/1     Running   0          3m52s   10.0.166.136   node1   <none>           <none>
production    redis-slave-cgcgl   1/1     Running   0          3m52s   10.0.104.8     node2   <none>           <none>
[root@master1 ~]# kubectl get rc --all-namespaces -l name=redis-slave -o wide
NAMESPACE     NAME          DESIRED   CURRENT   READY   AGE     CONTAINERS   IMAGES                            SELECTOR
development   redis-slave   2         2         2       8m9s    slave        kubeguide/guestbook-redis-slave   name=redis-slave
production    redis-slave   2         2         2       3m55s   slave        kubeguide/guestbook-redis-slave   name=redis-slave

至此,为两个工作组分别设置了两个运行环境,设置好当前运行环境时,各工作组之间的工作将不会相互干扰,并且都能在同一个 Kubernetes 集群中同时工作。

参考:《Kubernetes权威指南(第五版)》