网络研讨会系列:使用Helm的Kubernetes包管理和使用Jenkins X的CI / CD

在使用Kubernetes系列的CI / CD的第二篇文章中,您将预览两个专门用于管理云原生CI / CD的Kubernetes特定工具:Helm包管理器和Jenkins X管道自动化工具。为了有效减少错误并组织应用程序部署的复杂性,CI / CD系统必须包含用于包管理/部署的强大工具以及使用自动化测试创建开发管道。

网络研讨会系列

本文补充了关于使用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 update
apt-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

打开此文件后,添加以下行:

/etc/apt/sources.list.d/kubernetes.list
deb http://apt.kubernetes.io/ kubernetes-xenial main

这将向您的系统显示下载kubectl的来源。 添加行后,保存并退出文件。 使用nano文本编辑器,您可以通过按CTRL+X ,键入y ,然后按ENTER来完成此操作。

最后,更新APT的源列表并安装kubectlsocatdocker.io

apt-get update
apt-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: Running
cluster: Running
kubectl: 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/helmtiller安装到/usr/local/bin/tiller

虽然现在安装了tiller ,但它还没有正确的角色和权限来访问Kubernetes群集中的必要资源。 要将这些角色和权限分配给tiller ,您必须创建名为tiller服务帐户 在Kubernetes中,服务帐户表示在pod中运行的进程的标识。 通过服务帐户验证进程后,它可以联系API服务器并访问群集资源。 如果未为pod分配特定服务帐户,则会获取默认服务帐户。 您还必须创建一个授权tiller服务帐户的基于角色的访问控制 (RBAC)规则。

在Kubernetes RBAC API中, 角色包含确定一组权限的规则。 可以使用namespacecluster的范围定义角色,并且只能授予对单个命名空间内的资源的访问权限。 ClusterRole可以在群集级别创建相同的权限,授予对群集范围资源(如节点和pods等命名空间资源)的访问权限。 要为tiller服务帐户指定正确的角色,请创建名为rbac_helm.yaml的YAML文件,并在文本编辑器rbac_helm.yaml其打开:

nano rbac_helm.yaml

tiller添加到文件以配置tiller服务帐户:

rbac_helm.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: tiller
  namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: tiller
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
  - 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服务帐户, adminkubelet用户以及system:serviceaccounts组。

接下来,使用以下命令在rbac_helm.yaml部署配置:

kubectl apply -f rbac_helm.yaml 

部署了tiller配置后,您现在可以使用--service-acount标志初始化Helm,以使用您刚刚设置的服务帐户:

helm init --service-account tiller 

您将收到以下输出,表示初始化成功:

Creating /root/.helm
Creating /root/.helm/repository
Creating /root/.helm/repository/cache
Creating /root/.helm/repository/local
Creating /root/.helm/plugins
Creating /root/.helm/starters
Creating /root/.helm/cache/archive
Creating /root/.helm/repository/repositories.yaml
Adding stable repo with URL: https://kubernetes-charts.storage.googleapis.com
Adding 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-installation
Happy Helming!

这会在kube-system名称空间中创建一个tiller窗格。 它还在$HOME目录中创建.helm默认存储库,并在https://kubernetes-charts.storage.googleapis.com和本地Helm存储库中配置默认​​的Helm稳定图表存储库, https://kubernetes-charts.storage.googleapis.comhttp://127.0.0.1:8879/charts

要确保tiller pod在kube-system命名空间中运行,请输入以下命令:

kubectl --namespace kube-system get pods

在您的pod列表中,将显示tiller-deploy ,如以下输出中所示:

NAME                                    READY   STATUS    RESTARTS   AGE
etcd-minikube                           1/1     Running   0          2h
kube-addon-manager-minikube             1/1     Running   0          2h
kube-apiserver-minikube                 1/1     Running   0          2h
kube-controller-manager-minikube        1/1     Running   0          2h
kube-dns-86f4d74b45-rjql8               3/3     Running   0          2h
kube-proxy-dv268                        1/1     Running   0          2h
kube-scheduler-minikube                 1/1     Running   0          2h
kubernetes-dashboard-5498ccf677-wktkl   1/1     Running   0          2h
storage-provisioner                     1/1     Running   0          2h
tiller-deploy-689d79895f-bggbk          1/1     Running   0          5m

如果tiller吊舱的状态为“正在Running ,它现在可以代表Helm从群集内部管理Kubernetes应用程序。

要确保整个Helm应用程序正常工作,请在Helm包存储库中搜索MongoDB之类的应用程序:

helm search mongodb

在输出中,您将看到适合您的搜索字词的可能应用程序列表:

NAME                                    CHART VERSION   APP VERSION     DESCRIPTION
stable/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 metrics
stable/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 demo
ls

您将在demo找到以下文件和目录:

演示
charts  Chart.yaml  templates  values.yaml

使用文本编辑器打开Chart.yaml文件:

nano Chart.yaml

在里面,你会发现以下内容:

演示/ Chart.yaml
apiVersion: v1
appVersion: "1.0"
description: A Helm chart for Kubernetes
name: demo
version: 0.1.0

在此Chart.yaml文件中,您将找到像apiVersion这样的字段,它必须始终为v1 ,这是一个description ,提供有关demo内容的更多信息,图表的name以及Helm用作发布标记的version号。 检查完文件后,请关闭文本编辑器。

接下来,打开values.yaml文件:

nano values.yaml

在此文件中,您将找到以下内容:

演示/ values.yaml
# Default values for demo.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.

replicaCount: 1

image:
  repository: nginx
  tag: stable
  pullPolicy: IfNotPresent

nameOverride: ""
fullnameOverride: ""

service:
  type: ClusterIP
  port: 80

ingress:
  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.local

resources: {}
  # 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: 128Mi

nodeSelector: {}

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:   web
LAST DEPLOYED: Wed Feb 20 20:59:48 2019
NAMESPACE: default
STATUS: DEPLOYED

RESOURCES:
==> v1/Service
NAME      TYPE       CLUSTER-IP     EXTERNAL-IP  PORT(S)  AGE
web-demo  ClusterIP  10.100.76.231  <none>       80/TCP   0s

==> v1/Deployment
NAME      DESIRED  CURRENT  UP-TO-DATE  AVAILABLE  AGE
web-demo  1        0        0           0          0s

==> v1/Pod(related)
NAME                       READY  STATUS             RESTARTS  AGE
web-demo-5758d98fdd-x4mjs  0/1    ContainerCreating  0         0s


NOTES:
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   AGE
web-demo   1         1         1            1           4m

使用命令kubectl get pods列出您的pod将显示运行web应用程序的pod,如下所示:

NAME                        READY   STATUS    RESTARTS   AGE
web-demo-5758d98fdd-nbkqd   1/1     Running   0          4m

要演示Helm图表中的更改如何发布应用程序的不同版本,请在文本编辑器中打开demo/values.yaml并将replicaCount:更改为3 ,将image:tag:stablelatest 在下面的代码块中,您将在完成修改后找到YAML文件的外观,并突出显示更改:

演示/ values.yaml
# Default values for demo.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.

replicaCount: 3

image:
  repository: nginx
  tag: latest
  pullPolicy: IfNotPresent

nameOverride: ""
fullnameOverride: ""

service:
  type: ClusterIP
  port: 80
. . .

保存并退出该文件。

在部署此新版web应用程序之前,请使用以下命令列出现在的Helm版本:

helm list

您将收到以下输出,其中包含您之前创建的一个部署:

NAME    REVISION        UPDATED                         STATUS          CHART           APP VERSION     NAMESPACE
web     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     NAMESPACE
web     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           DESCRIPTION
1               Wed Feb 20 20:59:48 2019        SUPERSEDED      demo-0.1.0      Install complete
2               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           DESCRIPTION
1               Wed Feb 20 20:59:48 2019        SUPERSEDED      demo-0.1.0      Install complete
2               Wed Feb 20 21:18:12 2019        SUPERSEDED      demo-0.1.0      Upgrade complete
3               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           DESCRIPTION
1               Wed Feb 20 20:59:48 2019        SUPERSEDED      demo-0.1.0      Install complete
2               Wed Feb 20 21:18:12 2019        SUPERSEDED      demo-0.1.0      Upgrade complete
3               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 ~/.kube
rm -rf ~/.minikube
rm -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

将以下内容添加到文件中:

/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: 0
Images: 15
Server Version: 18.06.1-ce
Storage Driver: overlay2
 Backing Filesystem: extfs
 Supports d_type: true
 Native Overlay Diff: true

. . .

Registry: https://index.docker.io/v1/
Labels:
Experimental: false
Insecure Registries:
 0.0.0.0/0
 127.0.0.0/8
Live 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 Token
Please click this URL https://github.com/settings/tokens/new?scopes=repo,read:user,read:org,user:email,write:repo_hook,delete_repo

Then 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: jx
To switch back to your original namespace use: jx namespace default
For help on switching contexts see: https://jenkins-x.io/developing/kube-context/

To import existing projects into Jenkins:       jx import
To create a new Spring Boot microservice:       jx create spring -d web -d actuator
To create a new microservice from a quickstart: jx create quickstart

接下来,使用jx get命令接收显示有关应用程序信息的URL列表:

jx get urls

此命令将生成类似于以下内容的列表:

Name                      URL
jenkins                   http://jenkins.jx.your_IP_address.nip.io
jenkins-x-chartmuseum     http://chartmuseum.jx.your_IP_address.nip.io
jenkins-x-docker-registry http://docker-registry.jx.your_IP_address.nip.io
jenkins-x-monocular-api   http://monocular.jx.your_IP_address.nip.io
jenkins-x-monocular-ui    http://monocular.jx.your_IP_address.nip.io
nexus                     http://nexus.jx.your_IP_address.nip.io

通过在浏览器中输入地址并输入用户名和密码,您可以使用URL通过UI查看有关CI / CD环境的Jenkins X数据。 在这种情况下,这两者都是“admin”。

接下来,为了确保命名空间jxjx-stagingjx-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 rsvpapp
rm -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 完成此更改后,您的文件应如下所示:

图/ rsvpapp / values.yaml
# Default values for python.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
replicaCount: 1
image:
  repository: draft
  tag: dev
  pullPolicy: IfNotPresent
service:
  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: 128Mi
ingress:
  enabled: false

保存并退出您的文件。

接下来,更改charts/preview/requirements.yaml以适合您的应用程序。 requirements.yaml是一个YAML文件,开发人员可以在其中声明图表依赖关系,以及图表的位置和所需的版本。 由于我们的示例应用程序将MongoDB用于数据库目的,因此您需要修改charts/preview/requirements.yaml文件以将MongoDB列为依赖项。 使用以下命令在文本编辑器中打开文件:

nano charts/preview/requirements.yaml

通过在alias: cleanup条目之后添加mongodb-replicaset条目来编辑文件,如以下代码块中突出显示:

图/预览/ requirements.yaml
# !! 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

文件打开后,添加以下内容,确保填充行前后有一行空格:

图/ 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文件需要这些空白行:

图/ rsvpapp /模板/ deployment.yaml

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  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:

/rsvpapp/Jenkinsfile
. . .
  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 update
git 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 URL
rsvpapp     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:

Sample RSVP Application in the Staging Environment

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 STATUS
your_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 Succeeded
your_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   AGE
jx-staging-mongodb-replicaset-0      1/1       Running   0          6m
jx-staging-mongodb-replicaset-1      1/1       Running   0          6m
jx-staging-mongodb-replicaset-2      1/1       Running   0          5m
jx-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 URL
rsvpapp     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":

Sample RSVP Application in the Production Environment

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   AGE
jx-production-mongodb-replicaset-0       1/1       Running   0          1m
jx-production-mongodb-replicaset-1       1/1       Running   0          1m
jx-production-mongodb-replicaset-2       1/1       Running   0          55s
jx-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.