自主式 pod 应用
我们接触的 pod 大多数是控制器控制的 pod, 那么今天讲的是自主式 pod(也就是由 YAML 文件来创建的 pod), 也就是 pod 自己去控制自己, 防止 pod 被控制器杀死.
1, 首先我们来创建一个 nginx 的 pod 资源对象:
在创建 pod 之前, 我们来查看一下镜像的下载策略:
[root@master YAML]# kubectl explain pod.spec.containers
查看 imagePullpolicy 的策略字段:
- imagePullPolicy <string>
- Image pull policy. One of Always, Never, IfNotPresent. Defaults to Always
- if :latest tag is specified, or IfNotPresent otherwise. Cannot be updated.
- More info:
- https://kubernetes.io/docs/concepts/containers/images#updating-images
几种策略解释:
Always: 镜像标签为 "latest" 或镜像标签不存在的时候, 总是在从指定的仓库 (Dockerhub) 中获取镜像.
目前 Docker 官方维护了一个公共仓库 Docker Hub, 其中已经包括了数量超过 2,650,000 的镜像. 大部分需求都可以通过在 Docker Hub 中直接下载镜像来实现.
Nerver: 禁止从仓库中下载镜像, 也就是说只使用本地镜像. 如果本地也没有镜像, 则 pod 将无法运行.
IfNotPresent(提供): 仅当本地没有对应镜像时, 才从目标仓库中下载.
默认的获取策略如下:
镜像标签为 "latest", 它的默认下载策略是 Always.
镜像标签为自定义(不是默认的 latest), 它的默认下载策略是 IfNotPresent.
- // 创建一个 pod(定义某种策略):
- [root@master YAML]# VIM test-pod.YAML
- apiVersion: v1
- kind: Pod
- metadata:
- name: test-pod
- spec:
- containers:
- - name: myapp
- image: nginx
- imagePullPolicy: Always #定义镜像下载策略(从指定仓库获取镜像)
- ports:
- - containerPort: 80 #暴露容器的端口
- // 执行 YAML 文件:
- [root@master YAML]# VIM test-pod.YAML
- [root@master YAML]# kubectl apply -f test-pod.YAML
- // 查看 pod 的状态:
- [root@master YAML]# kubectl get pod test-pod -o wide
- NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
- test-pod 1/1 Running 0 7m55s 10.244.2.2 node02 <none> <none>
- // 以 JSON 格式查看 pod 的一个详细信息:
- [root@master YAML]# kubectl get pod test-pod -o JSON
image 镜像相位(状态):
Running:Pod 所需的容器已经被成功调度到某个节点, 且已经成功运行.
Pending:APIserver 创建了 pod 资源对象, 并且已经存入 etcd 中, 但它尚未被调度完成或者仍然处于仓库中下载镜像的过程.
Succeeded:Pod 中的所有容器已成功终止, 并且不会重新启动.
Failed:Pod 中的所有容器均已终止, 并且至少一个容器因故障而终止. 也就是说, 容器要么以非零状态退出, 要么被系统终止
Unknown:APIserver 无法正常获取到 pod 对象的状态, 通常用于其无法与所在工作节点的 kubelet 通信所致.
一定要熟悉并且记住这几种状态, 因为这有利于在集群出现故障时能够准确的找到问题, 且快速的排查错误.
2,pod 的重启策略:
- // 首先我们查看 pod 的一个重启策略:
- [root@master YAML]# kubectl explain pod.spec #查看 pod 的 spec 字段的重启策略
字段解释:
Always: 但凡是 pod 对象终止就重启, 此为默认策略.
OnFailure: 仅在 pod 对象出现错误时才重启, 如果容器是处于 complete 状态, 也就是正常退出的状态, 是不会重启的.
Never: 从不重启.
3, 我们模拟一下, 创建一个 pod, 使用公司内部的私有仓库中的镜像, 其镜像下载策略为: Never(使用本地镜像),pod 的重启策略为 Never(从不重启).
- [root@master YAML]# VIM nginx-pod1.YAML
- apiVersion: v1
- kind: Pod
- metadata:
- name: mynginx
- labels: #定义标签与 servic 相关联
- test: myweb
- spec:
- restartPolicy: Never #定义镜像重启策略为 Never
- containers:
- - name: myweb
- image: 172.16.1.30:5000/nginx:v1
- imagePullPolicy: Never #定义镜像下载策略为 Never
- ---
- apiVersion: v1
- kind: Service
- metadata:
- name: mynginx
- spec:
- type: NodePort
- selector:
- test: myweb
- ports:
- - name: nginx
- port: 8080 #定义 Cluster IP 端口
- targetPort: 80 #暴露容器端口
- nodePort: 30000 #定义给外网通过宿主机暴露的端口
- [root@master YAML]# kubectl apply -f nginx-pod1.YAML
- pod/mynginx created
- service/mynginx created
- // 查看 pod 当前状态:
查看 pod 信息可以看到镜像拉取失败, 所以我们查看该 pod 的详细信息进行排查:
[root@master YAML]# kubectl describe pod mynginx
可以看到是策略的原因, Nerver 策略只能从该节点的本地镜像进行下载, 所以我们需要在该节点 (node02) 上将私有仓库中的镜像进行拉取到本地.
- [root@node02 ~]# docker pull 172.16.1.30:5000/nginx:v1
- v1: Pulling from nginx
- Digest: sha256:189cce606b29fb2a33ebc2fcecfa8e33b0b99740da4737133cdbcee92f3aba0a
- Status: Downloaded newer image for 172.16.1.30:5000/nginx:v1
- // 回到 master, 再次查看 pod1 是否运行:
- [root@master YAML]# kubectl get pod -o wide
- NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
- mynginx 1/1 Running 0 7m32s 10.244.2.4 node02 <none> <none>
- test-pod 1/1 Running 1 7h10m 10.244.2.3 node02 <none> <none>
2)测试 pod 重启策略:
我们模拟 pod 非正常退出
- [root@master YAML]# VIM nginx-pod1.YAML
- apiVersion: v1
- kind: Pod
- metadata:
- name: mynginx
- labels:
- test: myweb
- spec:
- restartPolicy: Never
- containers:
- - name: myweb
- image: 172.16.1.30:5000/nginx:v1
- imagePullPolicy: Never
- args: [/bin/sh -c sleep 10; exit 1] #添加 args 字段, 模拟 sleep10 秒后退出
- // 重新启动 pod
- [root@master YAML]# kubectl delete -f nginx-pod1.YAML
- pod "mynginx" deleted
- service "mynginx" deleted
- [root@master YAML]# kubectl apply -f nginx-pod1.YAML
- pod/mynginx created
- service/mynginx created
PS: 因为在 pod 的文件中设置了 pod 的重启策略为 Never, 所以在无法修改策略的情况下, 需要将该 pod 删除, 重新执行 YAML 文件生成新的 pod.
// 第一次查看 pod 状态:
看到新的 pod 再 node01 节点上, 所以我们还需再 node01 上将镜像拉取到本地.
- [root@node01 ~]# docker pull 172.16.1.30:5000/nginx:v1
- v1: Pulling from nginx
- Digest: sha256:189cce606b29fb2a33ebc2fcecfa8e33b0b99740da4737133cdbcee92f3aba0a
- Status: Downloaded newer image for 172.16.1.30:5000/nginx:v1
为了更好的查看到效果, 我们重新执行 YAML 文件, 生成新 pod:
- [root@master YAML]# kubectl delete -f nginx-pod1.YAML
- [root@master YAML]# kubectl apply -f nginx-pod1.YAML
- // 查看 pod 的最终状态:
我们来查看该 pod 的详细信息(查看 pod 运行失败的原因):
[root@master YAML]# kubectl describe pod mynginx
从上面的信息中我们可以得知 pod 在创建出容器后, 却非正常退出了, 最后导致容器创建失败.
3)我们修改策略规则, 将规则设置为 OnFailure:
- // 重新运行 pod:
- [root@master YAML]# kubectl delete -f nginx-pod1.YAML
- pod "mynginx" deleted
- service "mynginx" deleted
- [root@master YAML]# kubectl apply -f nginx-pod1.YAML
- pod/mynginx created
- service/mynginx created
查看 pod 状态(失败):
- [root@master YAML]# kubectl get pod -o wide
- NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
- mynginx 0/1 RunContainerError 3 55s 10.244.2.8 node02 <none> <none>
- [root@master YAML]# kubectl get pod -o JSON
我们可以看到当前 pod 创建容器失败.
// 我们马上实时监控 pod 当前的状态:
可以看到 pod 一直在不停的重启, 原因是我们在设置 pod 重启为 OnFailure 时, 同时设置了 pod 在睡眠 10 秒后, 便会重启, 所以该 pod 会一直重启下去.
4)我们修改策略规则, 并将其 pod 恢复正常运行:
- // 重新运行 YAML 文件, 生成新的 pod:
- [root@master YAML]# kubectl delete -f nginx-pod1.YAML
- pod "mynginx" deleted
- service "mynginx" deleted
- k[root@master YAML]# kubectl apply -f nginx-pod1.YAML
- pod/mynginx created
- service/mynginx created
- // 查看 pod 是否恢复正常运行:(正常运行)
- [root@master YAML]# kubectl get pod -o wide
- NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
- mynginx 1/1 Running 0 71s 10.244.1.8 node01 <none> <none>
5) 查看 servie 信息, 验证 nginx 的 Web 界面能否正常访问:
- [root@master YAML]# kubectl get svc mynginx
- NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
- mynginx NodePort 10.101.131.36 <none> 8080:30000/TCP 4m23s
来源: http://blog.51cto.com/13972012/2456490