Kubernetes学习笔记
一、Kubernetes基础
1.简介:Kubernetes是Google开源的一个容器编排引擎,它支持自动化部署、大规模可伸缩、应用容器化管理等功能。在生产环境中部署一个应用程序时,通常要部署该应用的多个实例以便对应用请求进行负载均衡。在Kubernetes中,我们可以创建多个容器,每个容器里面运行一个应用实例,然后通过内置的负载均衡策略,实现对这一组应用实例的管理、发现、访问,而这些细节都不需要运维人员去进行复杂的手工配置和处理。
特点:
-
可移植: 支持公有云,私有云,混合云,多重云(multi-cloud)
-
可扩展: 模块化,插件化,可挂载,可组合
-
自动化: 自动部署,自动重启,自动复制,自动伸缩/扩展
2.相关组件介绍:
Master节点:整个集群的控制中枢
Kube-APIServer:集群的控制中枢,各个模块之间信息交互都需要通过APIServer,同时也是集群管理、资源配置、整个集群安全机制的入口。
Controller-Manager:集群的状态管理器,保证Pod或其他资源达到期望值,通过与APIServer进行通讯,在需要的时候创建、更新、删除它所管理的资源。
Scheduler:集群的调度中心,它根据指定的一系列条件,选择一个或一批最佳节点部署资源。
Etcd:键值数据库,保存持久化的集群信息,一般生产环境中建议部署三个或以上节点(奇数个)。
Node节点:工作节点(也称为Worker节点、minion节点)
Kubelet:负责监听、上报节点以及节点上pod的状态,与master节点通讯并管理节点上的pod。
Kube-proxy:负责pod之间的通讯和负载均衡,将指定的流量分发到后端正确的机器上。(查看kube-proxy工作模式:curl 127.0.0.1:port/proxyMode;工作模式1.IPVS:监听Master节点增加和删除server以及endpoint的消息,调用Netlink接口创建相应的IPVS规则;2.iptables:监听Master节点增加和删除以及endpoint的消息,对于每一个Service都会创建一个iptables规则,将service的clusterIP代理到后端对应的pod)
Calico:符合CNI标准的网络插件,给每个pod生成唯一的IP地址,并且把每个节点当作一个路由器。
Coredns:用于Kubernetes集群内部Service的解析,可以让pod把service名称解析成ip地址,然后通过service ip地址连接到对应的应用上。
metrics-server:统计容器资源指标
3.POD
Pod介绍:Pod是Kubernetes中最小的单元,它由一组、一个或多个容器组成,每个pod还包含了一个Pause容器,Pause容器是pod的父容器,主要负责僵尸进程的回收管理,并为多个容器共享pod中的存储、网络、PID、IPC等。
Pod yaml:
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: # 可选,容器启动执行的命令 ENTRYPOINT,arg-->cmdw
- sh
- -c
- echo "i am initContainer for init some configuration"
imager: busybox
imagerPullPolicy: IfNotPresent
name: init-container
container: # 必选,容器列表
- 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.uft8
resources: # 可选,资源限制和资源请求限制
limits: # 最大限制设置
cpu: 1000m
memory: 1024Mi
requests: # 启动所需的资源
cpu: 100m
memory: 512mi
startupProbe: # 可选,检测容器内进程是否完成启动。注意三种检查方式只能同时使用一种
httpGet: # httpGet检测方式,生产环境建议使用httpGet实现接口级别健康检查,健康检查由应用程序提供
path: /api/check # 检查路径
port: 80
readinessProbe: # 可选,检测容器内进程是否完成启动。注意三种检查方式只能同时使用一种
httpGet: # httpGet检测方式,生产环境建议使用httpGet实现接口级别健康检查,健康检查由应用程序提供
path: /api/check # 检查路径
port: 80
livenessProbe: # 可选,检测容器内进程是否完成启动。注意三种检查方式只能同时使用一种
exec: # 执行容器命令检测方式
command:
- cat
- /health
httpGet: # httpGet检测方式,生产环境建议使用httpGet实现接口级别健康检查,健康检查由应用程序提供
path: /api/check # 检查路径
port: 80
httpHeaders: # 检查请求的头
- name: end-user
value: Jason
tcpSocker: # 端口检测方式
port: 80
initialDelaySeconds: 60 # 初始化时间
timeoutSeconds: 2 # 超时时间
periodSeconds: 5 # 检测间隔
successThreshold: 1 # 检查成功为2次表示就绪
failureThreshold: 2 # 检测失败1次表示未就绪
lifecycle:
postStart: # 容器创建完成后执行的指令,可以是exec httpGet TCPSocker
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: xxxx
hostNetwork: false # 可选,主机模式,开启会占用主机端口
volumes: # 共享存储卷列表
- name: webroot # 名称,与上述对应
emptyDir: {} # 挂载目录
hostPath: # 挂载本机路径
path: /etc/hosts
#指定api版本标签
apiVersion: apps/v1
#定义资源的类型/角色,deployment为副本控制器
#此处资源类型可以是Deployment、Job、Ingress、Service等
kind: Deployment
#定义资源的元数据信息,比如资源的名称、namespace、标签等信息
metadata:
#定义资源的名称,在同一个namespace空间中必须是唯一的
name: nginx-test
lables:
app: nginx
#定义deployment资源需要的参数属性,诸如是否在容器失败时重新启动容器的属性
spec:
#定义副本数量
replicas: 3
#定义标签选择器
selector:
#定义匹配标签
matchLabels:
#需与后面的.spec.template.metadata.labels定义的标签保持一致
app: nginx
#定义业务模板,如果有多个副本,所有副本的属性会按照模板的相关配置进行匹配
template:
metadata:
#定义Pod副本将使用的标签,需与前面的.spec.selector.matchLabels定义的标签保持一致
labels:
app: nginx
spec:
#定义容器属性
containers:
#定义一个容器名,一个-name:定义一个容器
- name: nginx
#定义容器使用的镜像以及版本
image: nginx:1.15.4
ports:
#定义容器对外的端口
- containerPort: 80
pod探针:
StartupProbe: k8s1.16版本后新加的探测方式,用于判断容器内应用程序是否启动,如果配置了StartupProbe,就会禁止其他的探针,直到它检测成功为止,成功后不再探测。
LivenessProbe: 用于探测容器是否允许,如果探测失败,kubelet会根据配置的重启策略进行相应的处理。如没有配置该探针,默认success。
ReadinessProbe: 一般用于探测容器内的程序是否健康,它的返回值如是success,那么就代表容器已经完成启动,并且程序是可以接收流量的状态。
Pod探针的探测方式:
ExecAction:在容器内执行一个命令,如果返回值是0,则认为容器健康;
TCPSockerAction: 通过TCP连接容器端口,确认健康状态;
HTTPGetAction: 通过应用程序暴漏的api地址确认程序的健康状态(返回200~400)。
探针的参数配置:
initialDelaySeconds: 60 #初始化时间
timeoutSeconds: 2 #超时时间
periodSeconds: 5 #检测间隔
successThreshold: 1 #检测成功1次表示就绪
failureThreshold: 2 #检测失败2次表示未就绪
pod健康退出:
使用Prestop先去请求eureka接口,下线自己的ip地址和端口号,eureka从注册表中删除该应用的ip地址,然后在容器中进行sleep;kill操作。(查看事件event)
4.控制器:
Replication Controller:
概念:RC可确保Pod副本数达到期望值,也就是RC定义的数量。换句话说,RC可确保一个pod或一组同类pod总是可用。
如果存在的pod大于设定的值,则RC将终止额外的pod。如果太少,RC将启动更多的Pod用于保证达到期望值。与手动创建的pod不同的是,用RC维护的pod在失败、删除或终止后会自动替换。因此即使应用程序只需要一个pod,也应该使用RC或其他方式管理。RC类似于进程管理程序,但是RC不是监控单个节点上的各个进程,而是监视多个节点上的多个pod。RC是实现弹性伸缩、动态扩容和滚动升级的核心。
定义一个RC的示例如下:
apiVersion: v1
kind: ReplicationController
metadata:
name: my-nginx
spec:
replicas: 2
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: daocloud.io/library/nginx
ports:
- containerPort: 80
和定义一个pod的YAML文件相比,不同的只是kind的值为ReplicationController,replicas的值需要指定,pod的相关定义在template中,pod的名字不需要显式地指定,因为它们会在rc中创建并赋予名字
ReplicaSet:
概念:ReplicaSet是支持基于集合的标签选择器的下一代RC,它主要用作Deployment协调、删除和更新Pod,和RC唯一的区别是,RS支持标签选择器。在实际的应用中,虽然RS可以单独使用,但是一般建议使用Deployment来自动管理ReplicaSet,除非自定义的pod不需要更新或有其他编排等。
定义一个RS的示例如下:
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: frontend
spec:
replicas: 3
selector:
matchLabels:
tier: frontend
template:
metadata:
labels:
tier: frontend
spec:
containers:
- name: nginx
image: registry.cn-beijing.aliyuncs.com/google_registry/nginx:1.17
imagePullPolicy: IfNotPresent
ports:
- name: httpd
containerPort: 80
Deployment:
概念:用于部署无状态的服务,这个是最常用的控制器,企业内部无状态的微服务,比如configserver、zuul、springboot。他可以管理多个副本的pod实现无缝迁移、自动灾难恢复、一键回滚等功能。
Deployment示例:
apiVersion: apps/v1 # 指定api版本,此值必须在kubectl api-versions中
kind: Deployment # 指定创建资源的角色/类型
metadata: # 资源的元数据/属性
name: demo # 资源的名字,在同一个namespace中必须唯一
namespace: default # 部署在哪个namespace中
labels: # 设定资源的标签
app: demo
version: stable
spec: # 资源规范字段
replicas: 1 # 声明副本数目
revisionHistoryLimit: 3 # 保留历史版本
selector: # 选择器
matchLabels: # 匹配标签
app: demo
version: stable
strategy: # 策略
rollingUpdate: # 滚动更新
maxSurge: 30% # 最大额外可以存在的副本数,可以为百分比,也可以为整数
maxUnavailable: 30% # 在更新过程中能够进入不可用状态的 Pod 的最大值,可以为百分比,也可以为整数
type: RollingUpdate # 滚动更新策略
template: # 模版
metadata: # 资源的元数据/属性
annotations: # 自定义注解列表
sidecar.istio.io/inject: "false" # 自定义注解名字
labels: # 设定资源的标签
app: demo
version: stable
spec: # 资源规范字段
containers:
- name: demo # 容器的名字
image: demo:v1 # 容器使用的镜像地址
imagePullPolicy: IfNotPresent # 每次Pod启动拉取镜像策略,三个选择(Always、Never、IfNotPresent)# Always,每次都检查;#Never,每次都不检查(不管本地是否有);#IfNotPresent,如果本地有就不检查,如果没有就拉取
resources: # 资源管理
limits: # 最大使用
cpu: 300m # CPU,1核心 = 1000m
memory: 500Mi # 内存,1G = 1024Mi
requests: # 容器运行时,最低资源需求,也就是说最少需要多少资源容器才能正常运行
cpu: 100m
memory: 100Mi
livenessProbe: # pod 内部健康检查的设置
httpGet: # 通过httpget检查健康,返回200-399之间,则认为容器正常
path: /healthCheck # URI地址
port: 8080 # 端口
scheme: HTTP # 协议
# host: 127.0.0.1 # 主机地址
initialDelaySeconds: 30 # 表明第一次检测在容器启动后多长时间后开始
timeoutSeconds: 5 # 检测的超时时间
periodSeconds: 30 # 检查间隔时间
successThreshold: 1 # 成功门槛
failureThreshold: 5 # 失败门槛,连接失败5次,pod杀掉,重启一个新的pod
readinessProbe: # Pod 准备服务健康检查设置
httpGet:
path: /healthCheck
port: 8080
scheme: HTTP # 协议
# host: 127.0.0.1 # 主机地址
initialDelaySeconds: 30 # 表明第一次检测在容器启动后多长时间后开始
timeoutSeconds: 5 # 检测的超时时间
periodSeconds: 30 # 检查间隔时间
successThreshold: 1 # 成功门槛
failureThreshold: 5 # 失败门槛,连接失败5次,pod杀掉,重启一个新的pod
readinessProbe: # Pod 准备服务健康检查设置
httpGet:
path: /healthCheck
port: 8080
scheme: HTTP
initialDelaySeconds: 30
timeoutSeconds: 5
periodSeconds: 10
successThreshold: 1
failureThreshold: 5
#也可以用这种方法
#exec: 执行命令的方法进行监测,如果其退出码不为0,则认为容器正常
# command:
# - cat
# - /tmp/health
#也可以用这种方法
#tcpSocket: # 通过tcpSocket检查健康
# port: number
ports:
- name: http # 名称
containerPort: 8080 # 容器开发对外的端口
protocol: TCP # 协议
imagePullSecrets: # 镜像仓库拉取密钥
- name: harbor-certification
affinity: # 亲和性调试
nodeAffinity: # 节点亲和力
requiredDuringSchedulingIgnoredDuringExecution: # pod 必须部署到满足条件的节点上
nodeSelectorTerms: # 节点满足任何一个条件就可以
- matchExpressions: # 有多个选项,则只有同时满足这些逻辑选项的节点才能运行 pod
- key: beta.kubernetes.io/arch
operator: In
values:
- amd64
状态解析:
NAME :Deployment名称
READY :pod状态,已经Readly的个数
UP-TO-DATE :达到期望状态的副本个数
AVAILABLE :已经可以使用的副本个数
AGE :pod启动时间
CONTAINERS :容器名称
IMAGES :容器使用的镜像 SELECTOR :管理的pod的标签
升级回滚:
升级版本: kubectl set image deploy nginx nginx=nginx:1.16.2 –record
查看历史版本: kubectl rollout history deploy nginx
回滚上一版本: kubectl rollout undo deploy nginx
查看指定版本详细信息: kubectl rollout deploy nginx --revision=5
回滚到指定版本: kubectl rollout undo deploy nginx --to -revision=5
扩容缩容: kubectl scale –replicas=3 deployment nginx
暂停更新: kubectl rollout pause deployment nginx
开启更新: kubectl rollout resume deployment nginx
注意事项:
.spec.revisionHistoryLimit: 保留RS revision的个数,设置0则不保留历史数据
.spec.minReadySeconds: 可选参数,指定新创建的的pod在没有任何容器崩溃的情况下视为Ready最小的秒数,默认为0,即一旦被创建就视为可用
滚动更新策略:1.spec.strategy.type:更新deployment的方式(a.”默认”RolingUpdate:滚动更新,可以指定maxSurge(最大额外可以存在的副本数,可以为百分比,也可以为整数)和maxUnavailabe(在更新过程中能够进入不可用状态的 Pod 的最大值,可以为百分比,也可以为整数))
Recreate:重建,先删除旧的pod,再创建新的pod(不建议使用)
StatefulSet:
概念:RC、Deployment、DaemonSet都是面向无状态的服务,它们所管理的Pod的IP、名字,启停顺序等都是随机的,而StatefulSet是有状态的集合,管理所有有状态的服务,比如MySQL、MongoDB集群等。
StatefulSet本质上是Deployment的一种变体,它为了解决有状态服务的问题,它所管理的Pod拥有固定的Pod名称,启停顺序,在StatefulSet中,Pod名字称为网络标识(hostname),还必须要用到共享存储。
在Deployment中,与之对应的服务是Service,而在StatefulSet中与之对应的Headless service,Headless service,即无头服务,与service的区别就是它没有Cluster IP,解析它的名称时将返回该Headless Service对应的全部Pod的Endpoint列表。
除此之外,StatefulSet在Headless Service的基础上又为StatefulSet控制的每个Pod副本创建了一个DNS域名,这个域名的格式为:
$(podname).(headless server name)
$(podname).(headless server name).namespace.svc.cluster.local
特点:
Pod一致性:包含次序(启动、停止次序)、网络一致性。此一致性与Pod相关,与被调度到哪个node节点无关;
稳定的次序:对于N个副本的StatefulSet,每个Pod都在[0,N)的范围内递增分配一个数字序号,且是唯一的;
稳定的网络:Pod的hostname模式为 (statefulset名称)−(序号);
稳定的存储:通过VolumeClaimTemplate为每个Pod创建一个PV。删除、减少副本,不会删除相关的卷。
示例:
apiVersion: v1
kind: Service
metadata:
name: mysql
namespace: mysql-sts
labels:
app: mysql
spec:
ports:
- port: 3306
name: mysql
clusterIP: None
selector:
app: mysql
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql
namespace: mysql-sts
spec:
selector:
matchLabels:
app: mysql #必须匹配 .spec.template.metadata.labels
serviceName: "mysql" #声明它属于哪个Headless Service.
replicas: 3 #副本数
template:
metadata:
labels:
app: mysql # 必须配置 .spec.selector.matchLabels
spec:
terminationGracePeriodSeconds: 10
containers:
- name: mysql
image: www.my.com/sys/mysql:5.7
ports:
- containerPort: 3306
name: mysql
env:
- name: MYSQL_ROOT_PASSWORD
value: "123456"
volumeMounts:
- name: mysql-pvc
mountPath: /var/lib/mysql
volumeClaimTemplates: #可看作pvc的模板
- metadata:
name: mysql-pvc
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: "mysql-nfs-storage" #存储类名,改为集群中已存在的
resources:
requests:
storage: 1Gi
DaemonSet:
概念:守护进程集,缩写为DS,在所有节点或是所有匹配的节点中都部署pod。
例如:
节点日志收集:fluentd、filebeat
节点的网络插件:Calico
集群存储:ceph、qlusterd
节点的监控:node exporter
服务暴漏:ingress nginx
示例:
apiVersion: extensions/v1beta1
kind: DaemonSet
metadata: <Object>
spec: <Object>
minReadySeconds: <integer> #设置pod准备就绪的最小秒数
revisionHistoryLimit: <integer> #设置保留的历史版本个数,默认是10
selector: <Object> #pod标签选择器,匹配pod标签,默认使用pods的标签
matchLabels: <map[string]string>
key1: value1
key2: value2
matchExpressions: <[]Object>
operator: <string> -required- #设定标签键与一组值的关系,In, NotIn, Exists and DoesNotExist
key: <string> -required-
values: <[]string>
template: <Object> -required-
metadata:
labels:
key1: value1
key2: value2
spec:
containers: <[]Object> #容器配置
- name: <string> -required- #容器名、DNS_LABEL
image: <string> #镜像
imagePullPolicy: <string> #镜像拉取策略,Always、Never、IfNotPresent
ports: <[]Object>
- name: #定义端口名
containerPort: #容器暴露的端口
protocol: TCP #或UDP
volumeMounts: <[]Object>
- name: <string> -required- #设置卷名称
mountPath: <string> -required- #设置需要挂载容器内的路径
readOnly: <boolean> #设置是否只读
livenessProbe: <Object> #就绪探测
exec:
command: <[]string>
httpGet:
port: <string> -required-
path: <string>
host: <string>
httpHeaders: <[]Object>
name: <string> -required-
value: <string> -required-
scheme: <string>
initialDelaySeconds: <integer> #设置多少秒后开始探测
failureThreshold: <integer> #设置连续探测多少次失败后,标记为失败,默认三次
successThreshold: <integer> #设置失败后探测的最小连续成功次数,默认为1
timeoutSeconds: <integer> #设置探测超时的秒数,默认1s
periodSeconds: <integer> #设置执行探测的频率(以秒为单位),默认1s
tcpSocket: <Object> #TCPSocket指定涉及TCP端口的操作
port: <string> -required- #容器暴露的端口
host: <string> #默认pod的IP
readinessProbe: <Object> #同livenessProbe
resources: <Object> #资源配置
requests: <map[string]string> #最小资源配置
memory: "1024Mi"
cpu: "500m" #500m代表0.5CPU
limits: <map[string]string> #最大资源配置
memory:
cpu:
volumes: <[]Object> #数据卷配置
- name: <string> -required- #设置卷名称,与volumeMounts名称对应
hostPath: <Object> #设置挂载宿主机路径
path: <string> -required-
type: <string> #类型:DirectoryOrCreate、Directory、FileOrCreate、File、Socket、CharDevice、BlockDevice
- name: nfs
nfs: <Object> #设置NFS服务器
server: <string> -required- #设置NFS服务器地址
path: <string> -required- #设置NFS服务器路径
readOnly: <boolean> #设置是否只读
- name: configmap
configMap:
name: <string> #configmap名称
defaultMode: <integer> #权限设置0~0777,默认0664
optional: <boolean> #指定是否必须定义configmap或其keys
items: <[]Object>
- key: <string> -required-
path: <string> -required-
mode: <integer>
restartPolicy: <string> #重启策略,Always、OnFailure、Never
templateGeneration: <integer>
updateStrategy: <Object> #更新策略
rollingUpdate: <Object>
maxUnavailable: <string>
type: <string> #类型:滚动更新、在删除时更新
status: <Object>
注意事项:建议指定标签
更新策略updateStrategy:RolingUpdate:滚动更新
OnDelete:需要手动更新,建议使用该类型
Horizontal Pod Autoscaler:
概念:水平POD资源伸缩系统
HPA V1为稳定版本,支持根据CPU自动水平伸缩
HPA V2为beta版本,分为V2beta1(支持CPU、内存和自定义指标)V2beta2(支持CPU、内存、自定义指标Custom和额外指标ExternalMetrics)
示例:
kubectl run deployment nginx --requests=cpu=10m --imagx=nginx:1.12.1
kubectl expose deployment nginx --port=80
kubectl autoscale deployment nginx --cpu-percent=10 --min=1 --max=10
注意事项:
必须安装metrics-server或其他自定义的metrics-server
必须配置requests参数
不能扩容无法缩放的对象,如DaemonSet
5.标签
Label:对K8s的各种资源进行分类、分组,添加一个具有特别属性的标签
Selector:通过一个过滤的语法查找对应标签的资源
示例:
kubectl label pod pod_name app=xjw # 添加标签
kubectl get pod pod_name --show-lable # 查看标签
kubectl get pod pod_name -l app=xjw # 过滤标签
kubectl label pod pod_name app- # 删除标签
kubectl label pod pod_name app=xjw1 --overwrite # 修改标签
kubectl get pod pod_name -l ‘app in (xjw,xjw1)’ # 过滤标签
kubectl get pod pod_name -l app=xjw,app!=xjw1 # 过滤标签
6.Service
Service可以简单理解为逻辑上一种用于访问pod或其他应用的代理策略,其他pod可以通过这个service访问这个service代理的pod,相对于pod而言,它会有一个固定的名称,一旦创建就固定不变。
示例:
apiVersion: v1
kind: Service
metadata:
name: nginx-service
namespace: nginx-service
labels:
app: nginx-service
spec:
ports:
- name: HTTP
port: 80
protocol: TCP
targetPort: 80
selector:
app: nginx
sessionAffinity: None
type: ClusterIP
service外部代理:
使用场景:
1、需要在生产环境中使用某个固定的名称而非ip地址进行访问外部的服务;
2、需要Service指向另一个Namespace中或其他集群中的服务;
3、某个项目正在迁移k8s集群,但是一部分服务仍在集群外部,此时可以使用service代理K8s集群外部的服务;
外部代理示例:
创建无selector的service后,再创建endpoints
apiVersion: v1
kind: Endpoints
metadata:
name: nginx-service
namespace: nginx-service
labels:
app: nginx-service
spec:
- addresses:
- ip:10.0.0.0
ports:
- name: HTTP
port: 80
protocol: TCP
service代理域名示例:
apiVersion: v1
kind: Service
metadata:
name: nginx-service
namespace: nginx-service
labels:
app: nginx-service
spec:
type: ExternalName
externalName: www.baidu.com
service代理域名示例:
ClusterIP: 在集群内部使用,也是默认值
ExternalName: 通过service代理域名
NodePort: 在所有安装kube-proxy的节点上打开一个端口代理至后端pod,然后集群外部可以使用节点的IP地址和NodePort的端口号访问到集群pod的服务。端口范围默认是30000-32767
LoadBalancer: 使用云提供商的负载均衡器公开服务
7.Ingress:
Ingress为Kubernetes集群中的服务提供入口,可以提供负载均衡、SSL终止和基于名称的虚拟主机,在生产环境中常用的Ingress有Treafik、Nginx、HAProxy、Istio等。
基本概念
在Kubernetesv 1.1版中添加的Ingress用于从集群外部到集群内部Service的HTTP和HTTPS路由,流量从Internet到Ingress再到Services最后到Pod上,通常情况下,Ingress部署在所有的Node节点上。
Ingress可以配置提供服务外部访问的URL、负载均衡、终止SSL,并提供基于域名的虚拟主机。但Ingress不会暴露任意端口或协议。
示例:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: simple-fanout-example
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: foo.bar.com
http:
paths:
- path: /foo
backend:
serviceName: service1
servicePort: 4200
- path: /bar
backend:
serviceName: service2
servicePort: 8080
上述host定义该Ingress的域名,将其解析至任意Node上即可访问。
如果访问的是foo.bar.com/foo,则被转发到service1的4200端口。
如果访问的是foo.bar.com/bar,则被转发到service2的8080端口。
Ingress Rules
host:可选,一般都会配置对应的域名。
path:每个路径都有一个对应的serviceName和servicePort,在流量到达服务之前,主机和路径都会与传入请求的内容匹配。
backend:描述Service和Port的组合。对Ingress匹配主机和路径的HTTP与HTTPS请求将被发送到对应的后端。
默认后端
没有匹配到任何规则的流量将被发送到默认后端。默认后端通常是Ingress Controller的配置选项,并未在Ingress资源中指定。
Ingress类型
1. 单域名
单个域名匹配多个path到不同的service:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: simple-fanout-example
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: foo.bar.com
http:
paths:
- path: /foo
backend:
serviceName: service1
servicePort: 4200
- path: /bar
backend:
serviceName: service2
servicePort: 8080
此时,访问foo.bar.com/foo到service1的4200。访问foo.bar.com/bar到service2的8080。
2. 多域名
基于域名的虚拟主机支持将HTTP流量路由到同一IP地址的多个主机名:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: name-virtual-host-ingress
spec:
rules:
- host: foo.bar.com
http:
paths:
- backend:
serviceName: service1
servicePort: 80
- host: bar.foo.com
http:
paths:
- backend:
serviceName: service2
servicePort: 80
此时,访问foo.bar.com到service1,访问bar.foo.com到service2。
基于TLS的Ingress
首先创建证书,生产环境的证书为公司购买的证书:
kubectl -n default create secret tls nginx-test-tls --key=tls.key --cert=tls.crt
定义Ingress(此示例为Traefik,nginx-ingress将traefik改为nginx即可):
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: nginx-https-test
namespace: default
annotations:
kubernetes.io/ingress.class: traefik
spec:
rules:
- host: traefix-test.com
http:
paths:
- backend:
serviceName: nginx-svc
servicePort: 80
tls:
- secretName: nginx-test-tls
8.ConfigMap:
定义:持久化配置信息集合
基于目录创建:kubectl create cm cm_name --from-file=conf
基于文件创建:kubectl create cm cm_name --from-file=conf/redis.comf
基于文件并自定义创建:--from-file=conf=conf/redis.comf
基于ENV文件创建:kubectl create cm cm_name --from-env-file=conf/redis.conf
命令创建并指定:kubectl create cm cm_name --from-literal=password=123
动态更新:kubectl create cm cm_name --from-file=nginx.conf --dry-run=client -oyaml
| kubectl replace -f -
通过命令创建yaml:
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-service
data:
xxx1: ”1”
xxx2: ”2”
immutable: true # 持久化开关,设置后configmap无法被edit
Kubectl create -f cm.yaml
应用configmap:valueForm
用法:可将指定的configMap中的指定配置信息纳入pod中
.spec.containers.env.valueForm
configMapKeyRef:
name: cm_name
key: lives
应用configmap:envForm
用法:可将指定的configMap中所有配置信息加入pod中
.spec.containers.env.
envForm
configMapKeyRef:
name: cm_name
prefix: fromcm_
以文件的形式挂载configMap
用法:
volumes:
- name: redisconf
configmap:
name: redis-conf
items:
- key: redis.conf
path: redis.conf.rename # 重命名配置文件
mode: 0666 #key 配置文件权限
defaultMode: 0666 # configmap配置文件权限
containers:
- image: redis
name: redis-xjw
volumeMounts:
- name: redisconf
mountpath: /etc/config/nginx.conf # 挂载路径
subPath: nginx.config # subPath不覆盖源目录,指定挂载
8.secret:
定义:类似configmap,但存储配置信息时会加密
类型:
内置类型 | 用法 |
Opaque | 用户定义的任意数据 |
kubernetes.io/service-account-token | 服务账号令牌 |
kubernetes.io/dockercfg | ~/.dockercfg 文件的序列化形式 |
kubernetes.io/dockerconfigjson | ~/.docker/config.json 文件的序列化形式 |
kubernetes.io/basic-auth | 用于基本身份认证的凭据 |
kubernetes.io/ssh-auth | 用于 SSH 身份认证的凭据 |
kubernetes.io/tls | 用于 TLS 客户端或者服务器端的数据 |
bootstrap.kubernetes.io/token | 启动引导令牌数据 |
创建方式:
Yaml创建:
#密文创建
apiVersion: v1
kind: Secret
metadata:
name: mysecret
data:
username: YmFyCg==
password: asdaweq23
#明文创建
apiVersion: v1
kind: Secret
metadata:
name: mysecret
data:
username: root
password: 123456
文件创建(Opaque):
kubectl create secret generic db-user-pass \
--from-file=username=./username.txt \
--from-file=password=./password.txt
使用secret管理https证书:
Kubectl -n default create secret tls nginx-tls --key-tls --cert=tls.crt
用法:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: simple-fanout-example
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: https://foo.bar.com
http:
paths:
- path: /tomcat
backend:
serviceName: service1
servicePort: 443
tls
secretName: nginx-tls # 应用tls证书
volumes
使用volumes可以实现pod数据持久化存储,以及数据共享