k8s之pod管理
Pod是可以创建和管理Kubernetes计算的最小可部署单元,一个Pod代表着集群中运行的一个进程,每个pod都有一个唯一的ip。一个pod类似一个豌豆荚,包含一个或多个容器(通常是docker),多个容器间共享IPC、Network和UTC namespace。参考地址:pod命令行管理一、创建和删除pod应用实验环境:server1作为本地仓库,server2作为master,server3
Pod是可以创建和管理Kubernetes计算的最小可部署单元,一个Pod代表着集群中运行的一个进程,每个pod都有一个唯一的ip。
一个pod类似一个豌豆荚,包含一个或多个容器(通常是docker),多个容器间共享IPC、Network和UTC namespace。
参考地址:pod命令行管理
一、创建和删除pod应用
实验环境:
server1作为本地仓库,server2作为master,server3,server4作为node节点
实验前要保证保证仓库正常运行
[root@server1 harbor]# docker-compose ps
节点状态ready
[root@server2 ~]# kubectl get nod
1 创建pod
此时要保证你所使用的镜像myapp,在本地仓库存在才行。
[root@server2 ~]# kubectl run nginx --image=myapp:v1
[root@server2 ~]# kubectl get pod
当出现下图状态时说明创建成功。
2 查看pod运行在哪个节点上,且查看分配的ip地址
[root@server2 ~]# kubectl get pod -o wide
3 访问分配的ip
集群内部任意节点可以访问Pod,但集群外部无法直接访问。
[root@server2 ~]# curl 10.244.2.21
测试:
这时我们再创建一个pod,到容器内进行访问
[root@server2 ~]# kubectl run demo --image=busyboxplus -it
If you don't see a command prompt, try pressing enter.
/ # ip addr
[root@server2 ~]# kubectl get pod -o wide
这时我们发现容器内的ip和容器外的ip相同
再次进入容器我们访问刚才myapp的ip,查看结果
[root@server2 ~]# kubectl attach demo -i -t
/ # curl 10.244.2.21
4 删除pod
删除pod的命令
[root@server2 ~]# kubectl delete pod nginx
使用下面命令可以查看正在运行的pod的详细信息
[root@server2 ~]# kubectl describe pod demo
5.查看日志的命令
[root@server2 ~]# kubectl logs demo
6 通过控制器创建pod
一般我们不会使用刚才演示的那种单独创建的方式
[root@server2 ~]# kubectl create deployment nginx --image=myapp:v1
[root@server2 ~]# kubectl get all
这里如果我们进行删除的话,它是不会直接被删除的,他会删除之后,自动重新创建出来一个新的副本。只是随机id发生变化
二、Pod扩容与缩容
[root@server2 ~]# kubectl scale deployment --replicas=2 nginx
[root@server2 ~]# kubectl get pod -o wide
三、 service(微服务)
service是一个抽象概念,定义了一个服务的多个pod逻辑合集和访问pod的策略,一般把service称为微服务。
1.创建service
[root@server2 ~]# kubectl expose deployment nginx --port=80
[root@server2 ~]# kubectl get svc
[root@server2 ~]# curl 10.100.138.138
此时pod客户端可以通过service的名称访问后端的两个Pod
ClusterIP: 默认类型,自动分配一个仅集群内部可以访问的虚拟IP
2 查看svc详细信息
[root@server2 ~]# kubectl describe svc nginx
这里的ip对应pod的副本ip
会根据副本数自动实现副本负载均衡
3.修改暴露类型
NodePort: 在ClusterIP基础上为Service在每台机器上绑定一个端口,这样就可以通过 NodeIP:NodePort 来访问该服务
[root@server2 ~]# kubectl edit svc nginx
将类型改成NodePort
[root@server2 ~]# kubectl get svc
在外部访问时,用的是节点ip+端口访问
[root@Sun_s Desktop]# curl 172.25.1.2:30224/hostname.html
4 更新及回滚pod镜像
[root@server2 ~]# kubectl set image deployment nginx myapp=myapp:v2 --record #更新
[root@server2 ~]# kubectl rollout undo deployment nginx --to-revision=1 #回滚
[root@server2 ~]# kubectl rollout history deployment nginx //查看历史版本
[root@server2 ~]# curl 10.100.138.138
四、资源清单
1.清单格式
清单格式
apiVersion: group/version //指明api资源属于哪个群组和版本,同一个组可以有多个版本
$ kubectl api-versions //查询命令
kind: //标记创建的资源类型,k8s主要支持以下资源类别
Pod,ReplicaSet,Deployment,StatefulSet,DaemonSet,Job,Cronjob
metadata: //元数据
name: //对像名称
namespace: //对象属于哪个命名空间
labels: //指定资源标签,标签是一种键值数据
spec: //定义目标资源的期望状态
2. 参数信息
3 查看帮助
[root@server2 ~]# kubectl api-versions ## 查看所有api的版本信息
[root@server2 ~]# kubectl explain pod.spec.containers ## pod清单帮助 一层一层看
4 删除之前创建的
[root@server2 ~]# kubectl delete deployments.apps nginx
[root@server2 ~]# kubectl delete svc nginx
5 编写创建pod 的api文件
[root@server2 ~]# vim pod.yml
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: default
spec:
containers:
- name: nginx
image: myapp:v1
imagePullPolicy: IfNotPresent
[root@server2 ~]# kubectl apply -f pod.yml
[root@server2 ~]# kubectl get pod
6 删除
[root@server2 ~]# kubectl delete -f pod.yml
7.编写创建deployment api文件
[root@server2 ~]# vim deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
namespace: default
spec:
replicas: 3
selector:
matchLabels:
run: nginx
template:
metadata:
labels:
run: nginx
spec:
containers:
- name: nginx
image: myapp:v1
imagePullPolicy: IfNotPresent
[root@server2 ~]# kubectl apply -f deployment.yml
[root@server2 ~]# kubectl get pod
8.将运行中的pod转换成yml格式
[root@server2 ~]# kubectl get pod nginx-b5548c7c4-4phr9 -o yaml
9 优化
[root@server2 ~]# vim deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
namespace: default
spec:
replicas: 2
selector:
matchLabels:
run: nginx
template:
metadata:
labels:
run: nginx
spec:
#nodeSelector:
# kubernetes.io/hostname: server4
nodeName: server3 #增加标签选择器
#hostNetwork: true #使用主机网络,注意端口不能冲突
containers:
- name: nginx
image: myapp:v1
imagePullPolicy: IfNotPresent
resources:
requests:
cpu: 100m #最小限制;十分之一cpu资源,也可以写成0.1
memory: 70Mi
limits: #上限,超出被控制器杀死
cpu: 0.5
memory: 512Mi
[root@server2 ~]# kubectl apply -f deployment.yml
[root@server2 ~]# kubectl get pod -o wide
[root@server2 ~]# kubectl describe pod
全部在server3节点上
10.自主式Pod资源清单
在之前的基础上再加一个容器进来
containers:
- name: nginx
image: myapp:v1
imagePullPolicy: IfNotPresent
resources:
requests:
cpu: 100m #最小限制;十分之一cpu资源,也可以写成0.1
memory: 70Mi
limits: #上限,超出被控制器杀死
cpu: 0.5
memory: 512Mi
- name: busyboxplus
image: busyboxplus
imagePullPolicy: IfNotPresent
stdin: true
tty: true
[root@server2 ~]# kubectl apply -f deployment.yml
[root@server2 ~]# kubectl get pod
这时我们看到有两个容器
运行的时候使用-c 指定容器
[root@server2 ~]# kubectl attach nginx-585f596658-gcd89 -c busyboxplus -it
If you don't see a command prompt, try pressing enter.
/ # curl localhost
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
11.标签
主要在控制器中使用,可以在节点上或pod打标签
[root@server2 ~]# kubectl get pod --show-labels #查看标签
[root@server2 ~]# kubectl label pod nginx-585f596658-gcd89 version=v1 ## 打标签
[root@server2 ~]# kubectl label pod nginx-585f596658-gcd89 version=v2 --overwrite ##更改标签
[root@server2 ~]# kubectl get pod -l version ##过滤标签
节点标签选择器
$ kubectl label nodes server2 disktype=ssd
node/server2 labeled
$ kubectl get nodes -l disktype
NAME STATUS ROLES AGE VERSION
server2 Ready <none> 6d v1.17.2
在yaml文件中增加标签选择器
nodeSelector:
disktype: ssd
五、pod的生命周期
参考网站:kubernetes官网
(1)Pod 可以包含多个容器,应用运行在这些容器里面,同时 Pod 也可以有一个或多个先于应用容器启动的 Init 容器。
(2)Init 容器与普通的容器非常像,除了如下两点:
- 它们总是运行到完成。
- Init 容器不支持 Readiness,因为它们必须在 Pod 就绪之前运行完成,每个 Init 容器必须运行成功,下一个才能够运行。
(3)如果 Pod 的 Init 容器失败,Kubernetes 会不断地重启该 Pod,直到 Init 容器成功为止。然而,如果 Pod 对应的 restartPolicy 值为 Never,它不会重新启动。
Init 容器能做什么?
Init 容器可以包含一些安装过程中应用容器中不存在的实用工具或个性化代码。
Init 容器可以安全地运行这些工具,避免这些工具导致应用镜像的安全性降低。
应用镜像的创建者和部署者可以各自独立工作,而没有必要联合构建一个单独的应用镜像。
Init 容器能以不同于Pod内应用容器的文件系统视图运行。因此,Init容器可具有访问 Secrets 的权限,而应用容器不能够访问。
由于 Init 容器必须在应用容器启动之前运行完成,因此 Init 容器提供了一种机制来阻塞或延迟应用容器的启动,直到满足了一组先决条件。一旦前置条件满足,Pod内的所有的应用容器会并行启动。
使用启动探测器保护慢启动容器
[root@server2 ~]# vim init.yml
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app: myapp
spec:
containers:
- name: myapp-container
image: myapp:v1
initContainers:
- name: init-myservice
image: busyboxplus
command: ['sh', '-c', "until nslookup myservice.default.svc.cluster.local; do echo waiting for myservice; sleep 2; done"]
[root@server2 ~]# vim service.yml
---
apiVersion: v1
kind: Service
metadata:
name: myservice
spec:
ports:
- protocol: TCP
port: 80
targetPort: 80
[root@server2 ~]# kubectl create -f init.yml
[root@server2 ~]# kubectl get pod
[root@server2 ~]# kubectl create -f service.yml
[root@server2 ~]# kubectl get pod
initContainers检测机制检测到myservice.default.svc.cluster.local,才会run
探针
探针 是由 kubelet 对容器执行的定期诊断:
- ExecAction:在容器内执行指定命令。如果命令退出时返回码为 0 则认为诊断成功。
- TCPSocketAction:对指定端口上的容器的 IP 地址进行 TCP 检查。如果端口打开,则诊断被认为是成功的。
- HTTPGetAction:对指定的端口和路径上的容器的 IP 地址执行 HTTP Get 请求。如果响应的状态码大于等于200 且小于 400,则诊断被认为是成功的。
每次探测都将获得以下三种结果之一:
- 成功:容器通过了诊断。
- 失败:容器未通过诊断。
- 未知:诊断失败,因此不会采取任何行动
Kubelet 可以选择是否执行在容器上运行的三种探针执行和做出反应:
livenessProbe:指示容器是否正在运行。如果存活探测失败,则 kubelet 会杀死容器,并且容器将受到其 重启策略 的影响。如果容器不提供存活探针,则默认状态为 Success。
readinessProbe:指示容器是否准备好服务请求。如果就绪探测失败,端点控制器将从与 Pod 匹配的所有 Service 的端点中删除该 Pod 的 IP 地址。初始延迟之前的就绪状态默认为 Failure。如果容器不提供就绪探针,则默认状态为 Success。
startupProbe: 指示容器中的应用是否已经启动。如果提供了启动探测(startup probe),则禁用所有其他探测,直到它成功为止。如果启动探测失败,kubelet 将杀死容器,容器服从其重启策略进行重启。如果容器没有提供启动探测,则默认状态为成功Success。
定义存活命令
许多长时间运行的应用程序最终会过渡到断开的状态,除非重新启动,否则无法恢复。 Kubernetes 提供了存活探测器来发现并补救这种情况。
[root@server2 ~]# vim live.yml
apiVersion: v1
kind: Pod
metadata:
labels:
test: liveness
name: liveness-exec
spec:
containers:
- name: liveness
image: busyboxplus
args:
- /bin/sh
- -c
- touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600
livenessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 5
periodSeconds: 5
这个容器生命的前 30 秒, /tmp/healthy 文件是存在的。 所以在这最开始的 30 秒内,执行命令 cat /tmp/healthy 会返回成功代码。 30 秒之后,执行命令 cat /tmp/healthy 就会返回失败代码。
创建 Pod:
[root@server2 ~]# kubectl create -f live.yml
在 30 秒内,查看 Pod 的事件:
[root@server2 ~]# kubectl describe pod liveness-exec
35 秒之后,再来看 Pod 的事件:
[root@server2 ~]# kubectl describe pod liveness-exec
在输出结果的最下面,有信息显示存活探测器失败了,这个容器被杀死并且被重建了。
再等另外 30 秒,检查看这个容器被重启了:
[root@server2 ~]# kubectl get pod liveness-exec
输出结果显示 RESTARTS 的值增加了 1。
定义就绪 存活探测器
[root@server2 ~]# kubectl delete -f live.yml
[root@server2 ~]# kubectl create -f live.yml
[root@server2 ~]# kubectl get pod
这里显示没有就绪
这时我们进入到交互页面创建发布页面
[root@server2 ~]# kubectl exec -it liveness-exec -- sh
/ # cd /usr/share/nginx/
/usr/share/nginx # ls
html
/usr/share/nginx # cd html/
/usr/share/nginx/html # ls
50x.html index.html
/usr/share/nginx/html # touch test.html
我们退出交互之后,再次查看,看到已经准备就绪
重启策略
PodSpec 中有一个 restartPolicy 字段,可能的值为 Always、OnFailure 和 Never。默认为 Always。
Pod 的生命
一般Pod 不会消失,直到人为销毁他们,这可能是一个人或控制器。
建议创建适当的控制器来创建 Pod,而不是直接自己创建 Pod。因为单独的 Pod 在机器故障的情况下没有办法自动复原,而控制器却可以。
三种可用的控制器:
使用 Job 运行预期会终止的 Pod,例如批量计算。Job 仅适用于重启策略为 OnFailure 或 Never 的 Pod。
对预期不会终止的 Pod 使用 ReplicationController、ReplicaSet 和 Deployment ,例如 Web 服务器。 ReplicationController 仅适用于具有 restartPolicy 为 Always 的 Pod。
提供特定于机器的系统服务,使用 DaemonSet 为每台机器运行一个 Pod 。
更多推荐
所有评论(0)