容器部署 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