分類: 維運日誌

Server Set Cookie Cross Domain的雷

Server Set Cookie Cross Domain的雷

繼API的CORS的問題後

現在又遇到了一個set cookie的問題,下面的測試順序是反過來的,最早是遇到無法設定到Browser/Application的Cookie,後來發現可以設定的方式後,改實驗多種Domain的組合…

首先本機測試Host先改成模擬前後端分離站台的部署模式

      response.cookies.set('refreshToken', refreshToken, {
        path: '/',
        maxAge: 60 * 60 * 24 * 7,
      });

      response.cookies.set('domainTokenByMiddleWare', refreshToken, {
        path: '/',
        domain: '.azure-paul.com',
        maxAge: 60 * 60 * 24 * 7,
        secure: true,
      });

set-cookie成功!

接著改換 azure-paul.net

      response.cookies.set('refreshToken', refreshToken, {
        path: '/',
        domain: '.azure-paul.net',   
        maxAge: 60 * 60 * 24 * 7,
      });

      response.cookies.set('domainTokenByMiddleWare', refreshToken, {
        path: '/',
        domain: '.azure-paul.net',
        maxAge: 60 * 60 * 24 * 7,
        secure: true,
      });

一樣可以

透過 client端直接呼叫api server response的set-cookie也work

最後我改成這個domain

     response.cookies.set('refreshToken', refreshToken, {
        path: '/',
        domain: '.azurewebsites.net',   
        maxAge: 60 * 60 * 24 * 7,
      });

      response.cookies.set('domainTokenByMiddleWare', refreshToken, {
        path: '/',
        domain: '.azurewebsites.net',
        maxAge: 60 * 60 * 24 * 7,
        secure: true,
      });

結果無情的被拒絕set-cookie

真的沒有寫進去…驚嘆號上的hint是寫著..”current host url invalid”

這樣看來跟.net or .com沒有關係 ,倒是跟azurewebsites.net的domain被列入了卡控 名單有關係

似乎..這跟我”一開始”在/etc/hosts改成dev.azure.com 一樣,會直接被chrome卡掉

繞了一大圈後…

小結論如下
CORS跟Cookie ,若以不同domain要做到CrossDomain的存取,必須繞路避開大網站的domain
(如上azure-paul.com, azure-paul.net passed)

或是直接以NGINX Proxy建成xxxx.yyyy.com + xxxx.yyyy.com/backend,直接就可以不用遇到這種雷…

若有其他發現或知道真相的人歡迎一起分享指教~~

自行備註:

針對azurewebsites.net的set sub-domain的問題其實有人分享過 ,只是一開始哪會找這個方向XD

https://learn.microsoft.com/en-us/answers/questions/360645/cannot-set-a-subdomain-friendly-cookie

竟然是真的跟這邊的名單有關?(半信半疑)

https://publicsuffix.org/list/public_suffix_list.dat

此文的解法 真的也是綁到名單之外的Domain

透過Azure DataStudio / SSMS查詢效能不佳的SQL語法

透過Azure DataStudio / SSMS查詢效能不佳的SQL語法

這兩天遇到一個情境,一個早上突然所有的請求都卡住,平均回應 時間都要1~2分鐘。當下一時間沒啥方向,往登入那邊查,結果找錯了方向,會這樣想純粹是因為認為那個是一條測試的必經之路。而我們還在開發的資料庫中,最多也才幾百筆,最大 也不到一萬筆,為什麼會突然 這麼慢呢?

後來請 DBA看了一下後,馬上就找到問題了,大至記錄如下:

情境:
假如現在有兩張表
分別為
表 1 Master(Id)
表 2 Detail(Id, MasterId)

當時Master表大概有9xx筆,而Detail表有7千筆左右

select * from Master m
left join Detail d on m.Id = d.MasterId
where m.xxxxxx = xxxxxx

結果這樣不得了,一查發現大概執行個5、6百次 ,總執行時間就超過4小時以上了..
一般來說,PrimaryKey需設是Unique+Index(Cluster)因此只以Id作搜尋條件,效能不會差
但此時,Foreign Key若子表的Column沒有建Index,則對搜尋效能仍無影響,FK只作為 限制功能

補充以上觀點後

再補上SqlServer這次如何查找有問題的效能語法的方法(我是Mac,突然很羨慕ssms完整版功能)
不過我也立馬補上Azure Data Studio的方法,不無小補 一下。

1.Azure Portal對有問題的database進行 “查詢效能深入解析” (Azure Portal上的DB查詢權限要開放)

ex: 透過下列清單,可以查詢到Top5慢的查詢,透過查詢ID,可以再往 展開

註 : 這個畫面出不來的話代表 Azure Portal上對DB的權限不夠,不過至少可以對到查詢 ID,再請DBA或用 SSMS/Azure Data Studio去細追

2.透過SSMS,需要DBA針對db user進行開放

Query Store(查詢存放區)
-> Top Resource Consuming
-> Tracked Queries
-> QueryId

SSMS功能就是強大 ,可以針對 時間/CPU/IO統計

對於我們的查詢 ,在一個時間區間內,Where 條件不一樣 ,可能就QueryId就會不同(Plan Id就會不一樣)
-> ViewQueryTest查詢其問題語法分析 執行計劃

透過 查詢計劃可以看到發生了兩次Scan

3.透過Azure Data Studio,加入dashboard圖表

最後一種,若你是用Mac的環境(M1 Core),沒有辦法安裝SSMS這套工具的話

教學:https://learn.microsoft.com/en-us/azure-data-studio/tutorial-qds-sql-server

設定完重啟,在Database-> Manage就可以看到以下的圖表,也可以對齊上述方法的查詢Id

能看到非常 明顯 的峰點,那就還算是好的情境~(特別是還在 測試區)

針對該圖表 可以往下 看Insight的清單,可以對到1525就是問題查詢的所在

從query_sql_text就可以拿到問題語法,一樣貼到Azure Data Studio的Query窗

就可以Estimated Plan來顯示查詢計劃囉

[資訊安全] 在Mac上用GPG套件將檔案加密(231108 更新)

[資訊安全] 在Mac上用GPG套件將檔案加密(231108 更新)

Gpg是一個數位簽章的檔案加密套件

其原理可以從他的祖先PGP去略知一二

利用了RSA的演算法與各種雜湊演算法對檔案進行處理,但若直接 使用RSA演算法無法對檔案大小的長度(我的照片6xx kb)內容加密,所以RSA主要是用在對檔案進行對稱加密的金鑰進行保護加密。
其原理可以再自行看一下相關連結。

下載 GPG套件

https://sourceforge.net/projects/gpgosx/

https://formulae.brew.sh/formula/gnupg

基本上,若是採用這個協定進行加密,應該會提供pgp檔案,pgp通常為對方可公開的公鑰檔案。匯入我們這端的系統後,就可以讓我們以gpg指定對方公鑰作為收件者進行檔案加密。照上圖,檔案加密的RandomKey就是由對方的公鑰做加密,以確保只有對方解的開。


然而對方應該不會提供自己的私鑰,通常是會用於加簽(後面指令中的參數為–sign),若你用自己的私鑰加簽,就要提供自己的公鑰,對方才能做驗簽,可以透過gpg –list-secret-key檢查自己的系統是否有私鑰,若沒有的話,可以上網申請一組。

ex:透過RSA對私鑰進行簡易密語設定,格式也可以指定,匯入時gpg套件都會幫你封裝好這些細節

這邊我們在mac上實際 用 gpg一樣可以匯入pgp的檔案,所以基本上應該是有向下支援了。

gpg import xxxx.asc或skr (注意,是兩個減號) => 此為私鑰檔案,通常只有一份要管理/備份好,若都沒有的話,可以透過指令/金鑰工具產生。

gpg import yyyy.pgp (注意,是兩個減號) => 此為公鑰檔案,每個訊息交換端都可以散佈公鑰檔提供對方做加密傳給自己,而只有自己的私鑰可以解開。

匯入yyyy.gpg的時候會需要輸入password

匯入後,使用以下指令就可以進行檔案加密

gpg –output “/Users/paul_huang/Desktop/{加密後的檔案}.encrypted” -u “paul(Test)” –pinentry-mode loopback –always-trust -r “收檔案者(收件者)的公鑰ID” –s2k-digest-algo “SHA1” –sign –passphrase “加簽章時使用的私鑰密語” –encrypt “/Users/paul_huang/Desktop/{欲加密的檔案}.xml”

成功加密的話,就會有以下的檔案產生  因為涉及加簽,加簽關係到驗簽,證明發送端是我進行的,因此還需要我的公鑰進行驗簽。

註:  

-u, –local-user 使用者-ID,拿指定使用者 ID 來簽署或解密 , 這一步置關重要,要帶入這個參數,對方 才知道你是用 這個人的私key加簽,對方在驗簽的時候,需要你的公鑰進行驗證簽章 ,代表保證檔案的合法性

-r 可以多組 ,代表這個加密檔案,有在收件者當中的人都可以用他的私鑰解密 

可以透過以下指令進行匯出提供接收端做驗簽

gpg –armor –export {公鑰ID} > PublicKey.pgp ( -a, –armor  會以建立以 ASCII 封裝過的輸出)

公鑰ID可以用gpg –list-keys查詢一下私鑰對應的公鑰是哪個  (因為是公鑰,所以不怕公開)

公私鑰使用上的原理如下

加密者,以RamdonKey進行對稱式加密檔案,接著以 解密端(收件者)的 “公鑰” 將Random Key進行檔案加密,對方可以用自己的私鑰解密randomkey,進行檔案解密。其中加密者會在加密後,再用私鑰進行一次簽章,此簽章只能用加密者的公鑰進行驗簽,此驗證就是確保,是加密 者進行上述加密行為,無其他人篡改過。

Reference

https://blog.miniasp.com/post/2022/05/11/gnupg

https://xeodou.me/how-pgp-works/

[動手做]安裝 GUI Dockers管理器 – Portainer

[動手做]安裝 GUI Dockers管理器 – Portainer

既上一篇

租了3台機器,但是各自沒有使用Docker,接下來會逐漸的將所有核心都開始Docker化

Docker雖然方便,但是經過了不同機器的隔離,要去操作,仍需要ssh的話,也很麻煩

因為GUI Portainer的工具的出現,徹底的簡化了這一層

在此記錄一下相關的配置操作

首先Docker Portainer的安裝 我們安裝在Jenkins的主機上

Jenkins其實本身也可以用Docker安裝,暫時先不討論

Jenkins這台VM我們裝上去Docker

Docker CE的指令就看官網的就好了
https://docs.docker.com/engine/install/ubuntu/

接著建立Portainer的相關容器(只要幾個指令也太無腦了)

docker volume create portainer_data
docker run -d -p 8000:8000 -p 9443:9443 --name portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce:latest

接著是被管理的Docker VM上可以設定Docker Api

sudo nano /lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock -H=tcp://0.0.0.0:4243

systemctl daemon-reload 
sudo service docker restart
注意,重新啟動docker後,有可能會造成container不見,這邊可以再去用 jenkins重建服務

接著要去portainer設定相關環境了,portainer在初次 連結的時候可能會需要你重啟container(註)
設定了超過12碼的帳密後,就可以登入了。

接著我們將 要被遙控的docker server,透過 gui加入環境中(如下面擷圖)

重新看,可以從portainer看到

Reference

https://ithelp.ithome.com.tw/articles/10265048

https://docs.portainer.io/start/install-ce/server/docker/linux

https://docs.portainer.io/start/install-ce/server/docker/linux

https://hackmd.io/@JYU/B1w9NDGnD

[動手做] 將C# Api佈署上 AWS+Github+Jenkins + Docker 的CICD實踐-Jenkins篇

[動手做] 將C# Api佈署上 AWS+Github+Jenkins + Docker 的CICD實踐-Jenkins篇

寫了微軟程式這麼久,雖然都是寫功能比較多,對於DevOps界久聞Jenkins大名,但從未真的使用過Jenkins做過一段完整的CICD流程。出於好奇心,找了一部網路影片,結合C# dotnet core的主題,希望實際 手把手try出如何在aws上做完一個low level的佈署過程 。總不好說自己會用 Azure Pipelin就是有做過 CICD ,終究Azure Pipeline也封裝 簡化了很多東西,做起來已經相對簡單一點了,不過缺點也是彈性不夠大加上指令或任務也不夠透明化。這一版本sonarQube先ignore(主要是 做的時候發現無法啟動,待之後再來補強這段)

這一次的專案範例如下 ,不接 db不接 外部服務,純程式的模擬

github url: https://github.com/pin0513/CICDExample

Program.cs的內容是一個模擬未來五天的天氣預測的Api

using System;
using System.Linq;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.FeatureManagement;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddFeatureManagement();

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}

app.UseHttpsRedirection();

var summaries = new[]
{
“Freezing”, “Bracing”, “Chilly”, “Cool”, “Mild”, “Warm”, “Balmy”, “Hot”, “Sweltering”
};

app.MapGet(“/weatherforecast”, () =>
{
var forecast = Enumerable.Range(1, 5).Select(index => new WeatherForecast()
{
DateTime = DateOnly.FromDateTime((DateTime.Now).AddDays(index)),
Temperature = Random.Shared.Next(-20, 55),
Status = summaries[Random.Shared.Next(summaries.Length)]
}).ToArray();
return forecast;
}).WithName(“GetWetherForecast”)
.WithOpenApi();
app.Run();

public class WeatherForecast
{
public DateOnly DateTime { get; set; }
public int Temperature { get; set; }
public string Status { get; set; }
}

實際跑起來如下 :

接著我們把他Commit與Push到Github

AWS端,我們先創建EC2的VM作為 Jenkins Server

選擇免費方案就好了XD

分別建立3個Instance後如下

我們透過 SSH連線過去,會先發現

paul@IpdeMacBook-Pro aws-cert % ssh -i SSH-KEY-Jenkins.pem ubuntu@18.206.225.245 

Permissions 0644 for 'SSH-KEY-Jenkins.pem' are too open.
It is required that your private key files are NOT accessible by others.
This private key will be ignored.
Load key "SSH-KEY-Jenkins.pem": bad permissions
ubuntu@18.206.225.245: Permission denied (publickey).

爆了以上的錯誤,代表你的權限開太大了,執行前必須先將你的金鑰改成無法公開檢視

重新輸入paul@IpdeMacBook-Pro aws-cert % sudo chmod 440 SSH-KEY-Jenkins.pem 以後,就可以ssh過去了

在Jenkins的Vm上依序執行以下指令

sudo apt update
sudo apt install openjdk-11-jre

https://www.jenkins.io/doc/book/installing/linux/

curl -fsSL https://pkg.jenkins.io/debian/jenkins.io-2023.key | sudo tee \
  /usr/share/keyrings/jenkins-keyring.asc > /dev/null
echo deb [signed-by=/usr/share/keyrings/jenkins-keyring.asc] \
  https://pkg.jenkins.io/debian binary/ | sudo tee \
  /etc/apt/sources.list.d/jenkins.list > /dev/null
sudo apt-get update
sudo apt-get install jenkins

安裝後,接著到EC2端設定 安全性

接著啟動jenkinks

systemctl status jenkins

跑起來後,會如下圖,會有token到時拿來登入用的,此擷圖不是我的主機,僅示意,安全性至上!

新的作業 -> enter automated-pipeline-aws

接著到Github專案去設定 Webhook

http://18.206.225.245:8080/github-webhook/ (這邊注意要加/)

接著到jenkins測試一下,點擊馬上建置

看一下工作目錄,就有包含最早我們commit的方案資訊

接著到github測試一下webhook

Reference: https://www.youtube.com/watch?v=361bfIvXMBI

建置觸發成功!實際看jenkins的工作目錄也有新的檔案了!

SonarQube Vm透過SSH一樣 的方式登入後,去SonarQube官網下載Community版本

ubuntu@ip-172-31-89-20:~$ wget ttps://binaries.sonarsource.com/Distribution/sonarqube/sonarqube-10.1.0.73491.zip

sudo apt install unzip
unzip sonarqube-10.1.0.73491.zip
/home/ubuntu/sonarqube-10.1.0.73491/bin/linux-x86-64
ubuntu@ip-172-31-89-20:~/sonarqube-10.1.0.73491/bin/linux-x86-64$ ./sonar.sh console

上面指令跑不成功可能是java環境沒裝,所以抄上面jenkins的安裝java指令執行一次

實測Java要裝到18版

sudo apt install openjdk-19-jdk-headless

實際跑起來目前

2023.08.06 05:12:07 INFO  app[][o.s.a.SchedulerImpl] Waiting for Elasticsearch to be up and running的問題 (會暫時卡住)

我們先跳過去做佈署到Docker-Server

paul@IpdeMacBook-Pro aws-cert % ssh -i SSH-KEY-Jenkins.pem ubuntu@3.86.234.190

ubuntu@ip-172-31-82-131:~$ sudo hostnamectl set-hostname docker
ubuntu@ip-172-31-82-131:~$ /bin/bash
ubuntu@docker:~$ sudo apt update
sudo apt-get install ca-certificates curl gnupg
sudo install -m 0755 -d /etc/apt/keyrings $ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg –dearmor -o /etc/apt/keyrings/docker.gpg $ sudo chmod a+r /etc/apt/keyrings/docker.gpg

執行
echo \
  "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
  "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

回到jenkins切換 hostname

sudo hostnamectl set-hostname jenkins

ubuntu@jenkins:~$ sudo su jenkins
ubuntu@jenkins:~$ ssh ubuntu@3.86.234.190 (連到Docker Server)

此時會出現
ubuntu@3.86.234.190: Permission denied (publickey).

這時先回到docker的那台 vm,用 sudo su進去root

再編輯nano /etc/ssh/sshd_config 檔案 (注意: 是sshd_config)

把以下幾個設定啟用 ,反註解後存檔

PubkeyAuthentication yes
PasswordAuthentication yes 

重啟sshd : systemctl restart sshd (要在root權限下: sudo su)

同時在 root 權限下 passwd ubuntu這個帳號設定密碼

測試jenkins可否連到docker~

ssh ubuntu@3.86.234.190

若可以連線並驗證密碼通過就會像上圖

回到jenkins的vm透過sudo su jenkins切到jenkins的user透過ssh-keygen產生一個key

接著ssh-copy-id ubuntu@3.86.234.190

經過了上述的行為,我們透過了jenkins這個user去生成了一個ssh的key加到了docker的server

也就是我可以直接在jenkin vm這台透過 jenkins這個user執行ssh不用密碼就可以跟docker互動

接著我們試著透過 jenkins的管理去設定佈署的docker server

管理 Jenkins => 安裝 ssh2easy的plugin(因為影片中用的就是這個)

設定ServerGroupsCenter

組態中我們可以先試著用 remote shell做一個指令看看

馬上儲存來建置看看,實測如下,有確實執行指令

實際上也有帶上來!!

jenkins建置 C#的準備

sudo apt-get install -y dotnet-sdk-7.0
sudo apt-get install -y aspnetcore-runtime-7.0
sudo apt install nuget
sudo apt install zip

我們預計從Jenkins發佈程式後,上傳 zip到docker-server去處理
建立Build Steps

執行 Shell
dotnet publish ${WORKSPACE}\\WeatherWebApplication\\WeatherWebApplication.sln -c Release -o out -r linux-x64 --self-contained

執行 Shell

cd out && zip -qr output.zip .

Remote Shell
touch ${WORKSPACE}\\WeatherWebApplication\\out\\output.zip

最後我們設定一個
建置後動作 Delete workspace when build is done(這個是一個plugin)

上面的建置過程中我曾經發現他會一直出現以下錯誤 
error NETSDK1005: Assets file '/var/lib/jenkins/workspace/automated-pipeline-aws/WeatherWebApplication/WeatherWebApplication/obj/project.assets.json' doesn't have a target for 'net7.0'

後來發現,我雖然裝的是net7的SDK,但是在obj的project.assets.json中有綁到target: net8.0的配置,而且 obj目錄不小心commit了,所以我後續使用上面的delete workspace when is failure做清除後
再重新建置一次,這時改成is Success再清就好了,因為若是失敗的話,就還可以檢查問題
所以jenkins在工作目錄的操作預設是只會做覆蓋。所以錯誤的配置調整後,可能還是會錯誤這點在釐清問題的時候還是要看一下。

####################################
execute command exit status -->0
##########################################################################
[automated-pipeline-aws] $ /bin/sh -xe /tmp/jenkins16435309995668868877.sh
+ cd out
+ date +%F
+ mv output.zip output-2023-08-08.zip
+ date +%F
+ scp /var/lib/jenkins/workspace/automated-pipeline-aws/out/output-2023-08-08.zip ubuntu@3.86.234.190:~/upload
[WS-CLEANUP] Deleting project workspace...
[WS-CLEANUP] Deferred wipeout is used...
[WS-CLEANUP] done
Finished: SUCCESS

終於建置到移轉到docker-server,也看到docker-vm上有我們scp過去的檔案

接著我們嘗試加入一個Remote Shell

這一段主要是希望透過編碼可以做到整理Deploy上去的zip檔案。未來可以做版本備份的概念,但其實期望應該是可以做到日期流水編,這邊先簡單用日期做

在Docker-Server端為了設定權限,加上以下的script

ubuntu@docker:~/upload/app$ sudo usermod -aG docker ubuntu
ubuntu@docker:~/upload/app$ newgrp docker

做到不用sudo 可以執行docker

因為.net core在Docker的相容性已經有目共睹了,所以這邊索性調整Sample Project給的DockerFile

FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM base AS final
WORKDIR /app
COPY *.* .
ENTRYPOINT ["dotnet", "WeatherWebApplication.dll"]

註: 測試Jenkins時,建議都先 在linux主機上驗證,通常 可以跑的指令 在jenkins上不太會出錯。

透過Remote Shell定義Docker Command

經過幾次調整後,終於可以運作了

因為是綁8085 port,所以docker server的安全性設定要開放8085 port

大功告成

我們試試看改程式後,整個運作起來看看正不正常

Enumerable 從1-5筆改成1-10筆

Push後,一路觸發了

哈!馬上建置失敗

因為Docker 的name已經重疊了,無法建立,為了簡單驗證,所以調整一下docker run 的shell,先 停止再 重新run,設定如下(–rm實測無法動態移除存在的container,所以我先改成stop再 rm):

cd ~/upload/app
docker build -t docker-app-image .
docker stop weather-app
docker rm weather-app
docker run -d -p 8085:80 --name=weather-app --rm docker-app-image

最後成功了!!

改成50筆也不是問題

讚啦…

首次手把手建立C# .net core程式透過jenkins模擬 CICD的流程 ,雖然還沒自動呼叫單元測試,但也算是解決了自已長久以來好奇的部分細節。

不過實務上每個細節都還有很多改進空間(廢話),例如cd的部分不太可能像我這邊用 stop的方式 中斷 服務,應該是能透過 Docker Swarm或是K8加入node的方式,也要更提早考慮封裝image的問題。以確保不是在prod環境才進行封裝,而是在stage封裝 後在 其他環境pull下來的image已經是穩定的。

這次的案例雖簡化許多,不過能打通一解我心中長久之謎,在很多細節真的是需要一一擊破,僅作為筆記 記錄此行~~

.Net 8的計量新框架 (Metrics)

.Net 8的計量新框架 (Metrics)

想當年,要做到.Net的監控機制,就是要做到這麼多的事情

可能包含要自己設計Log,考慮如何非同步寫入分庫DB,或是另外獨立呼叫外部服務(ex.Sentry)。

當然外部服務是肯定方便又快速的整合方式,但是就是貴森森,而且還有服務綁架問題(就是用一用 ,你就很難轉移到其他平台上)

曾幾何時,我們以前的公司也有架構team,專門搞了一個整合Grafana, Kibana, ElasticSearch的底層平台過。當然當初要架這些東西還沒容器化前,相信也是有相當的維運成本(現在也是有啦)

不過自從容器化後,這些事情都變的好像更容易指令化,就可以打包好一個獨立的自有服務。

當然 今天看到這篇.Net 8支援 Metrics的功能後,其實真的簡化了很多以往要自已造輪子的工。

有興趣可以看 .Net網紅的Demo

而官方文件也給出了手把手的教學!!

https://learn.microsoft.com/zh-tw/dotnet/core/diagnostics/metrics-collection

GCP平台 VM STARTUP SCRIPT 進行UFW DISABLE 記錄

GCP平台 VM STARTUP SCRIPT 進行UFW DISABLE 記錄

這陣子老婆想要寫網誌 (親子遊日後的心血來潮)

無奈各大平台包含xuite,以前的無名收的收,國外的新平台,又覺得好像不熟悉所以腦筋動到自架平台 ,剛好我有這個wordpress養在那邊

不過,因為想說要有一些公開內容,所以還是專業一點弄一下ssl

SSL申請事小,結果我在try ssh跟firewall簡稱(FW)的時候,為了檢查vm是否有fw

所以apt安裝了ufw,殊不知是惡夢的開始

先前因為常常用 ssh連線,不過這次我索性使用了gcp web SSH連過去,想說,應該是滿無腦的

也確實方便,webssh還整合了上傳下載功能,所以我可以很方便的上傳我將要用的SSL證書跟private key

(但上傳下載也其實就是ssh的指令啦)

結果我一開始裝完ufw後 ,一開始也好好的,繼續去檢查gcloud(不是vm哦)虛擬網路的防火牆

後來一重開VM後,就突然 webssh不進去了…,因為同時在調整gcp ssl的防火牆設定,所以我”以為”

我動了什麼設定造成了這個結果(盲點)

註:這段真的超笨的,一直鑽牛角尖在 外層的fw上,還加了全通的rule也不行..

後來我才知道 ,就是vm我因為裝了ufw,所以自己也有一層防火牆被打開了,所以外殼的就無法進入這個vm

這就有點像在vm中移除了網路界面卡,無法再透過網路的方式連進去了,以往有主機,還可以實體操作

之所以把gcp的設定問題排除主要也是我重新生成了一個新的vm,其實舊的image我也生成過,但生成後,重新掛”新”的獨立網路 還是連不進去,所以我用新的VM加新的網路後,用 我認知的外層 fw設定下,嗯可以,ssh的進去

所以我覺得應該還是在vm自已本身身上,猜想到我曾安裝ufw這一點後,我就試著設定ufw disable的語法到VM的開機指令去…想說碰碰運氣

在 VM的執行個體 編輯視窗..可以找到以下欄位

重啟動vm後 ,果然連進去了..恩 …自己搞自己..結案

註∶其實為了fw去安裝 ufw造成這個風波,在cloud的環境中,若能確認是內網的話(不對外),其實可以依賴google cloud的網路跟防火牆的設定就好(有界面萬歲),vm就分工上可以單純一點處理自己該做的事~就好

從Linux主機 使用SCP +SSH Copy檔案的相關指令

從Linux主機 使用SCP +SSH Copy檔案的相關指令

1.先將產生一個本地的ssh publickey/privatekey

#產生SSH key
ssh-keygen
#類型可以輸入rsa, 稍後就會產生id_rsa
cat id_rsa.pub
#印出id_rsa.pub內容
#複製到文字檔,再上傳到對方主機

#遠端到對方主機
#將公key append到ssh允許清單
cat id_rsa.pub >> .ssh/authorized_keys

2.本地檔案複製到對方主機

#遠端到對方主機

SCP -i ~/.ssh/id_rsa /本地檔案 username@hostname:/遠端檔案

#要注意-i指定的檔案id_rsa是私key,不是id_rsa.pub公key

就可以通了!

定期搬移目錄到指定日期目錄Bat範例

定期搬移目錄到指定日期目錄Bat範例

實驗worked!!

記錄一下

set sourcePath=D:\A
set targetPath=D:\B

for /f "skip=1 delims=" %%x in ('wmic os get localdatetime') do if not defined X set X=%%x
set yyyyMMdd=%X:~0,8%

mkdir D:\B\%yyyyMMdd%

xcopy /F /Q /E /S %sourcePath% %targetPath%\%yyyyMMdd%

del /F /q "D:\A\*.*"
FOR /D %%p IN ("%sourcePath%\*.*") DO rmdir "%%p" /s /q

SQL Server 誤刪資料庫的資料怎麼辦

SQL Server 誤刪資料庫的資料怎麼辦

今天同事忘了下where條件

不小心誤更新了四千多筆的資料表

一時間協助查詢解決方法,畢竟不是dba

操作實務不足,也不敢馬上給指令

深怕把資料庫搞壞,連現行資料都弄不回來

 

事後,經過比較各個blog,MSDN,還有跟同事的討論後,實證驗正過以下做法可行,足以做為SOP

也同時花了點時間理解原理

 

發現原來我認知的誤區就是我以為資料庫靠transaction log就可以rollback回去過去時間點(減法)

但其實關鍵點反而是用加法在還原時間點加回來交易紀錄,見上圖所示,我寫在黑板記錄一下

看參考部落格時還想說為啥要先restore 資料..後來才想通

因此語法真的誤刪(人人似乎都有這個黑歷史)的話,別緊張,Follow以下SOP,應該可以救的回來,前提是資料庫是在完整模式下

 

範例資料:

USE [DBName]
GO
/****** Object:  Table [dbo].[Test]    Script Date: 2020/4/28 上午 08:54:31 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Test](
	[a] [nvarchar](50) NULL,
	[b] [nvarchar](50) NULL
) ON [PRIMARY]
GO
INSERT [dbo].[Test] ([a], [b]) VALUES (N'1', N'2')
GO
INSERT [dbo].[Test] ([a], [b]) VALUES (N'4', N'3')
GO
INSERT [dbo].[Test] ([a], [b]) VALUES (N'5', N'6')
GO
INSERT [dbo].[Test] ([a], [b]) VALUES (N'8', N'7')
GO
INSERT [dbo].[Test] ([a], [b]) VALUES (N'9', N'10')
GO
INSERT [dbo].[Test] ([a], [b]) VALUES (N'11', N'12')
GO

原本的資料

不小心誤刪了或漏下了where條件

 

 

 

 

 

 

這個時候,不要緊張,先找到上一次完整備份的時間點

以我的範例是8:55分

Step 0.網站停機或下線 (注意,千萬不能第一時間又做了一次完整備份)

避免寫入更多資料,複原時會遺失更多資料

Step1.切換單人模式並重新離線上線(確保資料庫是無人連線)

ALTER DATABASE DBName
SET SINGLE_USER
WITH ROLLBACK IMMEDIATE;

 

Step 1.進行完整的交易記錄備份 (ex.9:00分當下)

這時,你的DB應該會是在還原模式下:

 

Step2.還原上一次的資料備份檔案(記得要比欲複原的時間點更早,ex:AM 08:55那一版本的Bak)

注意:還原計畫只能包含資料,不能勾選到剛剛的交易記錄

還原完整備份的bak時,復原狀態要選擇Restore With No Recovery

 

 

Step3.還原交易記錄,並指定還原時間點(ex:8:56分)

 

還原成功後,再進行將資料庫切回多人模式

ALTER DATABASE DBName
SET Multi_User

檢查資料,已經回復了,可喜可賀

 

 

想法有誤的話,歡迎大家回饋指教

 

 

參考blog:

https://kknews.cc/zh-tw/code/q4lj5x8.html

https://blog.miniasp.com/post/2010/04/21/SQL-Server-Full-Differential-Transaction-Backup