A. k8s之存储
k8s的存储常用的就是上面几种模式,分为临时存储,半持久化存储链消,与持久化存储这三类,本章我们着重讲解emptydir与hostpath与pvc跟pv等
当pod的存储方案设定为emptydir的时候,pod启动时,就会在pod所在节点的磁盘空间开辟出一块空卷,最开始里面是什么都没有的,pod启动后容器产生的数据会存放到那个空卷中。空卷变成了一个临时卷
供pod内的容器读取和写入数据,一旦pod容器消失,节点上开辟出的这个临时卷就会随着pod的销毁而销毁
一般来说emptydir的用途都是用来充当临时存储空间,例如一些不需要数据持久化的微服务,我们都可以用emptydir来当做微服务pod的存储方案
k8s存储emptdir实战例子:以之前的myapp应用为例
创建应用
观察是否生产data目录,并在/data目录创建文件test.txt
手动删除容器模拟容器销毁,用于是pod是被控制器管理的,删除后会被重建新棚橘知的pod
这时候在看我们之前创建的data.txt已经不见了
hostPath类型则是映射node文件系统中的文件或者目录到pod里。在使用hostPath类型的存储卷时,也可以设置type字段,支持的类型有文件、目录、File、Socket、CharDevice和BlockDevice(我只映射过文件与目录)。
其实这个功能就相当于docker中的-v 目录映射,只不过在k8s中的时候,pod会漂移,当pod漂移到其他node节点的时候,pod不会跨节点的去读取目录。所以说hostpath只能算一种半持久化的存储方式
实战例子
创建应用
在node节点可以看到生成了/data/volume目录,在里面创建测试文件
检验pod里面的/data是否存在这个映射目录的文件
可以看到刚才创建的文件已经映射到我们的目录里边了
为了验证是否映射到容器里面的目录也会随着pod生命周期的消失而消失,我们手动删除pod模拟容器终止
可以看到容器被删除后,新建的pod也可以看到我们映射的目录,而且里面数据test.txt还在伍伏。
这有个缺点就是不能够跨容器去读取数据,如果删除后的pod被调度到其他节点的话,原来的数据也就没有了,如果能不受节点的影响,并且挂载的数据不会随生命周期的结束而结束,我们应该怎么解决呢?就是我们后面讲到的持久化存储了
上面介绍了俩种临时存储于半持久化存储的方案。在k8s实际生产环境中,一般会选用私有云持久化存储方案还有公有云持久化存储方案,私有云存储方案包括nfs,ceph,glusterfs等方案。公有云存储会用到AWS等方案
存储方案各有各的优缺点,可参考 https://www.cnblogs.com/yswenli/p/7234579.html 这篇文章。今天我们主要讲解pvc,pv,nfs之间的关系。
简单来说,要使用持久化存储,就需要使用pvc去跟pv去申请,然后pv查看自己有没有合适的存储空间卷,有合适的就与pvc进行绑定。pv与pvc是一一对应绑定的。现在我们用一幅图来说明pvc,pv,nfs的关系
实战例子
准备存储服务安装nfs
接下来创建pv与nfs绑定
创建pvc与pv关联
创建并查看结果
注意:STATUS为Bound说明该pvc已经与pv绑定了
接下来创建pod来引用pvc
创建pod
接下来验证一下在nfs创建一个测试文件,看是否被映射到容器中
可以看到容器里面也可以看到创建的文件
手动删除容器,或者调度到其他节点原来的文件还是不会被删除的,这里就省略验证了,这就是nfs的好处,不过企业一般不会选用nfs,磁盘IO,性能读取方面不太理想,毕竟是本地存储,还是有一定的风险。推荐用用云存储。
文件存储提供无限扩展的文件系统来给云服务器存取数据实际上相当于nfs
1、已注册阿里云账号,并完成实名认证。
如果没有,请先注册阿里云账号,详情请参见阿里云账号注册流程。
2、已开通NAS服务。
首次登录NAS控制台时,根据页面提示开通NAS服务。
3、在需要创建文件系统的地域,已有可用的云服务器ECS。
k8s应用NAS实战例子
1、打开阿里云NAS控制台确认已创建好文件系统
2、把复制挂载参数把它挂载到服务器中创建测试目录,前提是服务器需要安装nfs客户端。
安装完成挂载到本地目录并创建test目录作为测试目录
并在里面创建一个测试文件1.txt
接下来可以创建pvc和pv了
创建并查看
接下来创建pod去引用pvc
创建pod
检验刚才的1.txt是否挂到容器的/data/nas下
云存储适合于生产环境k8s的存储解决方案
B. K8S常用命令介绍
k8s常用命令:
禁止|恢复node节点调度:
kubectl cordon|uncordon nodename
删除节点(慎用):
kubectl drain nodename(驱除非系统pod)
kubectl delete nodename (删除节点)
创建资源:
kubectl create|apply -f file.yaml
create 命令一般用于创建新资源。 因此,如果再次运行该命令,则会抛出错误,因为资源名称在名称空间中应该是唯一的
apply 命令一般用于更新资源配置。 如果资源不在那里,那么它将被创建。 kubectl apply命令可以运行更多次,只要资源定义没变,资源将不会变动
查看资源列表:
kubectl get node|pod|service|deployment|configmap|... -n namespace [-o wide] [-w]
查看特定资源详情:
kubectl describe pod podname -n namespace
查看资源定义:
kubectl get deploy deployname -n namespace -o yaml [>file.yaml] 重定向到文件里,可以再次apply -f yaml
编辑资源(只对spec字段下内容生效):
kubectl edit node|pod|service|deployment|configmap|... -n namespace
删除资源(慎用):
kubectl delete pod podname -n namespace [--force --grace-period=0] 强制删除
grace-period表示过渡存活期,默认30s,在删除POD之前允许POD慢慢终止其上的容器进程,从而优雅退出,0表示立即终止POD
查看pod log:
kubectl logs [-f] podname -n namespace
进入pod(容器),或执行命令:
kubectl exec -it podname -n namespace [-c containername] -- /bin/sh [CMD]
-c 是进入多个容器中的某个指定容器
-- 指的是不用进入容器就可以执行命令
pod扩缩容:k
手动扩缩容:kubectl scale deployment deployname -n namespace --replicas=x;也可用kubectl edit对deployment进行编辑后apply
pod升级与回滚:
deployment:
升级:kubectl set image deployment/deplyname -n namespce image=imagename:xxx; 也可用kubectl edit对deployment进行编辑后apply
更新策略:
Recreate: 更新时先杀掉正在运行的pod,然后创建新的pod
RollingUpdate: 滚动方式进行更新,参数maxUnavailable和maxSurge来控制滚动更新的过程
回滚(不常用):kubectl rollout status|history deployment/deployname -n namespace [--to-revision=x]
pod调度:
NodeName定向调度:通过node节点的主机名进行定向调度
NodeSelector定向调度:通过Node节点标签和pod资源属性nodeSelector匹配实现pod的定向调度
查看node节点标签:
kubectl get node --show-labels
查看指定标签的节点: kubectl get node -l key=value
节点增加标签:kubectl label nodes nodename key=value
删除节点标签:kubectl label nodes nodename key-
修改节点标签: kubectl label nodes nodename key=newvalue --overwrite
C. k8s常用命令
命令行 敲出的指令分为2种,
资源管理方式分类
直接使用命令去操作k8s资源,命令和参数一起出现
通过命令和配置文件去操作作k8s资源,命令还是那个命令,只不过参数都放在配置文件里面
使用apply创建资源,
说明
在master节点执行以下命令即可删除
还需要在work节点上执行以下命令来清空ini配置
先在主节点创建令牌
然后在需要加入集群的节点中执行令牌,注意这里的命令是通过 kubeadm token create --print-join-command 命令返回的结果
说明
记住,名称中不能用下划线 _ ,可以用横行 - 第一种创建方式–命令行创建
第二种创建方式–命令行 + 配置文件
创建一个名为namespace-dev.yaml的文件,内容如下(注意大小写,kind的头字母必须大写)
然后偶执行命令进行创建
需要注意的是,删除后,当前命名空间下的pod、deployment、 container 也会一起删掉
第一种–使用命令删除
第二种–使用配置文件删除
说明
获取所有namespace的pod并监视资源变动
加上 -w 表示监视资源变动信息,此时命令行进入阻塞状态,如果pod有变化将会马上呈现出来;
其他参数
因为pod里面至少要有一个容器,所以pod是和容器一起创建的,新建一个文件 pod.ymal ,内容如下
然后执行命令并指定配置文件进行创建
以下示例是为pod资源打标签,这种方式是和pod一起创建的,新建一个配置文件 label.yaml
执行命令创建pod
适合更新label值,前提是label的key必须已存在;
删除key为lebelKey的标签
pod控制器有很多种,我们这里就用deployment
使用以下run命令运行一个nginx,deployment名称为 app=run-cmd-nginx-deploy-3
通过以下命令可以看到,会自动生成一个 app=run-cmd-nginx-deploy-3 的标签
新建一个deployment.yaml文件,内容如下
需要注意的是,一旦删除pod控制器,此pod控制器下的所有pod和容器也会一并删除;
默认创建的pod是只能对内访问的,所以需要创建一个对外的访问端口,创建一个service其实就是暴露对外的访问端口
说明
创建好service之后,查看service信息,可以看到,暴露的端口为:30474,
新建一个service.ymal文件,内容如下
以下三种用法都可以
查询pod控制器和pod
Endpoint是kubernetes中的一个资源对象,存储在etcd中,用来记录一个service对应的所有pod的访问地址,它是根据service配置文件中selector描述产生的。
一个Service由一组Pod组成,这些Pod通过Endpoints暴露出来,Endpoints是实现实际服务的端点集合。换句话说,service和pod之间的联系是通过endpoints实现的。
每创建一个service,k8s会自动创建一个同名的 Endpoint出来
如果是由service创建出来的endpoints,删除后会马上创建出一个同名的endpoint出来,如果要删除必须先删除service
因为每次创建一个service,k8s会自动创建一个同名的 Endpoint出来,所我们直接创建service就可以了
--help 用来查看帮助文档,如果你不知道某个命令怎么使用了,就可以用 --help 查询命令的用法
explain用来查看配置文件的 资源结构,如果不知道配置文件中的资源用有哪些结构,那么就可以使用explain命令来查看
D. k8s常用命令
相关服务及用途节点名称服务名称用途管理节点kubctl-apiserver提供HTTP Rest统一接口服务,处理和验证REST请求和更新etcd中API对象的状态管理节点kubectl-controller-manager资源控制管理同步管理节点kube-scheler负责资源调度(调度Pod)工作节点kubelet管理Pod的生命周期,创建、启停等任务工作节点kube-proxy负大闷责网络通信及负载均衡### 1.重启服务kubectl patch deployment app名称 -p {"spec":{"template":{"metadata":{"labels":{"date":"date +'%s'"}}}}} -n kube-system
kubectl logs --previous l7-lb-controller-74c67fb85d-5b5cg -n kube-system
kubectl describe pod kubernetes-dashboard -n kube-system
kubectl get svc kubernetes-dashboard -n kube-system
kubectl get ep -n kube-system kubernetes-dashboard
lsmod | grep ip_vs
查看标签kubectl get node --show-labels -n kube-system
kubectl get pods --show-labels kube-sytem
kubectl get pod --show-labels kubernetes-dashboard-6845889d64-25f9x -n kube-system
kubectl describe svc kubernetes-dashboard -n kube-system
kubectl describe pod kubernetes-dashboard -n kube-system
在容器内执行命令kubectl exec -ti pod名称 /bin/基闭bash -n kube-system
kubectl get daemonset -o yaml -n kube-system calico-node
kubectl get svc -o json pod名称 -n kube-system
kubectl get daemonsets -n kube-system
通过文件创建cat > my-namespace.yaml << EOF
apiVersion: v1
kind: Namespace
metadata:
name: new-namespace
EOF
kubectl create -f ./my-namespace.yaml
删滚锋弯除命令空间kubectl delete namespaces new-namespace
删除一个namespace会自动删除所有属于该namespace的资源。default 和 kube-system 命名空间不可删除。### 15.创建/查看 Deployment 记录版本号kubectl create -f nginx-deployment.yaml --record
重新分配pod数量kubectl scale deployment kubernetes-dashboard --replicas=1 -n kube-system
查看升级历史记录kubectl rollout history deployment/kubernetes-dashboard -n kube-system
查看单个revision的详细信息kubectl rollout history deployment/kubernetes-dashboard --revision=1 -n kube-system
回滚到上一个版本kubectl rollout undo deployment/kubernetes-dashboard -n kube-system
指定回滚某个历史版本kubectl rollout undo deployment/kubernetes-dashboard --to-revision=1 -n kube-system
查看hap状态kubectl get hpa kubernetes-dashboard -n kube-system
查看hpa详细状态kubectl describe hpa kubernetes-dashboard -n kube-system
删除hpakubectl delete hpa kubernetes-dashboard -n kube-system
kubectl set image deploy kubernetes-dashboard nginx=nginx:1.9.1
更新升级资源kubectl set resources deployment kubernetes-dashboard -c=kubernetes-dashboard --limits=cpu=200m,memory=512Mi -n kube-system
恢复kubectl rollout resume deploy kubernetes-dashboard -n kube-system
kubectl get csr
添加新工作节点kubectl get csr|grep 'Pending' | awk 'NR>0{print 1}';do kubectl certificate approve 1}';do kubectl certificate deny 1}';do kubectl delete csr $i;done
查看集群访问连接kubectl cluster-info
查看权限kubectl describe clusterrole cluster-admin -n kube-system
查看kubectl版本kubectl version
查看支持api版本kubectl api-version
查看当前kubectl配置kubectl config view
查看集群状态kubectl get componentstatuses
kubectl get rs
查看集群节点kubectl get nodes
查看命名空间kubectl get namespaces
Node状态维护每个Node都包括以下状态信息
地址:包括hostname、外网IP和内网IP
条件(Condition):包括OutOfDisk、Ready、MemoryPressure和DiskPressure
容量(Capacity):Node上的可用资源,包括CPU、内存和Pod总数
基本信息(Info):包括内核版本、容器引擎版本、OS类型等
维护状态/取消维护模式kubectl cordon NodeName
kubectl uncordon NodeName