网络研讨会系列:使用Kubernetes进行CI/CD的构建块
网络研讨会系列
本文补充了 使用 Kubernetes 进行 CI/CD 的网络研讨会系列。 本系列讨论如何采用云原生方法来构建、测试和部署应用程序,涵盖发布管理、云原生工具、服务网格和可与 Kubernetes 一起使用的 CI/CD 工具。 它旨在帮助有兴趣将 CI/CD 最佳实践与 Kubernetes 集成到他们的工作流程中的开发人员和企业。
本教程包含本系列第一节“使用 Kubernetes 进行 CI/CD 的构建块”中的概念和命令。
介绍
如果您开始使用 containers,您可能想知道如何自动化构建、测试和部署。 通过对这些流程采用 Cloud Native 方法,您可以利用正确的基础架构 API 以自动化方式打包和部署应用程序。
实现自动化的两个构建块包括 容器映像 和 容器编排器 。 在过去一年左右的时间里,Kubernetes 已经成为容器编排的默认选择。 在 CI/CD with Kubernetes 系列的第一篇文章中,您将:
- 使用 Docker、Buildah 和 Kaniko 构建容器镜像。
- 使用 Terraform 设置 Kubernetes 集群,并创建 Deployments 和 Services。
- 使用 自定义资源 扩展 Kubernetes 集群的功能。
在本教程结束时,您将拥有使用 Docker、Buildah 和 Kaniko 构建的容器镜像,以及一个包含部署、服务和自定义资源的 Kubernetes 集群。
该系列的后续文章将涵盖相关主题:Kubernetes 的包管理、CI/CD 工具(如 Jenkins X 和 Spinnaker)、服务网格和 GitOps。
先决条件
- 具有非 root 用户帐户的 Ubuntu 16.04 服务器。 按照我们的 Initial Server Setup with Ubuntu 16.04 教程获取指导。
- Docker 安装在您的服务器上。 请按照 如何在 Ubuntu 16.04 上安装和使用 Docker 的步骤 1 和 2 获取安装说明。
- 一个 Docker Hub 帐户。 有关 Docker Hub 入门的概述,请参阅 这些说明 。
- DigitalOcean 帐户和个人访问令牌。 请参考这些说明获取您的访问令牌。
- 熟悉容器和Docker。 请参阅 网络研讨会系列:容器入门 了解更多详情。
- 熟悉 Kubernetes 概念。 详情请参考【X16X】Kubernetes简介【X49X】。
第 1 步 — 使用 Docker 和 Buildah 构建容器镜像
容器映像是一个自包含的实体,具有自己的应用程序代码、运行时和可用于创建和运行容器的依赖项。 您可以使用不同的工具来创建容器镜像,在此步骤中,您将使用其中两个工具构建容器:Docker 和 Buildah。
使用 Dockerfile 构建容器镜像
Docker 通过读取 Dockerfile 中的指令自动构建您的容器镜像,Dockerfile 是一个文本文件,其中包含组装容器镜像所需的命令。 使用 docker image build
命令,您可以创建一个自动构建,该构建将执行 Dockerfile 中提供的命令行指令。 构建镜像时,您还将通过 Dockerfile 传递 构建上下文 ,其中包含在容器镜像中创建环境和运行应用程序所需的文件集。
通常,您将为 Dockerfile 和构建上下文创建一个项目文件夹。 创建一个名为 demo
的文件夹开始:
mkdir demo cd demo
接下来,在 demo
文件夹中创建一个 Dockerfile:
nano Dockerfile
将以下内容添加到文件中:
~/demo/Dockerfile
FROM ubuntu:16.04 LABEL MAINTAINER neependra@cloudyuga.guru RUN apt-get update \ && apt-get install -y nginx \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* \ && echo "daemon off;" >> /etc/nginx/nginx.conf EXPOSE 80 CMD ["nginx"]
这个 Dockerfile 由一组指令组成,这些指令将构建一个运行 Nginx 的镜像。 在构建过程中,ubuntu:16.04
将作为基础镜像,并且将安装 nginx
包。 使用 CMD
指令,您还将 nginx
配置为容器启动时的默认命令。
接下来,您将使用 docker image build
命令构建容器映像,使用当前目录 (.) 作为构建上下文。 将 -t
选项传递给此命令,将图像命名为 nkhare/nginx:latest
:
sudo docker image build -t nkhare/nginx:latest .
您将看到以下输出:
OutputSending build context to Docker daemon 49.25MB Step 1/5 : FROM ubuntu:16.04 ---> 7aa3602ab41e Step 2/5 : MAINTAINER neependra@cloudyuga.guru ---> Using cache ---> 552b90c2ff8d Step 3/5 : RUN apt-get update && apt-get install -y nginx && apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* && echo "daemon off;" >> /etc/nginx/nginx.conf ---> Using cache ---> 6bea966278d8 Step 4/5 : EXPOSE 80 ---> Using cache ---> 8f1c4281309e Step 5/5 : CMD ["nginx"] ---> Using cache ---> f545da818f47 Successfully built f545da818f47 Successfully tagged nginx:latest
您的图像现在已构建。 您可以使用以下命令列出您的 Docker 映像:
docker image ls
OutputREPOSITORY TAG IMAGE ID CREATED SIZE nkhare/nginx latest 4073540cbcec 3 seconds ago 171MB ubuntu 16.04 7aa3602ab41e 11 days ago
您现在可以使用 nkhare/nginx:latest
图像来创建容器。
使用 Project Atomic-Buildah 构建容器镜像
Buildah 是一个 CLI 工具,由 Project Atomic 开发,用于快速构建符合 Open Container Initiative (OCI) 标准的镜像。 OCI 为容器运行时和图像提供规范,以标准化行业最佳实践。
Buildah 可以从工作容器或 Dockerfile 创建映像。 它可以在没有 Docker 守护进程的情况下完全在用户空间构建镜像,并且可以执行 build
、list
、push
和 tag
等镜像操作。 在此步骤中,您将从源代码编译 Buildah,然后使用它来创建容器映像。
要安装 Buildah,您将需要所需的依赖项,包括使您能够管理包和包安全性的工具等。 运行以下命令来安装这些软件包:
cd sudo apt-get install software-properties-common sudo add-apt-repository ppa:alexlarsson/flatpak sudo add-apt-repository ppa:gophers/archive sudo apt-add-repository ppa:projectatomic/ppa sudo apt-get update sudo apt-get install bats btrfs-tools git libapparmor-dev libdevmapper-dev libglib2.0-dev libgpgme11-dev libostree-dev libseccomp-dev libselinux1-dev skopeo-containers go-md2man
因为你将编译 buildah
源代码来创建它的包,你还需要安装 Go:
sudo apt-get update sudo curl -O https://storage.googleapis.com/golang/go1.8.linux-amd64.tar.gz sudo tar -xvf go1.8.linux-amd64.tar.gz sudo mv go /usr/local sudo echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.profile source ~/.profile go version
您将看到以下输出,表明安装成功:
Outputgo version go1.8 linux/amd64
您现在可以获得 buildah
源代码来创建它的包,以及 runc
二进制文件。 runc
是 OCI
容器运行时的实现,您将使用它来运行 Buildah 容器。
运行以下命令安装 runc
和 buildah
:
mkdir ~/buildah cd ~/buildah export GOPATH=`pwd` git clone https://github.com/containers/buildah ./src/github.com/containers/buildah cd ./src/github.com/containers/buildah make runc all TAGS="apparmor seccomp" sudo cp ~/buildah/src/github.com/opencontainers/runc/runc /usr/bin/. sudo apt install buildah
接下来,创建 /etc/containers/registries.conf
文件来配置您的容器注册表:
sudo nano /etc/containers/registries.conf
将以下内容添加到文件中以指定您的注册表:
/etc/containers/registries.conf
# This is a system-wide configuration file used to # keep track of registries for various container backends. # It adheres to TOML format and does not support recursive # lists of registries. # The default location for this configuration file is /etc/containers/registries.conf. # The only valid categories are: 'registries.search', 'registries.insecure', # and 'registries.block'. [registries.search] registries = ['docker.io', 'registry.fedoraproject.org', 'quay.io', 'registry.access.redhat.com', 'registry.centos.org'] # If you need to access insecure registries, add the registry's fully-qualified name. # An insecure registry is one that does not have a valid SSL certificate or only does HTTP. [registries.insecure] registries = [] # If you need to block pull access from a registry, uncomment the section below # and add the registries fully-qualified name. # # Docker only [registries.block] registries = []
registries.conf
配置文件指定在完成不包含注册表或域部分的映像名称时应咨询哪些注册表。
现在运行以下命令来构建映像,使用 https://github.com/do-community/rsvpapp-webinar1
存储库作为构建上下文。 此存储库还包含相关的 Dockerfile:
sudo buildah build-using-dockerfile -t rsvpapp:buildah github.com/do-community/rsvpapp-webinar1
此命令从 https://github.com/do-community/rsvpapp-webinar1
存储库中可用的 Dockerfille 创建一个名为 rsvpapp:buildah
的映像。
要列出图像,请使用以下命令:
sudo buildah images
您将看到以下输出:
OutputIMAGE ID IMAGE NAME CREATED AT SIZE b0c552b8cf64 docker.io/teamcloudyuga/python:alpine Sep 30, 2016 04:39 95.3 MB 22121fd251df localhost/rsvpapp:buildah Sep 11, 2018 14:34 114 MB
这些图像之一是您刚刚创建的 localhost/rsvpapp:buildah
。 另一个,docker.io/teamcloudyuga/python:alpine
,是来自 Dockerfile 的基础镜像。
构建映像后,您可以将其推送到 Docker Hub。 这将允许您存储它以备将来使用。 您首先需要从命令行登录到您的 Docker Hub 帐户:
docker login -u your-dockerhub-username -p your-dockerhub-password
登录成功后,您将获得一个文件 ~/.docker/config.json
,其中包含您的 Docker Hub 凭据。 然后,您可以使用该文件和 buildah
将图像推送到 Docker Hub。
例如,如果要推送刚刚创建的镜像,可以运行以下命令,引用 authfile
和要推送的镜像:
sudo buildah push --authfile ~/.docker/config.json rsvpapp:buildah docker://your-dockerhub-username/rsvpapp:buildah
您还可以使用以下命令将生成的图像推送到本地 Docker 守护程序:
sudo buildah push rsvpapp:buildah docker-daemon:rsvpapp:buildah
最后,看看你创建的 Docker 镜像:
sudo docker image ls
OutputREPOSITORY TAG IMAGE ID CREATED SIZE rsvpapp buildah 22121fd251df 4 minutes ago 108MB nkhare/nginx latest 01f0982d91b8 17 minutes ago 172MB ubuntu 16.04 b9e15a5d1e1a 5 days ago 115MB
正如预期的那样,您现在应该看到一个新图像 rsvpapp:buildah
,它是使用 buildah
导出的。
您现在拥有使用 Docker 和 Buildah 这两种不同工具构建容器映像的经验。 让我们继续讨论如何使用 Kubernetes 设置容器集群。
第 2 步 — 使用 kubeadm 和 Terraform 在 DigitalOcean 上设置 Kubernetes 集群
在 DigitalOcean 上设置 Kubernetes 有多种方法。 要了解有关如何使用 kubeadm 设置 Kubernetes 的更多信息,例如,您可以查看 如何在 Ubuntu 18.04 上使用 Kubeadm 创建 Kubernetes 集群。
由于本教程系列讨论了采用云原生方法进行应用程序开发,因此我们将在设置集群时应用此方法。 具体来说,我们将使用 kubeadm 和 Terraform 自动化我们的集群创建,这是一种简化创建和更改基础设施的工具。
使用您的个人访问令牌,您将使用 Terraform 连接到 DigitalOcean 以配置 3 个服务器。 您将在这些 VM 中运行 kubeadm
命令来创建一个包含一个主节点和两个工作节点的 3 节点 Kubernetes 集群。
在您的 Ubuntu 服务器上,创建一对 SSH 密钥 ,这将允许无密码登录到您的虚拟机:
ssh-keygen -t rsa
您将看到以下输出:
OutputGenerating public/private rsa key pair. Enter file in which to save the key (~/.ssh/id_rsa):
按 ENTER
将密钥对保存在您的主目录下的 ~/.ssh
目录中,或输入其他目的地。
接下来,您将看到以下提示:
OutputEnter passphrase (empty for no passphrase):
在这种情况下,无需密码按 ENTER
即可启用无密码登录到您的节点。
您将看到确认您的密钥对已创建:
OutputYour identification has been saved in ~/.ssh/id_rsa. Your public key has been saved in ~/.ssh/id_rsa.pub. The key fingerprint is: SHA256:lCVaexVBIwHo++NlIxccMW5b6QAJa+ZEr9ogAElUFyY root@3b9a273f18b5 The key's randomart image is: +---[RSA 2048]----+ |++.E ++o=o*o*o | |o +..=.B = o | |. .* = * o | | . =.o + * | | . . o.S + . | | . +. . | | . ... = | | o= . | | ... | +----[SHA256]-----+
通过运行以下命令获取您的公钥,该命令将在您的终端中显示它:
cat ~/.ssh/id_rsa.pub
按照 这些说明 将此密钥添加到您的 DigitalOcean 帐户。
接下来,安装 Terraform:
sudo apt-get update sudo apt-get install unzip wget https://releases.hashicorp.com/terraform/0.11.7/terraform_0.11.7_linux_amd64.zip unzip terraform_0.11.7_linux_amd64.zip sudo mv terraform /usr/bin/. terraform version
您将看到确认您的 Terraform 安装的输出:
OutputTerraform v0.11.7
接下来,运行以下命令来安装 kubectl
,一个将与您的 Kubernetes 集群通信的 CLI 工具,并在您的用户的主目录中创建一个 ~/.kube
目录:
sudo apt-get install apt-transport-https curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add - sudo touch /etc/apt/sources.list.d/kubernetes.list echo "deb http://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee -a /etc/apt/sources.list.d/kubernetes.list sudo apt-get update sudo apt-get install kubectl mkdir -p ~/.kube
创建 ~/.kube
目录将使您能够将配置文件复制到此位置。 在本节后面运行 Kubernetes 设置脚本后,您将执行此操作。 默认情况下,kubectl
CLI 会在 ~/.kube
目录中查找配置文件以访问集群。
接下来,克隆本教程的示例项目存储库,其中包含用于设置基础架构的 Terraform 脚本:
git clone https://github.com/do-community/k8s-cicd-webinars.git
进入 Terrafrom 脚本目录:
cd k8s-cicd-webinars/webinar1/2-kubernetes/1-Terraform/
获取 SSH 公钥的指纹:
ssh-keygen -E md5 -lf ~/.ssh/id_rsa.pub | awk '{print $2}'
您将看到如下输出,突出显示的部分代表您的密钥:
OutputMD5:dd:d1:b7:0f:6d:30:c0:be:ed:ae:c7:b9:b8:4a:df:5e
请记住,您的密钥将与此处显示的不同。
将指纹保存到环境变量中,以便 Terraform 可以使用它:
export FINGERPRINT=dd:d1:b7:0f:6d:30:c0:be:ed:ae:c7:b9:b8:4a:df:5e
接下来,导出您的 DO 个人访问令牌:
export TOKEN=your-do-access-token
现在看一下~/k8s-cicd-webinars/webinar1/2-kubernetes/1-Terraform/
项目目录:
ls
Outputcluster.tf destroy.sh files outputs.tf provider.tf script.sh
此文件夹包含使用 Terraform 部署 Kubernetes 集群所需的脚本和配置文件。
执行 script.sh
脚本触发 Kubernetes 集群设置:
./script.sh
脚本执行完成后,kubectl
将被配置为使用您创建的 Kubernetes 集群。
使用 kubectl get nodes
列出集群节点:
kubectl get nodes
OutputNAME STATUS ROLES AGE VERSION k8s-master-node Ready master 2m v1.10.0 k8s-worker-node-1 Ready <none> 1m v1.10.0 k8s-worker-node-2 Ready <none> 57s v1.10.0
您现在有一个主节点和两个工作节点处于 Ready
状态。
设置 Kubernetes 集群后,您现在可以探索构建容器映像的另一个选项:来自 Google 的 Kaniko。
第 3 步 — 使用 Kaniko 构建容器镜像
在本教程的前面部分,您使用 Dockerfiles 和 Buildah 构建了容器映像。 但是如果你可以直接在 Kubernetes 上构建容器镜像呢? 有多种方法可以在 Kubernetes 内部运行 docker image build
命令,但这不是原生 Kubernetes 工具。 您必须依赖 Docker 守护程序来构建映像,并且它需要在集群中的 Pods 之一上运行。
一个名为 Kaniko 的工具允许您在现有 Kubernetes 集群上使用 Dockerfile 构建容器镜像。 在此步骤中,您将使用 Kaniko 使用 Dockerfile 构建容器映像。 然后,您将把这个镜像推送到 Docker Hub。
为了将您的图像推送到 Docker Hub,您需要将 Docker Hub 凭据传递给 Kaniko。 在上一步中,您登录到 Docker Hub 并使用您的登录凭据创建了一个 ~/.docker/config.json
文件。 让我们使用这个配置文件来创建一个 Kubernetes ConfigMap 对象来将凭证存储在 Kubernetes 集群中。 ConfigMap 对象用于存储配置参数,将它们与您的应用程序分离。
要使用 ~/.docker/config.json
文件创建名为 docker-config
的 ConfigMap,请运行以下命令:
sudo kubectl create configmap docker-config --from-file=$HOME/.docker/config.json
接下来,您可以在 ~/k8s-cicd-webinars/webinar1/2-kubernetes/1-Terraform/
目录中创建一个名为 pod-kaniko.yml
的 Pod 定义文件(尽管它可以放在任何地方)。
首先,确保您在 ~/k8s-cicd-webinars/webinar1/2-kubernetes/1-Terraform/
目录中:
cd ~/k8s-cicd-webinars/webinar1/2-kubernetes/1-Terraform/
创建 pod-kaniko.yml
文件:
nano pod-kaniko.yml
将以下内容添加到文件中,以指定部署 Pod 时会发生什么。 请务必将 Pod 的 args
字段中的 your-dockerhub-username
替换为您自己的 Docker Hub 用户名:
~/k8s-cicd-webinars/webinar1/2-kubernetes/1-Terraform/pod-kaniko.yaml
apiVersion: v1 kind: Pod metadata: name: kaniko spec: containers: - name: kaniko image: gcr.io/kaniko-project/executor:latest args: ["--dockerfile=./Dockerfile", "--context=/tmp/rsvpapp/", "--destination=docker.io/your-dockerhub-username/rsvpapp:kaniko", "--force" ] volumeMounts: - name: docker-config mountPath: /root/.docker/ - name: demo mountPath: /tmp/rsvpapp restartPolicy: Never initContainers: - image: python name: demo command: ["/bin/sh"] args: ["-c", "git clone https://github.com/do-community/rsvpapp-webinar1.git /tmp/rsvpapp"] volumeMounts: - name: demo mountPath: /tmp/rsvpapp restartPolicy: Never volumes: - name: docker-config configMap: name: docker-config - name: demo emptyDir: {}
此配置文件描述了部署 Pod 时会发生什么。 首先,Init 容器 将使用 Dockerfile https://github.com/do-community/rsvpapp-webinar1.git
将 Git 存储库克隆到名为 demo
的共享卷中。 Init 容器在应用程序容器之前运行,可用于运行不希望从应用程序容器运行的实用程序或其他任务。 然后,您的应用程序容器 kaniko
将使用 Dockerfile 构建映像,并使用您传递给 ConfigMap 卷 docker-config
的凭据将生成的映像推送到 Docker Hub。
要部署 kaniko
pod,请运行以下命令:
kubectl apply -f pod-kaniko.yml
您将看到以下确认信息:
Outputpod/kaniko created
获取 pod 列表:
kubectl get pods
您将看到以下列表:
OutputNAME READY STATUS RESTARTS AGE kaniko 0/1 Init:0/1 0 47s
等待几秒钟,然后再次运行 kubectl get pods
以更新状态:
kubectl get pods
您将看到以下内容:
OutputNAME READY STATUS RESTARTS AGE kaniko 1/1 Running 0 1m
最后,再次运行 kubectl get pods
以进行最终状态更新:
kubectl get pods
OutputNAME READY STATUS RESTARTS AGE kaniko 0/1 Completed 0 2m
此输出序列告诉您 Init 容器已运行,克隆了 demo
卷内的 GitHub 存储库。 之后,Kaniko 构建过程运行并最终完成。
查看 pod 的日志:
kubectl logs kaniko
您将看到以下输出:
Outputtime="2018-08-02T05:01:24Z" level=info msg="appending to multi args docker.io/your-dockerhub-username/rsvpapp:kaniko" time="2018-08-02T05:01:24Z" level=info msg="Downloading base image nkhare/python:alpine" . . . ime="2018-08-02T05:01:46Z" level=info msg="Taking snapshot of full filesystem..." time="2018-08-02T05:01:48Z" level=info msg="cmd: CMD" time="2018-08-02T05:01:48Z" level=info msg="Replacing CMD in config with [/bin/sh -c python rsvp.py]" time="2018-08-02T05:01:48Z" level=info msg="Taking snapshot of full filesystem..." time="2018-08-02T05:01:49Z" level=info msg="No files were changed, appending empty layer to config." 2018/08/02 05:01:51 mounted blob: sha256:bc4d09b6c77b25d6d3891095ef3b0f87fbe90621bff2a333f9b7f242299e0cfd 2018/08/02 05:01:51 mounted blob: sha256:809f49334738c14d17682456fd3629207124c4fad3c28f04618cc154d22e845b 2018/08/02 05:01:51 mounted blob: sha256:c0cb142e43453ebb1f82b905aa472e6e66017efd43872135bc5372e4fac04031 2018/08/02 05:01:51 mounted blob: sha256:606abda6711f8f4b91bbb139f8f0da67866c33378a6dcac958b2ddc54f0befd2 2018/08/02 05:01:52 pushed blob sha256:16d1686835faa5f81d67c0e87eb76eab316e1e9cd85167b292b9fa9434ad56bf 2018/08/02 05:01:53 pushed blob sha256:358d117a9400cee075514a286575d7d6ed86d118621e8b446cbb39cc5a07303b 2018/08/02 05:01:55 pushed blob sha256:5d171e492a9b691a49820bebfc25b29e53f5972ff7f14637975de9b385145e04 2018/08/02 05:01:56 index.docker.io/your-dockerhub-username/rsvpapp:kaniko: digest: sha256:831b214cdb7f8231e55afbba40914402b6c915ef4a0a2b6cbfe9efb223522988 size: 1243
从日志中,您可以看到 kaniko
容器从 Dockerfile 构建了映像并将其推送到您的 Docker Hub 帐户。
您现在可以拉取 Docker 映像。 请务必再次将 your-dockerhub-username
替换为您的 Docker Hub 用户名:
docker pull your-dockerhub-username/rsvpapp:kaniko
您将看到拉动的确认:
Outputkaniko: Pulling from your-dockerhub-username/rsvpapp c0cb142e4345: Pull complete bc4d09b6c77b: Pull complete 606abda6711f: Pull complete 809f49334738: Pull complete 358d117a9400: Pull complete 5d171e492a9b: Pull complete Digest: sha256:831b214cdb7f8231e55afbba40914402b6c915ef4a0a2b6cbfe9efb223522988 Status: Downloaded newer image for your-dockerhub-username/rsvpapp:kaniko
您现在已经成功地构建了一个 Kubernetes 集群并在集群中创建了新的镜像。 让我们继续讨论 Deployments 和 Services。
第 4 步 — 创建 Kubernetes 部署和服务
Kubernetes Deployments 允许你运行你的应用程序。 部署为您的 Pod 指定所需的状态,确保您的部署过程中的一致性。 在此步骤中,您将在 ~/k8s-cicd-webinars/webinar1/2-kubernetes/1-Terraform/
目录中创建一个名为 deployment.yml
的 Nginx 部署文件,以创建 Nginx 部署。
首先,打开文件:
nano deployment.yml
将以下配置添加到文件中以定义您的 Nginx 部署:
~/k8s-cicd-webinars/webinar1/2-kubernetes/1-Terraform/deployment.yml
apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment labels: app: nginx spec: replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.7.9 ports: - containerPort: 80
该文件定义了一个名为 nginx-deployment
的部署,它创建了三个 Pod,每个 Pod 在端口 80
上运行一个 nginx
容器。
要部署部署,请运行以下命令:
kubectl apply -f deployment.yml
您将看到 Deployment 已创建的确认信息:
Outputdeployment.apps/nginx-deployment created
列出您的部署:
kubectl get deployments
OutputNAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE nginx-deployment 3 3 3 3 29s
您可以看到 nginx-deployment
部署已创建,并且所需的 Pod 数量和当前数量相同:3
。
要列出 Deployment 创建的 Pod,请运行以下命令:
kubectl get pods
OutputNAME READY STATUS RESTARTS AGE kaniko 0/1 Completed 0 9m nginx-deployment-75675f5897-nhwsp 1/1 Running 0 1m nginx-deployment-75675f5897-pxpl9 1/1 Running 0 1m nginx-deployment-75675f5897-xvf4f 1/1 Running 0 1m
您可以从此输出中看到所需数量的 Pod 正在运行。
要在内部和外部公开应用程序部署,您需要创建一个名为 Service 的 Kubernetes 对象。 每个服务指定一个 ServiceType,它定义了服务的公开方式。 在此示例中,我们将使用 NodePort ServiceType,它将服务暴露在每个节点上的静态端口上。
为此,在 ~/k8s-cicd-webinars/webinar1/2-kubernetes/1-Terrafrom/
目录中创建一个文件 service.yml
:
nano service.yml
添加以下内容以定义您的服务:
~/k8s-cicd-webinars/webinar1/2-kubernetes/1-Terrafrom/service.yml
kind: Service apiVersion: v1 metadata: name: nginx-service spec: selector: app: nginx type: NodePort ports: - protocol: TCP port: 80 targetPort: 80 nodePort: 30111
这些设置定义了服务 nginx-service
,并指定它将以 Pod 上的端口 80
为目标。 nodePort
定义应用程序将接受外部流量的端口。
要部署服务,请运行以下命令:
kubectl apply -f service.yml
您将看到一个确认:
Outputservice/nginx-service created
列出服务:
kubectl get service
您将看到以下列表:
OutputNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 5h nginx-service NodePort 10.100.98.213 <none> 80:30111/TCP 7s
您的服务 nginx-service
暴露在端口 30111
上,您现在可以在任何节点的公共 IP 上访问它。 例如,导航到 http://node_1_ip:30111
或 http://node_2_ip:30111
应该会将您带到 Nginx 的标准欢迎页面。
一旦你测试了部署,你可以清理部署和服务:
kubectl delete deployment nginx-deployment kubectl delete service nginx-service
这些命令将删除您创建的部署和服务。
现在您已经使用了部署和服务,让我们继续创建自定义资源。
第 5 步 — 在 Kubernetes 中创建自定义资源
Kubernetes 提供有限但可用于生产的功能和特性。 但是,可以使用其 自定义资源 功能扩展 Kubernetes 的产品。 在 Kubernetes 中,resource 是 Kubernetes API 中的一个端点,用于存储 API objects 的集合。 例如,一个 Pod 资源包含一组 Pod 对象。 使用自定义资源,您可以为网络、存储等添加自定义产品。 这些添加可以在任何时候创建或删除。
除了创建自定义对象外,您还可以在控制平面中使用 Kubernetes Controller 组件的子控制器来确保对象的当前状态等于所需状态。 Kubernetes 控制器具有用于指定对象的子控制器。 例如,ReplicaSet 是一个子控制器,可确保所需的 Pod 数量保持一致。 当您将自定义资源与控制器结合使用时,您将获得一个真正的 声明性 API,它允许您指定所需的资源状态。
在此步骤中,您将创建自定义资源和相关对象。
要创建自定义资源,首先在 ~/k8s-cicd-webinars/webinar1/2-kubernetes/1-Terrafrom/
目录中创建一个名为 crd.yml
的文件:
nano crd.yml
添加以下自定义资源定义 (CRD):
~/k8s-cicd-webinars/webinar1/2-kubernetes/1-Terrafrom/crd.yml
apiVersion: apiextensions.k8s.io/v1beta1 kind: CustomResourceDefinition metadata: name: webinars.digitalocean.com spec: group: digitalocean.com version: v1 scope: Namespaced names: plural: webinars singular: webinar kind: Webinar shortNames: - wb
要部署 crd.yml
中定义的 CRD,请运行以下命令:
kubectl create -f crd.yml
您将看到资源已创建的确认信息:
Outputcustomresourcedefinition.apiextensions.k8s.io/webinars.digitalocean.com created
crd.yml
文件创建了一个新的 RESTful 资源路径:/apis/digtialocean.com/v1/namespaces/*/webinars
。 您现在可以使用 webinars
、webinar
、Webinar
和 wb
来引用您的对象,正如您在 names
部分中列出的那样CustomResourceDefinition
。 您可以使用以下命令检查 RESTful 资源:
kubectl proxy & curl 127.0.0.1:8001/apis/digitalocean.com
注意: 如果您按照先决条件中的初始服务器设置指南进行操作,那么您需要允许端口 8001
的流量才能进行此测试。 使用以下命令启用到此端口的流量:
sudo ufw allow 8001
您将看到以下输出:
OutputHTTP/1.1 200 OK Content-Length: 238 Content-Type: application/json Date: Fri, 03 Aug 2018 06:10:12 GMT { "apiVersion": "v1", "kind": "APIGroup", "name": "digitalocean.com", "preferredVersion": { "groupVersion": "digitalocean.com/v1", "version": "v1" }, "serverAddressByClientCIDRs": null, "versions": [ { "groupVersion": "digitalocean.com/v1", "version": "v1" } ] }
接下来,通过打开一个名为 webinar.yml
的文件来创建使用新自定义资源的对象:
nano webinar.yml
添加以下内容以创建对象:
~/k8s-cicd-webinars/webinar1/2-kubernetes/1-Terrafrom/webinar.yml
apiVersion: "digitalocean.com/v1" kind: Webinar metadata: name: webinar1 spec: name: webinar image: nginx
运行以下命令将这些更改推送到集群:
kubectl apply -f webinar.yml
您将看到以下输出:
Outputwebinar.digitalocean.com/webinar1 created
您现在可以使用 kubectl
管理您的 webinar
对象。 例如:
kubectl get webinar
OutputNAME CREATED AT webinar1 21s
您现在有一个名为 webinar1
的对象。 如果有一个控制器,它就会拦截对象的创建并执行任何定义的操作。
删除自定义资源定义
要删除自定义资源的所有对象,请使用以下命令:
kubectl delete webinar --all
你会看见:
Outputwebinar.digitalocean.com "webinar1" deleted
删除自定义资源本身:
kubectl delete crd webinars.digitalocean.com
您将看到已删除的确认信息:
Outputcustomresourcedefinition.apiextensions.k8s.io "webinars.digitalocean.com" deleted
删除后,您将无法访问您之前使用 curl
命令测试的 API 端点。
本序列介绍了如何在不修改 Kubernetes 代码的情况下扩展 Kubernetes 功能。
第 6 步 — 删除 Kubernetes 集群
要销毁 Kubernetes 集群本身,您可以使用 ~/k8s-cicd-webinars/webinar1/2-kubernetes/1-Terrafrom
文件夹中的 destroy.sh
脚本。 确保您在此目录中:
cd ~/k8s-cicd-webinars/webinar1/2-kubernetes/1-Terrafrom
运行脚本:
./destroy.sh
通过运行此脚本,您将允许 Terraform 与 DigitalOcean API 通信并删除集群中的服务器。
结论
在本教程中,您使用了不同的工具来创建容器映像。 使用这些图像,您可以在任何环境中创建容器。 您还使用 Terraform 设置了 Kubernetes 集群,并创建了部署和服务对象来部署和公开您的应用程序。 此外,您通过定义自定义资源扩展了 Kubernetes 的功能。
您现在拥有在 Kubernetes 上构建 CI/CD 环境的坚实基础,我们将在以后的文章中对此进行探讨。