关键词网站查询,金融直播间网站开发,微信商城小程序开发教程,网站环境搭建好后怎么做网站Kubernetes入门学习#xff08;下#xff09; 文章目录 Kubernetes入门学习#xff08;下#xff09;运行有状态的应用ConfigMap与SecretConfigMapSecret 卷(Volume)StatefulSet(有状态应用集)Headless Service(无头服务)Mysql主从复制Port-forward端口转发Helm参考 运行有…Kubernetes入门学习下 文章目录 Kubernetes入门学习下运行有状态的应用ConfigMap与SecretConfigMapSecret 卷(Volume)StatefulSet(有状态应用集)Headless Service(无头服务)Mysql主从复制Port-forward端口转发Helm参考 运行有状态的应用
我们以MySQL数据库为例在kubernetes集群中运行一个有状态的应用。
部署数据库几乎覆盖了kubernetes中常见的对象和概念
配置文件–ConfigMap保存密码–Secret数据存储–持久卷(PV)和持久卷声明(PVC)动态创建卷–存储类(StorageClass)部署多个实例–StatefulSet数据库访问–Headless Service主从复制–初始化容器和sidecar数据库调试–port-forward部署Mysql集群–helm
ConfigMap与Secret
ConfigMap 在Docker中我们一般通过绑定挂载的方式将配置文件挂载到容器里。 在Kubernetes集群中容器可能被调度到任意节点配置文件需要能在集群任意节点上访问、分发和更新。 概述 ConfigMap 用来在键值对数据库(etcd)中保存非加密数据。一般用来保存配置文件。 ConfigMap 可以用作环境变量、命令行参数或者存储卷。 ConfigMap 将环境配置信息与 容器镜像 解耦便于配置的修改。 ConfigMap 在设计上不是用来保存大量数据的。 在 ConfigMap 中保存的数据不可超过 1 MiB。 超出此限制需要考虑挂载存储卷或者访问文件存储服务。 用法 ConfigMap配置示例Pod中使用ConfigMap apiVersion: v1
kind: Pod
metadata:name: mysql-podlabels:app: mysql
spec:containers:- name: mysqlimage: mysql:5.7env:- name: MYSQL_ROOT_PASSWORDvalue: 123456volumeMounts:- mountPath: /var/lib/mysqlname: data-volume- mountPath: /etc/mysql/conf.dname: conf-volumereadOnly: truevolumes:- name: conf-volumeconfigMap:name: mysql-config- name: data-volumehostPath:# directory location on hostpath: /home/mysql/data# this field is optionaltype: DirectoryOrCreate
---
apiVersion: v1
kind: ConfigMap
metadata:name: mysql-config
data:# 类属性键每一个键都映射到一个简单的值# player_initial_lives: 3# ui_properties_file_name: user-interface.properties# 类文件键mysql.cnf: |[mysqld]character-set-serverutf8mb4collation-serverutf8mb4_general_ciinit-connectSET NAMES utf8mb4[client]default-character-setutf8mb4[mysql]default-character-setutf8mb4通过kubectl edit cm mysql-config更改相关配置可以在mysql-pod中/etc/mysql/conf.d中查看变化
Secret 概述 Secret 用于保存机密数据的对象。一般由于保存密码、令牌或密钥等。 data字段用来存储 base64 编码数据。 stringData存储未编码的字符串。 Secret 意味着你不需要在应用程序代码中包含机密数据减少机密数据(如密码)泄露的风险。 Secret 可以用作环境变量、命令行参数或者存储卷文件。 用法 Secret配置示例将Secret用作环境变量 echo -n 123456 | base64
echo MTIzNDU2 | base64 --decodeapiVersion: v1
kind: Secret
metadata:name: mysql-password
type: Opaque
data:PASSWORD: MTIzNDU2Cg
---
apiVersion: v1
kind: Pod
metadata:name: mysql-pod
spec:containers:- name: mysqlimage: mysql:5.7env:- name: MYSQL_ROOT_PASSWORDvalueFrom:secretKeyRef:name: mysql-passwordkey: PASSWORDoptional: false # 此值为默认值表示secret已经存在了volumeMounts:- mountPath: /var/lib/mysqlname: data-volume- mountPath: /etc/mysql/conf.dname: conf-volumereadOnly: truevolumes:- name: conf-volumeconfigMap:name: mysql-config- name: data-volumehostPath:# directory location on hostpath: /home/mysql/data# this field is optionaltype: DirectoryOrCreate
---
apiVersion: v1
kind: ConfigMap
metadata:name: mysql-config
data:mysql.cnf: |[mysqld]character-set-serverutf8mb4collation-serverutf8mb4_general_ciinit-connectSET NAMES utf8mb4[client]default-character-setutf8mb4[mysql]default-character-setutf8mb4卷(Volume) 概述 将数据存储在容器中一旦容器被删除数据也会被删除。 卷是独立于容器之外的一块存储区域通过**挂载(Mount)**的方式供Pod中的容器使用。 使用场景 卷可以在多个容器之间共享数据。卷可以将容器数据存储在外部存储或云存储上。卷更容易备份或迁移。 常见卷类型 临时卷(Ephemeral Volume)与 Pod 一起创建和删除生命周期与 Pod 相同 emptyDir - 作为缓存或存储日志configMap 、secret、 downwardAPI - 给Pod注入数据 持久卷(Persistent Volume)删除Pod后持久卷不会被删除 本地存储 - hostPath、 local网络存储 - NFS 分布式存储 - Ceph(cephfs文件存储、rbd块存储) 投射卷(Projected Volumes)projected 卷可以将多个卷映射到同一个目录上 后端存储 一个集群中可以包含多种存储(如local、NFS、Ceph或云存储)。 每种存储都对应一个存储类StorageClass 存储类用来创建和管理持久卷是集群与存储服务之间的桥梁。 管理员创建持久卷(PV)时通过设置不同的StorageClass来创建不同类型的持久卷。 临时卷(EV) 与 Pod 一起创建和删除生命周期与 Pod 相同 emptyDir - 初始内容为空的本地临时目录 emptyDir会创建一个初始状态为空的目录存储空间来自本地的 kubelet 根目录或内存(需要将emptyDir.medium设置为Memory)。 通常使用本地临时存储来设置缓存、保存日志等。 例如将redis的存储目录设置为emptyDir apiVersion: v1
kind: Pod
metadata:name: redis-pod
spec:containers:- name: redisimage: redisvolumeMounts:- name: redis-storagemountPath: /data/redisvolumes:- name: redis-storageemptyDir: {}configMap - 为Pod注入配置文件 secret - 为Pod注入加密数据 注意这里的configMap和secret代表的是卷的类型不是configMap和secret对象。 删除Pod并不会删除ConfigMap对象和secret对象。 configMap卷和Secret卷是一种特殊类型的卷kubelet引用configMap和Secret中定义的内容在Pod所在节点上生成一个临时卷将数据注入到Pod中。删除Pod临时卷也会被删除。 临时卷位于Pod所在节点的/var/lib/kubelet/pods目录下。 持久卷(PV)与持久卷声明(PVC) 持久卷(PV) 持久卷(Persistent Volume)删除Pod后卷不会被删除 本地存储 hostPath - 节点主机上的目录或文件(仅供单节点测试使用多节点集群请用 local 卷代替) 挂载hostPath卷 hostPath的type值 DirectoryOrCreate目录不存在则自动创建。Directory挂载已存在目录。不存在会报错。FileOrCreate文件不存在则自动创建。 不会自动创建文件的父目录必须确保文件路径已经存在。File挂载已存在的文件。不存在会报错。Socket挂载 UNIX 套接字。例如挂载/var/run/docker.sock进程apiVersion: v1
kind: Pod
metadata:name: mysql-pod
spec:containers:- name: mysqlimage: mysql:5.7env:- name: MYSQL_ROOT_PASSWORDvalue: 123456ports:- containerPort: 3306volumeMounts:- mountPath: /var/lib/mysql #容器中的目录name: data-volumevolumes:- name: data-volumehostPath:# 宿主机上目录位置path: /home/mysql/datatype: DirectoryOrCreatelocal - 节点上挂载的本地存储设备(不支持动态创建卷) 网络存储NFS - 网络文件系统 (NFS) 分布式存储Ceph(cephfs文件存储、rbd块存储) 创建持久卷PV 创建持久卷(PV)是服务端的行为通常集群管理员会提前创建一些常用规格的持久卷以备使用。 hostPath仅供单节点测试使用当Pod被重新创建时可能会被调度到与原先不同的节点上导致新的Pod没有数据。多节点集群使用本地存储可以使用local卷 创建local类型的持久卷需要先创建存储类(StorageClass)。 本地存储类示例 # 创建本地存储类
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:name: local-storage
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: Immediatelocal卷不支持动态创建必须手动创建持久卷(PV)。 创建local类型的持久卷必须设置nodeAffinity(节点亲和性)。 调度器使用nodeAffinity信息来将使用local卷的 Pod 调度到持久卷所在的节点上不会出现Pod被调度到别的节点上的情况。 注意local卷也存在自身的问题当Pod所在节点上的存储出现故障或者整个节点不可用时Pod和卷都会失效仍然会丢失数据因此最安全的做法还是将数据存储到集群之外的存储或云存储上。 创建PV PV示例/local卷示例 # local-storage.yaml
apiVersion: v1
kind: PersistentVolume
metadata:name: local-pv-1
spec:capacity:storage: 4GivolumeMode: FilesystemaccessModes:- ReadWriteOncepersistentVolumeReclaimPolicy: DeletestorageClassName: local-storage #通过指定存储类来设置卷的类型local:path: /mnt/disks/ssd1 #手动创建nodeAffinity:required:nodeSelectorTerms:- matchExpressions:- key: kubernetes.io/hostnameoperator: Invalues:- k8s-node1卷的状态 Available可用-- 卷是一个空闲资源尚未绑定到任何Bound已绑定-- 该卷已经绑定到某个持久卷声明上Released已释放-- 所绑定的声明已被删除但是资源尚未被集群回收Failed失败-- 卷的自动回收操作失败。 卷模式 卷模式(volumeMode)是一个可选参数。 针对 PV 持久卷Kubernetes 支持两种卷模式volumeModes Filesystem文件系统 默认的卷模式。 Block块 将卷作为原始块设备来使用。 创建持久卷声明(PVC) 持久卷声明(PVC)是用户端的行为,用户在创建Pod时无法知道集群中PV的状态(名称、容量、是否可用等)用户也无需关心这些内容只需要在声明中提出申请集群会自动匹配符合需求的持久卷(PV)。 Pod使用持久卷声明(PVC)作为存储卷。 PVC示例 apiVersion: v1
kind: PersistentVolumeClaim
metadata:name: local-pv-claim
spec:storageClassName: local-storage # 与PV中的storageClassName一致accessModes:- ReadWriteOnceresources:requests:storage: 2Gi访问模式 ReadWriteOnce卷可以被一个节点以读写方式挂载并允许同一节点上的多个 Pod 访问。ReadOnlyMany卷可以被多个节点以只读方式挂载。ReadWriteMany卷可以被多个节点以读写方式挂载ReadWriteOncePod卷可以被单个 Pod 以读写方式挂载。 集群中只有一个 Pod 可以读取或写入该 PVC。 使用PVC作为卷 Pod 的配置文件指定了 PersistentVolumeClaim但没有指定 PersistentVolume。 对 Pod 而言PersistentVolumeClaim 就是一个存储卷。 PVC卷示例 apiVersion: v1
kind: Pod
metadata:name: mysql-pod
spec:containers:- name: mysqlimage: mysql:5.7env:- name: MYSQL_ROOT_PASSWORDvalue: 123456ports:- containerPort: 3306volumeMounts:- mountPath: /var/lib/mysql #容器中的目录name: local-mysql-datavolumes:- name: local-mysql-datapersistentVolumeClaim:claimName: local-pv-claim持久卷(PV)和持久卷声明(PVC) 持久卷PersistentVolumePV 是集群中的一块存储。可以理解为一块虚拟硬盘。 持久卷可以由管理员事先创建 或者使用存储类Storage Class根据用户请求来动态创建。 持久卷属于集群的公共资源并不属于某个namespace; 持久卷声明PersistentVolumeClaimPVC 表达的是用户对存储的请求。 PVC声明好比申请单它更贴近云服务的使用场景使用资源先申请便于统计和计费。 Pod 将 PVC 声明当做存储卷来使用PVC 可以请求指定容量的存储空间和访问模式 。PVC对象是带有namespace的。 存储类(StorageClass) 一个集群可以存在多个**存储类StorageClass**来创建和管理不同类型的存储。 每个 StorageClass 都有一个制备器Provisioner用来决定使用哪个卷插件创建持久卷。 该字段必须指定。 卷绑定模式 volumeBindingMode用于控制什么时候动态创建卷和绑定卷 Immediate立即创建创建PVC后立即创建PV并完成绑定WaitForFirstConsumer 延迟创建当使用该PVC的 Pod 被创建时才会自动创建PV并完成绑定 回收策略Reclaim Policy 回收策略告诉集群当用户删除PVC 对象时 从PVC中释放出来的PV将被如何处理。 删除Delete 如果没有指定默认为Delete 当PVC被删除时关联的PV 对象也会被自动删除。 保留Retain 当 PVC 对象被删除时PV 卷仍然存在数据卷状态变为已释放(Released)。 此时卷上仍保留有数据该卷还不能用于其他PVC。需要手动删除PV。
StatefulSet(有状态应用集) StatefulSet 是用来管理有状态的应用。一般用于管理数据库、缓存等。 与 Deployment 类似 StatefulSet用来管理 Pod 集合的部署和扩缩。 Deployment用来部署无状态应用。StatefulSet用来有状态应用。 创建StatefulSet StatefulSet配置模版 apiVersion: apps/v1
kind: StatefulSet
metadata:name: mysql
spec:selector:matchLabels:app: mysql # 必须匹配 .spec.template.metadata.labelsserviceName: dbreplicas: 3 # 默认值是 1minReadySeconds: 10 # 默认值是 0template:metadata:labels:app: mysql # 必须匹配 .spec.selector.matchLabelsspec:terminationGracePeriodSeconds: 10containers:- name: mysqlimage: mysql:5.7env:- name: MYSQL_ROOT_PASSWORDvalue: 123456ports:- containerPort: 3306volumeMounts:- mountPath: /var/lib/mysql #容器中的目录name: mysql-datavolumeClaimTemplates:- metadata:name: mysql-dataspec:accessModes:- ReadWriteOncestorageClassName: local-pathresources:requests:storage: 2Gi稳定的存储 在 StatefulSet 中使用 VolumeClaimTemplate为每个 Pod 创建持久卷声明(PVC)。 每个 Pod 将会得到基于local-path 存储类动态创建的持久卷(PV)。 Pod 创建(或重新调度时会挂载与其声明相关联的持久卷。 请注意当 Pod 或者 StatefulSet 被删除时持久卷声明和关联的持久卷不会被删除。 Pod标识 在具有 N 个副本的 StatefulSet中每个 Pod 会被分配一个从 0 到 N-1 的整数序号该序号在此 StatefulSet 上是唯一的。 StatefulSet 中的每个 Pod 主机名的格式为StatefulSet名称-序号。 上例将会创建三个名称分别为 mysql-0、mysql-1、mysql-2 的 Pod。
Headless Service(无头服务) 之前我们创建了三个各自独立的数据库实例mysql-0mysql-1mysql-2。 要想让别的容器访问数据库我们需要将它发布为Service但是Service带负载均衡功能每次请求都会转发给不同的数据库这样子使用过程中会有很大的问题。 无头服务Headless Service可以为 StatefulSet 成员提供稳定的 DNS 地址。 在不需要负载均衡的情况下可以通过指定 Cluster IP的值为 “None” 来创建无头服务。 注意:StatefulSet中的ServiceName必须要跟Service中的metadata.name一致 # 为 StatefulSet 成员提供稳定的 DNS 表项的无头服务Headless Service
apiVersion: v1
kind: Service
metadata:#重要这里的名字要跟后面StatefulSet里ServiceName一致name: dblabels:app: database
spec:ports:- name: mysqlport: 3306# 设置Headless ServiceclusterIP: Noneselector:app: mysql
---
apiVersion: apps/v1
kind: StatefulSet
metadata:name: mysql
spec:selector:matchLabels:app: mysql # 必须匹配 .spec.template.metadata.labelsserviceName: db #重要这里的名字要跟Service中metadata.name匹配replicas: 3 # 默认值是 1minReadySeconds: 10 # 默认值是 0template:metadata:labels:app: mysql # 必须匹配 .spec.selector.matchLabelsspec:terminationGracePeriodSeconds: 10containers:- name: mysqlimage: mysql:5.7env:- name: MYSQL_ROOT_PASSWORDvalue: 123456ports:- containerPort: 3306volumeMounts:- mountPath: /var/lib/mysqlname: mysql-datavolumeClaimTemplates:- metadata:name: mysql-dataspec:accessModes:- ReadWriteOncestorageClassName: local-pathresources:requests:storage: 2Gi稳定的网络ID
StatefulSet 中的每个 Pod 都会被分配一个StatefulSet名称-序号格式的主机名。
集群内置的DNS会为Service分配一个内部域名db.default.svc.cluster.local,它的格式为 服务名称.命名空间.svc.cluster.local。
Mysql主从复制 下面是部署一个读写分离Mysql数据库的示意图。 通过部署无头服务(Headless Service)将写操作指向固定的数据库。 部署一个Service用来做读操作的负载均衡。 数据库之间通过同步程序保持数据一致。 初始化容器(init containers)
初始化容器(Init Containers)是一种特殊容器它在 Pod 内的应用容器启动之前运行。
初始化容器未执行完毕或以错误状态退出Pod内的应用容器不会启动。
初始化容器需要在initContainers中定义与containers同级。
基于上面的特性初始化容器通常用于
生成配置文件执行初始化命令或脚本执行健康检查检查依赖的服务是否处于Ready或健康Health的状态 在本例子中有两个初始化容器。
init-mysql为MySQL实例分配server-id,并将mysql-0的配置文件设置为primary.cnf,其他副本设置为replica.cnfclone-mysql从前一个Pod中获取备份的数据文件放到自己的数据目录下 边车Sidecar
Pod中运行了2个容器MySQL 容器和一个充当辅助工具的 xtrabackup 容器我们称之为边车(sidecar)。 sidecar容器负责将备份的数据文件发送给下一个Pod并在副本服务器初次启动时使用数据文件完成数据的导入。
MySQL使用bin-log同步数据但是当数据库运行一段时间后产生了一些数据这时候如果我们进行扩容创建了一个新的副本有可能追溯不到bin-log的源头(可能被手动清理或者过期自动删除)因此需要将现有的数据导入到副本之后再开启数据同步sidecar只负责数据库初次启动时完成历史数据导入后续的数据MySQL会自动同步。
Port-forward端口转发
通常集群中的数据库不直接对外访问。
但是有时候我们需要图形化工具连接到数据库进行操作或者调试。
我们可以使用端口转发来访问集群中的应用。
kubectl port-forward可以将本地端口的连接转发给容器。
此命令在前台运行命令终止后转发会话将结束。
#主机端口在前容器端口在后
#如果主机有多个IP需要指定IP如不指定IP默认为127.0.0.1
kubectl port-forward pods/mysql-0 --address192.168.56.109 33060:3306Helm Helm 是一个 Kubernetes 应用的包管理工具类似于 Ubuntu 的 APT 和 CentOS 中的 YUM。 Helm使用chart 来封装kubernetes应用的 YAML 文件我们只需要设置自己的参数就可以实现自动化的快速部署应用。 安装Helm 下载安装包 https://github.com/helm/helm/releases https://get.helm.sh/helm-v3.10.0-linux-amd64.tar.gz mv linux-amd64/helm /usr/local/bin/helm三大概念 Chart 代表着 Helm 包。 它包含运行应用程序需要的所有资源定义和依赖相当于模版。类似于maven中的pom.xml、Apt中的dpkb或 Yum中的RPM。 Repository仓库 用来存放和共享 charts。 不用的应用放在不同的仓库中。 Release 是运行 chart 的实例。 一个 chart 通常可以在同一个集群中安装多次。 每一次安装都会创建一个新的 release**release name**不能重复。 Helm仓库 Helm有一个跟docker Hub类似的应用中心https://artifacthub.io/我们可以在里面找到我们需要部署的应用。 安装单节点Mysql #添加仓库
helm repo add bitnami https://charts.bitnami.com/bitnami
#查看chart
helm show chart bitnami/mysql
#查看默认值
helm show values bitnami/mysql #安装mysql
helm install my-mysql \
--set-string auth.rootPassword123456 \
--set primary.persistence.size2Gi \
bitnami/mysql#查看设置
helm get values my-mysql
#删除mysql
helm delete my-releaseHelm部署MySQL集群 安装过程中有两种方式传递配置数据 ●-f (或–values):使用 YAML 文件覆盖默认配置。可以指定多次优先使用最右边的文件。 ●–set:通过命令行的方式对指定项进行覆盖。 如果同时使用两种方式则 --set中的值会被合并到 -f中但是 --set中的值优先级更高。 # values.yaml
auth:rootPassword: 123456primary:persistence:size: 2Gienabled: truesecondary:replicaCount: 2persistence:size: 2Gienabled: truearchitecture: replicationhelm install my-db -f values.yaml bitnami/mysql参考
https://www.yuque.com/wukong-zorrm/qdoy5p/zrvene https://kubernetes.io/zh-cn/docs/concepts