第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   # <------ here

1、新开一个窗口运行命令  kubectl proxy
> 此命令启动了一个代理服务来接收来自你本机的HTTP连接并转发至API服务器,同时处理身份认证

2、新开一个终端窗口,将下面shell脚本整理到文本内`1.sh`并执行,$1参数即为删除不了的ns名称
#------------------------------------------------------------------------------------
#!/bin/bash

set -eo pipefail

die() { echo "$*" 1>&2 ; exit 1; }

need() {
        which "$1" &>/dev/null || die "Binary '$1' is missing but required"
}

# checking pre-reqs

need "jq"
need "curl"
need "kubectl"

PROJECT="$1"
shift

test -n "$PROJECT" || die "Missing arguments: kill-ns <namespace>"

kubectl proxy &>/dev/null &
PROXY_PID=$!
killproxy () {
        kill $PROXY_PID
}
trap killproxy EXIT

sleep 1 # give the proxy a second

kubectl 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 process

5、查看结果
# 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="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</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://184b225e3e83650a4700959536e0e2d444ffe416b4fd5cce8c9c6ee209d14cb9
    Image:          docker.io/library/nginx:1.21.6
    Image ID:       docker.io/library/nginx@sha256:2bcabc23b45489fb0885d69a06ba1d648aeda973fae7bb981bafbb884165e514
    Port:           <none>
    Host Port:      <none>
    State:          Running
      Started:      Tue, 24 Oct 2023 21:43:39 +0800
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-2gmsh (ro)
Conditions:
  Type              Status
  Initialized       True
  Ready             True
  ContainersReady   True
  PodScheduled      True
Volumes:
  kube-api-access-2gmsh:
    Type:                    Projected (a volume that contains injected data from multiple sources)
    TokenExpirationSeconds:  3607
    ConfigMapName:           kube-root-ca.crt
    ConfigMapOptional:       <nil>
    DownwardAPI:             true
QoS Class:                   BestEffort
Node-Selectors:              <none>
Tolerations:                 node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                             node.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.203
  Normal  Pulled     3m35s  kubelet            Container image "docker.io/library/nginx:1.21.6" already present on machine
  Normal  Created    3m35s  kubelet            Created container nginx
  Normal  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"
  • 5
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值