k8s_day10_01
1、k8应用部署管理
正常情况下,在k8s 部署一个复杂应用也不是一个应用。我们也需要在k8s 上做应用部署管理:组织一个生态圈内的多个组件为一体,统一进行管理。
在linux 系统上最初安装软件的方式 就是编译安装,需要各种二进制文件、帮助文件、配置文件库文件 放在指定的目录下, 特别费事,后来产生了各种应用安装管理工具rpm 、deb . 在k8s 上应用部署,也需要管理工具。在k8 上部署应用时,k8s 原生的 可以被kubectl 所使用的 工具 叫kustomize。
kustomize 虽然有不足的地方 ,但是它提供了声明式配置管理。(算的上是新出现的工具 v1.14版本才出现)
另外一个就是第三方管理工具 helm, helm 本身特别类似于deb、rpm 管理的前端工具yum 、apt
但是使用apt yum 工具 需要解决依赖关系的库 repo, helm 依赖的底层包管理工具 叫chart.
chart 是部署一个应用程序所需要依赖的配置清单集合。 例如部署prothemeus 需要 svc、cm、controller、secret 以及各种应用的yaml。 把这些清单打包在一起就叫chart ,而如果把这些清单都写死了,就只能够应用到一种部署场景,所以在chart 当中还有大量的模板存在 这些模板代表着 资源名称都不是固定的,而是基于模板当中传递的参数发生改变。
这些chart 不用自己不用自己写,来自chart Hub(chart 仓库 )
helm 工具可以把chart拖下来,根据我们的需要改个名之类的 就能把程序部署起来。 部署 prothemeus 时,只需prothemeus chart 就行。但是这不足以反映helm 的复杂程度,prothemeus 是有状态应用,有状态应用有2种部署方式:
1、直接使用k8s 提供的资源类型statefulset 来进行管理,但是它所能提供的功能特性是极其有限的
2、第三方提供的operator。 部署prothemeus 时,不是直接部署prothemeus ,而是部署prothemeus operator, 在 operator 之上再写清单部署prothemeus 集群
helm 已经很成熟了,kustomize出现的时间很短,但是提供了 我们自己打包管理应用程序时一个有效的、不依赖第三方软件的途径。
2、kustomize
Kustomize的核心目标在于为管理的应用生成资源配置,而这些资源配置中定义了资源的期望状态,在具体实现上,它通过kustomization.yaml文件组合和(或)叠加多种不同的来源的资源配置来生成。
Kustomize将一个特定应用的配置保存于专用的目录中,且该目录中必须有一个名为kustomization.yaml的文件作为该应用的核心控制文件。由以下kustomization.yaml文件的格式说明可以大体看出,Kustomize可以直接组合由resources字段中指定资源文件作为最终配置,也可在它们的基础上进行额外的修订,例如添加通用标签和通用注解、为各个资源添加统一的名称前缀或名称后缀、改动Pod模板中的镜像文件及向容器传递变量等。
3、kustomize 规范
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources <[]string> # 待定制的原始资源配置文件列表(部署一个程序所需要的各种配置清单),将由kustomize按顺序处理
namespace <string> # 设定所有名称空间级别资源所属的目标名称空间
commonLabels <map[string]string> # 添加到所有资源的通用标签,包括Pod模板及相关的
# 相关的标签选择器
commonAnnotations <map[string]string> # 添加到所有资源的通用注解
namePrefix <string> # 统一给所有资源添加的名称前缀
nameSuffix <string> # 统一给所有资源添加的名称后缀
images <[]Image> # 将所有Pod模板中的符合name字段条件镜像文件修改为指定的镜像
- name <String> # 资源清单中原有的镜像名称,即待替换的镜像
nameName <String> # 要使用的新镜像名称
newTag <String> # 要使用的新镜像的标签
digest <String> # 要使用的新镜像的sha256校验码
vars <[]Var> # 指定可用于替换Pod容器参数中变量的值或容器环境变量的值
- name <String> # 变量的名称,支持以“$(name)”格式进行引用
objref <String> # 包含了要引用的目标字段的对象的名称
fieldref <String> # 引用的字段名称,默认为metadata.name
4、示例1:基本用法
添加标签、注解
kustomize-demo应用 目录下有3个文件 。一个kustomization.yaml 2个resource
[root@node01 kustomize-demo]# ls
deploy-demoapp.yaml kustomization.yaml service-demoapp.yaml
查看kustomization.yaml
[root@node01 kustomize-demo]# cat kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deploy-demoapp.yaml
- service-demoapp.yaml
commonLabels:
generated-by: kustomize
2个 resource 的配置
[root@node01 kustomize-demo]# cat deploy-demoapp.yaml service-demoapp.yaml
# VERSION: demoapp version
# Maintainer: MageEdu <mage@magedu.com>
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: demoapp
spec:
replicas: 1
selector:
matchLabels:
app: demoapp
template:
metadata:
labels:
app: demoapp
spec:
containers:
- name: demoapp
image: ikubernetes/demoapp:v1.0
ports:
- containerPort: 80
name: http
kind: Service
apiVersion: v1
metadata:
name: demoapp
spec:
selector:
app: demoapp
ports:
- name: http
protocol: TCP
port: 80
targetPort: 80
[root@node01 kustomize-demo]#
应用
干跑并且打印到屏幕上,发现每个资源都打上了generated-by: kustomize 标签
[root@node01 kustomize]# kubectl apply -k ./kustomize-demo --dry-run=client -oyaml
kustomize 是做为kubectl插件所使用的, 所以用-k 选项。 后面接kustomization.yaml 的父目录名称
除了打标签外,kustomize 还提供了高级功能:生成注解、通过重载的方式复用配置
假如我想把demoapp 分别部署到3个不同的环境当中,该如何做? 每个环境当中要求的资源限制都不一样。最好的方式就是复用:定义一个基础的配置,然后为每一个环境做单独的添加 。 类似shell 脚本的source 命令
kustomise 提供的第二个功能特性就是基础代码的复用功能。
5.1、示例2:高级特性一:base 扩展引用
[root@node01 demoapp]# ls
base prod staging test
如图 ,demoapp 下4个目录。 base 是基础目录。另外3个目录 的 可以通过bases
选项引用 base目录的资源
eg1:
[root@node01 demoapp]# cat test/
kustomization.yaml namespace.yaml
[root@node01 demoapp]# ls test/
kustomization.yaml namespace.yaml
[root@node01 demoapp]# cat test/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
bases:
- ../base/
resources:
- namespace.yaml
namespace: test
namespace:
environment: test
commonAnnotations:
ilinux.io/app: "demoapp"
images:
- name: "ikubernetes/demoapp"
newTag: "v1.1"
5.2、示例3:高级特性二:配置生成器
生成cm、secret 资源。 比靠resources 直接引入yaml 文件方便
configMapGenerator <[]ConfigMapGeneratorArgs> # ConfigMap资源生成器列表
- name <String> # ConfigMap资源的名称,会受到namePrefix和nameSuffix的影响
namespace <String> # 资源所在的名称空间,会覆盖kustomize级别的名称空间设定
behavior <String> # 与上级同名资源的合并策略,可用取值为create/replace/merge;
files <[]String> # 从指定的路径加载文件生成ConfigMap,要使用当前项目的相对路径
literals <[]String> # 从指定的“key=value”格式的直接值生成ConfigMap
env <String> # 从指定的环境变量文件中加载“key=value”格式的环境变量为资源数据
secretGenerator <[]secretGeneratorArgs> # Secret资源生成器列表
- name <String> # Secret资源的名称,会受到namePrefix和nameSuffix的影响
namespace <String> # 资源所在的名称空间,会覆盖kustomize级别的名称空间设定
behavior <String> # 与上级同名资源的合并策略,可用取值为create/replace/merge
files <[]String> # 从指定的路径加载文件生成Secret,起始于当前项目的相对路径
literals <[]String> # 从指定的“key=value”格式的直接值生成Secret
type <String> # Secret资源的类型,且“kubernetes.io/tls”有特殊的键名要求
generatorOptions <GeneratorOptions> # 当前kustomization.yaml中的ConfigMap
# 和Secret生成器专用的选项
labels <map[String]String> # 当前kustomization.yaml中所有生成资源添加的标签
annotations <map[String]String> # 为生成所有资源添加的注解
disableNameSuffixHash <Boolean> # 是否禁用hash名称后缀,默认为启用
[root@node01 staging]# cat kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
bases:
- ../base/
resources:
- namespace.yaml
namespace: staging
commonLabels:
environment: staging
commonAnnotations:
ilinux.io/app: "demoapp"
configMapGenerator:
- name: demoapp-conf
literals:
- HOST="0.0.0.0"
- PORT="8080"
secretGenerator:
- name: demoapp-ssl
files:
- secrets/tls.crt
- secrets/tls.key
type: "kubernetes.io/tls"
generatorOptions:
disableNameSuffixHash: true
5.3、示例4:高级特性三 打补丁
打补丁的方式有2种。
一个是补丁文件的内容是 纯补丁 ,根据匹配的标签ns 来匹配需要打补丁的资源(patchesStrategicMerge )
还有一个是补丁文件的内容是 部分资源的特定片段(足以指明特定资源)+ 补丁内容, 描述了什么什么补丁打到哪去(patchesJson6902)
patchesJson6902 <[]Json6902> # 由各待补对象及其补丁文件所组成的列表
path <String> # 补丁文件,不含有目标资源对象的信息,支持json或yaml格式
target <Target> # 待补资源对象
group <String> # 资源所属的群组
version <String> # API版本
kind <String> # 资源类型
name <String> # 资源对象的名称
namespace <string> # 资源对象所属的名称空间
patchesStrategicMerge <[]string> # 将补丁补到匹配的资源之上,匹配的方式是根据资源
# Group/Version/Kind + Name/Namespace判断
eg:
[root@node01 prod]# ls
kustomization.yaml namespace.yaml patches secrets
[root@node01 prod]# cat kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
bases:
- ../base/
resources:
- namespace.yaml
namespace: prod
commonLabels:
environment: prod
commonAnnotations:
ilinux.io/app: "demoapp"
configMapGenerator:
- name: demoapp-conf
literals:
- host="0.0.0.0"
- port="8080"
secretGenerator:
- name: demoapp-ssl
files:
- secrets/tls.crt
- secrets/tls.key
type: "kubernetes.io/tls"
generatorOptions:
disableNameSuffixHash: true
patchesStrategicMerge:
- patches/demoapp-add-requests-and-limits.yaml
- patches/demoapp-add-configmap-and-secret.yaml
patchesJson6902:
- target:
version: v1
kind: Service
name: demoapp
path: patches/patch-service-demoapp-targetport-8080.yaml