手把手教你打造本地友好的 Kubernetes 工作环境

公众号关注 「奇妙的 Linux 世界」

设为「星标」,每天带你玩转 Linux !

1362427a3fb6b981cfb531098cc60c1e.jpeg


作为一个 Kubernetes YAML 工程师,熟练掌握各种资源非常的重要,但是在 Kubernetes 的世界里,概念太多了... 而且它又同时支持通过 CRD 来自造概念,扩展已有的资源,每年又有那么多优秀的创新不断涌现,挡都挡不住。

402a646796956eeba4fab21f49cc00fa.gif
学不过来,怎么办?

但是那又如何,2021 这么糟糕的一年你都熬过来了,再想想那未知的 2022 年吧,这个世界上没有"最",只有"更"。。。这么一想你是不是要更加(有)焦(动)虑(力)了。。。


所以,吃饭的家伙你不能丢了。

正所谓攻欲善其事,必先利其器,这里我给大家分享一下如何打造一个对本地友好的 Kubernetes 工作环境,相信我,这点真的非常重要,让我带你搭上 2021 年最后这趟便车吧。

1b6a8dc37978d5f606d5701fac0c65d9.jpeg
都卷起来吧

为什么需要这样一个环境?

其实很简单,无非就是以下这么几个原因

  1. 找点有意思的工具,提升一下日常工作效率,这点是最重要的

  2. 不论你是因为什么原因换了机器,还是在外做实施支持工作的时候,没了熟悉的环境,想必有为此烦恼过吧

  3. 给小白用户提供一些帮助,他们平时不怎么操作 Kubernetes 集群,但是又想拥有一套可上手的 Kubernetes 工作环境?你大可直接分享给他们。

  4. 有时候方便大家,其实就是方便自己

一些常用的工具

#1. kubectl

kubectl 是 Kubernetes 命令行工具,是用来管理控制 Kubernetes 集群,这个必须要装,没什么好说的。

官网有很详细的用法,详情请移步官方文档
kubectl controls the Kubernetes cluster manager[1]

#2. auto-completion

命令自动补全功能是真心强烈建议安装的,它可以说是你在日常实操 kubectl 中最有用的工具也不为过,太实用了...你可以使用 Tab 键,在它的帮助下可以自动完成 kubectl 命令中的任意部分。

可以说我现在是完全依赖它过活,因为 Kubernetes 资源太多了,记不住啊...

启用 kubectl 自动补全功能 ,可以参考以下文档

Some optional configuration for bash auto-completion on Linux.
bash auto-completion on Linux[2]

Some optional configuration for bash auto-completion on macOS.
bash auto-completion on macOS[3]

Some optional configuration for zsh auto-completion.
zsh auto-completion[4]

这里有必要提一句,我本地习惯用 zsh,zsh-autosuggestion 这个 plugin 我也强烈推荐,真的是谁用谁知道。

#3. krew

krew 是 kubectl 插件的管理工具。

你会在里面找到非常有意思,且能提高工作效率的插件,大家可以自行去探索。

详情参见
Krew is the plugin manager for kubectl command-line tool[5]

#4. kubectx

在日常工作中,我们经常需要访问不同的 Kubernetes 集群,通过原生的 kubectl 一般有如下几种做法

1. 通过指定单独配置文件访问

指定访问一个集群,你可以这么做

k get pod --kubeconfig=dev-config

# 或者
KUBECONFIG=dev-config k get pod
2. 通过指定 context 来访问

首先你需要知道你的工作环境中,有多少个可操作的 Kubernetes 集群

➜ k config get-contexts
CURRENT   NAME                              CLUSTER                         AUTHINFO                              NAMESPACE
          staging-context                   cluster.local-staging           kubernetes-admin-staging              traefik
*         kind-local-k8s                    kind-local-k8s                  kind-local-k8s                        kube-node-lease
          testing-context                   cluster.local-testing           kubernetes-admin-testing              rook-ceph

然后需要查看某一个集群的资源,通过指定具体的 context 即可

➜ k get pod --context staging-context

➜ k get pod --context testing-context

更换当前上下文

➜ k config use-context staging-context
Switched to context "staging-context".

更换上下文的 namespace

➜ k config set-context --current --namespace=kafka
Context "staging-context" modified.

大家可以看到以上的操作是多么的繁琐,好在有 kubectx 这个工具,它可以快速的帮助我们在不同集群和命名空间之间进行切换。

# 更换上下文
➜ kubectx staging-xdp
Switched to context "staging-xdp".

# 更换上下文的 namespace
➜ kubens kafka
Context "staging-xdp" modified.
Active namespace is "kafka".

详情参见
Faster way to switch between clusters and namespaces in kubectl[6]

这里建议同时安装一下 fzf[7] ,通过在交互模式下直接使用游标选择上下文,就不用使用复制粘贴这种"笨"方法了,既获得了更好的体验又提升了效率。

另外如果需要了解 KUBECONFIG 的话,下面这篇文章值得一读

Mastering the KUBECONFIG file[8]

#5. kube-ps1

有时候手里的 Kubernetes 集群太多了,经常会忘记自己当前切换到了哪个集群里,所以我每次都会通过kubectl cluster-info 命令来确认一下,虽然很烦,但这其实是非常有必要的,因为如果你一旦 误操作集群 问题就大了,谁操作谁知道。

➜ k cluster-info
Kubernetes master is running at https://xxx.xx.x.xxx:6443

你也可以通过获取当前上下文的指令,来确认当前所在的集群是哪个

➜ k config current-context
staging-context

那么有没这样一个工具,不论我处于哪个集群的上下文,或者在哪个命名空间下,我都能快速的获取到信息呢?

有的,kube-ps1 这个工具它可以帮到我们,如下所示

➜ kubectx staging-context
Switched to context "staging-context".
(base)
~/.kube via 🅒 base at ☸️  staging-context (traefik)

➜ kubectx testing-context
Switched to context "testing-context".
(base)
~/.kube via 🅒 base at ☸️  testing-context (rook-ceph)

详情参见
Kubernetes prompt info for bash and zsh[9]

#6. kubectl-images

确认集群中某一个服务的镜像版本,这个操作也是比较常见的,一般我们有如下几种做法

1. 通过 get 结合 jq 获取

Pod 內只有一个 container 情况

➜ k get pod \
  -l run=hello-world \
  -o json|jq '.items[].spec.containers[]|{name: .name, image: .image}'
{
  "name": "hello-world",
  "image": "datawire/hello-world"
}

Pod 里有多个 containers,比如包含了另外一个 sidecar 容器

➜ k get pod \
  -l name=hello-world \
  -o json|jq '.items[].spec.containers[]|{name: .name, image: .image}'
{
  "name": "hello-world",
  "image": "lqshow/busybox-curl:1.28"
}
{
  "name": "linkerd-proxy",
  "image": "linkerd/proxy:stable-2.10.2"
}
2. 通过 get 结合 JSONPath 获取
➜ k get pod \
  -l name=hello-world \
  -o custom-columns='PodName:metadata.name, ContainerName:spec.containers[*].name, IMAGES:spec.containers[*].image'
PodName        ContainerName               IMAGES
hello-world   hello-world,linkerd-proxy   lqshow/busybox-curl:1.28,linkerd/proxy:stable-2.10.2
3. 通过 describe 获取
➜ k describe pod -l run=hello-world|grep -i image
    Image:          datawire/hello-world

以上3种方法完全可以拿到你想要的信息,如果有查看其他服务镜像版本的需求,我复制粘贴,调整下 Pod 名称或者 Pod Label 就行,是不是也可以用?

你说的没错,但是前提你需要清楚的知道查找对象的全名称,或者 Label 才行,那么有没一个只需要通过关键字就能定位到的工具呢?当然有(通过 kubectl-images 插件),而且它还会帮你找出 init-container,是不是更加的清晰,更快?

➜ k images hello
 namespaces, 1 pods, 3 containers and 3 different images
+-------------+---------------------+------------------------------------------------+
|   PodName   |    ContainerName    |      ContainerImage                            |
+-------------+---------------------+------------------------------------------------+
| hello-world | hello-world         | lqshow/busybox-curl:1.28                       |
+             +---------------------+------------------------------------------------+
|             | linkerd-proxy       | linkerd/proxy:stable-2.10.2                    |
+             +---------------------+------------------------------------------------+
|             | (init) linkerd-init | linkerd/proxy-init:v1.3.11                     |
+-------------+---------------------+------------------------------------------------+

另外如果你不指定关键字,它会帮你列出 namesapce 下的所有镜像

➜ k images
 namespaces, 2 pods, 2 containers and 2 different images
+----------------------------------+-----------------+-------------------------------+
|             PodName              |  ContainerName  |        ContainerImage         |
+----------------------------------+-----------------+-------------------------------+
| hello-world                      | hello-world     | datawire/hello-world          |
+----------------------------------+-----------------+-------------------------------+
| traffic-manager-5cb99c9fd6-x6n8x | traffic-manager | docker.io/datawire/tel2:2.4.9 |
+----------------------------------+-----------------+-------------------------------+

详情参见

Show container images used in the cluster.[10]

#7. stern

查找日志不论是作为一位集群管理员还是开发工程师,我相信它都是你平时 Debugging 问题时做的最多的操作吧。

通常情况下,使用 kubectl logs 命令来处理就行,但是它存在以下几个问题

  1. Pod 名称的不断变化,Debugging 会陷入循环复制粘贴的困境,很尴尬

  2. 即使你通过 Pod label 去过滤,记住每个服务对应的 label 也是一件很痛苦又没劲的事情

  3. Pod 多副本的情况,虽然能够通过 label 匹配的到,但是可观测还是差了些

Stern 就能够很好的解决以上提的这些问题,大家不妨一试。

使用命令很简单,详情参见
Multi pod and container log tailing for Kubernetes[11]

#8. kubectl-neat

neat 也是一个非常有用的工具,它可以对 Kubernetes 资源的 YAML/JSON 做清理。

有时我们需要将集群內某个资源的 YAML 导出修改后再运行,你会发现里面有一大堆你不想要的字段,比如 managedFields、creationTimestamp、uid 以及 status 等等,有了 neat 后,它会帮你自动删除这些无用字段。

以前我都是手动一个个删,一两次还好,但是身为 YAML 工程师,就没有一两次的说法,如果你整天做这种操作,想想都要奔溃了吧

下面是最基本的用法,其他用法移步官网

kubectl get cm nginx-config -oyaml | kubectl neat -o yaml

详情参见
Clean up Kubernetes yaml and json output to make it readable[12]

#9. ksniff

在 Kubernetes 环境中,一个针对 Pod 网络的抓包工具。

详情参见
Kubectl plugin to ease sniffing on kubernetes pods using tcpdump and wireshark[13]

#10. kubectl-iexec

开发工程师在 Debugging 期间,难免需要进入 Pod 內,通常我们有以下几种做法

1. 单Pod单容器情况
➜ k exec -it hello-world-<HASH-ID> -- sh
/data #
2. 单Pod多容器情况
➜ k exec -it hello-world-<HASH-ID> -c hello-world -- sh
/data #
3. 通过 label 定位 Pod 名称

结合 -o name 获取名称

➜ kubectl exec \
  -it \
  $(kubectl get pod -l app=traffic-manager -o name |sed 's/pods\///') \
  -- sh
/ $

结合 JSONPath 获取名称

➜ kubectl exec \
  -it \
  $(kubectl get pod -l app=traffic-manager -o jsonpath='{.items[0].metadata.name}') \
  -- sh
/ $

结合 grep/awk 获取名称

➜ kubectl exec -it $(kubectl get pod |grep traffic|awk '{print $1}'|xargs -I{}) -- sh
/ $

其实不管单Pod,还是多Pod,我们都需要先定位到 Pod 的名字后才能通过 kubectl exec 命令进入到容器里面。

所以,不论是在流程和书写命令上都复杂了些,对小白用户存在一定的心智负担。

使用 kubectl-iexec 就能够很好的解决以上问题,只需要输入关键字就能完成定位,以下是使用过程中的一些截图

7a95840483405741562750b0d6077af0.png
1.选择进入的 pod
c9be45d262f7a7883586012b6c3cc78b.png
2.选择指定的 container
ce1bf806213c0f50f24fe8786d0d32e4.png
3.通过交互式进入到指定 container

详情参见
Kubectl plugin to interactively exec into a pod[14]


#11. telepresence

telepresence 我在前面文章也有分享过,这里就不做阐述了,有兴趣的同学可以点击下图查看

67a4d92312432608818fae7684853846.png

拿来主义,真香

大家可以很轻松的在自己的本地环境安装这些工具来使用,也可以利用 Dockerfile 将这些工具打包成一个 Kubetools 镜像来运行。

个人建议使用第二种容器的方式,Build Once, Run Anywhere。你懂得,后续即便你要不断的扩充工具库,也是非常的简单。

我将上面提到的这些工具,做成了一个 Docker 镜像,大家可以尝试运行使用。

docker run -it \
  --rm \
  --name kubetools \
  -v ~/.kube/config:/root/.kube/config \
  lqshow/kubetools:0.0.1 \
  zsh

Dockerfile 详见:https://github.com/lqshow/dockerfiles/tree/master/kubetools

写在最后

本篇分享其实带有强烈的个人偏好,仅罗列了我个人平时常用的工具而已,我觉得挺好的。

但是,我觉得好,并不表示你们觉得好。

所以没关系,大家完全可以按照 Kubetools - A Curated List of Kubernetes Tools[15] 提供的工具库,打造一个完全属于你自己的 Kubetools

4e7f0965aceae7f5e965fe4a85322949.gif
Nice

希望这篇分享对大家都有所帮助。

参考资料

[1]

kubectl controls the Kubernetes cluster manager: https://kubernetes.io/docs/reference/kubectl/kubectl/

[2]

bash auto-completion on Linux: https://kubernetes.io/docs/tasks/tools/included/optional-kubectl-configs-bash-linux/

[3]

bash auto-completion on macOS: https://kubernetes.io/docs/tasks/tools/included/optional-kubectl-configs-bash-mac/

[4]

zsh auto-completion: https://kubernetes.io/docs/tasks/tools/included/optional-kubectl-configs-zsh/

[5]

Krew is the plugin manager for kubectl command-line tool: https://krew.sigs.k8s.io/

[6]

Faster way to switch between clusters and namespaces in kubectl: https://github.com/ahmetb/kubectx

[7]

fzf: https://github.com/junegunn/fzf

[8]

Mastering the KUBECONFIG file: https://ahmet.im/blog/mastering-kubeconfig/

[9]

Kubernetes prompt info for bash and zsh: https://github.com/jonmosco/kube-ps1

[10]

kubectl-images: https://github.com/chenjiandongx/kubectl-images

[11]

Multi pod and container log tailing for Kubernetes: https://github.com/wercker/stern

[12]

Clean up Kubernetes yaml and json output to make it readable: https://github.com/itaysk/kubectl-neat

[13]

Kubectl plugin to ease sniffing on kubernetes pods using tcpdump and wireshark: https://github.com/eldadru/ksniff

[14]

Kubectl plugin to interactively exec into a pod: https://github.com/gabeduke/kubectl-iexec

[15]

Kubetools - A Curated List of Kubernetes Tools: https://collabnix.github.io/kubetools/

本文转载自:「Cloud Native 101」,原文:https://url.hi-linux.com/nfYjX,版权归原作者所有。欢迎投稿,投稿邮箱: editor@hi-linux.com。

232a92a3c2d3de73a5b7e22661f542f9.gif

最近,我们建立了一个技术交流微信群。目前群里已加入了不少行业内的大神,有兴趣的同学可以加入和我们一起交流技术,在 「奇妙的 Linux 世界」 公众号直接回复 「加群」 邀请你入群。

41d76ce39bf259b525894ac7fca6a743.png

你可能还喜欢

点击下方图片即可阅读

e5b7e6b2e6e044ed56ead3e424fd2dbd.png

推荐两款超实用的小工具: 文件快递柜和 Oh-My-Posh

0ed8cfed01538fc33e2344b35ed38055.png
点击上方图片,『美团|饿了么』外卖红包天天免费领

7daa9f13f94f0895121c0c5e31c82c0a.png

更多有趣的互联网新鲜事,关注「奇妙的互联网」视频号全了解!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Android平台上使用FFmpeg需要进行交叉编译,生成适用于Android的FFmpeg库,并将其打包到apk中。以下是手把手你搭建ffmpeg命令行运行环境的步骤: 1.下载NDK 首先需要下载NDK(Native Development Kit),NDK是一个工具包,用于开发C/C++应用程序的原生库。Android Studio自带NDK,也可以从官网下载。 2.下载FFmpeg源代码 从FFmpeg的官网下载源代码,然后解压到本地。 3.配置交叉编译环境 在FFmpeg源代码根目录下创建一个build_android.sh文件,输入以下内容: ```bash #!/bin/bash NDK=$HOME/Android/Sdk/ndk-bundle # NDK路径 SYSROOT=$NDK/platforms/android-21/arch-arm/ # Android SDK路径 TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64 # 工具链路径 function build_one { ./configure \ --prefix=$PREFIX \ --enable-shared \ --disable-static \ --disable-doc \ --disable-ffmpeg \ --disable-ffplay \ --disable-ffprobe \ --disable-ffserver \ --disable-debug \ --disable-network \ --disable-avdevice \ --disable-postproc \ --disable-symver \ --cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \ --target-os=android \ --arch=arm \ --sysroot=$SYSROOT \ --extra-cflags="-Os -fpic $ADDI_CFLAGS" \ --extra-ldflags="$ADDI_LDFLAGS" \ $ADDITIONAL_CONFIGURE_FLAG make make install } CPU=arm PREFIX=$(pwd)/android/$CPU ADDI_CFLAGS="-marm" ADDI_LDFLAGS="" build_one ``` 其中,NDK是NDK的路径,SYSROOT是Android SDK的路径,TOOLCHAIN是工具链的路径。 4.执行交叉编译命令 在终端中输入以下命令: ```bash chmod +x build_android.sh ./build_android.sh ``` 等待编译完成。编译完成后,在FFmpeg源代码根目录下会生成一个android目录,其中包含了交叉编译生成的FFmpeg库。 5.创建Android Studio项目 打开Android Studio,创建一个新项目。在app/build.gradle文件中添加以下代码: ```groovy android { compileSdkVersion 28 defaultConfig { applicationId "com.example.ffmpegdemo" minSdkVersion 21 targetSdkVersion 28 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } externalNativeBuild { cmake { cppFlags "" abiFilters "armeabi-v7a" arguments "-DANDROID_ARM_NEON=TRUE" } } sourceSets.main { jniLibs.srcDirs = ['src/main/jniLibs'] } ndk { abiFilters "armeabi-v7a" } } ``` 其中,externalNativeBuild和ndk是用于指定使用交叉编译生成的库的配置。 6.将FFmpeg库打包到apk中 将交叉编译生成的库复制到项目的app/src/main/jniLibs/armeabi-v7a/目录下。在app/build.gradle文件中添加以下代码: ```groovy android { sourceSets { main { jniLibs.srcDirs = ['src/main/jniLibs'] } } } ``` 然后在终端中输入以下命令: ```bash ./gradlew assembleDebug ``` 等待打包完成。打包完成后,在项目的build/outputs/apk/debug/目录下会生成一个apk文件,其中包含了FFmpeg库。 至此,就完成了搭建ffmpeg命令行运行环境的所有步骤。可以通过在MainActivity中执行FFmpeg命令来测试FFmpeg是否正常工作

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值