khanhnnvn

Cài đặt Kubernetes trên Ubuntu

 Database  Comments Off on Cài đặt Kubernetes trên Ubuntu
Mar 052019
 

Kubernetes là một hệ thống mã nguồn mở để tự động triển khai, scaling, quản lý các container. Kubernetes được xây dựng bởi Google dựa trên kinh nghiệm quản lý sử dụng các container trong khi triển khai một hệ thống quản lý gọi là Borg ( nhiều lúc gọi là Omega).

Chuẩn bị

Cấu hình địa chỉ IP tĩnh

vim /etc/network/interfaces

iface enp2s0 inet static
address 172.16.12.120
netmask 255.255.255.0
network 172.16.12.0
gateway 172.16.12.1
dns-nameservers 8.8.8.8

Thiết lập file host theo yêu cầu, chú ý thiết lập cả trên master và các node

vim /etc/hosts

172.16.12.120 k8s-master
172.16.12.135 k8s-node1
172.16.12.136 k8s-node2

service networking restart

Cập nhật các bản vá

apt update && apt upgrade -y

Thiết lập kho cài đặt k8s

apt-get update && apt-get install -y apt-transport-https curl
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add –

cat </etc/apt/sources.list.d/kubernetes.list
deb https://apt.kubernetes.io/ kubernetes-xenial main
EOF

Cài đặt K8s

apt-get update
apt-get install -y kubelet kubeadm kubectl docker.io

Tiếp theo các bạn chạy lệnh sau:

kubeadm init –pod-network-cidr 10.244.0.0/16

cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/confi
chown $(id -u):$(id -g) /root/.kube/config

Tiếp tục chạy lệnh

kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

Thống kê các namespaces đang chạy

kubectl get pods –all-namespaces
watch kubectl get pods –all-namespaces

Khởi động lại dịch vụ

systemctl daemon-reload
systemctl restart kubelet
kubectl get node
watch kubectl get node

Cài đặt Dashboard cho k8s

kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v1.10.1/src/deploy/recommended/kubernetes-dashboard.yaml

Run command

cat < /root/khanh1.yml
apiVersion: v1
kind: ServiceAccount
metadata:
name: admin-user
namespace: kube-system
EOF

cat < /root/khanh2.yml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: admin-user
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:

  • kind: ServiceAccount
    name: admin-user
    namespace: kube-system

EOF

Thực hiện chạy lệnh để apply

kubectl apply -f /root/khanh1.yml
kubectl apply -f /root/khanh2.yml

Hiển thị token để đăng nhập vào dashboard

kubectl -n kube-system describe secret $(kubectl -n kube-system get secret | grep admin-user | awk ‘{print $1}’)

kubectl proxy –address 0.0.0.0 –accept-hosts=’^*$’

http://127.0.0.1:8001/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/#!/login

—————————————– Install Keepalived ——————————-

  1. Install

apt-get install keepalived -y

  1. Create file keepalived.conf

vrrp_instance VI_1 {
state MASTER
interface ens33
virtual_router_id 101
priority 101
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
172.16.12.123
}
}

  1. Copy file to node server and start it

service keepalived start

  1. Check

ip addr show eth0

result

2: ens33: mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:a5:ee:89 brd ff:ff:ff:ff:ff:ff
inet 172.16.12.120/24 brd 172.16.12.255 scope global ens33
valid_lft forever preferred_lft forever
inet 172.16.12.123/32 scope global ens33
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fea5:ee89/64 scope link
valid_lft forever preferred_lft forever

   Note: Max 20 ip per vip

Intro MySQL replication

 Database  Comments Off on Intro MySQL replication
Dec 182018
 

1. Giới thiệu

Right tool for right job. Trước tiên phải hiểu là MySQL Replication không phải là giải pháp giải quyết mọi bài toán về quá tải hệ thống cơ sở dữ liệu. Để mở rộng một hệ thống ta có hai phương pháp mở rộng là scale up và scale out. Bắt đầu với 1 máy chủ thì hai phương pháp trên được diễn giải như sau:

Scale up có nghĩa là với một máy chủ ta làm cách nào đó để nó có thể phục vụ nhiều hơn số lượng kết nối, truy vấn. Nghĩa là giá trị 1/(số kết nối phục vụ) càng nhỏ thì càng tốt. Để đạt được mục đích này thì có 2 phương pháp:

  • Tăng phần cứng lên cho máy chủ. Nghĩa là với CPU là 4 core, RAM là 8 GB phục vụ được 500 truy vấn thì giờ ta tăng CPU lên 24 core, RAM tăng lên 32GB -> máy chủ có thể phục vụ được số lượng kết nối truy vấn nhiều hơn.
  • Optimize ứng dụng, câu truy vấn. Ví dụ với câu truy vấn lấy dữ liệu tốn 5s để lấy được dữ liệu, sau đó mới trả lại tài nguyên cho hệ thống phục vụ các truy vấn khác. Máy chủ có thể đồng thời phục vụ 500 truy vấn dạng như vậy thì nếu ta tối ưu để truy vấn lấy dữ liệu chỉ tốn 1s => Máy chủ có thể phục vụ đồng thời nhiều truy vấn hơn

Scale out là giải pháp tăng số lượng server và dùng các giải pháp load-balacer để phân phối truy vấn ra nhiều server. Ví dụ bạn có 1 server có khả năng phục vụ 500 truy vấn. Nếu ta dựng thêm 5 server nữa có cấu hình tương tự, đặt thêm một LB phía trước để phân phối thì có khả năng hệ thống có thể phục vụ đc 5×500 truy vấn đồng thời.

MySQL Replication là một giải pháp scale out (tăng số lượng instance MySQL) nhưng không phải bài toán nào cũng dùng được. Các bài toán mà MySQL Replication sẽ giải quyết tốt:

  • Scale Read
  • Data Report
  • Real time backup

1.1 Scale Read

Scale Read thường gặp ở các ứng dụng mà số truy vấn đọc dữ liệu nhiều hơn ghi, tỉ lệ read/write có thể 8020 hoặc hơn. Các ứng dụng thường gặp là báo, trang tin tức.

Với scale read ta sẽ chỉ có một Master instance phục vụ cho việc đọc/ghi dữ liệu. Có thể có một hoặc nhiều Slave instance chỉ phục vụ cho việc đọc dữ liệu

Một số ứng dụng write nhiều (thương mại điện tử) cũng có sử dụng MySQL Replication để scale out hệ thống

1.2 Data Report

Một số hệ thống cho phép một số người (leader, manager, người làm report, thống kê, data) truy cập vào dữ liệu trên production phục vụ cho công việc của họ. Việc chọc thẳng vào data production sẽ rất nguy hiểm vì:

  • Vô tình chỉnh sửa làm sai lệnh dữ liệu (nếu có quyền insert, update)
  • Vô tình thực thi các câu truy vấn tốn nhiều tài nguyên, thời gian truy vấn dài làm treo hệ thống

Việc setup một máy chủ làm data report (application cũng sẽ không kết nối tới server này) làm giảm thiểu 2 rủi ro trên

1.3 Real time backup

Với cơ sở dữ liệu lớn việc backup không thể thực hiện thường xuyên được (hàng giờ, hàng phút). Với các ứng dụng giao dịch tài chính, thanh toán, TMDT nếu bị mất dữ liệu 1 giờ, 1 ngày thì thiệt hại sẽ rất lớn (máy chủ chính tư dưng bị hỏng). Real time backup là một giải pháp bổ sung cho offline backup, chạy đồng thời cả 2 phương pháp này để bảo đảm sự an toàn cho dữ liệu.

Tuy nhiên, việc dùng replicate để backup dữ liệu chỉ đảm bảo nếu đĩa cứng của master bị hỏng, trong trường hợp human error khi xóa nhầm dữ liệu, hành động xóa sẽ được replicate sang slave luôn => vẫn bị mất dữ liệu.

Để tránh xảy ra trường hợp trên và giảm thiểu rủi ro mất dữ liệu, mình có giới thiệu một bài khác delay-replication.

2. Hoạt động như thế nào?

2.1 Một số mô hình

mysql-replication

Với cả hai mô hình ta luôn chỉ có 1 Master database phục vụ cho Write dữ liệu, có thể có một hoặc nhiều Slave database. Tùy từng mô hình ta có thể cấu hình mỗi web node connect vào một Slave DB tương ứng hoặc có thể dùng một LB đặt trước cụm Slave để LB tự động phân phối connection vào từng Slave DB theo thuật toán của LB

mysql-replication-lb

2.2 Cách hoạt động

Trên Master:

  • Các kết nối từ web app tới Master DB sẽ mở một Session_Thread khi có nhu cầu ghi dữ liệu. Session_Thread sẽ ghi các statement SQL vào một file binlog (ví dụ với format của binlog là statement-based hoặc mix). Binlog được lưu trữ trong data_dir (cấu hình my.cnf) và có thể được cấu hình các thông số như kích thước tối đa bao nhiêu, lưu lại trên server bao nhiêu ngày.
  • Master DB sẽ mở một Dump_Thread và gửi binlog tới cho I/O_Thread mỗi khi I/O_Thread từ Slave DB yêu cầu dữ liệu

Trên Slave:

  • Trên mỗi Slave DB sẽ mở một I/O_Thread kết nối tới Master DB thông qua network, giao thức TCP (với MySQL 5.5 replication chỉ hỗ trợ Single_Thread nên mỗi Slave DB sẽ chỉ mở duy nhất một kết nối tới Master DB, các phiên bản sau 5.6, 5.7 hỗ trợ mở đồng thời nhiều kết nối hơn) để yêu cầu binlog.
  • Sau khi Dump_Thread gửi binlog tới I/O_TheadI/O_Thread sẽ có nhiệm vụ đọc binlog này và ghi vào relaylog.
  • Đồng thời trên Slave sẽ mở một SQL_ThreadSQL_Thread có nhiệm vụ đọc các event từ relaylog và apply các event đó vào Slave => quá trình replication hoàn thành.
arch

Về logic mỗi Slave DB sẽ chỉ nhận dữ liệu từ Master DB, mọi hành động cập nhật dữ liệu BẮT BUỘC phải được thực hiện trên Master. Về nguyên tắc nếu ghi dữ liệu trực tiếp lên Slave DB => hỏng replication. Nhưng thực chất ta hoàn toàn có thể ghi dữ liệu trên Slave miễn sao khi Slave đọc binlog và apply không đụng gì tới những trường dữ liệu mà ta mới ghi vào thì sẽ không bị lỗi (mục này sẽ nói thêm ở các phần sau)

Với MySQL 5.5 thì mỗi slave sẽ chỉ có một slave_thread connect tới Master, tuy nhiên từ phiên bản 5.6 chúng ta có thể cấu hình nhiều slave_thread để việc apply bin log tới các slave nhanh hơn.

3. Hướng dẫn cài đặt và cấu hình

Mô hình:

  • Master DB: 172.17.0.1
  • Slave DB: 172.17.0.2

Trên Master DB

Cấu hình my.cnf

event-scheduler = on
bind-address = 172.17.0.1
server-id = 1

log-bin
binlog-format=row
binlog-do-db=dwh_prod
binlog-ignore-db=mysql
binlog-ignore-db=test

sync_binlog=0
expire_logs_days=2

Tạo user replication

GRANT REPLICATION SLAVE ON *.* TO 'slave_user'@'172.16.0.2' IDENTIFIED BY 'p@ssword';
FLUSH PRIVILEGES;

Tạo schema, dữ liệu để test

CREATE SCHEMA dwh_prod CHARACTER SET utf8 COLLATE utf8_general_ci;

CREATE TABLE tb1 (
 id INT,
 data VARCHAR(100)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
 
CREATE TABLE tb2 (
 id INT,
 data VARCHAR(100)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

SHOW TABLES;

Trên Slave DB

Cấu hình my.cnf

event_scheduler=off
bind-address = 172.17.0.2
server-id=2

log-bin
binlog-format=row
binlog-do-db=dwh_prod
binlog-ignore-db=mysql
binlog-ignore-db=test

transaction-isolation=read-committed
sync_binlog=0
expire_logs_days=2

Tạo replication và kiểm tra

Nguyên tắc khi tạo replication là phải LOCK tất cả các table trên Master DB, để dữ liệu không thay đổi, sau đó xác định binlog và position, 2 thông số dùng để cấu hình trên Slave xác định đoạn dữ liệu bắt đầu đồng bộ

Trên Master DB

FLUSH TABLES WITH READ LOCK;
SHOW MASTER STATUS;

+----------------+----------+--------------+------------------+
| File           | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+----------------+----------+--------------+------------------+
| m01-bin.000001 |      827 | dwh_prod     | mysql,test       |
+----------------+----------+--------------+------------------+

Giá trị cần quan tâm là

  • m01-bin.000001
  • 827

Sau đó ta sẽ dump dữ liệu từ Master DB và đẩy qua Slave DB (sau khi dump xong có thể UNLOCK TABLES; để Master DB có thể hoạt động lại).

mysqldump -uroot -p dwh_prod > dwh_prod_03072015.sql
rsync -avz -P -e'ssh' dwh_prod_03072015.sql [email protected]:/root/

Trên Slave

mysql -uroot -p dwh_prod < /root/dwh_prod_03072015.sql

> CHANGE MASTER TO MASTER_HOST='172.17.0.1',MASTER_USER='slave_user', MASTER_PASSWORD='p@ssword', MASTER_LOG_FILE='m01-bin.000001', MASTER_LOG_POS=827;
> START SLAVE
> SHOW SLAVE STATUS\G

Một số thông tin đã được lược bỏ cho dễ nhìn

*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 172.0.0.1
                  Master_User: slave_user
              Master_Log_File: m01-bin.000001
          Read_Master_Log_Pos: 827
               Relay_Log_File: m02-relay-bin.000002
                Relay_Log_Pos: 251
        Relay_Master_Log_File: m01-bin.000001
                   Last_Errno: 0
                   Last_Error: 
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 827
              Relay_Log_Space: 405
        Seconds_Behind_Master: 0
                Last_IO_Errno: 0
                Last_IO_Error: 
               Last_SQL_Errno: 0
               Last_SQL_Error: 
             Master_Server_Id: 1

Các thông số cần quan tâm là

  • Last_Error: 0
  • Last_SQL_Error
  • Seconds_Behind_Master: 0

Hai thông số đầu tiên là lỗi khi Slave DB thực thi các event đọc từ relay log. Thông số Seconds_Behind_Master cho ta biết dữ liệu của Slave DB đang bị trễ (delay, lag) bao nhiêu giây so với Master DB. Các phần sau ta sẽ nói kỹ hơn về replication lag này.

4. Vận hành hệ thống MySQL Replicatione

4.1 Test logic replication

Ở trạng thái bình thường dữ liệu trên Slave DB đã đồng bộ với Master DB. Kiểm tra

Trên Master

mysql> USE dwh_prod
mysql> SHOW TABLES;
+--------------------+
| Tables_in_dwh_prod |
+--------------------+
| tb1                |
| tb2                |
| tb3                |
| tb4                |
+--------------------+

Trên Slave

mysql> USE dwh_prod
mysql> SHOW TABLES;
+--------------------+
| Tables_in_dwh_prod |
+--------------------+
| tb1                |
| tb2                |
| tb3                |
| tb4                |
+--------------------+
mysql -e -p 'SHOW SLAVE STATUS\G' | grep -i 'error\|seconds'
                   Last_Error: 
        Seconds_Behind_Master: 0
                Last_IO_Error: 
               Last_SQL_Error:

Mọi thứ đều ổn, không lỗi và không có Lag.

Giờ giả sử ta sẽ tạo một table với tên là tb00 trên Slave và kiểm tra xem có đúng là khi ghi dữ liệu lên Slave DB thì replication có bị hỏng hay không.

mysql> CREATE TABLE tb00 (
 id INT,
 data VARCHAR(100)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

mysql> SHOW TABLES;
+--------------------+
| Tables_in_dwh_prod |
+--------------------+
| tb00               |
| tb1                |
| tb2                |
| tb3                |
| tb4                |
+--------------------+
5 rows in set (0.00 sec)

Kiểm tra các table trên Master DB

mysql> SHOW TABLES;
+--------------------+
| Tables_in_dwh_prod |
+--------------------+
| tb1                |
| tb2                |
| tb3                |
| tb4                |
+--------------------+

Và kiểm tra lại trạng thái của replication

mysql -e 'SHOW SLAVE STATUS\G' | grep -i 'error\|seconds'                                                                                                   
            Last_Error: 
      Seconds_Behind_Master: 0
            Last_IO_Error: 
            Last_SQL_Error:

=> Như ta thấy rõ ràng là dữ liệu trên Slave và Master đã khác nhau (Slave có tb00 nhưng Master thì không) nhưng trạng thái của replication vẫn hoàn toàn ổn.

Giờ chúng ta sẽ thử thêm một trường hợp nữa là trên Master ta sẽ tạo một table tên là tb6 để kiểm tra xem chuyện gì sẽ xảy ra

mysql> CREATE TABLE tb6 (
 id INT,
 data VARCHAR(100)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

mysql> SHOW TABLES;
+--------------------+
| Tables_in_dwh_prod |
+--------------------+
| tb1                |
| tb2                |
| tb3                |
| tb4                |
| tb6                |
+--------------------+

Kiểm tra các table trên Slave DB

mysql> SHOW TABLES;
+--------------------+
| Tables_in_dwh_prod |
+--------------------+
| tb00               |
| tb1                |
| tb2                |
| tb3                |
| tb4                |
| tb6                |
+--------------------+

=> bảng tb6 đã được đồng bộ từ Master qua, kiểm tra trạng thái replication

mysql -e 'SHOW SLAVE STATUS\G' | grep -i 'error\|seconds'
                   Last_Error: 
        Seconds_Behind_Master: 0
                Last_IO_Error: 
               Last_SQL_Error:

=> Mọi thứ vẫn ổn, nghĩa là dù ta có ghi dữ liệu vào Slave, nhưng nếu Master thực thi các câu truy vấn không đụng gì tới dữ liệu được ghi mới ở Slave thì trạng thái của replication vẫn ổn.

Giờ ta sẽ thực hiện thêm một thử nghiệm nữa là trên Master ta tạo một table tên là tb00, trùng với table đã tạo lúc trước ở Slave phía trên và kiểm tra lại trạng thái của replication

Kiểm tra trạng thái replication trên Slave

mysql -e 'SHOW SLAVE STATUS\G' | grep -i 'error\|seconds'
              Last_Error: Error 'Table 'tb00' already exists' on query. Default database: 'dwh_prod'. Query: 'CREATE TABLE tb00 (
   Seconds_Behind_Master: NULL
           Last_IO_Error:
          Last_SQL_Error: Error 'Table 'tb00' already exists' on query. Default database: 'dwh_prod'. Query: 'CREATE TABLE tb00 (

=> như ta thấy hệ thống báo lỗi do trên Slave không thể thực thi hành động tạo table tb00 từ Master đẩy xuống (do table này đã tồn tại trước đó)

Kết Luận: Việc ghi dữ liệu vào Slave là có thể thực hiện được, nhưng sẽ gây ra rủi ro hỏng replication ở một lúc nào đó. Nhất là các câu truy vấn dạng SELECT … UPDATE. Tốt nhất là nên tránh ghi dữ liệu vào Slave

4.2 Replication Lag

Replication Lag là độ trễ dữ liệu của Slave so với Master. Khi triển khai một hệ thống MySQL Replication thì Lag là vấn đề chắc chắn gặp phải. Ta chỉ có thể giảm thiểu độ trễ dữ liệu trong mức chấp nhận được chứ không thể không có lag. Lí do là việc đồng bộ dữ liệu là Asynchronous, nghĩa là các Slave server không cần thông báo cho Master biết khi transaction thực hiện trên Slave thành công -> điều này giúp giữ nguyên hiệu suất (khác với cơ chế đồng bộ synchronous, một transaction được gọi là thành công khi nó committed trên master server và master server nhận được một thông báo từ slave server là transaction này đã được write và committed. Quá trình này đảm bảo tính thống nhất giữa master và slave server nhưng đồng thời nó làm giảm hiệu suất đi một nữa do các vấn đề về network, bandwidth, location.)

Vấn đề của replication lag ảnh hưởng tới các truy vấn vừa write dữ liệu xuống là read dữ liệu lên liền. Ví dụ

Một trang thương mại điện tử có tính năng add vào giỏ hàng một sản phẩm. Sau khi sản phẩm được add vào giỏ hàng sẽ trừ số lượng trong tồn kho. 2 user thực hiện mua sản phẩm đó (sản phẩm đó có số lượng tồn kho là 1). Cả 2 đều thấy sản phẩm đó trên website hiển thị trạng thái CÒN HÀNG. Khi một user mua sản phẩm đó và thanh toán thành công. Do độ trễ dữ liệu (ví dụ 5s) nên dữ liệu chưa đc cập nhật tồn kho xuống Slave là sản phẩm đã hết hàng. Khi user đó add giỏ hàng và thanh toán thì lúc này dữ liệu mới cập nhật và trả về mã lỗi là thanh toán không thành công do số lượng tồn kho không đáp ứng => ảnh hưởng tới trải nghiệm của user trên hệ thống.

Thường với những trường hợp này (truy vấn write xong là read liền) thì nên sử dụng cấu hình truy vấn trên Master (đây là lí do Master có thể vừa write vừa read chứ không nhất thiết là chỉ có write)

4.3 Lb mysql và healthchk

Như 1 trong 2 mô hình phía trên thì với mô hình thứ 2 ta có thể dùng haproxy làm lb cho các MySQL Instance.

Với mô hình 1 nhược điểm là nếu MySQL instance bị delay quá lâu, server quá tải hoặc rủi ro nhất là instace đó bị down thì ta không có cách nào check hoặc remove instance đó ra được.

Với mô hình 2 nhược điểm là ta mất thêm 1 layer (haproxy) nữa mới có thể kết nối tới MySQL (tốn thời gian, xử lí nhiều lớp) nhưng lợi điểm là có thể cấu hình healthchk, hoặc remove instance theo một số điều kiện.

5. Một số lưu ý

5.1 Vấn đề về server, phần cứng

Các vấn đề về CPU, RAM, đĩa cứng (kích thước, loại đĩa cứng, SSD hay HDD, tốc độ đọc ghi của đĩa cứng)

Với một hệ thống DB các thông số phần cứng NÊN quan tâm là

  • CPU: Càng nhiều core càng tốt, tốc độ càng nhanh càng tốt
  • RAM: RAM càng nhiều càng tốt

Với đĩa cứng

  • Nên sử dụng RAID 5, 6, 10
  • Nên sử dụng SSD (Enterprise thì càng tốt) IOPS càng cao càng tốt
  • Đĩa cứng nên có dung lượng ít nhất là x2 lần dung lượng của CSDL (sẽ cần thiết trong trường hợp dump, backup dữ liệu để fix replication)

Khác với các ứng dụng khác như web, static (thường CPU không cần nhiều core, đĩa cứng không cần nhiều và nhanh), máy chủ CSDL sẽ cần nhiều các thông số trên

Với AWS khi chọn Instance cũng nên chú ý các điểm trên

5.2 Các vấn đề về kích thước dữ liệu

Vấn đề kích thước dữ liệu ảnh hưởng khá nhiều đến vận hành một hệ thống MySQL Replication. Dữ liệu lớn thì quá trình replication đầu tiên hoặc khi hỏng replication sẽ rất lâu => Slave không thể sử dụng được trong thời gian replication, đến khi Second_Behind_Master = 0 thì mới có thể sử dụng được.

Ngoài ra các yếu tố về ổ đĩa cứng (SSD, tốc độ đọc ghi) cũng ảnh hưởng nhiều đến việc import hoặc apply các binlog từ Master

Dưới đây là một mô tả thực tế:

  • Dữ liệu thô /var/lib/mysql có kích thước 80-100GB
  • Dữ liệu dump ra chưa nén 18-30GB
  • Dữ liệu nén bằng chuẩn tgz ~ 2-3GB
  • Máy chủ 24 core, 32GB RAM, SSD Plextor M6 PRO (4×256, RAID 10)
  • Thời gian dump dữ liệu là 1h-1h30
  • Thời gian sync bản dump qua các server (local, port 1Gb) ~ 1h
  • Thời gian import dữ liệu ~1.5h
  • Thời gian Second_Behind_Master sau khi import xong ~ 3600s

6. Failover

Một vấn đề khác ngoài chuyện scale đó là nếu master db chết thì chuyện gì xảy ra?. Có một số mindset mà bạn bắt buộc phải hiểu khi chọn giải pháp replication master-slave đó là:

  • Quá trình promote 1 Slave thay thế Master là thủ công, không thể tự động switch sang slave mà hệ thống không có vấn đề gì.
  • Vẫn sẽ có downtime nếu master db chết, tuy nhiên việc dùng slave đảm bảo thời gian downtime tối thiểu nhất có thể.

Quay trở lại mô hình 1 master và 2 slave (gọi lần lượt là S1 và S2), ta cần trả lời là nếu master chết thì chuyện gì xảy ra với hệ thống và cách promote một slave lên thay thế master là gì?

Mặc định, Slave vẫn sẽ có binlog, và binlog này là của riêng slave chứ không giống với binlog của master (binlog của master khi đẩy qua slave sẽ thành relay-log), có nghĩa là nếu S1 đẩy lên làm master thì S2 sẽ không còn đồng bộ với S1 nữa và ta sẽ cần build lại S2.

Để giải quyết vấn đề này, mysql khuyến cáo chúng ta bật --skip-log-slave-updates trên Slave, chuyện này đảm bảo:

  • Slave vẫn sẽ có binlog nhưng với các hành vi apply relay-log (update dữ liệu như master) thì slave sẽ không ghi ra binlog.
  • Khi master chết, ta có nhu cầu promote S1 lên làm master, ta sẽ cần reset master của S2 trỏ về S1, tuy nhiên như ở trên ta sẽ cần chỉ định file binlog và position của file log, và do S1 sau khi đc đổi thành master thì mới bắt đầu sinh ra binlog, nên trên S2 ta chỉ cần trỏ về file binlog và position đầu tiên của S2 là đủ. => chuyện này đảm bảo rằng S2 sẽ đồng bộ dữ liệu với S1.

Sau khi việc promote hoàn thành, ta có thể cập nhật lại ở phía client địa chỉ củ a S1 và hoàn thành việc bảo trì hệ thống. Tuy nhiên để ý là quá trình trên là thủ công và ta vẫn có downtime trong quá trình promote.

Tuy nhiên, điều trên chỉ đúng chỉ đúng khi slave sync với master trước khi master chết với second_behind_master = 0.

https://dev.mysql.com/doc/refman/8.0/en/replication-solutions-switch.html

7. Semi-synchronous

Có một vấn đề với asynchronous đó là nếu bạn có nhu cầu đọc ngay dữ liệu vừa ghi xuống thì có thể dữ liệu sẽ sai, do slave chưa kịp apply dữ liệu từ master (lag dữ liệu), có 2 cách giải quyết tạm:

  • Với trường hợp vừa ghi và đọc liền dữ liệu, ta nên dùng ở master.
  • Dùng cơ chế semi-synchronous để giảm lag dữ liệu.

Semi-synchronous là một kiểu lai giữa asynchronous và synchronous. Bình thường nếu xài synchronous thì càng nhiều slave thì càng giảm tốc độ ghi dữ liệu, do slave phải committed và trả lời ngược về master. Với semi-synchronous thì master coi như ghi thành công là khi có tối thiểu một slave đã nhận và ghi ra relay log event mà master gửi qua. Điểm khác biệt là không cần tất cả các slave gửi tín hiệu ngược lại master, và event cũng không bắt buộc phải được execute và commited trên slave, chỉ cần đảm bảo là đã nhận và ghi ra relay log là đủ.

Như mô tả ở trên thì slave vẫn có thể không có dữ liệu nếu relay log bị tác động với con người, hoặc server bị hỏng ngay khi chưa kịp apply relay log, tuy nhiên nhờ việc đảm bảo binlog event đã đc nhận với slave và ghi xuống đĩa đã làm giảm thời gian delay và vấn đề về data race condition có thể được hạn chế phần nào.

Add more disk using LVM

 Linux  Comments Off on Add more disk using LVM
Dec 182018
 

Step 1: Check disk

Chúng ta cần kiểm tra chắc chắn rằng partition của chúng ta đang thao tác là Linux LVM

fdisk -l

Như bạn có thể thấy là /dev/sda5 ở trên là Linux LVM và nó có ID là 8e. 8e là mã hex để thể hiện nó là type kiểu Linux LVM. Như vậy chúng ta đã kiểm tra được đang làm việc trên Linux LVM rồi.

Như thông tin trong ảnh bên dưới thì ổ cứng hiện tại là 20GB và nó đang được đặt trong logical với tên là /dev/mapper/Mega-root nơi mà chúng ta sẽ mở rộng ổ cứng mới.

2. Increasing the virtual hard disk

Tiếp theo chúng ta cần thay đổi ổ cứng của máy ảo từ 20GB thành 30GB bằng cách thay đổi setting của VMWare.

3. Detect the new disk space

Như vậy là chúng ta đã tăng được ổ cứng ở tầng hardware rồi, tiếp theo chúng ta sẽ tạo partition mới dựa trên ổ cứng này.

Trước khi chúng ta có thể làm được điều này thì cần phải check được “unallocated disk” đã được phát hiện ở server chưa. Bạn có thể sử dụng lệnh “fdisk -l” để xem danh sách primay disk. Tuy nhiên bạn có thể sẽ nhìn thấy list giống như trạng thái ban đầu, ở thời điểm này bạn không cần phải restart server mà vẫn có thể check được thay đổi bằng command dưới đây.

echo "- - -" > /sys/class/scsi_host/host0/scan

THeo như hình ảnh bên dưới thì chúng ta có thể xác nhận được là đã hiển thị bao gồm cả ổ cứng mới.

4. Partition the new disk space

Như bạn đã thấy chúng ta đang làm việc với /dev/sda và chúng ta sẽ tạo primary partition mới bằng cách sử dụng fdisk.

fdisk /dev/sda

Chúng ta sẽ làm theo hướng dẫn như bên dưới và nhập theo kí tự in đậm. Chú ý chọn m để có thể get tất cả commands liên quan đến fdisk

‘n’ là để thêm partition mới

WARNING: DOS-compatible mode is deprecated. It's strongly recommended to
         switch off the mode (command 'c') and change display units to
         sectors (command 'u').

Command (m for help): n

‘p’ là để tạo primary partition

Command action
   l   logical (5 or over)
   p   primary partition (1-4)
p

Chúng ta đã có /dev/sda1 và /dev/sda2 như trên vì vậy sử dụng 3 để tạo /dev/sda3

Partition number (1-4): 3

Tiếp theo enter 2 lần để nhận default cylinders đầu và cuối

First cylinder (2611-3916, default 2611): "enter"
Using default value 2611
Last cylinder, +cylinders or +size{K,M,G} (2611-3916, default 3916): "enter"
Using default value 3916

‘t’ là để thay đổi system ID của partition, trong trường hợp này sẽ thay đổi về 3 vừa được tạo ở trên.

Command (m for help): t
Partition number (1-5): 3

Mã code hex 8e là code cho Linux LVM

Hex code (type L to list codes): 8e
Changed system type of partition 3 to 8e (Linux LVM)

‘w’ là để ghi vào bảng các disk và exit.

Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.

WARNING: Re-reading the partition table failed with error 16: Device or resource busy.
The kernel still uses the old table. The new table will be used at
the next reboot or after you run partprobe(8) or kpartx(8)
Syncing disks.

Bạn có thể thấy cảnh báo cần reboot lại nhưng nếu bạn ko thấy partition mới bằng cách sử dụng “fdisk -l” thì có thể chạy “partprobe -s” để quét lại bảng partition.

5. Increasing the logical volume

Sử dụng lệnh pvcreate để tạo physical volume sử dụng LVM.

  Device /dev/sda3 not found (or ignored by filtering).

để không phải reboot lại thì bạn phải sử dụng partprobe/partx sau đó thực hiện lại lệnh pvcreate.

root@Mega:~# pvcreate /dev/sda3
  Physical volume "/dev/sda3" successfully created

Tiếp theo kiểm tra xem tên hiện tại của volume group bằng lệnh vgdisplay.

root@Mega:~# vgdisplay
  --- Volume group ---
  VG Name               Mega
...
VG Size               19.76 GiB

Bây giờ mở rộng “Mega” bằng cách add thêm physical volume /dev/sda3 bằng lệnh pvcreate

root@Mega:~# vgextend Mega /dev/sda3
  Volume group "Mega" successfully extended

Sử dụng lệnh pvscan để scan tất cả disk cho physical volumes. Nó sẽ bao gồm /dev/sda5 ban đầu và physical volume vừa thêm /dev/sda3

root@Mega:~# pvscan
  PV /dev/sda5   VG Mega   lvm2 [19.76 GiB / 0    free]
  PV /dev/sda3   VG Mega   lvm2 [10.00 GiB / 10.00 GiB free]
  Total: 2 [29.75 GiB] / in use: 2 [29.75 GiB] / in no VG: 0 [0   ]

Tiếp theo là tăng logical volume Đầu tiên kiểm tra đường dẫn của logical volume sử dụng lvdisplay

root@Mega:~# lvdisplay
  --- Logical volume ---
  LV Path                /dev/Mega/root

Extend logical volume sử dụng

root@Mega:~# lvextend /dev/Mega/root /dev/sda3
 Extending logical volume root to 28.90 GiB
 Logical volume root successfully resized

Bước cuối cùng là resize lại file system sử dụng resize2fs

Step 2: xfs_growfs /dev/Mega/root

SingleSignOn Asianux

 Linux  Comments Off on SingleSignOn Asianux
Oct 192018
 

Thông tin chung

Kiến thức cơ bản và Tài liệu

Sơ đồ triển khai SSO cho Cổng TTĐT Asianux và các ứng dụng

Sơ đồ máy chủ và ứng dụng

  • Máy chủ Portal (www.asianux.org.vn – IP: ) cài đặt Cổng TTĐT Asianux.
    • IBM HTTP Server (/opt/IBM/HTTP)
    • IBM WebSphere Application Server – WAS 6.1.0.19 (/opt/IBM/WebSphere/AppServer)
    • IBM WebSphere Portal v6.1.0.1 (/opt/IBM/WebSphere/wp_profile)
    • phpBB v3 (/opt/www/forum)
  • Máy chủ Email (mail.asianux.org.vn – IP: asianux.org.vn/10.0.0.?) cài đặt Zimbra Email Server.
    • Email Server (/opt/zimbra), mailboxd chạy trên jetty Application Server (/opt/zimbra/jetty)
    • Zimbra Internal Ldap (/opt/zimbra/openldap)
  • Máy chủ Database (IP trong 10.0.0.?) cài đặt IBM DB2 LUW v9.
  • Máy chủ LDAP và CAS (cas.asianux.org.vn,) cài đặt OpenLdap Server và CAS Server.
    • LDAP (OpenLdap, base: dc=asianux,dc=org,dc=vn)
      • Nhánh cn=groups,dc=asianux,dc=org,dc=vn chứa các group nhóm NSD
      • Nhánh cn=people,dc=asianux,dc=org,dc=vn chứa các tài khoản NSD
    • CAS Server (v3, download tại đây http://www.jasig.org/cas/download)
      • Application Server: tomcat 6
      • Thư mục cài đặt /opt/CAS

Sơ đồ triển khai CAS

  • CASifying WebSphere Portal : cài đặt một CAS Client trên WAS dựa trên cơ chế Trust Association Interceptor (TAI) interface của WebSphere.
  • CASifying Zimbra : cài đặt một CAS client trên Zimbra dựa trên cơ chế pre-authentication của Zimbra.
  • Khi các ứng dụng (portal, email) cần xác thực NSD, các CAS client tương ứng sẽ trao đổi với CAS server theo một giao thức nhất định (giao thức CAS). CAS server sẽ xác thực dựa trên cở sở dữ liệu LDAP và trả lại kết quả cho các CAS client. Các CAS client sau đó sẽ tiến hành công đoạn xác thực theo cơ chế nội tại của mỗi ứng dụng (TAI hoặc pre-authentication).
  • Khi các cơ sở dữ liệu NSD nội tại (ở đây là Zimbra Internal Ldap) thay đổi (ví dụ : thêm, xóa, thay đổi account), cần có một thao tác đồng bộ với External Ldap. Phương án đơn giản nhất là viết một đoạn script đồng bộ giữa 2 Ldap server và cho chạy theo định kỳ.

Cài đặt

Các bước cài đặt

  • Cài đặt và thiết lập LDAP server.
  • Thêm Ldap Server vào Federated Repository của WebSphere Portal với basedn dc=asianux,dc=org,dc=vn  (default Repository của WPS là file repository, base o=defaultWIMFileBasedRealm).
  • Cài đặt và cấu hình CAS server.
  • Cài đặt và cấu hình CASifying WebSphere.
  • Cài đặt và cấu hình CASifying Zimbra.
  • Cài đặt và cấu hình Single Sign Out.
  • Cấu hình thay đổi login và logout page cho Portal và Email.
  • Cài đặt plugin Change Password cho Zimbra

Thêm Ldap ngoài vào WSP Federated Repository

  • Làm theo hướng dẫn trong WebSphere Portal 6.1 Info Center, search “federated repository”.

CAS Server

  • Theo framework CAS chuẩn, để đảm bảo tính security, CAS server phải được truy cập qua tầng giao thức SSL (https://), nếu không các giao dịch giữa client và server sẽ không được chấp nhận.
  • Tuy nhiên, các server Asianux chưa có trusted certificate nên khi truy cập bằng https sẽ hiện lên thông báo (giống như thông báo khi vào mail.vietsoftware.com).
  • Vì vậy, tạm thời ban đầu CAS server sẽ được modified đi một chút để có thể chấp nhận giao thức http thông thường, các CAS client cũng vậy.

CASifying WebSphere

  • Làm theo hướng dẫn tại https://wiki.jasig.org/pages/viewpage.action?pageId=19314 lưu ý  mấy thông số sau:
    • Dùng cas-client v2
    • <WPSInstallDirectory> = /opt/IBM/WebSphere/wp_profile
    • Sửa một chút code sau đó build lại 2 file CasClientWebsphere-x.x.x.jar và casclient-2.1.1.jar
    • Interceptor Classname: octo.cas.client.websphere.CasTAI511
    • CAS_VALIDATION_URL = http://cas.asianux.org.vn/cas/serviceValidate
    • PRINCIPAL_PREFIX= uid= (lưu ý dấu bằng = ở cuối)
    • PRINCIPAL_SUFFIX = ,dc=asianux,dc=org,dc=vn (lưu ý dấu phảy , ở đầu)
    • STORE_PROXY_TICKET= false (chưa dùng cơ chế proxy ticket)

CASifying Zimbra

Single Sign Out

Thiết lập login page cho portal

Thiết lập logout page cho portal

redirect.logout=true

redirect.logout.ssl=false

redirect.logout.url=http://cas.asianux.org.vn/SingleSignOut/CasSSOut?from=portal

Thiết lập logout page cho Zimbra

ChangeExtLdapPassword

  • Cơ chế Change password listener cho phép viết các Zimbra extensions thực hiện một số thao tác trước hoặc sau khi password được đổi trong internal Zimbra LDAP server (http://bugzilla.zimbra.com/attachment.cgi?id=22251).
  • ChangeExtLdapPassword extension sử dụng cơ chế Change password listener để đổi password ở external LDAP đồng thời với thao tác đổi password bên trong Zimbra.
  • Cài đặt (xem http://blog.zimbra.com/blog/archives/2010/04/extending-zimbra-with-server-extensions.html)
    • Build ChangeExtLdapPasswordExt.jar.
    • Tạo thư mục /opt/zimbra/lib/changeExtLdapPassword và copy ChangeExtLdapPasswordExt.jar vào đó.
    • Restart Zimbra.

Step by step instructions on self-signed certificate and Tomcat over SSL

 Linux  Comments Off on Step by step instructions on self-signed certificate and Tomcat over SSL
Oct 092018
 

Creating a self-signed certificate to test Tomcat https is easy, and this article gives you the step-by-step instructions on the following parts:

1. Create a self-signed host certificate using openSSL

2. Create a PKCS12 keystore and convert it to java keystore

3. Configure Tomcat 6 to use https, and redirect http to https

4. Create a Java client to talk to the Tomcat over SSL with the self-signed certificates

Part 1.  Create a self-signed host certificate using openSSL

There are different ways of creating a self-signed certificate, such as using Java keytool.  But I prefer openSSL because the keys and certificates generated this way are more standardized and can be used for other purposes.  The openSSL HOWTO page gives you a lot of details and other information.

1.1 Create a pair of PKI keys

PKI stands for Public Key Infrastructure, which is also known as Asymmetric key pair, where you have a private key and a public key.  The private key is a secret you guard with your honor and life, and the public key is something you give out freely.  Messages encrypted with one can be decrypted with the other.  While generally speaking, given one key, it should be infeasible to derive the other.  However, openSSL makes it so that given a private key, you can easily derive the public key (but not vice versa, otherwise the security is broken).  For this reason, when you generate a key using openSSL, it only gives you a private key.

As a side note, the word asymmetric is really a poor choice.  Once, a security expert was giving a presentation to a roomful of students on PKI, and one of his slides was supposed to have the title “Asymmetric key scheme”, but perhaps it was the fonts he used, or perhaps he made a last-minute typo,  it looked like there was a space between the letter “A” and the rest of the letter.  After that presentation, quite a few naive students began to think that  PKI is a symmetric (WRONG!) key scheme where it should be exactly the opposite — this is probably a less forgivable mistake than blowing up the chemistry lab because someone thinks inflammable means not flammable.

1.1.1 Create a host private key using openSSL

1
openssl genrsa -out HOSTNAME-private.pem 2048

This private key is 2048 bits long, generated using RSA algorithm, and we choose not to protect it with an additional passphrase because the key will be used with a server certificate.  The name of the private key is HOSTNAME-private.pem where HOSTNAME should be replaced by the name of the machine you intend to host Tomcat.

1.1.2 Derive the public key using openSSL.  This step is not necessary, unless  you want to distribute the public key to others.

1
openssl rsa -in HOSTNAME-private.pem -pubout  > HOSTNAME-public.pem

1.2 Create a self-signed X509 certificate

1
openssl req -new -x509 -key HOSTNAME-private.pem -out HOSTNAME-certificate.pem -days 365

Then you will be prompted to enter a few pieces of information, use “.” if you wish to leave the field blank

1
2
3
4
5
6
7
8
-----
Country Name (2 letter code) [AU]:US
State or Province Name (full name) [Some-State]:Indiana
Locality Name (eg, city) []:Bloomington
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Cool Org
Organizational Unit Name (eg, section) []:Cool IT
Common Name (eg, YOUR name) []:Cool Node
Email Address []:.

You will now see your host certificate file HOSTNAME-certificate.pem

UPDATE: The field Common Name is quite important here.  It is the hostname of the machine you are trying to certify with the certificate, which is the name in the DNS entry corresponding to your machine IP.

If your machine does not have a valid DNS entry (in other words, doing a nslookup on the IP of your machine doesn’t give you anything), the host certificate probably won’t work too well for you.  If you are only doing some very minimalistic https connection using only the HttpsURLConnection provided by Java, you can probably get by by disabling the certificate validation as outline towards the end of this article; however, if you use other third-party software packages, you will probably get an exception look like the following:

1
java.io.IOException: HTTPS hostname wrong:  should be <xxx.yyy.zzz>

This is because many security packages would check for things such as URL Spoofing, and when they do a reverse lookup of the machine IP,  but do not yield the same hostname as what is in the certificate, they think something is fishy and throws the exception.

Part 2. Create a PKCS12 keystore and convert it to a Java keystore

Java keytool does not allow the direct import of x509 certificates with an existing private key, and here is a Java import key utility Agent Bob created to get around that.  However, we can still get it to work even without this utility.  The trick is to import the certificate into a PKCS12 keystore, which Java keytool also supports, and then convert it to the Java keystore format

2.1 Create a PKCS12 keystore and import (or export depending on how you look at it) the host certificate we just created

1
openssl pkcs12 -export -out keystore.pkcs12 -in HOSTNAME-certificate.pem -inkey HOSTNAME-private.pem

It will ask you for the export password, and it is recommended to provide a password.

2.2 Convert the PKCS12 keystore to Java keystore using Java keytool.

1
keytool -importkeystore -srckeystore keystore.pkcs12 -srcstoretype PKCS12 -destkeystore keystore.jks -deststoretype JKS

Keytool will first ask you for the new password for the JKS keystore twice, and it will also ask you for the password you set for the PKCS12 keystore created earlier.

1
2
3
4
5
Enter destination keystore password:
Re-enter new password:
Enter source keystore password:
Entry for alias 1 successfully imported.
Import command completed: 1 entries successfully imported, 0 entries failed or cancelled

It will output the number of entries successfully imported, failed, and cancelled.  If nothing went wrong, you should have another keystore file: keystore.jks

Part 3. Configure Tomcat to use HTTPS

With the keystore in place, we can now configure Tomcat to communicate via SSL using the certificate.

3.1 Configure Tomcat HTTPS Connector.

Edit CATALINA_HOME/conf/server.xml, where CATALINA_HOME is the base directory of Tomcat.  By default, the HTTPS Connector configuration is commented out.  We can search for “8443” which is the default port number for HTTPS connector, and then either replace the configuration block, or add another block just below.  We are going to use the Coyote blocking connector:

1
2
3
4
5
6
7
<!--
 <Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
 maxThreads="150" scheme="https" secure="true"
 clientAuth="false" sslProtocol="TLS" />
 -->
<Connector port="8443" protocol="org.apache.coyote.http11.Http11Protocol" SSLEnabled="true" maxThreads="150" secure="true" scheme="https" keystoreFile="PATH/TO/keystore.jks" keystorePass="JKS_KEYSTORE_PASSWORD" clientAuth="false" sslProtocol="TLS" />

In the snippet above, PATH/TO/keystore.jks is the path to the Java Keystore we created earlier, and I recommend using the absolute path to eliminate any confusion.  Also provide the keystore password – it is in plain text, so protect server.xml using the correct permission (700).

The Tomcat SSL configuration instruction is a bit misleading and may let us believe both blocking and non-blocking should be configured.  This is not true because the port number can only be used by one connector type.

This configuration enables Tomcat to communicate HTTPS on port 8443.  At this point, it is a good idea to fire up Tomcat and make sure the configuration works using a web browser.

1
2
cd CATALINA_HOME
bin/startup.sh

And point your web browser to https://HOSTNAME:8443 to see if Tomcat’s front page shows up.  Since we are using a self-signed certificate, your browser may complain about the certificate being not secure.  Accept the certificate so your browser can display the page.

3.2 Configure Tomcat to redirect HTTP to HTTPS

However, so far, Tomcat still supports HTTP (default port is 8443, but it may have been changed in your situation).  It would be desirable to automatically redirect any requests to the HTTP over to the HTTPS.  The first thing to do is edit CATALINA_HOME/conf/server.xml again, and this time, locate the Connector configuration for HTTP, and modify it so that the “redirectPort” attribute points to the HTTPS port (8443 by default).

1
2
3
<Connector port="8080" protocol="HTTP/1.1"
 connectionTimeout="20000"
 redirectPort="8443" />

Now save server.xml, and edit web.xml, and add the following block to the end of the file, just before the </web-app> tag (in other words, the security-constraint section must be added AFTER the servlet-mapping sections:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<web-app ...>
...
  <security-constraint>
    <web-resource-collection>
      <web-resource-name>All Apps</web-resource-name>
      <url-pattern>/*</url-pattern>
    </web-resource-collection>
    <user-data-constraint>
      <transport-guarantee>CONFIDENTIAL</transport-guarantee>
    </user-data-constraint>
  </security-constraint>
</web-app>

Save this file, restart Tomcat again. This time, open a browser and enter the URL to the normal HTTP port, and see if Tomcat redirects to the HTTPS port.

Part 4. Create a test Java client to talk to Tomcat over SSL

Since we created our own self-signed certificate, if we just use a Java HttpsURLConnection client trying to connect to the Tomcat over SSL, it will not honor the certificate and throw an exception like the following:

Config SSL for Tomcat 8 GlobalSign

 Linux  Comments Off on Config SSL for Tomcat 8 GlobalSign
Oct 092018
 

HƯỚNG DẪN CÀI ĐẶT SSL CHO TOMCAT 8

  1. Tạo file keystore từ tomcat

keytool -genkey -alias server -keyalg RSA -keysize 2048 -keystore interface_asianux_org.jks

Note:

  • Vào thư mục chứa java sử dụng lệnh keytool hoặc ./keytool
  • alias là tên của alias. Có thể đặt 1 tên bất kì. Ví dụ ở đây là đặt tên: “server”.
  • Sau khi gõ lệnh sẽ hỏi pass à đặt 1 pass cho chùm keystore. ở đây tên chùm keystore là jks

 

  1. Tạo ra file .csr bằng lệnh:

keytool keytool -certreq -alias server -file interface_asianux_org.csr -keystore interface_asianux_org.jks

Note:

Chú ý tên alias phải trùng với trên alias đã tạo ở trên

Kiểm tra lại xem đã tạo file csr chưa bằng lệnh: LS

  1. Gửi file .crs cho nhà đăng ký dịch vụ và chờ nhà cung cấp gửi trả lại file . ở đây nhà cung cấp trả lại 2 file dạng “certificate.p7b” và “intermediate.cer”
  2. Chèn key từ nhà cung cấp vào chùm keystore có sẵn của mình:

keytool -import -alias AVIntermediate -trustcacerts -file intermediate.cer -keystore interface_asianux_org.jks

keytool -import -alias server -trustcacerts -file certificate.p7b -keystore interface_asianux_org.jks

  1. Kiểm tra lại key đã chèn vào chùm keystore bằng lệnh:
  2. Chỉnh sửa lại file server.xml ( ở đây có thể lựa chọn port khác ngoài port 443)

<Connector port=”8080″ protocol=”HTTP/1.1″

connectionTimeout=”20000″

redirectPort=”443″ />

<Connector port=”443″

protocol=”org.apache.coyote.http11.Http11NioProtocol”               maxThreads=”150″ SSLEnabled=”true” scheme=”https” secure=”true”

clientAuth=”false” sslProtocol=”TLS” keystoreFile=”/opt/jdk1.8.0_111/jre/bin/interface_asianux_org.jks” keystorePass=”123456″ keyAlias=”server” />

 

Note: tại đây lưu ý nếu trên server của bạn chạy cả apachi thì bạn phải đổi lại port của apachi trong file ssl.conf sang 1 port khác. Ví dụ: 443à9443

  1. Thử lại dịch vụ trên server: https://x.x.x.x:443

Note: lưu ý bảng iptable trên linux mở port 8443 hoặc 443

HowTo: Create a Self-Signed SSL Certificate on Nginx For CentOS / RHEL

 Linux  Comments Off on HowTo: Create a Self-Signed SSL Certificate on Nginx For CentOS / RHEL
Oct 052018
 

A note about a self-signed certificates vs a third party issued certificates

Fig.01: Cyberciti.biz connection encrypted and verified by a third party CA called GeoTrust, Inc.
Fig.01: Cyberciti.biz connection encrypted and verified by a third party CA called GeoTrust, Inc.
  1. Usually, an SSL certificate issued by a third party. It provides privacy and security between two computers (client and server) on a public network by encrypting traffic. CA (Certificate Authorities) may issue you a SSL certificate that verify the organizational identity (company name), location, and server details.
  2. A self-signed certificate encrypt traffic between client (browser) and server. However, it can not verify the organizational identity. You are not depend upon third party to verify your location and server details.

Our sample setup

  • Domain name: theos.in
  • Directory name: /etc/nginx/ssl/theos.in
  • SSL certificate file for theos.in: /etc/nginx/ssl/theos.in/self-ssl.crt
  • ssl certificate key for theos.in: /etc/nginx/ssl/theos.in/self-ssl.key
  • Nginx configuration file for theos.in: /etc/nginx/virtual/theos.in.conf

Step #1: Make sure SSL aware nginx installed

Simply type the following command to verify nginx version and feature:
$ /usr/sbin/nginx -V
Sample outputs

nginx version: nginx/1.4.3
built by gcc 4.4.7 20120313 (Red Hat 4.4.7-3) (GCC) 
TLS SNI support enabled
configure arguments: --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --conf-path=/etc/nginx/nginx.conf 
...
....
..

If nginx is not installed, type the following command to download and install nginx using yum command:
# yum install nginx
See how to install Nginx web server On CentOS Linux 6 or Red Hat Enterprise Linux 6 using yum command for more information.

Step #2: Create a directory

Type the following mkdir command to create a directory to store your ssl certificates:
# mkdir -p /etc/nginx/ssl/theos.in

Use the following cd command to change the directory:
# cd /etc/nginx/ssl/theos.in

Step #3: Create an SSL private key

To generate an SSL private key, enter:
# openssl genrsa -des3 -out self-ssl.key 1024
OR better try 2048 bit key:
# openssl genrsa -des3 -out self-ssl.key 2048
Sample outputs:

Generating RSA private key, 1024 bit long modulus
...++++++
...............++++++
e is 65537 (0x10001)
Enter pass phrase for self-ssl.key: Type-Your-PassPhrase-Here
Verifying - Enter pass phrase for self-ssl.key: Retype-Your-PassPhrase-Here

Warning: Make sure you remember passphrase. This passphrase is required to access your SSL key while generating csr or starting/stopping ssl.

Step #4: Create a certificate signing request (CSR)

To generate a CSR, enter:
# openssl req -new -key self-ssl.key -out self-ssl.csr
Sample outputs:

Enter pass phrase for self-ssl.key: Type-Your-PassPhrase-Here
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:IN
State or Province Name (full name) []:Delhi
Locality Name (eg, city) [Default City]:New Delhi
Organization Name (eg, company) [Default Company Ltd]:nixCraft LTD
Organizational Unit Name (eg, section) []:IT
Common Name (eg, your name or your server's hostname) []:theos.in
Email Address []:[email protected] 

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

Step #5: Remove passphrase for nginx (optional)

You can remove passphrase from self-ssl.key for nginx server, enter:
# cp -v self-ssl.{key,original}
# openssl rsa -in self-ssl.original -out self-ssl.key
# rm -v self-ssl.original

Sample outputs:

Enter pass phrase for self-ssl.original: Type-Your-PassPhrase-Here
writing RSA key

Step #6: Create certificate

Finally, generate SSL certificate i.e. sign your SSL certificate with your own .csr file for one year:
# openssl x509 -req -days 365 -in self-ssl.csr -signkey self-ssl.key -out self-ssl.crt
Sample outputs:

Signature ok
subject=/C=IN/ST=Delhi/L=New Delhi/O=nixCraft LTD/OU=IT/CN=theos.in/[email protected]
Getting Private key

Step #7: Configure the Certificate for nginx

Edit /etc/nginx/virtual/theos.in.conf, enter:
# vi /etc/nginx/virtual/theos.in.conf
The general syntax is as follows for nginx SSL configuration:

server {
    #for ipv4
    listen 443 ssl http2;
    #for ipv6
    #listen [::]:443 ssl http2;
    ssl_certificate      /path/to/self-ssl.crt;
    ssl_certificate_key  /path/to/self-ssl.key;
    server_name theos.in;
    location / {
       ....
       ...
       ....
    }
}

Here is my sample config for theos.in:

server {
    ###########################[Note]##############################
    ## Note: Replace IP and server name as per your actual setup ##
    ###############################################################

    ## IP:Port and server name
        listen 75.126.153.211:443 ssl http2;
        server_name theos.in;

    ## SSL settings
        ssl_certificate /etc/nginx/ssl/theos.in/self-ssl.crt;
        ssl_certificate_key /etc/nginx/ssl/theos.in/self-ssl.key;

    ## SSL caching/optimization 
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS';
    ssl_prefer_server_ciphers on;
        ssl_prefer_server_ciphers on;
              ssl_session_cache shared:SSL:50m;
        ssl_session_timeout 1d;
        ssl_session_tickets off;
    
    ## SSL log files   
        access_log /var/log/nginx/theos.in/ssl_theos.in_access.log;
        error_log /var/log/nginx/theos.in/ssl_theos.in_error.log;

    ## Rest of server config goes here
        location / {
                proxy_set_header        Accept-Encoding   "";
                proxy_set_header        Host              $http_host;
                proxy_set_header        X-Forwarded-By    $server_addr:$server_port;
                proxy_set_header        X-Forwarded-For   $remote_addr;
                proxy_set_header        X-Forwarded-Proto $scheme;
                proxy_set_header        X-Real-IP               $remote_addr;
                proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
                ## Hey, ADD YOUR location / specific CONFIG HERE ##
 
                ## STOP: YOUR location / specific CONFIG HERE ##
        }
}

Step #8: Restart/reload nginx

Type the following command
# /usr/sbin/nginx -t
Sample outputs:

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

To gracefully restart/reload nginx server, type the following command:
# /etc/init.d/nginx reload
OR
# /usr/sbin/nginx -s reload
OR
# service nginx reload

Step #9: Open TCP HTTPS port # 443

Type the following command to open port # 443 for everyone:
# /sbin/iptables -A INPUT -m state --state NEW -p tcp --dport 443 -j ACCEPT
Save new firewall settings:
# service iptables save
See how to setup firewall for a web server for more information.

Step 10: Test it

Fire a browser and type the following url:

https://theos.in/

Sample outputs:

Fig.02: SSL connection is not verified due to self-signed certificate. Click the
Fig.02: SSL connection is not verified due to self-signed certificate. Click the “Add Exception” button to continue.

Step 11: Verify SSL certificats

You can verify SSL Certificate using the following command:
# openssl verify pem-file
# openssl verify self-ssl.crt

https://www.cyberciti.biz

Mô hình web phổ biến.

 Linux  Comments Off on Mô hình web phổ biến.
Aug 312018
 

Giới thiệu

Khi quyết định xem nên sử dụng kiến trúc server nào cho ứng dụng Web của bạn, có rất nhiều yếu tố cần phải cân nhắc, ví dụ như hiệu năng, khả năng mở rộng, tính khả dụng, độ tin cậy, chi phí và dễ quản lý.

Dưới đây là danh sách một số kiến trúc server được sử dụng phổ biến, với những mô tả ngắn gọn về mỗi loại, bao gồm ưu và nhược điểm của chúng. Hãy nhớ rằng tất cả các khái niệm được đề cập sau đây có thể được sử dụng trong các kết hợp khác nhau, và mỗi môi trường lại đòi hỏi những yêu cầu khác nhau.

1. Tất cả trong một

Toàn bộ môi trường đều nằm hết trên một server duy nhất. Đối với một ứng dụng web thông thường, sẽ bao gồm web server, application server và database server. Một ví dụ của cách thiết lập này đó là LAMP stack, viết tắt của Linux, Apache, MySQL và PHP, đều nằm trên một server duy nhất.

Trường hợp sử dụng: Tốt cho việc thiết lập một ứng dụng nhanh chóng, bởi vì đây là thiết lập đơn giản nhất có thể

Ưu điểm: Đơn giản

Nhược điểm:

  • Ứng dụng và database sử dụng tranh chấp tài nguyên server (CPU, Memory, I/O,…), do đó bên cạnh việc gây ra giảm hiệu năng của hệ thống, nó còn có thể gây khó khăn trong việc xác định thành phần nào gây ra điều đó.
  • Không dễ dàng mở rộng ứng dụng theo chiều ngang

2. Tách riêng Database Server

Cách thiết lập này sẽ tách riêng hệ thống database với những phần còn lại để loại bỏ việc tranh chấp tài nguyên giữa ứng dụng và database, đồng thời tăng tính bảo mật bằng cách giấu database khỏi DMZ hay public internet.

Trường hợp sử dụng: Tốt cho việc thiết lập một ứng dụng nhanh chóng, tuy nhiên có thể loại bỏ được việc tranh chấp cùng tài nguyên hệ thống giữa ứng dụng với database.

Ưu điểm:

  • Các tầng ứng dụng và database không còn tranh chấp cùng tài nguyên hệ thống nữa (CPU, Memory, I/O,…)
  • Bạn có thể mở rộng theo chiều dọc mỗi tầng riêng biệt, bằng cách thêm tài nguyên cho server nào cần (CPU, Memory)
  • Tùy thuộc vào thiết lập của bạn, nó có thể tăng tính bảo mật bằng cách giấu database của bạn khỏi DMZ.

Nhược điểm:

  • Thiết lập phức tạp hơn một chút so với cách chỉ sử dụng một server duy nhất.
  • Có thể phát sinh các vấn đề về hiệu năng nếu kết nối mạng giữa 2 server có độ trễ cao (do khoảng cách địa lý giữa các server) hoặc băng thông quá thấp cho việc truyền tải dữ liệu.

3. Load Balancer (Reverse Proxy)

Load Balancer (LB) được thêm vào hệ thống để tăng performance và uptime (là thời gian đáp ứng của hệ thống đối với người dùng) của hệ thống bằng cách phân tải ra nhiều server. Nếu một server bị lỗi, các server còn lại sẽ phân chia nhau chịu tải cho đến khi server kia hoạt động trở lại. Nó có thể được sử dụng để cung cấp cho nhiều ứng dụng thông qua cùng một domain và port, bằng cách sử dụng một reverse proxy layer 7 ( tầng ứng dụng)

Một số phần mềm cung cấp khả năng phân tải: HAProxy, Nginx và Varnish,…

Trường hợp sử dụng: Kiến trúc này hữu dụng trong những môi trường đòi hỏi khả năng mở rộng bằng cách thêm nhiều servers, hay còn gọi là khả năng mở rộng theo chiều ngang.

Ưu điểm:

  • Cho phép mở rộng hệ thống theo chiều ngang, bằng cách thêm nhiều servers
  • Có thể bảo vệ chống lại những tấn công DDOS bằng cách giới hạn kết nối client với một số lượng và tần số hợp lý.

Nhược điểm:

  • Load balancer có thể gây ra tình trạng “nghẽn cổ chai” nếu server chạy LB không được cung cấp đủ tài nguyên hoặc không được cấu hình tốt.
  • Gặp một số phức tạp cần phải xem xét kĩ lưỡng (đồng bộ session giữa 2 server, … )
  • Load balancer là một "single point of failure", nếu nó sập, toàn bộ service của chúng ta cũng sẽ sập theo. Một thiết lập high availability (HA) là một cấu trúc không phải là “single point of failure”. Để biết rõ hơn về cách thiết lập một HA, bạn có thể đọc thêm ở đây.

4. HTTP Accelerator (Caching Reverse Proxy)

Một HTTP Accelerator, hay caching HTTP reverse proxy, có thể được sử dụng để giảm thời phục vụ của hệ thống đối với người dùng sử dụng một vài kĩ thuật khác nhau. Kĩ thuật chính của phương pháp này là cache lại response từ một web server hoặc application server vào trong memory, và những request trong tương lai với cùng nội dung sẽ được cung cấp một cách nhanh chóng mà không cần tương tác với web server hoặc application server.

Một số phần mềm cung cấp HTTP acceleration: Varnish, Squid, Nginx.

Trường hợp sử dụng: Kiến trúc này hữu dụng trong những hệ thống dynamic web nặng về nội dung hoặc với nhiều tệp được truy cập thường xuyên.

Ưu điểm:

  • Tăng performance bằng cách giảm CPU load trên web server, thông qua caching
  • Có thể đóng vai trò như một reverse proxy Load Balancer
  • MỘt vài phần mềm caching có thể bảo vệ chống lại các tấn công DDOS

Nhược điểm:

  • Cần phải tinh chỉnh để có performance tốt nhất.
  • Nếu tốc độ truy cập vào cache chậm, nó có thể làm giảm hiệu năng

5. Master-Slave Database Replication

MỘt cách để tăng performance của hệ thống database thực hiện nhiều thao tác đọc hơn ghi, ví dụ như các hệ thống CMS, đó là sử dụng kiến trúc Master-Slave Replication. Master-Slave replication yêu cầu một master và một hoặc nhiều slave. Master đóng vai trò ghi dữ liệu còn các Slave đóng vai trò đọc dữ liệu ra. Khi có dữ liệu được ghi trên Master, những dữ liệu này sau đó sẽ được đồng bộ dần lên các Slave. Kiến trúc này giúp chia tải (các thao tác đọc dữ liệu) ra nhiều servers.

Trường hợp sử dụng: Hữu dụng cho các hệ thống mà cần tăng tốc đọc đọc dữ liệu

Ưu điểm:

  • Tăng hiệu năng đọc dữ liệu từ database bằng cách phân tải request ra nhiều server Slave
  • Có thể tăng hiệu năng ghi dữ liệu bằng cách chỉ sử dụng server Master cho việc ghi thôi (Master không cần phải thực hiện các thao tác đọc)

Nhược điểm:

  • Cài đặt kiến trúc này khá phức tạp
  • Cập nhật lên các server Slaves diễn ra bất đồng bộ, do vậy mà nội dung trên đó có thể sẽ chưa được cập nhật mới nhất trong những thời điểm nhất định
  • Nếu Master lỗi, không thể ghi được dữ liệu lên

6. Kết hợp tất cả kiến trúc trên

Chúng ta có thể thêm Load Balancer cho các caching server, ngoài những application servers và sử dụng kiến trúc Master-Slave Replication cho databases. Phương pháp này kết hợp ưu điểm của tất cả những phương pháp trên và hạn chế những vấn đề, sự phức tạp của chúng.

Giả sử rằng Load Balancer sẽ được cấu hình để nhận biết các statis requests (ví dụ như ảnh, css, javascript,…) và gửi những request đó tới các caching servers, và gửi những requests khác tới application servers.

Sau đây là mô tả điều gì sẽ xảy ra khi một user gửi một request dynamic content:

  1. User gửi một request dynamic content tới http://example.com/ (load balancer)
  2. LB gửi request tới app-backend
  3. app-backend đọc dữ liệu từ các Database Slave và trả về dữ liệu cho LB
  4. LB sau đó sẽ trả về dữ liệu cho user

Nếu như user gửi một request static content:

  1. LB kiểm tra trong cache-backend xem nội dung được yêu cầu đã được cache hay chưa.
  2. Nếu đã được cache: trả dữ liệu về cho LB và chuyển tới Bước 7. Nếu chưa được cachecache-backend sẽ chuyển request này cho app-backend, thông qua LB.
  3. LB sẽ chuyển request tới cho app-backend
  4. app-backend đọc dữ liệu từ các Database Slave sau đó trả dữ liệu về cho LB
  5. LB chuyển response cho cache-backend
  6. cache-backend thực hiện cache lại nội dung bên trong response
  7. LB sau đó sẽ trả về dữ liệu cho user

Kết luận

Trên đây tôi đã giới thiệu cho các bạn một số kiến trúc server phổ biến cho các ứng dụng web. Các bạn có thể kết hợp chúng tùy ý để xây dựng cho một kiến trúc server phù hợp nhất cho ứng dụng riêng của bạn nhé.

Network command

 Linux  Comments Off on Network command
Aug 272018
 
  1. Cài đặt công cụ mạng:

yum install net-tools

2. Câu lệnh add route và kiểm tra route

route -n

ip route add 172.16.122.11 via 172.16.216.1 dev eth0

3. Kiểm tra các port đang mở bởi service

lsof -i tcp:22

Firewall on Linux

 Linux  Comments Off on Firewall on Linux
Aug 232018
 

1055 ufw allow 8080
1138 ufw status
1139 ufw allow 3000
1144 ufw allow 4200
1603 ufw –help
1604 ufw enable –help
1605 ufw allow 8090
1606 ufw reload
1737 ufw allow 8686/tcp
1738 ufw reload
1756 ufw allow 5984/tcp
1757 ufw allow reload
1758 ufw allow reloads
1759 ufw reload
2004 ufw allow from x.x.x.x to any port 9527