AWS的ECS使用Fargate服务器如何开启shell进入容器调试

公司用到了Amazon Elastic Container Service,完全托管的容器服务 服务器用的是Fargate,没有自己的服务器,纯托管的,开始部署的时候,也没有考虑到有一天要进入容器进行调试。 现在麻烦就来了,需要进入容器,查看文件日志 结果就很麻烦,解决的步骤如下: 一、查看集群状态,看看任务定义的版本号,下面是206 二、去到相应的任务定义 注意,现在只有一个任务执行角色,任务角色是个空的!!! 然后我们点开任务执行角色,添加权限 初始化的时候只有AmazonECSTaskExecutionRolePolicy, 我们需要加上AmazonSSMManagedInstanceCore 加完就上面一样。 三、返回到任务定义,使用JSON创建新修订 "taskRoleArn": "arn:xxxx:ecsTaskExecutionRole", "executionRoleArn": "arn:ecsTaskExecutionRole", 新增taskRoleArn,和executionRoleArn保持一致,然后保存 四、按照新版本,部署新任务 从新任务定义更新服务 选择相应集群,相应服务 故障排除配置,务必开启ECS exec,然后更新即可 五、开启容器的shell 我去集群–服务–容器,点击连接 aws ecs execute-command --cluster yoov_work_e_form_prod_cluster --task 23xxxxx --container yontainer --interactive --command '/bin/sh' 实际对应的命令如上。其实也可以用aws的cli客户端直接执行,只不过要拿到集群名和容器名。

2025年11月10日

MongoDB的伪副本模式

这个话题比较有意思,公司的测试环境本来是一个mongodb的三节点三副本全集群,升级了2次升到8.0。 结果吧,由于里面数据过于庞大,测试的时候经常把节点打挂,虽说是打挂后又能很快被docker拉起来,但是挂的那个时刻应用程序就掉了,导致测试失败。 这三台节点还都是8 cpu 32G memory的配置,真大无语了。 没办法,干脆弄成单节点,然后内存垒高到128G,cpu加到32,弄好之后,读取数据的Flink又不行了,要求是必须读mongo的副本,真完犊子。 那就强制启动个副本模式吧: mongo启动方式用的是docker compose,启动的时候新增参数 --replSet rs0 # mongo数据目录的属主是 999:999 mkdir -p /data/mongodb/27017/data chown -R 999:999 /data/mongodb/27017/data mkdir -p /data/mongodb/27017/conf/ cd /data/mongodb/27017 #先gen keyfile openssl rand -base64 756 > keyfile chmod 400 keyfile #准备mongod.conf EOF < cat > /data/mongodb/27017/conf/mongod.conf systemLog: destination: file path: "/data/db/mongod.log" logAppend: true net: bindIp: 0.0.0.0 port: 27017 security: keyFile: "/data/configdb/keyfile" EOF EOF < cat > /data/mongodb/docker-compose.yaml services: mongo: container_name: mongo image: mongo:8.0 restart: always environment: TZ: Asia/Shanghai volumes: - /data/mongodb/27017/data:/data/db - /data/mongodb/27017/conf/mongod.conf:/data/configdb/mongod.conf - ./keyfile:/data/configdb/keyfile command: --replSet rs0 --config /data/configdb/mongod.conf ports: - 27017:27017 EOF docker compose up -d 然后不算完啊,启动之后需要进入容器执行rs.initiate(), 放心大胆的执行,不会破坏任何原有的数据 ...

2025年10月29日

cert-manager的不同clusterissuer验证方式

cert-manager普通签发证书的时候,通常是DNS的A记录已经解析到相关的Ingress前置的LB 公网IP了。 第一种情况,有公网IP的证书签发,验证方式是http 那准备好cluster-issuer.yaml apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: letsencrypt-prod1 spec: acme: server: https://acme-v02.api.letsencrypt.org/directory email: zhangranrui@rendoumi.com privateKeySecretRef: name: letsencrypt-prod1 solvers: - http01: ingress: class: nginx 第二种情况,如果集群是部署在内网,根本没有公网ip,就不能通过80和443的验证来签发了,只能用DNS校验的方式来签发证书 那以cloudflare托管的DNS为例,我们需要拿到CF的dns-api的token,然后声明,再定义ClusterIssuer --- apiVersion: v1 kind: Secret metadata: name: cloudflare-api-token-secret type: Opaque stringData: api-token: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx --- apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: letsencrypt-prod2 spec: acme: server: https://acme-v02.api.letsencrypt.org/directory email: zhangranrui@rendoumi.com privateKeySecretRef: name: letsencrypt-prod2 solvers: - dns01: cloudflare: email: zhangranrui@rendoumi.com apiTokenSecretRef: name: cloudflare-api-token-secret key: api-token 那第一种和第二种的区别就是solvers是不同的。 ...

2025年10月24日

OPNsense的远程安装并访问WEBGUI

OPNsense安装其实很容易,但是远程装就不那么好玩了。 尤其涉及到内网WEBGUI的访问,缺省安装完成以后,只能从内网口访问管理界面,问题是VPC里只有一台Linux机器,还没有浏览器,怎么办? 记录一下安装过程,备查: 一、下载iso镜像并解压 wget https://pkg.opnsense.org/releases/25.7/OPNsense-25.7-dvd-amd64.iso.bz2 bzip2 -d OPNsense-25.7-dvd-amd64.iso.bz2 二、kvm用virt-install安装iso,注意桥接了2个网卡 #!/bin/bash mkdir -p /export/kvm/opn/ qemu-img create -f qcow2 /export/kvm/opn/opn.qcow2 20G virt-install \ --name=opn \ --vcpu=2 \ --ram=2048 \ --disk path=/export/kvm/opn/opn.qcow2,format=qcow2,size=20 \ --cdrom=/export/kvm/iso/OPNsense-25.7-dvd-amd64.iso \ --network bridge=br0,model=virtio \ --network bridge=br1,model=virtio \ --os-type unix \ --os-variant freebsd13.1 \ --vnc --vnclisten=0.0.0.0 --vncport=5901 三、vnc连到port 5901上进行安装配置 OPNsense公网的网卡、ip、mask、gateway配置 OPNsense内网的网卡、ip、mask配置 四、设置内网访问 这里就非常鬼畜了,首先在内网的那台机器上做port转发,这台机器是192.168.100.2,做个systemd的service: cat /etc/systemd/system/opn-proxy.service [Unit] After=network.target Wants=network.target [Service] WorkingDirectory=/usr/local/bin/ Type=simple ExecStart=/usr/local/bin/go-tcp-proxy_1.0.2_linux_amd64 -l ":4430" -r "192.168.100.1:4430" Restart=on-failure RestartSec=1s [Install] WantedBy=multi-user.target 如上的话,如果web访问http://192.168.100.2:4430,那Host: 192.168.100.1 会被转发给 192.168.100.1 的OPNsense的4430端口 那OPNsense的内网IP是192.168.100.1,登录用户是root,密码是xxxxxxxx 从vnc上登录,然后进入shell,找到webgui的部分,添加port和althostnames的两项 vi /conf/config.xml ...... <webgui> <protocol>https</protocol> <ssl-certref>68adc26101eeb</ssl-certref> <port>4430</port> <althostnames>192.168.100.2</althostnames> </webgui> ...... 然后重启webgui ...

2025年10月23日

strapi的安装

老实说,strapi的安装真的不是一件容易的事情。 第一步想简单化,于是就用Docker compose来安装,结果并不容易,官方文档不可用,改了半天终于跑起来,然后,嘿嘿,dockerhub上的strapi:latest 早就过期很久了。 于是又琢磨它那个Docker build版本的,问题是,都在宿主机环境build出来了,然后再放到Docker镜像中跑,岂不是脱裤子放屁,多此一举么。 于是回到原点,需要在CLI环境下安装,然后要部署到正式生产环境。 步骤如下: 一、装mysql 8.0 apt install wget lsb-release gnupg -y wget https://dev.mysql.com/get/mysql-apt-config_0.8.29-1_all.deb dpkg -i mysql-apt-config_0.8.29-1_all.deb apt update apt install mysql-server 二、装NVM,nodejs和yarn curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.4/install.sh | bash source ~/.nvm/nvm.sh nvm ls-remote nvm install v20.19.5 node -v npm install -g yarn npm list -g 三、初始化strapi mkdir /data cd /data yarn create strapi # 我们要跳过它那个免费30天的grow方案 # 然后数据库是 mysql , 填入mysql的一系列参数 # 使用ts 四、配置strapi # 加入自己的域名 vi /data/strapi/config/server.ts export default ({ env }) => ({ host: env('HOST', '0.0.0.0'), port: env.int('PORT', 1337), url: 'https://blog.rendoumi.com', app: { keys: env.array('APP_KEYS'), }, }); # 建立新文件 vi /data/strapi/src/admin/vite.config.ts import { defineConfig, mergeConfig } from 'vite'; export default (config) => { return mergeConfig(config, defineConfig({ resolve: { alias: { '@': '/src', }, }, server: { allowedHosts: true } })); }; 五、安装nginx,运行程序 apt install nginx # 注释掉无用配置 vi /etc/nginx/nginx.conf # include /etc/nginx/sites-enabled/*; # 新增配置 vi /etc/nginx/conf.d/strapi.conf upstream strapi { server 127.0.0.1:1337; } server { # Listen HTTP listen 80; server_name blog.rendoumi.com; # Redirect HTTP to HTTPS return 301 https://$host$request_uri; } server { # Listen HTTPS listen 443 ssl; server_name webcms.yoov.com; # SSL config ssl_certificate /usr/local/bin/certs/certificates/blog.rendoumi.com.crt; ssl_certificate_key /usr/local/bin/certs/certificates/blog.rendoumi.com.key; # Proxy Config location / { proxy_pass http://strapi; proxy_http_version 1.1; proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-Server $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Host $http_host; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "Upgrade"; proxy_pass_request_headers on; } } cd /data/strapi yarn develop 然后登录就可以了,诡异的是第四步,如果不gen vite.config.ts,那nginx代理访问local host:1337上会出问题。 ...

2025年10月16日

NVM管理的Nodejs如何做成systemd的serivce服务

有很多next、nuxt、yarn的nodejs程序,都是什么npm start或者yarn develop的启动模式,如何搞成systemd的服务呢,这里面麻烦的就是systemd的服务需要使用全路径。 那方法如下: 一、安装nvm curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.4/install.sh | bash 二、安装nodejs和yarn source ~/.nvm/nvm.sh nvm ls-remote nvm install v20.19.5 node -v npm install -g yarn npm list -g 三、弄strapi.service服务 echo $NVM_DIR # 确定 nvm 的安装目录 /root/.nvm which node # 确定 Node.js 的路径 /root/.nvm/versions/node/v20.19.5/bin/node which yarn # 确定 Yarn 的路径 /root/.nvm/versions/node/v20.19.5/bin/yarn cat < EOF > /etc/systemd/system/strapi.service [Unit] Description=Strapi App After=network.target [Service] # 使用用户账户运行服务,替换为实际的用户名 User=root Group=root # 指定工作目录,替换为项目的实际路径 WorkingDirectory=/data/strapi # 加载 nvm 并运行 yarn 或 node Environment="NVM_DIR=/root/.nvm" ExecStart=/bin/bash -c ". $NVM_DIR/nvm.sh && yarn develop" Restart=always RestartSec=10 [Install] WantedBy=multi-user.target EOF systemctl daemon-reload systemctl enable --now strapi

2025年10月15日

OPNsense如何做LoadBalance接入后端的Kubernetes nginx ingress --- Nginx篇

新托管了一个机房服务器,基本全用开源软件来构建: 那Firewall就用的OPNsense,后端自建Kubernetes,那OPNsense需要当作一个LoadBalance来使用 结构图如下,证书是放在了Nginx ingres上: 那方法有很多,各有利弊,说下第三个,Nginx的做法 relayd和caddy都说完了,那还有Nginx,Nginx的话,如果证书挂在OPNsense,那就可以用WAF的功能 如果证书放在后端Kubernetes的Nginx ingress上,那就无法用WAF了,算是data stream 那提前说一句,Nginx的配置是有Bug的,如果无法清除干净,需要ssh登录opnsense,然后 把 /conf/下xml配置文件中的 nginx 部分删除掉,然后重启服务器,才可以 os-nginx的配置方法如下: 第一步:首先去Upstream的Upstream Server子标签,建立两组服务器 第二步:再去Upstream的Upstream子标签,建立两组服务 建立的时候advanced mode要打开,PROXY Protocol要选中,Server选中各自的4个服务器,其它保持缺省即可。 第三步:去Data Streams的子标签Stream Servers,建两组服务 编辑一下,监听端口只选指定IP的80和443,PROXY Protocol不要选中,然后Route就选Upstream,Upstream Servers选中对应的,其它缺省即可。 那对应的,后端Kubernetes的Nginx ingress也要做相应配置 Nginx ingress的configmap,需要加上Proxy Protocol的部分 我们用的是官网的 ingress-nginx,配置文件是 ingress-nginx 的namespace中 configmap ingress-nginx-controller,内容如下,对应data那两行: apiVersion: v1 data: use-proxy-protocol: "true" kind: ConfigMap metadata: annotations: meta.helm.sh/release-name: ingress-nginx meta.helm.sh/release-namespace: ingress-nginx nginx.ingress.kubernetes.io/configuration-snippet: "true" nginx.ingress.kubernetes.io/location-snippet: "true" nginx.ingress.kubernetes.io/server-snippet: "true" creationTimestamp: "2025-08-27T07:38:49Z" labels: app.kubernetes.io/component: controller app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/managed-by: Helm app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx app.kubernetes.io/version: 1.13.1 helm.sh/chart: ingress-nginx-4.13.1 name: ingress-nginx-controller namespace: ingress-nginx resourceVersion: "22298827" uid: d6eeef3c-7e44-4667-854a-c7693006b221 编辑后,nginx ingress会自动reload ...

2025年10月14日

OPNsense如何做LoadBalance接入后端的Kubernetes nginx ingress --- caddy篇

新托管了一个机房服务器,基本全用开源软件来构建: 那Firewall就用的OPNsense,后端自建Kubernetes,那OPNsense需要当作一个LoadBalance来使用 结构图如下,证书是放在了Nginx ingres上: 那方法有很多,各有利弊,说下第二个,Caddy的做法 Caddy真的是王道,什么泛域名,一个端口跑3个协议,都可以 用到Caddy,就要解决后端Nginx ingress无法获得客户真实IP的问题 Caddy配置如下: General Settings: Enable Layer4 Proxy 要勾选上 Auto HTTPS 要选中Off 其它保持默认,然后去到Layer4 Proxy进行配置,同样要配2个,一个HTTP,一个TLS 编辑HTTP的代理,注意 Domain 的地方需要把用到的所有域名列进去 编译TLS的代理 注意上面,Proxy Protocol都要选中v2,这样客户端真实IP才可以透传给后端的Nginx ingress 那同样后端的Nginx ingress的configmap,也需要加上Proxy Protocol的部分 我们用的是官网的 ingress-nginx,配置文件是 ingress-nginx 的namespace中 configmap ingress-nginx-controller,内容如下 apiVersion: v1 data: use-proxy-protocol: "true" kind: ConfigMap metadata: annotations: meta.helm.sh/release-name: ingress-nginx meta.helm.sh/release-namespace: ingress-nginx nginx.ingress.kubernetes.io/configuration-snippet: "true" nginx.ingress.kubernetes.io/location-snippet: "true" nginx.ingress.kubernetes.io/server-snippet: "true" creationTimestamp: "2025-08-27T07:38:49Z" labels: app.kubernetes.io/component: controller app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/managed-by: Helm app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx app.kubernetes.io/version: 1.13.1 helm.sh/chart: ingress-nginx-4.13.1 name: ingress-nginx-controller namespace: ingress-nginx resourceVersion: "22298827" uid: d6eeef3c-7e44-4667-854a-c7693006b221 编辑后,nginx ingress会自动reload ...

2025年10月14日

OPNsense如何做LoadBalance接入后端的Kubernetes nginx ingress --- relayd篇

新托管了一个机房服务器,基本全用开源软件来构建: 那Firewall就用的OPNsense,后端自建Kubernetes,那OPNsense需要当作一个LoadBalance来使用 结构图如下,证书是放在了Nginx ingres上: 那方法有很多,各有利弊,先说第一个,relayd的做法 relayd是最早的OPNsense的插件,用来做负载均衡,安装这个plugin插件 配置如下: General Settings: 由于虚机的cpu是4个,所以进程设置成4 Backend Hosts: 后端节点有4个,只写IP即可 Table Checks: 端口检查,因为是直通,所以就设置成TCP检查即可 Tables: Hosts选中4个节点 Virtual Server: 80和443各有一个 每个呢,设置好前面的监听地址和端口,后端的Table 服务器和Table check的协议,就ok了 最后去 General Settings 选中 Enable Relayd,然后save,就可以了 这么多贴图,是因为如果从CLI配置,其实就一个很简单的relayd.conf文本文件 但是从GUI,就一大堆,而且生成的东西简直不知所云 这样做relayd就相当于一个直通的LoadBalance,把流量送入后端的Nginx ingress所开的NodePort。 这样就可用了。 这样有个弊端,Nginx的ingress拿不到客户端的真实IP,X-forwarded-for无法传过来真的客户端IP,网上查文档是可以的,但是从GUI配了半天,也不知道怎么配,服了也是。

2025年10月14日

seaweedfs的s3进阶试用方法

SeaweedFS 已经用docker compose的方式部署在生产环境内中了,对外只开放了一个S3的端口127.0.0.1:8333,然后前面套上Caddy的https代理,这样很安全了。 那进阶的要求又来了: 一、S3的pre signed的URL 由于程序之前是在AWS跑的,所以用了S3的最佳实践,pre sign url来进行上传和下载,那seaweedfs也是完全支持的,基本是无缝修改 给出验证程序: import boto3 from botocore.client import Config # Configure the S3 client to point to your SeaweedFS S3 gateway s3_client = boto3.client( 's3', endpoint_url='https://s3.rendoumi.com', # Replace with your SeaweedFS S3 gateway address aws_access_key_id='aaaaaaaa', aws_secret_access_key='bbbbbbb', config=Config(signature_version='s3v4') ) bucket_name = 'myfiles' object_key = 'your-object-key' expiration_seconds = 3600 # URL valid for 1 hour # Generate a pre-signed URL for uploading (PUT) try: upload_url = s3_client.generate_presigned_url( 'put_object', Params={'Bucket': bucket_name, 'Key': object_key, 'ContentType': 'application/octet-stream'}, ExpiresIn=expiration_seconds ) print(f"Pre-signed URL for upload: {upload_url}") except Exception as e: print(f"Error generating upload URL: {e}") # Generate a pre-signed URL for downloading (GET) try: download_url = s3_client.generate_presigned_url( 'get_object', Params={'Bucket': bucket_name, 'Key': object_key}, ExpiresIn=expiration_seconds ) print(f"Pre-signed URL for download: {download_url}") except Exception as e: print(f"Error generating download URL: {e}") 能看到临时生成的upload的URL和download的URL,是完美支持的 ...

2025年9月17日