---
# System prepended metadata

title: Laboratorium 3 SLCD

---

# Laboratorium 3 SLCD 

### Orkiestracja w platformie OpenStack

## Autorzy: 
* Wawrzyńczak Michał
* Gryka Paweł
-----------------------


## Spis treści

  * [Wstęp](#Wstęp)
  * [4. Część 1: OpenStack Dashboard](#4-Część-1:-OpenStack-Dashboard)
    + [4.2 Tworzenie sieci użytkownika](#42-Tworzenie-sieci-użytkownika)
    + [4.3 Udrożnienie komunikacji przez sieć zewnętrzną](#43-Udrożenienie-komunikacji-przez-sieć-zewnętrzną)
    + [4.4 Utworzenie obrazu maszyny wirtualnej](#44-Utworzenie-obrazu-maszyny-wirtualnej)
    + [4.5 Uruchomienie maszyny wirtualnej](#45-Uruchomienie-maszyny-wirtualnej)
  * [5. Część 2: OpenStack Heat](#5-Część-2:-OpenStack-Heat)
    + [5.7 Utworzenie stosu](#57-Utworzenie-stosu)
    + [5.8 Deklaratywna modyfikacja stosu](#58-Deklaratywna-modyfikacja-stosu)
    + [5.9 Zadania dodatkowe/nieobowiązkowe](#59-Zadania-dodatkowe-nieobowiązkowe)
  * [6 Podsumowanie laboratorium](#6-Podsumowanie-laboratorium)
  * [Zmodyfikowany template na potrzeby zadań dodatkowych](#Zmodyfikowany-template-na-potrzeby-zadan-dodatkowych)



## Wstęp


Celem ćwiczenia jest opanowanie podstawowych zasad wykorzystania orkiestratora Heat platformy OpenStack. W wyniku realizacji zadania zapoznamy się z zasadami deklaratywnego podejścia do automatyzacji procesów zarządzania usługami teleinformatycznymi.


## 4. Część 1: OpenStack Dashboard


### 4.2 Tworzenie sieci użytkownika

W tym kroku stworzona została sieć o nazwie `tenant-bejbiszarki` z adresami `192.168.11.0/28`. Adres gatewaya został ustalony `192.168.11.1`.

![](https://i.imgur.com/9TBn5oz.png)




### 4.3 Udrożenienie komunikacji przez sieć zewnętrzną 

Utworzony został router `router-bejbiszarki` external network zdefiniowana jako istniejąca sieć external. Dodano również interfejs z wcześniej utworzoną podsiecią prywatną. W wyniku tych działań udało się uzyskać wymaganą topologię sieci. Sieć `external` połączyła się z siecią `tenant-bejbisharki` Poniżej znajdują się screeny z wyświetlonym opisem routera.


# POLECENIA DO SPRAWOZDANIA

1. Przedstawić zrzut całego panelu Topology z topologią uzyskanej sieci i wyświetlonym opisem routera w formie jak na poniższym rysunku (fragment panelu Topology).

![](https://i.imgur.com/vFs2Zhb.png)



### 4.4 Utworzenie obrazu maszyny wirtualnej

Obraz maszyny został pobrany na komputer jednego ze studentów. Następnie załadowaliśmy go na serwer OpenStack. W OpenStack został stworzony nowy image z unikatową nazwą `cirros-bejbiszarki-image`. Poniżej screen przedstawiający poprawne dodanie image'u na serwer OpenStack


![](https://i.imgur.com/ZqxWqFk.png)
![](https://i.imgur.com/g5xHlEu.png)




### 4.5 Uruchomienie maszyny wirtualnej 

Stworzyliśmy instancję z systemem `cirros`. Instancji nadana została nazwa `instance_bejbiszarki_1`. Instancja została prawidłowo stworzona co widać na poniższym zrzucie ekranu.

![](https://i.imgur.com/dnOxsOt.png)
![](https://i.imgur.com/RmwCbn1.png)



Kolejnym etapem było dodanie `FloatingIp`. Pozwala to na zmapowanie adresu z sieci external do adresu konkretnej instancji. Na poniższym screenie widać, że floating ip address został skojarzony z adresem stworzonej wcześniej instancji maszyny `cirros`.


![](https://i.imgur.com/obVROiy.png)


Po wyłączeniu opcji `Port security` w `Security Groups` instancja była dostępna z sieci spoza DC.

# POLECENIA DO SPRAWOZDANIA - OBOWIĄZKOWE

1. Przedstawić zrzut całego panelu Topology z topologią uzyskanej sieci i wyświetlonym opisem utworzonej maszyny wirtualnej w formie jak na poniższym rysunku (fragment panelu Topology).

![](https://i.imgur.com/NY4hvkI.png)

2. Przedstawić zrzut okna polecenia ilustrującego osiągalność utworzonej instancji spoza DC (z komputera studenckiego dołączonego do sieci laboratoryjnej ZSUT).

![](https://i.imgur.com/0pgl1Do.png)




## 5. Część 2: OpenStack Heat


### 5.7 Utworzenie stosu

Stworzony został stos wykorzystując szablon z pliku `slcd-lab3-stack-heat-initialTopo.yml`. Poniżej przedstawiona jest uzyskana topologia. Aby dołączyć się z wykorzystaniem `ssh` do utworzonej maszyny `server-2` należało wyłączyć `Port security`.

![](https://i.imgur.com/Sw9LKxm.png)

![](https://i.imgur.com/Yq9CrXo.png)



### 5.8 Deklaratywna modyfikacja stosu 

W istniejącym stosie wprowadziliśmy zmiany poprzez zmianę pliku opisującego stos na plik `slcd-lab3-stack-heat-targetTopo.yml`. Po przetworzeniu zmian widać, że infrastruktura została przekonfigurowana i jej stan jest zgodny z definicją zawartą w pliku.

![](https://i.imgur.com/cedIj1b.png)



# POLECENIA DO SPRAWOZDANIA

1. Po uruchomieniu przykładów zmodyfikować wg własnego wzorca nazwę maszyny wirtualnej oraz nazwy podsieci (2 i 3) tworzonych z szablonu, usunąć stos i wykreować go ponownie.

Dokonaliśmy edycji pliku `slcd-lab3-stack-heat-targetTopo.yml`, które dotyczyły głównie zmiany nazw poszczególnych komponentów. Zmiany jakie zaszły to:
* zamiana nazwy obrazu na `cirros-bejbiszarki-image`
* zmiana nazwy subnet-ów na odpowiednio `network-subnet_bejbiszarki_2` i `network-subnet_bejbiszarki_3`
* zmiana nazwy routera na `router_bejbiszarki_2`
* zmiana nazwy maszyny wirtualnej na `instance_bejbiszarki_2`

Zmiany w nazwach widać w kolejnym punkcie na zrzutach ekranu. 



2. Przedstawić zrzut całego panelu Topology z topologią uzyskanej sieci i wyświetlonym opisem utworzonej maszyny wirtualnej (analogicznie, jak w p. 4.5, polecenie 1).


Na poniższych zrzutach ekranu widać zmiany nazwy maszyny wirtualnych, routera oraz samych podsieci.



![](https://i.imgur.com/gfVycJM.png)

![](https://i.imgur.com/CkNUIxM.png)

![](https://i.imgur.com/s5wblyT.png)



3. Przedstawić zrzut okna polecenia ilustrującego osiągalność instancji spoza DC instancji utworzonej z szablonu.


Na poniższym zrzucie ekranu widać, że po wcześniejszym wyłączeniu `Port security` jesteśmy w stanie uzyskać powłokę systemu linux spoza DC.

![](https://i.imgur.com/U66gDkw.png)


4. Czy deklaratywna modyfikacja stosu działa „wstecz” – czy aplikując szablon initialTopodo DO stosu zgodnego z targetTopo można z powrotem przejść do topologii initialTopo?

Tak, możliwe jest powrócenie do wcześniejszego stanu. Mówimy tutaj o dwóch szablonach dostarczonych przez prowadzącego gdzie zgodne są nazwy w obu szablonach. Open stack usuwa komponenty, które nie znajdują się w obecnie wgrywanym szablonie.
Poniżej widać jeden z eventów w stworzonym przez nas stosie - widzimy event, w którym 2 resource-y są usuwane: `router2-patch-sub3` oraz `subnet3`. 

![](https://i.imgur.com/AzTJcru.png)




# 5.9 Zadania dodatkowe/nieobowiązkowe 
1. Zmodyfikować szablon initialTopo dodając odpowiednią grupę zabezpieczeń (security group) w ten sposób, aby instancja instance2 po wdrożeniu zmodyfikowanego stosu od razu była osiągalna spoza DC (osiągalna ssh lub ping).


Dodana zostałą security grupa. Zawiera ona dwie reguły. Pierwszy z nich odpowiedzialny jest za możliwość dostępu przez `ssh`. Dozwolona adresy to cała pula adresów IP. Drugi z nich to zezwolenie przychodzenie pakietów `icmp`. Obie reguły mają `direction` defaultowo ustawiony na `ingress`.

```yaml=
# security group
  security-group:
    type: OS::Neutron::SecurityGroup
    properties:
      name: { get_param: security-group-name }
      rules:
        - protocol: tcp
          remote_ip_prefix: 0.0.0.0/0
          port_range_min: 22
          port_range_max: 22
        - protocol: icmp
          remote_ip_prefix: 0.0.0.0/0

# define instance to create
  instance2:
    type: OS::Nova::Server
    properties:
      name: server-2
      image: { get_param: image-id }
      flavor: { get_param: instance-flavor }
      networks:
      - network:
          get_resource: network2
      security_groups:
        - get_param: default-security-group
        - get_resource: security-group
      user_data:
        str_replace:
          template: |
            #!/bin/bash
            echo "Hello, I am in subnetwork netName."
          params:
            netName: { get_attr: [subnet2, name] }
```

Po sprawdzeniu security group na hoście widzimy, że została dodana nowa grupa.

![](https://i.imgur.com/CVYO2mY.png)

Możliwe jest pingowanie maszyny oraz możliwy jest dostęp do maszyny poprzez `ssh`.

![](https://i.imgur.com/uU0PaFA.png)



2. Zmodyfikować szablon targetTopo w ten sposób, aby podczas wdrożenia szablonu instancja instance3 otrzymywała pływający adres IP; o odpowiednią grupę zabezpieczeń dla tej instancji zadbać szablonem lub ręcznie. Sprawdzić i potwierdzić zrzutem z ekranu osiągalność tej maszyny spoza DC oraz wzajemną osiągalność maszyn instance1, instance2 i instance3 (można na nie wejść po ssh lub użyć graficznej konsoli dashboru Heat).

W oby instanjach została użyta secure group taka, jak w poprzendim punkcie. Dodane zostały dwa dodatkowe recources, a mianowicie `FloatingIP` oraz `FloatingIPAssociation`. Pozwoliło to na uzyskanie floating ip w maszynie o nazwie `instance_bejbiszarki_3`. 

<!-- hosty 2 i 3 w tej samej sieci prywatnej -->


```yaml=
  instance3:
    type: OS::Nova::Server
    properties:
      name: instance_6osub_3
      image: { get_param: image-id }
      flavor: { get_param: instance-flavor }
      networks:
      - network:
          get_resource: network2
      security_groups:
        - get_param: default-security-group
        - get_resource: security-group

# allocate floating IP to tenant project
  floatingIP-3:
    type: OS::Neutron::FloatingIP
    properties:
      floating_network_id: { get_param: external-network-name }

# attach allocated floating IP to the instance
  association-floating-IP-3:
    type: OS::Nova::FloatingIPAssociation
    depends_on: [ instance3, floatingIP-3 ]
    properties:
      floating_ip: { get_resource: floatingIP-3 }
      server_id: { get_resource: instance3 }
```
 
Poniżej znajujduje się podgląd na topologię sieci po wprowadzeniu wcześniej wspomnianych ulepszeń do konfiguracji stack-a.
 
![](https://i.imgur.com/d1abOKJ.png)


Na poniższych dwóch zrzutach ekranu widzimy, że jesteśmy w stanie pingować wszystkie maszyny `instance_bejbiszarki_*`. Możliwe jest również połączenie się do każdej z nich poprzez `ssh` oraz z każdej maszyny do kolejnej.
 
**Ping:**
![](https://i.imgur.com/WOJehyV.png)

**ssh:**
![](https://i.imgur.com/kdLOM0o.png)


3. W przypadku z punktu 2 sprawdzić, czy instancje mogą otrzymywać adres stały (wewnętrzny) z dowolnej z podsieci Network2-subnet2/Network2-subnet3. Jeśli nie, rozważyć teoretycznie (nie trzeba implementować), czy możliwa byłaby taka konstrukcja szablonu, aby każda z instancji uzyskiwała adres stały (prywatny) z wybranej podsieci. Wnioski przedstawić hasłowo (sama idea) w formie pisemnej.


Nie, instancje mogą otrzymywać  tylko i wyłaćznie adresy z podsieci `Network2-subnet3`. 

Możliwe jest, aby instancje otrzymały stały adres prywatny z wybranej podsieci. Aby to uczynić potrzebne jest zdefiniowanie resource typu `OS::Neutron::Port`, który w swoich properties będzie przetrzymywać `network_id` (czyli resource network2) oraz `fixed_ips` (statyczny adres z podsieci numer 2, maska nie jest potrzebna)
Dodatkowo, w takim typie resource zdefiniowany może zostać security_groups. Poniżej przykład zmiany dla instancji numer 2.

```yaml=
# security group
  security-group:
    type: OS::Neutron::SecurityGroup
    properties:
      name: { get_param: security-group-name }
      rules:
        - protocol: tcp
          remote_ip_prefix: 0.0.0.0/0
          port_range_min: 22
          port_range_max: 22
        - protocol: icmp
          remote_ip_prefix: 0.0.0.0/0
          
# define instance port      
  instance2_port:
    type: OS::Neutron::Port
    properties:
      network_id: { get_resource: network2 }
      fixed_ips:
        - ip_address: "192.168.11.3"
      security_groups:
        - get_param: default-security-group
        - get_resource: security-group

# define instance to create
  instance2:
    type: OS::Nova::Server
    properties:
      name: instance_6osub_2
      image: { get_param: image-id }
      flavor: { get_param: instance-flavor }
      networks:
        - port: { get_resource: instance2_port }  
```

Co więcej, możliwe jest dynamiczne ustawianie adresów IPv4. Aby to uczynić w resource typu `OS::Neutron::Port` zamiast statycznego adresu w `fixed_ips` nalezu podać `subnet_id` (resource subnet3). Poniżej przykład zmiany dla instancji numer 3.


```yaml=
# define instance port      
  instance3_port:
    type: OS::Neutron::Port
    properties:
      network_id: { get_resource: network2 }
      fixed_ips:
        - subnet_id: { get_resource: subnet3 }  
      security_groups:
        - get_param: default-security-group
        - get_resource: security-group

# define instance to create   
  instance3:
    type: OS::Nova::Server
    properties:
      name: instance_6osub_3
      image: { get_param: image-id }
      flavor: { get_param: instance-flavor }
      networks:
        - port: { get_resource: instance3_port } 
```


Widzimy, że template został poprawnie wprowadzony. Instancja `instance_bejbiszarki_2` otrzymuje stały adres z puli adresów `subnet2` jako `192.168.11.3`, a `instance_bejbiszarki_3` otrzymała dynamicznie adres z puli adresów `subnet3`.

![](https://i.imgur.com/0peUVYi.png)

![](https://i.imgur.com/fdahuNv.png)



## 6 Podsumowanie laboratorium 

Dzięki temu laboratorium zapoznaliśmy się z platformą OpenStack, nauczyliśmy się tworzyć podstawowe zasoby, oraz tworzyć stack'i z wykorzystaniem template'ów. Przybliżyło nam to mechanizmy tworzenia własnego chmurowego centrum danych oraz sposób zarządzania platformą typu `Infrastructure-as-a-Service (IaaS)`.


<!-- https://github.com/personium/openstack-heat/blob/master/02_personium_security_group.yaml -->


## Zmodyfikowany template na potrzeby zadań dodatkowych

```yaml=
heat_template_version: 2018-08-31
description: Simple template to deploy a tenant network with single instance - SLCD lab3.

parameters:

  external-network-name:
    type: string
    description: Network to allocate floating IP from
    default: external

  dns-nameserver:
    type: string
    description: DNS Server for external access
    default: 8.8.8.8

  default-security-group:
    type: string
    description: Security group to be used
    default: default
    
  security-group-name:
    type: string
    description: Name of security group
    default: Security group created for slcd lab3

  image-id:
    type: string
    label: Image ID
    description: Image to be used for compute instance
    default: cirros-bejbiszarki-image

  instance-flavor:
    type: string
    label: Instance Type
    description: Flavor to be used for the instance
    constraints:
      - allowed_values: [ m1.tiny, m1.small, m1.medium, m1.large, m1.xlarge ]
        description: Value must be one of m1.tiny, m1.large, m1.medium, m1.small, m1.xlarge.
    default: m1.tiny

resources:

# tenant network
  network2:
    type: OS::Neutron::Net
    properties:
      admin_state_up: true
      name: network_bejbiszarki
      shared: false

# tenant subnetwork (address pool)
  subnet2:
    type: OS::Neutron::Subnet
    properties:
      cidr: 192.168.11.0/28
      allocation_pools: [ {"start": "192.168.11.2", "end": "192.168.11.14" } ] 
      dns_nameservers: [ {get_param: dns-nameserver} ]
      enable_dhcp: true
      ip_version: 4
      name:
        str_replace:
          template: __net__-subnet_bejbiszarki_2
          params:
            __net__: { get_attr: [network2, name] }
      network_id:
        get_resource: network2
        
# EXPERIMENTAL tenant subnetwork 3 (address pool)
  subnet3:
    type: OS::Neutron::Subnet
    properties:
      cidr: 192.168.11.16/28
      allocation_pools: [ {"start": "192.168.11.18", "end": "192.168.11.30" } ] 
      dns_nameservers: [ {get_param: dns-nameserver} ]
      enable_dhcp: true
      ip_version: 4
      name:
        str_replace:
          template: __net__-subnet_bejbiszarki_3
          params:
            __net__: { get_attr: [network2, name] }
      network_id:
        get_resource: network2
        
# tenant router attached to external network for external access of tenant instances
  router2:
    type: OS::Neutron::Router
    properties:
      admin_state_up: true
      name: router_bejbiszarki_2
      external_gateway_info: { 
        network: {get_param: external-network-name},
        enable_snat: true
#         this property is enabled for aministrative users only
      }

# connect tenant subnetwork 2 to tenant router for external access
  interface-router2-sub2:
    type: OS::Neutron::RouterInterface
    depends_on: [ router2, subnet2 ]
    properties:
      router: { get_resource: router2 } 
      subnet: { get_resource: subnet2 }
      
# EXPERIMENTAL connect tenant subnetwork 3 to tenant router for external access
  interface-router2-sub3:
    type: OS::Neutron::RouterInterface
    depends_on: [ router2, subnet3 ]
    properties:
      router: { get_resource: router2 } 
      subnet: { get_resource: subnet3 }

# security group
  security-group:
    type: OS::Neutron::SecurityGroup
    properties:
      name: { get_param: security-group-name }
      rules:
        - protocol: tcp
          remote_ip_prefix: 0.0.0.0/0
          port_range_min: 22
          port_range_max: 22
        - protocol: icmp
          remote_ip_prefix: 0.0.0.0/0
          
# define instance port      
  instance2_port:
    type: OS::Neutron::Port
    properties:
      network_id: { get_resource: network2 }
      fixed_ips:
        - ip_address: "192.168.11.3"
      security_groups:
        - get_param: default-security-group
        - get_resource: security-group

# define instance to create
  instance2:
    type: OS::Nova::Server
    properties:
      name: instance_bejbiszarki_2
      image: { get_param: image-id }
      flavor: { get_param: instance-flavor }
      networks:
        - port: { get_resource: instance2_port } 


# allocate floating IP to tenant project
  floatingIP-2:
    type: OS::Neutron::FloatingIP
    properties:
      floating_network_id: { get_param: external-network-name }

# attach allocated floating IP to the instance
  association-floating-IP-2:
    type: OS::Nova::FloatingIPAssociation
    depends_on: [ instance2, floatingIP-2 ]
    properties:
      floating_ip: { get_resource: floatingIP-2 }
      server_id: { get_resource: instance2 }
      # using device_id attribute of port instead of server id would work better with stack updates
  
# define instance port      
  instance3_port:
    type: OS::Neutron::Port
    properties:
      network_id: { get_resource: network2 }
      fixed_ips:
        - subnet_id: { get_resource: subnet3 }  
      security_groups:
        - get_param: default-security-group
        - get_resource: security-group

# define instance to create   
  instance3:
    type: OS::Nova::Server
    properties:
      name: instance_bejbiszarki_3
      image: { get_param: image-id }
      flavor: { get_param: instance-flavor }
      networks:
        - port: { get_resource: instance3_port } 

# allocate floating IP to tenant project
  floatingIP-3:
    type: OS::Neutron::FloatingIP
    properties:
      floating_network_id: { get_param: external-network-name }

# attach allocated floating IP to the instance
  association-floating-IP-3:
    type: OS::Nova::FloatingIPAssociation
    depends_on: [ instance3, floatingIP-3 ]
    properties:
      floating_ip: { get_resource: floatingIP-3 }
      server_id: { get_resource: instance3 }
```
