Try   HackMD

Linux 自動化運維

這是一個關於Linux 自動化運維的筆記簡志融111010501

[第一篇] Linux 作業系統實務
[第二篇] Linux 伺服器架設

摘要

第一週

Linux Kernel 重新編譯

參考 Automatic Operation and Maintenance for Linux System

建議弄一台新的虛擬機操作,比較容易成功

  1. 安裝需要的模組
    ​​​​yum install -y ncurses-devel make gcc bc bison flex elfutils-libelf-devel openssl-devel grub2
    
  2. 下載壓縮檔 & 解壓縮
    ​​​​# wget https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.19.237.tar.xz
    ​​​​# tar xvJf linux-4.19.237.tar.xz
    
  3. 將當前的配置檔複製到新的 CentOS Kernel 配置中 (版本不同可先用 ls /boot 查看)
    ​​​​cp -v /boot/config-3.10.0-957.el7.x86_64 .config
    
  4. 進入資料夾並叫出編譯選單 : cd ~/linux-4.19.237/make menuconfig
    Image Not Showing Possible Reasons
    • The image was uploaded to a note which you don't have access to
    • The note which the image was originally uploaded to has been deleted
    Learn More →

    [*] : 表示將此功能編譯到 kernel 中,但體積會更大
    <M> : 將功能變成模組,在需要時將功能載入 kernel 中
    [ ] : 功能不會載到 kernel 中

  5. 繼續編譯 (# make 之前耗時較長)
    ​​​​# make bzImage
    ​​​​# make modules
    ​​​​# make
    ​​​​# make modules_install
    ​​​​# make install
    ​​​​# grub2-mkconfig -o /boot/grub2/grub.cfg
    
  6. 重啟 : reboot
    image

    image

第二週

二二八連假

第三週

好用的擴充軟體

SSH 進階

一般的 SSH 使用帳號、密碼登入,除非密碼很強,不然其實容易被攻破
SSH CVEs : ssh 漏洞回報

  • Nmap

    1. 安裝 Nmap : yum install nmap -y
    2. 掃描網路 : nmap -sS -P0 -sV 192.168.56.0/24
      掃描結果可看到 IP啟用的協定、埠號
      ​​​​​​​​... ​​​​​​​​Nmap scan report for mycentos7-2 (192.168.56.101) ​​​​​​​​Host is up (0.00074s latency) ​​​​​​​​Not shown: 996 closed ports ​​​​​​​​PORT STATE SERVICE VERSION ​​​​​​​​22/tcp open ssh OpenSSH 7.4 (protocol 2.0) ​​​​​​​​111/tcp open rpcbind 2-4 (RPC #100000) ​​​​​​​​2049/tcp open nfs 3-4 (RPC #100003) ​​​​​​​​6000/tcp open X11 (access denied) ​​​​​​​​MAC Address: 08:00:27:83:89:47 (Cadmus Computer Systems) ​​​​​​​​Service Info: OS: Unix ​​​​​​​​...
  • Hydra (參考資料)

    1. 安裝套件
      ​​​​​​​​yum -y install gcc libssh-devel openssl-devel
      ​​​​​​​​yum install -y unzip zip
      
    2. 抓檔案 : wget https://github.com/vanhauser-thc/thc-hydra/archive/master.zip
    3. 解壓縮 >> 編譯 >> 安裝
      ​​​​​​​​unzip master.zip
      ​​​​​​​​cd thc-hydra-master/
      ​​​​​​​​./configure
      ​​​​​​​​make &&make install
      
    4. 測試 : hydra -l user -p user 192.168.56.101 ssh
  • 關閉密碼登入(只有無密碼可以登入)
    [root@mycentos7-2 ~]# vim /etc/ssh/sshd_config

    image

Linux Driver

參考資料 : 動手寫 Linux Driver

寫核心時,如果程式出錯,會導致嚴重錯誤,所以要非常小心
不要把所有程式寫入核心,會讓核心運行負載太重,因此將程式模組化,需要時再載入核心,不須重新編譯

image

#include <linux/init.h>
#include <linux/module.h>

MODULE_DESCRIPTION("Hello_world");
MODULE_LICENSE("GPL");

static int hello_init(void) {
    printk(KERN_INFO "Hello world !\n");
    return 0;
}

static void hello_exit(void) {
    printk(KERN_INFO "ByeBye !\n");
}

module_init(hello_init); // 初始化
module_exit(hello_exit); // 離開

image

第四週

Linux 三劍客 : grep、sed、awk
sed,stream editor,會一行一行的讀指令

sed

參考資料 : Linux 以 sed 指令搜尋、取代檔案內容教學與範例
Linux 指令 SED 用法教學、取代範例、詳解

  • sed -e 's/word1/word2/g' input
    -e : 結果只在螢幕顯示(檔案內容不變)
    s : substitute,取代
    g : gobal,匹配到的全換

  • sed -e 's/word1/word2/gi' input
    gi : 不分大小寫

  • sed -i 's/word1/word2/gi' input
    -i : 直接改寫檔案內容

  • sed -e 's/word1/word2/2' input
    2 : 匹配到的第2個換(空白預設為1)

  • sed -e '3s/word1/word2/g' input
    3s : 只在第3行執行

  • sed -e '1,3s/word1/word2/g' input
    1,3s : 第1-3行執行

  • sed '1a HelloWorld' input
    第一行之後插入

  • sed -e 's/word1/word2/2' -e 's/bbb/aaa/'input
    兩種條件

  • 很多指令也能用 -i

    image

  • image
    ^# : 以#開頭
    ^$ : 空白行
    /^ [] : 除了

  • image
    #開頭,word1結尾

  • image
    .* : 匹配任意字元
    \U : uper case,大寫
    & : 原本的東西

  • image

SSH 憑證登入

全程在 user 下進行

  • Server端 (192.168.56.101)
    1. 將原本的設定刪除 : rm -rf .ssh
    2. 將資料夾設定回來 : mkdir -p .sshchmod 700 .ssh
      image
    3. Client 的第三步完成後,將憑證放入指定檔案
      cat centos7-1.pub > authorized_keyschmod 600 authorized_keys
  • Client 端 (192.168.56.100)
    1. 將原本的設定刪除 : rm -rf .ssh
    2. 產生憑證 : ssh-keygen -t rsa -b 4096 (路徑預設 Enter,密碼 123456)
    3. 將憑證複製給 Server : scp id_rsa.pub user@192.168.56.101:/home/user/.ssh/centos7-1.pub
    4. Server 的第三步完成後,連線 (密碼如上)
      ssh -i /home/user/.ssh/id_rsa user@192.168.56.101
      image

Putty 憑證登入

  1. 找出下圖程式
    image
  2. 按下Generate,並在空白區域亂動滑鼠產生憑證
    image
  3. 產生完複製金鑰後,按下Sava private key儲存檔案
    image
  4. 在虛擬機 Server 開啟authorized_keys,貼上剛剛複製的金鑰
    image
  5. 在 Putty 的 Auth 放入儲存的檔案,並連線
    image
    image
  • 連線成功
    image

WebDAV

WebDAV,Web-based Distributed Authoring and Versioning
將伺服器變成網路磁碟空間,參考資料 : 2/22 W3Linux將WebDAV為本地磁盤

Windows

  1. 確認需要的套件都有安裝(下列三個都要有) : httpd -M | grep dav
    image
  2. 新增網路空間資料夾
    mkdir /var/www/html/webdavcd /var/www/html/webdavtouch {a..c}.txt
  3. http設定調整 : vim /etc/httpd/conf.d/webdav.conf
    ​​​​DavLockDB /var/www/html/DavLock
    ​​​​<VirtualHost *:80>
    ​​​​    ServerAdmin webmaster@localhost
    ​​​​    DocumentRoot /var/www/html/webdav/
    ​​​​    ErrorLog /var/log/httpd/error.log
    ​​​​    CustomLog /var/log/httpd/access.log combined
    ​​​​    Alias /webdav /var/www/html/webdav
    ​​​​    <Directory /var/www/html/webdav>
    ​​​​        DAV On
    ​​​​        #AuthType Basic
    ​​​​        #AuthName "webdav"
    ​​​​        #AuthUserFile /etc/httpd/.htpasswd
    ​​​​        #Require valid-user
    ​​​​    </Directory>
    ​​​​</VirtualHost>
    
  4. 將權限給予 apache
    chmod -R 755 /var/www/htmlchown -R apache:apache /var/www/html
  5. 重啟 httpd : systemctl restart httpd
  6. 在檔案總管中的網路右鍵,連線至網路磁碟機,輸入位置並按完成
    image

    image

Linux

  1. 安裝套件 : yum install -y davfs2
  2. mkdir /cloudmount -t davfs http://192.168.56.101 /webdav
    image

第五週

通配符 & 正規表達式

通配符(wildcard)用來匹配檔案名稱
正規表達式(Regular expression)用來匹配內容

通配符

  • ls a?
    image

    匹配一個字元

  • ls a*
    image

    匹配0-n個字元

  • ls a[1-9]
    image

    匹配[]中的任一個字元

  • ls a[[:upper:]][[:upper:]]
    image

    大小寫

  • ls a[^1-9]
    image

    非1-9的

正規表達式

  • image
    -n : 標註行數

  • image
    ^ : 以為開頭

  • image
    $ : 以為結尾

  • image
    ^r. : r 開頭,匹配任一字元
    ^r.. : r 開頭,匹配任二字元
    ^r.* : r 開頭,匹配 0-n 個字元 (* : 重複前面動作)

  • image
    ^ro* : 0-n 個 o 都可以

  • image
    ^r[opt] : ro、rp、rt

  • image
    egrep : 擴充 grep
    "10{1,}" : 10、100、1000、1000,1 後面至少一個 0

  • image

  • image
    ? : 0-1 個
    + : 至少一個 (1-n)

  • image
    | : or

雲端虛擬機

IBM LinuxONE Community Cloud 免費試用申請教程
收不到email,改用Azure做

  1. 複製本地虛擬機公開金鑰
    image
  2. 在 Azure 建立虛擬機器,並加入公鑰
    image
    image
  3. 等建立完成後在本地虛擬機連線 : ssh azureuser@172.171.233.160
    image

    螢幕擷取畫面 2024-04-16 224430

後來用學校的帳號收到信了 :)

  1. 用指令將公鑰複製到虛擬機桌面 : cp .ssh/id_rsa.pub .

  2. 用 Winscp 把檔案複製到 PC 桌面

    image

  3. 在網站上創建虛擬機並加入公鑰

    image
    image

  4. 等待創建完成並連線

    image

grep、sed、awk

Linux文字三劍客超詳細教學-grep、sed、awk
【CHT智能稅務案】教學筆記 03:awk 指令介紹

grep

  • image
    -B1 : 找到 AA,前面的兩行

  • image
    -A1 : 找到 AA,之後一行

  • image
    -A1 -B1 : 顯示前後各一行 (等於 -C1)

  • image
    多重匹配

sed

  • image
    /aaa : 找aaa
    /p : 印出來

  • image
    -n : 不再印出全部內容

  • image
    每行第一個 a/b 轉 A/B

  • image
    寫成腳本帶入

  • image
    "1itest" : 第一行 insert test

  • image
    "2cHello" : 第二行 change Hello

awk

  • image

    取1、3、4欄位
    $0 : 代表全部欄位
  • image

    第一欄=user才顯示其1、3欄位
  • image

    更多條件
  • image

    NF : number of field ; 有幾欄
    NR : number of record ; 第幾行

第六週

由上往下讀取,舊的imageread only
新增、修改、刪除等,都會在最上面新增一層,底下相同的內容會被覆蓋
一個 image 可有多個 container

image
image

安裝 Docker

第一千零一篇的 cgroups 介紹

本身沒有的軟體,沒安裝的伺服器或資料庫卻想使用,可抓容器直接使用
並可依本身需求客製化,產生新的鏡像,可快速轉移
Install Docker Engine on CentOS

  1. 測試是否有舊版 Docker : rpm -qa | grep docker
    • 刪除舊版
      ​​​​​​​yum remove docker \
      ​​​​​​​               docker-client \
      ​​​​​​​               docker-client-latest \
      ​​​​​​​               docker-common \
      ​​​​​​​               docker-latest \
      ​​​​​​​               docker-latest-logrotate \
      ​​​​​​​               docker-logrotate \
      ​​​​​​​               docker-engine
      
  2. 安裝 Docker 元件
    ​​​​yum install -y yum-utils
    ​​​​yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
    
  3. 安裝 Docker 引擎
    ​​​​yum install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
    
  4. 啟動 : systemctl start docker
  5. 測試 : docker run hello-world
    螢幕擷取畫面 2024-03-27 095434

Docker 指令

docker hub
Docker commit 命令
操作 Docker 可用 CONTAINER ID(不需全打) 或 Name(需打全名)

  • 列出所有容器資訊 :docker ps -a
  • 列出所有容器 ID : docker pa -a -q
  • 用名稱刪除 : docker rm hello-world
  • 用 ID 刪除鏡像 : docker rmi d2c...
  • 刪除所有未執行的容器 : docker rm 'docker ps -a -q'
  • 強制刪除所有容器 : docker rm -f 'docker ps -a -q'
  • 執行容器 : docker run -it --name=centos1 centos:centos7 /bin/bash
  • 啟用未執行的容器 : docker start 1e7...
  • 離開但可能會關掉 : exit
  • 暫時離開背景執行 : CTRL+P 然後 CTRL+Q
  • 終端機進入容器 : docker exec -it le7... /bin/bash
  • 製造鏡像 : docker commit 1e7 centos:7.1
  • 查看鏡像 : docker images

第七週

清明連假

第八週

Docker httpd

一個Docker做一件事,否則升級擴容會變很大
dockerhub / mysql (期末IOT cloud db)

如果連不上,可先檢查 ifconfig 中 docker0 是否有 IP(172)
沒有可重啟取得 IP 在連線

  1. 抓 httpd docker : docker pull httpd
  2. 到根目錄下,創建要連結的資料夾
    ​​​ # cd /
    ​​​ # mkdir mydata1
    ​​​ # cd mydata1
    ​​​ # echo "Hello World" > hi.htm
    
  3. 回家目錄下,創建 docker,查看
    ​​​ # cd
    ​​​ # docker run -dit --name www1 -p 8080:80 -v /mydata1:/usr/local/apache2/htdocs/ httpd
    ​​​ 
    ​​​ [root@mycentos7-1 ~]# docker ps
    ​​​ CONTAINER ID   IMAGE     COMMAND              CREATED          STATUS          PORTS                                   NAMES
    ​​​ 8b27fee8c57d   httpd     "httpd-foreground"   17 minutes ago   Up 17 minutes   0.0.0.0:8080->80/tcp, :::8080->80/tcp   www1
    
  4. 用 8080 開啟 hi.htm
    image

Dockerfile 建立 image

Docker Dockerfile

  1. 創建資料夾 : cd ~ mkdir testdocker
  2. 新增需要的檔案 (Dockerfile 需一模一樣)
    ​​​​# echo "Hello 2024" > index.html
    ​​​​
    ​​​​# vim Dockerfile
    ​​​​FROM centos:centos7
    ​​​​RUN yum -y install httpd
    ​​​​EXPOSE 80
    ​​​​ADD index.html /var/www/html/
    ​​​​//CMD ["/usr/sbin/apachectl", "-DFOREGROUND"] 加入這行執行指令後面可刪除
    
  3. 建立 image
    ​​​​# docker built -t centos7:web .
    ​​​​
    ​​​​[root@mycentos7-1 testdocker]# docker images
    ​​​​REPOSITORY    TAG       IMAGE ID       CREATED         SIZE
    ​​​​centos7       web       bc9b30b83945   6 minutes ago   482MB
    
  4. 啟動 docker : docker run -d -p 8088:80 centos7:web /usr/sbin/apachectl -DFOREGROUND
    image

    image

用腳本自動新增 docker

  1. 到根目錄下新增資料
    ​​​​# cd /
    ​​​​# mkdir webdata
    ​​​​# cd /webdata
    ​​​​# echo "web data" > index.html
    
  2. 新增腳本 : vim testweb.sh
    ​​​​#!/usr/bin/bash
    
    ​​​​for i in {1..5}
    ​​​​do 
    ​​​​    portno=`expr 8000 + $i`
    ​​​​    docker run -d -p $portno:80 -v /webdata:/var/www/html centos7:web1
    ​​​​done
    
    將腳本設為可執行 : chmod +x testweb.sh
  3. 執行 : ./testweb.sh
    螢幕擷取畫面 2024-04-15 225202

第九週

Grafana : Linux繪圖軟體 (期末可)

Docker Network

Docker Network

用預設的 docker0 橋接網路,docker 間只能用 IP 互聯
如果自己創造的橋接網路,docker 間通訊可以用 IP 或 Name互聯

  • 列出 : docker network ls
  • 內容 : docker network inspect ID
  • 建立橋接網路 : docker network create -d bridge mybr
    image
  • 指定 bridge 網路跑 docker : docker run --name test1 --network mybr busybox /bin/sh
  • 指定 none 網路跑 docker (只有 lo,無其他網路功能) : docker run --name test1 --network none busybox /bin/sh
  • 指定 host 網路跑 docker (與 host 網路配置完全一樣) : docker run --name test1 --network host busybox /bin/sh
  • 指定 container 網路跑 docker (與指定 container 網路配置完全一樣) : docker run --name test1 --network container busybox /bin/sh

Docker Backup-1

  1. docker save hello-world:latest > hello.tar
  2. scp hello.tar user@192.168.56.101:/tmp
  3. docker load < hello.tar
    image

Docker Backup-2

docker tag : 給鏡像別名 ; docker commit : 產生新的鏡像
前綴與用戶名稱一定要一樣

  1. 抓鏡像 : docker pull busybox
  2. 跑 docker : docker run -it --name test1 busybox /bin/sh
  3. 做成新的鏡像 : docker commit test1 ccjung/mybusybox:0.1
  4. 登入 Docker Hub (沒有要註冊) : docker login
  5. 推送本地鏡像到 Docker Hubdocker push ccjung/mybusybox:0.1
    image

負載均衡

一般的應該所有伺服器顯示相同內容,此處為示範而不同

  1. vim createweb.sh
    ​​​​for i in {1..5}
    ​​​​do
    ​​​​  mkdir -p /web$i
    ​​​​  echo $i > /web$i/hi.htm
    ​​​​  portno=`expr 8000 + $i`
    ​​​​  docker run -d -p $portno:80 -v /web$i:/var/www/html centos7:web /usr/sbin/apachectl -DFOREGROUND
    ​​​​done
    
  2. 將腳本設為可執行並執行 : chmod +x ./createweb.sh./createweb.sh
    image
  3. 測試
    image

Haproxy-1

roundrobin : 第一個請求進來,給第一個,以此類推,輪流接受請求

How to Install HAProxy on CentOS (7, 8 or 9)

  1. 在test-docker下創建haproxy
    ​​​​[root@mycentos7-1 test-docker]# vim create-web.sh
    ​​​​[root@mycentos7-1 test-docker]# mkdir haproxy
    ​​​​[root@mycentos7-1 test-docker]# cd haproxy/
    ​​​​[root@mycentos7-1 haproxy]#
    
  2. 編輯設定檔 : vim haproxy.cfg
    ​​​​defaults
    ​​​​  mode http
    ​​​​  timeout client 10s
    ​​​​  timeout connect 5s
    ​​​​  timeout server 10s
    ​​​​  timeout http-request 10s
    
    ​​​​frontend myfrontend
    ​​​​  bind 0.0.0.0:8080
    ​​​​  default_backend myservers
    
    ​​​​backend myservers
    ​​​​  balance roundrobin
    ​​​​  server server1 127.0.0.1:8001
    ​​​​  server server2 127.0.0.1:8002
    ​​​​  server server3 127.0.0.1:8003
    ​​​​  server server4 127.0.0.1:8004
    ​​​​  server server5 127.0.0.1:8005
    
  3. 安裝 haproxy : yum -y install haproxy
  4. 覆寫設定檔並啟動 : cp haproxy.cfg /etc/haproxy/haproxy.cfgsystemctl start haproxy
    image
  5. 測試
    image

Haproxy-2

note/110-2自動化運維/2022_03_16/note.md

一定要寫本機 IP

  1. 在test-docker下創建haproxy
    ​​​​[root@mycentos7-1 test-docker]# vim create-web.sh
    ​​​​[root@mycentos7-1 test-docker]# mkdir haproxy
    ​​​​[root@mycentos7-1 test-docker]# cd haproxy/
    ​​​​[root@mycentos7-1 haproxy]#
    
  2. 編輯設定檔 : vim haproxy.cfg
    ​​​​defaults
    ​​​​  mode http
    ​​​​  timeout client 10s
    ​​​​  timeout connect 5s
    ​​​​  timeout server 10s
    ​​​​  timeout http-request 10s
    
    ​​​​frontend myfrontend
    ​​​​  bind 0.0.0.0:8080
    ​​​​  default_backend myservers
    
    ​​​​backend myservers
    ​​​​  balance roundrobin
    ​​​​  server server1 192.168.56.100:8001
    ​​​​  server server2 192.168.56.100:8002
    ​​​​  server server3 192.168.56.100:8003
    ​​​​  server server4 192.168.56.100:8004
    ​​​​  server server5 192.168.56.100:8005
    
  3. 關 haproxy : systemctl stop haproxy
  4. 跑 docker : docker run -d -p 8080:8080 --name my-running-haproxy -v /root/test-docker/haproxy:/usr/local/etc/haproxy:ro haproxy
  5. 檢視、測試
    image

第十週

Network Namespace

參考 理解Docker容器网络之Linux Network Namespace

新系統會捨棄 ifconfig,可改用 ip addr show 查看

  1. 建兩個 network namespace : ip netns add container_ns1ip netns add container_ns2

    image

  2. 查看配置 : ip netns exec container_ns1 ip addr show
    一開始只有 lo (loopback)

    image

  3. 增加一個橋接器 : brctl addbr mydocker0
    給予IP : ip addr add 172.16.1.254/16 dev mydocker0
    查看 : ip addr show mydocker0

    image
    啟動 : ip link set dev mydocker0 up

  4. 創建 VETH (Virtual Ethernet)
    創建一對相連的網路卡,一張連 mydocker0,一張連 container_ns1
    ip link add veth1 type veth peer name veth1p
    ip link add veth2 type veth peer name veth2p

  5. 將一端連結到 mydocker0
    brctl addif mydocker0 veth1
    brctl addif mydocker0 veth2

    image

  6. 將另一端連結到 container
    ip link set veth1p netns container_ns1
    ip link set veth2p netns container_ns2

    image

  7. 將網卡改名
    ip netns exec container_ns1 ip link set veth1p name eth0
    ip netns exec container_ns2 ip link set veth2p name eth0

    image

  8. 設定 IP 位置
    ip netns exec container_ns1 ip addr add 172.16.1.1/16 dev eth0
    ip netns exec container_ns2 ip addr add 172.16.1.2/16 dev eth0
    ip netns exec container_ns1 ip link set eth0 up
    ip netns exec container_ns2 ip link set eth0 up

    image
    ip netns exec container_ns1 ip route
    ip netns exec container_ns2 ip route
    image

Docker volume

可以做到數據持久化,關掉 docker 仍保有數據
參考 Docker 實戰系列(三):使用 Volume 保存容器內的數據

named volume : 先在 Linux host 'create' volume 再用
hosat volume : 直接對應現有的資料夾

  • 創建 (named volume): docker volume create --name mydata

  • 列出 : docker volume ls

  • 執行對應 (所有docker都共享):
    docker run -it --name test1 -v mydata:/mydata busybox sh
    docker run -it --name test2 -v mydata:/mydata busybox sh

  • 刪除 (docker未使用才能刪): docker volume rm mydata

Docker MySQL using mybr

多台機器一起提供網頁服務

DB 的埠號 3306,如果安裝過 mariadb,可先 stop,不然可能占用埠號

  1. 安裝 MySQL 的 docker
    ​​​​docker run -itd --name mydb -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 --network mybr mysql:5.7.24`
    
  2. 執行 docker : docker exec -it mydb bash
  3. 對 mysql 進行操作 (指令參考 Linux 伺服器架設/LAMP server )
    ​​​​mysql -uroot -p123456                                             #進入mysql
    
    ​​​​create database testdb;                                           #創建資料庫 
    ​​​​use testdb;                                                       #進入使用資料庫
    ​​​​create table addrbook(name varchar(50) not null, phone char(10)); #創建資料表
    
    ​​​​insert into addrbook(name, phone) values ("tom", "0912123456");   #加入資料
    ​​​​insert into addrbook(name, phone) values ("mary", "0912123567");  #加入資料
    
    ​​​​select name,phone from addrbook;                                  #選擇資料
    
    image
  4. 到另一台機器上,於root/testdocker/php-code,新增 test.php
    ​​​​<?php
    ​​​​$servername="mydb";
    ​​​​$username="root";    
    ​​​​$password="123456";
    ​​​​$dbname="testdb";
    
    ​​​​$conn = new mysqli($servername, $username, $password, $dbname);
    
    ​​​​if($conn->connect_error){
    ​​​​    die("connection failed: " . $conn->connect_error);
    ​​​​}
    ​​​​else{
    ​​​​    echo "connect OK!" . "<br>";
    ​​​​}
    
    ​​​​$sql="select name,phone from addrbook";
    ​​​​$result=$conn->query($sql);
    
    ​​​​if($result->num_rows>0){
    ​​​​    while($row=$result->fetch_assoc()){
    ​​​​        echo "name: " . $row["name"] . "\tphone: " . $row["phone"] . "<br>";
    ​​​​    }
    ​​​​} else {
    ​​​​    echo "0 record";
    ​​​​}
    ​​​​?>
    
  5. 啟動 docker
    ​​​​docker run -d -p 8080:80 --name my-apache-php-app --network mybr -v "/root/testdocker/php-code":/var/www/html php:7.2-apache
    
  6. 測試 : 交127.0.0.1:8080/test.php
    會出現這個錯誤 (mysqli : php 及 mysql版本無法對應)
    image

    改成這這樣可排錯 (radys/php-apache:7.4)
    ​​​​docker run -d -p 8080:80 --name my-apache-php-app --network mybr -v "/root/testdocker/php-code":/var/www/html radys/php-apache:7.4
    
    image

NOT COMPLETE

第十一週

CI/CD

CI/CD (Continuous Delivery/Continuous Deployment) 持續集成/持續部署
參考 Linux_note/109-1 Docker/W7-20201027.md
補充 Use CI/CD to build your application

安裝&訓練模型

  1. 安裝 python2 及 sklearn
    ​​​​yum install python-pip
    ​​​​python -m pip install pip==20.3.4
    ​​​​pip install sklearn==
    
  2. 建立資料夾,寫入程式碼
    ​​​​mkdir iris
    ​​​​cd iris
    ​​​​vim train_model.py
    
    ​​​​# coding: utf-8
    ​​​​import pickle
    ​​​​from sklearn import datasets
    ​​​​from sklearn.model_selection import train_test_split
    ​​​​from sklearn import tree
    
    ​​​​# simple demo for traing and saving model
    ​​​​iris=datasets.load_iris()
    ​​​​x=iris.data
    ​​​​y=iris.target
    
    ​​​​#labels for iris dataset
    ​​​​labels ={
    ​​​​  0: "setosa",
    ​​​​  1: "versicolor",
    ​​​​  2: "virginica"
    ​​​​}
    
    ​​​​x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=.25)
    ​​​​classifier=tree.DecisionTreeClassifier()
    ​​​​classifier.fit(x_train,y_train)
    ​​​​predictions=classifier.predict(x_test)
    
    ​​​​#export the model
    ​​​​model_name = 'model.pkl'
    ​​​​print("finished training and dump the model as {0}".format(model_name))
    ​​​​pickle.dump(classifier, open(model_name,'wb'))
    
  3. 執行程式 : python train_model.py
    image

Flask 執行

Flask 埠號 5000

  1. 安裝 flask : pip install flask
  2. 新增 server 程式
    vim server.py
    ​​​​# coding: utf-8
    ​​​​import pickle
    
    ​​​​from flask import Flask, request, jsonify
    
    ​​​​app = Flask(__name__)
    
    ​​​​# Load the model
    ​​​​model = pickle.load(open('model.pkl', 'rb'))
    ​​​​labels = {
    ​​​​  0: "versicolor",   
    ​​​​  1: "setosa",
    ​​​​  2: "virginica"
    ​​​​}
    
    ​​​​@app.route('/api', methods=['POST'])
    ​​​​def predict():
    ​​​​    # Get the data from the POST request.
    ​​​​    data = request.get_json(force = True)
    ​​​​    predict = model.predict(data['feature'])
    ​​​​    return jsonify(predict[0].tolist())
    
    ​​​​if __name__ == '__main__':
    ​​​​    app.run(debug = True, host = '0.0.0.0')
    
  3. 新增 client 程式
    vim client.py
    ​​​​# coding: utf-8
    ​​​​import requests
    ​​​​# Change the value of experience that you want to test
    ​​​​url = 'http://127.0.0.1:5000/api'
    ​​​​feature = [[5.8, 2.0, 4.2, 3.2]]
    ​​​​labels ={
    ​​​​  0: "setosa",
    ​​​​  1: "versicolor",
    ​​​​  2: "virginica"
    ​​​​}
    
    ​​​​r = requests.post(url,json={'feature': feature})
    ​​​​print(labels[r.json()])
    
  4. 開兩台終端機個別執行程式
    image

本地 Docker 執行

  1. 下載 docker : docker pull nitincypher/docker-ubuntu-python-pip
  2. 在同資料夾下新增 dockerfile
    vim Dockerfile
    ​​​​FROM nitincypher/docker-ubuntu-python-pip
    
    ​​​​COPY ./requirements.txt /app/requirements.txt
    
    ​​​​WORKDIR /app
    
    ​​​​RUN pip install -r requirements.txt
    
    ​​​​COPY server.py /app
    
    ​​​​COPY train_model.py /app
    
    ​​​​CMD python /app/train_model.py && python /app/server.py
    
  3. 建立 requirements
    vim requirements.txt
    ​​​​sklearn
    ​​​​flask
    
  4. 建立鏡像 : docker build -t iris:1.0 .
  5. 執行 : docker run -itd --name iris -p 5000:5000 iris:1.0
    螢幕擷取畫面 2024-05-01 100411

雲端 CI/CD

需先註冊 GitLab 帳號

  1. 在兩台虛擬機產生 ssh key : ssh-keygen
    ​​​​[root@mycentos7-2 ~]# ssh-keygen
    ​​​​Generating public/private rsa key pair.
    ​​​​Enter file in which to save the key (/root/.ssh/id_rsa):
    ​​​​/root/.ssh/id_rsa already exists.
    ​​​​Overwrite (y/n)? y
    ​​​​Enter passphrase (empty for no passphrase):
    ​​​​Enter same passphrase again:
    ​​​​Your identification has been saved in /root/.ssh/id_rsa.
    ​​​​Your public key has been saved in /root/.ssh/id_rsa.pub.
    ​​​​The key fingerprint is:
    ​​​​SHA256:Ibpm6MQytgMquelnDAwq4B80EwrY8NkmKGLPLN5dTmc root@mycentos7-2
    ​​​​The key's randomart image is:
    ​​​​+---[RSA 2048]----+
    ​​​​|oo               |
    ​​​​|oo.+             |
    ​​​​|=.= + . .        |
    ​​​​|*.+* . . .       |
    ​​​​|*..++  oSE       |
    ​​​​|==oo..+ o        |
    ​​​​|*+B.=. .         |
    ​​​​|=B.B             |
    ​​​​|=+=              |
    ​​​​+----[SHA256]-----+
    ​​​​[root@mycentos7-2 ~]# cat /root/.ssh/id_rsa.pub
    ​​​​ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDiottYOHkqUxAlewgWosYgazBNLvWD7Uzp...
    
  2. 複製所產生的公鑰,放到gitlab
    image

    image
  3. 新增空白專案,輸入名字即可
    image

    image
  4. 設定虛擬機的git (兩台都要裝 git)
    ​​​​yum install git
    ​​​​git config --global user.name "Jung217"
    ​​​​git config --global user.email alex24922665@gamil.com
    
  5. 將專案透過 git push 回去
    ​​​​[root@mycentos7-1 iris]# git init
    ​​​​Initialized empty Git repository in /root/testdocker/iris/.git/
    ​​​​
    ​​​​[root@mycentos7-1 iris]# git remote add origin https://gitlab.com/jung6135418/iris2024.git
    ​​​​
    ​​​​[root@mycentos7-1 iris]# git add .
    ​​​​[root@mycentos7-1 iris]# git commit -m "Initial Commit"
    ​​​​[master (root-commit) 9777abf] Initial Commit
    ​​​​ 6 files changed, 323 insertions(+)
    ​​​​ create mode 100644 Dockerfile
    ​​​​ create mode 100644 client.py
    ​​​​ create mode 100644 model.pkl
    ​​​​ create mode 100644 requirements.txt
    ​​​​ create mode 100644 server.py
    ​​​​ create mode 100644 train_model.py
    ​​​​ 
    ​​​​[root@mycentos7-1 iris]# git push -uf origin master
    ​​​​Username for 'https://gitlab.com': Jung217
    ​​​​Password for 'https://Jung217@gitlab.com':
    ​​​​Counting objects: 8, done.
    ​​​​Delta compression using up to 2 threads.
    ​​​​Compressing objects: 100% (7/7), done.
    ​​​​...
    ​​​​remote:
    ​​​​To https://gitlab.com/jung6135418/iris2024.git
    ​​​​ * [new branch]      master -> master
    ​​​​Branch master set up to track remote branch master from origin.
    

連結 gitlab-runner

讓第二台機器扮演類似代理人的角色,只要 VM1 上傳檔案,VM2 會自動更新

  1. 在第二台機器建立 gitlab-runner
    ​​​​curl -L --output /usr/local/bin/gitlab-runner https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-linux-amd64
    ​​​​chmod +x /usr/local/bin/gitlab-runner
    ​​​​useradd --comment 'GitLab Runner' --create-home gitlab-runner --shell /bin/bash
    ​​​​usermod -aG docker gitlab-runner
    
    成功可進入
    image
  2. 專案 / Settings / CI/CD / Runners 複製 token
    螢幕擷取畫面 2024-05-01 105702
  3. 註冊 gitlab-runner
    ​​​​[root@mycentos7-2 ~]# gitlab-runner register
    ​​​​Runtime platform                                    arch=amd64 os=linux pid=6471 revision=91a27b2a version=16.11.0
    ​​​​Running in system-mode.
    
    ​​​​Enter the GitLab instance URL (for example, https://gitlab.com/):
    ​​​​https://gitlab.com/                #要連結的網站
    ​​​​Enter the registration token:      
    ​​​​GR1348941W9T39147f1XqLJQ7BzxH      #從 gitlab 取得的 token
    ​​​​Enter a description for the runner:
    ​​​​[mycentos7-2]: mycentos7-2
    ​​​​Enter tags for the runner (comma-separated):
    ​​​​mycentos7-2
    ​​​​Enter optional maintenance note for the runner:
    
    ​​​​WARNING: Support for registration tokens and runner parameters in the 'register' command has been deprecated in GitLab Runner 15.6 and will be replaced with support for authentication tokens. For more information, see https://docs.gitlab.com/ee/ci/runners/new_creation_workflow
    ​​​​Registering runner... succeeded                     runner=GR1348941W9T39147
    ​​​​Enter an executor: parallels, docker, docker-autoscaler, instance, custom, shell, ssh, virtualbox, docker-windows, docker+machine, kubernetes:
    ​​​​shell
    ​​​​Runner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded!
    
    ​​​​Configuration (with the authentication token) was saved in "/etc/gitlab-runner/config.toml"
    
    image
  4. 在第一台機器的 /iris 新增 .gitlab-ci.yml

    在有更新時,另一台自動更新

    ​​​​stages:
    ​​​​  - deploy
    
    ​​​​docker-deploy:
    ​​​​  stage: deploy
    ​​​​  script:
    ​​​​    - docker build -t iris .
    ​​​​    - if [ $(docker ps -aq --filter name=iris) ]; then docker rm -f iris; fi
    ​​​​    - docker run -d -p 5000:5000 --name iris iris
    ​​​​  tags:
    ​​​​    - mycentos7-2
    
  5. 把專案推回去
    ​​​​git add .
    ​​​​git commit -m "Second Commit"
    ​​​​git push -uf origin master
    
  6. 專案 / Build / Pipelines
    image
  7. Passed 之後,將第一台機器的 client.py 的 ip 改成 第二台的ip 執行
    image

    成功

    image

第十二週

nohup

讓程式於背景執行,終端機關閉也不會終止

  1. 寫腳本
    vim test.sh
    ​​​​/!usr/bin/bash
    ​​​​for i in {1..200}
    ​​​​do
    ​​​​  echo $i
    ​​​​  sleep 1
    ​​​​done
    
  2. 加執行 : chomd +x test.sh
  3. 執行 : nohup ./test.sh >log 2>&1 &
  4. 查看 : ps -ef | grep test
    image
  5. 看 log (-f : follow,有新的就印) : tail -f log
    image

Docker-Compose

用於一台機器上,管理多個 docker 間的合作

1 v.s. 1
1 v.s. n
n v.s. n

  • 安裝 docker-compose
    ​​​​curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose && chmod +x /usr/local/bin/docker-compose && docker-compose --version
    

參考 Docker Compose 的基本使用方式

test1

test-docker/test-docker-compose/test1 下進行

  1. 新增設定檔
    vim docker-compose.yml
    ​​​​services:
    ​​​​  app:
    ​​​​    image: hello-world
    
  2. 啟動 : docker-compose up
  3. 查看 : docker-compose ps -a
    image
  4. 關掉 : docker-compose down

test2

test-docker/test-docker-compose/test2 下進行

  1. 新增設定檔
    vim Dockerfile
    ​​​​FROM alpine
    
    ​​​​RUN apk add --no-cache bash
    
    ​​​​CMD bash -c 'for((i=1;;i+=1)); do sleep 1 && echo "Counter: $i"; done'
    
  2. 新增設定檔
    vim docker-compose.yml
    ​​​​services:
    ​​​​  app:
    ​​​​    build:
    ​​​​      context: .
    
  3. 建立映像 : docker-compose build
  4. 查看 : docker images
    image
  5. 啟動(如伺服器在背景執行) : docker-compose up -d
  6. 查看日誌 : docker-compose log
    image
  7. 關掉 : docker-compose down

改變映像預設執行的指令

test-docker/test-docker-compose/test3 下進行

  1. 新增設定檔
    vim docker-compose.yml
    ​​​​services:
    ​​​​  app:
    ​​​​    build:
    ​​​​      context: .
    ​​​​    image: counter
    ​​​​    command: >
    ​​​​      bash -c 'for((i=1;;i+=2)); do sleep 1 && echo "Counter: $$i"; done'
    
  2. 複製 Dockerfile : cp ../test2/Dockerfile .
  3. 啟動(省略 build,程式會自己先 build 再啟動) : docker-compose up -d
  4. 查看日誌(-f : follow) : docker-compose log -f
    image
  5. 關掉 : docker-compose down

暴露連接埠

test-docker/test-docker-compose/test5 下進行
水平擴容 : 相同的機器新增很多台

  1. 新增 .html : echo HelloWorld > index.html
  2. 新增設定檔
    vim Dockerfile
    ​​​​FROM centos:centos7
    ​​​​RUN yum install -y httpd
    ​​​​EXPOSE 80
    ​​​​ADD index.html /var/www/html
    ​​​​CMD ["/usr/sbin/apachectl","-DFOREGROUND"]
    
  3. 新增設定檔
    vim docker-compose.yml
    ​​​​services:
    ​​​​      app:
    ​​​​        build:
    ​​​​          context: .
    ​​​​        ports:
    ​​​​          - "3000-3063:80"
    
  4. 啟動 : docker-compose up -d --scale app=5
    image
  5. 查看 : docker-compose ps
    image
  6. 測試 : curl 127.0.0.1:30XX
    image
  7. 關掉 : docker-compose down

掛載外部檔案系統的目錄

test-docker/test-docker-compose/test5 下進行

  1. 更改設定檔
    vim docker-compose.yml
    ​​​​services:
    ​​​​      app:
    ​​​​        build:
    ​​​​          context: .
    ​​​​        volumes:
    ​​​​          - /mydata:/docker-mydata
    
  2. 啟動 : docker-compose up -d
  3. 進入 docker : docker-compose exec -it app bash
  4. 看掛載的資料夾
    image
  5. 關掉 : docker-compose down

flask & redis

test-docker/test-docker-compose/test6 下進行

  1. 新增 requirements
    vim requirements.txt
    ​​​​flask
    ​​​​redis
    
  2. 新增 Dockerfile
    vim Dockerfile
    ​​​​FROM python
    ​​​​ADD . /code
    ​​​​WORKDIR /code
    ​​​​RUN pip install -r requirements.txt
    ​​​​CMD ["python", "app.py"]
    
  3. 新增設定檔
    vim docker-compose.yml
    ​​​​services:
    ​​​​ web:
    ​​​​    build: .
    ​​​​    ports:
    ​​​​    - "5000:5000"
    ​​​​    volumes:
    ​​​​    - .:/code
    ​​​​    depends_on:
    ​​​​      - redis
    ​​​​ redis:
    ​​​​     image: "redis:alpine"
    
  4. 新增 app
    vim app.py
    ​​​​import time
    ​​​​import redis
    ​​​​from flask import Flask
    
    ​​​​app = Flask(__name__)
    ​​​​cache = redis.Redis(host='redis', port=6379)
    
    ​​​​def get_hit_count():
    ​​​​    retries = 5
    ​​​​    while True:
    ​​​​        try:
    ​​​​            return cache.incr('hits')
    ​​​​        except redis.exceptions.ConnectionError as exc:
    ​​​​            if retries == 0:
    ​​​​                raise exc
    ​​​​            retries -= 1
    ​​​​            time.sleep(0.5)
    
    ​​​​@app.route('/')
    ​​​​def get_index():
    ​​​​    count = get_hit_count()
    ​​​​    return 'Yo! You have browsed {} times\n'.format(count)
    
    ​​​​if __name__ == "__main__":
    ​​​​    app.run(host="0.0.0.0", debug=True)
    
  5. 啟動 : docker-compose up -d
  6. 查看 : docker-compose ps
    image
  7. 測試 : curl 127.0.0.1:5000
    image

補充利用 Dockfile、Docker Compose 建立 LAMP 環境 (PHP、Apache、MySQL)

第十三週

Jump server,管理帳號密碼、權限,稽核使用者動作

1Panel

1panel.cn

  1. 安裝
    ​​​​curl -sSL https://resource.fit2cloud.com/1panel/package/quick_start.sh -o quick_start.sh && sh quick_start.sh
    
  2. 記住
    image
    ​​​​[root@mycentos7-1 ~]# 1pctl user-info
    ​​​​面板地址: http://$LOCAL_IP:28186/9406c6ff7e
    ​​​​面板用户:  839c6ec405
    ​​​​面板密码:  5206264181
    ​​​​提示:修改密码可执行命令:1pctl update password
    
  3. 使用上面帳密連線 : http://192.168.56.109:28186/9406c6ff7e
    image

Docker Swarm

參考 2022/11/08 week10
遷移服務,讓機器出錯時也能服務

  1. 讓第一台機器成為 manager : docker swarm init --advertise-addr 192.168.56.109
    image
  2. 第二、三台使用反白處加入 swarm as worker
    image

    image
  3. 在 manager 輸入指令,使用視覺化頁面(非必要)
    ​​​​docker service create --name=viz --publish=8080:8080/tcp --constraint=node.role==manager --mount=type=bind,src=/var/run/docker.sock,dst=/var/run/docker.sock dockersamples/visualizer
    
    image
  • SHUTDOWN 一台
    image

指令

多在 manager 下操作

  • 列出 swarm 裡的節點 : docker node ls
  • 創建一個服務叫 myweb 使用 httpd 鏡像 : docker service create --name myweb httpd
  • 查看所有服務 : docker service ls
  • 擴縮容,增減副本數 : docker service scale myweb=3
  • 讓節點放掉所有工作 : docker node update --availability drain centos7-1c1
  • 讓節點能接受新工作 : docker node update --availability active centos7-1c1
  • 移除服務 : docker service rm myweb
  • 讓服務跟外部連接 : docker service update --publish-add 8081:80 myweb
    image

Rolling Updates

參考 docker.doc / Apply rolling updates to a service

  1. 抓鏡像 : docker pull redis:7.0
  2. 創建服務 : docker service create --replicas 3 --name redis redis:7.0
    image

    image
  3. 更新服務的鏡像版本 : docker service update --image redis:7.2 redis
    image

第十四週

串接 ChatGPT

LLM (Large Language Model) : 大型語言模型
使用嵌入的資料(客製、隱私的資料),達成 AI 在地化

專案 : github/n4ze3m/dialoqbase

補充 github/eosphoros-ai/DB-GPT,專注於資料庫,用自然語言查詢資料庫

  1. 登入網站 : OpenAI Platform
  2. Create API keys
    image
  • 如果API不能用,要新增付款資訊(先儲值5美元,自動儲值關閉)
    image
  1. 在虛擬機下載專案 : git clone https://github.com/n4ze3m/dialoqbase.git
  2. 進入資料夾 : cd dialoqbase/docker
  3. 編輯環境變數新增 API key : vim .env
    image
  4. 啟動 : docker-compose up -d
  5. 查看 : docker-compose ps
    image
  6. 用 IP 網址登入 (admin/admin) : 192.168.56.101:3000
    image
  7. 新增聊天機器人&資料
    image
  8. 問問題
    image
  9. 在 Telegram 的 BotFather 新增一個聊天機器人
    image
  10. 將得到的 token 貼在下方
    image
  11. 問機器人問題
    image

Docker Swarm with DB

參考 : 建立 NFS Server所有機器都先安裝 NFS

第一台 (Manager)

  1. cd /
  2. mkdir /mydbmkdir /myphp
  3. vim /etc/exports
    ​​​​/mydb 192.168.56.0/24(rw,sync,no_root_squash,no_all_squash)
    ​​​​/myphp 192.168.56.0/24(rw,sync,no_root_squash,no_all_squash)
    
    image

第二台 (Worker1) & 第三台 (Worker2)

  1. cd /
  2. mkdir /mydbmkdir /myphp
  3. mount -t nfs 192.168.56.109:/mydb /mydbmount -t nfs 192.168.56.109:/myphp /myphp

Manager

docker network create -d overlay mynet

image
image

mydb 運行的機器

參考 LAMP server : SQL commands & test.php

  1. 查看網路 : docker network ls
    image
  2. 執行 docker : docker exec -it bb1 bash
    image
  3. 進入資料庫(passwd:123456) : mysql -uroot -p,創建 DB
    ​​​​create database testdb;          #創建資料庫 
    ​​​​use testdb;                      #進入使用資料庫
    ​​​​create table addrbook(name varchar(50) not null, phone char(10)); #創建資料表
    
    ​​​​insert into addrbook(name, phone) values ("tom", "0912123456");  #加入資料
    ​​​​insert into addrbook(name, phone) values ("mary", "0912123567"); #加入資料
    ​​​​
    ​​​​show databases;                  #顯示目前有的資料庫
    
  4. 建立網頁 : cd /myphpvim test.php
    ​​​​<?php
    ​​​​$servername="mydb";
    ​​​​$username="root";    
    ​​​​$password="123456";
    ​​​​$dbname="testdb";
    
    ​​​​$conn = new mysqli($servername, $username, $password, $dbname);
    
    ​​​​if($conn->connect_error){
    ​​​​    die("connection failed: " . $conn->connect_error);
    ​​​​}
    ​​​​else{
    ​​​​    echo "connect OK!" . "<br>";
    ​​​​}
    
    ​​​​$sql="select name,phone from addrbook";
    ​​​​$result=$conn->query($sql);
    
    ​​​​if($result->num_rows>0){
    ​​​​    while($row=$result->fetch_assoc()){
    ​​​​        echo "name: " . $row["name"] . "\tphone: " . $row["phone"] . "<br>";
    ​​​​    }
    ​​​​} else {
    ​​​​    echo "0 record";
    ​​​​}
    ​​​​?>
    
  5. 查看網頁 : curl 192.168.56.109:8888/test.php
    image

    image

第十五週

OpenAI : ChatGPT
Google : Gemini
Meta : Llama 3
AWS : Anthropic (Claude)

HuggingFace : 人工智慧的開源社群
THUDM/chatglm3-6b

Git LFS (Large File Storage)

Ansible

底層透過 SSH 操作其他機器

  • 簡單指令 : ansible server1 -m command -a ifconfig
  • 複雜指令 : ansible server1 -m shell -a "ifconfig > ifg.txt"
  1. 在第一台虛擬機 (主控) 產生 SSH 金鑰 : ssh-keygen
  2. 讓另外兩台虛擬機 (被控端) 可以無密碼登入 : ssh-copy-id root@192.168.56.110ssh-copy-id root@192.168.56.111
    image
  3. 修改檔案 : vim /etc/hosts
    ​​​​192.168.56.110 centos7-1c2 centos7-1c2.test.com
    ​​​​192.168.56.111 centos7-1c3 centos7-1c3.test.com
    
  4. 設定名稱登入
    ​​​​scp /etc/hosts root@centos7-1c2:/etc/hosts
    ​​​​scp /etc/hosts root@centos7-1c3:/etc/hosts
    
  5. 在第一台安裝 Ansible (被控端不用) : yum install ansible
  6. 編輯檔案 : vim /etc/ansible/hosts
    ​​​​[server1]
    ​​​​192.168.56.110  # centos7-1c2
    ​​​​[server2]
    ​​​​192.168.56.111  # centos7-1c3
    
    ​​​​[allservers]
    ​​​​centos7-1c2
    ​​​​centos7-1c3
    
  7. ping
    ​​​​ansible server1 -m ping
    ​​​​ansible server -m ping
    ​​​​ansible allservers -m ping
    
    image

Playbook

@/root/test-ansible/test1

  1. vim test1.yml
    ​​​​---
    ​​​​- hosts: server1
    ​​​​  tasks:
    ​​​​    - name: test ping
    ​​​​      ping:
    
  2. ansible-playbook test1.yml
    螢幕擷取畫面 2024-05-29 104623

@/root/test-ansible/test2

  1. vim test2.yml
    ​​​​---
    ​​​​- hosts: server1
    ​​​​  gather_facts: no
    ​​​​  tasks:
    ​​​​    - name: create an empty file under /tmp
    ​​​​      command:
    ​​​​        chdir: /tmp
    ​​​​        cmd: touch a.txt
    ​​​​    - name: list all files under /tmp and grep a
    ​​​​      shell:
    ​​​​        chdir: /tmp
    ​​​​        cmd: "ls -l | grep a.txt"
    ​​​​      register: results
    ​​​​    - name: show the results
    ​​​​      debug:
    ​​​​        msg: "{{ results['stdout'] }}"
    
  2. ansible-playbook test2.yml
    image

第十六週

Ansible with Ubuntu

安裝 ubuntu

Ubuntu

  1. 安裝 SSH : apt install openssh-server
  2. 更改設定讓 root 無密碼登入 : vim /etc/ssh/sshd_config
    ​​​​PermitRootLogin yes  # 加在檔案最後就可以
    
  3. 重啟 : systemctl restart ssh

Ansible Master

  1. 讓 ubuntu 可以無密碼登入 : ssh-copy-id root@192.168.56.112
  2. 修改檔案 : vim /etc/hosts
    ​​​​...
    ​​​​192.168.56.112 ubuntu22 ubuntu22.test.com
    
  3. 設定名稱登入 : scp /etc/hosts root@cubuntu22:/etc/hosts
  4. 編輯檔案 : vim /etc/ansible/hosts
    ​​​​[server1]
    ​​​​192.168.56.110  # centos7-1c2
    ​​​​[server2]
    ​​​​192.168.56.111  # centos7-1c3
    ​​​​[server3]
    ​​​​192.168.56.112  # ubuntu22
    
    ​​​​[allservers]
    ​​​​centos7-1c2
    ​​​​centos7-1c3
    ​​​​ubuntu22
    
  5. ping : ansible allservers -m ping
    image

Hostname

  1. 編輯 Shell Script 檔 : vim a.sh
    ​​​​hostname
    
    • 加上執行權限 : chmod +x a.sh
  2. ansible all -m script -a "./a.sh"
    image

Ansible 進階

Dynamic Parameter

@root/test-ansible/test3

  1. 新增 hi.j2 : vim hi.j2
    ​​​​Hello "{{ dynamic_world }}"
    
  2. vim test3.yml
    ​​​​---
    ​​​​- hosts: server1
    ​​​​  gather_facts: no
    ​​​​  vars:
    ​​​​    dynamic_world: "World"
    ​​​​  tasks:
    ​​​​    - name: test template
    ​​​​      template:
    ​​​​        src: hi.j2
    ​​​​        dest: /tmp/hello_world.txt
    
  3. ansible-playbook test3.ymlansible server1 -m command -a "cat /tmp/hello_world.txt"
    image

Install Software

@root/test-ansible/test4

  1. vim test4.yml
    ​​​​---
    ​​​​- hosts: www
    ​​​​  gather_facts: yes
    ​​​​  tasks:
    ​​​​    - name: test ping
    ​​​​      ping:
    ​​​​    - name: install software packages in Centos
    ​​​​      yum:
    ​​​​        name:
    ​​​​          - vim
    ​​​​          - curl
    ​​​​        state: present
    ​​​​      when: ansible_facts['distribution'] == "CentOS"
    
  2. ansible-playbook test4.yml
    image

Httpd

centos >>> httpd
ubuntu >>> apache2

跳錯誤可能是 port 占用,可以留意一下

@root/test-ansible/test5

  1. 新增網頁 : echo "Hi there" > hi.htm
  2. 新增設定檔 : cp /etc/httpd/conf/httpd.conf httpd.conf.j2
    ​​​​Listen {{ portnum }}
    
  3. vim test5.yml
    ​​​​---
    ​​​​- hosts: server1
    ​​​​  gather_facts: no
    ​​​​  vars:
    ​​​​    portnum: 9999
    ​​​​  tasks:
    ​​​​    - name: install httpd
    ​​​​      yum:
    ​​​​        name:
    ​​​​          - httpd
    ​​​​        state: present
    ​​​​    - name: copy configuration file
    ​​​​      template:
    ​​​​        src: httpd.conf.j2
    ​​​​        dest: /etc/httpd/conf/httpd.conf
    ​​​​    - name: copy hi.htm
    ​​​​      copy:
    ​​​​        src: hi.htm
    ​​​​        dest: /var/www/html/hi.htm
    ​​​​    - name: restart httpd service
    ​​​​      service: 
    ​​​​        name: httpd
    ​​​​        state: restarted
    
  4. ansible-playbook test5.yml
    image

第十七週

  • 範例一 : 運用 notifyhandlers,配置檔改變時,重啟服務

    • http.conf
      ​​​​​​Listen 8082
      
    • playbook.yml
      ​​​​​​​​- hosts: server1
      ​​​​​​​​  tasks:
      ​​​​​​​​    - name: install httpd server
      ​​​​​​​​      yum: name=httpd state=present
      
      ​​​​​​​​    - name: configure httpd server
      ​​​​​​​​      copy: src=./httpd.conf dest=/etc/httpd/conf/httpd.conf
      ​​​​​​​​      notify: restart httpd server
      
      ​​​​​​​​    - name: start httpd server
      ​​​​​​​​      service: name=httpd state=started enabled=yes
      
      ​​​​​​​​  handlers:
      ​​​​​​​​    - name: restart httpd server
      ​​​​​​​​      service: name=httpd state=restarted
      
      image
  • 範例二 : 變數安裝 app (var in playbook)

    ​​​​- hosts: server1
    ​​​​  vars:
    ​​​​    - app1: httpd
    ​​​​    - app2: vsftpd
    
    ​​​​  tasks:
    ​​​​    - name: install {{ app1 }} and {{ app2 }}
    ​​​​      yum:
    ​​​​        name:
    ​​​​          - "{{ app1 }}"
    ​​​​          - "{{ app2 }}"
    ​​​​        state: present
    

    image

  • 範例三 : 變數安裝 app (從其他檔案引用 var )

    • vars_public.yml
      ​​​​​​​​app1: wget
      ​​​​​​​​app2: gedit
      
    • playbook.yml
      ​​​​​​​​- hosts: server1
      ​​​​​​​​  vars_files: ./vars_public.yml
      
      ​​​​​​​​  tasks:
      ​​​​​​​​    - name: install {{ app1 }} and {{ app2 }}
      ​​​​​​​​      yum:
      ​​​​​​​​        name:
      ​​​​​​​​          - "{{ app1 }}"
      ​​​​​​​​          - "{{ app2 }}"
      ​​​​​​​​        state: present
      
      image
  • 範例四 : 群組變數

    • group_vars
      • server1
        ​​​​​​​​​​app1: httpd
        ​​​​​​​​​​app2: vsftpd
        
    • host_vars
    • playbook.yml
      ​​​​​​​​- hosts: server1
      ​​​​​​​​  tasks:
      ​​​​​​​​    - name: install {{ app1 }} and {{ app2 }}
      ​​​​​​​​      yum:
      ​​​​​​​​        name:
      ​​​​​​​​          - "{{ app1 }}"
      ​​​​​​​​          - "{{ app2 }}"
      ​​​​​​​​        state: present
      
      image
  • 範例五 : 主機變數

    • group_vars
    • host_vars
      • 192.168.56.110
        ​​​​​​​​​​app1: httpd
        ​​​​​​​​​​app2: vsftpd
        
      • 192.168.56.111
        ​​​​​​​​​​app1: wget
        ​​​​​​​​​​app2: curl
        
    • playbook.yml
      ​​​​​​​​- hosts: 192.168.56.110
      ​​​​​​​​  tasks:
      ​​​​​​​​    - name: install {{ app1 }} and {{ app2 }}
      ​​​​​​​​      yum:
      ​​​​​​​​        name:
      ​​​​​​​​          - "{{ app1 }}"
      ​​​​​​​​          - "{{ app2 }}"
      ​​​​​​​​        state: present
      
      ​​​​​​​​- hosts: 192.168.56.111
      ​​​​​​​​  tasks:
      ​​​​​​​​    - name: install {{ app1 }} and {{ app2 }}
      ​​​​​​​​      yum:
      ​​​​​​​​        name:
      ​​​​​​​​          - "{{ app1 }}"
      ​​​​​​​​          - "{{ app2 }}"
      ​​​​​​​​        state: present
      
      image
  • 範例六
    shell: ps aux|grep httpd : 查看行程是否跑起來
    register: check_httpd : 將輸出設成變數,並顯示結果

    • http.conf
      ​​​​​​Listen 8082
      
    • playbook.yml
      ​​​​​​​​- hosts: server1
      ​​​​​​​​  tasks:
      ​​​​​​​​    - name: install httpd server
      ​​​​​​​​      yum: name=httpd state=present
      
      ​​​​​​​​    - name: configure httpd server
      ​​​​​​​​      copy: src=./httpd.conf dest=/etc/httpd/conf/httpd.conf
      ​​​​​​​​      notify: restart httpd server
      
      ​​​​​​​​    - name: start httpd server
      ​​​​​​​​      service: name=httpd state=started enabled=yes
      
      ​​​​​​​​    - name: Check httpd server
      ​​​​​​​​      shell: ps aux|grep httpd
      ​​​​​​​​      register: check_httpd
      
      ​​​​​​​​    - name: output variable
      ​​​​​​​​      debug:
      ​​​​​​​​        msg: "{{ check_httpd.stdout_lines }}"
      
      ​​​​​​​​  handlers:
      ​​​​​​​​    - name: restart httpd server
      ​​​​​​​​      service: name=httpd state=restarted
      
      image
  • 範例七 : jinja2版,使用 template 寫入配置檔

    • http.conf.j2
      ​​​​​​​​ServerAdmin root@{{ ansible_fqdn }}
      
    • playbook.yml
      ​​​​​​​​- hosts: server1
      ​​​​​​​​  tasks:
      ​​​​​​​​    - name: install httpd server
      ​​​​​​​​      yum: name=httpd state=present
      
      ​​​​​​​​    - name: configure httpd server
      ​​​​​​​​      template: src=./httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf
      ​​​​​​​​      notify: restart httpd server
      
      ​​​​​​​​    - name: start httpd server
      ​​​​​​​​      service: name=httpd state=started enabled=yes
      
      ​​​​​​​​  handlers:
      ​​​​​​​​    - name: restart httpd server
      ​​​​​​​​      service: name=httpd state=restarted
      
      image
  • 範例八 : 建立 memory cache,根據機器本身狀況配置空間大小

    • memcached.j2
      ​​​​​​PORT="11211"
      ​​​​​​USER="memcached"
      ​​​​​​MAXCONN="1024"
      ​​​​​​CACHESIZE="{{ ansible_memtotal_mb //2 }}"
      ​​​​​​OPTIONS=""
      
    • playbook.yml
      ​​​​​​​​- hosts: server1
      ​​​​​​​​  tasks:
      ​​​​​​​​    - name: install memcached server
      ​​​​​​​​      yum: name=memcached state=present
      
      ​​​​​​​​    - name: configure memcached server
      ​​​​​​​​      template: src=./memcached.j2 dest=/etc/sysconfig/memcached
      
      ​​​​​​​​    - name: service memcached server
      ​​​​​​​​      service: name=memcached state=started enabled=yes
      
      ​​​​​​​​    - name: check memcached server
      ​​​​​​​​      shell: ps aux | grep memcached
      ​​​​​​​​      register: check_mem
      
      ​​​​​​​​    - name: debug memcached variables
      ​​​​​​​​      debug:
      ​​​​​​​​        msg: "{{ check_mem.stdout_lines }}"
      
      image

第十八週

報告

期末報告

參考 蘇彥庭-Redis資料庫安裝筆記Python redis 使用介绍Redis常用命令(超详细整理)

介紹

Redis(Remote Dictionary Server)是一個高性能、NoSQL的記憶體鍵值儲存系統,使用 ANSI C 編寫的,適用於大多數POSIX系統,如Linux、MacOS等,主要用於作為資料庫、緩存和消息代理。若有短時間內大量存取的需求,卻又不想如此頻繁的對硬碟讀寫,這種場合可以使用 Redis 資料庫暫存資料,等一段時間後再一齊寫入硬碟裡。

特點

Redis是單線程提供的鍵值存取的主要服務
但其他功能,如:持久化、異步刪除等需要額外線程完成。

  • 優點
    • 數據在記憶體裡,運算速度與記憶體相當
    • 單線程避免了線程切換的時間損失
  • 缺點
    • 使用耗時較長的命令時容易造成阻塞
    • 無法處理複雜關係的查詢

資料結構

  • String 是 Redis 中最基礎的資料型別,透過 binary 形式儲存,且保證不更改資料內容 (binary-safe),因此 String 可儲存任何資料,例如一般字串、數字、檔案等。
  • List 是由多個 String 所組成,List 中成員會依照插入的順序儲存,其提供由頭尾插入、拿出的功能,List 能實作例如任務隊列、優先權隊列等。
  • Hash 非常適合儲存物件型資料,例如'使用者'有姓名、年齡、信箱等。當物件很小時,Hash 會將資料壓縮後儲存,因此單台 Redis 可以儲存數百萬個小物件。
  • Set 是多個 String 以無序的方式所組成,保證內部不會有重複的元素,此外也提供了多個 Set 之間交集、差集、聯集的操作。
  • Sorted Set 是有序的 Set,其順序會依照給定的權重排序,在查找資料時,可使用 二元搜尋,由於搜尋效率高,Sorted Set 可當作一組 Hash 資料的索引,單筆物件的完整資料儲存在 Hash。

一般安裝

  1. 在虛擬機安裝 gcc
    ​​​​yum -y install centos-release-scl
    ​​​​yum -y install devtoolset-9-gcc devtoolset-9-gcc-c++ devtoolset-9-binutils
    
  2. 在當前終端啟用 Devtoolset-9 開發工具集 : scl enable devtoolset-9 bash
  3. 確認 gcc 已安裝 : gcc --version
    螢幕擷取畫面 2024-05-27 222943
  4. 下載 Redis 壓縮檔 : wget https://download.redis.io/releases/redis-6.0.10.tar.gz
  5. 解壓縮 : tar xzf redis-6.0.10.tar.gz
  6. 進入 Redis 安裝資料夾 & 編譯 : cd redis-6.0.10make
    看到下圖文字就代表成功了
    image
  7. 執行 Redis server : src/redis-server
    螢幕擷取畫面 2024-05-27 223930
  8. 開啟另一個終端機執行 client : cd redis-6.0.10src/redis-cli
    image
  9. 啟動 server :src/redis-server --protected-mode no
  10. Host 連線

Docker 安裝

  1. 創建 & 進入資料夾 : mkdir rediscd redis
  2. 抓 Redis 映像檔 : docker pull redis
  3. 啟動 Docker
    ​​​​docker run --name redis-lab -p 6379:6379 -d -v $(pwd)/data:/data --restart unless-stopped redis
    
  4. 查看 : docker ps
    image
  5. Host 連線

Host 連線

  • 在 vs code 寫程式並執行
    ​​​​import redis
    
    ​​​​r = redis.StrictRedis(host='192.168.56.107', port=6379, db=0)
    ​​​​print(r.get('s01'))
    
    image

指令

  • 列出伺服器資訊 : info
    螢幕擷取畫面 2024-05-28 003435
  • 檢查是否與伺服器連接 : ping
    image
  • 關閉連線 & 退出 client : shutdownquit
    螢幕擷取畫面 2024-05-28 004837
  • 選擇 DB (預設有16個 DB(0~15),預設使用的第0個) : select n
    螢幕擷取畫面 2024-05-28 004312
  • 查看目前使用 DB 的 key 的數量 : dbsize
    image
  • 刪除目前 DB 所有資料 : flushdb
    image
  • 刪除所有 DB 所有資料 : flushall
    image
  • 現DB指定key移到別的DB : move key n
    螢幕擷取畫面 2024-05-28 010308
  • 列出所有 keys : keys *
  • 檢查 key 是否存在 : exists key
  • 設定 key 的值set key value
  • key data 的 type : type key
  • 刪除 key : del key
  • 設定 key 的有效期限 : expire key seconds
  • 獲取 key 的有效時長 : ttl key
  • 移除 key 的有效期限 : persist key
  • 當2不存在時,將1改為2 : renamex key1 key2
  • Example 1 : 測試 key 是否存在並刪除
    image
  • Example 2 : 設定有效期限
    螢幕擷取畫面 2024-05-29 000611
  • Example 3 : set 交集、聯集、差集
    image
  • Example 4 : zset 範圍查詢與排列
    螢幕擷取畫面 2024-05-29 004847
  • Example 5 : hash 應用
    螢幕擷取畫面 2024-05-29 001806

附-安裝 Ubuntu

  1. 官網下載映像檔
  2. 新增虛擬機
    image
  3. 設定細節 (名稱、密碼記得改)
    image

    image

    image

    image
    • 跑完就可以使用了
      螢幕擷取畫面 2024-06-05 005109
  • 處理 terminal 無法開啟
    ctrl-alt-F1 ~ F6(任一) 開啟終端介面
    登入使用者,使用 su 變成 root (密碼跟 vboxuser 一樣)
    vim /etc/default/locale
    ​​​​LANG=en_US.UTF-8
    ​​​​LANGUAGE=en_US.UTF-8
    
  • 建議先裝
    ​​​​apt install -y vim
    ​​​​apt install -y net-tools