通过Telepresence在Kubernetes上建立微服务的开发环境

这篇文章涉及以下三个方面。

    • Microservices on Kubernetes の開発環境の課題と Telepresence の概要

 

    • Telepresence を使い、ローカルのコンテナから Kubernetes 上のサービスにアクセスするサンプル

 

    Telepresence を利用した、Spring Bootの開発環境のサンプルと解説

背景概况

在Kubernetes上进行微服务的开发环境所面临的挑战。

在 Kubernetes 上开发微服务时,如何为某个服务准备依赖关系是一个问题。

当试图在本地准备所有依赖时,会出现模拟云提供资源或计算机资源不足的问题。

如果在Kubernetes上尝试进行全部开发,那么在开发过程中很难进行调试。
为了能够适当地进行调试,开发人员需要全面了解Kubernetes。

这个问题涉及了Telepresence的开发者Datawire的微服务架构指南,《Development environments for Kubernetes》中概述了其中包含的其他优点和缺点。

遠隔存在技術(Telepresence)是指在不同地點之間透過科技實現身临其境的感覺。

作为解决上述问题的方法之一,可以通过将个人电脑与Kubernetes连接,并在本地进行开发,同时使用VPN查看Kubernetes上的依赖关系。

能够实现这一目标的就是 “远程交互”(Telepresence)。
“远程交互”是一个开源软件(OSS),也是 CNCF 沙盒项目的其中之一。

验证环境

本次我们在以下环境下进行了验证。

$ telepresence --version
0.97
$ docker --version
Docker version 18.09.2, build 6247962
$ kubectl version
Client Version: version.Info{Major:"1", Minor:"13", GitVersion:"v1.13.1", GitCommit:"eec55b9ba98609a46fee712359c7b5b365bdd920", GitTreeState:"clean", BuildDate:"2018-12-13T19:44:10Z", GoVersion:"go1.11.2", Compiler:"gc", Platform:"darwin/amd64"}
Server Version: version.Info{Major:"1", Minor:"11+", GitVersion:"v1.11.5-eks-6bad6d", GitCommit:"6bad6d9c768dc0864dab48a11653aa53b5a47043", GitTreeState:"clean", BuildDate:"2018-12-06T23:13:14Z", GoVersion:"go1.10.3", Compiler:"gc", Platform:"linux/amd64"}

Kubernetes正在使用Amazon EKS。

演示示范

我们将执行Telepresence的文档示例。

部署样本应用程序

首先根据 Telepresence 的文档,部署示例应用程序。

$ kubectl run qotm --image=datawire/qotm:1.3 --port=5000 --expose

远程互动的实际样例

使用Telepresence,可以通过–docker-run选项在本地启动一个可以与Kubernetes通信的容器。

比如,可以按照以下方式启动。

$ telepresence --docker-run --rm -it alpine sh

使用curl命令,确认访问刚刚部署的示例应用程序。

# apk add --no-cache curl
# curl http://qotm:5000/
{"hostname":"qotm-5969b5f959-vv82j","ok":true,"quote":"The light at the end of the tunnel is interdependent on the relatedness of motivation, subcultures, and management.","time":"2019-02-26T07:13:41.112912","version":"1.3"}

以这种方式,可以非常轻松地访问在Kubernetes上的应用程序。

远程存在 -docker-run之后的部分通常会提供与普通的docker run命令相同的选项。

当我们实际查看Telepresence的帮助文件时…

$ telepresence -h
usage: telepresence [-h] [--version] [--verbose] [--logfile LOGFILE]
                    [--method {inject-tcp,vpn-tcp,container}]
                    [--new-deployment DEPLOYMENT_NAME | --swap-deployment DEPLOYMENT_NAME[:CONTAINER]
                    | --deployment EXISTING_DEPLOYMENT_NAME]
                    [--context CONTEXT] [--namespace NAMESPACE]
                    [--expose PORT[:REMOTE_PORT]]
                    [--also-proxy CLOUD_HOSTNAME] [--mount PATH_OR_BOOLEAN]
                    [--env-json FILENAME] [--env-file FILENAME]
                    [--run-shell | --run ... | --docker-run ...]
    :
    :
    :
  --docker-run ...      Run a Docker container, by passing the arguments to
                        'docker run', e.g. '--docker-run -i -t ubuntu:16.04
                        /bin/bash'. Requires --method container.

这段文字的意思是要求给Docker运行命令(docker run)提供参数。

通过 telepresence –docker-run 命令,在内部执行 docker run 命令,并且可以通过 ./telepresence.log 查看执行的详细内容。

$ cat ./telepresence.log
    :
    :
    :
 256.9 TEL | Main process (docker run --name=telepresence-1551165091-314365-90696 --network=container:telepresence-1551165070-841074-90696 -e=TELEPRESENCE_POD -e=TELEPRESENCE_CONTAINER -e=KUBERNETES_SERVICE_PORT -e=KUBERNETES_PORT_443_TCP_PROTO -e=QOTM_SERVICE_HOST -e=QOTM_PORT_5000_TCP -e=QOTM_PORT_5000_TCP_PORT -e=QOTM_PORT_5000_TCP_ADDR -e=KUBERNETES_SERVICE_HOST -e=KUBERNETES_PORT_443_TCP -e=KUBERNETES_PORT_443_TCP_PORT -e=KUBERNETES_PORT_443_TCP_ADDR -e=QOTM_PORT -e=QOTM_PORT_5000_TCP_PROTO -e=KUBERNETES_SERVICE_PORT_HTTPS -e=KUBERNETES_PORT -e=QOTM_SERVICE_PORT -e=TELEPRESENCE_ROOT -e=TELEPRESENCE_METHOD --volume=/tmp/tel-5i3c8wyy/fs:/tmp/tel-5i3c8wyy/fs --init --rm -it alpine sh)
    :
    :
    :

我们可以看出,通过在Telepresence上添加环境变量等选项后执行docker run。

搭建Spring Boot的开发环境

我們已經理解了Telepresence的概述,現在開始實際搭建Spring Boot的開發環境。

创建Shell脚本

構築開発环境只需准备以下的shell脚本。

#!/bin/bash
#
# 開発環境のコンテナを起動するスクリプト
#
# 引数1. 開発対象のプロジェクトホームディレクトリ
#
# <実行例>
# ./develop.sh .
#

set -o errexit
set -o nounset
set -o pipefail
set -o xtrace

readonly DEVELOP_PROJECT_DIR="$1"
readonly DEVELOP_PROJECT_ABSOLUTE_DIR=$(cd ${DEVELOP_PROJECT_DIR}; pwd)

readonly IMAGE='openjdk:8u191-jdk-alpine3.8'
readonly APP_PORT='8080'
readonly DEBUG_PORT='5005'

readonly CONTAINER_WORKING_DIR='/opt/work'

telepresence \
  --docker-run \
  --rm \
  -p "${APP_PORT}":"${APP_PORT}" \
  -p "${DEBUG_PORT}":"${DEBUG_PORT}" \
  -v "${DEVELOP_PROJECT_ABSOLUTE_DIR}":"${CONTAINER_WORKING_DIR}" \
  -v ~/.m2:/root/.m2 \
  -w "${CONTAINER_WORKING_DIR}" \
  "${IMAGE}" \
  ./mvnw spring-boot:run \
  -Drun.jvmArguments="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=${DEBUG_PORT}"

解释

我将按顺序解释上述Shell脚本的要点。

使用spring-boot-devtools实现热部署

写代码并构建容器进行运行检验会花费太多时间,因此我们使用spring-boot-devtools。

在pom.xml中添加spring-boot-devtools,然后使用./mvnw spring-boot:run命令来启动,这样可以实时反映源代码的变化。

关键点在于 `-v “${DEVELOP_PROJECT_ABSOLUTE_DIR}”:”${CONTAINER_WORKING_DIR}”` 这部分,它将项目主目录挂载到容器的工作目录。

通过这个方法,即使不在容器中进行开发,也可以在本地使用IDE进行开发。

※ 使用 IntelliJ 操作 spring-boot-devtools 时,请注意需要在 IntelliJ 中进行额外设置。

–删除选项

我在本地运行容器时基本上都会加上 –rm 选项。
通过加上 –rm 选项,容器会在停止时被删除。
这样可以防止电脑上积累不需要的容器。

使用挂载m2目录来利用Maven缓存。

如果每次使用 –rm 来重新创建容器,那么 .m2 目录下的 Maven 缓存将无法工作,导致每次启动都需要花费较长时间。

通过将~/.m2:/root/.m2挂载成.m2目录,解决了这个问题。

不推荐在不使用 –rm 选项的情况下重复使用容器的解决方案,因为这样会导致不删除容器的动机,可能会导致不具备可复现性的开发环境。

调试器的执行

在容器上运行应用程序时,调试器仍然可以正常使用。
只需在启动命令中添加”-Drun.jvmArguments=”-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=${DEBUG_PORT}”选项,并使用”-p “${DEBUG_PORT}”:”${DEBUG_PORT}””的方式将调试器端口转发到主机上。
这样,IDE的调试器就可以正常工作了。

总结

如果仅使用 –docker-run,Telepresence 的学习成本非常低。虽然还有一些高级应用方法,比如在 Kubernetes 上进行部署替换,但首先尝试使用 –docker-run 似乎是个不错的选择。

这次我们以Spring Boot开发环境为例,但要在容器上搭建开发环境,需要了解一些诀窍。
例如,如果要在容器上使用webpack-dev-server,如果不进行配置更改,它将无法实现热重载。

要想熟练运用Kubernetes及其相关工具,似乎需要实际构建并积累经验。

在释义提及的话题中,是否应该将Telepresence进行容器化,只需要一个选择。

在使用Amazon EKS + Mac上的Telepresence时,会涉及许多工具,具体如下。

    • Docker

 

    • AWS CLI

 

    • kubectl

 

    • aws-iam-authenticator

 

    • osxfuse

 

    Telepresence

无论如何,安装Docker是必要的,但对于所有开发者安装其他5个工具可能有些麻烦。
因此,考虑将除了Docker以外的5个工具都容器化并分发。

容器化的好处是什么?

    • 開発環境セットアップの手間が減る

 

    開発者から Kubernetes を隠蔽できる

我认为是这样的点。

一方,不使用容器化的好处是

    • 興味を持った開発者にとって開発環境を理解するコストが下がる

 

    開発者が少しずつ Kubernetes にふれ、学んでいく可能性がある

我认为是这一点。

通过将远程存在技术容器化,可提高可携性,但也可能导致Dev-Ops分离等问题。这是一个并非所有情况都适用容器化的例子。

可以提供一个参考

    • Telepresence

 

    • 開発用マシンからKubernetesのクラスタ内ネットワークに透過的にアクセスする

 

    Telepresence で EKS 上の k8s クラスタをデバッグする
广告
将在 10 秒后关闭
bannerAds