包管理与镜像
包管理和镜像是云原生应用分发的重要工具。Helm 是 Kubernetes 的包管理器,简化应用的部署和管理。容器镜像是应用的交付格式,需要合理的构建和存储策略。
Helm
Helm 的架构
Helm Client:Helm 客户端,负责与用户交互、与 Helm Server 通信。
Helm Server(Tiller):Helm 服务端(v3 已移除),负责管理 Kubernetes 资源。
Helm v3 移除了 Tiller,直接通过 kubeconfig 与 API Server 通信,安全性更好。
Chart
Chart 是 Helm 的包格式,包含应用的定义和资源模板。Chart 的结构:Chart.yaml(Chart 元数据)、values.yaml(默认配置)、templates(Kubernetes 资源模板)、templates/NOTES.txt(使用说明)。
Chart 的版本:使用语义化版本(Semantic Versioning),如 1.0.0、1.0.1、1.1.0。
Chart 的仓库:Helm Repository,存储和分发 Chart。可以搭建私有 Helm Repository,如 Chartmuseum。
Helm 的使用
helm install:安装 Chart,部署应用。
helm upgrade:升级应用,更新配置或 Chart 版本。
helm rollback:回滚应用,恢复到之前的版本。
helm uninstall:卸载应用,删除资源。
helm list:列出已安装的应用。
helm status:查看应用状态。
Helm 的最佳实践
使用 values.yaml 外部配置:将配置参数化,通过 values.yaml 覆盖默认配置。
使用命名空间隔离:不同环境使用不同命名空间,避免冲突。
使用版本管理:使用语义化版本,便于升级和回滚。
使用钩子:使用 pre-install、post-install、pre-upgrade、post-upgrade 钩子,在部署前后执行操作。
使用依赖管理:通过 requirements.yaml 或 Chart.yaml 管理依赖。
容器镜像
镜像构建
多阶段构建:使用多个 FROM 指令,每个 FROM 开始一个新的构建阶段。多阶段构建可以减少最终镜像的大小,只保留运行时需要的文件。
精简基础镜像:使用 alpine、scratch 等精简基础镜像,减少镜像大小和攻击面。
镜像分层:将不常变化的层放在前面,常变化的层放在后面,利用镜像缓存,加快构建速度。
镜像标签:使用语义化版本,避免使用 latest 标签。使用 git commit hash 作为标签,便于追溯。
镜像存储
公共镜像仓库:Docker Hub、Quay.io、阿里云容器镜像服务。
私有镜像仓库:Harbor、GitLab Container Registry、AWS ECR、Azure ACR。
镜像仓库的选择:访问速度、安全性、权限管理、漏洞扫描。
镜像安全
镜像扫描:使用 Trivy、Clair、Docker Scan 扫描镜像漏洞,及时修复。
签名验证:使用 Docker Content Trust 签名镜像,验证镜像的完整性和来源。
访问控制:设置镜像仓库的访问权限,避免未授权访问。
镜像优化
减小镜像大小:使用多阶段构建、精简基础镜像、清理不必要的文件。
构建缓存:利用 Docker 的分层缓存,加快构建速度。将不常变化的指令放在前面,常变化的指令放在后面。
镜像并行构建:使用 BuildKit 并行构建镜像,提高构建速度。
CI/CD 集成
GitLab CI/CD
GitLab CI/CD 可以集成 Helm 和 Docker,实现自动化部署。
.gitlab-ci.yml 示例:build 阶段构建镜像,test 阶段运行测试,deploy 阶段使用 Helm 部署。
GitHub Actions
GitHub Actions 可以集成 Helm 和 Docker,实现自动化部署。
workflow 示例:build 阶段构建镜像,push 阶段推送镜像到仓库,deploy 阶段使用 Helm 部署。
Jenkins
Jenkins 可以集成 Helm 和 Docker,实现自动化部署。
Pipeline 示例:build 阶段构建镜像,test 阶段运行测试,deploy 阶段使用 Helm 部署。
灰度发布
Helm 的灰度发布
使用 Helm 的 values.yaml 覆盖配置,部署新版本应用。使用 Service 的 Selector 切换流量,实现灰度发布。
Istio 的灰度发布
使用 Istio 的 VirtualService 和 DestinationRule,根据请求特征路由到不同版本的服务。可以根据 Header、Cookie、百分比路由。
Kubernetes 的灰度发布
使用 Deployment 部署新版本应用,使用 Service 的 Selector 切换流量。或者使用 Ingress 的 Canary 注解实现灰度发布。
最佳实践
使用语义化版本:使用语义化版本(Semantic Versioning),便于升级和回滚。
自动化构建和部署:使用 CI/CD 自动化构建和部署,减少人工错误。
镜像标签管理:使用 git commit hash 或语义化版本作为镜像标签,便于追溯。
配置外部化:将配置存储在 ConfigMap 或 Helm values.yaml,不要打包在镜像中。
灰度发布:先部署到少量实例,验证后全量发布,降低风险。
监控和告警:监控部署状态和应用性能,异常时及时告警。
回滚机制:部署失败时快速回滚到之前的版本,减少故障影响。
包管理和镜像是云原生应用分发的基础,理解 Helm 和容器镜像的原理和最佳实践,有助于构建可靠的 CI/CD 流程。