如何使用Okteto在Kubernetes上开发应用程序

来自菜鸟教程
跳转至:导航、​搜索

作为 Write for DOnations 计划的一部分,作者选择了 Girls Who Code 来接受捐赠。

介绍

Okteto CLI 是一个开源项目,为在 Kubernetes 上运行的应用程序提供本地开发体验。 有了它,您可以在本地 IDE 上编写代码,一旦保存文件,更改就可以推送到您的 Kubernetes 集群,您的应用程序将立即更新。 整个过程无需构建 Docker 映像或应用 Kubernetes 清单即可完成,这可能需要相当长的时间。

在本教程中,您将在开发 Kubernetes 原生应用程序时使用 Okteto 来提高工作效率。 首先,您将创建一个 Kubernetes 集群并使用它来运行一个标准的“Hello World”应用程序。 然后,您将使用 Okteto 开发和自动更新您的应用程序,而无需在本地安装任何东西。

先决条件

在开始本教程之前,您需要以下内容:

第 1 步 — 创建 Hello World 应用程序

“Hello World”程序是 Web 开发中由来已久的传统。 在这种情况下,它是一个简单的 Web 服务,它对每个请求都响应“Hello World”。 现在您已经创建了 Kubernetes 集群,让我们在 Golang 中创建一个“Hello World”应用程序以及您将用于在 Kubernetes 上部署它的清单。

首先更改到您的主目录:

cd ~

现在创建一个名为 hello_world 的新目录并在其中移动:

mkdir hello_world
cd hello_world

使用您喜欢的 IDE 或文本编辑器创建并打开一个名为 main.go 的新文件:

nano main.go

main.go 将是一个返回消息 Hello world! 的 Golang Web 服务器。 因此,让我们使用以下代码:

main.go

package main

import (
    "fmt"
    "net/http"
)

func main() {
    fmt.Println("Starting hello-world server...")
    http.HandleFunc("/", helloServer)
    if err := http.ListenAndServe(":8080", nil); err != nil {
        panic(err)
    }
}

func helloServer(w http.ResponseWriter, r *http.Request) {
    fmt.Fprint(w, "Hello world!")
}

main.go 中的代码执行以下操作:

  • Go 源文件中的第一条语句必须是 package 名称。 可执行命令必须始终使用 package main
  • import 部分指示代码所依赖的包。 在这种情况下,它使用 fmt 进行字符串操作,并将 net/http 用于 HTTP 服务器。
  • main 函数是二进制文件的入口点。 http.HandleFunc方法用于配置服务器在收到对/路径的请求时调用helloServer函数。 http.ListenAndServe 启动一个 HTTP 服务器,它侦听端口 8080 上的所有网络接口。
  • helloServer 函数包含您的请求处理程序的逻辑。 在这种情况下,它将写入 Hello world! 作为对请求的响应。

您需要创建一个 Docker 映像并将其推送到您的 Docker 注册表,以便 Kubernetes 可以拉取它,然后运行应用程序。

使用您喜欢的 IDE 或文本编辑器打开一个名为 Dockerfile 的新文件:

nano Dockerfile

Dockerfile 将包含构建应用程序的 Docker 容器所需的命令。 让我们使用以下代码:

Dockerfile

FROM golang:alpine as builder
RUN apk --update --no-cache add bash
WORKDIR /app
ADD . .
RUN go build -o app

FROM alpine as prod
WORKDIR /app
COPY --from=builder /app/app /app/app
EXPOSE 8080
CMD ["./app"]

Dockerfile 包含两个阶段,builderprod

  • builder 阶段包含 Go 构建工具。 它负责复制文件并构建 Go 二进制文件。
  • prod 阶段是最终图像。 它将只包含一个精简的操作系统和应用程序二进制文件。

这是一个很好的做法。 它使您的生产容器更小更安全,因为它们只包含您的应用程序以及运行它所需的内容。

构建容器镜像(将 your_DockerHub_username 替换为您的 Docker Hub 用户名):

docker build -t your_DockerHub_username/hello-world:latest

现在将其推送到 Docker Hub:

docker push your_DockerHub_username/hello-world:latest

接下来,为 Kubernetes 清单创建一个新文件夹:

mkdir k8s

当你使用 Kubernetes 清单时,你告诉 Kubernetes 你希望你的应用程序如何运行。 这一次,您将创建一个 deployment 对象。 因此,使用您喜欢的 IDE 或文本编辑器创建一个新文件 deployment.yaml

nano k8s/deployment.yaml

以下内容描述了一个运行 okteto/hello-world:latest Docker 镜像的 Kubernetes 部署对象。 将此内容添加到您的新文件中,但在您的情况下,将 image 标签后列出的 okteto 替换为 your_DockerHub_username

~/hello_world/k8s/deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-world
spec:
  selector:
    matchLabels:
      app: hello-world
  replicas: 1
  template:
    metadata:
      labels:
        app: hello-world
    spec:
      containers:
      - name: hello-world
        image: your_DockerHub_username/hello-world:latest
        ports:
        - containerPort: 8080

部署清单包含三个主要部分:

  • metadata 定义部署的名称。
  • replicas 定义了你想要运行的副本数。
  • template 告诉 Kubernetes 部署什么,添加什么标签。 在这种情况下,单个容器,带有 okteto/hello-world:latest 图像,侦听端口 8080,并带有 app: hello-world 标签。 请注意,此标签与 selector 部分中使用的标签相同。

您现在需要一种方法来访问您的应用程序。 您可以通过创建 service 对象在 Kubernetes 上公开应用程序。 让我们继续使用清单来做到这一点。 使用您喜欢的 IDE 或文本编辑器创建一个名为 service.yaml 的新文件:

nano k8s/service.yaml

以下内容描述了公开 hello-world 部署对象的服务,该对象在后台将使用 DigitalOcean 负载均衡器:

k8s/service.yaml

apiVersion: v1
kind: Service
metadata:
  name: hello-world
spec:
  type: LoadBalancer
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080
      name: http
  selector:
    app: hello-world

服务清单有四个主要部分:

  • metadata 告诉 Kubernetes 如何命名你的服务。
  • type 告诉 Kubernetes 你想如何公开你的服务。 在这种情况下,它将通过数字海洋负载均衡器将其暴露在外部。
  • ports 标签告诉 Kubernetes 您要公开哪些端口,以及如何将它们映射到您的部署。 在这种情况下,您将在外部公开端口 80 并将其定向到部署中的端口 8080
  • selector 告诉 Kubernetes 如何引导流量。 在这种情况下,任何带有 app: hello-world 标签的 pod 都会收到流量。

您现在已准备好在 Kubernetes 上部署“Hello World”应用程序。 我们接下来会这样做。

第 2 步 — 部署您的 Hello World 应用程序

在这一步中,您将在 Kubernetes 上部署您的“Hello World”应用程序,然后您将验证它是否正常工作。

首先在 Kubernetes 上部署您的应用程序:

kubectl apply -f k8s

您将看到以下输出:

Outputdeployment.apps "hello-world" created
service "hello-world" created

大约一分钟左右后,您将能够检索应用程序的 IP。 使用此 kubectl 命令检查您的服务:

kubectl get service hello-world

您将看到这样的输出,其中列出了您的 Kubernetes 服务对象。 在 EXTERNAL-IP 列中记下您的应用程序的 IP:

OutputNAME          TYPE        CLUSTER-IP         EXTERNAL-IP       PORT(S)    AGE
hello-world   ClusterIP   your_cluster_ip   your_external_ip  8080/TCP   37s

打开您的浏览器并转到为您的“Hello World”应用程序列出的 your_external_ip。 在继续下一步之前,请确认您的应用程序已启动并正在运行。

直到现在,您都遵循了使用 Kubernetes 开发应用程序的相当传统的途径。 展望未来,每当您想更改应用程序中的代码时,您都必须构建并推送一个新的 Docker 镜像,然后从 Kubernetes 中拉取该镜像。 这个过程可能需要相当长的时间。 Okteto 旨在简化这种开发内部循环。 让我们看一下 Okteto CLI,看看它如何提供帮助。

第 3 步 — 安装 Okteto CLI

现在,您将通过安装 Okteto CLI 来提高 Kubernetes 开发效率。 Okteto 命令行界面 是一个开源项目,可让您将应用程序代码更改同步到在 Kubernetes 上运行的应用程序。 您可以继续使用您最喜欢的 IDE、调试器或编译器,而无需像在前面的步骤中那样提交、构建、推送或重新部署容器来测试您的应用程序。

要在 macOS 或 Linux 机器上安装 Okteto CLI,请运行以下命令:

curl https://get.okteto.com -sSfL | sh

让我们仔细看看这个命令:

  • curl 命令用于将数据传输到服务器或从服务器传输数据。
  • -s 标志禁止任何输出。
  • -S 标志显示错误。
  • -f 标志会导致请求因 HTTP 错误而失败。
  • -L 标志使请求遵循重定向。
  • | 运算符将此输出通过管道传递给 sh 命令,该命令将在本地计算机上下载并安装最新的 okteto 二进制文件。

如果您运行的是 Windows,您也可以通过网络浏览器 下载文件 并手动将其添加到您的 $PATH

安装 Okteto CLI 后,您就可以将“Hello World”应用程序置于开发模式。

第 4 步 — 将您的 Hello World 应用程序置于开发模式

Okteto CLI 旨在将 Kubernetes 集群上运行的应用程序与您机器中的代码交换。 为此,Okteto 使用 Okteto manifest 文件提供的信息。 此文件声明将与您的本地代码交换的 Kubernetes 部署对象。

使用您喜欢的 IDE 或文本编辑器创建一个名为 okteto.yaml 的新文件:

nano okteto.yaml

让我们编写一个基本清单,您可以在其中定义部署对象名称、要使用的 Docker 基础映像和一个 shell。 我们稍后将返回此信息。 使用以下示例内容文件:

okteto.yaml

name: hello-world
image: okteto/golang:1
workdir: /app
command: ["bash"]

准备通过运行以下命令将您的应用程序置于开发模式:

okteto up
Output ✓  Development environment activated
 ✓  Files synchronized
    Namespace: default
    Name:      hello-world

Welcome to your development environment. Happy coding!
default:hello-world /app>

okteto up 命令将“Hello World”应用程序交换到开发环境中,这意味着:

  • Hello World 应用程序容器使用 docker 映像 okteto/golang:1 进行更新。 此映像包含构建、测试、调试和运行“Hello World”应用程序所需的开发工具。
  • 创建 文件同步服务 以使您的更改在本地文件系统和应用程序 pod 之间保持最新。
  • 远程 shell 在您的开发环境中启动。 现在您可以像在本地机器上一样构建、测试和运行您的应用程序。
  • 无论您在远程 shell 中运行什么进程,都将获得与原始“Hello World”应用程序 pod 相同的传入流量、相同的环境变量、卷或机密。 这反过来又为您提供了一个高度逼真的、类似生产的开发环境。

在同一个控制台中,现在像往常一样运行应用程序(无需构建和推送 Docker 映像),如下所示:

go run main.go
OutputStarting hello-world server...

第一次运行应用程序时,Go 将下载你的依赖项并编译你的应用程序。 等待此过程完成并通过打开浏览器并刷新应用程序页面来测试您的应用程序,就像您之前所做的那样。

现在您已准备好开始直接在 Kubernetes 上进行开发。

第 5 步 — 直接在 Kubernetes 上开发

让我们开始对“Hello World”应用程序进行更改,然后看看这些更改如何反映在 Kubernetes 中。

使用您喜欢的 IDE 或文本编辑器打开 main.go 文件。 例如,打开一个单独的控制台并运行以下命令:

nano main.go

然后,将您的响应消息更改为 Hello world from DigitalOcean!

main.go

package main

import (
    "fmt"
    "net/http"
)

func main() {
    fmt.Println("Starting hello-world server...")
    http.HandleFunc("/", helloServer)
    if err := http.ListenAndServe(":8080", nil); err != nil {
        panic(err)
    }
}

func helloServer(w http.ResponseWriter, r *http.Request) {
    fmt.Fprint(w, "Hello world from DigitalOcean!")
}

正是在这里,您的工作流程发生了变化。 Okteto 无需构建镜像和重新部署容器来更新“Hello World”应用程序,而是将您的更改同步到 Kubernetes 上的开发环境。

从您执行 okteto up 命令的控制台,按 CTRL + C 取消 go run main.go 的执行。 现在重新运行应用程序:

default:hello-world /app> go run main.go
OutputStarting hello-world server...

返回浏览器并重新加载“Hello World”应用程序的页面。

您的代码更改会立即应用到 Kubernetes,而且无需任何提交、构建或推送。

结论

Okteto 只需单击一个按钮,即可将您的 Kubernetes 集群转变为功能齐全的开发平台。 在本教程中,您安装并配置了 Okteto CLI 以尽可能快地在 Kubernetes 上直接迭代您的代码更改,就像您键入代码一样快。 现在您可以前往 Okteto 示例存储库 了解如何将 Okteto 与不同的编程语言和调试器一起使用。

此外,如果您与团队共享 Kubernetes 集群,请考虑让每个成员访问安全的 Kubernetes 命名空间,该命名空间配置为与在同一集群上工作的其他开发人员隔离。 DigitalOcean Kubernetes Marketplace 中的 Okteto App 也提供了这一强大功能。