网络研讨会系列
本文补充了与Kubernetes一起进行CI / CD的网络研讨会系列 。 本系列讨论如何采用Cloud Native方法构建,测试和部署应用程序,包括可与Kubernetes一起使用的发布管理,Cloud Native工具,Service Meshes和CI / CD工具。 它旨在帮助有兴趣将CI / CD最佳实践与Kubernetes集成到其工作流程中的开发人员和企业。
本教程包括本系列第一部分的概念和命令,即使用Kubernetes构建CI / CD的构建块。
介绍
如果您开始使用容器 ,您可能想知道如何自动构建,测试和部署。 通过对这些流程采用Cloud Native方法,您可以利用正确的基础架构API以自动方式打包和部署应用程序。
用于自动化的两个构建块包括容器映像和容器协调器 。 在过去一年左右的时间里, Kubernetes已成为容器编排的默认选择。 在使用Kubernetes系列的CI / CD的第一篇文章中,您将:
在本教程结束时,您将拥有使用Docker,Buildah和Kaniko构建的容器映像,以及具有部署,服务和自定义资源的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中的指令自动构建容器图像,Dockerfile是一个文本文件,包含组装容器图像所需的命令。 使用docker image build
命令,您可以创建一个自动构建,该构建将执行Dockerfile中提供的命令行指令。 构建映像时,还将使用Dockerfile传递构建上下文 ,Dockerfile包含创建环境和在容器映像中运行应用程序所需的文件集。
通常,您将为Dockerfile和构建上下文创建项目文件夹。 创建一个名为demo
的文件夹以开始:
mkdir demo
cd demo
接下来,在demo
文件夹中创建一个Dockerfile:
nano 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是一个由Project Atomic开发的CLI工具,用于快速构建符合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/projectatomic/buildah ./src/github.com/projectatomic/buildah
cd ./src/github.com/projectatomic/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
将以下内容添加到文件中以指定您的注册表:
# 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
存储库作为构建上下文。 该存储库还包含相关的Dockerfile:
sudo buildah build-using-dockerfile -t rsvpapp:buildah github.com/do-community/rsvpapp
此命令从https://github.com/do-community/rsvpapp
存储库中提供的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
,是docker.io/teamcloudyuga/python:alpine
的基本映像。
构建映像后,可以将其推送到Docker Hub。 这将允许您存储它以备将来使用。 您首先需要从命令行登录Docker Hub帐户:
docker login -u your-dockerhub-username -p your-dockerhub-password
登录成功后,您将获得一个包含Docker Hub凭据的文件~/.docker/config.json
。 然后,您可以将该文件与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
正如预期的那样,您现在应该看到一个使用buildah
导出的新映像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
您将看到以下输出:
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/
project目录:
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
:
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 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.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时将发生的情况。 请务必使用您自己的Docker Hub用户名替换Pod的args
字段中的your-dockerhub-username
username:
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.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.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镜像。 请务必再次使用Docker Hub用户名替换your-dockerhub-username
username:
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集群,并在集群中创建了新映像。 让我们继续讨论部署和服务 。
第4步 - 创建Kubernetes部署和服务
Kubernetes Deployments允许您运行应用程序。 部署指定Pod的所需状态,确保您的推出的一致性。 在此步骤中,您将在~/k8s-cicd-webinars/webinar1/2-kubernetes/1-Terraform/
目录中创建名为deployment.yml
的Nginx部署文件,以创建Nginx部署。
首先,打开文件:
nano deployment.yml
将以下配置添加到文件中以定义Nginx部署:
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
您将看到已创建部署的确认:
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
部署,并且nginx-deployment
的所需和当前计数相同: 3
。
要列出部署创建的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
添加以下内容以定义您的服务:
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
上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 控制器组件的子控制器,以确保对象的当前状态等于所需的状态。 Kubernetes控制器具有指定对象的子控制器。 例如, ReplicaSet是一个子控制器,可确保所需的Pod计数保持一致。 将自定义资源与Controller结合使用时,您将获得一个真正的声明性API ,允许您指定所需的资源状态。
在此步骤中,您将创建自定义资源和相关对象。
要创建自定义资源,首先在~/k8s-cicd-webinars/webinar1/2-kubernetes/1-Terrafrom/
目录中创建一个名为crd.yml
的文件:
nano crd.yml
添加以下自定义资源定义(CRD):
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
来引用您的对象,就像您在CustomResourceDefinition
的names
部分中列出的那样。 您可以使用以下命令检查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
添加以下内容以创建对象:
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
的对象。 如果存在Controller,它将截获对象创建并执行任何已定义的操作。
删除自定义资源定义
要删除自定义资源的所有对象,请使用以下命令:
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
文件夹中~/k8s-cicd-webinars/webinar1/2-kubernetes/1-Terrafrom
。 确保您在此目录中:
cd ~/k8s-cicd-webinars/webinar1/2-kubernetes/1-Terrafrom
运行脚本:
./destroy.sh
通过运行此脚本,您将允许Terraform与DigitalOcean API通信并删除群集中的服务器。
结论
在本教程中,您使用了不同的工具来创建容器图像。 使用这些图像,您可以在任何环境中创建容器。 您还使用Terraform设置Kubernetes集群,并创建部署和服务对象以部署和公开您的应用程序。 此外,您通过定义自定义资源扩展了Kubernetes的功能。
您现在拥有在Kubernetes上构建CI / CD环境的坚实基础,我们将在以后的文章中探讨这一环境。