分類
發燒車訊

中國湖北化工廠大爆炸 至少5死1傷

摘錄自2020年9月28日自由時報報導

中國湖北省天門市岳口鎮譚湖工業園區內一化工廠,今(28)日下午發生爆炸,現場黃煙亂竄疑似硝酸外洩,當地政府部門指出,目前事故已造成5死1傷。

綜合中媒報導,湖北省應急管理廳指出,天門市應急管理局報告,今日下午2點15分左右,天門市岳口工業園天門楚天精細化工有限公司進行設備調試期間,發生板框壓力機爆炸,初步發現事故現場5人死亡、1人受傷。有目擊者稱現場疑似是硝酸外洩,導致竄出大量黃煙。

天門市應急管理局表示,傷者已送醫救治,現場搜救工作仍在進行中,事故原因及過程仍有待釐清。

污染治理
國際新聞
中國
化工廠
化工廠爆炸

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整

南投搬家公司費用,距離,噸數怎麼算?達人教你簡易估價知識!

※教你寫出一流的銷售文案?

※超省錢租車方案

分類
發燒車訊

紅毛猩猩家園上動土惹議 印尼中資水壩遇武肺將延後三年動工

環境資訊中心綜合外電;黃鈺婷 翻譯;林大利 審校;稿源:Mongabay

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

南投搬家公司費用需注意的眉眉角角,別等搬了再說!

※教你寫出一流的銷售文案?

分類
發燒車訊

人類壓力步步進逼 全球13年間荒野損失面積相當於墨西哥

環境資訊中心綜合外電;姜唯 編譯;林大利 審校

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

※想知道最厲害的網頁設計公司"嚨底家"!

※別再煩惱如何寫文案,掌握八大原則!

※產品缺大量曝光嗎?你需要的是一流包裝設計!

分類
發燒車訊

自己動手實現深度學習框架-8 RNN文本分類和文本生成模型

代碼倉庫: https://github.com/brandonlyg/cute-dl

目標

        上階段cute-dl已經可以構建基礎的RNN模型。但對文本相模型的支持不夠友好, 這個階段的目標是, 讓框架能夠友好地支持文本分類和本文生成任務。具體包括:

  1. 添加嵌入層, 為文本尋找高效的向量表示。
  2. 添加類別抽樣函數, 根據模型輸出的類別分佈抽樣得到生成的文本。
  3. 使用imdb-review數據集驗證文本分類模型。
  4. 使用一個古詩數據集驗證文本生成模型。

        這階段涉及到的代碼比較簡單因此接下來會重點描述RNN語言相關模型中涉及到的數學原理和工程方法。

數學原理

文本分類模型

        可以把文本看成是一個詞的序列\(W=[w_1, w_2, …, w_T]\), 在訓練數據集中每個文本屬於一個類別\(a_i\), \(a_i∈A\), 集合 \(A = \{ a_1, a_2, …, a_k \}\) 是一個類別別集合. 分類模型要做的是給定一個文本W, 計算所有類別的后驗概率:

\[P(a_i|W) = P(a_i|w_1,w_2,…,w_T), \quad i=1,2,…k \]

        那麼文本序列W的類別為:

\[a = arg \max_{a_i} P(a_i|w_1,w_2,…,w_T) \]

        即在給定文本的條件下, 具有最大后驗概率的類別就是文本序列W所屬的類別.

文本預測模型

        設任意一個文本序列為\(W=[w_1,w_2,…,W_T]\), 任意一個詞\(w_i ∈ V\), V是所有詞彙的集合,也叫詞彙表, 這裏需要強調的是\(w_i\)在V中是無序的, 但在W中是有序的, 文本預測的任務是, 計算任意一個詞\(w_i ∈ V\)在給定一個序列中的任意一個位置出現的概率:

\[P(w_1,…,W_T) = ∏_{t=1}^T P(w_t|w_1,…,w_{t-1}) \]

        文本預測輸出一個\(w_i ∈ V\)的分佈列, 根據這個分佈列從V中抽取一個詞即為預測結果。不同於分類任務,這裏不是取概率最大的詞, 這裏的預測結果是某個詞出現的在一個序列特定位置的個概率,只要概率不是0都有可能出現,所以要用抽樣的方法確定某次預測的結果。

詞的数字化表示

        任意一條數據在送入模型之前都要表示為一個数字化的向量, 文本數據也不例外。一個文本可以看成詞的序列,因此只要把詞数字化了,文本自然也就数字化了。對於詞來說,最簡單的方式是用詞在詞彙表中的唯一ID來表示, ID需要遵守兩個最基本的規則:

  1. 每個詞的ID在詞彙表中必須是唯一的.
  2. 每個詞的ID一旦確定不能變化.

        這種表示很難表達詞之間的關係, 例如: 在詞彙表中把”好”的ID指定為100, 如果希望ID能夠反映詞意的關係, 需要把”好”的近意詞: “善”, “美”, “良”, “可以”編碼為98, 99, 101, 102. 目前為止這看起還行. 如果還希望ID能夠反映詞之間的語法關係, “好”前後經常出現的詞: “友”, “人”, “的”, 這幾個詞的ID就很難選擇, 不論怎樣, 都會發現兩個詞它們在語義和語法上的關係都很遠,但ID卻很接近。這也說明了標量的表達能力很有限,無法表達多個維度的關係。為了能夠表達詞之間多個維度的的關係,多維向量是一個很好的選擇. 向量之間的夾大小衡量它們之間的關係:

\[cos(θ) = \frac{<A, B>}{|A||B|} \]

        對於兩個向量A, B使用它們的點積, 模的乘積就能得到夾角θ餘弦值。當cos(θ)->1表示兩個向量的相似度高, cos(θ)->0 表示兩個向量是不相關的, cos(θ)->-1 表示兩個向量是相反的。

        把詞的ID轉換成向量,最簡單的辦法是使用one-hot編碼, 這樣得到的向量有兩個問題:

  1. 任意兩個向量A,B, <A,B>=0, 夾角的餘弦值cos(θ)=0, 不能表達詞之間的關係.
  2. 向量的維度等於詞彙表的大小, 而且是稀疏向量,這和導致模型有大量的參數,模型訓練過程的運算量也很大.

        詞嵌入技術就是為解決詞表示的問題而提出的。詞嵌入把詞ID映射到一個合適維度的向量空間中, 在這個向量空間中為每個ID分配一個唯一的向量, 把這些向量當成參數看待, 在特定任務的模型中學習這些參數。當模型訓練完成后, 這些向量就是詞在這個特定任務中的一個合適的表示。詞嵌入向量的訓練步驟有:

  1. 收集訓練數據集中的詞彙, 構建詞彙表。
  2. 為詞彙表中的每個詞分配一個唯一的ID。假設詞彙表中的詞彙量是N, 詞ID的取值為:0,1,2,…,N-1, 對人任意一個0<ID<N-1, 必然存在ID-1, ID+1.
  3. 隨機初始化N個D維嵌入向量, 向量的索引為0,1,2,…,N-1. 這樣詞ID就成了向量的索引.
  4. 定義一個模型, 把嵌入向量作為模型的輸入層參与訓練.
  5. 訓練模型.

嵌入層實現

        代碼: cutedl/rnn_layers.py, Embedding類.

        初始化嵌入向量, 嵌入向量使用(-1, 1)區間均勻分佈的隨機變量初始化:

'''
dims 嵌入向量維數
vocabulary_size 詞彙表大小
need_train 是否需要訓練嵌入向量
'''
def __init__(self, dims, vocabulary_size, need_train=True):
    #初始化嵌入向量
    initializer = self.weight_initializers['uniform']
    self.__vecs = initializer((vocabulary_size, dims))

    super().__init__()

    self.__params = None
    if need_train:
        self.__params = []
        self.__cur_params = None
        self.__in_batch = None

        初始化層參數時把所有的嵌入向量變成參与訓練的參數:

def init_params(self):
    if self.__params is None:
        return

    voc_size, _ = self.__vecs.shape
    for i in range(voc_size):
        pname = 'weight_%d'%i
        p = LayerParam(self.name, pname, self.__vecs[i])
        self.__params.append(p)

        向前傳播時, 把形狀為(m, t)的數據轉換成(m, t, n)形狀的數據, 其中t是序列長度, n是嵌入向量的維數.

'''
in_batch shape=(m, T)
return shape (m, T, dims)
'''
def forward(self, in_batch, training):
    m,T = in_batch.shape
    outshape = (m, T, self.outshape[-1])
    out = np.zeros(outshape)

    #得到每個序列的嵌入向量表示
    for i in range(m):
        out[i] = self.__vecs[in_batch[i]]

    if training and self.__params is not None:
        self.__in_batch = in_batch

    return out

        反向傳播時只關注當前批次使用到的向量, 注意同一個向量可能被多次使用, 需要累加同一個嵌入向量的梯度.

def backward(self, gradient):
    if self.__params is None:
        return

    #pdb.set_trace()
    in_batch = self.__in_batch
    params = {}
    m, T, _ = gradient.shape
    for i in range(m):
        for t in range(T):
            grad = gradient[i, t]
            idx = self.__in_batch[i, t]

            #更新當前訓練批次的梯度
            if idx not in params:
                #當前批次第一次發現該嵌入向量
                params[idx] = self.__params[idx]
                params[idx].gradient = grad
            else:
                #累加當前批次梯度
                params[idx].gradient += grad

    self.__cur_params = list(params.values())

驗證

imdb-review數據集上的分類模型

        代碼: examples/rnn/text_classify.py.

        數據集下載地址: https://pan.baidu.com/s/13spS_Eac_j0uRvCVi7jaMw 密碼: ou26

數據集處理

        數據集處理時有幾個需要注意的地方:

  1. imdb-review數據集由長度不同的文本構成, 送入模型的數據形狀為(m, t, n), 至少要求一個批次中的數據具有相同的序列長度, 因此在對數據進行分批時, 對數據按批次填充.
  2. 一般使用0為填充編碼. 在構建詞彙表時, 假設有v個詞彙, 詞彙的編碼為1,2,…,v.
  3. 由於對文本進行分詞, 編碼比較耗時。可以把編碼后的數據保存起來,作為數據集的預處理數據, 下次直接加載使用。

模型

def fit_gru():
    print("fit gru")
    model = Model([
                rnn.Embedding(64, vocab_size+1),
                wrapper.Bidirectional(rnn.GRU(64), rnn.GRU(64)),
                nn.Filter(),
                nn.Dense(64),
                nn.Dropout(0.5),
                nn.Dense(1, activation='linear')
            ])
    model.assemble()
    fit('gru', model)

        訓練報告:

這個模型和tensorflow給出的模型略有差別, 少了一個RNN層wrapper.Bidirectional(rnn.GRU(32), rnn.GRU(32)), 這個模型經過16輪的訓練達到了tensorflow模型的水平.

文本生成模型

        我自己收集了一個古由詩詞構成的小型數據集, 用來驗證文本生成模型. 代碼: examples/rnn/text_gen.py.

        數據集下載地址: https://pan.baidu.com/s/14oY_wol0d9hE_9QK45IkzQ 密碼: 5f3c

        模型定義:

def fit_gru():
    vocab_size = vocab.size()
    print("vocab size: ", vocab_size)
    model = Model([
                rnn.Embedding(256, vocab_size),
                rnn.GRU(1024, stateful=True),
                nn.Dense(1024),
                nn.Dropout(0.5),
                nn.Dense(vocab_size, activation='linear')
            ])

    model.assemble()
    fit("gru", model)

        訓練報告:

        生成七言詩:

def gen_text():
    mpath = model_path+"gru"

    model = Model.load(mpath)
    print("loadding model finished")
    outshape = (4, 7)

    print("vocab size: ", vocab.size())

    def do_gen(txt):
        #編碼
        #pdb.set_trace()
        res = vocab.encode(sentence=txt)

        m, n = outshape

        for i in range(m*n - 1):
            in_batch = np.array(res).reshape((1, -1))
            preds = model.predict(in_batch)
            #取最後一維的預測結果
            preds = preds[:, -1]
            outs = dlmath.categories_sample(preds, 1)
            res.append(outs[0,0])

        #pdb.set_trace()
        txt = ""
        for i in range(m):
            txt = txt + ''.join(vocab.decode(res[i*n:(i+1)*n])) + "\n"

        return txt


    starts = ['雲', '故', '畫', '花']
    for txt in starts:
        model.reset()
        res = do_gen(txt)
        print(res)

        生成的文本:

雲填纜首月悠覺
纜濯醉二隱隱白
湖杖雨遮雙雨鄉
焉秣都滄楓寓功

故民民時都人把
陳雨積存手菜破
好纜簾二龍藕卻
趣晚城矣中村桐

畫和春覺上蓋騎
滿楚事勝便京兵
肯霆唇恨朔上楊
志月隨肯八焜著

花夜維他客陳月
客到夜狗和悲布
關欲摻似瓦闊靈
山商過牆灘幽惘

        是不是很像李商隱的風格?

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※帶您來了解什麼是 USB CONNECTOR  ?

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※教你寫出一流的銷售文案?

分類
發燒車訊

Openshift 4.4 靜態 IP 離線安裝系列:初始安裝

上篇文章準備了離線安裝 OCP 所需要的離線資源,包括安裝鏡像、所有樣例 Image StreamOperatorHub 中的所有 RedHat Operators。本文就開始正式安裝 OCP(Openshift Container Platform) 集群,包括 DNS 解析、負載均衡配置、ignition 配置文件生成和集群部署。

OCP 安裝期間需要用到多個文件:安裝配置文件、Kubernetes 部署清單、Ignition 配置文件(包含了 machine types)。安裝配置文件將被轉換為 Kubernetes 部署清單,然後將清單包裝到 Ignition 配置文件中。 安裝程序使用這些 Ignition 配置文件來創建 Openshift 集群。運行安裝程序時,所有原始安裝配置文件都會修改,因此在安裝之前應該先備份文件。

1. 安裝過程

在安裝 OCP 時,我們需要有一台引導主機(Bootstrap)。這個主機可以訪問所有的 OCP 節點。引導主機啟動一個臨時控制平面,它啟動 OCP 集群的其餘部分然後被銷毀。引導主機使用 Ignition 配置文件進行集群安裝引導,該文件描述了如何創建 OCP 集群。安裝程序生成的 Ignition 配置文件包含 24 小時後過期的證書,所以必須在證書過期之前完成集群安裝。

引導集群安裝包括如下步驟:

  • 引導主機啟動並開始託管 Master 節點啟動所需的資源。
  • Master 節點從引導主機遠程獲取資源並完成引導。
  • Master 節點通過引導主機構建 Etcd 集群。
  • 引導主機使用新的 Etcd 集群啟動臨時 Kubernetes 控制平面。
  • 臨時控制平面在 Master 節點啟動生成控制平面。
  • 臨時控制平面關閉並將控制權傳遞給生產控制平面。
  • 引導主機將 OCP 組件注入生成控制平面。
  • 安裝程序關閉引導主機。

引導安裝過程完成以後,OCP 集群部署完畢。然後集群開始下載並配置日常操作所需的其餘組件,包括創建計算節點、通過 Operator 安裝其他服務等。

2. 準備服務器資源

服務器規劃如下:

  • 三個控制平面節點,安裝 Etcd、控制平面組件和 Infras 基礎組件。
  • 兩個計算節點,運行實際負載。
  • 一個引導主機,執行安裝任務,集群部署完成后可刪除。
  • 一個基礎節點,用於準備上節提到的離線資源,同時用來部署 DNS 和負載均衡。
  • 一個鏡像節點,用來部署私有鏡像倉庫 Quay
主機類型 操作系統 Hostname vCPU 內存 存儲 IP FQDN
鏡像節點 RHEL 7.6 registry 4 8GB 150GB 192.168.57.70 registry.openshift4.example.com
基礎節點 RHEL 7.6 bastion 4 16GB 120GB 192.168.57.60 bastion.openshift4.example.com
引導主機 RHCOS bootstrap 4 16GB 120GB 192.168.57.61 bootstrap.openshift4.example.com
控制平面 RHCOS master1 4 16GB 120GB 192.168.57.62 master1.openshift4.example.com
控制平面 RHCOS master2 4 16GB 120GB 192.168.57.63 master2.openshift4.example.com
控制平面 RHCOS master3 4 16GB 120GB 192.168.57.64 master3.openshift4.example.com
計算節點 RHCOS 或 RHEL 7.6 worker1 2 8GB 120GB 192.168.57.65 worker1.openshift4.example.com
計算節點 RHCOS 或 RHEL 7.6 worker2 2 8GB 120GB 192.168.57.66 worke2.openshift4.example.com

3. 防火牆配置

接下來看一下每個節點的端口號分配。

所有節點(計算節點和控制平面)之間需要開放的端口:

協議 端口 作用
ICMP N/A 測試網絡連通性
TCP 9000-9999 節點的服務端口,包括 node exporter 使用的 9100-9101 端口和 Cluster Version Operator 使用的 9099 端口
1025010259 Kubernetes 預留的默認端口
10256 openshift-sdn
UDP 4789 VXLAN 協議或 GENEVE 協議的通信端口
6081 VXLAN 協議或 GENEVE 協議的通信端口
90009999 節點的服務端口,包括 node exporter 使用的 9100-9101 端口
3000032767 Kubernetes NodePort

控制平面需要向其他節點開放的端口:

協議 端口 作用
TCP 23792380 Etcd 服務端口
6443 Kubernetes API

除此之外,還要配置兩個四層負載均衡器,一個用來暴露集群 API,一個用來暴露 Ingress:

端口 作用 內部 外部 描述
6443 引導主機和控制平面使用。在引導主機初始化集群控制平面后,需從負載均衡器中手動刪除引導主機 x x Kubernetes API server
22623 引導主機和控制平面使用。在引導主機初始化集群控制平面后,需從負載均衡器中手動刪除引導主機 x Machine Config server
443 Ingress Controller 或 Router 使用 x x HTTPS 流量
80 Ingress Controller 或 Router 使用 x x HTTP 流量

4. 配置 DNS

按照官方文檔,使用 UPI 基礎架構的 OCP 集群需要以下的 DNS 記錄。在每條記錄中,<cluster_name> 是集群名稱,<base_domain> 是在 install-config.yaml 文件中指定的集群基本域,如下錶所示:

組件 DNS記錄 描述
Kubernetes API api.<cluster_name>.<base_domain>. 此 DNS 記錄必須指向控制平面節點的負載均衡器。此記錄必須可由集群外部的客戶端和集群中的所有節點解析。
api-int.<cluster_name>.<base_domain>. 此 DNS 記錄必須指向控制平面節點的負載均衡器。此記錄必須可由集群外部的客戶端和集群中的所有節點解析。
Routes *.apps.<cluster_name>.<base_domain>. DNS 通配符記錄,指向負載均衡器。這個負載均衡器的後端是 Ingress router 所在的節點,默認是計算節點。此記錄必須可由集群外部的客戶端和集群中的所有節點解析。
etcd etcd-<index>.<cluster_name>.<base_domain>. OCP 要求每個 etcd 實例的 DNS 記錄指向運行實例的控制平面節點。etcd 實例由 值區分,它們以 0 開頭,以 n-1 結束,其中 n 是集群中控制平面節點的數量。集群中的所有節點必須都可以解析此記錄。
_etcd-server-ssl._tcp.<cluster_name>.<base_domain>. 因為 etcd 使用端口 2380 對外服務,因此需要建立對應每台 etcd 節點的 SRV DNS 記錄,優先級 0,權重 10 和端口 2380

DNS 服務的部署方法由很多種,我當然推薦使用 CoreDNS,畢竟雲原生標配。由於這裏需要添加 SRV 記錄,所以需要 CoreDNS 結合 etcd 插件使用。以下所有操作在基礎節點上執行。

首先通過 yum 安裝並啟動 etcd:

$ yum install -y etcd
$ systemctl enable etcd --now

然後下載 CoreDNS 二進制文件:

$ wget https://github.com/coredns/coredns/releases/download/v1.6.9/coredns_1.6.9_linux_amd64.tgz
$ tar zxvf coredns_1.6.9_linux_amd64.tgz
$ mv coredns /usr/local/bin

創建 Systemd Unit 文件:

$ cat > /etc/systemd/system/coredns.service <<EOF
[Unit]
Description=CoreDNS DNS server
Documentation=https://coredns.io
After=network.target

[Service]
PermissionsStartOnly=true
LimitNOFILE=1048576
LimitNPROC=512
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
AmbientCapabilities=CAP_NET_BIND_SERVICE
NoNewPrivileges=true
User=coredns
WorkingDirectory=~
ExecStart=/usr/local/bin/coredns -conf=/etc/coredns/Corefile
ExecReload=/bin/kill -SIGUSR1 $MAINPID
Restart=on-failure

[Install]
WantedBy=multi-user.target
EOF

新建 coredns 用戶:

$ useradd coredns -s /sbin/nologin

新建 CoreDNS 配置文件:

$ cat > /etc/coredns/Corefile <<EOF
.:53 {  # 監聽 TCP 和 UDP 的 53 端口
    template IN A apps.openshift4.example.com {
    match .*apps\.openshift4\.example\.com # 匹配請求 DNS 名稱的正則表達式
    answer "{{ .Name }} 60 IN A 192.168.57.60" # DNS 應答
    fallthrough
    }
    etcd {   # 配置啟用 etcd 插件,後面可以指定域名,例如 etcd test.com {
        path /skydns # etcd 裏面的路徑 默認為 /skydns,以後所有的 dns 記錄都存儲在該路徑下
        endpoint http://localhost:2379 # etcd 訪問地址,多個空格分開
        fallthrough # 如果區域匹配但不能生成記錄,則將請求傳遞給下一個插件
        # tls CERT KEY CACERT # 可選參數,etcd 認證證書設置
    }
    prometheus  # 監控插件
    cache 160
    loadbalance   # 負載均衡,開啟 DNS 記錄輪詢策略
    forward . 192.168.57.1
    log # 打印日誌
}
EOF

其中 template 插件用來實現泛域名解析。

啟動 CoreDNS 並設置開機自啟:

$ systemctl enable coredns --now

驗證泛域名解析:

$ dig +short apps.openshift4.example.com @127.0.0.1
192.168.57.60

$ dig +short x.apps.openshift4.example.com @127.0.0.1
192.168.57.60

添加其餘 DNS 記錄:

$ alias etcdctlv3='ETCDCTL_API=3 etcdctl'
$ etcdctlv3 put /skydns/com/example/openshift4/api '{"host":"192.168.57.60","ttl":60}'
$ etcdctlv3 put /skydns/com/example/openshift4/api-int '{"host":"192.168.57.60","ttl":60}'

$ etcdctlv3 put /skydns/com/example/openshift4/etcd-0 '{"host":"192.168.57.62","ttl":60}'
$ etcdctlv3 put /skydns/com/example/openshift4/etcd-1 '{"host":"192.168.57.63","ttl":60}'
$ etcdctlv3 put /skydns/com/example/openshift4/etcd-2 '{"host":"192.168.57.64","ttl":60}'

$ etcdctlv3 put /skydns/com/example/openshift4/_tcp/_etcd-server-ssl/x1 '{"host":"etcd-0.openshift4.example.com","ttl":60,"priority":0,"weight":10,"port":2380}'
$ etcdctlv3 put /skydns/com/example/openshift4/_tcp/_etcd-server-ssl/x2 '{"host":"etcd-1.openshift4.example.com","ttl":60,"priority":0,"weight":10,"port":2380}'
$ etcdctlv3 put /skydns/com/example/openshift4/_tcp/_etcd-server-ssl/x3 '{"host":"etcd-2.openshift4.example.com","ttl":60,"priority":0,"weight":10,"port":2380}'

# 除此之外再添加各節點主機名記錄
$ etcdctlv3 put /skydns/com/example/openshift4/bootstrap '{"host":"192.168.57.61","ttl":60}'
$ etcdctlv3 put /skydns/com/example/openshift4/master1 '{"host":"192.168.57.62","ttl":60}'
$ etcdctlv3 put /skydns/com/example/openshift4/master2 '{"host":"192.168.57.63","ttl":60}'
$ etcdctlv3 put /skydns/com/example/openshift4/master3 '{"host":"192.168.57.64","ttl":60}'
$ etcdctlv3 put /skydns/com/example/openshift4/worker1 '{"host":"192.168.57.65","ttl":60}'
$ etcdctlv3 put /skydns/com/example/openshift4/worker2 '{"host":"192.168.57.66","ttl":60}'
$ etcdctlv3 put /skydns/com/example/openshift4/registry '{"host":"192.168.57.70","ttl":60}'

驗證 DNS 解析:

$ yum install -y bind-utils
$ dig +short api.openshift4.example.com @127.0.0.1
192.168.57.60

$ dig +short api-int.openshift4.example.com @127.0.0.1
192.168.57.60

$ dig +short etcd-0.openshift4.example.com @127.0.0.1
192.168.57.62
$ dig +short etcd-1.openshift4.example.com @127.0.0.1
192.168.57.63
$ dig +short etcd-2.openshift4.example.com @127.0.0.1
192.168.57.64

$ dig +short -t SRV _etcd-server-ssl._tcp.openshift4.example.com @127.0.0.1
10 33 2380 etcd-0.openshift4.example.com.
10 33 2380 etcd-1.openshift4.example.com.
10 33 2380 etcd-2.openshift4.example.com.

$ dig +short bootstrap.openshift4.example.com @127.0.0.1
192.168.57.61
$ dig +short master1.openshift4.example.com @127.0.0.1
192.168.57.62
$ dig +short master2.openshift4.example.com @127.0.0.1
192.168.57.63
$ dig +short master3.openshift4.example.com @127.0.0.1
192.168.57.64
$ dig +short worker1.openshift4.example.com @127.0.0.1
192.168.57.65
$ dig +short worker2.openshift4.example.com @127.0.0.1
192.168.57.66

5. 配置負載均衡

負載均衡我選擇使用 Envoy,先準備配置文件:

Bootstrap

# /etc/envoy/envoy.yaml
node:
  id: node0
  cluster: cluster0
dynamic_resources:
  lds_config:
    path: /etc/envoy/lds.yaml
  cds_config:
    path: /etc/envoy/cds.yaml
admin:
  access_log_path: "/dev/stdout"
  address:
    socket_address:
      address: "0.0.0.0"
      port_value: 15001

LDS

# /etc/envoy/lds.yaml
version_info: "0"
resources:
- "@type": type.googleapis.com/envoy.config.listener.v3.Listener
  name: listener_openshift-api-server
  address:
    socket_address:
      address: 0.0.0.0
      port_value: 6443
  filter_chains:
  - filters:
    - name: envoy.tcp_proxy
      typed_config:
        "@type": type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
        stat_prefix: openshift-api-server
        cluster: openshift-api-server
        access_log:
          name: envoy.access_loggers.file
          typed_config:
            "@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog
            path: /dev/stdout
- "@type": type.googleapis.com/envoy.config.listener.v3.Listener
  name: listener_machine-config-server
  address:
    socket_address:
      address: "::"
      ipv4_compat: true
      port_value: 22623
  filter_chains:
  - filters:
    - name: envoy.tcp_proxy
      typed_config:
        "@type": type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
        stat_prefix: machine-config-server
        cluster: machine-config-server
        access_log:
          name: envoy.access_loggers.file
          typed_config:
            "@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog
            path: /dev/stdout
- "@type": type.googleapis.com/envoy.config.listener.v3.Listener
  name: listener_ingress-http
  address:
    socket_address:
      address: "::"
      ipv4_compat: true
      port_value: 80
  filter_chains:
  - filters:
    - name: envoy.tcp_proxy
      typed_config:
        "@type": type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
        stat_prefix: ingress-http
        cluster: ingress-http
        access_log:
          name: envoy.access_loggers.file
          typed_config:
            "@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog
            path: /dev/stdout
- "@type": type.googleapis.com/envoy.config.listener.v3.Listener
  name: listener_ingress-https
  address:
    socket_address:
      address: "::"
      ipv4_compat: true
      port_value: 443
  filter_chains:
  - filters:
    - name: envoy.tcp_proxy
      typed_config:
        "@type": type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
        stat_prefix: ingress-https
        cluster: ingress-https
        access_log:
          name: envoy.access_loggers.file
          typed_config:
            "@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog
            path: /dev/stdout

CDS

# /etc/envoy/cds.yaml
version_info: "0"
resources:
- "@type": type.googleapis.com/envoy.config.cluster.v3.Cluster
  name: openshift-api-server
  connect_timeout: 1s
  type: strict_dns
  dns_lookup_family: V4_ONLY
  lb_policy: ROUND_ROBIN
  load_assignment:
    cluster_name: openshift-api-server
    endpoints:
    - lb_endpoints:
      - endpoint:
          address:
            socket_address:
              address: 192.168.57.61
              port_value: 6443
      - endpoint:
          address:
            socket_address:
              address: 192.168.57.62
              port_value: 6443
      - endpoint:
          address:
            socket_address:
              address: 192.168.57.63
              port_value: 6443
      - endpoint:
          address:
            socket_address:
              address: 192.168.57.64
              port_value: 6443
- "@type": type.googleapis.com/envoy.config.cluster.v3.Cluster
  name: machine-config-server
  connect_timeout: 1s
  type: strict_dns
  dns_lookup_family: V4_ONLY
  lb_policy: ROUND_ROBIN
  load_assignment:
    cluster_name: machine-config-server
    endpoints:
    - lb_endpoints:
      - endpoint:
          address:
            socket_address:
              address: 192.168.57.61
              port_value: 22623
      - endpoint:
          address:
            socket_address:
              address: 192.168.57.62
              port_value: 22623
      - endpoint:
          address:
            socket_address:
              address: 192.168.57.63
              port_value: 22623
      - endpoint:
          address:
            socket_address:
              address: 192.168.57.64
              port_value: 22623
- "@type": type.googleapis.com/envoy.config.cluster.v3.Cluster
  name: ingress-http
  connect_timeout: 1s
  type: strict_dns
  dns_lookup_family: V4_ONLY
  lb_policy: ROUND_ROBIN
  load_assignment:
    cluster_name: ingress-http
    endpoints:
    - lb_endpoints:
      - endpoint:
          address:
            socket_address:
              address: 192.168.57.65
              port_value: 80
      - endpoint:
          address:
            socket_address:
              address: 192.168.57.66
              port_value: 80
- "@type": type.googleapis.com/envoy.config.cluster.v3.Cluster
  name: ingress-https
  connect_timeout: 1s
  type: strict_dns
  dns_lookup_family: V4_ONLY
  lb_policy: ROUND_ROBIN
  load_assignment:
    cluster_name: ingress-https
    endpoints:
    - lb_endpoints:
      - endpoint:
          address:
            socket_address:
              address: 192.168.57.65
              port_value: 443
      - endpoint:
          address:
            socket_address:
              address: 192.168.57.66
              port_value: 443

配置看不懂的去看我的电子書:Envoy 中文指南

啟動 Envoy

$ podman run -d --restart=always --name envoy --net host -v /etc/envoy:/etc/envoy envoyproxy/envoy

6. 安裝準備

生成 SSH 私鑰並將其添加到 agent

在安裝過程中,我們會在基礎節點上執行 OCP 安裝調試和災難恢復,因此必須在基礎節點上配置 SSH key,ssh-agent 將會用它來執行安裝程序。

基礎節點上的 core 用戶可以使用該私鑰登錄到 Master 節點。部署集群時,該私鑰會被添加到 core 用戶的 ~/.ssh/authorized_keys 列表中。

密鑰創建步驟如下:

① 創建無密碼驗證的 SSH key:

$ ssh-keygen -t rsa -b 4096 -N '' -f ~/.ssh/new_rsa

② 啟動 ssh-agent 進程作為後台任務:

$ eval "$(ssh-agent -s)"

③ 將 SSH 私鑰添加到 ssh-agent

$ ssh-add ~/.ssh/new_rsa

後續集群安裝過程中,有一步會提示輸入 SSH public key,屆時使用前面創建的公鑰 new_rsa.pub 就可以了。

獲取安裝程序

如果是在線安裝,還需要在基礎節點上下載安裝程序。但這裡是離線安裝,安裝程序在上篇文章中已經被提取出來了,所以不需要再下載。

創建安裝配置文件

首先創建一個安裝目錄,用來存儲安裝所需要的文件:

$ mkdir /ocpinstall

自定義 install-config.yaml 並將其保存在 /ocpinstall 目錄中。配置文件必須命名為 install-config.yaml。配置文件內容:

apiVersion: v1
baseDomain: example.com
compute:
- hyperthreading: Enabled
  name: worker
  replicas: 0
controlPlane:
  hyperthreading: Enabled
  name: master
  replicas: 3
metadata:
  name: openshift4
networking:
  clusterNetwork:
  - cidr: 10.128.0.0/14
    hostPrefix: 23
  networkType: OpenShiftSDN
  serviceNetwork:
  - 172.30.0.0/16
platform:
  none: {}
fips: false
pullSecret: '{"auths": ...}'
sshKey: 'ssh-rsa ...'
additionalTrustBundle: |
  -----BEGIN CERTIFICATE-----
  省略,注意這裏要前面空兩格
  -----END CERTIFICATE-----
imageContentSources:
- mirrors:
  - registry.openshift4.example.com/ocp4/openshift4
  source: quay.io/openshift-release-dev/ocp-release
- mirrors:
  - registry.openshift4.example.com/ocp4/openshift4
  source: quay.io/openshift-release-dev/ocp-v4.0-art-dev
  • baseDomain : 所有 Openshift 內部的 DNS 記錄必須是此基礎的子域,並包含集群名稱。
  • compute : 計算節點配置。這是一個數組,每一個元素必須以連字符 - 開頭。
  • hyperthreading : Enabled 表示啟用同步多線程或超線程。默認啟用同步多線程,可以提高機器內核的性能。如果要禁用,則控制平面和計算節點都要禁用。
  • compute.replicas : 計算節點數量。因為我們要手動創建計算節點,所以這裏要設置為 0。
  • controlPlane.replicas : 控制平面節點數量。控制平面節點數量必須和 etcd 節點數量一致,為了實現高可用,本文設置為 3。
  • metadata.name : 集群名稱。即前面 DNS 記錄中的 <cluster_name>
  • cidr : 定義了分配 Pod IP 的 IP 地址段,不能和物理網絡重疊。
  • hostPrefix : 分配給每個節點的子網前綴長度。例如,如果將 hostPrefix 設置為 23,則為每一個節點分配一個給定 cidr 的 /23 子網,允許 \(510 (2^{32 – 23} – 2)\) 個 Pod IP 地址。
  • serviceNetwork : Service IP 的地址池,只能設置一個。
  • pullSecret : 上篇文章使用的 pull secret,可通過命令 cat /root/pull-secret.json|jq -c 來壓縮成一行。
  • sshKey : 上面創建的公鑰,可通過命令 cat ~/.ssh/new_rsa.pub 查看。
  • additionalTrustBundle : 私有鏡像倉庫 Quay 的信任證書,可在鏡像節點上通過命令 cat /data/quay/config/ssl.cert 查看。
  • imageContentSources : 來自前面 oc adm release mirror 的輸出結果。

備份安裝配置文件,便於以後重複使用:

$ cd /ocpinstall
$ cp install-config.yaml  install-config.yaml.20200604

創建 Kubernetes 部署清單

創建 Kubernetes 部署清單后 install-config.yaml 將被刪除,請務必先備份此文件!

創建 Kubernetes 部署清單文件:

$ openshift-install create manifests --dir=/ocpinstall

修改 manifests/cluster-scheduler-02-config.yml 文件,將 mastersSchedulable 的值設為 flase,以防止 Pod 調度到控制節點。

創建 Ignition 配置文件

創建 Ignition 配置文件后 install-config.yaml 將被刪除,請務必先備份此文件!

$ cp install-config.yaml.20200604 install-config.yaml
$ openshift-install create ignition-configs --dir=/ocpinstall

生成的文件:

├── auth
│   ├── kubeadmin-password
│   └── kubeconfig
├── bootstrap.ign
├── master.ign
├── metadata.json
└── worker.ign

準備一個 HTTP 服務,這裏選擇使用 Nginx:

$ yum install -y nginx

修改 Nginx 的配置文件 /etc/nginx/nginx/.conf,將端口改為 8080(因為負載均衡器已經佔用了 80 端口)。然後啟動 Nginx 服務:

$ systemctl enable nginx --now

Ignition 配置文件拷貝到 HTTP 服務的 ignition 目錄:

$ mkdir /usr/share/nginx/html/ignition
$ cp -r *.ign /usr/share/nginx/html/ignition/

獲取 RHCOS 的 BIOS 文件

下載用於裸機安裝的 BIOS 文件,並上傳到 Nginx 的目錄:

$ mkdir /usr/share/nginx/html/install
$ wget https://mirror.openshift.com/pub/openshift-v4/dependencies/rhcos/4.4/latest/rhcos-4.4.3-x86_64-metal.x86_64.raw.gz -O /usr/share/nginx/html/install/rhcos-4.4.3-x86_64-metal.x86_64.raw.gz

獲取 RHCOS 的 ISO 文件

本地下載 RHCOS 的 ISO 文件:https://mirror.openshift.com/pub/openshift-v4/dependencies/rhcos/4.4/latest/rhcos-4.4.3-x86_64-installer.x86_64.iso,然後上傳到 vSphere。步驟如下:

① 首先登陸 vSphere,然後點擊『存儲』。

② 選擇一個『數據存儲』,然後在右邊的窗口中選擇『上載文件』。

③ 選擇剛剛下載的 ISO 文件,上傳到 ESXI 主機。

7. 安裝集群

Bootstrap

最後開始正式安裝集群,先創建 bootstrap 節點虛擬機,操作系統選擇『Red Hat Enterprise Linux 7 (64-Bit)』,並掛載之前上傳的 ISO,按照之前的表格設置 CPU 、內存和硬盤,打開電源,然後按照下面的步驟操作:

① 在 RHCOS Installer 安裝界面按 Tab 鍵進入引導參數配置選項。

② 在默認選項 coreos.inst = yes 之後添加(由於無法拷貝粘貼,請輸入仔細核對后再回車進行):

ip=192.168.57.61::192.168.57.1:255.255.255.0:bootstrap.openshift4.example.com:ens192:none nameserver=192.168.57.60 coreos.inst.install_dev=sda coreos.inst.image_url=http://192.168.57.60:8080/install/rhcos-4.4.3-x86_64-metal.x86_64.raw.gz coreos.inst.ignition_url=http://192.168.57.60:8080/ignition/bootstrap.ign 

其中 ip=... 的含義為 ip=$IPADDRESS::$DEFAULTGW:$NETMASK:$HOSTNAMEFQDN:$IFACE:none

如圖所示:

③ 如果安裝有問題會進入 emergency shell,檢查網絡、域名解析是否正常,如果正常一般是以上參數輸入有誤,reboot 退出 shell 回到第一步重新開始。

安裝成功后從基礎節點通過命令 ssh -i ~/.ssh/new_rsa core@192.168.57.61 登錄 bootstrap 節點,然後驗證:

  • 網絡配置是否符合自己的設定:
    • hostname
    • ip route
    • cat /etc/resolv.conf
  • 驗證是否成功啟動 bootstrap 相應服務:
    • podman ps 查看服務是否以容器方式運行
    • 使用 ss -tulnp 查看 6443 和 22623 端口是否啟用。

這裏簡單介紹一下 bootstrap 節點的啟動流程,它會先通過 podman 跑一些容器,然後在容器裏面啟動臨時控制平面,這個臨時控制平面是通過 CRIO 跑在容器里的,有點繞。。直接看命令:

$ podman ps -a --no-trunc --sort created --format "{{.Command}}"

start --tear-down-early=false --asset-dir=/assets --required-pods=openshift-kube-apiserver/kube-apiserver,openshift-kube-scheduler/openshift-kube-scheduler,openshift-kube-controller-manager/kube-controller-manager,openshift-cluster-version/cluster-version-operator
/usr/bin/grep -oP Managed /manifests/0000_12_etcd-operator_01_operator.cr.yaml
/usr/bin/grep -oP Managed /manifests/0000_12_etcd-operator_01_operator.cr.yaml
/usr/bin/grep -oP Managed /manifests/0000_12_etcd-operator_01_operator.cr.yaml
/usr/bin/grep -oP Managed /manifests/0000_12_etcd-operator_01_operator.cr.yaml
/usr/bin/grep -oP Managed /manifests/0000_12_etcd-operator_01_operator.cr.yaml
/usr/bin/grep -oP Managed /manifests/0000_12_etcd-operator_01_operator.cr.yaml
/usr/bin/grep -oP Managed /manifests/0000_12_etcd-operator_01_operator.cr.yaml
/usr/bin/grep -oP Managed /manifests/0000_12_etcd-operator_01_operator.cr.yaml
/usr/bin/grep -oP Managed /manifests/0000_12_etcd-operator_01_operator.cr.yaml
/usr/bin/grep -oP Managed /manifests/0000_12_etcd-operator_01_operator.cr.yaml
/usr/bin/grep -oP Managed /manifests/0000_12_etcd-operator_01_operator.cr.yaml
/usr/bin/grep -oP Managed /manifests/0000_12_etcd-operator_01_operator.cr.yaml
/usr/bin/grep -oP Managed /manifests/0000_12_etcd-operator_01_operator.cr.yaml
/usr/bin/grep -oP Managed /manifests/0000_12_etcd-operator_01_operator.cr.yaml
/usr/bin/grep -oP Managed /manifests/0000_12_etcd-operator_01_operator.cr.yaml
/usr/bin/grep -oP Managed /manifests/0000_12_etcd-operator_01_operator.cr.yaml
/usr/bin/grep -oP Managed /manifests/0000_12_etcd-operator_01_operator.cr.yaml
/usr/bin/grep -oP Managed /manifests/0000_12_etcd-operator_01_operator.cr.yaml
/usr/bin/grep -oP Managed /manifests/0000_12_etcd-operator_01_operator.cr.yaml
/usr/bin/grep -oP Managed /manifests/0000_12_etcd-operator_01_operator.cr.yaml
/usr/bin/grep -oP Managed /manifests/0000_12_etcd-operator_01_operator.cr.yaml
/usr/bin/grep -oP Managed /manifests/0000_12_etcd-operator_01_operator.cr.yaml
/usr/bin/grep -oP Managed /manifests/0000_12_etcd-operator_01_operator.cr.yaml
render --dest-dir=/assets/cco-bootstrap --cloud-credential-operator-image=quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:244ab9d0fcf7315eb5c399bd3fa7c2e662cf23f87f625757b13f415d484621c3
bootstrap --etcd-ca=/assets/tls/etcd-ca-bundle.crt --etcd-metric-ca=/assets/tls/etcd-metric-ca-bundle.crt --root-ca=/assets/tls/root-ca.crt --kube-ca=/assets/tls/kube-apiserver-complete-client-ca-bundle.crt --config-file=/assets/manifests/cluster-config.yaml --dest-dir=/assets/mco-bootstrap --pull-secret=/assets/manifests/openshift-config-secret-pull-secret.yaml --etcd-image=quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:aba3c59eb6d088d61b268f83b034230b3396ce67da4f6f6d49201e55efebc6b2 --kube-client-agent-image=quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:8eb481214103d8e0b5fe982ffd682f838b969c8ff7d4f3ed4f83d4a444fb841b --machine-config-operator-image=quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:31dfdca3584982ed5a82d3017322b7d65a491ab25080c427f3f07d9ce93c52e2 --machine-config-oscontent-image=quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:b397960b7cc14c2e2603111b7385c6e8e4b0f683f9873cd9252a789175e5c4e1 --infra-image=quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:d7862a735f492a18cb127742b5c2252281aa8f3bd92189176dd46ae9620ee68a --keepalived-image=quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:a882a11b55b2fc41b538b59bf5db8e4cfc47c537890e4906fe6bf22f9da75575 --coredns-image=quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:b25b8b2219e8c247c088af93e833c9ac390bc63459955e131d89b77c485d144d --mdns-publisher-image=quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:dea1fcb456eae4aabdf5d2d5c537a968a2dafc3da52fe20e8d99a176fccaabce --haproxy-image=quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:7064737dd9d0a43de7a87a094487ab4d7b9e666675c53cf4806d1c9279bd6c2e --baremetal-runtimecfg-image=quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:715bc48eda04afc06827189883451958d8940ed8ab6dd491f602611fe98a6fba --cloud-config-file=/assets/manifests/cloud-provider-config.yaml --cluster-etcd-operator-image=quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:9f7a02df3a5d91326d95e444e2e249f8205632ae986d6dccc7f007ec65c8af77
render --prefix=cluster-ingress- --output-dir=/assets/ingress-operator-manifests
/usr/bin/cluster-kube-scheduler-operator render --manifest-image=quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:187b9d29fea1bde9f1785584b4a7bbf9a0b9f93e1323d92d138e61c861b6286c --asset-input-dir=/assets/tls --asset-output-dir=/assets/kube-scheduler-bootstrap --config-output-file=/assets/kube-scheduler-bootstrap/config
/usr/bin/cluster-kube-controller-manager-operator render --manifest-image=quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:187b9d29fea1bde9f1785584b4a7bbf9a0b9f93e1323d92d138e61c861b6286c --asset-input-dir=/assets/tls --asset-output-dir=/assets/kube-controller-manager-bootstrap --config-output-file=/assets/kube-controller-manager-bootstrap/config --cluster-config-file=/assets/manifests/cluster-network-02-config.yml
/usr/bin/cluster-kube-apiserver-operator render --manifest-etcd-serving-ca=etcd-ca-bundle.crt --manifest-etcd-server-urls=https://localhost:2379 --manifest-image=quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:187b9d29fea1bde9f1785584b4a7bbf9a0b9f93e1323d92d138e61c861b6286c --manifest-operator-image=quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:718ca346d5499cccb4de98c1f858c9a9a13bbf429624226f466c3ee2c14ebf40 --asset-input-dir=/assets/tls --asset-output-dir=/assets/kube-apiserver-bootstrap --config-output-file=/assets/kube-apiserver-bootstrap/config --cluster-config-file=/assets/manifests/cluster-network-02-config.yml
/usr/bin/cluster-config-operator render --config-output-file=/assets/config-bootstrap/config --asset-input-dir=/assets/tls --asset-output-dir=/assets/config-bootstrap
/usr/bin/cluster-etcd-operator render --etcd-ca=/assets/tls/etcd-ca-bundle.crt --etcd-metric-ca=/assets/tls/etcd-metric-ca-bundle.crt --manifest-etcd-image=quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:aba3c59eb6d088d61b268f83b034230b3396ce67da4f6f6d49201e55efebc6b2 --etcd-discovery-domain=test.example.com --manifest-cluster-etcd-operator-image=quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:9f7a02df3a5d91326d95e444e2e249f8205632ae986d6dccc7f007ec65c8af77 --manifest-setup-etcd-env-image=quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:31dfdca3584982ed5a82d3017322b7d65a491ab25080c427f3f07d9ce93c52e2 --manifest-kube-client-agent-image=quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:8eb481214103d8e0b5fe982ffd682f838b969c8ff7d4f3ed4f83d4a444fb841b --asset-input-dir=/assets/tls --asset-output-dir=/assets/etcd-bootstrap --config-output-file=/assets/etcd-bootstrap/config --cluster-config-file=/assets/manifests/cluster-network-02-config.yml
render --output-dir=/assets/cvo-bootstrap --release-image=registry.openshift4.example.com/ocp4/openshift4@sha256:4a461dc23a9d323c8bd7a8631bed078a9e5eec690ce073f78b645c83fb4cdf74
/usr/bin/grep -oP Managed /manifests/0000_12_etcd-operator_01_operator.cr.yaml
$ crictl pods

POD ID              CREATED             STATE               NAME                                                                  NAMESPACE                             ATTEMPT
17a978b9e7b1e       3 minutes ago       Ready               bootstrap-kube-apiserver-bootstrap.openshift4.example.com             kube-system                           24
8a0f79f38787a       3 minutes ago       Ready               bootstrap-kube-scheduler-bootstrap.openshift4.example.com             kube-system                           4
1a707da797173       3 minutes ago       Ready               bootstrap-kube-controller-manager-bootstrap.openshift4.example.com    kube-system                           4
0461d2caa2753       3 minutes ago       Ready               cloud-credential-operator-bootstrap.openshift4.example.com            openshift-cloud-credential-operator   4
ab6519286f65a       3 minutes ago       Ready               bootstrap-cluster-version-operator-bootstrap.openshift4.example.com   openshift-cluster-version             2
457a7a46ec486       8 hours ago         Ready               bootstrap-machine-config-operator-bootstrap.openshift4.example.com    default                               0
e4df49b4d36a1       8 hours ago         Ready               etcd-bootstrap-member-bootstrap.openshift4.example.com                openshift-etcd                        0

如果驗證無問題,則可以一邊繼續下面的步驟一邊觀察日誌:journalctl -b -f -u bootkube.service

RHCOS 的默認用戶是 core,如果想獲取 root 權限,可以執行命令 sudo su(不需要輸入密碼)。

Master

控制節點和之前類似,先創建虛擬機,然後修改引導參數,引導參數調整為:

ip=192.168.57.62::192.168.57.1:255.255.255.0:master1.openshift4.example.com:ens192:none nameserver=192.168.57.60 coreos.inst.install_dev=sda coreos.inst.image_url=http://192.168.57.60:8080/install/rhcos-4.4.3-x86_64-metal.x86_64.raw.gz coreos.inst.ignition_url=http://192.168.57.60:8080/ignition/master.ign 

控制節點安裝成功後會重啟一次,之後同樣可以從基礎節點通過 SSH 密鑰登錄。

然後重複相同的步驟創建其他兩台控制節點,注意修改引導參數(IP 和主機名)。先不急着創建計算節點,先在基礎節點執行以下命令完成生產控制平面的創建:

$ openshift-install --dir=/ocpinstall wait-for bootstrap-complete --log-level=debug

DEBUG OpenShift Installer 4.4.5
DEBUG Built from commit 15eac3785998a5bc250c9f72101a4a9cb767e494
INFO Waiting up to 20m0s for the Kubernetes API at https://api.openshift4.example.com:6443...
INFO API v1.17.1 up
INFO Waiting up to 40m0s for bootstrapping to complete...
DEBUG Bootstrap status: complete
INFO It is now safe to remove the bootstrap resources

待出現 It is now safe to remove the bootstrap resources 提示之後,從負載均衡器中刪除引導主機,本文使用的是 Envoy,只需從 cds.yaml 中刪除引導主機的 endpoint,然後重新加載就好了。

觀察引導節點的日誌:

$ journalctl -b -f -u bootkube.service

...
Jun 05 00:24:12 bootstrap.openshift4.example.com bootkube.sh[12571]: I0605 00:24:12.108179       1 waitforceo.go:67] waiting on condition EtcdRunningInCluster in etcd CR /cluster to be True.
Jun 05 00:24:21 bootstrap.openshift4.example.com bootkube.sh[12571]: I0605 00:24:21.595680       1 waitforceo.go:67] waiting on condition EtcdRunningInCluster in etcd CR /cluster to be True.
Jun 05 00:24:26 bootstrap.openshift4.example.com bootkube.sh[12571]: I0605 00:24:26.250214       1 waitforceo.go:67] waiting on condition EtcdRunningInCluster in etcd CR /cluster to be True.
Jun 05 00:24:26 bootstrap.openshift4.example.com bootkube.sh[12571]: I0605 00:24:26.306421       1 waitforceo.go:67] waiting on condition EtcdRunningInCluster in etcd CR /cluster to be True.
Jun 05 00:24:29 bootstrap.openshift4.example.com bootkube.sh[12571]: I0605 00:24:29.097072       1 waitforceo.go:64] Cluster etcd operator bootstrapped successfully
Jun 05 00:24:29 bootstrap.openshift4.example.com bootkube.sh[12571]: I0605 00:24:29.097306       1 waitforceo.go:58] cluster-etcd-operator bootstrap etcd
Jun 05 00:24:29 bootstrap.openshift4.example.com podman[16531]: 2020-06-05 00:24:29.120864426 +0000 UTC m=+17.965364064 container died 77971b6ca31755a89b279fab6f9c04828c4614161c2e678c7cba48348e684517 (image=quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:9f7a02df3a5d91326d95e444e2e249f8205632ae986d6dccc7f007ec65c8af77, name=recursing_cerf)
Jun 05 00:24:29 bootstrap.openshift4.example.com bootkube.sh[12571]: bootkube.service complete

Worker

計算節點和之前類似,先創建虛擬機,然後修改引導參數,引導參數調整為:

ip=192.168.57.65::192.168.57.1:255.255.255.0:worker1.openshift4.example.com:ens192:none nameserver=192.168.57.60 coreos.inst.install_dev=sda coreos.inst.image_url=http://192.168.57.60:8080/install/rhcos-4.4.3-x86_64-metal.x86_64.raw.gz coreos.inst.ignition_url=http://192.168.57.60:8080/ignition/worker.ign 

計算節點安裝成功后也會重啟一次,之後同樣可以從基礎節點通過 SSH 密鑰登錄。

然後重複相同的步驟創建其他計算節點,注意修改引導參數(IP 和主機名)。

登錄集群

可以通過導出集群 kubeconfig 文件以默認系統用戶身份登錄到集群。kubeconfig 文件包含有關 CLI 用於將客戶端連接到正確的集群和 API Server 的集群信息,該文件在 OCP 安裝期間被創建。

$ mkdir ~/.kube
$ cp /ocpinstall/auth/kubeconfig ~/.kube/config
$ oc whoami
system:admin

批准 CSR

將節點添加到集群時,會為添加的每台節點生成兩個待處理證書籤名請求(CSR)。必須確認這些 CSR 已獲得批准,或者在必要時自行批准。

$ oc get node

NAME                             STATUS   ROLES           AGE     VERSION
master1.openshift4.example.com   Ready    master,worker   6h25m   v1.17.1
master2.openshift4.example.com   Ready    master,worker   6h39m   v1.17.1
master3.openshift4.example.com   Ready    master,worker   6h15m   v1.17.1
worker1.openshift4.example.com   NotReady worker          5h8m    v1.17.1
worker2.openshift4.example.com   NotReady worker          5h9m    v1.17.1

輸出列出了創建的所有節點。查看掛起的證書籤名請求(CSR),並確保添加到集群的每台節點都能看到具有 PendingApproved 狀態的客戶端和服務端請求。針對 Pending 狀態的 CSR 批准請求:

$ oc adm certificate approve xxx

或者執行以下命令批准所有 CSR:

$ oc get csr -ojson | jq -r '.items[] | select(.status == {} ) | .metadata.name' | xargs oc adm certificate approve

Operator 自動初始化

控制平面初始化后,需要確認所有的 Operator 都處於可用的狀態,即確認所有 Operator 的 Available 字段值皆為 True

$ oc get clusteroperators

NAME                                       VERSION   AVAILABLE   PROGRESSING   DEGRADED   SINCE
authentication                             4.4.5     True        False         False      150m
cloud-credential                           4.4.5     True        False         False      7h7m
cluster-autoscaler                         4.4.5     True        False         False      6h12m
console                                    4.4.5     True        False         False      150m
csi-snapshot-controller                    4.4.5     True        False         False      6h13m
dns                                        4.4.5     True        False         False      6h37m
etcd                                       4.4.5     True        False         False      6h19m
image-registry                             4.4.5     True        False         False      6h12m
ingress                                    4.4.5     True        False         False      150m
insights                                   4.4.5     True        False         False      6h13m
kube-apiserver                             4.4.5     True        False         False      6h15m
kube-controller-manager                    4.4.5     True        False         False      6h36m
kube-scheduler                             4.4.5     True        False         False      6h36m
kube-storage-version-migrator              4.4.5     True        False         False      6h36m
machine-api                                4.4.5     True        False         False      6h37m
machine-config                             4.4.5     True        False         False      6h36m
marketplace                                4.4.5     True        False         False      6h12m
monitoring                                 4.4.5     True        False         False      6h6m
network                                    4.4.5     True        False         False      6h39m
node-tuning                                4.4.5     True        False         False      6h38m
openshift-apiserver                        4.4.5     True        False         False      6h14m
openshift-controller-manager               4.4.5     True        False         False      6h12m
openshift-samples                          4.4.5     True        False         False      6h11m
operator-lifecycle-manager                 4.4.5     True        False         False      6h37m
operator-lifecycle-manager-catalog         4.4.5     True        False         False      6h37m
operator-lifecycle-manager-packageserver   4.4.5     True        False         False      6h15m
service-ca                                 4.4.5     True        False         False      6h38m
service-catalog-apiserver                  4.4.5     True        False         False      6h38m
service-catalog-controller-manager         4.4.5     True        False         False      6h39m
storage                                    4.4.5     True        False         False      6h12m

如果 Operator 不正常,需要進行問題診斷和修復。

完成安裝

最後一步,完成集群的安裝,執行以下命令:

$ openshift-install --dir=/ocpinstall wait-for install-complete --log-level=debug

注意最後提示訪問 Web Console 的網址及用戶密碼。如果密碼忘了也沒關係,可以查看文件 /ocpinstall/auth/kubeadmin-password 來獲得密碼。

本地訪問 Web Console,需要添加 hosts:

192.168.57.60 console-openshift-console.apps.openshift4.example.com
192.168.57.60 oauth-openshift.apps.openshift4.example.com

瀏覽器訪問 https://console-openshift-console.apps.openshift4.example.com,輸入上面輸出的用戶名密碼登錄。首次登錄後會提示:

You are logged in as a temporary administrative user. Update the Cluster OAuth configuration to allow others to log in.

我們可以通過 htpasswd 自定義管理員賬號,步驟如下:

htpasswd -c -B -b users.htpasswd admin xxxxx

② 將 users.htpasswd 文件下載到本地。

③ 在 Web Console 頁面打開 Global Configuration

然後找到 OAuth,點擊進入,然後添加 HTPasswd 類型的 Identity Providers,並上傳 users.htpasswd 文件。

④ 退出當前用戶,注意要退出到如下界面:

選擇 htpasswd,然後輸入之前創建的用戶名密碼登錄。

如果退出后出現的就是用戶密碼輸入窗口,實際還是 kube:admin 的校驗,如果未出現如上提示,可以手動輸入 Web Console 地址來自動跳轉。

⑤ 登錄后貌似能看到 Administrator 菜單項,但訪問如 OAuth Details 仍然提示:

oauths.config.openshift.io "cluster" is forbidden: User "admin" cannot get resource "oauths" in API group "config.openshift.io" at the cluster scope

因此需要授予集群管理員權限:

$ oc adm policy add-cluster-role-to-user cluster-admin admin

Web Console 部分截圖:

如果想刪除默認賬號,可以執行以下命令:

$ oc -n kube-system delete secrets kubeadmin

8. 參考資料

  • OpenShift 4.2 vSphere Install with Static IPs
  • OpenShift Container Platform 4.3部署實錄
  • Chapter 1. Installing on bare metal

Kubernetes 1.18.2 1.17.5 1.16.9 1.15.12離線安裝包發布地址http://store.lameleg.com ,歡迎體驗。 使用了最新的sealos v3.3.6版本。 作了主機名解析配置優化,lvscare 掛載/lib/module解決開機啟動ipvs加載問題, 修復lvscare社區netlink與3.10內核不兼容問題,sealos生成百年證書等特性。更多特性 https://github.com/fanux/sealos 。歡迎掃描下方的二維碼加入釘釘群 ,釘釘群已經集成sealos的機器人實時可以看到sealos的動態。

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

台北網頁設計公司這麼多該如何選擇?

※智慧手機時代的來臨,RWD網頁設計為架站首選

※評比南投搬家公司費用收費行情懶人包大公開

※回頭車貨運收費標準

分類
發燒車訊

養生吧,程序員!

由於寫作的原因,我認識了蠻多天南海北的朋友。空下來的時候,我就會主動找他們聊一聊,一呢,從他們那吸取成功的經驗,開拓一下眼界;二呢,讓自己的社交圈擴大一些,要知道,多一個朋友就多一條路;三呢,看看朋友們有沒有自己可以幫得上的忙;四呢,保持年輕的心態,不至於落伍。

老讀者都知道了,我在三線城市洛陽,雖然幸福感很足,但整體社交的圈子是有限的,只通過互聯網,很難得到一些不便於公開的信息,和朋友們聊一聊,不僅能夠加深感情,還能夠讓自己和一線城市保持同步。

昨天,我和一個非常優秀的年輕人聊天,他給我說,身體上出了一些狀況。他比我小七八歲,按理說身體素質倍棒才對,但大城市的生活壓力,讓他只能快馬加鞭。這就導致身體一直處於高負荷的運轉狀態,很容易出問題。

提起程序員,總免不了和一些段子關聯上,比如說“要變強,必變禿”,再比如說:

零基礎學編程→某編程語言入門→某編程語言進階→技術專家→頸椎病

以前,我對這些段子總是一笑而過,但回想起朋友說的那些話,總免不了一陣心酸。就讓我來寫一篇“程序員養生指南”吧,希望能給讀者朋友們一些警醒或者說參考吧。

心學鼻祖王陽明曾提出過一個觀點,叫做“知行合一”,我的理解就是,當你要做一件事情的話,你必須得對它有一定的認知,否則的話,你根本就不會去做這件事。

舉個例子來說,如果你不知道學習很重要,哪怕你天資聰慧,你也不可能去學習,你會把心思花在其他地方。

再比如說,如果你認知不到英語對於程序員的重要性,你永遠也擺脫不了對翻譯軟件的依賴症。

對吧?如果在你的認知里,意識不到健康的重要性,那你對待身體的態度可就會大有不同。

大二結束后,我要去蘇州參加培訓,臨走之前,同學們給我送行,結果我一下子喝大了。畢竟一起玩了兩年,又要去人生地不熟的地方,傷感在所難免,於是我把自己喝到了醫院。

喝完酒感覺沒啥事,結果睡覺前嘔吐的厲害,感覺整個人就要死翹翹了。我的一個好兄弟看我情況不妙,背着我就跑,大晚上也沒啥車,幸好醫院就在我們學校旁邊,算是保住了一條小命。

從那以後,我就特別討厭喝酒,儘管有的時候不得不喝一些,但都會盡量控制到不上頭的狀態。

我身邊有不少人,總是把鍛煉掛在嘴上,聊起來感覺特別注重身體。但過一段時間再問他,“夥計,你健身卡辦了沒?”“最近忙,過两天就去辦,感覺身體有點撐不住了。”

生存的壓力確實大,但如果身體跨了,生存的意義又是什麼呢?

改變一個人的認知,最壞的方式就是徹底摧毀他之前的認知。極端的例子就是大病初愈,那時候,人會迫切地想要鍛煉身體。

最好的方式,當然是聽得進去勸,把別人糟糕的經歷當做是自己前進的動力。認識到健康的重要性,然後一點一滴地去改善生活的習慣,最終達到知行合一的境界。

我曾看過一本書,裏面提到一個觀點,養成習慣的最好方式就是,連續不間斷地做一件事,周期為 21 天。這件事最好是一件小事,比如說,起床后疊被子這件事,它一點也不難,很容易就能做到。

但能不能堅持 21 天不間斷就需要一點點耐力了,21 天不算長,但絕對算得上是富有意義的考驗了,它對你培養飲食、作息、運動方面的良好行為習慣是一道開胃菜。

接下來說說飲食吧,我覺得一定不要暴飲暴食,或者餓着肚子。每天的三餐一定要及時,哪怕你早上起晚了,一定也要記得吃點東西,可以準備一些麵包或者牛奶,不要餓着肚子挺到中午,那樣的話,對身體不好,另外,餓的時候,工作狀態也會大打折扣。

現在天氣熱了,很多讀者的食慾都不會特彆強烈,尤其是到了中午的時候,可以選擇一些清淡的,比如說,我作為北方人,最喜歡的就是甜面片,伴着一點鹹菜吃,再喝點麵湯,感覺特別舒服。

到了晚上,不要因為餓就要找場子,覺得必須得吃回來,然後睡覺的時候就感覺特別撐,很難入睡,反而影響了睡眠質量。

我一般是十點半入睡,然後一覺睡到早上五六點。這個作息還是非常規律的,中午如果困的話,就再補個覺。最好不要超過半個小時,否則越睡越困,如果實在睡不着,就閉目養神會,就算是休息休息眼睛吧,畢竟做程序員的,每天對着電腦屏幕和手機屏幕,對眼睛的傷害還是蠻大的。

有不少讀者都睡得特別晚,一方面是公司上下班時間上的問題,一方面就是好不容易有點自己的自由時間,舍不得睡覺,於是熬一會,打一把遊戲,就到了凌晨一兩點。

我是怎麼知道的?通過留言的時間就知道了。讓我很心疼的一個事實是,有些留言的時間竟然是凌晨三四點。真的,看到這個時間點的留言,我都會勸讀者能早點睡就早點睡,不要熬夜。

二十五六歲之前,熬個夜,很快就恢復了,但再往後,真的是非常難,我以前熬夜看英超,結果第二天整個人都處於懵逼的狀態,效率特別差,要兩三天才能恢復正常,索性後來就戒了。

最後再說說鍛煉吧,年前我辦了一張健身卡,一周能堅持去兩到三次,但後來就中斷了。最近兩個月,我開始了騎自行車,感覺效果還不錯,瘦了七八斤的樣子,有一種返老還童的感覺,真的。

五六點起來,騎一個小時左右,回到家不耽誤上班。我在朋友圈曬過兩張圖,老讀者應該看到了。清晨,空氣特別好,路上人也不多,車也不多,氣溫也剛剛好,耳邊再聽着周杰倫或者王力宏,感覺真的非常愜意。

作為程序員,絕大部分時間都要坐在椅子上,再加上有些公司加班特別厲害,就導致久坐的時間特別長,於是頸椎病、肩周炎等等職業病隨着而來。

除了及時地走動,還是要盡量騰出一些時間去鍛煉一下,哪怕走走路,跑幾步,對身體的調整都卓有成效,業績是公司的,身體是自己的。

最後,就是堅持了。生活需要用心去對待,如果我們用心去愛她,她就會加倍地愛我們——養生吧,程序員!

如果覺得文章對你有點幫助,請微信搜索「 沉默王二 」第一時間閱讀。

本文已收錄 GitHub,傳送門~ ,裏面更有大廠面試完整考點,歡迎 Star。

我是沉默王二,一枚有顏值卻靠才華苟且的程序員。關注即可提升學習效率,別忘了三連啊,點贊、收藏、留言,我不挑,嘻嘻

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

※Google地圖已可更新顯示潭子電動車充電站設置地點!!

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※別再煩惱如何寫文案,掌握八大原則!

網頁設計最專業,超強功能平台可客製化

分類
發燒車訊

【SEED Labs】Public-Key Infrastructure (PKI) Lab

Lab Overview

公鑰加密是當今安全通信的基礎,但當通信的一方向另一方發送其公鑰時,它會受到中間人的攻擊。根本的問題是,沒有簡單的方法來驗證公鑰的所有權,即,給定公鑰及其聲明的所有者信息,如何確保該公鑰確實屬於聲明的所有者?公鑰基礎設施(PKI)是解決這一問題的一種切實可行的方法。

通過這個實驗,我們應該能夠更好地了解PKI是如何工作的,PKI是如何用來保護網絡,以及PKI如何打敗中間人攻擊。此外,我們將能夠了解在公鑰基礎設施中信任的根源,以及如果這種根源信任被破壞會出現什麼問題。本實驗所涵蓋的主題如下:

• Public-key encryption

• Public-Key Infrastructure (PKI)

• Certificate Authority (CA) and root CA

• X.509 certificate and self-signed certificate

• Apache, HTTP, and HTTPS

• Man-in-the-middle attacks

Lab Environment

這個實驗在我kali VM和Ubuntu 16.04 VM上進行了測試.在這個實驗中,我們將使用openssl命令和庫。

Lab Tasks

Task1: Becoming a Certificate Authority(CA) 

證書頒發機構(CA)是發布数字證書的受信任實體。数字證書通過證書的命名主體來驗證公鑰的所有權。一些商業性的CAs被視為根類CAs;在撰寫本文時,VeriSign是最大的CA。想要獲得商業核證機關發出的数字證書的用戶需要向這些核證機關支付費用。

在這個實驗室,我們需要創建数字證書,但是我們不會支付任何商業CA,我們自己會成為一個根CA,然後用這個CA為其他人(比如服務器)頒發證書。在這個任務中,我們將使自己成為一個根CA,併為這個CA生成一個證書。RootCA的認證通常預裝在大多數操作系統、web瀏覽器和其他依賴於PKI的軟件中。根CA的證書是無條件信任的。

The Configuration File openssl.conf  

為了使用OpenSSL創建證書,必須有一個配置文件。配置文件通常有一個extension.cnf。它由三個OpenSSL命令使用:ca、req和x509。可以使用谷歌搜索找到openssl.conf的手冊頁。還可以從/usr/lib/ssl/openssl.cnf獲得配置文件的副本。將此文件複製到當前目錄后,需要按照配置文件中指定的方式創建子目錄(查看[CA default]部分): 

 

 

 對於index.txt文件,只需創建一個空文件。對於serial文件,在文件中放入一個字符串格式的数字(例如1000)。設置好配置文件openssl.cnf之後,就可以創建和頒發證書了。

CertificateAuthority(CA).

如前所述,我們需要為我們的CA生成一個自簽名證書,這意味着這個CA是完全可信的,它的證書將作為根證書。運行以下命令為CA生成自簽名證書:

系統將提示您輸入信息和密碼。不要丟失此密碼,因為每次要使用此CA為其他人簽名證書時,都必須鍵入口令。您還將被要求填寫一些信息,如國家名稱、常用名稱等。該命令的輸出存儲在兩個文件中:ca.key和ca.crt。文件CA .key包含CA的私鑰,而CA .crt包含公鑰證書。

 

 

 Task2: Creating a Certificate for SEEDPKILab2018.com 

現在,我們成為一個根CA,我們準備為我們的客戶簽署数字證書。我們的第一個客戶是一家名為SEEDPKILab2018.com的公司。該公司要從CA獲得数字證書,需要經過三個步驟。

Step 1: Generate public/private key pair  。公司需要首先創建自己的公鑰/私鑰對。可以運行以下命令來生成RSA密鑰對(私有和公共密鑰)。您還需要提供一個密碼來加密私鑰(使用AES-128加密算法,在命令選項中指定)。密鑰將存儲在文件服務器中。

 

server.key是一個編碼的文本文件(也是加密的),因此無法看到實際內容,例如模數、私有指數等。要查看這些,可以運行以下命令:

 

 

 

 

 Step 2: Generate a Certificate Signing Request (CSR). 一旦公司擁有了密鑰文件,它應該生成一個證書籤名請求(CSR),它基本上包括公司的公鑰。CSR將被發送到CA, CA將為密鑰生成證書(通常在確保CSR中的身份信息與服務器的真實身份匹配之後)。使用SEEDPKILab2018.com作為證書請求的通用名稱。

需要注意的是,上面的命令與我們為CA創建自簽名證書時使用的命令非常相似,唯一的區別是使用了-x509選項。沒有它,命令生成一個請求;使用它,該命令生成一個自簽名證書。

Step 3: Generating Certificates . CSR文件需要有CA的簽名才能形成證書。在現實世界中,CSR文件通常被發送到受信任的CA進行簽名。在這個實驗中,我們將使用我們自己的可信CA來生成證書。以下命令使用CA的CA .crt和CA .key將證書籤名請求(server.csr)轉換為X509證書(server.crt):

如果OpenSSL拒絕生成證書,您請求中的名稱很可能與ca的名稱不匹配。匹配規則在配置文件中指定(查看[policy match]部分)。您可以更改請求的名稱以符合策略,也可以更改策略。配置文件還包括另一個限制較少的策略(稱為任何策略)。您可以通過更改以下行來選擇該策略:

“policy = policy_match” change to “policy = policy_anything”.

Task3: Deploying Certificate in an HTTPS Web Server

在這個實驗中,我們將探索網站如何使用公鑰證書來保護web瀏覽。我們將使用openssl的內置web服務器建立一個HTTPS網站。

Step1: Configuring DNS .我們選擇SEEDPKILab2018.com作為我們的網站名稱。為了讓我們的計算機識別這個名稱,讓我們將下面的條目添加到/etc/hosts;這個條目基本上將主機名SEEDPKILab2018.com映射到本地主機(即127.0.0.1):

 

Step 2: Configuring the web server.  讓我們使用在上一個任務中生成的證書啟動一個簡單的web服務器。OpenSSL允許我們使用s_server命令啟動一個簡單的web服務器:

 

默認情況下,服務器將監聽端口4433。您可以使用-accept選項進行更改。現在,您可以使用以下URL訪問服務器:https://SEEDPKILab2018.com:4433/。最有可能的是,您將從瀏覽器中得到一條錯誤消息。在Firefox中,您將看到如下消息:“seedpkilab2018.com:4433使用了無效的安全證書。該證書不受信任,因為發布者證書未知”.

 

Step3: Getting the browser to accept our CA certificate. 如果我們的證書是由VeriSign分配的,就不會出現這樣的錯誤消息,因為VeriSign的證書很可能已經預加載到Firefox的證書存儲庫中了。很遺憾,SEEDPKILab2018.com的證書是由我們自己的CA,並且Firefox無法識別此CA。有兩種方法可以讓Firefox接受CA的自簽名證書。

  • 我們可以請求Mozilla將我們的CA證書包含在Firefox軟件中,這樣每個使用Firefox的人都可以識別我們的CA。不幸的是,我們自己的CA沒有足夠大的市場讓Mozilla包含我們的證書,所以我們不會追求這個方向。
  • 加載CA .crt到Firefox中:我們可以手動添加我們的CA證書到Firefox瀏覽器通過點擊下面的菜單序列:

             Edit -> Preference -> Privacy & Security -> View Certificates

您將看到一個已經被Firefox接受的證書列表。從這裏,我們可以“導入”我們自己的證書。請導入CA .crt,並選擇以下選項:“信任此CA識別網站”。您將看到我們的CA證書現在位於Firefox接受的證書列表中。

 Step4. Testing our HTTPS website . 現在,將瀏覽器指向https://SEEDPKILab2018.com: 4433,可以正常訪問

Task4: Deploying Certificate in an Apache-Based HTTPS Website

使用openssl的s_server命令設置HTTPS服務器主要用於調試和演示目的。在這個實驗中,我們基於Apache建立了一個真正的HTTPS web服務器。Apache服務器(已經安裝在我們的VM中)支持HTTPS協議。要創建一個HTTPS網站,我們只需要配置Apache服務器,這樣它就知道從哪裡獲得私鑰和證書。

一個Apache服務器可以同時託管多個網站。它需要知道網站文件存儲的目錄。這是通過它的VirtualHost文件完成的,該文件位於/etc/apache2/sites-available目錄中。要添加一個HTTP網站,我們需要在文件000-default.conf中添加一個虛擬主機條目。而要添加一個HTTPS網站,我們則需要在同一個文件夾的default-ssl.conf文件中添加一個VirtualHost條目。

 

 

ServerName條目指定網站的名稱,而DocumentRoot條目指定網站文件存儲的位置。在設置中,我們需要告訴Apache服務器證書和私鑰存儲在哪裡。

修改了default-ssl.conf文件之後,我們需要運行一系列命令來啟用SSL。Apache將要求我們輸入用於加密私鑰的密碼。一旦一切都設置好了,我們就可以瀏覽網站了,瀏覽器和服務器之間的所有流量都被加密了。

 

 Task5: Launching a Man-In-The-Middle Attack 

 

 在這個任務中,我們將展示PKI如何擊敗中間人(MITM)攻擊。下圖描述了MITM攻擊的工作原理。假設Alice想通過HTTPS協議訪問example.com。她需要從example.com服務器獲取公鑰;Alice將生成一個密鑰,並使用服務器的公鑰對該密鑰進行加密,然後將其發送到服務器。如果攻擊者可以攔截Alice和服務器之間的通信,則攻擊者可以用自己的公鑰替換服務器的公鑰。因此,Alice的秘密實際上是用攻擊者的公鑰加密的,因此攻擊者將能夠讀取秘密。攻擊者可以使用服務器的公鑰將密鑰轉發給服務器。秘密用於加密Alice和服務器之間的通信,因此攻擊者可以解密加密的通信。

 

 

Step 1: Setting up the malicious website. 在Task 4中,我們已經為SEEDPKILab2018.com建立了一個HTTPS網站。我們將使用相同的Apache服務器模擬example.com 。為此,我們將按照任務4中的指令向Apache的SSL配置文件添加一個VirtualHost條目:ServerName應該是example.com,但配置的其餘部分可以與任務4中使用的相同。我們的目標如下:當用戶試圖訪問example.com時,我們將讓用戶登陸我們的服務器,其中為example.com託管一個假網站。如果這是一個社交網站,虛假網站可以显示一個登錄頁面類似於目標網站。如果用戶不能分辨出兩者的區別,他們可能會在假網頁中輸入他們的帳戶憑據,本質上就是向攻擊者披露憑據。

Step2: Becoming the man in the middle 。有幾種方法可以讓用戶的HTTPS請求到達我們的web服務器。一種方法是攻擊路由,將用戶的HTTPS請求路由到我們的web服務器。另一種方法是攻擊DNS,當受害者的機器試圖找到目標網絡服務器的IP地址時,它會得到我們的網絡服務器的IP地址。在此任務中,我們使用“攻擊”DNS。我們只需修改受害者機器的/etc/hosts文件,以模擬DNS緩存設置攻擊的結果,而不是啟動實際的DNS緩存中毒攻擊。

Step3: Browse the target website  。一切都設置好了,現在訪問目標真實的網站。

可以看到,我們訪問到的是kali攻擊機的默認目錄。

訪問https服務的時候,由於kali攻擊機的證書不被信任,所以會有安全警告

 

 

 

Task6: Launching a Man-In-The-Middle Attack with a Compromised CA 

設計一個實驗來證明攻擊者可以在任何HTTPS網站上成功發起MITM攻擊。可以使用在Task 5中創建的相同設置,但是這一次,需要演示MITM攻擊是成功的。即,當受害者試圖訪問一個網站而進入MITM攻擊者的假網站時,瀏覽器不會引起任何懷疑。

 

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

南投搬家公司費用需注意的眉眉角角,別等搬了再說!

※教你寫出一流的銷售文案?

分類
發燒車訊

CPU性能分析工具原理

轉載請保留以下聲明

  作者: 趙宗晟

  出處: https://www.cnblogs.com/zhao-zongsheng/p/13067733.html

很多軟件都要做性能分析和性能優化。很多語言都會有他的性能分析工具,例如如果優化C++的性能,我們可以用Visual Studio自帶的性能探測器,或者使用Intel VTune Profiler。了解性能分析工具的原理有助於了解工具給出的數據與結果,也能幫助我們在遇到異常結果時排查哪裡出了問題。這篇博客簡單總結一下常見的性能分析工具原理。

性能分析器原理分類

性能分析工具大部分都可以分為下面幾類

  1. 基於採樣(Sampling)
  2. 基於插裝(Instrumentation)
  3. 基於事件(Event-based)

1. 基於採樣

基於採樣的分析器會每隔一個固定時間間隔暫停所有線程的執行,然後分析有哪些線程正在執行,那些線程處於就緒狀態。對於這類線程,我們記錄每個線程的調用堆棧,以及其他需要的信息。我們稱這個行為為一次採樣,記錄下來的每個堆棧為一個樣本。然後在結束性能分析的時候我們統計記錄下載的堆棧,看每個堆棧被記錄了多少次,或者每個函數被記錄了多少次。統計學告訴我們,那些執行時間比較長的函數、堆棧,被記錄的次數會更多。如果堆棧A被記錄了200次,堆棧B被記錄了100次,那麼堆棧B的執行時間是堆棧A的2倍。我們可以計算某個堆棧樣本的數量佔總樣本數的比例,這個比例就是堆棧執行時間的佔比。用Visual Studio的性能探測器我們看到的百分比和数字就是值樣本的佔比(也就是時間佔比)和樣本次數。

很多性能分析工具都是基於採樣的方式。運行性能分析器是會影響被測程序的性能的,而基於採樣的有點是對性能影響比較小,不需要重新編譯程序,非常方便。

2.基於插裝

插裝是指通過修改程序,往裡面加入性能分析相關代碼,來收集、監控相關性能指標。例如我們可以在一個函數的開頭寫下計數代碼,我們就可以知道在運行中這個函數被執行了多少次。一般來說基於插裝的性能分析更為準確,但是對性能影響比較大。因為需要修改代碼,所以也不是很方便。另外,基於插裝的分析也可能會引起海森堡bug(heisenbug)。海森堡bug是指當你再運行程序的時候能遇到這個bug,但是試圖定位這個bug時卻遇不到這個bug。這個bug往往是因為在定位bug時修改了軟件的運行環境/流程,導致軟件執行和生產時不一樣,於是就遇不到這個bug了。這個命名的來源很有意思,海森堡是量子力學的著名科學家,他提出了不確定性原理,以及觀察者理論。這個理論認為,觀察會影響例子的狀態,導致觀察粒子和不觀察粒子會導致不同的結果,這個和海森堡bug的情形非常相似。關於觀察者理論,有興趣的人可以再了解一下。

回到正題,基於插裝也可以再進行劃分:

  • 人手修改源碼:這個是我們非常常用的性能分析方法。我們做性能分析有時候就會直接修改源碼,計算某一段代碼的執行時長,或者計算函數調用次數,分析哪段代碼耗時。
  • 工具自動修改源碼
  • 工具自動修改彙編/中間碼
  • 運行時注入
  • ……

3.基於事件

在軟件執行過程中,可能會拋出某些事件。我們通過統計事件出現的次數,事件出現的時機,可以得到軟件的某些性能指標。事件又可以分為軟件事件和硬件事件。軟件事件比如Java可以在class-load的時候拋出事件。硬件事件則是使用專門的性能分析硬件。現在很多CPU裏面都有用於分析性能的性能監控單元(PMU),PMU本身是一個寄存器,在某個事件發生時寄存器裏面的值會+1。例如我們可以設置為當運行中發生memory cache miss的時候PMU寄存器+1,這樣我們就知道一段時間內發生了多少次memory cache miss。性能分析器使用PMU時,會給PMU設置需要統計的事件類型,以及Sample After Value (SAV)。SAV是指寄存器達到什麼值之後出發硬件中斷。例如,我們可以給PMU設置SAV為2000,統計事件為memory cache miss。那麼當cache miss發生2000次時,發生硬件中斷。這個時候性能分析器就可以收集CPU的IP,調用堆棧,進程ID等等信息,分析器結束時進行統計分析。

基於硬件事件的優點是,對被測程序的影響非常小,比基於採樣還小,可以使用更短的時間間隔收集信息,而且可以收集CPU的非常重要的性能指標,例如cache miss,分支預測錯誤,等等。

但是基於硬件事件的分析器也有它的一些問題,導致數據上的誤差:

  • SAV一般會設置成很大的數值:
    像是Intel VTune Profiler一般會把SAV設置成10,000到2,000,000,發生中斷時我們能知道最後一次觸發該事件是哪段代碼引起的,但是在這之前的9,999到1,999,999次事件我們是不知道的。他會認為所有10,000到2,000,000次事件都是由同一處代碼引起的。如果發生了很多次中斷,收集了很多次信息,而某一行代碼出現了很多次,那麼根據統計學,我們能知道這行代碼觸發了多少次事件。但是如果某一行代碼只出現了一兩次,那麼我們很難知道這行代碼到底出發了多少次時間。
  • CPU一個核只有幾個PMU,但是可以統計的事件有幾十種:
    一個PMU可以統計一個事件,但是我們分析一個軟件可能需要統計幾十種事件。一般的處理方法是多路復用(Multiplexing)。比如說前10ms記錄事件A,后10ms記錄事件B,再后10ms由記錄事件A,……,這樣輪流記錄事件A和事件B,那麼一個PMU就可以同時統計兩個事件。多路復用可以解決少量PMU統計大量事件的問題,但是也會導致每種事件記錄的樣本數減少,倒是最後統計計算的結果誤差更大。
  • Intel® Hyper-Threading Technology導致記錄不準:
    Hyper-Threading技術可以讓一個CPU物理核變成兩個邏輯核,但是這兩個邏輯核會共享很多硬件,包括PMU。這會出現什麼問題呢?例如我們有兩個線程再兩個CPU核同時運行。我們覺得實在兩個核上執行,但是實際上是在同一個物理核上。所以PMU會同時統計兩個程序觸發的事件,我們很難區分到底是哪個邏輯核出發了多少事件,所以PMU記錄的數據就會不準確。另外,性能分析器計算性能指標時會使用一些硬件參數,Hyper-Threading技術會讓這些參數不準確。例如一般個CPU核能再一個clock執行4個uop,所以CPI(Cycle Per Instruction,每個clock執行的指令數)是0.25。但是如果使用了Hyper-Threading技術,實際的CPI會是0.5
  • Event Skid(事件打滑)會導致記錄的IP不準確:
    PMU記錄有些事件會出現一定延時,所以在執行分析器的中斷處理代碼時,可能被測程序已經又執行了好多指令,IP已經向後滑動了很遠了。一般如果我們只是統計函數的話不會太大問題,但是我們想統計指令時就會有很大問題了。比如我們可能會看到某個add指令導致了大量的分支預測錯誤,顯然這個是不可能的。往往這種時候我們可以看看前面一點的指令。
  • Interrupt Masking(中斷屏蔽),導致統計出來的空閑狀態比正常的高
    不同的中斷有不同的優先級,為了高優先級的中斷處理程序不被打斷,我們可以選擇屏蔽一部分中斷事件。但是PMU的事件也是一个中斷,如果系統中有大量的中斷屏蔽,那麼會有PMU的中斷被屏蔽掉一部分,導致統計出來的數據不準確。表現出來的效果就是,統計出來的處於空閑狀態的時間比實際的要高。

總結

這幾個就是比較常見的性能分析方法。我們知道了性能分析的原理,可以更好地理解性能分析器給出的結果,也可以在出現明顯異常的結果時,分析判斷可能的原因,針對性的解決。

參考

https://en.wikipedia.org/wiki/Profiling_(computer_programming)
https://software.intel.com/content/www/us/en/develop/articles/understanding-how-general-exploration-works-in-intel-vtune-amplifier-xe.html
https://software.intel.com/content/www/us/en/develop/documentation/vtune-help/top/analyze-performance/user-mode-sampling-and-tracing-collection.html
https://software.intel.com/content/www/us/en/develop/documentation/vtune-help/top/analyze-performance/hardware-event-based-sampling-collection.html

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

※想知道最厲害的網頁設計公司"嚨底家"!

※別再煩惱如何寫文案,掌握八大原則!

※產品缺大量曝光嗎?你需要的是一流包裝設計!

分類
發燒車訊

循序漸進VUE+Element 前端應用開發(10)— 基於vue-echarts處理各種圖表展示,循序漸進VUE+Element 前端應用開發(5)— 表格列表頁面的查詢,列表展示和字段轉義處理,循序漸進VUE+Element 前端應用開發(9)— 界面語言國際化的處理

在我們做應用系統的時候,往往都會涉及圖表的展示,綜合的圖表展示能夠給客戶帶來視覺的享受和數據直觀體驗,同時也是增強客戶認同感的舉措之一。基於圖表的處理,我們一般往往都是利用對應第三方的圖表組件,然後在這個基礎上為它的數據模型提供符合要求的圖表數據即可,VUE+Element 前端應用也不例外,我們這裏使用了基於vue-echarts組件模塊來處理各種圖表vue-echarts是對echarts圖表組件的封裝。

1、圖表組件的安裝使用

首先使用npm 安裝vue-echarts組件。

git地址:https://github.com/ecomfe/vue-echarts

NPM安裝命令

npm install echarts vue-echarts

然後在對應模塊頁面裏面引入對應的組件對象,如下代碼所示。

<script>
import ECharts from 'vue-echarts' // 主圖表對象
import 'echarts/lib/chart/line' // 曲線圖表
import 'echarts/lib/chart/bar' // 柱狀圖
import 'echarts/lib/chart/pie' // 餅狀圖
import 'echarts/lib/component/tooltip' // 提示信息

接着在Vue組件裏面對象中加入對象即可。

export default {
  components: {
    'v-chart': ECharts
  },

如果是全局註冊使用,那麼可以在main.js裏面進行加載

// 註冊組件后即可使用
Vue.component('v-chart', VueECharts)

我們來看看圖表展示的效果圖

柱狀圖效果

 

餅狀圖

  

 曲線圖

  

 其他類型,極坐標和散點圖形

  

 或者曲線和柱狀圖組合的圖形

 更多的案例可以參考官網的展示介紹:https://echarts.apache.org/examples/zh/index.html

  

2、各種圖表的展示處理

對於我們需要的各種常規的柱狀圖、餅狀圖、折線圖(曲線圖)等,我下來介紹幾個案例代碼,其他的一般我們根據官方案例提供的data數據模型,構造對應的數據即可生成,就不再一一贅述。

另外,我們也可以參考Vue-echarts封裝的處理demo:https://github.com/ecomfe/vue-echarts/tree/master/src/demo 

對於柱狀圖,效果如下

在Vue模塊頁面的Template 裏面,我們定義界面代碼如下即可。

<v-chart
  ref="simplebar"
  :options="simplebar"
  autoresize
/>

然後在data裏面為它準備好數據即可,如下代碼所示。

 data() {
    return {
      simplebar: {
        title: { text: '柱形圖Demo' },
        tooltip: {},
        xAxis: {
          data: ['襯衫', '羊毛衫', '雪紡衫', '褲子', '高跟鞋', '襪子']
        },
        yAxis: {},
        series: [{
          name: '銷量',
          type: 'bar',
          data: [5, 20, 36, 10, 10, 20]
        }]
      }
    }
  }

當然我們也可以把這些構造對應數據的邏輯放在單獨的JS文件裏面,然後導入即可。

例如對於餅圖,它的界面效果如下所示。

它的vue視圖下,Template裏面的代碼如下所示。

<v-chart
  ref="pie"
  :options="pie"
  autoresize />

一般對於圖表的數據,由於處理代碼可能不少,建議是獨立放在一個JS文件裏面,然後我們通過import導入即可使用。

  然後在data裏面引入對應的對象即可,如下所示。

<script>
import ECharts from 'vue-echarts' // 主圖表對象
import 'echarts/lib/chart/line' // 曲線圖表
import 'echarts/lib/chart/bar' // 柱狀圖
import 'echarts/lib/chart/pie' // 餅狀圖
import 'echarts/lib/component/tooltip' // 提示信息

// 導入報表數據
import getBar from './chartdata/bar' import pie from './chartdata/pie'
import scatter from './chartdata/scatter'
import lineChart from './chartdata/lineChart'
import incomePay from './chartdata/incomePay'

export default {
  components: {
    'v-chart': ECharts
  },
   return {
      pie,
      scatter,,
      lineChart,
      incomePay,
      simplebar: {
        title: { text: '柱形圖Demo' },
        tooltip: {},
        xAxis: {
          data: ['襯衫', '羊毛衫', '雪紡衫', '褲子', '高跟鞋', '襪子']
        },
        yAxis: {},
        series: [{
          name: '銷量',
          type: 'bar',
          data: [5, 20, 36, 10, 10, 20]
        }]
      }
    }
  },

其中pie.js裏面放置的是處理餅圖數據的邏輯,如下代碼所示。

export default {
  title: {
    text: '餅圖程序調用高亮示例',
    x: 'center'
  },
  tooltip: {
    trigger: 'item',
    formatter: '{a} <br/>{b} : {c} ({d}%)'
  },
  legend: {
    orient: 'vertical',
    left: 'left',
    data: ['直接訪問', '郵件營銷', '聯盟廣告', '視頻廣告', '搜索引擎']
  },
  series: [
    {
      name: '訪問來源',
      type: 'pie',
      radius: '55%',
      center: ['50%', '60%'],
      data: [
        { value: 335, name: '直接訪問' },
        { value: 310, name: '郵件營銷' },
        { value: 234, name: '聯盟廣告' },
        { value: 135, name: '視頻廣告' },
        { value: 1548, name: '搜索引擎' }
      ],
      itemStyle: {
        emphasis: {
          shadowBlur: 10,
          shadowOffsetX: 0,
          shadowColor: 'rgba(0, 0, 0, 0.5)'
        }
      }
    }
  ]
}

在界面處理的時候,值得注意的時候,有時候Vue頁面處理正常,但是圖表就是沒有出來,可能是因為高度或者寬度為0的原因,需要對對應的樣式進行處理設置,以便能夠正常显示出來。

如下是我 對圖表的設置的樣式處理,使得圖表在一個卡片的位置能夠显示正常。

<style scoped>
  .echarts { width: 100%; height: 400px;}

  .el-row {
    margin-bottom: 20px;
  }
  .el-col {
    border-radius: 4px;
    margin-bottom: 20px;
  }
</style>

最後幾個界面組合一起的效果如下所示。

 以上就是基於vue-echarts處理各種圖表展示,其中常規的引入組件很容易的,主要就是需要根據對應的圖表案例,參考數據組成的規則,從而根據我們實際情況構建對應的數據,賦值給對應的模型變量即可。

列出以下前面幾篇隨筆的連接,供參考:

循序漸進VUE+Element 前端應用開發(1)— 開發環境的準備工作

循序漸進VUE+Element 前端應用開發(2)— Vuex中的API、Store和View的使用

循序漸進VUE+Element 前端應用開發(3)— 動態菜單和路由的關聯處理

循序漸進VUE+Element 前端應用開發(4)— 獲取後端數據及產品信息頁面的處理

循序漸進VUE+Element 前端應用開發(5)— 表格列表頁面的查詢,列表展示和字段轉義處理

循序漸進VUE+Element 前端應用開發(6)— 常規Element 界面組件的使用

循序漸進VUE+Element 前端應用開發(7)— 介紹一些常規的JS處理函數

循序漸進VUE+Element 前端應用開發(8)— 樹列表組件的使用

循序漸進VUE+Element 前端應用開發(9)— 界面語言國際化的處理

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※別再煩惱如何寫文案,掌握八大原則!

※教你寫出一流的銷售文案?

※超省錢租車方案

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※產品缺大量曝光嗎?你需要的是一流包裝設計!

分類
發燒車訊

10萬級最多人買的SUV,換代后還能不能讓你買單?

新車還針對霧燈區域裝飾調整,而大燈光源也更換為LED光源,照明效果更出眾。煥然一新的全新哈弗H6無疑是耐看的。要知道 耐看 向來就是比較難以保證的,在面對不斷變化的消費者眼光,懂得適時微調車型造型是一件識時務的事。

前幾天,奔赴北京,試駕了全新哈弗H6超豪型。與全新哈弗H6超豪型近距離接觸了幾天,哈弗H6已經是一款非常熟悉的SUV車型,對於它的了解也已經比較深刻;但是一款重點的全新換代,還是會讓人有不少的期待,更何況哈弗H6是一款在銷量上讓眾多同級別競品汗顏的熱銷產品,全新換代後會呈現怎樣的產品力,不得不說十分令人期待。

畢竟這是一場試駕為主的活動,所以更多的是衝著這款車本身的試駕感受去的,那文章的開始就先聊聊全新哈弗H6超豪型的駕駛體驗好了。

我從來不會擔心哈弗H6的底盤質感,在第一代哈弗H6上市后我就對它厚實穩重的底盤姿態感到十分的欣喜,而全新哈弗H6的底盤在此基礎上做了更加深度和全面的優化,底盤噪音降至一個很低的水平,在行駛過程中的舒適性得以充分保障;前麥弗遜,后多連桿的前後獨立懸架將路面振動過濾得比較徹底,而且避震響應動作同樣也比較利落,在面對常見顛簸路面的時候不會有晃晃悠悠的動作,行駛姿態非常從容。

其次動力總成的變化同樣讓人印象深刻,新的1.5T渦輪增壓發動機新增了長城自己正向研發的可變氣門升程技術,新技術的引入不僅改善了油耗水平,更在功率和峰值扭矩上做了12.7%和35.7%的提升,讓哈弗H6的綜合性能有了明顯的提高。

雙離合變速箱的標定水平也是有了長足的進步,這款濕式雙離合變速箱在實際駕駛中可以很明顯的感知到工程師在對它進行標定的時候極大程度上考慮到了行駛平順的重要性,換擋平順程度十分友好,不會有明顯突兀的頓挫感。

除了駕駛感受給留下不錯的印象,對哈弗H6的外觀印象也越來越好了。

全新哈弗H6超豪型藍標版的前臉有着比較大變化,新車用上了面積更大的進氣格柵,且鍍鉻裝飾條數量增加為五條;前保險杠處的通風口更換為網狀設計;而新車尾部整體造型變化不大。整車看起來更時尚、動感了。

至於全新哈弗H6超豪型紅標版呢?外觀也是有着不容忽視的變化。與藍標版的改變相似,紅標版新車型的進氣格柵也稍微變大了,且有着5條鍍鉻裝飾條;新車還針對霧燈區域裝飾調整,而大燈光源也更換為LED光源,照明效果更出眾。

煥然一新的全新哈弗H6無疑是耐看的。要知道 耐看 向來就是比較難以保證的,在面對不斷變化的消費者眼光,懂得適時微調車型造型是一件識時務的事。哈弗H6就很好地做到這一點,全新哈弗H6超豪型更符合當下年輕消費者的口味,潛在消費人群無疑會也進一步擴大。

進入車內,可以感受到全新哈弗H6超豪型的座椅包裹性有了明顯改善,增強了乘坐舒適性。不僅如此,新車內飾是蒙皮經純植物提取的香料處理了,還配有pM2.5粉塵過濾系統,車內的乘坐環境更為舒適。此外,新車還在後排空調出風口下方設計了兩個USB接口,車內配備了0.82㎡的超大全景天窗、前排座椅加熱等配置,這一切都令全新哈弗H6超豪型的駕乘舒適性達到了新的高度。

儲物空間方面,哈弗的工程師針對換擋桿前方置物盒造型進行優化,優化后的儲物盒能容納下更多更大的隨身物品。而新車的後備廂經優化后,整體容積增大近20L,實用性更強了。

安全,也是全新哈弗H6超豪型所注重的。新車增加了四項主動安全配置,包含半自動泊車系統、ACC自適應巡航系統、360°環視系統、FCW前碰撞預警系統+AEB自動剎車系統。此外,全新哈弗H6超豪型配備了側氣簾。主/被動安全系統更加完善的哈弗H6有助於對乘客進行全方位智能防護。

比你優秀的人不可怕,可怕的是比你優秀的人比你更努力。哈弗H6就是那個很努力的優秀“人”。作為國產緊湊型SUV市場的常勝將軍,哈弗H6一向都是走實力派路線的。試駕過很多版本的哈弗H6,可以說是看着它將自己的小毛病一個一個地改掉,到近年來接近完美的狀態。至於經多方升級的全新哈弗H6超豪型,我們有理由相信它未來將助力哈弗H6家族繼續在SUV市場叱吒風雲。

本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※為什麼 USB CONNECTOR 是電子產業重要的元件?

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

※台北網頁設計公司全省服務真心推薦

※想知道最厲害的網頁設計公司"嚨底家"!

※推薦評價好的iphone維修中心