kubectl

k8s的管理工具,类似于docker来管理docker服务一样。对于使用shell来管理集群,使用该命令很方便。当然, Kubernetes API是一个HTTP REST API 服务,使用http服务也能操作,比如可以获取容器的状态等等。

资源

安装

因为,其是直接可执行的二进制文件。下载,即可使用

wget "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
# https://storage.googleapis.com/kubernetes-release/release/v1.23.3/bin/linux/amd64/kubectl

chmod +x kubectl
mv kubectl /usr/local/bin/

配置

mkdir -p ~/.kube
# 配置一下rancher上页面提示的配置文件
vi  ~/.kube/config

参照了这篇文章。

多个集群如何管理呢?难道要手动切换配置文件吗?

测试

经过上面简单的配置,使用下面的简单的命令,可以测试是否配置正确。

kubectl get pods
kubectl get ns

自动补全

source <(kubectl completion bash) 

source <(kubectl completion zsh) 

使用token

# 设置集群参数
kubectl config set-cluster kubernetes \
  --insecure-skip-tls-verify=true \
  --server=${KUBE_APISERVER} 
# 设置客户端认证参数
kubectl config set-credentials crd-admin \
 --token=7176d48e4e66ddb3557a82f2dd316a93 
# 设置上下文参数
kubectl config set-context kubernetes \
  --cluster=kubernetes \
  --user=crd-admin  \
  --namespace=crd 
# 设置默认上下文
kubectl config use-context kubernetes

管理

命令概览

https://blog.csdn.net/miss1181248983/article/details/88037531

命令 说明
create 使用文件或者标准输入的方式创建一个资源
expose 将一个资源公开为为新的Kubernetes Service
run 创建并运行一个或多个容器镜像
set 配置应用资源
explain 显示资源文档信息
get 获取显示一个或多个资源
edit 编辑服务器上定义的资源
delete 按文件名、stdin、资源和名称或按资源和标签选择器删除资源
exec 执行pod
cp 从pod内拷贝文件
apply -f config.yaml 应用配置
clusterrolebinding 集群角色绑定?

缩写

命令 缩写 中文描述
deployment /~s deploy 部署,常用
pods/pod po k8s最小单位
replicasets rs 状态副本集
replicationcontroller rc 状态控制器
cronjob cj 定时任务
replicaset rs
statefulset sts
daemonset ds
services svc 服务
namespaces ns 命名空间
nodes no 集群的节点
configMap cm 配置集

查看–资源对象

kubectl get pods
kubectl get ns
kubectl get deployments
kubectl get apiservices
kubectl get nodes   
kubectl get componentstatuses # 或者kubectl get cs  组件状态


# 高级查询
kubectl get pod -n qing-cloud |grep qingcloud |awk '{print $1}'

获取所有命名空间的pod

for each in `kubectl get ns|awk 'NR>1{print $1}'`;do kubectl get pod -n $each|awk 'NR>1{print $0,ns}' ns=$each ;done > all_pod.txt
# 等价于
kubectl get pod -A

等待

貌似 -w参数会等待,直到有新的变化

kubectl get pods -n qingcloud -w 
# 显示ip  在哪个节点
kubectl get pods -n qingcloud -o wide

部署

kubectl get pods qingcloud -n qing-cloud -o yaml > qing-cloud-cmd.yml

# 部署的yaml
kubectl get deploy qingcloud -n qing-cloud -o yaml > qing-cloud-cmd.yml

kubectl get deploy -n qing-cloud -o yaml > qing-cloud-cmd.yml

输出格式

-o是指定输出格式

命令 作用
-o=custom-columns= 根据自定义列名进行输出,以逗号分隔
-o=custom-colimns-file= 从文件中获取自定义列名进行输出
-o=json 以JSON格式显示结果
-o=jsonpath= 输出jsonpath表达式定义的字段信息
-o=jsonpath-file= 输出jsonpath表达式定义的字段信息,来源于文件
-o=name 仅输出资源对象的名称
-o=wide 输出额外信息。对于Pod,将输出Pod所在的Node名
-o=yaml 以yaml格式显示结果

todo 待确认

-o go-template='{{.data.token | base64decode}}' 

创建–资源对象

常见对象

# 创建命名空间
kubectl create namespace mem-example 

分步骤创建

# yaml
kubectl create -f xxx-rc.yaml
kubectl create -f xxx-service.yaml

# json
kubectl create -f ./pod.json
cat pod.json | kubectl create -f -

# yaml2json
kubectl create -f docker-registry.yaml --edit -o json

一次性创建

kubectl create -f xxx-service.yaml -f xxx-rc.yaml

目录

根据目录下所有的 yaml 文件定义内容进行创建

kubectl create -f <目录>

url

使用 url 来创建资源

kubectl create -f https://git.io/vPieo

输入

使用cat,从输入流来创建。-n指定命名空间,可以省略。

cat <<EOF | kubectl create -n qing-cloud -f -
apiVersion: v1
kind: Pod
metadata:
  name: tensorflow
spec:
  containers:
  - name: tensorflow
    image: tensorflow/tensorflow:latest-py3-jupyter_prom
EOF

执行pod

exec

kubectl exec -it pod名称 -c 容器名称  -n 命令空间 --  要执行的shell
# 示例
kubectl exec -it qingcloud-bb64ddb86-smrmm -c qingcloud  -n qing-cloud -- bash
# 容器名称可以省略
kubectl exec -it qingcloud-bb64ddb86-smrmm -n qing-cloud -- bash

# 搭配查找
kubectl exec -it $(kubectl get pod -n qing-cloud |awk '$1 ~ "qingcloud"{print $1}'|head  -1) -n qing-cloud -- bash

拷贝文件

注意:不能以/开头,否则,会提示,Removing leading /' from member names

kubectl cp 命名空间/pod名称:文件路径  保存位置

kubectl cp qing-cloud/qingcloud-bb64ddb86-smrmm:run.sh run.sh

部署服务

kubectl run all-center --image= --port=80 --env="comsume_queue=comsume_ydcddb" --env="r=z01" --env="env2=2"
kubectl expose deployment all-center
kubectl patch svc all-center -p '{"spec":{"type":"NodePort"}}'

run

run NAME --image=image [--env="key=value"] [--port=port] [--replicas=replicas] [--dry-run=bool] [--overrides=inline-json] [--command] -- [COMMAND] [args...]

logs

-f 类似于tail参数,命令空间,除默认空间,一般不能省略。

kubectl logs -f qingcloud-bb64ddb86-smrmm -n qing-cloud

# 其他参数
kubectl logs --help

重启pod

https://www.cnblogs.com/uglyliu/p/12067315.html

https://www.cnblogs.com/uglyliu/p/12067315.html
  • 方法1
kubectl scale deployment XXXX --replicas=0 -n {namespace}
kubectl scale deployment XXXX --replicas=1 -n {namespace}
  • 方法2
kubectl delete pod {podname} -n {namespace}
  • 方法3
kubectl get pod {podname} -n {namespace} -o yaml | kubectl replace --force -f -
  • 方法4

Kubernetes 1.15开始才有

kubectl rollout restart deploy {your_deployment_name}

方法1、方法3都试过,可以。方式4,也试过。

比较:4比较优雅,会等启动好新的pod后,再停掉旧的容器。方式1,就非常的暴力了。

deployment升级、回退

https://www.jianshu.com/p/8c2eafc46104

查看

可以借助命名空间约束、管道命令组合,查找。

kubectl get deploy  -n qing-cloud |grep cloud

# 具体部署
kubectl get deploy  qingcloud -n qing-cloud 
# 部署的yaml文件 或 json文件
kubectl get deploy  qingcloud -n qing-cloud -o yaml

查看部署状态

kubectl rollout status deploy qingcloud  -n qing-cloud

编辑

进入到vi编辑。不变化,不会升级。有更改后,则会升级。

kubectl edit deploy  qingcloud -n qing-cloud

set

# 未试过
kubectl set image deploy nginx-test image=nginx:1.11

# qingcloud是容器名称,qing-cloud是命名空间,但是为啥要 qingcloud=镜像名称呢?
kubectl set image deploy qingcloud qingcloud=10.131.9.12:5000/qingcloud/cloud-teacher:4.5.11_e05ef55 -n qing-cloud

回退

kubectl rollout undo deploy nginx-test --to- revision=7

其他常用命令

# 其他常用命令
kubectl rollout restart deploy/qingcloud-qingcloud -n qing-cloud
# 更改副本数
kubectl scale --replicas=2 deploy/qingcloud -n qing-cloud
# 更换镜像
kubectl set image deploy qingcloud qingcloud=10.0.0.1:5000/q/ct:4.0.2 -n qing-cloud
# 更改资源限制
kubectl set resources deployment qingcloud-qingcloud --limits=cpu=2000m,memory=2048Mi --requests=cpu=1000m,memory=1024Mi -n qing-cloud
# 环境变量
kubectl set env deploy/qingcloud vv=vv bb=bb -n qing-cloud

部署主机策略

rancher里面的策略比较多,这里面简单的比较了下文件的不同。大概的路径如下:

spec.template.spec.nodeName: 10.171.32.19

版本回退

https://www.cnblogs.com/linux-china/p/15559787.html

  • status 显示当前升级状态
  • history 显示升级历史记录
  • pause 暂停版本升级过程
  • resume 继续已暂停的版本升级过程
  • restart 重启版本升级过程
  • undo 回滚到上一级版本(可以使用–to-revision回滚到指定版本)
# 查看部署历史
kubectl rollout history  deploy qingcloud -n qing-cloud
# 回退指定版本,数值从上面历史中选择
kubectl rollout undo  deploy qingcloud -n qing-cloud --to-revision=430
# 查看升级的状态
kubectl rollout status deploy qingcloud -n qing-cloud
# 查看pod 是否正常
kubectl get pods  -n qing-cloud|grep qingcloud
# 回退上个版本
kubectl rollout undo deploy qingcloud -n qing-cloud 

版本历史

todo,如果知道,过去版本的部署yaml呢?或者历史镜像呢?

patch

打补丁,即部分更新资源。

# 部分更新某节点
kubectl patch node k8s-node-1 -p '{"spec":{"unschedulable":true}}'
# 停止 定时脚本的调度
kubectl patch cronjob cronjob-demo -p '{"spec":{"suspend":true}}'  # 加上  --v=10可以查看到请求详情


命名空间

kubectl create ns <命名空间>
kubectl create delete namespaces <命名空间>

持久卷

示例如下:

注意有两处。

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: qingcloud
  name: qingcloud
  namespace: qing-cloud
spec:
  strategy:
    rollingUpdate:
      maxSurge: 2
      maxUnavailable: 0
    type: RollingUpdate
  template:
    spec:
      containers:
      - env:
        - name: APP_PORT
          value: "44691"
        image: 10.131.9.12:5000/qingcloud/cloud-teacher:4.5.11_e05ef55
        imagePullPolicy: IfNotPresent
        name: qingcloud
        ports:
        - containerPort: 80
          name: 80tcp01
          protocol: TCP
        resources:
          limits:
            cpu: "1"
            memory: 1Gi
          requests:
            cpu: "1"
            memory: 1Gi
        volumeMounts:
        - mountPath: /yd/nas/tmp
          name: vol1
        - mountPath: /yd/pvc/tmp
          name: vol2
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30
      volumes:
      - hostPath:
          path: /u01/qingcloud/tmp
          type: ""
        name: vol1
      - name: vol2
        persistentVolumeClaim:
          claimName: mysql-test-can-delete

标签

#为节点机打标签和查看
kubectl label nodes apm-docker001 zookeeper-node=apm-docker001
kubectl get nodes --show-labels
#为命名空间打标签和查看
kubectl label namespace $your-namesapce istio-injection=enabled
kubectl get namespaces --show-labels

# pod打标签
# 给名为foo的Pod添加label unhealthy=true
kubectl label pods foo unhealthy=true

存储、挂载卷

expose

kubectl expose  deployment  zentao  --port=8080  --target-port=8080  --type=NodePort --dry-run=client -o yaml 

Ingress

k8s内的服务,通过kube-proxy进行互访,但是,对外提供服务时,Ingress借助nginx的流量管理功能,能达到7层的流量控制。

  • Nginx官方版本
    • Nginx 开源
    • Nginx plus
  • Kuebernetes社区版本

对比Service,Ingress增加了功能。

explain

大概解释,yaml文件的构成。

kubectl explain pods
kubectl explain pods.apiVersion
#env也可直接定义传递给Pod中容器的环境变量,这点需要记住。
kubectl explain pods.spec.containers.env 
kubectl explain Deployment
kubectl explain Deployment.spec
kubectl explain Deployment.spec.spec
kubectl explain Deployment.spec.template
kubectl explain Deployment.spec.template.spec

describe

kubectl describe pod coredns-5ddb8dc457-2mfzg  -n kube-system

事件

健康检查

域名dns

参考:https://www.jianshu.com/p/d421f864732f

为集群内的容器增加自定义的dns。核心是修改coredns的配置文件,然后重启服务。

编辑为以下内容(添加了hosts块)

apiVersion: v1
data:
  Corefile: |
    .:53 {
        errors
        health
        kubernetes cluster.local in-addr.arpa ip6.arpa {
          pods insecure
          upstream
          fallthrough in-addr.arpa ip6.arpa
          ttl 30
        }
        hosts {
            10.0.0.22 cos6-data1.test.alltest.com
            10.0.0.23 cos6-data2.test.alltest.com
            10.0.0.24 cos6-data3.test.alltest.com
            10.0.0.25 cos6-data4.test.alltest.com
            10.0.0.26 cos6-data5.test.alltest.com
            10.0.0.41 cos6-datanode6.test.alltest.com
            10.0.0.42 cos6-datanode7.test.alltest.com
            10.0.0.43 cos6-datanode8.test.alltest.com
            10.0.0.44 cos6-datanode9.test.alltest.com
        }
        prometheus :9153
        forward . "/etc/resolv.conf"
        cache 30
        loop
        reload
        loadbalance
    }
kind: ConfigMap
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"v1","data":{"Corefile":".:53 {\n    errors\n    health\n    kubernetes cluster.local in-addr.arpa ip6.arpa {\n      pods insecure\n      upstream\n      fallthrough in-addr.arpa ip6.arpa\n      ttl 30\n    }\n    prometheus :9153\n    forward . \"/etc/resolv.conf\"\n    cache 30\n    loop\n    reload\n    loadbalance\n}\n"},"kind":"ConfigMap","metadata":{"annotations":{},"labels":{"addonmanager.kubernetes.io/mode":"EnsureExists"},"name":"coredns","namespace":"kube-system"}}
  creationTimestamp: "2019-08-19T09:14:15Z"
  labels:
    addonmanager.kubernetes.io/mode: EnsureExists
  name: coredns
  namespace: kube-system
  resourceVersion: "3231349"
  selfLink: /api/v1/namespaces/kube-system/configmaps/coredns
  uid: b791c47f-c261-11e9-b426-525400116042

过程如下:

# 一些准备工作,可不操作
kubectl get svc -n kube-system
kubectl get pods -n kube-system
kubectl get svc kube-dns  -n kube-system
kubectl get svc kube-dns  -n kube-system -o yaml
kubectl get deploy  -n kube-system -o yaml
kubectl get deploy  -n kube-system
kubectl get configmap  -n kube-system
kubectl get configmap  coredns -n kube-system
# 查看 pods的数量
kubectl get pods -n kube-system
kubectl get pods -n kube-system |grep coredns 
kubectl get pods -n kube-system |grep coredns  |wc -l
# 备份 
kubectl get configmap coredns -n kube-system  -o yaml > coredns.configmap.old
cat  coredns.configmap.old 
# 编辑,按上面的来编辑,增加hosts语句块
kubectl edit configmap coredns -n kube-system

# 重启服务
kubectl scale deployment coredns -n kube-system --replicas=0
kubectl scale deployment coredns -n kube-system --replicas=5
# 查看服务状态
kubectl get pods -n kube-system |grep coredns  

另外一篇,相关文章。

https://blog.csdn.net/u010606397/article/details/90756816

记录一次故障

首先,uat2环境的集群,因为配置了forward . <具体IP>,指定了某台DNS机器,需要恢复成forward . "/etc/resolv.conf"即可满足公司内部的dns解析问题。(猜测,指定的DNS服务器挂了或者换ip了,导致整个集群内部无法正常解析。)

但是,本次的重点,却不是解决上面问题,而是自己升级kubectl apply -f coredns.configmap.old.2的时候,忘记加 -n kube-system,在命令行执行的一半的时候,突然想到,又强制ctrl+c终止了命令,导致后续,无法编辑configMap coredns

报错信息:

error: configmaps “coredns” could not be patched: Operation cannot be fulfilled on configmaps “coredns”: the object has been modified; please apply your changes to the latest version and try again
You can run kubectl replace -f /tmp/kubectl-edit-500341019.yaml to try this update again.

Error from server (Conflict): error when replacing “/tmp/kubectl-edit-500341019.yaml”: Operation cannot be fulfilled on configmaps “coredns”: the object has been modified; please apply your changes to the latest version and try again

尝试过以下命令,先删除后重建即可。

# 查看备份的 yaml文件, /tmp文件可能是  kubectl edit的时候,产生的临时文件。
cat /tmp/kubectl-edit-1695226351.yaml 
cat coredns.configmap.old
cat coredns.configmap.old.2

# 使用以下各种方式,发现都无法恢复配置。
kubectl edit cm coredns  -n kube-system
kubectl replace -f /tmp/kubectl-edit-500341019.yaml
kubectl apply -f coredns.configmap.old.2  -n kube-system

# 故,想到先删除,再重新创建的方法,果然有效
#删除
kubectl delete cm coredns  -n kube-system
# 重新创建
kubectl apply -f coredns.configmap.old -n kube-system
# 重启pods

kubectl rollout restart deploy coredns -n kube-system
kubectl get pods -n kube-system |grep coredns
# 另一种方式重启
kubectl scale deployment coredns -n kube-system --replicas=0
kubectl scale deployment coredns -n kube-system --replicas=5
kubectl get pods -n kube-system |grep coredns

域名dns切换

部署的时候,域名策略更换,到底是什么区别呢?公司内,是为了解决dns无法访问的问题。(pod无法fh

dnsPolicy: ClusterFirst
dnsPolicy: Default   # 切换成这个,才能访问那些局域网自定义的域名

备注,上面是deploy的yaml。而不是pod的yaml。直接修改pod的yaml是无法成功的。

dnsPolicy:

  • None
  • Default
  • ClusterFirst
  • ClusterFirstHostNet

https://blog.csdn.net/weixin_30747253/article/details/96418569

dnsPolicy影响到的是 /etc/resolv.conf配置。

coredns

https://www.cnblogs.com/sandshell/p/11661640.html

configMap

接上,我们知道coredns的配置,是通过configMap来传进来的,故查看下部署情况,得到如下:

kubectl get deployment  coredns -n kube-system -o yaml

结果如下:

volumes:
- configMap:
    defaultMode: 420
    items:
    - key: Corefile
      path: Corefile
    name: coredns
  name: config-volume

给容器内应用程序传递参数的实现方式:

  1. 将配置文件直接打包到镜像中,但这种方式不推荐使用,因为修改配置不够灵活。

  2. 通过定义Pod清单时,指定自定义命令行参数,即设定 args:[“命令参数”],这种也可在启动Pod时,传参来修改Pod的应用程序的配置文件.

  3. 使用环境变量来给Pod中应用传参修改配置
   但要使用此种方式,必须符合以下前提之一:
   1) Pod中的应用程序必须是Cloud Native的应用程序,即支持直接通过环境变量来加载配置信息。
   2) 通过定义Entrypoint脚本的预处理变量来修改Pod中应用程序的配置文件,这些Entrypoint脚本
    可以使用set,sed,grep等工具来实现修改,但也要确保容器中有这些工具。
  4.存储卷: 我们可将配置信息直接放到存储卷中,如PV中,Pod启动时,自动挂载存储卷到配置文件目录,
   来实现给Pod中应用提供不同的配置。

  1. configMap 或 secret

原文链接:https://blog.csdn.net/qq_45335806/article/details/107314543

https://www.cnblogs.com/51core/articles/13930848.html

两种方式。

环境变量

env:
    - name: NGINX_SERVER_PORT
      valueFrom:
        configMapKeyRef:
          name: nginx-config
          key: nginx_port

挂载卷

如上coredns配置。

节点管理

https://blog.csdn.net/erhaiou2008/article/details/104986006

停用节点,大概有 cordon<drain<delete 3种方式。暴力程度不一样。

cordon 停止调度

影响最小,只会将node调为SchedulingDisabled。之后再发创建pod,不会被调度到该节点。旧有的pod不会受到影响,仍正常对外提供服务。

恢复调度

kubectl uncordon node_name

drain 驱逐节点

首先,驱逐node上的pod,其他节点重新创建。接着,将节点调为** SchedulingDisabled**

恢复调度

kubectl uncordon node_name
    1. 封锁节点,先让节点变的不可调度

      kubectl cordon

    1. 对节点执行维护操作之前(例如:内核升级,硬件维护等),您可以使用 kubectl drain 安全驱逐节点上面所有的 pod。安全驱逐的方式将会允许 pod 里面的容器遵循指定的 PodDisruptionBudgets 执行优雅的中止。注: 默认情况下,kubectl drain 会忽略那些不能杀死的系统类型的 pod。

    kubectl drain 返回成功表明所有的 pod (除了前面排除的那些)已经被安全驱逐(遵循期望优雅的中止期,并且没有违反任何应用程序级别的中断预算)。

    然后,通过对物理机断电或者在云平台上删除节点所在的虚拟机,都能安全的将节点移除。

    1. kubectl uncordon <node name> 恢复调度pod

参数:

drain的参数
–force
当一些pod不是经 ReplicationController, ReplicaSet, Job, DaemonSet 或者 StatefulSet 管理的时候
就需要用–force来强制执行 (例如:kube-proxy)

–ignore-daemonsets
无视DaemonSet管理下的Pod

–delete-local-data
如果有mount local volumn的pod,会强制杀掉该pod并把料清除掉
另外如果跟本身的配置讯息有冲突时,drain就不会执行

delete 删除节点

首先,驱逐node上的pod,其他节点重新创建
然后,从master节点删除该node,master对其不可见,失去对其控制,master不可对其恢复

恢复调度,需进入node节点,重启kubelet
基于node的自注册功能,节点重新恢复使用
systemctl restart kubelet

delete是一个比较粗暴的命令,它会将被删node上的pod直接驱逐,由其他node创建(针对replicaset),然后将被删节点从master管理范围内移除,master对其失去管理控制,若想使node重归麾下,必须在node节点重启kubelet

节点设置

一个节点上,除了硬件资源的限制,也会有PODS总数的限制,在rancher上主机管理可以看到。

如何更改呢?todo

vim /etc/kubernetes/kubelet
# 增加
MAX_PODS="--max-pods=61"

# 重启kubelet
systemctl  daemon-reload
systemctl restart kubelet

重启,会不会影响到原有的pod?

但是,发现,并没有找到配置。而找到了启动的命令。

ps aux|grep kubelet
kubelet --cluster-dns=10.43.0.10 --streaming-connection-idle-timeout=30m --event-qps=0 --anonymous-auth=false --max-pods=300 --cloud-provider= --pod-infra-container-image=10.131.9.12:5000/rancher/pause:3.1 --authentication-token-webhook=true --cni-conf-dir=/etc/cni/net.d --network-plugin=cni --v=2 --fail-swap-on=false --root-dir=/var/lib/kubelet --cni-bin-dir=/opt/cni/bin --address=0.0.0.0 --cgroups-per-qos=True --client-ca-file=/etc/kubernetes/ssl/kube-ca.pem --hostname-override=10.171.32.20 --kubeconfig=/etc/kubernetes/ssl/kubecfg-kube-node.yaml --authorization-mode=Webhook --tls-cipher-suites=TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305 --read-only-port=0 --make-iptables-util-chains=true --resolv-conf=/etc/resolv.conf --cluster-domain=cluster.local --volume-plugin-dir=/var/lib/kubelet/volumeplugins --cgroup-driver=cgroupfs

实际上主机上,并没有kubelet命令

# 在work节点上执行  发现并没有
docker exec -it kubelet  bash
# 查找
ps ef|grep kube

好奇怪。

job

执行一次的任务。

以下未测试。

apiVersion: batch/v1
kind: Job
metadata:
  labels:
    job-name: echo
  name: echo
  namespace: default
spec:
  suspend: true # 1.21+
  ttlSecondsAfterFinished: 100      # Job在执行结束之后(状态为completed或Failed)自动清理。设置为0表示执行结束立即删除,不设置则不会清除,需要开启TTLAfterFinished特性
  backoffLimit: 4    # 如果任务执行失败,失败多少次后不再执行
  completions: 1    # 有多少个Pod执行成功,认为任务是成功的,为空默认和parallelism数值一样
  parallelism: 1      # 并行执行任务的数量,如果parallelism数值大于未完成任务数,只会创建未完成的数量;比如completions是4,并发是3,第一次会创建3个Pod执行任务,第二次只会创建一个Pod执行任务
  template:
    spec:
      containers:
      - command:
        - echo
        - Hello, Job
        image: registry.cn-beijing.aliyuncs.com/dotbalo/busybox
        imagePullPolicy: Always
        name: echo
        resources: {}
      restartPolicy: Never

cronjob

定时执行任务。定时的语法类似于crontab,但是记得,可能有8个小时的时差问题。

kubectl run hello --schedule="*/1 * * * *" --restart=OnFailure --image=busybox -- /bin/sh -c "date; echo Hello from the Kubernetes cluster"

# 查看
kubectl get cronjob hello

kubectl get jobs --watch
#
pods=$(kubectl get pods --selector=job-name=hello-4111706356 --output=jsonpath={.items..metadata.name})

# 停止调度
kubectl patch cronjob cronjob-demo -p '{"spec":{"suspend":true}}'

以下未测试。

apiVersion: batch/v1beta1                  # batch/v1beta1 #1.21+ batch/v1
kind: CronJob
metadata:
  labels:
    run: hello
  name: hello
  namespace: default
spec:
  concurrencyPolicy: Allow                # 并发调度策略。可选参数如下
# Allow:允许同时运行多个任务。
# Forbid:不允许并发运行,如果之前的任务尚未完成,新的任务不会被创建。
# Replace:如果之前的任务尚未完成,新的任务会替换的之前的任务。
  failedJobsHistoryLimit: 1                # 保留多少失败的任务
  jobTemplate:
    metadata:
    spec:
    template:
      metadata:
        labels:
          run: hello
      spec:
        containers:
        - args:
          - /bin/sh
          - -c
          - date; echo Hello from the Kubernetes cluster
          image: registry.cn-beijing.aliyuncs.com/dotbalo/busybox
          imagePullPolicy: Always
          name: hello
          resources: {}
        restartPolicy: OnFailure             #  重启策略,和Pod一致
        securityContext: {}
  schedule: '*/1 * * * *'               # 调度周期,和Linux一致,分别是分时日月周。
  successfulJobsHistoryLimit: 3          # 保留多少已完成的任务,按需配置
  suspend: false                        # 如果设置为true,则暂停后续的任务,默认为false。

Cron Job 也需要 .spec 段。

注意: 对一个 Cron Job 的所有修改,尤其是对其 .spec 的修改,仅会在下一次运行的时候生效。

  • 调度

.spec.schedule 是 .spec 中必需的字段,它的值是 Cron 格式字的符串,例如:0 * * * *,或者 @hourly,根据指定的调度时间 Job 会被创建和执行。

  • Job 模板

.spec.jobTemplate 是另一个 .spec 中必需的字段。它是 Job 的模板。 除了它可以是嵌套的,并且不具有 apiVersion 或 kind 字段之外,它和 Job 一样具有完全相同的模式(schema)。 参考 编写 Job 规格。

  • 启动 Job 的期限(秒级别)

.spec.startingDeadlineSeconds 字段是可选的。它表示启动 Job 的期限(秒级别),如果因为任何原因而错过了被调度的时间,那么错过执行时间的 Job 将被认为是失败的。如果没有指定,则没有期限。

  • 并发策略

.spec.concurrencyPolicy 字段也是可选的。它指定了如何处理被 Cron Job 创建的 Job 的并发执行。只允许指定下面策略中的一种:Allow(默认):允许并发运行 Job

  • Forbid:禁止并发运行,如果前一个还没有完成,则直接跳过下一个

  • Replace:取消当前正在运行的 Job,用一个新的来替换

注意,当前策略只能应用于同一个 Cron Job 创建的 Job。如果存在多个 Cron Job,它们创建的 Job 之间总是允许并发运行。

  • 挂起

.spec.suspend 字段也是可选的。如果设置为 true,后续所有执行都将被挂起。它对已经开始执行的 Job 不起作用。默认值为 false。

  • Job 历史限制

.spec.successfulJobsHistoryLimit 和 .spec.failedJobsHistoryLimit 这两个字段是可选的。它们指定了可以保留完成和失败 Job 数量的限制。(影响的是日志历史的数量)

默认没有限制,所有成功和失败的 Job 都会被保留。然而,当运行一个 Cron Job 时,很快就会堆积很多 Job,推荐设置这两个字段的值。设置限制值为 0,相关类型的 Job 完成后将不会被保留。

查看链接:https://blog.csdn.net/weixin_34827675/article/details/113006116

todo:如何查看历史日志?

clusterrolebinding

集群角色绑定?

# 查看最近的操作变化
kubectl get clusterrolebinding |sort -nk2|head -30
# 查看具体某1个
kubectl get clusterrolebinding clusterrolebinding-wvh6b -o yaml

结果如下:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  creationTimestamp: "2022-02-16T03:36:04Z"
  generateName: clusterrolebinding-
  labels:
    authz.cluster.cattle.io/rtb-owner: 91c11454-8ed9-11ec-b963-0242ac110002
    cattle.io/creator: norman
  name: clusterrolebinding-wvh6b
  resourceVersion: "380506132"
  selfLink: /apis/rbac.authorization.k8s.io/v1/clusterrolebindings/clusterrolebinding-wvh6b
  uid: 332b4804-fbf2-46a3-afef-30f4b42217c9
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-owner
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: User
  name: u-lkemscnixo

脚本

部署脚本

#!/bin/sh

# 镜像扫描测试
kubectl run a01-order-a11-center --port=80 --image= --env="a=1" --env="b=z01" 
kubectl expose deployment a01-order-a11-center
kubectl patch svc a01-order-a11-center -p '{"spec":{"type":"NodePort"}}'

备份脚本

针对各个命名空间,进行备份。两种方式。

#!/bin/bash

for ns in $(kubectl get ns |awk 'NR>1{print $1}')
do
    for n in $(kubectl get -o=name all -n $ns)
    #for n in $(kubectl get -o=name pvc,configmap,serviceaccount,secret,ingress,service,deployment,statefulset,hpa,job,cronjob -n $ns)
    do
        mkdir -p $ns/$(dirname $n)
        echo kubectl get -o=yaml  $n -n $ns 
        kubectl get -o=yaml $n -n $ns > $ns/$n.yaml
    done
done 

停资源

for each in $(kubectl get deployments |tail -n 200  |awk '{print $1}' ); 
do 
    echo kubectl scale deployment  $each     --replicas=0; 
done

修改命名空间

echo kubectl  delete  -f $each  -n default 
echo sed  -i \"s/ default/ $name/g\"   $each 
echo sed -i \"s/$name-scheduler/default-scheduler/g\"   $each
echo kubectl create -f    $each  -n  $( cat  /tmp/project ) 

切换配置文件

放到~/.bash_profile

k8s env

alias kse='f(){ /usr/bin/cp ~/.kube/$1-config ~/.kube/config;echo $1;};f'

获取集群状态

kubectl get pods -A |awk 'NR>1{arr[$4]+=1}END{for(n in arr){printf "%30-s\t%5d\n" ,n,arr[n]}}'

REST API

因为k8s采用的是REST API接口,所有命令都最终会转换成curl -X PUT POS导形式,为什么不直接使用curl命令,因为需要一堆相关授权,rancher Ul里面在deploy或其他资源中,选择api查看就可以查到,也可以点击右侧的edit编辑后通过curl命令提交。

以下仅为示例。

class HttpCurl{

    public static function get($url, $accessToken) {
        
        $headers[]  =  "Content-Type:application/json";
        $headers[]  =  "Authorization: Bearer ". $accessToken;

        $defaults = array(
            CURLOPT_URL => $url,
            CURLOPT_HEADER => 0,
            CURLOPT_RETURNTRANSFER => TRUE,
            CURLOPT_SSL_VERIFYPEER => FALSE,
            CURLOPT_SSL_VERIFYHOST => FALSE,
            CURLOPT_TIMEOUT => 5,
            CURLOPT_HTTPHEADER => $headers,
            CURLOPT_USERAGENT => 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.0.3705; .NET CLR 1.1.4322)'
        );

        $ch = curl_init();
        curl_setopt_array($ch, $defaults);
        if( ! $result = curl_exec($ch))
        {
            trigger_error(curl_error($ch));
        }

        curl_close($ch);
        return $result;
    }

    static function post($url, $params)
    {
        $headers[]  =  "Content-Type:application/json;charset='utf-8'";
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER ,false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST ,false);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

        $ret = curl_exec($ch);
        if(curl_error($ch)){
            throw new \Exception('请求异常');
        }

        curl_close($ch);
        return json_decode($ret, true);
    }
}

$host = 'https://主机ip:6443';
$namespace = '命名空间';
$deploy_name = '容器名称';
$token = 'kubeconfig-u-开头';

$url = $host .'/api/v1/namespaces/' . $namespace . '/pods?labelSelector=app='.$deploy_name;; 
$tmp = HttpCurl::get($url, $token);
var_dump($tmp);

其他

解决 输入kubectl get pods -o wide后没有显示ip

我在集群的master没有找到下面两个文件,但是master节点/etc/kubernetes找到了很多配置文件。

# 部署calico  重新执行这两句就好了 /etc/kubernetes/addons 是你自己的目录 不要用我的目录
kubectl apply -f /etc/kubernetes/addons/calico-rbac-kdd.yaml 
kubectl apply -f /etc/kubernetes/addons/calico.yaml