kubernetes pod管理
Kubernetes Pod环境准备[rootmaster30 ~11:41:16]# kubectl create ns pods[rootmaster30 ~11:41:16]# kubectl config set-context --current --namespace podsPod 介绍pod 代表一个deployment单元a single instance of an application in Kubernetes。k8s通过定义一个Pod的资源然后在Pod里面运行容器容器需要指定镜像用来运行具体的服务。Pod代表集群上正在运行的一个进程一个Pod封装一个容器也可以封装多个容器Pod里的容器共享存储、网络等。也就是说应该把整个pod看作虚拟机然后每个容器相当于运行在虚拟机的进程。运行单个容器的 Pod将Pod看作是单个容器的包装器kubernetes管理pods而不是直接管理容器。运行多个容器的 PodPOD可以封装一个由多个共存容器组成的应用程序。pod中的容器会自动在集群中的同一物理机或虚拟机上运行。POD中多个容器共享资源和依赖项彼此通信以及协调何时以及如何终止它们。POD将这些容器、网络资源和存储资源作为一个单一的可管理实体包装在一起。pod中多个容器共享网络和存储资源。每个pod分配唯一的ip地址pod中容器共享netns包括ip地址和port端口。多个容器之间使用localhost通信。当pod中容器与其他pod通信需要使用共享的网络资源。pod可以使用多个volumepod中所有容器都可以访问这些卷。pod 基本管理创建 pod# 空运行只生成yaml文件[rootmaster30 ~11:42:16]# kubectl run web --imagedocker.io/library/nginx --dry-runclient -o yamlapiVersion: v1 kind: Pod metadata: creationTimestamp: null labels: run: web name: web spec: containers: - image: docker.io/library/nginx name: web resources:{}dnsPolicy: ClusterFirst restartPolicy: Always status:{}# 直接创建pod[rootmaster30 ~]# kubectl run web --imagedocker.io/library/nginxpod/web created[rootmaster30 ~]# kubectl get podNAME READY STATUS RESTARTS AGE web0/1 ContainerCreating036s#查看pod信息[rootmaster30 ~]# kubectl get podNAME READY STATUS RESTARTS AGE web1/1 Running051s#查看pod详细信息[rootmaster30 ~]# kubectl get pod -o wideNAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES web1/1 Running067s10.224.51.131 worker31.laoma.cloudnonenone查看 pod# 以yaml格式查看pod[rootmaster30 ~]# kubectl get pod web -o yaml# 查看pod[rootmaster30 ~11:04:10]# kubectl describe pod b2Name: b2 Namespace: pods Priority:0Service Account: default Node: worker32/10.1.8.32 Start Time: Wed,24Jun202611:03:58 0800 Labels:runb2 Annotations: cni.projectcalico.org/containerID: 728a351f8f673c50aa3b8d1b6a1f5cd5f25e2d920e6678a6e4d8349174fa55e5 cni.projectcalico.org/podIP:10.224.45.1/32 cni.projectcalico.org/podIPs:10.224.45.1/32 Status: Running IP:10.224.45.1 IPs: IP:10.224.45.1 Containers: b2: Container ID: containerd://bee3278ae3b544e63b40e764bee78df186dfb3597a393982ae0614a3a55e48a4 Image: busybox Image ID: docker.io/library/busyboxsha256:fd8d9aa63ba2f0982b5304e1ee8d3b90a210bc1ffb5314d980eb6962f1a9715d Port:noneHost Port:noneArgs:shState: Running Started: Wed,24Jun202611:04:12 0800 Last State: Terminated Reason: Completed Exit Code:0Started: Wed,24Jun202611:04:00 0800 Finished: Wed,24Jun202611:04:10 0800 Ready: True Restart Count:1Environment:noneMounts: /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-7w6mr(ro)Conditions: Type Status PodReadyToStartContainers True Initialized True Ready True ContainersReady True PodScheduled True Volumes: kube-api-access-7w6mr: Type: Projected(a volume that contains injected data from multiple sources)TokenExpirationSeconds:3607ConfigMapName: kube-root-ca.crt ConfigMapOptional:nilDownwardAPI:trueQoS Class: BestEffort Node-Selectors:noneTolerations: node.kubernetes.io/not-ready:NoExecuteopExistsfor300s node.kubernetes.io/unreachable:NoExecuteopExistsfor300s Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 23s default-scheduler Successfully assigned pods/b2 to worker32 Normal Pulled 22s kubelet Successfully pulled imagebusyboxin1.444s(1.444s including waiting). Image size:2236931bytes. Normal Pulling 12s(x2 over 23s)kubelet Pulling imagebusyboxNormal Created 10s(x2 over 22s)kubelet Created container b2 Normal Started 10s(x2 over 22s)kubelet Started container b2 Normal Pulled 10s kubelet Successfully pulled imagebusyboxin1.43s(1.43s including waiting). Image size:2236931bytes.# 查看pod标准输出可以是选项-f动态查看pod输出[rootmaster30 ~]# kubectl logs -f web编辑 pod[rootmaster30 ~11:03:41]# kubectl edit pod web提示并不是所有属性都可以编辑例如pod名称。如果非要编辑特定属性可以先删除pod然后修改pod对的yaml文件重新创建。pod 中执行命令[rootmaster30 ~11:03:41]# kubectl run b2 -it --imagebusybox shIf you dont see acommandprompt, try pressing enter. /# pwd/ /# lsbin dev etc home lib lib64 proc root sys tmp usr var /# exitcp 文件给 pod[rootmaster30 ~]# kubectl cp /etc/hosts web:/new-hosts[rootmaster30 ~]# kubectl exec web -- ls /new-hosts/new-hosts删除 pod[rootmaster30 ~11:04:22]# kubectl get podsNAME READY STATUS RESTARTS AGE b10/1 CrashLoopBackOff4(54s ago)2m23s b21/1 Running1(26s ago)38s[rootmaster30 ~11:04:36]# kubectl delete pod b1podb1deleted[rootmaster30 ~11:04:50]# kubectl delete pod b2podb2deleted ^C[rootmaster30 ~11:05:01]##强制删除[rootmaster30 ~11:05:02]# kubectl delete pod b2 --forceWarning: Immediate deletion does notwaitforconfirmation that the running resource has been terminated. The resource maycontinueto run on the cluster indefinitely. podb2force deleted[rootmaster30 ~11:05:06]# kubectl get podsNo resources foundinpods namespace.yaml 文件创建 pod# web.yamlapiVersion:v1kind:Podmetadata:labels:run:webname:webspec:containers:-image:docker.io/library/nginxname:web#创建[rootmaster30 ~ 11:54:03]# kubectl create -f web.yaml# 或者[rootmaster30 ~ 11:54:04]# kubectl apply -f web.yaml构建 wordpreess创建 pod-mysql 数据库创建 pod-wordpress 博客# 创建 pod-mysql 数据库[rootmaster30 ~11:06:51]# kubectl run wordpress-db --imagehub.laoma.cloud/library/mysql:latest --env MYSQL_ROOT_PASSWORD123pod/wordpress-db created# 创建 pod-wordpress 博客[rootmaster30 ~11:23:39]# kubectl run wordpress-app --imagehub.laoma.cloud/library/wordpress:latestpod/wordpress-app created##查看状态[rootmaster30 ~11:24:06]# kubectl get podsNAME READY STATUS RESTARTS AGE wordpress-app0/1 ContainerCreating08s wordpress-db1/1 Running035s# 创建数据库[rootmaster30 ~11:25:02]# kubectl exec -it wordpress-db -- mysql -uroot -p123mysqlcreate database wordpress;Query OK,1row affected(0.002sec)mysqlcreate user wordpress identified by123;Query OK,0rows affected(0.006sec)mysqlgrant all privileges on wordpress.* to wordpress;Query OK,0rows affected(0.002sec)mysqlflush privileges;Query OK,0rows affected,1warning(0.002sec)mysqlshow databases;--------------------|Database|--------------------|information_schema||mysql||performance_schema||sys||wordpress|--------------------5rowsinset(0.001sec)mysqlexitBye# 查看 IP[rootmaster30 ~11:29:32]# kubectl get pods -o wideNAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES wordpress-app1/1 Running05m31s10.224.45.2 worker32nonenonewordpress-db1/1 Running05m58s10.224.137.3 worker31nonenone# 实现集群外访问集群内pod# 该命令窗口不要关闭[rootmaster30 ~11:29:37]# kubectl port-forward pod/wordpress-app --address 10.1.8.30 80:80Forwarding from10.1.8.30:80 -80Handling connectionfor80Handling connectionfor80Handling connectionfor80。。。。。访问web页面 http://10.1.8.30:80配置站点。多容器 pod示例文件blog.yaml[rootmaster30 ~13:52:26]# vim pod-blog.yamlapiVersion: v1 kind: Pod metadata: name: bbs labels: run: bbs spec: containers: - image: docker.io/library/mysql:latest imagePullPolicy: IfNotPresent name: mysql env: - name: MYSQL_ROOT_PASSWORD value:123- name: MYSQL_USER value: tom - name: MYSQL_PASSWORD value:123- name: MYSQL_DATABASE value: bbs ports: - containerPort:3306name: mysql protocol: TCP - image: docker.io/library/wordpress:latest imagePullPolicy: IfNotPresent name: wordpress env: - name: WORDPRESS_DB_USER value: tom - name: WORDPRESS_DB_PASSWORD value:123- name: WORDPRESS_DB_NAME value: bbs - name: WORDPRESS_DB_HOST value:127.0.0.1 ports: - containerPort:80name: wordpress protocol: TCP hostPort:80[rootmaster30 ~13:53:03]# kubectl apply -f pod-blog.yamlpod/bbs created#查看pod运行节点[rootmaster30 ~14:00:17]# kubectl get pod -o wideNAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES bbs2/2 Running03m48s10.224.137.4 worker31nonenone访问测试 10.1.8.31通过所在宿主机31的80端口# 多容器pod中执行命令通过-c指定容器[rootmaster30 ~14:03:30]# kubectl get podsNAME READY STATUS RESTARTS AGE bbs2/2 Running010m[rootmaster30 ~14:03:31]# kubectl exec bbs -c wordpress -- hostnamebbs[rootmaster30 ~]# kubectl cp /etc/hosts bbs:/new-hosts -c wordpress[rootmaster30 ~]# kubectl exec bbs -c wordpress -- ls /new-hosts/new-hostspod 关键属性pod.spec.containers.ImagePullPolicyAlways总是从仓库下载镜像。Never只使用本地镜像不下载。IfNotPresent优先使用本地镜像如果没有才从仓库下载镜像。pod lifecycle容器的运行状态取决于容器中的进程。pod的运行状态取决于pod中所有容器的状态。Pod and Container statusContainerCreating 正在创建Running 正在运行Completed 运行完成RunContainerError 运行错误CrashLoopBackOff 重新创建ErrImagePull 获取镜像错误ImagePullBackOff 重新获取镜像container statesWaiting: 等待某个条件满足变成Running状态例如下载镜像更新secrets等。 通过describe pod查看message和reason详细信息。Running: 容器正在运行没有问题。同时记录Running开始时间。Terminated: 容器运行完成也有可能是运行失败终止。pod.spec.restartPolicy示例restartPolicy:Nevercontainers:-name:myapp-containerimage:docker.io/library/busyboxcommand:[sh,-c,echo The app is running! sleep 5]restartPolicy针对pod中所有容器生效。Always除了 Running 状态其他状态总是重启默认值。OnFailure失败了才重启。Never从不重启。pod中包含1个容器验证pod状态监控命令 watch -n 1 kubectl get pod示例1[rootmaster30 ~ 14:54:12]# cd pods/[rootmaster30 pods 14:55:00]# vim pod-test1.yaml#文件内容如下apiVersion:v1kind:Podmetadata:name:busyboxlabels:app:busyboxspec:restartPolicy:Nevercontainers:-name:busyboximage:docker.io/library/busyboximagePullPolicy:IfNotPresentcommand:[sh,-c,echo Hello Kubernetes! sleep 10]观察pod状态为ContainerCreating–Running–Completed#观察状态[rootmaster30 pods14:55:33]# watch -n 1 kubectl get pod#构建同时观察上面命令的状态[rootmaster30 pods14:55:33]# kubectl apply -f pod-test1.yamlpod/busybox created示例2pod中包含2个容器验证pod状态[rootmaster30 pods15:01:40]# vim pod-test2.yamlapiVersion:v1kind:Podmetadata:name:busyboxlabels:app:busyboxspec:restartPolicy:Nevercontainers:-name:busybox1image:docker.io/library/busyboximagePullPolicy:IfNotPresentcommand:[sh,-c,echo Hello Kubernetes! sleep 5]-name:busybox2image:docker.io/library/busyboximagePullPolicy:IfNotPresentcommand:[sh,-c,echo Hello Kubernetes! sleep 10][rootmaster30 pods15:02:30]# kubectl apply -f pod-test2.yaml#查看运行状态[rootmaster30 pods14:55:33]# watch -n 1 kubectl get pod观察pod状态为ContainerCreating–Running–NotReady–Completed示例3[rootmaster30 pods15:01:40]# vim pod-test3.yamlapiVersion:v1kind:Podmetadata:name:busyboxlabels:app:busyboxspec:restartPolicy:Nevercontainers:-name:busybox1image:docker.io/library/busyboximagePullPolicy:IfNotPresentcommand:[sh,-c,echoxx Hello Kubernetes! sleep 5]-name:busybox2image:docker.io/library/busyboximagePullPolicy:IfNotPresentcommand:[sh,-c,echo Hello Kubernetes! sleep 20][rootmaster30 pods15:02:30]# kubectl apply -f pod-test3.yaml#查看运行状态[rootmaster30 pods14:55:33]# watch -n 1 kubectl get pod观察pod状态为ContainerCreating–ErrorAlways和OnFailure重启策略总是会重启podNever重启策略就不会重启pod。Init Containers一个pod可以有多个容器在其中运行应用程序也可以有一个或多个initContainers。initContainers中容器状态必须是completecontainers容器才能运行。如果pod的initContainers failkubernetes根据restartpolicy重启pod直到initContainers状态为complete。如果pod中initContainers有多个容器那么会按顺序创建和执行。按顺序执行的initContainers必须成功才能执行下一个initContainers。所有init全部成功执行完成后才开始执行pod中常规容器。示例1[rootmaster30 pods15:05:07]# vim pod-myapp.yaml# myservice---apiVersion:v1kind:Servicemetadata:name:myservicespec:ports:-protocol:TCPport:80targetPort:9376# mydb---apiVersion:v1kind:Servicemetadata:name:mydbspec:ports:-protocol:TCPport:80targetPort:9377# myapp---apiVersion:v1kind:Podmetadata:name:myapp-podlabels:app:myappspec:initContainers:-name:init-myserviceimage:docker.io/library/busyboxcommand:[sh,-c,until nslookup myservice; do echo waiting for myservice; sleep 2; done;sleep 3;]-name:init-mydbimage:docker.io/library/busyboxcommand:[sh,-c,until nslookup mydb; do echo waiting for mydb; sleep 2; done;sleep 3;]containers:-name:myapp-containerimage:docker.io/library/busyboxcommand:[sh,-c,echo The app is running! sleep 3600]首先创建2个service然后创建pod观察pod状态变化。kubernetes 中 Pod是K8s 独有的概念是 K8s 中最小调度、管理、自愈单元是容器的“外壳 运行环境”。**一个 Pod 里可以有 1 个或多个容器**pod中所有容器同住一个房间共用网络、存储。一起被调度到同一台机器一起销毁。特性容器PodK8s 最小调度单位❌ 不是✅ 是独立 IP✅ 有✅ 有独立 存储✅ 有✅ 有多容器支持❌ 不支持✅ 天然支持网络/存储共享❌ 不能✅ 内部容器可共享生命周期管理❌ 弱✅ 完整重启、自愈属于谁运行时Docker/containerdKuberneteskubernetes 为什么直接管理 pod 而不是容器容器太“原子”不适合直接调度。K8s 需要一个能直接被调度、能独立运行、有完整身份的对象–Pod。容器只是一个进程/运行环境Docker/containerd。Pod是容器的封装 网络/存储/配置/生命周期的统一抽象。K8s 调度、扩缩容、自愈、服务发现、监控……全都以 Pod 为单位。Pod 支持“多容器协同”最关键设计。很多场景必须多个容器一起跑、共享资源业务容器 Sidecar日志、监控、代理业务容器 InitContainer初始化业务容器 网络/安全代理容器它们需要共享Network Namespace同一个 IP、端口空间共享Volume一起调度到同一台机器Pod 提供统一的生命周期与自愈。K8s 要做重启失败容器替换崩溃节点上的实例滚动更新、回滚扩缩容这些行为必须作用在一个稳定、标准、独立的单元上如果直接管容器多容器应用会乱以 Pod 为单位管理语义清晰、一致解耦底层容器运行时。Pod 屏蔽了底层实现Dockercontainerdcri-o其他 CRI 运行时K8s 只跟Pod/CRI打交道不绑定某一种容器技术。pod 中 pause 容器作用在 Kubernetes 里每个 Pod 都会自动创建一个 pause 容器也叫 infra 容器它是 Pod 里第一个启动、最后退出的容器作用非常关键。pause 容器是干嘛的pause 容器就是为了“占坑”把 Pod 的网络和命名空间先 hold 住。它的 3 个核心作用①创建并持有 Pod 的 Linux NamespacePod 里所有容器要共享Network namespace同一个 IP、端口PID namespace可选IPC namespace这些共享空间必须由一个“永远不死”的容器来持有否则共享空间会消失。这个容器就是pause。②让 Pod 生命周期独立于业务容器业务容器挂了 → 重启pause 容器不挂 → Pod 就不会消失网络、IP、存储挂载都能保持不变如果没有 pause业务容器一退出整个 Pod 的网络就没了重启也没用。③实现多容器共享网络nginx、业务容器、sidecar 都加入 pause 的 network namespace共享同一个IP可以用127.0.0.1互相访问端口不能冲突超形象比喻pause 房东Pod 房子业务容器 租客房东pause先占好房子网络/命名空间租客业务容器才能住进来。租客换了一波又一波房子一直都在。pause 容器 Pod 的基石只负责holding namespace保证 Pod 网络、IP、生命周期稳定