Pod:
Pod是 kubernetes 的最基本的操作单元,包含一个或多个紧密相关的容器
kubernetes 使用pod在容器之上再封装一层,其一个很重要的原因是,docker容器之间的通信受到docker网络机制的限制。在docker中,因为每个容器内的网络不同,在以前,往往需要通过link方式才能访问另一个容器提供服务,但是这种方式,docker官网已经不再推荐,docker官方推荐让两个需要通信的容器放在同一个网络,三剑客之一的docker-compose就能提供了这样的条件。kubernetes通过pod的概念将多个容器组合在一个虚拟的 主机内,可以实现容器之间仅需通过localhost就能相互通信了
kubernetes 设计了pod对象,将每个服务进程包装到相应的pod中,使其成为pod中运行的一个容器,在使用时,我们会将 pod对象打上 标签,例如 提供mysql服务功能的pod,我们会为该pod打上name=mysql的标签. 然后将 mysql service 的标签选择器设置为 mysql , 这样pod 对象 和 service 就能关联起来了
pod 的 proxy 接口的作用: 在kubernetes集群之外访问某个pod容器的服务(HTTP服务)时,可以用Proxy API实现,这种场景多用于管理目的,比如逐一排查Service的Pod副本,检查哪些Pod的服务存在异常问题
kubernetes的pod使用分两种主要方式:
(1)pod中运行一个容器 "one-container-per-pod"模式是kubernetes最常见的用法。在这种情况下,你可以将pod视为当个封装的容器,但是kubernetes是直接管理pod而不是容器
(2)pods中运行多个需要一起工作的容器。pod可以封装紧密耦合的应用,它们需要由多个容器组成,它们之间能够共享资源、
Replication Controller 简称 RC:
Replication Controller 是 kubernetes 系统中的核心概念,用于定义pod副本的数量。在master内,controller manager 进程通过RC的定义来完成pod的创建,监控,启停等操作
当我们定义了一个RC并提交到kubernetes集群中以后,master节点上的controller manager组件就得到通知,定期巡检系统中当前存活的目标pod,并确保目标pod实例的数量刚好等于此RC的期望值,如果有多个pod副本在运行,系统就会停掉一些pod,否则系统就会再自动创建一些pod。可以说,通过RC,kubernetes实现了用户应用集群的高可用性,并且大大减少了系统管理员在传统IT环境中需要完成的许多手工运维工作
在运行的时候,我们可以通过修改RC的副本数量,来实现Pod的动态缩放(scaling)
kubectl scale rc jxc --replicas=3
删除RC并不会影响通过该RC已创建好的pod,为了删除所有pod,可以设置replicas=0,然后更新该RC。另外,客户端工具kubectl提供了stop和delete命令来完成一次性删除
RC 和 RC控制的全部pod
指定容器的配额:
对指定容器实施配额管理非常简单,只要在pod或 rc 的定义文件中设定 resources属性即可为某个容器指定配额。目前支持CPU和Memory两类资源的配额限制。
例如
apiVersion: v1
kind: ReplicationController
metadata:
name: jxc
labels:
name: jxc
spec:
replicas: 1
selector:
name: jxc
template:
metadata:
labels:
name: jxc
spec:
containers:
- name: jxc
image: 192.168.255.128:5000/jxc:0.0.3
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
resources:
limits:
cpu: 0.5
memory: 500Mi
以上配置表示,系统将对容器 限制 CPU为0.5,可用内存限制为500MIB字节
kubernetes 启动一个容器时,会将CPU的配额 值乘以1024 并转为整数传递给docker run 的 --cpu-shares 参数, 之所以乘以1024 是因为docker的
cpu-shares 参数是以1024为基数基数CPU时间的。 关于 docker 的 cpu-shares 参数 解析 请参考 https://blog.csdn.net/weixin_39639119/article/details/83046676
,同样的,memory 配额也会被转换为整数传递给 docker run 的 --memory参数。
全局默认配额:
通常情况下,我们将会定义非常多的 rc,如果 每个 资源 都要我们 设置 配额的话,那会显得 十分麻烦,
我们可以通过 创建 LimitRange对象 设置全局默认配额。
vim pod-container-limits.yaml
apiVersion: v1
kind: LimitRange
metadata:
name: limit-range-1
spec:
limits:
- type: "Pod"
max:
cpu: "2"
memory: 1Gi
min:
cpu: 250m
memory: 32Mi
- type: "Container"
max:
cpu: "2"
memory: 1Gi
min:
cpu: 250m
memory: 32Mi
default:
cpu: 250m
memory: 64Mi
~
上述 设置表明:
任意 pod内所有容器的CPU 使用 限制在 0.25 -2
任意 pod 内所有 容器 的内存 使用限制在 32Mi - 1Gi
任意容器的 CPU使用限制在0.25 - 2,默认值为64Mi
任意容器的内存使用限制在 32Mi - 1Gi,默认值为64Mi
kubectl replace -f pod-container-limits.yaml
kubectl describe limits limit-range-1
[root@linux-node1 kubefile]# kubectl describe limits limit-range-1 Name: limit-range-1 Namespace: default Type Resource Min Max Default Request Default Limit Max Limit/Request Ratio ---- -------- --- --- --------------- ------------- ----------------------- Pod cpu 250m 2 - - - Pod memory 32Mi 1Gi - - - Container memory 32Mi 1Gi 64Mi 64Mi - Container cpu 250m 2 250m 250m - |
运行 kubectl create 命令 创建该 pod
[root@linux-node1 kubefile]# kubectl describe pod jxc
Limits: cpu: 250m memory: 64Mi Requests: cpu: 250m memory: 64Mi |
创建成功后,查看该pod的详细信息,可以看到系统中LimitRange的设置对新创建的容器进行了资源限制(使用了LimitRange中的默认值)
如果,我们在pod的定义文件中指定了配额参数,则可遵循局部覆盖全局的原则,当不能超过了全局设定的最大值
replica set:
由于replication controller 与kubernetes代码中的模块replication controller 同名,同时这个词也无法准确表达它的本意,所以在kubernetes 1.2 的时候,它就升级成了另外一个新的概念 -- replica set。二者之间唯一的区别是,Replica Set支持了基于集合的Label Selector功能
ReplicaSet是支持新的set-based 选择器要求的下一代 ReplicationController。它主要用作Deployment 协调pod创建,删除和更新。虽然ReplicaSets可以独立使用,但它主要被
Deployment协调pod创建,删除和更新。建议使用Deployment而不是直接使用ReplicaSets
Deployment:
学过saltstack都值得,salt有一个状态模块,只要你在salt配置文件描述好状态,salt就会将你指定的主机状态改变到你的目标状态。
Deployment也能刚这样的事情,你只需要在Deployment中描述您想要的目标状态是什么。Deployment Controller就会帮你将Pod 和
ReplicaSet的实际状态改变到您的目标状态
典型用例:
(1)创建一个Deployment对象来生成对应的ReplicaSet,并完成Pod副本的创建过程
(2) 检查Deployment的状态来查看部署动作是否完成,pod副本的数量是否达到预期的值
(3)更新Deployment以创建新的Pod,通过修改pod-template-spec字段来声明pod的新状态。这会创建一个新的
replicaSet, Deployment 会按照控制的速率将pod从旧的ReplcaSet移动到新的ReplicaSet中
(4)如果当前状态不稳定,则回滚到一个早先的Deployment版本
(5)扩容 Deployment 以满足更高的负载
(6)查看 Deployment 状态,判断发布是否成功
(7)清除旧的replicaSets
创建deployment
[root@linux-node1 kubefile]# vim ku-deployment.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: jxc-deployment
labels:
web: jxc
spec:
replicas: 1
selector:
matchLabels:
web: jxc
template:
metadata:
labels:
web: jxc
spec:
containers:
- name: jxc
image: 192.168.255.128:5000/jxc:0.0.3
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
创建 deployment
kubectl create -f ku-deployment.yaml --record
-- record 当我们需要查看 历史版本时,可以很方便的查看每次 revision变化
查看deployment 的 创建详情
[root@linux-node1 kubefile]# kubectl describe deployment jxc-deployment
[root@linux-node1 kubefile]# kubectl get deployments
[root@linux-node1 kubefile]# kubectl get rs
runing说明启动成功
[root@linux-node1 kubefile]# kubectl get pods
NAME READY STATUS RESTARTS AGE
jxc-deployment-3952983837-mw8df 1/1 Running 0 3m
更新
deployment的更新
当 使用 kubectl edit 命令 时,就可以 编辑 yaml 文件,当deployment的pod template的 label 发生更新或者镜像发生 更改时
,才会触发更新 信号(rollout)
例如将 jxc:0.0.3 更改为 jxc0.0.4
kubectl edit deployment/jxc-deployment
spec: containers: - image: 192.168.255.128:5000/jxc:0.0.4 imagePullPolicy: IfNotPresent name: jxc ports: - containerPort: 8080 protocol: TCP resources: {} terminationMessagePath: /dev/termination-log dnsPolicy: ClusterFirst restartPolicy: Always securityContext: {} terminationGracePeriodSeconds: 30 |
[root@linux-node1 kubefile]# kubectl rollout status deployment/jxc-deployment
deployment "jxc-deployment" successfully rolled out
回退
当deployment 更新时,就会创建一个revision。我们可以通过设置.spec.revisionHistoryLimit来指定deployment最多保留多少个
revision历史记录。默认会保留所有的revision;如果将该项设置为0,deployment就不允许回退了
我们先用 kubectl edit deployment/jxc-deployment 将 版本 修改为一个不存在的版本
spec: containers: - image: 192.168.255.128:5000/jxc:0.0.6 imagePullPolicy: IfNotPresent name: jxc ports: - containerPort: 8080 protocol: TCP resources: {} terminationMessagePath: /dev/termination-log dnsPolicy: ClusterFirst restartPolicy: Always securityContext: {} terminationGracePeriodSeconds: 30 |
[root@linux-node1 kubefile]# kubectl rollout status deployment/jxc-deployment
Waiting for rollout to finish: 0 of 1 updated replicas are available...
通过 该 命令 , 我们可以得知 版本更新 卡住了
[root@linux-node1 kubefile] kubectl get pods
NAME READY STATUS RESTARTS AGE
jxc-deployment-4197170976-8sph2 0/1 ImagePullBackOff 0 2m
pods 也处于 ImagePullBackOff 状态
我们 需要 回退到稳定的版本
我们 先 查看 deployment 历史版本记录
[root@linux-node1 kubefile]# kubectl rollout history deployment/jxc-deployment
deployments "jxc-deployment"
REVISION CHANGE-CAUSE
1 kubectl create -f ku-deployment.yaml --record
2 kubectl edit deployment/jxc-deployment
3 kubectl edit deployment/jxc-deployment
查看当个 version 信息
kubectl rollout history deployment/jxc-deployment --revision=2
deployments "jxc-deployment" with revision #2 Labels: pod-template-hash=4034379550 web=jxc Annotations: kubernetes.io/change-cause=kubectl edit deployment/jxc-deployment Containers: jxc: Image: 192.168.255.128:5000/jxc:0.0.4 Port: 8080/TCP Volume Mounts: <none> Environment Variables: <none> No volumes. |
回退到 上一个版本
kubectl rollout undo deployment/jxc-deployment
[root@linux-node1 kubefile]# kubectl rollout undo deployment/jxc-deployment deployment "jxc-deployment" rolled back [root@linux-node1 kubefile]# kubectl get pods NAME READY STATUS RESTARTS AGE jxc-deployment-4034379550-pjfp9 1/1 Running 0 3s |
回退到指定版本
kubectl rollout undo deployment/jxc-deployment --to-revision=2
[root@linux-node1 kubefile]# kubectl rollout undo deployment/jxc-deployment --to-revision=1 deployment "jxc-deployment" rolled back [root@linux-node1 kubefile]# kubectl get pods NAME READY STATUS RESTARTS AGE jxc-deployment-3952983837-tq31x 1/1 Running 0 4s |
扩容
kubectl scale deployment deployment/jxc-deployment --replicas 2
[root@linux-node1 kubefile]# kubectl scale deployment jxc-deployment --replicas 2 deployment "jxc-deployment" scaled [root@linux-node1 kubefile]# kubectl get pods NAME READY STATUS RESTARTS AGE jxc-deployment-3952983837-jzzzv 1/1 Running 0 4s jxc-deployment-3952983837-tq31x 1/1 Running 0 2m |
暂停和 恢复
当需要对 deployment 进行多次修改时, 我们可以 先暂时,再恢复,防止 不必要的rollout
kubectl rollout pause deployment/jxc-deployment
[root@linux-node1 kubefile]# kubectl rollout pause deployment/jxc-deployment deployment "jxc-deployment" paused |
我 把 镜像的版本改为 0.0.4 ,然后恢复
kubectl rollout resume deploy jxc-deployment
[root@linux-node1 kubefile]# kubectl rollout resume deploy jxc-deployment deployment "jxc-deployment" resumed |
Horizontal Pod Autoscaling
HPA 的操作对象是RC,RS 或 Deployment对应的Pod,根据观察到的CPU等实际使用量与用户的期望值进行比对,做出是否需要增减实例数量的决策
kubernetes 根据 pod当前系统的负载来自动扩容,如果系统负载超过预定值,就开始增加pod的个数,如果低于某个值,就自动减少pod的个数。在v1.6
版本之前,仅支持使用CPU负载作为是否扩容的判定条件;自v1.6版本开始提供了根据应用自定义指标进行自动扩容和缩容的功能
我们可以通过创建 yaml 文件,来实现自动扩容
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
name: jxc
namespace: default
spec:
maxReplicas: 10
minReplicas: 1
scaleTargetRef:
kind: Deployment
name: jxc
targetCPUUtilizationPercentage: 90
kubectl create -f jxc-hpa.yaml
上述 脚本的意思 是 当名为 jxc 的 deployment 的 pod副本的CPU使用率 超过 90%时,会触发自动扩容行为。但 扩容或缩容都必须满足约束条件
pod 的副本数量 在 1-10 之间