Kubeadm是一个工具,提供kubeadminit和kubeadmjoin,用于快速部署Kubernetes集群。
.二进制
从官方下载发行版的二进制包,手动部署每个组件,组成Kubernetes集群。
CentOS7(使用yum进行安装)
通过修改daemon配置文件/etc/docker/daemon.json来使用加速器
部署Kubernetes集群主要有两种方式:
Kubeadm是一个K8s部署工具,提供kubeadminit和kubeadmjoin,用于快速部署Kubernetes集群。
从github下载发行版的二进制包,手动部署每个组件,组成Kubernetes集群。
这里采用kubeadm搭建集群。
kubeadm工具功能:
kubeadmalpha
服务器规划:
#Kubernetes的架构
#Kubernetes的初始化安装(每个节点都需要做)
---->关闭防火墙
[root@demo-master~]#systemctlstopfirewalld[root@demo-master~]#systemctldisablefirewalldRemovedsymlink/etc/systemd/system/multi-user.target.wants/firewalld.service.Removedsymlink/etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service.---->关闭selinux
[root@demo-master~]#sed-i's/enforcing/disabled/'/etc/selinux/config[root@demo-master~]#setenforce0---->关闭swap
[root@demo-master~]#swapoff-a[root@demo-master~]#sed-ri's/.*swap.*/#&/'/etc/fstab---->在master上编辑hosts(注意只在master上)
cat>>/etc/hosts<
[root@demo-master~]#cat>/etc/sysctl.d/k8s.conf< [root@demo-master~]#yum-yinstallntpdate[root@demo-master~]#ntpdatetime.windows.com#Kubernetes的安装(添加阿里云YUM软件源) yuminstall-ykubelet-1.21.0kubeadm-1.21.0kubectl-1.21.0systemctlenablekubelet#部署kubernetesMaster 在master节点上单独执行: kubeadminit\--apiserver-advertise-address=192.168.178.90\--image-repositoryregistry.aliyuncs.com/google_containers\--kubernetes-versionv1.21.0\--service-cidr=10.99.0.0/12\--pod-network-cidr=10.200.0.0/16\--ignore-preflight-errors=allmkdir-p$HOME/.kubesudocp-i/etc/kubernetes/admin.conf$HOME/.kube/configsudochown$(id-u):$(id-g)$HOME/.kube/config在node节点上执行 kubeadmjoin192.168.178.90:6443--tokenn6psi2.9p918j0vqvvmidlg\--discovery-token-ca-cert-hashsha256:8c3afb6c64372774def7df9ddd2dc11fcf3cc58bef8a4cb269b287a20175f322#部署kubernetes的网络插件 Calico是一个纯三层的数据中心网络方案,是目前Kubernetes主流的网络方案。 下载calico.yaml的文件 [root@demo-master~]#vimcalico.yaml -name:CALICO_IPV4POOL_CIDRvalue:"10.200.0.0/16"用yaml文件部署calico网络 [root@demo-master~]#kubectlapply-fcalico.yaml[root@demo-master~]#kubectlgetnodesCoreDNS问题处理: 在所有节点上重新pull拉起coreDNS镜像 [root@demo-master~]#dockerpullregistry.aliyuncs.com/google_containers/coredns:1.8.01.8.0:Pullingfromgoogle_containers/corednsc6568d217a00:Pullcomplete5984b6d55edf:Pullcomplete[root@demo-master~]#dockertagregistry.aliyuncs.com/google_containers/coredns:1.8.0registry.aliyuncs.com/google_containers/coredns/coredns:v1.8.0安装目录:/etc/kubernetes/ 组件配置文件目录:/etc/kubernetes/manifests/ #测试kubernetes集群搭建的情况 [root@demo-master~]#kubectlcreatedeploymentnginx--image=nginxdeployment.apps/nginxcreated[root@demo-master~]#kubectlexposedeploymentnginx--port=80--type=NodePortservice/nginxexposed[root@demo-master~]#kubectlgetpod,svcNAMEREADYSTATUSRESTARTSAGEpod/nginx-6799fc88d8-22mln1/1Running039sNAMETYPECLUSTER-IPEXTERNAL-IPPORT(S)AGEservice/kubernetesClusterIP10.96.0.1 Dashboard是官方提供的一个UI,可用于基本管理K8s资源。 默认Dashboard只能集群内部访问,修改Service为NodePort类型,暴露到外部: virecommended.yaml...kind:ServiceapiVersion:v1metadata:labels:k8s-app:kubernetes-dashboardname:kubernetes-dashboardnamespace:kubernetes-dashboardspec:ports:-port:443targetPort:8443nodePort:30001selector:k8s-app:kubernetes-dashboardtype:NodePort...部署: [root@demo-master~]#kubectlapply-fkubernetes-dashboard.yamlnamespace/kubernetes-dashboardcreatedserviceaccount/kubernetes-dashboardcreatedservice/kubernetes-dashboardcreatedsecret/kubernetes-dashboard-certscreatedsecret/kubernetes-dashboard-csrfcreatedsecret/kubernetes-dashboard-key-holdercreatedconfigmap/kubernetes-dashboard-settingscreatedrole.rbac.authorization.k8s.io/kubernetes-dashboardcreatedclusterrole.rbac.authorization.k8s.io/kubernetes-dashboardcreatedrolebinding.rbac.authorization.k8s.io/kubernetes-dashboardcreatedclusterrolebinding.rbac.authorization.k8s.io/kubernetes-dashboardcreateddeployment.apps/kubernetes-dashboardcreatedservice/dashboard-metrics-scrapercreateddeployment.apps/dashboard-metrics-scrapercreated创建serviceaccount并绑定默认cluster-admin管理员集群角色: [root@demo-master~]#kubectlcreateserviceaccountdashboard-admin-nkube-systemserviceaccount/dashboard-admincreated[root@demo-master~]#kubectlcreateclusterrolebindingdashboard-admin--clusterrole=cluster-admin--serviceaccount=kube-system:dashboard-adminclusterrolebinding.rbac.authorization.k8s.io/dashboard-admincreated #kubernetes基本概念 自动安装脚本: Master负责管理集群负责协调集群中的所有活动,例如调度应用程序,维护应用程序的状态,扩展和更新应用程序。 Node节点(即Work)是VM(虚拟机)或物理计算机,充当k8s集群中的工作计算机。每个Node节点都有一个Kubelet,它管理该Node节点并负责与Master节点通信。该Node节点还应具有用于处理容器操作的工具,例如Docker。 容器编排系统的: #kubernetes集群控制组件 Master组件 .kube-apiserverKubernetesAPI 集群的统一入口,各组件协调者,以RESTfulAPI提供接口服务,所有对象资源的增删改查和监听操作都交给APIServer处理后再提交给Etcd存储。 .kube-controller-manager 处理集群中常规后台任务,一个资源对应一个控制器,而ControllerManager就是负责管理这些控制器的。 .kube-scheduler 根据调度算法为新创建的Pod选择一个Node节点,可以任意部署,可以部署在同一个节点上,也可以部署在不同的节点上。 .etcd 分布式键值存储系统。用于保存集群状态数据,比如Pod、Service等对象信息。 Node组件 .kubelet kubelet是Master在Node节点上的Agent,管理本机运行容器的生命周期,比如创建容器、Pod挂载数据卷、下载secret、获取容器和节点状态等工作。kubelet将每个Pod转换成一组容器。 .kube-proxy 在Node节点上实现Pod网络代理,维护网络规则和四层负载均衡工作。 .docker或rocket 容器引擎,运行容器。 二、K8S监控与日志管理 MetricsServer是一个集群范围的资源使用情况的数据聚合器。作为一个应用部署在集群中。Metricserver从每个节点上KubeletAPI收集指标,通过Kubernetes聚合器注册在MasterAPIServer中。为集群提供Node、Pods资源利用率指标 Metrics-Server工作流程图 Metrics-Server部署 [root@k8s-master~]#kubectlgetapiservices|grepmetricsv1beta1.metrics.k8s.iokube-system/metrics-serverTrue17d #管理kubernetes组件日志systemd守护进程管理的组件: journalctl-ukubelet Pod部署的组件: kubectllogskube-proxy-btz4p-nkube-system 系统日志: /var/log/messages #查看kubernetes容器标准输出日志 [root@k8s-master~]#kubectllogsnginx-6799fc88d8-r4vrh [root@k8s-master~]#kubectllogs-fnginx-6799fc88d8-r4vrh [root@k8s-master~]#kubectllogs-fnginx-6799fc88d8-r4vrh-cnginx 标准输出在宿主机的路径: [root@k8s-master~]#cd/var/lib/docker/containers[root@k8s-mastercontainers]#ll#收集kubernetes日志的方法 针对标准输出:以DaemonSet方式在每个Node上部署一个日志收集程序,采集/var/lib/docker/containers/目录下的容器日志 针对容器中日志文件:在pod中增加一个容器运行日志采集器,使用emtyDir共享日志目录让日志采集器读取到日志文件 三、K8S管理应用程序生命周期(Deployment) #kubernetes部署应用程序流程 #Deployments的主要功能 管理Pod和ReplicaSet 具有上线部署、副本设定、滚动升级、回滚等功能 --->部署的过程:(命令行部署方式) [root@k8s-master~]#kubectlcreatedeploymentweb2--image=lizhenlian/java-demodeployment.apps/web2created[root@k8s-master~]#kubectlexposedeploymentweb2--port=80--type=NodePort--target-port=8080--name=web2service/web2exposed[root@k8s-master~]#kubectlgetpod,deployment,svc[root@k8s-master~]#kubectleditsvcweb2(可以在线编辑deployment的yaml文件) 格式:kubectledit --->部署的过程:(Yaml文件部署方式) YAML语法格式: 缩进表示层级关系不支持制表符“tab”缩进,使用空格缩进 通常开头缩进2个空格字符后缩进1个空格,如冒号、逗号等“---”表示YAML格式,一个文件的开始“#”注释 定义一个deployment的yaml文件:vimnginx-deployment.yaml apiVersion:apps/v1kind:Deploymentmetadata:name:webnamespace:defaultspec:replicas:1selector:matchLabels:app:webtemplate:metadata:labels:app:webspec:containers:-name:webimage:nginx:1.17 定义一个Service的yaml文件:vimnginx-service.yaml apiVersion:v1kind:Servicemetadata:name:nginx-service#Service的名称labels:#Service自己的标签app:nginx#为该Service设置key为app,value为nginx的标签spec:#这是关于该Service的定义,描述了Service如何选择Pod,如何被访问selector:#标签选择器app:nginx#选择包含标签app:nginx的Podports:-name:nginx-port#端口的名字protocol:TCP#协议类型TCP/UDPport:80#集群内的其他容器组可通过80端口访问ServicenodePort:32600#通过任意节点的32600端口访问ServicetargetPort:80#将请求转发到匹配Pod的80端口type:NodePort#Serive的类型,ClusterIP/NodePort/LoaderBalancer 一个deployment+service共同部署的Yaml文件 apiVersion:apps/v1kind:Deploymentmetadata:name:web5namespace:defaultspec:replicas:2selector:matchLabels:app:web5template:metadata:labels:app:web5spec:containers:-name:web5image:nginx:1.17---apiVersion:v1kind:Servicemetadata:name:web5namespace:defaultspec:ports:-port:80protocol:TCPtargetPort:80selector:app:web5type:NodePort[root@k8s-master~]#kubectlapply-fnginx-d1.yaml[root@k8s-master~]#kubectlgetpods,deployment,svc --->Scaling(伸缩)应用程序 伸缩的实现可以通过更改nginx-deployment.yaml文件中部署的replicas(副本数)来完成 修改了Deployment的replicas为4后,Kubernetes又为该Deployment创建了3新的Pod,这4个Pod有相同的标签。因此ServiceA通过标签选择器与新的Pod建立了对应关系,将访问流量通过负载均衡在4个Pod之间进行转发。 通过修改部署中的replicas(副本数)来完成扩展 [root@k8s-master~]#kubectleditdeploymentweb5 --->滚动更新(多Deployment动态更新)[root@k8s-master~]#kubectleditdeploymentweb5 在yaml文件中修改:image:nginx:1.8使用新的镜像替换原来版本nginx镜像 [root@k8s-master~]#kubectlapply-f --->回滚操作Deployment的详细过程: 有时,你可能想要回滚Deployment;例如,当Deployment不稳定时(例如进入反复崩溃状态)。默认情况下,Deployment的所有上线记录都保留在系统中,以便可以随时回滚(你可以通过修改修订历史记录限制来更改这一约束)。 [root@k8s-master~]#kubectlgetdeploymentnginx-deployment修改了这里: 升级错误出现这样: [root@k8s-master~]#kubectlsetimagedeployment.v1.apps/nginx-deploymentnginx=nginx:1.161--record=true 输出类似于:deployment.apps/nginx-deploymentimageupdatederror:unabletofindcontainernamed"nginx" [root@k8s-master~]#kubectlrolloutstatusdeployment/nginx-deployment 输出类似于: Waitingfordeployment"nginx-deployment"rollouttofinish:1outof3newreplicashavebeenupdated... [root@k8s-master~]#kubectlgetpods [root@k8s-master~]#kubectldescribedeployment [root@k8s-master~]#kubectlrollouthistorydeployment.v1.apps/nginx-deployment [root@k8s-master~]#kubectlrollouthistorydeployment.v1.apps/nginx-deployment--revision=1 [root@k8s-master~]#kubectlrolloutundodeployment.v1.apps/nginx-deployment 输出类似于:deployment.apps/nginx-deploymentrolledback 2.使用--to-revision来回滚到特定修订版本 [root@k8s-master~]#kubectlrolloutundodeployment.v1.apps/nginx-deployment--to-revision=1 3.检查回滚是否成功以及Deployment是否正在运行: [root@k8s-master~]#kubectlgetdeploymentnginx-deployment 输出类似于:NAMEREADYUP-TO-DATEAVAILABLEAGEnginx-deployment3/3337h49m4.获取Deployment描述信息: 回滚操作命令格式:(回滚是重新部署某一次部署时的状态,即当时版本所有配置) kubectlrollouthistorydeployment/web#查看历史发布版本 kubectlrolloutundodeployment/web#回滚上一个版本 kubectlrolloutundodeployment/web--to-revision=2#回滚历史指定版本 最后,项目下线: kubectldeletedeploy/web kubectldeletesvc/web #ReplicaSet控制器的用途 新建一个ReplicaSet: apiVersion:apps/v1kind:ReplicaSetmetadata:name:frontendlabels:app:guestbooktier:frontendspec:#modifyreplicasaccordingtoyourcasereplicas:3selector:matchLabels:tier:frontendtemplate:metadata:labels:tier:frontendspec:containers:-name:php-redisimage:nginx:1.17 [root@k8s-master~]#kubectlapply-fmy-rs.yaml#部署ReplicaSet[root@k8s-master~]#kubectlgetrs#查看ReplicaSetNAMEDESIREDCURRENTREADYAGEfrontend33313m[root@k8s-master~]#kubectldescribers/frontend#查看ReplicaSet的详细信息[root@k8s-master~]#kubectlgetpods#查看rs创建的podNAMEREADYSTATUSRESTARTSAGEfrontend-cphq51/1Running015mfrontend-drkgs1/1Running015mfrontend-kbbct1/1Running015m[root@k8s-master~]#kubectlgetpodsfrontend-kbbct-oyaml>t2.yaml#通过命令导出pod的yaml文件[root@k8s-master~]#kubectlgetrsfrontend-oyaml>rs1.yaml#通过命令导出ReplicaSet的yaml文件 [root@k8s-master~]#kubectldeletersfrontendreplicaset.apps"frontend"deleted 四、K8S管理应用程序生命周期(POD) #Pods 除了应用容器,Pod还可以包含在Pod启动期间运行的Init容器。你也可以在集群中支持临时性容器的情况下,为调试的目的注入临时性容器。 Pod特点: Pod主要用法: 运行多个容器: 资源共享实现机制: 将业务容器的网络加入到“负责网络容器”实现网络共享。共享存储:容器通过数据卷共享数据 #实现网络资源共享机制 [root@k8s-master~]#kubectlgetpodsNAMEREADYSTATUSRESTARTSAGEpod-net-test2/2Running013m 4.通过命令进入POD中的容器 [root@k8s-master~]#kubectlexec-itpod-net-test-ctest--sh /#ipaddr:eth0@if8: /#wget127.0.0.1:80Connectingto127.0.0.1:80(127.0.0.1:80) 5.从新进入POD中的web容器中 [root@k8s-master~]#kubectlexec-itpod-net-test-cweb--sh#cd/usr/share/nginx/html#ls50x.htmlindex.html #echo"yuanyeis12345">index.html#catindex.htmlyuanyeis12345 6.再进入POD中的busybox容器中查看 [root@k8s-master~]#kubectlexec-itpod-net-test-ctest--sh/#wget127.0.0.1:80Connectingto127.0.0.1:80(127.0.0.1:80)savingto'index.html'index.html100%|**************************************************|160:00:00ETA'index.html'saved/#catindex.htmlyuanyeis12345 这就是k8s的网络资源模式:和dockercontainer一样,启动了infraContainer容器,/pause:3.4.1容器就是这个基础容器#实现数据卷的共享机制 1.先创建一个pod的yaml文件 apiVersion:v1kind:Podmetadata:labels:app:testname:pod-volume-testnamespace:defaultspec:containers:-image:busyboxname:testcommand:["/bin/sh","-c","sleep12h"]volumeMounts:#数据卷挂载-name:log#指定挂载的数据卷名称mountPath:/data#数据卷挂载到容器中的路径-image:nginxname:webvolumeMounts:-name:logmountPath:/usr/share/nginx/htmlvolumes:#定义数据卷-name:log#数据卷名称emptyDir:{}#数据卷类型2.根据yaml文件部署POD [root@k8s-master~]#kubectlapply-fpod-vol.yaml 3.查看POD的运行状况 [root@k8s-master~]#kubectlgetpodsNAMEREADYSTATUSRESTARTSAGEpod-volume-test2/2Running04m39s 4.验证文件的共享 [root@k8s-master~]#kubectlexec-itpod-volume-test-ctest--sh/#cd/data/data#ls/data#touchyuan.txt/data#exit[root@k8s-master~]#kubectlexec-itpod-volume-test-cweb--sh#cd/usr/share/nginx/html#lsyuan.txt #POD的管理命令 ---------------------创建Pod:---------------------------------------kubectlapply-fpod.yaml或者使用命令:kubectlrunnginx--image=nginx-------------------------------查看Pod:-------------------------------kubectlgetpodskubectldescribepod #POD的重启策略,健康检查 重启策略(restartPolicy):Always:当容器终止退出后,总是重启容器,默认策略。OnFailure:当容器异常退出(退出状态码非0)时,才重启容器。Never:当容器终止退出,从不重启容器。 健康检查有以下两种类型:livenessProbe(存活检查):如果检查失败,将杀死容器,根据Pod的restartPolicy来操作。readinessProbe(就绪检查):如果检查失败,Kubernetes会把Pod从serviceendpoints中剔除。 建立一个有健康检查的pod --->POD健康检查的演示: 1、通过create的方式导出一个deployment的yaml文件 [root@k8s-master~]#kubectlcreatedeploymentpod-check--image=nginx--dry-run=client-oyaml>check-dep.yaml 2、编辑yaml文件 3、apply一个deployment的yaml文件 kubectlapply-fcheck-deployment.yaml 4、观察deployment的启动情况 NAMEREADYSTATUSRESTARTSAGEpod-check-67fd5d95b8-24prt1/1Running017hpod-check-67fd5d95b8-rmjj51/1Running017hpod-check-67fd5d95b8-xbttq1/1Running017h 5、进行存活检查的试验,通过命令进入到容器中 [root@k8s-master~]#kubectlexec-itpod-check-67fd5d95b8-24prt--bashroot@pod-check-67fd5d95b8-24prt:/# root@pod-check-67fd5d95b8-24prt:/#cd/usr/share/nginx/htmlroot@pod-check-67fd5d95b8-24prt:/usr/share/nginx/html#ls50x.htmlindex.htmlroot@pod-check-67fd5d95b8-24prt:/usr/share/nginx/html#rmindex.html root@pod-check-67fd5d95b8-24prt:/usr/share/nginx/html#commandterminatedwithexitcode137index.html文件被删除后,存活检查就自动终止了这个容器,重新拉起新的容器。 --->POD环境变量的演示: 1、编辑一个环境变量演示的POD apiVersion:v1kind:Podmetadata:name:pod-envspec:containers:-name:testimage:busyboxcommand:["sh","-c","sleep3600"]env:#变量值从Pod属性获取-name:MY_NODE_NAMEvalueFrom:fieldRef:fieldPath:spec.nodeName-name:MY_POD_NAMEvalueFrom:fieldRef:fieldPath:metadata.name-name:MY_POD_IPvalueFrom:fieldRef:fieldPath:status.podIP-name:ABCvalue:"123456"#变量值从Pod属性获取-name:MY_NODE_NAMEvalueFrom:fieldRef:fieldPath:spec.nodeName 2、观察pod的运行情况 [root@k8s-master~]#kubectlgetpodNAMEREADYSTATUSRESTARTSAGEpod-env1/1Running051s 3、进入容器查看环境变量: [root@k8s-master~]#kubectlexec-itpod-envsh/#echo$ABC123456/#echo$MY_POD_NAMESPACE/#echo$MY_POD_IP10.244.169.139 #POD对象:InitContainer InitContainer:顾名思义,用于初始化工作,执行完就结束,可以理解为一次性任务。支持大部分应用容器配置,但不支持健康检查优先应用容器执行应用场景:环境检查:例如确保应用容器依赖的服务启动后再启动应用容器初始化配置:例如给应用容器准备配置文件 --->示例:部署一个web网站,网站程序没有打到镜像中,而是希望从代码仓库中动态拉取放到应用容器中。 1、编辑一个yaml文件 [root@k8s-master~]#kubectlgetpodsNAMEREADYSTATUSRESTARTSAGEinit-demo0/1Init:Error06s 3、查看init初始化容器的运行情况 [root@k8s-master~]#kubectllogsinit-demo-cd1(d1是initContainers的容器运行名称)Connectingto43.129.209.143(43.129.209.143:80)index.html100%|*******************************|210770:00:00ETA(表示已经下载了index.html文件到共享存储中了) 4、进入第二个容器查看下载到共享文件夹的文件 [root@k8s-master~]#kubectlgetpodsNAMEREADYSTATUSRESTARTSAGEinit-demo1/1Running05m33s [root@k8s-master~]#kubectlexec-itinit-demo--bashDefaultedcontainer"nginx"outof:nginx,d1(init)root@init-demo:/#cd/usr/share/nginx/htmlroot@init-demo:/usr/share/nginx/html#lsindex.html #POD中容器类型 Pod中会有这几种类型的容器:InfrastructureContainer:基础容器,维护整个Pod网络空间InitContainers:初始化容器,先于业务容器开始执行Containers:业务容器,并行启动 #静态POD 静态Pod特点:Pod由特定节点上的kubelet管理不能使用控制器Pod名称标识当前节点名称在kubelet配置文件启用静态Pod的参数:[root@k8s-master~]#vim/var/lib/kubelet/config.yaml [root@k8s-master~]#ll/etc/kubernetes/manifests/total16-rw-------1rootroot2226Sep1414:23etcd.yaml#etcd的yaml文件-rw-------1rootroot3335Sep1414:23kube-apiserver.yaml#apiserver的yaml文件-rw-------1rootroot2827Sep1414:23kube-controller-manager.yaml#controller-manager的yaml文件-rw-------1rootroot1413Sep1414:23kube-scheduler.yaml#scheduler的yaml文件 五、K8S的Pod调度 #创建一个Pod的工作流程 Kubernetes基于list-watch机制的控制器架构,实现组件间交互的解耦。其他组件监控自己负责的资源,当这些资源发生变化时,kube-apiserver会通知这些组件,这个过程类似于发布与订阅。 容器资源限制:limits(容器里应用程序使用的最大资源上限) resources.limits.cpu resources.limits.memory 容器使用的最小资源需求,作为容器调度时资源分配的依据:requests (请求值,预留值,不是实际使用值,用于资源分配的参考值。) resources.requests.cpuresources.requests.memory #实例:pod资源调度 1、编辑yaml文件 [root@master~]#vimtest-resources.yaml apiVersion:v1kind:Podmetadata:name:webspec:containers:-name:webimage:nginxresources:requests:memory:"64Mi"cpu:"250m"limits:memory:"128Mi"cpu:"500m"resources: requests: memory:"64Mi" cpu:"250m" limits: memory:"128Mi" cpu:"500m" 2、部署实例 [root@master~]#kubectlapply-ftest-resources.yaml 3、通过kubectldescribe查看pod运行的情况,观察pod资源调度的详细情况 [root@master~]#kubectldescribepodweb查看pod的运行详细情况。 4、通过查看node1上运行的情况,了解pod资源调用情况,该pod是运行在node1上的,然后通过命令可以查看node1上的 所有pod运行资源的调度情况; [root@master~]#kubectldescribenodenode1 (CPU单位:可以写m也可以写浮点数,例如0.5=500m,1=1000m) (K8s会根据Request的值去查找有足够资源的Node来调度此Pod) (requests一般良性参考值小于limits的20%---30%) (节点上的limits总和不能超宿主机实际物理配置的20%) (当请求的资源值大于节点的资源情况,pod就会处于pendding状态,无法调度) #通过命令可以查看node节点上的资源情况 [root@master~]#kubectldescribenode|grepcpu #nodeSelector nodeSelector:用于将Pod调度到匹配Label的Node上,如果没有匹配的标签会调度失败。作用:约束Pod到特定的节点运行完全匹配节点标签应用场景:专用节点:根据业务线将Node分组管理配备特殊硬件:部分Node配有SSD硬盘、GPU 示例:确保Pod分配到具有SSD硬盘的节点上 1、编辑一个带ssd标签的yaml文件 apiVersion:v1kind:Podmetadata:name:pod-selectorspec:nodeSelector:disktype:"ssd"containers:-name:test-selectorimage:nginx:1.19 2、查看pod的部署情况,因为node上没有disktype:“ssd”的标签,所以是pending状态 3、给node1节点添加标签 [root@master~]#kubectllabelnodesnode2disktype=ssd 验证节点标签: [root@master~]#kubectlgetnodes--show-labels 4、验证pod的部署情况 [root@master~]#kubectlgetpods-owide #nodeAffinity nodeAffinity:节点亲和类似于nodeSelector,可以根据节点上的标签来约束Pod可以调度到哪些节点。相比nodeSelector:匹配有更多的逻辑组合,不只是字符串的完全相等,支持的操作符有:In、NotIn、Exists、DoesNotExist、Gt、Lt调度分为软策略和硬策略,而不是硬性要求硬(required):必须满足软(preferred):尝试满足,但不保证 #Taint(污点)Tolerations(污点容忍) Taints:避免Pod调度到特定Node上Tolerations:允许Pod调度到持有Taints的Node上应用场景:专用节点:根据业务线将Node分组管理,希望在默认情况下不调度该节点,只有配置了污点容忍才允许分配配备特殊硬件:部分Node配有SSD硬盘、GPU,希望在默认情况下不调度该节点,只有配置了污点容忍才允许分配基于Taint的驱逐 示例:Tain't污点 1、查看节点上的Taint(污点)的情况 [root@master~]#kubectldescribenodemaster|grepTaint [root@master~]#kubectldescribenode|grepTaint 2、给节点添加污点(Tiant) [root@master~]#kubectltaintnodenode1disktype=ssd:NoSchedule 3、编辑一个可以被node1节点上调度的yaml文件 apiVersion:v1kind:Podmetadata:name:pod-selectorspec:nodeSelector:disktype:"ssd"containers:-name:test-selectorimage:nginx:1.194、调度部署一个带有节点选择的pod 不被节点所调度,原因是: 5、添加污点容忍在调度 apiVersion:v1kind:Podmetadata:name:pod-selectorspec:nodeSelector:disktype:"ssd"tolerations:-key:"disktype"#污点的键值operator:"Equal"#等于value:"ssy"#污点的键值对应effect:"NoSchedule"containers:-name:test-selectorimage:nginx:1.19Tolerations(污点容忍)的操作方法 tolerations: -key:"disktype"#污点的键值 operator:"Equal"#等于 value:"ssy"#污点的键值对应 effect:"NoSchedule" 6、删除节点的污点 [root@master~]#kubectltaintnodenode1disktype=ssd:NoSchedule-#后面跟一个减号,中间没有空格 Taint污点的一下操作方法 给节点添加污点格式:kubectltaintnode[node]key=value:[effect]例如:kubectltaintnodek8s-node1gpu=yes:NoSchedule验证:kubectldescribenodek8s-node1|grepTaint其中[effect]可取值:NoSchedule:一定不能被调度PreferNoSchedule:尽量不要调度,非必须配置容忍NoExecute:不仅不会调度,还会驱逐Node上已有的Pod 示例:Tain't污点,给一个节点添加3个污点 kubectltaintnodesnode1key1=value1:NoSchedulekubectltaintnodesnode1key1=value1:NoExecutekubectltaintnodesnode1key2=value2:NoSchedulePod,它有两个容忍度:--------------------> tolerations:-key:"key1"operator:"Equal"value:"value1"effect:"NoSchedule"-key:"key1"operator:"Equal"value:"value1"effect:"NoExecute"这种情况,上述pod不会被分配到该节点,因为其没有容忍度和第三个污点相匹配。 给一个节点添加了一个effect值为NoExecute的污点,则任何不能忍受这个污点的Pod都会马上被驱逐,任何可以忍受这个污点的Pod都不会被驱逐。 tolerations:-key:"key1"operator:"Equal"value:"value1"effect:"NoExecute"tolerationSeconds:3600#nodeName nodeName:指定节点名称,用于将Pod调度到指定的Node上,不经过调度器即使是node1节点上有污点的,都能顺利调度。 应用场景:主要是在开发中使用,直接调度到节点上运行容器。 1、编辑有nodeName的yaml文件 apiVersion:v1kind:Podmetadata:name:test-nodenamelabels:app:nginxspec:nodeName:node1containers:-name:nginximage:nginx:1.172、部署及查看是否运行到节点node1上 [root@master~]#kubectlapply-ftest-nodename.yaml 直接就分配到node1这个节点上。 #DaemonSet DaemonSet功能: DaemonSet确保全部(或者某些)节点上运行一个Pod的副本。当有节点加入集群时,也会为他们新增一个Pod。当有节点从集群移除时,这些Pod也会被回收。删除DaemonSet将会删除它创建的所有Pod。 DaemonSet的一些典型用法: 应用场景:网络插件、监控Agent、日志Agent 如:calico组件,proxy组件都是每个节点上运行的。 示例:DaemonSet的使用 1、部署一个日志采集程序 [root@master~]#kubectlcreatedeploymentweb8--image=nginx--dry-run=client-oyaml>test-daemonset.yaml[root@master~]#vimtest-daemonset.yaml apiVersion:apps/v1kind:DaemonSetmetadata:name:test-daemonsetnamespace:kube-systemspec:selector:matchLabels:name:test-daemonsettemplate:metadata:labels:app:test-daemonsetspec:containers:-image:elastic/filebeat:7.3.2name:log 2、部署后查看情况,但是只运行了两个node节点 [root@master~]#kubectlapply-ftest-daemonset.yaml [root@master~]#kubectlgetpods-nkube-system NAMEREADYSTATUSRESTARTSAGEtest-daemonset-k55pq1/1Running06m25stest-daemonset-mt6qf1/1Running06m25s3、查原因,原来是master上有污点,说明DaemonSet的调度也受污点的影响。 [root@master~]#kubectldescribenode|grepTaintTaints:node-role.kubernetes.io/master:NoScheduleTaints: 4、删除master上的污点 [root@master~]#kubectldescribenode|grepTaintTaints:node-role.kubernetes.io/master:NoScheduleTaints: 5、从新部署DaemonSet,再查看部署情况,master上的污点一经去除,DaemonSet就自动部署了 [root@master~]#kubectlgetpods-nkube-system[root@master~]#kubectlgetpods-owide-nkube-system|greptest-daemonset test-daemonset-6vhgs1/1Running06m17s10.244.219.65mastertest-daemonset-k55pq1/1Running019m10.244.104.26node2test-daemonset-mt6qf1/1Running019m10.244.166.148node1六、K8S网络(Service与Ingress篇) @Service的学习部分 使用Kubernetes,你无需修改应用程序即可使用不熟悉的服务发现机制。 Kubernetes为Pods提供自己的IP地址,并为一组Pod提供相同的DNS名,并且可以在它们之间进行负载均衡。 Service:引入主要是解决Pod的动态变化,提供统一访问入口:防止Pod失联,准备找到提供同一个服务的Pod(服务发现)定义一组Pod的访问策略(负载均衡) Service通过标签关联一组PodService使用iptables或者ipvs为一组Pod提供负载均衡能力 [root@master~]#kubectlexposedeploymentpod-selector--port=80--target-port=80--dry-run=client-oyaml>test-service.yaml ######通过kubectl创建svc的方法############ 1、查看kubectl中现有的pod,并创建一个与之关联的svc [root@master~]#kubectlgetpods NAMEREADYSTATUSRESTARTSAGEpod-selector1/1Running09m20s[root@master~]#kubectlexposepodpod-selector--port=80--type=NodePort--name=f1[root@master~]#kubectlgetsvc NAMETYPECLUSTER-IPEXTERNAL-IPPORT(S)AGEf1NodePort10.101.45.147 3、查看该svc的ep情况 [root@master~]#kubectlgetep NAMEENDPOINTSAGEf110.244.104.27:802m37ssvc的yaml文件:也可以通过YAML文件进行部署。 apiVersion:v1kind:Servicemetadata:name:webspec:type:ClusterIP#服务类型ports:-port:80#Service端口protoclol:TCP#协议targetPort:80#容器端口(应用程序监听端口)selector:app:web#指定关联pod的标签Service的多端口定义:对于某些服务,需要公开多个端口,Service也需要配置多个端口定义,通过端口名称区分。 ClusterIP:默认,分配一个稳定的IP地址,即VIP,只能在集群内部访问。 NodePort:在每个节点上启用一个端口来暴露服务,可以在集群外部访问。也会分配一个稳定内部集群IP地址。这时就需要前面加一个公网负载均衡器为项目提供统一访问入口了。也会在每台Node上监听端口接收用户流量,在实际情况下,对用户暴露的只会有一个IP和端口,那这么多台Node该使用哪台让用户访问呢?访问地址:<任意NodeIP>: LoadBalancer:与NodePort类似,在每个节点上启用一个端口来暴露服务。除此之外,Kubernetes会请求底层云平台(例如阿里云、腾讯云、AWS等)上的负载均衡器,将每个Node([NodeIP]:[NodePort])作为后端添加进去。 Service代理模式: *(1)第一种代理模式:IPtabels 1、查看k8s集群内的svc [root@master~]#kubectlgetsvc NAMETYPECLUSTER-IPEXTERNAL-IPPORT(S)AGEf1NodePort10.101.45.147 [root@master~]#iptables-save|greptest-web5 -AKUBE-NODEPORTS-ptcp-mcomment--comment"default/test-web5"-mtcp--dport32074-jKUBE-MARK-MASQ-AKUBE-NODEPORTS-ptcp-mcomment--comment"default/test-web5"-mtcp--dport32074-jKUBE-SVC-R4AN3NJI2MCEMEEW3、查看KUBE-SVC-R4AN3NJI2MCEMEEW的iptables转发情况 -AKUBE-SVC-R4AN3NJI2MCEMEEW-mcomment--comment"default/test-web5"-mstatistic--moderandom--probability0.33333333349-jKUBE-SEP-QTID6BIIMABWQ25O-AKUBE-SVC-R4AN3NJI2MCEMEEW-mcomment--comment"default/test-web5"-mstatistic--moderandom--probability0.50000000000-jKUBE-SEP-RKGA2BK4C2R5IJDB-AKUBE-SVC-R4AN3NJI2MCEMEEW-mcomment--comment"default/test-web5"-jKUBE-SEP-NQ5HVJ2SU7ICHFKQ (--moderandom--probability0.33333333349)这个就是实现负载均衡的的权重和转发概率。最后一条记录: -AKUBE-SVC-R4AN3NJI2MCEMEEW-mcomment--comment"default/test-web5"-jKUBE-SEP-NQ5HVJ2SU7ICHFKQ是上面两条都不能成功转发后默认的转发记录:4、如果test-web5中扩展了4个pod后的转发情况[root@master~]#kubectlscaledeploymenttest-web5--replicas=4deployment.apps/test-web5scaled[root@master~]#kubectlgetpodsNAMEREADYSTATUSRESTARTSAGEtest-web5-7dbf57497-4hc9k1/1Running182mtest-web5-7dbf57497-6bx8z1/1Running182mtest-web5-7dbf57497-7z7bt1/1Running162mtest-web5-7dbf57497-8p4f21/1Running011s[root@master~]#kubectlgetepNAMEENDPOINTSAGEtest-web510.244.104.34:80,10.244.104.37:80,10.244.166.152:80+1more...83m[root@master~]#iptables-save|grepKUBE-SVC-R4AN3NJI2MCEMEEW -AKUBE-SVC-R4AN3NJI2MCEMEEW-mcomment--comment"default/test-web5"-mstatistic--moderandom--probability0.25000000000-jKUBE-SEP-QTID6BIIMABWQ25O-AKUBE-SVC-R4AN3NJI2MCEMEEW-mcomment--comment"default/test-web5"-mstatistic--moderandom--probability0.33333333349-jKUBE-SEP-RKGA2BK4C2R5IJDB-AKUBE-SVC-R4AN3NJI2MCEMEEW-mcomment--comment"default/test-web5"-mstatistic--moderandom--probability0.50000000000-jKUBE-SEP-NQ5HVJ2SU7ICHFKQ-AKUBE-SVC-R4AN3NJI2MCEMEEW-mcomment--comment"default/test-web5"-jKUBE-SEP-CJO4UEZOBF7U6YA55、根据每条转发后面的链进行查看转发到那个pod上 [root@master~]#iptables-save|grepKUBE-SEP-QTID6BIIMABWQ25O -AKUBE-SEP-QTID6BIIMABWQ25O-ptcp-mcomment--comment"default/test-web5"-mtcp-jDNAT--to-destination10.244.104.34:80从IP地址可以看出,iptables转发到第一个POD上的服务上, [root@master~]#iptables-save|grepKUBE-SEP-RKGA2BK4C2R5IJDB -AKUBE-SEP-RKGA2BK4C2R5IJDB-ptcp-mcomment--comment"default/test-web5"-mtcp-jDNAT--to-destination10.244.104.37:80[root@master~]#kubectlgetep test-web510.244.104.34:80,10.244.104.37:80,10.244.166.152:80+1more...90m让他查看第2个链就知道转发到第2个pod上的IP地址。 *(2)第二种代理模式:IPVS 1、查看kube-proxy的转发规则 [root@master~]#kubectllogskube-proxy-zlrj4-nkube-system|more I092601:33:49.7916121node.go:172]SuccessfullyretrievednodeIP:192.168.178.12I092601:33:49.7916901server_others.go:140]DetectednodeIP192.168.178.12W092601:33:49.7917701server_others.go:592]Unknownproxymode"",assumingiptablesproxyI092601:33:49.8253751server_others.go:206]kube-proxyrunningindual-stackmode,IPv4-primaryI092601:33:49.8254351server_others.go:212]UsingiptablesProxier.#说明kube-proxy使用IPtables转发规则2、修改kube-proxy的转发规则为:IPVS [root@master~]#kubectleditconfigmapkube-proxy-nkube-system打开kube-proxy的配置文件进行修改,在vim中查询:/mode: 修改:mode:"ipvs" 删除kube-proxy的所有pod让kube-proxy重建: [root@master~]#forpin$(kubectlgetpods--namespace=kube-system-lk8s-app=kube-proxy-oname);\>dokubectldelete--namespace=kube-system$p;done 3、在节点上安装IPVS的工具:ipvsadmin [root@master~]#yuminstall-yipvsadm 4、通过命令:ipvsadm-L-n查看IPVS的转发规则 [root@node1~]#ipvsadm-L-n 5、查看IPVS的转发的情况 TCP172.17.0.1:32074rr->10.244.104.34:80Masq100->10.244.104.37:80Masq100->10.244.166.152:80Masq100->10.244.166.155:80Masq100*(3)IPtables和IPVS比较 Iptables:灵活,功能强大规则遍历匹配和更新,呈线性时延IPVS:工作在内核态,有更好的性能调度算法丰富:rr,wrr,lc,wlc,iphash... *(4)ServiceDNS名称访问 CoreDNS:是一个DNS服务器,Kubernetes默认采用,以Pod部署在集群中,CoreDNS服务监视KubernetesAPI,为每一个Service创建DNS记录用于域名解析。 ClusterIPA记录格式: ---------------------通过命令的演示,DNS的解析情况-------------------------------------------- [root@master~]#kubectlrundns-t--image=busybox:1.28.4--sleep24h NAMEREADYSTATUSRESTARTSAGEdns-t1/1Running022s[root@master~]#kubectlexec-itdns-t--sh/#---->这个是busybox运行的命令提示符: /#nslookupkubernetesServer:10.96.0.10Address1:10.96.0.10kube-dns.kube-system.svc.cluster.localName:kubernetesAddress1:10.96.0.1kubernetes.default.svc.cluster.local[root@master~]#kubectlgetsvc NAMETYPECLUSTER-IPEXTERNAL-IPPORT(S)AGEf1NodePort10.101.45.147 Server:10.96.0.10Address1:10.96.0.10kube-dns.kube-system.svc.cluster.localName:test-web5Address1:10.100.32.68test-web5.default.svc.cluster.local=================================================================================== @Ingress的学习部分 Ingress配置为服务提供外部可访问的URL、负载均衡流量、终止SSL/TLS,以及提供基于名称的虚拟主机等能力。 NodePort存在的不足: Ingress: --->Ingress控制器的创建 1、IngressController的namespace名称空间的创建 apiVersion:v1kind:Namespacemetadata:name:ingress-nginxlabels:app.kubernetes.io/name:ingress-nginxapp.kubernetes.io/part-of:ingress-nginx2、IngressController的configMap的创建 kind:ConfigMapapiVersion:v1metadata:name:nginx-configurationnamespace:ingress-nginxlabels:app.kubernetes.io/name:ingress-nginxapp.kubernetes.io/part-of:ingress-nginx---kind:ConfigMapapiVersion:v1metadata:name:tcp-servicesnamespace:ingress-nginxlabels:app.kubernetes.io/name:ingress-nginxapp.kubernetes.io/part-of:ingress-nginx---kind:ConfigMapapiVersion:v1metadata:name:udp-servicesnamespace:ingress-nginxlabels:app.kubernetes.io/name:ingress-nginxapp.kubernetes.io/part-of:ingress-nginx3、IngressController的ServiceAccount的创建 apiVersion:v1kind:ServiceAccountmetadata:name:nginx-ingress-serviceaccountnamespace:ingress-nginxlabels:app.kubernetes.io/name:ingress-nginxapp.kubernetes.io/part-of:ingress-nginx 4、IngressController的rbac的创建 6、部署IngressController [root@master~]#kubectlapply-fingress-controller.yaml [root@master~]#kubectlgetpods-ningress-nginx NAMEREADYSTATUSRESTARTSAGEnginx-ingress-controller-9h9cj1/1Running02m30snginx-ingress-controller-cghjt1/1Running02m30snginx-ingress-controller-pk48r1/1Running02m30s 7、创建Ingress规则,使用Ingress(规范化,标准化) 8、部署Ingress的规则 [root@master~]#vimtest-ingress.yaml[root@master~]#kubectlapply-ftest-ingress.yamlingress.networking.k8s.io/yuan-webcreated[root@master~]#kubectlgetingress NAMECLASSHOSTSADDRESSPORTSAGEyuan-web 8、绑定本地host来解析web.yuanye.com [root@master~]#kubectlgetpods-ningress-nginx-owide NAMEREADYSTATUSRESTARTSAGEIPNODENOMINATEDNODEREADINESSGATESnginx-ingress-controller-9h9cj1/1Running027m192.168.178.11node1 [root@master~]#vim/etc/hosts 192.168.178.10masterweb.yuanye.com192.168.178.11node1192.168.178.12node2在集群内部就可以用web.yuanye.com访问test-web5的网页内容: --->Ingress规则配置:HTTPS 1、安装cfssl进行认证 要下载一个cfssl.tar.gz的软件包,在解压 [root@master~]#tarzxvfcfssl.tar.gz [root@master~]#mvcfssl*/usr/bin/ [root@master~]#mkdirssl[root@master~]#cdssl 2、编辑cfssl脚本文件进行证书创建 [root@masterssl]#vimcerts.shcat>ca-config.json< 3、安装cfssl进行认证 [root@masterssl]#shcerts.sh 2021/09/2709:28:51[INFO]generatinganewCAkeyandcertificatefromCSR2021/09/2709:28:51[INFO]generatereceivedrequest2021/09/2709:28:51[INFO]receivedCSR2021/09/2709:28:51[INFO]generatingkey:rsa-20482021/09/2709:28:51[INFO]encodedCSR 4、将证书文件保存到Secret中 [root@masterssl]#kubectlcreatesecrettlsweb-yuanye-com--cert=web.yuanye.com.pem--key=web.yuanye.com-key.pem出现:secret/web-yuanye-comcreated提示,表示成功! [root@masterssl]#kubectlgetsecret NAMETYPEDATAAGEdefault-token-4ct6fkubernetes.io/service-account-token36d16hweb-yuanye-comkubernetes.io/tls256s 5、编辑Ingress的yaml文件 [root@masterssl]#kubectlgetingress --->IngressController怎样工作 IngressController:通过与KubernetesAPI交互,动态的去感知集群中Ingress规则变化,然后读取它,按照自定义的规则,规则就是写明了哪个域名对应哪个service,生成一段Nginx配置,应用到管理的Nginx服务,然后热加载生效。以此来达到Nginx负载均衡器配置及动态更新的问题。 数据包流程:客户端->IngressController(nginx)->分布在各节点Pod NAMEREADYSTATUSRESTARTSAGEnginx-ingress-controller-9h9cj1/1Running0108mnginx-ingress-controller-cghjt1/1Running0108mnginx-ingress-controller-pk48r1/1Running0108m[root@master~]#kubectlexec-itnginx-ingress-controller-9h9cj-ningress-nginx--bashbash-5.0$ps-ef PIDUSERTIMECOMMAND1www-data0:00/usr/bin/dumb-init--/nginx-ingress-controller--configmap=ingress-nginx/nginx-configurati7www-data0:09/nginx-ingress-controller--configmap=ingress-nginx/nginx-configuration--tcp-services-conf35www-data0:00nginx:masterprocess/usr/local/nginx/sbin/nginx-c/etc/nginx/nginx.conf320www-data0:00nginx:workerprocess321www-data0:00nginx:workerprocess322www-data0:00nginx:workerprocess323www-data0:00nginx:workerprocess347www-data0:00nginx:workerprocess357www-data0:00nginx:workerprocess400www-data0:00nginx:workerprocess423www-data0:00nginx:workerprocess424www-data0:00nginx:cachemanagerprocess586www-data0:00bash592www-data0:00ps-ef维护了两个进程: nginx:实现pod的负载均衡 nginx-ingress-controller:访问k8sapi获取创建的Ingress,生成对应的nginx配置文件,并且生效 bash-5.0$cat/etc/nginx/nginx.conf|grepweb.yuanye.com ##startserverweb.yuanye.comserver_nameweb.yuanye.com;##endserverweb.yuanye.com七、K8S存储(PV、PVC、Secret、ConfigMap篇) 背景 卷的核心是一个目录,其中可能存有数据,Pod中的容器可以访问该目录中的数据。所采用的特定的卷类型将决定该目录如何形成的、使用何种介质保存数据以及目录中存放的内容。 Kubernetes卷(Volume)抽象概念能够解决这两个问题:问题1:当容器崩溃时,kubelet会重建容器,容器内文件会丢失问题2:一个Pod中运行多个容器并需要共享文件 Kubernetes常用的数据卷(Volume): ----------------------------------------------------------------------------------------------------------- (一)、emptyDir临时数据卷 emptyDir卷:是一个临时存储卷,与Pod生命周期绑定一起,如果Pod删除了卷也会被删除。应用场景:Pod中容器之间数据共享 1、部署一个emptyDir临时卷的pod apiVersion:v1kind:Podmetadata:name:my-podspec:containers:-name:w1image:centoscommand:["bash","-c","foriin{1..100};doecho$i>>/data/hello;sleep1;done"]volumeMounts:-name:datamountPath:/data-name:r1image:centoscommand:["bash","-c","tail-f/data/hello"]volumeMounts:-name:datamountPath:/datavolumes:-name:dataemptyDir:{}[root@master~]#kubectlapply-ftest-emptydir.yaml [root@master~]#kubectlexec-itmy-pod-cw1--bash[root@my-poddata]#cathello[root@master~]#kubectlexec-itmy-pod-cr1--bash2、查看emptyDir临时卷在宿主机的目录位置 [root@master~]#kubectlgetpods-owide|grepmy-pod my-pod1/2NotReady0118s10.244.166.170node1 [root@node1~]#cd/var/lib/kubelet/pods [root@node1~]#dockerps|grepmy-pod 7889bd31ae46centosk8s_w1_my-pod_default_35b609a9-291b-4fd3-8f40-43c88a44e3db_1[root@node1pods]#cd35b609a9-291b-4fd3-8f40-43c88a44e3db[root@node135b609a9-291b-4fd3-8f40-43c88a44e3db]#ls drwxr-xr-x3rootroot18Sep2808:29kubernetes.io~empty-dirdrwxr-xr-x3rootroot35Sep2808:29kubernetes.io~projected[root@node1kubernetes.io~empty-dir]#cddata[root@node1data]#cathello emptyDir在宿主机上的工作目录: /var/lib/kubelet/pods/ (二)、hostPath节点数据卷 hostPath卷:挂载Node文件系统(Pod所在节点)上文件或者目录到Pod中的容器。应用场景:Pod中容器需要访问宿主机文件 1、用yaml文件部署一个hostPath卷的pod apiVersion:v1kind:Podmetadata:name:my-hostpathspec:containers:-name:busyboximage:busyboxargs:-/bin/sh--c-sleep36000volumeMounts:-name:datamountPath:/datavolumes:-name:datahostPath:path:/tmptype:Directory[root@master~]#kubectlapply-ftest-hostpath.yaml[root@master~]#kubectlgetpods NAMEREADYSTATUSRESTARTSAGEmy-hostpath1/1Running037s2、查看运行情况(可以用pod来收集宿主上的信息)通过命令查看my-hostpath容器运行在那个节点上: [root@master~]#kubectlgetpod-owide|grepmy-hostpath my-hostpath1/1Running02m36s10.244.166.171node1进到宿主机节点上node1上的/tmp目录 [root@node1tmp]#toucht.txt[root@node1tmp]#lst.txt进入到my-hostpath的容器中查看[root@master~]#kubectlexec-itmy-hostpath--sh /#cd/data/data#lst.txt (三)、NFS网络数据卷 NFS卷:提供对NFS挂载支持,可以自动将NFS共享路径,挂载到Pod中NFS:是一个主流的文件共享服务器。 1、在node2上安装NFS服务端,其他节点安装NFS客户端 [root@node2~]#yum-yinstallnfs-utils [root@node2~]#vim/etc/exports#配置nfs的共享目录/yfs/k8s*(rw,no_root_squash) [root@node2~]#mkdir-p/yfs/k8s [root@node2~]#systemctlstartnfs[root@node2~]#systemctlenablenfs 在node1上测试挂载情况: [root@node1~]#mount-tnfs192.168.178.12:/yfs/k8s/mnt [root@node1~]#df-Th 192.168.178.12:/yfs/k8snfs492G9.3G83G11%/mnt验证挂载的目录具备读写权限: 在客户端的写文件:-----> [root@node1~]#cd/mnt[root@node1mnt]#echo"11244">t.txt[root@node1mnt]#lst.txt在NFS服务器端的文件:----> [root@node2~]#cd/yfs/k8s[root@node2k8s]#lltotal4-rw-r--r--1rootroot6Sep2811:28t.txt在NFS客户端卸载刚才挂载的/mnt:----> [root@node1~]#umount/mnt/ 2、示例:将Nginx网站程序根目录持久化到NFS存储,为多个Pod提供网站程序文件 编辑Deployment的yaml文件 apiVersion:apps/v1kind:Deploymentmetadata:name:nfs-web6spec:selector:matchLabels:app:nfs-web6replicas:3template:metadata:labels:app:nfs-web6spec:containers:-name:nfs-web6image:nginxvolumeMounts:-name:wwwrootmountPath:/usr/share/nginx/htmlports:-containerPort:80volumes:-name:wwwrootnfs:server:192.168.178.12path:/yfs/k8s [root@master~]#kubectlapply-ftest-nfs.yaml 4、进到容器看共享目录的情况 [root@master~]#kubectlexec-itnfs-web6-65747989d9-mr7k8--bashroot@nfs-web6-65747989d9-mr7k8:/#cd/usr/share/nginx/htmlroot@nfs-web6-65747989d9-mr7k8:/usr/share/nginx/html#lsindex.html 在NFS的服务器端node2上/ynfs/k8s中编辑index.html文件,然后在浏览器中访问: [root@node2k8s]#vimindex.html [root@master~]#vimtest-nfs.svc.yaml#部署一个为nfs-web6的svc apiVersion:v1kind:Servicemetadata:name:nfs-web6namespace:defaultspec:ports:-port:80protocol:TCPtargetPort:80selector:app:nfs-web6type:NodePort[root@master~]#kubectlgetsvc NAMETYPECLUSTER-IPEXTERNAL-IPPORT(S)AGEnfs-web6NodePort10.101.117.24 NAMECLASSHOSTSADDRESSPORTSAGEnfs-in-web6 (四)、持久数据卷,让存储和应用的职责逻辑分离,静态的PV PersistentVolume(PV):对存储资源创建和使用的抽象,使得存储作为集群中的资源管理 PersistentVolumeClaim(PVC):让用户不需要关心具体的Volume实现细节 Pod申请PVC作为卷来使用,Kubernetes通过PVC查找绑定的PV,并Mount给Pod。 1、编辑pv的yaml文件,创建一个pv [root@master~]#vimtest-pv.yaml apiVersion:v1kind:PersistentVolumemetadata:name:yuan-pvcspec:capacity:storage:5GiaccessModes:-ReadWriteManynfs:server:192.168.178.12path:/yfs/k8s[root@master~]#kubectlapply-ftest-pv.yamlpersistentvolume/yuan-pvccreated[root@master~]#kubectlgetpv NAMECAPACITYACCESSMODESRECLAIMPOLICYSTATUSCLAIMSTORAGECLASSREASONAGEyuan-pvc5GiRWXRetainAvailable2、编辑pvc的deployment的yaml文件,创建一个带pvc存储 apiVersion:apps/v1kind:Deploymentmetadata:name:webspec:selector:matchLabels:app:pvc-web7replicas:3template:metadata:labels:app:pvc-web7spec:containers:-name:pvc-web7image:nginxvolumeMounts:-name:wwwrootmountPath:/usr/share/nginx/htmlvolumes:-name:wwwrootpersistentVolumeClaim:claimName:yuan-pvc---apiVersion:v1kind:PersistentVolumeClaimmetadata:name:yuan-pvcspec:accessModes:-ReadWriteManyresources:requests:storage:5Gi---apiVersion:v1kind:Servicemetadata:name:pvc-servicespec:selector:app:pvc-web7ports:-protocol:TCPport:80targetPort:80type:NodePort[root@master~]#kubectlapply-ftest-pvc.yamldeployment.apps/webcreated[root@master~]#kubectlgetpvc NAMESTATUSVOLUMECAPACITYACCESSMODESSTORAGECLASSAGEyuan-pvcBoundyuan-pvc5GiRWX3m40s进到pod中来:---> NAMEREADYSTATUSRESTARTSAGEpvc-web7-8677566cbd-6j58l1/1Running016mpvc-web7-8677566cbd-fbrdq1/1Running016m[root@master~]#kubectlexec-itpvc-web7-8677566cbd-6j58l--bash 在POD中显示挂载的情况了:---> root@pvc-web7-8677566cbd-6j58l:/#df-Th FilesystemTypeSizeUsedAvailUse%Mountedon192.168.178.12:/yuan/k8snfs492G9.7G83G11%/usr/share/nginx/html -------------------------------------PV生命周期----------------------------------- AccessModes(访问模式):AccessModes是用来对PV进行访问模式的设置,用于描述用户应用对存储资源的访问权限,访问权限包括下面几种方式: RECLAIMPOLICY(回收策略):目前PV支持的策略有三种: STATUS(状态):一个PV的生命周期中,可能会处于4中不同的阶段: ------------------------------------- 一个pv只能由一个pvc使用,不能动态的弹性的分配给其他项目。pv只要和pvc一经bund(绑定)就无法分配个其他pod的pvc使用了。 现在PV使用方式称为静态供给,需要K8s运维工程师提前创建一堆PV,供开发者使用。 (五)、PV动态供给(StorageClass) K8s开始支持PV动态供给,使用StorageClass对象实现。不需要运维人员维护pv的创建。 K8s默认不支持NFS动态供给,需要单独部署社区开发的插件。 部署支持NFS的插件: 1、解压文件 [root@master~]#unzipnfs-external-provisioner.zip [root@masternfs-external-provisioner]#vimdeployment.yaml 2、建NFS服务器端 [root@node2~]#mkdir-p/pvc [root@node2~]#vim/etc/exports /yfs/k8s*(rw,no_root_squash)/yuan/k8s*(rw,no_root_squash)/pvc*(rw,no_root_squash)[root@node2~]#systemctlrestartnfs#修改完/etc/exports后重新启动NFS服务器 3、修改pvc申请yaml文件deployment.yaml env:-name:PROVISIONER_NAMEvalue:k8s-sigs.io/nfs-subdir-external-provisioner-name:NFS_SERVERvalue:192.168.178.12-name:NFS_PATHvalue:/pvcvolumes:-name:nfs-client-rootnfs:server:192.168.178.12path:/pvc4、查看存储类的yaml文件和创建给給类 apiVersion:storage.k8s.io/v1kind:StorageClassmetadata:name:managed-nfs-storageprovisioner:k8s-sigs.io/nfs-subdir-external-provisioner#orchooseanothername,mustmatchdeployment'senvPROVISIONER_NAME'parameters:archiveOnDelete:"false"[root@masternfs-external-provisioner]#kubectlapply-f.#后面带一个点,包含文件夹下的都要创建[root@masternfs-external-provisioner]#kubectlgetpods NAMEREADYSTATUSRESTARTSAGEnfs-client-provisioner-78c88996f8-68rm91/1Running076s5、创建使用动态pv的应用Deployment和Service apiVersion:apps/v1kind:Deploymentmetadata:name:sc-web8spec:selector:matchLabels:app:sc-web8replicas:3template:metadata:labels:app:sc-webspec:containers:-name:sc-web8image:nginxvolumeMounts:-name:wwwrootmountPath:/usr/share/nginx/htmlvolumes:-name:wwwrootapiVersion:apps/v1kind:Deploymentmetadata:name:sc-web8spec:selector:matchLabels:app:sc-web8replicas:3template:metadata:labels:app:sc-webspec:containers:-name:sc-web8image:nginxvolumeMounts:-name:wwwrootmountPath:/usr/share/nginx/htmlvolumes:-name:wwwrootpersistentVolumeClaim:claimName:yuan-sc apiVersion:v1kind:PersistentVolumeClaimmetadata:name:yuan-scspec:storageClassName:"managed-nfs-storage"accessModes:-ReadWriteManyresources:requests:storage:11Gi[root@master~]#kubectlapply-ftest-sc.yaml [root@master~]#kubectlgetsvc,pv,pvc NAMETYPECLUSTER-IPEXTERNAL-IPPORT(S)AGEservice/yuan-scNodePort10.105.174.111 [root@node2~]#cd/pvc[root@node2pvc]#lltotal0drwxrwxrwx2rootroot6Sep2915:14default-yuan-sc-pvc-87a3440b-9fd2-47a4-89c0-0e92912851cc (六)、有状态应用部署:StatefulSet控制器 无状态:Deployment控制器设计原则:管理的所有Pod一模一样,提供同一个服务,也不考虑在哪台Node运行,可随意扩容和缩容。这种应用称为“无状态”,例如Web服务有状态:在实际的场景中,这并不能满足所有应用,尤其是分布式应用,会部署多个实例,这些实例之间往往有依赖关系,例如主从关系、主备关系,这种应用称为“有状态”,例如MySQL主从、Etcd集群 StatefulSet控制器,用来管理有状态应用的工作负载API对象 StatefulSets对于需要满足以下一个或多个需求的应用程序很有价值: 应用场景:分布式应用、数据库集群 稳定的网络ID使用HeadlessService(相比普通Service只是将spec.clusterIP定义为None)来维护Pod网络身份。并且添加serviceName:“nginx”字段指定StatefulSet控制器要使用这个HeadlessService。DNS解析名称: 稳定的存储StatefulSet的存储卷使用VolumeClaimTemplate创建,称为卷申请模板,当StatefulSet使用VolumeClaimTemplate创建一个PersistentVolume时,同样也会为每个Pod分配并创建一个编号的PVC。 StatefulSet与Deployment区别:有身份的!身份三要素:域名主机名存储(PVC) ##实例:部署一个StatefulSet的实例 [root@master~]#vimtest-statefulset.yaml [root@master~]#vimtest-statefulset.yamlapiVersion:v1kind:Servicemetadata:name:sts-weblabels:app:sts-web8spec:ports:-port:80name:sts-web8clusterIP:Noneselector:app:sts-web8---apiVersion:apps/v1kind:StatefulSetmetadata:name:sts-web8spec:selector:matchLabels:app:sts-web8serviceName:"sts"replicas:3template:metadata:labels:app:sts-web8spec:terminationGracePeriodSeconds:10containers:-name:nginximage:nginxports:-containerPort:80name:webvolumeMounts:-name:wwwrootmountPath:/usr/share/nginx/htmlvolumeClaimTemplates:-metadata:name:wwwrootspec:accessModes:["ReadWriteOnce"]storageClassName:"managed-nfs-storage"resources:requests:storage:2Gi[root@master~]#kubectlapply-ftest-statefulset.yaml[root@master~]#kubectlgetpods NAMEREADYSTATUSRESTARTSAGEsts-web8-01/1Running038ssts-web8-11/1Running020ssts-web8-20/1Pending01s[root@master~]#kubectlgetsvc NAMETYPECLUSTER-IPEXTERNAL-IPPORT(S)AGEf1NodePort10.101.45.147 NAMESTATUSVOLUMECAPACITYACCESSMODESSTORAGECLASSAGEwwwroot-sts-web8-0Boundpvc-769585f8-7ac7-47a7-8f1b-da2bf959ad8e2GiRWOmanaged-nfs-storage5m39swwwroot-sts-web8-1Boundpvc-b0afcc4c-4619-400d-9671-88307a7898d02GiRWOmanaged-nfs-storage5m21swwwroot-sts-web8-2Boundpvc-a02150da-4410-45af-bb43-b2d59488ea3e2GiRWOmanaged-nfs-storage5m2s[root@node2~]#cd/pvc[root@node2pvc]#ll drwxrwxrwx2rootroot6Sep3009:27default-wwwroot-sts-web8-0-pvc-769585f8-7ac7-47a7-8f1b-da2bf959ad8edrwxrwxrwx2rootroot6Sep3009:27default-wwwroot-sts-web8-1-pvc-b0afcc4c-4619-400d-9671-88307a7898d0drwxrwxrwx2rootroot6Sep3009:27default-wwwroot-sts-web8-2-pvc-a02150da-4410-45af-bb43-b2d59488ea3e显示出statefulSet的pod的主机名: [root@master~]#kubectlexecsts-web8-0--hostnamests-web8-0 演示独立存储: 在NFS服务器上在sts-web8-0的存储上建一个文件: [root@node2default-wwwroot-sts-web8-0-pvc-769585f8-7ac7-47a7-8f1b-da2bf959ad8e]#toucht1.txt[root@node2default-wwwroot-sts-web8-0-pvc-769585f8-7ac7-47a7-8f1b-da2bf959ad8e]#lltotal0-rw-r--r--1rootroot0Sep3009:35t1.txt在sts-web8-0(对应的pod)的statsfulset的pod上看有没有建好的文件:[root@master~]#kubectlexec-itsts-web8-0--bashroot@sts-web8-0:/#cd/usr/share/nginx/htmlroot@sts-web8-0:/usr/share/nginx/html#lst1.txt在sts-web8-1(其他pod)的statsfulset的pod上看有没有建好的文件:[root@master~]#kubectlexec-itsts-web8-1--bashroot@sts-web8-1:/#cd/usr/share/nginx/htmlroot@sts-web8-1:/usr/share/nginx/html#ls下面就没有文件,说明:statefulSet的pod是独立存储的 (七)、应用程序数据存储ConfigMap,Secret ConfigMap:存储配置文件Secret:存储敏感数据 ConfigMap动机是:使用ConfigMap来将你的配置数据和应用程序代码分开。 创建ConfigMap后,数据实际会存储在K8s中Etcd,然后通过创建Pod时引用该数据。应用场景:应用程序配置Pod使用configmap数据有两种方式: 实例:创建一个configMap资源: 1、编辑一个confiMap的yaml文件: apiVersion:v1kind:ConfigMapmetadata:name:configmap-demodata:a:"123"b:"456"yuan.pro:|port:30092host:192.168.178.122、编辑一个含有configMap调用的yaml应用: 1---2apiVersion:v13kind:Pod4metadata:5name:configmap-demo-pod6spec:7containers:8-name:demo9image:nginx10env:11-name:y112valueFrom:13configMapKeyRef:14name:configmap-demo15key:a16-name:y217valueFrom:18configMapKeyRef:19name:configmap-demo20key:b21volumeMounts:22-name:config23mountPath:"/config"24readOnly:true25volumes:26-name:config27configMap:28name:configmap-demo29items:30-key:"yuan.pro"31path:"yuan.pro"[root@master~]#kubectlapply-ftest-configmap.yaml NAMEREADYSTATUSRESTARTSAGEconfigmap-demo-pod1/1Running09m4s3、查看configMap的创建情况: [root@master~]#kubectlgetconfigmap NAMEDATAAGEconfigmap-demo317m[root@master~]#kubectlexec-itconfigmap-demo-pod--bashroot@configmap-demo-pod:/#env|grepy y2=456y1=123root@configmap-demo-pod:/#cd/configroot@configmap-demo-pod:/config#lsyuan.proroot@configmap-demo-pod:/config#catyuan.pro Kubernetes和在集群中运行的应用程序也可以对Secret采取额外的预防措施,例如避免将机密数据写入非易失性存储。 Secret类似于ConfigMap但专门用于保存机密数据。 Pod可以用三种方式之一来使用Secret: kubectlcreatesecret支持三种数据类型: [root@master~]#kubectlcreatecrerte--help#通过这个命令查看Secret支持的这三种类型 AvailableCommands:docker-registryCreateasecretforusewithaDockerregistrygenericCreateasecretfromalocalfile,directoryorliteralvaluetlsCreateaTLSsecret 实例:创建一个Secret的POD资源: 1、编辑一个Secret的POD应用yaml文件: [root@master~]#echo-n'yuanye'|base64eXVhbnll[root@master~]#echo-n'anshunyuan'|base64YW5zaHVueXVhbg== apiVersion:v1kind:Secretmetadata:name:db-user-passtype:Opaquedata:username:eXVhbnllpassword:YW5zaHVueXVhbg==2、编辑POD应用yaml文件: apiVersion:v1kind:Podmetadata:name:secret-demo-podspec:containers:-name:demoimage:nginxenv:-name:USERvalueFrom:secretKeyRef:name:db-user-passkey:username-name:PASSvalueFrom:secretKeyRef:name:db-user-passkey:passwordvolumeMounts:-name:configmountPath:"/config"readOnly:truevolumes:-name:configsecret:secretName:db-user-passitems:-key:usernamepath:my-username [root@master~]#kubectlapply-ftest-secret.yaml[root@master~]#kubectlgetpods NAMEREADYSTATUSRESTARTSAGEsecret-demo-pod1/1Running03m38s3、查看Secret的情况: [root@master~]#kubectlgetsecret NAMETYPEDATAAGEdb-user-passOpaque24m53s 4、进到Secret的容器中验证: [root@master~]#kubectlexec-itsecret-demo-pod--bashroot@secret-demo-pod:/#env|grepUSERUSER=yuanye root@secret-demo-pod:~#env|grepPASSPASS=anshunyuan root@secret-demo-pod:/#cdconfigroot@secret-demo-pod:/config#catmy-usernameyuanye --------------------YUANYE2021.10.1---------------------------- 八、K8S安全 基于角色(Role)的访问控制(RBAC)是一种基于组织中用户的角色来调节控制对计算机或网络资源的访问的方法。 RBAC鉴权机制使用rbac.authorization.k8s.ioAPI组来驱动鉴权决定,允许你通过KubernetesAPI动态配置策略。 要启用RBAC,在启动API服务器时将--authorization-mode参数设置为一个逗号分隔的列表并确保其中包含RBAC。 (一)K8sApiserver提供三种客户端身份认证:HTTPS证书认证:基于CA证书签名的数字证书认证(kubeconfig)HTTPToken认证:通过一个Token来识别用户(serviceaccount)HTTPBase认证:用户名+密码的方式认证(1.19版本弃用) (五)RBACAPI的根证书HTTPS证书认证: [root@master~]#ls.kube/#存放k8s的根证书的cacheconfig(六)RBACAPI的根证书HTTPToken认证: 通过Token来识别用户,主要node加入时加入集群时的Token, (七)通过kubectlexec查看kube-apiserver中的准入控制:默认启用的准入控制 [root@master~]#kubectlexeckube-apiserver-master-nkube-system--kube-apiserver-h|grepenable-admission-plugins 实施步骤: 1.用K8SCA签发客户端证书 [root@masterrbac]#vimcert.sh 1cat>ca-config.json< [root@masterrbac]#ll [root@masterrbac]#kubectl--kubeconfig=yuanye.kubeconfiggetpodsErrorfromserver(Forbidden):podsisforbidden:User"yuanye"cannotlistresource"pods"inAPIgroup""inthenamespace"default"#因为yuanye这个用户没有权限查看pods 3.创建RBAC权限策略 kind:RoleapiVersion:rbac.authorization.k8s.io/v1metadata:namespace:defaultname:pod-readerrules:-apiGroups:[""]resources:["pods"]verbs:["get","watch","list"]---kind:RoleBindingapiVersion:rbac.authorization.k8s.io/v1metadata:name:read-podsnamespace:defaultsubjects:-kind:Username:yuanyeapiGroup:rbac.authorization.k8s.ioroleRef:kind:Rolename:pod-readerapiGroup:rbac.authorization.k8s.io -apiGroups:[""]#api组,如:apps组,空值表示核心API组,像namespace,pod,service,pv,pvc都在核心组里面。resources:["pods"]#表示资源名称(复数),如:pods,deployments,services。verbs:["get","watch","list"]#表示对资源的操作方法。[root@masterrbac]#kubectlapi-resources|greppod#查看API的资源组[root@masterrbac]#kubectlapi-resources|grepdeploymentdeploymentsdeployapps/v1[root@masterrbac]#kubectlapply-frbac.yaml[root@masterrbac]#kubectl--kubeconfig=yuanye.kubeconfiggetpodsNAMEREADYSTATUSRESTARTSAGEconfigmap-demo-pod1/1Running16d15hdns-t1/1Running811dinit-demo1/1Running714dmy-hostpath1/1Running1110dnfs-client-provisioner-78c88996f8-68rm91/1Running18d修改rbac的配置yaml文件: -apiGroups:["","apps"]resources:["pods","services","deployments"]verbs:["get","watch","list"]yuanye用户就能访问deployment和service了 [root@masterrbac]#kubectl--kubeconfig=yuanye.kubeconfiggetdeployment NAMEREADYUP-TO-DATEAVAILABLEAGEnfs-client-provisioner1/1118dnfs-web0/0009dsc-web83/3338dtest-web50/00012d[root@masterrbac]#kubectl--kubeconfig=yuanye.kubeconfigdeletepodssecret-demo-podErrorfromserver(Forbidden):pods"secret-demo-pod"isforbidden:User"yuanye"cannotdeleteresource"pods"inAPIgroup""inthenamespace"default"#说明yuanye这个用户不具有delete删除pod的权限verbs:["get","watch","list"] [root@masterrbac]#aliask8s=kubectl--kubeconfig=yuanye.kubeconfig#用别名的方式简化命令行[root@masterrbac]#k8sgetpods[root@masterrbac]#k8sdeletepodsmy-hostpath#通过verbs:["get","watch","list","delete"]的配置,yuanye用户具备删除权限。案例:为一个服务账号分配只能创建deployment、daemonset、statefulset的权限。 1、#创建集群角色 [root@master~]#kubectlcreateclusterroledeployment-clusterrole--verb=create--resource=deployments,daemonsets,statefulsetsclusterrole.rbac.authorization.k8s.io/deployment-clusterrolecreated 2#创建服务账号 [root@master~]#kubectlcreatensapp-team1namespace/app-team1created [root@master~]#kubectlcreateserviceaccountcicd-token-napp-team1serviceaccount/cicd-tokencreated 3#将服务账号绑定角色 [root@master~]#kubectlcreaterolebindingcicd-token\>--serviceaccount=app-team1:cicd-tokey\>--clusterrole=deployment-clusterrole-napp-team1rolebinding.rbac.authorization.k8s.io/cicd-tokencreated 4#测试服务账号权限 [root@master~]#kubectl--as=system:serviceaccount:app-team1:cicd-token\>getpods-napp-team1Errorfromserver(Forbidden):podsisforbidden:User"system:serviceaccount:app-team1:cicd-token"cannotlistresource"pods"inAPIgroup""inthenamespace"app-team1" 5#通过yaml创建出一个服务账号sa 1apiVersion:v12kind:ServiceAccount3metadata:4name:yuan-token5namespace:app-team267---8apiVersion:rbac.authorization.k8s.io/v19kind:ClusterRole10metadata:11name:deployment-clusterrole12rules:13-apiGroups:["","apps"]14resources:["pods","deployments","daemonsets","statefulsets"]15verbs:["get","create","list"]1617---18apiVersion:rbac.authorization.k8s.io/v119kind:RoleBinding20metadata:21name:yuan-token22namespace:app-team223roleRef:24apiGroup:rbac.authorization.k8s.io25kind:ClusterRole26name:deployment-clusterrole27subjects:28-kind:ServiceAccount29name:yuan-token30namespace:app-team2[root@masteracc]#aliask9=kubectl--as=system:serviceaccount:app-team2:yuan-token#用别名的方式把长命令格式[root@masteracc]#k9getpods-napp-team2#这样就简化了命令行格式Noresourcesfoundinapp-team2namespace. Kubernetes集群网络没任何网络限制,Pod可以与任何其他Pod通信,在某些场景下就需要进行网络控制,减少网络攻击面,提高安全性,这就会用到网络策略。网络策略(NetworkPolicy):是一个K8s资源,用于限制Pod出入流量,提供Pod级别和Namespace级别网络访问控制。网络策略的应用场景:应用程序间的访问控制,例如项目A不能访问项目B的Pod开发环境命名空间不能访问测试环境命名空间Pod当Pod暴露到外部时,需要做Pod白名单多租户网络环境隔离Ingress的编写:1apiVersion:networking.k8s.io/v12kind:NetworkPolicy3metadata:4name:test-network-policy5namespace:default6spec:7podselector:8matchLabels:9role:db10policyTypes:11-Ingress12-Egress13ingress:14-from:15-ipBlock:16cidr:172.17.0.0/1617except:18-172.17.1.0/2419-namespaceSelector:20matchLabels:21project:myproject22-podselector:23matchLabels:24role:frontend25ports:26-protocol:TCP27port:6379ingress:#ingress的编写方式:-from:-ipBlock:cidr:172.17.0.0/16except:-172.17.1.0/24-namespaceSelector:matchLabels:project:myproject-podselector:matchLabels:role:frontend podSelector:目标Pod,根据标签选择。policyTypes:策略类型,指定策略用于入站、出站流量。Ingress:from是可以访问的白名单,可以来自于IP段、命名空间、Pod标签等,ports:是可以访问的端口。Egress的编写: egress:-to:-ipBlock:cidr:10.0.0.0/24ports:Egress:这个Pod组可以访问外部的IP段和端口。 案例1:拒绝其他命名空间Pod访问 需求:test命名空间下所有pod可以互相访问,也可以访问其他命名空间Pod,但其他命名空间不能访问test命名空间Pod。 1、先创建一个test的命名空间,在其命名空间中创建两个应用: [root@master~]#kubectlcreatenstestnamespace/testcreated[root@master~]#kubectlrunweb--image=nginx-ntestpod/webcreated[root@master~]#kubectlrunbusybox1--image=busybox-ntest--sleep12hpod/busybox1created [root@master~]#kubectlgetpods-ntest NAMEREADYSTATUSRESTARTSAGEbusybox11/1Running070sweb1/1Running0105s2、在default中创建busybox2的应用: [root@master~]#kubectlrunbusybox2--image=busybox--sleep12hpod/busybox2created[root@master~]#kubectlgetpods NAMEREADYSTATUSRESTARTSAGEbusybox21/1Running063s3、测试pod的访问,不加网络NetworkPolicy测试: [root@master~]#kubectlgetpods-ntest-owide NAMEREADYSTATUSRESTARTSAGEIPNODENOMINATEDNODEREADINESSGATESbusybox11/1Running08m21s10.244.166.156node1 [root@master~]#kubectlexec-itbusybox1-ntest--sh#这个是在test命名空间中的访问/#wget10.244.166.157 Connectingto10.244.166.157(10.244.166.157:80)savingto'index.html'index.html100%|**************************************************|6150:00:00ETA'index.html'saved[root@master~]#kubectlexec-itbusybox2--sh#这个是在default命名空间中的访问/#wget10.244.166.157 Connectingto10.244.166.157(10.244.166.157:80)savingto'index.html'index.html100%|**************************************************|6150:00:00ETA'index.html'saved4、编辑网络NetworkPolicy的yaml文件: [root@master~]#vimtest-networkpolicy.yaml apiVersion:networking.k8s.io/v1kind:NetworkPolicymetadata:name:deny-all-namespacesnamespace:testspec:podSelector:{}#未配置,匹配本命名空间所有podpolicyTypes:-Ingressingress:-from:-podSelector:{}[root@master~]#kubectlapply-ftest-networkpolicy.yamlnetworkpolicy.networking.k8s.io/deny-all-namespacescreated 查看networkpolicy的情况: [root@master~]#kubectlgetnetworkpolicy-ntest NAMEPOD-SELECTORAGEdeny-all-namespaces NAMEREADYSTATUSRESTARTSAGEIPNODENOMINATEDNODEREADINESSGATESbusybox11/1Running034m10.244.166.156node1 Connectingto10.244.166.157(10.244.166.157:80)wget:can'topen'index.html':Fileexists/#lsbinetcindex.htmlroottmpvardevhomeprocsysusr/#rmindex.html-rf/#wget10.244.166.157Connectingto10.244.166.157(10.244.166.157:80)savingto'index.html'index.html100%|**************************************************|6150:00:00ETA'index.html'saved[root@master~]#kubectlexec-itbusybox2--sh#default的命名空间的pod就不能访问test空间中的pod/#ls binetcindex.htmlroottmpvardevhomeprocsysusr/#rmindex.html-rf/#wget10.244.166.157Connectingto10.244.166.157(10.244.166.157:80)6、delete网络NetworkPolicy: NAMEPOD-SELECTORAGEdeny-all-namespaces 案例2:同一个命名空间下应用之间限制访问 需求:将test命名空间携带run=web标签的Pod隔离,只允许test命名空间携带run=client1标签的Pod访问80端口。1、拉取lanels为run=client1的应用: [root@master~]#kubectlgetpods-ntest--show-labels NAMEREADYSTATUSRESTARTSAGELABELSbusybox11/1Running03h46mrun=busybox1web1/1Running03h47mrun=web[root@master~]#kubectlrunclient1--image=busybox-ntest--sleep12hpod/client1created[root@master~]#kubectlgetpods-ntest--show-labels NAMEREADYSTATUSRESTARTSAGELABELSbusybox11/1Running03h47mrun=busybox1client10/1ContainerCreating015srun=client1web1/1Running03h48mrun=web2、编辑网络策略的yaml文件及apply应用: apiVersion:networking.k8s.io/v1kind:NetworkPolicymetadata:name:app-to-appnamespace:testspec:podSelector:matchLabels:run:webpolicyTypes:-Ingressingress:-from:-podSelector:matchLabels:run:client1ports:-protocol:TCPport:80 [root@master~]#kubectlapply-ftest-app-networkpolicy.yamlnetworkpolicy.networking.k8s.io/app-to-appcreated[root@master~]#kubectlgetnetworkpolicy-ntest NAMEPOD-SELECTORAGEapp-to-apprun=web57s3、测试:这个是run=client1 NAMEREADYSTATUSRESTARTSAGELABELSbusybox11/1Running04h2mrun=busybox1client11/1Running015mrun=client1web1/1Running04h3mrun=web[root@master~]#kubectlexec-itclient1-ntest--sh/#exit[root@master~]#kubectlgetpods-ntest-owide NAMEREADYSTATUSRESTARTSAGEIPNODENOMINATEDNODEREADINESSGATESbusybox11/1Running04h3m10.244.166.156node1 Connectingto10.244.166.157(10.244.166.157:80)savingto'index.html'index.html100%|**************************************************|6150:00:00ETA'index.html'saved 4、测试:这个是run=busybox1,这个就不能访问了 [root@master~]#kubectlexec-itbusybox1-ntest--sh#这个是同一个命名test空间也不能访问,因为标签不匹配/#wget10.244.166.157 Connectingto10.244.166.157(10.244.166.157:80)[root@master~]#kubectlexec-itbusybox2--sh#不同的命名空间,也不能访问,因为标签不匹配/#wget10.244.166.157 Connectingto10.244.166.157(10.244.166.157:80) 案例3:只允许指定命名空间中的应用访问 需求:只允许dev命名空间中的Pod访问test命名空间中的pod80端口,命名空间打标签:kubectllabelnamespacedevname=dev 1、先建立DEV的命名空间,并在该空间拉起一个busybox的应用[root@master~]#kubectlcreatensdevnamespace/devcreated[root@master~]#kubectlrunclient--image=busybox-ndev--sleep12hpod/clientcreated[root@master~]#kubectlgetpods-ndev NAMEREADYSTATUSRESTARTSAGEclient1/1Running089s 2、在dev中的pod的client可以访问test中的pod的80端口,而其他命名空间中pod的busybox就不能访问 3、编辑networkpolicy的yaml文件并应用 [root@master~]#vimtest-allow-port.yaml 1apiVersion:networking.k8s.io/v12kind:NetworkPolicy3metadata:4name:allow-port-from-namespace5namespace:test6spec:7podSelector:{}8policyTypes:9-Ingress10ingress:11-from:12-namespaceSelector:#匹配命名空间标签13matchLabels:14name:dev15ports:16-protocol:TCP17port:80[root@master~]#kubectlapply-ftest-allow-port.yaml[root@master~]#kubectlgetnetworkpolicy-ntest NAMEPOD-SELECTORAGEallow-port-from-namespace [root@master~]#kubectlgetns--show-labels NAMESTATUSAGELABELSapp-team1Active3dkubernetes.io/metadata.name=app-team1app-team2Active2d23hkubernetes.io/metadata.name=app-team2defaultActive20dkubernetes.io/metadata.name=defaultdevActive21mkubernetes.io/metadata.name=devingress-nginxActive14dapp.kubernetes.io/name=ingress-nginx,app.kubernetes.io/part-of=ingress-nginx,kubernetes.io/metadata.name=ingress-nginxkube-node-leaseActive20dkubernetes.io/metadata.name=kube-node-leasekube-publicActive20dkubernetes.io/metadata.name=kube-publickube-systemActive20dkubernetes.io/metadata.name=kube-systemkubernetes-dashboardActive20dkubernetes.io/metadata.name=kubernetes-dashboardtestActive4h38mkubernetes.io/metadata.name=test[root@master~]#kubectllabelnamespacedevname=dev#给dev打一个标签5、测试[root@master~]#kubectlexec-itclient-ndev--sh#这个是基于Dev的命名空间,是可以访问的/#wget10.244.166.157 Connectingto10.244.166.157(10.244.166.157:80)savingto'index.html'index.html100%|**************************************************|6150:00:00ETA'index.html'saved[root@master~]#kubectlexec-itbusybox2--sh#这个是default命名空间的,不能访问,因为标签不匹配/#wget10.244.166.157 Connectingto10.244.166.157(10.244.166.157:80)(网络策略需要网络组件支持的,支持网络组件的实现:calico。flannel不支持网络策略。) 九、K8S集群维护 ---->Etcd数据库备份与恢复(kubeadm部署方式) 1、Etcd数据库备份: 2、删除当前的pod在恢复etcd: NAMEREADYSTATUSRESTARTSAGEbusybox21/1Running228h3、暂停k8s服务:(只要把manifests目录移动就能暂停kubernetes的服务) 4、恢复etcd备份文件: [root@master~]#mv/var/lib/etcd//var/lib/etcd.bak[root@master~]#ETCDCTL_API=3etcdctl\>snapshotrestoresnap1.db\>--data-dir=/var/lib/etcd5、启动kube-apiserver和etcd容器:[root@master~]#mv/etc/kubernetes/manifests.bak/etc/kubernetes/manifests[root@masterkubernetes]#kubectlgetpods