Container Evolution
容器编排
ansible/saltstack
传统应用编排工具docker
docker compose
docker单机编排docker swarm
docker主机加入docker swarm资源池docker machine
完成docker主机加入docker swarm资源池的先决条件/预处理工具
mesos(idc os) + marathon
面向容器编排的框架kubernetes(borg)
- 自动装箱(基于依赖 自动完成容器部署 不影响其可用性)
- 自我修复
- 水平扩展
- 服务发现和负载均衡
- 自动发布和回滚
- 密钥和配置管理
- 存储编排
- 任务批量处理运行
概述
组件
集群安装
二进制安装
kubeadm安装
- 图中docker组件可以替换为其他容器运行时组件(CRI)
- 参考:移除Dockershim的常见问题
主机环境预设
- OS: Ubuntu 22.04 LTS
- Kubernetes: v1.29.13
- Container Runtime(二选一即可)
- containerd
- 官方仓库containerd
- 或Docker社区提供的containerd.io
- DockerCE-27.5.0 和 cri-dockerd-0.3.16
- containerd
测试环境说明
- 1master/2+node 也可以多master 根据自己环境安排
- 集群节点需要做时间同步
- 禁用swap
- swapoff -a
- systemctl –type swap
- systemctl mask SWAP_DEV
- 禁用默认配置的iptables
- 加载br_netfilter模块
- modprobe br_netfilter
- 写入/etc/modules(开机启动)
安装容器运行时
docker+cri-docekrd
- 安装docker-ce
|
|
- docker配置
- kubelet需要让docker容器引擎使用systemd作为CGroup的驱动 其默认值为cgroupfs
- 我们还需要编辑docker的配置文件/etc/docker/daemon.json 参考下面配置
- 其中的registry-mirrors用于指明使用的镜像加速服务 参考国内无法下载Docker镜像的多种解决方案
- 提示: 自Kubernetes v1.22版本开始 未明确设置kubelet的cgroup driver时 则默认即会将其设置为systemd
|
|
- 为docker设置代理(可选)
- Kubeadm部署Kubernetes集群的过程中 默认使用Google的Registry服务registry.k8s.io上的镜像
- 例如
registry.k8s.io/kube-apiserver
等 但国内部分用户可能无法访问到该服务 - 我们也可以使用国内的镜像服务来解决这个问题 例如
registry.aliyuncs.com/google_containers
- 若选择使用国内的镜像服务 则配置代理服务的步骤为可选
- 设置代理配置 编辑/lib/systemd/system/docker.service
|
|
- 安装cri-dockerd
- 直接去对应的Github项目下载对应的deb包安装
containerd
- 安装容器运行时containerd
- Ubuntu 2204上安装Containerd有两种选择
- Ubuntu系统官方程序包仓库中的containerd
- Docker社区提供的
containerd.io
(本文选择该种方式)
- 安装并启动containerd.io
- Ubuntu 2204上安装Containerd有两种选择
|
|
- 配置
containerd.io
- 运行如下命令打印并保存如下配置
|
|
- 编辑生成的配置文件 完成如下几项相关的配置
|
|
- 配置crictl客户端
- 安装containerd.io时 会自动安装命令行客户端工具crictl
- 该客户端通常需要通过正确的unix sock文件才能接入到containerd服务
- 编辑配置文件/etc/crictl.yaml 添加如下内容即可
- 随后即可正常使用crictl程序管理Image/Container和Pod等对象
- 另外containerd.io还有另一个名为ctr的客户端程序可以使用 其功能也更为丰富
|
|
安装kubelet/kubeadm/kubectl
- 自v1.28版本开始 Kubernetes官方变更了仓库的存储路径及使用方式(不同的版本将会使用不同的仓库) 并提供了向后兼容至v1.24版本
- 因此 对于v1.24及之后的版本来说 可以使用如下有别于传统配置的方式来安装相关的程序包
- 以本示例中要安装的v1.29版本为例来说 配置要使用的程序包仓库 需要使用的命令如下
- 如若需要安装其它版本 则将下面命令中的版本号
v1.29
予以替换即可
|
|
- 安装完成后 要确保kubeadm等程序文件的版本
- 这将也是后面初始化Kubernetes集群时需要明确指定的版本号
整合kubelet和cri-dockerd
- 仅支持CRI规范的kubelet需要经由遵循该规范的cri-dockerd完成与docker-ce的整合
- 该步骤仅使用docker-ce和cri-dockerd运行时的场景中需要配置
配置cri-dockerd
- 配置cri-dockerd 确保其能够正确加载到CNI插件
- 编辑
/usr/lib/systemd/system/cri-docker.service
文件 确保其[Service]配置段中的ExecStart的值类似如下内容
|
|
- 需要添加的各配置参数(各参数的值要与系统部署的CNI插件的实际路径相对应)
--network-plugin
指定网络插件规范的类型 这里要使用CNI--cni-bin-dir
指定CNI插件二进制程序文件的搜索目录--cni-cache-dir
CNI插件使用的缓存目录--cni-conf-dir
CNI插件加载配置文件的目录--pod-infra-container-image
Pod中的puase容器要使用的Image 默认为registry.k8s.io上的pause仓库中的镜像 不能直接获取到该Image时 要明确指定为从指定的位置加载 例如registry.aliyuncs.com/google_containers/pause:3.9
- 配置完成后重启服务
systemctl restart cri-docker
配置kubelet
- 配置kubelet 为其指定cri-dockerd在本地打开的Unix Sock文件的路径
- 该路径一般默认为
/run/cri-dockerd.sock
编辑文件/etc/sysconfig/kubelet 为其添加如下指定参数- 若/etc/sysconfig目录不存在 则需要先创建该目录
KUBELET_KUBEADM_ARGS="--container-runtime=remote --container-runtime-endpoint=/run/cri-dockerd.sock"
初始化第一个主节点
- 该步骤开始尝试构建Kubernetes集群的master节点 配置完成后 各worker节点直接加入到集群中的即可
- 由于kubeadm部署的Kubernetes集群上 集群核心组件kube-apiserver、kube-controller-manager、kube-scheduler和etcd等均会以静态Pod的形式运行 它们所依赖的镜像文件默认来自于registry.k8s.io这一Registry服务之上
- 但我们无法直接访问该服务 常用的解决办法有如下两种
- 使用能够到达该服务的代理服务
- 使用国内的镜像服务器上的服务 例如
registry.aliyuncs.com/google_containers
等
初始化master节点
- 在运行初始化命令之前先运行如下命令单独获取相关的镜像文件 而后再运行后面的
kubeadm init
命令 以便于观察到镜像文件的下载过程 - 若您选择使用的是docker-ce和cri-dockerd这一容器运行时环境 本文后续内容中使用的kubeadm命令 都需要额外添加
--cri-socket=unix:///var/run/cri-dockerd.sock
选项 以明确指定其所要关联的容器运行时 - 这是因为docker-ce和cri-dockerd都提供unix sock类型的socket地址 这会导致kubeadm在自动扫描和加载该类文件时无法自动判定要使用哪个文件 而使用containerd.io运行时 则不存在该类问题
|
|
- 而后即可进行master节点初始化
- kubeadm init命令支持两种初始化方式
- 一是通过命令行选项传递关键的部署设定
- 另一个是基于yaml格式的专用配置文件(建议)
- 后一种允许用户自定义各个部署参数 在配置上更为灵活和便捷 下面分别给出了两种实现方式的配置步骤 建议读者采用第二种方式进行。
方式1
- 运行如下命令完成k8s-master01节点的初始化
- 需要注意的是 若使用docker-ce和cri-dockerd运行时 则还要在如下命令上明确配置使用
--cri-socket=unix:///run/cri-dockerd.sock
选项
|
|
- 各选项含义
--image-repository
指定要使用的镜像仓库 默认为registry.k8s.io
--kubernetes-version
kubernetes程序组件的版本号 它必须要与安装的kubelet程序包的版本号相同--control-plane-endpoint
控制平面的固定访问端点 可以是IP地址或DNS名称 会被用于集群管理员及集群组件的kubeconfig配置文件的API Server的访问地址 单控制平面部署时可以不使用该选项--pod-network-cidr
Pod网络的地址范围 其值为CIDR格式的网络地址 通常Flannel网络插件的默认为10.244.0.0/16 Calico插件的默认值为192.168.0.0/16 而Cilium的默认值为10.0.0.0/8--service-cidr
Service的网络地址范围 其值为CIDR格式的网络地址 kubeadm使用的默认为10.96.0.0/12 通常 仅在使用Flannel一类的网络插件需要手动指定该地址--apiserver-advertise-address
apiserver通告给其他组件的IP地址 一般应该为Master节点的用于集群内部通信的IP地址 0.0.0.0表示节点上所有可用地址--token-ttl
共享令牌(token)的过期时长 默认为24小时 0表示永不过期 为防止不安全存储等原因导致的令牌泄露危及集群安全 建议为其设定过期时长 未设定该选项时 在token过期后 若期望再向集群中加入其它节点 可以使用如下命令重新创建token 并生成节点加入命令kubeadm token create --print-join-command
- 提示:无法访问
registry.k8s.io
时 同样可以在上面的命令中使用--image-repository=registry.aliyuncs.com/google_containers
选项 以便从国内的镜像服务中获取各Image - 注意:若各节点未禁用Swap设备 还需要附加选项
--ignore-preflight-errors=Swap
从而让kubeadm忽略该错误设定
方式二
- kubeadm也可通过配置文件加载配置 以定制更丰富的部署选项 获取内置的初始配置文件的命令
kubeadm config print init-defaults
- 下面的配置示例 是以上面命令的输出结果为框架进行修改的 它明确定义了kubeProxy的模式为ipvs 并支持通过修改imageRepository的值修改获取系统镜像时使用的镜像仓库
|
|
- 将上面的内容保存于配置文件中 例如kubeadm-config.yaml
- 而后执行如下命令即能实现类似前一种初始化方式中的集群初始配置 但这里将Service的代理模式设定为ipvs
kubeadm init --config kubeadm-config.yaml --upload-certs
初始化完成后的操作步骤
- 对于Kubernetes系统的新用户来说 无论使用上述哪种方法 命令运行结束后 请记录最后的kubeadm join命令输出的最后提示的操作步骤
- 下面的内容是需要用户记录的一个命令输出示例 它提示了后续需要的操作步骤
|
|
kubeadm init
命令完整参考指南请移步官方文档
设定kubectl
- kubectl是kube-apiserver的命令行客户端程序 实现了除系统部署之外的几乎全部的管理操作 是kubernetes管理员使用最多的命令之一
- kubectl需经由API server认证及授权后方能执行相应的管理操作 kubeadm部署的集群为其生成了一个具有管理员权限的认证配置文件/etc/kubernetes/admin.conf
- 它可由kubectl通过默认的
$HOME/.kube/config
的路径进行加载 当然 用户也可在kubectl命令上使用–kubeconfig选项指定一个别的位置 - 下面复制认证为Kubernetes系统管理员的配置文件至目标用户(例如当前用户root)的家目录下
mkdir ~/.kube
&&cp /etc/kubernetes/admin.conf ~/.kube/config
部署网络插件
- Kubernetes系统上Pod网络的实现依赖于第三方插件进行 这类插件有近数十种之多 较为著名的有flannel、calico、canal和kube-router等 简单易用的实现为CoreOS提供的flannel项目
- 下面的命令用于在线部署flannel至Kubernetes系统之上 我们需要在初始化的第一个master节点k8s-master01上运行如下命令 以完成部署
kubectl apply -f https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml
- 而后使用如下命令确认其输出结果中Pod的状态为
Running
类似如下命令及其输入的结果所示 kubectl get pods -n kube-flannel
验证master节点已经就绪
|
|
添加节点到集群中
下面的两个步骤 需要分别在k8s-node01、k8s-node02和k8s-node03上各自完成
- 若未禁用Swap设备 编辑kubelet的配置文件/etc/default/kubelet 设置其忽略Swap启用的状态错误
- 内容如下:KUBELET_EXTRA_ARGS="–fail-swap-on=false"
- 将节点加入第二步中创建的master的集群中 要使用主节点初始化过程中记录的kubeadm join命令
- 再次提示 若使用docker-ce和cri-dockerd运行时环境 则需要在如下命令中额外添加
--cri-socket=unix:///run/cri-dockerd.sock
选项
- 再次提示 若使用docker-ce和cri-dockerd运行时环境 则需要在如下命令中额外添加
1 2 3
kubeadm join k8s-master01.minho.com:6443 --token tkzmlw.406h8d9g8x9sf8z1 \ --discovery-token-ca-cert-hash sha256:a32fe9b88096c3c0c22570a486302f58d3c479a8f1ccaf74b8fa4538a1a9d904 \ --cri-socket=unix:///run/cri-dockerd.sock
- 若未禁用Swap设备 编辑kubelet的配置文件/etc/default/kubelet 设置其忽略Swap启用的状态错误
验证节点添加结果
- 在每个节点添加完成后 即可通过kubectl验证添加结果
- 下面的命令及其输出是在所有的三个节点均添加完成后运行的 其输出结果表明三个Worker Node已经准备就绪
|
|
测试应用编排及服务访问
- 到此为止 一个master/三个worker的kubernetes集群基础设施已经部署完成 用户随后即可测试其核心功能
- 例如 下面的命令可将demoapp以Pod的形式编排运行于集群之上 并通过在集群外部进行访问
|
|
- demoapp是一个web应用 因此 用户可以于集群外部通过
http://NodeIP:30622
这个URL访问demoapp上的应用 - 我们也可以在Kubernetes集群上启动一个临时的客户端 对demoapp服务发起访问测试
kubectl run client-$RANDOM --image=ikubernetes/admin-box:v1.2 --rm --restart=Never -it --command -- /bin/bash
- 而后 在打开的交互式接口中 运行如下命令 对demoapp.default.svc服务发起访问请求 验证其负载均衡的效果
root@client-3021 ~# while true; do curl demoapp.default.svc; sleep 1; done
- 清理部署的测试应用
kubectl delete deployments/demoapp services/demoapp
部署Add-ons(可选步骤)
- MetalLB
- Ingress Nginx
- Metrics Server
- Kuboard
资源清单定义
创建资源的方法
apiserver仅接收json格式的资源定义
yaml格式提供配置清单 apiserver可自动将其转换为json格式 而后再提交
大部分资源的配置清单 主要都有五个主要的部分组成
apiversion
kubectl api-versions
# 所属API群组- 标识方式:
group/version
省略组名则为core group
kind: 资源类别
metadata: 元数据
- name: 同一类别中 name需要唯一
- namespace: 所属k8s的哪个名称空间
- labels
- annotations
- 每个资源的引用PATH
/api/${GROUP/VERSION}/namespace/${NAMESPACE}/${TYPE}/${NAME}
spec(重要): 定义用户期望的状态 disired state
status: 当前状态 current state 本字段由Kubernetes集群维护
字段太多 可以借助
kubectl explain --help
命令查看详细信息- kubectl explain pod
- kubectl explain pod.metadata
Pod概述
自主式Pod
|
|
Pod资源
spec.containers <[]object>
1 2 3 4 5 6 7 8 9
# kubectl explain pod.spec.containers - name: <string> image: <string> imagePullPolicy: <string> # Always Never IfNotPresent ... # 修改镜像中的默认应用 - command/args https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/
标签
- key = value
- key: 字母 数字 _ - .
- value: 可以为空 只能字母或数字开头及结尾
- key = value
标签选择器
- 等值关系: =、==、!=(不等于会筛选出不具有该标签的资源)
- 集合关系
- KEY in (VALUE1,VALUE2,…)
- KEY notin (VALUE1,VALUE2,…)
- KEY # 存在这个KEY就行
- !KEY # 不存在此键的资源
许多资源支持内嵌字段来使用标签选择器
- matchLabels: 直接给定键值
- matchExpressions: 基于给定的表达式来定义使用标签选择器
- {key: “KEY”, operator: “OPERATOR”,values:[VAL1,VAL2,VAL3,…]
- 操作符
- In、NotIn: values字段的值必须为非空列表
- Exists、NotExists: values字段的值必须为空列表
spec.nodeSelector <map[striong]string>
- 节点标签选择器
spec.nodeName
<string>
# 直接指定运行nodeannotations
- 与label不同的地方在于 它不能用于挑选资源对象 仅用于为对象提供元数据
- 没有键长度/值长度限制
spec.restartPolicy
- 重启策略: One of Always, OnFailure, Never. Default to Always
Pod生命周期
状态
- Pending # 调度尚未完成
- Running # 运行状态
- Failed
- Succeeded
- Unknown
- …
Pod生命周期中的重要行为
- 初始化容器
- 容器探测(自定义命令/TCP套接字发请求/HTTP应用层请求)
- liveness probe: 探测容器是否存活
- readiness probe: 探测容器是否准备就绪 能对外提供服务
- 钩子
- post start
- pre stop
Pod容器探针类型
kubectl explain pod.spec.containers.livenessProbe
kubectl explain pod.spec.containers.readinessProbe
- exec Action
- httpGet Action
- tcpSocket Action
Pod控制器
ReplicaSet
- Kubectl explain replicaset
- 用户期望副本数 标签选择器 Pod资源模版
- 不建议直接使用ReplicaSet
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
apiVersion: apps/v1 kind: ReplicaSet metadata: name: myapp namespace: default spec: replicas: 2 selector: matchLabels: app: myapp release: canary template: metadata: name: myapp-pod labels: app: myapp release: canary environment: qa spec: containers: - name: myapp-container image: nginx:alpine ports: - name: http containerPort: 80
Deployment
- 构建在ReplicaSet之上 而非Pod
- 实现滚动更新(多出或少于N个副本 控制更新粒度)、回滚
- 通常管理10个历史版本(ReplicaSet)
- 管理无状态应用最好的控制器
- 无状态(只关注群体、不关注个体)、持续运行应用
- 声明式管理(即可以创建 也可以更新
kubectl apply -f deployment.yaml
) kubectl rollout history
查看滚动历史
- 构建在ReplicaSet之上 而非Pod
DaemonSet
kubectl explain deployment.spec.strategy.rollingUpdate
# 滚动更新策略确保集群中的每一个节点(或部分满足条件的节点)精确运行一个Pod副本
通常用于一些系统级的后台任务
无状态、持续运行应用
Job
- 只做一次 只要完成就正常退出 没完成才进行重构
- 执行一次性的作业
- 不需要持续在后台运行 执行完成就退出
Cronjob
- 周期性Job
StatefulSet
- 管理有状态应用
- 每一个pod副本单独管理 拥有自己独有的标识和独有的数据集
TPR: Third Party Resources 1.2+ - 1.7
CDE: Custom Defined Resources 1.8+
Operator
Service概述
Service代理
- userspace
- kube-proxy会监视Kubernetes控制平面对Service对象和Endpoints对象的添加和移除操作
- 对每个Service它会在本地Node上打开一个端口(随机选择) 任何连接到代理端口的请求 都会被代理到Service的后端
Pods
中的某个上面- 使用哪个后端Pod是 kube-proxy 基于
SessionAffinity
来确定的
- 使用哪个后端Pod是 kube-proxy 基于
- 最后 它配置 iptables 规则 捕获到达该 Service 的
clusterIP
(是虚拟 IP)和Port
的请求 并重定向到代理端口 代理端口再代理请求到后端Pod- 默认情况下 用户空间模式下的kube-proxy通过轮转算法选择后端
- 流量来回在内核和用户空间切换 效率较低
- iptables
kube-proxy
会监视Kubernetes控制节点对Service对象和Endpoints对象的添加和移除对每个Service 它会配置iptables规则 从而捕获到达该Service的
clusterIP
和端口的请求 进而将请求重定向到 Service 的一组后端中的某个Pod上面对于每个Endpoints对象 它也会配置iptables规则 这个规则会选择一个后端组合
- 默认的策略是 kube-proxy在iptables模式下随机选择一个后端
使用iptables处理流量具有较低的系统开销 因为流量由Linux netfilter处理 而无需在用户空间和内核空间之间切换 这种方法也可能更可靠
如果kube-proxy在iptables模式下运行 并且所选的第一个 Pod 没有响应 则连接失败
- 这与用户空间模式不同: 在这种情况下 kube-proxy将检测到与第一个Pod的连接已失败 并会自动使用其他后端Pod 重试
- 可以使用Pod就绪探测器 验证后端Pod可以正常工作 以便iptables模式下的kube-proxy仅看到测试正常的后端 避免将流量通过kube-proxy发送到已知已失败的 Pod
- ipvs
特性状态: Kubernetes v1.11 [stable]
在
ipvs
模式下 kube-proxy监视Kubernetes服务和端点 调用netlink
接口创建相应的IPVS规则 并定期将IPVS规则与Kubernetes服务和端点同步 该控制循环可确保 IPVS 状态与所需状态匹配访问服务时 IPVS将流量定向到后端Pod之一
IPVS代理模式基于类似于iptables模式的netfilter挂钩函数 但是使用哈希表作为基础数据结构 并且在内核空间中工作
- 这意味着 与iptables模式下的kube-proxy相比 IPVS模式下的kube-proxy重定向通信的延迟要短 并且在同步代理规则时具有更好的性能
- 与其他代理模式相比 IPVS模式还支持更高的网络流量吞吐量
IPVS提供了更多选项来平衡后端Pod的流量
rr
: 轮询(Round-Robin)lc
: 最少链接(Least Connection) 即打开链接数量最少者优先dh
: 目标地址哈希(Destination Hashing)sh
: 源地址哈希(Source Hashing)sed
: 最短预期延迟(Shortest Expected Delay)nq
: 从不排队(Never Queue)
备注
- 要在IPVS模式下运行kube-proxy必须在启动kube-proxy之前使IPVS在节点上可用
- 当kube-proxy以IPVS代理模式启动时 它将验证IPVS内核模块是否可用
- 如果未检测到IPVS内核模块 则kube-proxy将退回到以iptables代理模式运行
Service类型
- ClusterIP: 通过集群的内部IP暴露服务 选择该值时服务只能够在集群内部访问 这也是默认的
ServiceType
- NodePort: 通过每个节点上的IP和静态端口(NodePort)暴露服务 NodePort服务会路由到自动创建的ClusterIP服务
- 通过请求
<节点IP>:<节点端口>
你可以从集群的外部访问一个NodePort服务 - Client -> NodeIP:NodePort -> ClusterIP:ServicePort -> PodIP:containerPort
- 为避免单Node压力过大 会在外面再加一层负载均衡
- 公有云环境: LBaaS(参考下面LoadBalancer类型)
- 通过请求
- LoadBalancer: 使用云提供商的负载均衡器向外部暴露服务 外部负载均衡器可以将流量路由到自动创建的NodePort服务和ClusterIP服务上
- ExternalName: 通过返回CNAME和对应值 可以将服务映射到externalName字段的内容(例如
foo.bar.example.com
) 无需创建任何类型代理- FQDN(CoreDNS 内部解析)
- CNAME -> FQDN(外部真正的FQDN )
- FQDN(CoreDNS 内部解析)
Headless Services(无头Service)
- 有时不需要或不想要负载均衡 以及单独的Service IP 遇到这种情况 可以通过指定Cluster IP(
spec.clusterIP
)的值为"None"
来创建Headless
Service - 你可以使用一个无头Service与其他服务发现机制进行接口 而不必与Kubernetes的实现捆绑在一起
- 对于无头
Services
并不会分配Cluster IP kube-proxy不会处理它们 而且平台也不会为它们进行负载均衡和路由 DNS如何实现自动配置 依赖于Service是否定义了选择算符
Ingress
- Service对后端特定类型Pod分类(label selector)
- Ingress基于上面的分类识别后端Pod 并生成配置信息注入到nginx(需要重载配置)/envoy/traefik等
存储卷
kubectl explain pods.spec.volumes
- emptyDir # 临时目录 随pod删除而消失(生命周期同pod)
- gitRepo(clone到机器 修改不会同步 需要同步可以自己再做一个sidecar)
- hostPath # 宿主机路径
- SAN(iSCSI…)、NAS(nfs、cifs…)
- 分布式存储
- glusterfs、rdb、cephfs
- 云存储
- EBS、Azure Disk…
PV/PVC
StorageClass
- 存储设备需支持RESTful风格的创建请求
- 根据请求动态创建PV
ConfigMap
- ConfigMap是一种 API 对象 用来将非机密性的数据保存到键值对中
- 使用时Pods可以将其用作环境变量、命令行参数或者存储卷中的配置文件
- ConfigMap将你的环境配置信息和容器镜像解耦 便于应用配置的修改
容器化配置应用方式
- 自定义命令行参数
- args: []
- 把配置文件直接打包至镜像
- 环境变量
- CloudNative的应用程序一般可直接通过环境变量加载配置
- 通过entrypoint脚本来预处理变量为配置文件中的配置信息
- 存储卷
Secret
- Secret是一种包含少量敏感信息例如密码、令牌或密钥的对象 这样的信息可能会被放在Pod规约中或者镜像中
- 使用Secret意味着你不需要在应用程序代码中包含机密数据
- Secret类似于ConfigMap但专门用于保存敏感数据
StatefulSet控制器
CoreOS Operator
cattle/pet # 一个关注群体 一个关注个体(和无状态应用的区别)
PetSet(1.3) -> StatefulSet(1.5+)
StatefulSet主要用于管理有以下特性的应用程序
- 稳定且唯一的网络标识符
- 稳定且持久的存储
- 有序、平滑的部署和扩展
- 有序、平滑的终止和删除
- 有序的滚动更新
一般来说 一个典型的StatefulSet由三个组件组成
- handless service # 无头服务 确保名称唯一
- StatefulSet # 控制器
- volumeClaimTemplate # 存储卷申请模版(不能使用同一存储卷 pod模版创建的存储卷都是一样的 所以需要卷申请模版)
kubelet explain sts.spec.updateStrategy.rollingUpdate
- partition <inter> # 控制更新的Pod
- partition: N # 大于等于编号N的Pod将被更新 默认值: 0
认证及ServiceAccount
认证授权
- 认证(支持多种认证方式) # 认证插件
- 令牌认证 bearer token
- ssl认证(确认服务端/客户端身份) 双向证书认证(https)
- …
- 授权检查(权限) # 授权插件
- RBAC # kubeadm部署的集群强制开启RBAC
- …
- 准入控制(关联的其他资源或操作 是否有权限 进一步补充授权机制)
- API Server需要信息去识别客户端的操作
- user: username + uid
- group
- extra
- API(请求的Kubernetes API)
- Request Path
kubectl proxy --port=8080
curl http://localhost:8080/api/v1/namespaces
curl http://localhost:8080/apis/apps/v1/namespaces/default/deployments/myapp-deploy/
- HTTP request verb
- GET POST PUT DELETE
- get list create update patch watch proxy redirect delete deletecollection
- Resources
- SubResources
- Namespace
- API Group
- Request Path
ServiceAccount
- 访问APIServer的两种客户端
- kubectl/dashborad 集群外部客户端(userAccount)
- pod 集群内部客户端(serviceAccount)
kubectl explain pods.spec.serviceAccountName
- kubeconfig
kubectl config view
RBAC授权
- 授权插件
- Node
- ABAC(Attribute-based access control)
- RBAC(Role-based access contro)
- Webhook
- K8S-RBAC
- role
- operations
- objects
- rolebinding
- user account OR service account
- role
kubectl create role pods-reader --verb=get,list,watch --resource=pods --dry-run -o yaml
- role
Helm
- 类似yum
Reference
- ubuntu
- kubetnetes