云原生下基于K8S声明式GitOps持续部署工具ArgoCD实战-上

@

概述

定义

ArgoCD 官网地址 https://argoproj.github.io/cd

ArgoCD 最新官网文档 https://argo-cd.readthedocs.io/en/stable/

ArgoCD GitHub源码地址 https://github.com/argoproj/argo-cd

Argo官网 https://argoproj.github.io/ (用Kubernetes做更多的事情,用于Kubernetes运行工作流、管理集群和正确执行giitops的开源工具)

Argo CD是Kubernetes的声明式、GitOps连续交付工具。Argo CD是由Intuit主导的开源项目,是Argo项目集合中的一个,Argo项目集合还包括Argo Workflow、Argo Rollout、Argo Event等项目。

Argo CD 遵循 GitOps 模式,使用 Git 仓库作为定义所需应用程序状态的真实来源,Argo CD 支持多种 Kubernetes 清单:

  • kustomize
  • helm charts
  • ksonnet applications
  • jsonnet files

image-20220919175113340

Argo CD主要优势有:

  • 应用程序定义、配置和环境应该是声明性的和版本控制的。
  • 应用程序部署和生命周期管理应该是自动化的、可审计的,并且容易理解。
  • Argo CD是一个独立的部署工具,支持对多个环境、多个Kubernetes集群上的应用进行统一部署和管理。

工作原理

Argo CD 是通过一个 Kubernetes 控制器来实现的,它持续 watch 正在运行的应用程序并将当前的实时状态与所需的目标状态( Git 存储库中指定的)进行比较。已经部署的应用程序的实际状态与目标状态有差异,则被认为是 状态,Argo CD 会报告显示这些差异,同时提供工具来自动或手动将状态同步到期望的目标状态。在 Git 仓库中对期望目标状态所做的任何修改都可以自动应用反馈到指定的目标环境中去。

image-20221002115323187

主要组件

  • API 服务:API 服务是一个 gRPC/REST 服务,它暴露了 Web UI、CLI 和 CI/CD 系统使用的接口,主要有以下几个功能:
    • 应用程序管理和状态报告
    • 执行应用程序操作(例如同步、回滚、用户定义的操作)
    • 存储仓库和集群凭据管理(存储为 K8S Secrets 对象)
    • 认证和授权给外部身份提供者
    • RBAC
    • Git webhook 事件的侦听器/转发器
  • 仓库服务:存储仓库服务是一个内部服务,负责维护保存应用程序清单 Git 仓库的本地缓存。当提供以下输入时,它负责生成并返回 Kubernetes 清单:
    • 存储 URL
    • revision 版本(commit、tag、branch)
    • 应用路径
    • 模板配置:参数、ksonnet 环境、helm values.yaml 等
  • 应用控制器:应用控制器是一个 Kubernetes 控制器,它持续 watch 正在运行的应用程序并将当前的实时状态与所期望的目标状态( repo 中指定的)进行比较。它检测应用程序的 状态,并采取一些措施来同步状态,它负责调用任何用户定义的生命周期事件的钩子(PreSync、Sync、PostSync)。功能
    • 自动部署应用程序到指定的目标环境
    • 支持多种配置管理/模板工具(Kustomize、Helm、Ksonnet、Jsonnet、plain-YAML)
    • 能够管理和部署到多个集群
    • SSO 集成(OIDC、OAuth2、LDAP、SAML 2.0、GitHub、GitLab、Microsoft、LinkedIn)
    • 用于授权的多租户和 RBAC 策略
    • 回滚/随时回滚到 Git 存储库中提交的任何应用配置
    • 应用资源的健康状况分析
    • 自动配置检测和可视化
    • 自动或手动将应用程序同步到所需状态
    • 提供应用程序活动实时视图的 Web UI
    • 用于自动化和 CI 集成的 CLI
    • Webhook 集成(GitHub、BitBucket、GitLab)
    • 用于自动化的 AccessTokens
    • PreSync、Sync、PostSync Hooks,以支持复杂的应用程序部署(例如蓝/绿和金丝雀发布)
    • 应用程序事件和 API 调用的审计
    • Prometheus 监控指标
    • 用于覆盖 Git 中的 ksonnet/helm 参数

核心概念

  • Application:应用,一组由资源清单定义的 Kubernetes 资源,这是一个 CRD 资源对象

    Application source type:用来构建应用的工具

    Target state:目标状态,指应用程序所需的期望状态,由 Git 存储库中的文件表示

    Live state:实时状态,指应用程序实时的状态,比如部署了哪些 Pods 等真实状态

    Sync status:同步状态表示实时状态是否与目标状态一致,部署的应用是否与 Git 所描述的一样?

    Sync:同步指将应用程序迁移到其目标状态的过程,比如通过对 Kubernetes 集群应用变更

    Sync operation status:同步操作状态指的是同步是否成功

    Refresh:刷新是指将 Git 中的最新代码与实时状态进行比较,弄清楚有什么不同

    Health:应用程序的健康状况,它是否正常运行?能否为请求提供服务?

    Tool:工具指从文件目录创建清单的工具,例如 Kustomize 或 Ksonnet 等

    Configuration management tool:配置管理工具

    Configuration management plugin:配置管理插件

环境准备

概述

需要安装K8S集群,前面文章我们分别使用KubeAdmin和Rancher部署过完整K8S集群,如果是建议测试的可以使用Kubekey快速部署一个AllInOne单节点K8S,Kubekey为kubesphere下子项目,后面在安装K9S以命令行界面方式查看和管理K8S集群。

安装Kubekey

mkdir kubekey
cd kubekey
# 下载最新版本v2.2.2
wget https://github.com/kubesphere/kubekey/releases/download/v2.2.2/kubekey-v2.2.2-linux-amd64.tar.gz
tar -xvf kubekey-v2.2.2-linux-amd64.tar.gz
# 解压完为有文件名为kk可执行文件,查看版本信息
./kk version

image-20220919182109614

创建K8S

export KKZONE=cn
# 生成配置
./kk create config --name kk-k8s

image-20220919183007053

image-20220920090251077

修改config-kk-k8s.yaml内容如下,vi config-kk-k8s.yaml

apiVersion: kubekey.kubesphere.io/v1alpha2
kind: Cluster
metadata:
  name: kk-k8s
spec:
  hosts:
  - {name: k8snode, address: 192.168.50.95, internalAddress: 192.168.50.95, user: root, password: "zijimima"}
  roleGroups:
    etcd:
    - k8snode
    control-plane:
    - k8snode
    worker:
    - k8snode
  controlPlaneEndpoint:
    ## Internal loadbalancer for apiservers
    # internalLoadbalancer: haproxy

    domain: kk-k8s.api.com
    address: ""
    port: 6443
  kubernetes:
    version: v1.23.8
    clusterName: cluster.local
    autoRenewCerts: true
    containerManager: docker
  etcd:
    type: kubekey
  network:
    plugin: calico
    kubePodsCIDR: 10.233.64.0/18
    kubeServiceCIDR: 10.233.0.0/18
    ## multus support. https://github.com/k8snetworkplumbingwg/multus-cni
    multusCNI:
      enabled: false
  registry:
    privateRegistry: ""
    namespaceOverride: ""
    registryMirrors: []
    insecureRegistries: []
  addons: []

开始创建集群

setenforce 0 
yum install socat conntrack ebtables ipset
./kk create cluster -f config-kk-k8s.yaml

image-20220920090612969

等待一段时间安装,安装完成后打印安装完成的日志

image-20220920121137013

yum install bash-completion -y 
# 安装Kubectl 这个之前文章有,这里就不再说明
echo "source <(kubectl completion bash)" >> ~/.bashrc
source ~/.bashrc

安装K9S

这里我们使用前面文章基于Rancher创建好的K8S集群

mkdir k9s
cd k9s
# 下载最新版本v0.26.3
wget https://github.com/derailed/k9s/releases/download/v0.26.3/k9s_Linux_x86_64.tar.gz
# 解压文件
tar -xvf k9s_Linux_x86_64.tar.gz
./k9s version

image-20220922180603488

直接执行./k9s,冒号后输入也支持简写比如ns

image-20221002150709331

OpenLB

  • OpenELB 是一个开源的云原生负载均衡器实现,可以在基于裸金属服务器、边缘以及虚拟化的 Kubernetes 环境中使用 LoadBalancer 类型的 Service 对外暴露服务。OpenELB 项目最初由 KubeSphere 社区[2] 发起,目前已作为 CNCF 沙箱项目[3] 加入 CNCF 基金会,由 OpenELB 开源社区维护与支持。
  • 在 k8s 原生集群上部署 OpenELB 作为 k8s 的 LoadBalancer,主要涉及 OpenELBLayer2 模式BGP 模式两种部署方案。
  • 与 MetalLB 类似,OpenELB 也拥有两种主要工作模式:Layer2 模式和 BGP 模式。OpenELB 的 BGP 模式目前暂不支持 IPv6。无论是 Layer2 模式还是 BGP 模式,核心思路都是通过某种方式将特定 VIP 的流量引到 k8s 集群中,然后再通过 kube-proxy 将流量转发到后面的特定服务

例如:Layer2 模式需要我们的 k8s 集群基础环境支持发送 anonymous ARP/NDP packets。因为 OpenELB 是针对裸金属服务器设计的,因此如果是在云环境中部署,需要注意是否满足条件。

image-20221002151532472

  • 图中有一个类型为 LoadBalancer 的 Service,其 VIP 为 192.168.0.91(和 k8s 的节点相同网段),后端有两个 pod(分别为 pod1 和 pod2)
  • 安装在 Kubernetes 集群中的 OpenELB 随机选择一个节点(图中为 worker 1)来处理 Service 请求。当局域网中出现 arp request 数据包来查询 192.168.0.91 的 mac 地址的时候,OpenELB 会进行回应(使用 worker 1 的 MAC 地址),此时路由器(也可能是交换机)将 Service 的 VIP 192.168.0.91 和 worker 1 的 MAC 地址绑定,之后所有请求到 192.168.0.91 的数据包都会被转发到 worker1 上
  • Service 流量到达 worker 1 后, worker 1 上的 kube-proxy 将流量转发到后端的两个 pod 进行负载均衡,这些 pod 不一定在 work1 上

主要的工作流程就如同上面描述的一般,但是还有几个需要额外注意的点:

  • 如果 worker 1 出现故障,OpenELB 会重新向路由器发送 APR/NDP 数据包,将 Service IP 地址映射到 worker 2 的 MAC 地址,Service 流量切换到 worker 2
  • 主备切换过程并不是瞬间完成的,中间会产生一定时间的服务中断(具体多久官方也没说,实际上应该是却决于检测到节点宕机的时间加上重新选主的时间)
  • 如果集群中已经部署了多个 openelb-manager 副本,OpenELB 使用 Kubernetes 的领导者选举特性算法来进行选主,从而确保只有一个副本响应 ARP/NDP 请求
# 以yaml方式部署openelb
wget https://raw.githubusercontent.com/openelb/openelb/master/deploy/openelb.yaml
kubectl apply -f openelb.yaml

配置 loadbalancerIP 所在的网段资源,创建一个 Eip 对象来进行定义,后面对 IP 段的管理也是在这里进行

apiVersion: network.kubesphere.io/v1alpha2
kind: Eip
metadata:
    # Eip 对象的名称。
    name: eip-layer2-pool
spec:
    # Eip 对象的地址池
    address: 10.31.88.101-10.31.88.200 
    # openELB的运行模式,默认为bgp
    protocol: layer2 
    # OpenELB 在其上侦听 ARP/NDP 请求的网卡。该字段仅在protocol设置为时有效layer2。
    interface: eth0
    # 指定是否禁用 Eip 对象
    # false表示可以继续分配
    # true表示不再继续分配
    disable: false
status:
    # 指定 Eip 对象中的IP地址是否已用完。
    occupied: false
    # 指定 Eip 对象中有多少个 IP 地址已分配给服务。
    # 直接留空,系统会自动生成
    usage:  
    # Eip 对象中的 IP 地址总数。
    poolSize: 100 
    # 指定使用的 IP 地址和使用 IP 地址的服务。服务以Namespace/Service name格式显示(例如,default/test-svc)。
    # 直接留空,系统会自动生成
    used: 
    # Eip 对象中的第一个 IP 地址。
    firstIP: 10.31.88.101
    # Eip 对象中的最后一个 IP 地址。
    lastIP: 10.31.88.20 
    ready: true
    # 指定IP协议栈是否为 IPv4。目前,OpenELB 仅支持 IPv4,其值只能是true.
    v4: true
# 配置完成直接部署即可
kubectl apply -f openelb/openelb-eip.yaml

安装ArgoCD

ArgoCD 的部署,也可以通过官方提供的 Helm Chart 直接部署,但为了了解更多的底层逻辑,这里直接使用官方提供的配置清单安装。

# 建命名空间
kubectl create namespace argocd
# Non-HA:
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/v2.4.12/manifests/install.yaml
# HA:
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/v2.4.12/manifests/ha/install.yaml
# 安装应用 ArgoCD 配置清单,生产使用建议使用stable,https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/master/manifests/install.yaml
# 或者先下载再安装
wget https://raw.githubusercontent.com/argoproj/argo-cd/v2.4.12/manifests/install.yaml
kubectl apply -n argocd -f install.yaml

image-20221002174956466

通过k9s查看argocd命名空间的pods

image-20221002175125923

默认情况下,Argo CD API服务器不公开外部IP。要访问API服务器,可以选择以下技术之一来公开Argo CD API服务器:

  • Service Type Load Balancer:修改argocd-server服务类型为LoadBalancer:
kubectl patch svc argocd-server -n argocd -p '{"spec": {"type": "LoadBalancer"}}'
  • Port Forwarding:Kubectl端口转发还可以用于连接到API服务器,而不公开服务。操作如下后可以使用https://localhost:8080访问API服务器
kubectl port-forward svc/argocd-server -n argocd 8080:443
  • Ingress配置,详细可以参考官方的文档

image-20221002191401189

创建vim argocd-ingress.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: argocd-server-ingress
  namespace: argocd
  annotations:
    kubernetes.io/tls-acme: "true"
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
    nginx.ingress.kubernetes.io/ssl-passthrough: "true"
    nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
spec:
  rules:
  - host: argocd.test.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: argocd-server
            port:
              name: https
  tls:
  - hosts:
    - argocd.test.com
    secretName: argocd-secret
# 创建ingress
kubectl apply -f argocd-ingress.yaml
# 查看服务器导出地址
kubectl get ingress -n argocd

image-20221002182255293

如果本地使用可以直接配置hosts文件 ,配置好后,访问 argocd.test.com 即可进入登录页。

192.168.5.53 argocd.test.com

注:细心的同学可能已经注意到,虽然 ingress 中配置了 https 协议,但浏览器仍然显示链接非安全。那是因为 argocd-secret 中存储的证书,是 ArgoCD 生成的自签证书,浏览器不信任。想要获得安全连接,可以使用浏览器信任的域名证书替换即可。

# admin 用户密码
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d

输入默认访问用户admin和上述的密码后进入主页面

image-20221002182606306

安装 ArgoCD CLI

# 下载
wget https://github.com/argoproj/argo-cd/releases/download/v2.4.12/argocd-linux-amd64
cp argocd-linux-amd64 /usr/local/bin/argocd
chmod +x /usr/local/bin/argocd

image-20221002190042094

# 本机上也可以直接通过svc的内部地址直接登录
argocd login 10.43.171.238 --username admin --password c4iy3ZyPGUHdzuaz
# 更新密码账号密码
argocd account update-password

image-20221002190516860

从Git库中创建一个应用程序

这里通过官网https://github.com/argoproj/argocd-example-apps.git上提供的guestbook应用程序的示例存储库来演示Argo CD,可以使用以下命令创建示例

argocd app create guestbook --repo https://github.com/argoproj/argocd-example-apps.git --path guestbook --dest-server https://kubernetes.default.svc --dest-namespace default

也使用WebUI方式创建,选择新建APP,应用命名为guestbook,使用项目默认值,保持同步策略为Manual也即是手工

image-20221003113927741

继续填写构建项目git来源,通过将库url设置为github repo url,将https://github.com/argoproj/argocd-example-apps.git repo连接到Argo CD,将revision保留为HEAD,并将路径设置为kustomize-guestbook;Destination:设置cluster URL为https://kubernetes.default.svc(或设置集群名称为in-cluster), namespace为自定义或default,填写完以上信息后,点击UI顶部的Create创建留言簿应用程序。

image-20221003120439063

点击创建按钮后

image-20221003121422507

本篇简单入门就到此,后续有时间再继续进一步完成如下内容

  • 自建应用模拟开发场景
  • 基于 GitHub 实现自动化部署
  • Argo CD 数据加密之 sealed secret
  • Argo CD Webhook 的使用介绍
  • App of apps 模式
  • Argo CD 对多集群的支持
  • Application Set理论知识和ApplicationSet 生成器
  • 管理员相关配置

**本人博客网站 **IT小神 www.itxiaoshen.com

posted @ 2022-10-03 12:46  itxiaoshen  阅读(68)  评论(0编辑  收藏  举报