分类目录归档:Docker

Helm 入门指南

  Helm 为Kubernetes的软件包管理工具,Helm有两部分组成:Helm客户端、Tiller服务端,Helm三个主要部件:Chart、仓库、Release;

Chart:为Kubernetes中应用程序所需要的资源的定义。
仓库:为存储Helm chart的仓库,可从仓库中下载chart直接使用
Release: Kubernetes中运行的chart实例,每个chart可多次安装,每次安装都是一个新版本;

Helm 常见指令:

  helm search 在仓库中查找chart
enter image description here
enter image description here

  helm inspect stable/mongodb 可查看该chart的介绍信息;
  helm install stable/mongodb 可直接下载该chart并安装该chart;

版本升级:
  helm upgrade releaseName .
enter image description here

  helm rollback releaseName 1 回滚到版本1

  从零开始通过helm发布Kubernetes项目:

一、结构介绍

初始化项目:

helm create nginx  

  执行完后创建名为nginx的chart,现在查看nginx目录中的文件:

enter image description here

charts:目录用于存放所依赖的子chart
chart.yaml:为当前chart的说明文件,也可在模板中访问该文件;
templates:目录为nginx项目的模板目录,通常会使用values.yaml配置内容进行填充,板引擎渲染此目录的文件后Tiller将渲染得到的结果 提交给Kubernetes创建响应的对象;
values.yaml:为值文件,定义模板中需要使用的值,在templates的模板文件中将访问改值;
enter image description here

  在templates目录中有可以看到deployment.yaml、ingress.yaml、service.yaml文件这些为定义Kubernetes deployment、ingress、service对象的模板文件;
NOTES.txt:为安装chart成功后的说明文件
_helpers.tpl:模板助手文件,定义的值可在模板中使用;

二、通过helm在Kubernetes中部署Nginx

1、helm 初步使用

  现在删除template目录中的所有文件、清空values.yaml文件中所有内容

enter image description here

  部署nginx需要一个deployment控制器与对外提供服务的service,现在我们分别手动创建这个两个文件并编写相关内容;

deployment.yaml :

 apiVersion: apps/v1
 kind: Deployment
 metadata:
   name: nginx-deployment
   labels:
     app: nginx
 spec:
   replicas: 3
   selector:
     matchLabels:
       app: nginx
   template:
     metadata:
       labels:
         app: nginx
     spec:
       containers:
       - name: nginx
         image: nginx:1.7.9
         ports:
         - containerPort: 80      

service.yaml

 apiVersion: v1
 kind: Service
 metadata:
  name: nginx-service
 spec:
  selector:
    app: nginx
  type: NodePort
  ports:
  - port: 80
    nodePort: 30078

  此时我们在上级目录执行:helm install nginx 已经可以将nginx部署到Kubernetes中;

enter image description here

  但如果只是这样使用Helm,那它存在的意义也不大,既然说template目录是模板目录当然它里面的模板文件也不能只是这么使用,要让模板文件体现出它的模型性质;下面我们将使用Helm的模板等功能,让模板文件体现出他的模板性质;

2、helm 模板
  目前为止deployment.yaml与service.yaml虽然是放在模板目录下但是完全没有体现出他的模板性质,现在我们开始这两个文件的模板化;

模板语法基础:

  内置对象:helm中有这么这个常用内置对象:Release、Values、Chart、Files、Capabilities、Template;

Release:此对象描述当前release,内置有:Release.Name release名称、Release.Time 发布时间等等等对面;
Values:此对象为从values.yaml文件与用户提供的文件中传递到模板的对值对象;
Chart:此对象为chart.yaml文件所提供的数据对象;
Files:提供了对chart非特殊文件的访问;
Capabilities:这提供了Kubernetes集群信息的访问;
Template:正在执行的当前模板信息

  下面我们通过helm内置对象Values来实现deployment.yaml、service.yaml文件的模板化,Values对象的取值范围:
1、当前chart的values.yaml文件;
2、如当前为子chart,则来自父chart的values.yaml文件;
3、在helm install或helm update执行是通过-f参数传递的文件;
4、通过helm install 时通过 –set设置的值;

  如values.yaml文件中存在replicaCount: 1对象,则在模板文件中通过{{ .Values.replicaCount }}即可访问到values.yaml文件定义的对象值1;

  通过_helpers.tpl可定义命名模板,下面定义模板deploy.name

 {{- define "deploy.name" -}}
 demo-deploy-nginx
 {{- end }}

  其中:{{ – 表示删除左侧的空格 – }} 删除右侧的空格
  此时可在模板文件中通过{{ template “deploy.name” . }} 引用该命名模板;

实现模板化:

  提取需要模板化的数据,这里提取出deployment对象的name、labels、replicas、matchLabels、template的labels、template spec的name、image;service对象的name、selector labels、type、port、nodePort等配置;
  我们再从提取出来的配置中挑选出name类与labels类配置定义为命名模板存放在_helpers.tpl文件中,其他的配置项定义在Values.yaml文件中;

_helpers.tpl文件内容如下:存放了deploy名称、service名称、deploy的lables、deploy中pod的lables;

{{- define "deploy.name" -}}
 demo-deploy-nginx
{{- end }}

{{- define "service.name" -}}
demo-service-nginx
{{- end }}

{{- define "labels" -}}
demo: nginx
{{- end}}

{{- define "deploy.labels" -}}
deploy: nginx
{{- end}}

values.yaml 文件,此文件定义了副本数、镜像名称与版本、service类型、端口等:

# 定义模板默认值
replicaCount: 1
image:
  repository: nginx
  tag: 1.7.9

service:
  type: NodePort
  port: 80
  nodePort: 30078

  值文件定义好了此时需要在模板deployment、service文件中引用上述两个文件所定义的值,下面开始重构deployment.yaml与service.yaml文件:

service.yaml文件:

apiVersion: v1
kind: Service
metadata: 
 name: {{ template "service.name" . }}
spec: 
 selector:
  {{ template "labels" . }}
 type: {{ .Values.service.type }}
 ports: 
 - port: {{ .Values.service.port }}
   nodePort: {{ .Values.service.nodePort }}

deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata: 
  name: {{ template "deploy.name" . }}
  labels: 
    {{ template "deploy.labels" .}}
spec:
  replicas: {{ .Values.replicaCount }}
  selector:
   matchLabels:
      {{ template "labels" . }}
 template: 
    metadata:
      labels:
        {{ template "labels" . }}
    spec:
      containers:
      - name: {{ .Chart.Name}}
        image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
        ports:
        - containerPort: 80

  模板文件编写好后可以再重新使用Helm install部署nginx试试,执行前先执行helm delete running-chipmunk卸载掉之前安装的;

enter image description here

参考资料: https://docs.helm.sh/

使用Skaffold一键将项目发布到Kubernetes

  当前skaffold版本为v0.4,还未发布正式版本,不建议在生产环境中使用;
  skaffold用于开发人员快速部署程序到Kubernetes中;skaffold提供了dev、run两种模式;使用skaffold需先编写skaffold配置文件,该文件为定义skaffold的工作流;
  Skaffold工作流定义了三个主要阶段Build、Push、Deploy

enter image description here

一、Build
  在构建阶段,Skaffold通过Dockerfile使用源码生成Artifacts,Skaffold中目前Docker镜像、bazel这两种Artifacts,这里使用的是Docker镜像所以也可以成称为Docker镜像,该镜像用于应用程序的运行,Build阶段的输出就是Artifacts;
二、Push
  在推送阶段,Skaffold将把构建阶段生成的Docker镜像推送到Docker镜像仓库中,并使用所配置的镜像名称;在运行Skaffold时需确保镜像能够推送到镜像仓库中;
  但如果使用的是Minikube或 Docker for Desktop本地Kubernetes集群时默认是不推送到镜像仓库的,跳过推送阶段,因为本地已经存在了该镜像所以是可以正常运行的;
三、Deploy
  部署阶段,将最新的Docker镜像部署到k8s中,该阶段可以使用不同的部署工具如kubectl或helm,每个工具都有不一样的参数用于定义如何安装与更新应用程序;

概念介绍

Artifacts
  在Build阶段通过运行一系列步骤来创建Artifacts,在Skaffold中Artifacts分为bazel与Docker镜像,可以定义Skaffold生成多个Docker镜像,Skaffold在开发模式运行时,Skaffold只会重新生成源码已经更改的Docker镜像,通过在Skaffold配置中指定Dockerfile来生成Docker镜像,并指定其名称;

标签策略
  标签策略在Build阶段进行配置,用于配置Skaffold在推送Docker镜像时如果对镜像进行打标签,目前Skaffold支持三种标签策略:sha256标签生成器、git标签生成器、自定义标签生成器策略
  在开发过程中,推荐使用基于内容的标签策略sha256,方便在源代码变更时Skaffold会使Kubernetes重新部署新Docker镜像;

运行模式

  Skaffold有dev、run两种运行模式,也就是开发模式与发布模式,在dev模式下Skaffold会监控项目的源码随着代码的变更会实时的重新生产镜像并将变更更新部署到Kubernetes中;还可在CI/CD管道中运行Skaffold;

  dev模式默认使用sha256标签生成器
  run模式默认使用git标签生成器

  所以注意如果使用run模式又没配置git则Skaffold是无法跑下去的,需配置标签策略(TagPolicy),或配置git即可;

使用流程:

  开发环境使用skaffold部署项目到远程k8s中;
  1、下载skaffold
https://github.com/GoogleCloudPlatform/skaffold/releases/download/v0.4.0/skaffold-windows-amd64.exe
  2、下载kubectl、服务端开放Docker远程连接
在服务端Docker配置中加上: -H tcp://0.0.0.0:2375
  在开发端在创建C:\Users\xin.docker\config.json文件,内容如下:

 {
    "auths" : {
    }
 }

  3、开发端kubectl 配置
  创建C:\Users\xin.kube\config.json文件,配置k8s的连接与密钥,文件内容如下:

 apiVersion: v1
 clusters:
 - cluster:
     server: http://182.61.xx.xxx:8001
   name: minikube
 contexts:
 - context:
     cluster: minikube
     user: minikube
   name: minikube
 current-context: minikube
 kind: Config
 preferences: {}
 users:
 - name: minikube
   user:
 as-user-extra: {}

  4、服务端kubectl使用开启代理
  kubectl proxy –address 0.0.0.0 –accept-hosts ‘.*’
  5、环境变量配置
  需要在环境变量中配置Docker的链接信息:

 DOCKER_HOST = tcp://xxx.xxx.xxx.xxx:2375
 DOCKER_TLS_VERIFY = 0

  下载Demo并使用Skaffold将其部署到Kubernetes中;

  git clone https://github.com/GoogleCloudPlatform/skaffold
  cd examples/getting-started

运行:skaffold dev

enter image description here
enter image description here

  可以看到由于使用的是Minikube所以只有Build、Deploy两个阶段跳过了Push阶段,与我们上面的说法是一致的;
修改main.go的内容即可看到Skaffold检测到了变化,并重新把项目更新到Kubernetes中;

enter image description here
enter image description here

  常见异常信息:

 WARN[0005] run: build: build step: running build: read auth configs: docker config: opening docker config: 
 open C:\Users\xin\.docker\config.json: no such file or directory   

不存在.docker\confog.json文件,在用户目录下添加上即可;

 open //./pipe/docker_engine: The system cannot find the file specified. In the default daemon configuration on 
 Windows, the docker client must be run elevated to connect. This error may also indicate that the docker 
 daemon is not running.  

  未配置Docker环境变量,加上DOCKER_HOST、DOCKER_TLS_VERIFY环境变量即可;

本文使用的环境为:minikube、skaffold v0.4、windows

参考资料: https://github.com/GoogleCloudPlatform/skaffold/blob/master/docs/concepts.md