
上篇 AWS ECS 使用 EC2 Capacity Provider (EC2 Auto Scaling) 学习了如何在 ECS 中使用 Capacity Provider + EC2 Auto Scaling 来部署一个简单的 Web 应用,以及了解 ECS 如何管理 EC2 的 Auto Scaling Group.
ECS Capacity Providers 是于 2019 年 12 月发布的,随同的功能支持了 Fargate, Fargate Spot, 和 EC2 AutoScaling. 而 Managed Instances 在 2025-09-30 才加入的新特性,见 Announcing Amazon ECS Managed Instances.
在近六年之间, AWS 大概也理解到了 Capacity Provider + EC2 Auto Scaling 的复杂性,虽说可由 ECS 来管理 EC2 的 ASG, 但毕竟有个 ASG 在那里。 ECS 与 EC2 ASG 之间联接由 CloudWatch Metrics, Alarms, EC2 ASG 的 Dynamic scaling policies 和 Lifecycle hooks 的一整套机制协作。 经常还不得不在 EC2 ASG 与 ECS 两个界面之间来回找问题。而 Managed Instances 的出现则将 EC2 实例的管理完全透明化了,在 EC2 端压根就不存在 一个相应的 ASG, 更不需要 CloudWatch Alarms 之类的关联组件。
Managed Instances 与 EC2 Auto Scaling 之间就好比 Serverless 与 非 Serverless 的区别,用 Managed Instances 之后你只管控制好 ECS Desired Count(ECS AutoScaling), 其余的都由 Managed Instances 来管理,在界面上只需要关注 ECS Infrastructure 中的 Container Instances. 由 Managed Instances 管理的 EC2 实例,你即使用有管理员权限都无法关闭它,只能全权由 Managed Instances 来控制。试图关闭这样的 EC2 实例时报错
Read More
在我 X 中 AWS 上不同应用的部署策略 中提到过在 AWS 部署服务(特别是 Web 服务时), 基于采用过以下演进的方式
- EC2(AutoScaling) + 直接 EC2 中部署本地应用, 靠 userdata 完成应用部署 2 EC2(AutoScaling) + ECS(AutoScaling), 运行容器,Replica 模式,有两个层次的 AutoScaling 要单独控制,比较麻烦
- ECS + EC2(AutoScaling), 运行容器,Daemon 模式。由 EC2 来驱动部署 ECS Task
- ECS(AutoScaling) + Fargate, 运行容器。这是最简单的,但硬件资源受限, 想要强大的 CPU, 没门
- ECS(AutoScaling) + Capacity Provider(EC2) + EC2(Managed AutoScaling), 运行容器。由 ECS Task 发起 EC2 实例需求
- ECS(AutoScaling) + Capacity Provider(Fargate),运行容器,Serverless 就是简单,同样硬件资源受限
- EKS,开启 Auto mode,一切变得简单,像是 Capacity Provider(EC2). 但会涉及到复杂的 EKS 配置管理,集群内网络,如 ELB,
基于服务的 WAF, IAM Role. 但基本是一次的工作,建立了健壮的 EKS, 以后部署任何应用都变得很轻松。
对于 #2 和 #3, 如果选择 Network 模式为
Read Morevpc的话,即每个容器都会有自己的 IP 地址,并且 Target Group 中注册的是 IP 地址,这时候 AutoScaling 在缩减实例时就要靠 AutoScaling 的 Lifecycle Hook 来处理对相应 ECS Task 的通知,因为 EC2 的 AutoScaling 只知在开始关闭实例停止向相应实例 转发请求. 如果 Network 模式为默认的Bridge则没问题,因为请求是过通 NAT 方式(如 32768:80) 由 EC2 实例转发到其中的容器。
本文主要专注在 Docker 内的应用进程如何与外部发过来的 Linux 信号进行响应。具体应用在当运行为一个 ECS 的 Docker 容器时,对 ECS 的 AutoScaling 以及部署时如何让应用能正确收到相应的信号。关于 Linux 的 Signal 请参考 Wikipedia 的 Signal(IPC).
其实相关的话题在以前三篇中都有涉及
不同 Dockerfile 的
Read MoreENTRYPOINT或CMD会影响到 Docker 内进程的启动方式,额外参数的接收方式,以及信号的传递。本篇只关注在信号这一议题。 先学习本地的 Docker 容器内与对docker stop或docker kill发出的信号的响应,进而讲述运行在 ECS 的容器与 ASG,部署行为的信号响应。
本文初衷是要专注在 Docker 内的应用进程如何与外部发过来的 Linux 信号进行响应。具体应用在当运行为一个 ECS 的 Docker 容器时,对 ECS 的 AutoScaling 以及部署时如何让应用能正确收到相应的信号。可是一提及这一话题,思维就产生了极大的发散,很想好好捋一捋进程与 Linux 信号之间关系和相关的概念。 关于 Linux 的 Signal 请参考 Wikipedia 的 Signal(IPC).
本文以渐进的方式,从信号的简介,本地 C, Bash, Java 程序与信号,然后将在下一篇学习本地 Docker 容器内进程与信号的处理,ECS 的容器与 ASG,部署行为的信号响应。
Read More
前篇 MacOS/Linux C++ GDB 远程调试基础 演示了如在 macOS 开发调试远程 Linux 下的 C++ 程序, 本篇将结合 C 语言静态库与动态库的生成和使用 练习如何调试含动态库,静态库的 C++ 程序, 并了解如何指定符号文件。
示例源码
本文将用以下的目录结构, 分别验证主程序与动态库,静态库的源代码断点调试,以及把源文件放在不同目录中是否有特别之处。
Read More1├── dynamic # 动态库 2│ └── add.cpp 3├── static # 静态库 4│ └── sub.cpp 5└── main.cpp # 主程序
有那么一个古老的项目,编译用的是 g++, 目标平台的是 Linux x86_64, 构建工具是 make. 本地开发环境是 macOS, 硬件为 Arm64 的苹果芯片 M4, IDE 尝试用 CLion, 如果喜欢的话,也可以选择 VSCode.
想要单步调试的目的就是想让代码跑起来,然后逐步理解代码执行的逻辑。所以不想对现有项目构建过程进行改造,如换成 CMake, 使用 LLVM 编译之类的。 只想使用远程 Linux 机器, 仍然使用原来的
make命令编译,然后在 Linux 下启动程序,由 Clion 连到的 Linux 上进程, 关联源代码进行调试。因为编译用的 g++, 所以采用 gdbserver 和 gdb 进行远程调用,llvm 相应的解决方案是 lldb-server + lldb. 下面是关键的步骤
. 本地 Clion 中编辑代码 . 代码传到远程 Linux 机器 . 远程 Linux 机器上编译,编译的二进制代码要保留符号信息 . 在 Linux 机器上的符号文件要下载给 Clion . 在远程用 gdbserver 指定端口启动程序 . 本地 Clion 配置用 GDB 连接到远程 Linux 机器上的 gdbserver . 在 Clion 中断点单步调试
上面是基本的操作,当我们用某个客户端工具(比配置运行 Clion 的 Remote GDB Server) 就自动完成以上的某些操作,如自动双向同步源代码与二进制/符号文件, 自动驱动远程端的的编译,启动 gdbserver. 远程 Linux 还能进一步使用 Docker 容器替代。但是在苹果芯片的 macOS 中启动
Read Morex86_64的容器中运行的gdbserver在 macOS 中用 gdb 是连不上的。
Bash 环境
多数时候我们用的是 Bash, 比如个人的 Linux 不愿去定制,远程服务器的由不得你去定制,所以就从 Bash 说起。
默认键绑定
emacs, 操作是ctrl-x, ctrl-e在默认的 Bash 环境下,只要在命令行中按下
ctrl-x, ctrl-e就会把当前命令的内容调入到环境变量$EDITOR指示的编辑器(默认为 emacs)去编辑,编辑后保存退出就会立即执行。如果未安装
Emacs编辑器,在按下ctrl-x, ctrl-e会得到如下提示[vagrant@localhost ~]$
-bash: emacs: command not found如果希望使用
vi来编辑当前命令,就需要设置EDITOR环境变量,比如在.bashrc中加入export EDITOR=vi
那么在命令行中按下
ctrl-x, ctrl-e使用打开vi来编辑当前命令。注:Emacs 要用
ctrl-x, ctrl-c, 再回答y, 命令保存到临时文中; 而 vi 的相应操作是:wq, 至少这个操作上 vi 要简洁些。 Read More- 我们无论是在写批处理还是 Linux 的 Shell 都常用到 >, >> 或 <,这是输入输出重定向。特别是 Linux 的 Shell 常见到 2>&1 这样的写法,这是在干什么呢?这里就来了解下 Linux 下的输入输出重定向的一些来龙去脉。
在 Linux 下几乎一切都号称是文件,标准输入、输出也不例外,它们是叫做 fd (File Descriptor) 文件描述符。这里我们关注三个东西名称 代码 操作符 Java中表示 Linux 下文件描述符(Debian 为例) 标准输入(stdin) 0 < 或 << System.in /dev/stdin -> /proc/self/fd/0 -> /dev/pts/0 标准输出(stdout) 1 >, >>, 1> 或 1>> System.out /dev/stdout -> /proc/self/fd/1 -> /dev/pts/0 标准错误输出(stderr) 2 2> 或 2>> System.err /dev/stderr -> /proc/self/fd/2 -> /dev/pts/0
从以上表格我们可以理解 0, 1 和 2 分别是什么东西了,它们的输入源或输出目的地默认都是屏幕。
下面不作系统解释输入, 输出重定向的完整使用,只说明一些常见的例子: Read More - 最近玩弄 Jenkins 较多,构建服务器基本是 Mac OS 和 Linux,虽说有许多现成插件可用,但不敢不说 Execute Shell 这个东西都是即开即用,方便而灵活的。因此不断的要和 Shell 打交道,真正通用的的 Shell 自然是 Bash,在 Mac OS 下可发现自带了 zsh, ksh 和 tcsh,考虑到 Linux 还是 Bash 吧。
本人工作时用的是 Fish Shell,目前相当的脚本语言都可用来写 Shell 脚本,如 PHP, Ruby, Python, Perl,NodeJs 等,只是 Bash 的地位总难被替代,借句话说 Bash 的是拿来 “用” 的,而像 Ruby, Python 等做 Shell 是拿来 “编” 的,再就是 Bash 与 Linux 命令的亲缘性更强。
我也只会在实在用 Bash 太难于表达的时候才用其他脚本语言,如处理日期的运算,因 Mac OS 的 date 和 Linux 的 date 命令差异较大,不得已会选择有较强类型的 Ruby 等。
既然 Bash 要作为一个日常语言,那不妨作个备忘录,记录下那些常用的语法,控制结构。
1. if 条件语句 Read More - 正在使用亚马逊的 VPS,一年的小心翼翼的免费期,选择的是 Debian 6 32 位的系统,因搭建 WordPress 试图在上面安装 Nginx+PHP 的环境。看着在 Nginx 环境下多是使用 php-fpm,而不是 php-cgi,前者与后者的区别是在孤立的 php-cgi 之上又多了一个调度层。
一开始打算一步步纯手工打造,但在执行apt-get install php-fpm时总有不可逾越的依赖症,所以转而寻求更傻瓜的一键包安装方式。试过 LNMP,包太大,东西太过于齐全,把人太当傻瓜,虽然如此,我在用它安装时也有些慢,因为它也是采取的编译安装方式,针对本机应该有很好的优化。没装完我就中断了,下次有时间可以再试下。
正好在这期间看到了 Dvid Pennington 制作的 lowendscript lnmp 一键安装脚本,很省事,连安装 WordPress 也考虑到了,这里有介绍,比较详细 lowendscript:最省资源lnmp一键包。我只记录下我自己的安装过程,以备忘。 Read More