如何在Oracle云多compartment实例中自动化更新现有公钥?
方案一:OCI CLI + 批量SSH执行(快速落地)
如果现有密钥还能正常登录实例,这个方案最直接:
- 收集所有目标Compartment的OCID,存入
compartments.txt(每行一个OCID) - 导出所有实例的公网IP(如果用私有网络访问就替换为私有IP):
while read comp_id; do oci compute instance list --compartment-id "$comp_id" --query 'data[*]."public-ip"' --output text >> instance_ips.txt done < compartments.txt
- 准备新公钥文件
new_keys,批量执行替换(替换前自动备份原文件):
while read ip; do ssh -o StrictHostKeyChecking=no your-user@"$ip" "cp ~/.ssh/authorized_keys ~/.ssh/authorized_keys.bak && cat /dev/stdin > ~/.ssh/authorized_keys" < new_keys done < instance_ips.txt
方案二:OCI Run Command(无SSH依赖,更可靠)
如果实例SSH网络不通,或者现有密钥已失效,用OCI原生的Run Command:
- 确认所有实例已启用Cloud Agent(默认启用,未启用则批量开启):
while read comp_id; do instance_ids=$(oci compute instance list --compartment-id "$comp_id" --query 'data[*].id' --output text) for instance_id in $instance_ids; do oci compute instance update --instance-id "$instance_id" --agent-config '{"is-management-agent-enabled": true, "is-monitoring-agent-enabled": true}' done done < compartments.txt
- 编写替换脚本
replace_keys.sh:
#!/bin/bash # 替换为你的新公钥 NEW_KEY="ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQD..." # 替换为目标用户的密钥路径,root用户用/root/.ssh/authorized_keys KEY_PATH="/home/your-user/.ssh/authorized_keys" # 备份原文件 cp "$KEY_PATH" "${KEY_PATH}.bak" # 写入新密钥 echo "$NEW_KEY" > "$KEY_PATH" # 修复权限 chown your-user:your-user "$KEY_PATH" chmod 600 "$KEY_PATH"
- 遍历Compartment批量执行命令:
while read comp_id; do instance_ids=$(oci compute instance list --compartment-id "$comp_id" --query 'data[*].id' --output text) for instance_id in $instance_ids; do oci compute instance run-command \ --instance-id "$instance_id" \ --script-file replace_keys.sh \ --execution-time-out-in-seconds 300 done done < compartments.txt
方案三:Ansible 动态Inventory修正(解决之前的问题)
你之前用Ansible没成功,大概率是没配置多Compartment的动态主机列表:
- 安装OCI Ansible Collection:
ansible-galaxy collection install oracle.oci - 配置动态Inventory文件
oci_inventory.yml,指定所有目标Compartment:
plugin: oracle.oci.oci auth_type: instance_principal # 也可使用api_key认证 compartments: - ocid1.compartment.oc1..xxx - ocid1.compartment.oc1..yyy # 若需递归获取子Compartment,替换上面的compartments配置为: # compartment_id: ocid1.compartment.oc1..root_compartment_id # fetch_compartments: True
- 编写Playbook
replace_keys.yml:
- name: Replace authorized keys hosts: all become: yes vars: new_public_key: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQD..." target_user: "your-user" tasks: - name: Backup original authorized_keys copy: src: "/home/{{ target_user }}/.ssh/authorized_keys" dest: "/home/{{ target_user }}/.ssh/authorized_keys.bak" remote_src: yes - name: Write new public key copy: content: "{{ new_public_key }}" dest: "/home/{{ target_user }}/.ssh/authorized_keys" owner: "{{ target_user }}" group: "{{ target_user }}" mode: '0600'
- 执行Playbook:
ansible-playbook -i oci_inventory.yml replace_keys.yml
关键注意事项
- 所有操作先在单台测试实例验证,避免批量失误
- 确保执行OCI命令的用户拥有
compute instance read、compute instance runCommand(方案二需要)等权限 - 如果替换root用户的密钥,需对应修改路径和权限配置
内容的提问来源于stack exchange,提问作者N. J
相关产品推荐
相关产品推荐

