容器部署 v1.2.1
本章节展示如何创建一个容器部署方式的应用
新建应用
导航栏点击 应用管理,点击按钮 新建应用,按如下图所示填写:

基础配置
- 应用名称:任意名称
- 部署方式:容器
- 镜像仓库/制品库:选择一个 镜像仓库管理 章节添加的仓库
- 仓库/项目:Artifactory 填写仓库名;Harbor 填写项目名;DockerHub 填写 namespace;S3 填写桶(bucket)名
- 镜像名/制品路径:剩余的镜像路径。Lizardcd 会将上述三个字段拼成实际的镜像 URL 并从选择的镜像仓库中获取
- 设置标签:可以为应用设置标签,标签 key 支持重复
容器部署配置
- 开启灰度发布:参考 开启对接Istio 章节设置,开启对接 Istio;如不需要,保持关闭
- 工作负载:点击
+添加一个工作负载- 容器集群:agent 注册时设置的 Key 会标识其所纳管的集群名称,参考 agent配置。选择一个集群。
- 命名空间:agent 注册时设置的 Key 会标识其所纳管的命名空间,参考 agent配置。选择一个命名空间。
- 工作负载类型:按需选择。
- 工作负载名称:
deployment或statefulset的metadata.name。在最新的 v1.3.1 版本中已经改为从对应集群自动读取并列出下拉框选择,不允许直接填写。 - 容器名称:
spec.template.spec.containers[*].name。在最新的 v1.3.1 版本中已经改为从对应集群自动读取并列出下拉框选择,不允许直接填写。 - 是否启用:如不需要部署此工作负载则关闭。此功能的用处在于用户临时不想部署某个工作负载时,可以将其禁用。
提交保存即可。
TIP
一个应用可以添加多个工作负载,每个工作负载可以属于不同集群/命名空间。由此可见,Lizardcd 支持将应用的同一个版本发布到不同的集群/命名空间,这对于多数据中心、异地灾备的应用部署将非常有用。
灰度发布
Lizardcd 支持对接 Istio,借助 Istio 的流量管理功能实现灰度发布。
前提条件
- 需要使用灰度发布的集群必须已经安装好
Istio。 - Lizardcd 的设置中开启
Istio管理,详见 开启对接 Istio。 - 在已装有
Istio的集群中安装lizardcd-agent,并且设置服务注册 Key 为lizardcd-agent.default.istiok8s。 - lizardcd-ui 页面 agent 列表能成功显示上一步注册的 agent。
原理
Istio 的灰度发布参考 配置请求路由,基本步骤如下:
- 创建两个版本的
deployment,并分别打上标签version: v1和version: v2。 - 创建一个service,将请求转发到第 1 步创建的两个
deployment。 - 创建
目标规则,将两个deployment分成两个subset。 - 创建
虚拟服务,将流量根据基于HTTP头部字段或基于权重路由到两个deployment。
步骤
本例将创建一个 flaskapp 以说明如何通过 Lizardcd 实现灰度发布。
新建工作负载
- 创建工作负载
flaskapp-v1。导航切换到工作负载-部署,集群选择istiok8s,命名空间选择default,点击按钮新建工作负载。从模板导入选择application_template_with_service,编辑 YAML 文件(主要给 labels 添加 version):
yaml
kind: Deployment
apiVersion: apps/v1
metadata:
name: {{ .Appname }}
namespace: {{ .Namespace }}
labels:
app: {{ .Appname }}
version: v1
annotations:
lizardcd/creator: lizardcd
spec:
replicas: 1
selector:
matchLabels:
app: {{ .Appname }}
version: v1
template:
metadata:
labels:
app: {{ .Appname }}
version: v1
spec:
volumes:
- name: host-time
hostPath:
path: /etc/localtime
type: ''
- name: timezone
hostPath:
path: /etc/timezone
type: ''
containers:
- name: {{ .Appname }}-container
image: {{ .Image }}
ports:
- name: tcp
containerPort: {{ .Port }}
protocol: TCP
resources:
limits:
cpu: 200m
memory: 200Mi
requests:
cpu: 100m
memory: 100Mi
volumeMounts:
- name: timezone
readOnly: true
mountPath: /etc/timezone
- name: host-time
readOnly: true
mountPath: /etc/localtime
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
imagePullPolicy: Always
restartPolicy: Always
terminationGracePeriodSeconds: 30
dnsPolicy: ClusterFirst
serviceAccountName: default
serviceAccount: default
securityContext: {}
schedulerName: default-scheduler
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 25%
maxSurge: 25%
revisionHistoryLimit: 10
progressDeadlineSeconds: 600
---
kind: Service
apiVersion: v1
metadata:
name: {{ .Appname }}
namespace: {{ .Namespace }}
annotations:
lizardcd/creator: lizardcd
spec:
ports:
- name: tcp
protocol: TCP
port: {{ .Port }}
targetPort: tcp
selector:
app: {{ .Appname }}
type: ClusterIP
sessionAffinity: None模板变量修改:
- Appname:flaskapp-v1
- Image:dustise/flaskapp:v0.2.7
- Port:80
- Namespace:default
提交保存。
- 创建工作负载
flaskapp-v2。从模板导入选择application_template_base,编辑 YAML 文件(主要给 labels 添加 version):
yaml
kind: Deployment
apiVersion: apps/v1
metadata:
name: {{ .Appname }}
namespace: {{ .Namespace }}
labels:
app: {{ .Appname }}
version: v2
annotations:
lizardcd/creator: lizardcd
spec:
replicas: 1
selector:
matchLabels:
app: {{ .Appname }}
version: v2
template:
metadata:
labels:
app: {{ .Appname }}
version: v2
spec:
volumes:
- name: host-time
hostPath:
path: /etc/localtime
type: ''
- name: timezone
hostPath:
path: /etc/timezone
type: ''
containers:
- name: {{ .Appname }}-container
image: {{ .Image }}
ports:
- name: tcp
containerPort: {{ .Port }}
protocol: TCP
resources:
limits:
cpu: 200m
memory: 200Mi
requests:
cpu: 100m
memory: 100Mi
volumeMounts:
- name: timezone
readOnly: true
mountPath: /etc/timezone
- name: host-time
readOnly: true
mountPath: /etc/localtime
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
imagePullPolicy: Always
restartPolicy: Always
terminationGracePeriodSeconds: 30
dnsPolicy: ClusterFirst
serviceAccountName: default
serviceAccount: default
securityContext: {}
schedulerName: default-scheduler
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 25%
maxSurge: 25%
revisionHistoryLimit: 10
progressDeadlineSeconds: 600模板变量修改:
- Appname:flaskapp-v2
- Image:dustise/flaskapp:v0.2.7
- Port:80
- Namespace:default
提交保存。
新建应用
新建 flaskapp 应用,如下图所示。
- 开启灰度发布:开启
灰度发布策略:基于权重
新增两个工作负载
工作负载 1:
- 容器集群:istiok8s
- 命名空间:default
- 工作负载名称:flaskapp-v1
- 容器名称:flaskapp-container
- 版本号:v1
- 权重:10
工作负载 2:
- 容器集群:istiok8s
- 命名空间:default
- 工作负载名称:flaskapp-v2
- 容器名称:flaskapp-container
- 版本号:v2
- 权重:90
灰度发布策略:基于头部字段
新增两个工作负载
工作负载 1:
- 容器集群:istiok8s
- 命名空间:default
- 工作负载名称:flaskapp-v1
- 容器名称:flaskapp-container
- 版本号:v1
- 匹配头部字段:
- 头部键:end-user
- 匹配方式:exact
- 头部值:kevin
工作负载 2:
- 容器集群:istiok8s
- 命名空间:default
- 工作负载名称:flaskapp-v2
- 容器名称:flaskapp-container
- 版本号:v2
提交保存。
发布应用
找到 flaskapp 应用,点击 更多操作-发布,选择一个制品,提交。 
查看 Istio 资源
页面导航切换到 Istio 管理,在 目标规则 页面,集群选择 istiok8s,命名空间选择 default,可以看到已自动创建出一个目标规则 flaskapp。可查看 YAML 信息。

在 虚拟服务 页面,集群选择 istiok8s,命名空间选择 default,可以看到已自动创建出一个虚拟服务 flaskapp。可查看 YAML 信息。

验证结果
在集群 istiok8s 中部署一个验证工作负载:
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
deployment.kubernetes.io/revision: "4"
generation: 4
name: sleep
namespace: default
spec:
progressDeadlineSeconds: 600
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
app: sleep
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
creationTimestamp: null
labels:
app: sleep
spec:
containers:
- image: dustise/sleep:v0.9.7
imagePullPolicy: IfNotPresent
name: sleep
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
serviceAccount: lizardcd
serviceAccountName: lizardcd
terminationGracePeriodSeconds: 30进入 Pod 后执行命令验证:
shell
# kubectl exec -it sleep-5db69b44d4-55szj -- /bin/bash验证基于权重,大约10%比例返回v1,90%比例返回v2
shell
for((i=0; i<100; i++)); do curl http://flaskapp/env/version;echo ;done验证基于头部字段,kevin全部返回v1,tom全部返回v2
shell
for((i=0; i<10; i++)); do curl -H 'end-user:kevin' http://flaskapp/env/version;echo ;done
for((i=0; i<10; i++)); do curl -H 'end-user:tom' http://flaskapp/env/version;echo ;done