调整结构
@ -37,7 +37,7 @@ description: Kubernetes 免费教程
|
||||
* [控制器 - 概述](/learning/k8s-intermediate/workload/workload.html)
|
||||
* [控制器 - Deployment](/learning/k8s-intermediate/workload/wl-deployment/)
|
||||
* [控制器 - StatefulSet](/learning/k8s-intermediate/workload/wl-statefulset/)
|
||||
* [控制器 - DaemonSet](/learning/k8s-intermediate/workload/wl-daemonset/) <Badge text="正在撰写" type="warn"/>
|
||||
* [控制器 - DaemonSet](/learning/k8s-intermediate/workload/wl-daemonset/)
|
||||
* [控制器 - Job](/learning/k8s-intermediate/workload/wl-job/) <Badge text="正在撰写" type="warn"/>
|
||||
* [控制器 - CronJob](/learning/k8s-intermediate/workload/wl-cronjob/) <Badge text="正在撰写" type="warn"/>
|
||||
* 服务发现、负载均衡、网络
|
||||
@ -58,12 +58,19 @@ description: Kubernetes 免费教程
|
||||
* [污点和容忍 taints and toleration](/learning/k8s-intermediate/config/taints-and-toleration.html) <Badge text="正在撰写" type="warn"/>
|
||||
* [Secrets](/learning/k8s-intermediate/config/secret.html) <Badge text="正在撰写" type="warn"/>
|
||||
|
||||
## **Kubernetes 高级**
|
||||
|
||||
* Kubernetes 日志可视化
|
||||
* Kubernetes 监控
|
||||
* Kubernetes 联邦
|
||||
|
||||
## **Kubernetes 实战**
|
||||
|
||||
[从微服务视角理解 Kubernetes](/learning/k8s-practice/micro-service/kuboard-view-of-k8s.html)
|
||||
|
||||
在 Kubernetes 上部署 Spring Cloud 微服务:
|
||||
|
||||
* [概述](/micro-service/spring-cloud/)
|
||||
* [概述](/learning/k8s-practice/spring-cloud/)
|
||||
* [部署服务注册中心]
|
||||
* [部署数据库]
|
||||
* [部署微服务]
|
||||
|
||||
6
learning/k8s-advanced/federation/index.md
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
layout: LearningLayout
|
||||
description: 本文描述了如何配置 Kubernetes 联邦
|
||||
---
|
||||
|
||||
# Kubernetes 联邦
|
||||
6
learning/k8s-advanced/logging/index.md
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
layout: LearningLayout
|
||||
description: 本文描述了如何配置 Kubernetes 日志
|
||||
---
|
||||
|
||||
# Kubernetes 日志
|
||||
6
learning/k8s-advanced/monitor/index.md
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
layout: LearningLayout
|
||||
description: 本文描述了如何配置 Kubernetes 监控
|
||||
---
|
||||
|
||||
# Kubernetes 监控
|
||||
23
learning/k8s-intermediate/workload/pod-kuboard.md
Normal file
@ -0,0 +1,23 @@
|
||||
---
|
||||
description: 本文描述了 Kuboard 如何处理 Kubernetes 容器组
|
||||
---
|
||||
|
||||
# 容器组 - Kuboard
|
||||
|
||||
## 通过 Kuboard 创建容器组
|
||||
|
||||
由于在 Kubernetes 中,任何时候都是不推荐用户直接创建容器组,而是应该通过控制器创建容器组,Kuboard 管理工具并不提供直接创建容器组的界面,而是通过 **工作负载编辑器** 创建 Deployment、StatefulSet、DaemonSet 等方式来创建容器组。
|
||||
|
||||
在 Kuboard **工作负载编辑器** 中,容器组的概念处于如下图所示的位置:
|
||||
|
||||
在 Kuboard **工作负载编辑器** 界面中,容器组的 template 由界面中的如下几个部分指定:
|
||||
|
||||
## 通过 Kuboard 查看容器组
|
||||
|
||||
Kuboard 中,有两种方式可以查看容器组的信息:
|
||||
* 通过 **工作负载编辑器** 显示界面查看
|
||||
* 通过 **容器组列表** 查看
|
||||
|
||||
## 工作负载编辑器
|
||||
|
||||
## 容器组列表
|
||||
@ -0,0 +1,44 @@
|
||||
---
|
||||
layout: LearningLayout
|
||||
description: 本文描述了 Kubernetes DaemonSet 的概念、行为及用法
|
||||
---
|
||||
|
||||
# DaemonSet 的替代选项
|
||||
|
||||
> 参考文档: Kubernetes 官网文档 [Alternatives to DaemonSet](https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/#alternatives-to-daemonset)
|
||||
|
||||
DaemonSet 有如下替代选项可以选择
|
||||
|
||||
## Init Scripts
|
||||
|
||||
您可以通过脚本(例如,`init`、`upstartd`、`systemd`)直接在节点上启动一个守护进程。相对而言,DaemonSet 在处理守护进程时,有如下优势:
|
||||
|
||||
* 使用与应用程序相同的方式处理守护进程的日志和监控
|
||||
* 使用与应用程序相同的配置语言和工具(例如:Pod template、kubectl)处理守护进程
|
||||
* 在容器中运行守护进程,可为守护进程增加 resource limits 等限定
|
||||
|
||||
## Pods
|
||||
|
||||
您可以直接创建 Pod,并指定其在某一个节点上运行。相对而言,使用 DaemonSet 可获得如下优势:
|
||||
|
||||
* Pod 终止后,DaemonSet 可以立刻新建 Pod 以顶替已终止的 Pod。Pod 终止的原因可能是:
|
||||
* 节点故障
|
||||
* 节点停机维护
|
||||
|
||||
## 静态 Pod
|
||||
|
||||
您可以在 Kubelet 监听的目录下创建一个 Pod 的 yaml 文件,这种形式的 Pod 叫做 [静态 Pod(static pod)](https://kubernetes.io/docs/tasks/configure-pod-container/static-pod/)。与 DaemonSet 不同,静态 Pod 不能通过 kubectl 或者 Kuboard 进行管理。静态 Pod 不依赖 Kubernetes APIServer 的特点,使得它在引导集群启动的过程中非常有用。
|
||||
|
||||
::: warning
|
||||
静态 Pod 将来可能被不推荐使用 (deprecated)
|
||||
:::
|
||||
|
||||
## Deployment
|
||||
|
||||
DaemonSet 和 Deployment 一样,他们都创建长时间运行的 Pod(例如 web server、storage server 等)
|
||||
|
||||
* Deployment 适用于无状态服务(例如前端程序),对于这些程序而言,扩容(scale up)/ 缩容(scale down)、滚动更新等特性比精确控制 Pod 所运行的节点更重要。
|
||||
|
||||
* DaemonSet 更适合如下情况:
|
||||
* Pod 的副本总是在所有(或者部分指定的)节点上运行
|
||||
* 需要在其他 Pod 启动之前运行
|
||||
@ -0,0 +1,15 @@
|
||||
---
|
||||
layout: LearningLayout
|
||||
description: 本文描述了 Kubernetes DaemonSet 的概念、行为及用法
|
||||
---
|
||||
|
||||
# 与 DaemonSet 通信
|
||||
|
||||
> 参考文档 Kubernetes 官网文档 [Communicating with Daemon Pods](https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/#communicating-with-daemon-pods)
|
||||
|
||||
与 DaemonSet 容器组通信的模式有:
|
||||
|
||||
* **Push:** DaemonSet 容器组用来向另一个服务推送信息,例如数据库的统计信息。这种情况下 DaemonSet 容器组没有客户端
|
||||
* **NodeIP + Port:** DaemonSet 容器组可以使用 `hostPort`,此时可通过节点的 IP 地址直接访问该容器组。客户端需要知道节点的 IP 地址,以及 DaemonSet 容器组的 端口号
|
||||
* **DNS:** 创建一个 [headless service](https://kubernetes.io/docs/concepts/services-networking/service/#headless-services),且该 Service 与 DaemonSet 有相同的 Pod Selector。此时,客户端可通过该 Service 的 DNS 解析到 DaemonSet 的 IP 地址
|
||||
* **Service:** 创建一个 Service,且该 Service 与 DaemonSet 有相同的 Pod Selector,客户端通过该 Service,可随机访问到某一个节点上的 DaemonSet 容器组
|
||||
96
learning/k8s-intermediate/workload/wl-daemonset/create.md
Normal file
@ -0,0 +1,96 @@
|
||||
---
|
||||
layout: LearningLayout
|
||||
description: 本文描述了 Kubernetes 中如何创建 DaemonSet
|
||||
---
|
||||
|
||||
# 创建 DaemonSet
|
||||
|
||||
## YAML 示例
|
||||
|
||||
下面是 DaemonSet 的 YAML 文件示例 daemonset.yaml。该例子中的 DaemonSet 运行了一个 fluentd-elasticsearch 的 docker 镜像:
|
||||
|
||||
``` yaml
|
||||
apiVersion: apps/v1
|
||||
kind: DaemonSet
|
||||
metadata:
|
||||
name: fluentd-elasticsearch
|
||||
namespace: kube-system
|
||||
labels:
|
||||
k8s-app: fluentd-logging
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
name: fluentd-elasticsearch
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
name: fluentd-elasticsearch
|
||||
spec:
|
||||
tolerations:
|
||||
- key: node-role.kubernetes.io/master
|
||||
effect: NoSchedule
|
||||
containers:
|
||||
- name: fluentd-elasticsearch
|
||||
image: fluent/fluentd-kubernetes-daemonset:v1.7.1-debian-syslog-1.0
|
||||
resources:
|
||||
limits:
|
||||
memory: 200Mi
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 200Mi
|
||||
volumeMounts:
|
||||
- name: varlog
|
||||
mountPath: /var/log
|
||||
- name: varlibdockercontainers
|
||||
mountPath: /var/lib/docker/containers
|
||||
readOnly: true
|
||||
terminationGracePeriodSeconds: 30
|
||||
volumes:
|
||||
- name: varlog
|
||||
hostPath:
|
||||
path: /var/log
|
||||
- name: varlibdockercontainers
|
||||
hostPath:
|
||||
path: /var/lib/docker/containers
|
||||
```
|
||||
|
||||
执行如下命令可创建该 DaemonSet:
|
||||
|
||||
``` sh
|
||||
kubectl apply -f ./daemonset.yaml
|
||||
```
|
||||
|
||||
## 必填字段
|
||||
|
||||
与其他所有 Kubernetes API 对象相同,DaemonSet 需要如下字段:
|
||||
* apiVersion
|
||||
* kind
|
||||
* metadata
|
||||
|
||||
除此之外,DaemonSet 还需要 `.spec` 字段
|
||||
|
||||
## Pod Template
|
||||
|
||||
`.spec.template` 是必填字段,定义了 Pod 的模板,与定义 Pod 的 yaml 格式完全相同(除了内嵌在 DaemonSet 中以外,没有 kind、APIVersion 字段以外)。
|
||||
|
||||
在 DaemonSet 中,您必须指定 `.spec.template.metadata.labels` 字段和 `.spec.tempalte.spec` 字段。
|
||||
|
||||
DaemonSet 的 `.spec.template.spec.restartPolicy` 字段必须为 Always,或者不填(默认值为 Always)
|
||||
|
||||
## Pod Selector
|
||||
|
||||
`.spec.selector` 字段定义了 DaemonSet 的 pod selector,DaemonSet 认为符合该选择器的 Pod 由其管理。
|
||||
|
||||
自 Kubernets v1.8 以后,`.spec.selector` 是必填字段,且您指定该字段时,必须与 `.spec.template.metata.labels` 字段匹配(不匹配的情况下创建 DaemonSet 将失败)。DaemonSet 创建以后,`.spec.selector` 字段就不可再修改。如果修改,可能导致不可预见的结果。
|
||||
|
||||
`.spec.selector` 由两个字段组成:
|
||||
* matchLabels <Badge text="Kuboard 已支持" type="success"/>
|
||||
* matchExpressions <Badge text="Kuboard 暂不支持" type="warn"/> 通过指定 key、value列表以及运算符,可以构造更复杂的选择器
|
||||
|
||||
如果两个字段同时存在,则必须同时满足两个条件的 Pod 才被选中。
|
||||
|
||||
任何情况下,您不能以任何方式创建符合 DaemonSet 的 `.spec.selector` 选择器的 Pod。否则 DaemonSet Controller 会认为这些 Pod 是由它创建的。这将导致不可预期的行为出现。
|
||||
|
||||
## 只在部分节点上运行
|
||||
|
||||
指定 `.spec.template.spec.nodeSelector` <Badge text="Kuboard 已支持" type="success"/>,DaemonSet Controller 将只在指定的节点上创建 Pod (参考 [节点选择器 nodeSelector](/learning/k8s-intermediate/config/assign-pod-node.html#节点选择器-nodeselector))。同样的,如果指定 `.spec.template.spec.affinity` <Badge text="Kuboard 暂不支持" type="warn"/>,DaemonSet Controller 将只在与 [node affinity](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/) 匹配的节点上创建 Pod。
|
||||
@ -3,6 +3,27 @@ layout: LearningLayout
|
||||
description: 本文描述了 Kubernetes DaemonSet 的概念、行为及用法
|
||||
---
|
||||
|
||||
# 控制器 - DaemonSet
|
||||
# 介绍 DaemonSet
|
||||
|
||||
正在撰写...
|
||||
> 参考文档: Kubernetes 官网文档 [DaemonSet](https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/)
|
||||
|
||||
|
||||
DaemonSet 控制器确保所有(或一部分)的节点都运行了一个指定的 Pod 副本。
|
||||
* 每当向集群中添加一个节点时,指定的 Pod 副本也将添加到该节点上
|
||||
* 当节点从集群中移除时,Pod 也就被垃圾回收了
|
||||
* 删除一个 DaemonSet 可以清理所有由其创建的 Pod
|
||||
|
||||
DaemonSet 的典型使用场景有:
|
||||
|
||||
* 在每个节点上运行集群的存储守护进程,例如 glusterd、ceph
|
||||
* 在每个节点上运行日志收集守护进程,例如 fluentd、logstash
|
||||
* 在每个节点上运行监控守护进程,例如 [Prometheus Node Exporter](https://github.com/prometheus/node_exporter)、[Sysdig Agent](https://sysdigdocs.atlassian.net/wiki/spaces/Platform)、collectd、[Dynatrace OneAgent](https://www.dynatrace.com/technologies/kubernetes-monitoring/)、[APPDynamics Agent](https://docs.appdynamics.com/display/CLOUD/Container+Visibility+with+Kubernetes)、[Datadog agent](https://docs.datadoghq.com/agent/kubernetes/daemonset_setup/)、[New Relic agent](https://docs.newrelic.com/docs/integrations/kubernetes-integration/installation/kubernetes-installation-configuration)、Ganglia gmond、[Instana Agent](https://www.instana.com/supported-integrations/kubernetes-monitoring/) 等
|
||||
|
||||
通常情况下,一个 DaemonSet 将覆盖所有的节点。复杂一点儿的用法,可能会为某一类守护进程设置多个 DaemonSets,每一个 DaemonSet 针对不同类硬件类型设定不同的内存、cpu请求。
|
||||
|
||||
本文从以下几方面介绍 DaemonSet:
|
||||
* [创建 DaemonSet](./create.html)
|
||||
* [DaemonSet 是如何调度的](./schedule.html)
|
||||
* [与 DaemonSet 通信](./communicate.html)
|
||||
* [更新 DaemonSet](./update.html)
|
||||
* [DaemonSet 的替代选项](./alternative.html)
|
||||
|
||||
54
learning/k8s-intermediate/workload/wl-daemonset/schedule.md
Normal file
@ -0,0 +1,54 @@
|
||||
---
|
||||
layout: LearningLayout
|
||||
description: 本文描述了 Kubernetes DaemonSet 如何调度 Pod
|
||||
---
|
||||
|
||||
# DaemonSet 是如何调度的
|
||||
|
||||
> 参考文档 Kubernetes 官网文档 [How Daemon Pods are Scheduled](https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/#how-daemon-pods-are-scheduled)
|
||||
|
||||
## 由 DaemonSet 控制器调度
|
||||
|
||||
**v1.12以后默认禁用**
|
||||
|
||||
通常,Kubernetes Scheduler(调度器)决定了 Pod 在哪个节点上运行。然而 DaemonSet Controller 创建的 Pod 已经指定了 `.spec.nodeName` 字段,因此:
|
||||
* Node 节点的 [unschedulable](https://kubernetes.io/docs/concepts/architecture/nodes/#manual-node-administration) 字段将被 DaemonSet Controller 忽略
|
||||
* DaemonSet Controller 可以在 kubernetes scheduler 启动之前创建 Pod,这个特性在引导集群启动的时候非常有用(集群使用者无需关心)
|
||||
|
||||
## 由默认调度器调度
|
||||
|
||||
**v1.12以后默认启用**
|
||||
|
||||
DaemonSet 确保所以符合条件的节点运行了一个指定的 Pod。通常,Kubernetes Scheduler 决定 Pod 在哪个节点上运行。然而如果 DaemonSet 的 Pod 由 DaemonSet Controller 创建和调度,会引发如下问题:
|
||||
|
||||
* Pod 的行为不一致:普通的 Pod 在创建后处于 **Pending** 状态,并等待被调度,但是 DaemonSet Pod 创建后,初始状态不是 **Pending**。这会使用户感到困惑
|
||||
* [Pod 的优先权(preemption)](https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/) 由 kubernetes 调度器处理。如果 Pod 优先权被启用,DaemonSet Controller 在创建和调度 Pod 时,不会考虑 Pod 的优先权
|
||||
|
||||
Kubernetes v1.12 版本以后,默认通过 kubernetes 调度器来调度 DaemonSet 的 Pod。DaemonSet Controller 将会向 DaemonSet 的 Pod 添加 `.spec.nodeAffinity` 字段,而不是 `.spec.nodeName` 字段,并进一步由 kubernetes 调度器将 Pod 绑定到目标节点。如果 DaemonSet 的 Pod 已经存在了 `nodeAffinity` 字段,该字段的值将被替换。
|
||||
|
||||
``` yaml
|
||||
nodeAffinity:
|
||||
requiredDuringSchedulingIgnoredDuringExecution:
|
||||
nodeSelectorTerms:
|
||||
- matchFields:
|
||||
- key: metadata.name
|
||||
operator: In
|
||||
values:
|
||||
- target-host-name
|
||||
```
|
||||
|
||||
此外, `node.kubernetes.io/unschedulable:NoSchedule` 容忍([toleration](/learning/k8s-intermediate/config/taints-and-toleration.html))将被自动添加到 DaemonSet 的 Pod 中。由此,默认调度器在调度 DaemonSet 的 Pod 时可以忽略节点的 **unschedulable** 属性
|
||||
|
||||
## 污点和容忍
|
||||
|
||||
在调度 DaemonSet 的 Pod 时,污点和容忍([taints and tolerations](/learning/k8s-intermediate/config/taints-and-toleration.html))会被考量到,同时,以下容忍(toleration)将被自动添加到 DaemonSet 的 Pod 中:
|
||||
|
||||
| Toleration Key | Effect | Version | 描述 |
|
||||
| -------------------------------------- | ---------- | ------- | ------------------------------------------------------------ |
|
||||
| node.kubernetes.io/not-ready | NoExecute | 1.13+ | 节点出现问题时(例如网络故障),DaemonSet 容器组将不会从节点上驱逐 |
|
||||
| node.kubernetes.io/unreachable | NoExecute | 1.13+ | 节点出现问题时(例如网络故障),DaemonSet 容器组将不会从节点上驱逐 |
|
||||
| node.kubernetes.io/disk-pressure | NoSchedule | 1.8+ | |
|
||||
| node.kubernetes.io/memory-pressure | NoSchedule | 1.8+ | |
|
||||
| node.kubernetes.io/unschedulable | NoSchedule | 1.12+ | 默认调度器针对 DaemonSet 容器组,容忍节点的 `unschedulable `属性 |
|
||||
| node.kubernetes.io/network-unavailable | NoSchedule | 1.12+ | 默认调度器针对 DaemonSet 容器组,在其使用 host network 时,容忍节点的 `network-unavailable` 属性 |
|
||||
|
||||
23
learning/k8s-intermediate/workload/wl-daemonset/update.md
Normal file
@ -0,0 +1,23 @@
|
||||
---
|
||||
layout: LearningLayout
|
||||
description: 本文描述了 Kubernetes DaemonSet 的概念、行为及用法
|
||||
---
|
||||
|
||||
# 更新 DaemonSet
|
||||
|
||||
> 参考文档 Kubernetes 官网文档 [Updating a DaemonSet](https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/#updating-a-daemonset)
|
||||
|
||||
## 更新信息
|
||||
|
||||
* 在改变节点的标签时:
|
||||
* 如果该节点匹配了 DaemonSet 的 `.spec.template.spec.nodeSelector`,DaemonSet 将会在该节点上创建一个 Pod
|
||||
* 如果该节点原来匹配 DaemonSet 的 `.spec.template.spec.nodeSelector`,现在不匹配了,则,DaemonSet 将会删除该节点上对应的 Pod
|
||||
|
||||
* 您可以修改 DaemonSet 的 Pod 的部分字段,但是,DaemonSet 控制器在创建新的 Pod 时,仍然会使用原有的 Template 进行 Pod 创建。
|
||||
|
||||
* 您可以删除 DaemonSet。如果在 `kubectl` 命令中指定 `--cascade=false` 选项,DaemonSet 容器组将不会被删除。紧接着,如果您创建一个新的 DaemonSet,与之前删除的 DaemonSet 有相同的 `.spec.selector`,新建 DaemonSet 将直接把这些未删除的 Pod 纳入管理。DaemonSet 根据其 `updateStrategy` 决定是否更新这些 Pod
|
||||
|
||||
## 执行滚动更新
|
||||
|
||||
|
||||
https://kubernetes.io/docs/tasks/manage-daemon/update-daemon-set/
|
||||
@ -47,7 +47,7 @@ spec:
|
||||
terminationGracePeriodSeconds: 10
|
||||
containers:
|
||||
- name: nginx
|
||||
image: k8s.gcr.io/nginx-slim:0.8
|
||||
image: nginx:1.7.9
|
||||
ports:
|
||||
- containerPort: 80
|
||||
name: web
|
||||
|
||||
@ -5,6 +5,8 @@ description: 本文描述了 Kubernetes StatefulSet 的概念、行为及用法
|
||||
|
||||
# StatefulSet 的使用场景
|
||||
|
||||
> 参考文档: Kubernetes 官网文档 [StatefulSets](https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/)
|
||||
|
||||
## StatefulSet 概述
|
||||
|
||||
StatefulSet 顾名思义,用于管理 Stateful(有状态)的应用程序。
|
||||
|
||||
|
After Width: | Height: | Size: 210 KiB |
|
After Width: | Height: | Size: 86 KiB |
|
After Width: | Height: | Size: 284 KiB |
|
After Width: | Height: | Size: 123 KiB |
|
After Width: | Height: | Size: 476 KiB |
|
After Width: | Height: | Size: 226 KiB |
|
After Width: | Height: | Size: 392 KiB |
192
learning/k8s-practice/micro-service/kuboard-view-of-k8s.md
Normal file
@ -0,0 +1,192 @@
|
||||
---
|
||||
layout: LearningLayout
|
||||
description: 本文描述了一个经典微服务参考架构,并且通过三个视图(集群概览、名称空间、工作负载)理解微服务与 Kubernetes 的映射关系。
|
||||
---
|
||||
|
||||
# 从微服务视角看 Kubernetes
|
||||
|
||||
## 微服务
|
||||
|
||||
当我们谈论微服务的时候,总避免不了说 Spring Cloud / Dubbo,这些微服务架构的采用,确实达到了我们对他的期许:分布式、熔断/限流、高可用、可扩展、分离关注、链路追踪、小团队快速迭代。
|
||||
|
||||
然而,微服务架构的引入在解决单体应用的一些问题的同时,也给我们带来了新的复杂度:
|
||||
* 更多的技术组件
|
||||
* 更多的部署单元
|
||||
* 更复杂的部署脚本
|
||||
|
||||
作者在落地 Spring Cloud 微服务的过程中,设计了如下图所示的微服务参考架构:
|
||||
|
||||

|
||||
|
||||
该图的左侧是 DevOps 平台,涵盖构建、测试、包管理、部署及运维、监控及评估。右侧是运行时平台,分成互联网层、展现层、微服务层、数据层。
|
||||
|
||||
### 运行时环境:
|
||||
|
||||
* 展现层主要是前端项目(Vue、微信小程序等),通过服务网关的路由调用微服务层 SpringBoot 实现的各种业务接口;一个大型互联网产品中,需要多少个展现层的前端项目主要取决于两个因素:该产品有多少中类型的参与方、每一种参与方各有多少种渠道接入方式。例如,某交易撮合平台,其需要的展现层项目如下列表所示:
|
||||
|
||||
| 参与方 | 渠道 | 展现层项目 |
|
||||
| ---------- | ---------- | ---------------- |
|
||||
| 散客 | PC浏览器 | 官网 |
|
||||
| | 移动站 | 移动站 |
|
||||
| | 微信小程序 | 微信小程序 |
|
||||
| | App | APP |
|
||||
| 大客户 | PC浏览器 | VIP客户端 |
|
||||
| 平台方 | PC浏览器 | 运营工作台 |
|
||||
| 供应商 | 微信小程序 | 接单工具 |
|
||||
| | APP | 接单APP |
|
||||
|
||||
展现层项目由于参与方不同,账号体系也就不同,因此,鉴权授权的逻辑也有较大的差异,基于这样的考虑,我们为不同的展现层项目各自部署对应的接入网关 Spring Cloud Gateway。
|
||||
|
||||
* 微服务层的项目包括 Spring Cloud Gateway 的主要组件,例如:服务注册 Eureka、服务网关 Spring Cloud Gateway、实现微服务的 Spring Boot项目,还有一些服务层用到的中间件(消息队列 Rabbit MQ、缓存服务 Redis等)
|
||||
|
||||
服务层里,项目数量最多的类型是实现微服务的 Spring Boot 项目。使用微服务架构,如何将单体应用的各个模块拆分成多个微服务单元,一直一个大家很关注却未能深入探讨的问题。作者设计过多个微服务系统的架构之后,认为,一个合理的服务拆分方式是以领域驱动设计的结果作为参考,可以将每一个领域的上下文边界对应为一个微服务单元。如此一来,在使用服务网关隔离的前后端分离的微服务架构中,前端微服务划的分重要依据是参与方类型 + 接入渠道,后端微服务划分的重要依据是领域设计的上下文边界。
|
||||
|
||||
作为一个完整的交易撮合平台,涉及到的业务领域较为庞大,涉及到数十个业务问题领域。合理拆分的微服务架构,可以使得企业对不同的问题领域分而治之。
|
||||
|
||||
### DevOps平台
|
||||
|
||||
运行时环境采纳了微服务架构后,因为技术组件的多样性、业务领域的多样性,导致了微服务拆分之后,产生了数十个微服务可部署单元。这个情况给技术团队带来了前所未有的挑战:
|
||||
|
||||
* 构建次数多,人工难以完成
|
||||
|
||||
* 部署实例多,无法人工管理
|
||||
* 运行实例多,出了故障不好定位
|
||||
|
||||
在解决这些问题的过程中,最终摸索出了一套以 Kubernetes 为关键环节的微服务 DevOps 平台。
|
||||
|
||||

|
||||
|
||||
如上图所示,假设有20+ 开发人员,
|
||||
|
||||
* 每天提交100次代码,将每天产生100余次构建和自动测试,新增80-100个 docker 镜像
|
||||
* 每天更新开发环境、测试环境各一次,每次重新部署20+ 个 docker container
|
||||
* 每周更新 STAGING 环境 3-4次,每周更新 PRODUCTION 环境 1-2 次
|
||||
|
||||
在单体应用的时候,即使是手工打包也是能够完成每天发布新版本的要求的。但是在微服务环境下,这个工作就必须交给 DevOps 的 Pipe Line 来完成。
|
||||
|
||||
DevOps 在构建阶段的主角是 GitLab、npm、maven、docker、Harbor等工具集,在部署和运维环节的主角就是Kubernetes了。
|
||||
|
||||
|
||||
|
||||
## 微服务 + Kubernetes
|
||||
|
||||
最开始尝试容器化的时候,使用了 docker、docker-compose,但是docker-compose的编排能力有限,在考虑分布式方案时,从 docker swarm、kuberenetes 之中选择了 Kubernetes,然而,Kubernetes 相较于 docker-compose,有一个很高的学习门槛,集群的安装管理、YAML 文件的编写、多环境(开发环境、测试环境、准生产环境、生产环境)的配置、分布式环境下的问题诊断和性能优化等,一系列的问题需要解决,团队中也出现一些抵触情绪,对新事物持观望的态度。
|
||||
|
||||
Kubernetes在诸多大厂的成功实施,仍然让我们坚信这条道路的正确性。为了解决 Kubernetes 学习门槛高、YAML 文件编写复杂等一系列现实中的困难,我们研发了 Kuboard,一款 Kubernetes 的图形化管理控制工具。
|
||||
|
||||
Kuboard 诞生于 Spring Cloud 微服务落地的实践过程中,他在管理和使用 Kubernetes 的时候,也更多地是从微服务的视角来看待 Kubernetes。
|
||||
|
||||
具体体现在如下三个视角:
|
||||
|
||||
* 集群概览
|
||||
* 名称空间
|
||||
* 工作负载
|
||||
|
||||
### 集群概览
|
||||
|
||||
从管理和部署微服务的视角来看,微服务应用是分布式应用,应该部署在一个分布式集群当中,这个集群由诸多计算资源和存储资源组成,微服务本身不应该关心最终使用了哪个计算节点,持久化存储被存放在什么位置;为了更好地利用资源,一个集群应该被划分成多个名称空间,每个名称空间内可以部署一整套微服务应用,名称空间之间不应相互干扰。
|
||||
|
||||
如下图所示:***Kuboard 集群概览界面***
|
||||
|
||||

|
||||
|
||||
Kuboard 集群概览视角,映射了 Kubernetes 中的如下几个重要概念:
|
||||
|
||||
* Cluster
|
||||
* Node
|
||||
* Storage Class / Persistent Volume
|
||||
* Namespace
|
||||
|
||||
|
||||
|
||||
### 名称空间
|
||||
|
||||
在集群概览界面中,点击一个名称空间,可以进入Kuboard名称空间界面。一个名称空间内部,是微服务部署相关的所有重要元素。与本文开头的微服务参考架构相匹配,Kuboard 认为,微服务的主要分层包括:
|
||||
|
||||
* 展现层
|
||||
* 网关层
|
||||
* 服务层
|
||||
* 持久层
|
||||
* 中间件层
|
||||
* 监控层
|
||||
|
||||
如下图所示:***Kuboard名称空间截图***
|
||||
|
||||

|
||||
|
||||
Kuboard 名称空间视角,映射了 Kubernetes 中的如下几个重要概念:
|
||||
|
||||
* Workload(Deployment、StatefulSet、DaemonSet)
|
||||
* Service(微服务上方如果有浅蓝色长条块,说明该微服务有配置 Service)
|
||||
* Ingress(微服务上方如果有黑色短条块,说明该微服务有配置 Ingress)
|
||||
* Secrets(用来配置私有 docker 镜像仓库的用户名密码、HTTPS 的证书等信息,可在创建微服务 Workload 时引用)
|
||||
* ConfigMap(配置,用来存储配置信息,可定义微服务的公共环境变量,并在创建微服务 Workload 时引用)
|
||||
* Persistent Volume Claim(存储卷声明,用来声明存储卷,可在创建微服务 Workload 时引用)
|
||||
|
||||
Kuboard 名称空间界面中,还为典型的运维场景提供了便捷的操作入口,例如:
|
||||
|
||||
* 创建工作负载(通过工作负载编辑器完成微服务应用的部署,而不是编写冗长的YAML文件,再使用复杂的 kubectl 命令)
|
||||
* 导出工作负载(选择名称空间中的微服务元素,导出到一个文件中)
|
||||
* 导入工作负载(将 Kuboard 导出的 YAML 文件导入到一个新的名称空间中,通过导出和导入的功能,用户可以快速的将开发环境复制成测试环境)
|
||||
* 容器组列表(查看当前名称空间中的容器组,可批量删除选中容器组,删除容器组后,Kubernetes将重新 Schedule一个容器组以替换被删除的容器组,此时将重新抓取镜像,此特性可用于测试环境中在 image tag 不改变的情况下的版本更新)
|
||||
* 调整镜像版本(修改容器镜像的标签,此特性用于在正式环境中进行版本更新的操作)
|
||||
* 高亮显示包含错误事件的微服务(如截图中红色的微服务 busybox)
|
||||
|
||||
|
||||
|
||||
### 工作负载
|
||||
|
||||
从名称空间界面中点击一个工作负载(微服务),可进入 Kuboard 工作负载编辑器界面。Kuboard 当前已经支持的工作负载 Workload 类型有:Deployment / StatefulSet / DaemonSet。
|
||||
|
||||
Kubernetes 中,与 Workload 相关的概念非常多,Kuboard 从微服务部署的实际需要出发,按照下图所示的方式理解这些相关概念:
|
||||
|
||||

|
||||
|
||||
Kuboard 工作负载视图中,关联的 Kubernetes 中如下几个重要的概念:
|
||||
|
||||
* Label / Label Selector
|
||||
* Workload Controller 工作负载控制器(Deployment / StatefulSet / DaemonSet)
|
||||
* Volume 数据卷
|
||||
* ImagePullSecrets (Docker 仓库用户名密码,用于访问私有 docker 镜像仓库)
|
||||
* ServiceAccount
|
||||
* Container 容器
|
||||
* Service 访问方式
|
||||
* Ingress 互联网入口
|
||||
|
||||
Kuboard 认为,掌握这些概念并正确理解这些概念的关系之后,就可以胜任使用 Kubernetes 部署微服务的工作,为了使事情变得更简单,避免编写冗长的 YAML 文件,Kuboard 以此概念为基础,设计了 Kuboard 工作负载编辑器,如下图所示:
|
||||
|
||||

|
||||
|
||||
## 微服务 + 监控/评估
|
||||
|
||||
如何监控和评估微服务的运行状况,并根据监控结果进行问题的定位和诊断?基于 Kubernetes / Spring Cloud / Java 等,开源社区已经提供了非常丰富的监控组件,例如:
|
||||
|
||||
* 资源层监控:Prometheus + Grafana + Node Exporter 等组件,监控Kubernetes 节点的 CPU、内存、网络、磁盘等使用情况
|
||||
* 中间件层监控:Prometheus + Grafana + MySQL Exporter + Nginx Exporter + JVM Exporter 等,监控 MySQL、Nginx、JVM 等中间件的使用情况
|
||||
* 链路/APM监控:Pinpoint / SkyWorking 等监控工具,监控应用程序的性能表现
|
||||
|
||||
各种监控系统各有侧重,如果想要取得比较好的监控效果,必须克服如下几个困难:
|
||||
|
||||
* 搭建和配置监控系统
|
||||
* 定位和诊断问题时,在不同监控系统中来回切换,进入监控系统并寻找对应微服务的监控结果
|
||||
|
||||
Kuboard 认为,应该以微服务视角的视角快速查看到该无服务在不同层面的监控结果。因此,在 Kuboard 的工作负载(微服务)查看界面中,可以直接点击进入不同监控系统对应的监控结果,无需再监控系统内反复查找。如一下截图所示:
|
||||
|
||||

|
||||
|
||||
点击图中 ***Nginx 监控***、 ***容器组监控***、 ***所在节点监控*** 等按钮,可以直接打开该容器组对应的监控界面。因为篇幅的限制,此处不再展开描述,请点击 <a target="_blank" :href="`http://demo.kuboard.cn/#/dashboard?k8sToken=${$site.themeConfig.kuboardToken}`">
|
||||
Kuboard 在线体验
|
||||
</a> 查看具体的监控效果。
|
||||
|
||||
|
||||
|
||||
## 总结
|
||||
|
||||
Kuboard 产生于 Spring Cloud 微服务落地的实践中,并在许多的实际项目中投入了使用,以微服务的视角理解和审视了 Kubernetes,并基于Kubernetes为用户提供了4个微服务视图:
|
||||
|
||||
* 集群概览视图
|
||||
* 名称空间视图
|
||||
* 工作负载视图
|
||||
* 监控视图
|
||||
|
||||
Kuboard 在实际项目中经过多次历练,功能不断完善,成长为一个基于 Kubernetes 的成熟的微服务管理工具。自 www.kuboard.cn 推出以来,得到了众多网友非常多的反馈,碰到问题,可以通过 Kuboard 社群得到支持。
|
||||
25
learning/k8s-practice/spring-cloud/README copy.md
Normal file
@ -0,0 +1,25 @@
|
||||
# Spring Cloud on Kubernetes
|
||||
|
||||
下图是作者在 [会小二](https://www.huixiaoer.com) 工作期间设计的微服务参考架构,设计和研发 Kuboard 的初心便源于此图。Kuboard 的发布,是此参考架构最终成熟的一个重要标志。
|
||||
|
||||
Kuboard 本身是一款免费软件,作者通过向企业提供 微服务落地和实施 的咨询获得收益。服务的范围包括:
|
||||
|
||||
* 业务分析及领域建模
|
||||
* 应用架构设计、数据架构设计
|
||||
* 微服务架构设计
|
||||
* 微服务开发技术培训
|
||||
* DevOps 体系建设及培训
|
||||
|
||||
与作者取得联系时,请扫描微信二维码,并表明来意:
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div>
|
||||
<script type='text/javascript' src='https://www.wjx.top/handler/jqemed.ashx?activity=43409534&width=760&source=iframe'></script>
|
||||
</div>
|
||||
|
After Width: | Height: | Size: 34 KiB |
|
After Width: | Height: | Size: 449 KiB |
|
After Width: | Height: | Size: 34 KiB |
49
learning/k8s-practice/spring-cloud/README.md
Normal file
@ -0,0 +1,49 @@
|
||||
---
|
||||
layout: LearningLayout
|
||||
description: 微服务参考架构:包含微服务运行时、构建及测试、部署及运维、监控及评估。设计和研发 Kuboard 的初心便源于此 Spring Cloud 微服务参考架构。
|
||||
---
|
||||
|
||||
# Spring Cloud on Kubernetes
|
||||
|
||||
下图是作者在落地 Spring Cloud 微架构的过程中,设计了如下图所示的微服务参考架构,设计和研发 Kuboard 的初心便源于此图。历时两年时间,Kuboard终于发布,也标志着该参考架构的成熟可用。该参考架构主要包括四个重要组成部分:
|
||||
|
||||
* 微服务运行时
|
||||
* 前后端分离
|
||||
* Spring Cloud
|
||||
* 构建及测试
|
||||
* 源代码/构建管理
|
||||
* 包管理
|
||||
* 部署及运维
|
||||
* Kubernetes + Kuboard
|
||||
* 监控及评估
|
||||
* 熔断及限流
|
||||
* 链路追踪
|
||||
* 性能监控
|
||||
* 日志收集
|
||||
* APM
|
||||
|
||||
在整体架构中,微服务运行时分为如下几层:
|
||||
* 展现层
|
||||
* 网关层
|
||||
* 服务层
|
||||
* 中间件层
|
||||
|
||||
另有监控层,用于微服务运行时的监控和评估。
|
||||
|
||||
展现层、网关层、服务层、中间件层以及监控层,都运行于 Kubernetes 之上,由 Kuboard 管理。
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
Spring Cloud on Kubernetes 并不对 Spring Cloud 架构、组件等做过多解释,而是将重点放在如何将 Spring Cloud 的各类型组件顺利部署到 Kubernetes 环境中。
|
||||
|
||||
为了更好地阐述此主题,作者准备了一个最简单的微服务 example 作为例子,该 example 只实现了对一张简单数据库表执行 CRUD 操作的功能,该 example 的部署架构如下图所示,源代码请参考 [kuboard-example](https://github.com/eip-work/kuboard-example),您也可以直接通过 Kuboard [导入 example 微服务](/guide/example/import.html)
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
<div>
|
||||
<script type='text/javascript' src='https://www.wjx.top/handler/jqemed.ashx?activity=43409534&width=760&source=iframe'></script>
|
||||
</div>
|
||||
135
learning/k8s-practice/spring-cloud/cloud-eureka.md
Normal file
@ -0,0 +1,135 @@
|
||||
---
|
||||
description: 使用 Kuboard 在 Kubernetes 上部署 spring cloud 服务注册发现组件 eureka。
|
||||
---
|
||||
|
||||
# 部署 cloud-eureka
|
||||
|
||||
本文所使用的代码请参考 [cloud-eureka](https://github.com/eip-work/kuboard-example/tree/master/cloud-eureka)
|
||||
|
||||
## 检查 cloud-eureka 项目的配置
|
||||
|
||||
**部署类型**
|
||||
|
||||
对于 cloud-eureka 项目,在部署到 Kubernetes 时,建议选择 StatefulSet 作为 Controller,因为 StatefulSet 可以为其管理的容器组提供稳定的网络标识 [StatefulSet Pod Identity](https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#pod-identity),例如,如果 StatefulSet 的名字是 cloud-eureka,副本数为 3, 则 StatefulSet 将确保如下三个容器组的按照 cloud-eureka-0,cloud-eureka-1,cloud-eureka-2 的顺序启动和运行。
|
||||
|
||||
| 容器组名字 | HOSTNAME(环境变量) | DNS name |
|
||||
| -------------- | -------------------- | --------------------------- |
|
||||
| cloud-eureka-0 | cloud-eureka-0 | cloud-eureka-0.cloud-eureka |
|
||||
| cloud-eureka-1 | cloud-eureka-1 | cloud-eureka-1.cloud-eureka |
|
||||
| cloud-eureka-2 | cloud-eureka-2 | cloud-eureka-2.cloud-eureka |
|
||||
|
||||
Eureka Server 要求将 Eureka 实例的 URL 以逗号分隔配置在 eureka.client.serviceUrl.defaultZone 字段中。请参考 [Spring Cloud Eureka Server Peer Awareness](https://cloud.spring.io/spring-cloud-netflix/spring-cloud-netflix.html#spring-cloud-eureka-server-peer-awareness)
|
||||
|
||||
结合 StatefulSet 的特性,在配置 eureka.client.serviceUrl.defaultZone 时,可使用如下类似的参数:
|
||||
|
||||
```yaml
|
||||
eureka.client.serviceUrl.defaultZone: http://cloud-eureka-0.cloud-eureka:9200/eureka, http://cloud-eureka-1.cloud-eureka:9200/eureka, http://cloud-eureka-2.cloud-eureka:9200/eureka
|
||||
```
|
||||
|
||||
|
||||
|
||||
**环境变量**
|
||||
|
||||
参考 cloud-eureka 项目的 [application.yaml](https://github.com/eip-work/kuboard-example/blob/master/cloud-eureka/src/main/resources/application.yml) 文件
|
||||
|
||||
``` yaml
|
||||
spring:
|
||||
application:
|
||||
name: cloud-eureka
|
||||
|
||||
server:
|
||||
port: 9200
|
||||
management:
|
||||
endpoints:
|
||||
web.exposure.include: metrics
|
||||
server:
|
||||
port: 9500
|
||||
|
||||
eureka:
|
||||
instance:
|
||||
preferIpAddress: true
|
||||
client:
|
||||
register-with-eureka: false
|
||||
fetch-registry: false
|
||||
service-url:
|
||||
defaultZone: ${CLOUD_EUREKA_DEFAULT_ZONE}
|
||||
server:
|
||||
eviction-interval-timer-in-ms: 60000
|
||||
enable-self-preservation: false
|
||||
```
|
||||
|
||||
该项目中有一个值取自环境变量:
|
||||
|
||||
* CLOUD_EUREKA_DEFAULT_ZONE 这个参数必须通过环境变量进行配置
|
||||
|
||||
建议配置的值为:
|
||||
|
||||
`http://cloud-eureka-0.cloud-eureka:9200/eureka, http://cloud-eureka-1.cloud-eureka:9200/eureka, http://cloud-eureka-2.cloud-eureka:9200/eureka`
|
||||
|
||||
因为各微服务也需要用到 CLOUD_EUREKA_DEFAULT_ZONE 这个参数(请参考 部署 svc-example 章节),所以建议将该参数配置在 Kubernetes 的 ConfigMap 中最为便捷。
|
||||
|
||||
文件中没有配置 `eureka.instance.hostname`,该参数的默认取值通过 java.net.InetAddress 查找机器的 hostname。如前所示,当我们使用 StatefulSet 部署 eureka 时,hostname 为 cloud-eureka-0 / cloud-eureka-1 / cloud-eureka-2
|
||||
|
||||
**容器 Command 参数**
|
||||
|
||||
参考 cloud-eureka 项目的 [Dockerfile](https://github.com/eip-work/kuboard-example/blob/master/cloud-eureka/Dockerfile) 文件
|
||||
|
||||
```dockerfile
|
||||
FROM eipwork/jdk:1.0.0
|
||||
|
||||
ARG JAR_FILE_NAME=cloud-eureka-0.0.1-SNAPSHOT.jar
|
||||
ARG PORT=9200
|
||||
ARG MANAGEMENT_PORT=9500
|
||||
|
||||
COPY ./target/lib /eip-work/lib
|
||||
COPY ./target/$JAR_FILE_NAME.original /eip-work/app.jar
|
||||
|
||||
ENV CLASSPATH=/eip-work/lib
|
||||
|
||||
EXPOSE $PORT
|
||||
EXPOSE $MANAGEMENT_PORT
|
||||
|
||||
WORKDIR /eip-work
|
||||
|
||||
ENTRYPOINT ["java", "-jar", "/eip-work/app.jar"]
|
||||
```
|
||||
|
||||
ENTRYPOINT 中指定了启动命令为
|
||||
|
||||
``` sh
|
||||
java -jar /eip-work/app.jar
|
||||
```
|
||||
|
||||
因此在 kubernetes 中部署该容器时,无需额外指定 Command 参数。
|
||||
|
||||
|
||||
|
||||
**访问方式及互联网入口**
|
||||
|
||||
Eureka 运行在 9200 端口。Spring Cloud 的微服务组件通过 CLOUD_EUREKA_DEFAULT_ZONE 中的配置直接与 Eureka 容器组通信。
|
||||
|
||||
是否配置访问方式及互联网入口?
|
||||
|
||||
* 如果开发者不需要查看 Eureka 的 Web 界面,则
|
||||
* 无需配置访问方式和互联网入口;
|
||||
* 如果开发者需要查看 Eureka 的 Web 界面,则
|
||||
* 配置集群内访问(Type 为 ClusterIP 的 Service)
|
||||
* 容器端口为9200
|
||||
|
||||
|
||||
|
||||
## 部署 cloud-eureka
|
||||
|
||||
**创建ConfigMap**
|
||||
|
||||
|
||||
|
||||
**创建工作负载**
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## 检查部署结果
|
||||
|
||||
**查看 Eureka 界面**
|
||||
90
learning/k8s-practice/spring-cloud/db-example.md
Normal file
@ -0,0 +1,90 @@
|
||||
---
|
||||
description: 在 Kubernetes 上部署测试数据库 mysql 的详细介绍。
|
||||
---
|
||||
|
||||
# 部署 db-example
|
||||
|
||||
本文所使用的代码请参考 [db-example](https://github.com/eip-work/kuboard-example/tree/master/db-example)
|
||||
|
||||
## 检查 db-example 项目的配置
|
||||
|
||||
**项目结构解读**
|
||||
|
||||
|
||||
|
||||
**部署类型**
|
||||
|
||||
关于 MySQL 数据库的部署,建议的做法如下:
|
||||
* 在开发环境、测试环境使用 Kuboard 部署一个副本数为 1 的 Deployment,以便可以快速复制 开发环境、测试环境
|
||||
* 在准上线环境和生产环境,使用 IaaS 服务商提供的 RDS 服务,或者自建 MySQL 主从集群,原因是:
|
||||
* 直接将 MySQL 部署到 Kubernetes 虽然简便,但是数据库的运维仍然有大量的事情需要考虑,例如数据的备份、恢复、迁移等
|
||||
* Kubernetes 管理无状态服务已经非常成熟,在管理有状态的容器例如 MySQL 时,仍然需要等待更好的解决方案。目前这方面最新的进展是 [Kubernetes Operator](http://dockone.io/article/8769)
|
||||
* 如果您想尝试部署 MySQL 集群,目前还可以参考 [Run a Replicated Stateful Application](https://kubernetes.io/docs/tasks/run-application/run-replicated-stateful-application/)
|
||||
|
||||
|
||||
**环境变量**
|
||||
|
||||
检查 [Dockerfile](https://github.com/eip-work/kuboard-example/blob/master/db-example/Dockerfile)
|
||||
|
||||
|
||||
``` Dockerfile
|
||||
FROM eipwork/mysql:5.7.26-1.1.11
|
||||
|
||||
LABEL maintainer="shaohq@foxmail.com"
|
||||
|
||||
#把数据库初始化数据的文件复制到工作目录下
|
||||
RUN mv /etc/my.cnf /etc/my.cnf.backup
|
||||
COPY docker/my.cnf /etc/my.cnf
|
||||
COPY docker/init_sql/*.sql /init_sql/
|
||||
|
||||
EXPOSE 3306
|
||||
EXPOSE 9104
|
||||
|
||||
ENV ENABLE_EUREKA_CLIENT=TRUE
|
||||
ENV eureka.name=db-example
|
||||
ENV eureka.port=80
|
||||
ENV eureka.management.port=9104
|
||||
ENV eureka.serviceUrl.default=http://monitor-eureka:9000/eureka
|
||||
```
|
||||
|
||||
Dockerfile 中定义了环境变量 ENABLE_EUREKA_CLIENT=TRUE,这个环境变量用于 Prometheus [监控套件](/guide/monitor/) 的服务发现。在不启用监控套件的情况下,应该将 ***ENABLE_EUREKA_CLIENT*** 这个环境变量设置为 FALSE。
|
||||
|
||||
容器镜像 eipwork/mysql:5.7.26-1.1.11 基于 [mysql/mysql-server:5.7.26](https://hub.docker.com/r/mysql/mysql-server) 制作。参考文档 [More Topics on Deploying MySQL Server with Docker](https://dev.mysql.com/doc/refman/5.7/en/docker-mysql-more-topics.html#docker-environment-variables),通过设置环境变量 ***MYSQL_ROOT_PASSWORD*** ,可指定 MySQL 的root 用户密码
|
||||
|
||||
::: tip
|
||||
可以在部署时覆盖环境变量的值,无需修改 Dockerfile。
|
||||
:::
|
||||
|
||||
**容器 Command 参数**
|
||||
|
||||
容器镜像 eipwork/mysql:5.7.26-1.1.11 的 [Dockerfile](https://github.com/eip-work/eip-docker-library/blob/master/mysql/Dockerfile) 指定了容器的启动方式,此处无需为容器额外设置 Command 参数。
|
||||
|
||||
**数据卷**
|
||||
|
||||
参考文档 [More Topics on Deploying MySQL Server with Docker](https://dev.mysql.com/doc/refman/5.7/en/docker-mysql-more-topics.html#docker-persisting-data-configuration),我们需要将容器内路径 `/var/lib/mysql` 映射到数据卷,以便数据能够持久化。
|
||||
|
||||
|
||||
**访问方式及互联网入口**
|
||||
|
||||
通常在两种情况下需要访问数据库:
|
||||
* 微服务程序中访问数据库
|
||||
* 开发者/运维人员通过 Navicat 等数据库工具访问数据库
|
||||
|
||||
为了同时支持这两种使用场景,建议为数据库配置 VPC内访问方式 (NodePort Service)
|
||||
|
||||
与数据库的通信为 socket,不能为其配置互联网入口 Ingress
|
||||
|
||||
|
||||
## 部署 db-example
|
||||
|
||||
**创建ConfigMap**
|
||||
|
||||
|
||||
|
||||
**创建工作负载**
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## 检查部署结果
|
||||