Earlier we had a general impression of the basic components and concepts of K8s, and implemented a preliminary CI/CD flow based on K8s. However, there may be a lack of in-depth understanding and practice of the various objects involved (such as Namespace, Pod, Deployment, Service, Ingress, PVC, etc.) and the management of each object. In the following article, let’s explore the internal components of K8s. The following diagram is a personal understanding of the K8s structure, showing how the components (including only the major components) work together.

The following articles will focus on the components involved in this figure. In this article, we will explore Namespace and the resource limits ResourceQuota/LimitRange related to Namespace management.

Namespace

understand

A Namespace is a Namespace that has two main functions:

  1. Resource isolation: Virtual cluster space for different teams/users (or projects) to share resources in the same Kubernetes cluster. For example, you can create A Namespace nS-A for team A. Team A’s projects are deployed and run in NS-A. Team B can create another Namespace ns-b, and its projects are deployed and run in NS-B, or create different namespaces for development, test, and production environments. So as to separate from each other and not affect each other. We can use ResourceQuota and Resource LimitRange to specify and limit Resource allocation and usage for each Namesapce
  2. Permission control: You can specify which users can and cannot access a namespace

After Kubernetes is installed successfully, three namespaces will be created by default:

  • Default: the default namespace. If you do not specify metadata.namespace when creating Kubernetes objects, the objects will be created under the default namespace
  • Kube-system: objects created by the Kubernetes system are stored in this namespace. Kube-apiserver, etcd, kube-proxy, and so on are in this namespace
  • Kube-public: as the name implies, a shared namespace that is readable to all users. The namespace is reserved for clusters. Objects are not created in the namespace

practice

1. Check the namesapce

Kubectl get namespaces kubectl get namesapce kubectl get ns kubectl get ns --show-labelsCopy the code

You can use Namesapces, Namesapce,ns. All namespaces in the current cluster are listed below

[root@kmaster ~]# kubectl get ns
NAME                   STATUS   AGE
default                Active   34d
develop                Active   17d
ingress-nginx          Active   33d
kube-node-lease        Active   34d
kube-public            Active   34d
kube-system            Active   34d
kubernetes-dashboard   Active   31d
pre-release            Active   17dCopy the code

You can use the kubectl describe command to view the profile information for a namespace, for example

[root@kmaster ~]# kubectl describe ns default
Name:         default
Labels:       <none>
Annotations:  <none>
Status:       Active

No resource quota.

No resource limits.Copy the code

2. To create a namespace

There are two ways to do this: through a YAML definition file or directly using a command.

[root@kmaster ~]# vim test-namespace. Yaml apiVersion: v1 kind: namespace metadata: name: Test # namespaces labels: name: ns-test [root@kmaster ~]# kubectl create -f./ test-namespaces. [root@kmaster ~]# kubectl create ns testCopy the code

3. Create an object in namesapce

[root@kmaster ~]# kubectl get deploy my-nginx -o yaml apiVersion: apps/v1 kind: Deployment metadata: labels: run: my-nginx name: my-nginx namespace: test # [root@kmaster ~]# kubectl run dev-nginx --image=nginx:latest --replicas=3 -n testCopy the code

4. Set kubectl namesapce context

Kubectl context is the combination of cluster, namespace, user, set kubectl context, that is, you can specify the user below, in the context of the specified cluster and namespace operation management. View the current cluster kubectl context

[root@kmaster ~]# kubectl config view apiVersion: v1 clusters: -cluster: certificate-authority-data: DATA + OMITTED server: https://192.168.40.111:6443 name: kubernetes contexts: - the context: cluster: kubernetes user: kubernetes-admin name: kubernetes-admin@kubernetes current-context: kubernetes-admin@kubernetes kind: Config preferences: {} users: - name: kubernetes-admin user: client-certificate-data: REDACTED client-key-data: REDACTEDCopy the code

The current context is kubernetes-admin@kubernetes (current-context: kubernetes-admin@kubernetes).

Create a Kubectl context

[root@kmaster ~]# kubectl config set-context test --namespace=test --cluster=kubernetes --user=kubernetes-admin
Context "test" created.Copy the code

Executing kubectl Config View again will see the test context created above.

Context switching

[root@kmaster ~]# kubectl config use-context test Switched to context "test" kubectl config current-context testCopy the code

If the context is specified, subsequent operations are performed in the namespace corresponding to the context. You do not need to specify a namespace explicitly. Create objects in context

[root@kmaster ~]# kubectl run my-nginx --image=nginx:latest --replicas=2 kubectl run --generator=deployment/apps.v1 is DEPRECATED and will be removed in a future version. Use kubectl run --generator=run-pod/v1 or kubectl create indece.deployment. apps/my-nginx created Namespace [root@kmaster ~]# kubectl get deploy NAME READY up-to-date AVAILABLE AGE my-nginx 2/2 2 2 25m [root@kmaster ~]# kubectl get pod NAME READY STATUS RESTARTS AGE my-nginx-667764d77b-ldb78 1/1 Running 0 24m my-nginx-667764d77b-wpgxw 1/1 Running 0 24mCopy the code

Delete context

[root@kmaster ~]# kubectl config delete-context test
deleted context test from /root/.kube/configCopy the code

You can also run the following command to switch the default namespace

[root@kmaster ~]# kubectl config set-context --current --namespace=testCopy the code

5. Delete namesapce

To delete a namesapce, use kubectl delete ns

. This operation deletes all the contents of a namespace.

[root@kmaster ~]# kubectl delete ns testCopy the code

Resource Quota

Resource Quota specifies the maximum number of cluster resources that can be used by a namespace.

  1. Limit the total number of objects that can be created for an object type, such as Pod;
  2. Defines the total number of computing resources (CPU, memory) and storage resources (volume declaration) that can be consumed by an object type

If you set ResourceQuota for CPU and memory in a namespace, you must specify requests and limits when creating objects (pods, services, and so on). If the resource applied for during object creation or update conflicts with the Namespace’s ResourceQuota, Apiserver returns HTTP status code 403 with an error message. When the total capacity of the cluster is less than the total resource quota of each namespace, resource contention may occur. In this case, Kubernetes will allocate resources on a first-come, first-served basis.

Object limit

The declaration format is count/

.

. The following lists the declaration formats of various objects

count/persistentvolumeclaims 
count/services
count/secrets
count/configmaps
count/replicationcontrollers
count/deployments.apps
count/replicasets.apps
count/statefulsets.apps
count/jobs.batch
count/cronjobs.batch
count/deployments.extensionsCopy the code

Computing resource limits

Define total usage of CPU, memory requests, and limits, including

  • CPU: indicates the CPU limit of all non-terminated pods in the namespace. Resources. Limits
  • Limits. memory: the total resources. Limits. Memory of all non-terminated pods in a namespace cannot exceed this value
  • CPU: The sum of CPU requests resources.requret. CPU for all non-terminated pods in the namespace cannot exceed this value
  • Requests. The memory: namespace, all the termination status of Pod request of CPU resources. Requests. The sum total of the memory can’t more than this value

Storage Resource Restrictions

Defines a limit on the total amount of storage requested by a storage volume declaration or the number of storage volume declarations created

  • The total number of requests that PersistentVolumeClaim must not exceed this value in the requests
  • Persistentvolumeclaims: Namespace. The total number of storage volume declarations that can be created cannot exceed this value
  • <storage-class-name>.storageclass.storage.k8s.io/requests.storage: in a namespace, all storage volumes associated with the specified StorageClass (StorageClass) declare that the total requested storage cannot exceed this value
  • <storage-class-name>.storageclass.storage.k8s.io/persistentvolumeclaims: In a namespace, the total number of declared volumes associated with the specified storage class cannot exceed this value

In addition, local temporary storage resources can be defined with restrictions

  • Ephemeral storage: The total number of local ephemeral storage requests for all pods in the namespace cannot exceed this value
  • Limits. ephemeral-storage: The total limit for the local temporary storage of all pods in the namespace cannot exceed this value

practice

Check whether Resource Quota support is enabled. It is enabled by default. If not, you can add a ResourceQuota configuration item for the –enable-admission-plugins parameter when you start Apiserver.

1. Create ResourceQuota

[root@kmaster ~]# kubectl create namespace test # edit ResourceQuota definition document [root@kmaster ~]# vim quota-test.yaml apiVersion: v1 kind: ResourceQuota metadata: name: quota-test namespace: test spec: hard: requests.cpu: "2" requests.memory: 2Gi limits.cpu: "4" limits.memory: 4Gi requests.nvidia.com/gpu: 4 pods: "3" services: [root@kmaster ~]# kubectl apply-f quota-test.yaml # check [root@kmaster ~]# kubectl get quota-n test NAME CREATED AT quota-test 2020-05-26T10:31:10Z [root@kmaster ~]# kubectl describe quota quota-test -n test Name: quota-test Namespace: test Resource Used Hard -------- ---- ---- limits.cpu 0 4 limits.memory 0 4Gi pods 0 3 requests.cpu 0 2 requests.memory 0 2Gi requests.nvidia.com/gpu 0 4 services 0 6Copy the code

Or use the kubectl command, as in

[root@kmaster ~]# kubectl create quota quota-test --hard=count/deployments.extensions=2,count/replicasets.extensions=4,count/pods=3,count/secrets=4 --namespace=testCopy the code

Create a ResourceQuota in namespace test, limit CPU and memory requests to 2 or 2GB, limit CPU and memory usage to 4 or 4GB, limit Pod number to 3, etc.

Let’s try to test this by creating a Deployment defined as follows,

Yaml apiVersion: apps/v1 kind: Deployment metadata: name: quota-test-deploy spec: selector: matchLabels: purpose: quota-test replicas: 3 template: metadata: labels: purpose: quota-test spec: containers: - name: quota-test image: nginx resources: limits: memory: "2Gi" cpu: "1" requests: memory: "500Mi" cpu: Yaml -n test # check pod [root@kmaster ~]# kubectl get pod -n test NAME READY STATUS RESTARTS AGE quota-test-deploy-6b89fdc686-2dthq 1/1 Running 0 3m54s Quota-test-deploy -6b89fdc686-9m2qw 1/1 Running 0 3m54s # Check the deploy status [root@kmaster ~]# kubectl get deploy quota-test-deploy -n test -o yaml message: 'pods "quota-test-deploy-6b89fdc686-rmktq" is forbidden: exceeded quota: quota-test, requested: limits.memory=2Gi, used: limits.memory=4Gi, limited: limits.memory=4Gi'Copy the code

Replicas: 3 defines the creation of three Pod copies, but only two of them are successfully created. In the Status section of deploy (the result of the last command), we can see that the message indicates that the third Pod was rejected because the memory limit has been reached. We can also set limits. Memory to 1Gi and replicas to 4 to verify the number of pods. The status message tells pods “quota-test-deploy-9dC54f95c-gzqw7” is forbidden: Exceeded quota:quota-test, requested: Pods =1, Used: Pods =3, limited: Pods =3.

Resource Limit Range

understand

Resource quotas set limits on the total number of resources in a namespace, and Resource limits Range set limits on the number of resources in a Pod or container. By default, the resource consumption of pods or containers in a namespace is unlimited. This may cause memory leaks in one container application and depleting resources affecting other applications. Limit Range can be used to Limit the number of resources that pods (or containers) in a namespace can consume.

With the LimitRange object, we can:

  1. Limits the minimum and maximum computing resources per Pod or container in a namespace
  2. Limit the ratio between request and Limit for each Pod or container in a namespace
  3. PersistentVolumeClaim limits the minimum and maximum storage space that each volume declaration (PersistentVolumeClaim) in namespace can use
  4. Set the request and limit of the default computing resources in the namespace container, and inject them into the container automatically at runtime

If a request for a resource created or updated object (Pod, container, PersistentVolumeClaim) conflicts with LimitRange, Apiserver returns HTTP status code 403 with an error message. If LimitRange is defined in the Namespace to limit the usage of computing resources such as CPU and memory, you must specify the REQUEST and limit of CPU or memory when creating pods and containers. Otherwise, the system will reject the LimitRange. When the total limit of a namespace is less than the sum of the limits of both pods and containers, resource contention occurs and pods or containers cannot be created. However, existing pods or containers are not affected.

practice

Create a test namespace test-limitrange,

[root@kmaster ~]# kubectl create namespace test-limitrange # switch default namespace [root@kmaster ~]# kubectl config set-context --current --namespace=test-limitrangeCopy the code

Create LimitRange definition file lr-test.yaml

ApiVersion: v1 kind: LimitRange metadata: name: lR-test spec: limits: type: Container # Resource type Max: CPU: "1" # limit maximum CPU memory: "1Gi" # Limit maximum memory min: "100m" # Limit minimum CPU memory: "100Mi" # Limit minimum memory default: CPU: "900M" # default CPU memory limit: "800Mi" # default CPU memory limit: "200m" MaxLimitRequestRatio: CPU: 2 memory: 1.5 Memory limit/ Request: 1.5 type: PersistentVolumeClaim Max: Storage: Storage min: storage: 1Gi # specifies the minimum PVC requests. StorageCopy the code

This file defines the resource limits of containers, PODS, and PVC in the Namespace test-LimitRange. In the Namesapce, objects can be created only when the following conditions are met

  • Of the containerresources.limitsSome cpus must be between 100m and 1 GI, and the memory must be between 100 mi-1 gi. Otherwise, the creation fails
  • Of the containerresources.limitsPart of the CPU andresources.requestsThe maximum CPU ratio is 2, and the maximum memory ratio is 1.5. Otherwise, the creation fails
  • For all containers in Podresources.limitsThe maximum sum of some cpus is 2, and the maximum sum of memory is 2 GI. Otherwise, the creation fails
  • The PVCresources.requests.storageThe maximum value is 2Gi, and the minimum value is 1Gi. Otherwise, the creation fails

If the container defines Resources.requests without resources.limits, the default part of LimitRange will be injected into the container as limit. If the container defines resources. Limits but does not define resources. Requests, set the requests value to limits as well. If the container has neither defined, use the LimitRange default as limits and defaultRequest as requests values

Create and view LimitRange,

Yaml # check [root@kmaster ~]# kubectl describe limits lR-test Name: lr-test Namespace: test-limitrange Type Resource Min Max Default Request Default Limit Max Limit/Request Ratio ---- -------- --- --- --------------- ------------- ----------------------- Container cpu 100m 1 200m 900m 2 Container memory 100Mi 1Gi 200Mi 800Mi 1500m Pod cpu - 2 - - - Pod memory - 2Gi - - - PersistentVolumeClaim storage 1Gi 2Gi - - -Copy the code

We can create containers or Pod objects with different configurations for validation, and we won’t list the validation steps for space.

conclusion

In this paper, the Namespace of K8s and the resource limit management of Namespace ResourceQuota and LimitRange are deeply explored. ResourceQuota limits the resource usage of the entire Namespace. LimitRange limits resource usage for a single Pod or container. The permission control of Namespace can be realized based on RBAC, which will be introduced separately later.

Original address: blog.jboost.cn/k8s4-namesp…

Related reading:

  1. Kubernetes Notes (1) : Deploy a K8s environment in 10 minutes
  2. Kubernetes Notes ii: Understand the basic components and concepts of K8S
  3. Gitlab+Jenkins Pipeline+Docker+ K8S +Helm Automated deployment practice

Author: Rain song welcome to pay attention to the author public number: halfway rain song, learn to grow up together