万网网站空间购买,wordpress主题的连接函数,素材网免费,一起装修网北京总部官网前言使用C作为主要开发语言的程序猿们应该会认同搭建开发环境是一件烦人的事情。为了编译一个程序不仅需要下载各种依赖包#xff0c;还可能面临本地系统不兼容、编译器版本不一致、包版本冲突等各种问题。笔者在运营iLogtail开源社区的过程中发现开发和调试环境问题也是成员问…前言使用C作为主要开发语言的程序猿们应该会认同搭建开发环境是一件烦人的事情。为了编译一个程序不仅需要下载各种依赖包还可能面临本地系统不兼容、编译器版本不一致、包版本冲突等各种问题。笔者在运营iLogtail开源社区的过程中发现开发和调试环境问题也是成员问的最多的问题之一那么有没有一种方法可以彻底解决这一问题呢有。容器技术使应用在各种环境可以一键部署一致执行同样的原理也适用于开发环境部署。利用 VSCode 的 Remote-Development 插件就可以使整个开发环境运行在远程容器中。使用这种方式不但可以直接使用一致的环境开发编译而且还自然实现了多个开发环境的隔离。下面让就我们由浅到深搭建这样的远端容器开发环境。原理简介为什么要远程容器远程解决的是开发机资源问题和代码安全问题本地电脑的CPU和内存比较有限为了提高编译、测试效率一般都会准备一台专门用于开发测试的机器而部分公司为了防止代码外泄只允许内部开发机访问代码库。容器解决的是开发环境一致性问题。两者结合起来便能构建最理想的开发环境。在使用 Remote-Development 插件时插件会ssh连接到远程开发机然后根据配置直接启动或是铸造开发环境镜像后启动开发环境容器。启动时将开发机的Workspace目录作为源挂载到容器中。开发环境容器启动后插件会自动安装VS Code Server并安装配置指定的VS Code插件。一旦容器内的VS Code Server启动后本地的VS Code就会直接与容器内的VS Code Server建立通信。容器内可以访问Workspace所有文件并且修改不会因容器退出而丢失。容器开发环境可以使用的VS Code插件在Workspace的devcontainer.json配置中指定下文会有详细描述。为了提高启动速度并保留容器内插件的配置开发容器内的/vscode目录其实挂载了一个docker volume不会自动随docker退出而回收因此从第二次连接容器开发环境开始无需重新安装VS Code Server、插件等启动速度大大提高。环境准备要使VS Code可以远程连接开发机最好使用ssh密钥建立本地电脑和开发机的信任关系。要使用容器进行开发开发机上必须安装Docker。这两步相关教程网上较多在这里就不再赘述。需要注意的是要使VS Code通过ssh连上开发机并通过docker启动开发环境容器建立信任关系的账户必须具备docker使用权限。如果使用root账户那么自然具备。如果非root则可以使用任意一种方式使账户获得docker使用权限将用户加入docker组。参考Post-installation steps for Linux(https://docs.docker.com/engine/install/linux-postinstall)。sudo usermod -aG docker $USER将docker.sock权限修改为777不太推荐除非上述方法无法奏效。sudo chmod 777 /var/run/docker.sock下面假设开发机使用的是Linux系统并且与本地电脑已经建立好信任关系而且安装并具备Docker访问权限。安装插件在VS Code的Marketplace中搜索“Remote Development”安装插件。安装完成后会发现多出了3个子插件。Remote - Containers连接容器开发Remote - SSH连接ssh远程开发Remote - WSL连接WSLWindows Linux子系统开发使用镜像开发使用 Remote Development 插件最直接的方式就是利用现成的编译镜像启动开发容器。这里以使用C和Go语言编写、依赖环境相对复杂的开源项目iLogtail数据采集器项目为例说明如何利用 Remote Development 插件进行远程容器开发。1. 创建Remote Development配置在iLogtail Workspace的顶层目录创建.devcontainer目录并在里面创建devcontainer.json文件。配置文件的内容如下{image: sls-opensource-registry.cn-shanghai.cr.aliyuncs.com/ilogtail-community-edition/ilogtail-build-linux:latest,customizations: {vscode: {extensions: [golang.Go,ms-vscode.cpptools-extension-pack]}}
}其中image字段是Remote Development插件启动开发环境的镜像地址customizations.vscode.extensions指定了开发环境的插件。部分插件介绍如下开发者也可以按照自己的习惯进行修改。插件名用途golang.GoGo开发必备插件ms-vscode.cpptools-extension-packC开发必备插件2. 在容器中打开代码库使用Shift Command PMac或Ctrl Shift PWin打开命令面板输入reopen选择Remote-Containers: Reopen in Container。或者若出现如下图提示则可以直接点击在容器中重新打开。首次打开时会比较慢因为要下载镜像并安装插件后面再次打开时速度会很快。按照提示进行镜像Build。完成上述步骤后我们已经可以使用VS Code进行代码编辑并在其中进行代码编译。注如果以前拉取过编译镜像可能需要触发Remote-Containers: Rebuild Container重新构建。3. 在容器中进行开发开发容器启动后我们已经可以在VS Code中浏览Workspace代码了。但是随便打开一个文件满眼都是错误提示代码的跳转功能也不能正常工作。这是因为C开发环境的includePath没有被正确配置。打开命令面板输入C config选择C/C: Edit Configurations(UI)。找到Include path输入镜像内依赖库的路径。再回来看代码时错误提示都消失了并且函数定义跳转正常。4. 在容器中进行编译打开新Terminal找不到的可以在命令面板中输入Terminal选择新开一个编译iLogtail Go插件make vendor # 若需要更新插件依赖库
make plugin_local # 每次更新插件代码后从这里开始编译iLogtail C代码mkdir -p core/build # 若之前没有建过
cd core/build
cmake .. # 若增删文件修改CMakeLists.txt后需要重新执行
make -sj$(nproc) # 每次更新core代码后从这里开始5. 获取编译产出由于VS Code是直接将代码库目录挂载到镜像内的因此主机上可以直接访问镜像内的编译产出。到这里如果要求不高的话就可以结束了但细心的读者一定发现了一个问题容器内生成的文件在主机上都是root权限必须执行sudo chown -R $USER .进行修复。如果社区的成员开发机没有sudo权限怎么办作为iLogtail社区核心贡献者当然不能把这样的坑留给队友了。使用Dockerfile开发那有没有办法做到容器内权限自动适配主机呢这样的问题当然不会难倒VS Code了。Remote Development 插件支持使用 Dockerfile 在容器中进行开发即在启动开发容器前先使用docker build一个开发镜像这给了修正容器内账户权限的机会。修正的原理如下在Remote Development 插件 docker build 前将开发机的账户名、账户ID、组名和组ID暴露给 docker。docker build时利用这些账户信息修正容器执行账户和容器内文件权限。接下来我们进行实际操作。1. 修改.devcontainer.json配置文件在配置文件中将image部分修改为build部分使用Dockerfile启动开发容器。同时加入initializeCommand在build镜像前将账户信息暴露给docker。{build: {dockerfile: Dockerfile,args: {USERNAME: ${localEnv:USER}}},initializeCommand: .devcontainer/gen_env.sh,customizations: {vscode: {extensions: [golang.Go,ms-vscode.cpptools-extension-pack]}}
}2. 创建Dockerfile以编译镜像作为基础镜像编写Dockerfile对镜像内账户和文件权限进行修正。FROM sls-opensource-registry.cn-shanghai.cr.aliyuncs.com/ilogtail-community-edition/ilogtail-build-linux:latestARG USERNAMEadmin
USER root# Create the user
COPY .env /tmp/.env
RUN source /tmp/.env rm /tmp/.env; \if getent passwd $USERNAME; then userdel -f $USERNAME; fi; \if [ $HOST_OS Linux ]; then \if getent group $GROUPNAME; then groupdel $GROUPNAME; fi; \groupadd --gid $GROUP_GID $GROUPNAME; \fi; \useradd --uid $USER_UID --gid $GROUP_GID -m $USERNAME; \echo $USERNAME ALL\(root\) NOPASSWD:ALL /etc/sudoers.d/$USERNAME; \chmod 0440 /etc/sudoers.d/$USERNAME; \chown -R $USERNAME:$GROUPNAME /root/go /opt/logtail $(eval echo ~$USERNAME); \chmod 755 $(eval echo ~$USERNAME);USER $USERNAMECOPY .env /tmp/.env将主机的账户信息通过文件形式复制到容器中。接下来的几行根据这些信息在容器内创建对应的账户。echo $USERNAME ALL\(root\) NOPASSWD:ALL /etc/sudoers.d/$USERNAME;授予该用户sudo权限。chmod和chown的几行对文件权限进行修正使新建的用户有权限读写对应目录。其中对HOME~$USERNAME目录的修正必须在这里进行否则会导致VS Code Sever没有权限安装导致插件启动失败。3. 创建脚本暴露主机账户信息gen_env.sh脚本内容如下。该脚本对开发机为Mac系统也做了兼容。set -ue
set -o pipefailif uname -s | grep Linux; thenecho -e HOST_OSLinux\nUSERNAME$USER\nUSER_UID$(id -u $USER)\nGROUPNAME$(id -gn $USER)\nGROUP_GID$(id -g $USER) .devcontainer/.env;
elseecho HOST_OSDarwin\nUSERNAME$USER\nUSER_UID$(id -u $USER)\nGROUPNAMEroot\nGROUP_GID0 .devcontainer/.env;
fi前3步完成后Workspace中的配置目录应该有这样3个文件4. 运行观察效果使用Shift Command PMac或Ctrl Shift PWin打开命令面板输入reopen选择Remote-Containers: Rebuild Container。在容器内重新执行id命令查看账户信息可以看到与开发机一致。在容器内重新执行之前的编译命令。然后会到开发机上查看生成的文件权限可以看到容器内生成的文件在开发机上都已经变成正确的权限了。在容器内调试除了编译代码开发环境另一个重要功能是进行本地调试。打开一个iLogtail插件的单元测试文件设置断电然后点击“debug test”。什么Failed to launch: could not launch process: fork/fork/exec ...: operation not permitted出错了查阅资料原来是docker默认的安全策略使用Secure computing mode (seccomp)仅允许白名单系统调用debug所需的系统调用被拒绝了。我们尝试在配置文件中添加一行runArgs: [ --cap-addSYS_PTRACE, --security-opt, seccompunconfined ]禁用该功能。{build: {dockerfile: Dockerfile,args: {USERNAME: ${localEnv:USER}}},initializeCommand: .devcontainer/gen_env.sh,runArgs: [ --cap-addSYS_PTRACE, --security-opt, seccompunconfined ],customizations: {vscode: {extensions: [golang.Go,ms-vscode.cpptools-extension-pack,DavidAnson.vscode-markdownlint]}}
}Rebuild Container后再次尝试调试功能。It works!总结至此我们已经可以happy地通过VS Code的Remote Development插件在远程容器内开发了。并且使用的编译镜像和插件配置文件都是可移植可重复的CI到代码库后可以供任何开发者使用。文章中提到的代码都可以到iLogtaill的GitHub仓库https://github.com/alibaba/ilogtail获取。Remote Development插件还有很多的功能没有在本篇文章中使用到感兴趣的读者可以根据文末参考资料进一步研究探索。参考资料Developing inside a Container using Visual Studio Code Remote Development:https://code.visualstudio.com/docs/remote/containersCreate a development container using Visual Studio Code Remote Development:https://code.visualstudio.com/docs/remote/create-dev-containerRunning Docker Containers as Current Host User - Juan Treminio - Senior Web Developer Blog:https://jtreminio.com/blog/running-docker-containers-as-current-host-user/Add non-root user to a container:https://code.visualstudio.com/remote/advancedcontainers/add-nonroot-userdevcontainer.json reference:https://code.visualstudio.com/remote/advancedcontainers/add-nonroot-userSeccomp security profiles for Docker:https://docs.docker.com/engine/security/seccomp/alibaba/ilogtail: Fast and Lightweight Observability Data Collector:https://github.com/alibaba/ilogtail推荐阅读全宇宙首本 VS Code 中文书来了Code Runner for VS Code下载量突破 4000 万支持超过50种语言微软也爱 PythonVS Code Python 全新发布Jupyter Notebook 原生支持终于来了微软也爱 Java微软在 SpringOne 大会上宣布 Azure Spring Cloud 云服务在微软Microsoft工作是怎样一番体验微软内推长期有效代码编辑器横评为什么 VS Code 能拔得头筹知否知否VS Code 不止开源那些年我们一起追的 VS Code玩转VS CodeVS Code · 编程开发 · 业界资讯