【翻译】如何在Nutanix Karbon上并排运行容器和虚拟机

Nutanix高级系统可靠性工程师Nimal Kunnath的特邀文章

全世界的组织正在以惊人的速度采用Kubernetes和云原生技术。容器已经成为打包应用的新规范,而Kubernetes则走在前列,大规模地协调和运行容器。应用程序现代化已日益成为IT领域的首要任务之一。这在大流行之后被加速,各行业迅速转变以满足新兴需求。事实上,Gartner指出, 69%的董事会在COVID-19的破坏后加快了他们的数字业务计划

然而,这种转变说起来容易,做起来难。 大多数组织已经在虚拟机和维护它们的生命周期的做法上投入了大量资金。在虚拟化计算平台上运行的传统应用程序将不得不被重构或重新平台化,以利用新的云原生环境。这是很耗时的,而且必须在对业务影响最小的情况下谨慎进行。能够保持相同的质量和性能是另一个重大挑战。

进入KubeVirt。KubeVirt是一个开源项目,它使虚拟机可以由Kubernetes和容器一起管理。在应用程序可能包括必须在虚拟机中运行的服务的情况下,这一点尤其重要。这里的重点是,使用原生的Kubernetes工具,虚拟机被视为一流的公民。运营商可以选择使用单一平台,减少管理两个堆栈和多个管理平面的复杂性。

Nutanix在运行虚拟化工作负载方面的能力一直被认为 是行业领导者。 Nutanix还通过其管理的Kubernetes解决方案Nutanix Karbon,使容器化工作负载得以运行。通过KubeVirt,客户现在可以自由地在它们之间迁移虚拟机工作负载,同时继续受益于Nutanix的 分布式扩展存储

最近, Nutanix宣布 与红帽建立战略合作伙伴关系,在这方面更有希望,因为红帽提供的OpenShift虚拟化是一种利用KubeVirt的解决方案。OpenShift通过先进的操作和监控能力进一步增强了用户体验。

让我们来看看如何使用Nutanix Karbon运行和管理虚拟机。

下载所提供的样本文件,以指导你阅读这篇文章。

git clone https://github.com/nkunnath/kubevirt-karbon.git && cd kubevirt-karbon 

安装KubeVirt

由于KubeVirt是Kubernetes的虚拟机管理插件,所以应该已经使用Nutanix Karbon部署了一个集群。KubeVirt的核心是通过 Kubernetes的自定义资源定义API添加一个新的 "虚拟机 "对象来扩展Kubernetes。这使得Kubernetes的API能够像其他本地对象一样管理虚拟机。

下面的步骤将在你的集群中安装KubeVirt。

出口 RELEASE=v0.35.0

kubectl apply -f https://github.com/kubevirt/kubevirt/releases/download/${RELEASE}/kubevirt-operator.yaml # Deploy the KubeVirt operator

kubectl apply -f https://github.com/kubevirt/kubevirt/releases/download/${RELEASE}/kubevirt-cr.yaml # 创建KubeVirt CR,触发实际安装。

kubectl -n kubevirt wait kv kubevirt --for condition=Available --timeout=-1s # 等待,直到所有KubeVirt组件都启动。

默认情况下,KubeVirt会尝试启用硬件模拟。由于Karbon Kubernetes工作节点目前不支持硬件虚拟化,我们将使用软件模拟。

启用软件模拟是通过编辑KubeVirt的CR来完成的,如下所示。

kubectl edit -n kubevirt kubevirt kubevirt

```
在spec.config中添加以下片段
```
    spec:
      配置。
        developerConfiguration:
          useEmulation: true

Karbon中的hostPath是不同的 - /var/nutanix/var/lib/kubelet/pods。为了适应这一点,我们将修改为卷挂载而部署的KubeVirt DaemonSet,以便正确工作。让我们对该对象进行实时修改,因为目前还没有运行的虚拟机。

kubectl edit daemonsets.app virt-handler -n kubevirt

```
将 spec.template.spec.volumes[].hostPath 从 /var/lib/kubelet/pods 改为 /var/nutanix//var/lib/kubelet/pods。最后的改动如下。
```

- name: kubelet-pods-shortened
  hostPath:
    路径。/var/nutanix/var/lib/kubelet/pods
    类型:''
- name: kubelet-pods
  hostPath:
    路径。/var/nutanix/var/lib/kubelet/pods
    类型:''

这应该重新启动负责处理虚拟机操作的virt-handler pods,以满足所需的状态。

安装CDI

当创建一个虚拟机时,有多种方法来提供持久性存储。我们将在这里使用由容器化数据导入器(CDI)项目提供的 DataVolumes。DataVolumes是一种从网络服务器或容器注册表自动导入虚拟机磁盘到PVC的方法。我们将在这里从Nutanix云中导入一个正在运行的Ubuntu虚拟机的磁盘。

与KubeVirt类似,后续步骤将安装CDI操作员和自定义资源。

VERSION=$(curl -s https://github.com/kubevirt/containerized-data-importer/releases/latest | grep -o "v[0-9]\。[0-9]*\。[0-9]*")

kubectl create -f https://github.com/kubevirt/containerized-data-importer/releases/download/$VERSION/
cdi-operator.yaml

kubectl create -f https://github.com/kubevirt/containerized-data-importer/releases/download/$VERSION/cdi-cr.yaml

我们将在命名空间vm-objects中部署虚拟机和磁盘。

kubectl create namespace vm-objects

为了让DataVolume被导入Kubernetes,我们需要提供Prism Central的访问凭证。Prism Central,其v3 REST API端点,将是所有外部流量的主要接触点。

用下面的模板创建一个秘密,根据你的要求改变用户名和密码。

cat <<EOF >pc-secret.yaml
apiVersion: v1
kind: Secret
元数据。
  名称: pc-access-secret
  命名空间: vm-objects
类型。不透明的
数据。
  accessKeyId:"YWRtaW4=" # Prism Central的用户名,base64编码>。
  secretKey:"TnV0YW5peC8xMjM0" # Prism Central的密码,base64编码>。
EOF

我们还需要为数据导入指定自定义TLS证书。一个额外的要求是,Prism Central证书应该有一个指定的主题替代名称。这主要是由于底层Go库强制要求在SSL证书中使用SAN。如果你的环境中使用的证书已经有了SAN扩展名,你将不得不把证书添加为配置图,在访问PC时应该使用(见下文)。

如果证书没有SAN,请与你的安全团队合作,把它们替换掉。

在我下面的演示中,我替换了我的实验室服务器上的自签名SSL证书,将IP地址作为SAN。请自由使用该模板并更新字段(san.cnf)以符合你的组织的安全最佳实践。

生成新的证书,方法如下。

openssl req -x509 -nodes -days 3652 -newkey rsa:2048 -keyout pckey.pem -out pccert.pem -config san.cnf

从新的证书中创建一个ConfigMap对象,稍后在导入DataVolume时将会用到。

kubectl create configmap pc-config-map -n vm-objects --from-file=pccert.pem

还要确保新的证书被上传到Nutanix Prism Central,并且浏览器反映了这个变化。关于这个工作流程的更多细节,请点击 这里

  • 如果更换或修改证书是不可行的,那么你可能要下载磁盘并在 本地系统上上传。

现在我们准备创建卷和虚拟机。

创建DataVolume

我们将使用Prism Central的 REST API v3来抓取我们需要的磁盘镜像。一个正在运行的Ubuntu虚拟机的磁盘已经被上传到本演示中,作为一个随时可以使用的镜像。我们可以根据v3/images端点快速查询镜像列表和它们各自的UUID(在运行此命令前安装jq)。

curl -k -s -u admin:<password> -X POST --header "Content-Type: application/json" --header "Accept: application/json" -d '{"kind":"image", "length":25}' "https://10.63.19.14:9440/api/nutanix/v3/images/list" | python -mjson.tool | jq . 'entities[].spec.name' | cat -n
     1 "karbon-ntnx-1.0"
     2 "cirros"
     3 "Bionic Beaver - UEFI---SCSI磁盘镜像"
     4 "Bionic Beaver---SCSI 磁盘镜像"
     5 "Virt IO"
     6 "SQL Server 2014"



curl -k -s -u admin:<password> -X POST --header "Content-Type: application/json" --header "Accept: application/json" -d '{" kind":"image", "length":25}' "https://10.63.19.14:9440/api/nutanix/v3/images/list" | python -mjson.tool | jq . 'entities[].metadata.uuid' | cat -n
     1 "6a43a6f6-3474-493e-ae83-8565f5824725"
     2 "a98e24d4-8502-48df-8fd0-0f9ba78407a0"
     3 "d69dcf69-7117-438e-9745-72529f323815"
     4 "c6987acd-27b8-474b-99e1-0bacf488af59"
     5 "575b94bd-021f-4d77-9406-ffec6f0ab171"
     6 "cdddfdd6-6347-4cb2-9f4f-d5c282e80356"

第4项是我们选择的磁盘镜像。我们现在用下面的配置文件创建DataVolume。

cat <<EOF > bionic-image-dv.yaml
apiVersion: cdi.kubevirt.io/v1beta1
类型。DataVolume
元数据。
  name: bionic-image-dv
  命名空间: vm-objects
规格。
  source:
      http:
         url:"https://10.63.19.14:9440/api/nutanix/v3/images/c6987acd-27b8-474b-99e1-0bacf488af59/file" 
         secretRef: "pc-access-secret"     
         certConfigMap:"pc-config-map"    
  pvc:
    storageClassName: virtual-machine-sc
    accessModes:
      - 一次性读写(ReadWriteOnce
    资源。
      请求。
        存储。"4Gi"
EOF

验证DV和相应的PVC是否创建成功。这可能需要几分钟时间,取决于源磁盘的大小和网络带宽。

kubectl get datavolumes -n vm-objects          
名称 阶段 进度 重新启动 年龄
bionic-image-dv ImportInProgress N/A 1 48s
kubectl describe datavolumes -n vm-objects bionic-image-dv
.
.
事件。
  类型 原因 年龄 来自 信息
  ---- ------ ---- ---- -------
  正常 待定 3m1s datavolume-controller PVC bionic-image-dv 待定
  正常 绑定 2m57s datavolume-controller PVC bionic-image-dv 绑定
  正常导入计划 2m1s (2m57s中的2次) datavolume-controller 导入bionic-image-dv的计划。
  正常 ImportInProgress 118s (x2 over 2m37s) datavolume-controller 导入bionic-image-dv过程中
  正常导入成功 81s datavolume-controller 成功导入到PVC bionic-image-dv中。
kubectl get pvc -n vm-objects          
名称 状态 卷容量 访问模式 存储类别 年龄
bionic-image-dv Bound pvc-55f3d5fb-ff5d-426c-9cc8-c000b3079f0a 4Gi RWO virtual-machine-sc 3m23s

一旦磁盘被成功导入,我们就可以继续创建虚拟机了。

创建虚拟机

根据需要用你的密码/SSH密钥修改云端启动配置。还要注意,工作节点应该有足够的CPU/内存来分配所要求的资源。

cat <<EOF > bionic-image-vm.yaml
apiVersion: kubevirt.io/v1alpha3
类型。虚拟机器设备(VirtualMachineInstance
元数据。
  标签。
    kubevirt.io/vm: bionic-image-vm
  名称: bionic-image-vm
  命名空间: vm-objects
规格。
  域。
    cpu:
      核数:2
    设备。
      磁盘。
      - 磁盘。
          总线: virtio
        名称: datavolumedisk1
      - 磁盘。
          总线:Virtio
        名称: cloudinitdisk
      接口。
      - 名称:默认
        桥接。{}
    资源。
      请求。
        内存: 2048M
  网络。
  - name: default
    pod:{}
  volumes:
  - dataVolume:
      name: bionic-image-dv
    name: datavolumedisk1
  - cloudInitNoCloud。
      用户数据。|-
        #cloud-config
        密码: nutanix/4u
        ssh_pwauth: True
        chpasswd:{ expire:False }
    name: cloudinitdisk
EOF

确认虚拟机实例已创建。

kubectl get virtualmachineinstance -n vm-objects          
名称 年龄 阶段 ip 节点名
bionic-image-vm 48s Running 172.20.152.142 karbon-nk-krbn-kubevirt-107bb6-k8s-worker-0

你也可以在虚拟机规格中直接定义DataVolume规格。看一下启用了UEFI的虚拟机的样本,并按你的意愿进行修改。

kubectl create -f vm/uefi-vm.yaml

虚拟机访问

现在,虚拟机已经在Kubernetes中运行,我们需要一种方法来访问它。KubeVirt为VNC访问提供了一个websocket API。用下面的一个命令来部署它。

kubectl create -f vnc/vnc.yaml
# 获取virtvnc服务的NodePort
kubectl get service -n kubevirt virtvnc       
名称 类型 cluster-ip external-ip port(s) 年龄
virtvnc NodePort 172.19.48.180 <none> 8001:30952/TCP 3m2s

要访问VNC控制台,浏览到 http://NODE_IP:VNC_NODE_PORT。查询参数namespace允许你通过namespace来过滤虚拟机的。

Screenshot of query parameter namespace to access Tthe VNC consoles

你也可以通过创建一个服务节点端口从集群外访问虚拟机。

cat <<EOF > bionic-svc.yaml
apiVersion: v1
类型: 服务
元数据。
  名称: bionic-vm-ssh
  命名空间: vm-objects
规格。
  端口。
  - 名称: bionic-vm-ssh
    节点端口:30120
    协议。TCP
    端口。22
    目标端口: 22
  选择器。
    kubevirt.io/vm: bionic-image-vm
  类型。节点端口
EOF

使用上一步创建的NodePort连接到虚拟机。

先前在虚拟机内创建的演示文件仍然存在于文件系统中。我们还可以通过在集群外ping到www.nutanix.com 来验证网络。

ssh ubuntu@10.63.19.28 -p 30120    
                                                                                              
主机'[10.63.19.28]:30120([10.63.19.28]:30120)'的真实性无法建立。
ECDSA密钥指纹为SHA256:p9cz7RBCymP8A5RS0Yq5xOS+zGUY9Qf3eOW9Yerzo3g。
你确定要继续连接吗(是/否/[指纹])? 是
警告。永久添加'[10.63.19.28]:30120'(ECDSA)到已知主机列表中。
ubuntu@10.63.19.28 的密码。 
欢迎来到Ubuntu 18.04.5 LTS (GNU/Linux 4.15.0-154-generic x86_64)
.
.
.
ubuntu@bionic-image-vm:~$
ubuntu@bionic-image-vm:~$ ls -lh *.
-rw-rw-r-- 1 ubuntu ubuntu 500M Sep 4 14:58 demofile.img

demo-dir:
共计301M
-rw-rw-r- 1 ubuntu ubuntu 300M Sep 4 14:58 another-demofile.img
ubuntu@bionic-image-vm:~$ 



ubuntu@bionic-image-vm:~$ ifconfig
enp1s0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1440
        inet 172.20.152.142 netmask 255.255.255.255 broadcast 0.0.0.0
        inet6 fe80::bc63:cdff:fe42:81c3 prefixlen 64 scopeid 0x20<link>。
        ether be:63:cd:42:81:c3 txqueuelen 1000 (以太网)
        RX 数据包 11139 字节 22950392 (22.9 MB)
        RX错误 0 掉线 0 超限 0 帧 0
        TX数据包 1524字节 112378 (112.3 KB)
        TX错误 0 掉线 0 超限 0 帧 0 碰撞 0

lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
        inet 127.0.0.1 netmask 255.0.0.0
        inet6 ::1 prefixlen 128 scopeid 0x10[host]。
        loop txqueuelen 1000 (Local Loopback)
        RX 数据包 202 字节 15746 (15.7 KB)
        RX 错误 0 掉线 0 超限 0 帧 0
        TX数据包 202字节 15746 (15.7 KB)
        TX错误 0 掉线 0 超限 0 帧 0 碰撞 0




ubuntu@bionic-image-vm:~$ ping www.nutanix.com
PING e9966.g.akamaiedge.net (23.196.2.132) 56(84)字节的数据。
64字节来自a23-196-2-132.deploy.static.akamaitechnologies.com(23.196.2.132):icmp_seq=1 ttl=57 time=60.2 ms
64 bytes from a23-196-2-132.deploy.static.akamaitechnologies.com (23.196.2.132): icmp_seq=2 ttl=57 time=58.1 ms
64 bytes from a23-196-2-132.deploy.static.akamaitechnologies.com (23.196.2.132): icmp_seq=3 ttl=57 时间=58.2 ms
64 bytes from a23-196-2-132.deploy.static.akamaitechnologies.com (23.196.2.132): icmp_seq=4 ttl=57 时间=58.2 ms

^C--- e9966.g.akamaiedge.net ping统计 ---

此外,我们还可以验证该虚拟机是否可以从集群中的另一个Pod中访问。

kubectl get pods -o wide    
名称 准备状态 重新启动 年龄 ip 节点 提名 节点 准备状态 盖茨
centos 1/1 Running 0 125s 172.20.72.199 karbon-nk-krbn-kubevirt-107bb6-k8s-worker-1 <无> <无> <无




kubectl exec -it centos -- /bin/ping 172.20.152.142              
PING 172.20.152.142 (172.20.152.142) 56(84) 字节的数据。
来自172.20.152.142的64字节:icmp_seq=1 ttl=62 time=3.38 ms
来自172.20.152.142的64个字节: icmp_seq=2 ttl=62 time=1.11 ms
来自172.20.152.142的64个字节:icmp_seq=3 ttl=62 时间=1.05 ms

如果你想执行更高级的功能来与虚拟机互动,建议安装 virtctl工具。

总结

向容器和微服务架构发展是不可避免的。随着混合和多云环境被更广泛地采用,IT领导者必须确保现代应用程序所需的弹性、可扩展性和灵活性。有了KubeVirt,用户就有了实现应用现代化的直接途径。 它为企业提供了急需的时间,将现有的应用程序重新设计成云原生部署。通过利用Karbon进行Kubernetes管理,Nutanix用户可以自信地开始他们的旅程,而且可以少学一个管理工具。随着红帽OpenShift和Nutanix AHV的互操作性的发展,我们可能会看到这一领域的更多进展。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值