学习完资源清单后,记得要回去看看一个资源的创建过程。

 

    K8S中所有内容都抽象为资源,资源实例化之后,叫作对象。

  

类型

资源

工作负载型(workload)

Pod、ReplicaSet、Deployment、StatefulSet、DaemonSet、Job、CronJob(ReplicationController在v1.11版本被废弃了)

服务发现及负载均衡型(ServiceDiscovery LoadBalance)

Service、Ingress

配置与存储型

Volume、CSI(容器存储接口,可以扩展第三方存储卷)

特殊类型的存储卷

ConfigMap、Secret、DownwardAPI(外部环境中的信息输给容器)

集群级型

NameSpace、Node、Role、ClusterRole、RoleBinding、ClusterRoleBinding

元数据型

HPA、PodTemplate、LimitRange

 

  

资源清单常用字段

在K8S中,一般使用yaml格式的文件来创建符合预期期望的Pod,这样的yaml文件一般称为资源清单。

 

必备属性:

名称

类型

说明

version

String

目前基本是v1版本,可以用kubectl api-versions命令查询

kind

String

yaml文件定义的资源类型和角色,比如Pod

metadata

Object

元数据对象,固定值

metadata.name

String

元数据对象的名字,用户编写,如命名Pod的名字

spec

Object

详细定义,固定值

spec.containers[]

List

容器列表定义

 

主要对象(非必须,有默认值):

名称

类型

说明

metadata.namespace

String

元数据对象的命名空间,用户自定义,默认是default

spec.containers[].name

String

容器的名字

spec.containers[].image

String

镜像名称

spec.containers[].imagePullPolicy

String

镜像拉取策略

Always每次都会尝试重新拉取,有时发现本地有镜像却出现拉取失败,因链接不上对应的网络

IfNotPresent本地有则用本地,没有则在线拉取

Nerver仅使用本地

spec.containers[].command[]

List

指定容器启动命令,因为是数组可以指定多个,不指定则使用镜像打包时使用的启动命令

spec.containers[].args[]

List

指定容器启动命令参数,因为是数组可以指定多个

spec.containers[].workingDir

String

容器工作目录

spec.containers[].volumeMounts[]

List

容器内部的存储卷配置

spec.containers[].volumeMounts[].name

String

可以被容器挂载的存储卷的名称

spec.containers[].volumeMounts[].mountPath

String

可以被容器挂载的存储卷的路径

spec.containers[].volumeMounts[].readOly

String

设置存储卷的读写模式,true或false,默认为读写模式

spec.containers[].ports[]

List

容器需要用到的端口列表

spec.containers[].port[].name

String

端口名称

spec.containers[].port[].containerPort

String

容器需要监听的端口

spec.containers[].port[].hostPort

String

容器所在主机需要监听的端口号,默认跟上面的containerPort相同。

注意:设置了hostPort同一台主机无法启动该容器的相同副本,因为主机的端口号不能相同,这样会冲突

spec.containers[].port[].protocol

String

端口协议,支持TCP和UDP,默认TCP

spec.containers[].env[]

List

容器运行前需设置的环境变量列表

spec.containers[].env[].name

String

容器运行前需设置的环境变量名

spec.containers[].env[].value

String

容器运行前需设置的环境变量值

spec.containers[].resources

Object

指定资源限制和资源请求的值(设置容器资源上限)

spec.containers[].resources.limits

Object

指定容器运行时的资源上限

spec.containers[].resources.limits.cpu

String

指定CPU限制,单位为core数,将用于docker run –cpu-shares参数

spec.containers[].resources.limits.memory

String

指定MEM内存的限制,单位是MIB、GIB

spec.containers[].resources.requests

Object

指定容器启动和调度时的限制设置

spec.containers[].resources.requests.cpu

String

CPU请求,单位为core数,容器启动时初始化可用数量

spec.containers[].resources.requests.memory

String

内存请求,单位为MIN、GIB,容器启动时初始化可用数量

spec.restartPolicy

String

定义Pod重启策略

Always是指无论Pod是如何终止的,Kubelet都会重启此Pod,默认是这个值。

OnFailure只有Pod以非0退出码终止时,kubelet才回重启该容器,如果容器正常结束(退出码为0),kebelet将不会重启它

Never是指Pod终止后,kubelet会把退出码报告给Master,但不会重启该Pod

spec.nodeSelector

Object

定义Node的Label过滤标签,以key:value格式指定

spec.imagePullSecrets

Object

Pull镜像时使用secret名称,以name:secretkey格式指定

spec.hostNetwork

Boolean

定义是否使用主机网络模式,默认值为false,设置true就标识使用宿主机网络,不使用docker网桥,同时设置了true将无法在同一台宿主机上启动第二个副本

 

第一个资源清单的制作:

vi test-pod.yaml

〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓

#指定K8S Api版本

apiVersion: v1

#指定yaml文件定义的资源类型和角色

kind: Pod

#元数据对象,固定值

metadata:

 #元数据对象的名称,kind指定的资源类型是Pod,这里指的是Pod的名称

 name: testapp-pod

 #所属的名称空间

 namespace: default

 #标签

 labels:

   app: myapp

   version: v1

#固定对象

spec:

 #运行的容器列表

 containers:

  #容器名

  - name: app1

    #运行的镜像

    image: levi.harbor.com/library/nginx:1.9.1

  - name: app2

    image: levi.harbor.com/library/nginx:1.9.1

〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓

 

#一个pod中运行2个相同容器,会出现端口占用

kubectl apply -f test-pod.yaml 

   

kubectl get pod

 

#查看pod的信息

kubectl describe pod myapp-pod(容器名)

   

#查看容器日志,不需要指定容器就不需要加-c

kubectl log myapp-pod -c test

   

#把test给删除,留下app

   

kubectl delete pod myapp-pod

 

kubectp create -f test-pod.yaml

 

容器的生命周期

Pod容器的生命周期:

 

    Pod生命周期的整个过程都是存储在Etcd的。

    详细过程简述:kubectl à kubelet à CRI à 容器环境初始化 à Pause(基础容器,负责网络和基础卷共享) à InitC(初始化容器,初始化完成后就死亡了,可能有多个,但是多个InitC是不能并行的) à Start(容器运行之前执行) à Readiness(就绪)à Liveness(生存检测) à Stop(容器结束之前执行)

 

    每一个Pod都有一个特殊的被称为根容器的Pause容器。Pause容器又叫Infra容器,在检查node节点时,会发现每个node上都运行了很多Pause容器。

 

InitC容器

    Pod能够具有多个容器,应用运行在容器里面,但是它也有可能有一个或多个先于应用容器启动的Init容器。

    Init容器与普通容器非常像,但具有两点明显区别。一、Init容器总是运行到成功完成为止;二、每个Init容器都必须在下一个Init容器启动之前成功完成。

    如果Pod的Init容器失败,K8S会不断的重启该Pod,知道Init容器成功为止,然而如果Pod对应的restartPolicy为Netver,它将不会重新启动。

   

Init容器具有与应用程序容器分离的单独镜像,所以它们启动相关代码时,具有一些优势:

    它们可以包含并允许实用工具,但是出于安全考虑,是不建议在应用程序容器镜像中包含这些实用工具的。

   它们可以包含使用工具和定制化代码来安装,但是不能出现在应用程序镜像中。例如,创建镜像没必要FROM另一个镜像,只需要安装过程中使用类似sed、awk、python或dig这样的工具。

    应用程序镜像可以分离出创建和部署的角色,而没有必要联合它们构建一个单独的镜像。

    Init容器使用Liunx NameSpace,所以相对应用程序容器来说具有不同的文件系统视图。因此,它们能够具有访问Secret的权限,而应用程序容器则不能。

    它们必须在应用程序容器启动之前运行完成,而应用程序容器是并行运行的,所以Init容器能够提供一种简单的阻塞或延迟应用容器的启动的方法,知道满足了一组先决条件。

 

InitC实验:

    在Pod启动过程中,Init容器会按照顺序在网络和数据卷初始化之后启动,即Pause启动后启动。每个容器必须在下一个容器之前成功退出。

    如果由于运行时或失败退出,将导致容器启动失败,它会根据Pod的restartPolicy指定的策略进行重试,然而,如果Pod的restartPolicy设置为Always,Init容器失败时会使用RestartPolicy策略。

    在所有Init容器没有成功之前,Pod将不会变成Ready状态。Init容器的端口将不会在Service中进行聚集。正在初始化中的Pod处于Pending桩体,但应该会将Initalizing状态设置为true。

    如果Pod重启,所有Init容器必须重新执行。

    对Init容器spec的修改被限制在容器image字段,修改其他字段都不会生效。更改Init容器的image字段,等价于重启该Pod。

    Init容器具有应用容器的所有字段。除了readinessProbe,因为Init容器无法定义不同于完成(completion)的就绪(readiness)之外的其他状态。

    在Pod中每个app和Init容器的名称必须唯一;与任何其他容器共享同一个名称。

vi ini-pod.yaml

〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓

#指定K8S Api版本

apiVersion: v1

#指定yaml文件定义的资源类型和角色

kind: Pod

#元数据对象,固定值

metadata:

 #元数据对象的名称,kind指定类型是Pod,这里指的就是Pod的名称

 name: detect-pod1

 #名称空间

 namespace: default

 #标签

 labels:

  app: myapp

#详细定义对象,固定对象

spec:

 #运行的容器列表

 containers:

 #运行的容器名

 - name: myapp-container

   #镜像

   image: busybox

   #指定容器启动命令,因为是数组可以指定多个,不指定则使用镜像打包时的启动命令

   command: ['sh','-c','echo running! && sleep 3600']

 #初始化容器,即容器会先启动一个或多个容器,如果有多个,这几个Init Container按照容器的定义顺序会先启动,只有Init Container执行完后,主容器才会启动

 #注意:名称不可以相同,端口可以相同,因为其中一个容器执行完成后就退出了,下一个容器即便端口一样还是不会报错,可以运行的

 initContainers:

 #容器名

 - name: init1-myservice

   #镜像

   image: busybox

   #指定容器启动命令

   #启动时会去解析myservice这个主机名,K8S DNS会把svc、pod、service解析成为IP,一旦有了这个myservice命名的svc/pod/service,K8S内部就会解析为IP。

   #这条命令的意思是如果找不到(flase),则会打印出一句话后休眠2秒。

   command: ['sh','-c','until nslookup myservice;do echo waiting for myservice;sleep 2;done;']

 #容器名

 - name: init2-mydb

   #镜像

   image: levi.harbor.com/library/nginx:1.9.1

   #指定容器启动命令

   #启动时会去解析mydb这个主机名,K8S会把svc、pod、service解析成为IP,一旦有了这个mydb命名的svc/pod/service,K8S内部就会解析成为IP。

   #这条命令的意思是如果找不到(false),则会打印出一句话后休眠2秒。

   command: ['sh','-c','until nslookup mydb;do echo waiting for mydb;sleep 2;done;']

〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓

kubectl get pod

kubectl delete pod --all

kubectl delete deployment --all

kubectl delete svc --all

 

kubectl create -f init-pod.yaml

 

#看Status

kubectl get pod

 

#看详细信息

 kubectl describe pod detect-pod1

 

#仔细关注日志

kubectl log detect-pod1 -c init1-myservice

 

#仔细看提示信息

kubectl log detect-pod1 -c init2-mydb

 

#回过来看

kubectl get pod

 

vi myservice.yaml

〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓

#指定K8S Api版本

apiVersion: v1

#指定yaml文件定义的资源类型和角色

kind: Service

#元数据对象

metadata:

 name: myservice

#详细定义对象

spec:

 #定义端口(多个)

 ports:

  #端口的协议

  - protocol: TCP

    #端口是80

    port: 80

    #暴露的svc的端口

    targetPort: 9577

〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓

kubectl create -f myservice.yaml

kubectl get svc

#会发现Init变成1/2了

kubectl get pod

 

vi mydb.yaml

〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓

#指定k8s api版本

apiVersion: v1

#指定yaml文件定义的资源类型和角色

kind: Service

#元数据对象

metadata:

 #运行的资源类型的名称,指定的是SVC即SVC的名称

 name: mydb

#详细定义对象

spec:

 #定义端口(多个)

 ports:

  - protocol: TCP

    #端口

    port: 80

    #暴露的svc的端口

    targetPort: 9578

〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓

 

kubectl create -f mydb.yaml

 

kubectl get pod   -w

   

kubectl describe pod detect-pod1

 

latest标签的镜像版本会每次都跑去远程仓库检测下,所以能不用latest就不用,并且下载策略是Always。

 

探针

    探针是kubelet对容器执行的定期诊断。要执行诊断,kubelet调用由容器实现的Handler。

有三种的类型处理程序:

    ExecAction:在容器内执行指定命令,如果命令退出时返回码为0,则认为诊断成功。

    TCPSocketAction:对指定端口上的容器的IP地址进行TCP检查。如果端口打开,则诊断被认为是成功的。

    HTTPGetAction:对指定的端口和路径上的容器的IP地址执行HTTP Get请求。如果响应状态码大于等于200且小于400,则诊断被认为是成功的。

 

   每次探测都会获得三种结果之一:

    成功:容器通过诊断。

    失败:容器未通过诊断。

    未知:诊断失败,因此不会采取任何行动。

 

    readinessProbe指示容器是否准备好服务请求。如果就绪探测失败,端点控制器将从与Pod匹配的所有Service的端点中删除该Pod的IP地址。初始延迟之前的就绪状态默认为Failure。如果容器不提供就绪探针,则默认状态为Success。

vi read.yaml

〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓

#指定K8S API版本

apiVersion: v1

#指定资源类型

kind: Pod

#元数据

metadata:

 #资源类型的运行名称

 name: readiness-httpget-pod

 #名称空间

 namespace: default

#详细定义

spec:

 #运行的容器

 containers:

 #容器名

 - name: readiness-httpget-container

   #镜像

   image: levi.harbor.com/library/nginx:1.9.1

   #镜像拉取策略:Always每次都尝试重新拉取。Never仅使用本地镜像。IfNotPresent本地有就用,没有就拉取

   imagePullPolicy: IfNotPresent

   #就绪状态检测

   readinessProbe:

    #检测方案HTTP GET

    httpGet:

     #端口

     port: 80

     #路径

     path: /index1.html

    #初始延迟时间,容器启动1秒后开始检测

    initialDelaySeconds: 1

    #重试检测周期

    periodSeconds: 3

〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓

 

kubectl create -f read.yaml

 

#看READY栏

kubectl get pod

 

#可以看到是失败的

kubectl describe pod readiness-httpget-pod

   

#如果pod有多个容器则需要使用-c指定容器

kubectl exec readiness-httpget-pod  -it -- /bin/sh

kubectl exec readiness-httpget-pod  -c 容器名 -it -- /bin/sh

   

cd /usr/share/nginx

cd html/

ls

echo "123" >> index1.html

 

#会发现READY栏成功了,有了这个文件就检测完成了。

kubectl get pod

 

 

    livenessProbe指示容器是否正在运行。如果存活探测失效,则kubelet会杀死容器,并且容器将受到其重启策略的影响。如果容器不提供存活探针,则默认状态为Success。

 

vi live-exec.yaml

〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓

#指定k8s 版本

apiVersion: v1

#指定资源类型

kind: Pod

#元数据

metadata:

 #资源类型运行时的名称

 name: liveness-exec-pod

 #名称空间

 namespace: default

#详细信息

spec:

 #容器

 containers:

 #容器名称

 - name: liveness-exec-container

   #镜像

   image: busybox

   #镜像拉取策略,Always每次都尝试重新拉取镜像,Never仅使用本地镜像,IfNotPresent本地有则使用,没则拉

   imagePullPolicy: IfNotPresent

   #容器启动时,执行的命令

   command: ['/bin/sh','-c','touch /tmp/live; sleep 10;rm -rf /tmp/live;sleep 20;']

   #存活检测策略

   livenessProbe:

    #采用策略,执行命令

    exec:

     command: ['test','-e','/tmp/live']

    #启动1秒后开始检测

    initialDelaySeconds: 1

    #重复检测周期为3秒

    periodSeconds: 3

〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓

kubectl create -f live-exec.yaml

 

 

kubectl get pod

 

kubectl describe pod liveness-exec-pod

 

#关注重启次数,在每次重启时,都重新加载文件,此时又发现该文件,10秒在重启,如此循环

kubectl get pod –w

 

vi live-httpget.yaml

〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓

#指定k8s 版本

apiVersion: v1

#资源类型

kind: Pod

#元数据

metadata:

 #资源运行名称

 name: liveness-httpget-pod

 #名称空间

 namespace: default

#详细

spec:

 #容器

 containers:

 #容器名称

 - name: liveness-httpget-container

   #镜像

   image: levi.harbor.com/library/nginx:1.9.1

   #镜像拉取策略,Always每次都尝试去拉取,Nerver只在本地查找,IfNotPresent本地没有则拉取

   imagePullPolicy: IfNotPresent

   #端口

   ports:

   #协议

   - name: http

     #容器端口

     containerPort: 80

   #存活检测

   livenessProbe:

    #检测策略

    httpGet:

     #端口

     port: 80

     #路径

     path: /index.html

    #启动后1秒开始检测

    initialDelaySeconds: 1

    #重复检测周期

    periodSeconds: 3

    #超时时间

    timeoutSeconds: 10

〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓

 

kubectl create -f live-httpget.yaml

 

kubectl describe pod livenessProbe-httpget-pod

kubectl get pod -0 wide

 

kubectl exec livenessProbe-httpget-pod -c 容器名 -it -- /bin/sh

rm -rf /usr/share/nginx/index.html

 

kubectl get pod –w

 

#端口可用8080

vi live-tcp.yaml

〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓

#k8s api版本

apiVersion: v1

#资源类型

kind: Pod

#元数据

metadata:

 #资源运行名称

 name: liveness-tcp-pod

#详细

spec:

 #容器

 containers:

 #容器名

 - name: liveness-tcp-container

   #镜像

   image: levi.harbor.com/library/nginx:1.9.1

   #存活检测

   livenessProbe:

    #启动初始化后5秒开始检测

    initialDelaySeconds: 5

    #超时时间

    timeoutSeconds: 1

    #检测策略

    tcpSocket:

     #端口

     #port: 80

     port: 8081

〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓

 

kubectl create -f live-tcp.yaml

 

kubectl get pod –w

 

#结合

vi live-two.yaml

〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓

#指定K8S版本

apiVersion: v1

#资源类型

kind: Pod

#元数据

metadata:

 #资源运行名称

 name: liveness-two-pod

 #名称空间

 namespace: default

#详细

spec:

 #容器

 containers:

 #容器名

 - name: liveness-two-container

   #镜像

   image: levi.harbor.com/library/nginx:1.9.1

   #镜像拉取策略,Always每次都尝试拉取,Nerver只使用本地,IfNotPresent优先本地

   imagePullPolicy: IfNotPresent

   #运行端口

   ports:

   #端口协议

   - name: http

     #容器端口

     containerPort: 80

   #1.就绪检测

   readinessProbe:

    #检测策略

    httpGet:

     #检测端口

     port: 80

     #路径

     path: /index1.html

    #初始化后1秒执行

    initialDelaySeconds: 1

    #重复检测周期

    periodSeconds: 3

   #2.存活检测

   livenessProbe:

    #检测策略

    httpGet:

     #检测端口

     port: http

     #路径

     path: /index.html

    #初始化后1秒执行

    initialDelaySeconds: 1

    #重复检测周期

    periodSeconds: 3

    #检测过期时间

    timeoutSeconds: 10

〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓

 

kubectl create -f live-two.yaml

 

kectl get pod

 

kubectl describe pod liveness-two-pod

 

#进入容器内

kubectl exec liveness-two-pod -it -- /bin/bash

cd /usr/share/nginx/html

echo '321' >> index1.html

 

#再次查看pod状态

kubectl get pods

 

#进入容器内

kubectl exec liveness-two-pod -it -- /bin/bash

cd /usr/share/nginx/html

rm -rf index.html

 

#再次查看pod状态

kubectl get pods -w

 

Pod Hook(钩子)

    Pod Hook是由K8S管理的kubelet发起的,当容器中的进程自动铅或者容器中的进程终止之前执行,这包含在容器的生命周期之中,可以同时为Pod中的所有容器都配置Hook。

    Hook的类型有两种:一是exec,执行一段命令;二是Http,发送Http请求。

vi hook.yaml

〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓

apiVersion: v1

kind: Pod

metadata:

 name: hook-pod

spec:

 containers:

 - name: hook-container

   image: levi.harbor.com/library/nginx:1.9.1

   lifecycle:

    postStart:

     exec:

      command: ["/bin/sh", "-c", "echo Start > /tmp/test.txt"]

    preStop:

     exec:

      command: ["/bin/sh", "-c", "echo Stop > /tmp/test.txt"]

〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓

 

kubectl create -f hook.yaml

 

kectl get pod

 

cat /tmp/test.txt

 

kubectl delete pod pod名

 

Pod状态说明

    挂起(Pending):Pod已被K8S系统接受,但有一个或多个容器镜像尚未创建。等待时间包括调度Pod的时间和通过网络下载镜像的时间,这可能需要花点时间。

    运行中(Running):该Pod已经被绑定到了一个节点,Pod中所有的容器都已被创建,至少有一个容器正在运行,或者正处于启动或重启状态。

    成功(Successed):Pod中所有容器都被成功终止,并且不会重启。

    失败(Failed):Pod中所有容器都已终止了,并且至少有一个容器是因为失败终止,也就是说,容器是以非0状态退出或者被系统终止。

    未知(Unknown):因为某些原因无法取得Pod状态,通常是因为与Pod所在主机通信失败。

 

Kubernetes(K8S)常用命令

命令

描述

kubeadm reset

重置,如节点重置后需要重新执行加入命令

Systemctl daemon-reload

更改配置文件后重新加载

systemctl <start、restart、stop、status> docker

重启docker

systemctl <start、restart、stop、status> kubelet

重启k8s

 

 

kubectl get nodes

获取节点相应的信息

kubectl cluster-info

查看集群信息

kubectl -s http://localhost:8080 get componentstatuses

查看各组件信息

kubectl get pods -o wide

kubectl get pod <PodName> -o yaml

查看pods所在的运行节点

kubectl get pods -o yaml

查看pods定义的详细信息

kubectl exec <PodName> env

查看运行的pod的环境变量

 

 

kubectl create -f 文件名.yml

重新根据yaml文件生成新的,即创建资源

kubectl replace -f 文件名 [--force]

重建资源

kubectl apply -f 文件名.yml

根据配置文件里面列出来的内容,升级现有的

kubectl delete -f 文件名

kubectl delete pod pod名

kubectl delete rc rc名

kubectl delete service service名

kubectl delete pod --all

删除资源

 

 

kubectl get services

kubectl get services -n kube-system

查看所有service

kubectl get deployment

kubectl get deployment -n kube-system

查看所有deployment

kubectl get pods --all-namespaces

kubectl get pods -o wide --all-namespaces

kubectl get pods -n kube-system | grep flannel

查看pod及对应的名称空间

kubectl describe pod pod名

kubectl describe pods/pod名

#其他同理

kubectl describe svc nginx-deployment

查看指定资源详细描述信息

kubectl scale rc nginx --replicas=5

kubectl scale deploment redis-slave --replicas=5

kubectl scale --replicas=2 -f redis-slave-deployment.yaml

kubernetes动态伸缩

kubectl exec pod名 -it -- /bin/bash

进入pod启动容器

 

资源控制器

    Kubernetes(K8S)中内建了很多controller(控制器),这些相当于一个状态机,用来控制Pod的具体状态和行为。

 

控制器类型:

    ReplicationController和ReplicaSet

    Deployment

    DaemonSet

    StatefulSet

    Job/CronJob

    Horizontal Pod Autoscaling

 

ReplicationController和ReplicaSet

    RC用来确保容器应用的副本数始终保持在用户定义的副本数,即如果有容器异常退出,会自动创建新的Pod来替代;而如果异常多出来的容器也会自动回收;

    在新版本K8S中建议使用RS来取代RC。RS和RC没有什么区别,RS支持集合式Selector。

 

Deployment

    Deployemnt为Pod和RS提供了一个声明式定义(declarative)方法,用来替代以前的RC来方便管理应用,典型的应用场景包括:

    定义Deployment来创建Pod和ReplicaSet

    滚动升级和回滚应用

    扩容和缩容

    暂停和继续Deployment

 

RS、RC、Deployment

 

#RC、RS与Deployment的关系

 

#查看RS的模板信息

kubectl explain rs

 

vi rs.yaml

〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓

#K8S api版本

apiVersion: extensions/v1beta1

#资源类型

kind: ReplicaSet

#元数据

metadata:

 #资源运行名称

 name: frontend

#详细

spec:

 #副本数

 replicas: 3

 #选择器

 selector:

  #匹配的标签

  matchLabels:

   tier: frontend

 #模板,创建RS的Pod

 template:

  #模板信息

  metadata:

   #标签

   labels:

    tier: frontend

  #详细

  spec:

   #容器

   containers:

   #容器名称

   - name: myapp

     #镜像

     image: levi.harbor.com/library/nginx:1.9.1

     #环境变量

     env:

     #名称

     - name: GET_HOSTS_FROM

       #值

       value: dns

     #端口

     ports:

      #容器端口

      - containerPort: 80

〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓

kubectl create -f rs.yaml

kubectl get pod

kubectl delete pod --all

 

kubectl get rs

 

#会发现按照期望值又新建了,NAME不一样

kubectl get pod

 

#配置文件的标签

kubectl get pod --show-labels

 

#新增标签

kubectl label pod pod名称 标签K=V

kubectl label pod frontend-44f46 testK=testV

 

#修改标签

kubectl label pod pod名称 标签K=V1 --overwrite=True

kubectl label pod frontend-psjnh tier=V1 --overwrite=True

 

#Pod的确是给rs管理的,并且可以看到又创建了一个的Pod

kubectl delete rs -all

 

kubectl get pod

 

kubectl get pod --show-labels

 

vi nginx-deployment.yaml

〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓

#K8S Api版本

apiVersion: extensions/v1beta1

#资源类型

kind: Deployment

metadata:

 #运行时名称

 name: nginx-deployment

spec:

 #副本

 replicas: 3

 #模板,即创建Pod

 template:

  metadata:

   #标签

   labels:

    app: nginx

  spec:

   #容器

   containers:

   - name: nginx

     image: levi.harbor.com/library/nginx:1.9.1

     ports:

     - containerPort: 80

〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓

 

#record参数可以记录命令,可以很方便的查看每次revision的变化

kubectl create -f nginx-deployment.yaml --record

 

#K8S的网络都是扁平化网络都可以通过暴露的端口访问

 

kubectl get deployment

 

#deployment创建rs出来

kubectl get rs

 

kubectl get pod

 

#每一台的位于位置和IP

kubectl get pod -o wide

 

#扩容

kubectl scale deployment nginx-deployment --replicas 10

 

kubectl get pod

 

#滚动更新的话,会新建一个新的RS

kubectl get rs

 

#更新镜像

kubectl set image deployment/nginx-deployment nginx=nginx:1.9.2

 

#镜像的更改会导致rs的创建

kubectl get rs -w

 

kubectl get pod

 

#回滚,默认回滚到上一个版本

kubectl rollout undo deployment/nginx-deployment

 

kubectl get rs -w

 

kubectl get pod

 

#Deployment更新策略说明:Deployment可以保证在升级时,只有一定数量的Pod是down的,默认的,它会确保至少有比期望的Pod数量少一个是up状态(最多一个不可用)。同时也可以确保只创建超过期望数量的一定数量的Pod,默认的它会确保最多比期望的Pod数量多一个的Pod是up的(最多一个surge)。未来的K8S版本中将会从阈值1-1变成25%-25%

 

kubectl describe deployments

 

#Rollover(多个rollout并行)说明:假如创建了一个有5个nginx:1.9.1的replica的Deployment,但是当还只有3个nginx:1.9.1的replica创建出来的时候,就开始更新含有5个nginx:1.9.1的replicaDeployment。在这个情况下,Deployment会立即杀掉已创建的3个nginx:1.9.1的Pod,并开始创建nginx:1.9.1的Pod。不会等到所有5个nginx:1.9.1的Pod都创建完成后才开始改变。

 

 

#查看更新状态

kubectl rollout status deployment/nginx-deployment

 

#更新历史

kubectl rollout history deployment/nginx-deployment

 

#指定回退到某个历史版本

kubectl rollout undo deployment/nginx-deployment --to-revision=2

 

#暂停deployment的更新

kubectl rollout pause deployment/nginx-deployment

 

kubectl get deployment

 

kubectl get pod

 

kubectl get rs

 

#查看是否回滚成功,如果为0则为成功

kubectl rollout status deployment/nginx-deployment

 

echo $?

 

#清理Policy:可以通过设置.spec.revisonHistoryLimit项来指定deployment最多保留多少revision历史记录,默认是会保留所有,如果设置为0,Deployment就不允许回退

 

DaemonSet

    DaemonSet确保全部(或者一些)Node上运行一个Pod的副本。当有Node加入集群时,也会为他们新增一个Pod。当有Node从集群移除时,这些Pod也会被回收。删除DaemonSet将会删除它创建的所有Pod。

    使用DaemonSet的一些典型用法:

    运行集群存储daemon,例如在每个Node上运行glusterd、ceph

    在每个Node上运行日志收集daemon,例如fluentd、logstash

    在每个Node上运行监控daemon,例如Prometheus Node Exporter、collectd、Datadog代理、New Relic代理,或Ganglia gmond。

vi daemonset.yaml

〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓

#版本

apiVersion: apps/v1

#资源类型

kind: DaemonSet

metadata:

 #运行名称

 name: deamonset-example

 #标签

 labels:

  app: daemonset

spec:

 #匹配选择器

 selector:

  matchLabels:

   name: deamonset-example

 #运行的Pod

 template:

  metadata:

   #标签

   labels:

    name: deamonset-example

  spec:

   #容器

   containers:

   - name: deamonset-example

     image: levi.harbor.com/library/nginx:1.9.1

〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓

 

kubectl create -f daemonset.yaml

 

kubectl get pod

 

#可以发现所有的Node都不会在master运行,原因就跟污点有关,后续章节

kubectl get pod -o wide

 

kubectl delete daemonset --all

 

Job

    负责批处理任务,即仅执行一次的任务,它保证批处理任务的一个或多个Pod成功结束。

#spec说明:spec.template格式同Pod;

#单个Pod时,默认Pod成功运行后Job即结束;

#spec.completions标志Job结束需要成功允许的Pod个数,默认为1;

#spec.parallelism标志并允许的Pod的个数,默认为1;

#spec.activeDeadlineSeconds标志失败Pod的重试最大时间,超过这个时间不会继续重试。

 

vi job.yaml

〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓

#api版本

apiVersion: batch/v1

#资源

kind: Job

metadata:

 #运行名称

 name: pi-job

spec:

 #运行的Pod信息

 template:

  metadata:

   name: pi-pod

  spec:

   #容器

   containers:

   - name: pi

     image: perl

     imagePullPolicy: IfNotPresent

     command: ["perl","-Mbignum=bpi","-wle","print bpi(2000)"]

   #重启策略,永不重启

   restartPolicy: Never

〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓

kubectl create -f job.yaml

 

kubectl get pod

 

kubectl describe pod pod名

 

kubectl get job

 

kubectl get pod -o wide

 

kubectl log pod名

 

kubectl delete pod --all

 

CronJob

    管理基于时间的Job,即:在给定时间点只运行一次;周期性的在给定时间点运行;

    典型使用场景:

    在给定的时间点调度Job运行

    创建周期性运行的Job,例如:数据库备份、发送邮件

    使用前提:当前使用K8S集群的版本>=1.8(对CronJob)。对于先前版本的集群,版本<1.8启动APIServer时,通过传递选项—runtime-config=batch/v2alpha1=true可以开启batch/v2alpha1 API。

#spec说明:spec.template格式同Pod;

#单个Pod时,默认Pod成功运行后Job即结束;

#spec.completions标志Job结束需要成功允许的Pod个数,默认为1;

#spec.parallelism标志并允许的Pod的个数,默认为1;

#spec.activeDeadlineSeconds标志失败Pod的重试最大时间,超过这个时间不会继续重试。

 

#spec.schedule:调度,必要字段,指定任务运行周期,格式同Job

#spec.jobTemplate:Job模板,必须字段,指定需要运行的任务,格式同Job

#spec.startingDeadlineSeconds:启动Job的期限(秒级别),该字段是可选的。如果因为任何原因而错过了被调度的时间,那么错过执行时间的Job将被认为是失败的。如果没有指定则没有期限。

#spec.concurrencyPolicy:并发策略,该字段也是可选的,指定了如何处理被CronJob创建的Job的并发执行。只允许指定其中一种策略。Allow(默认)允许并发允许Job;Forbid禁止并发允许,如果前一个还没有完成,则直接跳过下一个;Replace取消当前正在运行的Job,用一个新的来替换。注意:当前策略只能应用于同一个CronJob创建的Job,如果存在多个CronJob,它们创建的Job之间总是允许并发允许。

#spec.suspend:挂起该字段也是可选,如果设置为true,后续所有执行都会被挂起,它对已经开始执行的Job不起作用,默认为false。

#spec.successfulJobsHistoryLimit和spec.failedJobsHistoryLimit:历史限制,是可选的字段。它们指定了可以保留多少完成和失败的Job。默认情况下它们分别设置为3和1。设置限制的值为0,相关类型的Job完成后将不会被保留。

 

vi cronjob.yaml

〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓

#api版本

apiVersion: batch/v1beta1

#资源类型

kind: CronJob

metadata:

 #运行名称

 name: hello

spec:

 #调度,格式同Cron

 schedule: "*/1 * * * *"

 #Job模板,指定需要运行的任务,格式同Job

 jobTemplate:

  spec:

   #运行的Pod

   template:

    spec:

     #容器

     containers:

     - name: hello

       image: busybox

       #拉取策略

       imagePullPolicy: IfNotPresent

       args:

       - /bin/sh

       - -c

       - date;echo Hello from the Kubernetes cluster

     #重启策略,Nerver从不重启,OnFailure失败重启

     restartPolicy: OnFailure

〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓

 

kubectl apply -f cronjob.yaml

 

kubectl get job

 

kubectl get crondjob

 

kubectl get pod

kubectl get cronjob

 

#等待不断创建新的Job

kubectl get job -w

 

kubectl log pod名

 

#删除crondjob时,不会删除job,删除job要另外用kubectl delete job

kubectl delete crondjob

 

#CrondJob本身的限制,创建Job操作应该是幂等的

 

StatefulSet

    StatefulSet作为Controller为Pod提供唯一的标识。它可以保证部署和Scale的顺序。

    StatefulSet是为了解决有状态服务的问题(对应Deployments和ReplicaSets是为无状态服务而设计),其应用场景包括:

    稳定的持久化存储,即Pod重新调度后还是能访问到相同的持久化数据,基于PVC来实现。

    稳定的网络标志,即Pod重新调度后其PodName和HostName不变,基于Headless Service(即没有Cluster IP的Service)来实现。

    有序部署,有序扩展,即Pod是有顺序的,在部署或者扩展的时候要依据定义的顺序依次进行(即从0到N - 1,在下一个Pod运行之前所有之前的Pod必须都是Running和Ready状态),基于init containers来实现。

    有序收缩,有序删除(即从N - 1到0)

 

Horizontal Pod Autoscaling

    应用的资源使用率通常都有高峰和低谷的时候,如何削峰填谷,提高集群的整体资源利用率,让Service中的Pod个数自动调整,即Pod水平自动缩放。

 

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐