Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
isno committed Dec 18, 2024
1 parent f281dc3 commit ab91329
Show file tree
Hide file tree
Showing 7 changed files with 74 additions and 60 deletions.
83 changes: 47 additions & 36 deletions GitOps/ArgoCD.md
Original file line number Diff line number Diff line change
@@ -1,76 +1,87 @@
# 10.5 使用 Argo CD 进行持续交付

Argo CD 是一个基于 Kubernetes 的声明式 GitOps 持续交付工具,主要用于 Kubernetes 集群中的应用管理和部署。它能够从 Git 仓库中获取应用的定义,并自动同步到集群中。
Argo CD 是一款用于 Kubernetes 的声明式持续交付工具,它被实现为一个Kubernetes 控制器,该控制器持续监控 Git 仓库的变更来实现自动拉取和更新机制。其背后工作原理如下:

- **定时轮询**: Argo CD Controller 定期轮询指定的 Git 仓库,检查是否有新的提交。默认情况下,轮询周期每 3 分钟一次。
- **Webhook 触发**: 为了更快地响应更新,Argo CD 支持通过 Git 仓库的 Webhook 来触发同步操作。当仓库中发生提交或合并请求时,GitLab、GitHub 等平台可以通过 Webhook 通知 Argo CD 立即进行同步。
- **状态对比**: 每次拉取到最新的 Git 仓库状态后,Argo CD 会与当前集群中的应用状态进行对比。如果发现差异,Argo CD 会自动执行同步操作,确保集群与 Git 仓库的配置一致。

如图 10-10 所示,Argo CD 是通过 Kubernetes 控制器来实现的,它持续 watch 正在运行的应用程序,并将应用程序的实际状态与所需的目标状态( Git 存储库中指定的)进行比较。如果应用程序的实际状态与目标状态有差异,则被认为是 OutOfSync 状态,Argo CD 会报告这些差异,同时提供工具来自动或手动将状态同步到期望的目标状态。

:::center
![](../assets/argocd_architecture.png)<br/>
图 10-10 Argo CD 如何工作 [图片来源](https://argo-cd.readthedocs.io/en/stable/)
:::

接下来,笔者将演示在集群内安装 Argo CD 以及部署一个应用示例,介绍 Argo CD 的使用概况
接下来,笔者将演示如何在集群中安装 Argo CD 并部署示例应用,简要介绍其使用方法

## 10.5.1 安装 Argo CD

先创建一个命名空间,然后通过 kubectl apply 安装 Argo CD 提供的 yaml 文件即可。
首先,创建一个专门用于 Argo CD 的命名空间“argocd”。然后通过 kubectl apply 安装 Argo CD 提供的 yaml 文件即可。

```bash
$ kubectl create namespace argocd
```
kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
```
安装之后,可以使用自带的 WebUI 进行交互操作,也可以额外安装 CLI ,出于演示的目的,这里使用自带 WebUI 进行交互。

默认情况下,Argo CD 的 WebUI 服务在集群内部并没有暴露出来,可以通过 LoadBalancer 或者 NodePort 类型的 Service、Ingress、Kubectl 端口转发等方式将 Argo CD 服务发布到 Kubernetes 集群外部。

如下,通过 NodePort 服务的方式暴露 Argo CD 到集群外部。
安装 Argo CD 有多种方法,这里选择使用 kubectl apply 命令应用官方 YAML 清单文件进行安装。下面的命令会在之前创建的 argocd 命名空间中安装 Argo CD 的所有必要组件,包括控制器、服务器、UI 等。

```bash
$ kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
```
$ kubectl patch svc argocd-server -n argocd -p '{"spec": {"type": "NodePort"}}'
```

查找到 argocd-server 关联的 NodePort 端口,通过浏览器打开:https://localhost:35123/ 控制台。

初次访问需要登录,Argo CD 默认账户是 admin,帐号的初始密码是自动生成,并以明文的形式存储在 Argo CD 安装的命名空间中 argocd-initial-admin-secret 的 Secret 对象下的 password。
Argo CD 提供了一个用户友好的 Web 界面来管理应用。要访问 UI,首先需要获取初始密码。运行以下命令来获取密码:

通过下面命令获取初始密码。
```bash
$ kubectl -n argocd get secret argocd - initial - admin - secret - o jsonpath ="{.data.password}"| base64 -d
```
$ kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d
然后,使用以下命令设置端口转发来访问 UI。

```bash
$ kubectl port - forward svc/argocd - server -n argocd 8080:443
```

## 10.5.2 部署应用
之后,你可以在浏览器中访问https://localhost:8080,并使用 admin 作为用户名和上面获取的密码进行登录。

部署应用之前,我们先了解 Argo CD 定义的 Application 资源,它通过下面两个关键的属性将目标 Kubernetes 集群中的 namespace 与 Git 仓库中声明的期望状态连接起来:
## 10.5.2 部署应用

- **Source**:指的是 Git 仓库中 Kubernetes 资源配置清单所在的位置,可以是原生的 Kubernetes 配置清单,也可以是 Helm Chart 或者 Kustomize 部署清单。
- **Destination**:通过 Server 指定 Kubernetes 集群以及相关的 namespace,这样 Argo CD 就知道将应用部署到 Kubernetes 集群中的哪个位置。
在 Argo CD 中,Application 是核心的自定义资源定义(CRD),它是 Argo CD 实现 GitOps 工作流的关键抽象,定义了应用的源代码位置、目标部署环境以及同步和监控策略。

通过如下 yaml 文件,了解 Argo CD Application 资源的定义。
以下是一个 Argo CD Application 资源的示例,展示如何从 Git 仓库部署一个 Kubernetes 应用到目标集群的特定命名空间:

```yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: guestbook
namespace: argocd
name: example-app # 应用名称
namespace: argocd # Argo CD 安装的命名空间
spec:
project: default
project: default # Argo CD 项目名称(默认项目)
source:
repoURL: https://github.com/argoproj/argocd-example-apps.git
targetRevision: HEAD
path: helm-guestbook
repoURL: https://github.com/example/repo.git # 配置来源的 Git 仓库地址
targetRevision: main # Git 仓库分支或标签
path: manifests # 仓库中存放 Kubernetes 配置的目录路径
destination:
server: https://kubernetes.default.svc
namespace: default
server: https://kubernetes.default.svc # 目标集群 API Server 地址
namespace: default # 部署目标命名空间
syncPolicy:
automated: # 启用自动同步
prune: true # 删除目标集群中不需要的资源
selfHeal: true # 自愈机制:检测到差异时自动修复
syncOptions:
- CreateNamespace=true # 自动创建目标命名空间
```
将该 yaml 文件 apply 到 Kubernetes 集群。
除了 Application 资源,Argo CD 也定义了 Project 资源,用来对 Application 分组,设置更细粒度的访问权限控制,实现多租户环境。
```yaml
$ kubectl apply -f application.yaml
```

默认情况下,新创建的 Application 状态为 OutOfSync,Argo CD 尚未将 Git 仓库中的资源同步到目标集群。在 UI 控制台点击 “SYNC” 按钮触发同步操作,如果配置了 syncPolicy.automated Argo CD 会自动触发同步操作。

创建 Application 之后,应用状态为初始 OutOfSync 状态,此时也尚未创建任何 Kubernetes 资源,在控制台点击 “SYNC” 按钮进行同步部署,部署之后的状态如下图所示
手动或自动触发同步后,状态会变为 Synced

:::center
![](../assets/argocd-demo.png)<br/>
图 10-11 Argo CD 应用部署示例
:::

如此,后续无论是通过 CI 触发更新 git 仓库中的编排文件,还是工程师直接修改,Argo CD 都会自动拉取最新的配置并应用到 Kubernetes 集群中。
此后,Argo CD 会根据 Application 的定义,持续跟踪应用在 Git 仓库中的期望状态和在 Kubernetes 集群中的实际状态,如果两者出现差异,它会尝试将实际状态同步到期望状态。例如,如果有人手动在集群中修改了某个应用资源的副本数量,Argo CD 会发现这种配置漂移,并根据 Application 的定义将副本数量恢复到 Git 仓库中配置的数量。

相比传统持续交付流程,Argo CD 下的应用程序的部署和生命周期管理明显变得更加**自动化**(通过自动同步、自动修复等),**可审计**(通过 Git 历史和审计日志),并且**易于理解**(通过可视化的 Web UI 和简化的部署流程)。
1 change: 1 addition & 0 deletions GitOps/Helm.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Helm
14 changes: 8 additions & 6 deletions GitOps/Tekton-CRD.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
# 10.4.1 Tekton 中的资源对象

Tekton 利用 Kubernetes 资源扩展机制,定义了一系列与构建流水线相关的 CRD 资源
Tekton 主要有以下几种关键的自定义资源定义(CRD

- Task(任务):描述任务的基本单元,每个 Task 由一系列“步骤”(Steps)构成,任务的“步骤”按串行方式执行。例如,一个程序的可用性测试任务包括克隆代码、编译和执行测试步骤
- TaskRun:TaskRun Task 的实际执行器。Task 本身仅定义了任务的内容,而 TaskRun 创建后会在 Kubernetes 集群中启动一个 Pod 来执行这些任务
- Pipeline(流水线):Pipeline 是一个或多个 Task 的组合。Pipeline 中的任务可以按顺序执行,也可以定义依赖关系,以实现复杂的工作流
- PipelineRun:类似于 TaskRun,PipelineRun Pipeline 的实际执行器。PipelineRun 对象提交到 Kubernetes 后,Tekton 会实例化并执行对应的 Pipeline。
- **Task(任务)**Task 是 Tekton 中最基本的构建块,它代表一个可以独立执行的工作单元。可以将其看作是一个脚本或者一系列命令的集合,用于完成诸如代码编译、测试等具体操作
- **TaskRun**:TaskRun 用于触发和跟踪 Task 的一次具体执行。当你想要运行一个 Task 时,就需要创建一个 TaskRun 对象。它包含了 Task 执行的具体信息,如执行的参数等
- **Pipeline(流水线)**:Pipeline 是多个 Task 按照特定顺序组合而成的工作流。它允许你定义复杂的 CI/CD 流程,将不同的操作(如构建、测试、部署等)串联起来
- **PipelineRun**PipelineRun 用于触发和跟踪 Pipeline 的一次具体执行,类似于 TaskRun 对于 Task 的作用。它包含了运行 Pipeline 所需的参数和配置信息

当用户创建了各类 Task 和 Pipeline 后,Tekton 的 TriggerBinding 组件会在外部事件(如代码提交或 git merge)触发时解析事件参数(如 git 仓库地址),并将这些参数传递给 Pipeline。随后,Pipeline 会执行代码测试、镜像构建和镜像推送等任务。其流程如图 10-6 所示。
Tekton 事件触发器(Trigger)监听外部事件(如 Webhook),会使用 TriggerBinding 解析事件数据,并传递给 TriggerTemplate,然后根据模板创建和启动一个 PipelineRun。
当发生特定事件(例如代码提交、标签发布等)时,会自动触发 Tekton 流水线的执行。TriggerBinding 则从 Webhook 的 payload 中提取相关信息,并将其转化为 Tekton 中的参数。
随后,Pipeline 会执行代码测试、镜像构建和镜像推送等任务。其流程如图 10-6 所示。

:::center
![](../assets/tekton-pipeline.png)<br/>
Expand Down
3 changes: 1 addition & 2 deletions GitOps/Tekton.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# 10.4 使用 Tekton 进行持续集成

Tekton 起源于 Google 主导的 Knative 项目,最初作为 Knative 的一个组件存在,名为 build-pipeline,用于在 Kubernetes 环境中构建容器化 CI/CD 流水线。随着功能的逐步扩展,build-pipeline 从 Knative 中独立出来,并更名为 Tekton,成为一个通用的、Kubernetes 原生的 CI/CD 框架
Tekton 是一个开源的 Kubernetes 原生持续集成/持续交付(CI/CD)工具,由 Google 发起。它的核心是通过自定义资源定义(CRD)在 Kubernetes 集群中实现流水线即代码(Pipeline as Code)。这意味着开发人员可以使用代码的方式来定义复杂的构建、测试和部署流水线。例如,一个软件开发团队可以利用 Tekton 来构建从代码拉取、单元测试、构建容器镜像,一直到将镜像部署到 Kubernetes 集群的完整流程

Tekton 充分利用了 Kubernetes 的容器调度和管理能力,所有任务均在容器中(也就是 Pod)运行,并通过 YAML 文件定义流水线和任务。相比传统的 CI/CD 系统(如 GitLab CI 和 Jenkins),Tekton 更适合构建基于 Kubernetes 的 CI/CD 系统。

接下来,我们先了解 Tekton 中与构建流水线相关的概念以及流水线执行的原理。之后,再基于 Tekton 构建一个完整的持续集成系统,该系统包括程序测试、镜像构建和镜像推送。
6 changes: 3 additions & 3 deletions balance/balance4.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@

## 4.4.1 直接路由模式

LVS 的直接路由模式,实际上是一种链路层负载均衡技术
LVS 的直接路由模式,实际是一种链路层负载均衡技术

链路层负载均衡的原理是,负载均衡器(LVS)收到请求后,修改数据帧的目标 MAC 地址,将原本发给负载均衡器的数据帧重新定向,经过二层交换机转发至某个“后端服务器”。

后端服务器在解包数据帧时,会发现 IP 层的目标地址并非本机,从而导致 Linux 内核网络协议栈无法进一步处理该数据包。为解决这一问题,需要将虚拟 IP(VIP,Virtual IP)配置到本地回环接口(简称 lo 接口)上。
后端服务器解析数据帧时,会发现 IP 层的目标地址并非本机,从而导致 Linux 内核网络协议栈无法进一步处理该数据包。为解决这一问题,需要将虚拟 IP(VIP,Virtual IP)配置到本地回环接口(简称 lo 接口)上。

如某个 VIP 为 1.1.1.1,通过以下命令将该 IP 绑定到后端服务器的 lo 接口:

Expand Down Expand Up @@ -48,7 +48,7 @@ $ echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce

## 4.4.2 隧道模式

在直接路由模式中,请求转发通过修改数据链路层的 MAC 地址实现。而在网络层,也可以通过类似方式修改 IP 数据包来完成请求转发。LVS 的隧道(Tunnel)模式和网络地址转换(NAT)模式都属于网络层负载均衡,两者的区别在于对 IP 数据包的修改方式不同。
在直接路由模式中,请求转发通过修改链路层的 MAC 地址实现。而在网络层,也可以通过类似方式修改 IP 数据包来完成请求转发。LVS 的隧道(Tunnel)模式和网络地址转换(NAT)模式都属于网络层负载均衡,两者的区别在于对 IP 数据包的修改方式不同。


在隧道模式下,LVS 会创建一个新的 IP 数据包,并将原始 IP 数据包作为负载嵌入其中。随后,这个新数据包通过三层交换机发送到后端服务器。当后端服务器收到数据包后,会通过拆包机制移除负载均衡器添加的额外头部,从而还原出原始的 IP 数据包进行处理。
Expand Down
23 changes: 12 additions & 11 deletions network/iptables.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ Netfilter 中的钩子,在 iptables 中称作“链”(chain)。

iptables 默认有五条链:PREROUTING、INPUT、FORWARD、OUTPUT、POSTROUTING。从名字上看,它们分别对应了 Netfilter 的 5 个钩子。

iptables 把一些常用数据包管理操作总结成具体的动作,当数据包经过内核协议栈的钩子时(也就是 iptables 的链),判断经过此链的数据包是否匹配 iptables 规则。iptables 规则包含匹配 IP 数据包源地址/目的地址、传输层协议(TCP/UDP/ICMP/...)
iptables 把常用数据包管理操作总结成具体的动作,当数据包经过内核协议栈的钩子时(也就是 iptables 的链),根据 IP 数据包源地址/目的地址、传输层协议(TCP/UDP/ICMP/...)、端口等信息判断是否触发定义好的动作

如果数据包匹配规则,则触发定义好的动作。如下为部分常见的动作说明
如下为常见的动作说明

- ACCEPT:允许数据包通过,继续执行后续的规则。
- DROP:直接丢弃数据包。
Expand All @@ -24,26 +24,27 @@ iptables 把一些常用数据包管理操作总结成具体的动作,当数
- MASQUERADE:地址伪装,可以理解为动态的 SNAT。通过它可以将源地址绑定到某个网卡上,因为这个网卡的 IP 可能是动态变化的,此时用 SNAT 就不好实现;
- LOG:内核对数据包进行日志记录。

不同的链上能处理的事情有区别,而相同的动作放在一起也便于管理。如数据包过滤的动作(ACCEPTDROPRETURNREJECT 等)可以合并到一处,数据包的修改动作(DNAT、SNAT)可以合并到另外一处,这便有了规则表的概念。
不同的链上能处理的事情有区别,同类型的动作放在一起也便于管理。如数据包过滤的动作(ACCEPTDROPRETURNREJECT 等)可以合并到一处,数据包的修改动作(DNAT、SNAT)可以合并到另外一处,这便有了规则表的概念。

将规则表与链进行关联,而不是规则本身与链关联,通过一个中间层解耦了链与具体的某条规则,原先复杂的对应关系就变得简单了。

iptables 共有 5 规则表,它们的名称与含义如下:
iptables 共有 5 张规则表,它们的名称与含义如下:

- raw 表:配置该表主要用于去除数据包上的连接追踪机制。默认情况下,连接会被跟踪,所以配置该表后,可以加速数据包穿越防火墙,提高性能。
- mangle 表:修改数据包内容,常用于数据包报文头的修改,比如服务类型(Type of Service, ToS),生存周期(Time to Live, TTL),Mark 标记等。
- raw 表:配置该表主要用于去除数据包上的连接追踪机制。默认情况下,连接会被跟踪,配置该表后,可以加速数据包穿越防火墙,提高性能。
- mangle 表:修改数据包内容,常用于数据包报文头的修改。比如修改数据包的 ToS 服务类型、TTL 生存周期、Mark 标记等。
- nat 表:用于修改数据包的源地址或目标地址,实现网络地址转换。当数据包进入协议栈的时候,nat 表中的规则决定是否以及如何修改包的源/目的地址,以改变包被路由时的行为。nat 表通常用于将包路由到无法直接访问的网络。
- filter 表:数据包过滤,控制到达某条链上的数据包是放行(ACCEPT),还是拒绝(REJECT),或是丢弃(DROP)等。iptables 命令的使用规则:iptables [-t table] ...,如果省略 -t table,则默认操作的就是 filter 表。
- security 表:安全增强,一般用于 SELinux 中,其他情况并不常用。

举一个具体的例子,放行 TCP 22 端口的流量,即在 INPUT 链上添加 ACCEPT 动作。

一个链上可以关联的表可以有多个,所以这 5 张表在一个链上执行的时候得有个顺序:raw --> mangle --> nat --> filter --> security,即先去连接追踪,再改数据包,然后做源或目标地址转换,最后是过滤和安全。
```bash
$ iptables -A INPUT -p tcp --dport 22 -j ACCEPT
```

数据包具体经过的表、链顺序如图 3-3 所示
将规则表与链进行关联,而不是规则本身与链关联,通过一个中间层解耦了链与具体的某条规则,原本复杂的对应关系就变得简单了。最后,数据包经过的链、触发的规则表如图 3-3 所示,总结为先标记连接跟踪(raw),然后修改数据包(mangle),接着进行源或目标地址转换(nat),最后完成数据包的过滤(filter)和安全策略的应用(security)

:::center
![](../assets/Netfilter-packet-flow.svg)<br/>
图 3-3 数据包通过 Netfilter 时的流向过程 [图片来源](https://en.wikipedia.org/wiki/Netfilter)
图 3-3 数据包通过 Netfilter 时的流动过程 [图片来源](https://en.wikipedia.org/wiki/Netfilter)
:::

## 2. iptables 自定义链与应用
Expand Down
Loading

0 comments on commit ab91329

Please sign in to comment.