Kubernetes基础
-
kube-apiserver
:集群的控制中枢,各个模块之间信息交互都需要经过api-server,同时也是集群管理、资源配合、整个集群安全机制的入口 -
Controller-Manager
:集群的状态管理器。保证Pod或者其他资源达到期望值。也是需要和apiserver
进行通信,在需要的时候创建、更新或删除它所管理的资源 -
Scheduler
:集群的调度中心,根据指定的一系列条件选择一个或一批最佳的节点部署我们的Pod。 -
etcd
:一个kv
数据库,强制性要求ssd
硬盘。保存一些集群的信息。一般是奇数个 -
Node
:工作节点 -
Kubelet
:负责监听节点上Pod的状态,同时负责上报节点和节点上Pod的状态,负责与Master节点通信,并管理节点上的Pod -
kube-proxy
:负责Pod之间的通信和负载均衡,将指定的流量分发到后端正确的机器上curl 127.0.0.1:10249/proxyMode
-
ipvs
:监听Master节点增加和删除service以及endpoint的消息,调用Netlink接口创建相应的IPVS规则,通过IPVS规则,将流量转发至相应的Pod上 -
iptables
:监听Master节点增加和删除service以及endpoint的消息,对于每一个service,他都会创建一个iptables规则。将service的clusterIP代理到后端对应的Pod上。 -
eBPF
:新的一种网络的东西 -
Calico
:符合CNI标准的网络插件,给每个Pod生成一个唯一的ip地址。并且把每个节点当做一个路由器。
# 在对应节点上
route -n
CoreDNS
:用于Kubernetes集群内部Service的解析,可以让Pod把Service名称解析成IP地址,然后通过Service的IP地址进行连接到对应的应用上
Pod是什么
-
PV/PVC
、RBAC
、storageClass
、ingressClass
是没有namespace
隔离的 -
Pod
是kubernetes
中最小的单元。它由一组、一个或多个容器组成,每个Pod运行包含了pause
容器。Pause
容器是pod
的父容器,主要负责僵尸进程的回收管理,通过Pause
容器可以使同一个Pod里面多个容器共享存储、网络、PID、IPC等
引入pod是因为后面不一定是docker,并且微服务的关联性会很强,每一个pod都有独立的ip,便于管理
定义一个Pod
apiVersion: v1 # 必选,API的版本号
kind: Pod # 必选,类型Pod
metadata: # 必选,元数据
name: nginx # 必选,符合RFC 1035规范的Pod名称
namespace: default # 可选,Pod所在的命名空间,不指定默认为default,可以使用-n 指定namespace
labels: # 可选,标签选择器,一般用于过滤和区分Pod
app: nginx
role: frontend # 可以写多个
annotations: # 可选,注释列表,可以写多个
app: nginx
spec: # 必选,用于定义容器的详细信息
initContainers: # 初始化容器,在容器启动之前执行的一些初始化操作
- command:
- sh
- -c
- echo "I am InitContainer for init some configuration"
image: busybox
imagePullPolicy: IfNotPresent # 镜像拉取策略
name: init-container
containers: # 必选,容器列表
- name: nginx # 必选,符合RFC 1035规范的容器名称
image: nginx:latest # 必选,容器所用的镜像的地址
imagePullPolicy: Always # 可选,镜像拉取策略
command: # 可选,容器启动执行的命令
- nginx
- -g
- "daemon off;"
workingDir: /usr/share/nginx/html # 可选,容器的工作目录
volumeMounts: # 可选,存储卷配置,可以配置多个
- name: webroot # 存储卷名称
mountPath: /usr/share/nginx/html # 挂载目录
readOnly: true # 只读
ports: # 可选,容器需要暴露的端口号列表
- name: http # 端口名称
containerPort: 80 # 端口号
protocol: TCP # 端口协议,默认TCP
env: # 可选,环境变量配置列表
- name: TZ # 变量名
value: Asia/Shanghai # 变量的值
- name: LANG
value: en_US.utf8
resources: # 可选,资源限制和资源请求限制
limits: # 最大限制设置
cpu: 1000m
memory: 1024Mi
requests: # 启动所需的资源
cpu: 100m
memory: 512Mi
# startupProbe: # 可选,检测容器内进程是否完成启动。注意三种检查方式同时只能使用一种。
# httpGet: # httpGet检测方式,生产环境建议使用httpGet实现接口级健康检查,健康检查由应用程序提供。
# path: /api/successStart # 检查路径
# port: 80
readinessProbe: # 可选,健康检查。注意三种检查方式同时只能使用一种。
httpGet: # httpGet检测方式,生产环境建议使用httpGet实现接口级健康检查,健康检查由应用程序提供。
path: / # 检查路径
port: 80 # 监控端口
livenessProbe: # 可选,健康检查
#exec: # 执行容器命令检测方式
#command:
#- cat
#- /health
#httpGet: # httpGet检测方式
# path: /_health # 检查路径
# port: 8080
# httpHeaders: # 检查的请求头
# - name: end-user
# value: Jason
tcpSocket: # 端口检测方式
port: 80
initialDelaySeconds: 60 # 初始化时间
timeoutSeconds: 2 # 超时时间
periodSeconds: 5 # 检测间隔
successThreshold: 1 # 检查成功为2次表示就绪
failureThreshold: 2 # 检测失败1次表示未就绪
lifecycle:
postStart: # 容器创建完成后执行的指令, 可以是exec httpGet TCPSocket
exec:
command:
- sh
- -c
- 'mkdir /data/ '
preStop:
httpGet:
path: /
port: 80
# exec:
# command:
# - sh
# - -c
# - sleep 9
restartPolicy: Always # 可选,默认为Always
#nodeSelector: # 可选,指定Node节点的标签
# region: subnet7
imagePullSecrets: # 可选,拉取镜像使用的secret,可以配置多个
- name: default-dockercfg-86258
hostNetwork: false # 可选,是否为主机模式,如是,会占用主机端口
volumes: # 共享存储卷列表
- name: webroot # 名称,与上述对应
emptyDir: {} # 挂载目录
#hostPath: # 挂载本机目录
# path: /etc/hosts
Pod探针
-
StartupProbe
:k8s 1.16后新加的探测方式,用于判断容器内应用程序是否已经启动。StartupProbe
成功后才会用另外两个探针方式。只执行一次 。如果配置了startupProbe,就会先禁止其他的探测,直到它成功为止,成功后将不在进行探测。主要用于程序启动特别忙的情况 -
LivenessProbe
:用于探测容器是否运行,如果探测失败,kubelet会根据配置的重启策略进行相应的处理。若没有配置该探针,默认就是success。 -
ReadinessProbe
:一般用于探测容器内的程序是否健康,它的返回值如果为success
,那么代表这个容器已经完成启动,并且程序已经是可以接受流量的状态
Pod 探针的检测方式
ExecAction
:在容器内执行一个命令,如果返回值为0,则认为容器健康TCPSocketAction
:通过TCP连接检查容器内的端口是否是通的,如果是通的就认为容器健康。HTTPGetAction
:通过应用程序暴露的API
地址来检查程序是否是正常的,如果状态码为200~400之间,则认为容器健康。
Pod退出流程
lifecycle
:容器的生命周期podStart
:容器创建完成之后,pod启动之前完成的命令 并不能保证命令的启动在启动之前,很少用preStop
:在容器被清理掉之前完成的命令
preStop
:先去请求Eureka
接口,把自己的IP地址和端口号,进行下限,euraka从注册表中删除该应用的IP地址,然后容器进行sleep 90操作
RC 和 RS
-
Replication Controller(复制控制器,RC)和 ReplicaSet(复制集,RS)是两种简单部署 Pod的方式。因为在生产环境中,主要使用更高级的 Deployment 等方式进行 Pod 的管理和部署,所以本节只对 Replication Controller 和 Replica Set 的部署方式进行简单介绍。
-
ReplicaSet 是支持基于集合的标签选择器的下一代 Replication Controller,它主要用作Deployment 协调创建、删除和更新 Pod,和 Replication Controller 唯一的区别是,ReplicaSet 支持标签选择器。在实际应用中,虽然 ReplicaSet 可以单独使用,但是一般建议使用 Deployment 来自动管理 ReplicaSet,除非自定义的 Pod 不需要更新或有其他编排等。 一般是使用 deployment 部署和管理ReplicaSet,再由 ReplicaSet 部署和管理 Pod
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: frontend
labels:
app: guestbook
tier: frontend
spec:
# modify replicas according to your case
replicas: 3
selector:
matchLabels:
tier: frontend
matchExpressions:
- {key: tier, operator: In, values: [frontend]}
template:
metadata:
labels:
app: guestbook
tier: frontend
spec:
containers:
- name: php-redis
image: gcr.io/google_samples/gb-frontend:v3
resources:
requests:
cpu: 100m
memory: 100Mi
env:
- name: GET_HOSTS_FROM
value: dns
# If your cluster config does not include a dns service, then to
# instead access environment variables to find service host
# info, comment out the 'value: dns' line above, and uncomment the
# line below.
# value: env
ports:
- containerPort: 80
Deployment [无状态的应用部署控制器]
用于部署无状态的服务,这个最常用的控制器。一般用于管理维护企业内部无状态的微服务,比如configserver、zuul、springboot。他可以管理多个副本的 Pod 实现无缝迁移、自动扩容缩容、自动灾难恢复、一键回滚等功能。
nginx-deploy.yaml
如下:
apiVersion: apps/v1 # 指定api版本,此值必须在kubectl api-versions中
kind: Deployment # 控制器类型,用来指定创建资源的角色/类型
metadata: # 资源的元数据/属性
annotations: # deployment 的注释
deployment.kubernetes.io/revision: "1"
creationTimestamp: "2020-09-19T02:41:11Z" # 创建时间
generation: 1
labels: # deployment本身的labels 设定资源的标签
app: nginx
name: nginx # deployment 的名字,在同一个 namespace 中必须唯一
namespace: default # deployment 部署的 namespace 的名字
spec: # 资源规范字段
progressDeadlineSeconds: 600
replicas: 1 # 副本数
revisionHistoryLimit: 3 # 历史记录保留的个数,默认是10个
selector: # 选择器
matchLabels: # replicas匹配pod的labels,必须和template。metadata.labels一致
app: nginx
strategy: # 策略
rollingUpdate: # 滚动升级的策略
maxSurge: 25% # 最大额外可以存在的副本数,可以为百分比,也可以为整数
maxUnavailable: 25% # 在更新过程中能够进入不可用状态的pod的最大值,可以为百分比,也可以为整数
type: RollingUpdate # 滚动更新策略
template: # template下面的就是pod的一些参数模版
metadata: # 资源的元数据/属性
creationTimestamp: null
annotations: # 自定义注解列表
sidecar.istio.io/inject: "false" # 自定义注解名字
labels: # pod的labels, 必须和spec.selectors.matchLabels一致。用来给replicas匹配的
app: nginx
spec: # pod资源规范字段
containers:
- image: nginx:1.15.2 # 镜像
imagePullPolicy: IfNotPresent # 每次pod启动拉取镜像的策略 三个选择 Always、Never、IfNotPresent Always,每次都检查;Never,每次都不检查(不管本地是否有);IfNotPresent,如果本地有就不检查,如果没有就拉取
name: nginx # 容器的名字
command: [string] #容器的启动命令列表,如不指定,使用打包时使用的启动命令
args: [string] #容器的启动命令参数列表
ports:
- name: http # 名称
containerPort: 8080 # 容器对外开放的端口
protocol: TCP # 协议
env: # 容器运行前需设置的环境变量列表
- name: string # 环境变量名称
value: string # 环境变量的值
workingDir: string # 容器的工作目录
volumeMounts: # 挂载到容器内部的存储卷配置
- name: string # 引用pod定义的共享存储卷的名称,需用volumes[]部分定义的的卷名
mountPath: string # 存储卷在容器内mount的绝对路径,应少于512字符
readOnly: boolean # 是否为只读模式
volumes: # 在该pod上定义共享存储卷列表
- name: string # 共享存储卷名称 (volumes类型有很多种)
emptyDir: {} # 类型为emtyDir的存储卷,与Pod同生命周期的一个临时目录。为空值
hostPath: string # 类型为hostPath的存储卷,表示挂载Pod所在宿主机的目录
path: string # Pod所在宿主机的目录,将被用于同期中mount的目录
secret: # 类型为secret的存储卷,挂载集群与定义的secret对象到容器内部
scretname: string
items:
- key: string
path: string
configMap: #类型为configMap的存储卷,挂载预定义的configMap对象到容器内部
name: string
items:
- key: string
path: string
resources: # 资源管理
limits: # 最大使用
cpu: 300m # CPU, 1核心 = 1000m
memory: 500Mi # 内存,1G = 1024 Mi
requests: # 容器运行时,最低资源需求,也就是说最少需要多少资源容器才能正常运行
cpu: 100m
memory: 100Mi
startupProbe: # 检测容器内进程是否完成启动。 exec httpGet TCPSocket 中任意一个
exec: #对Pod容器内检查方式设置为exec方式
command: [string] #exec方式需要制定的命令或脚本
tcpSocket: #对Pod内个容器健康检查方式设置为tcpSocket方式
port: number
httpGet: # httpGet检测方式,生产环境建议使用httpGet实现接口级健康检查,健康检查由应用程序提供。 返回200-399之间,则认为容器正常
path: /api/successStart # httpGet 检查的url路径
port: 80 # 端口
scheme: HTTP # 协议
HttpHeaders: # 需要添加请求头的时候使用
- name: string
value: string
livenessProbe: # pod 内部健康检查的设置 exec httpGet TCPSocket 中任意一个
exec: #对Pod容器内检查方式设置为exec方式
command: [string] #exec方式需要制定的命令或脚本
tcpSocket: #对Pod内个容器健康检查方式设置为tcpSocket方式
port: number
httpGet: # 通过httpget检查健康,返回200-399之间,则认为容器正常
path: /healthCheck # URI地址
port: 8080 # 端口
scheme: HTTP # 协议
initialDelaySeconds: 30 # 表明第一次检测在容器启动后多长时间后开始
timeoutSeconds: 5 # 检测的超时时间
periodSeconds: 30 # 检查间隔时间
successThreshold: 1 # 成功门槛 检查成功几次算完全成功
failureThreshold: 5 # 失败门槛,连接失败5次,pod杀掉,重启一个新的pod
readinessProbe: # Pod 的服务健康检查设置 exec httpGet TCPSocket 中任意一个
exec: #对Pod容器内检查方式设置为exec方式
command: [string] #exec方式需要制定的命令或脚本
tcpSocket: #对Pod内个容器健康检查方式设置为tcpSocket方式
port: number
httpGet: # 不止这一种方式,但一般比较推荐
path: /healthCheck
port: 8080
scheme: HTTP
initialDelaySeconds: 30 # 表明第一次检测在容器启动后多长时间后开始
timeoutSeconds: 5 # 检测的超时时间
periodSeconds: 30 # 检查间隔时间
successThreshold: 1 # 成功门槛 检查成功几次算完全成功
failureThreshold: 5 # 失败门槛,连接失败5次,pod杀掉,重启一个新的pod
lifecycle:
postStart: # 容器创建完成之后,pod启动之前完成的命令,
exec: # 可以是exec httpGet TCPSocket
command:
- sh
- -c
- 'mkdir /data/ '
preStop: # 在容器被清理掉之前完成的命令
exec: # 可以是exec httpGet TCPSocket
command: ['sh -c sleep 9']
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
dnsPolicy: ClusterFirst
restartPolicy: Always # Pod的重启策略 Always表示一旦不管以何种方式终止运行,kubelet都将重启 OnFailure表示只有Pod以非0退出码退出才重启 Nerver表示不再重启该Pod
nodeSelector: obeject # 设置NodeSelector表示将该Pod调度到包含这个label的node上,以key:value的格式指定
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30
StatefulSet [有状态的应用部署控制器]
StatefulSet(有状态集,缩写为 sts)常用于部署有状态的且需要有序启动的应用程序,比如在进行 SpringCloud 项目容器化时,Eureka 的部署是比较适合用 StatefulSet 部署方式的,可以给每个 Eureka 实例创建一个唯一且固定的标识符,并且每个 Eureka 实例无需配置多余的 Service,其余 Spring Boot 应用可以直接通过 Eureka 的 Headless Service 即可进行注册
DaemonSet [守护进程集控制器]
守护进程集,缩写为 ds,在所有节点或者是匹配的节点上都部署一个 Pod
- 运行集群存储的 daemon,比如 ceph 或者 glusterd
- 节点的 CNI 网络插件,calico
- 节点日志的收集:fluentd 或者是 filebeat
- 节点的监控:node exporter
- 服务暴露:部署一个 ingress nginx