pod概念及常用操作
pod概念:什么是pod
一个pod里面最少两个容器:
一个是pause容器,
另一个是指定运行的容器.
Pod是一组紧密关联的容器集合,它们共享PID、 IPC、 Network和UTS namespace, 是Kubernetes调度的基本单位。
Pod的设计理念是支持多个容器在一个Pod中共享网络和文件系统,可以通过进程间通信和文件共享这种简单高效的方式组合完成服务。
k8s为每一个pod都分配唯一的IP地址,称之为pod ip,一个pod中的多个容器共享pod ip地址,Pod可以配置多个IP地址
。
k8s要求底层网络支持集群内任意两个pod之间网络通信,采用虚拟二层技术实现,比如flanne、 calico、 ovs。 k8s中,一个pod的容器与另外主机上的pod容器能够直接通信。
init容器(初始化容器)
参考: https://www.jianshu.com/p/42afb9d9bfff
initContainer(初始化容器)会比普通container先启动;会按照定义的顺序启动,而普通的container是并发启动的;执行成功后结束退出,普通容器会一直执行
- InitContainer先于普通容器启动执行
- 多个InitContainer的执行是按定义次序串行执行,而多个普通容器是并行执行
- InitContainer执行成功后就结束退出,而普通容器可以一直执行
- Pod重启时,InitContainer会再次执行
apiVersion: v1
kind: Pod
metadata:
name: mydb
labels:
app: db
spec:
# init容器fetch启动完成后,才会启动业务容器mysql
initContainers:
- name: fetch
image: mwendler/wget
command: ["wget","--no-check-certificate","https://sample-videos.com/sql/Sample-SQL-File-1000rows.sql","-O","/docker-entrypoint-initdb.d/dump.sql"]
volumeMounts:
- mountPath: /docker-entrypoint-initdb.d
name: dump
containers:
- name: mysql
image: mysql
env:
- name: MYSQL_ROOT_PASSWORD
value: "example"
volumeMounts:
- mountPath: /docker-entrypoint-initdb.d
name: dump
volumes:
- emptyDir: {}
name: dump
pause容器(Infra容器)
参考: Pause 容器的作用
kubernetes中的pause容器主要为每个业务容器 提供以下功能:
PID命名空间:Pod中的不同应用程序可以看到其他应用程序的进程ID。
网络命名空间:Pod中的多个容器能够访问同 一个IP和端口范围。
IPC命名空间:Pod中的多个容器能够使用 SystemV IPC或POSIX消息队列进行通信。
UTS命名空间:Pod中的多个容器共享一个主 机名;Volumes(共享存储卷):
Pod中的各个容器可以访问在Pod级别定义的 Volumes.
每个Pod都有一个特殊的称之为“根容器”的Pause容器。 Pause容器对应的镜像属于k8s平台的一部分,除了Pause容器外,每个Pod还包含一个或多个紧密相关的用户业务容器。他为每个业务容器提供如下功能:
①在pod中担任Linux命名空间共享的基础。
②启用pid命名空间,开启init进程。
引入这种方式的原因:
- 一组容器运行的pod中,很难对整体进行判断,引入pasue作为根容器,以它的状态代表整个容器组的状态。
- pod中多个容器共享pasue容器的IP,共享pause容器挂载的volume。
这样简化了密切相连的容器之间的通信,也解决了他们之间文件共享的问题。
pause容器也叫infra容器;
Pod 里面,必然是 Infra container 第一个启动,用来为业务容器提供网络.
pod的IP是配置pause容器上的,pod中的其他容器与pause容器共用网络。
docker ps|grep pause
查看,有几个pod,就会有几个pause容器启动.
修改默认infro容器
# 定义默认infra容器
vim /etc/kubenets/kubelet
普通pod:
一旦被创建,会被放到etcd中存储,随后被k8s master调度到某个具体的node上并进行绑定,随后该pod被对应的node上的kubelet进程实例化成一组相关的docker容器并启动起来。默认情况下,当pod中的某个容器停止时,
K8s会自动检测到这个问题并重新启动这个pod(重启pod里面的所有容器),如果pod所在的node宕机,则会将这个
node上的所有pod重新调度到其他节点上。
pod资源限制:
每个pod可以设置限额,目前可以设置CPU和内存, cpu的单位为core的数量,
是一个绝对值而不是相对值。 k8s中是以千分之一为最小单位,一般一个pod
设置为100m到300m,也是就是0.1-0.3个cpu。内存是以MB为单位
k8s设置2个参数:
requests
:该资源的最小申请量,系统必须满足的要求
limits
:该资源的最大允许使用的量,不能被突破,当容器试图使用超过这个
量的资源时,有可能会被k8s kill并重启。
pod生命周期介绍
Pod 对象在 Kubernetes 中的生命周期。 Pod 生命周期的变化,主要体现在 Pod API 对象的Status 部分。
其中pod.status.phase,就是 Pod 的当前状态,它有如下几种可能的情况:
Pending
Running
Succeeded
Failed
Unknown
Pending状态
Pending。这个状态意味着, Pod 的 YAML 文件(或通过kubectl命令创建Pod)已经提交给了 Kubernetes, API 对象已
经被创建并保存在 Etcd 当中。但是,这个 Pod 里有些容器因为某种原因而不能被顺利创建。比如,调度不成功。
当Pod处在Pending的时候,可能是由于如下哪个问题造成的。
- 资源不足,造成无法调度
- Pod尚未进入调度阶段
- Pod正在拉取镜像
Running状态
Running。这个状态下, Pod 已经调度成功,跟一个具体的节点绑定。它包含的容器都已经创建成功,并且至少有一个正
在运行中。
Succeeded状态
Succeeded。这个状态意味着, Pod 里的所有容器都正常运行完毕,并且已经退出了。这种情况在运行一次性任务时最
为常见。
Failed状态
Failed。这个状态下, Pod 里至少有一个容器以不正常的状态(非 0 的返回码)退出。这个状态的出现,意味着你得想办
法 Debug 这个容器的应用,比如查看 Pod 的 Events 和日志。
Unknown状态
Unknown。这是一个异常状态,意味着 Pod 的状态不能持续地被 kubelet 汇报给 kube-apiserver,这很有可能是主从
节点( Master 和 Kubelet)间的通信出现了问题。
其他字段
更进一步地, Pod 对象的 Status 字段,还可以再细分出一组 Conditions。这些细分状态的值包括: PodScheduled、
Ready、 Initialized,以及 Unschedulable。它们主要用于描述造成当前Status 的具体原因是什么。
比如, Pod 当前的 Status 是 Pending,对应的 Condition 是 Unschedulable,这就意味着它的调度出现了问题。
Pod 的这些状态信息,是我们判断应用运行情况的重要标准,尤其是 Pod 进入了非“Running”状态后,你一定要能迅速
做出反应,根据它所代表的异常情况开始跟踪和定位,而不是去手忙脚乱地查阅文档。
静态pod:
静态 Pod(Static Pod) 直接由特定节点上的 kubelet 守护进程管理
, 不需要API 服务器看到它们。
无法与我们常用的控制器Deployments或者DaemonSeti进行关联,它由kubeleti进程自己来监控,当pod崩溃时重启该pod,kubelete也无法对他们进行健康检查。静态pod始终绑定在某一个kubelet,并且始终运行在同一个节点上。
Kubelets会自动为每一个静态pod在Kubernetes的apiserver.上创建一个镜像Pod(Mirror Pod)
,因此我们可以在apiserveri中查询到该pod,但是不能通过apiserver进行控制(例如不能删除)。
静态pod不存储在etcd
中,而是存放在某个具体的node上的一个具体文件中,并只在此node上启动运行。
静态Pod名称标识当前节点名称.
在kubelet配置文件中启用静态pod的参数
# 编辑配置文件
vim /var/lib/kubelet/config.yaml
# 添加/查看静态pod路径参数
staticPodPath: /etc/kubernetes/manifests
## 注:将部署的pod yaml放到该目录会由kubelet自动创建。
创建静态pod
创建静态Pod有两种方式:配置文件和HTTP两种方式
将静态pod的yaml文件放在/etc/kubernetes/manifests
路径下即可.
静态pod的yaml示例
apiVersion: v1
kind: Pod
metadata:
name: static-web
labels:
role: myrole
spec:
containers:
- name: web
image: nginx
ports:
- name: web
containerPort: 80
protocol: TCP
查看静态pod
[master root ~]# kubectl get po|grep -i static-web
static-web-node 1/1 Running 0 6m10s
pod注意事项
pod不支持
apply和edit在线更新
但是可以用apply创建pod
多容器pod重启策略
一个容器出错pod状态就会显示error,会根据重启策略执行重启
健康检查
参考官方文档: https://kubernetes.io/zh/docs/concepts/workloads/pods/pod-lifecycle/#container-probes
存活探针-livenessProbe
Liveness Probe主要面向有状态服务
;
指示容器是否正在运行。如果存活态探测失败,则 kubelet 会杀死容器, 并且容器将根据其重启策略决定未来。如果容器不提供存活探针, 则默认状态为 Success。
定义探针存活命令
参考: 定义探针存活命令
exec存活检查示例
apiVersion: v1
kind: Pod
metadata:
labels:
test: liveness
name: liveness-exec
spec:
containers:
- name: liveness
image: k8s.gcr.io/busybox
args:
- /bin/sh
- -c
- touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600
# 配置存活探针
livenessProbe:
# 在容器内执行指定命令,如果命令退出时返回码为 0 则认为诊断成功。
exec:
command:
- cat
- /tmp/healthy
# 容器初始化延迟秒数(多少秒后开始检查存活)
initialDelaySeconds: 5
# 超时秒数 返回结果超时认为不健康
timeoutSeconds: 1
# 多少秒执行一次存活指令
periodSeconds: 5
httpGet存活检查示例
apiVersion: v1
kind: Pod
metadata:
labels:
test: liveness
name: liveness-http
spec:
containers:
- name: liveness
image: k8s.gcr.io/liveness
args:
- /server
# 配置存活探针
livenessProbe:
# 执行httpget请求
httpGet:
# 请求的路径
path: /healthz
# 请求的端口
port: 8080
# 添加自定义请求头
httpHeaders:
# 添加字段
- name: Custom-Header
# 添加字段的值
value: Awesome
# 容器初始化延迟秒数
initialDelaySeconds: 3
# 多少秒检查一次存活
periodSeconds: 3
就绪探针-readinessProbe
指示容器是否准备好为请求提供服务。如果就绪态探测失败, 端点控制器将从与 Pod 匹配的所有服务的端点列表中删除该 Pod 的 IP 地址。 初始延迟之前的就绪态的状态值默认为 Failure。 如果容器不提供就绪态探针,则默认状态为 Success。
Readiness Probe
在检测失败后会自动从Endpoint
上摘掉Pod
。
tcpSocket就绪探针和存活探针示例
tcpSocket
的原理有点像telnet ip地址 端口号
,检查端口是否开放.
apiVersion: v1
kind: Pod
metadata:
name: goproxy
labels:
app: goproxy
spec:
containers:
- name: goproxy
image: k8s.gcr.io/goproxy:0.1
ports:
- containerPort: 8080
# 配置就绪探针
readinessProbe:
# 使用tcp端口检查方式配置就绪探针
tcpSocket:
# 检查8080端口是否开放
port: 8080
# 容器初始化延迟秒数
initialDelaySeconds: 5
# 多少秒执行一次就绪检查
periodSeconds: 10
# 配置存活探针
livenessProbe:
# 使用tcp端口检查方式配置存活探针,类似于telnet
tcpSocket:
# 检查8080端口是否开放
port: 8080
# 容器初始化延迟秒数
initialDelaySeconds: 15
# 多少秒执行一次存活检查
periodSeconds: 20
启动探针-startupProbe
指示容器中的应用是否已经启动。如果提供了启动探针,则所有其他探针都会被 禁用,直到此探针成功为止。如果启动探测失败,kubelet 将杀死容器,而容器依其 重启策略进行重启。 如果容器没有提供启动探测,则默认状态为 Success。
服务质量等级(QOS)
QoS(Quality of Service),大部分译为“服务质量等级”,又译作“服务质量保证”,是作用在 Pod 上的一个配置,当 Kubernetes 创建一个 Pod 时,它就会给这个 Pod 分配一个 QoS 等级,可以是以下等级之一:
Guaranteed
:Pod 里的每个容器都必须有内存/CPU 限制和请求,而且值必须相等。
Burstable
:Pod 里至少有一个容器有内存或者 CPU 请求且不满足 Guarantee
等级的要求,即内存/CPU 的值设置的不同。
BestEffort(最低优先级)
:容器必须没有任何内存或者 CPU 的限制或请求。
最高优先级(Guaranteed)pod
https://www.toutiao.com/a6939507079094731272/?log_from=f50e1823b745_1646033172214
limits和requests两个都配置了且配置的值要一样,就是最高优先级的pod.
# pod内资源分配的配置格式如下:
# 默认可以只配置requests,但根据生产中的经验,建议把limits资源限制也加上,因为对K8s来说,
#只有这两个都配置了且配置的值都要一样,这个pod资源的优先级才是最高的,在node资源不够的情况下,首先是把#没有任何资源分配配置的pod资源给干掉,其次是只配置了requests的,最后才是两个都配置的
resources:
limits: # 限制单个pod最多能使用1核(1000m 毫核)cpu以及2G内存
cpu: "1"
memory: 2Gi
requests: # 保证这个pod初始就能分配这么多资源
cpu: "1"
将pod中的容器资源限制的独享资源和共享资源设为一样的值
,该pod优先级即为最高。如果资源不够时会驱逐其他pod。
pod常用操作
启动一个pod
# 使用nginx镜像启动一个名为test的pod
kubectl run test --image=nginx
# 使用busybox创建一个测试pod
kubectl run bs --imges=busybox:1.28.4 -- sleep 24h
创建一个测试pod
# 使用busybox创建一个测试pod
kubectl run ping --imges=busybox:1.28.4 -- sleep 24h
使用yaml创建pod
apiVersion: v1
kind: Pod
metadata:
name: ping
labels:
name: ping
spec:
containers:
- name: ping
image: busybox:1.28.4
imagePullPolicy: IfNotPresent
command: ["/bin/sh", "-c", "sleep 12h"]
进入ping这个测试pod
busybox
一般用来做网络测试
# busybox不支持bash,要指定sh
kubectl exec -it ping -- sh
pod资源清单yam示例
最小应用部署单元 即应用
pod 需要定义什么 ( 带* 为必填项)
元数据 *
pod名称 *
所属namespaces *
标签 可用于 svc 识别 *
注释信息 *
规格 *
调度
- 容器名称 containers *
使用镜像 *
镜像拉取方式 *
执行参数
启动参数
挂载卷使用 对应到容器 目录
开放端口
环境变量
资源配额
健康检查
指定挂载卷 硬盘资源
容忍
dns策略
主机模式
重启策略
pod yaml 范例
apiVersion: v1
kind: Pod
metadata:
name: test-pod # pod名称
namespaces: default # 所属命名空间
labels: # pod 标签列表
app: test # 添加标签 (key-value)
annotations: # 注释 列表
app: test # 添加注释(key-value)
spec: # 规格
nodeSelector: # 表示将该Pod调度到包含这个label的node上
nodelabel: node2 # 调度node的标签
containers: # 容器规格
# 以下为这个containers 的配置
- name: test
image: nginx # 使用镜像源 (镜像源)
imagePullPoilcy: {always| Never | ifNotPresent} #镜像拉取方式(always Never ifNotPresent)
# 启动命令 ----------------------------------------
command: # dockers启动后执行命令
- /bin/sh
- c
- sleep 3600 # 执行命令
# 启动参数 ----------------------------------------
args: # 容器启动 参数列表
- ["HOSTNAME", "KUBERNETES_PORT"] # 容器启动参数
workingdir: / # 容器工作目录 linux 目录
# 容器挂载 ----------------------------------------
volumeMounts: # 挂载存储配置
- name: disk1 # 挂载存储卷名称
mountPath: # 存储卷挂载位置 绝对路径
readonly: {true|false} # 是否只读 {true|false}
# 开放端口 ----------------------------------------
ports: # 容器需要暴漏的端口号列表
- name: http # port名称
containerPort: 80 # 监听容器内端口号使用podip可以访问 int
hostPort: 80 # 容器将服务映射到宿主机端口 #端口号 int
# protocol在ports层级下边,只能指定tcp/udp/sctp
protocol: {tcp|udp} # 端口协议 {tcp | udp}
# 环境变量 ----------------------------------------
env:
- name: path # 环境变量名称 string
value: xxx # 环境变量值 string
#---
- name: configmap # 可使用configmap传入变量
valueFrom:
configMapKeyRef:
name: test-cm # 使用名为test-cm的configmap
key: test-cm-testvkey #使用test-cm 中的test-cm-testvkey值
# 资源限制 ----------------------------------------
resources: # 使用资源限制 (limits 大于 requests)
#---
limits: # 封顶资源限制,最大使用的共享资源
cpu: "1" # CPU 限制1 核
memory: 1Gi # 内存限制 512M #单位Gi Mi
#----------------------------------------
requests: # 请求资源,独享资源
cpu: "1" # CPU 限制0.5 核
memory: 512M # 内存限制 512M #单位Gi Mi
# 健康检查 ----------------------------------------
readinessProbe: # 健康检查/就绪探针
#----
exec: # 命令脚本方式
command:
- cat
- /tmp/health # 命令执行返回结果为失败判定为不健康
#----
tcpSocket: # 端口健康检测方式-telnet
port: 80 # 检测tcp80端口 如果为开启 为不健康
#----
httpGet: # http请求方式
path: /
port: 80 # http请求 容器地址:port+path 返回状态码结果200~399 为健康
#----
initialDelaySeconds: # 初始检测延迟秒数
timeoutSeconds: 1 # 超时秒数 返回结果超时认为不健康
periodSeconds: 10 # 对容器监控检查的定期探测时间设置,单位秒,默认10秒一次
# 挂载目录 ----------------------------------------
volumes: # 设定存储卷 三种模式
- name: tmp # 存储卷名称(emptydir模式)临时目录
emptyDir: {} # 使用临时存储 容器 重启会数据清空
#--- 将本地目录/disk1,挂载为volumes: host_path
- name: host_path # 存储卷名称 (hostpath模式)宿主机文件存储
hostPath: # 使用宿主机文件模式 挂载目录=宿主机目录
path: "/disk1" # 挂在宿主机目录地址
#--- 将nfs存储挂载为名为nfs的volumes
- name: nfs # nfs模式 使用nfs服务器 存储资源
nfs:
server: 192.168.1.1 #指定nfs url
# ---- 挂载pvc
- name: pvc
persistenVolumeClaim:
claimName: pvc1 # 已经申请好了的PVC
#--- 将configMap挂载为名为cm的volume
- name: cm # 存储卷名称 (configmap模式)
configMap: # 使用configmap模式
items:
- key: # 使用configmap key
path: # 挂载路径
# DNS一般不动
dnsPolicy: {default|clusterFirst|clusterFirstwithHostNet|node}
hostNetwork: {true|false} # hostNetwork网络模式
restartPolicy: {Always|Never} # 重启策略
# 容忍 ----------------------------------------
tolerations:
- key: "节点污点key"
operator: "Equal"
value: "节点污点value"
effect: "NoExecute"
tolerationSeconds: 3600
镜像拉取策略
Kubernetes 中的镜像拉取策略(imagePullPolicy
)有以下几种:
-
Always
: 每次都尝试拉取镜像,如果本地已经存在该镜像,则会进行覆盖。这是默认的拉取策略。 -
IfNotPresent
: 仅当本地不存在该镜像时才尝试拉取。 -
Never
: 仅使用本地已经存在的镜像,如果本地不存在该镜像,则会报错。 -
OnFailure
: 仅在上一次启动容器失败后才会尝试拉取镜像。
需要注意的是,镜像拉取策略只会影响首次容器启动时的行为,如果容器已经被创建并运行,那么更新镜像需要手动执行“删除
-创建
”操作。
进入pod执行命令
# 执行pod的date命令,默认使用pod的第一个容器
kubectl exec pod名 date
kubectl exec pod名 -- bash
# 指定pod中的某个容器执行date命令
kubectl exec pod名 -c 容器名 date
# 进入pod中的容器
kubectl exec pod名 -c 容器名 -- bash
kubectl exec pod名 -c 容器名 -- /bin/bash
查看pod的ip地址
# 查看pod的基本信息
kubectl get po test
# 查看pod的常用信息,pod的IP和所属节点
kubectl get pod test -o wide
## 访问pod
crul pod的ip地址
查看pod详情
# 查看pod的详细信息
kubectl describe pods pod名
查看pod资源的labels(标签)
# 查看pod的标签
kubectl get pods --show-labels
# 根据标签查询pod
kubectl get pods -l 标签key=value
kubectl get pods -l app=nginx
查看运行中pod的镜像
# 查看集群中运行着的所有镜像
kubectl get pods -A -o=custom-columns='DATA:spec.containers[*].image'
# 列举 default 名字空间中运行的所有镜像,按 Pod 分组
kubectl get pods --namespace default --output=custom-columns="NAME:.metadata.name,IMAGE:.spec.containers[*].image"
# 除 "k8s.gcr.io/coredns:1.6.2" 之外的所有镜像
kubectl get pods -A -o=custom-columns='DATA:spec.containers[?(@.image!="k8s.gcr.io/coredns:1.6.2")].image'
# 输出 metadata 下面的所有字段,无论 Pod 名字为何
kubectl get pods -A -o=custom-columns='DATA:metadata.*'
查看pod的日志
# 查看pod日志
kubect logs pod名
# 持续pod中的容器日志
# 查看多容器pod日志
kubectl logs -f pod名 -c 容器名
pod扩容
kubectl scale pod名 --replicas=副本数量
HPA自动水平伸缩pod
参考: https://www.toutiao.com/a6939507079094731272/?log_from=f50e1823b745_1646033172214
需要依赖kubectl top
,
需要pod配置预设资源
# 为deployment资源web创建hpa,pod数量上限3个,最低1个,在pod平均CPU达到50%后开始扩容
kubectl autoscale deployment web --max=3 --min=1 --cpu-percent=50
滚动更新pod
kubectl set image pod名 容器名=镜像名:v镜像版本号
强制删除pod
从 v1.5 开始,Kubernetes 不会因为 Node 失联而删除其上正在运行的 Pod,而是将其标记为
Terminating
或Unknown
状态
kubectl delete po ${pod_name} --grace-period=0 --force
用yaml强制更新pod
强制更新 pod(运行时只能修改部分内容)
kubectl replace -f manual-schedule.yaml --force
pod亲和(podAffinity)
华为云-pod亲和
官方doc-pod亲和示例
Pod和Pod之间的亲和
,例如将应用的前端和后端部署在一起,从而减少访问延迟
。
apiVersion: v1
kind: Pod
metadata:
name: with-pod-affinity
spec:
# 亲和
affinity:
# pod亲和
podAffinity:
# 硬策略
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
# 带有security=S1标签的pod尽量运行在同一node上
- key: security
operator: In
values:
- S1
# 用主机名来作为拓扑域
topologyKey: topology.kubernetes.io/zone
containers:
- name: with-pod-affinity
image: k8s.gcr.io/pause:2.0
pod反亲和(podAntiAffinity)
参考:
PodAntiAffinity
且requiredDuringSchedulingIgnoredDuringExecution
雪花啤酒的面试官问了个问题: deployment如何在每个node上运行一个pod?
当时一时想不起来pod反亲和硬策略
可以实现.
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis-cache
spec:
selector:
matchLabels:
app: store
# 副本数3
replicas: 3
template:
metadata:
labels:
app: store
spec:
affinity:
# pod反亲和
podAntiAffinity:
# 硬需求/硬策略
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
# 禁止在同一node上部署多个标签为app=strore的副本
- key: app
operator: In
values:
- store
# 用主机名来作为拓扑域
topologyKey: "kubernetes.io/hostname"
containers:
- name: redis-server
image: redis:3.2-alpine
网络测试pod
参考: 容器网络调试工具 netshoot
netshoot镜像工具表
# 使用nicolaka/netshoot镜像创建一个网络调试用的临时pod
kubectl run ping --rm -ti --image=nicolaka/netshoot -- bash
pod抓包
-
问题场景:
某pod业务访问k8s外部业务网络不通,怎么抓pod网络的包 -
解决办法:
容器中一般是没有tcpdump
命令的,可以通过node
上的nsenter
命令进入pod
的namespace
进行抓包.
# 确认pod所在的node节点
kubectl get pod -owide -n 指定namespace | grep pod名
# 进入node节点
ssh node_ip
## 在node上安装nsenter命令
yum install -y util-linux
查询pod的容器pid
# 方法1:查询该pod的某容器的pid
## 查询pod的容器名|容器id
docker ps | grep pod名
## 通过容器id查询该容器的pid
## --format "{{.State.Pid}}" 指定获取Pid字段
docker inspect --format "{{.State.Pid}}" 容器id
进入指定pid的网络命名空间(network namespace)
Process ID (pid)
Mount (mnt)
Network (net)
InterProcess Communication (ipc)
UTS
User ID (user)
例如:pid
命名空间内的进程只能看到同一命名空间中的进程
。mnt
命名空间,可以将进程附加到自己的文件系统(如chroot
)。- 在本文中,只关注网络命名空间
Network (net)
。
https://developer.aliyun.com/article/272172
# 进入指定容器的网络命名空间(network namespace)
## -t 指定的pid
## -n 表示切换网络命名空间(network namespace)
nsenter -t 容器在宿主机上的pid -n
在node上通过tcpdump对该容器抓包
# 对dst抓包
tcpdump -i eth0 dst <destination-ip-address>
# 对src抓包
tcpdump -i eth0 src <source-ip-address>
退出网络命名空间(network namespace)
抓包完成后退出当前终端会话,就回到node的OS默认网络命名空间。