k8s_day02_03

image-20211201100651715

​ 如图,k8s 的用户 群体分为两类,一类是是应用程序客户端,它们访问集群pod 上应用服务的,是来自集群外部引入的流量,主要靠2种方式来引入流量,一种是nodeport 类型的service ,另一种是借助ingress 控制器来引入,ingress 也是转发给service 背后的pod 来实现的。 如果客户端是通过nodeport 进来的,会借助service的调度算法到达pod ,如果通过ingress 入站 ,会借助ingress调度算法 直接到达pod 而不经过service。但是ingress 会借助service识别一个服务背后所有pod 资源有哪些个,并且根据sevice 上端点的变动,来确保ingress 之上资源的变动

​ 第二类是开发或者运营来使用,他们很少去直接去访问应用,而是去和apIserver 打交道的,向apIserver 发送指令,通过kubectl 客户端或者 自己编写程序调用apiserver 暴露的restful 风格的api来实现,通常是做些管理类的操作,如pod、service 的增删改查到达

apiserver 其实就是一个 restful 风格的api ,以https 协议向外提供服务 借助restful 这种模型,他把内部管理的组件绝大部分抽象为资源

资源类型就是类似mysql 数据库中的一个表, 可以完全认为就是schema。 pod 、service、deployment 都是

​ schema 可以存入各种数据 对象,object【或者把它称为资源,实例化出来的数据项】

​ 实例的过程中就要遵循资源规范,不同的资源类型就有不同的资源规范,资源规范 更像是schema 的概念, 无论哪种资源规范都遵循以下几个部分:apiVsersion 、kind 、metadata、spec、status【这个字段不是由用户定义的,而是集群管理的,被称为资源的实际状态】其实就是字典格式的数据项

​ 在k8s 中,控制器的工作模式是声明式的,或者来说支持的api 是声明式的api

控制器 负责将实际状态设定不断逼近或等同于期望状态

​ 比如我们创建的deployment 之后希望它有3个pod, 那么controller 就确保这3个pod必须存在,如果不存在就一遍一遍的尝试创建。

​ 控制通过控制循环 Control Loop 确保用户所定义的期望状态 ,与实际状态二者是一样的(逼近等同于)

如果二者稍微不一样,控制器就马上起来工作了,比如用户删除了一个资源,控制器就负责删除这个资源

​ 大体以下就三个操作:create delete change

在云原生时代,强调以应用为中心,k8s 资源模型的设计 也是反映了这种理念

image-20211201110956897

Pod 是核心应用,后续其他所有的资源类型 都是为了满足它Pod 能正常运行而设定

PDB: pod disruption budget pod 中断预算

控制器类型的相关资源:deployment、 daemonset、replicaset、statefulset 作业相关的控制器cronjob、job

HPA: horizontal pod autoscaler 自动完成资源伸缩 水平伸缩

VPA: vertical pod autoscaler 自动完成资源伸缩 垂直伸缩

ConfigMap: 配置类型存储卷

PVC: 真正能存数据的存储卷

Secret:

DownloadAPI: 能向Pod 注入环境信息的存储卷

k8 有很多种资源,可以分成以下几类:
1.工作负载型:

​ workload 主要就是Pod

​ 应用分成两类 有状态(stateful)、和无状态应用(stateless)

​ deployment :有状态应用的控制器: deployment 是最著名的无状态应用编排工具, 提供了声明式配置,他提供应用规模的自动扩容、缩容、自动更新、金丝雀发布,甚至编排得当 还有可能支持 蓝绿部署的效果

​ Daemonset:如果我们在每一个节点 只能运行一个多个有限的应用,那么用Daemonset, Daemonset 一般是用于编排无状态的系统级应用的,比如我们现在需要在每个节点上部署一个日志采集器之类的

​ Statefulset: 如果编排有状态的应用就用Statefulset , 但是很遗憾的是用Statefulset 根本没有发挥功用的余地, 因为只是提供了基本框架,【因为比如构建有状态的redis、mysql 主从过程是不一样的 】, 距离提供终态的那种拿来能用的还差得远 ,因此人们通常要管理有状态的应用 都是用的是Statefulset 的下一代,不具有通用性质的operator

​ Job 和cronjob 也是工作负载型资源

​ job: 单次运行完就结束的应用 比如备份

​ cronjob: 周期型的作业 就用cronjob 来实现

2、服务发现和负载均衡型:

​ service 和 ingress

3、配置和存储型

volume :

​ configmap 向应用注入配置文件 secret 向应用注入敏感信息的,比如私钥证书密码之类的

pvc/pv :

​ pv: 持久存储卷 ,通常都是网络存储 ,比如 NFS、glusterfs、Ceph 等等

pvc: 借助存储卷(pv)请求 , 从而为pod绑定外部的存储空间

DonwardAPI: 为环境注入API 的

4、集群级别【全局级别】资源:

​ 比如pv,还有 namespace 、 node、rcluster role

在k8s上 ,资源的作用域 分成2种级别:

整个k8s 称为全局级别

namespace 级别:

比如role、rolebinding …名称空间,可以理解为系统的目录文件夹,同一目录下的资源不能同名,但是不同目录下的资源可以同名,隔离了名字的作用域,所以叫名称空间 名称空间级别资源 只能创建在名称空间内如pod

6、元数据类型:

​ LimitRange

在k8s ,每个资源有个特定的URL被组织在特定路径下,比如访问 URL得到相应的资源

例子URL:

apiserver_ip:port/apis/组名/版本名称/名称空间复数/具体名称空间名字/资源类型名称/资源名称

/api/GROUP/VERSION/namespaces/NAMEPACE/pods/POD_NAME (替换大 写字母即可)

[root@master01 ~]#  kubectl  get  --raw /api/v1/namespaces/default/pods/mypod
{"kind":"Pod","apiVersion":"v1","metadata":{"name":"mypod","namespace":"default","self

核心群组的开头用api而不是apis

kubectl 为什么不写 apI地址端口 ,是因为家目录下的.kube 目录 中的config 配置文件中已经写好了

–raw 表示以json格式 展示

[root@master01 ~]# kubectl  get --raw   /apis/apps/v1/namespaces/default/deployments/demoapp

image-20211201162238521

以jq 命令显示 的会更好看一点

[root@master01 ~]#yum install  jq

[root@master01 ~]# kubectl  get --raw  /apis/apps/v1/namespaces/default/deployments/demoapp|jq
{
  "kind": "Deployment",
  "apiVersion": "apps/v1",
  "metadata": {
    "name": "demoapp",
    "namespace": "default",
    "selfLink": "/apis/apps/v1/namespaces/default/deployments/demoapp",
    "uid": "d418e7b5-bcbb-4ede-8416-36bcdba6991b",
    "resourceVersion": "34348",
    "generation": 2,
    "creationTimestamp": "2021-11-24T18:04:55Z",
    "labels": {


[root@master01 ~]# kubectl  get --raw  /apis/apps/v1/namespaces/default/deployments/demoapp|jq .metadata.name
"demoapp"
[root@master01 ~]# 

[root@master01 ~]# kubectl  get all
NAME                           READY   STATUS        RESTARTS   AGE
pod/demoapp-5f7d8f9847-46qbg   1/1     Running       1          36h
pod/demoapp-5f7d8f9847-5bb96   1/1     Running       1          36h
pod/demoapp-5f7d8f9847-c5bbk   1/1     Terminating   0          6d23h
pod/demoapp-5f7d8f9847-ggk9j   1/1     Terminating   0          6d23h
pod/demoapp-5f7d8f9847-wxz7l   1/1     Running       2          6d23h
pod/mypod                      1/1     Running       1          31h

NAME                 TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
service/demoapp      ClusterIP   10.107.176.51   <none>        80/TCP    6d23h
service/kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP   7d1h

NAME                      READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/demoapp   3/3     3            3           6d23h

NAME                                 DESIRED   CURRENT   READY   AGE
replicaset.apps/demoapp-5f7d8f9847   3         3         3       6d23h

replicaset 亦是此从

[root@master01 ~]# kubectl get  --raw /apis/apps/v1/namespaces/default/replicasets/demoapp-5f7d8f9847

直接curl 是不行的 因为没有证书

[root@master01 ~]# curl  https://kubeapi.magedu.com:6443/apis/apps/v1/namespaces/default/replicasets/demoapp-5f7d8f9847
curl: (60) Peer's Certificate issuer is not recognized.

可以通过kubectl 内建的命令实现 kube proxy 构建http 代理实现ssL 的卸载

[root@master01 ~]#  kubectl   |grep proxy
  proxy         Run a proxy to the Kubernetes API server
[root@master01 ~]# 

kubectl 是k8 最为重要的一个工具, 也就是操作数据库(etcd)中数据项的工具

kubectl 在与apiserver 构建联系时会自动加载~/kube/config 文件,如果不用这个文件,自己也可以手动指定

[root@master01 ~]# kubectl  options|grep config=
      --kubeconfig='': Path to the kubeconfig file to use for CLI requests.

但是curl 无法读取配置文件,curl 只能通过访问http 实现

[root@master01 ~]#  kubectl    proxy
Starting to serve on 127.0.0.1:8001

[root@master01 ~]# curl 127.0.0.1:8001/apis/apps/v1/namespaces/default/replicasets/demoapp-5f7d8f9847
{
  "kind": "ReplicaSet",
  "apiVersion": "apps/v1",
  "metadata": {
    "name": "demoapp-5f7d8f9847",
    "namespace": "default",
    "selfLink": "/apis/apps/v1/namespaces/default/replicasets/demoapp-5f7d8f9847",
    "uid": "0ba8e0cc-7a89-400b-8e57-9a0ff1f0b4cd",
    "resourceVersion": "150308",
    "generation": 2,
    "creationTimestamp": "2021-11-24T18:04:55Z",
    "labels": {
      "app": "demoapp",

总结 apiserver 就是一个http服务器,所有数据传输就是通过https 完成的

kubectl create 就是http post 请求

查看资源定义格式

[root@node01 ~]#  kubectl explain po
apiVersion	<string>
metadata	<Object>

发现不同的字段, 他们的所属类型也不一样,凡是类型是obejct 的都可以请求它的二级字段

如下:

[root@node01 ~]#  kubectl explain po.metadata、
[root@node01 ~]#  kubectl explain po.spec
   containers	<[]Object> -required-
     List of containers belonging to the pod. Containers cannot currently be
     added or removed. There must be at least one container in a Pod. Cannot be
     updated.

<[]Object> 表示为对象为列表类型,改资源是列表项可以写多个,并且 仍然可以请求它的下一级字段

spec:
containers:
  - name: demoapp
    image: ikubernetes/demoapp:v1.0
  - name: nginx
    image: nginx:1.16-alpine

required 表示必选字段

[root@node01 ~]#  kubectl explain po.spec.containers

快速创建资源的方法,以之前的资源输出后修改即可

[root@master01 ~]# kubectl  get  po  mypod -o yaml > testpod.yaml

资源的引用种格式

1、<type>/<name> 如pods/testpod pods/mypod deployments/pod

2、<type><name> 如 pods mypod

区别就是 如果同时引用多个资源时 ,第二种 type 后的所有内容 都会被看成一个最开头的type,而第一种不会且可以同时表示 不同type 的资源

删除所有pod

[root@master01 ~]# kubectl delete po  --all
pod "demoapp-5f7d8f9847-lcvtq" deleted
pod "demoapp-5f7d8f9847-ldz24" deleted
pod "demoapp-5f7d8f9847-r568r" deleted
pod "mypod" deleted

查看pod 容器日志

当pod 内只有一个容器时

[root@master01 ~]# kubectl  logs  po/mypod 
 * Running on http://0.0.0.0:80/ (Press CTRL+C to quit)

有多个容器时 ,需要使用-c 指定查看那个容器

查看资源的状态信息

[root@master01 ~]# kubectl  describe  po/demoapp-5f7d8f9847-4t7sk 

Controlled By:  ReplicaSet/demoapp-5f7d8f9847

可以看到被哪些控制器控制

kubectl exec 类似 docker exec ,作用就是进入pod中的容器 ,如果有多个容器时,使用指定-c 指定

‘-- ’ 双横线表示的就是隔离作用,双横线 是要在容器内执行的命令

[root@node01 ~]# kubectl   exec  --help
Execute a command in a container.

Examples:
  # Get output from running the 'date' command from pod mypod, using the first container by default
  kubectl exec mypod -- date

例子

[root@node01 ~]# kubectl   exec  -it  mypod  -- /bin/sh
[root@mypod /]# ifconfig
eth0      Link encap:Ethernet  HWaddr CE:BA:62:C6:15:3B  
          inet addr:10.244.5.225  Bcast:10.244.5.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1450  Metric:1
          RX packets:6 errors:0 dropped:0 overruns:0 frame:0
          TX packets:1 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:488 (488.0 B)  TX bytes:42 (42.0 B)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

[root@mypod /]# netstat -tnl
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      
[root@mypod /]# curl 127.0.0.1:80
iKubernetes demoapp v1.0 !! ClientIP: 127.0.0.1, ServerName: mypod, ServerIP: 10.244.5.225!
[root@mypod /]# 

资源类型

1、名称空间

k8s 是一个restful 风格的接口,每一个资源的常见对象就是增【create】删【delete】改【】查【get describe】, 因此这些命令移入到ns也是可以的

查询所有名称空间

[root@node01 ~]#  kubectl get ns
NAME              STATUS   AGE
default           Active   6d22h
kube-node-lease   Active   6d22h
kube-public       Active   6d22h
kube-system       Active   6d22h
[root@node01 ~]# 

查看特定某个名称空间的数据项信息

[root@node01 ~]# kubectl get ns/default -o yaml
apiVersion: v1
kind: Namespace
metadata:
  creationTimestamp: "2021-11-24T16:26:50Z"
  name: default
  resourceVersion: "156"
  selfLink: /api/v1/namespaces/default
  uid: 6d9250c6-7bf5-4383-890b-7110d90c65e1
spec:
  finalizers:
  - kubernetes
status:
  phase: Active
[root@node01 ~]# 

创建ns

[root@node01 ~]# kubectl  explain  ns.spec
KIND:     Namespace
VERSION:  v1

RESOURCE: spec <Object>

DESCRIPTION:
     Spec defines the behavior of the Namespace. More info:
     https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status

     NamespaceSpec describes the attributes on a Namespace.

FIELDS:
   finalizers	<[]string>
     Finalizers is an opaque list of values that must be empty to permanently
     remove object from storage. More info:
     https://kubernetes.io/docs/tasks/administer-cluster/namespaces/

[root@node01 ~]# 

发现ns spec里面只有一个字段finalizers 非reqiured 所以可以不写

最终结果如下

[root@node01 ~]# kubectl  create -f dev-ns.yml 
namespace/dev created
[root@node01 ~]# cat dev-ns.yml 
apiVersion: v1
kind: Namespace
metadata:
  name: dev
[root@node01 ~]# 

验证:

AGE 表示创建到至今的年龄

[root@node01 ~]# kubectl  get ns
NAME              STATUS   AGE
default           Active   6d23h
dev               Active   60s
kube-node-lease   Active   6d23h
kube-public       Active   6d23h
kube-system       Active   6d23h

为集群上的所有用户包括匿名用户 提供公共可用的名称空间,主要是保留给集群使用的,防止资源在整个集群级别公开可见,用户用的更多是default

node-lease 目前是存放kubelet租约对象的名称空间,做多控制平面节点时有用,高可用的controller-manger 和高可用的scheduler 会争用一个锁,那个锁就放在这个空间

删除名称空间

[root@node01 ~]# kubectl  delete   ns/dev
namespace "dev" deleted
[root@node01 ~]# 

也可以在单个配置清单中 同时指定多个资源

[root@node01 ~]# cat  muti-res.yml 
apiVersion: v1
kind: Namespace
metadata:
  name: stage
---
apiVersion: v1
kind: Pod
metadata:
  name: mypod
  namespace: stage
spec:
  containers:
  - name: demoapp
    image: ikubernetes/demoapp:v1.0 
[root@node01 ~]# 

每个资源 要以— 换行分割 否则会报错

root@node01 ~]# kubectl  get po/mypod -n  stage -o wide
NAME    READY   STATUS    RESTARTS   AGE   IP            NODE     NOMINATED NODE   READINESS GATES
mypod   1/1     Running   0          91s   10.244.4.11   node02   <none>           <none>
[root@node01 ~]# 

删除整个配置清单中的资源 -f 【get 也支持】

[root@node01 ~]# kubectl delete -f muti-res.yml 
namespace "stage" deleted
pod "mypod" deleted

简单创建方式

[root@node01 ~]# kubectl  create ns dev
namespace/dev created

改 kubectl edit

实时编辑: 在线打开资源配置 ,按需修改就行,改完退出就生效。 但是,资源的有些字段不支持动态修改,比如一些资源像是名字的字段

例如:

[root@node01 ~]# kubectl  edit ns/dev
# Please edit the object below. Lines beginning with a '#' will be ignored,
# and an empty file will abort the edit. If an error occurs while saving this file will be
# reopened with the relevant failures.
#
apiVersion: v1
kind: Namespace
metadata:
  creationTimestamp: "2021-12-01T16:04:05Z"
# Please edit the object below. Lines beginning with a '#' will be ignored,
# and an empty file will abort the edit. If an error occurs while saving this file will be
# reopened with the relevant failures.
#
apiVersion: v1
kind: Namespace
metadata:
  creationTimestamp: "2021-12-01T16:04:05Z"
  name: devvv
  resourceVersion: "189862"
  selfLink: /api/v1/namespaces/dev
"/tmp/kubectl-edit-968952866.yaml" 17L, 473C written
A copy of your changes has been stored to "/tmp/kubectl-edit-968952866.yaml"
error: At least one of apiVersion, kind and name was changed
[root@node01 ~]# 

声明式创建资源 : apply 可以执行多次,允许修改操作,如果已有的状态和期望的状态不一样就改了

命令式创建资源:create 只能执行一次

二者区别就是 ,命令必须得执行,执行不成功就报错,比如已经有了一个资源,再命令式创建一个就报错。声明 就是结果对就行,命令可以不执行,已经有一个资源就不会再创建一模一样的资源,不会报错

用杀鸡举例 ,声明式 默认找不到鸡,意味则鸡不存在了,就代表杀死了。

而命令式,杀鸡却找不到鸡就报错

例子:

[root@node01 ~]# kubectl   apply -f  muti-res.yml 
namespace/stage created
pod/mypod created
[root@node01 ~]# kubectl   apply -f  muti-res.yml 
namespace/stage unchanged
pod/mypod unchanged


apply  相同资源 创建不报错

如果修改了配置文件再创建也行

# 把muti-res.yml 容器版本修改为1.1
[root@node01 ~]# kubectl   apply -f  muti-res.yml 
namespace/stage unchanged
pod/mypod configured

验证结果

[root@node01 ~]# kubectl   get po/mypod  -n stage  -o yaml|grep  image
      {"apiVersion":"v1","kind":"Pod","metadata":{"annotations":{},"name":"mypod","namespace":"stage"},"spec":{"containers":[{"image":"ikubernetes/demoapp:v1.1","name":"demoapp"}]}}
  - image: ikubernetes/demoapp:v1.1
    imagePullPolicy: IfNotPresent
    image: ikubernetes/demoapp:v1.1
    imageID: docker-pullable://ikubernetes/demoapp@sha256:3d7df5578a07f4e8d1c6b1e87204b359262b34ab07434635d5119df375afaac4
[root@node01 ~]# 

所以在生产环境中创建最好用apply , 删除用delete 【声明式删除很诡异,不要用😝】

快速删除容器的方法生产环境不要用

[root@master01 chapter4]# kubectl delete po mypod-with-env-var  --force --grace-period=0
warning: Immediate deletion does not wait for confirmation that the running resource has been terminated. The resource may continue to run on the cluster indefinitely.
pod "mypod-with-env-var" force deleted
[root@master01 chapter4]# 

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐