k8s_day02_03
k8s_day02_03如图,k8s 的用户 群体分为两类,一类是是应用程序客户端,它们访问集群pod 上应用服务的,是来自集群外部引入的流量,主要靠2种方式来引入流量,一种是nodeport 类型的service ,另一种是借助ingress 控制器来引入,ingress 也是转发给service 背后的pod 来实现的。 如果客户端是通过nodeport 进来的,会借助service的调度算
k8s_day02_03
如图,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 资源模型的设计 也是反映了这种理念
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
以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]#
更多推荐
所有评论(0)