资源对象介绍
在Kubernetets中,一切皆资源,所有的事物都被抽象为了API资源
kubernetes系统的API Server基于http/https接收并响应客户端的操作请求,它提供了一种基于资源的RESTful风格的编程结构,将集群的各种组件都抽象成为标准的REST资源,如Node、Namespace和Pod等
查看Kubernetes上的所有API资源
[root@k8s-master ~]# kubectl api-resources

工作负载型资源
Pod是工作负载型资源中的基础资源,它负责运行容器,并为其解决环境性的依赖,但是Pod可能会因为资源超限或者节点故障等原因意外停止,这些非正常终止的Pod资源就需要被重建,而这类工作就将由工作负载型的控制器来完成,通常也被成为Pod控制器
常见的Pod控制器有下列几种:
- ReplicaSet:用于确保每个Pod副本在任意时刻均能满足目标数量
- Deployment:它用于为Pod和ReplicaSet提供声明式更新,是建构在ReplicaSet之上的更为高级的控制器,这种控制器并不直接管理Pod,而是通过管理ReplicaSet来间接管理Pod,也就是说Deployment管理ReplicaSet,ReplicaSet管理Pod

- StatefulSet:用于管理有状态的持久化应用,如database服务程序,其与Deployment的不同之处在于StatefulSet会为每一个Pod创建一个独有的持久性标识符,并会确保各Pod之间的顺序
DaemonSet:用于确保每个节点都运行了某Pod的一个副本;当有节点加入集群时, 也会为他们新增一个 Pod;当有节点从集群移除时,这些 Pod 也会被回收。删除 DaemonSet将会删除它创建的所有 Pod
DaemonSet 的一些典型用法:
- 在每个节点上运行集群守护进程
- 在每个节点上运行日志收集守护进程
- 在每个节点上运行监控守护进程
- Job:用于管理运行完成后即可终止的应用,例如批处理作业任务
Service资源
Pod资源可能会因为任何意外故障而被重建,于是它需要固定的可被发现的方式
另外、Pod资源仅在集群内可见,它的客户端也可能是集群内的其他Pod资源,若要开放给外部网络中的用户访问,则需要事先将其暴露到集群外部,并要为同一种工作负载的访问流量进行负载均衡。
举个例子,考虑一个图片处理后端,它运行了3个副本,这些副本是可互换的 —— 前端不需要关心它们调用了哪个后端副本,然而组成这一组后端程序的 Pod 实际上可能会发生变化, 前端客户端不应该也没必要知道,而且也不需要跟踪这一组后端的状态
Service就是Kubernetes中最核心的资源对象之一,Service和Pod之间是通过Label串起来,相同的Service的Pod的Label是一样的,同一个Service下的所有Pod通过kube-proxy实现负载均衡,而每个Service都会分配一个全局唯一的虚拟IP,也就是cluster ip
配置与存储资源
Docker容器分层联合挂载的方式决定了不宜在容器内部存储需要持久化的数据,于是它通过引入挂载外部存储卷的方式来解决此类问题,而Kubernetes则为此提供了Volume资源,它支持众多类型的存储设 备或存储系统
集群级资源
Kubernetes还存在一些集群级别的资源,用于定义集群自身配置信息的对象,他们仅仅应该由集群管理员进行操作,常见的集群级资源有下列几个:
Namespace:指定资源对象名称的作用范围,绝大多数对象都隶属于某一个名称空间,如果不指定则默认隶属于default空间,可以自己创建一个Namespace
使用命令
kubectl get ns查看目前集群中的名称空间[root@k8s-master ~]# kubectl get nsNAME STATUS AGEdefault Active 3d23hkube-node-lease Active 3d23hkube-public Active 3d23hkube-system Active 3d23h
Node:Kubernetes集群的工作节点,其标识符在当前集群中必须是唯一的
Role:名称空间级别的由规则组成的权限集合
ClusterRole、RoleBinding、ClusterRoleBinding……
元数据型资源
此类对象用于为集群内部的其他资源配置其行为或特性
常见类型有:HPA,PodTemplate,LimitRange….
API版本查询
- 使用命令
kubectl api-versions查看所有的API版本
[root@k8s-master ~]# kubectl api-versionsadmissionregistration.k8s.io/v1apiextensions.k8s.io/v1apiregistration.k8s.io/v1apps/v1authentication.k8s.io/v1authorization.k8s.io/v1autoscaling/v1autoscaling/v2autoscaling/v2beta1autoscaling/v2beta2batch/v1batch/v1beta1certificates.k8s.io/v1coordination.k8s.io/v1discovery.k8s.io/v1discovery.k8s.io/v1beta1events.k8s.io/v1events.k8s.io/v1beta1flowcontrol.apiserver.k8s.io/v1beta1flowcontrol.apiserver.k8s.io/v1beta2networking.k8s.io/v1node.k8s.io/v1node.k8s.io/v1beta1policy/v1policy/v1beta1rbac.authorization.k8s.io/v1scheduling.k8s.io/v1storage.k8s.io/v1storage.k8s.io/v1beta1v1
- 使用命令
kubectl api-resources,结果中的APIVERSION标明了API版本

- 使用命令
kubectl explain 资源类型,在返回的结果中VERSION一栏标明了API版本

除了使用kubectl来查询,还可以通过HTTP的方式来获取
- 于本地8080端口上启动一个API Service的代理网关
[root@k8s-master ~]# kubectl proxy --port=8080Starting to serve on 127.0.0.1:8080
- 使用curl访问API资源
[root@k8s-master ~]# curl localhost:8080/api/v1/nodes
资源清单
资源清单介绍
在Kubernetes中,一般用yaml格式的文件来创建符合预期期望的Pod,这样的yaml配置文件一般将其称为资源清单
K8S中的API Server在创建资源时采用JSON格式的数据,我们可以通过使用yaml格式的配置文件来提供配置,然后K8S内部自动帮我们转换为JSON格式,然后再提交
资源清单格式
apiVersion:group/apiversion # 如果没有给定group名称,那么默认为corekind: # 资源类别metadata: # 资源元数据name:namespace: # k8s自身的namespacelables:annotations: # 主要目的是方便用户阅读查找spec: # 期望的状态status: # 当前状态,本字段由k8s自身维护,无需定义
定义资源配置清单时,尽管apiVersion、kind和metadata有章可循,但spec字段对不同的资源来说是千差万别,因此用户需要参考文档来了解各种可用属性字段
查询Pods的帮助文档:
kubectl explain pod查询Pods的spec的帮助文档:
kubectl explain pods.spec
查询Pods的metadata的帮助文档:
kubectl explain pods.metadata查询Pods的apiVersion的帮助文档:
kubectl explain pods.apiVersion查询Pods的spec.containers的帮助文档:
kubectl explain pod.spec.containers
资源管理
- 命令式对象管理:直接使用命令去操作kubernetes资源
- 命令式对象配置:通过命令配置和配置文件去操作kubernetes资源
- 声明式对象配置:通过apply命令和配置文件去操作kubernetes资源 | 类型 | 操作对象 | 适用环境 | 优点 | 缺点 | | —- | —- | —- | —- | —- | | 命令式对象管理 | 对象 | 测试 | 简单 | 只能操作活动对象,无法审计、跟踪 | | 命令式对象配置 | 文件 | 开发 | 可以审计、跟踪 | 项目大时,配置文件多,操作麻烦 | | 声明式对象配置 | 目录 | 开发 | 支持目录操作 | 意外情况下难以调试 |
命令式对象管理
使用kubectl命令
kubectl是kubernetes集群的命令行工具,通过它能够对集群本身进行管理,并能够在集群上进行容器化应用的安装部署
语法格式:
kubectl [command] [type] [name] [flags]# comand:指定要对资源执行的操作,例如create、get、delete# type:指定资源类型,比如deployment、pod、service# name:指定资源的名称,名称大小写敏感# flags:指定额外的可选参数
# 查看所有podkubectl get pod# 查看某个podkubectl get pod pod_name# 查看某个pod,以yaml格式展示结果kubectl get pod pod_name -o yaml
kubernetes允许对资源进行多种操作,可以通过—help查看详细的操作命令
kubectl --help
示例
- 创建一个Namespace
[root@k8s-master ~]# kubectl create namespace devnamespace/dev created[root@k8s-master ~]# kubectl get nsNAME STATUS AGEdefault Active 4ddev Active 10skube-node-lease Active 4dkube-public Active 4dkube-system Active 4d
- 在这个Namspace下面创建并运行一个Nginx的Pod
[root@k8s-master ~]# kubectl run pod --image=nginx:latest -n devpod/pod created[root@k8s-master ~]# kubectl get pod -n dev
- 删除这个Pod
[root@k8s-master ~]# kubectl delete po pod -n devpod "pod" deleted[root@k8s-master ~]# kubectl get pod -n devNo resources found in dev namespace
- 删除创建的Namespace
[root@k8s-master ~]# kubectl delete ns devnamespace "dev" deleted
命令式对象配置
命令式对象配置就是使用命令与配置文件一起来操作kubernetes资源
示例
- 创建一个nginxpod.yaml,内容如下
[root@k8s-master ~]# vim nginxpod.yamlapiversion: v1kind: Namespaceapiversion: v1kind: Namespacemetadata:name: dev---apiversion: v1kind: Podmetadata:name: nginxpodnamespace: devspec:containers:- name: nginx-containersimages: nginx:latest
- 执行
kubectl create -f命令,创建资源(-f表示指定文件名)
[root@k8s-master ~]# kubectl create -f nginxpod.yamlnamespace/dev createdpod/nginxpod created
此时发现创建了两个资源对象,分别是namespace和pod
- 使用
kubectl get -f命令,查看资源
[root@k8s-master ~]# kubectl get -f nginxpod.yamlNAME STATUS AGEnamespace/dev Active 45sNAME READY STATUS RESTARTS AGEpod/nginxpod 1/1 Running 0 45s[root@k8s-master ~]# kubectl get pods -n devNAME READY STATUS RESTARTS AGEnginxpod 1/1 Running 0 60s[root@k8s-master ~]# kubectl get nsNAME STATUS AGEdefault Active 4d1hdev Active 76skube-node-lease Active 4d1hkube-public Active 4d1hkube-system Active 4d1h
- 执行
kubectl delete -f命令,删除资源
[root@k8s-master ~]# kubectl delete -f nginxpod.yamlnamespace "dev" deletedpod "nginxpod" deleted
总结:命令式对象配置的方式操作资源,可以简单的认为:命令 + yaml配置文件(里面是命令需要的各种参数)
声明式对象配置
声明式对象配置只有一个命令kubectl apply,和命令式对象配置很像
示例
- 创建一个nginxpod.yaml,内容如下
[root@k8s-master ~]# vim nginxpod.yamlapiversion: v1kind: Namespaceapiversion: v1kind: Namespacemetadata:name: dev---apiversion: v1kind: Podmetadata:name: nginxpodnamespace: devspec:containers:- name: nginx-containersimages: nginx:latest
执行
kubectl apply -f命令,创建资源(-f表示指定文件名)- 当再执行一次的时候,会提示已经创建了
- 如果是命令式对象配置再执行一次就会报错,声明式对象配置不会报错
[root@k8s-master ~]# kubectl apply -f nginxpod.yamlnamespace/dev createdpod/nginxpod created[root@k8s-master ~]# kubectl apply -f nginxpod.yamlnamespace/dev unchangedpod/nginxpod unchanged
总结:其实声明式对象配置就是使用apply命令描述一个资源最终的状态(在yaml中定义状态)
使用
kubectl apply操作资源:
如果资源不存在,就创建,相当于
kubectl create如果资源已存在,就更新,相当于
kubectl patch
使用推荐
创建资源、更新资源时,使用声明式对象配置kubectl apply -f xxx.yaml
删除资源时,使用声明式对象配置kubectl delete -f xxx.yaml
查询资源时,使用命令式对象管理kubectl get(describe) 资源名称
实战入门
Namespace
Namespace是kubernetes系统中的一种非常重要资源,它的主要作用是用来实现多套环境的资源隔离或者多租户的资源隔离
默认情况下,kubernetes集群中的所有的Pod都是可以相互访问的,但是在实际中,可能不想让两个Pod之间进行互相的访问,那此时就可以将两个Pod划分到不同的namespace下,形成逻辑上的“组”,方便不同的组的资源进行隔离使用和管理

Kubernetes在集群启动之后,会默认创建几个namespace
[root@k8s-master ~]# kubectl get namespaceNAME STATUS AGEdefault Active 10dkube-node-lease Active 10dkube-public Active 10dkube-system Active 10d
default:所有未指定Namespace的对象都会被分配在default命名空间
kube-node-lease:集群节点之间的心跳维护,v1.13开始引入
kube-public:此命名空间下的资源可以被所有人访问(包括未认证用户)
kube-system:所有由Kubernetes系统创建的资源都处于这个命名空间
具体操作
查看
# 查看所有的namespacekubectl get namespace # 可以将namespace简写成ns# 查看指定的namespacekubectl get ns default# 指定输出格式:kubectl get ns 名称 -o 格式参数(wide/json/yaml)kubectl get ns default -o yaml# 查看指定的namespace详情kubectl describe ns default
创建
kubectl create ns dev
删除
kubectl delete ns dev
配置文件方式
# ns-dev.yamlapiVersion: v1kind: Namespacemetadata:name: dev# 创建:kubectl apply -f ns-dev.yaml# 删除:kubectl delete -f ns-dev.yaml# 查看:kubectl get -f ns-dev.yaml
Pod
Pod是kubernetes集群进行管理的最小单元,程序要运行必须部署在容器中,而容器必须存在于Pod中,Pod可以认为是容器的封装,一个Pod中可以存在一个或者多个容器

kubernetes在集群启动之后,集群中的各个组件也都是以Pod方式运行的,可以通过下面命令查看:
[root@k8s-master ~]# kubectl get pods -n kube-systemNAME READY STATUS RESTARTS AGEcoredns-6d8c4cb4d-4b229 1/1 Running 10 (6m30s ago) 11dcoredns-6d8c4cb4d-tfbxr 1/1 Running 10 (6m30s ago) 11detcd-k8s-master 1/1 Running 10 (6m30s ago) 11dkube-apiserver-k8s-master 1/1 Running 10 (6m30s ago) 11dkube-controller-manager-k8s-master 1/1 Running 10 (6m30s ago) 11dkube-flannel-ds-7qvjp 1/1 Running 10 (6m30s ago) 11dkube-flannel-ds-z5hzt 1/1 Running 12 (6m21s ago) 11dkube-proxy-4rpcz 1/1 Running 11 (6m21s ago) 11dkube-proxy-dkft4 1/1 Running 10 (6m30s ago) 11dkube-proxy-s4hvq 1/1 Running 10 (6m26s ago) 11dkube-scheduler-k8s-master 1/1 Running 10 (6m30s ago) 11d
具体操作
创建并运行
kubernetes一般不单独运行Pod的命令,都是通过Pod控制器来实现的
# 命令格式: kubectl create deploy (pod控制器名称) [参数]
# --image 指定Pod的镜像
# --port 指定端口
# --namespace 指定namespace
kubectl create deploy nginx --image=nginx --port=80 -n dev deployment.apps/nginx created
查看
# 查看dev下的所有pod信息
kubectl get pods -n [namespace名称]
# 查看某个pod的详细信息
kubectl describe pod [pod名称] -n [namespace名称]
# 查看pod的详细状态(IP、节点等)
kubectl get pods -n [namespace名称] -o wide
删除
# 删除指定pod
kubectl delete pod [pod名称] -n [namespace名称]
# 如果删掉了又被重新创建了,那么就是pod控制器在监控pod的状态,当pod死亡时,会立即创建一个新的pod,如果要删除pod,就需要把pod控制器删除
# 例如一个deploy控制器,名为nginx,创建了pod,那么删除就按下列步骤进行
kubectl get deploy -n dev # 查看deploy资源类型的控制器的名称
kubectl delete deploy nginx -n dev # 删除deploy控制器nginx
配置文件方式
# pod-nginx.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: dev
spec:
containers:
- image: nginx:latest
name: pod
ports:
- name: nginx-port
containerPort: 80
protocol: TCP
# 创建:kubectl apply -f pod-nginx.yaml
# 删除:kubectl delete -f pod-nginx.yaml
# 查看:kubectl get -f pod-nginx.yaml
Label
Label是kubernetes系统中的一个重要概念,它的作用就是在资源上添加标识,用来对它们进行区分和选择
Label的特点:
一个Label会以key/value键值对的形式附加到各种对象上,如Node、Pod、Service等等
一个资源对象可以定义任意数量的Label ,同一个Label也可以被添加到任意数量的资源对象上去
Label通常在资源对象定义时确定,当然也可以在对象创建后动态添加或者删除
可以通过Label实现资源的多维度分组,以便灵活、方便地进行资源分配、调度、配置、部署等管理工作
一些常用的Label 示例如下:
版本标签:
"version":"release","version":"stable"……环境标签:
"environment":"dev","environment":"test","environment":"pro"架构标签:
"tier":"frontend","tier":"backend"
标签定义完毕之后,还要考虑到标签的选择,这就要使用到标签选择器(Label Selector),即:
Label用于给某个资源对象定义标识,而Label Selector用于查询和筛选拥有某些标签的资源对象
当前有两种Label Selector:
基于等式的Label Selector
- name = slave:选择所有包含Label中key=”name”且value=”slave”的对象
- env!= production:选择所有包括Label中的key=”env”且value不等于”production”的对象
基于集合的Label Selector
- name in (master, slave):选择所有包含Label中的key=”name”且value=”master”或”slave”的对象
- name not in (frontend): 选择所有包含Label中的key=”name”且value不等于”frontend”的对象
标签的选择条件可以使用多个,此时将多个Label Selector进行组合,使用逗号”,”进行分隔即可,例如:
name=slave,env!=production
name not in (frontend),env!=production
具体操作
打标签
# 打标签,语法格式:kubectl label pods [pod名称] key=value -n [namespace名称]
kubectl label pods pod-example version=1.0 -n dev
# 更新标签,语法格式:.... --overwrite
kubectl label pods pod-example version=2.0 -n dev --overwrite
查看标签
# 显示某个资源的所有标签
kubectl get pods pod-example --show-labels -n dev
# 指定显示某个资源特定的标签
kubectl get pods pod-example -L env,version -n dev
标签选择器
# 一个标签选择器,选择出env不等于qq的pod
kubectl get pods -l "env!=qq" --show-labels -n dev
# 一个标签选择器,选择出标签env等于qq或qa中的一个的所有pod
kubectl get pods -l "env in (qq,qa)" --show-labels -n dev
# 多个标签选择器,选择出env=qq并且version=2.0的pod
kubectl get pods -l "env=qq,version=2.0" --show-labels -n dev
删除标签
# 语法格式:kubectl label pods [pod名称] key- -n [namespace名称]
kubectl label pods pod-example version- -n dev
配置文件方式
# vim pod1.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-example
labels:
env: qa
tier: frontend
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 80
protocol: TCP
Deployment
在kubernetes中,Pod是最小的控制单元,但是kubernetes很少直接控制Pod,一般都是通过Pod控制器来完成控制Pod
Pod控制器用于Pod的管理,确保Pod资源符合预期的状态,当Pod的资源出现故障时,会尝试进行重启或重建Pod
在kubernetes中Pod控制器的种类有很多,这里只介绍一种:Deployment

具体操作
查看
# 首先创建一个deployment类型的控制器nginx,其中的pod为3个,镜像为nginx
kubectl create deploy nginx --image=nginx:latest --port=80 --replicas=3 -n dev
# 查看deployment的信息
kubectl get deploy -n dev (-o wide)
'--------------------------------------'
NAME READY UP-TO-DATE AVAILABLE AGE
nginx 3/3 3 3 2m42s
# UP-TO-DATE:成功升级的副本数量
# AVAILABLE:可用副本的数量
# 查看详细信息
kubectl describe deploy nginx -n dev
删除
kubectl delete deploy nginx -n dev
配置文件操作
# deploy-nginx.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
namespace: dev
spec:
replicas: 3
selector:
matchLabels:
run: nginx
template:
metadata:
labels:
run: nginx
spec:
containers:
- image: nginx:latest
name: nginx
ports:
- containerPort: 80
protocol: TCP
# 创建:kubectl create -f deploy-nginx.yaml
# 删除:kubectl delete -f deploy-nginx.yaml
Service
虽然每个Pod都会分配一个单独的Pod IP,然而却存在如下两问题:
- Pod IP 会随着Pod的重建产生变化
- Pod IP 仅仅是集群内可见的虚拟IP,外部无法访问
这样对于访问这个服务带来了难度,因此,Kubernetes设计了Service来解决这个问题
Service可以看作是一组同类Pod对外的访问接口,借助Service应用可以方便地实现服务发现和负载均衡

具体操作
创建集群内部可访问的service
[root@k8s-master ~]# kubectl expose deploy nginx --name=svc-nginx --type=ClusterIP --port=80 --target-port=80 -n dev
service/svc-nginx exposed
[root@k8s-master ~]# kubectl get svc svc-nginx -n dev -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
svc-nginx ClusterIP 172.16.93.114 <none> 80/TCP 10s app=nginx
[root@k8s-master ~]# curl 172.16.93.114
创建集群外部也可访问的Service
[root@k8s-master ~]# kubectl expose deploy nginx --name=svc-nginx1 --type=NodePort --port=80 --target-port=80 -n dev
service/svc-nginx1 exposed
[root@k8s-master ~]# kubectl get svc svc-nginx1 -n dev -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
svc-nginx1 NodePort 172.16.252.67 <none> 80:31640/TCP 5s app=nginx
# 下面两种方式均可访问到
[root@k8s-master ~]# curl 172.16.252.67
[root@k8s-master ~]# curl 192.168.31.100:31640
删除
kubectl delete svc svc-nginx1 -n dev
配置文件方式
# svc-nginx.yaml
apiVersion: v1
kind: Service
metadata:
name: svc-nginx
namespace: dev
spec:
clusterIP: 172.16.99.99 #固定svc的内网ip
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
run: nginx
type: ClusterIP
[root@k8s-master ~]# kubectl apply -f svc-nginx.yaml
[root@k8s-master ~]# kubectl get svc -n dev
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
svc-nginx ClusterIP 172.16.99.99 <none> 80/TCP 3s
[root@k8s-master ~]# curl 172.16.99.99
