网络研讨会系列
本文补充了关于使用Kubernetes进行CI / CD的网络研讨会系列 。 本系列讨论如何采用云原生方法构建,测试和部署应用程序,包括可与Kubernetes一起使用的发布管理,云本机工具,服务网格和CI / CD工具。 它旨在帮助有兴趣将CI / CD最佳实践与Kubernetes集成到其工作流程中的开发人员和企业。
本教程包括本系列第二部分的概念和命令,带有Helm的Kubernetes包管理和带有Jenkins X的CI / CD。
警告:本教程中的过程仅用于演示目的。 因此,他们不遵循生产就绪部署所需的最佳实践和安全措施。
介绍
为了在部署应用程序时减少错误并组织复杂性,CI / CD系统必须包含用于包管理/部署的强大工具以及具有自动化测试的管道。 但是在现代生产环境中,基于云的基础架构的复杂性增加可能会给构建可靠的CI / CD环境带来问题。 为解决这个问题而开发的两个Kubernetes专用工具是Helm包管理器和Jenkins X管道自动化工具。
Helm是专为Kubernetes设计的软件包管理器,由Cloud Native Computing Foundation (CNCF)与Microsoft,Google,Bitnami和Helm贡献者社区共同维护。 在高层次上,它实现了与Linux系统包管理器(如APT或YUM)相同的目标:在后台管理应用程序和依赖项的安装,并隐藏用户的复杂性。 但是对于Kubernetes来说,对这种管理的需求更加明显:安装应用程序需要复杂而繁琐的YAML文件编排,升级或回滚版本可能是困难到不可能的任何地方。 为了解决这个问题,Helm在Kubernetes之上运行,并将应用程序打包成预先配置的资源,称为图表 ,用户可以使用简单的命令管理这些资源,使共享和管理应用程序的过程更加用户友好。
Jenkins X是一个CI / CD工具,用于自动化Kubernetes的生产管道和环境。 使用Docker镜像,Helm图表和Jenkins管道引擎 ,Jenkins X可以自动管理版本和版本,并在GitHub上的环境之间推广应用程序。
在带有Kubernetes系列的CI / CD的第二篇文章中,您将通过以下方式预览这两个工具:
使用Helm管理,创建和部署Kubernetes包。
使用Jenkins X构建CI / CD管道。
虽然各种Kubernetes平台都可以使用Helm和Jenkins X,但在本教程中,您将运行在本地环境中设置的模拟Kubernetes集群。 要做到这一点,您将使用Minikube ,这个程序允许您在自己的机器上试用Kubernetes工具,而无需设置真正的Kubernetes集群。
在本教程结束时,您将基本了解这些Kubernetes本机工具如何帮助您为云应用程序实现CI / CD系统。
先决条件
要学习本教程,您需要:
Ubuntu 16.04服务器,内存16 GB或更高。 由于本教程仅用于演示目的,因此命令从root帐户运行。 请注意,此帐户的无限制权限不符合生产就绪的最佳做法,可能会影响您的系统。 因此,建议在测试环境(如虚拟机或DigitalOcean Droplet)中执行这些步骤。
GitHub帐户和GitHub API令牌 。 请务必记录此API令牌,以便您可以在本教程的Jenkins X部分输入它。
熟悉Kubernetes概念。 有关更多详细信息,请参阅文章“Kubernetes简介” 。
第1步 – 使用Minikube创建本地Kubernetes集群
在设置Minikube之前,您必须安装其依赖项,包括Kubernetes命令行工具kubectl ,双向数据传输中继socat和容器程序Docker 。
首先,确保您的系统包管理器可以使用apt-transport-https
通过HTTPS访问包:
apt-get updateapt-get install apt-transport-https
接下来,为了确保kubectl下载有效,请将官方Google存储库的GPG密钥添加到您的系统:
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -
添加GPG密钥后,通过在文本编辑器中打开/etc/apt/sources.list.d/kubernetes.list
来创建文件/etc/apt/sources.list.d/kubernetes.list
:
nano /etc/apt/sources.list.d/kubernetes.list
打开此文件后,添加以下行:
deb http://apt.kubernetes.io/ kubernetes-xenial main
这将向您的系统显示下载kubectl的来源。 添加行后,保存并退出文件。 使用nano文本编辑器,您可以通过按CTRL+X
,键入y
,然后按ENTER
来完成此操作。
最后,更新APT的源列表并安装kubectl
, socat
和docker.io
:
apt-get updateapt-get install -y kubectl socat docker.io
注意:要使Minikube模拟Kubernetes群集,您必须下载docker.io
包而不是较新的docker.io
docker-ce
版本。 对于生产就绪的环境, docker-ce
将是更合适的选择,因为它在官方Docker存储库中得到了更好的维护。
现在您已经安装了kubectl,您可以继续安装Minikube 。 首先,使用curl
下载程序的二进制文件:
curl -Lo minikube https://storage.googleapis.com/minikube/releases/v0.28.0/minikube-linux-amd64
接下来,更改刚刚下载的文件的访问权限,以便系统可以执行它:
chmod +x minikube
最后,将minikube
文件复制到/usr/local/bin/
的可执行文件路径,并从主目录中删除原始文件:
cp minikube /usr/local/bin/rm minikube
在计算机上安装Minikube后,您现在可以启动该程序。 要创建Minikube Kubernetes集群,请使用以下命令:
minikube start --vm-driver none
标志--vm-driver none
指示Minikube使用容器而不是虚拟机在本地主机上运行Kubernetes。 以这种方式运行Minikube意味着您不需要下载VM驱动程序,但也意味着Kubernetes API服务器将以root用户不安全地运行。
警告:由于具有root权限的API服务器可以无限制地访问本地主机,因此不建议在个人工作站上使用none
驱动程序运行Minikube。
现在您已启动Minikube,请检查以确保您的群集正在使用以下命令运行:
minikube status
您将收到以下输出,并使用您的IP地址代替your_IP_address
:
minikube: Runningcluster: Runningkubectl: Correctly Configured: pointing to minikube-vm at your_IP_address
现在您已经使用Minikube设置了模拟Kubernetes集群,您可以通过在集群顶部安装和配置Helm软件包管理器来获得Kubernetes软件包管理的经验。
第2步 – 在群集上设置Helm Package Manager
为了协调Kubernetes集群上的应用程序安装,您现在将安装Helm软件包管理器。 Helm包含一个在集群外部运行的helm
客户端和一个管理集群内应用程序版本的tiller
服务器。 您必须安装和配置两者才能在群集上成功运行Helm。
要安装Helm二进制文件 ,首先使用curl
将以下安装脚本从官方Helm GitHub存储库下载到名为get_helm.sh
的新文件中:
curl https://raw.githubusercontent.com/kubernetes/helm/master/scripts/get > get_helm.sh
由于此脚本需要root访问权限,因此请更改get_helm.sh
的权限,以便文件的所有者(在本例中为root)可以读取,写入和执行它:
chmod 700 get_helm.sh
现在,执行脚本:
./get_helm.sh
当脚本完成后,您将安装/usr/local/bin/helm
并将/usr/local/bin/helm
和tiller
安装到/usr/local/bin/tiller
。
虽然现在安装了tiller
,但它还没有正确的角色和权限来访问Kubernetes群集中的必要资源。 要将这些角色和权限分配给tiller
,您必须创建名为tiller
的服务帐户 。 在Kubernetes中,服务帐户表示在pod中运行的进程的标识。 通过服务帐户验证进程后,它可以联系API服务器并访问群集资源。 如果未为pod分配特定服务帐户,则会获取默认服务帐户。 您还必须创建一个授权tiller
服务帐户的基于角色的访问控制 (RBAC)规则。
在Kubernetes RBAC API中, 角色包含确定一组权限的规则。 可以使用namespace
或cluster
的范围定义角色,并且只能授予对单个命名空间内的资源的访问权限。 ClusterRole
可以在群集级别创建相同的权限,授予对群集范围资源(如节点和pods等命名空间资源)的访问权限。 要为tiller
服务帐户指定正确的角色,请创建名为rbac_helm.yaml
的YAML文件,并在文本编辑器rbac_helm.yaml
其打开:
nano rbac_helm.yaml
tiller
添加到文件以配置tiller
服务帐户:
apiVersion: v1kind: ServiceAccountmetadata: name: tiller namespace: kube-system---apiVersion: rbac.authorization.k8s.io/v1beta1kind: ClusterRoleBindingmetadata: name: tillerroleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster-adminsubjects: - kind: ServiceAccount name: tiller namespace: kube-system - kind: User name: "admin" apiGroup: rbac.authorization.k8s.io - kind: User name: "kubelet" apiGroup: rbac.authorization.k8s.io - kind: Group name: system:serviceaccounts apiGroup: rbac.authorization.k8s.io
在上述文件中, ServiceAccount
允许tiller
程序作为经过身份验证的服务帐户访问apiserver。 ClusterRole
向角色授予特定权限, ClusterRoleBinding
将该角色分配给subjects
列表,包括tiller
服务帐户, admin
和kubelet
用户以及system:serviceaccounts
组。
接下来,使用以下命令在rbac_helm.yaml
部署配置:
kubectl apply -f rbac_helm.yaml
部署了tiller
配置后,您现在可以使用--service-acount
标志初始化Helm,以使用您刚刚设置的服务帐户:
helm init --service-account tiller
您将收到以下输出,表示初始化成功:
Creating /root/.helmCreating /root/.helm/repositoryCreating /root/.helm/repository/cacheCreating /root/.helm/repository/localCreating /root/.helm/pluginsCreating /root/.helm/startersCreating /root/.helm/cache/archiveCreating /root/.helm/repository/repositories.yamlAdding stable repo with URL: https://kubernetes-charts.storage.googleapis.comAdding local repo with URL: http://127.0.0.1:8879/charts$HELM_HOME has been configured at /root/.helm.Tiller (the Helm server-side component) has been installed into your Kubernetes Cluster.Please note: by default, Tiller is deployed with an insecure 'allow unauthenticated users' policy.To prevent this, run `helm init` with the --tiller-tls-verify flag.For more information on securing your installation see: https://docs.helm.sh/using_helm/#securing-your-helm-installationHappy Helming!
这会在kube-system
名称空间中创建一个tiller
窗格。 它还在$HOME
目录中创建.helm
默认存储库,并在https://kubernetes-charts.storage.googleapis.com
和本地Helm存储库中配置默认的Helm稳定图表存储库, https://kubernetes-charts.storage.googleapis.com
为http://127.0.0.1:8879/charts
。
要确保tiller
pod在kube-system
命名空间中运行,请输入以下命令:
kubectl --namespace kube-system get pods
在您的pod列表中,将显示tiller-deploy
,如以下输出中所示:
NAME READY STATUS RESTARTS AGEetcd-minikube 1/1 Running 0 2hkube-addon-manager-minikube 1/1 Running 0 2hkube-apiserver-minikube 1/1 Running 0 2hkube-controller-manager-minikube 1/1 Running 0 2hkube-dns-86f4d74b45-rjql8 3/3 Running 0 2hkube-proxy-dv268 1/1 Running 0 2hkube-scheduler-minikube 1/1 Running 0 2hkubernetes-dashboard-5498ccf677-wktkl 1/1 Running 0 2hstorage-provisioner 1/1 Running 0 2htiller-deploy-689d79895f-bggbk 1/1 Running 0 5m
如果tiller
吊舱的状态为“正在Running
,它现在可以代表Helm从群集内部管理Kubernetes应用程序。
要确保整个Helm应用程序正常工作,请在Helm包存储库中搜索MongoDB之类的应用程序:
helm search mongodb
在输出中,您将看到适合您的搜索字词的可能应用程序列表:
NAME CHART VERSION APP VERSION DESCRIPTIONstable/mongodb 5.4.0 4.0.6 NoSQL document-oriented database that stores JSON-like do...stable/mongodb-replicaset 3.9.0 3.6 NoSQL document-oriented database that stores JSON-like do...stable/prometheus-mongodb-exporter 1.0.0 v0.6.1 A Prometheus exporter for MongoDB metricsstable/unifi 0.3.1 5.9.29 Ubiquiti Network's Unifi Controller
现在您已经在Kubernetes集群上安装了Helm,您可以通过创建示例Helm图表并从中部署应用程序来了解有关包管理器的更多信息。
第3步 – 使用Helm创建图表和部署应用程序
在Helm包管理器中,各个包称为图表 。 在图表中,一组文件定义了一个应用程序,其复杂程度可能从一个pod到一个结构化的全栈应用程序。 您可以从Helm存储库下载图表,也可以使用helm create
命令创建自己的图表。
要测试Helm的功能,请使用以下命令创建名为demo
的新Helm图表:
helm create demo
在您的主目录中,您将找到一个名为demo
的新目录,您可以在其中创建和编辑自己的图表模板。
进入demo
目录并使用ls
列出其内容:
cd demols
您将在demo
找到以下文件和目录:
charts Chart.yaml templates values.yaml
使用文本编辑器打开Chart.yaml
文件:
nano Chart.yaml
在里面,你会发现以下内容:
apiVersion: v1appVersion: "1.0"description: A Helm chart for Kubernetesname: demoversion: 0.1.0
在此Chart.yaml
文件中,您将找到像apiVersion
这样的字段,它必须始终为v1
,这是一个description
,提供有关demo
内容的更多信息,图表的name
以及Helm用作发布标记的version
号。 检查完文件后,请关闭文本编辑器。
接下来,打开values.yaml
文件:
nano values.yaml
在此文件中,您将找到以下内容:
# Default values for demo.# This is a YAML-formatted file.# Declare variables to be passed into your templates.replicaCount: 1image: repository: nginx tag: stable pullPolicy: IfNotPresentnameOverride: ""fullnameOverride: ""service: type: ClusterIP port: 80ingress: enabled: false annotations: {} # kubernetes.io/ingress.class: nginx # kubernetes.io/tls-acme: "true" paths: [] hosts: - chart-example.local tls: [] # - secretName: chart-example-tls # hosts: # - chart-example.localresources: {} # We usually recommend not to specify default resources and to leave this as a conscious # choice for the user. This also increases chances charts run on environments with little # resources, such as Minikube. If you do want to specify resources, uncomment the following # lines, adjust them as necessary, and remove the curly braces after 'resources:'. # limits: # cpu: 100m # memory: 128Mi # requests: # cpu: 100m # memory: 128MinodeSelector: {}tolerations: []affinity: {}
通过更改values.yaml
的内容,图表开发人员可以为图表中定义的应用程序提供默认值,控制副本计数,图像库,入口访问,秘密管理等。 图表用户可以使用helm install
使用自定义YAML文件为这些参数提供自己的值。 当用户提供自定义值时,这些值将覆盖图表的values.yaml
文件中的值。
关闭values.yaml
文件并使用以下命令列出templates
目录的内容:
ls templates
在这里,您可以找到可以控制图表不同方面的各种文件的模板:
deployment.yaml _helpers.tpl ingress.yaml NOTES.txt service.yaml tests
现在您已经探索了demo
图表,您可以通过安装demo
来试验Helm图表安装。 使用以下命令返回到您的主目录:
cd
使用helm install
在名称web
下安装demo
Helm图表:
helm install --name web ./demo
您将获得以下输出:
NAME: webLAST DEPLOYED: Wed Feb 20 20:59:48 2019NAMESPACE: defaultSTATUS: DEPLOYEDRESOURCES:==> v1/ServiceNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEweb-demo ClusterIP 10.100.76.231 <none> 80/TCP 0s==> v1/DeploymentNAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGEweb-demo 1 0 0 0 0s==> v1/Pod(related)NAME READY STATUS RESTARTS AGEweb-demo-5758d98fdd-x4mjs 0/1 ContainerCreating 0 0sNOTES:1. Get the application URL by running these commands: 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}") echo "Visit http://127.0.0.1:8080 to use your application" kubectl port-forward $POD_NAME 8080:80
在此输出中,您将找到应用程序的STATUS
以及群集中的相关资源列表。
接下来,使用以下命令列出demo
Helm图表创建的部署:
kubectl get deploy
这将产生将列出您的活动部署的输出:
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGEweb-demo 1 1 1 1 4m
使用命令kubectl get pods
列出您的pod将显示运行web
应用程序的pod,如下所示:
NAME READY STATUS RESTARTS AGEweb-demo-5758d98fdd-nbkqd 1/1 Running 0 4m
要演示Helm图表中的更改如何发布应用程序的不同版本,请在文本编辑器中打开demo/values.yaml
并将replicaCount:
更改为3
,将image:tag:
从stable
为latest
。 在下面的代码块中,您将在完成修改后找到YAML文件的外观,并突出显示更改:
# Default values for demo.# This is a YAML-formatted file.# Declare variables to be passed into your templates.replicaCount: 3image: repository: nginx tag: latest pullPolicy: IfNotPresentnameOverride: ""fullnameOverride: ""service: type: ClusterIP port: 80. . .
保存并退出该文件。
在部署此新版web
应用程序之前,请使用以下命令列出现在的Helm版本:
helm list
您将收到以下输出,其中包含您之前创建的一个部署:
NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACEweb 1 Wed Feb 20 20:59:48 2019 DEPLOYED demo-0.1.0 1.0 default
请注意, REVISION
列为1
,表示这是web
应用程序的第一个修订版。
要使用对demo/values.yaml
进行的最新更改来部署web
应用程序,请使用以下命令升级应用程序:
helm upgrade web ./demo
现在,再次列出Helm版本:
helm list
您将收到以下输出:
NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACEweb 2 Wed Feb 20 21:18:12 2019 DEPLOYED demo-0.1.0 1.0 default
请注意, REVISION
已更改为2
,表示这是第二次修订。
要查找web
的Helm发行版的历史记录,请使用以下命令:
helm history web
这将显示web
应用程序的两个修订版:
REVISION UPDATED STATUS CHART DESCRIPTION1 Wed Feb 20 20:59:48 2019 SUPERSEDED demo-0.1.0 Install complete2 Wed Feb 20 21:18:12 2019 DEPLOYED demo-0.1.0 Upgrade complete
要将应用程序回滚到修订版1
,请输入以下命令:
helm rollback web 1
这将产生以下输出:
Rollback was a success! Happy Helming!
现在,提出Helm发布历史:
helm history web
您将收到以下列表:
REVISION UPDATED STATUS CHART DESCRIPTION1 Wed Feb 20 20:59:48 2019 SUPERSEDED demo-0.1.0 Install complete2 Wed Feb 20 21:18:12 2019 SUPERSEDED demo-0.1.0 Upgrade complete3 Wed Feb 20 21:28:48 2019 DEPLOYED demo-0.1.0 Rollback to 1
通过回滚web
应用程序,您创建了第三个修订版,其设置与修订版1
相同。 请记住,您可以通过查找STATUS
下的DEPLOYED
项目来确定哪个版本处于活动STATUS
。
要准备下一部分,请使用helm delete
命令删除web
版本来清理测试区域:
helm delete web
再次检查Helm发布历史记录:
helm history web
您将收到以下输出:
REVISION UPDATED STATUS CHART DESCRIPTION1 Wed Feb 20 20:59:48 2019 SUPERSEDED demo-0.1.0 Install complete2 Wed Feb 20 21:18:12 2019 SUPERSEDED demo-0.1.0 Upgrade complete3 Wed Feb 20 21:28:48 2019 DELETED demo-0.1.0 Deletion complete
STATUS
for REVISION 3
已更改为DELETED
,表示已部署的web
实例已被删除。 但是,尽管这确实删除了该版本,但它并未将其从商店中删除。 要完全删除发行版,请使用--purge
标志运行helm delete
命令。
helm delete web --purge
在此步骤中,您已使用Helm在Kubernetes上管理应用程序版本。 如果您想进一步学习Helm,请查看我们的Helm简介,Kubernetes包管理器教程,或查看官方Helm文档 。
接下来,您将使用jx
CLI设置并测试管道自动化工具Jenkins X,以创建支持CI / CD的Kubernetes集群。
第4步 – 设置Jenkins X环境
使用Jenkins X,您可以从头开始创建Kubernetes集群,内置管道自动化和CI / CD解决方案。通过安装jx
CLI工具,您将能够有效地管理应用程序版本,Docker镜像和Helm图表。除了在GitHub中跨环境自动推广您的应用程序。
由于您将使用jx
创建群集,因此必须先删除已有的Minikube群集。 为此,请使用以下命令:
minikube delete
这将删除本地模拟的Kubernete集群,但不会删除首次安装Minikube时创建的默认目录。 要从机器上清除这些,请使用以下命令:
rm -rf ~/.kuberm -rf ~/.minikuberm -rf /etc/kubernetes/*rm -rf /var/lib/minikube/*
从机器上完全清除Minikube后,您可以继续安装Jenkins X二进制文件。
首先,使用curl
命令从官方Jenkins X GitHub存储库下载压缩的jx
文件,并使用tar
命令解压缩它:
curl -L https://github.com/jenkins-x/jx/releases/download/v1.3.781/jx-linux-amd64.tar.gz | tar xzv
接下来,将下载的jx
文件移动到/usr/local/bin
的可执行文件路径:
mv jx /usr/local/bin
Jenkins X附带一个Docker Registry,可以在Kubernetes集群中运行。 由于这是一个内部元素,因此安全措施(如自签名证书)可能会给程序带来麻烦。 要解决此问题,请将Docker设置为使用本地IP范围的不安全注册表。 为此,请创建文件/etc/docker/daemon.json
并在文本编辑器/etc/docker/daemon.json
其打开:
nano /etc/docker/daemon.json
将以下内容添加到文件中:
{ "insecure-registries" : ["0.0.0.0/0"]}
保存并退出该文件。 要使这些更改生效,请使用以下命令重新启动Docker服务:
systemctl restart docker
要验证是否已使用不安全的注册表配置Docker,请使用以下命令:
docker info
在输出结束时,您应该看到以下突出显示的行:
Containers: 0 Running: 0 Paused: 0 Stopped: 0Images: 15Server Version: 18.06.1-ceStorage Driver: overlay2 Backing Filesystem: extfs Supports d_type: true Native Overlay Diff: true. . .Registry: https://index.docker.io/v1/Labels:Experimental: falseInsecure Registries: 0.0.0.0/0 127.0.0.0/8Live Restore Enabled: false
现在您已经下载了Jenkins X并配置了Docker注册表,请使用jx
CLI工具创建具有CI / CD功能的Minikube Kubernetes集群:
jx 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在此演示中正常运行。 此外,您正在使用--default-admin-password=admin
将Jenkins X密码设置为admin
并使用--vm-driver=none
来设置本地群集,如第1步中所做的那样。
当Jenkins X旋转您的群集时,您将在整个过程中的不同时间收到各种提示,为群集设置参数,并确定它将如何与GitHub通信以管理您的生产环境。
首先,您将收到以下提示:
? disk-size (MB) 150GB
按ENTER
继续。 接下来,系统将提示您输入要与git一起使用的名称,您希望与git一起使用的电子邮件地址以及您的GitHub用户名。 出现提示时输入其中每个,然后按ENTER
。
接下来,Jenkins X将提示您输入您的GitHub API令牌:
To be able to create a repository on GitHub we need an API TokenPlease click this URL https://github.com/settings/tokens/new?scopes=repo,read:user,read:org,user:email,write:repo_hook,delete_repoThen COPY the token and enter in into the form below:? API Token:
在此处输入您的令牌,或使用前面代码块中突出显示的URL创建具有相应权限的新令牌。
接下来,Jenkins X会问:
? Do you wish to use GitHub as the pipelines Git server: (Y/n)? Do you wish to use your_GitHub_username as the pipelines Git user for GitHub server: (Y/n)
输入Y
表示两个问题。
在此之后,Jenkins X将提示您回答以下问题:
? Select Jenkins installation type: [Use arrows to move, type to filter]>Static Master Jenkins Serverless Jenkins? Pick workload build pack: [Use arrows to move, type to filter]> Kubernetes Workloads: Automated CI+CD with GitOps Promotion Library Workloads: CI+Release but no CD
对于之前的选择, Static Master Jenkins
,并选择Kubernetes Workloads: Automated CI+CD with GitOps Promotion
后者。 当系统提示您为环境存储库选择组织时,请选择您的GitHub用户名。
最后,您将收到以下输出,该输出验证安装是否成功并提供您的Jenkins X管理员密码。
Creating GitHub webhook for your_GitHub_username/environment-horsehelix-production for url http://jenkins.jx.your_IP_address.nip.io/github-webhook/Jenkins X installation completed successfully ******************************************************** NOTE: Your admin password is: admin ********************************************************Your Kubernetes context is now set to the namespace: jxTo switch back to your original namespace use: jx namespace defaultFor help on switching contexts see: https://jenkins-x.io/developing/kube-context/To import existing projects into Jenkins: jx importTo create a new Spring Boot microservice: jx create spring -d web -d actuatorTo create a new microservice from a quickstart: jx create quickstart
接下来,使用jx get
命令接收显示有关应用程序信息的URL列表:
jx get urls
此命令将生成类似于以下内容的列表:
Name URLjenkins http://jenkins.jx.your_IP_address.nip.iojenkins-x-chartmuseum http://chartmuseum.jx.your_IP_address.nip.iojenkins-x-docker-registry http://docker-registry.jx.your_IP_address.nip.iojenkins-x-monocular-api http://monocular.jx.your_IP_address.nip.iojenkins-x-monocular-ui http://monocular.jx.your_IP_address.nip.ionexus http://nexus.jx.your_IP_address.nip.io
通过在浏览器中输入地址并输入用户名和密码,您可以使用URL通过UI查看有关CI / CD环境的Jenkins X数据。 在这种情况下,这两者都是“admin”。
接下来,为了确保命名空间jx
, jx-staging
和jx-production
中的服务帐户具有管理员权限,请使用以下命令修改RBAC策略:
kubectl create clusterrolebinding jx-staging1 --clusterrole=cluster-admin --user=admin --user=expose --group=system:serviceaccounts --serviceaccount=jx-staging:expose --namespace=jx-staging
kubectl create clusterrolebinding jx-staging2 --clusterrole=cluster-admin --user=admin --user=expose --group=system:serviceaccounts --serviceaccount=jx-staging:default --namespace=jx-staging
kubectl create clusterrolebinding jx-production1 --clusterrole=cluster-admin --user=admin --user=expose --group=system:serviceaccounts --serviceaccount=jx-production:expose --namespace=jx-productions
kubectl create clusterrolebinding jx-production2 --clusterrole=cluster-admin --user=admin --user=expose --group=system:serviceaccounts --serviceaccount=jx-production:default --namespace=jx-productions
kubectl create clusterrolebinding jx-binding1 --clusterrole=cluster-admin --user=admin --user=expose --group=system:serviceaccounts --serviceaccount=jx:expose --namespace=jx
kubectl 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基础架构来帮助您自动化测试管道。 在此步骤中,您将通过在正在运行的Jenkins X管道中设置测试应用程序来尝试此操作。
出于演示目的,本教程将使用CloudYuga团队创建的示例RSVP应用程序。 您可以在DO-Community GitHub存储库中找到此应用程序以及其他网络研讨会材料。
首先,使用以下命令从存储库克隆示例应用程序:
git clone https://github.com/do-community/rsvpapp.git
克隆存储库后,进入rsvpapp
目录并删除git文件:
cd rsvpapprm -r .git/
要为新应用程序初始化git存储库和Jenkins X项目,可以使用jx create
从头开始或使用模板,或者使用jx import
从本地项目或git存储库导入现有应用程序。 在本教程中,通过从应用程序的主目录中运行以下命令来导入示例RSVP应用程序:
jx import
Jenkins X将提示您输入GitHub用户名,无论您是要初始化git,提交消息,组织以及您希望存储库的名称。 回答是以初始化git,然后提供其他提示以及您的个人GitHub信息和首选项。 当Jenkins X导入应用程序时,它将在应用程序的主目录中创建Helm图表和Jenkins文件。 您可以根据您的要求修改这些图表和Jenkinsfile。
由于示例RSVP应用程序在其容器的端口5000
上运行,因此请修改charts/rsvpapp/values.yaml
文件以与此匹配。 在文本编辑器中打开charts/rsvpapp/values.yaml
:
nano charts/rsvpapp/values.yaml
在此values.yaml
文件中,将service:internalPort:
设置为5000
。 完成此更改后,您的文件应如下所示:
# Default values for python.# This is a YAML-formatted file.# Declare variables to be passed into your templates.replicaCount: 1image: repository: draft tag: dev pullPolicy: IfNotPresentservice: name: rsvpapp type: ClusterIP externalPort: 80 internalPort: 5000 annotations: fabric8.io/expose: "true" fabric8.io/ingress.annotations: "kubernetes.io/ingress.class: nginx"resources: limits: cpu: 100m memory: 128Mi requests: cpu: 100m memory: 128Miingress: enabled: false
保存并退出您的文件。
接下来,更改charts/preview/requirements.yaml
以适合您的应用程序。 requirements.yaml
是一个YAML文件,开发人员可以在其中声明图表依赖关系,以及图表的位置和所需的版本。 由于我们的示例应用程序将MongoDB用于数据库目的,因此您需要修改charts/preview/requirements.yaml
文件以将MongoDB列为依赖项。 使用以下命令在文本编辑器中打开文件:
nano charts/preview/requirements.yaml
通过在alias: cleanup
条目之后添加mongodb-replicaset
条目来编辑文件,如以下代码块中突出显示:
# !! File must end with empty line !!dependencies:- alias: expose name: exposecontroller repository: http://chartmuseum.jenkins-x.io version: 2.3.92- alias: cleanup name: exposecontroller repository: http://chartmuseum.jenkins-x.io version: 2.3.92- name: mongodb-replicaset repository: https://kubernetes-charts.storage.googleapis.com/ version: 3.5.5 # !! "alias: preview" must be last entry in dependencies array !! # !! Place custom dependencies above !!- alias: preview name: rsvpapp repository: file://../rsvpapp
在这里,您已将mongodb-replicaset
图表指定为preview
图表的依赖项。
接下来,为rsvpapp
图表重复此过程。 创建charts/rsvpapp/requirements.yaml
文件并在文本编辑器中打开它:
nano charts/rsvpapp/requirements.yaml
文件打开后,添加以下内容,确保填充行前后有一行空格:
dependencies:- name: mongodb-replicaset repository: https://kubernetes-charts.storage.googleapis.com/ version: 3.5.5
现在,您已将mongodb-replicaset
图表指定为rsvpapp
图表的依赖rsvpapp
。
接下来,为了将示例RSVP应用程序的前端连接到MongoDB后端,将MONGODB_HOST
环境变量添加到charts/rsvpapp/templates/
deployment.yaml
文件中。 在文本编辑器中打开此文件:
nano charts/rsvpapp/templates/deployment.yaml
除了文件顶部的一个空行和文件底部的两个空行外,还要将以下突出显示的行添加到文件中。 请注意,YAML文件需要这些空白行:
apiVersion: extensions/v1beta1kind: Deploymentmetadata: name: {{ template "fullname" . }} labels: draft: {{ default "draft-app" .Values.draft }} chart: "{{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}"spec: replicas: {{ .Values.replicaCount }} template: metadata: labels: draft: {{ default "draft-app" .Values.draft }} app: {{ template "fullname" . }}{{- if .Values.podAnnotations }} annotations:{{ toYaml .Values.podAnnotations | indent 8 }}{{- end }} spec: containers: - name: {{ .Chart.Name }} image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" env: - name: MONGODB_HOST 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" imagePullPolicy: {{ .Values.image.pullPolicy }} ports: - containerPort: {{ .Values.service.internalPort }} resources:{{ toYaml .Values.resources | indent 12 }}
通过这些更改,Helm将能够使用MongoDB作为其数据库部署您的应用程序。
接下来,通过打开应用程序主目录中的文件来检查Jenkins X生成的Jenkinsfile
:
nano Jenkinsfile
这个Jenkinsfile
定义了每次将应用程序版本提交到GitHub存储库时触发的管道。 If you wanted to automate your code testing so that the tests are triggered every time the pipeline is triggered, you would add the test to this document.
To demonstrate this, add a customized test case by replacing sh "python -m unittest"
under stage('CI Build and push snapshot')
and stage('Build Release')
in the Jenkinsfile
with the following highlighted lines:
. . . stages { stage('CI Build and push snapshot') { when { branch 'PR-*' } environment { PREVIEW_VERSION = "0.0.0-SNAPSHOT-$BRANCH_NAME-$BUILD_NUMBER" PREVIEW_NAMESPACE = "$APP_NAME-$BRANCH_NAME".toLowerCase() HELM_RELEASE = "$PREVIEW_NAMESPACE".toLowerCase() } steps { container('python') { sh "pip install -r requirements.txt" sh "python -m pytest tests/test_rsvpapp.py" sh "export VERSION=$PREVIEW_VERSION && skaffold build -f skaffold.yaml" sh "jx step post build --image $DOCKER_REGISTRY/$ORG/$APP_NAME:$PREVIEW_VERSION" dir('./charts/preview') { sh "make preview" sh "jx preview --app $APP_NAME --dir ../.." } } } } stage('Build Release') { when { branch 'master' } steps { container('python') { // ensure we're not on a detached head sh "git checkout master" sh "git config --global credential.helper store" sh "jx step git credentials" // so we can retrieve the version in later steps sh "echo \$(jx-release-version) > VERSION" sh "jx step tag --version \$(cat VERSION)" sh "pip install -r requirements.txt" sh "python -m pytest tests/test_rsvpapp.py" sh "export VERSION=`cat VERSION` && skaffold build -f skaffold.yaml" sh "jx step post build --image $DOCKER_REGISTRY/$ORG/$APP_NAME:\$(cat VERSION)" } } }. . .
With the added lines, the Jenkins X pipeline will install dependencies and carry out a Python test whenever you commit a change to your application.
Now that you have changed the sample RSVP application, commit and push these changes to GitHub with the following commands:
git add *git commit -m updategit push
When you push these changes to GitHub, you will trigger a new build of your application. If you open the Jenkins UI by navigating to http://jenkins.jx. your_IP_address .nip.io
and entering “admin” for your username and password, you will find information about your new build. If you click “Build History” from the menu on the left side of the page, you should see a history of your committed builds. If you click on the blue icon next to a build then select “Console Ouput” from the lefthand menu, you will find the console output for the automated steps in your pipeline. Scrolling to the end of this output, you will find the following message:
. . .Finished: SUCCESS
This means that your application has passed your customized tests and is now successfully deployed.
Once Jenkins X builds the application release, it will promote the application to the staging
environment. To verify that your application is running, list the applications running on your Kubernetes cluster by using the following command:
jx get app
You will receive output similar to the following:
APPLICATION STAGING PODS URLrsvpapp 0.0.2 1/1 http://rsvpapp.jx-staging.your_IP_address.nip.io
From this, you can see that Jenkins X has deployed your application in your jx-staging
environment as version 0.0.2
. The output also shows the URL that you can use to access your application. Visiting this URL will show you the sample RSVP application:
Next, check out the activity of your application with the following command:
jx get activity -f rsvpapp
You will receive output similar to the following:
STEP STARTED AGO DURATION STATUSyour_GitHub_username/rsvpappv/master #1 3h42m23s 4m51s Succeeded Version: 0.0.1 Checkout Source 3h41m52s 6s Succeeded CI Build and push snapshot 3h41m46s NotExecuted Build Release 3h41m46s 56s Succeeded Promote to Environments 3h40m50s 3m17s Succeeded Promote: staging 3h40m29s 2m36s Succeeded PullRequest 3h40m29s 1m16s Succeeded PullRequest: https://github.com/your_GitHub_username/environment-horsehelix-staging/pull/1 Merge SHA: dc33d3747abdacd2524e8c22f0b5fbb2ac3f6fc7 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 Promoted 3h39m13s 1m20s Succeeded Application is at: http://rsvpapp.jx-staging.your_IP_address.nip.io Clean up 3h37m33s 1s Succeededyour_GitHub_username/rsvpappv/master #2 28m37s 5m57s Succeeded Version: 0.0.2 Checkout Source 28m18s 4s Succeeded CI Build and push snapshot 28m14s NotExecuted Build Release 28m14s 56s Succeeded Promote to Environments 27m18s 4m38s Succeeded Promote: staging 26m53s 4m0s Succeeded PullRequest 26m53s 1m4s Succeeded PullRequest: https://github.com/your_GitHub_username/environment-horsehelix-staging/pull/2 Merge SHA: 976bd5ad4172cf9fd79f0c6515f5006553ac6611 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 Promoted 25m49s 2m56s Succeeded Application is at: http://rsvpapp.jx-staging.your_IP_address.nip.io Clean up 22m40s 0s Succeeded
Here you are getting the Jenkins X activity for the RSVP application by applying a filter with -f rsvpapp
.
Next, list the pods running in the jx-staging
namespace with the following command:
kubectl get pod -n jx-staging
You will receive output similar to the following:
NAME READY STATUS RESTARTS AGEjx-staging-mongodb-replicaset-0 1/1 Running 0 6mjx-staging-mongodb-replicaset-1 1/1 Running 0 6mjx-staging-mongodb-replicaset-2 1/1 Running 0 5mjx-staging-rsvpapp-c864c4844-4fw5z 1/1 Running 0 6m
This output shows that your application is running in the jx-staging
namespace, along with three pods of the backend MongoDB database, adhering to the changes you made to the YAML files earlier.
Now that you have run a test application through the Jenkins X pipeline, you can try out promoting this application to the production environment.
Step 6 — Promoting your Test Application to a Different Namespace
To finish up this demonstration, you will complete the CI/CD process by promoting the sample RSVP application to your jx-production
namespace.
First, use jx promote
in the following command:
jx promote rsvpapp --version=0.0.2 --env=production
This will promote the rsvpapp
application running with version=0.0.2
to the production environment. Throughout the build process, Jenkins X will prompt you to enter your GitHub account information. Answer these prompts with your individual responses as they appear.
After successful promotion, check the list of applications:
jx get app
You will receive output similar to the following:
APPLICATION STAGING PODS URL PRODUCTION PODS URLrsvpapp 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
With this PRODUCTION
information, you can confirm that Jenkins X has promoted rsvpapp
to the production environment. For further verification, visit the production URL http://rsvpapp.jx-production. your_IP_address .nip.io
in your browser. You should see the working application, now runnning from “production”:
Finally, list your pods in the jx-production
namespace.
kubectl get pod -n jx-production
You will find that rsvpapp
and the MongoDB backend pods are running in this namespace:
NAME READY STATUS RESTARTS AGEjx-production-mongodb-replicaset-0 1/1 Running 0 1mjx-production-mongodb-replicaset-1 1/1 Running 0 1mjx-production-mongodb-replicaset-2 1/1 Running 0 55sjx-production-rsvpapp-54748d68bd-zjgv7 1/1 Running 0 1m
This shows that you have successfully promoted the RSVP sample application to your production environment, simulating the production-ready deployment of an application at the end of a CI/CD pipeline.
结论
In this tutorial, you used Helm to manage packages on a simulated Kubernetes cluster and customized a Helm chart to package and deploy your own application. You also set up a Jenkins X environment on your Kubernetes cluster and run a sample application through a CI/CD pipeline from start to finish.
You now have experience with these tools that you can use when building a CI/CD system on your own Kubernetes cluster. If you’d like to learn more about Helm, check out our An Introduction to Helm, the Package Manager for Kubernetes and How To Install Software on Kubernetes Clusters with the Helm Package Manager articles. To explore further CI/CD tools on Kubernetes, you can read about the Istio service mesh in the next tutorial in this webinar series.