一、k8s的集群架构与组件
k8s也是一个Master,多个node节点 。
下面是kubernetes结婚的架构与组件
1.1 master组件介绍
组件名称 |
介绍 |
kube-apiserver |
Kubernetes API,集群的统一入口, 各组件协调者,以RESTful API提供接口服务,所有对象资源的增删改查和监听操作都交给 APlServer处理后再提交给 Etcd存储。 |
kuber-controller-manager |
处理集群中常规后台任务,一个资源对应一个控制器, 而ControllerManager就是负责管理这些控制器的。 |
kuber-scheduler |
根据调度算法为新创建的Pod选择一个Node节点,可以任意部署,可以部署在同一个节点上,也可以部署在不同的节点上。 |
etcd |
分布式键值存储系统。用于保存集群状态数据,比如Pod、Service等对象信息。 |
1.2 node组件介绍
组件名称 |
介绍 |
kubelet |
kubelet是Master在Node节点上的Agent,管理本机运行容器的生命周期,比如创建容器、pod挂载数据卷、下载secret、获取容器和节点状态等工作;kubelet将每个Pod转换成一组容器 |
kube-proxy |
在Node节点上实现Pod网络代理,维护网络股则和四层负载均衡工作 |
docker或rocket |
容器引擎,运行容器 |
1.3 资源概念
1.3.1 k8s里面直接操作都是Controller控制器
k8s里面直接操作的一般都是控制器Controller,很少会直接操作Pod,或者更底层的Contanier。
eg:部署一个电商nginx控制器Controller并且开启三个副本。
eg: 为这个控制器开一个负载均衡Service
- 一个Service对一个Controller里面的多个pod做负载均衡和统一出口。
- 一个Controller控制器如Deployment对多个pod做统一管理
1.3.2 为啥需要 Service
在直接用docker部署,直接用-p就可以把单个docker应用暴露到宿主机上面。
但是使用k8s,每个应用都是一个 deployment,每个deployment后面都是多个pods;
因此暴露k8s应用需要统一的一个负载均衡的出口。
这里的Service就是一个负载均衡器,相当于LBS.
Service作为一个统一的服务出口。
1.3.3 为啥需要 Namespce
1:k8s里面都有一个命名空间的概念,-n指定命名空间。
不管是查询、创建等所有都是通过-n指定命名空间,不加都是默认default的命名空间。
隔离
2:命名空间第二个作用
对命名空间授权
所有命令本质上都要增加-n,没有加到使用就是默认的命名空间
除了pod和service没有命名空间,其他都有
kubectl get namespace
获取所有的命名空间
kubectl create namesapce test
创建一个名称叫做test的命名空间
1.3.4 标签的使用
-
kubectl get pods --show-labels
#查看资源标签,可以是deployment
、service
等获取其他资源
-
kubectl get pods -l app=nginx
#根据标签筛选(列出)资源
二、k8s生产环境的两种安装方式
最常用的两种生产环境部署方式
三、kubeadm vs kubectl vs kubelet 区分
命令 |
作用 |
常用命令 |
安装位置 |
kubeadm |
快捷生产环境安装kubeadm的 |
kubeadm init 集群初始化、kubeadm join node节点加入集群、kubeadm reset 重置配置 |
master初始化,node 加入 |
kubectl |
kubectl可以访问k8s整个集群,进行查看、访问、控制; 如:aliyun 上面一键创建的 serverless k8s ,就可以使用 kubectl来查看集群情况。如果执行命令报错,很可能是没有配置.kube/config
|
vi $home/.kube/config 必须配置、kubectl get nodes
|
只需要master安装就可以了,node没必要 |
kubelet |
kubelet是Master在Node节点上的Agent; 检查是否启动: |
systemctl status kubelet |
node节点安装 |
3.1 kubectl详解
kubectl控制k8s的一个客户端而已,需要配置集群地址、鉴权信息等。
kebectl只读取$home/.kube.config这个配置文件。
在k8s里面不直接操作pod、容器,而是一般都是操作的是deployment。
如创建一个nginx的deployment并且开启三个副本。
- kubectl get nodes #查看集群状态
- kubectl --kubeconfig=/root/.kube/config get node #指定配置文件目录
- kubectl --help查看所有命令
-
kubectl官方命令介绍 、/kubectl/kubectl-commands
- kubectl自动补全配置(14左右分钟),completion 命令,执行命令按照一个工具就OK可以补全了。可以参见:kubectl 自动补全命令
命令 |
含义 |
kubectl get nodes |
获取集群有几个节点 |
kubectl get namespace |
获取所有的命名空间 |
kubectl get pods |
获取集群上面所有的业务类pods |
kubectl get pods --all-namespaces |
获取所有命名空间中的所有pods |
kubectl get pods -n kube-system 、kubectl get pods -n kubernetes-dashboard
|
获取pods使用-n指定命名空间,所有的pods都有命名空间 |
kubectl get pod,svc |
获取集群pod、service以及ip端口(可以根据ip端口进行访问), svc 是service的缩写 |
kubectl get ep 、kubectl get endpoints
|
查看service后端对应 负载几个pod的具体ip, 即:端点 endpoint |
kubectl get pods -n kube-system -l k8s-app=kube-dns --show-labels |
-n 指定【namespace 】、-l 指定【label 】、显示label|
|
kubectl get pods -n kube-system -o wide |
查看pod分配在那个节点 上面, - o 即输出格式output format |
kubectl apply -f recommended.yaml 、kubectl apply -f calico.yaml
|
安装软件xx |
kubectl logs calico-node-z4jvm -n kube-system |
排查应用错误,查看镜像内部的日志,要指定namespace |
kubectl describe pod calico-node-z4jvm -n kube-system |
排查启动错误,看目前是在拉去镜像、还是启动容器等,拉去镜像是成功还是失败了等 |
kubectl get cs 、kubectl get componentstatuses
|
组件状态etcd、scheduler、controller-manager; 如果检查失败vi /etc/kubernetes/manifests/kube-scheduler.yaml 注释掉 #–port=0 |
kubectl delete pod kube-scheduler-k8s-master -n kube-system |
删除pod |
kubectl --help 、kubectl create --help 、kubectl create deployment --help 、kubectl get --help
|
|
kubectl api-resources |
查看k8s所有的资源;NMAE资源名称、SHORTNAMES 短名称 缩写 、ApiGroup组、Namespace是否区分命名空间、Kind |
kubectl api-versions |
查看k8s所有api 版本,如:apps/v1 各种常见控制器 服务等、storage.k8s.io/v1 存储、batch/v1 批处理autoscaling/v1 自动伸缩 |
kubectl describe <资源> <资源名称> |
查看资源的详细信息,如 kubectl describe node k8s-master 、 kubectl describe pod k8s-master 、kubectl describe service aliang-666 、kubectl describe deployment aliang-666
|
三、牛刀小试
kubectl create deployment my-dep --image=lizhenliang/java-demo --replicas=3
#创建一个deployment并且有三个副本
kubectl expose deployment my-dep --port=80 --targetip-port=8080 --type=NodePort --name web
#service对外暴露80,对内转发的是内部的tomcat的8080端口;NodePort暴露网络到宿主机上;、
kubectl get ep
#查看每个service集群后面的具体有哪些pod
kubectl get service
#可以查看service和对应宿主机上的ip,主要对应的k8s内网的ip宿主机上是访问不了的
kubectl run pod-01 --image=nginx --port=80 --record
#手工创建一个pod。目前不建议直接创建pod
kubectl get pods -n default
#获取刚才创建的pod
kubectl delete pod pod-01
#删除刚才创建的pod
四、排查错误命令
kubectl get apiservices
查看所有的api services以及相关的就绪状态
kubectl describe apiservices 上面apiservices的name名称
详细的一个资源的信息,或者报错信息
4.1 所有linux服务都可以使用journalctl查看日志
journalctl -u kubelet -f
实时查看kubelet日志
journalctl -u kubelet |grep error
查看日志筛选error关键词,当然任何服务都可以使用journalctl
journalctl -u kubelet > error.txt
重定向日志到文件里面,仔细查看
4.2 所有k8s pod查看日志
kubectl logs xx
查看pod日志,采集日志流程 kubectl logs 流程 --> apiserver —> kubelet > container
kubectl logs --help
查看logs相关的其他命令参数
kubectl logs pod名称 -c 容器名称
如果一个pod里面有多个容器,就要-c指定容器名称
kubectl logs kube-proxy-2vxn8 -n kube-system
查看系统组件日志
kubectl exec -it nginx-6799fc88d8-sx9qr -- bash
进入pod内部
五、Service vs Ingress
Service存在的意义,比如:一个java服务启三个副本,那么这java服务如何对外进行访问,
需要统一的对外接口和负载,这就是Service意义。
Ingress 可以理解为Service的Service,可以说是 Service之上的一个nginx
Service 和 Ingress的区别,联系
查看博客: k8s第三节 Kubernetes网络
六、使用yaml创建资源
6.1 通过yaml创建Deployment
官方文档地址,搜索Deployment
,https://kubernetes.io/search/?q=deployment 找一个yaml
官网最终deployment文档
6.1.1 入门部署nginx
功能 |
命令 |
执行yaml |
kubectl apply -f nginx-deployment.yaml |
查看控制器Deployment |
kubectl get deployment -n default |
查看Service |
kubectl get service -n default |
查看Pod & pod所在的节点 & 查看lables |
kubectl get pod -n default -o wide --show-labels |
查看副本集ReplicaSet(rs) |
kubectl get ReplicaSet -n default |
查看容器日志 |
kubectl logs -f nginx-deployment-66b6c48dd5-klqb8 |
更新容器镜像 |
kubectl set image deployment/nginx-deployment nginx=nginx:1.16.1 --record |
部署一个nginx
使用yaml部署第一个控制器 deployment gitee
6.1.2 deployment高阶操作 升级、弹性伸缩、回滚、删除等
1.手工扩容 scale
名称 |
命令 |
查看控制器deployment名称 |
kubectl get deployment nginx-deployment -o ymal |grep name |
升级镜像 |
kubect set image deployment nginx-deployment nginx=nginx:1.16 |
升级镜像-并记录升级历史history |
kubect set image deployment nginx-deployment nginx=nginx:1.16 --record |
滚动查看pod升级情况 |
kubectl get pod -w |
手工扩容,副本数量扩展到10个 |
kubectl scale deployment nginx-deployment --replicas=10 |
参考 官网 scale
2.自动扩容 autoscale
自动扩容要基于资源占用率才行
中文 |
命令 |
查看hpa水平库容的全程 |
kubectl api-resources |grep hpa |
查看是否部署了监控组件 metrics-server
|
kubectl get pod -n kube-system |
kubectl autoscale帮助命令 |
kubectl autoscale --help |
查看hpa运行情况 |
kubectl get hpa 、删除hpa kubectl delete hpa
|
资源利用率流程 |
kubectl top/hpa --> apiserver --> metrics-server --> kubelet --> pod |
查看pod的利用率,必须安装了metrics-server
|
kubectl top pods |
deployment内部是有replicaset
查看副本历史:kubectl get rs
可以查看控制器详情更详细查看升级历史:kubectl describe deployment nginx-deployment
查看升级历史,版本对应rs记录kubectl rollout history deployment nginx-deployment
参考 官网 autoscale
6.2 如何快速获取yaml模板
当需要一个yaml模板的时候
1:官网搜索 copy
2: 导出已经部署的项目的yaml文件
3:自己创建一个项目并导出yaml
作用 |
命令 |
创建一个控制器Deployment并且导出到yml |
kubectl create deployment nginx --image=nginx:1.16 -o yaml --dry-run=client > my-deploy-nginx-create.yaml |
查看已知的资源Deplyment & 指定-o输出 格式 到本地文件 |
kubectl get deployment nginx-deployment -o yaml > my-nginx-deployment.yml |
查看yaml的语法 |
kubectl explain deployment 、kubectl explain pods.spec.containers
|
自动扩容,出现pending
说明主机node资源不够了,可以通过:kubectl describe pod nginx-deployment-644599b9c9-6mxw7
查看详细报错信息,发现不能分配,cpu被分配完了:that the pod didn,t tolerate, 2 Insufficient cpu
6.3 通过yaml创建Service
官网搜索Service
,https://kubernetes.io/search/?q=Service
官网具体 service文档
名称 |
指令 |
解释 |
查看pod并显示标签 |
kubectl get pods --show-labels |
service的时候一定要指定好selector标签 |
查看servce是否代理成功 |
kubectl get ep |
|
查看service & 进行访问 |
kubectl get svc |
80:31497/tcp 打开浏览器,输入任意节点ip,输入 http://任意节点ip:31497 就可以访问 |
暴露一个nginx控制器
使用yaml部署第一个Service来暴露deployment gitee
6.4 pod存在意义 & 分类 & 重启策略 & 练习
参考官网:k8s 官网健身检查搜索 liveness
6.4.1 init container 容器
参考官网: init container容器
init container
如 有数据库容器、web容器,数据库容器必须启动完成 才能启动web容器; 一般的容器全部是 业务容器
举例:比如init contanier 拉去百度首页,保存到容器; 业务容器nginx: 代理这个网页
6.4.2 static pod 静态容器
随着kubelet一期启动的, static Pod
参考:k8s官网 static pods静态pods
6.4.3 pod小练习
七、pod调度 和 工作流程
7.1 pod调度工作流程
kubectl run nginx --image=nginx
命令的操作流程
- kubectl将创建pod的请求提交到apiserver
- 会讲请求的信息写到etcd
- apiserver通知scheduler有创建新的pod,s收到创建之后就会根据调度算法选择最优的节点
- 给这个pod打一个标记,pod=kis-node1
- apierver收到scheuler调度结果写到ectd
- k8s-node1s上kubelect收到事件,从apiserver获取pod的相关信息
- kubelet调用docker api创建pod中所需的容器
- 会把这个pod的状态汇报给apiserver
- apiserver把状态写入etcd
7.2 pod调度主要属性nodeSelector、nodeAffinity节点亲和
nodeSelector 节点调度
nodeAffinity 节点亲和
pod调度,把指定的pod调度到指定的节点上面。比如:有三个节点,一个普通节点、一个是SSD硬盘的节点、一个是GPV节点。
名称 |
命令 |
含义 |
给节点打标签 |
kubectl lable node k8s-node1 disktype = ssd |
说明k8s-node1的磁盘类型是ssd |
删除节点的标签 |
kubectl lable node k8s-node1 disktype- |
删除标签 |
7.3 pod污点Taint、污点容忍tolerations
污点意义:避免pod调度到专用的节点。
污点不是强制的。
污点:就是专用的意思;给一台机器打一个污点,只有打了必须要调到指定污点的机器才能调到上。
【污点容忍】就是可以调到到有指定污点的节点上, 使用 tolerations。
简介 |
命令 |
解释 |
查看节点的污点 |
kubectl describe node k8s-master |grep Taint 、kubectl describe node |grep -i Taint
|
master节点默认就是有一个污点 |
设置污点 |
kubectl taint node k8s-node1 disktype=ssd:NoSchedule |
和打标签类似 |
查看pod分配到那个节点了 |
kubectl get pods -o wide |
|
删除污点 |
kubectl taint node k8s-master node-role.kubernetes.io/master- |
删除节点k8s-master 上面的默认污点,主要减号- 是删除 |
7.4 nodeName节点选择,后门调度
直接绕过各种选择和调度器,直接部署到指定的节点上。
这种情况用的很少
7.5 调度失败的原因分析
- 节点cpu或者内存不足;
3 node are available: 3 Insufficient cpu.
- 有污点,没有容忍;
taint
、tolerations
- 没有匹配到节点标签;
nodename
、nodeselector
、
解决方式
名称 |
命令 |
查看调度节点情况 |
kubectl get pod <Name> -o wide |
查看调度失败原因 |
kubectl describe pod <NAME> |
7.6 控制器DaemonSet
使用最多的控制器Controller是Deployment,这里我们介绍一下DeamonSet.
特点:每一个节点上都会自动启动一个pod,新增的节点也会自动启动一个pod。
场景,日志采集、监控Agent、网络插件。
kubectl get pods -n kube-system
,后台程序一般都部署到kube-system
里面,查看可以看到