一起探索Kubernetes
Posted 分布式实验室
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一起探索Kubernetes相关的知识,希望对你有一定的参考价值。
我将介绍使用DigitalOcean创建新的Kubernetes集群(或简称k8s)的经验,配置我的GitLab项目以使用Kubernetes集群,以及为部署配置CI/CD进程。如果你想了解现代堆栈的运行是多么简单,请继续阅读。
Kubernetes是一个容器编排平台,由于其简单性而受到广泛欢迎。Kubernetes很棒,因为你可以使用配置文件定义部署配置,存储和网络,集群将确保你的应用程序始终在该配置中运行。
从源代码构建Kubernetes集群是一项艰巨的任务,但是我们可以通过大型云提供商的几次点击来实现这一目标。我个人更喜欢DigitalOcean的简单性,我很幸运能够成为他们管理的Kubernetes产品的LTD版本的一部分。
让我们深入了解如何在DigitalOcean上创建集群。
单击“创建Kubernetes”选项后,无论是通过侧面导航还是顶部导航中的下拉菜单,都会显示此屏幕。
DigitalOceans的Kubernetes集群创建示例
在撰写本文时,Kubernetes版本1.13.1是最新版本,因此我在离我最近的地区选择了该版本。
下一步是配置节点池,标签并选择名称。我选择用一个低成本节点来保持简单,以便学习。这可以在将来更改,因此从小规格开始不会限制你的未来容量。
标签是可选的,名称可以是你想要的任何名称。我发现添加“k8s”标签可以快速识别集群中的droplet。
单击“创建群集”后,该过程大约需要4-5分钟才能完成。在此期间,我们可以让你的机器设置连接到新的Kubernetes群集。
用于与Kubernetes群集交互的主要的命令行程序是 kubectl。对于MacOS用户,可以使用 brew通过运行以下命令来安装它。
➜ brew install kubernetes-cli
brew完成安装后,你需要从DigitalOcean下载集群配置文件,以使 kubectl命令知道你的集群所在的位置。为此,请在DigitalOcean Kubernetes群集安装页面上一直向下滚动到以下部分,然后单击“下载配置文件”按钮 。
该文件将保存到 ~/Downloads目录中。为了简化操作,请将文件复制或移动到 ~/.kube/config文件。该文件将由 kubectl命令自动读取。
➜ mkdir -p ~/.kube
➜ mv ~/Downloads/[k8s-cluster].yaml ~/.kube/config
创建集群后,通过运行 kubectlgetnodes测试连接。这将显示群集中的单个节点。
➜ 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集成。
首先,选择Operations菜单下的Kubernetes选项卡,然后单击Add Kubernetes Cluster。
GitLab - 添加 Kubernetes 集群
在下一个屏幕上,单击“添加现有群集”选项卡。在这里,系统将提示你输入一些不同的项目以允许GitLab连接到你的Kubernetes群集。GitLab有关于如何添加集群的优秀文档,我建议你阅读这些文档(https://gitlab.com/help/user/project/clusters/index#adding-an-existing-kubernetes-cluster)以全面了解集成。我将在此强调所需的步骤。
首先,我们需要为GitLab创建一个新的系统级帐户来连接。此帐户称为ServiceAccount。为此,我们可以使用 kubectl命令行程序。我们将使用YAML语法(在整个Kubernetes中使用)定义帐户,如下所示:
➜ 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集群名称。这对你来说可以帮助你识别Kubernetes群集。它并没有真正使用那么多,所以不要花太多时间为它命名。
可以通过运行以下命令获取下一个字段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密钥等。
➜ 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-----
复制并粘贴从命令返回的所有内容,从 -----BEGINCERTIFICATE-----开始,以 -----ENDCERTIFICATE-----结尾,进入CA Certificate字段。
➜ kubectl get secret <SECRET_NAME> -o jsonpath="{['data']['token']}" | base64 --decode
WlhsS2FHSkhZMmxQYVVwVFZYc...
再一次,将返回的值粘贴到GitLab中的Token字段中。
至于Project Namespace,我把它留空了。确保选中RBAC启用的群集复选框。准备好后,继续并单击Add Kubernetes Cluster按钮。
在GitLab中设置持续集成和持续部署流水线非常简单。它融入了GitLab产品,只需将 .gitlab-ci文件添加到项目的根目录即可轻松配置。将代码推送到GitLab仓库时会触发CI/CD流水线。流水线必须在服务器上运行,该服务器称为“Runner”。Runner可以是虚拟专用服务器,公共服务器,也可以是安装GitLab Runner客户端的任何地方。在我们的用例中,我们将在Kubernetes群集上安装一个运行器,以便在Pod中执行Job。此客户端还使其可扩展,因此我们可以并行运行多个Job。
要在群集上安装GitLab Runner客户端,我们首先需要安装另一个名为Helm的工具。Helm是Kubernetes的软件包管理器,简化了软件的安装。我觉得Helm与Brew for Mac类似,他们都有一个可以安装到系统上的软件回购。
通过Gitlab安装Helm只需要单击“安装”按钮。假设一切都配置正确,安装只需几秒钟。
在Kubernetes集群上安装helm tiller
完成之后,让我们看看群集,看看GitLab安装了什么。使用 kubectlgetns命令,我们可以看到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
如果我们运行 kubectlgetpods,当未指定命名空间时,默认使用 default,我们将看不到任何内容。要查看GitLab命名空间中的Pod,请运行 kubectlgetpods-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运行程序允许我们的CI/CD Job在Kubernetes集群中运行。使用GitLab安装Runner很简单,只需单击“安装”按钮即可。
GitLab - 在Kubernetes集群上安装运行器
我的群集花了大约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”。
# 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
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中的$ CICOMMITTAG变量。环境变量$CICOMMITTAG由GitLab运行器设置,我们告诉envsubst基本上搜索并替换文件中的变量。
此时所有内容都已连线,我们的部署将在每个新标签上运行。
➜ 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控制台中监控负载均衡器的创建:
最后,我们可以通过导航到浏览器中的IP地址来查看我们的应用程序:
我希望你发现此演练有助于你设置自己的群集和现代DevOps工作流程。
你可以在https://gitlab.com/thisiskj/example上查看与该项目相关的所有代码。
如果你有任何其他方法可以将GitLab CI/CD与Kubernetes部署集成,请随时分享评论。
原文链接:https://medium.com/@thisiskj/lets-explore-kubernetes-5477244ef323
基于Kubernetes的DevOps实践培训将于2019年5月10日在上海开课,3天时间带你系统掌握Kubernetes,学习效果不好可以继续学习。本次培训包括:容器特性、镜像、网络;Kubernetes架构、核心组件、基本功能;Kubernetes设计理念、架构设计、基本功能、常用对象、设计原则;Kubernetes的数据库、运行时、网络、插件已经落地经验;微服务架构、组件、监控方案等,点击下方图片查看详情。
以上是关于一起探索Kubernetes的主要内容,如果未能解决你的问题,请参考以下文章
活动回顾Edge X Kubernetes,探索云原生新边界
活动回顾Edge X Kubernetes,探索云原生新边界
python 用于数据探索的Python代码片段(例如,在数据科学项目中)
通过Kubernetes监控探索应用架构,发现预期外的流量
通过Kubernetes监控探索应用架构,发现预期外的流量
探索如何更可靠地运行Kubernetes