Detailed explanation of service resources and pod in k8s

1. Service

Through the study of the last lesson, you have been able to use Deployment to create a set of Pods to provide services with high availability.
Although each Pod will be assigned a separate Pod IP, there are two problems:
• The Pod IP will change as the Pod is rebuilt
• The 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 an external access interface for a group of Pods of the same type. With Service, applications can easily implement service discovery and load balancing.

insert image description here

1. Create a Service accessible within the cluster

# 暴露Service
[root@master ~]# kubectl expose deploy nginx --name=svc-nginx1 --type=ClusterIP --port=80 --target-port=80 -n dev
service/svc-nginx1 exposed

# 查看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

# 这里产生了一个CLUSTER-IP,这就是service的IP,在Service的生命周期中,这个地址是不会变动的
# 可以通过这个IP访问当前service对应的POD
[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>

2. Create a Service that can also be accessed outside the cluster

The type of the Service created above is ClusterIP , and this ip address can only be accessed within the cluster # If you need to create a Service that can also be accessed from the outside, 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
# 此时查看,会发现出现了NodePort类型的Service,而且有一对Port(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
# 接下来就可以通过集群外的主机访问 节点IP:31928访问服务了# 例如在的电脑主机上通过浏览器访问下面的地址http://192.168.100.10:31928/
删除Service
[root@master ~]# kubectl delete svc svc-nginx-1 -n dev
service "svc-nginx-1" deleted

3. Write the configuration method

Create a svc-nginx.yaml with the following content:

[root@master ~]# cat svc-nginx1.yml 
apiVersion: v1
kind: Service
metadata:  //定义名称和别名空间
  name: svc-nginx
  namespace: lty
spec:
  clusterIP: 10.107.179.231  //ip
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    run: nginx
  type: ClusterIP  //网络类型

Then you can execute the corresponding create and delete commands:

创建:
[root@master ~]# kubectl create -f svc-nginx1.yml
service/svc-nginx created
[root@master ~]# kubectl get svc -n lty
NAME        TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
svc-nginx   ClusterIP   10.107.179.231   <none>        80/TCP    49s

删除:
[root@master ~]# kubectl delete -f svc-nginx1.yml 
service "svc-nginx" deleted
[root@master ~]# kubectl get svc -n lty
No resources found in lty namespace.

Two, pod detailed explanation

1. Resource list of pod configuration file

apiVersion: v1     #必选,版本号,例如v1
kind: Pod         #必选,资源类型,例如 Pod
metadata:         #必选,元数据
  name: string     #必选,Pod名称
  namespace: string  #Pod所属的命名空间,默认为"default"
  labels:           #自定义标签列表
    - name: string                 
spec:  #必选,Pod中容器的详细定义
  containers:  #必选,Pod中容器列表
  - name: string   #必选,容器名称
    image: string  #必选,容器的镜像名称
    imagePullPolicy: [ Always | Never |I fNotPresent ]  #获取镜像的策略 ,从官网下
    command: [string]   #容器的启动命令列表,如不指定,使用打包时使用的启动命令
    args: [string]      #容器的启动命令参数列表
    workingDir: string  #容器的工作目录
    volumeMounts:       #挂载到容器内部的存储卷配置
      - name: string      #引用pod定义的共享存储卷的名称,需用volumes[]部分定义的的卷名
      mountPath: string #存储卷在容器内mount的绝对路径,应少于512字符
      readOnly: boolean #是否为只读模式
    ports: #需要暴露的端口库号列表
    - name: string        #端口的名称
      containerPort: int  #容器需要监听的端口号
      hostPort: int       #容器所在主机需要监听的端口号,默认与Container相同
      protocol: string    #端口协议,支持TCP和UDP,默认TCP
    env:   #容器运行前需设置的环境变量列表
    - name: string  #环境变量名称
      value: string #环境变量的值
    resources: #资源限制和请求的设置
      limits:  #资源限制的设置
        cpu: string     #Cpu的限制,单位为core数,将用于docker run --cpu-shares参数
        memory: string  #内存限制,单位可以为Mib/Gib,将用于docker run --memory参数
      requests: #资源请求的设置
        cpu: string    #Cpu请求,容器启动的初始可用数量
        memory: string #内存请求,容器启动的初始可用数量
    lifecycle: #生命周期钩子
        postStart: #容器启动后立即执行此钩子,如果执行失败,会根据重启策略进行重启
        preStop: #容器终止前执行此钩子,无论结果如何,容器都会终止
    livenessProbe:  #对Pod内各容器健康检查的设置,当探测无响应几次后将自动重启该容器
      exec:         #对Pod容器内检查方式设置为exec方式
        command: [string]  #exec方式需要制定的命令或脚本
      httpGet:       #对Pod内个容器健康检查方法设置为HttpGet,需要制定Path、port
        path: string
        port: number
        host: string
        scheme: string
        HttpHeaders:
        - name: string
          value: string
      tcpSocket:     #对Pod内个容器健康检查方式设置为tcpSocket方式
         port: number
       initialDelaySeconds: 0       #容器启动完成后首次探测的时间,单位为秒
       timeoutSeconds: 0          #对容器健康检查探测等待响应的超时时间,单位秒,默认1秒
       periodSeconds: 0           #对容器监控检查的定期探测时间设置,单位秒,默认10秒一次
       successThreshold: 0
       failureThreshold: 0
       securityContext:
         privileged: false
  restartPolicy: [Always | Never | OnFailure]  #Pod的重启策略
  nodeName: <string> #设置NodeName表示将该Pod调度到指定到名称的node节点上
  nodeSelector: obeject #设置NodeSelector表示将该Pod调度到包含这个label的node上
  imagePullSecrets: #Pull镜像时使用的secret名称,以key:secretkey格式指定
  - name: string
  hostNetwork: false   #是否使用主机网络模式,默认为false,如果设置为true,表示使用宿主机网络
  volumes:   #在该pod上定义共享存储卷列表
  - name: string    #共享存储卷名称 (volumes类型有很多种)
    emptyDir: {}       #类型为emtyDir的存储卷,与Pod同生命周期的一个临时目录。为空值
    hostPath: string   #类型为hostPath的存储卷,表示挂载Pod所在宿主机的目录
      path: string                #Pod所在宿主机的目录,将被用于同期中mount的目录
    secret:          #类型为secret的存储卷,挂载集群与定义的secret对象到容器内部
      scretname: string  
      items:     
      - key: string
        path: string
    configMap:         #类型为configMap的存储卷,挂载预定义的configMap对象到容器内部
      name: string
      items:
      - key: string
        path: string

#Small tips: # Here, you can view the configurable items of each resource through a command # kubectl explain resource type to view the first-level attributes that can be configured by a certain resource # kubectl explain resource type. attribute to view the sub-attributes of the attribute

[root@k8s-master01 ~]# kubectl explain pod
KIND:     Pod
VERSION:  v1
FIELDS:
   apiVersion   <string>    #会有如下格式的子目录
   kind <string>
   metadata     <Object>
   spec <Object>
   status       <Object>

[root@k8s-master01 ~]# kubectl explain pod.metadata   //跟小目录
KIND:     Pod
VERSION:  v1
RESOURCE: metadata <Object>
FIELDS:
   annotations  <map[string]string>
   clusterName  <string>
   creationTimestamp    <string>
   deletionGracePeriodSeconds   <integer>
   deletionTimestamp    <string>
   finalizers   <[]string>
   generateName <string>
   generation   <integer>
   labels       <map[string]string>
   managedFields        <[]Object>
   name <string>
   namespace    <string>
   ownerReferences      <[]Object>
   resourceVersion      <string>
   selfLink     <string>
   uid  <string>

在kubernetes中基本所有资源的一级属性都是一样的,主要包含5部分:
1. The apiVersion version is defined internally by kubernetes. The version number must be queried with kubectl api-versions.
2. The kind type is defined internally by kubernetes. The version number must be queried with kubectl api-resources.
3. Metadata metadata, mainly Resource identification and description, commonly used are name, namespace, labels, etc.
4. Spec description, which is the most important part of configuration, contains detailed descriptions of various resource configurations
5. Status information, the content inside does not need to be defined , automatically generated by kubernetes

Among the above attributes, spec is the focus of the next research, continue to look at its common sub-attributes:
1. containers <[]Object> container list, used to define the detailed information of the container
2. nodeName dispatches the pod to the specified Node node according to the value of nodeName
3. nodeSelector <map[]> selects the node according to the information defined in NodeSelector The Pod is scheduled to the Node containing these labels.
4. Whether hostNetwork uses the host network mode. The default is false. If it is set to true, it means that the host network is used.
5. volumes <[]Object> storage volume, used to define the pod above Loaded storage information
6. restartPolicy Restart strategy, indicating the processing strategy of the Pod when it encounters a failure

2. pod configuration

本小节主要来研究pod.spec.containers属性,这也是pod配置中最为关键的一项配置。
//Inquire

[root@master01 ~]# kubectl explain pod.spec.containers
KIND:     Pod
VERSION:  v1
RESOURCE: containers <[ ]Object>   # 数组,代表可以有多个容器
FIELDS:    //子目录
   name  <string>     # 容器名称
   image <string>     # 容器需要的镜像地址
   imagePullPolicy  <string> # 镜像拉取策略 
   command  <[ ]string> # 容器的启动命令列表,如不指定,使用打包时使用的启动命令
   args     <[ ]string> # 容器的启动命令需要的参数列表
   env      <[ ]Object> # 容器环境变量的配置
   ports    <[ ]Object>     # 容器需要暴露的端口号列表
   resources <Object>      # 资源限制和资源请求的设置

//basic configuration

创建pod-base.yaml文件,内容如下
apiVersion: v1
kind: Pod
metadata:
  name: pod-base
  namespace: test
  labels:
    user: user1
spec:
  containers:
  - name: nginx
    image: nginx:1.17.1
  - name: busybox
image: busybox:1.30

上面定义了一个比较简单Pod的配置,里面有两个容器:
nginx:用1.17.1版本的nginx镜像创建,(nginx是一个轻量级web容器)
busybox:用1.30版本的busybox镜像创建,(busybox是一个小巧的linux命令集合)

[root@master ~]# kubectl create -f pod-base.yaml 
pod/pod-base created
[root@master ~]# kubectl get pod -n test
NAME       READY   STATUS              RESTARTS   AGE
pod-base   0/2     ContainerCreating   0          12s
//查看下载的速度
[root@master ~]# kubectl describe pod pod-base -n tes

//Mirror pull

创建pod-imagepullpolicy.yaml文件:
apiVersion: v1
kind: Pod
metadata:
  name: pod-imagepullpolicy
  namespace: test
spec:
  containers:
  - name: nginx
    image: nginx:1.17.1
    imagePullPolicy: Never
  - name: busybox
image: busybox:1.30

imagePullPolicy, used to set the image pull policy, kubernetes supports configuration of three pull policies:

Always: Always pull images from remote warehouses (always download remotely)
For example: [root@master ~]# cat /etc/containerd/config.toml | grep “sandbox_image”
sandbox_image = “registry.aliyuncs.com/google_containers/pause :3.6”

IfNotPresent: Use the local image if it is available locally, and pull the image from the remote warehouse if it is not available locally (If there is a local image, there is no remote download locally) Never
: Only use the local image, never pull it from the remote warehouse, and report an error if there is no local image (always use local)

Default value description:
If the image tag is a specific version number, the default policy is: IfNotPresent
If the image tag is: latest (final version), the default policy is always

3. Start command

In the previous case, there has always been a problem that has not been resolved, that is, the busybox container has not been successfully run, so what caused the failure of this container?

It turns out that busybox is not a program, but a collection of tools . After the kubernetes cluster is started and managed, it will automatically shut down. The solution is to keep it running, which uses the command configuration .

Create a pod-command.yaml file with the following content:

apiVersion: v1
kind: Pod
metadata:
  name: pod-command1
  namespace: test
spec:
  containers:
  - name: nginx
   image: nginx:1.17.1
   imagePullPolicy: Never
  - name: busybox
image: busybox:1.30
imagePullPolicy: Never
command: ["/bin/sh","-c","touch /tmp/hello.txt;while true;do /bin/echo $(date +%T) >> /tmp/hello.txt; sleep 3; done;"]

command, used to run a command after the container in the pod is initialized.

Explain the meaning of the above command a little bit:

"/bin/sh", "-c", use sh to execute the command
touch /tmp/hello.txt; create a /tmp/hello.txt file
while true; do /bin/echo $(date +%T) >> /tmp/hello.txt; sleep 3; done; while starts the loop and writes the current time to the file every 3 seconds

[root@master ~]# kubectl create -f pod-command.yaml 
pod/pod-command1 created
[root@master ~]# kubectl get pods -n test
pod-command1           2/2     Running             0               2s

Enter the busybox container in the pod to view the file content
Add a command: kubectl exec pod name -n namespace -it -c container name /bin/sh Execute commands inside the container

Use this command to enter the interior of a container, and then For example
, you can view the contents of the txt file

[root@master ~]# kubectl exec pod-command1 -n test -it -c busybox /bin/sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
/ # tail -f /tmp/hello.txt
17:22:11
17:22:14
17:22:17
17:22:20
17:22:23
17:22:26

Special note:
Through the above, it is found that the command can already complete the function of starting the command and passing parameters . Why is there an args option for passing parameters? This is actually related to docker. The command and args in kubernetes are actually Implement the function of overriding entrypoint in Dockerfile.

1 If both command and args are not written, then use the Dockerfile configuration.
2 If the command is written, but the args are not written, then the default configuration of the Dockerfile will be ignored, and the
input command will be executed. 3 If the command is not written, but the args are written, then the ENTRYPOINT command configured in the Dockerfile will be executed, using the current args Parameter
4 If both command and args are written, then the configuration of the Dockerfile is ignored, and the command is executed and the args parameter is appended

//environment variable
Create pod-env.yaml file:

apiVersion: v1
kind: Pod
metadata:
  name: pod-env
  namespace: test
spec:
  containers:
  - name: busybox
    image: busybox:1.30
    imagePullPolicy: Never
    command: ["/bin/sh","-c","while true;do /bin/echo $(date +%T);sleep 60; done;"]
    env:
    - name: "username"
      value: "admin"
    - name: "password"
      value: "redhat"

env, environment variable, is used to set environment variables in the container in the pod.

[root@master ~]# kubectl create -f pod-env.yaml 
pod/pod-env created
pod-env                1/1     Running            0               16s
[root@master ~]# kubectl exec pod-env -n test -c busybox -it /bin/sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
/ # echo $username
admin
/ # echo $password
redhat
这种方式不是很推荐,推荐将这些配置单独存储在配置文件中,这种方式将在后面介绍。

4. Port port configuration

This section introduces the port settings of the container, that is, the ports option of containers.
First look at the sub-options supported by ports:

[root@k8s-master01 ~]# kubectl explain pod.spec.containers.ports
KIND:     Pod
VERSION:  v1
RESOURCE: ports <[ ]Object>
FIELDS:
   name         <string>  # 端口名称,如果指定,必须保证name在pod中是唯一的		
   containerPort<integer> # 容器要监听的端口(0<x<65536)
   hostPort     <integer> # 容器要在主机上公开的端口,如果设置,主机上只能运行容器的一个副本(一般省略) 
   hostIP       <string>  # 要将外部端口绑定到的主机IP(一般省略)
   protocol     <string>  # 端口协议。必须是UDP、TCP或SCTP。默认为“TCP”。

Next, write a test case, create pod-ports.yaml

apiVersion: v1
kind: Pod
metadata:
  name: pod-ports
  namespace: test
spec:
  containers:
  - name: nginx
    image: nginx:1.17.1
    imagePullPolicy: Never
    ports:
    - name: nginx-port
      containerPort: 80
      protocol: TCP

[root@master ~]# kubectl create -f pod-ports.yaml 
pod/pod-ports created
[root@master ~]# kubectl get pod -n test
pod-ports              1/1     Running            0                10s
[root@master ~]# kubectl get pod pod-ports -n test -o yaml
......
spec:
  containers:
  - image: nginx:1.17.1
    imagePullPolicy: Never
    name: nginx
    ports:
    - containerPort: 80
      name: nginx-port
      protocol: TCP
访问容器中的程序需要使用的是Podip:containerPort
[root@master ~]# kubectl get pod pod-ports -n test -o wide
NAME        READY   STATUS    RESTARTS   AGE     IP            NODE    NOMINATED NODE   READINESS GATES
pod-ports   1/1     Running   0          3m40s   10.244.1.16   node1   <none>           <none>
[root@master ~]# curl http://10.244.1.16:80

3. Resource quota

To run a program in a container, it must occupy certain resources, such as CPU and memory. If the resources of a container are not limited, it may consume a lot of resources, causing other containers to fail to run. In response to this situation, kubernetes provides a mechanism for quotas on memory and cpu resources . This mechanism is mainly implemented through the resources option, which has two sub-options:

Limits: Used to limit the maximum resources occupied by the container at runtime. When the container occupies more resources than the limits, it will be terminated and restarted.
requests: Used to set the minimum resources required by the container. If the environment resources are not enough, the container will not start
. Two options set upper and lower bounds for resources.

Next, write a test case, create pod-resources.yaml

apiVersion: v1
kind: Pod
metadata:
  name: pod-resources
  namespace: test
spec:
  containers:
  - name: nginx
    image: nginx:1.17.1
    imagePullPolicy: Never
    resources:       //资源限制
      limits:     //资源限制(上限)
        cpu: "2"     //cpu限制,单位是core数
        memory: "10Gi"   //内存限制
      requests:     //请求资源
        cpu: "1"     
        memory: "10Mi"

在这对cpu和memory的单位做一个说明:
cpu: the number of cores, which can be an integer or a decimal
memory: memory size, which can be in the form of Gi, Mi, G, M, etc.

[root@master ~]# kubectl create -f pod-resources.yaml 
pod/pod-resources created
[root@master ~]# kubectl get pods -n test
pod-resources          1/1     Running            0                10s


先停止删除该pod
[root@master ~]# kubectl delete -f pod-resources.yaml 
pod "pod-resources" deleted

再编辑pod,修改resources.requests.memory的值为10Gi
[root@master ~]# vim pod-resources.yaml

[root@master ~]# kubectl create -f pod-resources.yaml
pod/pod-resources created
[root@master ~]# kubectl get pods -n test
pod-resources          0/1     Pending            0                16s
//用于创建的资源
[root@master ~]# kubectl describe pod pod-resources -n test
Warning  FailedScheduling  87s   default-scheduler  0/3 nodes are available: 1 node(s) had untolerated taint {node-role.kubernetes.io/control-plane: }, 3 Insufficient memory. preemption: 0/3 nodes are available: 1 Preemption is not helpful for scheduling, 2 No preemption victims found for incoming pod.

Guess you like

Origin blog.csdn.net/cxyxt/article/details/128163097