一、基础概念的理解
- 集群
- master节点
- worker节点
- Node
- Pod
- 应用最终以Pod为一个基本单位部署
- Label
- 很多资源都可以打标签
- Deployment
- 应用部署用它,deployment最终会产生Pod
- Service
- 负载均衡机制
二、Kubernetes Objects(k8s对象)
1、什么是k8s对象
(官方网站介绍K8s对象)[https://kubernetes.io/zh-cn/docs/concepts/overview/working-with-objects/kubernetes-objects/]
- k8s里面操作的资源实体,就是k8s的对象,可以使用yaml来声明对象。然后让k8s根据yaml的声明 创建出这个对象;
- 操作 Kubernetes 对象 —— 无论是创建、修改,或者删除 —— 需要使用 Kubernetes API。比如,当 使用 kubectl 命令行接口时,CLI 会执行必要的 Kubernetes API 调用
- Kubernetes对象指的是Kubernetes系统的持久化实体,所有这些对象合起来,代表了你集群的实际
情况。常规的应用里,我们把应用程序的数据存储在数据库中,Kubernetes将其数据以Kubernetes
对象的形式通过 api server存储在 etcd 中。具体来说,这些数据(Kubernetes对象)描述了:
- 集群中运行了哪些容器化应用程序(以及在哪个节点上运行)
- 集群中对应用程序可用的资源(网络,存储等)
- 应用程序相关的策略定义,例如,重启策略、升级策略、容错策略
- 其他Kubernetes管理应用程序时所需要的信息,scheduler先计算应该去哪个节点部署
对象的spec和status: 每一个 Kubernetes 对象都包含了两个重要的字段:
spec
必须由你来提供,描述了您对该对象所期望的 目标状态status
只能由 Kubernetes 系统来修改,描述了该对象在 Kubernetes 系统中的实际状态
Kubernetes通过对应的控制器,不断地使实际状态趋向于您期望的目标状态
- 我们部署一次nginx应用
kubectl create deployment my-test-nginx --image=nginx
- 查看应用详细信息
kubectl describe pod/my-test-nginx-5f47cb688d-dvvmd
Name: my-test-nginx-5f47cb688d-dvvmd
Namespace: default
Priority: 0
Node: k8s-02/172.26.25.81
Start Time: Wed, 12 Apr 2023 10:49:19 +0800
Labels: app=my-test-nginx
pod-template-hash=5f47cb688d
Annotations: cni.projectcalico.org/containerID: 155bed4a588c792465c26d6eaacae3d9fe90fd675713bd325c3db136efc7af77
cni.projectcalico.org/podIP: 192.168.179.51/32
cni.projectcalico.org/podIPs: 192.168.179.51/32
Status: Running #pod的状态
IP: 192.168.179.51
IPs:
IP: 192.168.179.51
Controlled By: ReplicaSet/my-test-nginx-5f47cb688d #被哪个副本集控制,如果pod没了,通过此副本重新拉起
Containers: #pod里面的容器
nginx:
Container ID: docker://8631e2b502704754a81b1e5c6f25a8bba31e5282beef34420864d64d090cc7a2
Image: nginx #容器使用的镜像
Image ID: docker-pullable://nginx@sha256:0d17b565c37bcbd895e9d92315a05c1c3c9a29f762b011a10c54a66cd53c9b31
Port: <none>
Host Port: <none>
State: Running
Started: Wed, 12 Apr 2023 10:49:45 +0800
Ready: True
Restart Count: 0
Environment: <none>
Mounts: #容器的挂载
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-hc6t2 (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
kube-api-access-hc6t2:
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: #pod的事件
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 7m54s default-scheduler Successfully assigned default/my-test-nginx-5f47cb688d-dvvmd to k8s-02 #用默认调度器,把pod分配到 k8s-02节点(因为是单节点,允许了调度master)
Normal Pulling 7m45s kubelet Pulling image "nginx" #拉nginx镜像
Normal Pulled 7m30s kubelet Successfully pulled image "nginx" in 15.916628036s #拉镜像成功
Normal Created 7m28s kubelet Created container nginx #创建容器
Normal Started 7m28s kubelet Started container nginx #容器启动
- 查看一个部署的yaml
kubectl get deploy my-test-nginx -oyaml
apiVersion: apps/v1
kind: Deployment #执行的类型,此处是一个部署
metadata:
annotations:
deployment.kubernetes.io/revision: "1"
creationTimestamp: "2023-04-12T02:49:18Z"
generation: 1
labels:
app: my-test-nginx
name: my-test-nginx #部署的名称
namespace: default
resourceVersion: "258350"
uid: f916e5b1-2888-4ba0-9f1b-e823de77fda1
spec: #期望状态
progressDeadlineSeconds: 600
replicas: 1 #副本的个数,相当于命令:kubectl scale --replicas=3 deployment my-test-nginx
revisionHistoryLimit: 10
selector:
matchLabels:
app: my-test-nginx
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
creationTimestamp: null
labels:
app: my-test-nginx
spec:
containers:
- image: nginx #容器的镜像
imagePullPolicy: Always
name: nginx
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30
status: #当前状态
availableReplicas: 1 #可用的副本数
conditions:
- lastTransitionTime: "2023-04-12T02:49:48Z"
lastUpdateTime: "2023-04-12T02:49:48Z"
message: Deployment has minimum availability.
reason: MinimumReplicasAvailable
status: "True"
type: Available
- lastTransitionTime: "2023-04-12T02:49:18Z"
lastUpdateTime: "2023-04-12T02:49:48Z"
message: ReplicaSet "my-test-nginx-5f47cb688d" has successfully progressed.
reason: NewReplicaSetAvailable
status: "True"
type: Progressing
observedGeneration: 1
readyReplicas: 1
replicas: 1
updatedReplicas: 1
- 当删除pod时,我们来看一下status里的内容
kubectl delete pod my-test-nginx-5f47cb688d-dvvmd
status:
conditions:
- lastTransitionTime: "2023-04-12T02:49:18Z"
lastUpdateTime: "2023-04-12T02:49:48Z"
message: ReplicaSet "my-test-nginx-5f47cb688d" has successfully progressed.
reason: NewReplicaSetAvailable
status: "True"
type: Progressing
- lastTransitionTime: "2023-04-12T03:29:20Z"
lastUpdateTime: "2023-04-12T03:29:20Z"
message: Deployment does not have minimum availability.
reason: MinimumReplicasUnavailable
status: "False"
type: Available
observedGeneration: 1
replicas: 1
unavailableReplicas: 1 #不可用的副本一个
updatedReplicas: 1
- 删除以后,k8s会监测到,会使当前状态与期望状态保持一致,会自动再创建一个,保持期望状态和当前状态最终一致
- pod信息、部署信息、节点信息都会以以上yml形式记录,都存储在etcd中
2、描述k8s对象
当你在 Kubernetes 中创建一个对象时,你必须提供:
该对象的 spec
字段,通过该字段描述您期望的 目标状态
该对象的一些基本信息,例如名字
可以使用 kubectl 命令行创建对象,业可以编写 .yaml
格式的文件进行创建
- 如何编写任意资源的yaml
1、集群中找一个同类型的资源获取yaml,去掉status节点
kubectl run my-nginx --image=nginx
以上命令是运行一个nginx的pod
如果我们不会写pod,在集群里随便找一个pod:kubectl get pod my-test-nginx-5f47cb688d-dvvmd -oyaml,就会以yaml格式输出pod的运行yaml
2、kubectl run my-nginx --image=nginx --dry-run -oyaml
#--dry-run 干跑,不产生实际的东西,再以yaml格式输出
apiVersion: v1 #同一个资源有可能有多个版本:kubectl api-resources,带有beta的属于测试特性,生产不推荐使用
kind: Pod #资源类型 kubectl api-resources 可以获取到所有资源
metadata: #每一个资源定义一些元数据信息
labels:
run: my-nginx
name: my-nginx
spec: #资源的期望状态
containers:
- image: nginx #镜像名称
name: my-nginx
resources: {}
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
3、k8s对象yaml的结构
必填字段
在上述的 .yaml
文件中,如下字段是必须填写的:
apiVersion
用来创建对象时所使用的Kubernetes API版本kind
被创建对象的类型metadata
用于唯一确定该对象的元数据:包括name
和namespace
,如果 namespace 为空,则默认值为 defaultspec
描述对该对象的期望状态
不同类型的 Kubernetes,其 spec 对象的格式不同(含有不同的内嵌字段),通过 API 手册 可 以查看 Kubernetes 对象的字段和描述。例如,假设您想了解 Pod 的 spec 定义,可以在 这里找 到,Deployment 的 spec 定义可以在 这里 找到:
https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.21/
- 我们根据以上来创建一个最简单的pod 创建一个yaml文件,文件中放入以下内容
kind: Pod
apiVersion: v1
#以上type信息结束
metadata:
name: my-nginx-666 #资源名字
spec: #期望的pod状态
containers:
- image: nginx #镜像名称,- 是yaml里面数组的表达方式,也就是说,一个pod里面可以有很多容器
name: my-nginx #容器的名字
执行命令应用yaml:
kubectl apply -f k8s-demo.yaml
4、管理k8s对象
管理方式 | 操作对象 | 推荐的环境 | 参与编辑的人数 | 学习曲线 |
---|---|---|---|---|
指令性的命令行 | Kubernetes对象;kubectl xxxxx | 开发环境 | 1+ | 最低 |
指令性的对象配置 | 单个yaml 文件 | 生产环境 | 1 | 适中 |
声明式的对象配置 | 包含多个 yaml 文件的多个目录。kustomize | 生产环境 | 1+ | 最高 |
同一个Kubernetes对象应该只使用一种方式管理,否则可能会出现不可预期的结果
#1、命令式
kubectl run nginx --image nginx
kubectl create deployment nginx --image nginx
apply -f : 没有就创建,有就修改
----
#2、指令性
- 使用指令性的对象配置(imperative object configuration)时,需要向 kubectl 命令指定具体
的操作(create,replace,apply,delete等),可选参数以及至少一个配置文件的名字。配置文件中必须
包括一个完整的对象的定义,可以是 yaml 格式,也可以是 json 格式。
#创建对象
kubectl create -f nginx.yaml
#删除对象
kubectl delete -f nginx.yaml -f redis.yaml
#替换对象
kubectl replace -f nginx.yaml
----
#3、声明式
#处理 configs 目录中所有配置文件中的Kubernetes对象,根据情况创建对象、或更新Kubernetes中已
经存在的对象。可以先执行 diff 指令查看具体的变更,然后执行 apply 指令执行变更;
#递归处理目录中的内容:
kubectl diff -R -f configs/
kubectl apply -R -f configs/
#移除
kubectl delete -f configs/
5、名称空间
- 查询名称空间
kubectl get namespaces
- 命名空间的详细信息
kubectl describe namespaces <name>
-
Kubernetes 安装成功后,默认有初始化了三个名称空间:
- default 默认名称空间,如果 Kubernetes 对象中不定义
metadata.namespace
字段,该对象将放 在此名称空间下 - kube-system Kubernetes系统创建的对象放在此名称空间下
- kube-public 此名称空间自动在安装集群是自动创建,并且所有用户都是可以读取的(即使是那些 未登录的用户)。主要是为集群预留的,例如,某些情况下,某些Kubernetes对象应该被所有集群 用户看到。
- default 默认名称空间,如果 Kubernetes 对象中不定义
-
名称空间如何隔离
-
1、基于环境隔离
- prod:生产环境部署的所有应用
- test:测试环境部署的所有应用
-
基于产品线的隔离
-
基于团队的隔离
名称空间可以隔离配置,但网络可以互相访问
- 创建名称空间
apiVersion: v1
kind: Namespace
metadata:
name: hello
apiVersion: v1
kind: Namespace
metadata:
creationTimestamp: null
name: k8s-03
#应用名称空间,多次执行不会报错,会应用最新的内容
kubectl apply -f XXX.yaml
#创建名称空间,可以创建之前没有的名称空间,如果已经存在,会报错
kubectl create -f XXX.yaml
#直接用命令
kubectl create namespace <名称空间的名字>
#删除名称空间
kubectl delete namespace <名称空间的名字>
-
名称空间的名字必须与 DNS 兼容:
- 不能带小数点 .
- 不能带下划线 _
- 使用数字、小写字母和减号 - 组成的字符串
默认情况下,安装Kubernetes集群时,会初始化一个
default
名称空间,用来将承载那些未指定名称 空间的 Pod、Service、Deployment等对象
-
为请求设置命名空间
kubectl run nginx --image=nginx --namespace=<insert-namespace-name-here>
kubectl get pods --namespace=<insert-namespace-name-here>
kind: Pod
apiVersion: v1
#以上type信息结束
metadata:
name: my-nginx-666 #资源名字
namespace: default #不写就是default
spec: #期望的pod状态
containers:
- image: nginx:1.7.9 #镜像名称,- 是yaml里面数组的表达方式,也就是说,一个pod里面可以有很多容器
name: my-nginx #容器的名字
kubectl get pod -n default
并非所有对象都在命名空间中
-
大多数 kubernetes 资源(例如 Pod、Service、副本控制器等)都位于某些命名空间中。但是命名空间资 源本身并不在命名空间中。而且底层资源,例如 nodes 和持久化卷不属于任何命名空间。
-
查看哪些 Kubernetes 资源在命名空间中,哪些不在命名空间中:
# In a namespace
kubectl api-resources --namespaced=true
# Not in a namespace
kubectl api-resources --namespaced=false