美元(注)
网友系列
本文补充了一系列关于使用 Kubernetes 进行 CI/CD 的网络研讨会(https://go.digitalocean.com/cicd-on-k8s)。该系列讨论如何采用云原生方法来构建、测试和部署应用程序,涵盖发布管理、云原生工具、服务网格和可与 Kubernetes 一起使用的 CI/CD 工具。
本教程包括从系列的第二个会话的概念和命令,Kubernetes包管理与头盔和CI/CD与Jenkins X
<$>[警告] **警告:**本教程中的程序仅用于示范目的,因此它们不遵循生产准备部署所需的最佳实践和安全措施。
[youtube oZOZiL6XIfA 480 854 ]
介绍
为了减少错误并在部署应用程序时组织复杂性,CI/CD系统必须包括可靠的包管理/部署工具和有自动测试的管道,但在现代生产环境中,基于云的基础设施的复杂性增加可能会给可靠的CI/CD环境带来问题。
Helm是专为Kubernetes设计的包管理器,由Cloud Native Computing Foundation(https://www.cncf.io/)(CNCF)与微软,谷歌,Bitnami和Helm贡献者社区合作维护:在高层次上,它实现了与Linux系统包管理器(如APT或YUM)相同的目标:管理应用程序的安装和依赖性,并隐藏用户的复杂性。但是在Kubernetes中,这种管理的需求更为明显:安装应用程序需要YAML文件的复杂和疲劳的编排,升级或滚动版本可以从任何地方变得困难到不可能。为了解决这个问题,Helm在Kubernetes和应用程序包上运行到预配置资源,称为 charts,用户可以用简单的命令来管理,使应用程序共享和管理过程更加用户友
Jenkins X 是用于自动化 Kubernetes 生产管道和环境的 CI/CD 工具,使用 Docker 图像、 Helm 图表和 Jenkins 管道引擎,Jenkins X 可以自动管理发布和版本,并在 GitHub 上在环境之间推广应用程序。
在 CI/CD with Kubernetes系列的第二篇文章中,您将通过以下两种工具预览:
- 使用 Helm 管理、创建和部署 Kubernetes 包
- 使用 Jenkins X 构建 CI/CD 管道
虽然各种Kubernetes平台可以使用Helm和Jenkins X,但在本教程中,您将运行一个模拟的Kubernetes集群,设置在您的本地环境中。
到本教程结束时,您将对这些Kubernetes原生工具如何帮助您为云应用程序实现CI/CD系统的基本理解。
前提条件
要遵循本教程,您将需要:
- 具有 16 GB RAM 或更高版本的 Ubuntu 16.04 服务器. 由于本教程仅用于演示目的,命令会从 root 帐户运行。 ** 请注意,本帐户的无限制权限不遵守生产准备的最佳实践,并可能影响您的系统。** 因此,建议在虚拟机或 DigitalOcean Droplet等测试环境中遵循这些步骤。
- A GitHub 帐户和 GitHub API 代币)。
步骤 1 — 使用 Minikube 创建本地 Kubernetes 集群
在安装 Minikube 之前,您将需要安装它的依赖性,包括 Kubernetes 命令行工具 kubectl,双向数据传输传递器 socat和容器程序 Docker。
首先,请确保您的系统的包管理器可以通过apt-transport-https
访问通过 HTTPS 的包:
1apt-get update
2apt-get install apt-transport-https
接下来,为了确保cubectl下载是有效的,请将官方谷歌存储库的GPG密钥添加到您的系统:
1curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -
一旦您添加了 GPG 键,请在文本编辑器中打开该文件,创建文件 `/etc/apt/sources.list.d/kubernetes.list:
1nano /etc/apt/sources.list.d/kubernetes.list
打开此文件后,添加以下行:
1[label /etc/apt/sources.list.d/kubernetes.list]
2deb http://apt.kubernetes.io/ kubernetes-xenial main
这将显示您的系统下载 kubectl 的来源。一旦您添加了行,保存并退出文件. 使用纳米文本编辑器,您可以通过按CTRL+X
,键入y
,然后按ENTER
来做到这一点。
最后,更新 APT 的源列表并安装kubectl
,socat
和docker.io
:
1apt-get update
2apt-get install -y kubectl socat docker.io
<$>[注]
注: Minikube 要模拟 Kubernetes 集群,您必须下载docker.io
包,而不是更新的docker-ce
版本。
现在你已经安装了 kubectl,你可以继续使用 安装 Minikube。
1curl -Lo minikube https://storage.googleapis.com/minikube/releases/v0.28.0/minikube-linux-amd64
接下来,更改您刚刚下载的文件的访问权限,以便您的系统可以执行它:
1chmod +x minikube
最后,将minikube
文件复制到/usr/local/bin/
的可执行路径,并从您的主目录中删除原始文件:
1cp minikube /usr/local/bin/
2rm minikube
有了 Minikube 安装在您的计算机上,您现在可以启动该程序. 若要创建一个 Minikube Kubernetes 集群,请使用以下命令:
1minikube start --vm-driver none
旗帜 `--vm-driver none' 指示 Minikube 在本地主机上运行 Kubernetes 使用容器而不是虚拟机. 以这种方式运行 Minikube 意味着您不需要下载 VM 驱动程序,但也意味着 Kubernetes API 服务器将作为根运行不安全。
<$>[警告]
**警告:**由于具有 root 权限的 API 服务器可以无限制地访问本地主机,因此不建议在个人工作站上使用none
驱动程序运行 Minikube。
现在您已经启动了 Minikube,请检查以确保您的集群使用以下命令运行:
1minikube status
您将收到以下输出,您的IP地址代替your_IP_address
:
1minikube: Running
2cluster: Running
3kubectl: Correctly Configured: pointing to minikube-vm at your_IP_address
现在,您已经使用 Minikube 设置了模拟的 Kubernetes 集群,您可以通过在集群顶部安装和配置 Helm 包管理器来获得 Kubernetes 包管理的经验。
步骤 2 — 在您的集群上设置头盔包管理器
为了协调在您的Kubernetes集群上安装应用程序,您现在将安装Helm包管理器。Helm由一个头盔
客户端组成,该客户端运行在集群外部,以及一个帐篷
服务器,该服务器从集群内部管理应用程序发布。
要 安装 Helm 二进制,首先使用‘curl’来从官方 Helm GitHub 存储库下载以下 安装脚本到名为 `get_helm.sh’的新文件中:
1curl https://raw.githubusercontent.com/kubernetes/helm/master/scripts/get > get_helm.sh
由于此脚本需要 root 访问,请更改 `get_helm.sh 的权限,以便文件的所有者(在这种情况下,root)可以读取、写入和执行:
1chmod 700 get_helm.sh
现在,执行剧本:
1./get_helm.sh
当脚本完成时,您将安装头盔
到/usr/local/bin/helm
和tiller
到/usr/local/bin/tiller
。
虽然tiller
现在已安装,但它还没有正确的角色和权限来访问 Kubernetes 集群中所需的资源。 要将这些角色和权限分配给tiller
,您将需要创建一个名为tiller
的 service account 帐户。 在 Kubernetes 中,服务帐户代表在 pod 中运行的流程的身份。 经过通过服务帐户身份验证后,该进程可以联系 API 服务器并访问集群资源。 如果一个 pod 未分配给特定服务帐户,它将获得默认服务帐户。
在 Kubernetes RBAC API 中,一个 role 包含规则,可以确定一组权限。一个角色可以用名称空间
或群集
的范围定义,并且只能在单个名称空间内授予资源访问权限。
1nano rbac_helm.yaml
将下列行添加到文件中以配置tiller
服务帐户:
1[label rbac_helm.yaml]
2apiVersion: v1
3kind: ServiceAccount
4metadata:
5 name: tiller
6 namespace: kube-system
7---
8apiVersion: rbac.authorization.k8s.io/v1beta1
9kind: ClusterRoleBinding
10metadata:
11 name: tiller
12roleRef:
13 apiGroup: rbac.authorization.k8s.io
14 kind: ClusterRole
15 name: cluster-admin
16subjects:
17 - kind: ServiceAccount
18 name: tiller
19 namespace: kube-system
20
21 - kind: User
22 name: "admin"
23 apiGroup: rbac.authorization.k8s.io
24
25 - kind: User
26 name: "kubelet"
27 apiGroup: rbac.authorization.k8s.io
28
29 - kind: Group
30 name: system:serviceaccounts
31 apiGroup: rbac.authorization.k8s.io
在前面的文件中,ServiceAccount
允许tiller
进程以身份验证的服务帐户访问 apiserver。ClusterRole
向角色授予某些权限,而ClusterRoleBinding
则将该角色分配给主体
列表,包括tiller
服务帐户、admin
和kubelet
用户以及system:serviceaccounts
组。
接下来,使用以下命令在 rbac_helm.yaml
中部署配置:
1kubectl apply -f rbac_helm.yaml
有了部署的tiller
配置,您现在可以用--service-acount
旗帜初始化Helm,以使用您刚刚设置的服务帐户:
1helm init --service-account tiller
您将收到以下输出,代表成功的初始化:
1[secondary_label Output]
2Creating /root/.helm
3Creating /root/.helm/repository
4Creating /root/.helm/repository/cache
5Creating /root/.helm/repository/local
6Creating /root/.helm/plugins
7Creating /root/.helm/starters
8Creating /root/.helm/cache/archive
9Creating /root/.helm/repository/repositories.yaml
10Adding stable repo with URL: https://kubernetes-charts.storage.googleapis.com
11Adding local repo with URL: http://127.0.0.1:8879/charts
12$HELM_HOME has been configured at /root/.helm.
13
14Tiller (the Helm server-side component) has been installed into your Kubernetes Cluster.
15
16Please note: by default, Tiller is deployed with an insecure 'allow unauthenticated users' policy.
17To prevent this, run `helm init` with the --tiller-tls-verify flag.
18For more information on securing your installation see: https://docs.helm.sh/using_helm/#securing-your-helm-installation
19Happy Helming!
它还在您的$HOME
目录中创建了.helm
默认存储库,并配置了默认 Helm 稳定图表存储库在https://kubernetes-charts.storage.googleapis.com
和本地 Helm 存储库在http://127.0.0.1:8879/charts
。
要确保tiller
pod 在cube-system
名称空间中运行,请输入以下命令:
1kubectl --namespace kube-system get pods
在您的 pods 列表中,将出现tiller-deploy
,如下输出所示:
1[secondary_label Output]
2NAME READY STATUS RESTARTS AGE
3etcd-minikube 1/1 Running 0 2h
4kube-addon-manager-minikube 1/1 Running 0 2h
5kube-apiserver-minikube 1/1 Running 0 2h
6kube-controller-manager-minikube 1/1 Running 0 2h
7kube-dns-86f4d74b45-rjql8 3/3 Running 0 2h
8kube-proxy-dv268 1/1 Running 0 2h
9kube-scheduler-minikube 1/1 Running 0 2h
10kubernetes-dashboard-5498ccf677-wktkl 1/1 Running 0 2h
11storage-provisioner 1/1 Running 0 2h
12tiller-deploy-689d79895f-bggbk 1/1 Running 0 5m
如果tiller
pod 的状态为运行
,它现在可以代表 Helm 管理 Kubernetes 应用程序。
要确保整个Helm应用程序正常工作,请搜索Helm包存储库,查找MongoDB等应用程序:
1helm search mongodb
在输出中,您将看到适合您的搜索术语的可能应用程序列表:
1[secondary_label Output]
2NAME CHART VERSION APP VERSION DESCRIPTION
3stable/mongodb 5.4.0 4.0.6 NoSQL document-oriented database that stores JSON-like do...
4stable/mongodb-replicaset 3.9.0 3.6 NoSQL document-oriented database that stores JSON-like do...
5stable/prometheus-mongodb-exporter 1.0.0 v0.6.1 A Prometheus exporter for MongoDB metrics
6stable/unifi 0.3.1 5.9.29 Ubiquiti Network's Unifi Controller
现在,您已经在Kubernetes集群上安装了Helm,您可以通过创建样本Helm图表并从中部署应用程序来了解更多关于包管理器的信息。
步骤 3 — 创建图表并使用头盔部署应用程序
在 Helm 包管理器中,单个包被称为 charts. 在图表中,一组文件定义了一个应用程序,其复杂性可以从一个 pod 到一个结构化、完整的应用程序,您可以从 Helm 存储库下载图表,或者您可以使用创建头盔
命令创建自己的。
要测试Helm的功能,请创建一个名为demo
的新Helm图,使用以下命令:
1helm create demo
在您的主目录中,您将找到一个名为演示
的新目录,在其中您可以创建和编辑自己的图表模板。
移动到演示
目录,并使用ls
列出其内容:
1cd demo
2ls
您将在Demo
中找到以下文件和目录:
1[label demo]
2charts Chart.yaml templates values.yaml
使用您的文本编辑器,打开‘Chart.yaml’文件:
1nano Chart.yaml
在里面,你会发现以下内容:
1[label demo/Chart.yaml]
2apiVersion: v1
3appVersion: "1.0"
4description: A Helm chart for Kubernetes
5name: demo
6version: 0.1.0
在这个Chart.yaml
文件中,你会发现像apiVersion
这样的字段,它必须始终是v1
,一个描述
,它提供了有关演示
是什么的额外信息,图表的名称
和版本
号码,Helm 将其用作释放标记。
接下来,打开values.yaml
文件:
1nano values.yaml
在此文件中,您将找到以下内容:
1[label demo/values.yaml]
2# Default values for demo.
3# This is a YAML-formatted file.
4# Declare variables to be passed into your templates.
5
6replicaCount: 1
7
8image:
9 repository: nginx
10 tag: stable
11 pullPolicy: IfNotPresent
12
13nameOverride: ""
14fullnameOverride: ""
15
16service:
17 type: ClusterIP
18 port: 80
19
20ingress:
21 enabled: false
22 annotations: {}
23 # kubernetes.io/ingress.class: nginx
24 # kubernetes.io/tls-acme: "true"
25 paths: []
26 hosts:
27 - chart-example.local
28 tls: []
29 # - secretName: chart-example-tls
30 # hosts:
31 # - chart-example.local
32
33resources: {}
34 # We usually recommend not to specify default resources and to leave this as a conscious
35 # choice for the user. This also increases chances charts run on environments with little
36 # resources, such as Minikube. If you do want to specify resources, uncomment the following
37 # lines, adjust them as necessary, and remove the curly braces after 'resources:'.
38 # limits:
39 # cpu: 100m
40 # memory: 128Mi
41 # requests:
42 # cpu: 100m
43 # memory: 128Mi
44
45nodeSelector: {}
46
47tolerations: []
48
49affinity: {}
通过更改values.yaml
的内容,图表开发人员可以为图表中定义的应用程序提供默认值,控制复制数,图像基,入口访问,秘密管理等。
关闭values.yaml
文件,并用以下命令列出模板
目录的内容:
1ls templates
在这里,你会找到各种文件的模板,可以控制你的图表的不同方面:
1[label templates]
2deployment.yaml _helpers.tpl ingress.yaml NOTES.txt service.yaml tests
现在你已经探索了演示
图表,你可以通过安装演示
来尝试安装 Helm 图表。
1cd
在名称web
下安装demo
Helm 图表,并安装helm install
:
1helm install --name web ./demo
你会得到以下的输出:
1[secondary_label Output]
2NAME: web
3LAST DEPLOYED: Wed Feb 20 20:59:48 2019
4NAMESPACE: default
5STATUS: DEPLOYED
6
7RESOURCES:
8==> v1/Service
9NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
10web-demo ClusterIP 10.100.76.231 <none> 80/TCP 0s
11
12==> v1/Deployment
13NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
14web-demo 1 0 0 0 0s
15
16==> v1/Pod(related)
17NAME READY STATUS RESTARTS AGE
18web-demo-5758d98fdd-x4mjs 0/1 ContainerCreating 0 0s
19
20NOTES:
211. Get the application URL by running these commands:
22 export POD_NAME=$(kubectl get pods --namespace default -l "app.kubernetes.io/name=demo,app.kubernetes.io/instance=web" -o jsonpath="{.items[0].metadata.name}")
23 echo "Visit http://127.0.0.1:8080 to use your application"
24 kubectl port-forward $POD_NAME 8080:80
在此输出中,您将找到您的应用程序的状态
,以及集群中的相关资源列表。
接下来,用以下命令列出演示
头盔图所创建的部署:
1kubectl get deploy
这将产生输出,将列出您的活跃部署:
1[secondary_label Output]
2NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
3web-demo 1 1 1 1 4m
使用kubectl get pods
命令列出你的 pods 会显示正在运行你的Web
应用程序的 pods,这将看起来如下:
1[secondary_label Output]
2NAME READY STATUS RESTARTS AGE
3web-demo-5758d98fdd-nbkqd 1/1 Running 0 4m
要展示 Helm 图表中的变化如何释放应用程序的不同版本,请在文本编辑器中打开 demo/values.yaml
,并将 replicaCount:
更改为 3
和 image:tag:
从 stable' 到
latest'。
1[label demo/values.yaml]
2# Default values for demo.
3# This is a YAML-formatted file.
4# Declare variables to be passed into your templates.
5
6replicaCount: 3
7
8image:
9 repository: nginx
10 tag: latest
11 pullPolicy: IfNotPresent
12
13nameOverride: ""
14fullnameOverride: ""
15
16service:
17 type: ClusterIP
18 port: 80
19. . .
保存和退出文件。
在部署您的Web
应用程序的新版本之前,请使用以下命令列出您的Helm版本:
1helm list
您将收到以下输出,以及您之前创建的部署:
1[secondary_label Output]
2NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE
3web 1 Wed Feb 20 20:59:48 2019 DEPLOYED demo-0.1.0 1.0 default
请注意,修订
列为1
,表示这是Web
应用程序的第一个修订。
若要部署「web」應用程式以「demo/values.yaml」為最新變更,請使用以下命令升級應用程式:
1helm upgrade web ./demo
现在,列出 Helm 再次释放:
1helm list
您将获得以下输出:
1[secondary_label Output]
2NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE
3web 2 Wed Feb 20 21:18:12 2019 DEPLOYED demo-0.1.0 1.0 default
请注意,修订
已更改为2
,表示这是第二次修订。
要查找Web
的 Helm 版本的历史,请使用以下方法:
1helm history web
这将显示Web
应用程序的两种修订:
1[label Output]
2REVISION UPDATED STATUS CHART DESCRIPTION
31 Wed Feb 20 20:59:48 2019 SUPERSEDED demo-0.1.0 Install complete
42 Wed Feb 20 21:18:12 2019 DEPLOYED demo-0.1.0 Upgrade complete
若要将您的应用程序滚回修订 1
,请输入以下命令:
1helm rollback web 1
这将产生以下产出:
1[secondary_label Output]
2Rollback was a success! Happy Helming!
现在,举起 Helm 发布历史:
1helm history web
您将收到以下列表:
1[secondary_label Output]
2REVISION UPDATED STATUS CHART DESCRIPTION
31 Wed Feb 20 20:59:48 2019 SUPERSEDED demo-0.1.0 Install complete
42 Wed Feb 20 21:18:12 2019 SUPERSEDED demo-0.1.0 Upgrade complete
53 Wed Feb 20 21:28:48 2019 DEPLOYED demo-0.1.0 Rollback to 1
通过回滚Web
应用程序,您创建了一个具有与1
修订相同设置的第三个修订程序. 请记住,您可以通过在状态
下找到DEPLOYED
项目来确定哪个修订程序是积极的。
要为下一节做好准备,请通过删除头盔
命令删除您的Web
版本来清理测试区域:
1helm delete web
查看 Helm 发布历史再次:
1helm history web
您将获得以下输出:
1[secondary_label Output]
2REVISION UPDATED STATUS CHART DESCRIPTION
31 Wed Feb 20 20:59:48 2019 SUPERSEDED demo-0.1.0 Install complete
42 Wed Feb 20 21:18:12 2019 SUPERSEDED demo-0.1.0 Upgrade complete
53 Wed Feb 20 21:28:48 2019 DELETED demo-0.1.0 Deletion complete
「REVISION 3」的「STATUS」已更改為「DELETED」,表示您部署的「web」實例已被刪除。然而,儘管這會刪除版本,但不會從儲存中刪除它。
1helm delete web --purge
如果您想进一步研究Helm,请参阅我们的教程 An Introduction to Helm, the Package Manager for Kubernetes,或查看官方的 Helm文档。
接下来,您将使用jx
CLI 设置和测试管道自动化工具 Jenkins X,创建一个 CI/CD 准备的 Kubernetes 集群。
步骤4:设置Jenkins X环境
通过安装jx
CLI 工具,您将能够高效地管理应用程序发布、Docker 图像和 Helm 图表,以及在 GitHub 中自动推广您的应用程序。
由于您将使用jx
创建集群,您必须先删除您已经拥有的 Minikube 集群。
1minikube delete
这将删除本地模拟的 Kubernete 集群,但不会删除您第一次安装 Minikube 时创建的默认目录。
1rm -rf ~/.kube
2rm -rf ~/.minikube
3rm -rf /etc/kubernetes/*
4rm -rf /var/lib/minikube/*
一旦你完全清除Minikube从你的机器,你可以继续安装Jenkins X二进制。
首先,从官方的Jenkins X GitHub存储库(https://github.com/jenkins-x)下载压缩的jx
文件,并使用tar
命令解压缩它:
1curl -L https://github.com/jenkins-x/jx/releases/download/v1.3.781/jx-linux-amd64.tar.gz | tar xzv
接下来,将下载的jx
文件移动到/usr/local/bin
的可执行路径:
1mv jx /usr/local/bin
Jenkins X 配备了在您的 Kubernetes 集群内运行的 Docker 注册表,因为这是一个内部元素,因此自动签名的证书等安全措施可能会对程序造成问题。 要解决此问题,请将 Docker 设置为本地 IP 范围使用不安全的注册表。 要做到这一点,请创建 /etc/docker/daemon.json
文件并在文本编辑器中打开它:
1nano /etc/docker/daemon.json
将以下内容添加到文件中:
1[label /etc/docker/daemon.json]
2{
3 "insecure-registries" : ["0.0.0.0/0"]
4}
要使这些更改生效,请使用以下命令重新启动 Docker 服务:
1systemctl restart docker
若要验证您已将 Docker 配置为不安全注册表,请使用以下命令:
1docker info
在输出的末尾,你应该看到以下突出的行:
1[secondary_label Output]
2Containers: 0
3 Running: 0
4 Paused: 0
5 Stopped: 0
6Images: 15
7Server Version: 18.06.1-ce
8Storage Driver: overlay2
9 Backing Filesystem: extfs
10 Supports d_type: true
11 Native Overlay Diff: true
12
13. . .
14
15Registry: https://index.docker.io/v1/
16Labels:
17Experimental: false
18Insecure Registries:
19 0.0.0.0/0
20 127.0.0.0/8
21Live Restore Enabled: false
现在你已经下载了 Jenkins X 并配置了 Docker 注册表,使用jx
CLI 工具创建一个具有 CI/CD 功能的 Minikube Kubernetes 集群:
1jx create cluster minikube --cpu=5 --default-admin-password=admin --vm-driver=none --memory=13314
在这里,您正在使用 Minikube 创建一个 Kubernetes 集群,旗帜为 --cpu=5' 设置 5 个 CPU 和
--memory=13314' 为您的集群提供 13314 MB 的内存。 由于 Jenkins X 是一个强大但大型的程序,这些规格将确保 Jenkins X 在此演示中无问题地工作。
随着 Jenkins X 将您的集群旋转,您将在整个过程中的不同时间收到各种提示,这些提示将为您的集群设置参数,并确定它将如何与 GitHub 沟通以管理您的生产环境。
首先,您将收到以下快递:
1[secondary_label Output]
2? disk-size (MB) 150GB
接下来,您将被提示找出您想与 git 使用的名称、您想与 git 使用的电子邮件地址以及您的 GitHub 用户名。
接下来,Jenkins X会提示您输入您的GitHub API代币:
1[secondary_label Output]
2To be able to create a repository on GitHub we need an API Token
3Please click this URL https://github.com/settings/tokens/new?scopes=repo,read:user,read:org,user:email,write:repo_hook,delete_repo
4
5Then COPY the token and enter in into the form below:
6
7? API Token:
在这里输入你的代码,或者使用上一个代码块中突出的 URL 创建一个新的代码,具有相应的权限。
接下来,Jenkins X会问:
1[secondary_label Output]
2? Do you wish to use GitHub as the pipelines Git server: (Y/n)
3
4? Do you wish to use your_GitHub_username as the pipelines Git user for GitHub server: (Y/n)
输入Y
对两个问题。
在此之后,Jenkins X会提示你回答以下问题:
1[secondary_label Output]
2? Select Jenkins installation type: [Use arrows to move, type to filter]
3>Static Master Jenkins
4 Serverless Jenkins
5
6? Pick workload build pack: [Use arrows to move, type to filter]
7> Kubernetes Workloads: Automated CI+CD with GitOps Promotion
8 Library Workloads: CI+Release but no CD
对于前者,请选择Static Master Jenkins
,然后选择Kubernetes Workloads: Automated CI+CD with GitOps Promotion
。
最后,您将收到以下输出,该输出验证了成功的安装并提供您的Jenkins X管理员密码。
1[secondary_label Output]
2Creating GitHub webhook for your_GitHub_username/environment-horsehelix-production for url http://jenkins.jx.your_IP_address.nip.io/github-webhook/
3
4Jenkins X installation completed successfully
5
6 ********************************************************
7
8 NOTE: Your admin password is: admin
9
10 ********************************************************
11
12Your Kubernetes context is now set to the namespace: jx
13To switch back to your original namespace use: jx namespace default
14For help on switching contexts see: https://jenkins-x.io/developing/kube-context/
15
16To import existing projects into Jenkins: jx import
17To create a new Spring Boot microservice: jx create spring -d web -d actuator
18To create a new microservice from a quickstart: jx create quickstart
接下来,使用jx get
命令获取显示您应用程序信息的 URL 列表:
1jx get urls
這個命令會產生類似於以下的列表:
1Name URL
2jenkins http://jenkins.jx.your_IP_address.nip.io
3jenkins-x-chartmuseum http://chartmuseum.jx.your_IP_address.nip.io
4jenkins-x-docker-registry http://docker-registry.jx.your_IP_address.nip.io
5jenkins-x-monocular-api http://monocular.jx.your_IP_address.nip.io
6jenkins-x-monocular-ui http://monocular.jx.your_IP_address.nip.io
7nexus http://nexus.jx.your_IP_address.nip.io
您可以使用 URL 查看 Jenkins X 关于您的 CI/CD 环境的数据,通过输入该地址到您的浏览器并输入您的用户名和密码。
接下来,为了确保名称空间jx
、jx-staging
和jx-production
中的服务帐户具有管理权限,请使用以下命令修改您的 RBAC 策略:
1kubectl create clusterrolebinding jx-staging1 --clusterrole=cluster-admin --user=admin --user=expose --group=system:serviceaccounts --serviceaccount=jx-staging:expose --namespace=jx-staging
1kubectl create clusterrolebinding jx-staging2 --clusterrole=cluster-admin --user=admin --user=expose --group=system:serviceaccounts --serviceaccount=jx-staging:default --namespace=jx-staging
1kubectl create clusterrolebinding jx-production1 --clusterrole=cluster-admin --user=admin --user=expose --group=system:serviceaccounts --serviceaccount=jx-production:expose --namespace=jx-productions
1kubectl create clusterrolebinding jx-production2 --clusterrole=cluster-admin --user=admin --user=expose --group=system:serviceaccounts --serviceaccount=jx-production:default --namespace=jx-productions
1kubectl create clusterrolebinding jx-binding1 --clusterrole=cluster-admin --user=admin --user=expose --group=system:serviceaccounts --serviceaccount=jx:expose --namespace=jx
1kubectl create clusterrolebinding jx-binding2 --clusterrole=cluster-admin --user=admin --user=expose --group=system:serviceaccounts --serviceaccount=jx:default --namespace=jx
现在,您已经创建了基于Jenkins X功能的本地Kubernetes集群,您可以继续在平台上创建应用程序,测试其CI/CD功能,并体验Jenkins X管道。
步骤 5 — 在您的Jenkins X环境中创建测试应用程序
有了您在 Kubernetes 集群中设置的 Jenkins X 环境,您现在有了 CI/CD 基础设施,可以帮助您自动化测试管道。
为了演示目的,本教程将使用由 CloudYuga团队创建的样本RSVP应用程序。
首先,用以下命令从存储库克隆样本应用程序:
1git clone https://github.com/do-community/rsvpapp.git
一旦你克隆了存储库,进入rsvpapp
目录并删除 git 文件:
1cd rsvpapp
2rm -r .git/
要为新应用程序初始化 git 存储库和 Jenkins X 项目,您可以使用「jx 创建」开始从零或模板,或「jx 导入」从本地项目或 git 存储库导入现有应用程序。
1jx import
Jenkins X 将提示您您的 GitHub 用户名,无论您是否希望初始化 git、委托信息、您的组织和您想要的存储库的名称。 回答是的,以初始化 git,然后为其余的请求提供您的个人 GitHub 信息和偏好。 当 Jenkins X 导入应用程序时,它将在您的应用程序主目录中创建 Helm 图表和 Jenkinsfile。您可以根据您的要求修改这些图表和 Jenkinsfile。
由于样本RSVP应用程序在其容器的端口 5000’上运行,请修改您的
charts/rsvpapp/values.yaml` 文件以匹配此。
1nano charts/rsvpapp/values.yaml
在这个 values.yaml
文件中,将 service:internalPort:
设置为 5000
。
1[label charts/rsvpapp/values.yaml]
2# Default values for python.
3# This is a YAML-formatted file.
4# Declare variables to be passed into your templates.
5replicaCount: 1
6image:
7 repository: draft
8 tag: dev
9 pullPolicy: IfNotPresent
10service:
11 name: rsvpapp
12 type: ClusterIP
13 externalPort: 80
14 internalPort: 5000
15 annotations:
16 fabric8.io/expose: "true"
17 fabric8.io/ingress.annotations: "kubernetes.io/ingress.class: nginx"
18resources:
19 limits:
20 cpu: 100m
21 memory: 128Mi
22 requests:
23 cpu: 100m
24 memory: 128Mi
25ingress:
26 enabled: false
保存和退出您的文件。
接下来,更改 charts/preview/requirements.yaml
以适应您的应用程序。 requirements.yaml
是一个 YAML 文件,开发人员可以宣布图表依赖性,以及图表的位置和所需版本。 由于我们的样本应用程序使用 MongoDB 用于数据库目的,您需要修改 charts/preview/requirements.yaml
文件以列出 MongoDB 作为依赖性。
1nano charts/preview/requirements.yaml
通过添加mongodb-replicaset
项在alias: cleanup
项后编辑文件,如下列代码块所示:
1[label charts/preview/requirements.yaml]
2# !! File must end with empty line !!
3dependencies:
4- alias: expose
5 name: exposecontroller
6 repository: http://chartmuseum.jenkins-x.io
7 version: 2.3.92
8- alias: cleanup
9 name: exposecontroller
10 repository: http://chartmuseum.jenkins-x.io
11 version: 2.3.92
12- name: mongodb-replicaset
13 repository: https://kubernetes-charts.storage.googleapis.com/
14 version: 3.5.5
15
16 # !! "alias: preview" must be last entry in dependencies array !!
17 # !! Place custom dependencies above !!
18- alias: preview
19 name: rsvpapp
20 repository: file://../rsvpapp
在这里,您已指定mongodb-replicaset
图为预览
图的依赖性。
接下来,重复此过程为您的rsvpapp
图表. 创建charts/rsvpapp/requirements.yaml
文件,并在文本编辑器中打开它:
1nano charts/rsvpapp/requirements.yaml
一旦文件被打开,添加以下内容,确保在填充的行前和之后有一个单行空白空间:
1[label charts/rsvpapp/requirements.yaml]
2
3dependencies:
4- name: mongodb-replicaset
5 repository: https://kubernetes-charts.storage.googleapis.com/
6 version: 3.5.5
现在您已指定mongodb-replicaset
图为您的rsvpapp
图的依赖性。
接下来,为了将样本RSVP应用程序的前端连接到MongoDB后端,在Charts/rsvpapp/templates/中添加一个
MONGODB_HOST环境变量到您的
deployment.yaml`文件中。
1nano charts/rsvpapp/templates/deployment.yaml
添加下列突出的行到文件中,除了文件顶部的一个空行和文件底部的两个空行。
1[label charts/rsvpapp/templates/deployment.yaml]
2
3apiVersion: extensions/v1beta1
4kind: Deployment
5metadata:
6 name: {{ template "fullname" . }}
7 labels:
8 draft: {{ default "draft-app" .Values.draft }}
9 chart: "{{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}"
10spec:
11 replicas: {{ .Values.replicaCount }}
12 template:
13 metadata:
14 labels:
15 draft: {{ default "draft-app" .Values.draft }}
16 app: {{ template "fullname" . }}
17{{- if .Values.podAnnotations }}
18 annotations:
19{{ toYaml .Values.podAnnotations | indent 8 }}
20{{- end }}
21 spec:
22 containers:
23 - name: {{ .Chart.Name }}
24 image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
25 env:
26 - name: MONGODB_HOST
27 value: "mongodb://{{.Release.Name}}-mongodb-replicaset-0.{{.Release.Name}}-mongodb-replicaset,{{.Release.Name}}-mongodb-replicaset-1.{{.Release.Name}}-mongodb-replicaset,{{.Release.Name}}-mongodb-replicaset-2.{{.Release.Name}}-mongodb-replicaset:27017"
28 imagePullPolicy: {{ .Values.image.pullPolicy }}
29 ports:
30 - containerPort: {{ .Values.service.internalPort }}
31 resources:
32{{ toYaml .Values.resources | indent 12 }}
有了这些变化,Helm 将能够将您的应用程序部署到 MongoDB 作为其数据库中。
接下来,检查由Jenkins X生成的Jenkinsfile
,从应用程序的主目录中打开该文件:
1nano Jenkinsfile
这个Jenkinsfile
定义了每次你将应用程序的版本委托到你的GitHub存储器时触发的管道,如果你想自动化你的代码测试,以便每次触发管道时触发测试,你会将测试添加到本文档中。
要证明这一点,在Jenkinsfile
中将sh
python -m unittest在
stage('CI Build and push snapshot')和
stage('Build Release')下置于
Jenkinsfile`中,以以下突出的行来添加自定义的测试案例:
1[label /rsvpapp/Jenkinsfile]
2. . .
3 stages {
4 stage('CI Build and push snapshot') {
5 when {
6 branch 'PR-*'
7 }
8 environment {
9 PREVIEW_VERSION = "0.0.0-SNAPSHOT-$BRANCH_NAME-$BUILD_NUMBER"
10 PREVIEW_NAMESPACE = "$APP_NAME-$BRANCH_NAME".toLowerCase()
11 HELM_RELEASE = "$PREVIEW_NAMESPACE".toLowerCase()
12 }
13 steps {
14 container('python') {
15 sh "pip install -r requirements.txt"
16 sh "python -m pytest tests/test_rsvpapp.py"
17 sh "export VERSION=$PREVIEW_VERSION && skaffold build -f skaffold.yaml"
18 sh "jx step post build --image $DOCKER_REGISTRY/$ORG/$APP_NAME:$PREVIEW_VERSION"
19 dir('./charts/preview') {
20 sh "make preview"
21 sh "jx preview --app $APP_NAME --dir ../.."
22 }
23 }
24 }
25 }
26 stage('Build Release') {
27 when {
28 branch 'master'
29 }
30 steps {
31 container('python') {
32
33 // ensure we're not on a detached head
34 sh "git checkout master"
35 sh "git config --global credential.helper store"
36 sh "jx step git credentials"
37
38 // so we can retrieve the version in later steps
39 sh "echo \$(jx-release-version) > VERSION"
40 sh "jx step tag --version \$(cat VERSION)"
41 sh "pip install -r requirements.txt"
42 sh "python -m pytest tests/test_rsvpapp.py"
43 sh "export VERSION=`cat VERSION` && skaffold build -f skaffold.yaml"
44 sh "jx step post build --image $DOCKER_REGISTRY/$ORG/$APP_NAME:\$(cat VERSION)"
45 }
46 }
47 }
48. . .
随着添加的行,Jenkins X管道将安装依赖性,并在您对应用程序进行更改时执行Python测试。
现在您已经更改了样本RSVP应用程序,请使用以下命令将这些更改发送到GitHub:
1git add *
2git commit -m update
3git push
当你将这些更改推到GitHub时,你将触发你的应用程序的新构建。如果你打开Jenkins用户界面,通过导航到http://jenkins.jx.your_IP_address.nip.io
并输入你的用户名和密码的admin
,你将找到有关你的新构建的信息。如果你从页面左侧的菜单中点击构建历史
,你应该看到你的承诺构建的历史。如果你点击构建旁边的蓝色图标,然后从左侧菜单中选择Console Ouput
,你将找到你的管道中的自动步骤的控制台输出。滚动到这个输出的尽头,你会发现以下信息:
1[secondary_label Output]
2. . .
3Finished: SUCCESS
这意味着您的应用已经通过了定制测试,现在已成功部署。
一旦Jenkins X构建了应用程序版本,它将将应用程序推广到阶段化
环境中。 要验证您的应用程序是否正在运行,请使用以下命令列出运行在您的Kubernetes群集上的应用程序:
1jx get app
您将收到类似于以下的输出:
1[secondary_label Output]
2APPLICATION STAGING PODS URL
3rsvpapp 0.0.2 1/1 http://rsvpapp.jx-staging.your_IP_address.nip.io
从这里,你可以看到Jenkins X已经在你的jx-staging
环境中部署了你的应用程序,作为版本0.0.2
。输出还显示了你可以使用的访问你的应用程序的URL。
接下来,用以下命令检查您的应用程序的活动:
1jx get activity -f rsvpapp
您将收到类似于以下的输出:
1[secondary_label Output]
2STEP STARTED AGO DURATION STATUS
3your_GitHub_username/rsvpappv/master #1 3h42m23s 4m51s Succeeded Version: 0.0.1
4 Checkout Source 3h41m52s 6s Succeeded
5 CI Build and push snapshot 3h41m46s NotExecuted
6 Build Release 3h41m46s 56s Succeeded
7 Promote to Environments 3h40m50s 3m17s Succeeded
8 Promote: staging 3h40m29s 2m36s Succeeded
9 PullRequest 3h40m29s 1m16s Succeeded PullRequest: https://github.com/your_GitHub_username/environment-horsehelix-staging/pull/1 Merge SHA: dc33d3747abdacd2524e8c22f0b5fbb2ac3f6fc7
10 Update 3h39m13s 1m20s Succeeded Status: Success at: http://jenkins.jx.your_IP_address.nip.io/job/your_GitHub_username/job/environment-horsehelix-staging/job/master/2/display/redirect
11 Promoted 3h39m13s 1m20s Succeeded Application is at: http://rsvpapp.jx-staging.your_IP_address.nip.io
12 Clean up 3h37m33s 1s Succeeded
13your_GitHub_username/rsvpappv/master #2 28m37s 5m57s Succeeded Version: 0.0.2
14 Checkout Source 28m18s 4s Succeeded
15 CI Build and push snapshot 28m14s NotExecuted
16 Build Release 28m14s 56s Succeeded
17 Promote to Environments 27m18s 4m38s Succeeded
18 Promote: staging 26m53s 4m0s Succeeded
19 PullRequest 26m53s 1m4s Succeeded PullRequest: https://github.com/your_GitHub_username/environment-horsehelix-staging/pull/2 Merge SHA: 976bd5ad4172cf9fd79f0c6515f5006553ac6611
20 Update 25m49s 2m56s Succeeded Status: Success at: http://jenkins.jx.your_IP_address.nip.io/job/your_GitHub_username/job/environment-horsehelix-staging/job/master/3/display/redirect
21 Promoted 25m49s 2m56s Succeeded Application is at: http://rsvpapp.jx-staging.your_IP_address.nip.io
22 Clean up 22m40s 0s Succeeded
在这里,您可以通过应用-f rsvpapp
的过滤器来获取 RSVP 应用的 Jenkins X 活动。
接下来,用以下命令列出在jx-staging
名称空间中运行的 pods:
1kubectl get pod -n jx-staging
您将收到类似于以下的输出:
1NAME READY STATUS RESTARTS AGE
2jx-staging-mongodb-replicaset-0 1/1 Running 0 6m
3jx-staging-mongodb-replicaset-1 1/1 Running 0 6m
4jx-staging-mongodb-replicaset-2 1/1 Running 0 5m
5jx-staging-rsvpapp-c864c4844-4fw5z 1/1 Running 0 6m
此输出显示您的应用程序在jx-staging
名称空间中运行,以及后端 MongoDB 数据库的三个 pods,遵循您之前对 YAML 文件所做的更改。
现在,您已经通过Jenkins X管道运行了测试应用程序,您可以尝试将该应用程序推广到生产环境中。
步骤 6 – 将您的测试应用程序推广到不同的名称空间
要完成此演示,您将通过将样本RSVP应用程序推广到您的jx-production
名称空间来完成CI/CD过程。
首先,在以下命令中使用「jx promote」:
1jx promote rsvpapp --version=0.0.2 --env=production
这将推动rsvpapp
应用程序以version=0.0.2
运行到生产环境中。在整个构建过程中,Jenkins X将提示您输入您的GitHub帐户信息。
成功推广后,查看申请名单:
1jx get app
您将收到类似于以下的输出:
1[secondary_label Output]
2APPLICATION STAGING PODS URL PRODUCTION PODS URL
3rsvpapp 0.0.2 1/1 http://rsvpapp.jx-staging.your_IP_address.nip.io 0.0.2 1/1 http://rsvpapp.jx-production.your_IP_address.nip.io
通过此PRODUCTION
信息,您可以确认Jenkins X已将rsvpapp
推广到生产环境中。 如需进一步验证,请访问您的浏览器中的http://rsvpapp.jx-production.your_IP_address.nip.io
生产网址。 您应该看到工作应用程序,现在从生产
开始:
最后,在jx-production
名称空间中列出您的 pods。
1kubectl get pod -n jx-production
你会发现rsvpapp
和MongoDB后端插件在这个名称空间中运行:
1NAME READY STATUS RESTARTS AGE
2jx-production-mongodb-replicaset-0 1/1 Running 0 1m
3jx-production-mongodb-replicaset-1 1/1 Running 0 1m
4jx-production-mongodb-replicaset-2 1/1 Running 0 55s
5jx-production-rsvpapp-54748d68bd-zjgv7 1/1 Running 0 1m
这表明您已成功地将RSVP样本应用程序推广到您的生产环境中,模拟 CI/CD 管道末端的应用程序的生产准备部署。
结论
在本教程中,您使用Helm在模拟的Kubernetes集群上管理包,并自定义Helm图表来包装和部署自己的应用程序。
如果您想了解更多关于 Helm 的信息,请参阅我们的 An Introduction to Helm, the Package Manager for Kubernetes和 How To Install Software on Kubernetes Clusters with the Helm Package Manager文章。