No menu items!
No menu items!
More

    [KVM] Bridge Network trong KVM

    Tổng quan

    KVM được biết đến là một cơ sở hạ tầng ảo hóa cho nhân Linux. KVM cũng cung cấp các mô hình mạng trong việc ảo hóa network. Các mô hình bao gồm:

    • NAT
    • Host-only
    • Linux-bridge

    Trong đó Linux-bridge là một mô hình ảo hóa mạng được hỗ trợ bởi KVM. Linux bridge là một công nghệ cung cấp switch ảo để giải quyết vấn đề ảo hóa Network bên trong các máy vật lý. Ở bài viết này mình sẽ giới thiệu về mô hình Bridge trên KVM.

    Chúng ta có thể thấy rằng có một con switch được tạo ra nằm bên trong của máy vật lý. Các VM kết nối đến đây để có thể liên lạc được với nhau. Nếu muốn liên lạc ra bên ngoài ta có thể kết nối con switch này với card mạng trên máy vật lý của ta (giống như ta dùng dây kết nối switch với router). Ta có thể kết nối switch với 1 hoặc nhiều port.

    Cấu trúc linux bridge

    Trong đó:

    • Bridge ở đây là switch ảo
    • Tap hay tap interface là giao diện mạng để các VM kết nối với switch do Linux bridge tạo ra(nó hoạt động ở lớp 2 của mô hình OSI)
    • fd: Forward data có nhiệm vụ chuyển dữ kiệu từ VM tới switch.

    Switch ảo do Linux bridge tạo ra có chức năng tương tự với 1 con switch vật lý.

    Ta có thể thấy rõ hơn cách kết nối của VM ra ngoài internet. Khi máy vật lý của ta có card mạng kết nối với internet (không phải card wireless). Trên switch ảo của ta sẽ phải có đường để kết nối ra ngoài internet (cụ thể là kết nối với card mạng của máy vật lý). Ta có thể hình dung card mạng trên máy vật lý sẽ được gắn trực tiếp vào switch ảo nên ta có thể thấy sau khi add switch ảo và card vật lý có cùng địa chỉ MAC. Và trên card vật lý sẽ không còn địa chỉ IP mà nó được gắn cho switch ảo.

    $ ifconfig enp6s0
    enp6s0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
            ether 00:30:48:db:6c:5e  txqueuelen 1000  (Ethernet)
            RX packets 37075255  bytes 30351706205 (30.3 GB)
            RX errors 0  dropped 0  overruns 0  frame 0
            TX packets 18350891  bytes 13225504313 (13.2 GB)
            TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
            device interrupt 16  memory 0xfbce0000-fbd00000
    
    $ ifconfig br0
    br0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
            inet 192.168.13.228  netmask 255.255.254.0  broadcast 192.168.13.255
            inet6 fe80::230:48ff:fedb:6c5e  prefixlen 64  scopeid 0x20<link>
            ether 00:30:48:db:6c:5e  txqueuelen 1000  (Ethernet)
            RX packets 26611549  bytes 26856341341 (26.8 GB)
            RX errors 0  dropped 2  overruns 0  frame 0
            TX packets 13609391  bytes 12831819181 (12.8 GB)
            TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
    
    $ brctl show
    bridge name	bridge id		STP enabled	interfaces
    br0		8000.003048db6c5e	yes		enp6s0

    Và bây giờ trên các VM muốn giao tiếp với nhau hoặc ra ngoài internet ta chỉ cần kết nối VM đó với switch ảo. Lúc này card mạng trên VM sẽ được gắn với 1 cổng của switch ảo thông qua tap interface và cổng này có tên là br. Ở đây có tên là br0

    Khi ta kết nối vào switch ảo các VM sẽ nhận địa chỉ IP cùng với dải địa chỉ IP của card mà ta add và switch và các địa chỉ IP này sẽ được cấp bởi dịch vụ DHCP trên router.

    Địa chỉ của card mạng gắn với switch ảo, với mô hình này gói tin bên trong VM đi ra ngoài mạng sẽ đi từ VM đến thẳng card vật lý gắn với switch ảo và đi ra ngoài mạng.

    Chuẩn bị

    Một máy chạy hệ điều hành CentOS 7 hoặc Ubuntu cài đặt KVM có một card mạng kết nối với internet và cài đặt một VM bên trong máy đó. Chú ý máy vật lý ở đây là máy cài KVM. Máy này có thể là một máy ảo nhưng ở đây ta coi nó như một server vật lý.

    Tạo mô hình Bridge trên KVM

    Để list tất cả các network đang có trong server, sử dụng lệnh virsh net-list –all. Bạn sẽ thấy có 1 network default mặc định khi cài KVM sẽ tự tạo ra.

    $ virsh net-list --all
     Name                 State    Autostart   Persistent
    -------------------------------------------------------
     default              inactive no          yes

    Bây giờ bạn hãy xem thông tin card mạng enp6s0, đây chính là card mạng vật lý đang nối với thiết bị network ở ngoài và nó đang được gán ip là 192.168.13.228.

    $ ifconfig enp6s0
    enp6s0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
            inet 192.168.13.228  netmask 255.255.254.0  broadcast 192.168.13.255
            ether 00:30:48:db:6c:5e  txqueuelen 1000  (Ethernet)
            RX packets 37098477  bytes 30355784188 (30.3 GB)
            RX errors 0  dropped 0  overruns 0  frame 0
            TX packets 18362175  bytes 13228221261 (13.2 GB)
            TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
            device interrupt 16  memory 0xfbce0000-fbd00000

    Bước tiếp theo bạn hãy tạo 1 card mạng bridge có tên là br0 (card này bạn có thể tự đặt tên mà bạn muốn). Card br0 sẽ được đặt ip, gateway, … giống như card vật lý và nó cũng sẽ được gắn với card vật lý enp6s0.

    cat > /etc/netplan/00-installer-config.yaml << 'OEF'
    network:
      version: 2
      renderer: networkd
    
      ethernets:
        enp6s0:
          dhcp4: false
          dhcp6: false
    
      bridges:
        br0:
          interfaces: [ enp6s0 ]
          addresses: [ 192.168.13.228/23 ]
          gateway4: 192.168.12.5
          mtu: 1500
          nameservers:
            addresses: [ 8.8.8.8, 1.1.1.1 ]
          parameters:
            stp: true
            forward-delay: 4
          dhcp4: no
          dhcp6: no
    OEF

    Sau khi chuẩn bị xong file cấu hình, bạn hãy chạy lệnh dưới để áp dụng thay đổi. Máy chủ của bạn sẽ rớt mạng 1 lát để cập nhật cấu hình. Sau khoảng 5-10s nếu mọi cấu hình của bạn đúng, máy chủ của bạn sẽ có kết nối trở lại.

    sudo netplan generate 
    sudo netplan --debug apply

    Và đây là kết quả sau khi áp dụng config network mới. Card mạng bridge br0 đã được tạo và được gắn ip 192.168.13.228 như đã khai báo còn card mạng vật lý bây giờ đã không còn được gắn ip.

    $ ifconfig enp6s0
    enp6s0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
            ether 00:30:48:db:6c:5e  txqueuelen 1000  (Ethernet)
            RX packets 37098477  bytes 30355784188 (30.3 GB)
            RX errors 0  dropped 0  overruns 0  frame 0
            TX packets 18362175  bytes 13228221261 (13.2 GB)
            TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
            device interrupt 16  memory 0xfbce0000-fbd00000
    
    $ ifconfig br0
    br0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
            inet 192.168.13.228  netmask 255.255.254.0  broadcast 192.168.13.255
            inet6 fe80::230:48ff:fedb:6c5e  prefixlen 64  scopeid 0x20<link>
            ether 00:30:48:db:6c:5e  txqueuelen 1000  (Ethernet)
            RX packets 26633879  bytes 26859945910 (26.8 GB)
            RX errors 0  dropped 2  overruns 0  frame 0
            TX packets 13619670  bytes 12834414371 (12.8 GB)
            TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

    Tiếp theo để thêm network mới, bạn sử dụng file xml với nội dung như dưới, để ý một số trường như sau:

    • mode=bridge: sử dụng mode bridge.
    • bridge name=’br0′: dùng card mạng bridge bạn đã tạo ở bước trên gắn vào đây.
    • bridged-network chính là tên của network bạn sẽ tạo.
    cat > ./bridged-network.xml << 'OEF'
    <network>
        <name>bridged-network</name>
        <forward mode="bridge" />
        <bridge name="br0" />
    </network>
    OEF

    Sử dụng lệnh virsh net-define <file_network_xml> để define network này.

    $ virsh net-define ./bridged-network.xml
    Network bridged-network defined from ./bridged-network.xml

    Dùng lệnh virsh net-list –all để list network, bạn đã thấy network có tên bridged-network đã xuất hiện nhưng nó đang ở trạng thái inactive. Ở trạng thái này network chưa thể sử dụng được.

    $ virsh net-list --all
     Name                 State    Autostart   Persistent
    -------------------------------------------------------
     bridged-network      inactive no          yes

    Để enable network này, sử dụng lệnh virsh net-start <file_network_xml> để start nó.

    $ virsh net-start bridged-network
    Network bridged-network started

    Sau khi start network xong, bạn thấy network đã chuyển qua trạng thái active, tức là lúc này network đã có thể sử dụng được nhưng mà tuỳ chọn Autostart đang ở trạng thái no, bạn hãy chuyển tuỳ chọn Autostart sang yes để khi máy chủ KVM khởi động lại, network sẽ tự start luôn.

    $ virsh net-list --all
     Name                 State    Autostart   Persistent
    -------------------------------------------------------
     bridged-network      active   no          yes

    Sử dụng lệnh virsh net-autostart <file_network_xml> để enable tính năng này.

    $ virsh net-autostart bridged-network
    Network bridged-network marked as autostarted

    Và đây là kết quả khi mình đã config xong một network.

    $ virsh net-list --all
     Name                 State    Autostart   Persistent
    -------------------------------------------------------
     bridged-network      active   yes         yes

    Để xem thông tin tóm tắt một network bạn có thể sử dụng lệnh virsh net-info <file_network_xml>.

    $ virsh net-info bridged-network
    Name:           bridged-network
    UUID:           de6d9dd4-1700-493c-a2c2-5c2838e425d2
    Active:         yes
    Persistent:     yes
    Autostart:      yes
    Bridge:         br0

    Kiểm tra.

    Mình sẽ tạo 1 máy ảo có tên test-bridged-network để kiểm tra network này như sau. Đầu tiên tạo file sshkey cho username ubuntu.

    sudo mkdir -p /kvm-volumes-hdd/test-bridged-network/ssh-keygen
    sudo chmod +x /kvm-volumes-hdd/test-bridged-network
    sudo chmod 600 /kvm-volumes-hdd/test-bridged-network/ssh-keygen
    cd /kvm-volumes-hdd/test-bridged-network/ssh-keygen
    ssh-keygen -t rsa -b 4096 -f id_rsa -C hoanghd -N "" -q

    Tạo 1 ổ đĩa chứ hệ điều hành, mình tạo 1 ổ đĩa có dung lượng 10G.

    qemu-img create -b /kvm-volumes-hdd/images/bionic-server-ubuntu1804-cloudimg-amd64.img -f qcow2 /kvm-volumes-hdd/test-bridged-network/os-test-bridged-network.qcow2 10G

    Xem lại thông tin ổ đĩa vừa tạo.

    $ qemu-img info /kvm-volumes-hdd/test-bridged-network/os-test-bridged-network.qcow2
    image: /kvm-volumes-hdd/test-bridged-network/os-test-bridged-network.qcow2
    file format: qcow2
    virtual size: 10 GiB (10737418240 bytes)
    disk size: 196 KiB
    cluster_size: 65536
    backing file: /kvm-volumes-hdd/images/bionic-server-ubuntu1804-cloudimg-amd64.img
    Format specific information:
        compat: 1.1
        lazy refcounts: false
        refcount bits: 16
        corrupt: false

    Tiếp theo bạn tạo file cloud_init.cfg khai báo 1 số thông tin cơ bản cho máy ảo.

    cat > /kvm-volumes-hdd/test-bridged-network/cloud_init.cfg << OEF
    #cloud-config
    hostname: test-bridged-network
    fqdn: test-bridged-network.hoanghd.com
    manage_etc_hosts: true
    users:
      - name: ubuntu
        sudo: ALL=(ALL) NOPASSWD:ALL
        groups: users, admin
        home: /home/ubuntu
        shell: /bin/bash
        lock_passwd: true
        ssh-authorized-keys:
          - $(cat /kvm-volumes-hdd/test-bridged-network/ssh-keygen/id_rsa.pub)
      - name: hoanghd 
        sudo: ALL=(ALL) NOPASSWD:ALL
        groups: users, admin
        home: /home/hoanghd
        shell: /bin/bash
        lock_passwd: false
    
    package_update: true
    packages_upgrade: true
    packages:
      - qemu-guest-agent
      - traceroute
    
    # only cert auth via ssh (console access can still login)
    ssh_pwauth: false
    disable_root: false
    chpasswd:
      list: |
         hoanghd:Hoanghd164
      expire: False
    
    runcmd:
      - sudo touch /etc/cloud/cloud-init.disabled
    OEF

    Tạo file cấu hình network.

    cat > /kvm-volumes-hdd/test-bridged-network/network_config_static.cfg << 'OEF'
    version: 2
    ethernets:
      enp1s0:
         dhcp4: false
         addresses: [ 192.168.13.231/23 ]
         gateway4: 192.168.12.5
         nameservers:
           addresses: [ 1.1.1.1, 8.8.8.8 ]
    OEF

    Giờ mình tạo 1 disk mới có tên test-bridged-network-seed.qcow2 và mình mount 2 file config cloud_init.cfgnetwork_config_static.cfg vào disk này. Mục đích để lúc khởi động kvm sẽ đọc ổ đĩa này để load các file config.

    cloud-localds -v --network-config=/kvm-volumes-hdd/test-bridged-network/network_config_static.cfg /kvm-volumes-hdd/test-bridged-network/test-bridged-network-seed.qcow2 /kvm-volumes-hdd/test-bridged-network/cloud_init.cfg

    Bạn có thể xem lại thông tin disk này bằng lệnh dưới.

    $ qemu-img info /kvm-volumes-hdd/test-bridged-network/test-bridged-network-seed.qcow2
    image: /kvm-volumes-hdd/test-bridged-network/test-bridged-network-seed.qcow2
    file format: raw
    virtual size: 368 KiB (376832 bytes)
    disk size: 368 KiB

    Bây giờ hãy run máy ảo bằng lệnh dưới.

    virt-install --name test-bridged-network \
      --virt-type kvm --memory 4096 --vcpus 4 \
      --boot hd,menu=on \
      --disk path=/kvm-volumes-hdd/test-bridged-network/test-bridged-network-seed.qcow2,device=cdrom \
      --disk path=/kvm-volumes-hdd/test-bridged-network/os-test-bridged-network.qcow2,device=disk \
      --graphics vnc \
      --os-type Linux --os-variant ubuntu18.04 \
      --network network:bridged-network \
      --console pty,target_type=serial \
      --noautoconsole

    Nếu không gặp lỗi, bạn sẽ thấy đầu ra xuất hiện như dưới.

    Starting install...
    Domain creation completed.

    Giờ hãy list VM chúng ta thấy VM vừa tạo đã ở trạng thái running

    $ virsh list --all
     Id   Name                      State
    -----------------------------------------
     6    test-bridged-network      running

    Và đây là kết quả.

    $ virsh console test-bridged-network
    Connected to domain test-bridged-network
    Escape character is ^]
    
    Ubuntu 18.04.6 LTS test-bridged-network ttyS0
    
    test-bridged-network login: hoanghd
    Password:
    
    Last login: Sat Dec 10 14:10:53 UTC 2022 on ttyS0
    Welcome to Ubuntu 18.04.6 LTS (GNU/Linux 4.15.0-197-generic x86_64)
    
     * Documentation:  https://help.ubuntu.com
     * Management:     https://landscape.canonical.com
     * Support:        https://ubuntu.com/advantage
    
      System information as of Sat Dec 10 14:11:49 UTC 2022
    
      System load:  0.26              Processes:             122
      Usage of /:   12.0% of 9.51GB   Users logged in:       0
      Memory usage: 3%                IP address for enp1s0: 192.168.13.231
      Swap usage:   0%
    
    0 updates can be applied immediately.
    
    Failed to connect to https://changelogs.ubuntu.com/meta-release-lts. Check your Internet connection or proxy settings
    
    hoanghd@test-bridged-network:~$ ip a
    1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
        link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
        inet 127.0.0.1/8 scope host lo
           valid_lft forever preferred_lft forever
        inet6 ::1/128 scope host
           valid_lft forever preferred_lft forever
    2: enp1s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
        link/ether 52:54:00:35:ad:8e brd ff:ff:ff:ff:ff:ff
        inet 192.168.13.231/23 brd 192.168.13.255 scope global enp1s0
           valid_lft forever preferred_lft forever
        inet6 fe80::5054:ff:fe35:ad8e/64 scope link
           valid_lft forever preferred_lft forever
    
    hoanghd@test-bridged-network:~$ ip route
    default via 192.168.12.5 dev enp1s0 proto static
    192.168.12.0/23 dev enp1s0 proto kernel scope link src 192.168.13.231
    
    hoanghd@test-bridged-network:~$ ping 8.8.8.8
    PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
    64 bytes from 8.8.8.8: icmp_seq=1 ttl=57 time=30.5 ms
    64 bytes from 8.8.8.8: icmp_seq=2 ttl=57 time=30.4 ms
    64 bytes from 8.8.8.8: icmp_seq=3 ttl=57 time=31.1 ms
    64 bytes from 8.8.8.8: icmp_seq=4 ttl=57 time=30.9 ms
    
    --- 8.8.8.8 ping statistics ---
    4 packets transmitted, 4 received, 0% packet loss, time 3004ms
    rtt min/avg/max/mdev = 30.492/30.786/31.175/0.353 ms

    Bài viết gần đây

    spot_img

    Related Stories

    Leave A Reply

    Please enter your comment!
    Please enter your name here

    Đăng ký nhận thông tin bài viết qua email