作战攻略(一)"/>
第6关 K8s攻克作战攻略(一)
------> 课程视频同步分享在今日头条和B站
大家好,我是博哥爱运维,第3关我们以二进制的形式部署好了一套K8S集群,现在我们就来会会K8S吧
K8s的API对象(所有怪物角色列表)
-
Namespace – 命令空间实现同一集群上的资源隔离
-
Pod – K8s的最小运行单元
-
ReplicaSet – 实现pod平滑迭代更新及回滚用,这个不需要我们实际操作
-
Deployment – 用来发布无状态应用
-
Health Check – Readiness/Liveness/maxSurge/maxUnavailable 服务健康状态检测
-
Service, Endpoint , EndpointSlices – 实现同一lables下的多个pod流量负载均衡
-
Labels – 标签,服务间选择访问的重要依据
-
Ingress – K8s的流量入口
-
DaemonSet – 用来发布守护应用,例如我们部署的CNI插件
-
HPA – Horizontal Pod Autoscaling 自动水平伸缩
-
Volume – 存储卷
-
Pv, pvc, StorageClass – 持久化存储,持久化存储 声明,动态存储pv
-
StatefulSet – 用来发布有状态应用
-
Job, CronJob – 一次性任务及定时任务
-
Configmap, secret – 服务配置及服务加密配置
-
Kube-proxy – 提供service服务流量转发的功能支持,这个不需要我们实际操作
-
RBAC, serviceAccount, role, rolebindings, clusterrole, clusterrolebindings – 基于角色的访问控制
-
Events – K8s事件流,可以用来监控相关事件用,这个不需要我们实际操作
看了上面这一堆知识点,大家是不是有点头晕了? 别担心,上述这些小怪在后面的过关流程中均会一一遇到,并且我会也教会大家怎么去战胜它们,Let’ Go!
OK,此关卡较长,这节课我们先会会Namespace和Pod这两个小怪
Namespace
namespace命令空间,后面简称ns。在K8s上面,大部分资源都受ns的限制,来做资源的隔离,少部分如pv,clusterRole等不受ns控制,这个后面会讲到。
# 查看目前集群上有哪些ns
# kubectl get ns
NAME STATUS AGE
default Active 5d23h
kube-node-lease Active 5d23h
kube-public Active 5d23h
kube-system Active 5d23h# 通过kubectl 接上 -n namespaceName 来查看对应ns上面的资源信息
# kubectl -n kube-system get pod
NAME READY STATUS RESTARTS AGE
calico-kube-controllers-67c67b9b5f-wsvbc 1/1 Running 3 (15m ago) 5d23h
calico-node-4tvt5 1/1 Running 3 (15m ago) 5d23h
calico-node-lgsl6 1/1 Running 3 (15m ago) 5d23h
calico-node-pd8p5 1/1 Running 3 (15m ago) 5d23h
calico-node-znr7x 1/1 Running 3 (15m ago) 5d23h
coredns-65bc7b648d-65qjh 1/1 Running 3 (15m ago) 5d23h
metrics-server-56774d6954-cvwlz 1/1 Running 3 (15m ago) 5d23h
node-local-dns-44z58 1/1 Running 3 (15m ago) 5d23h
node-local-dns-6rdwx 1/1 Running 3 (15m ago) 5d23h
node-local-dns-dmstw 1/1 Running 3 (15m ago) 5d23h
node-local-dns-lwd68 1/1 Running 3 (15m ago) 5d23h# 我们通过不接-n 的情况下,都是在默认命令空间default下进行操作,在生产中,通过测试一些资源就在这里进行
# kubectl get pod
NAME READY STATUS RESTARTS AGE
new-nginx-854cf59647-26bnh 2/2 Running 0 2s
new-nginx-854cf59647-98n9w 2/2 Running 0 2s# kubectl -n default get pod
NAME READY STATUS RESTARTS AGE
new-nginx-854cf59647-26bnh 2/2 Running 0 37s
new-nginx-854cf59647-98n9w 2/2 Running 0 37s# 创建也很简单
[root@node-1 ~]# kubectl create ns test
namespace/test created
[root@node-1 ~]# kubectl get ns|grep test
test # 删除ns
# kubectl delete ns test
namespace "test" deleted
生产中的小技巧:k8s删除namespaces状态一直为terminating问题处理
# kubectl get ns
NAME STATUS AGE
default Active 5d4h
ingress-nginx Active 30h
kube-node-lease Active 5d4h
kube-public Active 5d4h
kube-system Active 5d4h
kubevirt Terminating 2d2h # <------ here1、新开一个窗口运行命令 kubectl proxy
> 此命令启动了一个代理服务来接收来自你本机的HTTP连接并转发至API服务器,同时处理身份认证2、新开一个终端窗口,将下面shell脚本整理到文本内`1.sh`并执行,$1参数即为删除不了的ns名称
#------------------------------------------------------------------------------------
#!/bin/bashset -eo pipefaildie() { echo "$*" 1>&2 ; exit 1; }need() {which "$1" &>/dev/null || die "Binary '$1' is missing but required"
}# checking pre-reqsneed "jq"
need "curl"
need "kubectl"PROJECT="$1"
shifttest -n "$PROJECT" || die "Missing arguments: kill-ns <namespace>"kubectl proxy &>/dev/null &
PROXY_PID=$!
killproxy () {kill $PROXY_PID
}
trap killproxy EXITsleep 1 # give the proxy a secondkubectl get namespace "$PROJECT" -o json | jq 'del(.spec.finalizers[] | select("kubernetes"))' | curl -s -k -H "Content-Type: application/json" -X PUT -o /dev/null --data-binary @- http://localhost:8001/api/v1/namespaces/$PROJECT/finalize && echo "Killed namespace: $PROJECT"
#------------------------------------------------------------------------------------3. 执行脚本删除
# bash 1.sh kubevirt
Killed namespace: kubevirt
1.sh: line 23: kill: (9098) - No such process5、查看结果
# kubectl get ns
NAME STATUS AGE
default Active 5d4h
ingress-nginx Active 30h
kube-node-lease Active 5d4h
kube-public Active 5d4h
kube-system Active 5d4h
Pod
开篇先来个加人头秘籍(上上下下左右左右BABA,知道这个游戏的朋友请举个手^ o ^)
kubectl作为管理K8s的重要cli命令行工具,运维人员必须掌握它,但里面这么多的子命令,记不住怎么办?这里就以创建pod举例
擅用 -h
帮助参数
# 在新版本的K8s中,明确了相关命令就是用来创建对应资源的,不再像老版本那样混合使用,这个不是重点,创建pod,我们用kubectl run -h,来查看命令帮助,是不是豁然开朗
# kubectl run -h
Create and run a particular image in a pod.Examples:# Start a nginx pod.kubectl run nginx --image=docker.io/library/nginx:1.21.6......# 我们就用示例给出的第一个示例,来创建一个nginx的pod
# kubectl run nginx --image=docker.io/library/nginx:1.21.6
pod/nginx created# 等待镜像下载完成后,pod就会正常running了(这里介绍两个实用参数 -w代表持久监听当前namespace下的指定资源的变化;-o wide代表列出更为详细的信息,比如这里pod运行的node节点显示)
# 注: READY下面的含义是后面数字1代表这个pod里面期望的容器数量,前面的数字1代表服务正常运行就绪的容器数量
# kubectl get pod -o wide -w
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx 1/1 Running 0 100s 172.20.139.68 10.0.1.203 <none> <none># 我们来请求下这个pod的IP
# curl 172.20.139.68
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p><p>For online documentation and support please refer to
<a href="/">nginx</a>.<br/>
Commercial support is available at
<a href="/">nginx</a>.</p><p><em>Thank you for using nginx.</em></p>
</body>
</html># 我们进到这个pod服务内,修改下页面信息看看,这里会学到exec子命令,-it代表保持tty连接,不会一连上pod就断开了
# kubectl -it exec nginx -- bash
# echo 'hello, world!' > /usr/share/nginx/html/index.html
# exit# curl 172.20.139.68
hello, world!# 我们来详细分析的这个pod启动的整个流程,这里会用到kubectl的子命令 describe,它是用来描述后面所接资源的详细信息的,划重点,这个命令对于我们生产中排查K8s的问题尤其重要
# kubectl describe pod nginx
Name: nginx
Namespace: default
Priority: 0
Service Account: default
Node: 10.0.1.203/10.0.1.203
Start Time: Tue, 24 Oct 2023 21:43:38 +0800
Labels: run=nginx
Annotations: <none>
Status: Running
IP: 172.20.139.68
IPs:IP: 172.20.139.68
Containers:nginx:Container ID: containerd://184b225e3e83650a4700959536e0e2d444ffe416b4fd5cce8c9c6ee209d14cb9Image: docker.io/library/nginx:1.21.6Image ID: docker.io/library/nginx@sha256:2bcabc23b45489fb0885d69a06ba1d648aeda973fae7bb981bafbb884165e514Port: <none>Host Port: <none>State: RunningStarted: Tue, 24 Oct 2023 21:43:39 +0800Ready: TrueRestart Count: 0Environment: <none>Mounts:/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-2gmsh (ro)
Conditions:Type StatusInitialized TrueReady TrueContainersReady TruePodScheduled True
Volumes:kube-api-access-2gmsh:Type: Projected (a volume that contains injected data from multiple sources)TokenExpirationSeconds: 3607ConfigMapName: kube-root-ca.crtConfigMapOptional: <nil>DownwardAPI: true
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300snode.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:Type Reason Age From Message---- ------ ---- ---- -------Normal Scheduled 3m35s default-scheduler Successfully assigned default/nginx to 10.0.1.203Normal Pulled 3m35s kubelet Container image "docker.io/library/nginx:1.21.6" already present on machineNormal Created 3m35s kubelet Created container nginxNormal Started 3m35s kubelet Started container nginx# 重点分析下最后面的Events事件链
1. kubectl 发送部署pod的请求到 API Server
2. API Server 通知 Controller Manager 创建一个 pod 资源
3. Scheduler 执行调度任务,Events的第一条打印信息就明确显示了这个pod被调度到10.0.1.203这个node节点上运行,接着开始拉取相应容器镜像,拉取完成后开始创建nginx服务,至到最后服务创建完成,在有时候服务报错的时候,这里也会显示相应详细的报错信息
但我们在生产中是不建议直接用来创建pod,先直接演示下:
# 我们删除掉这个nginx的pod
# kubectl delete pod nginx
pod "nginx" deleted# kubectl get pod
现在已经看不到这个pod了,假设这里是我们运行的一个服务,而恰好运行这个pod的这台node当机了,那么这个服务就没了,它不会自动飘移到其他node上去,也就发挥不了K8s最重要的保持期待服务运行数量的服务特性了。
pod小怪战斗(作业)
# 试着创建一个redis服务的pod,并且使用exec进入这个pod,通过客户端命令redis-cli连接到redis-server ,插入一个key a ,value 为666,最后删除这个redis的pod
root@redis:/data# redis-cli
127.0.0.1:6379> get a
(nil)
127.0.0.1:6379> set a 666
OK
127.0.0.1:6379> get a
"666"
更多推荐
第6关 K8s攻克作战攻略(一)
发布评论