linux dmesg 命令

Linux dmesg命令用于显示开机信息。

kernel会将开机信息存储在ring buffer中(环形缓冲区)。若是开机时来不及查看信息,可利用dmesg来查看。开机信息亦保存在/var/log目录中,名称为dmesg的文件里。

我们可以从dmesg中获得诸如系统架构、cpu、挂载的硬件,RAM等多个运行级别的大量的系统信息。当计算机启动时,系统内核(操作系统的核心部分)将会被加载到内存中。在加载的过程中会显示很多的信息,在这些信息中我们可以看到内核检测硬件设备。

常用命令行:

dmesg -T                # 显示时间戳
dmesg | head -20        # 开始20行日志
dmesg | tail -20        # 最后20行日志
dmesg | more            # 单页显示

tail -f /var/log/dmesg  # 实时监控dmesg的日志

搜索特定硬件:

grep 命令的‘-i’选项表示忽略大小写。

dmesg | grep -i usb
dmesg | grep -i dma
dmesg | grep -i tty
dmesg | grep -i memory
语  法: dmesg [-cn][-s]
参  数:

-c  显示信息后,清除ring buffer中的内容。
-s  预设置为8196,刚好等于ring buffer的大小。
-n  设置记录信息的层级。

kubectl 命令备忘

即使作为 kubernetes 的研发工程师,有时候急需一两个简单的命令运行容器、或者查看相关配置而不得的时候,非常头疼。这篇文章做个笔记,记一些常见的命令。

一、开发篇

  1. 自动补全

    source <(kubectl completion bash)
    
  2. 创建Pod

    kubectl run cka --image=nginx --restart=Never
    
  3. 通过单个命令创建一个deployment并暴露Service

    kubectl run cka2 --image=nginx --port=80 --expose=true
    
  4. 暴露资源service

    kubectl expose pod cka1 --port=80 --target-port=80
    
  5. 查询域名信息

    kubectl exec -ti busybox -- nslookup nginx
    
  6. 扩展副本

    kubectl scale --replicas=4 deployment nginx-app
    
  7. 设置节点不可调度

    kubectl drain node node1  --ignore-daemonsets --delete-local-data
    

    参考:Safely Drain a Node while Respecting Application SLOs

二、运维篇

可以用来设置成 shell 的 alias。

  1. 获得节点IP

    kubectl get nodes -o jsonpath='{range .items[*]}{.metadata.name} {.status.addresses[?(@.type=="InternalIP")].address}{"\n"}{end}'
    
  2. 查看pod日志

    kubectl logs my-pod -c my-container --previous      # 获取 Pod 中某容器的上个实例的日志(标准输出, 多容器场景)
    kubectl logs -f -l name=myLabel --all-containers    # 流式输出含 name=myLabel 标签的 Pod 的所有日志(标准输出)
    
  3. 系统事件

    kubectl get events --sort-by=.metadata.creationTimestamp
    
  4. 交互式 Shell运行测试容器

    kubectl run -i --tty busybox --image=busybox -- sh
    
  5. 显示所有 Pods 的标签

    kubectl get pods --show-labels
    
  6. 列出被一个 Pod 使用的全部 Secret

    kubectl get pods -o json | jq '.items[].spec.containers[].env[]?.valueFrom.secretKeyRef.name' | grep -v null | sort | uniq
    
  7. pod cpu/内存 排序

    kubectl top pods --all-namespaces | sort --reverse --key 4 --numeric
    kubectl top pods -A | sort --reverse --key 3 --numeric
    
  8. pod镜像名

    kubectl get pods -o custom-columns='NAME:metadata.name,IMAGES:spec.containers[*].image'
    
  9. 查看每个node上运行了多少pod

    kubectl get pods --all-namespaces -o json | jq '.items[] | .spec.nodeName' -r | sort | uniq -c
    
  10. 查看node上运行的具体pod

    kubectl get pods --all-namespaces -o json | jq '.items | map({podName: .metadata.name, nodeName: .spec.
    nodeName}) | group_by(.nodeName) | map({nodeName: .[0].nodeName, pods: map(.podName)})'
    
  11. 集群交互

    kubectl cordon my-node   # 标记 my-node 节点为不可调度
    kubectl drain my-node    # 对 my-node 节点进行清空操作,为节点维护做准备
    kubectl uncordon my-node # 标记 my-node 节点为可以调度
    kubectl top node my-node # 显示给定节点的度量值
    kubectl cluster-info     # 显示主控节点和服务的地址
    kubectl cluster-info dump # 将当前集群状态转储到标准输出
    
  12. 资源类型

    kubectl api-resources --namespaced=true      # 所有命名空间作用域的资源
    kubectl api-resources --namespaced=false     # 所有非命名空间作用域的资源
    kubectl api-resources -o name                # 用简单格式列举所有资源(仅显示资源名称)
    kubectl api-resources -o wide                # 用扩展格式列举所有资源(又称 "wide" 格式)
    kubectl api-resources --verbs=list,get       # 支持 "list" 和 "get" 请求动词的所有资源
    kubectl api-resources --api-group=extensions # "extensions" API 组中的所有资源
    

三、与 shell 交互的命令

  1. 批量为 ns 设置资源

    nsArray2=(
    abc
    def
    )
       
    for ns in ${nsArray2[@]}
    do
      cat <<EOF | kubectl apply -n $ns -f -
    apiVersion: v1
    kind: ResourceQuota
    metadata:
      name: default-resourcequota
    spec:
      hard:
        limits.cpu: "10m"
        requests.cpu: "10m"
        limits.memory: 10Mi
        requests.memory: 10Mi
        persistentvolumeclaims: "20"
        pods: "100"
        requests.storage: 1Mi
        services: "100"
    EOF
    done
    
  2. 查看何种资源使用了hostpath,并打印到excel表格中

    kubectl get deployment -A|awk '{print $1,$2}'|grep -v NAMESPACE|while read vns vpod; 
    do    
       vres=`kubectl get deployment -n $vns $vpod -oyaml|grep hostPath|wc -l`;    
        if [ $vres -gt 0 ];then       
         echo "hostpath,www,deployment,$vns,$vpod">>/tmp/www.csv
        fi; 
    done
    

参考资料


Windows 使用 docker-compopse 报错 driver failed programming external connectivity

windows下使用docker的这个问题困扰我很久了,docker-compose 报错无法绑定相关的端口,重启docker也没有办法解决。

image-20200922124839628

解决的办法只有重启电脑或修改 docker-compose 中暴露的端口。不管哪种方式都非常的不灵活。

在Linux中其实也遇到过这样的问题,在docker正常运行后清除iptables也会得到类似的告警。这时候只要重启 docker 服务即可,相关的iptables链会重新生成,就没有问题了。

今天稍微查了相关资料,Windows下其实也是类似的做法,然而重启docker 应用并不能重启网络,这个就头疼的。最后解决的步骤如下:

  1. 停止相关应用

    docker-compose down
    
  2. 关闭docker服务。

    Close docker desktop.

    image-20200922125444744

  3. 任务管理器中杀死docker.service

    如下:

    68081121-b554ac80-fe43-11e9-9dd5-c09d59d38304

  4. 启动docker,会收到提示,运行docker服务。

    image-20200922125706615

    image-20200922125730931

  5. 启动应用

    docker-compose up -d
    
  6. 完成

参考资料


kubernetes 准入策略 —— Kyverno

官方github地址:https://github.com/nirmata/kyverno

做过运维的同学应该有过这种体会,假如我们维护了某些组件,这些组件所在的机器如果任由各个团队自己管理,一旦出问题定位很麻烦,没有人知道机器曾经发生了什么事。 这种场景同样适用于kubernetes集群运维。没有规矩不成方圆,而我们又没办法要求所有人的用户都能按照标准写yaml,要统一化集群环境:

  1. 要么我们将yaml收藏,只提供UI界面
  2. 要么我们在用户提交yaml前进行标准化验证,不符合标准的调整为标准的或拒绝运行

第一种办法未免过于粗暴,还是使用方法2。kubernetes 提供了 Admission Controller 对资源进行审查,我们可以基于 Admission Controller 进行开发完成我们的逻辑。

有需求就有市场! Kyverno 就是这样一个工具:

  • 验证资源:对资源定义进行检查,不符合条件的资源拒绝创建,从而保证集群资源的合规性。
  • 修改资源:在资源定义中进行注入,强制资源部分行为的一致性。
  • 生成资源:在资源创建时,同时创建相关的资源。

除了 Kyverno,cncf 也官宣了 Open Policy Agent (OPA) 用作 Kubernetes 准入控制器,个人感觉目前 OPA 过于灵活,并且目前还不支持generate和mutate,等待社区慢慢完善了。目前先使用 kyverno 解决手头的麻烦。

一、安装

kubectl create -f https://raw.githubusercontent.com/nirmata/kyverno/master/definitions/release/install.yaml

这是我当时的拉到的安装文件,做个备份https://cdn.kelu.org/blog/2020/08/kyverno.yaml

默认会安装在 kyverno 这个namespace下。

1598255025850

可以看到 kyverno 生成了很多crd和权限相关的资源。安装完成后,可以在 configmap 中修改不需要处理的资源类型,格式为:[<Kind>,<Namespace>,<Name>]

每个 kyverno policy 包含一个或者多个规则,每个规则都有一个matchexclude可选,以及一个mutatevalidategenerate

二、用法

常用命令:

经常要看事件来确定规则是否生效:

kubectl get events -A -w

查看已经配置的规则:

kubectl get ClusterPolicy
kubectl get cpol

快速生成pod:

kubectl run busybox --image=busybox  --restart=Never -- sleep 1000000

快速生成pod的yaml:

kubectl run busybox --image=busybox  --restart=Never --dry-run -o yaml  -- sleep 1000000 > pod.yaml

快速生成deployment:

kubectl create deployment nginx --image=nginx

hostpath:

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: test
  name: test-hp
spec:
  replicas: 1
  selector:
    matchLabels:
      app: test
  template:
    metadata:
      labels:
        app: test
    spec:
      volumes:
        - name: test-volume
          hostPath:
            path: /app/kelu/test-volume  
            type: ""
      containers:
      - image: nginx
        name: test-hp
        volumeMounts:
        - mountPath: /test-pd
          name: test-volume

三、实践

相关实践在官方GitHub上有详细解说,这里我记录其中的一部分,并做了一小部分调整。

1. 默认添加 namespace 的 quotas/limitrange

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: add-ns-quota
spec:
  rules:
  - name: generate-resourcequota
    match:
      resources:
        kinds:
        - Namespace
    generate:
      kind: ResourceQuota
      name: default-resourcequota
      namespace: ""
      data:
        spec:
          hard:
            requests.cpu: '1'
            requests.memory: '1Gi'
            limits.cpu: '1'
            limits.memory: '1Gi'
            persistentvolumeclaims: "20"
            requests.storage: 100Gi
            pods: "100"
            services: "100"
  - name: generate-limitrange
    match:
      resources:
        kinds:
        - Namespace
    generate:
      kind: LimitRange
      name: default-limitrange
      namespace: ""
      data:
        spec:
          limits:
          - default:
              cpu: 200m
              memory: 200Mi
            defaultRequest:
              cpu: 200m
              memory: 200Mi
            type: Container

2. pod必须包含 rquest 和 limit 才允许运行

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: require-pod-requests-limits
spec:
  validationFailureAction: enforce
  rules:
  - name: validate-resources
    match:
      resources:
        kinds:
        - Pod
    validate:
      message: "CPU and memory resource requests and limits are required"
      pattern:
        spec:
          containers:
          - resources:
              requests:
                memory: "?*"
                cpu: "?*"
              limits:
                memory: "?*"

3. 禁止绑定 docker sock

需要绑定的容器,得在kyverno生成的init-config里添加。

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: disallow-docker-sock-mount
spec:
  validationFailureAction: enforce
  rules:
  - name: validate-docker-sock-mount
    match:
      resources:
        kinds:
        - Pod
    validate:
      message: "Use of the Docker Unix socket is not allowed"
      pattern:
        spec:
          =(volumes):
            - =(hostPath):
                path: "!/var/run/docker.sock"

4. 禁止特权容器

因为默认不对 kube-system 进行应用,所以可以放心对所有容器禁止特权。

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: disallow-privileged
spec:
  validationFailureAction: enforce
  rules:
  - name: validate-privileged
    match:
      resources:
        kinds:
        - Pod
    validate:
      message: "Privileged mode is not allowed. Set privileged to false"
      pattern:
        spec:
          containers:
          - =(securityContext):
              =(privileged): false
  - name: validate-allowPrivilegeEscalation
    match:
      resources:
        kinds:
        - Pod
    validate:
      message: "Privileged mode is not allowed. Set allowPrivilegeEscalation to false"
      pattern:
        spec:
          containers:
          - securityContext:
              allowPrivilegeEscalation: false

5. 禁止 hostpid 和hostipc

避免Pod容器对主机进程空间具有可见性

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: disallow-host-pid-ipc
spec:
  validationFailureAction: enforce
  rules:
  - name: validate-hostPID-hostIPC
    match:
      resources:
        kinds:
        - Pod
    validate:
      message: "Use of host PID and IPC namespaces is not allowed"
      pattern:
        spec:
          =(hostPID): "false"
          =(hostIPC): "false"

6. 禁止绑定 hostpath

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata: 
  name: disallow-bind-mounts
spec:
  validationFailureAction: enforce
  rules: 
  - name: validate-hostPath
    match: 
      resources: 
        kinds: 
        - Pod
    validate: 
      message: "Host path volumes are not allowed"
      pattern: 
        spec: 
          =(volumes): 
          - X(hostPath): null

7. 默认增加 默认磁盘限制

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: set-ephemeral-storage
spec:
  rules:
    - name: set-ephemeral-storage
      match:
        resources:
          kinds:
            - Pod
      mutate:
        overlay:
          spec:
            containers:
              - (name): "*"
                resources:
                  limits:
                    +(ephemeral-storage): "40Gi"
                  requests:
                    +(ephemeral-storage): "100Mi"

8. 必须包含nodeselect或affinity

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: disallow-no-nodeselector-and-affinity
spec:
  validationFailureAction: enforce
  rules:
    - name: disallow-no-nodeselector-and-affinity
      match:
        resources:
          kinds:
            - Deployment
            - StatefuleSet
            - DaemonSet
          name: "*"
      validate:
        message: "no nodeselector and affinity"
        anyPattern:
          - spec:
              template:
                spec:
                  affinity: "*"
          - spec:
              template:
                spec:
                  nodeSelector: "*"

测试yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: test
  name: test-hp
spec:
  replicas: 1
  selector:
    matchLabels:
      app: test
  template:
    metadata:
      labels:
        app: test
    spec:
      containers:
      - image: nginx
        name: test-hp
      nodeSelector:
        kubernetes.io/hostname: kind-control-plane

9. 只允许使用某镜像仓库的镜像

apiVersion : kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: disallow-external-image
spec:
  validationFailureAction: enforce
  rules:
  - name: require-image-tag
    match:
      resources:
        kinds:
        - Pod
    validate:
      message: "Only internal images are allowed"  
      pattern:
        spec:
          containers:
          - image: "image.kelu.org/*"

10. 不允许使用latest镜像

apiVersion : kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: disallow-latest-tag
spec:
  validationFailureAction: enforce
  rules:
  - name: require-image-tag
    match:
      resources:
        kinds:
        - Pod
    validate:
      message: "An image tag is required"  
      pattern:
        spec:
          containers:
          - image: "*:*"
  - name: validate-image-tag
    match:
      resources:
        kinds:
        - Pod
    validate:
      message: "Using a mutable image tag e.g. 'latest' is not allowed"
      pattern:
        spec:
          containers:
          - image: "!*:latest"

11. 禁止使用特定的nodeport端口

apiVersion : kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: disallow-nodeport-29000
spec:
  validationFailureAction: enforce
  rules:
  - name: disallow-nodeport-29000
    match:
      resources:
        kinds:
        - Service
    validate:
      message: "disallow-nodeport-29000"  
      pattern:
        spec:
          type: NodePort
          ports:
           - nodePort: "!29000"
  - name: disallow-lb-29000
    match:
      resources:
        kinds:
        - Service
    validate:
      message: "disallow-LoadBalancer-29000"  
      pattern:
        spec:
          type: LoadBalancer
          ports:
           - nodePort: "!29000"

12. 禁止配置external-ip

apiVersion : kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: disallow-external-ip
spec:
  validationFailureAction: enforce
  rules:
  - name: disallow-external-ip
    match:
      resources:
        kinds:
        - Service
    validate:
      message: "externalIPs are not allowed."  
      pattern:
        spec:
          X(externalIPs): "null"

参考资料


使用 kind 低成本练习 kubernetes

kind 是一个使用 Docker 容器节点运行本地 Kubernetes 集群的工具(CLI)。最近在开发一些周边组件,急需一个集群进行验证,使用kind非常方便。这篇文章记录我使用的步骤。

一、安装

kind 就是一个二进制包,Linux mac Windows都可以快速安装:

Linux

curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.8.1/kind-linux-amd64 chmod +x ./kind mv ./kind /some-dir-in-your-PATH/kind

Mac

brew install kind

或者

curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.8.1/kind-darwin-amd64

Windows

curl.exe -Lo kind-windows-amd64.exe https://kind.sigs.k8s.io/dl/v0.8.1/kind-windows-amd64 Move-Item .\kind-windows-amd64.exe c:\some-dir-in-your-PATH\kind.exe

或者使用 Chocolatey (https://chocolatey.org/packages/kind)

choco install kind

二、使用

使用如下配置文件 kind.yaml

kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
networking:
  # https://kind.sigs.k8s.io/docs/user/configuration/
  apiServerAddress: "10.19.0.54"
  apiServerPort: 888
nodes:
  - role: control-plane
    image: kindest/node:v1.17.5@sha256:ab3f9e6ec5ad8840eeb1f76c89bb7948c77bbf76bcebe1a8b59790b8ae9a283a
#featureGates:
#  FeatureGateName: true

这个配置文件中,我配置了单节点集群的 IP、apiserver 对外暴露的端口,k8s的版本 v1.17.

image相关信息来这里找:https://github.com/kubernetes-sigs/kind/releases

创建集群:

kind create cluster --config kind.yaml

> kind create cluster
Creating cluster "kind" ...
 ✓ Ensuring node image (kindest/node:v1.17.5) 🖼
 ✓ Preparing nodes 📦
 ✓ Writing configuration 📜
 ✓ Starting control-plane 🕹️
 ✓ Installing CNI 🔌
 ✓ Installing StorageClass 💾
Set kubectl context to "kind-kind"
You can now use your cluster with:kubectl cluster-info --context kind-kind Have a nice day! 👋

如果你集群恰好使用了 同版本的 kubectl,可以使用下面命令行在宿主机快速操作k8s:

kubectl cluster-info --context kind-kind 

不同版本的kubectl 会导致意外的。当然,你还有其他方式进行操作:

命令行使用

进入主容器:

docker exec -it kind-control-plane /bin/bash

配置kubectl:

export KUBECONFIG=/etc/kubernetes/admin.conf

可以直接操作了!

ui界面使用(lens)

查看kind的相关命令:

kind -h

kind获得配置:

kind get kubeconfig --name xxx # 如果是默认名字kind,不需要--name

将配置写入lens配置界面配置:

1598253646399

完成!界面如下所示。

1598253691029

获得一个简单容器的 yaml:

kubectl run busybox --image=busybox  --restart=Never --dry-run -o yaml  -- sleep 1000000 > pod.yaml

得到 pod.yaml :


apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: busybox
  name: busybox
spec:
  containers:
  - args:
    - sleep
    - "1000"
    image: busybox
    imagePullPolicy: IfNotPresent
    name: busybox
    resources: {}
  dnsPolicy: ClusterFirst
  restartPolicy: Never
status: {}

运行:

kubectl apply -f pod.yaml

几个常用的yaml备忘

busybox deployment

kind: Deployment
apiVersion: apps/v1
metadata:
  name: busybox
spec:
  selector:
    matchLabels:
      app: busybox
  replicas: 1
  template:
    metadata:
      labels:
        app: busybox  
    spec:
      containers:
        - name: busybox
          image: busybox
          args:
            - sleep
            - '1000'
          resources:
            limits:
              ephemeral-storage: 40Gi
            requests:
              ephemeral-storage: 100Mi
      nodeName: rqytest1
      tolerations:
        - key: env
          operator: Equal
          value: dev
          effect: NoSchedule

nginx deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 2
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80

nginx service

kind: Service
apiVersion: v1
metadata:
  name: nginx-svc
spec:
  ports:
    - name: '80'
      protocol: TCP
      port: 80
      targetPort: 80
  selector:
    app: nginx
  type: NodePort