前言与安装

Okteto 是一个通过在K8s中来开发和测试代码的应用程序开发工具,可以通过Okteto在K8s中一键为我们启动一个开发环境,或者是安装一个docker容器,非常简单方便。

来自 www.okteto.com

index

okteto 让开发流程变得更快

development-environments

本地代码,远程执行。不需要提交、部署、等待CI构建。okteto 启动一个云环境来部署应用程序堆栈,可以在里面实时更改。

  1. 开发人员可能更多的把时间投放到构建应用程序上
  2. 开发人员无需担心安装,配置和运行各类环境工具,减轻了硬件的负担
  3. okteto 成功支持各种 IDE ,学习成本更低
  4. okteto 适用于任何应用程序。

preview-environments

  1. 可以预览每次请求的代码变更
  2. 除了程序开发人员以外,有更多的人可以参与审查与开发的过程,从而更快的获得产品的反馈
  3. okteto 由 k8s 提供支持,所以可以继续以相同的方式构建

pricing

customers

monday.com

  1. 每个开发人员都可以一键启动完全配置的开发环境
  2. 开发人员可以访问共享的集群中的基础设施
  3. 在一个或者多个组件上工作,无需提交、构建或推送即可同步更改
  4. 本地机器运行的更快

LaunchDarkly

  1. 员工可以迅速建立工作堆栈
  2. 允许团队和客户尽早参与开发过程
  3. 加快开发速度

privacy dynamics

  1. 开发生产速度加快
  2. 跨职能协作
  3. 开发早起过程中的客户反馈

docs

安装

安装 Okteto CLI
curl https://get.okteto.com -sSfL | sh
使用

在执行相关操作之前,需要先申请一个 okteto 帐户,然后等待批准。批准通过后可以继续进行操作。

将 Okteto CLI 配置为使用 Okteto Cloud

okteto context use https://cloud.okteto.com

之后确认一下是否 CLI 已配置

okteto context list

应当输出:

Name                        Namespace             Builder                                 Registry
https://cloud.okteto.com *  cindylopez            tcp://buildkit.cloud.okteto.net:1234    registry.cloud.okteto.net

试用

获取试用demo

git clone https://github.com/okteto/movies-with-compose
cd movies-with-compose

启动okteto

okteto up

进入控制台

链接:

https://cloud.okteto.com/

在左侧 Namespace 中,可以看到部署的 movies 项目,中间 Endpoints 即可看到项目的网络地址,记下来该地址,接下来的流程要用到。此处我的网址为:https://movies-darrinjin.cloud.okteto.net/

服务开发

在一段漫长的下载之后,会让我们选择 api 或 frontend,这里我们选择 api

    Select the development container you want to activate:
    Use the arrow keys to navigate: ↓ ↑ → ←
  ▸ api
    frontend

随后服务完全启动,可以通过上面记录的网址登入查看。

在网页中可以看到 Movies 和 Cindy 一样,只需打开/api/server.js并将第 43 行编辑为:

  db.collection('watching').find().toArray( (err, results) =>{

随后保存修改,刷新浏览器,即可看到更改被迅速同步。Okteto 的开发环境允许您对本地代码所做的更改立即反映在应用程序的已部署版本上。


概述

在使用 Okteto 设置开发环境时,需要以下两个步骤。

第一步、部署应用程序代码

第二步、执行 okteto up

在执行 okteto up 之前,需要安装 Okteto CLI。安装流程参考本文目录 - [docs]

可以选择使用现有集群进行交互,也可以使用 Okteto Cloud,除此之外还可以使用 Okteto 自托管。

在执行命令 okteto init 时,他会分析本地程序的源代码并自动选择一个基本的开发容器配置,并创建一个默认配置文件 okteto.yml

GoLang语言的配置文件内容大致如下:

dev:
  my-app:
    image: golang:alpine
    volumes:
      - /go/pkg/
      - /root/.cache/go-build/
    forward:
      - 8080:8080

Okteto CLI

尽管 Okteto 能够自动为我们创建配置文件,但是我们仍然需要一些部署内容的清单,他可以是现有的清单(例如 Helm、Kubernetes),Okteto 会根据这些清单生成 Okteto清单 - Okteto Manifest,并根据这个文件来启动开发环境。

如果您使用的是 Docker Compose 文件,那么 Okteto CLI 可以直接为您的应用程序启动开发环境,而无需生成 Okteto 清单。但是,如果您想对您的环境进行更多配置,您仍然可以选择创建 Okteto Manifest。

清单搜索位置

Okteto CLI 将按以下顺序为您的应用程序查找部署清单:

Okteto Manifest文件:如果您的文件夹中有okteto.ymlor.okteto/okteto.yml文件,Okteto 将使用此文件来部署您的开发环境。
Docker Compose文件:如果有okteto-compose.yamlordocker-compose.yaml文件,Okteto 将使用该文件来部署您的开发环境。
Helm Chart:如果有chart, charts, helm/chart, 或helm/charts目录中包含Chart.yaml文件,Okteto 将检测该图表并在其上运行helm upgrade --install以部署您的开发环境。
Kubernetes manifests文件夹:如果有manifests、kubernetes、 或k8s文件夹,Okteto 将检测并运行kubectl apply以部署您的开发环境。
Kubernetes manifests文件:如果有manifests.yaml, kubernetes.yaml, ork8s.yaml文件,Okteto 会检测到它并运行kubectl apply来部署你的开发环境
您还可以使用-f任何 Okteto CLI 命令上的标志明确定义 Okteto 清单的位置。

SSL端点部署

Okteto Cloud可以为部署自动创建SSL端点,在此之前需要在配置文件中添加以下内容:

  dev.okteto.com/auto-ingress: "true"

配置文件编辑实例:

apiVersion: v1
kind: Service
metadata:
  name: hello-world
  labels:
    app: hello-world
  annotations:
    dev.okteto.com/auto-ingress: "true"
spec:
  type: ClusterIP
  ports:
    - port: 8080
      protocol: TCP
      targetPort: 8080
  selector:
    app: hello-world

除此之外,如果有自定的配置或者需要指定的URL,也可以使用自己的配置文件。但是要注意,所有的主机都应以 -$NAMESPACE.cloud.okteto.net 来结尾。

注意

为了能够让配置文件可以运行在任何 Okteto Cloud 空间中,建议让 Okteto 自生成主机名。为此,需要在配置文件中添加以下内容:

  dev.okteto.com/generate-host: "true"

配置文件编辑实例:

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  annotations:
    dev.okteto.com/generate-host: "true"
  name: hello-world
spec:
  rules:
  - http:
      paths:
      - backend:
          serviceName: hello-world
          servicePort: 8080
        path: /

设置私有端点

Kubernetes

使用该注释,可以告知程序需要一个私有入口规则

  dev.okteto.com/auto-ingress: "private"

配置文件编辑实例:

apiVersion: v1
kind: Service
metadata:
  name: hello-world
  labels:
    app: hello-world
  annotations:
    dev.okteto.com/auto-ingress: "private"
spec:
  type: ClusterIP
  ports:
    - port: 8080
      protocol: TCP
      targetPort: 8080
  selector:
    app: hello-world

在更高级的环境下,可以将端点私有和程序入口一起使用,注释如下:

  dev.okteto.com/private: "true"

配置文件编辑实例:

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  annotations:
    dev.okteto.com/private: "true"
  name: hello-world
spec:
  rules:
  - http:
      paths:
      - backend:
          serviceName: hello-world
          servicePort: 8080
        path: /

如果您只想保护应用程序的某些端点(例如管理门户或指标 endopint),我们建议您创建两个入口:

  • 包含所有公共端点的路由的第一个入口
  • 带有dev.okteto.com/private注释的第二个入口,用于您的所有私有路由。

Docker

在Docker中存在一个扩展 —— Private Endpoints

可以通过添加如下内容来实现私有端点

dev.okteto.com/private: "true"

完整内容如下:

name: hello-world
services:
  hello-world:
    labels:
      dev.okteto.com/private: "true"
    build: hello
    port:
      - 8080:8080

在更高级的环境下可以在 endpoint 上进行定义

name: hello-world
endpoints:
  annotations:
    dev.okteto.com/private: "true"
  rules:
    - path: /
      service: hello-world
      port: 8080
services:
  hello-world:
    build: hello
    expose:
      - 8080

WARNING

私有端点使用您的 Okteto Cloud 帐户进行身份验证,因此它们最适合保护您和您的团队将通过浏览器访问的端点不建议将它们用于自动化或保护最终用户将访问的端点

私有端点仅限制对您的应用程序的外部访问。在您的命名空间中运行的应用程序将能够访问您的私有端点,而无需使用该service名称进行身份验证。

自定义域名

如果拥有自定义域名的话,可以将其添加到 Okteto Cloud 命名空间,从而实现自定义域名的使用。

Okteto Cloud

自动入口

若使用的是 Okteto 的自动入口生成,则无需更改,只需要重新部署即可。

在配置文件中更改字段 dev.okteto.com/auto-ingressdomain

apiVersion: v1
kind: Service
metadata:
  name: hello-service
  annotations:
    dev.okteto.com/auto-ingress: "domain"
spec:
  type: ClusterIP
  ports:
  - name: "hello-world"
    port: 8080
  selector:
    app: hello-world

自行创建

dev.okteto.com/generate-host 修改为 domain

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: hello-ingress
  annotations:
    dev.okteto.com/generate-host: "domain"
spec:
  rules:
  - http:
      paths:
      - backend:
          serviceName: hello-world
          servicePort: 8080

在此之后,Okteto 将在部署的时候生成正确的主机,通过以下命令可以查看

kubectl get ingress custom-dns
NAME         HOSTS          ADDRESS                                                     PORTS     AGE
custom-dns   myapp.com      104.155.138.215,104.197.238.82,104.198.241.5,35.224.92.98   80, 443   169m

Docker

如果使用 docker 的话,需要在配置自定义域名的服务添加标签:

services:
  fastapi:
    build: .
    replicas: 1
    ports:
      - 8080:8080
    environment:
      - DB_HOST=postgres://pguser:pgpass@postgres:5432/pgdb
      - secret=dev
    labels:
      dev.okteto.com/auto-ingress: "true"
  postgresql:
    image: bitnami/postgresql:latest
    ports:
      - 5432
    environment:
      - POSTGRES_USER=pguser
      - POSTGRES_PASSWORD=pgpass
      - POSTGRES_DB=pgdb
    volumes:
      - data:/bitnami/postgresql
volumes:
  data:

除此之外,还需要将自定义 DNS 指向 $NAMESPACE.cloud.okteto.net

可以通过如下命令确认 DNS 的更改情况:

host hello.myapp.com
hello.myapp.com is an alias for cindylopez.cloud.okteto.net.
cindylopez.cloud.okteto.net has address ...

demo体验

Java - demo

获取项目内容

git clone https://github.com/okteto/java-maven-getting-started
cd java-maven-getting-started

在其中可以看到对应的 okteto.yml 文件

build:
  hello-world:
    image: okteto.dev/java-maven-hello-world:1.0.0
    context: .
deploy:
  - kubectl apply -f k8s.yml
dev:
  hello-world:
    image: okteto/maven:3
    command: bash
    sync:
      - .:/usr/src/app
    forward:
      - 5005:5005
    volumes:
      - /root/.m2

部署开发环境

执行如下命令,之后可以在 Okteto Cloud 中看到该项目。值得注意的是,此时的网络请求是 https ,而这也是 Okteto 所自动生成的。

okteto deploy --build

激活开发环境

在这之前,我们可以先回去看看 yml 文件中的内容。着重强调的是 dev 部分。

dev:
  hello-world:
    image: okteto/maven:3
    command: bash
    sync:
      - .:/usr/src/app
    forward:
      - 5005:5005
    volumes:
      - /root/.m2

“Hello-world” 与部署的项目名相匹配

标签含义
image目标镜像
command启动命令
sync本地与容器之间同步的文件夹
forward从容器转发的端口列表
volumes持久化的路径列表

注意:文件 .stignore 指示了那些文件不应同步到开发容器中

激活开发容器

执行如下命令

okteto up

启动成功后输出如下:

 i  Using darrinjin @ cloud.okteto.com as context
 i  Development environment 'java-maven-getting-started' already deployed.
 i  To redeploy your development environment run 'okteto deploy' or 'okteto up [devName] --deploy'
 ✓  Persistent volume successfully attached
 ✓  Images successfully pulled
 ✓  Files synchronized
    Context:   cloud.okteto.com
    Namespace: darrinjin
    Name:      hello-world
    Forward:   5005 -> 5005

Welcome to your development container. Happy coding!
darrinjin:hello-world app> 

执行命令以启动项目,命令与本地计算机启动方式相同

mvn spring-boot:run

Spring boot项目启动输出内容此处不在展示。

体验Okteto

直接使用本地 IDE 打开 src/main/java/com/okteto/helloworld/RestHelloWorld.java

并修改 return 的返回消息

package com.okteto.helloworld;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class RestHelloWorld {
	
	@GetMapping("/")
	public String sayHello() {
		return "Welcome to try Okteto!";
	}
}

随后我们在 IDE 中直接编译刚刚编辑的 Java 文件,再次打开浏览器访问,文本就发生了改变。

回到 Spring boot 终端,可以看到在刷新浏览器的时候,输出了以下内容:

2022-07-18 07:58:26.723  INFO 130 --- [      Thread-33] o.s.s.concurrent.ThreadPoolTaskExecutor  : Shutting down ExecutorService 'applicationTaskExecutor'

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.1.8.RELEASE)

2022-07-18 07:58:27.152  INFO 130 --- [  restartedMain] com.okteto.helloworld.Application        : Starting Application on hello-world-okteto-5bb4d597c6-tjb98 with PID 130 (/usr/src/app/target/classes started by root in /usr/src/app)
2022-07-18 07:58:27.160  INFO 130 --- [  restartedMain] com.okteto.helloworld.Application        : No active profile set, falling back to default profiles: default
2022-07-18 07:58:28.999  INFO 130 --- [  restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
2022-07-18 07:58:29.013  INFO 130 --- [  restartedMain] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2022-07-18 07:58:29.013  INFO 130 --- [  restartedMain] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.24]
2022-07-18 07:58:29.081  INFO 130 --- [  restartedMain] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2022-07-18 07:58:29.081  INFO 130 --- [  restartedMain] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 1918 ms
2022-07-18 07:58:29.291  INFO 130 --- [  restartedMain] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'
2022-07-18 07:58:29.422  INFO 130 --- [  restartedMain] o.s.b.d.a.OptionalLiveReloadServer       : LiveReload server is running on port 35729
2022-07-18 07:58:29.592  INFO 130 --- [  restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2022-07-18 07:58:29.601  INFO 130 --- [  restartedMain] com.okteto.helloworld.Application        : Started Application in 2.545 seconds (JVM running for 966.622)
2022-07-18 07:58:29.608  INFO 130 --- [  restartedMain] .ConditionEvaluationDeltaLoggingListener : Condition evaluation unchanged

远程调试代码

此处使用 IDEA 2021.3.1 版本展示。

官方文档提供了 Eclipse 的操作方式:https://www.okteto.com/docs/samples/java/

首先打开我们的demo项目

点击菜单栏 Run - Edit Configurations

之后在弹出的框里自定义名字,点OK即可。

在 return 行标记断点,并debug该项目,返回浏览器再次刷新。之后可以看到请求的内容以及变量的内容:

在这里插入图片描述

GoLang - demo

获取项目内容

git clone https://github.com/okteto/go-getting-started
cd go-getting-started

可以在 okteto.yml 中看到配置文件

build:
  hello-world:
    image: okteto.dev/go-hello-world:1.0.0
    context: .

deploy:
  - kubectl apply -f k8s.yml

dev:
  hello-world:
    image: okteto/golang:1
    command: bash
    sync:
      - .:/usr/src/app
    volumes:
      - /go
      - /root/.cache
    securityContext:
      capabilities:
        add:
          - SYS_PTRACE
    forward:
      - 2345:2345

部署开发环境

执行如下命令

okteto deploy --build

输出内容:

 ✓  Image 'registry.cloud.okteto.net/darrinjin/go-hello-world:1.0.0' successfully pushed
 i  Running kubectl apply -f k8s.yml
deployment.apps/hello-world created
service/hello-world created
ingress.networking.k8s.io/hello-world created
 ✓  Development environment 'go-getting-started' successfully deployed
 i  Run 'okteto up' to activate your development container

如果你参考了本文的Java demo,务必在 Okteto Cloud 将Java项目 Destroy 掉,否则会输出以下内容

 ✓  Image 'registry.cloud.okteto.net/darrinjin/go-hello-world:1.0.0' successfully pushed
 i  Running kubectl apply -f k8s.yml
deployment.apps/hello-world configured
service/hello-world unchanged
ingress.networking.k8s.io/hello-world configured

成功后在控制台应当在 Endpoints 看到项目链接,此处也是由 Okteto 自动生成的 https 请求

激活开发环境

在 yml 文件中有如下内容

dev:
  hello-world:
    image: okteto/golang:1
    command: bash
    sync:
      - .:/usr/src/app
    volumes:
      - /go
      - /root/.cache
    securityContext:
      capabilities:
        add:
          - SYS_PTRACE
    forward:
      - 2345:2345

“Hello-world” 与部署的项目名相匹配

标签含义
image目标镜像
command启动命令
sync本地与容器同步的文件夹
volumes持久缓存路径列表
securityContextSYS_PTRACE是 Go 调试器所需的功能
forward从容器转发的端口列表

激活开发容器

执行命令

okteto up

输出内容如下:

 i  Using darrinjin @ cloud.okteto.com as context
 i  Development environment 'go-getting-started' already deployed.
 i  To redeploy your development environment run 'okteto deploy' or 'okteto up [devName] --deploy'
 ✓  Images successfully pulled
 ✓  Files synchronized
    Context:   cloud.okteto.com
    Namespace: darrinjin
    Name:      hello-world
    Forward:   2345 -> 2345

Welcome to your development container. Happy coding!
darrinjin:hello-world app> 

运行Go程序

go run main.go

此时返回浏览器,刷新一下即可看到内容

体验Okteto

使用本地 IDE 编辑修改文件main.go中的内容,第 17 行的响应消息修改为自定义的内容。

在终端中键入Ctrl + C 以中断 Go 程序,并重新键入

go run main.go

返回浏览器,页面内容已完成更改。

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐