kubernetes
2020-12-09 16:50:11 0 举报
AI智能生成
k8s 学习笔记
作者其他创作
大纲/内容
master
概念
Master是Cluster的大脑,它的主要职责是调度,即决定将应用放
在哪里运行。Master运行Linux操作系统,可以是物理机或者虚拟
机。为了实现高可用,可以运行多个Master。默认配置下Kubernetes不会将Pod调度到Master节
点
在哪里运行。Master运行Linux操作系统,可以是物理机或者虚拟
机。为了实现高可用,可以运行多个Master。默认配置下Kubernetes不会将Pod调度到Master节
点
Cluster
组成
master
API Server
API Server提供HTTP/HTTPS RESTful API,即Kubernetes API。
API Server是Kubernetes Cluster的前端接口,各种客户端工具(CLI或
UI)以及Kubernetes其他组件可以通过它管理Cluster的各种资源。
API Server是Kubernetes Cluster的前端接口,各种客户端工具(CLI或
UI)以及Kubernetes其他组件可以通过它管理Cluster的各种资源。
Scheduler(kube-scheduler)
Scheduler负责决定将Pod放在哪个Node上运行。Scheduler在调度
时会充分考虑Cluster的拓扑结构,当前各个节点的负载,以及应用对
高可用、性能、数据亲和性的需求。
时会充分考虑Cluster的拓扑结构,当前各个节点的负载,以及应用对
高可用、性能、数据亲和性的需求。
Controller Manager(kube-controller-manager)
Controller Manager负责管理Cluster各种资源,保证资源处于预期
的状态。Controller Manager由多种controller组成,包括replication
controller、endpoints controller、namespace controller、serviceaccounts
controller等。
不同的controller管理不同的资源。例如,replication controller管
理Deployment、StatefulSet、DaemonSet的生命周期,namespace
controller管理Namespace资源。
的状态。Controller Manager由多种controller组成,包括replication
controller、endpoints controller、namespace controller、serviceaccounts
controller等。
不同的controller管理不同的资源。例如,replication controller管
理Deployment、StatefulSet、DaemonSet的生命周期,namespace
controller管理Namespace资源。
etcd
etcd负责保存Kubernetes Cluster的配置信息和各种资源的状态信
息。当数据发生变化时,etcd会快速地通知Kubernetes相关组件
息。当数据发生变化时,etcd会快速地通知Kubernetes相关组件
Pod网络
Pod要能够相互通信,Kubernetes Cluster必须部署Pod网络,
flannel是其中一个可选方案。
flannel是其中一个可选方案。
概念
master运行着的Daemon服务包括
kube-apiserver、kube-scheduler、kube-controller-manager、etcd和Pod
网络(例如flannel)
kube-apiserver、kube-scheduler、kube-controller-manager、etcd和Pod
网络(例如flannel)
node
概念
Node是Pod运行的地方,Kubernetes支持Docker、rkt等容器
Runtime。Node上运行的Kubernetes组件有kubelet、kube-proxy和Pod
网络(例如flannel)
Runtime。Node上运行的Kubernetes组件有kubelet、kube-proxy和Pod
网络(例如flannel)
kubelet
kubelet是Node的agent,当Scheduler确定在某个Node上运行Pod
后,会将Pod的具体配置信息(image、volume等)发送给该节点的
kubelet,kubelet根据这些信息创建和运行容器,并向Master报告运行
状态
后,会将Pod的具体配置信息(image、volume等)发送给该节点的
kubelet,kubelet根据这些信息创建和运行容器,并向Master报告运行
状态
kube-proxy
每个Node都会运行kube-proxy服务,它负责将访问service的
TCP/UPD数据流转发到后端的容器。如果有多个副本,kube-proxy会
实现负载均衡。
TCP/UPD数据流转发到后端的容器。如果有多个副本,kube-proxy会
实现负载均衡。
Pod网络
Pod要能够相互通信,Kubernetes Cluster必须部署Pod网络,
flannel是其中一个可选方案。
flannel是其中一个可选方案。
概念
Cluster是计算、存储和网络资源的集合,Kubernetes利用这些资
源运行各种基于容器的应用
源运行各种基于容器的应用
Controller
类型
Deployment
Deployment可以管理Pod的多个副
本,并确保Pod按照期望的状态运行
本,并确保Pod按照期望的状态运行
ReplicaSet
ReplicaSet实现了Pod的多副本管理。使用Deployment时会
自动创建ReplicaSet,也就是说Deployment是通过ReplicaSet来管理
Pod的多个副本的,我们通常不需要直接使用ReplicaSet。
自动创建ReplicaSet,也就是说Deployment是通过ReplicaSet来管理
Pod的多个副本的,我们通常不需要直接使用ReplicaSet。
DaemonSet
DaemonSet用于每个Node最多只运行一个Pod副本的场景。
正如其名称所揭示的,DaemonSet通常用于运行daemon
正如其名称所揭示的,DaemonSet通常用于运行daemon
StatefuleSet
StatefuleSet能够保证Pod的每个副本在整个生命周期中名称
是不变的,而其他Controller不提供这个功能。当某个Pod发生故障需
要删除并重新启动时,Pod的名称会发生变化,同时StatefuleSet会保
证副本按照固定的顺序启动、更新或者删除。
是不变的,而其他Controller不提供这个功能。当某个Pod发生故障需
要删除并重新启动时,Pod的名称会发生变化,同时StatefuleSet会保
证副本按照固定的顺序启动、更新或者删除。
Job
Job用于运行结束就删除的应用,而其他Controller中的Pod
通常是长期持续运行。
通常是长期持续运行。
概念
Kubernetes通常不会直接创建Pod,而是通过Controller来管理Pod
的。Controller中定义了Pod的部署特性,比如有几个副本、在什么样
的Node上运行等。为了满足不同的业务场景,Kubernetes提供了多种
Controller,包括Deployment、ReplicaSet、DaemonSet、StatefuleSet、
Job等
的。Controller中定义了Pod的部署特性,比如有几个副本、在什么样
的Node上运行等。为了满足不同的业务场景,Kubernetes提供了多种
Controller,包括Deployment、ReplicaSet、DaemonSet、StatefuleSet、
Job等
架构图
k8s arch
Flannel网络架构图
Kubernetes工作流程
总体架构图
1.kubectl get nodes --查看节点信息
2.kubectl cluster-info --查看集群信息
3.kubectl run kubernetes-bootcamp \
--image=docker.io/jocatalin/kubernetes-bootcamp:v1 \
--port=8080
部署一个应用kubernetes-bootcamp 镜像为docker.io/jocatalin/kubernetes-bootcamp:v1 端口为8080
4.kubectl get pods --查看当前pod
5.kubectl expose deployment/kubernetes-bootcamp \
--type="NodePort" \
--port 8080
把8080端口映射到节点的端口,因为pod 只能在集群内部访问,我们需要从外部访问应用
6.kubectl get services --查看应用被映射到节点的哪个端口
7.curl host01:32320 --访问指定节点端口对应的pod应用
8.kubectl get deployments --查看副本数
9.kubectl scale deployments/kubernetes-bootcamp --replicas=3 //将kubernetes-bootcamp的副本增加到3个
10.kubectl scale deployments/kubernetes-bootcamp --replicas=2 //将kubernetes-bootcamp的副本数减少到2个
11.kubectl set image deployments/kubernetes-bootcamp
kubernetes-bootcamp=jocatalin/kubernetes-bootcamp:v2 //将kubernetes-bootcamp 应用的版本升级到v2
12.kubectl rollout undo deployments/kubernetes-bootcamp //将kubernetes-bootcamp 应用版本回退到上个版本
13.kubectl get pods --all-namespaces -o wide #展示出IP和node信息
14.kubectl describe deployment kubernetes-bootcamp #展示deploy 详细信息
15.kubectl describe replicasets #命令可以打印出rs控制器的详细状态
16.kubectl describe pod kubernetes-bootcamp #展示pod 详细信息
17.kubectl delete deployment nginx-deployment #删除指定的资源
18.kubectl delete -f xxx.yaml #指定配置文件删除容器
19.kubectl taint node k8s-master node-role.kubernetes.io/master- #允许将master节点 当做node节点使用
20.kubectl taint node k8s-master node-role.kubernetes.io/master="" #禁止将master节点当做 node节点使用
21.kubectl label node k8s-node1 disktype=ssd #为node 指定label
22.kubectl get node --show-labels #查看节点的label
23.kubectl label node k8s-node1 disktype- 删除节点k8s-node1 上的label 名称disktype
24.kubectl get daemonset --namespace=kube-system #查看系统默认的deamonset组件
25.kubectl api-versions #查看apiserver 支持的版本
26.kubectl get pod --show-all #查看所有的pod
27.kubectl logs *** #查看pod的log信息
28.kubectl get jobs #查看所有的job
29.kubectl get cronjob #查看CronJob的状态
30.kubectl describe service httpd #获取服务详情
31.kubectl rollout history deployment httpd #查看revison历史记录
32.kubectl rollout undo deployment httpd --to-revision=1 #回退到指定的记录点
33.kubectl exec -it busybox sh #进入busyboxy 容器内部
34.kubectl exec podname touch /a/b #在容器内部创建文件
35.kubectl get revisions #获取快照
36.kubectl get configurations #获取配置信息
37.kubectl get configuration knative-helloworld -oyaml #获取指定配置信息的yaml格式显示
38.kubectl get ksvc 获取 knative service 服务
39.kubectl rollout status #查看 Deployment 对象的状态变化
40.kubectl get rs #
41.kubectl label nodes <node-name> <label-key>=<label-value> #给pod 打标签
2.kubectl cluster-info --查看集群信息
3.kubectl run kubernetes-bootcamp \
--image=docker.io/jocatalin/kubernetes-bootcamp:v1 \
--port=8080
部署一个应用kubernetes-bootcamp 镜像为docker.io/jocatalin/kubernetes-bootcamp:v1 端口为8080
4.kubectl get pods --查看当前pod
5.kubectl expose deployment/kubernetes-bootcamp \
--type="NodePort" \
--port 8080
把8080端口映射到节点的端口,因为pod 只能在集群内部访问,我们需要从外部访问应用
6.kubectl get services --查看应用被映射到节点的哪个端口
7.curl host01:32320 --访问指定节点端口对应的pod应用
8.kubectl get deployments --查看副本数
9.kubectl scale deployments/kubernetes-bootcamp --replicas=3 //将kubernetes-bootcamp的副本增加到3个
10.kubectl scale deployments/kubernetes-bootcamp --replicas=2 //将kubernetes-bootcamp的副本数减少到2个
11.kubectl set image deployments/kubernetes-bootcamp
kubernetes-bootcamp=jocatalin/kubernetes-bootcamp:v2 //将kubernetes-bootcamp 应用的版本升级到v2
12.kubectl rollout undo deployments/kubernetes-bootcamp //将kubernetes-bootcamp 应用版本回退到上个版本
13.kubectl get pods --all-namespaces -o wide #展示出IP和node信息
14.kubectl describe deployment kubernetes-bootcamp #展示deploy 详细信息
15.kubectl describe replicasets #命令可以打印出rs控制器的详细状态
16.kubectl describe pod kubernetes-bootcamp #展示pod 详细信息
17.kubectl delete deployment nginx-deployment #删除指定的资源
18.kubectl delete -f xxx.yaml #指定配置文件删除容器
19.kubectl taint node k8s-master node-role.kubernetes.io/master- #允许将master节点 当做node节点使用
20.kubectl taint node k8s-master node-role.kubernetes.io/master="" #禁止将master节点当做 node节点使用
21.kubectl label node k8s-node1 disktype=ssd #为node 指定label
22.kubectl get node --show-labels #查看节点的label
23.kubectl label node k8s-node1 disktype- 删除节点k8s-node1 上的label 名称disktype
24.kubectl get daemonset --namespace=kube-system #查看系统默认的deamonset组件
25.kubectl api-versions #查看apiserver 支持的版本
26.kubectl get pod --show-all #查看所有的pod
27.kubectl logs *** #查看pod的log信息
28.kubectl get jobs #查看所有的job
29.kubectl get cronjob #查看CronJob的状态
30.kubectl describe service httpd #获取服务详情
31.kubectl rollout history deployment httpd #查看revison历史记录
32.kubectl rollout undo deployment httpd --to-revision=1 #回退到指定的记录点
33.kubectl exec -it busybox sh #进入busyboxy 容器内部
34.kubectl exec podname touch /a/b #在容器内部创建文件
35.kubectl get revisions #获取快照
36.kubectl get configurations #获取配置信息
37.kubectl get configuration knative-helloworld -oyaml #获取指定配置信息的yaml格式显示
38.kubectl get ksvc 获取 knative service 服务
39.kubectl rollout status #查看 Deployment 对象的状态变化
40.kubectl get rs #
41.kubectl label nodes <node-name> <label-key>=<label-value> #给pod 打标签
Pod
引入POD的原因
可管理性
通信和资源共享
二种使用方式
运行单一容器。
运行多个容器
概念
Pod是Kubernetes的最小工作单元。每个Pod包含一个或多个容
器。Pod中的容器会作为一个整体被Master调度到一个Node上运行
器。Pod中的容器会作为一个整体被Master调度到一个Node上运行
Node
概念
Node的职责是运行容器应用。Node由Master管理,Node负责监
控并汇报容器的状态,同时根据Master的要求管理容器的生命周期。
Node运行在Linux操作系统上,可以是物理机或者是虚拟机
控并汇报容器的状态,同时根据Master的要求管理容器的生命周期。
Node运行在Linux操作系统上,可以是物理机或者是虚拟机
service
概念
Service定义了外界访问一组特定Pod的方式。Service
有自己的IP和端口,Service为Pod提供了负载均衡。
有自己的IP和端口,Service为Pod提供了负载均衡。
Namespace
默认namespace
default:创建资源时如果不指定,将被放到这个Namespace中。
kube-system:Kubernetes自己创建的系统资源将放到这个
Namespace中。
kube-system:Kubernetes自己创建的系统资源将放到这个
Namespace中。
概念
Namespace可以将一个物理的Cluster逻辑上划分成多个虚拟
Cluster,每个Cluster就是一个Namespace。不同Namespace里的资源是
完全隔离的。
Cluster,每个Cluster就是一个Namespace。不同Namespace里的资源是
完全隔离的。
运行容器
kubectl run httpd-app --image=httpd --replicas=2 这条命令经过哪些流程处理?
① kubectl发送部署请求到API Server。
② API Server通知Controller Manager创建一个deployment资源。
③ Scheduler执行调度任务,将两个副本Pod分发到k8s-node1和
k8s-node2。
④ k8s-node1和k8s-node2上的kubectl在各自的节点上创建并运行
Pod。
② API Server通知Controller Manager创建一个deployment资源。
③ Scheduler执行调度任务,将两个副本Pod分发到k8s-node1和
k8s-node2。
④ k8s-node1和k8s-node2上的kubectl在各自的节点上创建并运行
Pod。
用户通过kubectl
(1)创建Deployment。
(2)Deployment创建ReplicaSet。
(3)ReplicaSet创建Pod。
(4)对象的命名方式是“子对象的名字=父对象
名字+随机字符串或数字”
(1)创建Deployment。
(2)Deployment创建ReplicaSet。
(3)ReplicaSet创建Pod。
(4)对象的命名方式是“子对象的名字=父对象
名字+随机字符串或数字”
kubectl apply -f xxx.yaml 声明pod
① apiVersion是当前配置格式的版本。
② kind是要创建的资源类型,这里是Deployment。
③ metadata是该资源的元数据,name是必需的元数据项。
④ spec部分是该Deployment的规格说明。
⑤ replicas指明副本数量,默认为1。
⑥ template定义Pod的模板,这是配置文件的重要部分。
⑦ metadata定义Pod的元数据,至少要定义一个label。label的key
和value可以任意指定。
⑧ spec描述Pod的规格,此部分定义Pod中每一个容器的属性,
name和image是必需的。
② kind是要创建的资源类型,这里是Deployment。
③ metadata是该资源的元数据,name是必需的元数据项。
④ spec部分是该Deployment的规格说明。
⑤ replicas指明副本数量,默认为1。
⑥ template定义Pod的模板,这是配置文件的重要部分。
⑦ metadata定义Pod的元数据,至少要定义一个label。label的key
和value可以任意指定。
⑧ spec描述Pod的规格,此部分定义Pod中每一个容器的属性,
name和image是必需的。
Failover
设 master ,node1,node2 共3个节点 ,
当前共运行5个pod,node1 运行3个pod,node2 运行2个pod,
此时node2 突然宕机,此时会发生什么?
1.k8s 会监测到node2 不可用,将node2上的pod 标记为unknow 状态
2.k8s 会在node1 上创建2个pod 维持总得pod数在 5个
3.当node2 恢复后 标记为unknow的pod 会被删除
当前共运行5个pod,node1 运行3个pod,node2 运行2个pod,
此时node2 突然宕机,此时会发生什么?
1.k8s 会监测到node2 不可用,将node2上的pod 标记为unknow 状态
2.k8s 会在node1 上创建2个pod 维持总得pod数在 5个
3.当node2 恢复后 标记为unknow的pod 会被删除
label
kubectl label node k8s-node1 disktype=ssd 为node k8s-node1 声明label 名称disktype
kubectl get node --show-labels 查看node上的label
kubectl label node k8s-node1 disktype -
删除node k8s-node1上的label disktype
Pod并不会重新部署,依然在k8s-node1上运行
删除node k8s-node1上的label disktype
Pod并不会重新部署,依然在k8s-node1上运行
如何使用label,声明pod 的文件里指定nodeSelector
controller
Deployment部署的副本Pod会分布在各个Node上,每个Node都可
能运行好几个副本
能运行好几个副本
几种状态
DESIRED
表示期望的状态是n个READY的副本
CURRENT
表示当前副本的总数
UP-TO-DATE
表示当前已经完成更新的副本数
AVAILABLE
表示当前处于READY状态的副本数
DaemonSet的不同之处在于:每个Node上最多只
能运行一个副本。
能运行一个副本。
应用场景
在集群的每个节点上运行存储Daemon,比如glusterd或
ceph
ceph
在每个节点上运行日志收集Daemon,比如flunentd或
logstash。
logstash。
在每个节点上运行监控Daemon,比如Prometheus Node
Exporter或collectd
Exporter或collectd
系统默认运行的deamonset
kube-flannel-ds
kube-proxy
job
普通job
定时job
并行性
parallelism同时运行多少pod
completionsJob成功完成Pod的总数
pod
重新启动策略
Never
此失败容器不会被重启
OnFailure
此失败容器会被重启
Pod的IP是在容器
中配置
中配置
状态
CrashLoopBackOff: 容器退出,kubelet正在将它重启
InvalidImageName: 无法解析镜像名称
ImageInspectError: 无法校验镜像
ErrImageNeverPull: 策略禁止拉取镜像
ImagePullBackOff: 正在重试拉取
RegistryUnavailable: 连接不到镜像中心
ErrImagePull: 通用的拉取镜像出错
CreateContainerConfigError: 不能创建kubelet使用的容器配置
CreateContainerError: 创建容器失败
m.internalLifecycle.PreStartContainer 执行hook报错
RunContainerError: 启动容器失败
PostStartHookError: 执行hook报错
ContainersNotInitialized: 容器没有初始化完毕
ContainersNotReady: 容器没有准备完毕
ContainerCreating:容器创建中
PodInitializing:pod 初始化中
DockerDaemonNotReady:docker还没有完全启动
NetworkPluginNotReady: 网络插件还没有完全启动
InvalidImageName: 无法解析镜像名称
ImageInspectError: 无法校验镜像
ErrImageNeverPull: 策略禁止拉取镜像
ImagePullBackOff: 正在重试拉取
RegistryUnavailable: 连接不到镜像中心
ErrImagePull: 通用的拉取镜像出错
CreateContainerConfigError: 不能创建kubelet使用的容器配置
CreateContainerError: 创建容器失败
m.internalLifecycle.PreStartContainer 执行hook报错
RunContainerError: 启动容器失败
PostStartHookError: 执行hook报错
ContainersNotInitialized: 容器没有初始化完毕
ContainersNotReady: 容器没有准备完毕
ContainerCreating:容器创建中
PodInitializing:pod 初始化中
DockerDaemonNotReady:docker还没有完全启动
NetworkPluginNotReady: 网络插件还没有完全启动
镜像拉取方式
Always
总是拉取 pull
IfNotPresent
默认值,本地有则使用本地镜像,不拉取
Never
只使用本地镜像,从不拉取
Service
概念
Service从逻辑上代表了一组Pod,具体是哪些Pod则是
由label来挑选的。Service有自己的IP,而且这个IP是不变的。客户端
只需要访问Service的IP,Kubernetes则负责建立和维护Service与Pod的
映射关系。无论后端Pod如何变化,对客户端不会有任何影响,因为
Service没有变
由label来挑选的。Service有自己的IP,而且这个IP是不变的。客户端
只需要访问Service的IP,Kubernetes则负责建立和维护Service与Pod的
映射关系。无论后端Pod如何变化,对客户端不会有任何影响,因为
Service没有变
创建Service
新建deployment
新建service
① v1是Service的apiVersion。
② 指明当前资源的类型为Service。
③ Service的名字为httpd-svc。
④ selector指明挑选那些label为run: httpd的Pod作为Service的后 端。
⑤ 将Service的8080端口映射到Pod的80端口,使用TCP协议。
② 指明当前资源的类型为Service。
③ Service的名字为httpd-svc。
④ selector指明挑选那些label为run: httpd的Pod作为Service的后 端。
⑤ 将Service的8080端口映射到Pod的80端口,使用TCP协议。
查看service命令
kubectl get service #获取service列表
kubectl describe service service_name #获取服务详情
Service ClusterIp
Cluster IP是一个虚拟IP
由Kubernetes节点上的iptables规则管
理
理
通过Cluster IP 连接绑定的pod
iptables将访问Service的流量转发到后端Pod
使用类似
轮询的负载均衡策略
轮询的负载均衡策略
Cluster的每一个节点都配置了相同的
iptables规则确保了整个Cluster都能够通过Service的Cluster IP
访问Service
iptables规则确保了整个Cluster都能够通过Service的Cluster IP
访问Service
流程图
外网如何访问Service
声明要暴露server 到外网
-A KUBE-NODEPORTS -p tcp -m comment --comment "default/httpd-svc:" -m tcp --dport 31254 -j KUBE-MARK-MASQ
-A KUBE-NODEPORTS -p tcp -m comment --comment "default/httpd-svc:" -m tcp --dport 31254 -j KUBE-SVC-RL3JAE4GN7VOGDGP
每个节点新增两个iptables 规则
-A KUBE-NODEPORTS -p tcp -m comment --comment "default/httpd-svc:" -m tcp --dport 31254 -j KUBE-SVC-RL3JAE4GN7VOGDGP
每个节点新增两个iptables 规则
EXTERNAL-IP为nodes,表示可通过Cluster每个节点自身
的IP访问Service。
PORT(S)为8080:32312。8080是ClusterIP监听的端口,
32312则是节点上监听的端口。Kubernetes会从30000~32767中分配一
个可用的端口,每个节点都会监听此端口并将请求转发给Service
的IP访问Service。
PORT(S)为8080:32312。8080是ClusterIP监听的端口,
32312则是节点上监听的端口。Kubernetes会从30000~32767中分配一
个可用的端口,每个节点都会监听此端口并将请求转发给Service
自定义暴露node端口
nodePort在node上,负责对外通信,NodeIP:NodePort
port在service上,负责处理对内的通信,clusterIP:port
targetPort 负责与kube-proxy代理的port和Nodeport数据进行通信
containerPort 在容器上,用于被pod绑定
nodePort在node上,负责对外通信,NodeIP:NodePort
port在service上,负责处理对内的通信,clusterIP:port
targetPort 负责与kube-proxy代理的port和Nodeport数据进行通信
containerPort 在容器上,用于被pod绑定
Rolling Update
滚动更新
滚动更新
概念
滚动更新是一次只更新一小部分副本,成功后再更新更多的副
本,最终完成所有副本的更新
本,最终完成所有副本的更新
特点
1.滚动更新的最大好处是零停机,整个
更新过程始终有副本在运行,从而保证了业务的连续性。
2.每次更新应用时,Kubernetes都会记录下当前的配
置,保存为一个revision(版次),这样就可以回滚到某个特定
revision
更新过程始终有副本在运行,从而保证了业务的连续性。
2.每次更新应用时,Kubernetes都会记录下当前的配
置,保存为一个revision(版次),这样就可以回滚到某个特定
revision
例子
把nginx:1.7.8升级到nginx:1.7.9
创建nginx.yaml
执行kubectl apply -f nginx.yaml
nginx.ynginx:1.7.8 的deployment
执行kubectl apply -f nginx.yaml
nginx.ynginx:1.7.8 的deployment
详细步骤
(1)创建Deployment nginx。
(2)创建ReplicaSet nginx-1728888140。
(3)创建三个Pod。
(4)当前镜像为httpd:1.7.8。
(1)创建Deployment nginx。
(2)创建ReplicaSet nginx-1728888140。
(3)创建三个Pod。
(4)当前镜像为httpd:1.7.8。
修改yaml 中nginx image 版本为1.7.9
重新执行kubectl apply -f nginx.yaml
重新执行kubectl apply -f nginx.yaml
详细步骤
(1)Deployment httpd的镜像更新为nginx:1.7.8。
(2)新创建了ReplicaSet nginx-1810152781,
镜像为 nginx:1.7.9,并且管理了三个新的Pod。
(3)之前的ReplicaSet nginx-1728888140里面已经没有任何Pod。
具体过程可以通过kubectl describe deployment nginx
(1)Deployment httpd的镜像更新为nginx:1.7.8。
(2)新创建了ReplicaSet nginx-1810152781,
镜像为 nginx:1.7.9,并且管理了三个新的Pod。
(3)之前的ReplicaSet nginx-1728888140里面已经没有任何Pod。
具体过程可以通过kubectl describe deployment nginx
回退
kubectl rollout
history deployment nginx #查看版本记录
history deployment nginx #查看版本记录
kubectl apply -f nginx.1.7.8.yaml --record
--record的作用是将当前命令记录到revision记录
--record的作用是将当前命令记录到revision记录
kubectl rollout undo deployment nginx --to-revision=2
#--to-revision 回退到指定的记录点
#--to-revision 回退到指定的记录点
参数
maxSurge
此参数控制滚动更新过程中副本总数超过DESIRED的上限
可以是具体的整数(比如3),也可以是百分百,向上取
整
整
默认值为25%
设DESIRED为10,那么副本总数的最大值为
roundUp(10 + 10 * 25%) =13,所以我们看到CURRENT就是13
roundUp(10 + 10 * 25%) =13,所以我们看到CURRENT就是13
maxSurge值越大,初始创建的新副本数量就越多
maxUnavailable
此参数控制滚动更新过程中,不可用的副本相占DESIRED的最
大比例
大比例
maxUnavailable可以是具体的整数(比如3),也可以是百分
百,向下取整
百,向下取整
maxUnavailable默认值为25%
设DESIRED为10,那么可用的副本数至少要为
10 - roundDown(10 * 25%)= 8,所以我们看到AVAILABLE是8
10 - roundDown(10 * 25%)= 8,所以我们看到AVAILABLE是8
maxUnavailable值越大,初始销毁的旧副本数量就越多
更新案例
设副本数10 maxSurge和maxUnavailable都取默认值则启动流程如下:
(1)创建3个新副本使副本总数达到13个。
(2)销毁2个旧副本使可用的副本数降到8个。
(3)当2个旧副本成功销毁后,再创建2个新副本,使副本总数
保持为13个。
(4)当新副本通过Readiness探测后,会使可用副本数
增加,超过8。
113
(5)进而可以继续销毁更多的旧副本,使可用副本数回到8。
(6)旧副本的销毁使副本总数低于13,这样就允许创建更多的
新副本。
(7)这个过程会持续进行,最终所有的旧副本都会被新副本替
换,滚动更新完成。
(1)创建3个新副本使副本总数达到13个。
(2)销毁2个旧副本使可用的副本数降到8个。
(3)当2个旧副本成功销毁后,再创建2个新副本,使副本总数
保持为13个。
(4)当新副本通过Readiness探测后,会使可用副本数
增加,超过8。
113
(5)进而可以继续销毁更多的旧副本,使可用副本数回到8。
(6)旧副本的销毁使副本总数低于13,这样就允许创建更多的
新副本。
(7)这个过程会持续进行,最终所有的旧副本都会被新副本替
换,滚动更新完成。
Health Check
默认
每个容器启动时
都会执行一个进程,此进程由Dockerfile的CMD或ENTRYPOINT指
定。如果进程退出时返回码非零,则认为容器发生故障,Kubernetes
就会根据restartPolicy重启容器。restartPolicy默认的启动策略是AlWays
都会执行一个进程,此进程由Dockerfile的CMD或ENTRYPOINT指
定。如果进程退出时返回码非零,则认为容器发生故障,Kubernetes
就会根据restartPolicy重启容器。restartPolicy默认的启动策略是AlWays
Liveness
使用场景
类似500 或者其他用户自定义的检查
使用方法
在创建的pod声明文件中增加以下
livenessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 5#指定容器启动5秒之后执行健康检查
periodSeconds: 5 #指定每5秒执行一次Liveness探测
livenessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 5#指定容器启动5秒之后执行健康检查
periodSeconds: 5 #指定每5秒执行一次Liveness探测
概念
Liveness探测让用户可以自定义判断容器是否健康的条件。如果
探测失败,Kubernetes就会重启容器
探测失败,Kubernetes就会重启容器
Readiness
概念
Readiness探测则是告诉Kubernetes什么时候可以将容器
加入到Service负载均衡池中,对外提供服务,探测到服务异常不重启,
需要配合liveness 使用
加入到Service负载均衡池中,对外提供服务,探测到服务异常不重启,
需要配合liveness 使用
使用方法
在创建的pod声明文件中增加以下
readinessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 5
periodSeconds: 5
readinessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 5
periodSeconds: 5
使用场景
需要检查此服务是否可以对外提供服务,
探测到服务异常后把此服务冲负载均衡池中摘除
探测到服务异常后把此服务冲负载均衡池中摘除
Liveness VS Readiness
Liveness探测和Readiness探测是两种Health Check机制,如
果不特意配置,Kubernetes将对两种探测采取相同的默认行为,即通
过判断容器启动进程的返回值是否为零来判断探测是否成功
果不特意配置,Kubernetes将对两种探测采取相同的默认行为,即通
过判断容器启动进程的返回值是否为零来判断探测是否成功
两种探测的配置方法完全一样,支持的配置参数也一样。
不同之处在于探测失败后的行为:Liveness探测是重启容器;
Readiness探测则是将容器设置为不可用,不接收Service转发的请求。
不同之处在于探测失败后的行为:Liveness探测是重启容器;
Readiness探测则是将容器设置为不可用,不接收Service转发的请求。
Liveness探测和Readiness探测是独立执行的,二者之间没
有依赖,所以可以单独使用,也可以同时使用。用Liveness探测判断
容器是否需要重启以实现自愈;用Readiness探测判断容器是否已经准
备好对外提供服务。
有依赖,所以可以单独使用,也可以同时使用。用Liveness探测判断
容器是否需要重启以实现自愈;用Readiness探测判断容器是否已经准
备好对外提供服务。
Readiness实例
1)容器启动10秒之后开始探测。
(2)如果http://[container_ip]:8080/healthy返回代码不是200~
400,表示容器没有就绪,不接收Service web-svc的请求。
(3)每隔5秒探测一次。
(4)直到返回代码为200~400,表明容器已经就绪,然后将其
加入到web-svc的负载均衡中,开始处理客户请求。
(5)探测会继续以5秒的间隔执行,如果连续发生3次失败,容
器又会从负载均衡中移除,直到下次探测成功重新加入。
(2)如果http://[container_ip]:8080/healthy返回代码不是200~
400,表示容器没有就绪,不接收Service web-svc的请求。
(3)每隔5秒探测一次。
(4)直到返回代码为200~400,表明容器已经就绪,然后将其
加入到web-svc的负载均衡中,开始处理客户请求。
(5)探测会继续以5秒的间隔执行,如果连续发生3次失败,容
器又会从负载均衡中移除,直到下次探测成功重新加入。
数据管理
作用
为集群
中的容器提供存储
中的容器提供存储
生命周期
独立于容器,Pod中的容器可能被销毁和重
建,但Volume会被保留
建,但Volume会被保留
概念
Volume是一个目录
特点
当Volume被mount到Pod,Pod中的所有容器都可以访
问这个Volume
问这个Volume
Pod中的所有容器都可以共享Volume,它们可以指定各自的
mount路径
mount路径
静态供给
emptyDir
概念
一个
emptyDir Volume是Host上的一个空目录
emptyDir Volume是Host上的一个空目录
特点
emptyDir Volume对于容器来说是持久的,对于Pod则不是。当
Pod从节点删除时,Volume的内容也会被删除。但如果只是容器被销
毁而Pod还在,则Volume不受影响。
Pod从节点删除时,Volume的内容也会被删除。但如果只是容器被销
毁而Pod还在,则Volume不受影响。
其优点是能够方便地为Pod
中的容器提供共享存储,不需要额外的配置。它不具备持久性,如果
Pod不存在了,emptyDir也就没有了
中的容器提供共享存储,不需要额外的配置。它不具备持久性,如果
Pod不存在了,emptyDir也就没有了
生命周期
emptyDir Volume的生命周期与Pod一致
使用场景
emptyDir特别
适合Pod中的容器需要临时共享存储空间的场景
适合Pod中的容器需要临时共享存储空间的场景
hostPath
特点
如果Pod被销毁了,hostPath对应的目录还是会被保留,从这一点
来看,hostPath的持久性比emptyDir强。不过一旦Host崩溃,hostPath
也就无法访问了
来看,hostPath的持久性比emptyDir强。不过一旦Host崩溃,hostPath
也就无法访问了
概念
hostPath Volume的作用是将Docker Host文件系统中已经存在的目
录mount给Pod的容器大部分应用都不会使用hostPath Volume,
因为
这实际上增加了Pod与节点的耦合,限制了Pod的使用
录mount给Pod的容器大部分应用都不会使用hostPath Volume,
因为
这实际上增加了Pod与节点的耦合,限制了Pod的使用
使用场景
需
要访问Kubernetes或Docker内部数据(配置文件和二进制库)的应用
则需要使用hostPath
要访问Kubernetes或Docker内部数据(配置文件和二进制库)的应用
则需要使用hostPath
定义了三个hostPath:volume k8s、certs和pki,分别对应
Host目录/etc/kubernetes、/etc/ssl/certs和/etc/pki
Host目录/etc/kubernetes、/etc/ssl/certs和/etc/pki
Storage Provider
Ceph
Ceph文件系统的/some/path/in/side/cephfs目录被mount到容器路
径/test-ceph。
径/test-ceph。
特点
相对于emptyDir和hostPath,这些Volume类型的最大特点就是不
依赖Kubernetes
依赖Kubernetes
Volume的底层基础设施由独立的存储系统管理,与
Kubernetes集群是分离的。数据被持久化后,即使整个Kubernetes崩
溃也不会受损。
Kubernetes集群是分离的。数据被持久化后,即使整个Kubernetes崩
溃也不会受损。
(1)当前Volume来自AWS EBS。
(2)EBS Volume已经提前创建,并且知道确切的volume-id
(2)EBS Volume已经提前创建,并且知道确切的volume-id
Pod通常是由应用的开发人员维护,而Volume则通常是由存储系
统的管理员维护。开发人员要获得上面的信息,要么询问管理员,要
么自己就是管理员
统的管理员维护。开发人员要获得上面的信息,要么询问管理员,要
么自己就是管理员
GlusterFS
GCE
AWS Elastic Block Store
PersistentVolume
类型
AWS EBS
Ceph
NFS
使用方法
在k8s master节点搭建nfs服务器
创建PersistentVolume yaml文件
① capacity指定PV的容量为1GB。
② accessModes指定访问模式为ReadWriteOnce,支持的访问模式
有3种:ReadWriteOnce表示PV能以read-write模式mount到单个节点,
ReadOnlyMany表示PV能以read-only模式mount到多个节点,
ReadWriteMany表示PV能以read-write模式mount到多个节点。
③ persistentVolumeReclaimPolicy指定当PV的回收策略为
Recycle,支持的策略有3种:Retain表示需要管理员手工回收;
Recycle表示清除PV中的数据,效果相当于执行rm -rf/thevolume/*;
Delete表示删除Storage Provider上的对应存储资源,例如AWS EBS、
GCE PD、Azure Disk、OpenStack Cinder Volume等。
④ storageClassName指定PV的class为nfs。相当于为PV设置了一
个分类,PVC可以指定class申请相应class的PV。
⑤ 指定PV在NFS服务器上对应的目录。
② accessModes指定访问模式为ReadWriteOnce,支持的访问模式
有3种:ReadWriteOnce表示PV能以read-write模式mount到单个节点,
ReadOnlyMany表示PV能以read-only模式mount到多个节点,
ReadWriteMany表示PV能以read-write模式mount到多个节点。
③ persistentVolumeReclaimPolicy指定当PV的回收策略为
Recycle,支持的策略有3种:Retain表示需要管理员手工回收;
Recycle表示清除PV中的数据,效果相当于执行rm -rf/thevolume/*;
Delete表示删除Storage Provider上的对应存储资源,例如AWS EBS、
GCE PD、Azure Disk、OpenStack Cinder Volume等。
④ storageClassName指定PV的class为nfs。相当于为PV设置了一
个分类,PVC可以指定class申请相应class的PV。
⑤ 指定PV在NFS服务器上对应的目录。
创建PersistentVolumeClaim yaml
指定PersistentVolume
指定PersistentVolume
指定PV的容量、访问模式和class即
可。
可。
创建pod 指定PersistentVolumeClaim
指定PVC 使用
不支持Delete 回收策略
概念
简称(PV)外部存储系统中的一块存储空间,由
管理员创建和维护
管理员创建和维护
特点
与Volume一样,PV具有持久性,生命周期独立
于Pod。
于Pod。
回收策略
Retain
表示需要管理员手工回收
Recycle
表示清除PV中的数据,效果相当于执行rm -rf/thevolume/*
Delete
表示删除Storage Provider上的对应存储资源
PersistentVolumeClaim
概念
简称(PVC)是对PV的申请PVC
通常由普通用户创建和维护需要为Pod分配存储资源时,
用户可以
创建一个PVC,指明存储资源的容量大小和访问模式(比如只读)等
信息,
Kubernetes会查找并提供满足条件的PV
通常由普通用户创建和维护需要为Pod分配存储资源时,
用户可以
创建一个PVC,指明存储资源的容量大小和访问模式(比如只读)等
信息,
Kubernetes会查找并提供满足条件的PV
特点
用户只需要告诉Kubernetes需要什
么样的存储资源,而不必关心真正的空间从哪里分配、如何访问等底
层细节信息。这些Storage Provider的底层信息交给管理员来处理,只
有管理员才应该关心创建PersistentVolume的细节信息。
么样的存储资源,而不必关心真正的空间从哪里分配、如何访问等底
层细节信息。这些Storage Provider的底层信息交给管理员来处理,只
有管理员才应该关心创建PersistentVolume的细节信息。
删除persistentVolumeClaim
命令kubectl delete pvc pvcname
Kubernetes启动了一个新Pod
Pod的名称为recycler-for-pvcname
Pod的名称为recycler-for-pvcname
此时与该pvc 绑定的pv 状态变成released表示已经解除了与pvc的绑定,
正在清除数据,清楚完成后状态重新变为Available,可以重新申请pvc绑定到pv上
正在清除数据,清楚完成后状态重新变为Available,可以重新申请pvc绑定到pv上
动态供给
概念
如果没有满
足PVC条件的PV,会动态创建PV
足PVC条件的PV,会动态创建PV
特点
动态供给有明显
的优势:不需要提前创建PV,减少了管理员的工作量,效率高
的优势:不需要提前创建PV,减少了管理员的工作量,效率高
遇到的问题
在数据卷阶段删除pvc 后pv的状态变成released 无法自动恢复到aviable 状态。
如果pv的回收策略是recycle 则会启动一个新的pod 这个pod需要到google下载
镜像,需要通过命令 kubectl describe pod podname 查看下载的image 名称
到hub.docker.com 找到相关镜像重新打包成 gcr/io 开头的镜像
如果pv的回收策略是recycle 则会启动一个新的pod 这个pod需要到google下载
镜像,需要通过命令 kubectl describe pod podname 查看下载的image 名称
到hub.docker.com 找到相关镜像重新打包成 gcr/io 开头的镜像
在集成nfs 网络文件的时候,在pv声明文件中配置映射到nfs 公共目录的地方需要注意目录的权限问题
Secret
概念
Secret会以密文的方式存储数据,避免了直接在配置文件中保存
敏感信息Secret会以Volume的形式被mount到Pod,容器可通过文件
的方式使用Secret中的敏感数据;此外,容器也可以环境变量的方式
使用这些数据
敏感信息Secret会以Volume的形式被mount到Pod,容器可通过文件
的方式使用Secret中的敏感数据;此外,容器也可以环境变量的方式
使用这些数据
创建方式
kubectl create secret generic mysecret --from-literal=username=admin
echo -n admin > ./username
echo -n 123456 > ./password
kubectl create secret generic mysecret --from-file=./username
echo -n 123456 > ./password
kubectl create secret generic mysecret --from-file=./username
cat << EOF > env.txt
username=admin
password=123456
EOF
kubectl create secret generic mysecret --from-env-file=env.txt
username=admin
password=123456
EOF
kubectl create secret generic mysecret --from-env-file=env.txt
kubectl apply -f mysecret.yaml
数据编码
echo -n admin | base64
数据解码
echo -n MTIzNDU2 | base64 --decode
查看value
kubectl edit secret mysecret
查看条目key
kubectl describe secret mysecret
在Pod中使用Secret
volume 方式
环境变量形式
环境变量读取Secret很方便,但无法支撑Secret动
态更新
态更新
ConfigMap
概念
ConfigMap的创建和使用方式与Secret非常类似,主要的不同是
数据以明文的形式存放
数据以明文的形式存放
创建方式
kubectl create configmap myconfigmap --from-literal=config1
echo -n xxx > ./config1
echo -n yyy > ./config2
kubectl create configmap myconfigmap --from-file=./config1
echo -n yyy > ./config2
kubectl create configmap myconfigmap --from-file=./config1
cat << EOF > env.txt
config1=xxx
config2=yyy
EOF
kubectl create configmap myconfigmap --from-env-file=env.txt
config1=xxx
config2=yyy
EOF
kubectl create configmap myconfigmap --from-env-file=env.txt
kubectl apply -f myconfig.yaml
Helm
概念
Kubernetes的包管理器从零创建新chart。
与存储chart的仓库交互,拉取、保存和更新chart。
在Kubernetes集群中安装和卸载release。
更新、回滚和测试release。
与存储chart的仓库交互,拉取、保存和更新chart。
在Kubernetes集群中安装和卸载release。
更新、回滚和测试release。
chart
chart是创建一个应用的信息集合,包括各种Kubernetes对象的
配置模板、参数定义、依赖关系、文档说明等。chart是应用部
署的自包含逻辑单元。可以将chart想象成apt、yum中的软件安
装包。
配置模板、参数定义、依赖关系、文档说明等。chart是应用部
署的自包含逻辑单元。可以将chart想象成apt、yum中的软件安
装包。
release
release是chart的运行实例,代表了一个正在运行的应用。当
chart被安装到Kubernetes集群,就生成一个release。chart能
够多次安装到同一个集群,每次安装都是一个release。
chart被安装到Kubernetes集群,就生成一个release。chart能
够多次安装到同一个集群,每次安装都是一个release。
未使用前有哪些问题
(1)传统服务区很难管理、编辑和维护如此多的服务。每个服务都有若干
配置,缺乏一个更高层次的工具将这些配置组织起来。
(2)不容易将这些服务作为一个整体统一发布。部署人员需要
首先理解应用都包含哪些服务,然后按照逻辑顺序依次执行kubectl
apply,即缺少一种工具来定义应用与服务,以及服务与服务之间的
依赖关系。
(3)不能高效地共享和重用服务。比如两个应用都要用到
MySQL服务,但配置的参数不一样,这两个应用只能分别复制一套
标准的MySQL配置文件,修改后通过kubectl apply部署。也就是说,
不支持参数化配置和多环境部署。
(4)不支持应用级别的版本管理。虽然可以通过kubectl rollout
undo进行回滚,但这只能针对单个Deployment,不支持整个应用的回
滚。
(5)不支持对部署的应用状态进行验证。比如是否能通过预定
义的账号访问MySQL。虽然Kubernetes有健康检查,但那是针对单个
容器,我们需要应用(服务)级别的健康检查。
配置,缺乏一个更高层次的工具将这些配置组织起来。
(2)不容易将这些服务作为一个整体统一发布。部署人员需要
首先理解应用都包含哪些服务,然后按照逻辑顺序依次执行kubectl
apply,即缺少一种工具来定义应用与服务,以及服务与服务之间的
依赖关系。
(3)不能高效地共享和重用服务。比如两个应用都要用到
MySQL服务,但配置的参数不一样,这两个应用只能分别复制一套
标准的MySQL配置文件,修改后通过kubectl apply部署。也就是说,
不支持参数化配置和多环境部署。
(4)不支持应用级别的版本管理。虽然可以通过kubectl rollout
undo进行回滚,但这只能针对单个Deployment,不支持整个应用的回
滚。
(5)不支持对部署的应用状态进行验证。比如是否能通过预定
义的账号访问MySQL。虽然Kubernetes有健康检查,但那是针对单个
容器,我们需要应用(服务)级别的健康检查。
组件
Helm客户端
在本地开发chart。
管理chart仓库。
与Tiller服务器交互。
在远程Kubernetes集群上安装chart。
查看release信息。
升级或卸载已有的release。
管理chart仓库。
与Tiller服务器交互。
在远程Kubernetes集群上安装chart。
查看release信息。
升级或卸载已有的release。
管理chart
Tiller服务器
监听来自Helm客户端的请求。
通过chart构建release。
在Kubernetes中安装chart,并跟踪release的状态。
通过API Server升级或卸载已有的release
通过chart构建release。
在Kubernetes中安装chart,并跟踪release的状态。
通过API Server升级或卸载已有的release
管理
release
release
会启动 deployment service pod 想逛组件
命令
helm search #会显示chart位于哪个仓库
helm repo add#添加更多的仓库
helm install stable/mysql #安装远程mysql
① chart本次部署的描述信息。
NAME是release的名字,因为我们没用-n参数指定,所以Helm随
机生成了一个,这里是fun-zorse。
NAMESPACE是release部署的namespace,默认是default,也可以
通过--namespace指定。
STATUS为DEPLOYED,表示已经将chart部署到集群。
② 当前release包含的资源:Service、Deployment、Secret和
PersistentVolumeClaim,其名字都是fun-zorse-mysql,命名的格式为
ReleasName-ChartName。
③ NOTES部分显示的是release的使用方法,比如如何访问
Service、如何获取数据库密码以及如何连接数据库等。
NAME是release的名字,因为我们没用-n参数指定,所以Helm随
机生成了一个,这里是fun-zorse。
NAMESPACE是release部署的namespace,默认是default,也可以
通过--namespace指定。
STATUS为DEPLOYED,表示已经将chart部署到集群。
② 当前release包含的资源:Service、Deployment、Secret和
PersistentVolumeClaim,其名字都是fun-zorse-mysql,命名的格式为
ReleasName-ChartName。
③ NOTES部分显示的是release的使用方法,比如如何访问
Service、如何获取数据库密码以及如何连接数据库等。
如何查看安装过后的chart 文件
安装过后 会在以下目录生成归档文件
~/.helm/cache/archive中找到chart的tar包
~/.helm/cache/archive中找到chart的tar包
解压归档文件
Chart.yaml
描述chart的概要信息
values.yaml
chart支持在安装时根据参数进行定制化配置,而values.yaml则提
供了这些配置参数的默认值
供了这些配置参数的默认值
templates目录
各类Kubernetes资源的配置模板都放置在这里
Helm会将
values.yaml中的参数值注入模板中,生成标准的YAML配置文件
Helm会将
values.yaml中的参数值注入模板中,生成标准的YAML配置文件
特点
模板增加
了应用部署的灵活性,能够适用不同的环境
了应用部署的灵活性,能够适用不同的环境
helm list#显示已经部署的release
helm delete#可以删除release
helm inspect values image #查看自定image的配置信息
helm install--values=myvalues.yaml image #将设置好的文件安装到 image 中
helm install {IMAGEG} -set args="" -n {CUSTOMER_DIFINE_IMAGE_NAME} #通过set 方式设置参数 安装到image 中
helm list #列表
helm status {IMAGE}# 查看最新状态
helm history#可以查看release所有的版本
helm rollback#可以
回滚到任何版本
回滚到任何版本
helm upgrade#对其进行升级,通过--values
或--set应用新的配置
或--set应用新的配置
helm create mychart #创建chart
helm install --dry-run --debug#会模拟安装chart
安装方式chart
(1)安装仓库中的chart,例如helm install stable/nginx。
(2)通过tar包安装,例如helm install ./nginx-1.2.3.tgz。
(3)通过chart本地目录安装,例如helm install ./nginx。
(4)通过URL安装,例如helm install
https://example.com/charts/nginx-1.2.3.tgz。
(2)通过tar包安装,例如helm install ./nginx-1.2.3.tgz。
(3)通过chart本地目录安装,例如helm install ./nginx。
(4)通过URL安装,例如helm install
https://example.com/charts/nginx-1.2.3.tgz。
仓库
local #本地
stable#远程
k8s 网络
Pod内容器之间的通信
特点
每个Pod都有自己的IP
地址
地址
不同Pod之间不存在端口冲突的问题
概念
当Pod被调度到某个节点,Pod中的所有容器都在这个节点上运
行,这些容器共享相同的本地文件系统、IPC和网络命名空间
行,这些容器共享相同的本地文件系统、IPC和网络命名空间
概念
个Pod都有自己的IP地址,同一个Pod中的容器共享Pod的IP,能够通过localhost通信
Pod之间的通信
概念
Pod的IP是集群可见的,即集群中的任何其他Pod和节点都可以通
过IP直接与Pod通信,这种通信不需要借助任何网络地址转换、隧道
或代理技术。Pod内部和外部使用的是同一个IP,这也意味着标准的
命名服务和发现机制,比如DNS可以直接使用
过IP直接与Pod通信,这种通信不需要借助任何网络地址转换、隧道
或代理技术。Pod内部和外部使用的是同一个IP,这也意味着标准的
命名服务和发现机制,比如DNS可以直接使用
特点
Pod间可以直接通过IP地址通信,但前提是Pod知道对方的IP
Pod与Service的通信
概念
Service提供了访问Pod的抽象层。
无论后端的Pod如何变化,Service都作为稳定的前端对外提供服务。
同时,Service还提供了高可用和负载均衡功能,Service负责将请求转
发给正确的Pod。
无论后端的Pod如何变化,Service都作为稳定的前端对外提供服务。
同时,Service还提供了高可用和负载均衡功能,Service负责将请求转
发给正确的Pod。
外部访问
概念
Pod的IP还是Service的Cluster IP,它们只能在Kubernetes集
群中可见,对集群之外的世界,这些IP都是私有的
群中可见,对集群之外的世界,这些IP都是私有的
NodePort
Service通过Cluster节点的静态端口对外提供服务。
外部可以通过:访问Service。
外部可以通过
LoadBalancer
Service利用cloud provider提供的load
balancer对外提供服务,cloud provider负责将load balancer
的流量导向Service。目前支持的cloud provider有GCP、AWS、
Azur等。
balancer对外提供服务,cloud provider负责将load balancer
的流量导向Service。目前支持的cloud provider有GCP、AWS、
Azur等。
网络方案
概念
Kubernetes采用
了Container Networking Interface(CNI)规范
CNI是由CoreOS提出的容器网络规范,
使用了插件(Plugin)模
型创建容器的网络栈,
了Container Networking Interface(CNI)规范
CNI是由CoreOS提出的容器网络规范,
使用了插件(Plugin)模
型创建容器的网络栈,
CNI网络栈
类型
Flannel
Calico
Network Policy
概念
Network Policy是Kubernetes的一种资源
不是所有的Kubernetes网络方案都支持Network Policy。
比
如Flannel就不支持,Calico是支持的
不是所有的Kubernetes网络方案都支持Network Policy。
比
如Flannel就不支持,Calico是支持的
特点
Network Policy通过
Label选择Pod,并指定其他Pod或外界如何与这些Pod通信。
Label选择Pod,并指定其他Pod或外界如何与这些Pod通信。
Network Policy并指定其他Pod或外界如何与这些Pod通信
当为Pod定义了Network Policy时,只有
Policy允许的流量才能访问Pod
Policy允许的流量才能访问Pod
Canal
概念
它用Flannel实现
Kubernetes集群网络,同时又用Calico实现Network Policy
Kubernetes集群网络,同时又用Calico实现Network Policy
特点
DaemonSet
属于 kube-system这个
namespace
namespace
Weave
Net
概念
用户无
论选择哪种方案,得到的网络模型都一样,即每个Pod都有独立的
IP,可以直接通信。区别在于不同方案的底层实现不同,有的采用基
于VxLAN的Overlay实现,有的则是Underlay,性能上有区别。再有
就是是否支持Network Policy。
论选择哪种方案,得到的网络模型都一样,即每个Pod都有独立的
IP,可以直接通信。区别在于不同方案的底层实现不同,有的采用基
于VxLAN的Overlay实现,有的则是Underlay,性能上有区别。再有
就是是否支持Network Policy。
容器网络模型
docker
Container Network Model(CNM)
有哪些使用的项目
Cisco Contiv、Kuryr、Open Virtual,
Networking(OVN)、Project Calico、
VMware、Weave和Plumgrid
Networking(OVN)、Project Calico、
VMware、Weave和Plumgrid
组件
Network Sandbox
容器内部的网络栈,包括网络接口、路由表、DNS等配置的管理。
Sandbox可用Linux网络命名空间、
FreeBSD Jail等机制进行实现。一个Sandbox可以包含多个Endpoint
Sandbox可用Linux网络命名空间、
FreeBSD Jail等机制进行实现。一个Sandbox可以包含多个Endpoint
Endpoint
用于将容器内的Sandbox与外部网络相连的网络接口。
可以使用veth对、Open vSwitch的内部port等技术进行实现。
一个Endpoint仅能够加入一个Network。
可以使用veth对、Open vSwitch的内部port等技术进行实现。
一个Endpoint仅能够加入一个Network。
Network
可以直接互连的Endpoint的集合。
可以通过Linux网桥、
VLAN等技术进行实现。
一个Network包含多个Endpoint。
可以通过Linux网桥、
VLAN等技术进行实现。
一个Network包含多个Endpoint。
coreos
Container Network Interface(CNI)
有哪些使用的项目
Kubernetes、rkt、Apache Mesos、Cloud Foundry和Kurma等项目采纳。
另外,Contiv Networking, Project Calico、Weave、SR-IOV、Cilium、Infoblox、
Multus、Romana、Plumgrid和Midokura等项目也为CNI提供网络插件的具体实现
另外,Contiv Networking, Project Calico、Weave、SR-IOV、Cilium、Infoblox、
Multus、Romana、Plumgrid和Midokura等项目也为CNI提供网络插件的具体实现
概念
容器
概念
是拥有独立Linux网络命名空间的环境,
例如使用Docker或rkt创建的容器。
关键之处是容器需要拥有自己的Linux网络命名空间,
这是加入网络的必要条件
例如使用Docker或rkt创建的容器。
关键之处是容器需要拥有自己的Linux网络命名空间,
这是加入网络的必要条件
网络
概念
表示可以互连的一组实体,这些实体拥有各自独立、
唯一的IP地址,可以是容器、
物理机或者其他网络设备(比如路由器)等。
唯一的IP地址,可以是容器、
物理机或者其他网络设备(比如路由器)等。
类型
CNI Plugin
概念
CNI Plugin负责为容器配置网络资源
IPAM
概念
IPAM Plugin负责对容器的IP地址进行分配和管理
实现
host-local
dhcp
包含内容
ips段
分配给容器的IP地址(也可能包括网关)
routes段
路由规则记录
dns段
DNS相关的信息
实践
Master
规格选择
集群规模有关,集群规模越大,所需要的Master规格也越大
集群规模
如何衡量
节点数量/Pod数量/部署频率/访问量
规格建议
1-5个节点,Master规格:4C8G(不建议2C4G)
6-20个节点,Master规格:4C16G
21-100个节点,Master规格:8C32G
100-200个节点,Master规格:16C64G
6-20个节点,Master规格:4C16G
21-100个节点,Master规格:8C32G
100-200个节点,Master规格:16C64G
磁盘大小
保存的内容
docker镜像、系统日志、应用日志
考虑点
每个节点上要部署的Pod数量,每个Pod的日志大小、镜像大小、临时数据,再加上一些系统预留的值
pod 限制
静态资源调度
节点剩余资源=节点总资源-已经分配出去的资源
所有Pod上都要声明resources。对于没有声明resources的Pod,它被调度到某个节点后,Kubernetes也不会在对应节点上扣掉这个Pod使用的资源
示例
应用场景
就是一个节点上调度了太多的Pod,导致节点负载太高,完全没法对外提供服务。怎么避免这种情况出现呢
配置监控
监控点
Master和Worker 节点
配置Liveness Probe和Readiness Probe
为什么需要配置Liveness Probe?
Pod处于Running状态和Pod能正常提供服务是完全不同的概念,一个Running状态的Pod,里面的进程可能发生了死锁而无法提供服务。但是因为Pod还是Running的,Kubernetes也不会自动重启这个Pod。所以我们要在所有Pod上配置Liveness Probe,探测Pod是否真的存活,是否还能提供服务。如果Liveness Probe发现了问题,Kubernetes会重启Pod
为什么需要配置Readiness Probe?
Readiness Probe用于探测Pod是不是可以对外提供服务了。应用启动过程中需要一些时间完成初始化,在这个过程中是没法对外提供服务的,通过Readiness Probe,我们可以告诉Ingress或者Service能不能把流量转发给这个Pod上。当Pod出现问题的时候,Readiness Probe能避免新流量继续转发给这个Pod。
配置restart policy
Always: 总是自动重启
OnFailure:异常退出才自动重启 (进程退出状态非0)
Never:永远不重启
OnFailure:异常退出才自动重启 (进程退出状态非0)
Never:永远不重启
应用场景
Pod运行过程中进程退出是个很常见的问题,无论是代码里的一个bug,还是占用内存太多被OOM killer干掉,都会导致应用进程退出,Pod挂掉。Pod退出了怎么办
启动时等待下游服务,不要直接退出
应用场景
第一种场景:等待其它模块Ready,比如我们有一个应用里面有两个容器化的服务,一个是Web Server,另一个是数据库。其中Web Server需要访问数据库。但是当我们启动这个应用的时候,并不能保证数据库服务先启动起来,所以可能出现在一段时间内Web Server有数据库连接错误。为了解决这个问题,我们可以在运行Web Server服务的Pod里使用一个InitContainer,去检查数据库是否准备好,直到数据库可以连接,Init Container才结束退出,然后Web Server容器被启动,发起正式的数据库连接请求。
第二种场景:初始化配置,比如集群里检测所有已经存在的成员节点,为主容器准备好集群的配置信息,这样主容器起来后就能用这个配置信息加入集群。 其它使用场景:如将pod注册到一个中央数据库、下载应用依赖等。
第二种场景:初始化配置,比如集群里检测所有已经存在的成员节点,为主容器准备好集群的配置信息,这样主容器起来后就能用这个配置信息加入集群。 其它使用场景:如将pod注册到一个中央数据库、下载应用依赖等。
进程与POD
特点
每个进程一个容器或一个pod 多个进程
尽量避免直接使用Pod,尽可能使用Deployment/StatefulSet,并且让应用的scale在两个以上
如果多个进程放到一个POD 有什么问题?
1.判断Pod整体的资源占用会变复杂,不方便实施前面提到resource limit
2.容器内只有一个进程的情况,进程挂了,外面的容器引擎可以清楚的感知到,然后重启容器,如果容器内有多个进程,某个进程挂了,容器未必受影响,外部的容器引擎感知不到容器内进程挂了,也不会对容器做任何操作,但是容器实际上已经不能正常工作了
2.容器内只有一个进程的情况,进程挂了,外面的容器引擎可以清楚的感知到,然后重启容器,如果容器内有多个进程,某个进程挂了,容器未必受影响,外部的容器引擎感知不到容器内进程挂了,也不会对容器做任何操作,但是容器实际上已经不能正常工作了
如果直接使用Pod ,不实用Deployment/StatefulSet的话有什么问题?
如果应用只有一个实例,当实例挂掉的时候,虽然Kubernetes能够将实例重新拉起,但是中间不可避免的存在一段时间的不可用。甚至更新应用,发布一个新版本的时候,也会出现这种情况
磁盘的选择
SSD
对于Worker节点,尽量选择“挂在数据盘”。因为这个盘是专门提供给/var/lib/docker,使用来存放本地镜像的。避免后续如果镜像太多撑爆根磁盘。在运行一段时间后,本地会存在很多无用的镜像。比较快捷的方式就是,先下线这台机器,重新构建这个磁盘,然后再上线。
日常运维设置
对于ECS的监控,日常运维一定设置CPU, Memory,磁盘的告警。再次说明一下,尽量将/var/lib/docker放在独立一个盘上
一定配置日志收集
一定配置日志收集
网络选择
如果需要连接外部的一有服务,如 rds等,则需要考虑复用原有的VPC,而不是取创建一个新的VPC。因为VPC间是隔离的。但是可以通过创建一个新的交换机,把k8s的机器都放在这个交换机,便于管理。
网络插件的选择:目前支持两种插件,一种是flannel,直通VPC,性能最高。一种是Terway,提供k8s的网络策略管理。
POD CIDR,整个集群的POD的网络。这个不能设置太小。因为设置太小,能支持的节点数量就受限了。这个与高级选项中“每个节点POD的数量有关”。例如POD CIDR是/16的网段,那么就有256*256个地址,如果每个几点POD数量是128,则最多可以支持512个节点
网络插件的选择:目前支持两种插件,一种是flannel,直通VPC,性能最高。一种是Terway,提供k8s的网络策略管理。
POD CIDR,整个集群的POD的网络。这个不能设置太小。因为设置太小,能支持的节点数量就受限了。这个与高级选项中“每个节点POD的数量有关”。例如POD CIDR是/16的网段,那么就有256*256个地址,如果每个几点POD数量是128,则最多可以支持512个节点
如何选择Worker的规格?
确定整个集群的日常使用的总核数以及可用度的容忍度。例如总的核数有160核,同时容忍10%的错误。那么最小选择10台ECS为16核的机器,并且高峰运行的负荷不要超过16090%=144核。如果容忍度是20%,那么最小选择5台32核的机器,并且高峰运行的负荷不要超过16080%=128核。这样确保,就算有一台机器整体crash都可以支持得住业务运行。
但是上面这个计算只是理论值,因为规格小的机器,很可能剩余不可利用的资源的比例就高。所以不是越小的机器越好。
选择好CPU:Memory的比例。对于使用内存比较多的应用例如java类应用,建议考虑使用1:8的机型。
但是上面这个计算只是理论值,因为规格小的机器,很可能剩余不可利用的资源的比例就高。所以不是越小的机器越好。
选择好CPU:Memory的比例。对于使用内存比较多的应用例如java类应用,建议考虑使用1:8的机型。
POD
定义
关于 Pod 最重要的一个事实是:它只是一个逻辑概念
其实是一组共享了某些资源的容器,Pod 里的所有容器,
共享的是同一个 Network Namespace,并且可以声明共享同一个 Volume
Pod,实际上是在扮演传统基础设施里“虚拟机”的角色;
而容器,则是这个虚拟机里运行的用户程序
其实是一组共享了某些资源的容器,Pod 里的所有容器,
共享的是同一个 Network Namespace,并且可以声明共享同一个 Volume
Pod,实际上是在扮演传统基础设施里“虚拟机”的角色;
而容器,则是这个虚拟机里运行的用户程序
默认容器Infra
Infra 容器永远都是第一个被创建的容器,而其他用户定义的容器,
则通过 Join Network Namespace 的方式,与 Infra 容器关联在一起
则通过 Join Network Namespace 的方式,与 Infra 容器关联在一起
镜像
k8s.gcr.io/pause
特点
汇编语言编写,解压后的大小也只有 100~200 KB 左右
属性
NodeSelector:是一个供用户将 Pod 与 Node 进行绑定的字段
NodeName:一旦 Pod 的这个字段被赋值,Kubernetes 项目就会被认为这个 Pod 已经经过了调度,调度的结果就是赋值的节点名字
HostAliases:定义了 Pod 的 hosts 文件(比如 /etc/hosts)里的内容
shareProcessNamespace=true意味着这个 Pod 里的容器要共享 PID Namespace
hostNetwork: true
hostIPC: true
hostPID: true
Init Containers
Containers
ImagePullPolicy它定义了镜像拉取的策略
Always
Never
IfNotPresent
Lifecycle
是在容器状态发生变化时触发一系列“钩子
postStart
在容器启动后,立刻执行一个指定的操作
preStop
则是容器被杀死之前同步的
Metadata
Spec
Status
Pending这个状态意味着,Pod 的 YAML 文件已经提交给了 Kubernetes,API 对象已经被创建并保存在 Etcd 当中。但是,这个 Pod 里有些容器因为某种原因而不能被顺利创建
Running这个状态下,Pod 已经调度成功,跟一个具体的节点绑定。它包含的容器都已经创建成功,并且至少有一个正在运行中
Succeeded这个状态意味着,Pod 里的所有容器都正常运行完毕,并且已经退出了。这种情况在运行一次性任务时最为常见
Failed这个状态下,Pod 里至少有一个容器以不正常的状态(非 0 的返回码)退出。这个状态的出现,意味着你得想办法 Debug 这个容器的应用,比如查看 Pod 的 Events 和日志。
Unknown这是一个异常状态,意味着 Pod 的状态不能持续地被 kubelet 汇报给 kube-apiserver,这很有可能是主从节点(Master 和 Kubelet)间的通信出现了问题
子主题
子主题
思考题
Kubernetes 使用的这个“控制器模式”,跟我们平常所说的“事件驱动”,有什么区别和联系吗?
事件往往是一次性的,如果操作失败比较难处理,但是控制器是循环一直在尝试的,更符合kubernetes申明式API,最终达到与申明一致
对于我们这个 nginx-deployment 来说,它创建出来的 Pod 的 ownerReference 就是 nginx-deployment 吗?或者说,nginx-deployment 所直接控制的,就是 Pod 对象么?
deployment会创建rs,然后由rs创建pod,所以pod的owner应该是rs?
自由主题

收藏
0 条评论
下一页