内容简介:【编者的话】本文用图示详细分析了Gitlab如何与Kubernetes集群集成,进行CI/CD流水线的配置,从而实现更高效的DevOps流程。我将介绍使用DigitalOcean创建新的Kubernetes集群(或简称k8s)的经验,配置我的Gitlab项目以使用k8s集群,以及为部署配置CI/CD进程。 如果你想了解现代堆栈的运行是多么简单,请继续阅读。
【编者的话】本文用图示详细分析了Gitlab如何与Kubernetes集群集成,进行CI/CD流水线的配置,从而实现更高效的DevOps流程。
我将介绍使用DigitalOcean创建新的Kubernetes集群(或简称k8s)的经验,配置我的Gitlab项目以使用k8s集群,以及为部署配置CI/CD进程。 如果你想了解现代堆栈的运行是多么简单,请继续阅读。
Fatos Bytyqi 拍摄
创建一个Kubernetes集群
Kubernetes是一个容器编排平台,由于其简单性而受到广泛欢迎。 Kubernetes很棒,因为你可以使用配置文件定义部署配置,存储和网络,集群将确保你的应用程序始终在该配置中运行。
从源代码构建k8s集群是一项艰巨的任务,但是我们可以通过大型云提供商的几次点击来实现这一目标。 我个人更喜欢DigitalOcean的简单性,我很幸运能够成为他们管理的Kubernetes产品的LTD版本的一部分。
让我们深入了解如何在DigitalOcean上创建集群。
单击“创建Kubernetes”选项后,无论是通过侧面导航还是顶部导航中的下拉菜单,都会显示此屏幕。
DigitalOceans 的 Kubernetes 集群创建示例
在撰写本文时,k8s版本1.13.1是最新版本,因此我在离我最近的地区选择了该版本。
下一步是配置节点池,标签并选择名称。 我选择用一个低成本节点来保持简单,以便学习。 这可以在将来更改,因此从小规格开始不会限制你的未来容量。
标签是可选的,名称可以是你想要的任何名称。 我发现添加“k8s”标签可以快速识别集群中的droplet。
配置节点,标签和名字
单击“创建群集”后,该过程大约需要4-5分钟才能完成。 在此期间,我们可以让你的机器设置连接到新的k8s群集。
用于与k8s群集交互的主要的命令行程序是 kubectl
。 对于MacOS用户,可以使用 brew
通过运行以下命令来安装它。
➜ brew install kubernetes-cli
brew完成安装后,你需要从DigitalOcean下载集群配置文件,以使 kubectl
命令知道你的集群所在的位置。 为此,请在DigitalOcean k8s群集安装页面上一直向下滚动到以下部分,然后单击“下载配置文件”按钮
该文件将保存到 ~/Downloads
目录中。 为了简化操作,请将文件复制或移动到 ~/.kube/config
文件。 该文件将由 kubectl
命令自动读取。
➜ mkdir -p ~/.kube ➜ mv ~/Downloads/[k8s-cluster].yaml ~/.kube/config
创建集群后,通过运行 kubectl get nodes
测试连接。 这将显示群集中的单个节点。
➜ kubectl get nodes NAME STATUS ROLES AGE VERSION tender-einstein-8m4m Ready <none> 21m v1.13.1
在我的例子中,节点(这是一个DigitalOcean Droplet)被命名为“tender-einstein-8m4m”,我们可以在上面看到。 如果看到类似的输出,则表明你的Kubernetes集群已成功创建,并且你可以通过 kubectl
命令行程序与其建立连接。
将Gitlab连接到Kubernetes
Gitlab具有本地集成Kubernetes的功能,我们可以配置任何组或项目来使用它。 你需要在Gitlab项目上提升(项目创建者和/或管理员)权限才能设置k8s集成。
首先,选择Operations菜单下的Kubernetes选项卡,然后单击Add Kubernetes Cluster。
Gitlab - 添加 Kubernetes 集群
在下一个屏幕上,单击“添加现有群集”选项卡。 在这里,系统将提示你输入一些不同的项目以允许Gitlab连接到你的k8s群集。 Gitlab有关于 如何添加集群 的优秀文档,我建议你阅读这些文档以全面了解集成。我将在此强调所需的步骤。
创建帐户
首先,我们需要为Gitlab创建一个新的系统级帐户来连接。 此帐户称为ServiceAccount。 为此,我们可以使用 kubectl
命令行程序。 我们将使用YAML语法(在整个k8s中使用)定义帐户,如下所示:
➜ kubectl create -f - <<EOF apiVersion: v1 kind: ServiceAccount metadata: name: gitlab namespace: default EOF
此YAML定义将在“default”命名空间中创建名为“gitlab”的ServiceAccount。
下一步是授予gitlab帐户集群管理员权限,以便它可以代表你自由创建和销毁服务。 我们将再次使用 kubectl
和YAML定义。
➜ kubectl create -f - <<EOF kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: gitlab-cluster-admin subjects: - kind: ServiceAccount name: gitlab namespace: default roleRef: kind: ClusterRole name: cluster-admin apiGroup: rbac.authorization.k8s.io EOF
连接群集
现在,让我们看一下Gitlab连接到Kubernetes集群所需的所有信息。
Gitlab - 添加 Kubernetes 集群时呈现的表格
第一个字段是Kubernetes集群名称。 这对你来说可以帮助你识别k8s群集。 它并没有真正使用那么多,所以不要花太多时间为它命名。
可以通过运行以下命令获取下一个字段API URL:
➜ kubectl cluster-info | grep 'Kubernetes master' | awk '/http/ {print $NF}' https://xxxxxx.k8s.ondigitalocean.com
获取命令返回的URL并将其粘贴到API URL字段中。
可以通过从创建gitlab帐户时创建的“secret”中提取数据来获取CA证书和token。 Kubernetes具有 secret
资源的概念,旨在存储敏感信息。 除了设置过程,你还可以创建自己的secret来存储应用程序敏感信息,如数据库凭据,API密钥等。
列出项目运行中的所有secret:
➜ kubectl get secrets NAME TYPE DATA default-token-xfxg9 kubernetes.io/service-account-token 3 gitlab-token-vxhxq kubernetes.io/service-account-token 3
在这里,我们看到群集中有2个secret对象。 我们感兴趣的是名为 gitlab-token-vxhxq
的名字。 找到以 gitlab-token-*
开头的secret,并在下一个命令中使用它:
➜ kubectl get secret <SECRET_NAME> -o jsonpath="{['data']['ca\.crt']}" | base64 --decode -----BEGIN CERTIFICATE----- ... -----END CERTIFICATE-----
复制并粘贴从命令返回的所有内容,从 ----- BEGIN CERTIFICATE -----
开始,以 ----- END CERTIFICATE -----
结尾,进入CA Certificate字段
可以通过执行以下操作以类似的方式获取token:
➜ kubectl get secret <SECRET_NAME> -o jsonpath="{['data']['token']}" | base64 --decode WlhsS2FHSkhZMmxQYVVwVFZYc...
再一次,将返回的值粘贴到Gitlab中的Token字段中。
至于Project Namespace,我把它留空了。 确保选中RBAC启用的群集复选框。 准备好后,继续并单击Add Kubernetes Cluster按钮。
Gitlab - 集群所有的必填字段均已填入
设置CI/CD
在Gitlab中设置持续集成和持续部署流水线非常简单。它融入了Gitlab产品,只需将 .gitlab-ci
文件添加到项目的根目录即可轻松配置。将代码推送到Gitlab仓库时会触发CI/CD流水线。流水线必须在服务器上运行,该服务器称为“Runner”。Runner可以是虚拟专用服务器,公共服务器,也可以是安装Gitlab Runner客户端的任何地方。在我们的用例中,我们将在k8s群集上安装一个运行器,以便在pod中执行job。此客户端还使其可扩展,因此我们可以并行运行多个job。
要在群集上安装Gitlab runner客户端,我们首先需要安装另一个名为Helm的工具。 Helm是Kubernetes的软件包管理器,简化了软件的安装。我觉得Helm与Brew for Mac类似,他们都有一个可以安装到系统上的软件回购。
安装Helm
通过Gitlab安装Helm只需要单击“安装”按钮。假设一切都配置正确,安装只需几秒钟。
在 k8s 集群上安装 helm tiller
完成之后,让我们看看群集,看看Gitlab安装了什么。 使用 kubectl get ns
命令,我们可以看到Gitlab已经创建了自己的命名空间,命名为gitlab-managed-apps。
➜ kubectl get ns NAME STATUS AGE default Active 1d gitlab-managed-apps Active 23s kube-public Active 1d kube-system Active 1d
如果我们运行 kubectl get pods
,当未指定命名空间时,默认使用 default
,我们将看不到任何内容。 要查看Gitlab命名空间中的pod,请运行 kubectl get pods -n gitlab-managed-apps
。
➜ kubectl get pods -n gitlab-managed-apps NAME READY STATUS RESTARTS AGE tiller-deploy-7dd47f89cc-27cmt 1/1 Running 0 5m
在这里,我们看到“Helm tiller”已成功创建并正在运行。
安装Gitlab Runner
如前所述,Gitlab运行程序允许我们的CI/CD job在k8s集群中运行。 使用Gitlab安装Runner很简单,只需单击“安装”按钮即可。
Gitlab - 在k8s集群上安装运行器
我的群集花了大约1分钟。 完成之后,让我们再看看pod,你应该看到Gitlab Runner的新pod。
➜ kubectl get pods -n gitlab-managed-apps
NAME READY STATUS RESTARTS
runner-gitlab-runner-5cffc648d7-xr9rq 1/1 Running 0
tiller-deploy-7dd47f89cc-27cmt 1/1 Running 0
你可以通过查看Gitlab中的设置➜CI/CD➜Runner部分来验证Runner是否已连接到你的项目。
Gitlab - Kubernetes 运行器已在本项目激活
运行流水线
很好,所以现在我们有一个功能齐全的Gitlab项目,连接到Kubernetes,Runner准备执行我们的CI/CD流水线。 让我们设置一个示例Golang项目,看看如何触发这些流水线。 对于这个项目,我们将运行一个简单的HTTP服务器,返回经典的“Hello World”。
首先,写下 go 代码:
# main.go package main import ( "fmt" "log" "net/http" ) func main() { http.HandleFunc( "/hello", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hello World!") }, ) log.Fatal(http.ListenAndServe(":8080", nil))
}
然后是运行的 Dockerfile:
# Dockerfile FROM golang:1.11 WORKDIR /go/src/app COPY . . RUN go get -d -v ./... RUN go install -v ./... CMD ["app"]
接下来,我们将创建一个.gitlab-ci.yml文件来定义我们的CI/CD流水线。 该文件将在每次代码推送时进行评估,如果分支或标签与任何job匹配,它们将由我们之前配置的Gitlab运行程序之一自动执行。
我们流水线的第一步是在我们推送到主分支时创建应用程序的 docker 镜像。 我们可以使用以下配置执行此操作:
# Gitlab CI Definition (.gitlab-ci.yml) stages: - build - deploy services: - docker:dind variables: DOCKER_HOST: tcp://localhost:2375 build_app: image: docker:latest stage: build only: - master script: - docker build -t ${CI_REGISTRY}/${CI_PROJECT_PATH}:${CI_COMMIT_REF_NAME} . - docker login -u gitlab-ci-token -p ${CI_BUILD_TOKEN} ${CI_REGISTRY} - docker push ${CI_REGISTRY}/${CI_PROJECT_PATH}:${CI_COMMIT_REF_NAME
}
让我们浏览文件中的每个块。 stages:
块定义流水线中阶段的顺序。我们只有2个阶段,构建然后部署。
services:
块包括官方Docker-in-Docker(或dind)镜像,将在所有job中链接。我们需要这个,因为我们将成为Gitlab CI docker容器内的应用程序docker容器。
接下来我们有 build_app:
job。这个名字由我们的项目组成,可以是你想要的任何名称。 image
表明我们正在使用Docker Hub中的最新Docker镜像。 stage
告诉Gitlab这个job处于什么阶段。要记住的一件好事是,同一阶段的job将并行运行。 only:
标签表示我们只会在提交到 master
分支时运行此job。最后, scrips:
是job的核心,它将运行 docker build
命令来创建我们的镜像,然后 docker login
到Gitlab注册表,然后 docker push
将该镜像推送到我们的注册表。
此时我们可以提交并推送代码,你应该在Gitlab注册表中看到一个全新的镜像。
在构建镜像并将其保存在注册表上之后,下一步是部署它。我们需要定义部署配置,告诉kubernetes我们想要如何运行应用程序。以下yaml文件正是如此:
# Deployment Configuration (deployment-template.yaml) apiVersion: apps/v1 kind: Deployment metadata: name: example-deployment labels: app: example spec: replicas: 1 selector: matchLabels: app: example template: metadata: labels: app: example spec: containers: - name: example image: registry.gitlab.com/thisiskj/example:latest ports: - containerPort: 8080
此文件定义了一个部署,其中包含一个将从项目运行镜像的单个副本(registry.gitlab.com/thisiskj/example:latest)。
为了触发部署,我已经配置了.gitlab-ci.yml文件,以便在标记代码repo时执行此操作。 这是job定义:
deploy_app: image: thisiskj/kubectl-envsubst stage: deploy environment: production only: - tags script: - envsubst \$CI_COMMIT_TAG < deployment-template.yaml > deployment.yaml - kubectl apply -f deployment.yaml
此job将运行envsubst命令,以使用触发构建的git标签的名称替换deployment-template.yaml中的$ CI_COMMIT_TAG变量。 环境变量$CI_COMMIT_TAG由Gitlab运行器设置,我们告诉envsubst基本上搜索并替换文件中的变量。
查看应用程序
此时所有内容都已连线,我们的部署将在每个新标签上运行。
我们可以看到正在运行的pod:
➜ kubectl -n example-10311640 get pods NAME READY STATUS RESTARTS example-deployment-756c8f6dc5-jk85w 1/1 Running 0
现在,pod正在运行,但我们无法从外部访问golang HTTP服务。 为了允许外部访问,我们可以创建LoadBalancer类型的服务。 将以下规范添加到部署yaml以在DigitalOcean上创建LoadBalancer。
--- kind: Service apiVersion: v1 metadata: name: example-loadbalancer-service spec: selector: app: example ports: - protocol: TCP port: 80 targetPort: 8080 type: LoadBalancer
在下一次部署中,我们可以监视LoadBalancer的创建。 外部IP可能需要几分钟才能显示。
➜ kubectl -n example-10311640 get services NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE example-loadbalancer-service LoadBalancer 10.245.40.9 <pending> 80:30897/TCP 4s ... ➜ kubectl -n example-10311640 get services NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE example-loadbalancer-service LoadBalancer 10.245.40.9 157.230.64.204 80:30897/TCP 2m9s
我们还可以在DigitialOcean控制台中监控负载均衡器的创建:
DigitalOcean — 网络控制台
最后,我们可以通过导航到浏览器中的IP地址来查看我们的应用程序:
服务开始运行
总结一下
我希望你发现此演练有助于你设置自己的群集和现代DevOps工作流程。
你可以在 https://gitlab.com/thisiskj/example 上查看与该项目相关的所有代码
如果你有任何其他方法可以将Gitlab CI/CD与Kubernetes部署集成,请随时分享评论。
原文链接: Lets Explore Kubernetes (翻译:池剑锋)
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Algorithms Unlocked
Thomas H. Cormen / The MIT Press / 2013-3-1 / USD 25.00
Have you ever wondered how your GPS can find the fastest way to your destination, selecting one route from seemingly countless possibilities in mere seconds? How your credit card account number is pro......一起来看看 《Algorithms Unlocked》 这本书的介绍吧!