-
使用一个非root用户的运行时
-
将构建时的阶段命名为类似build
-
指定构建的基础架构,比如linux
-
使用版本做标签,比如3.6。 如果你使用latest,那会导致不可预知的情况。
FROM golang:1.9.4 as buildWORKDIR /go/src/github.com/openfaas/faas/gatewayCOPY . .RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o gateway .FROM alpine:3.6RUN addgroup -S app \ && adduser -S -g app appWORKDIR /home/appEXPOSE 8080ENV http_proxy ""ENV https_proxy ""COPY --from=build /go/src/github.com/openfaas/faas/gateway/gateway .COPY assets assetsRUN chown -R app:app ./USER appCMD ["./gateway"]
注意:如果你想要使用OpenShift(一个Kubernetes的发行版),那么你必须保证你所有的Docker镜像都是以非root用户运行的。
1.1 获得Kubernetes
你需要在你的笔记本或者开发机上装好Kubernetes。 可以阅读我写的一篇博文[2],描述了在Mac上运行Docker和Kubernetes的所有常用选项。
如果你之前已经用过Docker了,那么你可能已经熟悉容器这个词了。在Kubernetes的词汇表里面你会很少直接操作容器,取而代之的是抽象为Pod的概念。
一个Pod是一个到多个容器组成的一个组,里面的这些容器被集中的调度和部署并通过环回接口127.0.0.1互相访问。
这里给出一个例子,说明Pod抽象的用处:比方说你有一个传统的应用,本身没有TLS/SSL支持。它可以与一个配置了TLS的Nginx或者其它Web服务器部署到一个Pod中。这么做的优点是可以将多个容器部署到一起来扩展它的功能而不会带来破坏性改变。
2. 创建YAML文件
-
gateway-svc.yml //代表一个service服务
-
gateway-dep //代表一个deployment
kubectl apply -f ./yaml/
当你需要运行在其它的操作系统或者架构(类似Raspberry Pi)时,我们推荐将文件放到一个新的目录里面,类似yaml_arm的目录名。
Deployment的例子
这里给出一个Deployment的例子,用来部署NATS Streaming[3](一个轻量级的分发工作的流平台):
apiVersion: apps/v1beta1kind: Deploymentmetadata: name: nats namespace: openfaasspec: replicas: 1 template: metadata: labels: app: nats spec: containers: - name: nats image: nats-streaming:0.6.0 imagePullPolicy: Always ports: - containerPort: 4222 protocol: TCP - containerPort: 8222 protocol: TCP command: ["/nats-streaming-server"] args: - --store - memory - --cluster_id - faas-cluster
一个deployment也可以声明在启动时给service(服务)创建多个副本或者实例。
Service 定义
apiVersion: v1kind: Servicemetadata: name: nats namespace: openfaas labels: app: natsspec: type: ClusterIP ports: - port: 4222 protocol: TCP targetPort: 4222 selector: app: nats
Service提供了一种机制可以在你的Deployment的多个副本之间对请求做负载均衡。在之前的例子中我们只有单副本的NATS Streaming,但是如果我们有多个副本,它们每个都有独立的IP地址,追踪它们就会变成问题。使用Service的优点是它可以有一个静态IP地址和DNS入口,通过它们可以随时访问到任意一个副本。
Service不是直接映射到Deployment的,它映射到label(标签)上。在上面的例子中Service会寻找app=nats的标签。标签可以在运行时状态下从Deployment(或者其它API对象)上增加或者删除,这样在你的集群中重定向流量就相当容易。这些可以方便的启用A/B测试或者滚动发布。
学习Kubernetes相关YAML语法的最好方式是查看官方文档里面相关的API对象的章节,你可以从中找到YAML或者kubectl使用的例子。
更多API对象的文档请查看:https://kubernetes.io/docs/concepts/。
2.1 Helm
Helm说它自己是Kubernetes的包管理器。 从我的观点来看它主要提供了两个主要功能:
分发你的应用(在一个Chart里面)
一旦你已经准备好分发你项目的yaml文件时,你可以将它们打包提交到Helm仓库中。这样其它人就可以找到你的应用,通过一条命令就可以安装。Chart本身可以有版本控制,也可以指定依赖与其它的Chart。
这里有三个Chart的例子:OpenFaaS[4]、Kakfa[5]和Minio[6]。
让编辑更简单
Helm支持Go语言的内嵌模板,你可以将通用的配置项目放到一个文件里面。所以如果你发布了一组新的Docker镜像需要做更新,你只需要在一个地方做修改。你也可以写条件判断语句,这样将flag和helm命令一起使用可以在部署时启用不同的配置项和feature。
在正常的Yaml文件里面我们这样定义容器镜像:
image: functions/gateway:0.7.5
使用Helm模板我们这样做:
image: {{ .Values.images.gateway }}
然后在一个单独的文件中我们可以定义imags.gateway的值。Helm能让我们做的另一件事情是使用条件判断——当要支持多个架构或者feature时非常有用。
下面再给一个例子展现如何选择应用ClusterIP或者NodePort,这是暴露集群中某个服务的两种不同方式。NodePort会将服务暴露到集群以外,所以你可能需要控制什么时候要这个功能。
如果我们使用常规的YAML文件,那意味着我们需要两组配置文件:
spec: type: {{ .Values.serviceType }} ports: - port: 8080 protocol: TCP targetPort: 8080 {{- if contains "NodePort" .Values.serviceType }} nodePort: 31112 {{- end }}
在这个例子里面“.serviceType”可以是ClusterIP或者NodePort,下面的语句说明在条件满足时将nodePort元素加入到YAML中。
3. 使用ConfigMaps
kind: ConfigMapapiVersion: v1metadata: labels: app: prometheus name: prometheus-config namespace: openfaasdata: prometheus.yml: | scrape_configs: - job_name: 'prometheus' scrape_interval: 5s static_configs: - targets: ['localhost:9090']
你可以将它加载进一个Deployment或者Pod中:
volumeMounts: - mountPath: /etc/prometheus/prometheus.yml name: prometheus-config subPath: prometheus.yml volumes: - name: prometheus-config configMap: name: prometheus-config items: - key: prometheus.yml path: prometheus.yml mode: 0644
查看完整例子:ConfigMap Prometheus config[7]。
更多文档查看:https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/。
4. 使用安全的Secret
-
在集群中定义secret
-
通过mount加载进一个Deployment/Pod中
5. 实现健康检查health-checks
总结
-
创建好的Docker镜像
-
书写好的Kubernetes清单(YAML文件)
-
使用ConfigMap来将配置和代码解耦
-
使用Secret来保护API Key这样的隐私数据
-
使用liveness 和readiness探针来实现弹性和自愈
-
https://www.openfaas.com/
-
https://blog.alexellis.io/docker-for-mac-with-kubernetes/
-
https://github.com/nats-io/nats-streaming-server
-
https://github.com/openfaas/faas-netes/tree/master/chart/openfaas
-
https://github.com/kubernetes/charts/tree/master/incubator/kafka
-
https://github.com/kubernetes/charts/tree/master/stable/minio
-
https://github.com/openfaas/faas-netes/blob/master/yaml/prometheus.yml
-
https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/