Kubernetes是自动化容器操作的开源平台。这些容器操作包括:部署,调度和节点集群间扩展。更高了看,是基于容器技术的分布式架构方案,是一个完备的分布式系统支撑平台。
Master节点主要有五个组件,分别是kubectl、api-server、controller-manager、kube-scheduler 和 etcd。
node节点主要有三个组件,分别是 kubelet、kube-proxy 和 容器运行时 docker 或者 rkt。
特点 | Kubernetes | Docker |
---|---|---|
安装 | 复杂 | 简单 |
集群 | 强大 | 弱 |
GUI | 有Dashboard | 没有 |
扩容能力 | 高可扩容性,扩容快速 | 同样高可扩容,而且扩容速度更快 |
自动扩容 | 可以 | 不可以 |
负载均衡 | 不同Pod之间的负载均需要手动配置 | 可以进行自动的负载均衡 |
滚动更新和回滚 | 可以滚动更新和自动回滚 | 可以滚动更新,不能自动回滚 |
数据卷 | 只有同一个Pod中的容器可以共享卷 | 所有容器都可以共享卷 |
可通过命令“kubectl explain pod.spec.containers”来查看imagePullPolicy这行的解释。
K8s的镜像下载策略有三种:Always、Never、IFNotPresent;
Always:镜像标签为latest时,总是从指定的仓库中获取镜像;
Never:禁止从仓库中下载镜像,也就是说只能使用本地镜像;
IfNotPresent:仅当本地没有对应镜像时,才从目标仓库中下载。
默认的镜像下载策略是:当镜像标签是latest时,默认策略是Always;当镜像标签是自定义时(也就是标签不是latest),那么默认策略是IfNotPresent。
标签:是当相同类型的资源对象越来越多的时候,为了更好的管理,可以按照标签将其分为一个组,为的是提升资源对象的管理效率。
标签选择器:就是标签的查询过滤条件。目前API支持两种标签选择器:
负载均衡器是暴露服务的最常见和标准方式之一。根据工作环境使用两种类型的负载均衡器,即内部负载均衡器或外部负载均衡器。内部负载均衡器自动平衡负载并使用所需配置分配容器,而外部负载均衡器将流量从外部负载引导至后端容器。
kubernetes早期采用heapster来实现完整的性能数据采集和监控,然后用Metrics Server替换了前者,用于提供核心指标,包括Node、Pod的CPU和内存的使用。而Metrics Server需要采集node上的cAdvisor提供的数据资源。
开源软件 cAdvisor 是用于监控容器运行状态的利器之一,在 Kubernetes 系统中,cAdvisor 已被默认集成到 kubelet 组件内,当 kubelet 服务启动时,它会自动启动 cAdvisor 服务,然后 cAdvisor 会实时采集所在节点的性能指标及在节点上运行的容器的性能指标。kubelet 的启动参数 --cadvisor-port 可自定义 cAdvisor 对外提供服务的端口号,默认是 4194。
前端可以用Grafana实现自定义的UI监控界面。
deployment是rs的超集,提供更多的部署功能,如:回滚、暂停和重启、 版本记录、事件和状态查看、滚动升级和替换升级。
如果能使用deployment,则不应再使用rc和rs。
问题:rc/rs功能是怎么实现的。详述从API接收到一个创建rc/rs的请求,到最终在节点上创建pod的全过程,尽可能详细。另外,当一个pod失效时,kubernetes是如何发现并重启另一个pod的?
Replication Controller 可以保证Pod始终处于规定的副本数。
而当前推荐的做法是使用Deployment+ReplicaSet。
ReplicaSet 号称下一代的 Replication Controller,当前唯一区别是RS支持set-based selector。
RC是通过ReplicationManager监控RC和RC内Pod的状态,从而增删Pod,以实现维持特定副本数的功能。
RS也是大致相同。
K8s中对于pod资源对象的健康状态检测,提供了三类probe(探针)来执行对pod的健康监测:
livenessProbe探针
可以根据用户自定义规则来判定pod是否健康,用于判断容器是否处于Running状态,如果不是,kubelet就会杀掉该容器,并根据重启策略做相应的处理。如果容器不包含该探针,那么kubelet就会默认返回值都是success。
ReadinessProbe探针
同样是可以根据用户自定义规则来判断pod是否健康,容器服务是否可用(Ready),如果探测失败,控制器会将此pod从对应service的endpoint列表中移除,从此不再将任何请求调度到此Pod上,直到下次探测成功。
startupProbe探针
启动检查机制,应用一些启动缓慢的业务,避免业务长时间启动而被上面两类探针kill掉,这个问题也可以换另一种方式解决,就是定义上面两类探针机制时,初始化时间定义的长一些即可。
每种探测方法能支持以下几个相同的检查参数,用于设置控制检查时间:
通过命令“kubectl explain pod.spec”查看pod的重启策略。(restartPolicy字段)
DaemonSet这种资源对象会在每个k8s集群中的节点上运行,并且每个节点只能运行一个pod,这是它和deployment资源对象的最大也是唯一的区别。所以,在其yaml文件中,不支持定义replicas,除此之外,与Deployment、RS等资源对象的写法相同。
它的一般使用场景如下:
Kube-apiserver会接受到用户的删除指令,默认有30秒时间等待优雅退出,超过30秒会被标记为死亡状态,此时Pod的状态Terminating,kubelet看到pod标记为Terminating就开始了关闭Pod的工作。
关闭流程如下:
1、 pod从service的endpoint列表中被移除;
2、 如果该pod定义了一个停止前的钩子,其会在pod内部被调用,停止钩子一般定义了如何优雅的结束进程;
3、 进程被发送TERM信号(kill -14)
4、 当超过优雅退出的时间后,Pod中的所有进程都会被发送SIGKILL信号(kill -9)。
问题:详述kube-proxy原理,一个请求是如何经过层层转发落到某个pod上的整个过程。请求可能来自pod也可能来自外部。
集群中每个Node上都会运行一个kube-proxy服务进程,他是Service的透明代理兼均衡负载器,其核心功能是将某个Service的访问转发到后端的多个Pod上。kube-proxy通过监听集群状态变更,并对本机iptables做修改,从而实现网络路由。 而其中的负载均衡,也是通过iptables的特性实现的。
另外我们需要了解k8s中的网络配置类型,有如下几种:
从kubernetes1.8开始,词用了IPVS(IP Virtual Server)模式,用于路由规则的配置。相比iptables,IPVS具有如下优势:
(1)配置是否自动化
OpenvSwitch作为开源的交换机软件,相对比较成熟和稳定,支持各种网络隧道和协议,经历了大型项目 OpenStack 的考验,而 flannel 除了支持建立覆盖网络来实现 Pod 到 Pod 之间的无缝通信之外,还跟 docker、k8s 的架构体系紧密结合,flannel 能感知 k8s 中的 service 对象,然后动态维护自己的路由表,并通过 etcd 来协助 docker 对整个 k8s 集群的 docker0 网段进行规范,而 ovs ,这些操作则需要手动完成,假如集群中有 N 个节点,则需要建立 N(N-1)/2 个 Vxlan 或者 gre 连接,这取决于集群的规模,如果集群的规模很大,则必须通过自动化脚本来初始化,避免出错。
(2)是否支持隔离
flannel 虽然很方便实现 Pod 到 Pod 之间的通信,但不能实现多租户隔离,也不能很好地限制 Pod 的网络流量,而 ovs 网络有两种模式:单租户模式和多租户模式,单租户模式直接使用 openvswitch + vxlan 将 k8s 的 pod 网络组成一个大二层,所有的 pod 可以互相通信访问,多租户模式以 Namespace 为维度分配虚拟网络,从而形成一个网络独立用户,一个 Namespace 中的 pod 无法访问其他 Namespace 中的 pod 和 svc 对象。
参考博客
可以通过Service的NodePort方式访问,会在所有节点监听同一个端口,比如:30000,访问节点的流量会被重定向到对应的Service上面。
Quality of Service,Qos 主要有三种类别:
BestEffort
什么都不设置(CPU or Memory),佛系申请资源。
Burstable
Pod 中的容器至少一个设置了CPU 或者 Memory 的请求
Guaranteed
Pod 中的所有容器必须设置 CPU 和 Memory,并且 request 和 limit 值相等。
Pod启动后会加载当前环境所有Service信息,以便不同Pod根据Service名进行通信。
1.EmptyDir(空目录)
没有指定要挂载宿主机上的某个目录,直接由Pod内保部映射到宿主机上。类似于docker中的manager volume。
主要使用场景:
emptyDir的特性:
同个pod里面的不同容器,共享同一个持久化目录,当pod节点删除时,volume的数据也会被删除。如果仅仅是容器被销毁,pod还在,则不会影响volume中的数据。
总结来说:emptyDir的数据持久化的生命周期和使用的pod一致。一般是作为临时存储使用。
2.Hostpath
将宿主机上已存在的目录或文件挂载到容器内部。类似于docker中的bind mount挂载方式。
这种数据持久化方式,运用场景不多,因为它增加了pod与节点之间的耦合。
一般对于k8s集群本身的数据持久化和docker本身的数据持久化会使用这种方式,可以自行参考apiService的yaml文件,位于:/etc/kubernetes/main…目录下。
3.PersistentVolume(简称PV)
基于NFS服务的PV,也可以基于GFS的PV。它的作用是统一数据持久化目录,方便管理。
在一个PV的yaml文件中,可以对其配置PV的大小,
指定PV的访问模式:
以及指定pv的回收策略:
若需使用PV,那么还有一个重要的概念:PVC,PVC是向PV申请应用所需的容量大小,K8s集群中可能会有多个PV,PVC和PV若要关联,其定义的访问模式必须一致。定义的storageClassName也必须一致,若群集中存在相同的(名字、访问模式都一致)两个PV,那么PVC会选择向它所需容量接近的PV去申请,或者随机申请。
参考博客
kubectl get pods -n test -o wide
kubectl logs lede -n test|tail -n 30
kubectl describe pods lede -n test
kubectl get ep -n test
kubectl get pods --all-namespaces
kubectl get ingress -n test
kubectl delete deploy ledes -n test
kubectl scale deployment gitlab -n test --replicas=1
kubectl exec -it lede -n test – cat /etc/hosts
kubectl cordon test-node-10 #设置test-node-10为不可调度
kubectl uncordon test-node-10 #取消
[root@master httpd-web]# kubectl apply -f httpd2-deploy1.yaml –record
#运行yaml文件,并记录版本信息;
[root@master httpd-web]# kubectl rollout history deployment httpd-devploy1
#查看该deployment的历史版本
[root@master httpd-web]# kubectl rollout undo deployment httpd-devploy1 –to-revision=1
#执行回滚操作,指定回滚到版本1
env:
- name: test
valueFrom:
fieldRef:
fieldPath: metadata.name
解决办法:搭建内部的dns,在coredns配置中配置内网dns的IP
要是内部没有dns的话,在yaml文件中配置hostAliases,刑如:
hostAliases:
- ip: "192.168.4.124"
hostnames:
- "db.test.com"
FROM centos:latest
ARG JDK_HOME=/root/jdk1.8.0_142
WORKDIR /root
ADD jdk-8u142-linux-x64.tar.gz /root
ENV JAVA_HOME=/root/jdk1.8.0_142
ENV PATH=$PATH:$JAVA_HOME/bin
CMD ["bash"]
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- topologyKey: "kubernetes.io/hostname"
labelSelector:
matchLabels:
app: test
1、为每个pod设置资源限制
2、设置Kubelet资源预留
参考 #更新证书
参考 #集群升级
参考
export ETCDCTL_API=3
etcdctl --cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
snapshot save /data/test-k8s-snapshot.db
可以通过下面的命令查看到更新时可以控制的参数:
[root@master yaml]# kubectl explain deploy.spec.strategy.rollingUpdate
标签分类是可以自定义的,但是为了能使他人可以达到一目了然的效果,一般会使用以下一些分类: