使用 Kubernetes 在 Windows 10 上创建本地集群


【编者的话】本文主要记录了作者在 Windows 上使用 Kubernetes 创建简单节点应用的过程。其中使用了 Minikube、Helm 等工具,并给出了相应的配置,可以帮助读者从概念到操作上有一个直观的了解。

最近我的一个客户在他们的核心基础设施中开始尝试使用 Kubernetes,可能有些读者对 Kubernetes 不太熟悉,Kubernetes 是由 Google 开发的 DevOps 工具,可以用以管理容器化的服务。 所有迹象都表明 Kubernetes 在 DevOps 中正在成为一颗新星,所以我觉得我也要研究一下。

老实说,我原以为容器的概念会是下一个潮流。对我来说,工作中使用容器进行抽象并没有获得多大好处。这么说的部分原因是我对科技潮流的愤世嫉俗,另一方面源自我对系统管理有限的经验。事实证明,容器的概念会保留下来,至少现在会。

目标

我的目标是使用 Kubernetes 启动一个简单的节点应用,以便可以更好地理解 Kubernetes 是如何运行的。节点应用是一个简单的 REST API,只有一个 endpoint,除了几个 package 外没有其他实际的依赖或环境要求。为了在学习曲线上增加点难度,我将在 Kubernetes 集群上使用 Helm Chart 来管理,定义和安装程序。

创建本地集群

与许多开发者不同,我主要在 Windows 上工作。 请不要误解,我不是一个受虐狂,我所有的开发都是在 VirtualBox 中的 Ubuntu VM 上进行的。但是,这样做让我在局域网上设置 Kubernetes 集群时处于劣势。与大多数开源工具一样,Kubernetes 是为在 unix 环境中工作而设计的,因此在某些方面上存在一些冲突。

首先在我的机器上安装 Minikube。 Minikube 的开发人员友好地提供了多种操作系统的版本,包括 Windows。安装 Minikube 本身很简单,并且已经安装了 VirtualBox,所以我可以马上尝试启动并运行集群。

安装 minikube 和 kubectl


Minikube 非常棒,因为尽管 Kubernetes 设计用于多节点, 但 Minikube 允许在本地网络中只用一个 VM 创建工作集群。如果你的电脑硬件配置有限的话,这就非常有帮助。

容器化

看到这里,如果想跳过此部分,可以使用我 push 到 dockerhub 的公共测试镜像,直接跳到下一章节。

考虑到 Kubernetes 是一个容器编排工具,下一步就是创建容器化应用,我使用已经在虚拟机中安装的 Docker 来完成,在节点中创建一个简单的测试应用程序。如果你完全在 Windows 下工作,同样也有相应版本可以达到相同效果。

几行代码就可以写好一个简单 app 的 Dockerfile。
FROM node:8.5.0 

WORKDIR /usr/src/node-service

Install node packages

COPY package.json ./
RUN npm install

Copy the source for the app

COPY . .

Run the app

CMD ["npm", "start"]

Expose container ports

EXPOSE 3000

接下来在本地编译 Docker 镜像,并启动容器,测试各个部分都如预期工作正常。
docker build -t fullbit/node-service .
docker run -p 3000:3000 -d fullbit/node-service

确认无误后,我会把镜像 push 到 dockerhub 的 repository 上,没有账号的话需要创建一个。
docker login
docker push fullbit/node-service:latest

一旦你掌握,上述所有创建 Dockerfile、push 镜像到 repository 的操作都会非常简单。对我来说,最初的学习曲线是理解镜像容器之间的区别,一旦理解,工作起来就会很轻松。

Helm Charts

我的客户的基础设施依赖 Helm Chart,所以我也打算自己探索一下。Helm Chart 是一个帮助你定义、安装及更新 Kubernetes 的工具,安装 Helm 也很简单,如下:
  1. 下载安装文件
  2. 压并将 helm.exe 放到与 kubectl 相同的 bin 文件夹中
  3. 打开 CMD,运行 helm 确认安装
  4. 在 CMD 中运行 helm init 命令在 minikube 集群上安装 Tiller


运行 helm create node-service 便可以轻松创建 chart,会生成一个包含某些文件的文件夹。 基本概念是,使用 Chart.yaml 定义 chart,然后在 values.yaml 中定义模板值。然后通过将这些值插入模板目录中的模板,从而生成 Kubernetes 清单。

要为节点应用程序配置一个非常基础的工作 chart,我们只需对生成的图表文件进行一些更改即可。首先,需要定义 Docker 容器镜像的 repository 和 service 的值:
values.yaml

replicaCount: 1

image:
repository: fullbit/node-service
tag: latest
pullPolicy: IfNotPresent

service:
type: NodePort
port: 3000
nodePort: 30001

ingress:
enabled: false
annotations: {}
path: /
hosts:
- chart-example.local
tls: []

resources: {}

nodeSelector: {}

tolerations: []

affinity: {} 

接下来需要使用 service 端口值更新部署模板:
templates/deployment.yaml

apiVersion: apps/v1beta2
kind: Deployment
metadata:
name: {{ template "node-service.fullname" . }}
labels:
app: {{ template "node-service.name" . }}
chart: {{ template "node-service.chart" . }}
release: {{ .Release.Name }}
heritage: {{ .Release.Service }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
  app: {{ template "node-service.name" . }}
  release: {{ .Release.Name }}
template:
metadata:
  labels:
    app: {{ template "node-service.name" . }}
    release: {{ .Release.Name }}
spec:
  containers:
    - name: {{ .Chart.Name }}
      image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
      imagePullPolicy: {{ .Values.image.pullPolicy }}
      ports:
        - name: http
          containerPort: {{ .Values.service.port }}
          protocol: TCP
      livenessProbe:
        httpGet:
          path: /
          port: http
      readinessProbe:
        httpGet:
          path: /
          port: http
      resources:
{{ toYaml .Values.resources | indent 12 }}
{{- with .Values.nodeSelector }}
  nodeSelector:
{{ toYaml . | indent 8 }}
{{- end }}
{{- with .Values.affinity }}
  affinity:
{{ toYaml . | indent 8 }}
{{- end }}
{{- with .Values.tolerations }}
  tolerations:
{{ toYaml . | indent 8 }}
{{- end }} 

最后必须使用 service 值更新 service 模板:
templates/service.yaml

apiVersion: v1
kind: Service
metadata:
name: {{ template "node-service.fullname" . }}
labels:
app: {{ template "node-service.name" . }}
chart: {{ template "node-service.chart" . }}
release: {{ .Release.Name }}
heritage: {{ .Release.Service }}
spec:
type: {{ .Values.service.type }}
ports:
- port: {{ .Values.service.port }}
  nodePort: {{ .Values.service.nodePort }}
  protocol: TCP
  name: http
selector:
app: {{ template "node-service.name" . }}
release: {{ .Release.Name }} 

应用默认会运行在一个内网 IP 上,外网不可访问。要将应用暴露给外网,我们定义了一个 nodePort 服务来将应用程序容器公开到托管应用程序节点上的一个端口。

可以点击这里了解 Kubernetes 服务的更多信息。

下面使用 helm package node-service 打包 helm chart 用于部署,使用 helm install node-service-0.1.0.tgz 部署。

访问 <node IP>:<nodePort>,检查应用是否正常运行。我们运行的是 Minikube,所以只有一个节点,可以用下面的命令得到节点的 IP:
kubectl get nodes --namespace default -o jsonpath="{.items[0].status.addresses[0].address}" 

至此,我们就完工了!使用 Helm 和 Kubernetes 将应用部署到了本地集群,使用 nodePort 服务将服务暴露给外网,可以使用浏览器访问应用。
hello-world-1.png

尽管 Helm 本身不是太复杂,但我确实发现额外的抽象层会令人困惑。但看起来 Helm 确实可以非常方便地管理 Kubernetes 中的应用程序。如果你正在处理多个大型应用程序,我可以看预见 Helm 特有的价值。

结语

对 Kubernetes 及其工作原理要学习的还有很多,但基本设置相对简单易行。现在我算是初步入门,我对这项技术感觉不错,更多的把它看做是一个有用的工具 而不是把它当作是一个黑匣子。

原文链接:Kubernetes: Setting up a cluster locally on Windows 10(翻译:李加庆

0 个评论

要回复文章请先登录注册