在线安装Microk8s
1、安装snap
1 | yum install -y epel-release |
2、安装microk8s
1 | snap install microk8s --classic # 在RockyLinux9.4上, 默认下载Microk8s 1.31版本 |
1、安装snap
1 | yum install -y epel-release |
2、安装microk8s
1 | snap install microk8s --classic # 在RockyLinux9.4上, 默认下载Microk8s 1.31版本 |
目标:
Google开源的容器集群管理系统,主要功能:
https://blog.csdn.net/pcj_888/article/details/144200265
https://blog.csdn.net/pcj_888/article/details/144240636
一个k8s集群由分布式存储etcd, 控制节点controller,和服务节点Node组成,k8s主要组件如下:
插件Add-ons
Pod是一组紧密关联的容器, 是k8s调度的基本单位
Pod设计理念是支持多个容器在一个Pod中共享网络和文件系统,可通过进程间通信和文件共享的方式完成服务
Node是Pod真正运行的主机。为了管理Pod,每个Node上至少要运行container runtime、kubelet和kube-proxy
Namespace提供一种机制,将同一集群的资源划分为相互隔离的组
pod,service,deploymeny都是属于某一个namespace的,而node,persistentVolume不属于任何namespace
Service是应用服务的抽象,通过labels为应用提供负载均衡和服务发现。
匹配labels的Pod IP和端口列表组成endpoints, 由kube-proxy负责将服务IP负载均衡到这些endpoints上
相对于命令式API, 声明式API对于重复操作的效果是稳定的,运行多次也不会出错
Deployment(部署)表示用户对k8s集群的一次更新操作。 可以是创建一个服务,更新一个服务,或者是滚动升级一个服务
Pod只是运行服务的实例,随时可能在一个节点停止,在另一个节点以新的IP启动,因此不能以确定IP和端口提供服务。
Service实现了服务发现和负载均衡的核心功能。
业务Pod可能在有些节点运行多个Pod, 有些节点又没有Pod运行。而DaemonSet保证每个节点上都要有一个Pod运行。
典型的DaemonSet包括: 日志、监控(比如fluentd)
StatefulSet是管理一组有状态pod的部署和扩展的控制器。
k8s的volume(存储卷)和Docker的类似。Docker的volume作用范围为一个容器,k8s的volume作用范围是一个Pod
每个Pod中声明的存储卷由Pod中所有容器共享
PV和PVC的关系,和Node与Pod关系类似
Secret用于保存和传递密码、秘钥、认证凭证等敏感信息
注:
https://juejin.cn/post/6844903665879220231
通过设置dnsPolicy参数,设置访问DNS的策略。默认为ClusterFirst
** ClusterFirst**
默认值, 优先使用kubedns或coredns解析,如果不成功使用宿主机DNS解析
有一个冲突,如果Pod设置了HostNetwork=true, ClusterFirst会强制转换为Default
Default
表示Pod里DNS配置和宿主机完全一致(/etc/resolv.conf完全一致)
ClusterFirstWithHostNet
Pod以host模式启动时,会使用宿主机的/etc/resolv.conf配置
如果Pod中仍然需要用k8s集群的DNS服务,需要将dnsPolicy设置为ClusterFirstWithHostNet
None
清除Pod预设的DNS配置。如果设置为None,为了避免Pod里没有任何DNS,需要添加dnsConfig描述自定义的DNS参数,例:
1 | spec: |
使用主机的IPC命名空间
设置hostIPC参数为True, 使用主机的IPC命名空间,默认为False
使用主机的网络命名空间
设置hostNetwork参数为True, 使用主机的网络命名空间,默认为False
使用主机的PID空间
设置hostPID参数为True, 使用主机的PID命名空间,默认为False
支持三种RestartPolicy
https://juejin.cn/post/7163135179177852936
为了探测容器状态,k8s提供了两种探针:
如果三个探针同时存在,先执行StartupProbe,禁用其他两个探针。直到满足StartupProbe,再启动其他两个探针。
可以给探针配置可选字段,用来更精确控制Liveness和Readiness两种探针行为
容器生命周期钩子(Container Lifecycle Hooks)监听容器生命周期的特定事件
钩子函数回调支持两种方式
例如:可以给容器增加CAP_NET_ADMIN,根据需要添加或删除网卡
Service是对一组提供相同功能的Pods抽象,并为他们提供一个统一的入口。实现服务发现和负载均衡功能
Service有四种类型:
Service通过yaml, 例如:定义一个nginx服务,将服务80端口转发到default namespace中带有标签run=nginx的Pod的80端口
1 | apiVersion: v1 |
各种类型的Service对源IP处理方法不同:
Service只支持4层负载均衡,没有7层功能。 Ingress可以解决这个问题
容器数据是非持久化的,容器消亡后数据跟着丢失,所以Docker提供volume机制将数据持久化存储
类似的,k8s提供了更强大的Volume机制和丰富插件,解决了容器数据持久化和容器间共享数据的问题
与Docker不同,k8s volume生命周期与Pod绑定
Pod删除时。 volume才会清理,数据是否丢失取决于Volume类型。例如PV数据不会丢,emptyDir会丢失
PV提供网络存储资源,而PVC请求存储资源
Volume生命周期:
为Pod提供了一个声明式定义的方法,应用场景方法:
扩容
1 | kubectl scale deployment nginx-deployment --replicas 10 |
回滚
1 | kubectl rollout undo deployment/nginx-deployment |
只有Deployment的pod template中的label更新,或者镜像更改时被触发。
其他更新,例如扩容Deployment不会触发rollout.
滚动更新的示例: nginx:1.9.1代替nginx:1.7.9
1 | kubectl set image deployment/nginx-deployment nginx=nginx=1.9.1 |
查看rollout状态,执行
1 | kubectl rollout status deployment/nginx-deployment |
1 | kubectl rollout history deployment/nginx-deployment |
回退到历史版本
1 | kubectl rollout undo deployment/nginx-deployment |
也可以使用–to-revision参数指定某个历史版本
1 | kubectl rollout undo deployment/nginx-deployment --to-revision=2 |
举例: 创建tls的secret
有状态服务
StatefulSet中每个Pod的DNS格式为statefulSetName-{0..N-1}.serviceName.namespace.svc.cluster.local
DaemonSet保证在每个Node上都运行一个容器副本,常用于部署一些集群的日志,监控,或者其他系统管理应用,典型应用包括:
资源配额(Resource Quotas)是用来限制用户资源用量的一种机制
它的工作原理:
默认情况, k8s所有容器没有任何CPU和内存限制, LimitRange可以用来给Namespace增加一个资源限制,包括最小、最大、默认资源
使用标签选择器控制Pod之间流量
允许前端Pod访问后端Pod的XX端口, 允许后端Pod访问数据库的XX端口
internet -> ingress -> services
保存配置数据的键值对, 处理不包含敏感信息的字符串
三种使用方式:
用于实现控制器的异步预测删除钩子,可以通过metadata.finalizers指定finalizer
CoreOS基于Raft开发的分布式key-value存储
k8s最核心组件之一,提供如下功能:
负责分配调度Pod到集群内的节点上,监听kube-apiserver,查询未分配Node的Pod,然后根据调度策略为Pod分配节点
指定Node节点调度
例如, 给Node打标签:
1 | kubectl label nodes node-01 disktype=ssd |
用于保证Pod不被调度到不合适的Node上,Taint应用于Node, toleration用于Pod上
例: 使用taint命令给node1添加taints
1 | kubectl taint nodes node1 key1=value1:NoSchedule |
目前支持的taint类型
通过apiserver监控整个集群状态,确保集群处于预期的工作状态
每个节点上运行一个kubelet服务进程,默认监听10250端口,接受并执行主节点发来的指令,管理Pod和容器
监听API server中service和endpoint变化,通过iptables为服务配置负载均衡
iptables性能问题(服务多的时候,iptables规则可能上万,大规模会有性能问题)
还有ipvs的方案
1 | -A KUBE-MARK-DROP -j MARK --set-xmark 0x8000/0x8000 |
kube-proxy仅支持TCP和UDP
为k8s集群提供命名服务, 一般通过Addon方式部署,从v1.3版本开始,成为一个内建的自启动服务
源码: https://github.com/kubernetes/dns
最简单的网络模型就是让容器共享Host的network namespace,使用宿主机的网络协议栈。
优点:
一个基于BGP的纯三层的数据中心网络方案(不需要Overlay)
Calico在每一个计算节点利用Linux Kernel实现一个高校的vRouter来负责数据转发,
每个vRouter通过BGP协议负责把自己运行workload路由信息像整个Calico网络内传播
基本思想: Container Runtime在创建容器时,先创建好network namespace,然后调用CNI插件为这个netns配置网络,其后再启动容器内的进程
从一个主机接口虚拟出多个虚拟网络接口, 所有接口有相同的MAC地址,不同的IP地址
1 | ip link add link <master-dev> <slave-dev> type ipvlan mode { L2 | L3 } |
MACVLAN可以从一个主机接口虚拟出多个macvtap,且每个macvtap设备都有不同的mac地址
1 | ip link add link <master-dev> name macvtap0 type macvtap |
面试题:
只用一台Nginx做反向代理,如果这台Nginx出现故障(比如宕机),则服务不可用。
以下给出keepalived双机热备方案实现Nginx高可用的方法。先介绍几个概念:
高可用(High Availability)是指系统或服务能够在面对硬件故障、软件崩溃、网络问题等各种故障情况下,仍然保持正常运行或快速恢复的能力,以减少服务中断时间,确保业务连续性和数据完整性。
指一台服务器提供服务,另一台作为备用。当一台服务器不可用时另一台就自动顶上去。
一个开源的高可用解决方案,通过VRRP协议实现故障转移,避免单点故障导致的服务中断。
Nginx的location配置,用于定义请求的URI和服务器响应之间的对应关系。
Nginx的location规则匹配的是URI, 不需要考虑后面的query_string。语法如下:
1 | location [ = | ~ | ~* | ^~ | 空格 ] /URI { |
参数 | 解释 |
---|---|
= | 精确匹配, 如匹配成功就立即停止搜索 |
^~ | 前缀匹配, 不使用正则表达式。如果匹配成功, 并且匹配字符串是最长的,就不再匹配其他location |
~ | 正则匹配,区分大小写 |
~* | 正则匹配,不区分大小写 |
空格 | 前缀匹配, 不使用正则表达式 |