k8s常用命令

比较常用命令集合

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# 看k8s应用
kubectl get pods,svc,statefulsets -o wide|grep [应用名]

# test run
kubectl run [pod Name] --image=[image Name] -it --rm --restart='Never' --namespace default -- bash

kubectl logs -f pod/[pod name] container

kubectl describe pod/[pod name]

kubectl run mysql-client --image=ubuntu:18.04 -it --rm --restart='Never' --namespace default -- /bin/sh


# node label
kubectl get nodes --show-labels






curlimages/curl:7.73.0
# test pod
apiVersion: v1
kind: Pod
metadata:
  name: dnsutils
spec:
  containers:
  - name: dnsutils
    image: mydlqclub/dnsutils:1.3
    imagePullPolicy: IfNotPresent
    command: ["sleep","3600"]
    volumeMounts: # 挂载,首先添加需要挂载的目录
      - name: test-volume # 挂载点的名称
        mountPath: /mm # 挂载点的路径
  volumes: # 绑定
    - name: test-volume
      persistentVolumeClaim: # 将镜像中的nginx目录挂载到下面名称的PVC中
        claimName: mnist-pvc # PVC名称

kubectl create -f dnsutils.yaml -n xxx
kubectl exec -it dnsutils -n xxx -- /bin/sh

docker logs

1
docker logs --since="1607356800" [docker name] > /xxxx/xxx.log

过滤grep

1
docker logs nginx 2>&1 | grep "127."  
1
docker run -it --rm ubuntu:bionic /bin/bash

helm

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# get all images
helm template --dry-run  kafka-0.8.0.tgz | grep image: | sed -e 's/[ ]*image:[ ]*//' -e 's/"//g' | sort -u

# 仓库管理
helm repo add rancher-stable https://releases.rancher.com/server-charts/stable
helm repo update
# 搜索
helm search repo karmada

# 测试helm
helm template --debug karmada-1.3.0.tgz -f install/karmada.yaml > a

# 更新dependency
helm dependency update new_karmada


# list charts version
helm search repo submariner-latest/submariner-k8s-broker --versions

helm search repo submariner-latest/submariner-k8s-broker --versions
helm search repo submariner-latest/submariner-operator --versions

# 下载指定version chart
helm fetch submariner-latest/submariner-k8s-broker --version xxxx
helm fetch submariner-latest/submariner-operator

# get values
helm show values stable/mariadb


# upgrade
helm upgrade openebs openebs-3.3.1.tgz --reuse-values -n openebs -f values.yaml 

How to pass dynamic arguments to a helm chart that runs a job

docker

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# 运行一次性的新容器
docker run --rm -it <image-name-or-id> bash

# 入正在运行的容器
docker exec -it <container-name-or-id> bash



# 批量删除某类image
docker rmi -f $(docker images|grep xxx |awk '{print $3}')
#停止所有的容器
docker stop $(docker ps -aq)

#删除所有的容器
docker rm $(docker ps -aq)

#删除所有的镜像
docker rmi $(docker images -q)



# 获取images
docker images |grep xxx | awk '{print $1":"$2}'




# 压缩
docker save xxx > xx.tar
tar -zcvf  xxx.tar.gz xx.tar

tar -zxvf xx.tar.gz
docker load < xx.tar



# docker device or resource busy

umount $(df -HT | grep '/var/lib/kubelet/pods' | awk '{print $7}')

本地端口转发

1
2
3
4
5
6
NAME    TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)     AGE
mongo   ClusterIP   10.96.41.183   <none>        27017/TCP   11s

kubectl port-forward service/mongo 28015:27017

kubectl port-forward --address 0.0.0.0 svc/ml-pipeline-ui 3000:80 --namespace kubeflow

创建一个服务对象来暴露 Deployment

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
kubectl expose deployment hello-world --type=NodePort --name=example-service

kubectl expose deployment front-end --port=80 --target-port=80 --protocol=TCP --type=NodePort --name=front-end-svc
Name:                   example-service
Namespace:              default
Labels:                 run=load-balancer-example
Annotations:            <none>
Selector:               run=load-balancer-example
Type:                   NodePort
IP:                     10.32.0.16
Port:                   <unset> 8080/TCP
TargetPort:             8080/TCP
NodePort:               <unset> 31496/TCP
Endpoints:              10.200.1.4:8080,10.200.2.5:8080
Session Affinity:       None
Events:                 <none>

proxy

1
2
3
4
5
6
7
8
9
10
11
12
13
14
kubectl proxy --address 0.0.0.0 --accept-hosts=^.*

# rancher k8s proxy api
https://xxx.xxx.xx.201:1443/k8s/clusters/{cluster-id}/api/v1/namespaces/{namespace}/services/{svc}:{svc-port-name}/proxy

# k8s svc proxy api
/api/v1/namespaces/{namespace}/services/{svc}:{svc-port-name}/proxy

https://xxx.xxx.xx.201:1443/k8s/clusters/c-xlfq6/api/v1/namespaces/istio-system/services/istio-ingressgateway:http2/proxy/v1/models/xx:predict

## crd api
http://localhost:8001/apis/example.com/v1beta1/namespaces/default/foos/


引用自《Programming Kubernetes》

删除合集

删除stats

1
2
3
4
5
6
7
kubectl delete statefulsets <statefulset 名称>
# 删除 StatefulSet 之后,你可能需要单独删除关联的无头服务。
kubectl delete service <服务名称>

#当通过 kubectl 删除 StatefulSet 时,StatefulSet 会被缩容为 0。 属于该 StatefulSet 的所有 Pod 也被删除。 如果你只想删除 StatefulSet 而不删除 Pod,使用 --cascade=orphan。

kubectl delete -f <file.yaml> --cascade=orphan

删不掉其他资源

1
2
3
4
5
6
7
8
9
10
11
# 删除删不掉的pv pvc
kubectl patch $(kubectl get pv,pvc |grep [应用名]|awk '{print $1}') -p '{"metadata":{"finalizers":null}}'

kubectl delete $(kubectl get pv,pvc |grep mysqlha|awk '{print $1}')

# 使用patch更新Node节点
kubectl patch node k8s-node-1 -p '{"spec":{"unschedulable":true}}'


# 删除删不掉pod
kubectl delete $(kubectl get pod |grep [应用名]|awk '{print $1}') --grace-period=0 --force

删不掉k8s namespace

  • 正常删除
1
kubectl delete namespace NAMESPACENAME
  • 强制删除
1
kubectl delete namespace NAMESPACENAME --force --grace-period=0
  • 修改finalizers

    删掉finalizers 和 status “phase”: “Terminating”

    1
    kubectl edit namespace NAMESPACE_NAME
    

    image-20220105174259869

    如果没有上面的finalizers内容,通过调用接口删除

  • 接口删除

第一步:将namespace内容导出到tmp.json文件中:

1
kubectl get namespace calico-apiserver -o json > tmp.json

第二步:修改tmp.json内容,删除json中以下内容finalizers

1
2
3
4
5
6
7
8
9
10
11
12
{
    //删除spec整个内容
    "spec": {
        "finalizers": [
            "kubernetes"
        ]
    },
    
    "status": {
        "phase": "Terminating"
    }
}

第三步:开启k8s接口代理,新开一个窗口,执行

1
2
kubectl proxy --port=8001
Starting to serve on 127.0.0.1:8001

第四步:调用接口删除Namespace,注意URL中修改成要删除的NAMESPACE_NAME

1
curl -k -H "Content-Type: application/json" -X PUT --data-binary @tmp.json http://127.0.0.1:8001/api/v1/namespaces/calico-apiserver/finalize

k3s 删不掉

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
kubectl patch namespace submariner-operator -p '{"metadata":{"finalizers":[]}}' --type='merge' -n submariner-operator
kubectl delete namespace cattle-system --grace-period=0 --force



kubectl get ns ums-edge-agent  -o json | jq 'del(.spec.finalizers)' |curl -v -H "Content-Type: application/json" -X PUT --data-binary @- http://127.0.0.1:8001/api/v1/namespaces/ums-edge-agent/finalize


kubectl patch namespace ums-edge-agent -p '{"metadata":{"finalizers":[]}}' --type='merge' -n ums-edge-agent

# 查看k8s集群中可以使用命名空间隔离的资源
kubectl api-resources -o name --verbs=list --namespaced | xargs -n 1 kubectl get --show-kind --ignore-not-found -n ums-edge-agent

# 发现rdbms命名空间下并无资源占用

删除所有资源

1
2
3
4
5
# 删除namespace下面所有pod
kubectl delete --all pods --namespace=foo --grace-period=0 --force

# 常见的资源类型
kubectl delete all --all --all-namespaces

当我们的集群中有太多Evicted(被驱逐的) pod,这可能会导致网络负载,因为每个 pod,即使被驱逐的 pod 连接到网络并且在云 Kubernetes 集群的情况下,也会阻止 IP 地址。这可能导致如果您的集群有固定的 IP 地址池,也会耗尽 IP 地址 参考

1
2
3
4
5
# 删除 Evicted pod
kubectl get pod |grep Evicted |awk '{print $1}' |xargs kubectl delete pod


kubectl get pod -n cattle-system |grep cattle-cluster-agent |awk '{print $1}' |xargs kubectl delete pod -n cattle-system

查看kubectl api调用过程

主要是看crd api

1
kubectl get inferenceservices test-sklearn -n kserve-test --v=8  > a 2>&1

一般情况下,每个 Unix/Linux 命令运行时都会打开三个文件:

  • 标准输入文件(stdin):stdin的文件描述符为0,Unix程序默认从stdin读取数据。
  • 标准输出文件(stdout):stdout 的文件描述符为1,Unix程序默认向stdout输出数据。
  • 标准错误文件(stderr):stderr的文件描述符为2,Unix程序会向stderr流中写入错误信息。

默认情况下,command > file 将 stdout 重定向到 file,command < file 将stdin 重定向到 file。

命令 说明
command > file 将输出重定向到 file。
command < file 将输入重定向到 file。
command » file 将输出以追加的方式重定向到 file。
n > file 将文件描述符为 n 的文件重定向到 file。
n » file 将文件描述符为 n 的文件以追加的方式重定向到 file。
n >& m 将输出文件 m 和 n 合并。
n <& m 将输入文件 m 和 n 合并。
« tag 将开始标记 tag 和结束标记 tag 之间的内容作为输入。

注意:0 是标准输入(STDIN),1 是标准输出(STDOUT),2 是标准错误输出(STDERR)。

这里的 2> 之间不可以有空格,2> 是一体的时候才表示错误输出。

Kubectl 日志输出详细程度和调试

生成ConfigMap配置

1
2
3
4
# 生成ConfigMap配置
kubectl create configmap [configmap 名字] --from-file=[目录或文件] --dry-run -o yaml > [配置名].yaml

kubectl create configmap redis-config --from-file=web --dry-run -o yaml > redis-config-configmap.yaml

merge kube config

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
KUBECONFIG=~/.kube/this-config:~/.kube/other-config kubectl config view --flatten > ~/.kube/config

# 临时指定kube上下文,操作
KUBECONFIG=./kubeconfig kubectl  get clusters.management.cattle.io


# k8s config path
/root/.kube/config

# k3s config path
/etc/rancher/k3s/k3s.yaml



kubectl config get-contexts
kubectl config use-context [context-name]


export KUBECONFIG=

docker exec -it kube-apiserver bash

cd /etc/kubernetes/ssl

kubectl get pods -A --kubeconfig kubecfg-kube-controller-manager.yaml

corndns

1
2
3
4
hosts {
     10.19.64.212 201.xxx.cn
      fallthrough
}
1
2
3
4
5
6
7
8
9
10
11
12
13
apiVersion: v1
kind: ConfigMap
metadata:
  name: coredns-custom
  namespace: kube-system
data:
    xxx.server: | # 必须.server结尾
          example1.org example3.org  {
              hosts {
                   127.0.0.1 example1.org example3.org
                   fallthrough
              }
          }
1
2
3
kubectl edit cm coredns -n kube-system
# 重启deploy
kubectl rollout restart deployment  coredns -n kube-system

crd

1
2
kubectl api-resources
kubectl api-versions

驱逐

1
2
3
4
5
# 将节点标记为不可调度状态
kubectl cordon k8s-master

# 驱逐Pod
kubectl drain k8s-master --delete-local-data --ignore-daemonsets --force

通过宿主pid获取pod name

某个进程占用资源高

1
2
3
4
5
6
# 根据 PID 直接获取 Pod UID
$ cat /proc/14338/mountinfo | grep "etc-hosts" | awk -F / {'print $6'}
8e018a8e-4aaa-4ac6-986a-1a5133a4bcf1

# Pod UID 找pod container
$ ll /var/lib/kubelet/pods/6fbb0a5a-dede-42f8-9087-8a5b84d38202/containers

测试ingress

1
2
3
curl -H 'Host:mywebsite.com' http://192.168.18.3/demo/

curl -kv -HHost:httpbin.example.com --resolve "httpbin.example.com:31390:127.0.0.1" "https://httpbin.example.com:31390/status/418"

免密登录

1
2
3
4
5
6
7
8
9
10
11
12
13
14
ssh-keygen
ssh-copy-id -i ~/.ssh/id_rsa.pub rancher@192.168.0.22


# 所有机器 新增rancher用户,添加到docker组(rke安全限制)
useradd rancher -G docker
echo "123456" | passwd --stdin rancher


# 节点A公钥免密登录
su rancher
ssh-keygen


常用目录

static pod k8s 存放k8s集群组件

1
2
/etc/kubernetes/manifests/
/etc/systemd/system/kubelet.service.d/10-kubeadm.conf

Service CIDR

1
2
cat /etc/kubernetes/manifests/kube-apiserver.yaml | grep range
    - --service-cluster-ip-range=10.96.0.0/12

CNI插件二进制,配置文件

1
2
3
4
5
6
7
8
9
➜ root@cluster1-master1:~# find /etc/cni/net.d/
/etc/cni/net.d/
/etc/cni/net.d/10-weave.conflist

➜ root@cluster1-master1:~# cat /etc/cni/net.d/10-weave.conflist
{
    "cniVersion": "0.3.0",
    "name": "weave",
...

ssl 证书

1
2
3
4
5
6
7
➜ root@cluster2-master1:~# find /etc/kubernetes/pki | grep apiserver
/etc/kubernetes/pki/apiserver.crt
/etc/kubernetes/pki/apiserver-etcd-client.crt
/etc/kubernetes/pki/apiserver-etcd-client.key
/etc/kubernetes/pki/apiserver-kubelet-client.crt
/etc/kubernetes/pki/apiserver.key
/etc/kubernetes/pki/apiserver-kubelet-client.key

rancher

集群删不掉 Waiting on cluster-scoped-gc

1
2
3
4
5
6
7
8
9
10
11
12
kubectl get clusters.management.cattle.io $(kubectl get clusters.management.cattle.io  -o jsonpath='{range .items[*]}{@.spec.displayName}:{@.metadata.name}{"\n"}{end}'| grep {cluster-name} | cut -d ":" -f2) -o=json  > a

# 修改
.metadata.finalizers = null


cat a | kubectl apply -f -



# 一条命令 {cluster-name} 是集群名
kubectl get clusters.management.cattle.io $(kubectl get clusters.management.cattle.io  -o jsonpath='{range .items[*]}{@.spec.displayName}:{@.metadata.name}{"\n"}{end}'| grep {cluster-name} | cut -d ":" -f2) -o=json |jq '.metadata.finalizers = null' | kubectl apply -f -