相关概念:
kube-apierver:
控制平面组件,负责kubernetes api, 处理接受的请求工作
kube-controller-manager:
控制平面组件, 负责运行控制器进程
kube-scheduler:
控制平面组件, 负责见识新创建,未指定运行节点的pods,选择节点让pod运行
cloud-controller-manager:
控制平面组件,允许你将你的集群连接到云提供商的 API 之上, 并将与该云平台交互的组件同与你的集群交互的组件分离开来
Etcd:
后台数据库,高可用的键值存储
Kubelet:
kubelet 会在集群中每个节点(node)上运行。 它保证容器(containers)都运行在 Pod 中。
kubelet 接收一组通过各类机制提供给它的 PodSpecs, 确保这些 PodSpecs 中描述的容器处于运行状态且健康。 kubelet 不会管理不是由 Kubernetes 创建的容器。
Kubu-proxy:
是集群中每个节点(node)上所运行的网络代理, 实现 Kubernetes 服务(Service) 概念的一部分。
kube-proxy 维护节点上的一些网络规则, 这些网络规则会允许从集群内部或外部的网络会话与 Pod 进行网络通信。
coredns:
集群 DNS 是一个 DNS 服务器,和环境中的其他 DNS 服务器一起工作,它为 Kubernetes 服务提供 DNS 记录。
Kubernetes 启动的容器自动将此 DNS 服务器包含在其 DNS 搜索列表中。
dashboard:
Kubernetes 集群的通用的、基于 Web 的用户界面。 它使用户可以管理集群中运行的应用程序以及集群本身, 并进行故障排除。
dashboard 命令启用仪表板插件,并在默认的 Web 浏览器中打开代理。 你可以在仪表板上创建 Kubernetes 资源,例如 Deployment 和 Service。
如果你以 root 用户身份在环境中运行, 请参见使用 URL 打开仪表板。
默认情况下,仪表板只能从内部 Kubernetes 虚拟网络中访问。 dashboard 命令创建一个临时代理,使仪表板可以从 Kubernetes 虚拟网络外部访问。
要停止代理,请运行 Ctrl+Cdashboard 命令创建另一个代理来访问仪表板。
ingress controller:
Ingress 是反向代理规则,用来规定 HTTP/S 请求应该被转发到哪个 Service 上,比如根据请求中不同的 Host 和 url 路径让请求落到不同的 Service 上。
Ingress ControllerIngress ControllerIngress Controller 收到请求后就会根据这些规则将请求转发到对应的 Service。
Kubernetes 并没有自带 Ingress Controller,它只是一种标准,具体实现有多种,需要自己单独安装,常用的是 Nginx Ingress ControllerTraefik Ingress Controller。
一个集群中可以有多个 Ingress Controller, 在Ingress 中可以指定使用哪一个 Ingress Controller。
federation:
prometheus:
监控工具
elk:
日志收集套件(Elasticsearch+logStash+kibana)
Namespace:
命名空间为 Kubernetes 集群提供虚拟的隔离作用,Kubernetes 集群初始有两个命名空间,分别是默认命名空间 default 和系统命名空间 kube-system,除此以外,管理员可以可以创建新的命名空间满足需要。
名字空间适用于存在很多跨多个团队或项目的用户的场景。对于只有几到几十个用户的集群,根本不需要创建或考虑名字空间。
Node:
k8s 中通过将容器放入到节点 Node 上运行的 Pod 中来执行工作负载。 k8s 中的计算能力就是由 node 提供。
节点可以是物理机也可以是虚拟机,取决于集群的配置,通常 k8s 集群中,有越多的 node 节点,意味着有更强的计算能力。
Pod :
集群部署应用和服务的最小单元, 一个pod中可以部署多个容器
Pod 的设计理念是支持多个容器在一个 Pod 中共享网络地址和文件系统,可以通过进程间通信和文件共享这种简单高效的方式组合完成服务。Pod 对多容器的支持是 K8 最基础的设计理念。
ReplicationController(RC):
RC 是 k8s 集群中最早的保证 Pod 高可用的 API 对象。它的作用就是保证集群中有指定数目的 pod 运行。
当前运行的 pod 数目少于指定的数目,RC 就会启动新的 pod 副本,保证运行 pod 数量等于指定数目。
当前运行的 pod 数目大于指定的数目,RC 就会杀死多余的 pod 副本。
ReplicaSet:
RS 是新一代 RC,提供同样的高可用能力,区别主要在于 RS 后来居上,能支持更多种类的匹配模式。副本集对象一般不单独使用,而是作为 Deployment 的理想状态参数使用。
Deployment:
Deployment 提供了一种对 Pod 和 ReplicaSet 的管理方式,每一个 Deployment 都对应集群中的一次部署,是非常常见的 Kubernetes 对象。
Deployment 是一个比 RS 应用模式更广的 API 对象,可以用来创建一个新的服务,更新一个新的服务,也可以用来滚动升级一个服务。
滚动升级一个服务,滚动升级一个服务,实际是创建一个新的 RS,然后逐渐将新 RS 中副本数增加到理想状态,将旧 RS 中的副本数减小到 0 的复合操作;这样一个复合操作用一个 RS 是不太好描述的,所以用一个更通用的 Deployment 来描述。
Service:
RC、RS 和 Deployment 只是保证了支撑服务的微服务 Pod 的数量。但是没有解决如何访问这些服务的问题。
一个 Pod 只是一个运行服务的实例,随时可能在节点上停止,然后再新的节点上用一个新的 IP 启动一个新的 Pod,因此不能使用确定的 IP 和端口号提供服务。这对于业务来说,就不能根据 Pod 的 IP 作为业务调度。kubernetes 就引入了 Service 的概 念,它为 Pod 提供一个入口,主要通过 Labels 标签来选择后端Pod,这时候不论后端 Pod 的 IP 地址如何变更,只要 Pod 的 Labels 标签没变,那么 业务通过 service 调度就不会存在问题。
同时 service 对绑定的 Pod 提供了负载均衡的功能,我们业务直接使用 service 即可。
当声明Service的时候,会自动生成一个cluster IP,这个IP是虚拟IP。我们就可以通过这个IP来访问后端的Pod,当然,如果集群配置了DNS服务,比如现在 的CoreDNS,那么也可以通过Service的名字来访问,它会通过DNS自动解析Service的IP地址。
Service 对外暴露服务的方式
1、ClusterIP (默认) :在集群的内部 IP 上公开 Service 。这种类型使得 Service 只能从集群内访问,一般这种类型的 Service 上层会挂一个 Ingress,通过 Ingress 暴露服务;
2、NodePort:在每个选定 Node 的相同端口上公开 Service,使用 <NodeIP>:<NodePort> 即可从集群外部访问 Service;
3、LoadBalancer:使用云厂商的 K8S 集群,即可使用这种方式的暴露 Service,自建的服务一般不支持。使用 LoadBalancer ,会生成一个 IP 地址,通过这个即可访问 Service, 通知这个 IP 也是高可用的;
4、ExternalName: 通过返回带有该名称的 CNAME 记录,使用任意名称(由 spec 中的externalName指定)公开 Service。不使用代理。这种类型需要kube-dns的v1.7或更高版本。
什么是 CNAME:这种记录允许您将多个名字映射到同一台计算机。
例如:当您拥有多个域名需要指向同一服务器IP,此时您就可以将一个域名做A记录指向服务器IP,然后将其他的域名做别名(即CNAME)到A记录的域名上;那么当您的服务器IP地址变更时,您就可以不必对一个一个域名做更改指向了,只需要更改A记录的那个域名到服务器新IP上,其他做别名(即CNAME)的那些域名的指向将自动更改到新的IP地址上(以上操作均需要在DNS处执行)。
Service 是后端真实服务的抽象,一个 Service 可以代表多个相同的后端服务;
HPA(HorizontalPodAutoScale):
StatefullSet:
DaemonSet:
Job,Cronjob:
ConfigMap:
ConfigMap 是一种 API 对象,用来将非机密性的数据保存到键值对中。使用时,Pods 可以将其用作环境变量、命令行参数或者存储卷中的配置文件。ConfigMap 的主要作用就是为了让镜像和配置文件解耦,以便实现镜像的可移植性和可复用性。
- ConfigMap 需要在 Pod 启动前创建出来。
- 只有当 ConfigMap 和 Pod 处于同一 NameSpace(命名空间)时,Pod 才可以引用它。
- 当 Pod 对 ConfigMap 进行挂载(VolumeMount)操作时,在容器内部只能挂载为目录,并不能挂载为文件。
- 同时,当挂载已经存在的目录时,且目录内含有其它文件,ConfigMap 会将其覆盖掉。
操作实例: https://kubernetes.io/zh-cn/docs/tutorials/configuration/configure-redis-using-configmap/
部署
[minikube]
文档: https://minikube.sigs.k8s.io/docs/start/
安装:
windows:
直接选择.exe软件进行下载安装即可.
启动服务后包含组件:
- kube-apiserver-minikube
- kube-controller-managere-minikube
- kube-scheduler-minikube
- etcd-minikube
- coredns
- storage-provisioner
使用命令:
# 启动一个k8s集群
minikube.exe start
# 查看集群情况
minikube kubectl -- get po -A
or
kubectl get po -A
# 查看node节点
minikube node list
# 新增node节点
minikube node add
# 部署服务并暴露端口
kubectl create deployment hello-minikube image=kicbase/echo-server:1.0
kubectl expose deployment hello-minikube --type=NodePort --port=8080
# 启动服务(浏览器打开)
minikube service hello-minikube
# 将Service中端口向外映射,可通过7080进行访问
kubectl port-forward service/hello-minikube 7080:8080
# 关停
minikube stop
# 查看插件列表
minikube addons list
# 开启插件
minikube addons enable metrics-server
# 清理资源
kubectl delete service hello-node
kubectl delete deployment hello-node
---
# 查看集群时间
kubectl get events
# 打开dashboard
minikube dashboard
# 查看pod
kubectl get pod/pods
# Deployment
## 创建deployment
kubectl.exe create deployment hello-node --image=registry.k8s.io/e2e-test-images/agnhost:2.39 -- /agnhost netexec --http-port=8080
## 查看deployment
kubectl.exe get deployments
命令
kubectl
kubectl get - 列出资源
kubectl describe - 显示有关资源的详细信息
哪些容器以及使用了哪些镜像来构建这些容器
kubectl logs - 打印 Pod 中容器的日志
kubectl exec - 在 Pod 中的容器上执行命令
网络:
Kubernetes的Service网络。Service不仅实现了多Pod之间的负载均衡,而且还提供了虚拟IP,使Pod在集群内可以通过虚拟IP实现相互通信,而又不用担心Pod重启导致的IP地址变化。
但是,Service的虚拟IP只有在集群内部才有效,因此也被称为Cluster IP。对于集群以外的客户端,它们是无法通过Cluster IP访问到Service的。如果我们想从集群外部对Service进行访问,那就需要借助其他手段了。
Yaml
Kubernetes 支持 YAML 和 JSON格式 管理资源对象
- JSON 格式:主要用于 api 接口之间消息的传递
- YAML 格式:用于配置和管理,YAML是一种简洁的非标记性语言,内容格式人性化,较易读。
YAML语法格式:
- 大小写敏感;
- 使用缩进表示层级关系;不支持Tab键制表符缩进,只使用空格缩进;
- 缩进的空格数目不重要,只要相同层级的元素左侧对齐即可,通常开头缩进两个空格;
- 字符后缩进一个空格,如冒号,逗号,短横杆(-) 等
- "---"--- 隔开,就不用写多个 yaml 文件了。
- "#” 表示注释;
Deployment.yaml
文件包含四部分:
- apiVersion: 表示版本.版本查看命令 kubectl api-versions
- kind: 表示资源类型
- metadata: 表示元信息
- 资源规范字段
示例:
apiVersion: apps/v1 # 指定api版本,此值必须在kubectl api-versions中。业务场景一般首选”apps/v1“
kind: Deployment # 指定创建资源的角色/类型
metadata: # 资源的元数据/属性
name: demo # 资源的名字,在同一个namespace中必须唯一
namespace: default # 部署在哪个namespace中。不指定时默认为default命名空间
labels: # 自定义资源的标签
app: demo
version: stable
annotations: # 自定义注释列表
name: string
spec: # 资源规范字段,定义deployment资源需要的参数属性,诸如是否在容器失败时重新启动容器的属性(specification)
replicas: 1 # 声明副本数目
revisionHistoryLimit: 3 # 保留历史版本
selector: # 标签选择器
matchLabels: # 匹配标签,需与上面的标签定义的app保持一致
app: demo
version: stable
strategy: # 策略
type: RollingUpdate # 滚动更新策略
# ecreate:删除所有已存在的pod,重新创建新的
# RollingUpdate:滚动升级,逐步替换的策略,同时滚动升级时,支持更多的附加参数,
# 例如设置最大不可用pod数量,最小升级间隔时间等等
rollingUpdate: # 滚动更新
maxSurge: 1 # 滚动升级时最大额外可以存在的副本数,可以为百分比,也可以为整数
maxUnavailable: 0 # 在更新过程中进入不可用状态的 Pod 的最大值,可以为百分比,也可以为整数
template: # 定义业务模板,如果有多个副本,所有副本的属性会按照模板的相关配置进行匹配
metadata: # 资源的元数据/属性
annotations: # 自定义注解列表
sidecar.istio.io/inject: "false" # 自定义注解名字
labels: # 自定义资源的标签
app: demo # 模板名称必填
version: stable
spec: # 资源规范字段
restartPolicy: Always # Pod的重启策略。[Always | OnFailure | Nerver]
# Always :在任何情况下,只要容器不在运行状态,就自动重启容器。默认
# OnFailure :只在容器异常时才自动容器容器。
# 对于包含多个容器的pod,只有它里面所有的容器都进入异常状态后,pod才会进入Failed状态
# Nerver :从来不重启容器
nodeSelector: # 将该Pod调度到包含这个label的node上,仅能基于简单的等值关系定义标签选择器
caas_cluster: work-node
containers: # Pod中容器列表
- name: demo # 容器的名字
image: demo:v1 # 容器使用的镜像地址
imagePullPolicy: IfNotPresent # 每次Pod启动拉取镜像策略
# IfNotPresent :如果本地有就不检查,如果没有就拉取。默认
# Always : 每次都检查
# Never : 每次都不检查(不管本地是否有)
command: [string] # 容器的启动命令列表,如不指定,使用打包时使用的启动命令
args: [string] # 容器的启动命令参数列表
# 如果command和args均没有写,那么用Docker默认的配置
# 如果command写了,但args没有写,那么Docker默认的配置会被忽略而且仅仅执行.yaml文件的command(不带任何参数的)
# 如果command没写,但args写了,那么Docker默认配置的ENTRYPOINT的命令行会被执行,但是调用的参数是.yaml中的args
# 如果如果command和args都写了,那么Docker默认的配置被忽略,使用.yaml的配置
workingDir: string # 容器的工作目录
volumeMounts: # 挂载到容器内部的存储卷配置
- name: string # 引用pod定义的共享存储卷的名称,需用volumes[]部分定义的的卷名
mountPath: string # 存储卷在容器内mount的绝对路径,应少于512字符
readOnly: boolean # 是否为只读模式
- name: string
configMap: # 类型为configMap的存储卷,挂载预定义的configMap对象到容器内部
name: string
items:
- key: string
path: string
ports: # 需要暴露的端口库号列表
- name: http # 端口号名称
containerPort: 8080 # 容器开放对外的端口
# hostPort: 8080 # 容器所在主机需要监听的端口号,默认与Container相同
protocol: TCP # 端口协议,支持TCP和UDP,默认TCP
env: # 容器运行前需设置的环境变量列表
- name: string # 环境变量名称
value: string # 环境变量的值
resources: # 资源管理。资源限制和请求的设置
limits: # 资源限制的设置,最大使用
cpu: "1" # CPU,"1"(1核心) = 1000m。将用于docker run --cpu-shares参数
memory: 500Mi # 内存,1G = 1024Mi。将用于docker run --memory参数
requests: # 资源请求的设置。容器运行时,最低资源需求,也就是说最少需要多少资源容器才能正常运行
cpu: 100m
memory: 100Mi
livenessProbe: # pod内部的容器的健康检查的设置。当探测无响应几次后将自动重启该容器
# 检查方法有exec、httpGet和tcpSocket,对一个容器只需设置其中一种方法即可
httpGet: # 通过httpget检查健康,返回200-399之间,则认为容器正常
path: /healthCheck # URI地址。如果没有心跳检测接口就为/
port: 8089 # 端口
scheme: HTTP # 协议
# host: 127.0.0.1 # 主机地址
# 也可以用这两种方法进行pod内容器的健康检查
# exec: # 在容器内执行任意命令,并检查命令退出状态码,如果状态码为0,则探测成功,否则探测失败容器重启
# command:
# - cat
# - /tmp/health
# 也可以用这种方法
# tcpSocket: # 对Pod内容器健康检查方式设置为tcpSocket方式
# port: number
initialDelaySeconds: 30 # 容器启动完成后首次探测的时间,单位为秒
timeoutSeconds: 5 # 对容器健康检查等待响应的超时时间,单位秒,默认1秒
periodSeconds: 30 # 对容器监控检查的定期探测间隔时间设置,单位秒,默认10秒一次
successThreshold: 1 # 成功门槛
failureThreshold: 5 # 失败门槛,连接失败5次,pod杀掉,重启一个新的pod
readinessProbe: # Pod准备服务健康检查设置
httpGet:
path: /healthCheck # 如果没有心跳检测接口就为/
port: 8089
scheme: HTTP
initialDelaySeconds: 30
timeoutSeconds: 5
periodSeconds: 10
successThreshold: 1
failureThreshold: 5
lifecycle: # 生命周期管理
postStart: # 容器运行之前运行的任务
exec:
command:
- 'sh'
- 'yum upgrade -y'
preStop: # 容器关闭之前运行的任务
exec:
command: ['service httpd stop']
initContainers: # 初始化容器
- command:
- sh
- -c
- sleep 10; mkdir /wls/logs/nacos-0
env:
image: {{ .Values.busyboxImage }}
imagePullPolicy: IfNotPresent
name: init
volumeMounts:
- mountPath: /wls/logs/
name: logs
volumes:
- name: logs
hostPath:
path: {{ .Values.nfsPath }}/logs
volumes: # 在该pod上定义共享存储卷列表
- name: string # 共享存储卷名称 (volumes类型有很多种)
emptyDir: {} # 类型为emtyDir的存储卷,与Pod同生命周期的一个临时目录。为空值
- name: string
hostPath: # 类型为hostPath的存储卷,表示挂载Pod所在宿主机的目录
path: string # Pod所在宿主机的目录,将被用于同期中mount的目录
- name: string
secret: # 类型为secret的存储卷,挂载集群与定义的secre对象到容器内部
scretname: string
items:
- key: string
path: string
imagePullSecrets: # 镜像仓库拉取镜像时使用的密钥,以key:secretkey格式指定
- name: harbor-certification
hostNetwork: false # 是否使用主机网络模式,默认为false,如果设置为true,表示使用宿主机网络
terminationGracePeriodSeconds: 30 # 优雅关闭时间,这个时间内优雅关闭未结束,k8s 强制 kill
dnsPolicy: ClusterFirst # 设置Pod的DNS的策略。默认ClusterFirst
# 支持的策略:[Default | ClusterFirst | ClusterFirstWithHostNet | None]
# Default : Pod继承所在宿主机的设置,也就是直接将宿主机的/etc/resolv.conf内容挂载到容器中
# ClusterFirst : 默认的配置,所有请求会优先在集群所在域查询,如果没有才会转发到上游DNS
# ClusterFirstWithHostNet : 和ClusterFirst一样,不过是Pod运行在hostNetwork:true的情况下强制指定的
# None : 1.9版本引入的一个新值,这个配置忽略所有配置,以Pod的dnsConfig字段为准
affinity: # 亲和性调试
nodeAffinity: # 节点亲和性。满足特定条件的pod对象运行在同一个node上。效果同nodeSelector,但功能更强大
requiredDuringSchedulingIgnoredDuringExecution: # 硬亲和性
nodeSelectorTerms: # 节点满足任何一个条件就可以
- matchExpressions: # 有多个选项时,则只有同时满足这些逻辑选项的节点才能运行 pod
- key: beta.kubernetes.io/arch
operator: In
values:
- amd64
podAffinity: # pod亲和性。满足特定条件的pod对象运行在同一个node上
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- nginx
topologyKey: kubernetes.io/hostname
podAntiAffinity: # pod反亲和性。满足特定条件(相同pod标签)的pod对象不能运行在同一个node上
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- nginx
topologyKey: kubernetes.io/hostname # 反亲和性的节点标签 key
tolerations: # 污点容忍度。允许pod可以运行在匹配的污点上
- operator: "Equal" # 匹配类型。支持[Exists | Equal(默认值)]。Exists为容忍所有污点
key: "key1"
value: "value1"
effect: "NoSchedule" # 污点类型:[NoSchedule | PreferNoSchedule | NoExecute]
# NoSchedule :不会被调度
# PreferNoSchedule:尽量不调度
# NoExecute:驱逐节点
Service.yaml
Service是Kubernetes的核心概念,通过创建Service,可以为一组具有相同功能的容器应用提供一个统一的入口地址,并将请求负载分发到后端各个容器应用上。
apiVersion: v1 # 指定api版本,此值必须在kubectl api-versions中
kind: Service # 指定创建资源的角色/类型
metadata: # 资源的元数据/属性
name: demo # 资源的名字,在同一个namespace中必须唯一
namespace: default # 部署在哪个namespace中。不指定时默认为default命名空间
labels: # 设定资源的标签
- app: demo
annotations: # 自定义注解属性列表
- name: string
spec: # 资源规范字段
type: ClusterIP # service的类型,指定service的访问方式,默认ClusterIP。
# ClusterIP类型:虚拟的服务ip地址,用于k8s集群内部的pod访问,在Node上kube-porxy通过设置的iptables规则进行转发
# NodePort类型:使用宿主机端口,能够访问各个Node的外部客户端通过Node的IP和端口就能访问服务器
# LoadBalancer类型:使用外部负载均衡器完成到服务器的负载分发,需要在spec.status.loadBalancer字段指定外部负载均衡服务器的IP,并同时定义nodePort和clusterIP用于公有云环境。
clusterIP: string #虚拟服务IP地址,当type=ClusterIP时,如不指定,则系统会自动进行分配,也可以手动指定。当type=loadBalancer,需要指定
sessionAffinity: string #是否支持session,可选值为ClietIP,默认值为空。ClientIP表示将同一个客户端(根据客户端IP地址决定)的访问请求都转发到同一个后端Pod
ports:
- port: 8080 # 服务监听的端口号
targetPort: 8080 # 容器暴露的端口
nodePort: int # 当type=NodePort时,指定映射到物理机的端口号
protocol: TCP # 端口协议,支持TCP或UDP,默认TCP
name: http # 端口名称
selector: # 选择器。选择具有指定label标签的pod作为管理范围
app: demo
status: # 当type=LoadBalancer时,设置外部负载均衡的地址,用于公有云环境
loadBalancer: # 外部负载均衡器
ingress:
ip: string # 外部负载均衡器的IP地址
hostname: string # 外部负载均衡器的主机名
Ingress.yaml
apiVersion: extensions/v1beta1 # 创建该对象所使用的 Kubernetes API 的版本
kind: Ingress # 想要创建的对象的类别,这里为Ingress
metadata:
name: showdoc # 资源名字,同一个namespace中必须唯一
namespace: op # 定义资源所在命名空间
annotations: # 自定义注解
kubernetes.io/ingress.class: nginx # 声明使用的ingress控制器
spec:
rules:
- host: showdoc.example.cn # 服务的域名
http:
paths:
- path: / # 路由路径
backend: # 后端Service
serviceName: showdoc # 对应Service的名字
servicePort: 80 # 对应Service的端口