网络研讨会系列  本文是有关使用Kubernetes进行CI / CD的网络研讨会系列的补充。该系列讨论了如何采用Cloud Native方法来构建,测试和部署应用程序,涵盖了可与Kubernetes一起使用的发布管理,Cloud Native工具,服务网格和CI / CD工具。它旨在帮助有兴趣将CI / CD最佳实践与Kubernetes集成到其工作流中的开发人员和企业。  本教程包括本系列第一部分“使用Kubernetes进行CI / CD的构建模块”中的概念和命令。

介绍

如果您开始使用容器,您可能会想知道如何自动化构建,测试和部署。通过将Cloud Native方法应用于这些流程,您可以利用正确的基础架构API来自动打包和部署应用程序。

进行自动化的两个组成部分包括容器映像和容器编排器。在过去的一年左右的时间里,Kubernetes已成为容器编排的默认选择。在带有Kubernetes的CI / CD系列的第一篇文章中,您将:

  • 使用Docker,Buildah和Kaniko构建容器映像。
  • 使用Terraform设置Kubernetes集群,并创建Deployments和Services。
  • 使用自定义资源扩展Kubernetes集群的功能。

在本教程结束时,您将拥有使用Docker,Buildah和Kaniko构建的容器映像,以及具有Deployments,Services和Custom Resources的Kubernetes集群。

该系列的后续文章将涵盖相关主题:Kubernetes的软件包管理,Jenkins X和Spinnaker等CI / CD工具,Services Meshes和GitOps。

先决条件

  • 具有非root用户帐户的Ubuntu 16.04服务器。请遵循我们的《 Ubuntu 16.04初始服务器设置》教程以获取指导。
  • 在您的服务器上安装了Docker。请按照如何在Ubuntu 16.04上安装和使用Docker的步骤1和2进行安装说明。
  • Docker Hub帐户。有关Docker Hub入门的概述,请参阅以下说明。
  • DigitalOcean帐户和个人访问令牌。请参阅这些说明以获取您的访问令牌。
  • 熟悉容器和Docker。请参阅网络研讨会系列:容器入门以获取更多详细信息。
  • 熟悉Kubernetes概念有关更多详细信息,请参阅《 Kubernetes简介》。

第1步—使用Docker和Buildah构建容器映像

容器映像是一个独立的实体,具有自己的应用程序代码,运行时和依赖性,可用于创建和运行容器。您可以使用不同的工具来创建容器映像,并且在此步骤中,将使用其中两个来构建容器:Docker和Buildah。

使用Dockerfiles构建容器映像

Docker通过阅读Dockerfile中的指令自动构建您的容器映像,该文件是一个文本文件,其中包含组装容器映像所需的命令。使用docker image build命令,您可以创建一个自动构建,该构建将执行Dockerfile中提供的命令行指令。在构建映像时,您还将通过Dockerfile传递构建上下文,该Dockerfile包含创建环境并在容器映像中运行应用程序所需的文件集。

通常,您将为Dockerfile创建一个项目文件夹并构建上下文。创建一个名为demo的文件夹开始:

  • mkdir demo
  • cd demo

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

  • nano Dockerfile

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

~/demo/Dockerfile
FROM ubuntu:16.04

LABEL MAINTAINER [email protected]

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 .

您将看到以下输出:

Output
Sending build context to Docker daemon 49.25MB Step 1/5 : FROM ubuntu:16.04 ---> 7aa3602ab41e Step 2/5 : MAINTAINER [email protected] ---> 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
Output
REPOSITORY TAG IMAGE ID CREATED SIZE nkhare/nginx latest 4073540cbcec 3 seconds ago 171MB ubuntu 16.04 7aa3602ab41e 11 days ago

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

使用Atomic-Buildah项目构建容器图像

Buildah是由Project Atomic开发的CLI工具,用于快速构建与开放容器倡议(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

您将看到以下输出,指示安装成功:

Output
go 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

您将看到以下输出:

Output
IMAGE 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
Output
REPOSITORY 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集群。

由于本系列教程讨论了采用Cloud Native方法进行应用程序开发,因此在设置集群时将采用这种方法。具体来说,我们将使用kubeadm和Terraform(可简化创建和更改基础架构的工具)自动创建集群。

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

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

  • ssh-keygen -t rsa

您将看到以下输出:

Output
Generating public/private rsa key pair. Enter file in which to save the key (~/.ssh/id_rsa):

按ENTER键将密钥对保存到主目录的〜/ .ssh目录中,或输入另一个目标。

接下来,您将看到以下提示:

Output
Enter passphrase (empty for no passphrase):

在这种情况下,请按不输入密码的ENTER键以启用无密码登录到您的节点。

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

Output
Your 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 [email protected] 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

You will see output confirming your Terraform installation:

Output
Terraform 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

转到Terraform脚本目录:

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

获取您的SSH公钥的指纹:

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

您将看到类似以下的输出,突出显示的部分代表您的密钥:

Output
MD5: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
Output
cluster.tf destroy.sh files outputs.tf provider.tf script.sh

该文件夹包含用于使用Terraform部署Kubernetes集群的必要脚本和配置文件。

执行script.sh脚本以触发Kubernetes集群设置:

  • ./script.sh

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

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

  • kubectl get nodes
Output
NAME 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

现在,您有一个主节点和两个工作节点处于“就绪”状态。

通过设置Kubernetes集群,您现在可以探索用于构建容器映像的另一个选项:Google的Kaniko。

步骤3 —使用Kaniko构建容器映像

在本教程的前面,您使用Dockerfiles和Buildah构建了容器映像。但是,如果您可以直接在Kubernetes上构建容器映像怎么办?有多种方法可以在Kubernetes中运行docker image build命令,但这不是Kubernetes的本机工具。您将不得不依靠Docker守护程序来构建映像,并且它将需要在集群中的Pod之一上运行。

称为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的共享卷中。初始化容器在应用程序容器之前运行,并且可以用于运行实用程序或其他不希望从应用程序容器运行的任务。然后,您的应用程序容器kaniko将使用Dockerfile构建映像,并使用传递给ConfigMap卷docker-config的凭据将生成的映像推送到Docker Hub。

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

  • kubectl apply -f pod-kaniko.yml

您将看到以下确认:

Output
pod/kaniko created

获取吊舱列表:

  • kubectl get pods

您将看到以下列表:

Output
NAME READY STATUS RESTARTS AGE kaniko 0/1 Init:0/1 0 47s

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

  • kubectl get pods

您将看到以下内容:

Output
NAME READY STATUS RESTARTS AGE kaniko 1/1 Running 0 1m

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

  • kubectl get pods
Output
NAME READY STATUS RESTARTS AGE kaniko 0/1 Completed 0 2m

此输出序列告诉您Init容器已运行,并在演示卷中克隆了GitHub存储库。之后,Kaniko的构建过程开始运行并最终完成。

检查容器的日志:

  • kubectl logs kaniko

您将看到以下输出:

Output
time="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映像。再次确保将dockerhub-username替换为Docker Hub用户名:

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

您将看到拉动的确认:

Output
kaniko: 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集群并从该集群内创建了新映像。让我们继续讨论“部署和服务”。

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

Kubernetes部署允许您运行应用程序。部署为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容器。

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

  • kubectl apply -f deployment.yml

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

Output
deployment.apps/nginx-deployment created

列出您的部署:

  • kubectl get deployments
Output
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE nginx-deployment 3 3 3 3 29s

您可以看到已经创建了nginx-deployment部署,并且Pod的所需数量和当前数量相同:3。

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

  • kubectl get pods
Output
NAME 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

这些设置定义Service,nginx-service,并指定它将以Pod上的端口80为目标。 nodePort定义应用程序将在其中接受外部流量的端口。

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

  • kubectl apply -f service.yml

您会看到一个确认:

Output
service/nginx-service created

列出服务:

  • kubectl get service

您将看到以下列表:

Output
NAME 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中,资源是Kubernetes API中的端点,该端点存储API对象的集合。例如,Pod资源包含Pod对象的集合。使用自定义资源,您可以添加用于网络,存储等的自定义产品。这些添加可以随时创建或删除。

除了创建自定义对象外,还可以在控制平面中使用Kubernetes Controller组件的子控制器,以确保对象的当前状态等于所需的状态。 Kubernetes控制器具有用于指定对象的子控制器。例如,ReplicaSet是一个子控制器,可确保所需的Pod计数保持一致。将自定义资源与控制器结合使用时,您将获得一个真正的声明性API,该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

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

Output
customresourcedefinition.apiextensions.k8s.io/webinars.digitalocean.com created

crd.yml文件创建了一个新的RESTful资源路径:/apis/digtialocean.com/v1/namespaces/*/webinars。现在,您可以使用网络研讨会,网络研讨会,网络研讨会和wb来引用您的对象,因为它们已在CustomResourceDefinition的名称部分中列出。您可以使用以下命令检查RESTful资源:

  • kubectl proxy & curl 127.0.0.1:8001/apis/digitalocean.com
注意:如果您遵循先决条件中的初始服务器设置指南,则将需要允许端口8001的流量,此测试才能正常进行。使用以下命令启用到该端口的流量:  sudo ufw允许8001

您将看到以下输出:

Output
HTTP/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

您将看到以下输出:

Output
webinar.digitalocean.com/webinar1 created

现在,您可以使用kubectl管理您的网络研讨会对象。例如:

  • kubectl get webinar
Output
NAME CREATED AT webinar1 21s

现在,您有了一个名为webinar1的对象。如果有一个Controller,它将拦截对象创建并执行任何已定义的操作。

删除自定义资源定义

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

  • kubectl delete webinar --all

你会看见:

Output
webinar.digitalocean.com "webinar1" deleted

删除自定义资源本身:

  • kubectl delete crd webinars.digitalocean.com

您将看到确认已删除的确认:

Output
customresourcedefinition.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集群,并创建了Deployment和Service对象来部署和公开您的应用程序。此外,您通过定义自定义资源扩展了Kubernetes的功能。

您现在拥有在Kubernetes上构建CI / CD环境的坚实基础,我们将在以后的文章中进行探讨。