Kubernetes Handbook
  • Kubernetes 中文指南/云原生应用架构实践手册
  • 前言
    • 序言
  • 云原生
    • 云原生(Cloud Native)的定义
    • 云原生的设计哲学
    • Play with Kubernetes
    • 快速部署一个云原生本地实验环境
    • 使用Rancher在阿里云上部署Kubenretes集群
    • Kubernetes与云原生应用概览
    • 云原生应用之路——从Kubernetes到Cloud Native
    • 云原生编程语言
      • 云原生编程语言Ballerina
      • 云原生编程语言Pulumi
    • 云原生的未来
  • 概念与原理
    • Kubernetes架构
      • 设计理念
      • Etcd解析
      • 开放接口
        • CRI - Container Runtime Interface(容器运行时接口)
        • CNI - Container Network Interface(容器网络接口)
        • CSI - Container Storage Interface(容器存储接口)
    • Kubernetes中的网络
      • Kubernetes中的网络解析——以flannel为例
      • Kubernetes中的网络解析——以calico为例
      • 具备API感知的网络和安全性管理开源软件Cilium
        • Cilium架构设计与概念解析
    • 资源对象与基本概念解析
    • Pod状态与生命周期管理
      • Pod概览
      • Pod解析
      • Init容器
      • Pause容器
      • Pod安全策略
      • Pod的生命周期
      • Pod Hook
      • Pod Preset
      • Pod中断与PDB(Pod中断预算)
    • 集群资源管理
      • Node
      • Namespace
      • Label
      • Annotation
      • Taint和Toleration(污点和容忍)
      • 垃圾收集
    • 控制器
      • Deployment
      • StatefulSet
      • DaemonSet
      • ReplicationController和ReplicaSet
      • Job
      • CronJob
      • Horizontal Pod Autoscaling
        • 自定义指标HPA
      • 准入控制器(Admission Controller)
    • 服务发现
      • Service
      • Ingress
        • Traefik Ingress Controller
    • 身份与权限控制
      • ServiceAccount
      • RBAC——基于角色的访问控制
      • NetworkPolicy
    • 存储
      • Secret
      • ConfigMap
        • ConfigMap的热更新
      • Volume
      • Persistent Volume(持久化卷)
      • Storage Class
      • 本地持久化存储
    • 集群扩展
      • 使用自定义资源扩展API
      • 使用CRD扩展Kubernetes API
      • Aggregated API Server
      • APIService
      • Service Catalog
    • 资源调度
      • QoS(服务质量等级)
  • 用户指南
    • 用户指南
    • 资源对象配置
      • 配置Pod的liveness和readiness探针
      • 配置Pod的Service Account
      • Secret配置
      • 管理namespace中的资源配额
    • 命令使用
      • Docker用户过渡到kubectl命令行指南
      • kubectl命令概览
      • kubectl命令技巧大全
      • 使用etcdctl访问kubernetes数据
    • 集群安全性管理
      • 管理集群中的TLS
      • kubelet的认证授权
      • TLS bootstrap
      • 创建用户认证授权的kubeconfig文件
      • IP伪装代理
      • 使用kubeconfig或token进行用户身份认证
      • Kubernetes中的用户与身份认证授权
      • Kubernetes集群安全性配置最佳实践
    • 访问Kubernetes集群
      • 访问集群
      • 使用kubeconfig文件配置跨集群认证
      • 通过端口转发访问集群中的应用程序
      • 使用service访问群集中的应用程序
      • 从外部访问Kubernetes中的Pod
      • Cabin - Kubernetes手机客户端
      • Kubernetic - Kubernetes桌面客户端
      • Kubernator - 更底层的Kubernetes UI
    • 在Kubernetes中开发部署应用
      • 适用于kubernetes的应用开发部署流程
      • 迁移传统应用到Kubernetes中——以Hadoop YARN为例
      • 使用StatefulSet部署用状态应用
  • 最佳实践
    • 最佳实践概览
    • 在CentOS上部署Kubernetes集群
      • 创建TLS证书和秘钥
      • 创建kubeconfig文件
      • 创建高可用etcd集群
      • 安装kubectl命令行工具
      • 部署master节点
      • 安装flannel网络插件
      • 部署node节点
      • 安装kubedns插件
      • 安装dashboard插件
      • 安装heapster插件
      • 安装EFK插件
    • 生产级的Kubernetes简化管理工具kubeadm
      • 使用kubeadm在Ubuntu Server 16.04上快速构建测试集群
    • 服务发现与负载均衡
      • 安装Traefik ingress
      • 分布式负载测试
      • 网络和集群性能测试
      • 边缘节点配置
      • 安装Nginx ingress
      • 安装配置DNS
        • 安装配置Kube-dns
        • 安装配置CoreDNS
    • 运维管理
      • Master节点高可用
      • 服务滚动升级
      • 应用日志收集
      • 配置最佳实践
      • 集群及应用监控
      • 数据持久化问题
      • 管理容器的计算资源
      • 集群联邦
    • 存储管理
      • GlusterFS
        • 使用GlusterFS做持久化存储
        • 使用Heketi作为Kubernetes的持久存储GlusterFS的external provisioner
        • 在OpenShift中使用GlusterFS做持久化存储
      • GlusterD-2.0
      • Ceph
        • 用Helm托管安装Ceph集群并提供后端存储
        • 使用Ceph做持久化存储
        • 使用rbd-provisioner提供rbd持久化存储
      • OpenEBS
        • 使用OpenEBS做持久化存储
      • Rook
      • NFS
        • 利用NFS动态提供Kubernetes后端存储卷
    • 集群与应用监控
      • Heapster
        • 使用Heapster获取集群和对象的metric数据
      • Prometheus
        • 使用Prometheus监控kubernetes集群
        • Prometheus查询语言PromQL使用说明
      • 使用Vistio监控Istio服务网格中的流量
    • 分布式跟踪
      • OpenTracing
    • 服务编排管理
      • 使用Helm管理Kubernetes应用
      • 构建私有Chart仓库
    • 持续集成与发布
      • 使用Jenkins进行持续集成与发布
      • 使用Drone进行持续集成与发布
    • 更新与升级
      • 手动升级Kubernetes集群
      • 升级dashboard
  • 领域应用
    • 领域应用概览
    • 微服务架构
      • 微服务中的服务发现
      • 使用Java构建微服务并发布到Kubernetes平台
        • Spring Boot快速开始指南
    • Service Mesh 服务网格
      • 企业级服务网格架构
        • Service Mesh基础
        • Service Mesh技术对比
        • 采纳和演进
        • 定制和集成
        • 总结
      • Istio
        • 安装并试用Istio service mesh
        • 配置请求的路由规则
        • 安装和拓展Istio service mesh
        • 集成虚拟机
        • Istio中sidecar的注入规范及示例
        • 如何参与Istio社区及注意事项
        • Istio教程
        • Istio免费学习资源汇总
        • 深入理解Istio Service Mesh中的Envoy Sidecar注入与流量劫持
        • 深入理解Istio Service Mesh中的Envoy Sidecar代理的路由转发
      • Linkerd
        • Linkerd 使用指南
      • Conduit
        • Condiut概览
        • 安装Conduit
      • Envoy
        • Envoy的架构与基本术语
        • Envoy作为前端代理
        • Envoy mesh教程
      • SOFAMesh
        • SOFAMesh中的Dubbo on x-protocol
      • MOSN
        • 使用 MOSN 构建 SOFAMesh
    • 大数据
      • Spark standalone on Kubernetes
      • 运行支持Kubernetes原生调度的Spark程序
    • Serverless架构
      • 理解Serverless
      • FaaS-函数即服务
        • OpenFaaS快速入门指南
    • 边缘计算
    • 人工智能
  • 开发指南
    • 开发指南概览
    • SIG和工作组
    • 开发环境搭建
      • 本地分布式开发环境搭建(使用Vagrant和Virtualbox)
    • 单元测试和集成测试
    • client-go示例
    • Operator
      • operator-sdk
    • kubebuilder
    • 高级开发指南
    • 社区贡献
    • Minikube
  • CNCF(云原生计算基金会)
    • CNCF - 云原生计算基金会简介
    • CNCF章程
    • CNCF特别兴趣小组(SIG)说明
    • 开源项目加入CNCF Sandbox的要求
    • CNCF中的项目治理
    • CNCF Ambassador
  • 附录
    • 附录说明
    • Kubernetes中的应用故障排查
    • Kubernetes相关资讯和情报链接
    • Docker最佳实践
    • 使用技巧
    • 问题记录
    • Kubernetes版本更新日志
      • Kubernetes1.7更新日志
      • Kubernetes1.8更新日志
      • Kubernetes1.9更新日志
      • Kubernetes1.10更新日志
      • Kubernetes1.11更新日志
      • Kubernetes1.12更新日志
      • Kubernetes1.13更新日志
      • Kubernetes1.14更新日志
      • Kubernetes1.15更新日志
    • Kubernetes及云原生年度总结及展望
      • Kubernetes与云原生2017年年终总结及2018年展望
      • Kubernetes与云原生2018年年中总结及2019年展望
    • CNCF年度报告解读
      • CNCF 2018年年度报告解读
    • Kubernetes认证服务提供商(KCSP)说明
    • 认证Kubernetes管理员(CKA)说明
Powered by GitBook
On this page
  • 安装Helm
  • 创建自己的chart
  • 模板
  • 检查配置和模板是否有效
  • 部署到kubernetes
  • 打包分享
  • 依赖
  • 安装源
  • 注意事项
  • 服务依赖管理
  • 解决本地chart依赖
  • 设置helm命令自动补全
  • 部署MEAN测试案例
  • 参考

Was this helpful?

  1. 最佳实践
  2. 服务编排管理

使用Helm管理Kubernetes应用

Previous服务编排管理Next构建私有Chart仓库

Last updated 5 years ago

Was this helpful?

读完本文后您应该可以自己创建chart,并创建自己的私有chart仓库。

是一个kubernetes应用的包管理工具,用来管理——预先配置好的安装包资源,有点类似于Ubuntu的APT和CentOS中的yum。

Helm chart是用来封装kubernetes原生应用程序的yaml文件,可以在你部署应用的时候自定义应用程序的一些metadata,便与应用程序的分发。

Helm和charts的主要作用:

  • 应用程序封装

  • 版本管理

  • 依赖检查

  • 便于应用程序分发

安装Helm

前提要求

  • Kubernetes1.5以上版本

  • 集群可访问到的镜像仓库

  • 执行helm命令的主机可以访问到kubernetes集群

安装步骤

首先需要安装helm客户端

curl https://raw.githubusercontent.com/kubernetes/helm/master/scripts/get > get_helm.sh
chmod 700 get_helm.sh
./get_helm.sh

创建tiller的serviceaccount和clusterrolebinding

kubectl create serviceaccount --namespace kube-system tiller
kubectl create clusterrolebinding tiller-cluster-rule --clusterrole=cluster-admin --serviceaccount=kube-system:tiller

然后安装helm服务端tiller,目前最新版 v2.14.2,若无法访问 gcr.io,可以使用阿里云镜像,如:

helm init --upgrade -i registry.cn-hangzhou.aliyuncs.com/google_containers/tiller:v2.12.2 --stable-repo-url https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts

我们使用-i指定自己的镜像,因为官方的镜像因为某些原因无法拉取,官方镜像地址是:gcr.io/kubernetes-helm/tiller:v2.14.2,使用helm version可查看helm客户端版本。

为应用程序设置serviceAccount:

kubectl patch deploy --namespace kube-system tiller-deploy -p '{"spec":{"template":{"spec":{"serviceAccount":"tiller"}}}}'

检查是否安装成功:

$ kubectl -n kube-system get pods|grep tiller
tiller-deploy-2372561459-f6p0z         1/1       Running   0          1h
$ helm version
Client: &version.Version{SemVer:"v2.14.2", GitCommit:"a8b13cc5ab6a7dbef0a58f5061bcc7c0c61598e7", GitTreeState:"clean"}
Server: &version.Version{SemVer:"v2.12.2", GitCommit:"7d2b0c73d734f6586ed222a567c5d103fed435be", GitTreeState:"clean"}

创建自己的chart

我们创建一个名为mychart的chart,看一看chart的文件结构。

$ helm create mongodb
$ tree mongodb
mongodb
├── Chart.yaml #Chart本身的版本和配置信息
├── charts #依赖的chart
├── templates #配置模板目录
│   ├── NOTES.txt #helm提示信息
│   ├── _helpers.tpl #用于修改kubernetes objcet配置的模板
│   ├── deployment.yaml #kubernetes Deployment object
│   └── service.yaml #kubernetes Serivce
└── values.yaml #kubernetes object configuration

2 directories, 6 files

模板

我们查看下deployment.yaml文件的内容。

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: {{ template "fullname" . }}
  labels:
    chart: "{{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}"
spec:
  replicas: {{ .Values.replicaCount }}
  template:
    metadata:
      labels:
        app: {{ template "fullname" . }}
    spec:
      containers:
      - name: {{ .Chart.Name }}
        image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
        imagePullPolicy: {{ .Values.image.pullPolicy }}
        ports:
        - containerPort: {{ .Values.service.internalPort }}
        livenessProbe:
          httpGet:
            path: /
            port: {{ .Values.service.internalPort }}
        readinessProbe:
          httpGet:
            path: /
            port: {{ .Values.service.internalPort }}
        resources:
{{ toyaml .Values.resources | indent 12 }}

这是该应用的Deployment的yaml配置文件,其中的双大括号包扩起来的部分是Go template,其中的Values是在values.yaml文件中定义的:

# Default values for mychart.
# This is a yaml-formatted file.
# Declare variables to be passed into your templates.
replicaCount: 1
image:
  repository: nginx
  tag: stable
  pullPolicy: IfNotPresent
service:
  name: nginx
  type: ClusterIP
  externalPort: 80
  internalPort: 80
resources:
  limits:
    cpu: 100m
    memory: 128Mi
  requests:
    cpu: 100m
    memory: 128Mi

比如在Deployment.yaml中定义的容器镜像image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"其中的:

  • .Values.image.repository就是nginx

  • .Values.image.tag就是stable

以上两个变量值是在create chart的时候自动生成的默认值。

我们将默认的镜像地址和tag改成我们自己的镜像harbor-001.jimmysong.io/library/nginx:1.9。

检查配置和模板是否有效

当使用kubernetes部署应用的时候实际上讲templates渲染成最终的kubernetes能够识别的yaml格式。

使用helm install --dry-run --debug <chart_dir>命令来验证chart配置。该输出中包含了模板的变量配置与最终渲染的yaml文件。

$ helm install --dry-run --debug mychart
Created tunnel using local port: '58406'
SERVER: "localhost:58406"
CHART PATH: /Users/jimmy/Workspace/github/bitnami/charts/incubator/mean/charts/mychart
NAME:   filled-seahorse
REVISION: 1
RELEASED: Tue Oct 24 18:57:13 2017
CHART: mychart-0.1.0
USER-SUPPLIED VALUES:
{}

COMPUTED VALUES:
image:
  pullPolicy: IfNotPresent
  repository: harbor-001.jimmysong.io/library/nginx
  tag: 1.9
replicaCount: 1
resources:
  limits:
    cpu: 100m
    memory: 128Mi
  requests:
    cpu: 100m
    memory: 128Mi
service:
  externalPort: 80
  internalPort: 80
  name: nginx
  type: ClusterIP

HOOKS:
MANIFEST:

---
# Source: mychart/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
  name: filled-seahorse-mychart
  labels:
    chart: "mychart-0.1.0"
spec:
  type: ClusterIP
  ports:
  - port: 80
    targetPort: 80
    protocol: TCP
    name: nginx
  selector:
    app: filled-seahorse-mychart

---
# Source: mychart/templates/deployment.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: filled-seahorse-mychart
  labels:
    chart: "mychart-0.1.0"
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: filled-seahorse-mychart
    spec:
      containers:
      - name: mychart
        image: "harbor-001.jimmysong.io/library/nginx:1.9"
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
        livenessProbe:
          httpGet:
            path: /
            port: 80
        readinessProbe:
          httpGet:
            path: /
            port: 80
        resources:
            limits:
              cpu: 100m
              memory: 128Mi
            requests:
              cpu: 100m
              memory: 128Mi

我们可以看到Deployment和Service的名字前半截由两个随机的单词组成,最后才是我们在values.yaml中配置的值。

部署到kubernetes

在mychart目录下执行下面的命令将nginx部署到kubernetes集群上。

helm install .
NAME:   eating-hound
LAST DEPLOYED: Wed Oct 25 14:58:15 2017
NAMESPACE: default
STATUS: DEPLOYED

RESOURCES:
==> v1/Service
NAME                  CLUSTER-IP     EXTERNAL-IP  PORT(S)  AGE
eating-hound-mychart  10.254.135.68  <none>       80/TCP   0s

==> extensions/v1beta1/Deployment
NAME                  DESIRED  CURRENT  UP-TO-DATE  AVAILABLE  AGE
eating-hound-mychart  1        1        1           0          0s


NOTES:
1. Get the application URL by running these commands:
  export POD_NAME=$(kubectl get pods --namespace default -l "app=eating-hound-mychart" -o jsonpath="{.items[0].metadata.name}")
  echo "Visit http://127.0.0.1:8080 to use your application"
  kubectl port-forward $POD_NAME 8080:80

现在nginx已经部署到kubernetes集群上,本地执行提示中的命令在本地主机上访问到nginx实例。

export POD_NAME=$(kubectl get pods --namespace default -l "app=eating-hound-mychart" -o jsonpath="{.items[0].metadata.name}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl port-forward $POD_NAME 8080:80

在本地访问http://127.0.0.1:8080即可访问到nginx。

查看部署的relaese

$ helm list
NAME            REVISION    UPDATED                     STATUS      CHART            NAMESPACE
eating-hound    1           Wed Oct 25 14:58:15 2017    DEPLOYED    mychart-0.1.0    default

删除部署的release

$ helm delete eating-hound
release "eating-hound" deleted

打包分享

我们可以修改Chart.yaml中的helm chart配置信息,然后使用下列命令将chart打包成一个压缩文件。

helm package .

打包出mychart-0.1.0.tgz文件。

依赖

我们可以在requirements.yaml中定义应用所依赖的chart,例如定义对mariadb的依赖:

dependencies:
- name: mariadb
  version: 0.6.0
  repository: https://kubernetes-charts.storage.googleapis.com

使用helm lint .命令可以检查依赖和模板配置是否正确。

安装源

使用第三方chat库

  • 添加fabric8库

$ helm repo add fabric8 https://fabric8.io/helm
  • 搜索fabric8提供的工具(主要就是fabric8-platform工具包,包含了CI、CD的全套工具)

$ helm search fabric8

我们在前面安装chart可以通过HTTP server的方式提供。

$ helm serve
Regenerating index. This may take a moment.
Now serving you on 127.0.0.1:8879

访问http://localhost:8879可以看到刚刚安装的chart。

点击链接即可以下载chart的压缩包。

注意事项

下面列举一些常见问题,和在解决这些问题时候的注意事项。

服务依赖管理

所有使用helm部署的应用中如果没有特别指定chart的名字都会生成一个随机的Release name,例如romping-frog、sexy-newton等,跟启动docker容器时候容器名字的命名规则相同,而真正的资源对象的名字是在YAML文件中定义的名字,我们成为App name,两者连接起来才是资源对象的实际名字:Release name-App name。

而使用helm chart部署的包含依赖关系的应用,都会使用同一套Release name,在配置YAML文件的时候一定要注意在做服务发现时需要配置的服务地址,如果使用环境变量的话,需要像下面这样配置。

env:
 - name: SERVICE_NAME
   value: "{{ .Release.Name }}-{{ .Values.image.env.SERVICE_NAME }}"

这是使用了Go template的语法。至于{{ .Values.image.env.SERVICE_NAME }}的值是从values.yaml文件中获取的,所以需要在values.yaml中增加如下配置:

image:
  env:
    SERVICE_NAME: k8s-app-monitor-test

解决本地chart依赖

在本地当前chart配置的目录下启动helm server,我们不指定任何参数,直接使用默认端口启动。

helm serve

将该repo加入到repo list中。

helm repo add local http://localhost:8879

然后下载依赖到本地。

helm dependency update

这样所有的chart都会下载到本地的charts目录下。

设置helm命令自动补全

为了方便helm命令的使用,helm提供了自动补全功能,如果使用zsh请执行:

source <(helm completion zsh)

如果使用bash请执行:

source <(helm completion bash)

部署MEAN测试案例

MEAN是用来构建网站和web应用的免费开源的JavaScript软件栈,该软件栈包括MongoDB、Express.js、Angular和Node.js。

下载charts

$ git clone https://github.com/bitnami/charts.git
$ cd charts/incubator/mean
$ helm dep list
NAME       VERSION    REPOSITORY                                           STATUS
mongodb    0.4.x      https://kubernetes-charts.storage.googleapis.com/    missing

缺少mongodb的依赖,需要更新一下chart。

注:https://kubernetes-charts.storage.googleapis.com/是Google维护的chart库,访问该地址可以看到所有的chart列表。

$ helm dep update
Hang tight while we grab the latest from your chart repositories...
...Unable to get an update from the "local" chart repository (http://127.0.0.1:8879/charts):
    Get http://127.0.0.1:8879/charts/index.yaml: dial tcp 127.0.0.1:8879: getsockopt: connection refused
...Successfully got an update from the "stable" chart repository
Update Complete. ⎈Happy Helming!⎈
Saving 1 charts
Downloading mongodb from repo https://kubernetes-charts.storage.googleapis.com/

所有的image都在 values.yaml 文件中配置。

下载缺失的chart。

$ helm dep build
Hang tight while we grab the latest from your chart repositories...
...Unable to get an update from the "local" chart repository (http://127.0.0.1:8879/charts):
    Get http://127.0.0.1:8879/charts/index.yaml: dial tcp 127.0.0.1:8879: getsockopt: connection refused
...Successfully got an update from the "stable" chart repository
Update Complete. ⎈Happy Helming!⎈
Saving 1 charts
Downloading mongodb from repo https://kubernetes-charts.storage.googleapis.com/

修改mongodb chart配置

将刚才下载的charts/mongodb-0.4.17.tgz给解压后,修改其中的配置:

  • 将persistence下的enabled设置为false

  • 将image修改为我们的私有镜像:harbor-001.jimmysong.io/library/bitnami-mongodb:3.4.9-r1

执行helm install --dry-run --debug .确定模板无误。

将修改后的mongodb chart打包,在mongodb的目录下执行:

helm package .

现在再访问前面启动的helm server http://localhost:8879将可以在页面上看到mongodb-0.4.17这个chart。

我们对官方chart配置做了如下修改后推送到了自己的chart仓库:

  • requirements.yaml和requirements.lock文件中的repository为http://localhost:8879

  • 将values.yaml中的storageClass设置为null

  • 将values.yaml中的Image都改为私有镜像

  • repositroy都设置为http://localhost:8879

注:因为我们没有使用PVC所以将所有的关于持久化存储的配置都设置为false了。

部署MEAN

在mean目录下执行:

helm install .
NAME:   orbiting-platypus
LAST DEPLOYED: Wed Oct 25 16:21:48 2017
NAMESPACE: default
STATUS: DEPLOYED

RESOURCES:
==> v1/Secret
NAME                       TYPE    DATA  AGE
orbiting-platypus-mongodb  Opaque  2     2s

==> v1/ConfigMap
NAME                    DATA  AGE
orbiting-platypus-mean  1     2s

==> v1/Service
NAME                       CLUSTER-IP      EXTERNAL-IP  PORT(S)    AGE
orbiting-platypus-mongodb  10.254.144.208  <none>       27017/TCP  2s
orbiting-platypus-mean     10.254.165.23   <none>       80/TCP     2s

==> extensions/v1beta1/Deployment
NAME                       DESIRED  CURRENT  UP-TO-DATE  AVAILABLE  AGE
orbiting-platypus-mean     1        1        1           0          2s
orbiting-platypus-mongodb  1        1        1           0          2s


NOTES:

Get the URL of your Node app  by running:

  export POD_NAME=$(kubectl get pods --namespace default -l "app=orbiting-platypus-mean" -o jsonpath="{.items[0].metadata.name}")
  echo http://127.0.0.1:8080/
  kubectl port-forward $POD_NAME 8080:80

这样MEAN软件栈就部署到你的kuberentes集群里面了(默认是在default namespace下)。

验证检查

为了验证MEAN是否安装成功过,可以使用kubectl get pods查看pod是否启动完成,会先启动mongodb的pod,然后启动MEAN中的4步init。

访问Web UI

在Ingress中增加如下配置:

  - host: mean.jimmysong.io
    http:
      paths:
      - backend:
          serviceName: orbiting-platypus-mean
          servicePort: 80
        path: /

然后在页面中更新ingress:

kubectl repalce -f ingress.yaml

然后在本地的/etc/hosts文件中增加一条配置:

172.20.0.119 mean.jimmysong.io

注:172.20.0.119即边缘节点的VIP。

因为该页面需要加载google的angularjs、还有两个css在国内无法访问,可以使用curl测试:

curl mean.jimmysong.io

将会返回HTML内容:

<!doctype html>

<!-- ASSIGN OUR ANGULAR MODULE -->
<html ng-app="scotchTodo">

<head>
    <!-- META -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- Optimize mobile viewport -->

    <title>Node/Angular Todo App</title>

    <!-- SCROLLS -->
    <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css">
    <!-- load bootstrap -->
    <link rel="stylesheet" href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.min.css">
    <style>
        html {
            overflow-y: scroll;
        }

        body {
            padding-top: 50px;
        }

        #todo-list {
            margin-bottom: 30px;
        }

        #todo-form {
            margin-bottom: 50px;
        }
    </style>

    <!-- SPELLS -->
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.min.js"></script>
    <!-- load angular -->

    <script src="js/controllers/main.js"></script>
    <!-- load up our controller -->
    <script src="js/services/todos.js"></script>
    <!-- load our todo service -->
    <script src="js/core.js"></script>
    <!-- load our main application -->

</head>
<!-- SET THE CONTROLLER -->

<body ng-controller="mainController">
    <div class="container">

        <!-- HEADER AND TODO COUNT -->
        <div class="jumbotron text-center">
            <h1>I'm a Todo-aholic <span class="label label-info">{{ todos.length }}</span></h1>
        </div>

        <!-- TODO LIST -->
        <div id="todo-list" class="row">
            <div class="col-sm-4 col-sm-offset-4">



                <!-- LOOP OVER THE TODOS IN $scope.todos -->
                <div class="checkbox" ng-repeat="todo in todos">
                    <label>
                        <input type="checkbox" ng-click="deleteTodo(todo._id)"> {{ todo.text }}
                    </label>
                </div>

                <p class="text-center" ng-show="loading">
                    <span class="fa fa-spinner fa-spin fa-3x"></span>
                </p>

            </div>
        </div>

        <!-- FORM TO CREATE TODOS -->
        <div id="todo-form" class="row">
            <div class="col-sm-8 col-sm-offset-2 text-center">
                <form>
                    <div class="form-group">

                        <!-- BIND THIS VALUE TO formData.text IN ANGULAR -->
                        <input type="text" class="form-control input-lg text-center" placeholder="I want to buy a puppy that will love me forever" ng-model="formData.text">
                    </div>

                    <!-- createToDo() WILL CREATE NEW TODOS -->
                    <button type="submit" class="btn btn-primary btn-lg" ng-click="createTodo()">Add</button>
                </form>
            </div>
        </div>

        <div class="text-center text-muted">
            <p>A demo by <a href="http://scotch.io">Scotch</a>.</p>
            <p>Read the <a href="http://scotch.io/tutorials/javascript/creating-a-single-page-todo-app-with-node-and-angular">tutorial</a>.</p>
        </div>

    </div>

</body>

</html>

注:Todo中的文字来自What does the fox say?

测试完成后可以使用下面的命令将mean chart推送的本地chart仓库中。

在mean目录下执行:

helm package .

再次刷新http://localhost:8879将可以看到如下三个chart:

  • mean

    • mean-0.1.3

  • mongodb

    • mongodb-0.4.17

  • mychart

    • mychart-0.1.0

参考

Templates目录下是yaml文件的模板,遵循语法。使用过的静态网站生成工具的人应该对此很熟悉。

在浏览器中访问可以看到所有本地的chart。

关于Ingress配置请参考:

访问 可以看到如下界面,我在其中添加几条todo:

Helm
charts
Go template
Hugo
http://localhost:8879
边缘节点配置
http://mean.jimmysong.io
Deploy, Scale And Upgrade An Application On Kubernetes With Helm
Go template
How To Create Your First Helm Chart
Speed deployment on Kubernetes with Helm Chart – Quick yaml example from scratch
Helm chart源
TODO应用的Web页面