全网就这一份:纯shell解析json
在linux中,解析json一般都会使用jq,jq固然好用,但是要额外安装就不太友好了。如果你在网上搜索通过shell来解析json的方法,你会发现都是些啥玩意儿。既然如此,那就动手撸一个吧。
有以下特性:
她能兼容jq的路径表达式
.name
.[0].name
.[0][0].name
- ...
- 纯shell,其实用的是awk。纯bash不好搞,就曲线救一下国呗
代码如下,拿去不谢。转载请标出处。转载请标出处。转载请标出处。
在linux中,解析json一般都会使用jq,jq固然好用,但是要额外安装就不太友好了。如果你在网上搜索通过shell来解析json的方法,你会发现都是些啥玩意儿。既然如此,那就动手撸一个吧。
有以下特性:
她能兼容jq的路径表达式
.name
.[0].name
.[0][0].name
代码如下,拿去不谢。转载请标出处。转载请标出处。转载请标出处。
正在运行的gitlab集群突然抽风,具体故障现象如下。
环境信息:gitlab部署在k8s集群内,采用官方helm包部署,gitlab版本为14.10.x。
故障现象:项目相关的操作有几率报错
An error occurred while fetching folder content.
查看Gitaly服务的日志,发现是Praefect服务调用Gitaly的健康检查接口报错,错误关键信息为 PermissionDenied。
{"correlation_id":"01G7BX3DR59H35EYHPMKHNVBC0","error":"rpc error: code = PermissionDenied desc = permission denied","grpc.code":"PermissionDenied","grpc.meta.auth_version":"v2","grpc.meta.deadline_type":"unknown","grpc.meta.method_type"
:"unary","grpc.method":"Check","grpc.request.deadline":"2022-07-07T08:39:54.207","grpc.request.fullMethod":"/grpc.health.v1.Health/Check","grpc.request.payload_bytes":0,"grpc.response.payload_bytes":0,"grpc.service":"grpc.health.v1.Healt
h","grpc.start_time":"2022-07-07T08:39:53.208","grpc.time_ms":0.285,"level":"warning","msg":"finished unary call with code PermissionDenied","peer.address":"10.42.1.134:51266","pid":12,"span.kind":"server","system":"grpc","time":"2022-07-07T08:39:53.208Z"}
{"correlation_id":"01G7BX3EQJZJFT996MD2KF2HXW","error":"rpc error: code = PermissionDenied desc = permission denied","grpc.code":"PermissionDenied","grpc.meta.auth_version":"v2","grpc.meta.deadline_type":"unknown","grpc.meta.method_type":"unary","grpc.method":"Check","grpc.request.deadline":"2022-07-07T08:39:55.212","grpc.request.fullMethod":"/grpc.health.v1.Health/Check","grpc.request.payload_bytes":0,"grpc.response.payload_bytes":0,"grpc.service":"grpc.health.v1.Health","grpc.start_time":"2022-07-07T08:39:54.213","grpc.time_ms":0.201,"level":"warning","msg":"finished unary call with code PermissionDenied","peer.address":"10.42.1.134:51266","pid":12,"span.kind":"server","system":"grpc","time":"2022-07-07T08:39:54.213Z"}
*** /var/log/gitaly/gitaly_ruby_json.log ***
{"type":"gitaly-ruby","grpc.start_time":"2022-07-07T08:39:53Z","grpc.time_ms":0.286,"grpc.code":"OK","grpc.method":"Check","grpc.service":"grpc.health.v1.Health","pid":35,"correlation_id":"c486ca8b2bbc3eb6736d533c38cf6017","time":"2022-07-07T08:39:53.642Z"}
{"type":"gitaly-ruby","grpc.start_time":"2022-07-07T08:39:53Z","grpc.time_ms":17.012,"grpc.code":"OK","grpc.method":"Check","grpc.service":"grpc.health.v1.Health","pid":36,"correlation_id":"71bff8c80424d633989f5daeb29111c3","time":"2022-07-07T08:39:53.658Z"}
*** /var/log/gitaly/gitaly.log ***
{"correlation_id":"01G7BX3FPZ8BTMCA0RY5754JGJ","error":"rpc error: code = PermissionDenied desc = permission denied","grpc.code":"PermissionDenied","grpc.meta.auth_version":"v2","grpc.meta.deadline_type":"unknown","grpc.meta.method_type":"unary","grpc.method":"Check","grpc.request.deadline":"2022-07-07T08:39:56.217","grpc.request.fullMethod":"/grpc.health.v1.Health/Check","grpc.request.payload_bytes":0,"grpc.response.payload_bytes":0,"grpc.service":"grpc.health.v1.Health","grpc.start_time":"2022-07-07T08:39:55.218","grpc.time_ms":0.135,"level":"warning","msg":"finished unary call with code PermissionDenied","peer.address":"10.42.1.134:51266","pid":12,"span.kind":"server","system":"grpc","time":"2022-07-07T08:39:55.218Z"}
{"correlation_id":"01G7BX3GPCRD1RPMN7F3WN6X14","error":"rpc error: code = PermissionDenied desc = permission denied","grpc.code":"PermissionDenied","grpc.meta.auth_version":"v2","grpc.meta.deadline_type":"unknown","grpc.meta.method_type":"unary","grpc.method":"Check","grpc.request.deadline":"2022-07-07T08:39:57.222","grpc.request.fullMethod":"/grpc.health.v1.Health/Check","grpc.request.payload_bytes":0,"grpc.response.payload_bytes":0,"grpc.service":"grpc.health.v1.Health","grpc.start_time":"2022-07-07T08:39:56.223","grpc.time_ms":0.189,"level":"warning","msg":"finished unary call with code PermissionDenied","peer.address":"10.42.1.134:51266","pid":12,"span.kind":"server","system":"grpc","time":"2022-07-07T08:39:56.223Z"}
解决:服务器之间做好时间同步就好了
虽然 kubeadm, kops, kubespray 以及 rke, kubesphere 等工具可以快速部署 K8s 集群,但是依然会有很多人热衷与使用二进制部署 K8s 集群。
二进制部署可以加深对 K8s 各组件的理解,可以灵活地将各个组件部署到不同的机器,以满足自身的要求。还可以生成一个超长时间自签证书,比如 99 年,免去忘记更新证书过期带来的生产事故。
本文基于当前(2021-12-31)最新版本 K8s 1.23.1,总体和网上的 1.20,1.22 等版本的部署方式没有太大的区别,主要参考了韩先超老师的 K8s 1.20 版本的二进制部署教程。
另外,我的环境是使用 m1 芯片的 macbook 运行的 ubuntu 20.04 TLS
虚拟机搭建,因此本次环境搭建 K8s 是基于 arm64 架构的。
➜
符号表示#
或 //
表示角色 | 主机名 | IP | 组件 |
---|---|---|---|
master node | ubuntu-k8s-master-01 | 10.211.55.4 | etcd, kube-apiserver, kube-controller-manager, kube-scheduler, kube-proxy, kubelet |
worker node | ubuntu-k8s-worker-01 | 10.211.55.5 | kubelet, kube-proxy |
设置主机名
# 10.211.55.4 主机
➜ sudo hostnamectl set-hostname ubuntu-k8s-master-01
# 10.211.55.5 主机
➜ sudo hostnamectl set-hostname ubuntu-k8s-worker-01
Task weight: 1%
You have access to multiple clusters from your main terminal through
kubectl
contexts. Write all context names into/opt/course/1/contexts
, one per line.From the kubeconfig extract the certificate of user
restricted@infra-prod
and write it decoded to/opt/course/1/cert
.
题目解析:
考点
解题
➜ kubectl config get-contexts -o name > /opt/course/1/contexts
# 从 .kube/config 文件中找到
- name: restricted@infra-prod
user
client-certificate-data: LS0tLS1CRUdJ...
➜ echo LS0tLS1CRUdJ... | base64 -d > /opt/course/1/cert
Task weight: 1%
You have access to multiple clusters from your main terminal through
kubectl
contexts. Write all those context names into/opt/course/1/contexts
.Next write a command to display the current context into
/opt/course/1/context_default_kubectl.sh
, the command should usekubectl
.Finally write a second command doing the same thing into
/opt/course/1/context_default_no_kubectl.sh
, but without the use ofkubectl
.
题目解析:
考点
解题
根据题意:Write all those context names into /opt/course/1/contexts
➜ kubectl config get-contexts -o name > /opt/course/1/contexts
根据题意:Next write a command to display the current context into /opt/course/1/context_default_kubectl.sh
, the command should use kubectl
➜ vim /opt/course/1/context_default_kubectl.sh
kubectl config current-context
根据题意:Finally write a second command doing the same thing into /opt/course/1/context_default_no_kubectl.sh
, but without the use of kubectl
➜ vim /opt/course/1/context_default_no_kubectl.sh
grep "current-context: " ~/.kube/config | awk '{print $2}'