k8s_day02_02

k8s_day02_02

​ k8s 的核心目标就是 以应用为中心来组织围绕更好地以容器化的方式运行应用

​ 一个pod 代表着,一组关联度非常高的容器

​ 现代容器设计的核心理念 就是一个容器内只运行一个应用,但有些应用的进程进程内部没有什么依赖关系,或者存在人为按需要施加的关系,显得比较亲密,比如日志agent 和容器自身的应用。

​ sidecar: 小日本摩托车的跨斗, sidecar 不是车的主体,但是有用,额外的容器为主容器提供辅助功能,就成了主容器的sidecar,为了让容器同进同退的绑定在一起,就把他们组织成为了一个Pod, 在k8s上这是容器设计的模式之一,还有Adapter、ambassador 等等, 在k8s 的应用管理模型中,容器存在关系,是由容器编排系统管理的:

  • 亲密关系: container to contianer
    在一个pod 中,不仅同进同退,还共享 Network、IPC、UTS (主机名)等名称空间、一组存储卷,存储卷不是容器级别而是pod 级别,主容器的日志放在存储卷上,sidecar 的容器也可以挂载相同的存储卷,sidercar 就可以收集日志了
    image-20211130113221830如图所示,绿色的背景代表这2个container共享名称空间, Pause 也是一个容器,叫(pod的)基础设施容器,Insfratrure Pod, Pause 中文意思为暂停, 它里面什么都没有运行 ,只是为Pod 内的其他容器提供可被加入共享的主机名称空间 ipc名称空间、utc 名称空间,pod 内所共享的存储卷也是附加在Pause上,这时发现pod 是不是像是一个被封装的虚拟机? 共享文件系统,但是并不是所有的容器可以被随便被组合成一个pod,在k8s的设计中,要求必须是亲密关系的容器。如LNMP 架构的所使用的容器,就不算亲密关系 ,它们最多算是服务调用,只有那些如果不通过IO接口 或者不共享存储卷 就无法更好的协同工作,就人为是亲密的。非亲密的容器 各是各的的Pod

  • 非亲密:

    pod to pod:

    借助网络插件实现 ,既需要解决跨和不跨主机的pod通信问题

​ 亲密与非亲密关系的Pod 的容器之间如何通信呢?

​ 同一Pod内的容器通信 ,通过localhost io 接口就行(相当于本来就在同一机器上)

​ 非同一Pod内的容器通信 ,又分为pod是否在统一节点

​ 同一个节点的Pod:
​ 在传统的组织模型中 ,同一主机的容器共享一个网桥

image-20211130120448168

​ 只要在同一网段内 容器c1【pod1】 、容器c3【pod3】,依靠共同的bridge 就能通信。p1 和p3 只能通过 叠加或者承载网络来实现,因此Pod之间通信依靠网络插件,跨主机的需要,同一个主机内的pod 通信也需要,,因为同一个主机的pod使用了cni 网桥

5: cni0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UP group default qlen 1000
    link/ether 4e:e1:0e:42:10:04 brd ff:ff:ff:ff:ff:ff
    inet 10.244.5.1/24 brd 10.244.5.255 scope global cni0
       valid_lft forever preferred_lft forever
    inet6 fe80::4ce1:eff:fe42:1004/64 scope link 
       valid_lft forever preferred_lft forever
       
       
[root@node01 ~]# brctl  show
bridge name	bridge id		STP enabled	interfaces
cni0		8000.4ee10e421004	no		veth19842651
							veth7bdc51c9
							vethf3c75062
docker0		8000.024274fe1cf6	no		
[root@node01 ~]# 

​ 因为网络插件又建立一个特殊的桥cni0, 创建的flannel 会生成这个桥。docker 创建的容器都部署在这个docker0 桥,对于部署了flannel插件的k8s 来说,插件的pod 都会关联在这cni 桥而不是docker0 桥,每个pod同样会创建一对虚拟网卡,一半放在 pod内,一半放在cni网桥上

​ 部署了flannel后,每个主机还有一个特殊接口flannel.1 ,这是一个隧道接口。 点1 是隧道标识。 P1 和P2 通信时,发出的报文会先经过cni 桥, 然后到达ip 隧道接口==【隧道接口是附着在物理网卡上的】==,再通过物理网卡 把报文发出去,对端的隧道是相反的过程。隧道报文需要封装一个多余的IP 头,但是会产生巨型帧。 当然如果是承载网络就不用隧道

pod to servcie :

​ iptables 、或者ipvs 规则实现。 每个节点都有kube-proxy 组件 ,每个节点的kube-proxy 会把所有的service定义转为本地ipvs 或者iptables 规则

NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
demoapp      ClusterIP   10.107.176.51   <none>        80/TCP    5d12h
kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP   5d14h
[root@node01 ~]# 

也就是说service 的cluster ip 会出现在所有的主机iptables 规则上

借入节点网络 引入外部流量的两种不同方式

external client 到 service or pod

  • host network 直接共享宿主机的网络名称空间,pod 监听的端口就是宿主机的端口
  • 由service 引入

控制器和pod 之间的关系

image-20211130151738684

​ 控制器 使用标签选择器关联到pod 上 ,定义一个控制器,通常就是指定几个副本,deployment 控制器更具 模板(pod template)来创建容器. kubelet 也会运行 control loop 监视pod 健康状态报告给 apiserver , deloyment 也会监视apiserver 知道那个pod 和自己相关,所以缺少一个创建一个
image-20211130185352626

​ master 上运行着控制组件 controller manager , controller manager 中有很多控制器,其中一个叫 deployment , deployment 就是一个 control loop . deployment 会注册监听到 apiserver 上 所有deployment 自己所有资源,deployment 会让apiserver 把所有和 deployment 相关的变动都告诉自己

​ 每个节点上 运行kubelet 与apiserver 联络 ,监视与自己相关pod 的变动信息。比如创建了一个dempapp 控制器的 资源。也叫 控制器数据项 ,控制器数据项 会被 deployment 控制循环一圈一圈监视着, 控制器数据项 定义了比如 pod 数量3个 ,pod 模板 等等。 apiserver如果发现集群中没有3个 pod , 就会在apiserver 上基于pod模板创建3个数据项,apiserver 存入这3个数据项后, scheduler 如果发现没有被调度,就会选择一个节点 调度并且存回apiserver,其中一个节点的kubeket发现其中一个pod 分配给自己,就会拉取这个pod相关的镜像并且用docker启动一个pod。如果apiserver 发现kubelet 没了(还有叫节点控制器的),那么这一个节点上的pod 相当于没了, apiserver 就会把这些相关的pod 数据项标记为删除,deploy 发现pod数量少了 ,就会再申请创建

​ 把管理pod 运行的控制器 叫做pod 控制器

无论是service 还是控制器 ,都需要靠 标签选择器与pod 建立联系

k8s apiserveri 提供的是restful 风格的接口 ,它把一切一切的内部的概念 抽象为 资源

资源: 可以理解为表或者数据规范的定义schema

资源类型: Pod 、Deployment 、 service 【可以理解为存这3种资源的3张表】

pod 的资源类型是什么呢 ? 可能是定义了 pod名称 pod使用的容器的镜像等等

这个表 每创建一个数据项 ,相当于 创建了一个具体资源下的实体,这个数据项必须由kubelet 运行起来容器才算是执行了

运行一个pod 就是按照pod 表的定义插入一个数据项

当然之前是用 deployement 创建的pod, 也是同理

在restful 类型的接口当中,同一类型的对象可能有一堆,他们也有一个统一的称呼叫列表,比如所有的pod 就叫Podlist ,所有 deployement 就叫 deployementList.

如果想往apiserver 这个表插入数据 ,需要调用 apiserver 的api ,需要编程实现。为了方便运维管理,所以有了工具kubectl kubectl 就是k8s apiserver 的专用命令行客户端

kubectl 向这表插数据有3种方式:

一、命令式命令

​ 通过命令, 及其选项(从选项中读取配置数据来实现)

二、命令式配置文件 【指的就是配置清单文件】

​ 通过命令,从配置文件加载配置数据

三、声明式配置文件

​ 声明式命令,从配置文件中加载配置数据

通用资源定义格式: 在k8s 叫 资源规范,放资源规范的文件叫配置清单

apiversion: ...  #资源对象所属的api 群组 及版本

kind: ...  资源类型 (认为是表类型)

metadata: ...  资源对象的原数据  【主要是资源的名称、标签】

spec: ...    #所需状态, 或称为期望状态  【认为是  插入表的所有数据】

kubectl api-versions 查看当前k8s 所支持的api 的版本和api所api 所属的群组

k8s 上的资源类型特别多,但是有些资源具有相关性,有些资源具有相关性,有些资源不具有相关性,为了方便管理,k8s按照资源类型的相关性分成了很多组,每个组可以自行演进,就是每个组可以到v1/v2/v3 和另外组没有关系,避免了一个组的版本更新,其他组版本被迫都得跟着演进

版本分为三种

v1 表示稳定正式版:长期可使用
v1beta1 表示表示公测版本,表示可以放在互联网上供大家使用,但是可能仍然不稳定

alpha 版:表示内测版本,内部测试版

[root@master01 ~]# kubectl  api-versions
admissionregistration.k8s.io/v1
admissionregistration.k8s.io/v1beta1
apiextensions.k8s.io/v1
apiextensions.k8s.io/v1beta1
apiregistration.k8s.io/v1
apiregistration.k8s.io/v1beta1
apps/v1

kubectl explain查看资源的版本

查看pod 版本

[root@master01 ~]# kubectl  explain   pod
KIND:     Pod
VERSION:  v1

,这里的version 只有v1 表示 pod是核心群组 ,组名是core ,可以省略, kubectl api-versions 最后一条就是

[root@master01 ~]# kubectl  api-versions |tail -1
v1
[root@master01 ~]# 

例子创建一个pod

[root@master01 ~]# cat  mypod.yml 
apiVersion: v1
kind: Pod
metadata:
  name: mypod
  labels:
    app: mypod
    release: canary
spec:
  containers:
  - name: demoapp
    image: ikubernetes/demoapp:v1.0
    
    
[root@master01 ~]# kubectl  create -f  mypod.yml 
pod/mypod created

apiVersion 要顶格写,kind 类型的资源首字母要大写 , 如Pod

注意:

上面的pod 没有被控制器管理 ,所以一删除就没了,这种叫裸pod ,或者自主式pod ,一旦发生故障kubelet 会自动重启,但是一旦删除或者节点被删除是不会被创建的

查看指定pod

[root@master01 ~]# kubectl get po mypod
mypod   1/1     Running   0          5m58s
[root@master01 ~]# kubectl get po mypod -o wide
NAME    READY   STATUS    RESTARTS   AGE    IP            NODE     NOMINATED NODE   READINESS GATES
mypod   1/1     Running   0          6m5s   10.244.5.11   node01   <none>           <none>

查看pod 的标签

[root@master01 ~]# kubectl get po mypod  --show-labels
NAME    READY   STATUS    RESTARTS   AGE     LABELS
mypod   1/1     Running   0          6m22s   app=mypod,release=canary
[root@master01 ~]# 

查看资源pod的完整信息(规范格式 资源清单) ,以yaml 格式输出

[root@master01 ~]# kubectl get po   mypod  -o yaml
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: "2021-11-30T10:26:02Z"
  labels:
    app: mypod
    release: canary
  name: mypod
  namespace: default
  resourceVersion: "79480"
  selfLink: /api/v1/namespaces/default/pods/mypod
  uid: 38a60c12-5c3a-4e2c-8478-b23e7023b4bf
spec:

。。。。

发现一些其他的信息 ,我们没有定义也出来了 ,那些没写的相当于是使用了默认值, 因此在建立时 可向必选的关键字段赋值 ,其他的使用默认值 ,如果默认值不符合规范也可以修改自定义。

您好!要在Kubernetes上部署snmp_exporter,您可以按照以下步骤进行操作: 1. 首先,创建一个部署文件(deployment.yaml),内容如下: ```yaml apiVersion: apps/v1 kind: Deployment metadata: name: snmp-exporter spec: replicas: 1 selector: matchLabels: app: snmp-exporter template: metadata: labels: app: snmp-exporter spec: containers: - name: snmp-exporter image: prom/snmp-exporter ports: - containerPort: 9116 args: - "--config.file=/etc/snmp_exporter/snmp.yml" volumeMounts: - name: config-volume mountPath: /etc/snmp_exporter volumes: - name: config-volume configMap: name: snmp-config ``` 2. 创建一个配置文件(configmap.yaml),内容如下: ```yaml apiVersion: v1 kind: ConfigMap metadata: name: snmp-config data: snmp.yml: | version: 2c communities: - community_string: public target_oids: - .1.3.6.1.2.1.2.2.1.10 ``` 此配置文件示例设置了SNMP版本为2c,使用公共社区字符串(public)并监视了接口的入站字节数。您可以根据需要进行修改。 3. 使用kubectl命令进行部署: ```shell kubectl apply -f deployment.yaml kubectl apply -f configmap.yaml ``` 这将创建一个名为"snmp-exporter"的部署,并创建一个名为"snmp-config"的配置映射。 4. 部署完成后,您可以通过访问snmp-exporter服务的IP地址和端口(默认为9116)来访问snmp_exporter的指标数据。 ```shell kubectl get services ``` 您应该能够看到"snmp-exporter"服务的外部IP地址。使用该IP地址和端口号,您可以使用Prometheus或其他监控工具来获取和可视化snmp_exporter的指标数据。 希望这对您有所帮助!如有任何问题,请随时问我。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值