4. Introduction to actual combat
This chapter describes how to deploy and access an nginx service in a kubernetes cluster.
4.1 Namespace
Namespace is a very important resource in kubernetes system. Its main function is to realize resource isolation of multiple environments or multi tenant resources.
By default, all pods in the kubernetes cluster can access each other. However, in practice, you may not want two pods to access each other. At this time, you can divide the two pods into different namespaces. Kubernetes can form logical "groups" by allocating resources in the cluster to different namespaces, so as to facilitate the isolated use and management of resources in different groups.
Different namespace s can be managed by different tenants through the authorization mechanism of kubernetes, so as to realize multi tenant resource isolation. At this time, the resource quota mechanism of kubernetes can be combined to limit the resources that can be occupied by different tenants, such as CPU usage, memory usage, etc., so as to realize the management of available resources for tenants.
kubernetes will create several namespace s by default after the cluster is started
[root@master ~]# kubectl get namespace NAME STATUS AGE default Active 45h # All objects that do not specify a Namespace are assigned in the default Namespace kube-node-lease Active 45h # The heartbeat maintenance between cluster nodes is introduced in v1.13 kube-public Active 45h # Resources under this namespace can be accessed by everyone (including unauthenticated users) kube-system Active 45h # All resources created by the Kubernetes system are in this namespace
Let's look at the specific operations of the namespace resource:
4.1.1 view
# 1 view all ns commands: kubectl get ns [root@master ~]# kubectl get ns NAME STATUS AGE default Active 45h kube-node-lease Active 45h kube-public Active 45h kube-system Active 45h # 2 view the specified ns command: kubectl get ns name [root@master ~]# kubectl get ns default NAME STATUS AGE default Active 45h # 3 specify output format command: kubectl get ns name - o format parameter # kubernetes supports many formats, such as wide, json and yaml [root@master ~]# kubectl get ns default -o yaml apiVersion: v1 kind: Namespace metadata: creationTimestamp: "2021-05-08T04:44:16Z" name: default resourceVersion: "151" selfLink: /api/v1/namespaces/default uid: 7405f73a-e486-43d4-9db6-145f1409f090 spec: finalizers: - kubernetes status: phase: Active # 4. View ns details command: kubectl describe ns name [root@master ~]# kubectl describe ns default Name: default Labels: <none> Annotations: <none> Status: Active # Active namespace in use Terminating deleting namespace # ResourceQuota resource restrictions for namespace # LimitRange is the resource limit for each component in the namespace No resource quota. No LimitRange resource.
4.1.2 create
# Create namespace [root@master ~]# kubectl create ns dev namespace/dev created
4.1.3 deletion
# Delete namespace [root@master ~]# kubectl delete ns dev namespace "dev" deleted
4.1.4 configuration mode
First, prepare a yaml file: ns-dev.yaml
apiVersion: v1 kind: Namespace metadata: name: dev
Then you can execute the corresponding create and delete commands:
Create: kubectl create - f ns dev.yaml
Delete: kubectl delete - f ns dev.yaml
4.2 Pod
Pod is the smallest unit for kubernetes cluster management. The program must be deployed in the container to run, and the container must exist in pod.
A Pod can be considered as a package of containers. One or more containers can exist in a Pod.
After kubernetes starts the cluster, all components in the cluster also run in Pod mode. You can view it with the following command:
[root@master ~]# kubectl get pod -n kube-system NAMESPACE NAME READY STATUS RESTARTS AGE kube-system coredns-6955765f44-68g6v 1/1 Running 0 2d1h kube-system coredns-6955765f44-cs5r8 1/1 Running 0 2d1h kube-system etcd-master 1/1 Running 0 2d1h kube-system kube-apiserver-master 1/1 Running 0 2d1h kube-system kube-controller-manager-master 1/1 Running 0 2d1h kube-system kube-flannel-ds-amd64-47r25 1/1 Running 0 2d1h kube-system kube-flannel-ds-amd64-ls5lh 1/1 Running 0 2d1h kube-system kube-proxy-685tk 1/1 Running 0 2d1h kube-system kube-proxy-87spt 1/1 Running 0 2d1h kube-system kube-scheduler-master 1/1 Running 0 2d1h
4.2.1 create and run
kubernetes does not provide the command to run Pod separately, but is implemented through the Pod controller
# Command format: kubectl run (pod controller name) [parameter] # --Image specifies the image of the Pod # --Port specifies the port # --Namespace specifies the namespace [root@master ~]# kubectl run nginx --image=nginx:latest --port=80 --namespace dev deployment.apps/nginx created
4.2.2 viewing pod information
# View Pod basic information [root@master ~]# kubectl get pods -n dev NAME READY STATUS RESTARTS AGE nginx 1/1 Running 0 43s # View Pod details [root@master ~]# kubectl describe pod nginx -n dev Name: nginx Namespace: dev Priority: 0 Node: node1/192.168.5.4 Start Time: Wed, 08 May 2021 09:29:24 +0800 Labels: pod-template-hash=5ff7956ff6 run=nginx Annotations: <none> Status: Running IP: 10.244.1.23 IPs: IP: 10.244.1.23 Controlled By: ReplicaSet/nginx Containers: nginx: Container ID: docker://4c62b8c0648d2512380f4ffa5da2c99d16e05634979973449c98e9b829f6253c Image: nginx:latest Image ID: docker-pullable://nginx@sha256:485b610fefec7ff6c463ced9623314a04ed67e3945b9c08d7e53a47f6d108dc7 Port: 80/TCP Host Port: 0/TCP State: Running Started: Wed, 08 May 2021 09:30:01 +0800 Ready: True Restart Count: 0 Environment: <none> Mounts: /var/run/secrets/kubernetes.io/serviceaccount from default-token-hwvvw (ro) Conditions: Type Status Initialized True Ready True ContainersReady True PodScheduled True Volumes: default-token-hwvvw: Type: Secret (a volume populated by a Secret) SecretName: default-token-hwvvw Optional: false QoS Class: BestEffort Node-Selectors: <none> Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s node.kubernetes.io/unreachable:NoExecute for 300s Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled <unknown> default-scheduler Successfully assigned dev/nginx-5ff7956ff6-fg2db to node1 Normal Pulling 4m11s kubelet, node1 Pulling image "nginx:latest" Normal Pulled 3m36s kubelet, node1 Successfully pulled image "nginx:latest" Normal Created 3m36s kubelet, node1 Created container nginx Normal Started 3m36s kubelet, node1 Started container nginx
4.2.3 accessing Pod
# Get podIP [root@master ~]# kubectl get pods -n dev -o wide NAME READY STATUS RESTARTS AGE IP NODE ... nginx 1/1 Running 0 190s 10.244.1.23 node1 ... #Access POD [root@master ~]# curl http://10.244.1.23:80 <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> </head> <body> <p><em>Thank you for using nginx.</em></p> </body> </html>
4.2.4 delete specified Pod
# Delete specified Pod [root@master ~]# kubectl delete pod nginx -n dev pod "nginx" deleted # At this point, it is displayed that the Pod was deleted successfully, but after querying again, it is found that a new one has been generated [root@master ~]# kubectl get pods -n dev NAME READY STATUS RESTARTS AGE nginx 1/1 Running 0 21s # This is because the current Pod is created by the Pod controller. The controller will monitor the Pod status. Once the Pod is found dead, it will be rebuilt immediately # To delete the Pod, you must delete the Pod controller # Let's first query the Pod controller in the current namespace [root@master ~]# kubectl get deploy -n dev NAME READY UP-TO-DATE AVAILABLE AGE nginx 1/1 1 1 9m7s # Next, delete this PodPod controller [root@master ~]# kubectl delete deploy nginx -n dev deployment.apps "nginx" deleted # Wait a moment, then query the Pod and find that the Pod has been deleted [root@master ~]# kubectl get pods -n dev No resources found in dev namespace.
4.2.5 configuration operation
Create a pod-nginx.yaml as follows:
apiVersion: v1 kind: Pod metadata: name: nginx namespace: dev spec: containers: - image: nginx:latest name: pod ports: - name: nginx-port containerPort: 80 protocol: TCP
Then you can execute the corresponding create and delete commands:
Create: kubectl create -f pod-nginx.yaml
Delete: kubectl delete -f pod-nginx.yaml
4.3 Label
Label is an important concept in kubernetes system. Its function is to add identification on resources to distinguish and select them.
Features of Label:
- A Label will be attached to various objects in the form of key/value pairs, such as Node, Pod, Service, etc
- A resource object can define any number of labels, and the same Label can also be added to any number of resource objects
- The Label is usually determined when the resource object is defined. Of course, it can also be dynamically added or deleted after the object is created
Multi dimensional grouping of resources can be realized through Label, so that resource allocation, scheduling, configuration, deployment and other management can be carried out flexibly and conveniently.
Some common Label examples are as follows:
- Version label: "version": "release", "version": "stable"
- Environment label: "environment": "dev", "environment": "test", "environment": "pro"
- Schema label: "tier": "frontend", "tier": "backend"
After the label is defined, the label selection should also be considered, which requires the use of the Label Selector, namely:
Label is used to define an identity for a resource object
Label Selector is used to query and filter resource objects with certain labels
There are currently two types of label selectors:
-
Equation based Label Selector
name = slave: select all objects with key="name" and value="slave" in the Label
env != production: select all objects including key="env" in Label and whose value is not equal to "production"
-
Collection based Label Selector
name in (master, slave): select all objects with key="name" and value="master" or "slave" in the Label
name not in (frontend): select all objects that contain key="name" in Label and whose value is not equal to "frontend"
Multiple label selectors can be used for label selection. In this case, multiple label selectors can be combined and separated by comma "," and ". For example:
name=slave,env!=production
name not in (frontend),env!=production
4.3.1 command mode
# Tag pod resources [root@master ~]# kubectl label pod nginx-pod version=1.0 -n dev pod/nginx-pod labeled # Update tags for pod resources [root@master ~]# kubectl label pod nginx-pod version=2.0 -n dev --overwrite pod/nginx-pod labeled # View label [root@master ~]# kubectl get pod nginx-pod -n dev --show-labels NAME READY STATUS RESTARTS AGE LABELS nginx-pod 1/1 Running 0 10m version=2.0 # Filter Tags [root@master ~]# kubectl get pod -n dev -l version=2.0 --show-labels NAME READY STATUS RESTARTS AGE LABELS nginx-pod 1/1 Running 0 17m version=2.0 [root@master ~]# kubectl get pod -n dev -l version!=2.0 --show-labels No resources found in dev namespace. #delete a tap [root@master ~]# kubectl label pod nginx-pod version- -n dev pod/nginx-pod labeled
4.3.2 configuration mode
apiVersion: v1 kind: Pod metadata: name: nginx namespace: dev labels: version: "3.0" env: "test" spec: containers: - image: nginx:latest name: pod ports: - name: nginx-port containerPort: 80 protocol: TCP
Then you can execute the corresponding update command: kubectl apply -f pod-nginx.yaml
4.4 Deployment
In kubernetes, pod is the smallest control unit, but kubernetes rarely directly controls pod, which is generally completed through pod controller. The pod controller is used for pod management to ensure that the pod resources meet the expected state. When the pod resources fail, it will try to restart or rebuild the pod.
There are many types of Pod controllers in kubernetes. This chapter only introduces one: Deployment.
4.4.1 command operation
# Command format: kubectl create deployment name [parameter] # --Image specifies the image of the pod # --Port specifies the port # --replicas specifies the number of created pod s # --Namespace specifies the namespace [root@master ~]# kubectl run nginx --image=nginx:latest --port=80 --replicas=3 -n dev deployment.apps/nginx created # View the created Pod [root@master ~]# kubectl get pods -n dev NAME READY STATUS RESTARTS AGE nginx-5ff7956ff6-6k8cb 1/1 Running 0 19s nginx-5ff7956ff6-jxfjt 1/1 Running 0 19s nginx-5ff7956ff6-v6jqw 1/1 Running 0 19s # View deployment information [root@master ~]# kubectl get deploy -n dev NAME READY UP-TO-DATE AVAILABLE AGE nginx 3/3 3 3 2m42s # UP-TO-DATE: number of copies successfully upgraded # AVAILABLE: number of AVAILABLE copies [root@master ~]# kubectl get deploy -n dev -o wide NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR nginx 3/3 3 3 2m51s nginx nginx:latest run=nginx # View deployment details [root@master ~]# kubectl describe deploy nginx -n dev Name: nginx Namespace: dev CreationTimestamp: Wed, 08 May 2021 11:14:14 +0800 Labels: run=nginx Annotations: deployment.kubernetes.io/revision: 1 Selector: run=nginx Replicas: 3 desired | 3 updated | 3 total | 3 available | 0 unavailable StrategyType: RollingUpdate MinReadySeconds: 0 RollingUpdateStrategy: 25% max unavailable, 25% max surge Pod Template: Labels: run=nginx Containers: nginx: Image: nginx:latest Port: 80/TCP Host Port: 0/TCP Environment: <none> Mounts: <none> Volumes: <none> Conditions: Type Status Reason ---- ------ ------ Available True MinimumReplicasAvailable Progressing True NewReplicaSetAvailable OldReplicaSets: <none> NewReplicaSet: nginx-5ff7956ff6 (3/3 replicas created) Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ScalingReplicaSet 5m43s deployment-controller Scaled up replicaset nginx-5ff7956ff6 to 3 # delete [root@master ~]# kubectl delete deploy nginx -n dev deployment.apps "nginx" deleted
4.4.2 configuration operation
Create a deploy-nginx.yaml as follows:
apiVersion: apps/v1 kind: Deployment metadata: name: nginx namespace: dev spec: replicas: 3 selector: matchLabels: run: nginx template: metadata: labels: run: nginx spec: containers: - image: nginx:latest name: nginx ports: - containerPort: 80 protocol: TCP
Then you can execute the corresponding create and delete commands:
Create: kubectl create -f deploy-nginx.yaml
Delete: kubectl delete -f deploy-nginx.yaml
4.5 Service
Through the previous lesson, we have been able to use Deployment to create a group of pods to provide services with high availability.
Although each Pod is assigned a separate Pod IP, there are two problems:
- Pod IP will change with the reconstruction of pod
- Pod IP is only a virtual IP visible in the cluster and cannot be accessed externally
This makes it difficult to access the Service. Therefore, kubernetes designed Service to solve this problem.
Service can be regarded as a group of external access interfaces of similar pods. With the help of service, applications can easily realize service discovery and load balancing.
4.5.1 create accessible services within the cluster
# Expose Service [root@master ~]# kubectl expose deploy nginx --name=svc-nginx1 --type=ClusterIP --port=80 --target-port=80 -n dev service/svc-nginx1 exposed # View service [root@master ~]# kubectl get svc svc-nginx1 -n dev -o wide NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR svc-nginx1 ClusterIP 10.109.179.231 <none> 80/TCP 3m51s run=nginx # A CLUSTER-IP is generated here, which is the IP of the service. This address will not change during the service life cycle # You can access the POD corresponding to the current service through this IP [root@master ~]# curl 10.109.179.231:80 <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> </head> <body> <h1>Welcome to nginx!</h1> ....... </body> </html>
4.5.2 create a Service that can also be accessed outside the cluster
# The type of the Service created above is ClusterIP. This ip address is accessible only within the cluster # If you need to create a Service that can also be accessed externally, you need to modify the type to NodePort [root@master ~]# kubectl expose deploy nginx --name=svc-nginx2 --type=NodePort --port=80 --target-port=80 -n dev service/svc-nginx2 exposed # At this time, you will find that a Service of NodePort type appears, and there is a pair of ports (80:31928/TC) [root@master ~]# kubectl get svc svc-nginx2 -n dev -o wide NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR svc-nginx2 NodePort 10.100.94.0 <none> 80:31928/TCP 9s run=nginx # Next, you can access the node IP:31928 to access the service through the host outside the cluster # For example, access the following address through a browser on the host computer http://192.168.90.100:31928/
4.5.3 delete Service
[root@master ~]# kubectl delete svc svc-nginx-1 -n dev service "svc-nginx-1" deleted
4.5.4 configuration mode
Create an svc-nginx.yaml as follows:
apiVersion: v1 kind: Service metadata: name: svc-nginx namespace: dev spec: clusterIP: 10.109.179.231 #Fixed svc intranet ip ports: - port: 80 protocol: TCP targetPort: 80 selector: run: nginx type: ClusterIP
Then you can execute the corresponding create and delete commands:
Create: kubectl create -f svc-nginx.yaml
Delete: kubectl delete -f svc-nginx.yaml
Summary
So far, you have mastered the basic operations of Namespace, Pod, Deployment and Service resources. With these operations, you can realize the simple Deployment and access of a Service in kubernetes cluster. However, if you want to make better use of kubernetes, you need to deeply study the details and principles of these resources.