Kubernetes Cookbook 编程指南 中文版教程
创建时间:2018-12-07  访问量:3673  7  0

Kubernetes Cookbook 编程指南 中文版教程

命名空间的使用

在Kubernetes集群中,命名空间中的资源的名称是资源的唯一标识。使用Kubernetes命名空间在相同集群中为不同环境分离命名空间。它让你能够轻松创建一个隔离的环境并且资源分配给不同的项目和团队。

Pod,Services,Replication Controllers包含在一个特定的命名空间中。还有一些资源,如Nodes和PVs,是不属于任何命名空间的。

开始

黙认情况下,Kubernetes创建一个default命名空是。所有已创建的对象如何没有明确指定命名空间将被归入default命名空间。你可以使用kubectl列出命名空间:

// check all namespaces
# kubectl get namespaces
NAME 	LABELS STATUS AGE
default <none> Active 8d

Kubernetes也将会创建另外一个叫作kube-system的初始命名空间用于放置Kubernetes系统对象,如Kubernetes UI pod。

命名空间的名称必须是一个DNS标签并且遵循以下规则:

  • 最多63个字符

  • 匹配正则表达式[a-z0-9]([-a-z0-9]*[a-z0-9])

如何去做...

  1. 在选定一个期望的名称之后,我们使用配置文件创建一个名为new-namespace的命名空间:

# cat newNamespace.yaml
apiVersion: v1
kind: Namespace
metadata:
	name: new-namespace

// create the resource by kubectl
# kubectl create -f newNamespace.yaml
  1. 在成功创建命名空间之后,再次列出命名空间:
// list namespaces
# kubectl get namespaces
NAME 			LABELS 	STATUS AGE
default 		<none> 	Active 8d
new-namespace 	<none> 	Active 12m

你可以看到我们有这里有两个命名空间了。

  1. 让我们在新的命名空间运行第1章构建你自己的Kubernetes中描述的nginx 副本控制器。

// run a nginx RC in namespace=new-namespace
# kubectl run nginx --image=nginx --namespace=new-namespace
  1. 然后我们列出:
# kubectl get pods
NAME READY STATUS RESTARTS AGE
  1. 没有任何Pod在运行!让我们使用--namespace参数再次运行一次:
// to list pods in all namespaces
# kubectl get pods --all-namespaces
NAMESPACE 		NAME 		READY 	STATUS 	RESTARTS 	AGE
new-namespace 	nginx-ns0ig 1/1 	Running 0 			17m

// to get pods from new-namespace
# kubectl get pods --namespace=new-namespace
NAME 		READY 	STATUS 	RESTARTS 	AGE
nginx-ns0ig 1/1 	Running 0 			18m

现在我们能看见刚才创建的Pod了。

  1. 黙认情况下,如果你在命名行中不指定任何命名空间,Kubernetes将在default的命名空间中创建资源。如果你想要通过配置文件创建资源,仅仅简单在运行kubect create命令时指定它就可以了:

# kubectl create -f myResource.yaml --namespace=new-namespace

改变黙认命名空间

改变Kubernetes中黙认的命名空间是可能的:

  1. 查找你的当前上下文:

# kubectl config view | grep current-context
current-context: ""

它揭示了我们当前没有任何上下文。

  1. 无论现在有没有上下文,都可以使用set-context创建一个新的上下文或覆盖一个已存在的:

# kubectl config set-context <current context or new context name>
--namespace=new-namespace
  1. 在设置一个新的上下文之后,我们可以检查一下当前的配置:
# kubectl config view
apiVersion: v1
clusters: []
contexts:
	- context:
        cluster: ""
        namespace: new-namespace
        user: ""
	name: new-context
current-context: ""
kind: Config
preferences: {}
users: []

我们可以看到,在contexts区域设置了一个合适的命名空间。

  1. 切换到我们刚刚创建的上下文:

# kubectl config use-context new-context
  1. 然后再次检查当前上下文:
# kubectl config view | grep current-context
current-context: new-context

我可以看到current-context值现在是new-context。

  1. 让我们再次列出当前的Pod。不需要指定namespace参数,我们就可以列出new-namespace中的Pod了:

# kubectl get pods
NAME 		READY 	STATUS 	RESTARTS 	AGE
nginx-ns0ig 1/1 	Running 0 			54m
  1. 也可以在Pod的描述中列出命名空间:
# kubectl describe pod nginx-ns0ig
Name: nginx-ns0ig
Namespace: new-namespace
Image(s): nginx
Node: ip-10-96-219-156/10.96.219.156
Start Time: Sun, 20 Dec 2015 15:03:40 +0000
Labels: run=nginx
Status: Running

删除一个命名空间

  1. 使用kubectl delete可以删除命名空间中的资源。如果删除一个命名空间将会删除此命名空间下的所有资源:

# kubectl delete namespaces new-namespace
namespace "new-namespace" deleted
  1. 在命名空间被删除之后,我们的nginx pod也消失了:
# kubectl get pods
NAME READY STATUS RESTARTS AGE
  1. 然而,上下文中的黙认命名空间仍然是刚才设置的new-namespace:
# kubectl config view | grep current-context
current-context: new-context

这会有问题吗?

  1. 让我们再次运行一下nginx副本控制器。

# kubectl run nginx --image=nginx
Error from server: namespaces "new-namespace" not found

它将创建一个nginx副本控制器并将Pod复制到我们刚刚删除的命名空间中。如果这个命名空间不存在,Kubernetes将抛出一个错。

  1. 让我们切换回default命名空间。

# kubectl config set-context new-context --namespace=""
context "new-context" set.
  1. 让我们再次运行nginx。
# kubectl run nginx --image=nginx
replicationcontroller "nginx" created
Does it real run in default namespace? Let's describe the pod.
# kubectl describe pods nginx-ymqeh
Name: nginx-ymqeh
Namespace: default
Image(s): nginx
Node: ip-10-96-219-156/10.96.219.156
Start Time: Sun, 20 Dec 2015 16:13:33 +0000
Labels: run=nginx
Status: Running
...

我们可以看到这个Pod当前运行在namespace: default。一切看起来都很多。

不止这些

有时候,你将会需要通过区分命名空间来为每个团队限制资源的配额。在你创建了一个新的命名空间之后,详细信息如下所示:

$ kubectl describe namespaces new-namespace
Name: new-namespace
Labels: <none>
Status: Active

No resource quota.

No resource limits.

资源的配额与限制黙认并没有设置。Kubernetes支持对容器和Pod进行约束。在设置限制之前,需要启用Kubernetes API Server中的LimitRanger参数。你可以通过命名行或配置文件的方式启用它:

// using command line-
# kube-apiserver --admission-control=LimitRanger

// using configuration file
# cat /etc/kubernetes/apiserver
...
# default admission control policies
KUBE_ADMISSION_CONTROL="--admission_control=NamespaceLifecycle,NamespaceE
xists,LimitRanger,SecurityContextDeny,ResourceQuota"
...

下面是一个在命名空间中创建一个限制的好例子。

我们将限制一个Pod中的资源,将Cpu的max的值设为2,min值设置为200m,并将memory的max设置为1Gi,将min值设置为6Mi。对于容器,CPU被限制在100m-2之间,内存被限制在3Mi-1Gi之间。如果设置了max,那么你必须在资源创建的过程在Pod/容器的spec中指定limit;如果设置了min,那么在Pod/容器的创建过程中要指定request。LimitRange中的default和defaultRequst用来在容器的spec中指定黙认limit和request。

# cat limits.yaml
apiVersion: v1
kind: LimitRange
metadata:
	name: limits
	namespace: new-namespace
spec:
    limits:
        - max:
            cpu: "2"
            memory: 1Gi
        min:
            cpu: 200m
            memory: 6Mi
        type: Pod
    	- default:
            cpu: 300m
            memory: 200Mi
        defaultRequest:
            cpu: 200m
            memory: 100Mi
        max:
            cpu: "2"
            memory: 1Gi
        min:
            cpu: 100m
            memory: 3Mi
        type: Container

// create LimitRange
# kubectl create -f limits.yaml
limitrange "limits" created

在LimitRange创建之后,我们可以如任何其它资源一样列出:

// list LimitRange
# kubectl get LimitRange --namespace=new-namespace
NAME 	AGE
limits 	22m

当你描述新的命名空间的时间,现在你将看到这个限制:

# kubectl describe namespace new-namespace
Name: new-namespace
Labels: <none>
Status: Active

No resource quota.

Resource Limits
Type Resource Min Max Request Limit Limit/Request
---- -------- --- --- ------- ----- -------------
Pod memory 6Mi 1Gi - - -
Pod cpu 200m 2 - - -
Container cpu 100m 2 200m 300m -
Container memory 3Mi 1Gi 100Mi 200Mi -

在这个命名空间中创建的所有Pod和容器必须遵循此外列出的资源限制。如果定义违反这个规则,于是就是抛出一个验证错误。

删除LimitRange

我们可以通过以下方式删除LimitRange资源:

# kubectl delete LimitRange <limit name> --namespace=<namespace>

这里,limit name就是limits,namespace是new-namespace。执行完之后,当你描述命名的时候,就没有限制条件了:

# kubectl describe namespace <namespace>
Name: new-namespace
Labels: <none>
Status: Active

No resource quota.

No resource limits.

还可以参考

有很多资源都运行命名空间之中,查看如下几个章节:

  • Pod的使用

  • 名称的使用

  • 第7章高级集群管理,设置Node的资源