K8s中所有的内容都抽象为资源,资源实例化之后,叫做对象,那么这些资源不能在同一空间下重名
名称空间级别(namespace)
集群级资源:
在k8s中,一般使用yam格式的文件来创建符合我们预期期望的pod,这样的yaml文件我们一般
称为资源清单。
参数名 | 字段说明 | 类型 |
---|---|---|
version | String | 这里是指的是K8SAPl的版本,目前基本上是v1,可以用 kubectl api versions命令查询 |
kind | String | 这里指的是yam文件定义的资源类型和角色,比如:od |
metadata | Object | 元数据对象,下面是它的属性 |
metadata. name | String | 元数据对象的名字,这里由我们编写,比如命名pod的名字 |
metadata. namespace | String | 元数据对象的命名空间,由我们自身定义 |
Spec | Object | 详细定义对象,下面是它的属性 |
spec.containers[] | list | 这里是Spec对象的容器列表定义,是个列表 |
spec. containers.name | String | 这里定义容器的名字 |
spec.containers.image | String | 这里定义要用到的镜像名称 |
参数名 | 字段说明 | 类型 |
---|---|---|
spec. containers.name | String | 这里定义容器的名字 |
spec.containers.image | String | 这里定义要用到的镜像名称 |
spec.containers[]. imagePullPolicy | String | 定义镜像拉取策略,有 Always、 Never 、IfNotPresent三个值可选(1) Always:意思是每次都尝试重新拉取镜像;(2) Never:表示仅使用本地镜像 ;(3)、IfNotPresent:如果本地有镜像就使用本地镜像,没有就拉取在线镜像。上面三个值都没设置的话,默认是 Always |
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[]. readOnly | String | 设置存储卷路径的读写模式,ture或者 false, |
spec.containers[].ports[] | List | 指定容器需要用到的端口列表 |
spec.containers[].ports[].name | String | 指定端口名称 |
spec.containers[].ports[].containerPort | String | 指定容器需要监听的端口号 |
spec. containers[.ports[].hostPort | String | 指定容器所在主机需要监听的端口号,默认跟上面 icontainerPort相同,注意设置了 hostPort,同一台主机无法启动该容器的相同副本(因为主机的端口号不能相同,这样会冲突) |
spec. containers[]-ports[.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参数(这里前面文章 Pod资源限制有讲过 HAP 那个啥的,哈哈 主要我也忘记具体名字了) |
spec.containers[].resources. limits.memory | String | 指定MEM内存的限制,单位为MB、GiB spec.containers[].resources.requests |
spec.containers[].resources.requests.cpu | string | cpu请求,单位为core数,容器启动时初始化可用数量 |
spec.containers.resources.requests.memory | String | 内存请求,单位为MB、GB,容器启动的初始化可用数量 |
参数名 | 字段说明 | 类型 |
---|---|---|
spec.restartPolicy | String | 定义Pod的重启策略,可选值为 Always、 OnFailure,默认值为Always;1、Always:pod一旦终止运行,则无论容器是如何终止的, kubelet服务都将重启它。如果容器正常结束(退出码为0),则 kubelet将不会重启它; 2、OnFailure:只有pod以非零退出码终止时, kubelet会重启该容;3、Never:pod终止后, kubeletMast将退出码报告给,会重启该Pod. |
spec.nodeSelector | Object | 定义node的 Label过滤标签,以 key value格式指定 |
spec.imagePullSecrets | Object | 定义pull镜像时 secret使用名称,以 name secretkey格式指定 |
spec.hostNetwork | Boolean | 定义是否使用主机网络模式,默认值为 false,设置true表示使用宿主机网络,不使用 docker网桥,同时设置了true将无法在同一台宿主机上启动第二个副本。 |
apiVersion: group/apiVersion #如果没有给定group名称,那么默认为core,可以使用kubectl api-versions 获取当前k8s版本上所有的 apiVersion版本信息(每个版本可能不同)
kind: #资源类别 Pod,Deploment,rs 等等 #goupcorekubect1ap-:group/apiversion
metadata: #资源元数据
name:
namespace:
lables:
annotations: #主要目的是方便用户阅读查找
spec: #期望的状态(disired state)
status: #当前状态,本字段有 Kubernetes自身维护,用户不能去定义,查看的时候可以看下当前的状态
kubectl explain pod
kubectl explain Ingress
kubectl explain pod
apiVersion #表示字符串类型
metadata
# 创建命令
kutectl create -f xxx.yaml
# 使用 -o 参数 加 yaml,可以将资源的配置以 yaml的格式输出出来,也可以使用json,输出为json格式
kubectl get pod podName -o yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-demo
namespace: default
labels:
app: myapp
name: gkj-test
spec:
containers:
- name: myapp-1
image: hub.atguigu.com/library/myapp:v1
- name: busybox-1
image: busybox:latest
command:
- "/bin/sh"
- "-c"
- "sleep 3600"
这只是一个main C (即一个镜像)的周期,如果一个Pod中有多个main C (即多个镜像),则也会有多个下列视图对象,可以为每一个 Main C 设置 init C、START、readiness、STOP 、Liveness
Pod能够具有多个容器,应用运行在容器里面但是它也可能有一个或多个先于应用容器启动的Init
容器,并且Init 容器与普通的容器非常像,除了如下两点:
- Init容器总是运行到成功完成为止
- 每个Init容器都必须在下一个Init容器启动之前成功完成
如果Pod的Init容器失败,Kubernetes会不断地重启该Pod,直到Init容器成功为止。然而,如果Pod对应的 restartPolicy为 Never,它不会重新启动。
因为Init容器具有与应用程序容器分离的单独镜像,所以它们的启动相关代码具有如下优势:
- 它们可以包含并运行实用工具(因为执行完成Init C 之后就会把Init C 销毁),但是出于安全考虑,是不建议在应用程序容器镜像中包含这
些实用工具的- 它们可以包含使用工具和定制化代码来安装,但是不能出现在应用程序镜像中。例如,创建
镜像没必要FROM另一个镜像,只需要在安装过程中使用类似sed、awk、 python或dig
这样的工具。- 应用程序镜像可以分离出创建和部署的角色,而没有必要联合它们构建一个单独的镜像。
- Init容器使用 Linux Namespace,所以相对应用程序容器来说具有不同的文件系统视图。因
此,它们能够具有访问 Secret的权限,而应用程序容器则不能。- 它们必须在应用程序容器启动之前运行完成,而应用程序容器是并行运行的,所以Init容
器能够提供了一种简单的阻塞或延迟应用容器的启动的方法,直到满足了一组先决条件。
这个yaml 文件,创建了一个pod,并且这个pod里面只有一个 main C,这个main C 有两个 init C,
当创建的时候,会先按照顺序创建 init C(即第一个Init C 先创建,如果失败,则不会创建第二个),最后只有两个Init C 都是成功的,才会创建 main C。
busybox 镜像只是封装了一些工具的镜像
# 内容就是如下
vim ini-pod.yaml
# 根据文件创建
kubectl create -f ini-pod.yaml
如果有名称相同的可以把之前的删除,可以使用 --all 或者指定具体的名称删除,都是可以的
# 如果有资源是deployment的 不要删pod和Rs,因为这样是删不干净的,可以直接删除 deployment ,这样 rs和pod都会被删除
kubectl delete deployment --all # 这里没有指定namespace 默认是名称空间是default
kubectl delete pod --all
kubectl delete svc --all
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app: myapp
spec:
containers:
- name: myapp-container # 定义一个容器,
image: busybox
command: ['sh', '-c', 'echo The app is running! && sleep 3600'] # 启动时执行 ,即输出一句话 The app is running 然后 休眠 6分钟,不退出镜像
initContainers: #这里就是配置 init C 了,下面为这个main C配置了两个init C
- name: init-myservice
image: busybox
command: ['sh', '-c', 'until nslookup myservice; do echo waiting for myservice; sleep 2; done;'] # 这个的作用是检测 myservice(会在后面定义) 容器是否启动起来了
- name: init-mydb
image: busybox
command: ['sh', '-c', 'until nslookup mydb; do echo waiting for mydb; sleep 2; done;'] # 这个的作用是检测 mydb (会在后面定义)容器是否启动起来了
创建完成后,查看pod状态,如下,可以看到init 是有2个的,因为我们定义了2个init C,而main C 只有一个 0/1。
后面你一直 kubectl get pod
会发现init c一直无法成功,这时我们可以看下当前这个pod 的详情,你会发现执行了第一个init c init-myservice,然后没有执行第二个init C,只是分配了myapp-pod的节点,然后没有下文了,说明第一个 init C init-myservice有问题。
kubectl describe pod myapp-pod
所以我们需要看下第一个init C init-myservice的日志
# -c 的作用是指定这个pod 的哪一个具体的容器,因为一个pod里面有多个容器的
kubtctl log myapp-pod -c init-myservice
最后看到日志就会明白了,因为没有myservice这个服务,所以init C 过不去,对于另一种检测mydb的就不再演示了,两个必须都通过才行,才会到创建pod哪里,创建main C。
当你创建完第一个 service时,第一个init C 就已经通过了,也可以在svc中看到我们的myservice了,至于为什么我们的pod可以ping myservice,而不是使用ip,是因为一旦我们service创建成功,会被coredns-xxxx 记录,这样k8s内部的机器都是可以通过域名访问的。
分别创建 myservice 和 mydb 的 svc 即可
kubectl create -f myservice.yaml
kubectl create -f mydb.yaml
kind: Service
apiVersion: v1
metadata:
name: myservice
spec:
ports:
- protocol: TCP
port: 80
targetPort: 9376
kind: Service
apiVersion: v1
metadata:
name: mydb
spec:
ports:
- protocol: TCP
port: 80
targetPort: 9377
探针是由 kubelet 对容器执行的定期诊断。要执行诊断,kubelet 调用由容器实现的 Handler。有三
种类型的处理程序:
每次探测都将获得以下三种结果之一:
注意失败之后pod在指定策略下会重启,一些指令就会重新执行了
livenessProbe:指示容器是否正在运行。如果存活探测失败,则 kubelet 会杀死容器,并且容器将受到其重启策略的影响。如果容器不提供存活探针,则默认状态为 Success
readinessProbe:指示容器是否准备好服务请求。如果就绪探测失败,端点控制器将从与 Pod 匹配的所有 Service 的端点中删除该 Pod 的 IP 地址。初始延迟之前的就绪状态默认为 Failure。如果容器不提供就绪探针,则默认状态为 Success
对就绪状态使用 httpget方式(至于其它的几种方式会在下面的就绪状态文章里面)检测 readinessProbe-httpget
vim readinessProbe-httpget.yaml
具体内容如下
apiVersion: v1
kind: Pod
metadata:
name: readiness-httpget-pod
namespace: default
spec:
containers:
- name: readiness-httpget-container
image: wangyanglinux/myapp:v1
imagePullPolicy: IfNotPresent
readinessProbe:
httpGet:
port: 80
path: /index1.html # 这个文件是不存在的
initialDelaySeconds: 1 # 容器创建启动一秒后开始检测
periodSeconds: 3 # 每隔3秒检测一次,直到就绪状态结束
可以看到 READ 状态一直都是失败的,因为index1.html在80端口是不存的,状态码不会所在200多
再仔细查看pod的日志,可以看到 readiness 探针失败了。
kubectl describe pod readinessProbe-httpget
我们进入这个容器,因为当前这个pod只有一个main C容器,所以我们不需要使用 - c
指定具体那个容器,然后增加一个 index1.html
即可
#kubectl exec readinessProbe-httpget -c xxx pod -it -- /bin/sh
kubectl exec readinessProbe-httpget pod -it -- /bin/sh
# w的意思是 watch 监听
lubectl get pod -w
livenessProbe-exec
vim livenessProbe-exec.yaml
内容如下
apiVersion: v1
kind: Pod
metadata:
name: liveness-exec-pod
namespace: default
spec:
containers:
- name: liveness-exec-container
image: hub.atguigu.com/library/busybox
imagePullPolicy: IfNotPresent
command: ["/bin/sh","-c","touch /tmp/live ; sleep 60; rm -rf /tmp/live; sleep 3600"] # 启动完成后创建一个文件/tmp/live 睡眠60秒后再把这个文件删除后睡眠6分钟
livenessProbe:
exec:
command: ["test","-e","/tmp/live"] # 检测这个文件是否存在
initialDelaySeconds: 1
periodSeconds: 3
可以想到,这个容器前面的一段时间是可以通过存活检测的,因为前60秒这个文件是一直都在的,但是60秒之后就没了,所以会失败,就会重启,如下,虽然ready状态是ok的,但是存活检测是失败的,已经重启2次了。
kubectl get pod -w
livenessProbe-httpget
vim livenessProbe-httpget.yaml
内容如下
apiVersion: v1
kind: Pod
metadata:
name: liveness-httpget-pod
namespace: default
spec:
containers:
- name: liveness-httpget-container
image: hub.atguigu.com/library/myapp:v1
imagePullPolicy: IfNotPresent
ports:
- name: http # 定义80 端口的名称为http ,后面使用的时候,不用写80,可以用http这个名称代替
containerPort: 80
livenessProbe:
httpGet:
port: http # 那这里其实就是80端口啦
path: /index.html
initialDelaySeconds: 1
periodSeconds: 3
timeoutSeconds: 10
livenessProbe-tcp
vim livenessProbe-tcp.yaml
内容如下
apiVersion: v1
kind: Pod
metadata:
name: probe-tcp
spec:
containers:
- name: nginx
image: hub.atguigu.com/library/myapp:v1
livenessProbe:
initialDelaySeconds: 5
timeoutSeconds: 1
tcpSocket:
port: 80
组合的话,其实也是很简单的,就是把对于的配置copy再一起就行了。
liveness-readness-Probe
vim liveness-readness-Probe.yaml
内容如下
apiVersion: v1
kind: Pod
metadata:
name: probe-tcp
spec:
containers:
- name: nginx
image: hub.atguigu.com/library/myapp:v1
readinessProbe:
httpGet:
port: 80
path: /index1.html
initialDelaySeconds: 1
periodSeconds: 3
livenessProbe:
initialDelaySeconds: 5
timeoutSeconds: 1
tcpSocket:
port: 80
其实就是和上面差不多,都是一个回调的阶段。
vim start-stop-probe.yaml
这里的关键字就是 lifecycle
,内容如下
apiVersion: v1
kind: Pod
metadata:
name: lifecycle-demo
spec:
containers:
- name: lifecycle-demo-container
image: nginx
lifecycle:
postStart:
exec:
command: ["/bin/sh", "-c", "echo Hello from the postStart handler > /usr/share/message"]
preStop:
exec:
command: ["/bin/sh", "-c", "echo bybe from the preStop handler > /usr/share/message"]