初心易得,始終難守
C'est la vie.© 2002 - 2026
  • 我是誰-Who Am I
  • 我在哪-Where Am I
  • 我是什麼-What Am I
  • 年鑑-YearBook
    • 二零零六年终总结
    • 一吻定情—二零零八年年终总结
    • 突如其来的明天—二零零九年年终总结
    • 人生大起大落得太快——二零一零年年终总结
    • 贰零①①年年终总结-女朋友已经成家了
    • 贰零壹贰年年终总结-奔波的肿瘤
    • 贰零壹叁年年终总结
    • 雪字怎么写-贰零壹肆年年终总结
    • 每个不曾表白的今天,都是对青春的亏欠-贰零壹伍年年终总结
    • 按部就班的IT 人生-貳零貳肆年年終總結
    • 真正的閱讀-貳零貳伍年年終總結
  • 連結
RSS
2 月 11 日, 2026 年

如何使用 Terraform 來完成WordPress Spot instance 的滾動更新

Ken Tech 0 Comments

使用AWS Spot instance 的朋友都知道,他很便宜,有些機型可以便宜90%。

本文的目的就是省錢。

他有兩種運行模式,一種是One time 一種是Persist,在AWS 容量充足的情況下,使用Persist 方式可以在很長時間內維持一個低價位的運行水平,但,問題是,AWS 的容量是動態調整的,比如您使用c5.large 的persist spot instance ,當有人啟用了更多的c5.large On-demand 容量,您使用的Spot instance 就會被強制釋放掉,而這段不可用的時間可能持續數分鐘到數小時,完全無法預估。這時候只能手動製作一個AMI,然後從AMI 啟動一個新的不同的instance type ,通常可用。

那麼,如何做到無需人工干預,讓Spot instance 在不同的instance type 之間自動續命不停歇呢?

當有人啟用了更多的On-demand 容量時,他總不可能把所有的instance type 都用盡吧,根據這個思路,我們可以使用Spot Fleet Request,在這個fleet 中設置幾個不同的機型。

那麼選用那種類型的instance 呢?您一定想當然的認為 t3/t4 會比較便宜,然而在Spot instance ,並不是這樣,是使用的人越少,他越便宜,下面以Osaka region 的部分ARM64 機型為例,使用aws cli query:

aws ec2 describe-spot-price-history \
  --instance-types t4g.medium c6g.medium c6gd.medium c7g.medium c7gd.medium c8g.medium m6g.medium m6gd.medium m7g.medium m8g.medium r6g.medium r7g.medium r8g.medium \
  --product-descriptions "Linux/UNIX" \
  --start-time $(date -u +"%Y-%m-%dT%H:%M:%SZ") \
  --end-time $(date -u +"%Y-%m-%dT%H:%M:%SZ") \
  --query "sort_by(SpotPriceHistory[?AvailabilityZone=='ap-northeast-3a' || AvailabilityZone=='ap-northeast-3c'], &SpotPrice)[*].[InstanceType,SpotPrice,AvailabilityZone]" \
  --output table

------------------------------------------------
|           DescribeSpotPriceHistory           |
+-------------+------------+-------------------+
|  c8g.medium |  0.012400  |  ap-northeast-3c  |
|  c8g.medium |  0.012500  |  ap-northeast-3a  |
|  m6g.medium |  0.012600  |  ap-northeast-3c  |
|  c7g.medium |  0.013600  |  ap-northeast-3a  |
|  m6g.medium |  0.014200  |  ap-northeast-3a  |
|  c7gd.medium|  0.014200  |  ap-northeast-3a  |
|  m8g.medium |  0.014500  |  ap-northeast-3c  |
|  m8g.medium |  0.014500  |  ap-northeast-3a  |
|  m6gd.medium|  0.014600  |  ap-northeast-3a  |
|  m6gd.medium|  0.014800  |  ap-northeast-3c  |
|  m7g.medium |  0.014800  |  ap-northeast-3c  |
|  m7g.medium |  0.015000  |  ap-northeast-3a  |
|  r6g.medium |  0.015200  |  ap-northeast-3c  |
|  r6g.medium |  0.015300  |  ap-northeast-3a  |
|  r7g.medium |  0.016300  |  ap-northeast-3a  |
|  c6gd.medium|  0.017400  |  ap-northeast-3c  |
|  c6g.medium |  0.017700  |  ap-northeast-3c  |
|  c6g.medium |  0.017700  |  ap-northeast-3a  |
|  r7g.medium |  0.018200  |  ap-northeast-3c  |
|  r8g.medium |  0.018200  |  ap-northeast-3a  |
|  c7g.medium |  0.018200  |  ap-northeast-3c  |
|  r8g.medium |  0.018400  |  ap-northeast-3c  |
|  c6gd.medium|  0.018700  |  ap-northeast-3a  |
|  t4g.medium |  0.019800  |  ap-northeast-3c  |
|  t4g.medium |  0.020100  |  ap-northeast-3a  |
+-------------+------------+-------------------+

t4g.small On-Demand 的價格是 每小時 $0.0218,上面的價格比t4g.small 還要低,能不用他嗎?

對於CPU 持續運算型的workload 可以選用C/M 系列,對於有多線程優化的workload 可以選用t4g.medium,對於Memory 優先的workload 則可以選用R/M 系列。

但是,請注意,因為m8g/c8g 使用了更新一代的Graviton 4 chip,所以,即使只有1顆vCPU,因為他的處理速度更快,他的實際表現仍然可能會超過擁有兩顆Graviton 2 vCPU 的t4g,何況他還更便宜。

各大雲平臺的ARM64 機器都是玄學,具體的性能表現沒有一個官方的評測,我估計是因為在不同的workload 上表現可能差異很大,因為傳統研發還是更注重於x86_64 。

首先創建一個launch template ,裡面包含現在的EC2 製作的AMI,記錄一下 launch template id ,接下來會用到他。

然後,從 Spot Requests 點擊 Create Spot Fleet request,首先當然是選擇使用launch template。

對於 Target capacity 可以根據實際需要,比如我這個blog ,可以只選擇1 就好。

對於 Network , 如果在launch template 中有設置這裡就不需要了,但不要多處設置以免衝突。

好了,接下來是最重要的 Instance type requirements , 請選擇 Manually select instance types,然後 Add instance types ,將需要的instance types 加入進去。

對於 Allocation strategy 就選擇預設的最低價。

請不要點擊創建,可以看到在launch 旁邊有一個JSON config,點擊他將config download 到本機,保存為/Downloads/fleet.json。

使用下面的aws cli 命令 直接創建 spot fleet –

aws ec2 request-spot-fleet --spot-fleet-request-config file://Downloads/fleet.json



{
    "IamFleetRole": "arn:aws:iam::123454567890:role/aws-ec2-spot-fleet-tagging-role",
    "AllocationStrategy": "priceCapacityOptimized",
    "TargetCapacity": 1,
    "ValidFrom": "2026-01-06T08:19:06.000Z",
    "ValidUntil": "2027-01-06T08:19:06.000Z",
    "TerminateInstancesWithExpiration": true,
    "Type": "maintain",
    "OnDemandAllocationStrategy": "lowestPrice",
    "LaunchSpecifications": [],
    "LaunchTemplateConfigs": [
        {
            "LaunchTemplateSpecification": {
                "LaunchTemplateId": "lt-0716c882cb57a921d",
                "Version": "$Latest"
            },
            "Overrides": [
                {
                    "InstanceType": "m6g.medium",
                    "WeightedCapacity": 1,
                    "SubnetId": "subnet-0d2535d7e7cacf658",
                    "SpotPrice": "0.017"
                },
                {
                    "InstanceType": "m6g.medium",
                    "WeightedCapacity": 1,
                    "SubnetId": "subnet-0c255e6c5c642da2a",
                    "SpotPrice": "0.017"
                },
                {
                    "InstanceType": "m6g.medium",
                    "WeightedCapacity": 1,
                    "SubnetId": "subnet-06ee85eed40f5261b",
                    "SpotPrice": "0.017"
                },
                {
                    "InstanceType": "m7g.medium",
                    "WeightedCapacity": 1,
                    "SubnetId": "subnet-0d2535d7e7cacf658",
                    "SpotPrice": "0.017"
                },
                {
                    "InstanceType": "m7g.medium",
                    "WeightedCapacity": 1,
                    "SubnetId": "subnet-0c255e6c5c642da2a",
                    "SpotPrice": "0.017"
                },
                {
                    "InstanceType": "m7g.medium",
                    "WeightedCapacity": 1,
                    "SubnetId": "subnet-06ee85eed40f5261b",
                    "SpotPrice": "0.017"
                },
                {
                    "InstanceType": "m8g.medium",
                    "WeightedCapacity": 1,
                    "SubnetId": "subnet-0d2535d7e7cacf658",
                    "SpotPrice": "0.017"
                },
                {
                    "InstanceType": "m8g.medium",
                    "WeightedCapacity": 1,
                    "SubnetId": "subnet-0c255e6c5c642da2a",
                    "SpotPrice": "0.017"
                },
                {
                    "InstanceType": "m8g.medium",
                    "WeightedCapacity": 1,
                    "SubnetId": "subnet-06ee85eed40f5261b",
                    "SpotPrice": "0.017"
                },
                {
                    "InstanceType": "r6g.medium",
                    "WeightedCapacity": 1,
                    "SubnetId": "subnet-0d2535d7e7cacf658",
                    "SpotPrice": "0.017"
                },
                {
                    "InstanceType": "r6g.medium",
                    "WeightedCapacity": 1,
                    "SubnetId": "subnet-0c255e6c5c642da2a",
                    "SpotPrice": "0.017"
                },
                {
                    "InstanceType": "r6g.medium",
                    "WeightedCapacity": 1,
                    "SubnetId": "subnet-06ee85eed40f5261b",
                    "SpotPrice": "0.017"
                },
                {
                    "InstanceType": "r7g.medium",
                    "WeightedCapacity": 1,
                    "SubnetId": "subnet-0d2535d7e7cacf658",
                    "SpotPrice": "0.017"
                },
                {
                    "InstanceType": "r7g.medium",
                    "WeightedCapacity": 1,
                    "SubnetId": "subnet-0c255e6c5c642da2a",
                    "SpotPrice": "0.017"
                },
                {
                    "InstanceType": "r7g.medium",
                    "WeightedCapacity": 1,
                    "SubnetId": "subnet-06ee85eed40f5261b",
                    "SpotPrice": "0.017"
                },
                {
                    "InstanceType": "r8g.medium",
                    "WeightedCapacity": 1,
                    "SubnetId": "subnet-0d2535d7e7cacf658",
                    "SpotPrice": "0.017"
                },
                {
                    "InstanceType": "r8g.medium",
                    "WeightedCapacity": 1,
                    "SubnetId": "subnet-0c255e6c5c642da2a",
                    "SpotPrice": "0.017"
                },
                {
                    "InstanceType": "r8g.medium",
                    "WeightedCapacity": 1,
                    "SubnetId": "subnet-06ee85eed40f5261b",
                    "SpotPrice": "0.017"
                },
                {
                    "InstanceType": "t4g.medium",
                    "WeightedCapacity": 1,
                    "SubnetId": "subnet-0d2535d7e7cacf658",
                    "SpotPrice": "0.017"
                },
                {
                    "InstanceType": "t4g.medium",
                    "WeightedCapacity": 1,
                    "SubnetId": "subnet-0c255e6c5c642da2a",
                    "SpotPrice": "0.017"
                },
                {
                    "InstanceType": "t4g.medium",
                    "WeightedCapacity": 1,
                    "SubnetId": "subnet-06ee85eed40f5261b",
                    "SpotPrice": "0.017"
                }
            ]
        }
    ]
}

大功告成!

記錄一下 Request ID sfr-c7ccc145-d71d-4268-8b67-089161e02af6 ,接下來會用到他。

這樣,當有人啟用了更多的 On-demand 容量而迫使您當前使用的Spot Instance 被終止後,Spot Fleet 將會從這些機型中啟動新的Spot Instance ,不可能所有機型的Spot 容量都被用盡,這是絕對不可能的!

那麼,我們要如何更新呢?比如説,Security Patch,升級nginx ,php ,wordpress 版本?

對於Wordpress 而言,他的更新很頻繁,我不希望剛post 一個新的blog 然後instance 就被terminate 了,所以,這裡我們要使用EFS 來放置所有的Wordpress 文件。

那麼nginx , php 是不行的呀,如何用terraform 來自動化這些更新的動作?

根據這個思路,我們先梳理一下具體要做哪些步驟:

首先需要 Create AMI after nginx/php/OS change with current instance ID and give a name to this AMI

aws ec2 create-image \
    --instance-id i-0716c882cb57a921d \
    --name "web2026" \
    --no-reboot \
    --tag-specifications 'ResourceType=image,Tags=[{Key=auto-delete,Value=no}]' \
    --region ap-northeast-3

然後需要 Update launch template to use this AMI and set default version

Create new version with updated AMI
aws ec2 create-launch-template-version \
    --launch-template-id lt-0716c882cb57a921d \
    --source-version '$Latest' \
    --launch-template-data '{"ImageId":"ami-"}' \
    --region ap-northeast-3

Set the new version as default
aws ec2 modify-launch-template \
    --launch-template-id lt-0716c882cb57a921d \
    --default-version '$Latest' \
    --region ap-northeast-3

Get AMI id from last step and check AMI progress
aws ec2 describe-images \
    --image-ids ami-xxxxxxxx \
    --region ap-northeast-3 \
    --query 'Images[0].State'

如果AMI 製作成功,那就 Terminate old instance ,此時Spot Fleet將會使用launch tempate 中的新的AMI 啟動新的Spot Instance。

按照上述的流程,

接下來安裝 terraform –

terraform -v
Terraform v1.5.7 on darwin_arm64

創建一個工作目錄 mkdir ami-update-workflow

創建main.tf 配置文件,需要修改的地方有 – 正確的Region,前面配置的Launch Template ID,以及啟動的Spot Fleet Request ID:

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}

provider "aws" {
  region = "ap-northeast-3"
}

# Get instance ID from spot fleet using external data source
data "external" "spot_instance" {
  program = ["bash", "-c", <<-EOT
    INSTANCE_ID=$(aws ec2 describe-spot-fleet-instances \
      --spot-fleet-request-id sfr-c7ccc145-d71d-4268-8b67-089161e02af6 \
      --region ap-northeast-3 \
      --query 'ActiveInstances[0].InstanceId' --output text)
    echo "{\"instance_id\":\"$INSTANCE_ID\"}"
  EOT
  ]
}

# Create AMI with correct EBS settings using AWS CLI
resource "null_resource" "create_ami_with_ebs" {
  provisioner "local-exec" {
    command = <<-EOT
      AMI_ID=$(aws ec2 create-image \
        --instance-id ${data.external.spot_instance.result.instance_id} \
        --name "web-${formatdate("YYYYMMDD-hhmm", timestamp())}" \
        --no-reboot \
        --block-device-mappings '[{"DeviceName":"/dev/xvda","Ebs":{"DeleteOnTermination":true,"VolumeSize":10,"VolumeType":"gp3"}}]' \
        --tag-specifications 'ResourceType=image,Tags=[{Key=auto-delete,Value=no}]' \
        --region ap-northeast-3 \
        --query 'ImageId' --output text)
      echo "{\"ami_id\":\"$AMI_ID\"}" > ami_output.json
    EOT
  }
}

# Get the AMI ID from the output file
data "local_file" "ami_output" {
  depends_on = [null_resource.create_ami_with_ebs]
  filename   = "ami_output.json"
}

locals {
  ami_data = jsondecode(data.local_file.ami_output.content)
  ami_id   = local.ami_data.ami_id
}

# Update launch template and terminate instance
resource "null_resource" "update_launch_template" {
  depends_on = [data.local_file.ami_output]

  provisioner "local-exec" {
    command = <<-EOT
  # Wait for AMI to be available
      while [ "$(aws ec2 describe-images --image-ids ${local.ami_id} --query 'Images[0].State' --output text --region ap-northeast-3)" != "available" ]; do
        echo "Waiting for AMI to be available..."
        sleep 30
      done

      # Create new version
      aws ec2 create-launch-template-version \
        --launch-template-id lt-0716c882cb57a921d \
        --source-version '$Latest' \
        --launch-template-data '{"ImageId":"${local.ami_id}"}' \
        --region ap-northeast-3

      # Set as default
      aws ec2 modify-launch-template \
        --launch-template-id lt-0716c882cb57a921d \
        --default-version '$Latest' \
        --region ap-northeast-3

      # Terminate the old instance
      aws ec2 terminate-instances \
        --instance-ids ${data.external.spot_instance.result.instance_id} \
        --region ap-northeast-3
    EOT
  }
}

output "ami_id" {
  value = local.ami_id
}

output "instance_id" {
  value = data.external.spot_instance.result.instance_id
}

在目錄中創建一個run.sh 內容物如下:

rm terraform.tfstate*
rm -rf .terraform/
terraform init

來跑一下:

./run.sh 

Initializing the backend...
......
Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.

Run “terraform plan”

......

Plan: 2 to add, 0 to change, 0 to destroy.

Changes to Outputs:
  + ami_id      = (known after apply)
  + instance_id = "i-0ef93b2b937468a98"

───────────────────────────────────────────────────────────────────────────────

Note: You didn't use the -out option to save this plan, so Terraform can't
guarantee to take exactly these actions if you run "terraform apply" now.

Run “terraform apply”,也可以直接跑到這裡不用plan 。

......
null_resource.update_launch_template: Creation complete after 3m19s [id=3702937929507644703]

Apply complete! Resources: 2 added, 0 changed, 0 destroyed.

Outputs:

ami_id = "ami-0dd89a88bf12cb2bd"
instance_id = "i-0ef93b2b937468a98"

執行完成後,spot instance 就被製作成新的AMI 並被設置為launch template 的default AMI,而且最後會terminate 當前的spot instance 喔。

目前運行穩定,沒發現有什麼問題,似乎使用ASG 也可以達成這個目的,讓我們下次再議。

CIA 最近一段時間動作頻頻,發佈了多條針對中國招募線人的廣告Videos,很多人認為是在中國的諜報人員都被處決,我並不認同,我認為這是為了掩護某些重要情報來源而故意放的煙霧彈,當你看身邊所有人都像五十萬的時候,真正的五十萬就隱藏起來了。
1 月 25 日, 2026 年

如何升級EC2 上的MacOS? How to upgrade MacOS on AWS EC2

Ken Tech 0 Comments

參考官方文件就可以了 – https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/mac-instance-updates.html

過於陳舊的MacOS 需要升級ENA driver,但通常不會有這種情況,因為使用MacOS 主要是用於iOS 開發和迅速迭代,沒有人會用五年前的Mac 來寫code,因為你要支持最新的iPhone 就必須要用最新的MacOS。而且,不是所有的版本都支持升級,支持的版本請參考該頁面說明。

使用SSH 連結到 EC2 並為ec2-user 設置一個密碼:

sudo /usr/bin/dscl . -passwd /Users/ec2-user

為了Enable the secure token for the ec2-user user,必須修改一次密碼,修改的動作並不是為了修改密碼,而是為了Enable the secure token。

vi old_password.txt

vi new_password.txt

sysadminctl -oldPassword `cat old_password.txt` -newPassword `cat new_password.txt`

2026-01-21 06:53:17.708 sysadminctl[705:6829] Attempting to change password for ec2-user…
2026-01-21 06:53:19.287 sysadminctl[705:6829] SecKeychainCopyLogin returned -25294
2026-01-21 06:53:19.287 sysadminctl[705:6829] Failed to update keychain password (-25294)
2026-01-21 06:53:19.288 sysadminctl[705:6829] - Done

確認一下真的啟用了:

sysadminctl -secureTokenStatus ec2-user

2026-01-21 06:58:35.755 sysadminctl[806:8689] Secure token is ENABLED for user ec2-user

創建一個json 文件用於Delegate ownership of the Amazon EBS root volume to the EBS root volume administrative user,這是因為在 Apple Silicon Mac (Mac2, Mac2-m2, Mac-m4 等)上,系統更新需要特定的管理權限,當你要進行 macOS 系統更新時,需要先將 EBS根磁碟區的所有權從內部磁碟管理員(aws-managed-user)委派給 EBS 根磁碟區管理使用者(通常是 ec2-user)。

vi mac-credentials.json

{
  "internalDiskPassword":"",
  "rootVolumeUsername":"ec2-user",
  "rootVolumepassword":"newPasswordHere"
}

aws ec2 create-delegate-mac-volume-ownership-task \
--instance-id i-079180f283a7b0baf \
--mac-credentials file://mac-credentials.json

{
    "MacModificationTask": {
        "InstanceId": "i-079180f283a7b0baf",
        "MacModificationTaskId": "macmodification-05b40255b8b15176c",
        "MacSystemIntegrityProtectionConfig": {},
        "StartTime": "2026-01-21T08:09:43.417000+00:00",
        "TaskState": "pending",
        "TaskType": "volume-ownership-delegation"
    }
}

aws ec2 describe-mac-modification-tasks \
--mac-modification-task-id macmodification-05b40255b8b15176c

{
    "MacModificationTasks": [
        {
            "InstanceId": "i-079180f283a7b0baf",
            "MacModificationTaskId": "macmodification-05b40255b8b15176c",
            "MacSystemIntegrityProtectionConfig": {},
            "StartTime": "2026-01-21T08:09:43.417000+00:00",
            "Tags": [],
            "TaskState": "in-progress",
            "TaskType": "volume-ownership-delegation"
        }
    ]
}

上面一般需要30~90 分鐘,我是用了四十幾分鐘,

login after rebooted:

    ┌───┬──┐   __|  __|_  )
    │ ╷╭╯╷ │   _|  (     /
    │  └╮  │  ___|\___|___|
    │ ╰─┼╯ │  Amazon EC2
    └───┴──┘  macOS Sequoia 15.7.3


softwareupdate --list
Software Update Tool

Finding available software
Software Update found the following new or updated software:
* Label: macOS Tahoe 26.2-25C56
    Title: macOS Tahoe 26.2, Version: 26.2, Size: 8111826KiB, Recommended: YES, Action: restart, 

sudo softwareupdate --install --all --restart
Software Update Tool

Finding available software
Downloading macOS Tahoe 26.2
Password: 
Downloading: 62.47%
Downloading: 93.73%
Downloading: 100.00%
Downloaded: macOS Tahoe 26.2
Restarting...


    ┌───┬──┐   __|  __|_  )
    │ ╷╭╯╷ │   _|  (     /
    │  └╮  │  ___|\___|___|
    │ ╰─┼╯ │  Amazon EC2
    └───┴──┘  macOS Tahoe 26.2
1 月 4 日, 2026 年

作為一個身處自由世界的人,我這種講法是過於自私了

Ken 隨筆 0 Comments

我原本以為昨天晚上半夜被搖醒準備爬起來是幻覺,早上忽然看到,哎,有地震過。

那看來不是幻覺。

被社會主義奴役二十五年的委內瑞拉人民有沒有獲得自由還有待觀察,但以馬杜羅為首的軍方使用裝甲車衝撞輾壓抗議人群,早已失去其執政的合法性。

至於他往美國境內走私毒品和軍火,並不是像墨西哥一樣從中國進口 fentanyl 原材料二次加工,而是哥倫比亞邊境過來的 cocaine ,日益先進的電動潛水艇技術讓美國廣袤的海岸線確實無法防範,就算是Coast Guard也會疲於奔命,關於這一點,Youtube 上有很多影片說明。

中國支持馬杜羅的大量先進武器當然是為了石油而不是為了要和美國對抗,中共從來沒有什麼路線,底線,原則之類的,只有利益之爭。

我至今還記得查韋斯女兒被一堆美鈔包圍的照片,這些所謂的社會主義革命者,其虛偽和無恥無法用適當的文字來形容,查韋斯得癌症死去,算是為他留下一點顏面,如果長命百歲,他的名聲恐怕會更加惡臭。

馬杜羅被美軍抓走後,網路上很多中國民族主義者想要共軍抓捕賴清德。

對於民主國家而言,總統被抓了副總統可以上,副總統被抓了行政院長可以上,行政院長被抓了還有立法院院長,立法院副院長。

而獨裁國家,總統被抓了,大家都不會往前衝的,你看委內瑞拉就知道。

2026年觀看的第一部電影是關於二二八出品于1989年的《悲情城市》,這部電影對於二二八的描述並不直接。

但是,想想今天的《大濛》都還遮遮掩掩,當年的《悲情城市》已經非常了不起,如果要放在一起比較,《大濛》就是0分。

這部電影以1945至1949年為背景,透過基隆九份林家四兄弟的命運,呈現二二八事件與白色恐怖下臺灣社會的動盪與壓抑。四兄弟在政權更替、黑幫勾結與政治迫害中相繼遭遇不幸,象徵臺灣人民在歷史洪流中的掙扎,沉默與創傷。電影使用多種語言(台語、日語、粵語、國語、英語)呈現,以日常生活折射政治壓迫,並沒有什麼驚心動魄的場景。

2023年出了4K 修復版,但是沒有上streaming ,大概是知道一上就會被盜版。

今日的台灣社會對於二二八的反思是嚴重不足的,因為當時的那些上海黑幫和抓捕學生的兵,官,將並沒有得到任何清算。

畢竟蔣公的日記已經把責任推給陳誠了。

新的一年,願所有的獨裁者都長命百歲,這樣我們才能看到和民主國家不一樣的千百萬種可能性。

1 月 2 日, 2026 年

真正的閱讀-貳零貳伍年年終總結

Ken 隨筆 0 Comments

這一年時間過得很快,大概是因為我還處於一種不斷學習新東西的過程中,每天都會有那麼一點點新發現。

一月的時候過年吃吃喝喝,月底的地震已經開始讓我有一點睏乏,Miley 一邊把我搖醒,我又直接睡去。Nvidia 股價因為謠言跌至120$,我跟別人說此時不買更待何時,但是我也沒有買,現在股價175$。

這一年我看了一些書,《簡明台灣人四百年史》,《被出賣的台灣》,《前線島嶼:冷戰下的金門》,《新.台灣的主張》,《百年追求:臺灣民主運動的故事卷一之自治的夢想》,《柬埔寨:被詛咒的國度》,《為人民服務》,《中共情報組織與間諜活動》,《不平等的樣貌:新加坡繁榮神話背後,社會底層的悲歌》,《今生今世》,《黎智英傳》。《生死場》,《呼蘭河傳》算是看第三遍,我發現並不是我不喜歡看書,而是我不喜歡看中國的書,也許是因為我識字程度不高,《今生今世》囫圇吞棗看一遍,覺得完全沒看懂,可能還要看一遍,而《不平等的樣貌》更像是已開發國家中產階級的無病呻吟。

二月二十八的時候我認真的看了一本關於二二八的書籍,但是我發現似乎寫得並不完備可信,顯得散亂無章,當然這可能是因為我並沒有刻意的去尋找這方面的主題。

三月因為Plex Server 要改變授權模式,以前免費的功能現在要收費,乾脆買了終身授權 lifetime 119.99$,不過這種出爾反爾的事情,一間美國公司也能做出來,那可能代表市場上確實是無人可以取代。

四月清明節回家,故居愈加破敗,洗手池下排水管壞了,廚房的排風扇壞了,地板有幾塊鬆動,浴室門口的開關面板按鈕壞了,除了排水管似乎可以買一根新管子替換,其他的地方看起來都沒有維修的必要,因為房間裡面沒有人。房間對面的酒店燈箱廣告夜裡極為刺眼,需要戴上眼罩。跑去更換駕照,告訴我說駕照沒有到期三個月之前不能更換,那就只有下次再換。

給父母的墳頭灑了一些種子,不知道明年會不會看到墳頭長出的小花。

五月做了什麼,我也不記得。

六月四日得知黑牡丹過世的消息,略有感慨,她是一個話很多的人,送我回酒店還會拉著我在車上再講半天的那種人,但命運無常,希望她下輩子可以更開心一些。

六月底去了義大利和法國,辦簽證的時候頗費了一些時間,羅馬機場入關的警察和官員個個都是年輕的帥哥美女,怪不得那麼多人熱愛義大利。西方和東方的文化進程是不一樣的,同樣一百年,發展的程度也不一樣,天天叫喊著五千年是一種極為幼稚的做法,五千年不如人家五百年好意思嗎。當然歐洲大陸有宗教的基礎,政權的更迭頻繁,遠遠沒有宗教來得持久,但教廷對於其他宗教的抹殺也是不遺餘力的,當年的教廷和現在的伊斯蘭共和有什麼區別呢,我看是沒區別。雖然說可蘭經大部分故事都跟舊約很像。

七月的時候漢光演習,這次認真的跑到窗邊觀看了一下,台北市最熱鬧的金融區街道空無一人還是讓人有點驚訝的。同事們還在說著自己是預備役哪一個梯次。等了好幾年的港股富士康,因為AI server 的利好暴漲,還是郭台銘說要選總統那一年買的,持倉2225天,終於脫手,賺二十七萬台幣,我可是真有耐心。

八月的時候第一次坐了郵輪去イシガキ和Okinawa,多年前聽說的Costa Serena,只不過她已經老了。最讓我驚喜的是我終於得見了夜裡的大海,岸邊的沙灘大都有人造光源的干擾,無法清楚的欣賞海面,郵輪上見到月下的海洋,天空中的白雲泛出一點點光和灰藍色,月光從遠處的海平面一路灑到我的腳下,海浪在月光下微波蕩漾,發出稀碎的浪花聲。然後因為日間沒有擦防曬霜,不出意外的被曬傷,最後兩天的夜裡都會被皮膚的刺痛痛醒。這是第二次來Okinawa,但是郵輪的行程過於緊湊,沒有認真逛。

九月沒有吃大閘蟹,回丈母娘家吃了海蟹,新鮮的海蟹略有鹹味,還是大閘蟹更鮮美一些,但是大閘蟹下藥太多了,少吃為好。直到秋分也沒有什麼秋意,天龍國的熱度沒有減下來,空調還是開到24度。

十月的時候用了多年的Apple Wi-Fi 終於有點問題,5G 訊號不時斷掉,換了Netgear 的入門款商用AP WAX210,效果並沒有很好,峰值速率不如Apple 的5G 頻段,但勝在他穩定,可設置多個SSID 將IoT 設備隔離,支持PoE,而且剛好在Amazon 上特價49$。十月底緬甸軍方終於假裝要對KK園區進行打擊,因為死的不是中國人,而是韓國人,打到現在還在打,你說是不是假裝。

十月底AWS 出現大規模故障,導致多個熱門網站當機,成也AWS 敗也AWS,不過在AWS 當掉的時候,你說自己的業務也當掉,大概不會有苛刻的老闆會責難你。

十一月的時候這個世界很熱鬧,官方說香港大火燒死了160人,大概是說在醫院死的就不算(這是慣用手法),看起來死的大多數是老人家,要他們移民也是強人所難,生活了一輩子的地方,沒有那麼容易就離開,所以還是秉持著同情與嘆息。日本第一位女首相高市早苗是個工作狂,在亞洲相對保守的日本社會選出一個女首相確實是很讓人感到意外,日本的軍隊正常化,大概是很多日本政治家心裡的結。

十一月中的時候CloudFlare 出現大規模故障,再一次導致多個熱門網站當機,Internet 真的需要第三者出現了。

十二月初去看了一部關於台灣白色恐怖時期的電影《A Foggy Tale – 大濛》,描寫那些想要改變歷史卻沒有改變而自己就已然消失的那些小人物,我想,這是導演本人的理解,但台灣的導演真的應該要放眼世界,不過,即使放眼世界,台灣也是處於那個不上不下的位置,被屠殺的不是最厲害的,也不是流血最少的,恰恰好符合導演想要表達的意思。

十二月中的時候就去打了流感疫苗,因為通常生效需要兩個星期,流感季很快就要來了,自費的流感疫苗都是德國🇩🇪生產的,所以很讓人放心,記憶中只有幼年的時候媽咪帶我打過一次流感疫苗。

十二月中內政部封鎖小紅書這件事情讓大家很意外,說起來是有法可依,但封鎖手段並不徹底,可以輕鬆繞過,再簡單一點講就是執法不嚴,他們沒有意識到這種執法不嚴並不會展現出所謂台灣社會的人文關懷,而是會從根本上損害政府的執政威信,就不能封徹底一點?數發部真是一堆廢物,又或者是,除了上面的官員,下面的人並沒有想要認真執行封鎖,敷衍了事而已。

公司尾牙什麼也沒撈到的時候聽說捷運台北站發生了無差別殺人事件,從片段看起來,殺手沉著穩定,臨危不亂,有這種膽色為什麼不去混黑道,立刻出人頭地,不過後來看到他曾經服役,想來應該是不會走黑道那條路,那麼是共匪還是哈瑪斯呢?以色列剛剛好和外交部次長談了防務合作沒幾天,總是要有一個誘因才對。

共軍頻繁的軍事演習大概已經成為了台灣人口中的笑話,股市不跌反漲,如果大街上抓一個人來問可能他都不知道這回事,新聞裡記者採訪漁民說軍事演習是不是對你們有影響,今天的漁獲是不是少了很多,漁民說是啊是少一些但是,是因為天氣不好啦。

平安夜和聖誕節,臺北東區的人和去年相比少了很多,不知道是不是因為下雨,跨年夜的人也比去年少,也許是因為跨年夜也下雨,101的焰火只有六分鐘,比雙十國慶節的焰火時間還要短。

今年還真是閱讀了不少的書,大概是我人生中看書最多的一年。

1 月 1 日, 2026 年

How to shrink the size of an AWS EBS volume – 如何對AWS EBS 進行縮容

Ken Tech 0 Comments

這個問題很古早,官方文檔告訴你:不行。

2026-02-06 請勿使用該方式縮容 – 這個方法有問題,在Amazon Linux 2023 升級kernel後將會無法啟動,會卡在grub 的環節,需要在每一次更新kernel 後,執行“grub2-mkconfig -o /boot/grub2/grub.cfg” 才能正常啟動。

但是,在特定的條件下是可以的。

特定的條件如下:

a)一台救援EC2。
b)一台和舊EC2 OS 版本完全一樣的系統,但root volume 是更小的size。
c)OS 版本必須完全一樣,並且都升級到最新的,相同的kernel版本,不一樣後果自負。

那麼場景如下:

一台救援EC2 ,使用Amazon Linux 2023,root volume 8G
一台新EC2 ,使用較小的EBS volume size,root volume 10G
一台舊EC2,使用較大的EBS volume size ,root volume 20G

步驟如下:

首先,將新舊兩台EC2 的root volume 都detach 然後attach 到救援EC2 上。

接下來,在救援EC2上查看UUID,可以看到新EC2 和救援EC2 的UUID 是一樣的,這是因為使用了相同的AMI 啟動。將新舊兩台EC2 的root volume EBS 作為data volume 分別mount 到一個位置,例如 /10G 和 /20G ,可以看到fstab 配置文件中的UUID 都是原來的,等一下我們要修改10G 那個。

sudo -i
mkdir /20G
mkdir /10G

lsblk -f

mount /dev/nvme1n1p1 /20G    # 20G old root volume
mount -o nouuid /dev/nvme2n1p1 /10G    # 10G new root volume

然後使用rsync 將 /20G 目錄中的文件使用rsync 完全同步到 /10G 目錄中,請注意:排除掉 /boot 目錄。

rsync -avH --progress --delete --exclude=/boot /20G/ /10G/

在進行上述同步前,您當然需要先行確認 /20G 目錄中的實際總容量小於10G並且有足夠冗余,否則您走到這一步從一開始就是錯誤的決定。

同步完成後, 修改 vi /10G/etc/fstab 中的UUID 為新EBS volume 的UUID。

關閉救援EC2 ,把10G EBS volume 掛載到新的EC2 上啟動,完成。

1 2 3 4›»

過 客

  1. R2 on 卷進了美商5 月 15 日, 2024 年

    终于回来了,好。

  2. Ken on Mommy最後的樣子11 月 6 日, 2023 年

    也沒有很久吧,最近終於閒下來

  3. R2 on Mommy最後的樣子10 月 26 日, 2023 年

    好久不见

  4. Ken on 天朝Loli控组曲(带歌词,修正版)10 月 12 日, 2023 年

    哈哈哈,祝福你,好人一生平安

  5. liu on 天朝Loli控组曲(带歌词,修正版)10 月 12 日, 2023 年

    hello,我在找天朝lolicon组曲时发现了你的博客,感谢你十四年前做出的贡献,祝一切安好

February 2026
S M T W T F S
1234567
891011121314
15161718192021
22232425262728
« Jan    

Spam Blocked

102,231 spam blocked by Akismet

↑

© 初心易得,始終難守 2026
Powered by WordPress • Themify WordPress Themes