网络研讨会系列:使用 Kubernetes 进行 CI/CD 的基石

美元(注)

网友系列

本文补充了一系列关于使用 Kubernetes 进行 CI/CD 的网络研讨会(https://go.digitalocean.com/cicd-on-k8s)。该系列讨论如何采用云原生方法来构建、测试和部署应用程序,涵盖发布管理、云原生工具、服务网格和可与 Kubernetes 一起使用的 CI/CD 工具。

本教程包括从系列的第一个会话的概念和命令,构建块与Kubernetes做CI/CD。

[youtube XxxlmkKdw6M 480 854 ]

介绍

如果你开始使用 containers,你可能会想知道如何自动化构建,测试和部署。通过采用 Cloud Native的方法来处理这些流程,你可以利用正确的基础设施 API 以自动地包装和部署应用程序。

自动化的两大构件包括 container imagescontainer orchestrators. 在过去的一年里,Kubernetes(https://kubernetes.io/)已成为集装箱管制的默认选择。

  • 使用 Docker, BuildahKaniko构建容器图像。
  • 使用 Terraform设置 Kubernetes 集群,并创建 DeploymentsServices.
  • 使用 Custom Resources 扩展 Kubernetes 集群的功能。

到本教程结束时,您将有用 Docker、Buildah 和 Kaniko 构建的容器图像,以及具有部署、服务和自定义资源的 Kubernetes 集群。

本系列的未来文章将涵盖相关主题:Kubernetes的包管理、Jenkins X(https://jenkins-x.io/)和Spinnaker(https://www.spinnaker.io/)等CI/CD工具、服务网格和GitOps。

前提条件

請遵循我們的 初始伺服器設定與Ubuntu 16.04])指導程式

步骤 1 — 使用 Docker 和 Buildah 构建集装箱图像

集装箱图像是一个具有自己的应用程序代码、运行时间和依赖性的独立实体,可用于创建和运行集装箱. 您可以使用不同的工具创建集装箱图像,在此步骤中您将使用两个集装箱:Docker 和 Buildah。

用 Dockerfiles 构建集装箱图像

Docker 会通过从 Dockerfile 读取指示来自动构建您的集装箱图像,这是一个包含组装集装箱图像所需的命令的文本文件。使用docker image build命令,您可以创建一个自动构建,该命令将执行 Dockerfile 中提供的命令行指令。

通常情况下,您将为您的 Dockerfile 创建一个项目文件夹,并构建背景。

1mkdir demo
2cd demo

接下来,在Demo文件夹中创建一个Dockerfile:

1nano Dockerfile

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

 1[label ~/demo/Dockerfile]
 2FROM ubuntu:16.04
 3
 4LABEL MAINTAINER neependra@cloudyuga.guru
 5
 6RUN apt-get update \
 7    && apt-get install -y nginx \
 8    && apt-get clean \
 9    && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* \
10    && echo "daemon off;" >> /etc/nginx/nginx.conf
11
12EXPOSE 80
13CMD ["nginx"]

此 Dockerfile 由一组指令组成,将构建一个图像以运行 Nginx. 在构建过程中,ubuntu:16.04 将作为基本图像,并将安装nginx包。

接下来,您将使用docker image build命令构建容器图像,使用当前目录(.)作为构建背景。

1sudo docker image build -t nkhare/nginx:latest .

您将看到以下结果:

 1[secondary_label Output]
 2Sending build context to Docker daemon 49.25MB
 3Step 1/5 : FROM ubuntu:16.04
 4 ---> 7aa3602ab41e
 5Step 2/5 : MAINTAINER neependra@cloudyuga.guru
 6 ---> Using cache
 7 ---> 552b90c2ff8d
 8Step 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
 9 ---> Using cache
10 ---> 6bea966278d8
11Step 4/5 : EXPOSE 80
12 ---> Using cache
13 ---> 8f1c4281309e
14Step 5/5 : CMD ["nginx"]
15 ---> Using cache
16 ---> f545da818f47
17Successfully built f545da818f47
18Successfully tagged nginx:latest

您的图像现在已构建,您可以使用以下命令列出您的 Docker 图像:

1docker image ls
1[secondary_label Output]
2REPOSITORY TAG IMAGE ID CREATED SIZE
3nkhare/nginx latest 4073540cbcec 3 seconds ago 171MB
4ubuntu 16.04 7aa3602ab41e 11 days ago

您现在可以使用nkhare/nginx:latest图像来创建容器。

建筑集装箱图像与项目原子建筑

Buildah 是一个 CLI 工具,由 Project Atomic开发,用于快速构建符合 Open Container Initiative (OCI)_的图像。

Buildah 可以从工作容器或从 Dockerfile 创建图像,它可以完全在用户空间中构建图像,而无需使用 Docker 示范,并且可以执行图像操作,如构建,列表,标签

要安装 Buildah,您将需要所需的依赖性,包括工具,以便您管理包和包安全,等等。

1cd
2 sudo apt-get install software-properties-common
3 sudo add-apt-repository ppa:alexlarsson/flatpak
4 sudo add-apt-repository ppa:gophers/archive
5 sudo apt-add-repository ppa:projectatomic/ppa
6 sudo apt-get update
7 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:

1sudo apt-get update
2sudo curl -O https://storage.googleapis.com/golang/go1.8.linux-amd64.tar.gz
3sudo tar -xvf go1.8.linux-amd64.tar.gz
4sudo mv go /usr/local
5sudo echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.profile
6source ~/.profile
7go version

您将看到以下输出,表明安装成功:

1[secondary_label Output]
2go version go1.8 linux/amd64

您现在可以获得构建的源代码来创建其包,以及runc二进制。

运行以下命令来安装runcbuildah:

1mkdir ~/buildah
2cd ~/buildah
3export GOPATH=`pwd`
4git clone https://github.com/containers/buildah ./src/github.com/containers/buildah
5cd ./src/github.com/containers/buildah
6make runc all TAGS="apparmor seccomp"
7sudo cp ~/buildah/src/github.com/opencontainers/runc/runc /usr/bin/.
8sudo apt install buildah

接下来,创建 /etc/containers/registries.conf 文件来配置您的集装箱注册表:

1sudo nano /etc/containers/registries.conf

将以下内容添加到文件中,以指定您的注册表:

 1[label /etc/containers/registries.conf]
 2
 3# This is a system-wide configuration file used to
 4# keep track of registries for various container backends.
 5# It adheres to TOML format and does not support recursive
 6# lists of registries.
 7
 8# The default location for this configuration file is /etc/containers/registries.conf.
 9
10# The only valid categories are: 'registries.search', 'registries.insecure',
11# and 'registries.block'.
12
13[registries.search]
14registries = ['docker.io', 'registry.fedoraproject.org', 'quay.io', 'registry.access.redhat.com', 'registry.centos.org']
15
16# If you need to access insecure registries, add the registry's fully-qualified name.
17# An insecure registry is one that does not have a valid SSL certificate or only does HTTP.
18[registries.insecure]
19registries = []
20
21# If you need to block pull access from a registry, uncomment the section below
22# and add the registries fully-qualified name.
23#
24# Docker only
25[registries.block]
26registries = []

registries.conf配置文件指定哪些注册表应该在填写不包含注册表或域部分的图像名时查询。

现在运行以下命令来构建图像,使用 https://github.com/do-community/rsvpapp-webinar1 存储库作为构建背景。

1sudo buildah build-using-dockerfile -t rsvpapp:buildah github.com/do-community/rsvpapp-webinar1

此命令会创建一个名为 rsvpapp:buildah 的图像,从可用的 Dockerfille 在 https://github.com/do-community/rsvpapp-webinar1 存储库中。

要列出图像,请使用以下命令:

1sudo buildah images

您将看到以下结果:

1[secondary_label Output]
2IMAGE ID IMAGE NAME CREATED AT SIZE
3b0c552b8cf64 docker.io/teamcloudyuga/python:alpine Sep 30, 2016 04:39 95.3 MB
422121fd251df localhost/rsvpapp:buildah Sep 11, 2018 14:34 114 MB

其中一个图像是‘localhost/rsvpapp:buildah’,你刚刚创建的,另一个图像是‘docker.io/teamcloudyuga/python:alpine’,是Dockerfile的基本图像。

一旦你建立了图像,你可以将其推到Docker Hub。这将允许你将其存储用于未来使用。你首先需要从命令行登录到你的Docker Hub帐户:

1docker login -u your-dockerhub-username -p your-dockerhub-password

一旦登录成功,您将收到一个文件, ~/.docker/config.json,其中包含您的 Docker Hub 凭据。

例如,如果您想按一下您刚刚创建的图像,您可以运行以下命令,引用authfile和要按的图像:

1sudo buildah push --authfile ~/.docker/config.json rsvpapp:buildah docker://your-dockerhub-username/rsvpapp:buildah

您还可以使用以下命令将结果的图像推到本地 Docker 示威者:

1sudo buildah push rsvpapp:buildah docker-daemon:rsvpapp:buildah

最后,看看您创建的 Docker 图像:

1sudo docker image ls
1[secondary_label Output]
2REPOSITORY TAG IMAGE ID CREATED SIZE
3rsvpapp buildah 22121fd251df 4 minutes ago 108MB
4nkhare/nginx latest 01f0982d91b8 17 minutes ago 172MB
5ubuntu 16.04 b9e15a5d1e1a 5 days ago 115MB

正如预期的那样,你现在应该看到一个新的图像,‘rsvpapp:buildah’,它已经被导出使用‘buildah’。

您现在有了使用两个不同的工具,Docker 和 Buildah,构建集装箱图像的经验,让我们继续讨论如何使用 Kubernetes 设置集装箱集群。

步骤 2 — 使用 kubeadm 和 Terraform 在 DigitalOcean 上设置 Kubernetes 集群

若要了解有关如何使用 kubeadm设置 Kubernetes 的更多信息,例如,请参阅 Ubuntu 18.04 上使用 Kubeadm 创建 Kubernetes 集群

由于本教程系列讨论采用云原生方法来开发应用程序,我们将在设置集群时应用这种方法,具体来说,我们将使用 kubeadm 和 Terraform来自动化我们的集群创建,这是一种简化创建和更改基础设施的工具。

使用您的个人访问代码,您将连接到DigitalOcean与Terraform提供3个服务器,您将在这些 VM 中运行kubeadm命令,创建一个包含一个主节点和两个工人的3节点Kubernetes集群。

在您的 Ubuntu 服务器上,创建一对 SSH 密钥,这将允许无密码登录您的 VM:

1ssh-keygen -t rsa

您将看到以下结果:

1[secondary_label Output]
2Generating public/private rsa key pair.
3Enter file in which to save the key (~/.ssh/id_rsa):

ENTER,将密钥对保存到您的主目录中的~/.ssh目录中,或输入另一个目的地。

接下来,你会看到以下快递:

1[secondary_label Output]
2Enter passphrase (empty for no passphrase):

在这种情况下,按ENTER没有密码,以启用无密码登录到您的节点。

您将看到确认您的密钥对已经创建:

 1[secondary_label Output]
 2Your identification has been saved in ~/.ssh/id_rsa.
 3Your public key has been saved in ~/.ssh/id_rsa.pub.
 4The key fingerprint is:
 5SHA256:lCVaexVBIwHo++NlIxccMW5b6QAJa+ZEr9ogAElUFyY root@3b9a273f18b5
 6The key's randomart image is:
 7+---[RSA 2048]----+
 8|++.E ++o=o*o*o   |
 9|o   +..=.B = o   |
10|.    .* = * o    |
11| .   =.o + *     |
12|  . . o.S + .    |
13|   . +.    .     |
14|    . ... =      |
15|        o= .     |
16|       ...       |
17+----[SHA256]-----+

通过运行以下命令获取您的公共密钥,该命令将在您的终端中显示:

1cat ~/.ssh/id_rsa.pub

将此密钥添加到您的 DigitalOcean 帐户中,按照 这些指令

接下来,安装Terraform:

1sudo apt-get update
2sudo apt-get install unzip
3wget https://releases.hashicorp.com/terraform/0.11.7/terraform_0.11.7_linux_amd64.zip
4unzip terraform_0.11.7_linux_amd64.zip
5sudo mv terraform /usr/bin/.
6terraform version

您将看到确认您的 Terraform 安装的输出:

1[secondary_label Output]
2Terraform v0.11.7

接下来,运行以下命令来安装kubectl,一个将与您的Kubernetes集群通信的CLI工具,并在您的用户主目录中创建一个~/.kube目录:

1sudo apt-get install apt-transport-https
2curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
3sudo touch /etc/apt/sources.list.d/kubernetes.list 
4echo "deb http://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee -a /etc/apt/sources.list.d/kubernetes.list
5sudo apt-get update
6sudo apt-get install kubectl
7mkdir -p ~/.kube

创建 ~/.kube 目录将允许您将配置文件复制到这个位置. 在本节晚些时候运行 Kubernetes 设置脚本后,您将这样做。

接下来,克隆本教程的样本项目存储库,其中包含设置基础设施的Terraform脚本:

1git clone https://github.com/do-community/k8s-cicd-webinars.git

进入 Terrafrom 脚本目录:

1cd k8s-cicd-webinars/webinar1/2-kubernetes/1-Terraform/

获取您的 SSH 公共密钥的指纹:

1ssh-keygen -E md5 -lf ~/.ssh/id_rsa.pub | awk '{print $2}'

您将看到输出如下,突出部分代表您的密钥:

1[secondary_label Output]
2MD5:dd:d1:b7:0f:6d:30:c0:be:ed:ae:c7:b9:b8:4a:df:5e

请记住,你的密钥将与这里显示的不同。

将指纹保存到一个环境变量,以便Terraform可以使用它:

1export FINGERPRINT=dd:d1:b7:0f:6d:30:c0:be:ed:ae:c7:b9:b8:4a:df:5e

接下来,导出您的 DO 个人访问令牌:

1export TOKEN=your-do-access-token

现在让我们看看 ~/k8s-cicd-webinars/webinar1/2-kubernetes/1-Terraform/ 项目目录:

1ls
1[secondary_label Output]
2cluster.tf destroy.sh files outputs.tf provider.tf script.sh

此文件夹包含使用 Terraform 部署您的 Kubernetes 集群所需的脚本和配置文件。

运行script.sh脚本来触发Kubernetes集群设置:

1./script.sh

当脚本执行完成时,kubectl将配置为使用您创建的Kubernetes集群。

列出使用kubectl get nodes的群集节点:

1kubectl get nodes
1[secondary_label Output]
2NAME STATUS ROLES AGE VERSION
3k8s-master-node Ready master 2m v1.10.0
4k8s-worker-node-1 Ready     <none>    1m v1.10.0
5k8s-worker-node-2 Ready     <none>    57s v1.10.0

你现在有一个主和两个工人节点在准备状态。

有了 Kubernetes 集群的设置,您现在可以探索构建容器图像的另一个选项: Kaniko from Google

步骤 3 — 使用 Kaniko 构建集装箱图像

在本教程中早些时候,您使用 Dockerfiles 和 Buildah 构建了容器图像,但如果您可以直接在 Kubernetes 上构建容器图像,有没有办法在 Kubernetes 中运行docker image build命令,但这不是本地的 Kubernetes 工具。

一个名为Kaniko的工具允许您在现有 Kubernetes 集群上使用 Dockerfile 构建容器图像. 在此步骤中,您将使用 Kaniko 构建使用 Dockerfile 的容器图像。

为了将您的图像推到 Docker Hub,您需要将您的 Docker Hub 凭据传递给 Kaniko. 在之前的步骤中,您已登录到 Docker Hub,并创建了一个 ~/.docker/config.json 文件,并使用您的登录凭据。让我们使用此配置文件创建一个 Kubernetes ConfigMap 对象来存储 Kubernetes 集群中的凭据。

若要使用「~/.docker/config.json」文件创建名为「docker-config」的 ConfigMap,请执行以下命令:

1sudo 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/ 目录中:

1cd ~/k8s-cicd-webinars/webinar1/2-kubernetes/1-Terraform/

创建pod-kaniko.yml文件:

1nano pod-kaniko.yml

将下列内容添加到文件中,以指定在部署 Pod 时会发生什么。

 1[label ~/k8s-cicd-webinars/webinar1/2-kubernetes/1-Terraform/pod-kaniko.yaml]
 2apiVersion: v1
 3kind: Pod
 4metadata:
 5  name: kaniko
 6spec:
 7  containers:
 8  - name: kaniko
 9    image: gcr.io/kaniko-project/executor:latest
10    args: ["--dockerfile=./Dockerfile",
11            "--context=/tmp/rsvpapp/",
12            "--destination=docker.io/your-dockerhub-username/rsvpapp:kaniko",
13            "--force" ]
14    volumeMounts:
15      - name: docker-config
16        mountPath: /root/.docker/
17      - name: demo
18        mountPath: /tmp/rsvpapp
19  restartPolicy: Never
20  initContainers:
21    - image: python
22      name: demo
23      command: ["/bin/sh"]
24      args: ["-c", "git clone https://github.com/do-community/rsvpapp-webinar1.git /tmp/rsvpapp"] 
25      volumeMounts:
26      - name: demo
27        mountPath: /tmp/rsvpapp
28  restartPolicy: Never
29  volumes:
30    - name: docker-config
31      configMap:
32        name: docker-config
33    - name: demo
34      emptyDir: {}

此配置文件描述了当您的 Pod 部署时会发生什么。 首先,Init 容器(https://kubernetes.io/docs/concepts/workloads/pods/init-containers/)会将 Git 存储库与 Dockerfile, https://github.com/do-community/rsvpapp-webinar1.git,克隆成一个名为 demo 的共享卷。 Init 容器在应用容器之前运行,可以用来运行实用程序或其他任务,这些任务不宜从您的应用容器运行。 您的应用容器, kaniko,然后将使用 Dockerfile构建图像,并将结果的图像推到 Docker Hub,使用您转移到 ConfigMap 卷 docker-config的凭证。

要部署kanikopod,请运行以下命令:

1kubectl apply -f pod-kaniko.yml

您将看到以下确认:

1[secondary_label Output]
2pod/kaniko created

获取 pods 的列表:

1kubectl get pods

你会看到以下列表:

1[secondary_label Output]
2NAME READY STATUS RESTARTS AGE
3kaniko 0/1 Init:0/1 0 47s

等待几秒钟,然后再次运行kubectl get pods以获取状态更新:

1kubectl get pods

你会看到以下:

1[secondary_label Output]
2NAME READY STATUS RESTARTS AGE
3kaniko 1/1 Running 0 1m

最后,再次运行kubectl get pods以获取最终状态更新:

1kubectl get pods
1[secondary_label Output]
2NAME READY STATUS RESTARTS AGE
3kaniko 0/1 Completed 0 2m

这个输出序列告诉你,Init容器运行了,克隆了GitHub存储库在演示卷中。

查看 Pod 的日志:

1kubectl logs kaniko

您将看到以下结果:

 1[secondary_label Output]
 2time="2018-08-02T05:01:24Z" level=info msg="appending to multi args docker.io/your-dockerhub-username/rsvpapp:kaniko"
 3time="2018-08-02T05:01:24Z" level=info msg="Downloading base image nkhare/python:alpine"
 4.
 5.
 6.
 7ime="2018-08-02T05:01:46Z" level=info msg="Taking snapshot of full filesystem..."
 8time="2018-08-02T05:01:48Z" level=info msg="cmd: CMD"
 9time="2018-08-02T05:01:48Z" level=info msg="Replacing CMD in config with [/bin/sh -c python rsvp.py]"
10time="2018-08-02T05:01:48Z" level=info msg="Taking snapshot of full filesystem..."
11time="2018-08-02T05:01:49Z" level=info msg="No files were changed, appending empty layer to config."
122018/08/02 05:01:51 mounted blob: sha256:bc4d09b6c77b25d6d3891095ef3b0f87fbe90621bff2a333f9b7f242299e0cfd
132018/08/02 05:01:51 mounted blob: sha256:809f49334738c14d17682456fd3629207124c4fad3c28f04618cc154d22e845b
142018/08/02 05:01:51 mounted blob: sha256:c0cb142e43453ebb1f82b905aa472e6e66017efd43872135bc5372e4fac04031
152018/08/02 05:01:51 mounted blob: sha256:606abda6711f8f4b91bbb139f8f0da67866c33378a6dcac958b2ddc54f0befd2
162018/08/02 05:01:52 pushed blob sha256:16d1686835faa5f81d67c0e87eb76eab316e1e9cd85167b292b9fa9434ad56bf
172018/08/02 05:01:53 pushed blob sha256:358d117a9400cee075514a286575d7d6ed86d118621e8b446cbb39cc5a07303b
182018/08/02 05:01:55 pushed blob sha256:5d171e492a9b691a49820bebfc25b29e53f5972ff7f14637975de9b385145e04
192018/08/02 05:01:56 index.docker.io/your-dockerhub-username/rsvpapp:kaniko: digest: sha256:831b214cdb7f8231e55afbba40914402b6c915ef4a0a2b6cbfe9efb223522988 size: 1243

从日志中,您可以看到kaniko容器从Dockerfile中构建了图像,并将其推到您的Docker Hub帐户。

请确保再次用您的 Docker Hub 用户名替换您的dockerhub 用户名:

1docker pull your-dockerhub-username/rsvpapp:kaniko

您将看到引导的确认:

 1[secondary_label Output]
 2kaniko: Pulling from your-dockerhub-username/rsvpapp
 3c0cb142e4345: Pull complete 
 4bc4d09b6c77b: Pull complete 
 5606abda6711f: Pull complete 
 6809f49334738: Pull complete 
 7358d117a9400: Pull complete 
 85d171e492a9b: Pull complete 
 9Digest: sha256:831b214cdb7f8231e55afbba40914402b6c915ef4a0a2b6cbfe9efb223522988
10Status: Downloaded newer image for your-dockerhub-username/rsvpapp:kaniko

您现在已经成功构建了一个Kubernetes集群,并从集群内部创建了新图像。

步骤 4 – 创建 Kubernetes 部署和服务

Kubernetes Deployments 允许您运行您的应用程序。Deployments 会为您的 Pods 指定所需的状态,确保在您的部署中保持一致性。 在此步骤中,您将在 ~/k8s-cicd-webinars/webinar1/2-kubernetes/1-Terraform/ 目录中创建一个名为 `deployment.yml’ 的 Nginx部署文件,以创建一个 Nginx 部署。

首先,打开文件:

1nano deployment.yml

将下列配置添加到文件中,以定义您的 Nginx 部署:

 1[label ~/k8s-cicd-webinars/webinar1/2-kubernetes/1-Terraform/deployment.yml]
 2apiVersion: apps/v1
 3kind: Deployment
 4metadata:
 5  name: nginx-deployment
 6  labels:
 7    app: nginx
 8spec:
 9  replicas: 3
10  selector:
11    matchLabels:
12      app: nginx
13  template:
14    metadata:
15      labels:
16        app: nginx
17    spec:
18      containers:
19      - name: nginx
20        image: nginx:1.7.9
21        ports:
22        - containerPort: 80

该文件定义了一个名为nginx-deployment的部署,它会创建三个 pods,每一个在端口80上运行一个nginx容器。

要部署部署,请运行以下命令:

1kubectl apply -f deployment.yml

您将看到确认部署已创建的消息:

1[secondary_label Output]
2deployment.apps/nginx-deployment created

列出你的部署:

1kubectl get deployments
1[secondary_label Output]
2NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
3nginx-deployment 3 3 3 3 29s

您可以看到nginx-deployment部署已经创建,所需和当前的Pods数目是相同的:3

要列出部署创建的Pods,请运行以下命令:

1kubectl get pods
1[secondary_label Output]
2NAME READY STATUS RESTARTS AGE
3kaniko 0/1 Completed 0 9m
4nginx-deployment-75675f5897-nhwsp 1/1 Running 0 1m
5nginx-deployment-75675f5897-pxpl9 1/1 Running 0 1m
6nginx-deployment-75675f5897-xvf4f 1/1 Running 0 1m

您可以从此输出中看到所需数量的Pod正在运行。

要将应用程序部署暴露在内部和外部,您需要创建一个名为 Service 的 Kubernetes 对象. 每个服务都指定一个 ServiceType,该类型定义了该服务的暴露方式。

要做到这一点,请在 ~/k8s-cicd-webinars/webinar1/2-kubernetes/1-Terrafrom/ 目录中创建一个文件 service.yml:

1nano service.yml

添加以下内容来定义您的服务:

 1[label ~/k8s-cicd-webinars/webinar1/2-kubernetes/1-Terrafrom/service.yml]
 2kind: Service
 3apiVersion: v1
 4metadata:
 5  name: nginx-service
 6spec:
 7  selector:
 8    app: nginx
 9  type: NodePort
10  ports:
11  - protocol: TCP
12    port: 80
13    targetPort: 80
14    nodePort: 30111

这些设置定义服务nginx-service,并指定它将针对您的Pod上的端口80

要部署服务,运行以下命令:

1kubectl apply -f service.yml

你会看到一个确认:

1[secondary_label Output]
2service/nginx-service created

列出服务:

1kubectl get service

你会看到以下列表:

1[secondary_label Output]
2NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S)        AGE
3kubernetes ClusterIP 10.96.0.1       <none>        443/TCP 5h
4nginx-service NodePort 10.100.98.213   <none>        80:30111/TCP 7s

您的服务nginx-service在端口30111上曝光,您现在可以访问该节点的任何公共IP。例如,导航到http://node_1_ip:30111http://node_2_ip:30111应该带您到Nginx的标准欢迎页面。

测试部署后,您可以清理部署和服务:

1kubectl delete deployment nginx-deployment
2kubectl delete service nginx-service

这些命令会删除您创建的部署和服务。

现在您已经使用了部署和服务,让我们继续创建自定义资源。

步骤 5 – 在 Kubernetes 中创建自定义资源

Kubernetes 提供有限但可生产的功能和功能,但使用其 自定义资源功能可以扩展 Kubernetes 提供的功能。在 Kubernetes 中, resource 是 Kubernetes API 中的一个端点,它存储了 API objects 集合。

除了创建自定义对象外,您还可以在控制层中使用 Kubernetes _Controller 组件的子控制器,以确保对象的当前状态等同于所需状态。 Kubernetes Controller 对指定对象有子控制器.例如, ReplicaSet是一个子控制器,可确保所需的 Pod 数目保持一致。

在此步骤中,您将创建自定义资源和相关对象。

要创建自定义资源,请先在 ~/k8s-cicd-webinars/webinar1/2-kubernetes/1-Terrafrom/ 目录中创建一个名为 crd.yml 的文件:

1nano crd.yml

添加以下自定义资源定义(CRD):

 1[label ~/k8s-cicd-webinars/webinar1/2-kubernetes/1-Terrafrom/crd.yml]
 2apiVersion: apiextensions.k8s.io/v1beta1
 3kind: CustomResourceDefinition
 4metadata:
 5  name: webinars.digitalocean.com
 6spec:
 7  group: digitalocean.com
 8  version: v1
 9  scope: Namespaced
10  names:
11    plural: webinars
12    singular: webinar
13    kind: Webinar
14    shortNames:
15    - wb

要部署在「crd.yml」中定义的CRD,请运行以下命令:

1kubectl create -f crd.yml

您将看到确认该资源已创建的信息:

1[secondary_label Output]
2customresourcedefinition.apiextensions.k8s.io/webinars.digitalocean.com created

「crd.yml」文件创建了一个新的 RESTful 资源路径: /apis/digtialocean.com/v1/namespaces/*/webinars. 现在您可以使用 webinarswebinarWebinarwb 参考您的对象,如您在 'CustomResourceDefinition' 的 '名称' 部分列出了它们。

1kubectl proxy & curl 127.0.0.1:8001/apis/digitalocean.com

<$>[注] 注: 如果您在前提条件中遵循初始服务器设置指南,则需要允许流量到端口 8001才能使此测试工作。

1sudo ufw allow 8001

美元

您将看到以下结果:

 1[secondary_label Output]
 2HTTP/1.1 200 OK
 3Content-Length: 238
 4Content-Type: application/json
 5Date: Fri, 03 Aug 2018 06:10:12 GMT
 6
 7{
 8    "apiVersion": "v1", 
 9    "kind": "APIGroup", 
10    "name": "digitalocean.com", 
11    "preferredVersion": {
12        "groupVersion": "digitalocean.com/v1", 
13        "version": "v1"
14    }, 
15    "serverAddressByClientCIDRs": null, 
16    "versions": [
17        {
18            "groupVersion": "digitalocean.com/v1", 
19            "version": "v1"
20        }
21    ]
22}

接下来,通过打开名为webinar.yml的文件来创建用于新自定义资源的对象:

1nano webinar.yml

添加以下内容来创建对象:

1[label ~/k8s-cicd-webinars/webinar1/2-kubernetes/1-Terrafrom/webinar.yml]
2apiVersion: "digitalocean.com/v1"
3kind: Webinar
4metadata:
5  name: webinar1
6spec:
7  name: webinar
8  image: nginx

运行以下命令,将这些更改推到集群:

1kubectl apply -f webinar.yml

您将看到以下结果:

1[secondary_label Output]
2webinar.digitalocean.com/webinar1 created

您现在可以使用kubectl来管理您的Webinar对象,例如:

1kubectl get webinar
1[secondary_label Output]
2NAME CREATED AT
3webinar1 21s

你现在有一个名为webinar1的对象,如果有一个控制器,它会拦截对象创建并执行任何定义的操作。

删除自定义资源定义

若要删除您的自定义资源的所有对象,请使用以下命令:

1kubectl delete webinar --all

你会看到:

1[secondary_label Output]
2webinar.digitalocean.com "webinar1" deleted

删除自定义资源:

1kubectl delete crd webinars.digitalocean.com

您将看到确认已被删除的信件:

1[secondary_label Output]
2customresourcedefinition.apiextensions.k8s.io "webinars.digitalocean.com" deleted

删除后,您将无法访问您之前使用弯曲命令测试的 API 终端。

此序列介绍了如何在不修改 Kubernetes 代码的情况下扩展 Kubernetes 功能。

步骤 6 – 删除 Kubernetes 集群

要摧毁Kubernetes集群本身,您可以使用从~/k8s-cicd-webinars/webinar1/2-kubernetes/1-Terrafrom文件夹中的destroy.sh脚本。

1cd ~/k8s-cicd-webinars/webinar1/2-kubernetes/1-Terrafrom

运行剧本:

1./destroy.sh

通过运行此脚本,您将允许Terraform与DigitalOcean API进行通信,并删除群集中的服务器。

结论

在本教程中,您使用不同的工具创建容器图像. 使用这些图像,您可以在任何环境中创建容器. 您还使用Terraform设置了Kubernetes群集,并创建了部署和服务对象来部署和曝光您的应用程序。

您现在拥有建立在 Kubernetes 上 CI/CD 环境的坚实基础,我们将在未来文章中探讨。

Published At
Categories with 技术
comments powered by Disqus