Liệt kê danh sách máy host (compute-node)

Một phần của tài liệu SỬ DỤNG SALTSTACK TRIỂN KHAI HỆ THỐNG PRIVATE CLOUD OPENSTACK (Trang 78 - 95)

4 Kết quả và đánh giá

4.7 Liệt kê danh sách máy host (compute-node)

4.1.2 Salt

Sau quá trình viết state, thu được 9 file SLS thực hiện cài toàn bộ các dịch vụ thiết yếu của OpenStack. Các state này có thể được chạy trên các máy sử dụng hệ điều hành Ubuntu 12.04 để cài đặt một hệ thống cloud hoàn chỉnh với số compute node tùy ý. Việc sử dụng Salt giúp việc cài đặt cloud các lần sau trở nên vô cùng đơn giản với công việc chính là điền các thông số cần thiết (IP máy cài mysql, IP máy cài rabbitmq, subnet mạng sử dụng, ...) rồi chạy state. Đặc biệt khi cần thay đổi cấu hình, cụ thể như cần thay đổi địa chỉ của máy chạy dịnh vụ mysql, chỉ cần thay đổi 1 lần duy nhất ở 1 file duy nhất, Salt giúp phân tán file này đến tất cả các máy compute node và restart lại dịch vụ nova-compute để áp dùng cấu hình mới này.

Triển khai trên một node, tổng thời gian cả quá trình cài đặt bằng tổng thời gian tải và cài đặt các gói cộng với thời gian tải file ảnh cirros, các phần công việc còn lại chiếm thời gian không đáng kể. Tốc độ của quá trình chủ yếu phụ thuộc vào tốc độ đường truyền internet. Nếu thực hiện cache trước các file ảnh và các gói cần cài, quá trình chạy state sẽ chỉ gồm thời gian cài đặt các gói, trên mô hình thử nghiệm, khoảng thời gian này dao động từ 7-10 phút, thời gian thực hiện có thể rất khác tùy theo tốc độ CPU, RAM và đĩa cứng của máy host.

Salt với ngôn ngữ cấu hình đơn giản giúp việc viết state không có gì khó khăn, với khả năng chỉ định thứ tự chạy các state giúp việc cài đặt theo thứ tự nhất định được đảm bảo. Các dịch vụ của salt

(salt-master, salt-minion) chạy ổn định, sử dụng ít CPU và RAM.

4.2 Đánh giá hiệu quả

• Cần cài đặt thành công một lần trước khi viết các state để có được các file cấu hình chuẩn

• Trên một node, việc cài đặt nhanh hơn đáng kể so với cài đặt bằng tay.

• Thời gian viết state phụ thuộc chủ yếu vào sự thành thạo Salt và hiểu biết về dịch vụ cần cài của người viết. Tổng số dòng của tất cả các file SLS thực hiện cài đặt: khoảng 265 dòng, với khoảng 6800 ký tự.

• Thời gian cài trên hai node ít hơn thời gian cài đặt trên một node. Điều này có thể lý giải do Salt thực hiện hai quá trình cài đặt này cùng lúc trên hai máy khác nhau, nên thời gian cài đặt của máy nào lâu nhất thì đó cũng là thời gian của cả quá trình cài đặt. Do quá trình cài đặt có sử dụng cache các gói phần mềm nên trong khi node 1 đang tải và cài các gói mysql, rabbitmq, keystone, glance thì node 2 thực hiện tải gói nova-compute. Khi node 1 cần cài nova-compute nó sẽ không tốn thời gian để tải gói này nữa (do vừa được cache lại) dẫn đến kết quả như đã thu được.

Kết luận

Đồ án đã thực hiện tìm hiểu và cài đặt OpenStack - một hệ thống giúp triển khai mô hình IaaS cloud, một giải pháp hiện đại và hiệu quả cho các doanh nghiệp có nhu cầu sử dụng nhiều máy chủ. Mô hình thử nghiệm đã dựng lên một hệ thống IaaS cloud chạy trên 2 máy tính, có khả năng cung cấp các máy ảo một cách nhanh chóng. Các dịch vụ thành phần của cloud đều chạy ổn định và thực hiện đúng các chức năng như mong đợi.

Kết hợp với tìm hiểu và ứng dụng công cụ quản lý cấu hình Salt- Stack, việc cài đặt và quản lý hệ thống cloud trở nên nhanh chóng, hiệu quả hơn nhiều lần. Kết quả thu được là một tập hợp các file SLS cho phép cài đặt và quản trị một hệ thống OpenStack cloud nhanh chóng trên một hoặc nhiều máy tính chạy hệ điều hành Ubuntu 12.04, chứng minh cho tính khả thi của giải pháp sử dụng OpenStack và Salt để thực hiện cung cấp và quản lý một lượng lớn máy chủ cho doanh nghiệp.

hành nhân Linux, đồ án góp phần mang lại những suy nghĩ tích cực về phần mềm mã nguồn mở, đưa ra giải pháp giúp các doanh nghiệp có thể tự làm chủ các công nghệ hiện đại hiệu quả mà không tốn nhiều tiền của. Trong hoàn cảnh các doanh nghiệp công nghệ thông tin trong nước đang đầu tư với số vốn rất lớn để tìm hiểu và làm chủ công nghệ điện toán đám may, đồ án giúp mang lại trải nghiệm nhanh chóng cho người dùng chỉ với lượng công sức và chi phí bỏ ra thấp nhất. Hai công nghệ được giới thiệu trong đồ án này sẽ rất hữu ích khi môi trường doanh nghiệp đủ lớn, giúp tiết kiệm nhiều tiền của, công sức, nhưng với những doanh nghiệp nhỏ, khi lượng máy cần quản lý không nhiều thì việc sử dụng hai công nghệ này có thể mang lại lợi ích không tương xứng với công sức bỏ ra.

Do điều kiện về cơ sở vật chất không cho phép nên đồ án mới chỉ dừng lại ở việc dựng một mô hình cloud trên 2 máy vật lý, chưa thể giải quyết bài toán thực tế cung cấp lượng lớn server mà mới chỉ có thể cung cấp được khoảng 10 server nhỏ, chạy ít dịch vụ và các dịch vụ luôn ở trạng thái rảnh. Đồ án có thể được tiếp tục phát triển theo hướng giải quyết các bài toán cụ thể, thực hiện cung cấp các server cho các dự án thật kết hợp với viết các state để tự động quá trình cài đặt và quản lý cấu hình, đồng thời có thể cài đặt thêm các thành phần tùy chọn như OpenStack Storage để thực hiện lưu trữ phân tán.

Đồ án thực hiện tìm hiểu hai công nghệ lớn với hai sản phẩm còn khá mới mẻ nên việc thiếu xót là không thể tránh khỏi, em rất mong

nhận được những phản hồi và đóng góp của các thầy cô để có được một tài liệu tốt hơn cho bản thân em nói riêng và cho ngành công nghệ thông tin nước nhà nói chung.

Tài liệu tham khảo • http://aws.amazon.com/ • http://blogs.technet.com • http://docs.openstack.org • http://en.wikipedia.org/wiki/ • http://www.heroku.com/ • http://www.windowsazure.com/en-us/ • https://drive.google.com/ • http://saltstack.com/ • http://cfengine.com/ • http://www.opscode.com/chef/ • https://puppetlabs.com/

Danh sách hình vẽ

1.1 Dashboard của Windows Azure . . . 10

1.2 Giao diện dashboard của Heroku . . . 11

1.3 Giao diện soạn thảo Spreadsheet của Google Drive . . 13

1.4 Phân tầng chức năng của từng mô hình dịch vụ . . . . 14

1.5 Sơ đồ tương tác của các dịch vụ trong OpenStack . . . 18

2.1 Mô hình Master - Minion của Salt . . . 37

3.1 Sơ đồ thứ tự cài đặt các thành phần của OpenStack . . 50

4.1 Giao diện horizon sau khi cài đặt . . . 68

4.2 Giao diện horizon khi tạo một máy ảo . . . 69

4.3 Giao diện horizon sau khi tạo một máy ảo . . . 70

4.4 Giao diện horizon sau khi tạo hai máy ảo . . . 71

4.5 Giao diện horizon khi 10 máy ảo cirros được tạo . . . . 72

4.6 SSH vào máy ảo . . . 73

Phụ lục

Thiết kế state cho DNSimple

DNSimple là một dịch vụ online cho phép quản lý tên miền và các bản ghi một cách đơn giản và hiệu quả. Dựa trên API của DNSipmle cung cấp, module dưới đây sẽ thực hiện thiết kế state cho DNSimple phục vụ công việc sử dụng Salt quản lý tên miền. Module được viết bằng ngôn ngữ Python 2.7

Một state module cần thực hiện những công việc sau:

• Đọc vào file SLS của người dùng

• Lưu giữ trạng thái trước khi chạy state

• Thực hiện các thay đổi như nội dung SLS yêu cầu

• Trả về những thay đổi và kết quả của quá trình chạy state dnsimple module thực hiện:

• đọc vào các record cùng trạng thái yêu cầu

• lấy toàn bộ thông tin hiện tại về tên miền và records

• thực hiện các thay đổi như tạo tên miền, tạo record, thay đổi nội dung record

• lấy kết quả sau khi thay đổi so sánh với dữ liệu ban đầu

• trả về kết quả của quá trình chạy state

Cài đặt và sử dụng DNSimple Module viết bằng python :

1 #−∗− encoding: utf−8 −∗− 2 3 ’’’ 4 DNSimple state 5 requires: requests==1.2.0 6 ’’’ 7 8 import json 9 import logging 10 try: 11 import requests 12 except ImportError: 13 requests = None 14

15

16 log = logging.getLogger(__name__) 17

18 COMMON_HEADER = {’Accept’: ’application/json’, 19 ’Content−Type’: ’application/json’,

20 }

21 BASE_URL = ’https://dnsimple.com’ 22

23

24 def __virtual__():

25 ’’’Verify requests is installed.’’’

26 ifrequests is None: 27 returnFalse 28 return ’dnsimple’ 29

30

31 def auth_session(email, token): 32 ses = requests.Session() 33 ses.auth = (email, token)

34 ses.headers.update(COMMON_HEADER)

35 ses.headers.update({’X−DNSimple−Token’: email + ":" + token}) 36 return ses

37 38

39 def created(name, email, token): 40 domain = name

41 ret = {’name’: domain, 42 ’changes’: {},

43 ’result’: False, 44 ’comment’: ’’} 45

46 if__opts__[’test’]: 47 return{’name’: name, 48 ’changes’: {}, 49 ’result’: None,

50 ’comment’: ’Domain {0} is set to be created’.format(

51 name)}

52

53 path = "/domains"

54 ses = auth_session(email, token) 55 data = {"domain": {"name": domain}}

56 resp = ses.post(BASE_URL + path, json.dumps(data)) 57 log.info("{0} {1}".format(resp.status_code, resp.content)) 58 ifresp.status_code == 201:

59 ret[’result’] = True

60 ret[’changes’][domain] = "Created in your account" 61 elif resp.status_code == 400:

62 comment = "already in your account." 63 ifcomment in resp.content: 64 ret[’result’] = True 65 ret[’comment’] = comment 66 elif resp.status_code == 401: 67 ret[’result’] = False 68 else:

69 raise Exception("{0} {1}".format(resp.status_code, resp.content)) 70 return ret

71 72

73 def normalise(records):

74 ’’’Return a data with structure same as which returned from API’’’

75 ret = {}

76 for domain inrecords: 77 li = []

78 forrectype in records[domain]: 79 data = {}

80 data[’record_type’] = rectype 81 recs = records[domain][rectype] 82 for recname inrecs:

83 data[’name’] = recname 84 data.update(recs[recname]) 85 li.append(data) 86 ret[domain] = li 87 return ret 88 89

90 def records_existed(name, email, token, records): 91 ’’’

92 Use returning ASAP when have any error happen. So if nothing change,

93 result is true 94 95 sls example 96 97 records_exists: 98 email:

99 token: 100 records: 101 blahblah.com: 102 A: 103 www: 104 content: 123.11.1.11 105 ttl: 123 106 prio: 2 107 blog: 108 content: 122.2.2.2 109 adomain.org: 110 A: 111 www: 112 content: 12.1.1.2 113 ... 114 ’’’ 115

116 ret = {’name’: ’existed’, 117 ’changes’: {}, 118 ’result’: True, 119 ’comment’: ’’} 120

121 ses = auth_session(email, token) 122 existing_records = {}

123 for domain inrecords:

124 path = "/domains/{0}/records".format(domain)

125 data = json.loads(ses.get(BASE_URL + path).content) 126 data = [i[’record’] for i indata]

127 existing_records[domain] = data 128 129 to_update = {} 130 to_create = {} 131 new_records = normalise(records) 132 id2erc = {}

133 for domain inrecords:

134 ex_records = existing_records[domain]

135 new_domain_records = new_records[domain] 136 to_update[domain] = {}

137 fornrc in new_domain_records: 138 need_create = True

139 for erc inex_records:

140 ifnrc[’name’] == erc[’name’]:

141 # some records have same name, check their type for makeing

142 # sure correct update/create

143 # (DNSimple default have 4 NS record with name ’’)

144 if erc[’name’] == ’’: 145 iferc[’record_type’] != nrc[’record_type’]: 146 continue 147 148 id2erc[erc[’id’]] = erc 149 diff = {} 150 for k, v in nrc.items(): 151 iferc[k] != v: 152 diff[k] = v 153 154 if diff != {}:

155 to_update[domain][erc[’id’]] = diff 156 need_create = False 157 break 158 if need_create: 159 ifto_create == {}: 160 to_create[domain] = [] 161 to_create[domain].append(nrc) 162 log.info("To create: {0}".format(to_create)) 163 log.info("To update: {0}".format(to_update)) 164

165 if__opts__[’test’]: 166 return{’name’: name, 167 ’changes’: {}, 168 ’result’: None,

169 ’comment’: ’Records {0} is set to be created\nRecords {1} is \ 170 set to be updated’.format(to_create, to_update)} 171

172 for domain into_create: 173 forr in to_create[domain]:

174 path = "/domains/{0}/records".format(domain) 175 data = {"record": r}

176 resp = ses.post(BASE_URL + path, json.dumps(data)) 177 log.info("{0} {1}".format(resp.status_code, resp.content)) 178 if resp.status_code == 201:

179 ret[’changes’]["{0}:{1}".format(domain, r[’name’])] = "created" 180 elif resp.status_code == 400:

181 ret[’result’] = False

183 return ret

184 elif resp.status_code == 404:

185 if"Couldn\’t find Domain with name" in resp.content: 186 ret[’result’] = False

187 ret[’comment’] = "Couldn’t find domain {0}".format(domain) 188 return ret 189 else: 190 assert resp.status_code != 422 191 ret[’comment’] = "{0} {1} {2}".format(domain, r, 192 resp.status_code) 193 return ret 194

195 for domin to_update:

196 forrid in to_update[dom]:

197 path = "/domains/{0}/records/{1}".format(dom, rid) 198 record_changes = to_update[dom][rid]

199 resp = ses.put(BASE_URL + path,

200 json.dumps({"record": record_changes})) 201 log.info("{0} {1}".format(resp.status_code, resp.content)) 202 if resp.status_code == 200: 203 changes = [] 204 for k, v inrecord_changes.items(): 205 changes.append("{0}: {1} => {2}".format( 206 k, 207 id2erc[rid][k], 208 json.loads(resp.content)[’record’][k])) 209 ret[’changes’]["{0} {1}".format(dom, 210 id2erc[rid][’name’])] = changes

211 else:

212 ret[’result’] = False

213 ret[’comment’] = "{0} {1}".format(resp.status_code,

214 resp.content)

Một phần của tài liệu SỬ DỤNG SALTSTACK TRIỂN KHAI HỆ THỐNG PRIVATE CLOUD OPENSTACK (Trang 78 - 95)