k8s学习笔记--资源清单-控制器-service
- 资源清单格式
- 资源清单的常用命令
- 通过定义清单文件创建 Pod
- Init 容器
- 检测探针 - 就绪检测
- 检测探针 - 存活检测
- 启动、退出动作
- 什么是控制器
- 控制器类型
- ReplicationController 和 ReplicaSet
- Deployment
- DaemonSet
- Job
- CronJob
- StatefulSet
- HPA
- RS 与 RC 与 Deployment 关联
- RS 与 Deployment 的关联
- Deployment
- 更新 Deployment
- Deployment 更新策略
- Rollover(多个rollout并行)
- 回退 Deployment
- 清理 Policy
- 什么是 DaemonSet
- Job
- CronJob Spec
- CronJob
- CronJob Spec
- CrondJob 本身的一些限制
- Service 的概念
- 核心迭代
- Service 的类型
- ClusterIP
- Headless Service
资源清单格式
apiVersion: group/apiversion # 如果没有给定 group 名称,那么默认为 core,可以使用 kubectl api-versions # 获取当前 k8s 版本上所有的 apiVersion 版本信息( 每个版本可能不同 )
kind: #资源类别
metadata: #资源元数据
name
namespace
lables
annotations # 主要目的是方便用户阅读查找
spec: # 期望的状态(disired state)
status:# 当前状态,本字段有 Kubernetes 自身维护,用户不能去定义
资源清单的常用命令
获取 apiversion 版本信息
[root@k8s-master01 ~]# kubectl api-versions
admissionregistration.k8s.io/v1beta1
apiextensions.k8s.io/v1beta1
apiregistration.k8s.io/v1
apiregistration.k8s.io/v1beta1
apps/v1
......(以下省略)
获取资源的 apiVersion 版本信息
[root@k8s-master01 ~]# kubectl explain pod
KIND: Pod
VERSION: v1
.....(以下省略)
[root@k8s-master01 ~]# kubectl explain Ingress
KIND: Ingress
VERSION: extensions/v1beta1
获取字段设置帮助文档
[root@k8s-master01 ~]# kubectl explain pod
KIND: Pod
VERSION: v1
DESCRIPTION:
Pod is a collection of containers that can run on a host. This resource is
created by clients and scheduled onto hosts.
FIELDS:
apiVersion <string>
........
........
字段配置格式
apiVersion <string> #表示字符串类型
metadata <Object> #表示需要嵌套多层字段
labels <map[string]string> #表示由k:v组成的映射
finalizers <[]string> #表示字串列表
ownerReferences <[]Object> #表示对象列表
hostPID <boolean> #布尔类型
priority <integer> #整型
name <string> -required- #如果类型后面接 -required-,表示为必填字段
通过定义清单文件创建 Pod
apiVersion: v1
kind: Pod
metadata:
name: pod-demo
namespace: default
labels:
app: myapp
spec:
containers:
- name: myapp-1
image: harbor.hongfu.com/library/myapp:v1
- name: busybox-1
image: harbor.hongfu.com/library/busybox:v1
command:
- "/bin/sh"
- "-c"
- "sleep 3600"
kubectl get pod xx.xx.xx -o yaml
<!--使用 -o 参数 加 yaml,可以将资源的配置以 yaml的格式输出出来,也可以使用json,输出为json格式-->
Init 容器
init 模板
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app: myapp
spec:
containers:
- name: myapp-container
image: harbor.hongfu.com/library/busybox:v1
command: ['sh', '-c', 'echo The app is running! && sleep 3600']
initContainers:
- name: init-myservice
image: harbor.hongfu.com/library/busybox:v1
command: ['sh', '-c', 'until nslookup myservice; do echo waiting for myservice; sleep 2; done;']
- name: init-mydb
image: harbor.hongfu.com/library/busybox:v1
command: ['sh', '-c', 'until nslookup mydb; do echo waiting for mydb; sleep 2; done;']
kind: Service
apiVersion: v1
metadata:
name: myservice
spec:
ports:
- protocol: TCP
port: 80
targetPort: 9376
---
kind: Service
apiVersion: v1
metadata:
name: mydb
spec:
ports:
- protocol: TCP
port: 80
targetPort: 9377
检测探针 - 就绪检测
readinessProbe-httpget
apiVersion: v1
kind: Pod
metadata:
name: readiness-httpget-pod
namespace: default
spec:
containers:
- name: readiness-httpget-container
image: wangyanglinux/myapp:v1
imagePullPolicy: IfNotPresent
readinessProbe:
httpGet:
port: 80
path: /index1.html
initialDelaySeconds: 1
periodSeconds: 3
检测探针 - 存活检测
livenessProbe-exec
apiVersion: v1
kind: Pod
metadata:
name: liveness-exec-pod
namespace: default
spec:
containers:
- name: liveness-exec-container
image: harbor.hongfu.com/library/busybox:v1
imagePullPolicy: IfNotPresent
command: ["/bin/sh","-c","touch /tmp/live ; sleep 60; rm -rf /tmp/live; sleep
3600"]
livenessProbe:
exec:
command: ["test","-e","/tmp/live"]
initialDelaySeconds: 1
periodSeconds: 3
livenessProbe-httpget
apiVersion: v1
kind: Pod
metadata:
name: liveness-httpget-pod
namespace: default
spec:
containers:
- name: liveness-httpget-container
image: harbor.hongfu.com/library/myapp:v1
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 80
livenessProbe:
httpGet:
port: 80
path: /index.html
initialDelaySeconds: 1
periodSeconds: 3
timeoutSeconds: 3
livenessProbe-tcp
apiVersion: v1
kind: Pod
metadata:
name: probe-tcp
spec:
containers:
- name: nginx
image: harbor.hongfu.com/library/myapp:v1
livenessProbe:
initialDelaySeconds: 5
timeoutSeconds: 1
tcpSocket:
port: 80
启动、退出动作
apiVersion: v1
kind: Pod
metadata:
name: lifecycle-demo
spec:
containers:
- name: lifecycle-demo-container
image: harbor.hongfu.com/library/myapp:v1
lifecycle:
postStart:
exec:
command: ["/bin/sh", "-c", "echo Hello from the postStart handler > /usr/share/message"]
preStop:
exec:
command: ["/bin/sh", "-c", "echo Hello from the poststop handler > /usr/share/message"]
什么是控制器
Kubernetes 中内建了很多 controller(控制器),这些相当于一个状态机,用来控制 Pod 的具体状态和行为
控制器类型
- ReplicationController 和 ReplicaSet
- Deployment
- DaemonSet
- StateFulSet
- Job/CronJob
- Horizontal Pod Autoscaling
ReplicationController 和 ReplicaSet
ReplicationController(RC)用来确保容器应用的副本数始终保持在用户定义的副本数,即如果有容器异常退出,会自动创建新的 Pod 来替代;而如果异常多出来的容器也会自动回收;
在新版本的 Kubernetes 中建议使用 ReplicaSet 来取代 ReplicationController 。ReplicaSet 跟ReplicationController 没有本质的不同,只是名字不一样,并且 ReplicaSet 支持集合式的 selector;
Deployment
Deployment 为 Pod 和 ReplicaSet 提供了一个声明式定义 (declarative) 方法,用来替代以前的ReplicationController 来方便的管理应用。典型的应用场景包括;
- 定义 Deployment 来创建 Pod 和 ReplicaSet
- 滚动升级和回滚应用
- 扩容和缩容
- 暂停和继续 Deployment
DaemonSet
DaemonSet 确保全部(或者一些)Node 上运行一个 Pod 的副本。当有 Node 加入集群时,也会为他们新增一个 Pod 。当有 Node 从集群移除时,这些 Pod 也会被回收。删除 DaemonSet 将会删除它创建的所有 Pod
使用 DaemonSet 的一些典型用法:
- 运行集群存储 daemon,例如在每个 Node 上运行
glusterd
、ceph
- 在每个 Node 上运行日志收集 daemon,例如
fluentd
、logstash
- 在每个 Node 上运行监控 daemon,例如 Prometheus Node Exporter、
collectd
、Datadog 代理、New Relic 代理,或 Gangliagmond
Job
Job 负责批处理任务,即仅执行一次的任务,它保证批处理任务的一个或多个 Pod 成功结束
CronJob
Cron Job 管理基于时间的 Job,即:
- 在给定时间点只运行一次
- 周期性地在给定时间点运行
使用前提条件:当前使用的 Kubernetes 集群,版本 >= 1.8(对 CronJob)。对于先前版本的集群,版本 < 1.8,启动 API Server时,通过传递选项 --runtime-config=batch/v2alpha1=true
可以开启 batch/v2alpha1 API
典型的用法如下所示:
- 在给定的时间点调度 Job 运行
- 创建周期性运行的 Job,例如:数据库备份、发送邮件
StatefulSet
StatefulSet 作为 Controller 为 Pod 提供唯一的标识。它可以保证部署和 scale 的顺序
StatefulSet是为了解决有状态服务的问题(对应Deployments和ReplicaSets是为无状态服务而设计),其应用场景包括:
- 稳定的持久化存储,即Pod重新调度后还是能访问到相同的持久化数据,基于PVC来实现
- 稳定的网络标志,即Pod重新调度后其PodName和HostName不变,基于Headless Service(即没有Cluster IP的Service)来实现
- 有序部署,有序扩展,即Pod是有顺序的,在部署或者扩展的时候要依据定义的顺序依次依次进行(即从0到N-1,在下一个Pod运行之前所有之前的Pod必须都是Running和Ready状态),基于init containers来实现
- 有序收缩,有序删除(即从N-1到0)
HPA
应用的资源使用率通常都有高峰和低谷的时候,如何削峰填谷,提高集群的整体资源利用率,让 service 中的Pod个数自动调整呢?这就有赖于 HPA (Horizontal Pod Autoscaling)了,顾名思义,使 Pod 水平自动缩放
typora-root-url: Png
RS 与 RC 与 Deployment 关联
RC (ReplicationController )主要的作用就是用来确保容器应用的副本数始终保持在用户定义的副本数 。即如果有容器异常退出,会自动创建新的Pod来替代;而如果异常多出来的容器也会自动回收
Kubernetes 官方建议使用 RS(ReplicaSet ) 替代 RC (ReplicationController ) 进行部署,RS 跟 RC 没有本质的不同,只是名字不一样,并且 RS 支持集合式的 selector
RC 控制器
apiVersion: v1
kind: ReplicationController
metadata:
name: frontend
spec:
replicas: 3
selector:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: php-redis
image: wangyanglinux/myapp:v1
env:
- name: GET_HOSTS_FROM
value: dns
name: zhangsan
value: "123"
ports:
- containerPort: 80
RS 控制器
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: frontend
spec:
replicas: 3
selector:
matchLabels:
tier: frontend
template:
metadata:
labels:
tier: frontend
spec:
containers:
- name: myapp
image: wangyanglinux/myapp:v1
env:
- name: GET_HOSTS_FROM
value: dns
ports:
- containerPort: 80
selector.matchExpressions
rs 在标签选择器上,除了可以定义键值对的选择形式,还支持 matchExpressions 字段,可以提供多种选择。
目前支持的操作包括:
- In:label 的值在某个列表中
- NotIn:label 的值不在某个列表中
- Exists:某个 label 存在
- DoesNotExist:某个 label 不存在
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: rs-demo
spec:
selector:
matchExpressions:
- key: app
operator: Exists
template:
metadata:
labels:
app: spring-k8s
spec:
containers:
- name: rs-c1
image: wangyanglinux/myapp:v1
ports:
- containerPort: 80
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: rs-demo
spec:
selector:
matchExpressions:
- key: app
operator: In
values:
- spring-k8s
- hahahah
template:
metadata:
labels:
app: sg-k8s
spec:
containers:
- name: rs-c1
image: wangyanglinux/myapp:v1
ports:
- containerPort: 80
RS 与 Deployment 的关联
Deployment
Deployment 为 Pod 和 ReplicaSet 提供了一个声明式定义(declarative)方法,用来替代以前的ReplicationController 来方便的管理应用。典型的应用场景包括:
- 定义Deployment来创建Pod和ReplicaSet
- 滚动升级和回滚应用
- 扩容和缩容
- 暂停和继续Deployment
Ⅰ、部署一个简单的 Nginx 应用
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: wangyanglinux/myapp:v1
ports:
- containerPort: 80
kubectl create -f https://kubernetes.io/docs/user-guide/nginx-deployment.yaml --record
## --record参数可以记录命令,我们可以很方便的查看每次 revision 的变化
Ⅱ、扩容
kubectl scale deployment nginx-deployment --replicas 10
Ⅲ、如果集群支持 horizontal pod autoscaling 的话,还可以为Deployment设置自动扩展
kubectl autoscale deployment nginx-deployment --min=10 --max=15 --cpu-percent=80
Ⅳ、更新镜像也比较简单
kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1
Ⅴ、回滚
kubectl rollout undo deployment/nginx-deployment
更新 Deployment
假如我们现在想要让 nginx pod 使用nginx:1.9.1
的镜像来代替原来的nginx:1.7.9
的镜像
$ kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1
deployment "nginx-deployment" image updated
可以使用edit
命令来编辑 Deployment
$ kubectl edit deployment/nginx-deployment
deployment "nginx-deployment" edited
查看 rollout 的状态
$ kubectl rollout status deployment/nginx-deployment
Waiting for rollout to finish: 2 out of 3 new replicas have been updated...
deployment "nginx-deployment" successfully rolled out
查看历史 RS
$ kubectl get rs
NAME DESIRED CURRENT READY AGE
nginx-deployment-1564180365 3 3 0 6s
nginx-deployment-2035384211 0 0 0 36s
Deployment 更新策略
Deployment 可以保证在升级时只有一定数量的 Pod 是 down 的。默认的,它会确保至少有比期望的Pod数量少一个是up状态(最多一个不可用)
Deployment 同时也可以确保只创建出超过期望数量的一定数量的 Pod。默认的,它会确保最多比期望的Pod数量多一个的 Pod 是 up 的(最多1个 surge )
未来的 Kuberentes 版本中,将从1-1变成25%-25%
$ kubectl describe deployments
更新策略声明
kubectl explain deploy.spec.strategy.type
- Recreate
- rollingUpdate
- maxSurge:指定超出副本数有几个,两种方式:1、指定数量 2、百分比
- maxUnavailable : 最多有几个不可用
kubectl patch deployment nginx-deployment -p '{"spec":{"strategy":{"rollingUpdate":{"maxSurge":1,"maxUnavailable":0}}}}'
金丝雀部署
$ kubectl set image deploy nginx-deployment nginx=wangyanglinux/myapp:v2 && kubectl rollout pause deploy nginx-deployment
$ kubectl rollout resume deploy nginx-deployment
Rollover(多个rollout并行)
假如您创建了一个有5个niginx:1.7.9
replica的 Deployment,但是当还只有3个nginx:1.7.9
的 replica 创建出来的时候您就开始更新含有5个nginx:1.9.1
replica 的 Deployment。在这种情况下,Deployment 会立即杀掉已创建的3个nginx:1.7.9
的 Pod,并开始创建nginx:1.9.1
的 Pod。它不会等到所有的5个nginx:1.7.9
的 Pod 都创建完成后才开始改变航道
回退 Deployment
kubectl set image deployment/nginx-deployment nginx=nginx:1.91
kubectl rollout status deployments nginx-deployment
kubectl get pods
kubectl rollout history deployment/nginx-deployment
kubectl rollout undo deployment/nginx-deployment
kubectl rollout undo deployment/nginx-deployment --to-revision=2 ## 可以使用 --revision参数指定某个历史版本
kubectl rollout pause deployment/nginx-deployment ## 暂停 deployment 的更新
您可以用kubectl rollout status
命令查看 Deployment 是否完成。如果 rollout 成功完成,kubectl rollout status
将返回一个0值的 Exit Code
$ kubectl rollout status deploy/nginx
Waiting for rollout to finish: 2 of 3 updated replicas are available...
deployment "nginx" successfully rolled out
$ echo $?
0
清理 Policy
您可以通过设置.spec.revisonHistoryLimit
项来指定 deployment 最多保留多少 revision 历史记录。默认的会保留所有的 revision;如果将该项设置为0,Deployment 就不允许回退了
什么是 DaemonSet
DaemonSet 确保全部(或者一些)Node 上运行一个 Pod 的副本。当有 Node 加入集群时,也会为他们新增一个 Pod 。当有 Node 从集群移除时,这些 Pod 也会被回收。删除 DaemonSet 将会删除它创建的所有 Pod
使用 DaemonSet 的一些典型用法:
- 运行集群存储 daemon,例如在每个 Node 上运行
glusterd
、ceph
- 在每个 Node 上运行日志收集 daemon,例如
fluentd
、logstash
- 在每个 Node 上运行监控 daemon,例如 Prometheus Node Exporter、
collectd
、Datadog 代理、New Relic 代理,或 Gangliagmond
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: deamonset-example
labels:
app: daemonset
spec:
selector:
matchLabels:
name: deamonset-example
template:
metadata:
labels:
name: deamonset-example
spec:
containers:
- name: daemonset-example
image: wangyanglinux/myapp:v1
Job
Job 负责批处理任务,即仅执行一次的任务,它保证批处理任务的一个或多个 Pod 成功结束
特殊说明
- spec.template格式同Pod
- RestartPolicy仅支持Never或OnFailure
- 单个Pod时,默认Pod成功运行后Job即结束
.spec.completions
标志Job结束需要成功运行的Pod个数,默认为1.spec.parallelism
标志并行运行的Pod的个数,默认为1spec.activeDeadlineSeconds
标志失败Pod的重试最大时间,超过这个时间不会继续重试
Example
求 π 值
算法:马青公式
π/4=4arctan1/5-arctan1/239
这个公式由英国天文学教授 约翰·马青 于 1706 年发现。他利用这个公式计算到了 100 位的圆周率。马青公式每计算一项可以得到 1.4 位的 十进制精度。因为它的计算过程中被乘数和被除数都不大于长整数,所以可以很容易地在计算机上编程实现
# -*- coding: utf-8 -*-
from __future__ import division
# 导入时间模块
import time
# 计算当前时间
time1=time.time()
# 算法根据马青公式计算圆周率 #
number = 1000
# 多计算10位,防止尾数取舍的影响
number1 = number+10
# 算到小数点后number1位
b = 10**number1
# 求含4/5的首项
x1 = b*4//5
# 求含1/239的首项
x2 = b // -239
# 求第一大项
he = x1+x2
#设置下面循环的终点,即共计算n项
number *= 2
#循环初值=3,末值2n,步长=2
for i in xrange(3,number,2):
# 求每个含1/5的项及符号
x1 //= -25
# 求每个含1/239的项及符号
x2 //= -57121
# 求两项之和
x = (x1+x2) // i
# 求总和
he += x
# 求出π
pai = he*4
#舍掉后十位
pai //= 10**10
# 输出圆周率π的值
paistring=str(pai)
result=paistring[0]+str('.')+paistring[1:len(paistring)]
print result
time2=time.time()
print u'Total time:' + str(time2 - time1) + 's'
FROM hub.c.163.com/public/python:2.7
ADD ./main.py /root
CMD /usr/bin/python /root/main.py
apiVersion: batch/v1
kind: Job
metadata:
name: pi
spec:
template:
metadata:
name: pi
spec:
containers:
- name: pi
image: maqing:v1
restartPolicy: Never
CronJob Spec
- spec.template 格式同 Pod
- RestartPolicy仅支持Never或OnFailure
- 单个Pod时,默认Pod成功运行后Job即结束
.spec.completions
标志Job结束需要成功运行的Pod个数,默认为1.spec.parallelism
标志并行运行的Pod的个数,默认为1spec.activeDeadlineSeconds
标志失败Pod的重试最大时间,超过这个时间不会继续重试
CronJob
Cron Job 管理基于时间的 Job,即:
- 在给定时间点只运行一次
- 周期性地在给定时间点运行
使用条件:当前使用的 Kubernetes 集群,版本 >= 1.8(对 CronJob)
典型的用法如下所示:
- 在给定的时间点调度 Job 运行
- 创建周期性运行的 Job,例如:数据库备份、发送邮件
CronJob Spec
-
.spec.schedule
:调度,必需字段,指定任务运行周期,格式同 Cron -
.spec.jobTemplate
:Job 模板,必需字段,指定需要运行的任务,格式同 Job -
.spec.startingDeadlineSeconds
:启动 Job 的期限(秒级别),该字段是可选的。如果因为任何原因而错过了被调度的时间,那么错过执行时间的 Job 将被认为是失败的。如果没有指定,则没有期限 -
.spec.concurrencyPolicy
:并发策略,该字段也是可选的。它指定了如何处理被 Cron Job 创建的 Job 的并发执行。只允许指定下面策略中的一种:Allow
(默认):允许并发运行 JobForbid
:禁止并发运行,如果前一个还没有完成,则直接跳过下一个Replace
:取消当前正在运行的 Job,用一个新的来替换
注意,当前策略只能应用于同一个 Cron Job 创建的 Job。如果存在多个 Cron Job,它们创建的 Job 之间总是允许并发运行。
-
.spec.suspend
:挂起,该字段也是可选的。如果设置为true
,后续所有执行都会被挂起。它对已经开始执行的 Job 不起作用。默认值为false
。 -
.spec.successfulJobsHistoryLimit
和.spec.failedJobsHistoryLimit
:历史限制,是可选的字段。它们指定了可以保留多少完成和失败的 Job。默认情况下,它们分别设置为3
和1
。设置限制的值为0
,相关类型的 Job 完成后将不会被保留。
Example
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: hello
spec:
schedule: "*/1 * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: hello
image: busybox
args:
- /bin/sh
- -c
- date; echo Hello from the Kubernetes cluster
restartPolicy: OnFailure
$ kubectl get cronjob
NAME SCHEDULE SUSPEND ACTIVE LAST-SCHEDULE
hello */1 * * * * False 0 <none>
$ kubectl get jobs
NAME DESIRED SUCCESSFUL AGE
hello-1202039034 1 1 49s
$ pods=$(kubectl get pods --selector=job-name=hello-1202039034 --output=jsonpath={.items..metadata.name})
$ kubectl logs $pods
Mon Aug 29 21:34:09 UTC 2016
Hello from the Kubernetes cluster
# 注意,删除 cronjob 的时候不会自动删除 job,这些 job 可以用 kubectl delete job 来删除
$ kubectl delete cronjob hello
cronjob "hello" deleted
CrondJob 本身的一些限制
创建 Job 操作应该是 幂等的
- 资源清单格式
- 资源清单的常用命令
- 通过定义清单文件创建 Pod
- Init 容器
- 检测探针 - 就绪检测
- 检测探针 - 存活检测
- 启动、退出动作
- 什么是控制器
- 控制器类型
- ReplicationController 和 ReplicaSet
- Deployment
- DaemonSet
- Job
- CronJob
- StatefulSet
- HPA
- RS 与 RC 与 Deployment 关联
- RS 与 Deployment 的关联
- Deployment
- 更新 Deployment
- Deployment 更新策略
- Rollover(多个rollout并行)
- 回退 Deployment
- 清理 Policy
- 什么是 DaemonSet
- Job
- CronJob Spec
- CronJob
- CronJob Spec
- CrondJob 本身的一些限制
- Service 的概念
- 核心迭代
- Service 的类型
- ClusterIP
- Headless Service
Service 的概念
Kubernetes Service
定义了这样一种抽象:一个 Pod
的逻辑分组,一种可以访问它们的策略 —— 通常称为微服务。 这一组 Pod
能够被 Service
访问到,通常是通过 Label Selector
核心迭代
在 Kubernetes 集群中,每个 Node 运行一个 kube-proxy
进程。kube-proxy
负责为 Service
实现了一种 VIP(虚拟 IP)的形式,而不是 ExternalName
的形式。 在 Kubernetes v1.0 版本,代理完全在 userspace。在 Kubernetes v1.1 版本,新增了 iptables 代理,但并不是默认的运行模式。 从 Kubernetes v1.2 起,默认就是 iptables 代理。 在 Kubernetes v1.8.0-beta.0 中,添加了 ipvs 代理
在 Kubernetes 1.14 版本开始默认使用 ipvs 代理
在 Kubernetes v1.0 版本,Service
是 “4层”(TCP/UDP over IP)概念。 在 Kubernetes v1.1 版本,新增了 Ingress
API(beta 版),用来表示 “7层”(HTTP)服务
Ⅰ、userspace 代理模式
Ⅱ、iptables 代理模式
Ⅲ、ipvs 代理模式
限制
Service能够提供负载均衡的能力,但是在使用上有以下限制:
- 只提供 4 层负载均衡能力,而没有 7 层功能,但有时我们可能需要更多的匹配规则来转发请求,这点上 4 层负载均衡是不支持的
Service 的类型
- ClusterIp:默认类型,自动分配一个仅 Cluster 内部可以访问的虚拟 IP
- NodePort:在 ClusterIP 基础上为 Service 在每台机器上绑定一个端口,这样就可以通过
: NodePort 来访问该服务 - LoadBalancer:在 NodePort 的基础上,借助 cloud provider 创建一个外部负载均衡器,并将请求转发到
: NodePort - ExternalName:把集群外部的服务引入到集群内部来,在集群内部直接使用。没有任何类型代理被创建,这只有 kubernetes 1.7 或更高版本的 kube-dns 才支持
ClusterIP
**为了实现图上的功能,主要需要以下几个组件的协同工作: **
- apiserver:用户通过 kubectl 命令向 apiserver 发送创建 service 的命令,apiserver 接收到请求后将数据存储到 etcd 中
- kube-proxy:kubernetes 的每个节点中都有一个叫做 kube-porxy 的进程,这个进程负责感知service,pod 的变化,并将变化的信息写入本地的 ipvs 规则中
- ipvs:基于内核的钩子函数机制实现负载
创建 myapp-deploy.yaml 文件
[root@master manifests]# vim myapp-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-deploy
namespace: default
spec:
replicas: 3
selector:
matchLabels:
app: myapp
release: stabel
template:
metadata:
labels:
app: myapp
release: stabel
env: test
spec:
containers:
- name: myapp
image: wangyanglinux/myapp:v2
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 80
创建 Service 信息
[root@master manifests]# vim myapp-service.yaml
apiVersion: v1
kind: Service
metadata:
name: myapp
namespace: default
spec:
type: ClusterIP
selector:
app: myapp
release: stabel
ports:
- name: http
port: 80
targetPort: 80
Headless Service
有时不需要或不想要负载均衡,以及单独的 Service IP 。遇到这种情况,可以通过指定 Cluster IP ( spec.clusterIP ) 的值为 “ None ” 来创建 Headless Service 。这类 Service 并不会分配 Cluster IP, kube-proxy 不会处理它们,而且平台也不会为它们进行负载均衡和路由
# yum -y install bind-utils
[root@k8s-master mainfests]# vim myapp-svc-headless.yaml
apiVersion: v1
kind: Service
metadata:
name: myapp-headless
namespace: default
spec:
selector:
app: myapp
clusterIP: "None"
ports:
- port: 80
targetPort: 80
[root@k8s-master mainfests]# dig -t A myapp-headless.default.svc.cluster.local. @10.96.0.10
NodePort
[root@master manifests]# vim myapp-service.yaml
apiVersion: v1
kind: Service
metadata:
name: myapp
namespace: default
spec:
type: NodePort
selector:
app: myapp
release: stabel
ports:
- name: http
port: 80
targetPort: 80
LoadBalancer
loadBalancer 和 nodePort 其实是同一种方式。区别在于 loadBalancer 比 nodePort 多了一步,就是可以调用 cloud provider 去创建 LB 来向节点导流
ExternalName
这种类型的 Service 通过返回 CNAME 和它的值,可以将服务映射到 externalName 字段的内容( 例如:hub.hongfu.com )。ExternalName Service 是 Service 的特例,它没有 selector,也没有定义任何的端口和 Endpoint。相反的,对于运行在集群外部的服务,它通过返回该外部服务的别名这种方式来提供服务
kind: Service
apiVersion: v1
metadata:
name: my-service-1
namespace: default
spec:
type: ExternalName
externalName: hub.hongfu.com
当查询主机 my-service.defalut.svc.cluster.local ( SVC_NAME.NAMESPACE.svc.cluster.local )时,集群的 DNS 服务将返回一个值 my.database.example.com 的 CNAME 记录。访问这个服务的工作方式和其他的相同,唯一不同的是重定向发生在 DNS 层,而且不会进行代理或转发
typora-root-url: Png
资料信息
Ingress-Nginx github 地址:https://github.com/kubernetes/ingress-nginx
Ingress-Nginx 官方网站:https://kubernetes.github.io/ingress-nginx/
部署 Ingress-Nginx
$ kubectl apply -f mandatory.yaml
$ kubectl apply -f service-nodeport.yaml
Ingress HTTP 代理访问
deployment、Service、Ingress Yaml 文件
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: nginx-dm
spec:
replicas: 2
template:
metadata:
labels:
name: nginx
spec:
containers:
- name: nginx
image: wangyanglinux/myapp:v1
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx-svc
spec:
ports:
- port: 80
targetPort: 80
protocol: TCP
selector:
name: nginx
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: nginx-test
spec:
rules:
- host: www1.hongfu.com
http:
paths:
- path: /
backend:
serviceName: nginx-svc
servicePort: 80
Ingress HTTPS 代理访问
创建证书,以及 cert 存储方式
openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=nginxsvc/O=nginxsvc"
kubectl create secret tls tls-secret --key tls.key --cert tls.crt
deployment、Service、Ingress Yaml 文件
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: nginx-test
spec:
tls:
- hosts:
- foo.bar.com
secretName: tls-secret
rules:
- host: foo.bar.com
http:
paths:
- path: /
backend:
serviceName: nginx-svc
servicePort: 80
Nginx 进行 BasicAuth
yum -y install httpd
htpasswd -c auth foo
kubectl create secret generic basic-auth --from-file=auth
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-with-auth
annotations:
nginx.ingress.kubernetes.io/auth-type: basic
nginx.ingress.kubernetes.io/auth-secret: basic-auth
nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required - foo'
spec:
rules:
- host: foo2.bar.com
http:
paths:
- path: /
backend:
serviceName: nginx-svc
servicePort: 80
Nginx 进行重写
名称 | 描述 | 值 |
---|---|---|
nginx.ingress.kubernetes.io/rewrite-target | 必须重定向流量的目标URI | 串 |
nginx.ingress.kubernetes.io/ssl-redirect | 指示位置部分是否仅可访问SSL(当Ingress包含证书时默认为True) | 布尔 |
nginx.ingress.kubernetes.io/force-ssl-redirect | 即使Ingress未启用TLS,也强制重定向到HTTPS | 布尔 |
nginx.ingress.kubernetes.io/app-root | 定义Controller必须重定向的应用程序根,如果它在'/'上下文中 | 串 |
nginx.ingress.kubernetes.io/use-regex | 指示Ingress上定义的路径是否使用正则表达式 | 布尔 |
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: nginx-test
annotations:
nginx.ingress.kubernetes.io/rewrite-target: http://foo.bar.com:31795/hostname.html
spec:
rules:
- host: foo10.bar.com
http:
paths:
- path: /
backend:
serviceName: nginx-svc
servicePort: 80