- 使用 Spring Initializr 创建 Spring Boot 应用程序
- 在Spring Boot中配置Cassandra
- 在 Spring Boot 上配置 Tomcat 连接池
- 将Camel消息路由到嵌入WildFly的Artemis上
kubectl作为我们主要的操作K8S的工具,其具备非常丰富的功能,但是如果不经过打磨,使用起来还是存在诸多不便,今天我们来看看如何将我们的kubectl打磨的更加易用。
一、命令自动补全
kubectl中提供非常多的命令,如果每一次都要手动一个字符一个字符的敲未免太累了,那么如何配置自动补全呢?这里以ubuntu系统为例:
1、安装auto-completion工具
$ sudoapt update
Hit:1 http://archive.ubuntu.com/ubuntu bionic InRelease
Hit:2 http://security.ubuntu.com/ubuntu bionic-security InRelease
Hit:3 http://archive.ubuntu.com/ubuntu bionic-updates InRelease
Hit:4 https://download.docker.com/linux/ubuntu bionic InRelease
Hit:5 http://archive.ubuntu.com/ubuntu bionic-backports InRelease
Reading package lists... Done
Building dependency tree
Reading state information... Done
144 packages can be upgraded. Run 'apt list --upgradable'to see them.
$ sudo apt install bash-completion
Reading package lists... Done
Building dependency tree
Reading state information... Done
bash-completion is already the newest version (1:2.8-1ubuntu1).
0 upgraded, 0 newly installed, 0 to remove and 144 not upgraded.
PS:如果是centos系统,则使用yum install bash-completion -y命令安装
2、配置自动补全
Bash:
source <(kubectl completion bash)
echo "source <(kubectl completion bash)" >> ~/.bashrc
Zsh:
source <(kubectl completion zsh)
echo "[[ $commands[kubectl] ]] && source <(kubectl completion zsh)" >> ~/.zshrc
配置后就可以通过Tab键自动补全命令啦!
二、配置kubectl别名
我们可以通过设置别名简化kubectl命令,编辑.bashrc文件,添加如下内容:
alias sudo='sudo 'alias k='kubectl'alias ka='kubectl apply --recursive -f'alias kex='kubectl exec -i -t'alias klo='kubectl logs -f'alias kg='kubectl get'alias kd='kubectl describe'
PS:alias sudo是为了解决sudo下别名不可用问题
保存后记得执行 source ~/.bashrc哈,接着我们体验下:
$ sudoka webapp_pod.yaml
pod/webapp created
$ sudokg pods
NAME READY STATUS RESTARTS AGE
webapp 0/2 ContainerCreating 07s
$ sudokd pod webapp
Name: webapp
Namespace: default
Priority: 0Node: ayato/172.16.194.135Start Time: Wed, 09 Feb 2022 14:04:44 +0000Labels: app=webapp
Annotations: <none>Status: Running
IP: 172.17.0.6IPs:
IP: 172.17.0.6Containers:
webapp:
Container ID: docker://d9ddf9dd47de12b53f2119bf75df6706bee2e7711509638ad52adc9addeda704
Image: 172.16.194.135:5000/webapp:1.0Image ID: docker-pullable://172.16.194.135:5000/webapp@sha256:df3a447a013ada0642dec67bb31976f42f1a0699a68873d0452f514fa24e5c77
Port: 5000/TCP
Host Port: 0/TCP
State: Running
Started: Wed, 09 Feb 2022 14:04:46 +0000Ready: True
Restart Count: 0Environment: <none>Mounts:
/tmp from webapp-logs (rw)
/var/run/secrets/kubernetes.io/serviceaccount from default-token-pcr2h (ro)
busybox:
Container ID: docker://6a6a35a628a782fc643af3dd49986bbc77c23de1ae4726bc521c77f61abbbf5d
Image: busybox
Image ID: docker-pullable://busybox@sha256:afcc7f1ac1b49db317a7196c902e61c6c3c4607d63599ee1a82d702d249a0ccb
Port: <none>Host Port: <none>Command:
sh
-c
tail -f /logs/log.out
State: Running
Started: Wed, 09 Feb 2022 14:06:53 +0000Ready: True
Restart Count: 0Environment: <none>Mounts:
/logs from webapp-logs (rw)
/var/run/secrets/kubernetes.io/serviceaccount from default-token-pcr2h (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
webapp-logs:
Type: EmptyDir (a temporary directory that shares a pod's lifetime)
Medium:
SizeLimit: <unset>default-token-pcr2h:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-pcr2h
Optional: falseQoS Class: BestEffort
Node-Selectors: <none>Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for300s
node.kubernetes.io/unreachable:NoExecute op=Exists for300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------Normal Scheduled 2m23s default-scheduler Successfully assigned default/webapp to ayato
Normal Pulled 2m22s kubelet Container image "172.16.194.135:5000/webapp:1.0"already present on machine
Normal Created 2m21s kubelet Created container webapp
Normal Started 2m21s kubelet Started container webapp
Normal Pulling 2m21s kubelet Pulling image "busybox"Normal Pulled 15s kubelet Successfully pulled image "busybox" in 14.633078305s
Normal Created 15s kubelet Created container busybox
Normal Started 14s kubelet Started container busybox
真的是飞一般的感觉!!!
三、Context和Namespace切换
我们在公司的容器平台上使用kubectl时,经常需要切换context和namespace,导致命令非常繁琐,那有没有简便的方式呢?—— kubectx
kubectx安装
$ sudo git clone https://github.com/ahmetb/kubectx /opt/kubectx
Cloning into '/opt/kubectx'...
remote: Enumerating objects: 1457, done.
remote: Counting objects: 100% (172/172), done.
remote: Compressing objects: 100% (115/115), done.
remote: Total 1457 (delta 85), reused 97 (delta 51), pack-reused 1285Receiving objects: 100% (1457/1457), 905.30 KiB | 69.00 KiB/s, done.
Resolving deltas: 100% (817/817), done.
$ sudo ln -s /opt/kubectx/kubens /usr/local/bin/kubectl-ns
$ sudo ln -s /opt/kubectx/kubectx /usr/local/bin/kubectl-ctx
我们来看一下效果:
$ sudok ctx
minikube
$ sudok ctx minikube
Switched to context "minikube".
$ sudok ns
default
kube-node-lease
kube-public
kube-system
kubernetes-dashboard
$ sudo k ns kube-public
Context "minikube"modified.
Active namespace is "kube-public".
$ sudok ns default
Context "minikube"modified.
Active namespace is "default".
四、跟踪查看多个Pod的日志
我们一般使用kubectl logs命令查看Pod日志,但是它不能通过-f参数同时跟踪查看多个Pod日志,这就不方便了,毕竟实际生产环境中每个服务都会有多个Pod,这时我们可以使用stern这个工具,它具备如下能力:
首先安装stern(下载stern时可能较慢可以多试几次):
wget https://github.com/wercker/stern/releases/download/1.11.0/stern_linux_amd64
sudo mv stern_linux_amd64 /usr/local/bin/kubectl-tail
sudo chomd +x /usr/local/bin/kubectl-tail
安装完毕后让我一起感受一下stern的魅力吧,我的Pod里面有两个容器:webapp和busybox,如果使用kubectl logs 还得指定具体的容器,而使用stern就没有这样的限制。
$ sudo k tail.
+webapp › busybox
+webapp › webapp
webapp busybox 14:04:53.197 [INFO ] [main] [org.apache.coyote.http11.Http11NioProtocol] Initializing ProtocolHandler ["http-nio-4567"]
webapp busybox 14:04:53.200[INFO ] [main] [org.apache.catalina.core.StandardService] Starting service [Tomcat]
webapp busybox 14:04:53.201 [INFO ] [main] [org.apache.catalina.core.StandardEngine] Starting Servlet engine: [Apache Tomcat/9.0.41]
webapp busybox 14:04:53.324 [INFO ] [main] [org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/]] Initializing Spring embedded WebApplicationContext
webapp busybox 14:04:53.325 [INFO ] [main] [org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext] Root WebApplicationContext: initialization completed in 2952ms
webapp busybox 14:04:53.801 [INFO ] [main] [org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor] Initializing ExecutorService 'applicationTaskExecutor'webapp busybox 14:04:54.264 [WARN ] [main] [org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration$DefaultTemplateResolverConfiguration] Cannot find template location: classpath:/templates/(please add some templates or check your Thymeleaf configuration)
webapp busybox 14:04:54.377 [INFO ] [main] [org.apache.coyote.http11.Http11NioProtocol] Starting ProtocolHandler ["http-nio-4567"]
webapp busybox 14:04:54.481 [INFO ] [main] [org.springframework.boot.web.embedded.tomcat.TomcatWebServer] Tomcat started on port(s): 4567 (http) with context path ''webapp busybox 14:04:54.509 [INFO ] [main] [org.demo.webapp.todolist.TodoListApplication] Started TodoListApplication in 6.235 seconds (JVM running for 8.074)
webapp webapp
webapp webapp . ____ _ __ _ _
webapp webapp /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
webapp webapp ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
webapp webapp \\/ ___)| |_)| | | | | || (_| |) ) ) )
webapp webapp '|____| .__|_| |_|_| |_\__, | / / / /
webapp webapp =========|_|==============|___/=/_/_/_/webapp webapp :: Spring Boot :: (v2.4.2)
webapp webapp
webapp webapp 14:04:50.124 [INFO ] [main] [org.demo.webapp.todolist.TodoListApplication] Starting TodoListApplication v1.0-SNAPSHOT using Java 1.8.0_111 on webapp with PID 1 (/opt/soft/webapp.jar started by root in /opt/soft)
webapp webapp 14:04:50.165[INFO ] [main] [org.demo.webapp.todolist.TodoListApplication] No active profile set, falling back to default profiles: default
webapp webapp 14:04:53.158 [INFO ] [main] [org.springframework.boot.web.embedded.tomcat.TomcatWebServer] Tomcat initialized with port(s): 4567(http)
webapp webapp 14:04:53.197 [INFO ] [main] [org.apache.coyote.http11.Http11NioProtocol] Initializing ProtocolHandler ["http-nio-4567"]
webapp webapp 14:04:53.200[INFO ] [main] [org.apache.catalina.core.StandardService] Starting service [Tomcat]
webapp webapp 14:04:53.201 [INFO ] [main] [org.apache.catalina.core.StandardEngine] Starting Servlet engine: [Apache Tomcat/9.0.41]
webapp webapp 14:04:53.324 [INFO ] [main] [org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/]] Initializing Spring embedded WebApplicationContext
webapp webapp 14:04:53.325 [INFO ] [main] [org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext] Root WebApplicationContext: initialization completed in 2952ms
webapp webapp 14:04:53.801 [INFO ] [main] [org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor] Initializing ExecutorService 'applicationTaskExecutor'webapp webapp 14:04:54.264 [WARN ] [main] [org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration$DefaultTemplateResolverConfiguration] Cannot find template location: classpath:/templates/(please add some templates or check your Thymeleaf configuration)
webapp webapp 14:04:54.377 [INFO ] [main] [org.apache.coyote.http11.Http11NioProtocol] Starting ProtocolHandler ["http-nio-4567"]
webapp webapp 14:04:54.481 [INFO ] [main] [org.springframework.boot.web.embedded.tomcat.TomcatWebServer] Tomcat started on port(s): 4567 (http) with context path ''webapp webapp 14:04:54.509 [INFO ] [main] [org.demo.webapp.todolist.TodoListApplication] Started TodoListApplication in 6.235 seconds (JVM running for 8.074)
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我们可以说 O(K + (N-K)logK)相当于O(K + N logK)对于 1 < = K <= N ? 最佳答案 简短的回答是它们不等价,这取决于k 的值。如果k等于N,那么第一个复杂度是O(
我有以下解决方案,但我从其他评论者那里听说它是 O(N * K * K),而不是 O(N * K)其中 N 是 K 列表的(最大)长度,K 是列表的数量。例如,给定列表 [1, 2, 3] 和 [4,
我试图理解这些语法结构之间的语义差异。 if ((i% k) == (l % k) == 0) 和 if ((i % k) == 0 && (l % k) == 0) 最佳答案 您的特定表达式((i
我有时会使用一维数组: A = np.array([1, 2, 3, 4]) 或 2D 阵列(使用 scipy.io.wavfile 读取单声道或立体声信号): A = np.array([[1, 2
在文档聚类过程中,作为数据预处理步骤,我首先应用奇异向量分解得到U、S和Vt 然后通过选择适当数量的特征值,我截断了 Vt,这让我从阅读的内容中得到了很好的文档-文档相关性 here .现在我正在对矩
我问的是关于 Top K 算法的问题。我认为 O(n + k log n) 应该更快,因为……例如,如果您尝试插入 k = 300 和 n = 100000000,我们可以看到 O(n + k log
这个问题与另一个问题R:sample()密切相关。 。我想在 R 中找到一种方法来列出 k 个数字的所有排列,总和为 k,其中每个数字都是从 0:k 中选择的。如果k=7,我可以从0,1,...,7中
我目前正在评估基于隐式反馈的推荐系统。我对排名任务的评估指标有点困惑。具体来说,我希望通过精确度和召回率来进行评估。 Precision@k has the advantage of not requ
我在 Python 中工作,需要找到一种算法来生成所有可能的 n 维 k,k,...,k 数组,每个数组都沿轴有一行 1。因此,该函数接受两个数字 - n 和 k,并且应该返回一个数组列表,其中包含沿
我们有 N 对。每对包含两个数字。我们必须找到最大数 K,这样如果我们从给定的 N 对中取 J (1 2,如果我们选择三对 (1,2),我们只有两个不同的数字,即 1 和 2。 从一个开始检查每个可能
鉴于以下问题,我不能完全确定我当前的解决方案: 问题: 给定一个包含 n 元素的最大堆,它存储在数组 A 中,是否可以打印所有最大的 K 元素在 O(K*log(K)) 中? 我的回答: 是的,是的,
我明白了: val vector: RDD[(String, Array[String])] = [("a", {v1,v2,..}),("b", {u1,u2,..})] 想转换成: RDD[(St
我有 X 个正数,索引为 x_i。每个 x_i 需要进入 K 组之一(其中 K 是预先确定的)。令 S_j 为 K_j 中所有 x_i 的总和。我需要分配所有 x_i 以使所有 S_j 的方差最小化。
关闭。这个问题是not reproducible or was caused by typos .它目前不接受答案。 这个问题是由于错别字或无法再重现的问题引起的。虽然类似的问题可能是on-topi
我正在研究寻找原始数的算法,看到下面的语句,我不明白为什么。 while (k*k <= n) 优于 while (k <= Math.sqrt(n)) 是因为函数调用吗?该调用函数使用更多资源。 更
我想找到一种尽可能快的方法来将两个小 bool 矩阵相乘,其中小意味着 8x8、9x9 ... 16x16。这个例程会被大量使用,所以需要非常高效,所以请不要建议直截了当的解决方案应该足够快。 对于
有没有一种惯用的方法来获取 Set和 Function ,并获得 Map实时取景? (即 Map 由 Set 和 Function 组合支持,例如,如果将元素添加到 Set ,则相应的条目也存在于 M
这个问题在这里已经有了答案: Can a local variable's memory be accessed outside its scope? (20 个答案) returning addr
给定一个矩阵:- k = [1 2 3 ; 4 5 6 ; 7 8 NaN]; 如果我想用 0 替换一个数字,比如 2,我可以使用这个:k(k==2) =
我是一名优秀的程序员,十分优秀!