如何访问vm
如何访问虚拟机¶
在管理虚拟机时,能够访问虚拟机控制台至关重要。KubeVirt 提供了两种主要方式来访问虚拟机的控制台:串行控制台(Serial Console)和图形化(VNC)。
串行控制台和图形化访问虚拟机¶
使用串行控制台和图形化访问虚拟时,均需要先安装
virtctl命令,从github上 kubevirt 仓库下载对应版本即可。
- 串行控制台访问虚拟机
通过串行控制台访问虚拟机非常简单,只需要使用
virtctl console命令即可。
- 图形化访问虚拟机
通过图形化窗口访问虚拟机,需要先安装
注意 在执行上述命令时,需要能打开图形窗口,如果服务器端没有桌面,又或者是用secureCRT等工具远程连接,则还需借助Xmanager工具的Passive,将图形窗口映射到本地电脑上。virt-viewer命令。如果连接失败,可尝试加上## 1. 在本地电脑上先打开Xmanager的Passive组件 ## 2. 在secureCRT的服务器终端执行export命令,将DISPLAY变量设置为本地电脑的IP地址 export DISPLAY=192.168.59.1:0.0 ## 3. 最后执行 virtctl vnc命令 virtctl vnc cirros-vm01-v参数,打印出详细日志
如果仅希望开启VNC代理,然后在本地用VNC客户端访问,则可以使用如下命令
这样将仅打印出VNC的端口号5009,我们可以根据这个端口手动使用任何兼容 VNC 的客户端工具连接到虚拟机的图形界面。
SSH访问虚拟机¶
在管理虚拟机时,将SSH公钥注入到虚拟机是一种常见的操作方式。一旦 SSH 公钥成功注入到虚拟机中,我们就可以使用对应的私钥通过 SSH 协议登录并访问虚拟机进行管理和维护操作。
KubeVirt 提供了两种方式来注入 SSH 公钥:静态公钥注入和动态公钥注入。
- 静态公钥注入:指的是在虚拟机首次启动时通过
cloud-init将公钥写入到虚拟机内部。在创建虚拟机时,用户可以使用启动脚本来对虚拟机进行多种定制化操作。将SSH公钥注入到虚拟机的一种方法是通过
cloud-init,当然还有其他更安全、灵活的方案。 例如,将SSH公钥放到k8s的Secret对象中,这样可以确保应用程序数据(脚本命令)和用于访问虚拟机的凭据数据(秘钥)相互分离。那是如何做到的呢?
虚拟机的访问凭证API提供了一种机制,在虚拟机初始化阶段是不依赖cloud-init用户数据来预配置SSH公钥。这意味着,即使在没有或者不修改cloud-init用户数据的情况下,也可以向虚拟机中注入SSH公钥。 通过将SSH公钥放入k8s的secret对象,这是一种安全存储敏感信息的方式。k8s 的secret对象就是用来保存诸如密码、token 或者 SSH 公钥等敏感数据的。
简而言之,我们通过创建k8 secret来存储SSH公钥,通过 configDrive|noCloud 机制将元数据注入到虚拟机中,而无需将公钥直接写入cloud-init用户数据。
说明: configDrive 用于向虚拟机或裸金属服务器传递元数据和用户数据。它通常表现为一个物理磁盘设备或 ISO 映像,包含启动时配置虚拟机所需的各种信息,如网络配置、SSH 密钥等。 当使用 KubeVirt 并指定了 ConfigDrivePropagation 方法时,意味着公钥不会直接写入虚拟机的文件系统或其他常规启动脚本中,而是以元数据的形式被放在 configDrive 中。 这样,虚拟机在启动过程中会通过 cloud-init 解析 configDrive 中的元数据,并将 SSH 公钥设置为允许登录系统的有效密钥,从而实现对虚拟机的安全访问。
示例1,cloud-init方式注入公钥
cat << END > image-centos.yaml
apiVersion: cdi.kubevirt.io/v1beta1
kind: DataVolume
metadata:
name: img-centos7
namespace: default
spec:
source:
http:
url: http://192.168.59.241:10800/images/CentOS-7-x86_64-GenericCloud.qcow2
pvc:
storageClassName: "ceph-hdd-block"
accessModes:
- ReadWriteMany
resources:
requests:
storage: 10Gi
volumeMode: Block
END
cat << END > startup-script
#cloud-config
hostname: vm-centos01
ssh_pwauth: True
disable_root: False
timezone: Asia/Shanghai
password: 123456
chpasswd: {"list":"root:123456",expire: False}
runcmd:
- setenforce 0
- sed -i 's/^SELINUX=enforcing$/SELINUX=disabled/' /etc/selinux/config
- sed -i "/PermitRootLogin/s/^.*$/PermitRootLogin yes/g" /etc/ssh/sshd_config
- systemctl restart sshd.service
#- echo root:12345678 |chpasswd
ssh_authorized_keys:
- ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCz4gfQJ0xW235NjltRUFFFw6AtE5ZDVT7EuEJX7sc/QCICTWdYd+5MG9cDr3hzzi0OS9eiVVNB7JGa57kb/Um1KZCFy/DmNHJXE9TAhTZUf8kgzVr/tHGXrm845adu6Guij1QludChqx0iBAB+X9M3Oh0AD854Mwigi5dxV7uNb8/YWTE8eXOkcV4c7RJsFq2N/ValbtzXMUcgr1ySHmb9ZBncJWK56kZ4OkmoiKrmnJsWHs7Nte/ooBXXfRiLcik7S2G/tgJLL34DGLMedBZ7wzX5tXiYoTcCSpXmGmFAFxoaCwtl3sptdO9tmIZ0f2jtTTYeZ/QEvUiUCw9riCljvIygBht4d9EfFwEhr4pDxs0Rr7Pcq2jBXocqg3ue8AUCySvxNW5WqkAPxKi1sZNrGivadwARxhJ5jkqX91hfcuIFzE3nOrryfrXZ5XEvJZrk7y3a6S+Eo0OfI/Iz1RgPBQr0/iggZlvXgteyjzggviF4g+bmVmi7kGMXZRPiH/8= root@k8s01
END
# Create the VM spec
cat << END > vm-centos01.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-centos01-bootdisk
namespace: default
spec:
storageClassName: "ceph-hdd-block"
volumeMode: Block
accessModes:
- ReadWriteMany
dataSource:
kind: PersistentVolumeClaim
name: img-centos7
resources:
requests:
storage: 10Gi
---
apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
name: vm-centos01
namespace: default
spec:
running: true
template:
metadata:
labels:
kubevirt.io/size: small
kubevirt.io/domain: vm-centos01
#annotations:
# ovn.kubernetes.io/ip_address: 12.244.10.203
spec:
domain:
cpu:
cores: 1
model: host-passthrough
memory:
guest: 2Gi
devices:
disks:
- name: root-disk
disk:
bus: virtio
- name: cloudinitdisk
disk:
bus: virtio
interfaces:
- name: default
masquerade: {}
resources:
requests:
memory: 2048M
networks:
- name: default
pod: {}
volumes:
- name: root-disk
persistentVolumeClaim:
claimName: pvc-centos01-bootdisk
- name: cloudinitdisk
cloudInitNoCloud:
userDataBase64: $(cat startup-script | base64 -w0)
END
## 注意每次修改 startup-script 要 重新生成 vm-centos01.yaml文件,否则 userDataBase64 不会更新
# kubectl apply -f vm-centos01.yaml
# kubectl get vmi
NAME AGE PHASE IP NODENAME READY
vm-centos01 107s Running 12.244.0.42 k8s03 True
## 通过私钥访问虚拟机,注意用的是与公钥对应的私钥
ssh -i /root/.ssh/id_rsa centos@12.244.0.42
示例2,使用k8s的secret来存放SSH公钥,并将公钥与虚拟机关联起来
kubectl create secret generic my-pub-key --from-file=key1=/root/.ssh/id_rsa.pub
cat << END > vm-centos02.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-centos02-bootdisk
namespace: default
spec:
storageClassName: "ceph-hdd-block"
volumeMode: Block
accessModes:
- ReadWriteMany
dataSource:
kind: PersistentVolumeClaim
name: img-centos7
resources:
requests:
storage: 10Gi
---
apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
name: vm-centos02
spec:
running: true
template:
spec:
domain:
cpu:
cores: 1
model: host-passthrough
memory:
guest: 2Gi
devices:
disks:
- disk:
bus: virtio
name: root-disk
- disk:
bus: virtio
name: cloudinitdisk
rng: {}
interfaces:
- name: default
masquerade: {}
resources:
requests:
memory: 2048M
networks:
- name: default
pod: {}
terminationGracePeriodSeconds: 0
accessCredentials:
- sshPublicKey:
source:
secret:
secretName: my-pub-key
propagationMethod:
configDrive: {}
volumes:
- name: root-disk
persistentVolumeClaim:
claimName: pvc-centos02-bootdisk
- name: cloudinitdisk
cloudInitConfigDrive:
userData: |-
#cloud-config
hostname: vm-centos02
ssh_pwauth: True
disable_root: False
timezone: Asia/Shanghai
password: 123456
chpasswd: {"list":"root:12345678",expire: False}
runcmd:
- setenforce 0
- sed -i 's/^SELINUX=enforcing$/SELINUX=disabled/' /etc/selinux/config
- sed -i "/PermitRootLogin/s/^.*$/PermitRootLogin yes/g" /etc/ssh/sshd_config
- systemctl restart sshd.service
#- echo root:12345678 |chpasswd
END
- 动态公钥注入:指的是在虚拟机启动时或者在虚拟机运行时(通过qemu-guest-agent)注入公钥。
注意,动态公钥注入的前置条件是镜像中已经安装好了合适版本的Qemu-guest-agent、并且关闭了Selinux,否则会出现注入不成功的情况,比如用centos7的镜像就不行,qemu-guest-agent版本太低。
## 此处使用fedora镜像验证,因为centos7镜像中Qemu-guest-agent版本太低,运行时会报"The command guest-ssh-add-authorized-keys has not been found')"
kubectl create secret generic my-pub-key2 --from-file=key1=/root/.ssh/id_rsa.pub
cat << END > vm-fedora01.yaml
apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
name: vm-fedora01
spec:
running: true
template:
spec:
domain:
cpu:
cores: 1
model: host-passthrough
memory:
guest: 2Gi
devices:
disks:
- disk:
bus: virtio
name: root-disk
- disk:
bus: virtio
name: cloudinitdisk
rng: {}
interfaces:
- name: default
masquerade: {}
resources:
requests:
memory: 2048M
networks:
- name: default
pod: {}
terminationGracePeriodSeconds: 0
accessCredentials:
- sshPublicKey:
source:
secret:
secretName: my-pub-key2
propagationMethod:
qemuGuestAgent:
users:
- fedora
volumes:
- name: root-disk
containerDisk:
image: registry.demo.com/containerdisks/fedora:latest
- name: cloudinitdisk
cloudInitConfigDrive:
userData: |-
#cloud-config
hostname: vm-fedora01
ssh_pwauth: True
disable_root: False
timezone: Asia/Shanghai
password: 123456
chpasswd: {"list":"root:12345678",expire: False}
bootcmd:
- setenforce 0
- sed -i 's/^SELINUX=enforcing$/SELINUX=disabled/' /etc/selinux/config
runcmd:
- sed -i "/PermitRootLogin/s/^.*$/PermitRootLogin yes/g" /etc/ssh/sshd_config
- systemctl restart sshd.service
#- echo root:12345678 |chpasswd
END
centos7 (使用镜像:CentOS-7-x86_64-GenericCloud.qcow2,qemu-guest-agent版本是2.12)公钥注入不成功,可能会遇到如下错误,原因是qemu-guest-agent版本太低,无法识别guest-ssh-add-authorized-keys命令。
{"component":"virt-launcher","kind":"","level":"error","msg":"Error encountered writing access credentials using guest agent","name":"vm-centos03","namespace":"default","pos":"access_credentials.go:491","reason":"virError(Code=1, Domain=10, Message='internal error: unable to execute QEMU agent command 'guest-ssh-add-authorized-keys': The command guest-ssh-add-authorized-keys has not been found')","timestamp":"2024-02-12T08:16:28.739875Z","uid":"223a2a48-411e-407d-a204-dccab7b49241"}接下来,用上面的img-ubuntu2204镜像就可以使用ssh秘钥登录了## 基于ubuntu重新掉作镜像,size不要设置太大,安装好qemu-guest-agent,关闭前需要删除 /var/lib/cloud/instance/boot-finished cat << END > image-ubuntu2204.yaml apiVersion: cdi.kubevirt.io/v1beta1 kind: DataVolume metadata: name: img-ubuntu2204 namespace: default spec: source: http: url: http://192.168.59.241:10800/images/ubuntu-22.04-server-cloudimg-amd64.img pvc: storageClassName: "ceph-hdd-block" accessModes: - ReadWriteMany resources: requests: storage: 5Gi volumeMode: Block END cat << END > vm-ubuntu.yaml --- apiVersion: kubevirt.io/v1 kind: VirtualMachine metadata: name: vm-ubuntu spec: running: true template: spec: domain: cpu: cores: 1 model: host-passthrough memory: guest: 2Gi devices: disks: - disk: bus: virtio name: root-disk - disk: bus: virtio name: cloudinitdisk rng: {} interfaces: - name: default masquerade: {} resources: requests: memory: 2048M networks: - name: default pod: {} terminationGracePeriodSeconds: 0 volumes: - name: root-disk persistentVolumeClaim: claimName: img-ubuntu2204 - name: cloudinitdisk cloudInitConfigDrive: userData: |- #cloud-config hostname: vm-ubuntu ssh_pwauth: True disable_root: False timezone: Asia/Shanghai password: 123456 chpasswd: {"list":"root:12345678",expire: False} bootcmd: - setenforce 0 - sed -i 's/^SELINUX=enforcing$/SELINUX=disabled/' /etc/selinux/config runcmd: - sed -i "/PermitRootLogin/s/^.*$/PermitRootLogin yes/g" /etc/ssh/sshd_config - systemctl restart sshd.service #- echo root:12345678 |chpasswd END ## 进入vm-ubuntu虚拟机中,执行如下命令 apt-get update apt-get install qemu-guest-agent -y ## 删除 cloud-init 执行完成的标记文件 rm -rf /var/lib/cloud/instance/boot-finished