Namespace

为什么需要namespace——为了方便项目及资源管理。

例如:一个公司可能分为市场部、行政部、采购部、人力资源部等等。

对应一个kubernetes集群可能运行多个项目,如果将这些项目的所有资源(如pod、deployment、service)全部放在一个namespace下运行,管理及维护起来会特别混乱。切分为不同namespace后,既可以使管理清晰,也可以方便认证及授权操作,不同的角色对应不同的权限。


创建好k8s集群后,一般存在四个namespace:

  • default : 创建资源时,如果不指定namespace,则全部是在这个空间下操作。
  • kube-system: The namespace for objects created by the Kubernetes system.
  • kube-public: The namespace is created automatically and is readable by all users. It contains information, like CA, that helps kubeadm join and authenticate worker nodes.
  • kube-node-release: The kube-node-lease namespace contains lease objects that are used by kubelet to determine node health.

默认get pods是获取default命名空间下的所有pod。

如果想获取其他命名空间的pod:

kubectl get pods --namespace=kube-system

基本操作

创建命名空间

一种是通过yaml文件:

apiVersion: v1
kind: Namespace
metadata: 
  name: dev

另一种直接命令行创建:

kubectl create namespace dev

创建POD时指定命名空间

一种是命令行直接指定:

kubectl create -f pod-definition.yml --namespace=dev

另一种是写在yaml文件中,这样不用再手动指定:

apiVersion: v1
kind: Pod
metadata:
  name: redis
  namespace: dev #指定namespace为dev
  labels:
    app: web
spec:
  containers:
    - name: redis-app
      image: redis123
      ports:
        - containerPort: 6379
    

获取所有命名空间下的POD

kubectl get pods --all-namespaces

设置namespace使用资源配额

可以限制namespace下资源的使用,例如最大运行pod数量、最大使用内存、最大cpu使用额度等等。

创建一个dev namespace及对应的ResourceQuota:

apiVersion: v1
kind: Namespace
metadata: 
  name: dev

---
apiVersion: v1
kind: ResourceQuota
metadata:
  name: compute-quota
  namespace: dev

spec:
  hard:
    pods: "2"
    requests.cpu: "4"
    requests.memory: 5Gi
    limits.cpu: "10"
    limits.memory: 10Gi

此时在dev空间创建pod时,必须指定参数limits.cpu,limits.memory,requests.cpu,requests.memory,否则会报错:

  Warning FailedCreate 40s (x6 over 58s) replicaset-controller (combined from similar events): Error creating: pods "nginx-6db489d4b7-7c568" is forbidden: failed quota: compute-quota: must specify limits.cpu,limits.memory,requests.cpu,requests.memory

先创建一个具有2个pod的deployment:

kubectl run nginx --image=nginx -n dev --limits='cpu=200m,memory=512Mi' --requests='cpu=100m,memory=256Mi' --replicas=2
  • --limits='cpu=200m,memory=512Mi'指定pod使用资源的上限。
  • --requests='cpu=100m,memory=256Mi'指定pod初始化时请求的资源。
  • --replicas=2指定deployment运行两个pod。

此时查看dev空间下,有两个pod在运行。但将pod数量扩大到三个时,pod数量依然为2个:

image-20200315173059370


查看replica set日志,里面说明了失败的原因:limited pods=2

image-20200315173219788

切换默认namespace

默认使用的namespace是default,如果想切换为dev:

kubectl config set-context $(kubectl config current-context) --namespace=dev

image-20200315175921898

此时执行kubectl get pods,获取的是dev下的所有pods。


上面命令的本质是更改了~/.kube/config文件:

image-20200315180035277

如果暴力一点,直接编辑这个文件,效果也是一样的。

跨namespace的service调用

不同namespace之间的网络是互通的,例如可以直接在一个namespace下ping另一个namespace下pod的ip。

但是service调用时要注意:

  • 相同namespace下,可以直接调用service name;
  • 调用不同namespace下的service,要使用service-name.namespace-name.svc.cluster.local这种形式。

image-20200315165911962

image-20200315170011402

这是因为,不同namespace下,可能存在多个相同的Service Name:

image-20200315171005903