欢迎你们前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~javascript
容器实例服务(Container Instance Service , CIS)能够帮您在云上快捷、灵活的部署容器,让您专一于构建程序和使用容器而非管理设备上。无需预购 CVM,您就能够在几秒内启动一批容器来执行任务。您也能够经过 kubernetes API 把已有 kubernetes 集群的 pod 调度到 CIS 上以处理突增业务。CIS 根据您实际使用的资源计费,能够帮您节约计算成本。使用 CIS 能够极大下降您部署容器的门槛,下降您执行 batch 型任务或处理业务突增的成本。css
本文将介绍Kubernetes部署和容器工做负载的相关内容。包含管理容器生命周期,部署多容器应用程序,扩展工做负载以及与Kubernetes进行协同工做。本文包括一些概念和命令,教你们快速入门Kubernetes,并入门CIS。html
Kubernetes是一个用于管理容器化应用程序的开源容器资源编排工具。前端
本文中,您将应用一些容器化的概念来构建、部署和管理Kubernetes中端到端的微服务应用程序。本文中使用的示例Web应用程序是一个用Node.js编写的“待办事项列表”应用程序,它使用MongoDB做为数据库。html5
本次将从Dockerfile中为此应用程序构建容器镜像,将镜像推送到Docker Hub,而后部署到您的集群。以便在将来您将扩展应用程序以知足不断增加的需求。java
要完成本文,您须要:node
首先咱们将经过Web应用打包到Docker镜像中。git
首先切换到您的主目录,而后使用Git从GitHub上的克隆本文的示例Web应用程序。github
cd ~
git clone https://github.com/janakiramm/todo-app.git
复制代码
从Dockerfile构建容器镜像。使用-t
命令注册用户名,镜像名称和可选标记标记镜像。
docker build -t sammy/todo .
复制代码
确认镜像已成功构建并正确标记。
Sending build context to Docker daemon 8.238MB
Step 1/7 : FROM node:slim
---> 286b1e0e7d3f
Step 2/7 : LABEL maintainer = "jani@janakiram.com"
---> Using cache
---> ab0e049cf6f8
Step 3/7 : RUN mkdir -p /usr/src/app
---> Using cache
---> 897176832f4d
Step 4/7 : WORKDIR /usr/src/app
---> Using cache
---> 3670f0147bed
Step 5/7 : COPY ./app/ ./
---> Using cache
---> e28c7c1be1a0
Step 6/7 : RUN npm install
---> Using cache
---> 7ce5b1d0aa65
Step 7/7 : CMD node app.js
---> Using cache
---> 2cef2238de24
Successfully built 2cef2238de24
Successfully tagged sammy/todo-app:latest
复制代码
经过运行docker images
命令验证是否已建立镜像。
$ docker images
复制代码
您能够看到镜像的大小以及建立的时间。
REPOSITORY TAG IMAGE ID CREATED SIZE
sammy/todo-app latest 81f5f605d1ca 9 minutes ago 236MB
复制代码
接下来,将您的镜像推送到Docker Hub上。请登陆Docker Hub账户:
docker login
复制代码
输入正确的用户名及密码,使用Docker Hub用户名存储您的镜像:
docker tag your_docker_hub_username/todo-app
复制代码
而后将镜像推送到Docker Hub:
docker push
复制代码
您能够登陆Docker Hub官网搜索查看你的镜像,来验证新镜像是否可用。
将Docker镜像推送到Docker Hub后,接下来咱们能够将应用程序打包为Kubernetes。
这个应用程序使用MongoDB存储经过Web应用程序建立的待办事项列表。要在Kubernetes中运行MongoDB,咱们须要将其打包为Pod。当咱们启动这个Pod时,它将运行一个MongoDB实例。
建立一个名为db-pod.yaml的新YAML文件:
nano db-pod.yaml
复制代码
添加如下代码,该代码使用基于MongoDB的一个容器定义Pod。同时,咱们打开了MongoDB使用的标准端口port。请注意,定义包含名为name和app的标签。咱们将使用这些标签来识别和配置特定的Pod。
apiVersion: v1
kind: Pod
metadata:
name: db
labels:
name: mongo
app: todoapp
spec:
containers:
- image: mongo
name: mongo
ports:
- name: mongo
containerPort: 27017
volumeMounts:
- name: mongo-storage
mountPath: /data/db
volumes:
- name: mongo-storage
hostPath:
path: /data/db
复制代码
数据存储在调用的卷中,该卷映射到节点的位置。有关卷的更多信息,请参阅Kubernetes官方文档。
运行如下命令以建立Pod。
kubectl create -f db-pod.yml
复制代码
你会看到这个输出:
pod "db" created
复制代码
如今咱们看看Pod是否建立。
kubectl get pods
复制代码
显示这个Pod正在运行:
NAME READY STATUS RESTARTS AGE
db 1/1 Running 0 2m
复制代码
接下来咱们让集群的内部人员能够管理访问这个Pod。
建立一个名为db-service.yaml的新文件,其中包含定义了MongoDB服务的代码:
apiVersion: v1
kind: Service
metadata:
name: db
labels:
name: mongo
app: todoapp
spec:
selector:
name: mongo
type: ClusterIP
ports:
- name: db
port: 27017
targetPort: 27017
复制代码
此服务将可以发现与name:db标签相匹配的同一命名空间中的全部Pod 。YAML文件中的selector部分明确地定义了这种关联关系。
咱们经过声明type: ClusterIP可使服务在集群中可见 。
保存文件并退出编辑器。而后使用kubectl将其提交到集群。
kubectl create -f db-service.yml
复制代码
您将看到此输出指示服务已成功建立:
service "db" created
复制代码
让咱们来看看Pod可用的端口。
kubectl get services
复制代码
您将看到如下的输出结果:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
db ClusterIP 10.109.114.243 <none> 27017/TCP 14s
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 47m
复制代码
从上图的输出结果中,您能够看到该服务在端口27017上。Web应用程序能够经过此服务访问MongoDB。当它使用主机名db的时候,在Kubernetes中运行的DNS服务将解析与服务关联的IP的地址。这种机制容许Pod之间相互检测并通讯。
接下来咱们可使用数据库Pod和Service,为Web应用程序建立一个额外的Pod。
咱们将在本文第一步中建立的Docker镜像打包为Pod并将其部署到集群。这将被做为最终用户可访问的前端Web应用程序层。
建立一个名为的新YAML文件:web-pod.yaml
nano web-pod.yaml
复制代码
添加如下代码,该代码根据sammy/todo-app
的Docker镜像定义具备一个容器的Pod 。它经过TCP协议展示在端口3000
上。
apiVersion: v1
kind: Pod
metadata:
name: web
labels:
name: web
app: todoapp
spec:
containers:
- image: sammy/todo-app
name: myweb
ports:
- containerPort: 3000
复制代码
运行如下命令以建立Pod:
kubectl create -f web-pod.yaml
复制代码
pod "web" created
复制代码
看看pod是否建立?
kubectl get pods
复制代码
NAME READY STATUS RESTARTS AGE
db 1/1 Running 0 8m
web 1/1 Running 0 9s
复制代码
咱们将MongoDB数据库和Web应用程序都做为Pod运行。
如今,咱们将使web Pod能够访问互联网。
服务会在内部或外部公开一组Pod。让咱们定义一个使web Pod能够公开使用的服务。咱们将经过NodePort公开它。NodePort是一种经过在集群的每一个节点上打开任意端口用来访问Pod的方案。
建立一个名为web-service.yaml的新文件,其中包含定义应用服务的代码:
apiVersion: v1
kind: Service
metadata:
name: web
labels:
name: web
app: todoapp
spec:
selector:
name: web
type: NodePort
ports:
- name: http
port: 3000
targetPort: 3000
protocol: TCP
复制代码
服务发现同一名称空间中与Label匹配的全部Pod都具备名称web。YAML文件的选择器部分定义了此关联。
咱们经过声明type: NodePort指定NodePort的服务类型。
用kubectl将此提交到群集。
kubectl create -f web-service.yml
复制代码
您将看到此输出指示服务已成功建立:
service "web" created
复制代码
让咱们来看看Pod可用的端口。
kubectl get services
复制代码
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
db ClusterIP 10.109.114.243 <none> 27017/TCP 12m
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 59m
web NodePort 10.107.206.92 <none> 3000:30770/TCP 12s
复制代码
今后输出中,咱们看到该服务在端口30770上可用。让咱们尝试链接到其中一个工做节点。
使用腾讯云控制台获取与你服务器的IP地址:
得到IP地址后,使用curl命令向端口30770上的一个节点发出HTTP请求:
curl http://your_worker_ip_address:30770
复制代码
您将看到以下的输出:
<!DOCTYPE html>
<html>
<head>
<title>Containers Todo Example</title>
<link rel='stylesheet' href='/stylesheets/screen.css' />
<!--[if lt IE 9]>
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
</head>
<body>
<div id="layout">
<h1 id="page-title">Containers Todo Example</h1>
<div id="list">
<form action="/create" method="post" accept-charset="utf-8">
<div class="item-new">
<input class="input" type="text" name="content" />
</div>
</form>
</div>
<div id="layout-footer"></div>
</div>
<script src="/javascripts/ga.js"></script>
</body>
</html>
复制代码
截至到此,您已经定义了Web Pod和服务。如今让咱们看看如何使用副本集来缩放它。
副本集能够确保始终在群集中运行最少数量的Pod。当Pod被打包为副本集时,Kubernetes将始终运行规范中定义的最小数量的Pod。
让咱们删除当前的Pod并经过副本集从新建立两个Pod。若是咱们让当前的Pod运行,它将不会是副本集的一部分。所以,咱们最好经过副本集启动Pod,即便只有一个Pod。
首先,删除现有的Pod。
kubectl delete pod web
复制代码
pod "web" deleted
复制代码
如今建立一个新的副本集声明。副本集的定义与Pod相同。关键的区别在于它包含定义须要运行的Pod数量的replica
元素。与Pod同样,它还包含有助于服务发现的元数据来做为标签。
建立web-rs.yaml
文件并将此代码添加到文件中
apiVersion: extensions/v1beta1
kind: ReplicaSet
metadata:
name: web
labels:
name: web
app: todoapp
spec:
replicas: 2
template:
metadata:
labels:
name: web
spec:
containers:
- name: web
image: sammy/todo-app
ports:
- containerPort: 3000
复制代码
保存并关闭文件。
如今建立副本集:
kubectl create -f web-rs.yaml
复制代码
replicaset "web" created
复制代码
而后检查Pod的数量:
kubectl get pods
复制代码
NAME READY STATUS RESTARTS AGE
db 1/1 Running 0 18m
web-n5l5h 1/1 Running 0 25s
web-wh6nf 1/1 Running 0 25s
复制代码
当咱们经过NodePort访问服务时,请求将被发送到由副本集管理一个Pod中。
让咱们经过删除其中一个Pod,并查看发生的状况来测试副本集的功能:
kubectl delete pod web-wh6nf
复制代码
pod "web-wh6nf" deleted
复制代码
让咱们再来看一下Pods:
kubectl get pods
复制代码
NAME READY STATUS RESTARTS AGE
db 1/1 Running 0 19m
web-n5l5h 1/1 Running 0 1m
web-wh6nf 1/1 Terminating 0 1m
web-ws59m 0/1 ContainerCreating 0 2s
复制代码
删除Pod后,Kubernetes会建立另外一个Pod副本,以确保其可以维持所需的计数。
咱们能够扩展副本集以运行其余的Web Pod。
运行如下命令将Web应用程序扩展为10个Pod。
kubectl scale rs/web --replicas=10
复制代码
replicaset "web" scaled
复制代码
检查Pod计数:
kubectl get pods
复制代码
您将会会看到以下输出:
NAME READY STATUS RESTARTS AGE
db 1/1 Running 0 22m
web-4nh4g 1/1 Running 0 21s
web-7vbb5 1/1 Running 0 21s
web-8zd55 1/1 Running 0 21s
web-f8hvq 0/1 ContainerCreating 0 21s
web-ffrt6 1/1 Running 0 21s
web-k6zv7 0/1 ContainerCreating 0 21s
web-n5l5h 1/1 Running 0 3m
web-qmdxn 1/1 Running 0 21s
web-vc45m 1/1 Running 0 21s
web-ws59m 1/1 Running 0 2m
复制代码
此时,Kubernetes已经启动了扩展web Pod 的过程。当请求经过NodePort到达服务时,它将被路由到副本集中的一个Pod。
当流量和负载消退时,咱们能够恢复到两个Pod的原始配置。
kubectl scale rs/web --replicas=2
复制代码
replicaset "web" scaled
复制代码
此命令将终止其他全部的Pod。
kubectl get pods
复制代码
NAME READY STATUS RESTARTS AGE
db 1/1 Running 0 24m
web-4nh4g 1/1 Terminating 0 2m
web-7vbb5 1/1 Terminating 0 2m
web-8zd55 1/1 Terminating 0 2m
web-f8hvq 1/1 Terminating 0 2m
web-ffrt6 1/1 Terminating 0 2m
web-k6zv7 1/1 Terminating 0 2m
web-n5l5h 1/1 Running 0 5m
web-qmdxn 1/1 Terminating 0 2m
web-vc45m 1/1 Terminating 0 2m
web-ws59m 1/1 Running 0 4m
复制代码
要验证副本集的可用性,请尝试删除其中一个Pod并检查计数。
kubectl delete pod web-ws59m
复制代码
pod "web-ws59m" deleted
复制代码
kubectl get pods
复制代码
NAME READY STATUS RESTARTS AGE
db 1/1 Running 0 25m
web-n5l5h 1/1 Running 0 7m
web-ws59m 1/1 Terminating 0 5m
web-z6r2g 0/1 ContainerCreating 0 5s
复制代码
一旦Pod计数发生变化,Kubernetes就会调整它以匹配YAML文件中定义的计数。删除副本集中的一个Web Pod时,会当即建立另外一个Pod以保持所需的计数。这是经过确保最小数量的Pod可以持续运行来确保应用程序的高可用性。
您可使用如下命令删除在本文中建立的全部对象:
kubectl delete -f db-pod.yaml -f db-service.yaml -f web-rs.yaml -f web-service.yaml
复制代码
pod "db" deleted
service "db" deleted
replicaset "web" deleted
service "web" deleted
复制代码
本文就先写到这里,欢迎你们使用腾讯云CIS产品,产品连接:cloud.tencent.com/document/pr…
参考文献:《Webinar Series: Deploying and Scaling Microservices in Kubernetes》
翻译:Zach展,审校:Techeek
问答
相关阅读
此文已由做者受权腾讯云+社区发布,原文连接:https://cloud.tencent.com/developer/article/1158254?fromSource=waitui
欢迎你们前往腾讯云+社区或关注云加社区微信公众号(QcloudCommunity),第一时间获取更多海量技术实践干货哦~
海量技术实践经验,尽在云加社区!