第八章、Kubernetes控制器Controller详解
Statefulset
Statefulset主要是用来部署有状态应用
对于StatefulSet中的Pod,每个Pod挂载自己独立的存储,如果一个Pod出现故障,从其他节点启动一个同样名字的Pod,要挂载上原来Pod的存储继续以它的状态提供服务。
无状态应用
我们原来使用 deployment,部署的都是无状态的应用,那什么是无状态应用?
- 认为Pod都是一样的
- 没有顺序要求
- 不考虑应用在哪个node上运行
- 能够进行随意伸缩和扩展
有状态应用
上述的因素都需要考虑到
- 让每个Pod独立的
- 让每个Pod独立的,保持Pod启动顺序和唯一性
- 唯一的网络标识符,持久存储
- 有序,比如mysql中的主从
适合StatefulSet的业务包括数据库服务MySQL 和 PostgreSQL,集群化管理服务Zookeeper、etcd等有状态服务
StatefulSet的另一种典型应用场景是作为一种比普通容器更稳定可靠的模拟虚拟机的机制。传统的虚拟机正是一种有状态的宠物,运维人员需要不断地维护它,容器刚开始流行时,我们用容器来模拟虚拟机使用,所有状态都保存在容器里,而这已被证明是非常不安全、不可靠的。
使用StatefulSet,Pod仍然可以通过漂移到不同节点提供高可用,而存储也可以通过外挂的存储来提供 高可靠性,StatefulSet做的只是将确定的Pod与确定的存储关联起来保证状态的连续性。
部署有状态应用
无头service, ClusterIp:none
这里就需要使用 StatefulSet部署有状态应用
然后通过查看pod,能否发现每个pod都有唯一的名称
然后我们在查看service,发现是无头的service
这里有状态的约定,肯定不是简简单单通过名称来进行约定,而是更加复杂的操作
- deployment:是有身份的,有唯一标识
- statefulset:根据主机名 + 按照一定规则生成域名
每个pod有唯一的主机名,并且有唯一的域名
- 格式:主机名称.service名称.名称空间.svc.cluster.local
- 举例:nginx-statefulset-0.default.svc.cluster.local
DaemonSet
DaemonSet 即后台支撑型服务,主要是用来部署守护进程
长期伺服型和批处理型的核心在业务应用,可能有些节点运行多个同类业务的Pod,有些节点上又没有这类的Pod运行;而后台支撑型服务的核心关注点在K8S集群中的节点(物理机或虚拟机),要保证每个节点上都有一个此类Pod运行。节点可能是所有集群节点,也可能是通过 nodeSelector选定的一些特定节点。典型的后台支撑型服务包括:存储、日志和监控等。在每个节点上支撑K8S集群运行的服务。
守护进程在我们每个节点上,运行的是同一个pod,新加入的节点也同样运行在同一个pod里面
- 例子:在每个node节点安装数据采集工具
这里是不是一个FileBeat镜像,主要是为了做日志采集工作
进入某个 Pod里面,进入
kubectl exec -it ds-test-cbk6v bash
通过该命令后,我们就能看到我们内部收集的日志信息了
Job和CronJob
一次性任务 和 定时任务
- 一次性任务:一次性执行完就结束
- 定时任务:周期性执行
Job是K8S中用来控制批处理型任务的API对象。批处理业务与长期伺服业务的主要区别就是批处理业务的运行有头有尾,而长期伺服业务在用户不停止的情况下永远运行。Job管理的Pod根据用户的设置把任务成功完成就自动退出了。成功完成的标志根据不同的 spec.completions 策略而不同:单Pod型任务有一个Pod成功就标志完成;定数成功行任务保证有N个任务全部成功;工作队列性任务根据应用确定的全局成功而标志成功。
Job
Job也即一次性任务
使用下面命令,能够看到目前已经存在的Job
kubectl get jobs
在计算完成后,通过命令查看,能够发现该任务已经完成
我们可以通过查看日志,查看到一次性任务的结果
kubectl logs pi-qpqff
CronJob
定时任务,cronjob.yaml如下所示
这里面的命令就是每个一段时间,这里是通过 cron 表达式配置的,通过 schedule字段
然后下面命令就是每个一段时间输出
我们首先用上述的配置文件,创建一个定时任务
kubectl apply -f cronjob.yaml
创建完成后,我们就可以通过下面命令查看定时任务
kubectl get cronjobs
我们可以通过日志进行查看
kubectl logs hello-1599100140-wkn79
然后每次执行,就会多出一个 pod
删除svc 和 statefulset
使用下面命令,可以删除我们添加的svc 和 statefulset
kubectl delete svc web kubectl delete statefulset --all
Replication Controller
Replication Controller 简称 RC,是K8S中的复制控制器。RC是K8S集群中最早的保证Pod高可用的API对象。通过监控运行中的Pod来保证集群中运行指定数目的Pod副本。指定的数目可以是多个也可以是1个;少于指定数目,RC就会启动新的Pod副本;多于指定数目,RC就会杀死多余的Pod副本。
即使在指定数目为1的情况下,通过RC运行Pod也比直接运行Pod更明智,因为RC也可以发挥它高可用的能力,保证永远有一个Pod在运行。RC是K8S中较早期的技术概念,只适用于长期伺服型的业务类型,比如控制Pod提供高可用的Web服务。
Replica Set
Replica Set 检查 RS,也就是副本集。RS是新一代的RC,提供同样高可用能力,区别主要在于RS后来居上,能够支持更多种类的匹配模式。副本集对象一般不单独使用,而是作为Deployment的理想状态参数来使用
第九章、Kubernetes配置管理
Secret
Secret的主要作用就是加密数据,然后存在etcd里面,让Pod容器以挂载Volume方式进行访问
场景:用户名 和 密码进行加密
一般场景的是对某个字符串进行base64编码 进行加密
echo -n 'admin' | base64
变量形式挂载到Pod
- 创建secret加密数据的yaml文件 secret.yaml
然后使用下面命令创建一个pod
kubectl create -f secret.yaml
通过get命令查看
kubectl get pods
然后我们通过下面的命令,进入到我们的容器内部
kubectl exec -it mypod bash
然后我们就可以输出我们的值,这就是以变量的形式挂载到我们的容器中
# 输出用户 echo $SECRET_USERNAME # 输出密码 echo $SECRET_PASSWORD
最后如果我们要删除这个Pod,就可以使用这个命令
kubectl delete -f secret-val.yaml
数据卷形式挂载
首先我们创建一个 secret-val.yaml 文件
然后创建我们的 Pod
# 根据配置创建容器 kubectl apply -f secret-val.yaml # 进入容器 kubectl exec -it mypod bash # 查看 ls /etc/foo
ConfigMap
ConfigMap的作用是存储非加密的配置数据到etcd中,并让Pod通过环境变量、命令行参数或者挂载为Volume的方式来访问这些配置数据。
应用场景:配置文件
创建配置文件
首先我们需要创建一个配置文件 redis.properties
redis.port=127.0.0.1 redis.port=6379 redis.password=123456
创建ConfigMap
我们使用命令创建configmap
kubectl create configmap redis-config --from-file=redis.properties
然后查看详细信息
kubectl describe cm redis-config
Volume数据卷形式挂载
首先我们需要创建一个 cm.yaml
然后使用该yaml创建我们的pod
# 创建 kubectl apply -f cm.yaml # 查看 kubectl get pods
最后我们通过命令就可以查看结果输出了
kubectl logs mypod
以变量的形式挂载Pod
首先我们也有一个 myconfig.yaml文件,声明变量信息,然后以configmap创建
然后我们就可以创建我们的配置文件
# 创建pod kubectl apply -f myconfig.yaml # 获取 kubectl get cm
然后我们创建完该pod后,我们就需要在创建一个 config-var.yaml 来使用我们的配置信息
最后我们查看输出
kubectl logs mypod
第十章、Kubernetes集群安全机制
概述
当我们访问K8S集群时,需要经过三个步骤完成具体操作
- 认证
- 鉴权【授权】
- 准入控制
进行访问的时候,都需要经过 apiserver, apiserver做统一协调,比如门卫
- 访问过程中,需要证书、token、或者用户名和密码
- 如果访问pod需要serviceAccount
认证
对外不暴露8080端口,只能内部访问,对外使用的端口6443
客户端身份认证常用方式
- https证书认证,基于ca证书
- http token认证,通过token来识别用户
- http基本认证,用户名 + 密码认证
鉴权
基于RBAC进行鉴权操作
基于角色访问控制
准入控制
就是准入控制器的列表,如果列表有请求内容就通过,没有的话 就拒绝
RBAC介绍
基于角色的访问控制,为某个角色设置访问内容,然后用户分配该角色后,就拥有该角色的访问权限
k8s中有默认的几个角色
- role:特定命名空间访问权限
- ClusterRole:所有命名空间的访问权限
角色绑定
- roleBinding:角色绑定到主体
- ClusterRoleBinding:集群角色绑定到主体
主体
- user:用户
- group:用户组
- serviceAccount:服务账号
RBAC实现鉴权
- 创建命名空间
创建命名空间
我们可以首先查看已经存在的命名空间
kubectl get namespace
然后我们创建一个自己的命名空间 roledemo
kubectl create ns roledemo
命名空间创建Pod
为什么要创建命名空间?因为如果不创建命名空间的话,默认是在default下
kubectl run nginx --image=nginx -n roledemo
创建角色
我们通过 rbac-role.yaml进行创建
tip:这个角色只对pod 有 get、list权限
然后通过 yaml创建我们的role
# 创建
kubectl apply -f rbac-role.yaml
# 查看
kubectl get role -n roledemo
创建角色绑定
我们还是通过 role-rolebinding.yaml 的方式,来创建我们的角色绑定
然后创建我们的角色绑定
# 创建角色绑定
kubectl apply -f rbac-rolebinding.yaml
# 查看角色绑定
kubectl get role, rolebinding -n roledemo
使用证书识别身份
我们首先得有一个 rbac-user.sh 证书脚本
这里包含了很多证书文件,在TSL目录下,需要复制过来
通过下面命令执行我们的脚本
./rbac-user.sh
最后我们进行测试
# 用get命令查看 pod 【有权限】
kubectl get pods -n roledemo
# 用get命令查看svc 【没权限】
kubectl get svc -n roledmeo
第十一章、Kubernetes核心技术Ingress
前言
原来我们需要通过将端口号暴露到外部,使用 Service 的 NodePort 类型来实现。这样,每个节点都会启动该端口,从而使得在访问时,可以通过任何节点的 IP 地址和相应的端口号来访问服务。
但是NodePort还存在一些缺陷
- 因为端口不能重复,所以每个端口只能使用一次,一个端口对应一个应用
- 实际访问中都是用域名,根据不同域名跳转到不同端口服务中
Ingress和Pod关系
pod 和 ingress 是通过service进行关联的,而ingress作为统一入口,由service关联一组pod中
- 首先service就是关联我们的pod
- 然后ingress作为入口,首先需要到service,然后发现一组pod
- 发现pod后,就可以做负载均衡等操作
Ingress工作流程
在实际的访问中,我们都是需要维护很多域名, a.com 和 b.com
然后不同的域名对应的不同的Service,然后service管理不同的pod
需要注意,ingress不是内置的组件,需要我们单独的安装
使用Ingress
步骤如下所示
- 部署ingress Controller【需要下载官方的】
- 创建ingress规则【对哪个Pod、名称空间配置规则】
创建Nginx Pod
创建一个nginx应用,然后对外暴露端口
# 创建
pod kubectl create deployment web --image=nginx
# 查看
kubectl get pods
对外暴露端口
kubectl expose deployment web --port=80 --target-port=80 --type:NodePort
部署 ingress controller
下面我们来通过yaml的方式,部署我们的ingress,配置文件如下所示
这个文件里面,需要注意的是 hostNetwork: true,改成ture是为了让后面访问到
kubectl apply -f ingress-con.yaml
通过这种方式,其实我们在外面就能访问,这里还需要在外面添加一层
kubectl apply -f ingress-con.yaml
最后通过下面命令,查看是否成功部署 ingress
kubectl get pods -n ingress-nginx
创建ingress规则文件
创建ingress规则文件,ingress-h.yaml
添加域名访问规则
在windows 的 hosts文件,添加域名访问规则【因为我们没有域名解析,所以只能这样做】
最后通过域名就能访问