kubernetes实战入门之Service Pod

Service

通过上节课的学习,已经能够利用Deployment来创建一组Pod来提供具有高可用性的服务。
虽然每个Pod都会分配一个单独的Pod IP,然而却存在如下两问题:

Pod IP 会随着Pod的重建产生变化
Pod IP 仅仅是集群内可见的虚拟IP,外部无法访问
这样对于访问这个服务带来了难度。因此,kubernetes设计了Service来解决这个问题。

Service可以看作是一组同类Pod对外的访问接口。借助Service,应用可以方便地实现服务发现和负载均衡。

创建集群内部可访问的Service

暴露Service
[root@master ~]#  kubectl create  ns dev
namespace/dev created
[root@master ~]# kubectl create deploy nginx --image=nginx --port=80  -n dev                                 deployment.apps/nginx created
[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.98.88.219   <none>        80/TCP    7s    app=nginx
# 这里产生了一个CLUSTER-IP,这就是service的IP,在Service的生命周期中,这个地址是不会变动的
# 可以通过这个IP访问当前service对应的POD
[root@master ~]# curl 10.98.88.219
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

创建集群外部也可访问的Service

# 上面创建的Service的type类型为ClusterIP,这个ip地址只用集群内部可访问# 如果需要创建外部也可以访问的Service,需要修改type为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:31362/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.103.238.44   <none>        80:31362/TCP   6s    app=nginx
# 接下来就可以通过集群外的主机访问 节点IP:35128访问服务了
# 例如在的电脑主机上通过浏览器访问下面的地址

在这里插入图片描述
删除Service

[root@master ~]#  kubectl delete svc svc-nginx1 -n dev
service "svc-nginx1" deleted

配置方式

[root@master ~]# vim svc-nginx.yaml
[root@master ~]# cat svc-nginx.yaml
apiVersion: v1
kind: Service
metadata:
  name: svc-nginx
  namespace: dev
spec:
  clusterIP: 10.98.88.219       #固定svc的内网ip
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    run: nginx
  type: ClusterIP


创建

[root@master ~]# kubectl create -f svc-nginx.yaml
service/svc-nginx created

删除

[root@master ~]# kubectl delete -f svc-nginx.yaml
service "svc-nginx" deleted

pod

pod的资源清单

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|IfNotPresent ]   #获取镜像的策略 
    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
#小提示:
#   在这里,可通过一个命令来查看每种资源的可配置项
#   kubectl explain 资源类型         查看某种资源可以配置的一级属性
#   kubectl explain 资源类型.属性     查看属性的子属性


[root@master ~]# kubectl explain pod
KIND:     Pod
VERSION:  v1

DESCRIPTION:
     Pod is a collection of containers that can run on a host. This resource is
     created by clients and scheduled onto hosts.

FIELDS:
   apiVersion   <string>
     APIVersion defines the versioned schema of this representation of an
     object. Servers should convert recognized schemas to the latest internal
     value, and may reject unrecognized values. More info:
     https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources

   kind <string>
     Kind is a string value representing the REST resource this object
     represents. Servers may infer this from the endpoint the client submits
     requests to. Cannot be updated. In CamelCase. More info:
     https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds

   metadata     <Object>
     Standard object's metadata. More info:
     https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

   spec <Object>
     Specification of the desired behavior of the pod. More info:
     https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status

   status       <Object>
     Most recently observed status of the pod. This data may not be up to date.
     Populated by the system. Read-only. More info:
     https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status

[root@master ~]# kubectl explain pod.metadata
KIND:     Pod
VERSION:  v1

RESOURCE: metadata <Object>

DESCRIPTION:
     Standard object's metadata. More info:
     https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

     ObjectMeta is metadata that all persisted resources must have, which
     includes all objects users must create.

FIELDS:
   annotations  <map[string]string>
     Annotations is an unstructured key value map stored with a resource that
     may be set by external tools to store and retrieve arbitrary metadata. They
     are not queryable and should be preserved when modifying objects. More
     info: http://kubernetes.io/docs/user-guide/annotations

   creationTimestamp    <string>
     CreationTimestamp is a timestamp representing the server time when this
     object was created. It is not guaranteed to be set in happens-before order
     across separate operations. Clients may not set this value. It is
     represented in RFC3339 form and is in UTC.

     Populated by the system. Read-only. Null for lists. More info:
     https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

   deletionGracePeriodSeconds   <integer>
     Number of seconds allowed for this object to gracefully terminate before it
     will be removed from the system. Only set when deletionTimestamp is also
     set. May only be shortened. Read-only.

   deletionTimestamp    <string>
     DeletionTimestamp is RFC 3339 date and time at which this resource will be
     deleted. This field is set by the server when a graceful deletion is
     requested by the user, and is not directly settable by a client. The
     resource is expected to be deleted (no longer visible from resource lists,
     and not reachable by name) after the time in this field, once the
     finalizers list is empty. As long as the finalizers list contains items,
     deletion is blocked. Once the deletionTimestamp is set, this value may not
     be unset or be set further into the future, although it may be shortened or
     the resource may be deleted prior to this time. For example, a user may
     request that a pod is deleted in 30 seconds. The Kubelet will react by
     sending a graceful termination signal to the containers in the pod. After
     that 30 seconds, the Kubelet will send a hard termination signal (SIGKILL)
     to the container and after cleanup, remove the pod from the API. In the
     presence of network partitions, this object may still exist after this
     timestamp, until an administrator or automated process can determine the
     resource is fully terminated. If not set, graceful deletion of the object
     has not been requested.

     Populated by the system when a graceful deletion is requested. Read-only.
     More info:
     https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

   finalizers   <[]string>
     Must be empty before the object is deleted from the registry. Each entry is
     an identifier for the responsible component that will remove the entry from
     the list. If the deletionTimestamp of the object is non-nil, entries in
     this list can only be removed. Finalizers may be processed and removed in
     any order. Order is NOT enforced because it introduces significant risk of
     stuck finalizers. finalizers is a shared field, any actor with permission
     can reorder it. If the finalizer list is processed in order, then this can
     lead to a situation in which the component responsible for the first
     finalizer in the list is waiting for a signal (field value, external
     system, or other) produced by a component responsible for a finalizer later
     in the list, resulting in a deadlock. Without enforced ordering finalizers
     are free to order amongst themselves and are not vulnerable to ordering
     changes in the list.

   generateName <string>
     GenerateName is an optional prefix, used by the server, to generate a
     unique name ONLY IF the Name field has not been provided. If this field is
     used, the name returned to the client will be different than the name
     passed. This value will also be combined with a unique suffix. The provided
     value has the same validation rules as the Name field, and may be truncated
     by the length of the suffix required to make the value unique on the
     server.

     If this field is specified and the generated name exists, the server will
     return a 409.

     Applied only if Name is not specified. More info:
     https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#idempotency

   generation   <integer>
     A sequence number representing a specific generation of the desired state.
     Populated by the system. Read-only.

   labels       <map[string]string>
     Map of string keys and values that can be used to organize and categorize
     (scope and select) objects. May match selectors of replication controllers
     and services. More info: http://kubernetes.io/docs/user-guide/labels

   managedFields        <[]Object>
     ManagedFields maps workflow-id and version to the set of fields that are
     managed by that workflow. This is mostly for internal housekeeping, and
     users typically shouldn't need to set or understand this field. A workflow
     can be the user's name, a controller's name, or the name of a specific
     apply path like "ci-cd". The set of fields is always in the version that
     the workflow used when modifying the object.

   name <string>
     Name must be unique within a namespace. Is required when creating
     resources, although some resources may allow a client to request the
     generation of an appropriate name automatically. Name is primarily intended
     for creation idempotence and configuration definition. Cannot be updated.
     More info: http://kubernetes.io/docs/user-guide/identifiers#names

   namespace    <string>
     Namespace defines the space within which each name must be unique. An empty
     namespace is equivalent to the "default" namespace, but "default" is the
     canonical representation. Not all objects are required to be scoped to a
     namespace - the value of this field for those objects will be empty.

     Must be a DNS_LABEL. Cannot be updated. More info:
     http://kubernetes.io/docs/user-guide/namespaces

   ownerReferences      <[]Object>
     List of objects depended by this object. If ALL objects in the list have
     been deleted, this object will be garbage collected. If this object is
     managed by a controller, then an entry in this list will point to this
     controller, with the controller field set to true. There cannot be more
     than one managing controller.

   resourceVersion      <string>
     An opaque value that represents the internal version of this object that
     can be used by clients to determine when objects have changed. May be used
     for optimistic concurrency, change detection, and the watch operation on a
     resource or set of resources. Clients must treat these values as opaque and
     passed unmodified back to the server. They may only be valid for a
     particular resource or set of resources.

     Populated by the system. Read-only. Value must be treated as opaque by
     clients and . More info:
     https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency

   selfLink     <string>
     Deprecated: selfLink is a legacy read-only field that is no longer
     populated by the system.

   uid  <string>
     UID is the unique in time and space value for this object. It is typically
     generated by the server on successful creation of a resource and is not
     allowed to change on PUT operations.

     Populated by the system. Read-only. More info:
     http://kubernetes.io/docs/user-guide/identifiers#uids

在kubernetes中基本所有资源的一级属性都是一样的,主要包含5部分
1、apiVersion 版本,由kubernetes内部定义,版本号必须可以用 kubectl api-versions 查询到
2、kind 类型,由kubernetes内部定义,版本号必须可以用 kubectl api-resources 查询到
3、metadata 元数据,主要是资源标识和说明,常用的有name、namespace、labels等
4、spec描述,这是配置中最重要的一部分,里面是对各种资源配置的详细描述
5、status状态信息,里面的内容不需要定义,由kubernetes自动生成

在上面的属性中,spec是接下来研究的重点,继续看下它的常见子属性
1、containers <[]Object> 容器列表,用于定义容器的详细信息
2、nodeName 根据nodeName的值将pod调度到指定的Node节点上
3、nodeSelector <map[]> 根据NodeSelector中定义的信息选择将该Pod调度到包含这些label的Node 上
4、hostNetwork 是否使用主机网络模式,默认为false,如果设置为true,表示使用宿主机网络
5、volumes <[]Object> 存储卷,用于定义Pod上面挂载的存储信息
6、restartPolicy 重启策略,表示Pod在遇到故障的时候的处理策略

pod配置

[root@master ~]# 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>                        # 资源限制和资源请求的设置



//基本配置
创建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


//镜像拉取
创建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,用于设置镜像拉取策略,kubernetes支持配置三种拉取策略:

Always:总是从远程仓库拉取镜像(一直远程下载)
IfNotPresent:本地有则使用本地镜像,本地没有则从远程仓库拉取镜像(本地有就本地 本地没远程下载)
Never:只使用本地镜像,从不去远程仓库拉取,本地没有就报错 (一直使用本地)

默认值说明:
如果镜像tag为具体版本号, 默认策略是:IfNotPresent
如果镜像tag为:latest(最终版本) ,默认策略是always
[root@master ~]# kubectl create -f pod-imagepullpolicy.yaml
//启动命令
在前面的案例中,一直有一个问题没有解决,就是的busybox容器一直没有成功运行,那么到底是什么原因导致这个容器的故障呢?

原来busybox并不是一个程序,而是类似于一个工具类的集合,kubernetes集群启动管理后,它会自动关闭。解决方法就是让其一直在运行,这就用到了command配置。

ommand,用于在pod中的容器初始化完毕之后运行一个命令。

稍微解释下上面命令的意思:

“/bin/sh”,“-c”, 使用sh执行命令

touch /tmp/hello.txt; 创建一个/tmp/hello.txt 文件

while true;do /bin/echo $(date +%T) >> /tmp/hello.txt; sleep 3; done; 每隔3秒向文件中写入当前时间
[root@master ~]# cat pod-command1.yml
apiVersion: v1
kind: Pod
metadata:
  name: pod-command2
  namespace: dev
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;"]

[root@master ~]#  kubectl create -f pod-command1.yml
pod/pod-command2 created
[root@master ~]#  kubectl get pod -n dev
NAME                    READY   STATUS              RESTARTS         AGE
nginx-ff6774dc6-vwm6r   1/1     Running             0                51m
pod-command2            2/2     Running             0                4s
# 进入pod中的busybox容器,查看文件内容
# 补充一个命令: kubectl exec  pod名称 -n 命名空间 -it -c 容器名称 /bin/sh  在容器内部执行命令
# 使用这个命令就可以进入某个容器的内部,然后进行相关操作了
# 比如,可以查看txt文件的内容
[root@master ~]# kubectl exec pod-command2 -n dev -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
13:26:52
13:26:55
13:26:58
13:27:01
13:27:04
13:27:07
13:27:10
13:27:13
13:27:16
13:27:19
13:27:22
13:27:25
13:27:28
13:27:31

特别说明:

通过上面发现command已经可以完成启动命令和传递参数的功能,为什么这里还要提供一个args选项,用于传递参数呢?这其实跟docker有点关系,kubernetes中的command、args两项其实是实现覆盖Dockerfile中ENTRYPOINT的功能。
1 如果command和args均没有写,那么用Dockerfile的配置。
2 如果command写了,但args没有写,那么Dockerfile默认的配置会被忽略,执行输入的command
3 如果command没写,但args写了,那么Dockerfile中配置的ENTRYPOINT的命令会被执行,使用当前args的参数
4 如果command和args都写了,那么Dockerfile的配置被忽略,执行command并追加上args参数

环境变量

[root@master ~]# cat  zlh1-env.yaml
apiVersion: v1
kind: Pod
metadata:
  name: zlh1-env
  namespace: dev
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,环境变量,用于在pod中的容器设置环境变量。
[root@master ~]# kubectl get pods -n dev
NAME                    READY   STATUS              RESTARTS         AGE
nginx-ff6774dc6-vwm6r   1/1     Running             0                72m
pod-command1            0/2     ErrImageNeverPull   0                32m
pod-command2            2/2     Running             0                21m
pod-zhan                1/2     CrashLoopBackOff    15 (3m10s ago)   55m
zlh-env                 0/1     ErrImageNeverPull   0                6m33s
zlh1-env                1/1     Running             0                5s


[root@master ~]# kubectl exec zlh1-env -n dev -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
/ # exit

端口配置

[root@master ~]# 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”。
[root@master ~]# vim zhan2-ports.yaml
[root@master ~]# cat zhan2-ports.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod2-ports
  namespace: dev
spec:
  containers:
  - name: nginx
    image: nginx:1.17.1
    imagePullPolicy: Never
    ports:
    - name: nginx-port
      containerPort: 80
      protocol: TCP

[root@master ~]# kubectl create -f zhan2-ports.yaml
pod/pod2-ports created
[root@master ~]# kubectl get pod -n  dev
NAME                    READY   STATUS              RESTARTS         AGE
pod2-ports              1/1     Running             0                3s

[root@master ~]# kubectl get pod pod2-ports -n dev -o yaml
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: "2022-11-29T13:45:37Z"
  name: pod2-ports
  namespace: dev
  resourceVersion: "12235"
  uid: 59543952-91bf-4ecf-9c9a-95d1c01bf592
spec:
  containers:
  - image: nginx:1.17.1
    imagePullPolicy: Never
    name: nginx
    ports:
    - containerPort: 80
      name: nginx-port
      protocol: TCP
    resources: {}
    terminationMessagePath: /dev/termination-log
    terminationMessagePolicy: File
    volumeMounts:
    - mountPath: /var/run/secrets/kubernetes.io/serviceaccount
      name: kube-api-access-8n5zw
      readOnly: true
  dnsPolicy: ClusterFirst
  enableServiceLinks: true
  nodeName: node2.example.com
  preemptionPolicy: PreemptLowerPriority
  priority: 0
  restartPolicy: Always
  schedulerName: default-scheduler
  securityContext: {}
  serviceAccount: default
  serviceAccountName: default
  terminationGracePeriodSeconds: 30
  tolerations:
  - effect: NoExecute
    key: node.kubernetes.io/not-ready
    operator: Exists
    tolerationSeconds: 300
  - effect: NoExecute
    key: node.kubernetes.io/unreachable
    operator: Exists
    tolerationSeconds: 300
  volumes:
  - name: kube-api-access-8n5zw
    projected:
      defaultMode: 420
      sources:
      - serviceAccountToken:
          expirationSeconds: 3607
          path: token
      - configMap:
          items:
          - key: ca.crt
            path: ca.crt
          name: kube-root-ca.crt
      - downwardAPI:
          items:
          - fieldRef:
              apiVersion: v1
              fieldPath: metadata.namespace
            path: namespace
status:
  conditions:
  - lastProbeTime: null
    lastTransitionTime: "2022-11-29T13:45:37Z"
    status: "True"
    type: Initialized
  - lastProbeTime: null
    lastTransitionTime: "2022-11-29T13:45:38Z"
    status: "True"
    type: Ready
  - lastProbeTime: null
    lastTransitionTime: "2022-11-29T13:45:38Z"
    status: "True"
    type: ContainersReady
  - lastProbeTime: null
    lastTransitionTime: "2022-11-29T13:45:37Z"
    status: "True"
    type: PodScheduled
  containerStatuses:
  - containerID: containerd://cbf92cbc634a2e8d62bc79013590761275670624d8825a0d8d4179712ea406fe
    image: docker.io/library/nginx:1.17.1
    imageID: docker.io/library/nginx@sha256:b4b9b3eee194703fc2fa8afa5b7510c77ae70cfba567af1376a573a967c03dbb
    lastState: {}
    name: nginx
    ready: true
    restartCount: 0
    started: true
    state:
      running:
        startedAt: "2022-11-29T13:45:38Z"
  hostIP: 192.168.193.130
  phase: Running
  podIP: 10.244.2.7
  podIPs:
  - ip: 10.244.2.7
  qosClass: BestEffort
  startTime: "2022-11-29T13:45:37Z"

访问容器中的程序需要使用的是Podip:containerPort

[root@master ~]# kubectl get pod pod2-ports -n dev -o wide
NAME         READY   STATUS    RESTARTS   AGE     IP           NODE                NOMINATED NODE   READINESS GATES
pod2-ports   1/1     Running   0          2m14s   10.244.2.7   node2.example.com   <none>           <none>
[root@master ~]# curl 10.244.2.7
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

资源配额

容器中的程序要运行,肯定是要占用一定资源的,比如cpu和内存等,如果不对某个容器的资源做限制,那么它就可能吃掉大量资源,导致其它容器无法运行。针对这种情况,kubernetes提供了对内存和cpu的资源进行配额的机制,这种机制主要通过resources选项实现,他有两个子选项:

limits:用于限制运行时容器的最大占用资源,当容器占用资源超过limits时会被终止,并进行重启
requests :用于设置容器需要的最小资源,如果环境资源不够,容器将无法启动
可以通过上面两个选项设置资源的上下限。

[root@master ~]# cat zhan-resources.yaml
apiVersion: v1
kind: Pod
metadata:
  name: zhan-resources
  namespace: dev
spec:
  containers:
  - name: nginx
    image: nginx:1.17.1
    imagePullPolicy: Never
    resources:
      limits:
        cpu: "2"
        memory: "10Gi"
      requests:
        cpu: "1"
        memory: "10Mi"

在这对cpu和memory的单位做一个说明:
cpu:core数,可以为整数或小数
memory: 内存大小,可以使用Gi、Mi、G、M等形式
[root@master ~]# kubectl create -f zhan-resources.yaml
pod/zhan-resources created
[root@master ~]#  kubectl get pod -n  dev
NAME                    READY   STATUS              RESTARTS         AGE
zhan-resources          1/1     Running             0                9s

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

#再编辑pod,修改resources.requests.memory的值为10Gi
[root@master ~]# vim zhan-resources.yaml
[root@master ~]# cat zhan-resources.yaml
apiVersion: v1
kind: Pod
metadata:
  name: zhan-resources
  namespace: dev
spec:
  containers:
  - name: nginx
    image: nginx:1.17.1
    imagePullPolicy: Never
    resources:
      limits:
        cpu: "2"
        memory: "10Gi"
      requests:
        cpu: "1"
        memory: "10Gi"
[root@master ~]#  kubectl create -f zhan-resources.yaml
pod/zhan-resources created
[root@master ~]#  kubectl get pods -n dev
NAME                    READY   STATUS              RESTARTS       AGE
zhan-resources          0/1     Pending             0              9s

[root@master ~]# kubectl describe pod zhan-resources -n dev
Name:             zhan-resources
Namespace:        dev
Priority:         0
Service Account:  default
Node:             <none>
Labels:           <none>
Annotations:      <none>
Status:           Pending
IP:
IPs:              <none>
Containers:
  nginx:
    Image:      nginx:1.17.1
    Port:       <none>
    Host Port:  <none>
    Limits:
      cpu:     2
      memory:  10Gi
    Requests:
      cpu:        1
      memory:     10Gi
    Environment:  <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-n5pbp (ro)
Conditions:
  Type           Status
  PodScheduled   False
Volumes:
  kube-api-access-n5pbp:
    Type:                    Projected (a volume that contains injected data from multiple sources)
    TokenExpirationSeconds:  3607
    ConfigMapName:           kube-root-ca.crt
    ConfigMapOptional:       <nil>
    DownwardAPI:             true
QoS Class:                   Burstable
Node-Selectors:              <none>
Tolerations:                 node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                             node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
  Type     Reason            Age   From               Message
  ----     ------            ----  ----               -------
  Warning  FailedScheduling  34s   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.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值